| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- //协议反序列化
- package util
- import (
- "bytes"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "math"
- "reflect"
- "runtime/debug"
- "sync"
- "unsafe"
- )
- //将二进制协议转为结构体
- func UnPack(data []byte, v interface{}) error {
- d := decodeState{*bytes.NewBuffer(data)}
- return d.unmarshal(v)
- }
- func (d *decodeState) unmarshal(v interface{}) (err error) {
- defer func() {
- if r := recover(); r != nil {
- if je, ok := r.(error); ok {
- err = je
- } else {
- err = errors.New("unpack error:" + fmt.Sprint(r) + " debug:" + string(debug.Stack()))
- }
- }
- }()
- rv := reflect.ValueOf(v)
- if rv.Kind() != reflect.Ptr || rv.IsNil() {
- return errors.New("unpack not support type:" + reflect.TypeOf(v).String())
- }
- d.reflectValue(rv.Elem())
- return
- }
- //按长度读取字符串
- func (d *decodeState) ReadBytesLen(l uint32) []byte {
- buf := make([]byte, l)
- _, err := io.ReadFull(d, buf)
- if err != nil {
- panic(err)
- }
- return buf
- }
- //读取数字类型(需要明确v指针类型)
- func (d *decodeState) ReadInt(v interface{}) {
- err := binary.Read(d, binary.BigEndian, v)
- if err != nil {
- panic(err)
- }
- }
- type decodeState struct {
- bytes.Buffer
- }
- func (d *decodeState) reflectValue(v reflect.Value) {
- typeDecoder(v.Type())(d, v)
- }
- type decoderFunc func(e *decodeState, v reflect.Value)
- var decoderCache sync.Map // map[reflect.Type]decoderFunc
- func typeDecoder(t reflect.Type) decoderFunc {
- if fi, ok := decoderCache.Load(t); ok {
- return fi.(decoderFunc)
- }
- var (
- wg sync.WaitGroup
- f decoderFunc
- )
- wg.Add(1)
- fi, loaded := decoderCache.LoadOrStore(t, decoderFunc(func(e *decodeState, v reflect.Value) {
- wg.Wait()
- f(e, v)
- }))
- if loaded {
- return fi.(decoderFunc)
- }
- f = newTypeDecoder(t)
- wg.Done()
- decoderCache.Store(t, f)
- return f
- }
- func newTypeDecoder(t reflect.Type) decoderFunc {
- switch t.Kind() {
- case reflect.Bool:
- return boolDecoder
- case reflect.Int:
- return intDecoder
- case reflect.Int32:
- return int32Decoder
- case reflect.Uint:
- return uintDecoder
- case reflect.Uint32:
- return uint32Decoder
- case reflect.Int8:
- return int8Decoder
- case reflect.Int16:
- return int16Decoder
- case reflect.Int64:
- return int64Decoder
- case reflect.Uint8:
- return uint8Decoder
- case reflect.Uint16:
- return uint16Decoder
- case reflect.Uint64:
- return uint64Decoder
- case reflect.Float32:
- return float32Decoder
- case reflect.Float64:
- return float64Decoder
- case reflect.String:
- return stringDecoder
- case reflect.Struct:
- return newStructDecoder(t)
- case reflect.Slice:
- return newSliceDecoder(t)
- case reflect.Array:
- return newArrayDecoder(t)
- default:
- panic(errors.New("proto unpack: unsupported type: " + t.String()))
- }
- }
- func boolDecoder(d *decodeState, v reflect.Value) {
- b, err := d.ReadByte()
- if err != nil {
- panic(err)
- }
- if b == 1 {
- v.SetBool(true)
- } else {
- v.SetBool(false)
- }
- }
- //读取四个字节
- func intDecoder(d *decodeState, v reflect.Value) {
- var t int32
- d.ReadInt(&t)
- v.SetInt(int64(t))
- }
- //读取四个字节
- func int32Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*int32)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- //读取四个字节
- func uintDecoder(d *decodeState, v reflect.Value) {
- var t uint32
- d.ReadInt(&t)
- v.SetUint(uint64(t))
- }
- func uint32Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*uint32)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- func int8Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*int8)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- func int16Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*int16)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- func int64Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*int64)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- func uint8Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*uint8)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- func uint16Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*uint16)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- func uint64Decoder(d *decodeState, v reflect.Value) {
- d.ReadInt((*uint64)((unsafe.Pointer)(v.UnsafeAddr())))
- }
- //float32
- func float32Decoder(d *decodeState, v reflect.Value) {
- var b uint32 = 0
- d.ReadInt(&b)
- v.SetFloat(float64(math.Float32frombits(b)))
- }
- //float64
- func float64Decoder(d *decodeState, v reflect.Value) {
- var b uint64 = 0
- d.ReadInt(&b)
- v.SetFloat(math.Float64frombits(b))
- }
- //string解析
- func stringDecoder(d *decodeState, v reflect.Value) {
- var l uint32 = 0
- d.ReadInt(&l)
- if l == 0 {
- return
- }
- b := make([]byte, l)
- _, err := io.ReadFull(d, b)
- if err != nil {
- panic(err)
- }
- v.SetString(string(b))
- }
- func newSliceDecoder(t reflect.Type) decoderFunc {
- if t.Elem().Kind() == reflect.Uint8 {
- return decodeByteSlice
- }
- dec := sliceDecoder{newArrayDecoder(t)}
- return dec.decode
- }
- func newArrayDecoder(t reflect.Type) decoderFunc {
- dec := arrayDecoder{typeDecoder(t.Elem())}
- return dec.decode
- }
- func decodeByteSlice(d *decodeState, v reflect.Value) {
- var l uint32
- d.ReadInt(&l)
- if l == 0 {
- return
- }
- v.SetBytes(d.ReadBytesLen(l))
- }
- type sliceDecoder struct {
- arrayDec decoderFunc
- }
- type arrayDecoder struct {
- elemDec decoderFunc
- }
- func (se sliceDecoder) decode(d *decodeState, v reflect.Value) {
- se.arrayDec(d, v)
- }
- func (ae arrayDecoder) decode(d *decodeState, v reflect.Value) {
- var l uint32
- d.ReadInt(&l)
- if l == 0 {
- return
- }
- L := int(l)
- if v.Kind() == reflect.Slice {
- v.Set(reflect.MakeSlice(v.Type(), L, L))
- }
- for i := 0; i < L; i++ {
- ae.elemDec(d, v.Index(i))
- }
- }
- type structDecoder struct {
- fields []deField
- }
- func (se structDecoder) decode(d *decodeState, v reflect.Value) {
- for i := range se.fields {
- f := &se.fields[i]
- f.decoder(d, v.Field(i))
- }
- }
- var deFieldCache sync.Map // map[reflect.Type]structDecoder
- type deField struct {
- decoder decoderFunc
- }
- func newStructDecoder(t reflect.Type) decoderFunc {
- return cachedDeFields(t).decode
- }
- func cachedDeFields(t reflect.Type) structDecoder {
- if f, ok := deFieldCache.Load(t); ok {
- return f.(structDecoder)
- }
- f, _ := deFieldCache.LoadOrStore(t, typeDeFields(t))
- return f.(structDecoder)
- }
- func typeDeFields(t reflect.Type) structDecoder {
- var fields []deField
- for i := 0; i < t.NumField(); i++ {
- sf := t.Field(i)
- st := sf.Type
- if st == t {
- panic("proto:not support recursive type:" + st.String())
- }
- if sf.PkgPath != "" {
- panic("proto:not support type:" + t.String() + ",name:" + sf.Name)
- }
- fields = append(fields, deField{decoder: typeDecoder(st)})
- }
- return structDecoder{fields}
- }
|