github.com/niubaoshu/gotiny@v0.0.4-0.20211018120156-10d393f19ad0/encoder.go (about) 1 package gotiny 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type Encoder struct { 9 buf []byte //编码目的数组 10 off int 11 boolPos int //下一次要设置的bool在buf中的下标,即buf[boolPos] 12 boolBit byte //下一次要设置的bool的buf[boolPos]中的bit位 13 14 engines []encEng 15 length int 16 } 17 18 func Marshal(is ...interface{}) []byte { 19 return NewEncoderWithPtr(is...).Encode(is...) 20 } 21 22 // 创建一个编码ps 指向类型的编码器 23 func NewEncoderWithPtr(ps ...interface{}) *Encoder { 24 l := len(ps) 25 engines := make([]encEng, l) 26 for i := 0; i < l; i++ { 27 rt := reflect.TypeOf(ps[i]) 28 if rt.Kind() != reflect.Ptr { 29 panic("must a pointer type!") 30 } 31 engines[i] = getEncEngine(rt.Elem()) 32 } 33 return &Encoder{ 34 length: l, 35 engines: engines, 36 } 37 } 38 39 // 创建一个编码is 类型的编码器 40 func NewEncoder(is ...interface{}) *Encoder { 41 l := len(is) 42 engines := make([]encEng, l) 43 for i := 0; i < l; i++ { 44 engines[i] = getEncEngine(reflect.TypeOf(is[i])) 45 } 46 return &Encoder{ 47 length: l, 48 engines: engines, 49 } 50 } 51 52 func NewEncoderWithType(ts ...reflect.Type) *Encoder { 53 l := len(ts) 54 engines := make([]encEng, l) 55 for i := 0; i < l; i++ { 56 engines[i] = getEncEngine(ts[i]) 57 } 58 return &Encoder{ 59 length: l, 60 engines: engines, 61 } 62 } 63 64 // 入参是要编码值的指针 65 func (e *Encoder) Encode(is ...interface{}) []byte { 66 engines := e.engines 67 for i := 0; i < len(engines) && i < len(is); i++ { 68 engines[i](e, (*[2]unsafe.Pointer)(unsafe.Pointer(&is[i]))[1]) 69 } 70 return e.reset() 71 } 72 73 // 入参是要编码的值得unsafe.Pointer 指针 74 func (e *Encoder) EncodePtr(ps ...unsafe.Pointer) []byte { 75 engines := e.engines 76 for i := 0; i < len(engines) && i < len(ps); i++ { 77 engines[i](e, ps[i]) 78 } 79 return e.reset() 80 } 81 82 // vs 是持有要编码的值 83 func (e *Encoder) EncodeValue(vs ...reflect.Value) []byte { 84 engines := e.engines 85 for i := 0; i < len(engines) && i < len(vs); i++ { 86 engines[i](e, getUnsafePointer(&vs[i])) 87 } 88 return e.reset() 89 } 90 91 // 编码产生的数据将append到buf上 92 func (e *Encoder) AppendTo(buf []byte) { 93 e.off = len(buf) 94 e.buf = buf 95 } 96 97 func (e *Encoder) reset() []byte { 98 buf := e.buf 99 e.buf = buf[:e.off] 100 e.boolBit = 0 101 e.boolPos = 0 102 return buf 103 }