代码拉取完成,页面将自动刷新
package coderx
import (
"encoding/binary"
"fmt"
"gitee.com/zhongguo168a/gocodes/datax"
"gitee.com/zhongguo168a/gocodes/datax/binaryx"
"gitee.com/zhongguo168a/gocodes/datax/schemax"
"gitee.com/zhongguo168a/gocodes/datax/schemax/basickind"
"gitee.com/zhongguo168a/gocodes/myx/errorx"
"io"
"math"
"strconv"
)
func NewByteToMapWithType(_type string) (obj *ByteToMap, err error) {
schema := schemax.GetDeclByKey(_type)
if schema == nil {
err = errorx.New("schema not found: ", datax.M{"_type": _type})
return
}
obj = NewByteToMapWithSchema(schema.(*schemax.ClassDecl))
return
}
func NewByteToMapWithSchema(schema *schemax.ClassDecl) (obj *ByteToMap) {
obj = NewByteToMap()
obj.schema = schema
return
}
func NewByteToMap() (obj *ByteToMap) {
obj = &ByteToMap{}
obj.endian = binary.LittleEndian
return
}
type ByteToMap struct {
schema *schemax.ClassDecl
//
change bool
//
endian binary.ByteOrder
}
func (coder *ByteToMap) Reset() {
coder.schema = nil
coder.endian = binary.LittleEndian
coder.change = false
}
func (coder *ByteToMap) SetByteOrder(order binary.ByteOrder) *ByteToMap {
coder.endian = order
return coder
}
func (coder *ByteToMap) Read(reader io.Reader, target map[string]interface{}) (err error) {
if target == nil {
err = errorx.New("target is nil")
return
}
change, readerr := binaryx.ReadBool(reader, coder.endian)
if readerr != nil {
err = errorx.Wrap(readerr, fmt.Sprintf("read change"))
return
}
coder.change = change
return coder.decodeAllObj(target, reader, coder.schema)
}
// keyMode 0-source的字段, 1-所有字段
func (coder *ByteToMap) decodeAllObj(targetMap map[string]interface{}, reader io.Reader, schema schemax.IDecl) (err error) {
var (
decl = schema.(*schemax.ClassDecl)
)
allfields := decl.GetAllField()
if coder.change {
var newfields []*schemax.Field
groupLen := int(math.Ceil(float64(len(allfields)) / 8.0))
for i := 0; i < groupLen; i++ {
state, readerr := binaryx.ReadUint8(reader, coder.endian)
if readerr != nil {
err = errorx.Wrap(readerr, fmt.Sprintf("read state"))
return
}
for j := 0; j < 8; j++ {
if binaryx.GetState(uint(state), 1<<j) {
index := i*8 + j
newfields = append(newfields, allfields[index])
}
}
}
allfields = newfields
}
for _, field := range allfields {
fname := field.Name
switch ftyp := field.Type.(type) {
case *schemax.ClassType:
st, derr := coder.decodeAllClass(reader, ftyp.Decl)
if derr != nil {
err = errorx.Wrap(derr, fname)
return
}
targetMap[fname] = st
case *schemax.ArrayType:
data, derr := coder.decodeAllSlice(reader, fname, ftyp)
if derr != nil {
err = errorx.Wrap(derr, fname)
return
}
targetMap[fname] = data
case *schemax.MapType:
data, derr := coder.decodeAllMap(reader, ftyp)
if derr != nil {
err = errorx.Wrap(derr, fname)
return
}
targetMap[fname] = data
case *schemax.EnumType:
data, derr := coder.decodeAllEnum(reader, ftyp.Decl)
if derr != nil {
err = errorx.Wrap(derr, fname)
return
}
targetMap[fname] = data
case *schemax.BasicType:
data, derr := coder.decodeAllBasic(reader, ftyp.Kind)
if derr != nil {
err = errorx.Wrap(derr, fname)
return
}
targetMap[fname] = data
case *schemax.AnyType:
continue
default:
}
}
return
}
func (coder *ByteToMap) decodeAllClass(reader io.Reader, decl string) (st map[string]interface{}, err error) {
isNil, readerr := binaryx.ReadBool(reader, coder.endian)
if readerr != nil {
err = errorx.Wrap(readerr, fmt.Sprintf("read class nil"))
return
}
if isNil {
return
}
stdesc := schemax.GetDeclByKey(decl)
if stdesc == nil {
err = errorx.New("schema not found: ", datax.M{"decl": decl})
return
}
st = map[string]interface{}{}
err = coder.decodeAllObj(st, reader, stdesc)
return
}
func (coder *ByteToMap) decodeAllEnum(reader io.Reader, decl string) (data interface{}, err error) {
idesc := schemax.GetDeclByKey(decl)
if idesc == nil {
err = errorx.New("schema not found", datax.M{"decl": decl})
return
}
enumdesc := idesc.(*schemax.EnumDecl)
data, err = coder.decodeAllBasic(reader, basickind.Kind(enumdesc.Kind))
if err != nil {
return
}
return
}
func (coder *ByteToMap) decodeAllSlice(reader io.Reader, fname string, ftyp *schemax.ArrayType) (arr []interface{}, err error) {
ilen, readerr := binaryx.ReadInt16(reader, coder.endian)
if readerr != nil {
err = errorx.Wrap(readerr, fmt.Sprintf("read array length"))
return
}
mlen := int(ilen)
if mlen == 0 {
return
}
switch etyp := ftyp.Elem.(type) {
case *schemax.ClassType:
for i := 0; i < mlen; i++ {
st, derr := coder.decodeAllClass(reader, etyp.Decl)
if derr != nil {
err = errorx.Wrap(derr, strconv.Itoa(i))
return
}
arr = append(arr, st)
}
case *schemax.BasicType:
for i := 0; i < mlen; i++ {
val, derr := coder.decodeAllBasic(reader, etyp.Kind)
if derr != nil {
err = errorx.Wrap(derr, strconv.Itoa(i))
return
}
arr = append(arr, val)
}
case *schemax.EnumType:
for i := 0; i < mlen; i++ {
val, derr := coder.decodeAllEnum(reader, etyp.Decl)
if derr != nil {
err = errorx.Wrap(derr, strconv.Itoa(i))
return
}
arr = append(arr, val)
}
default:
err = errorx.New("decode array: not support type: " + etyp.String())
return
}
return
}
func (coder *ByteToMap) decodeAllMap(reader io.Reader, ftyp *schemax.MapType) (mmap map[string]interface{}, err error) {
isNil, nilerr := binaryx.ReadBool(reader, coder.endian)
if nilerr != nil {
err = errorx.Wrap(nilerr, fmt.Sprintf("read map nil"))
return
}
if isNil {
return
}
mlen, nilerr := binaryx.ReadInt16(reader, coder.endian)
if nilerr != nil {
err = errorx.Wrap(nilerr, fmt.Sprintf("read map length"))
return
}
mmap = map[string]interface{}{}
for i := 0; i < int(mlen); i++ {
mkey, readerr := binaryx.ReadUTF(reader, coder.endian)
if readerr != nil {
err = errorx.Wrap(readerr, fmt.Sprintf("read map key"))
return
}
switch etyp := ftyp.Value.(type) {
case *schemax.ClassType:
st, derr := coder.decodeAllClass(reader, etyp.Decl)
if derr != nil {
err = errorx.Wrap(derr, mkey)
return
}
mmap[mkey] = st
case *schemax.BasicType:
val, derr := coder.decodeAllBasic(reader, etyp.Kind)
if derr != nil {
err = errorx.Wrap(derr, mkey)
return
}
mmap[mkey] = val
case *schemax.EnumType:
val, derr := coder.decodeAllEnum(reader, etyp.Decl)
if derr != nil {
err = errorx.Wrap(derr, mkey)
return
}
mmap[mkey] = val
default:
err = errorx.New("not support type: " + etyp.String())
return
}
}
return
}
func (coder *ByteToMap) decodeAllBasic(reader io.Reader, kind basickind.Kind) (val interface{}, err error) {
switch kind {
case basickind.Bool:
data, rerr := binaryx.ReadBool(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read bool"))
return
}
val = data
case basickind.Int8:
data, rerr := binaryx.ReadInt8(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read int8"))
return
}
val = data
case basickind.Int16:
data, rerr := binaryx.ReadInt16(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read int16"))
return
}
val = data
case basickind.Int32:
data, rerr := binaryx.ReadInt32(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read int32"))
return
}
val = data
case basickind.Int64:
data, rerr := binaryx.ReadInt64(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read int64"))
return
}
val = data
case basickind.Uint8:
data, rerr := binaryx.ReadUint8(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read uint8"))
return
}
val = data
case basickind.Uint16:
data, rerr := binaryx.ReadUint8(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read uint16"))
return
}
val = data
case basickind.Uint32:
data, rerr := binaryx.ReadUint32(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read uint32"))
return
}
val = data
case basickind.Uint64:
data, rerr := binaryx.ReadUint64(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read uint64"))
return
}
val = data
case basickind.Float32:
data, rerr := binaryx.ReadFloat32(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read float32"))
return
}
val = data
case basickind.Float64:
data, rerr := binaryx.ReadFloat64(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read float64"))
return
}
val = data
case basickind.String:
data, rerr := binaryx.ReadUTF(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read string"))
return
}
val = data
case basickind.Bytes:
data, rerr := binaryx.ReadBytes(reader, coder.endian)
if rerr != nil {
err = errorx.Wrap(rerr, fmt.Sprintf("read bytes"))
return
}
val = data
}
return
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。