gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/datax/coderx/ByteToMap.go (about) 1 package coderx 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "gitee.com/zhongguo168a/gocodes/datax" 7 "gitee.com/zhongguo168a/gocodes/datax/binaryx" 8 "gitee.com/zhongguo168a/gocodes/datax/schemax" 9 "gitee.com/zhongguo168a/gocodes/datax/schemax/basickind" 10 "gitee.com/zhongguo168a/gocodes/myx/errorx" 11 "io" 12 "math" 13 "strconv" 14 ) 15 16 func NewByteToMapWithType(_type string) (obj *ByteToMap, err error) { 17 schema := schemax.GetDeclByKey(_type) 18 if schema == nil { 19 err = errorx.New("schema not found: ", datax.M{"_type": _type}) 20 return 21 } 22 obj = NewByteToMapWithSchema(schema.(*schemax.ClassDecl)) 23 return 24 } 25 26 func NewByteToMapWithSchema(schema *schemax.ClassDecl) (obj *ByteToMap) { 27 obj = NewByteToMap() 28 obj.schema = schema 29 30 return 31 } 32 33 func NewByteToMap() (obj *ByteToMap) { 34 obj = &ByteToMap{} 35 obj.endian = binary.LittleEndian 36 return 37 } 38 39 type ByteToMap struct { 40 schema *schemax.ClassDecl 41 // 42 change bool 43 // 44 endian binary.ByteOrder 45 } 46 47 func (coder *ByteToMap) Reset() { 48 coder.schema = nil 49 coder.endian = binary.LittleEndian 50 coder.change = false 51 } 52 53 func (coder *ByteToMap) SetByteOrder(order binary.ByteOrder) *ByteToMap { 54 coder.endian = order 55 return coder 56 } 57 58 func (coder *ByteToMap) Read(reader io.Reader, target map[string]interface{}) (err error) { 59 if target == nil { 60 err = errorx.New("target is nil") 61 return 62 } 63 change, readerr := binaryx.ReadBool(reader, coder.endian) 64 if readerr != nil { 65 err = errorx.Wrap(readerr, fmt.Sprintf("read change")) 66 return 67 } 68 coder.change = change 69 return coder.decodeAllObj(target, reader, coder.schema) 70 } 71 72 // keyMode 0-source的字段, 1-所有字段 73 func (coder *ByteToMap) decodeAllObj(targetMap map[string]interface{}, reader io.Reader, schema schemax.IDecl) (err error) { 74 var ( 75 decl = schema.(*schemax.ClassDecl) 76 ) 77 allfields := decl.GetAllField() 78 if coder.change { 79 var newfields []*schemax.Field 80 groupLen := int(math.Ceil(float64(len(allfields)) / 8.0)) 81 for i := 0; i < groupLen; i++ { 82 state, readerr := binaryx.ReadUint8(reader, coder.endian) 83 if readerr != nil { 84 err = errorx.Wrap(readerr, fmt.Sprintf("read state")) 85 return 86 } 87 for j := 0; j < 8; j++ { 88 if binaryx.GetState(uint(state), 1<<j) { 89 index := i*8 + j 90 newfields = append(newfields, allfields[index]) 91 } 92 } 93 } 94 95 allfields = newfields 96 } 97 98 for _, field := range allfields { 99 fname := field.Name 100 switch ftyp := field.Type.(type) { 101 case *schemax.ClassType: 102 st, derr := coder.decodeAllClass(reader, ftyp.Decl) 103 if derr != nil { 104 err = errorx.Wrap(derr, fname) 105 return 106 } 107 targetMap[fname] = st 108 case *schemax.ArrayType: 109 data, derr := coder.decodeAllSlice(reader, fname, ftyp) 110 if derr != nil { 111 err = errorx.Wrap(derr, fname) 112 return 113 } 114 targetMap[fname] = data 115 case *schemax.MapType: 116 data, derr := coder.decodeAllMap(reader, ftyp) 117 if derr != nil { 118 err = errorx.Wrap(derr, fname) 119 return 120 } 121 targetMap[fname] = data 122 case *schemax.EnumType: 123 data, derr := coder.decodeAllEnum(reader, ftyp.Decl) 124 if derr != nil { 125 err = errorx.Wrap(derr, fname) 126 return 127 } 128 targetMap[fname] = data 129 case *schemax.BasicType: 130 data, derr := coder.decodeAllBasic(reader, ftyp.Kind) 131 if derr != nil { 132 err = errorx.Wrap(derr, fname) 133 return 134 } 135 targetMap[fname] = data 136 case *schemax.AnyType: 137 continue 138 default: 139 } 140 } 141 return 142 } 143 144 func (coder *ByteToMap) decodeAllClass(reader io.Reader, decl string) (st map[string]interface{}, err error) { 145 isNil, readerr := binaryx.ReadBool(reader, coder.endian) 146 if readerr != nil { 147 err = errorx.Wrap(readerr, fmt.Sprintf("read class nil")) 148 return 149 } 150 if isNil { 151 return 152 } 153 stdesc := schemax.GetDeclByKey(decl) 154 if stdesc == nil { 155 err = errorx.New("schema not found: ", datax.M{"decl": decl}) 156 return 157 } 158 159 st = map[string]interface{}{} 160 err = coder.decodeAllObj(st, reader, stdesc) 161 return 162 } 163 func (coder *ByteToMap) decodeAllEnum(reader io.Reader, decl string) (data interface{}, err error) { 164 idesc := schemax.GetDeclByKey(decl) 165 if idesc == nil { 166 err = errorx.New("schema not found", datax.M{"decl": decl}) 167 return 168 } 169 170 enumdesc := idesc.(*schemax.EnumDecl) 171 data, err = coder.decodeAllBasic(reader, basickind.Kind(enumdesc.Kind)) 172 if err != nil { 173 return 174 } 175 return 176 } 177 178 func (coder *ByteToMap) decodeAllSlice(reader io.Reader, fname string, ftyp *schemax.ArrayType) (arr []interface{}, err error) { 179 ilen, readerr := binaryx.ReadInt16(reader, coder.endian) 180 if readerr != nil { 181 err = errorx.Wrap(readerr, fmt.Sprintf("read array length")) 182 return 183 } 184 mlen := int(ilen) 185 if mlen == 0 { 186 return 187 } 188 switch etyp := ftyp.Elem.(type) { 189 case *schemax.ClassType: 190 for i := 0; i < mlen; i++ { 191 st, derr := coder.decodeAllClass(reader, etyp.Decl) 192 if derr != nil { 193 err = errorx.Wrap(derr, strconv.Itoa(i)) 194 return 195 } 196 arr = append(arr, st) 197 } 198 case *schemax.BasicType: 199 for i := 0; i < mlen; i++ { 200 val, derr := coder.decodeAllBasic(reader, etyp.Kind) 201 if derr != nil { 202 err = errorx.Wrap(derr, strconv.Itoa(i)) 203 return 204 } 205 arr = append(arr, val) 206 } 207 case *schemax.EnumType: 208 for i := 0; i < mlen; i++ { 209 val, derr := coder.decodeAllEnum(reader, etyp.Decl) 210 if derr != nil { 211 err = errorx.Wrap(derr, strconv.Itoa(i)) 212 return 213 } 214 arr = append(arr, val) 215 } 216 default: 217 err = errorx.New("decode array: not support type: " + etyp.String()) 218 return 219 220 } 221 222 return 223 } 224 225 func (coder *ByteToMap) decodeAllMap(reader io.Reader, ftyp *schemax.MapType) (mmap map[string]interface{}, err error) { 226 isNil, nilerr := binaryx.ReadBool(reader, coder.endian) 227 if nilerr != nil { 228 err = errorx.Wrap(nilerr, fmt.Sprintf("read map nil")) 229 return 230 } 231 if isNil { 232 return 233 } 234 235 mlen, nilerr := binaryx.ReadInt16(reader, coder.endian) 236 if nilerr != nil { 237 err = errorx.Wrap(nilerr, fmt.Sprintf("read map length")) 238 return 239 } 240 241 mmap = map[string]interface{}{} 242 for i := 0; i < int(mlen); i++ { 243 mkey, readerr := binaryx.ReadUTF(reader, coder.endian) 244 if readerr != nil { 245 err = errorx.Wrap(readerr, fmt.Sprintf("read map key")) 246 return 247 } 248 249 switch etyp := ftyp.Value.(type) { 250 case *schemax.ClassType: 251 st, derr := coder.decodeAllClass(reader, etyp.Decl) 252 if derr != nil { 253 err = errorx.Wrap(derr, mkey) 254 return 255 } 256 mmap[mkey] = st 257 case *schemax.BasicType: 258 val, derr := coder.decodeAllBasic(reader, etyp.Kind) 259 if derr != nil { 260 err = errorx.Wrap(derr, mkey) 261 return 262 } 263 mmap[mkey] = val 264 case *schemax.EnumType: 265 val, derr := coder.decodeAllEnum(reader, etyp.Decl) 266 if derr != nil { 267 err = errorx.Wrap(derr, mkey) 268 return 269 } 270 mmap[mkey] = val 271 default: 272 err = errorx.New("not support type: " + etyp.String()) 273 return 274 } 275 } 276 return 277 } 278 279 func (coder *ByteToMap) decodeAllBasic(reader io.Reader, kind basickind.Kind) (val interface{}, err error) { 280 switch kind { 281 case basickind.Bool: 282 data, rerr := binaryx.ReadBool(reader, coder.endian) 283 if rerr != nil { 284 err = errorx.Wrap(rerr, fmt.Sprintf("read bool")) 285 return 286 } 287 val = data 288 case basickind.Int8: 289 data, rerr := binaryx.ReadInt8(reader, coder.endian) 290 if rerr != nil { 291 err = errorx.Wrap(rerr, fmt.Sprintf("read int8")) 292 return 293 } 294 val = data 295 case basickind.Int16: 296 data, rerr := binaryx.ReadInt16(reader, coder.endian) 297 if rerr != nil { 298 err = errorx.Wrap(rerr, fmt.Sprintf("read int16")) 299 return 300 } 301 val = data 302 case basickind.Int32: 303 data, rerr := binaryx.ReadInt32(reader, coder.endian) 304 if rerr != nil { 305 err = errorx.Wrap(rerr, fmt.Sprintf("read int32")) 306 return 307 } 308 val = data 309 case basickind.Int64: 310 data, rerr := binaryx.ReadInt64(reader, coder.endian) 311 if rerr != nil { 312 err = errorx.Wrap(rerr, fmt.Sprintf("read int64")) 313 return 314 } 315 val = data 316 case basickind.Uint8: 317 data, rerr := binaryx.ReadUint8(reader, coder.endian) 318 if rerr != nil { 319 err = errorx.Wrap(rerr, fmt.Sprintf("read uint8")) 320 return 321 } 322 val = data 323 case basickind.Uint16: 324 data, rerr := binaryx.ReadUint8(reader, coder.endian) 325 if rerr != nil { 326 err = errorx.Wrap(rerr, fmt.Sprintf("read uint16")) 327 return 328 } 329 val = data 330 case basickind.Uint32: 331 data, rerr := binaryx.ReadUint32(reader, coder.endian) 332 if rerr != nil { 333 err = errorx.Wrap(rerr, fmt.Sprintf("read uint32")) 334 return 335 } 336 val = data 337 case basickind.Uint64: 338 data, rerr := binaryx.ReadUint64(reader, coder.endian) 339 if rerr != nil { 340 err = errorx.Wrap(rerr, fmt.Sprintf("read uint64")) 341 return 342 } 343 val = data 344 case basickind.Float32: 345 data, rerr := binaryx.ReadFloat32(reader, coder.endian) 346 if rerr != nil { 347 err = errorx.Wrap(rerr, fmt.Sprintf("read float32")) 348 return 349 } 350 val = data 351 case basickind.Float64: 352 data, rerr := binaryx.ReadFloat64(reader, coder.endian) 353 if rerr != nil { 354 err = errorx.Wrap(rerr, fmt.Sprintf("read float64")) 355 return 356 } 357 val = data 358 case basickind.String: 359 data, rerr := binaryx.ReadUTF(reader, coder.endian) 360 if rerr != nil { 361 err = errorx.Wrap(rerr, fmt.Sprintf("read string")) 362 return 363 } 364 val = data 365 case basickind.Bytes: 366 data, rerr := binaryx.ReadBytes(reader, coder.endian) 367 if rerr != nil { 368 err = errorx.Wrap(rerr, fmt.Sprintf("read bytes")) 369 return 370 } 371 val = data 372 } 373 return 374 }