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  }