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  }