github.com/niubaoshu/gotiny@v0.0.4-0.20211018120156-10d393f19ad0/decoder.go (about) 1 package gotiny 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type Decoder struct { 9 buf []byte //buf 10 index int //下一个要使用的字节在buf中的下标 11 boolPos byte //下一次要读取的bool在buf中的下标,即buf[boolPos] 12 boolBit byte //下一次要读取的bool的buf[boolPos]中的bit位 13 14 engines []decEng //解码器集合 15 length int //解码器数量 16 } 17 18 func Unmarshal(buf []byte, is ...interface{}) int { 19 return NewDecoderWithPtr(is...).Decode(buf, is...) 20 } 21 22 func NewDecoderWithPtr(is ...interface{}) *Decoder { 23 l := len(is) 24 engines := make([]decEng, l) 25 for i := 0; i < l; i++ { 26 rt := reflect.TypeOf(is[i]) 27 if rt.Kind() != reflect.Ptr { 28 panic("must a pointer type!") 29 } 30 engines[i] = getDecEngine(rt.Elem()) 31 } 32 return &Decoder{ 33 length: l, 34 engines: engines, 35 } 36 } 37 38 func NewDecoder(is ...interface{}) *Decoder { 39 l := len(is) 40 engines := make([]decEng, l) 41 for i := 0; i < l; i++ { 42 engines[i] = getDecEngine(reflect.TypeOf(is[i])) 43 } 44 return &Decoder{ 45 length: l, 46 engines: engines, 47 } 48 } 49 50 func NewDecoderWithType(ts ...reflect.Type) *Decoder { 51 l := len(ts) 52 des := make([]decEng, l) 53 for i := 0; i < l; i++ { 54 des[i] = getDecEngine(ts[i]) 55 } 56 return &Decoder{ 57 length: l, 58 engines: des, 59 } 60 } 61 62 func (d *Decoder) reset() int { 63 index := d.index 64 d.index = 0 65 d.boolPos = 0 66 d.boolBit = 0 67 return index 68 } 69 70 // is is pointer of variable 71 func (d *Decoder) Decode(buf []byte, is ...interface{}) int { 72 d.buf = buf 73 engines := d.engines 74 for i := 0; i < len(engines) && i < len(is); i++ { 75 engines[i](d, (*[2]unsafe.Pointer)(unsafe.Pointer(&is[i]))[1]) 76 } 77 return d.reset() 78 } 79 80 // ps is a unsafe.Pointer of the variable 81 func (d *Decoder) DecodePtr(buf []byte, ps ...unsafe.Pointer) int { 82 d.buf = buf 83 engines := d.engines 84 for i := 0; i < len(engines) && i < len(ps); i++ { 85 engines[i](d, ps[i]) 86 } 87 return d.reset() 88 } 89 90 func (d *Decoder) DecodeValue(buf []byte, vs ...reflect.Value) int { 91 d.buf = buf 92 engines := d.engines 93 for i := 0; i < len(engines) && i < len(vs); i++ { 94 engines[i](d, unsafe.Pointer(vs[i].UnsafeAddr())) 95 } 96 return d.reset() 97 }