github.com/niubaoshu/gotiny@v0.0.4-0.20211018120156-10d393f19ad0/decEngine.go (about) 1 package gotiny 2 3 import ( 4 "reflect" 5 "sync" 6 "time" 7 "unsafe" 8 ) 9 10 type decEng func(*Decoder, unsafe.Pointer) // 解码器 11 12 var ( 13 rt2decEng = map[reflect.Type]decEng{ 14 reflect.TypeOf((*bool)(nil)).Elem(): decBool, 15 reflect.TypeOf((*int)(nil)).Elem(): decInt, 16 reflect.TypeOf((*int8)(nil)).Elem(): decInt8, 17 reflect.TypeOf((*int16)(nil)).Elem(): decInt16, 18 reflect.TypeOf((*int32)(nil)).Elem(): decInt32, 19 reflect.TypeOf((*int64)(nil)).Elem(): decInt64, 20 reflect.TypeOf((*uint)(nil)).Elem(): decUint, 21 reflect.TypeOf((*uint8)(nil)).Elem(): decUint8, 22 reflect.TypeOf((*uint16)(nil)).Elem(): decUint16, 23 reflect.TypeOf((*uint32)(nil)).Elem(): decUint32, 24 reflect.TypeOf((*uint64)(nil)).Elem(): decUint64, 25 reflect.TypeOf((*uintptr)(nil)).Elem(): decUintptr, 26 reflect.TypeOf((*unsafe.Pointer)(nil)).Elem(): decPointer, 27 reflect.TypeOf((*float32)(nil)).Elem(): decFloat32, 28 reflect.TypeOf((*float64)(nil)).Elem(): decFloat64, 29 reflect.TypeOf((*complex64)(nil)).Elem(): decComplex64, 30 reflect.TypeOf((*complex128)(nil)).Elem(): decComplex128, 31 reflect.TypeOf((*[]byte)(nil)).Elem(): decBytes, 32 reflect.TypeOf((*string)(nil)).Elem(): decString, 33 reflect.TypeOf((*time.Time)(nil)).Elem(): decTime, 34 reflect.TypeOf((*struct{})(nil)).Elem(): decIgnore, 35 reflect.TypeOf(nil): decIgnore, 36 } 37 38 baseDecEngines = []decEng{ 39 reflect.Invalid: decIgnore, 40 reflect.Bool: decBool, 41 reflect.Int: decInt, 42 reflect.Int8: decInt8, 43 reflect.Int16: decInt16, 44 reflect.Int32: decInt32, 45 reflect.Int64: decInt64, 46 reflect.Uint: decUint, 47 reflect.Uint8: decUint8, 48 reflect.Uint16: decUint16, 49 reflect.Uint32: decUint32, 50 reflect.Uint64: decUint64, 51 reflect.Uintptr: decUintptr, 52 reflect.UnsafePointer: decPointer, 53 reflect.Float32: decFloat32, 54 reflect.Float64: decFloat64, 55 reflect.Complex64: decComplex64, 56 reflect.Complex128: decComplex128, 57 reflect.String: decString, 58 } 59 decLock sync.RWMutex 60 ) 61 62 func getDecEngine(rt reflect.Type) decEng { 63 decLock.RLock() 64 engine := rt2decEng[rt] 65 decLock.RUnlock() 66 if engine != nil { 67 return engine 68 } 69 decLock.Lock() 70 buildDecEngine(rt, &engine) 71 decLock.Unlock() 72 return engine 73 } 74 75 func buildDecEngine(rt reflect.Type, engPtr *decEng) { 76 engine, has := rt2decEng[rt] 77 if has { 78 *engPtr = engine 79 return 80 } 81 82 if _, engine = implementOtherSerializer(rt); engine != nil { 83 rt2decEng[rt] = engine 84 *engPtr = engine 85 return 86 } 87 88 kind := rt.Kind() 89 var eEng decEng 90 switch kind { 91 case reflect.Ptr: 92 et := rt.Elem() 93 defer buildDecEngine(et, &eEng) 94 engine = func(d *Decoder, p unsafe.Pointer) { 95 if d.decIsNotNil() { 96 if isNil(p) { 97 *(*unsafe.Pointer)(p) = unsafe.Pointer(reflect.New(et).Elem().UnsafeAddr()) 98 } 99 eEng(d, *(*unsafe.Pointer)(p)) 100 } else if !isNil(p) { 101 *(*unsafe.Pointer)(p) = nil 102 } 103 } 104 case reflect.Array: 105 l, et := rt.Len(), rt.Elem() 106 size := et.Size() 107 defer buildDecEngine(et, &eEng) 108 engine = func(d *Decoder, p unsafe.Pointer) { 109 for i := 0; i < l; i++ { 110 eEng(d, unsafe.Pointer(uintptr(p)+uintptr(i)*size)) 111 } 112 } 113 case reflect.Slice: 114 et := rt.Elem() 115 size := et.Size() 116 defer buildDecEngine(et, &eEng) 117 engine = func(d *Decoder, p unsafe.Pointer) { 118 header := (*reflect.SliceHeader)(p) 119 if d.decIsNotNil() { 120 l := d.decLength() 121 if isNil(p) || header.Cap < l { 122 *header = reflect.SliceHeader{Data: reflect.MakeSlice(rt, l, l).Pointer(), Len: l, Cap: l} 123 } else { 124 header.Len = l 125 } 126 for i := 0; i < l; i++ { 127 eEng(d, unsafe.Pointer(header.Data+uintptr(i)*size)) 128 } 129 } else if !isNil(p) { 130 *header = reflect.SliceHeader{} 131 } 132 } 133 case reflect.Map: 134 kt, vt := rt.Key(), rt.Elem() 135 skt, svt := reflect.SliceOf(kt), reflect.SliceOf(vt) 136 var kEng, vEng decEng 137 defer buildDecEngine(kt, &kEng) 138 defer buildDecEngine(vt, &vEng) 139 engine = func(d *Decoder, p unsafe.Pointer) { 140 if d.decIsNotNil() { 141 l := d.decLength() 142 var v reflect.Value 143 if isNil(p) { 144 v = reflect.MakeMapWithSize(rt, l) 145 *(*unsafe.Pointer)(p) = unsafe.Pointer(v.Pointer()) 146 } else { 147 v = reflect.NewAt(rt, p).Elem() 148 } 149 keys, vals := reflect.MakeSlice(skt, l, l), reflect.MakeSlice(svt, l, l) 150 for i := 0; i < l; i++ { 151 key, val := keys.Index(i), vals.Index(i) 152 kEng(d, unsafe.Pointer(key.UnsafeAddr())) 153 vEng(d, unsafe.Pointer(val.UnsafeAddr())) 154 v.SetMapIndex(key, val) 155 } 156 } else if !isNil(p) { 157 *(*unsafe.Pointer)(p) = nil 158 } 159 } 160 case reflect.Struct: 161 fields, offs := getFieldType(rt, 0) 162 nf := len(fields) 163 fEngines := make([]decEng, nf) 164 defer func() { 165 for i := 0; i < nf; i++ { 166 buildDecEngine(fields[i], &fEngines[i]) 167 } 168 }() 169 engine = func(d *Decoder, p unsafe.Pointer) { 170 for i := 0; i < len(fEngines) && i < len(offs); i++ { 171 fEngines[i](d, unsafe.Pointer(uintptr(p)+offs[i])) 172 } 173 } 174 case reflect.Interface: 175 engine = func(d *Decoder, p unsafe.Pointer) { 176 if d.decIsNotNil() { 177 name := "" 178 decString(d, unsafe.Pointer(&name)) 179 et, has := name2type[name] 180 if !has { 181 panic("unknown typ:" + name) 182 } 183 v := reflect.NewAt(rt, p).Elem() 184 var ev reflect.Value 185 if v.IsNil() || v.Elem().Type() != et { 186 ev = reflect.New(et).Elem() 187 } else { 188 ev = v.Elem() 189 } 190 getDecEngine(et)(d, getUnsafePointer(&ev)) 191 v.Set(ev) 192 } else if !isNil(p) { 193 *(*unsafe.Pointer)(p) = nil 194 } 195 } 196 case reflect.Chan, reflect.Func: 197 panic("not support " + rt.String() + " type") 198 default: 199 engine = baseDecEngines[kind] 200 } 201 rt2decEng[rt] = engine 202 *engPtr = engine 203 }