gitee.com/quant1x/gox@v1.21.2/encoding/binary/cstruct/buffer.go (about)

     1  package cstruct
     2  
     3  import (
     4  	"encoding/binary"
     5  	"io"
     6  	"reflect"
     7  	"unsafe"
     8  )
     9  
    10  type Buffer struct {
    11  	buf   []byte
    12  	index int
    13  }
    14  
    15  func NewBuffer(e []byte) *Buffer {
    16  	return &Buffer{buf: e}
    17  }
    18  
    19  func (p *Buffer) Reset() {
    20  	p.buf = p.buf[:0]
    21  	p.index = 0
    22  }
    23  
    24  // Pack
    25  
    26  func (p *Buffer) Marshal(obj IStruct) error {
    27  	t, base, err := getbase(obj)
    28  	if structPointer_IsNil(base) {
    29  		return ErrNil
    30  	}
    31  	if err == nil {
    32  		props := GetProperties(t.Elem())
    33  		s := p.size_struct(props, base)
    34  		p.buf = make([]byte, s)
    35  		err = p.enc_struct(props, base)
    36  	}
    37  	return err
    38  }
    39  
    40  func getbase(obj IStruct) (t reflect.Type, b structPointer, err error) {
    41  	if obj == nil {
    42  		err = ErrNil
    43  		return
    44  	}
    45  	t = reflect.TypeOf(obj)
    46  	value := reflect.ValueOf(obj)
    47  	b = toStructPointer(value)
    48  	return
    49  }
    50  
    51  func (o *Buffer) size_struct(prop *StructProperties, base structPointer) int {
    52  	ret := prop.fixedSize
    53  	for _, p := range prop.Prop {
    54  		if p.siz != nil {
    55  			ret += p.siz(o, p, base)
    56  		}
    57  	}
    58  	return ret
    59  }
    60  
    61  func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
    62  	for _, p := range prop.Prop {
    63  		if p.enc != nil {
    64  			if err := p.enc(o, p, base); err != nil {
    65  				return err
    66  			}
    67  		}
    68  	}
    69  	return nil
    70  }
    71  
    72  // Unmarshal
    73  
    74  func (p *Buffer) Unmarshal(obj IStruct) error {
    75  	typ, base, err := getbase(obj)
    76  	if err != nil {
    77  		return err
    78  	}
    79  
    80  	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), base)
    81  }
    82  
    83  func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, base structPointer) error {
    84  	for _, p := range prop.Prop {
    85  		if p.dec != nil {
    86  			if err := p.dec(o, p, base); err != nil {
    87  				return err
    88  			}
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  // bool
    95  func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
    96  	v := structPointer_BoolVal(base, p.field)
    97  	x := 0
    98  	if *v {
    99  		x = 1
   100  	}
   101  	o.buf[o.index] = uint8(x)
   102  	o.index++
   103  	return nil
   104  }
   105  
   106  func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
   107  	i := o.index + 1
   108  	if i < 0 || i > len(o.buf) {
   109  		return io.ErrUnexpectedEOF
   110  	}
   111  	o.index = i
   112  	u := uint8(o.buf[i-1])
   113  	v := structPointer_BoolVal(base, p.field)
   114  	*v = (u != 0)
   115  	return nil
   116  }
   117  
   118  // uint8
   119  func (o *Buffer) enc_uint8(p *Properties, base structPointer) error {
   120  	v := (*uint8)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   121  	o.buf[o.index] = *v
   122  	o.index++
   123  	return nil
   124  }
   125  
   126  func (o *Buffer) dec_uint8(p *Properties, base structPointer) error {
   127  	i := o.index + 1
   128  	if i < 0 || i > len(o.buf) {
   129  		return io.ErrUnexpectedEOF
   130  	}
   131  	o.index = i
   132  	u := uint8(o.buf[i-1])
   133  	v := (*uint8)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   134  	*v = u
   135  	return nil
   136  }
   137  
   138  // uint16
   139  func (o *Buffer) enc_uint16(p *Properties, base structPointer) error {
   140  	v := (*uint16)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   141  	binary.LittleEndian.PutUint16(o.buf[o.index:], *v)
   142  	o.index += 2
   143  	return nil
   144  }
   145  
   146  func (o *Buffer) dec_uint16(p *Properties, base structPointer) error {
   147  	u, err := o.readUInt16()
   148  	if err != nil {
   149  		return err
   150  	}
   151  	v := (*uint16)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   152  	*v = u
   153  	return nil
   154  }
   155  
   156  // uint32
   157  func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
   158  	v := (*uint32)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   159  	binary.LittleEndian.PutUint32(o.buf[o.index:], *v)
   160  	o.index += 4
   161  	return nil
   162  }
   163  
   164  func (o *Buffer) dec_uint32(p *Properties, base structPointer) error {
   165  	v := (*uint32)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   166  	i := o.index + 4
   167  	if i < 0 || i > len(o.buf) {
   168  		return io.ErrUnexpectedEOF
   169  	}
   170  	o.index = i
   171  	*v = binary.LittleEndian.Uint32(o.buf[i-4:])
   172  	return nil
   173  }
   174  
   175  // uint64
   176  func (o *Buffer) enc_uint64(p *Properties, base structPointer) error {
   177  	v := (*uint64)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   178  	binary.LittleEndian.PutUint64(o.buf[o.index:], *v)
   179  	o.index += 8
   180  	return nil
   181  }
   182  
   183  func (o *Buffer) dec_uint64(p *Properties, base structPointer) error {
   184  	v := (*uint64)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   185  	i := o.index + 8
   186  	if i < 0 || i > len(o.buf) {
   187  		return io.ErrUnexpectedEOF
   188  	}
   189  	o.index = i
   190  	*v = binary.LittleEndian.Uint64(o.buf[i-8:])
   191  	return nil
   192  }
   193  
   194  // string
   195  func (o *Buffer) enc_string(p *Properties, base structPointer) error {
   196  	v := structPointer_StringVal(base, p.field)
   197  	ln := len(*v)
   198  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   199  	o.index += 2
   200  	if ln > 0 {
   201  		copy(o.buf[o.index:], *v)
   202  		o.index += ln
   203  	}
   204  	return nil
   205  }
   206  
   207  func (o *Buffer) dec_string(p *Properties, base structPointer) error {
   208  	nb, err := o.readUInt16()
   209  	if err != nil {
   210  		return err
   211  	}
   212  
   213  	end := o.index + int(nb)
   214  	if end < o.index || end > len(o.buf) {
   215  		return io.ErrUnexpectedEOF
   216  	}
   217  	buf := o.buf[o.index:end]
   218  	o.index = end
   219  
   220  	v := structPointer_StringVal(base, p.field)
   221  	*v = string(buf)
   222  	return nil
   223  }
   224  
   225  func (o *Buffer) size_string(p *Properties, base structPointer) int {
   226  	v := structPointer_StringVal(base, p.field)
   227  	return len(*v)
   228  }
   229  
   230  // []byte
   231  func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
   232  	v := structPointer_Bytes(base, p.field)
   233  	ln := len(*v)
   234  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   235  	o.index += 2
   236  	if ln > 0 {
   237  		copy(o.buf[o.index:], *v)
   238  		o.index += ln
   239  	}
   240  	return nil
   241  }
   242  
   243  func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
   244  	v := structPointer_Bytes(base, p.field)
   245  	nb, err := o.readUInt16()
   246  	if err != nil {
   247  		return err
   248  	}
   249  
   250  	end := o.index + int(nb)
   251  	if end < o.index || end > len(o.buf) {
   252  		return io.ErrUnexpectedEOF
   253  	}
   254  	*v = append((*v)[:0], o.buf[o.index:end]...)
   255  	o.index = end
   256  	return nil
   257  }
   258  
   259  func (o *Buffer) size_slice_byte(p *Properties, base structPointer) int {
   260  	v := structPointer_Bytes(base, p.field)
   261  	return len(*v)
   262  }
   263  
   264  // cstruct ptr
   265  func (o *Buffer) enc_substruct_ptr(p *Properties, base structPointer) error {
   266  	v := structPointer_GetStructPointer(base, p.field)
   267  	if v == nil {
   268  		o.buf[o.index] = uint8(0)
   269  		o.index++
   270  		return nil
   271  	} else {
   272  		o.buf[o.index] = uint8(1)
   273  		o.index++
   274  		return o.enc_struct(p.sprop, v)
   275  	}
   276  }
   277  func (o *Buffer) dec_substruct_ptr(p *Properties, base structPointer) error {
   278  	bas := structPointer_GetStructPointer(base, p.field)
   279  	i := o.index + 1
   280  	if i < 0 || i > len(o.buf) {
   281  		return io.ErrUnexpectedEOF
   282  	}
   283  	o.index = i
   284  	flag := uint8(o.buf[i-1])
   285  	if flag == 0 {
   286  		return nil
   287  	}
   288  	if structPointer_IsNil(bas) {
   289  		bas = toStructPointer(reflect.New(p.stype))
   290  		structPointer_SetStructPointer(base, p.field, bas)
   291  	}
   292  	return o.unmarshalType(p.stype, p.sprop, bas)
   293  }
   294  func (o *Buffer) size_substruct_ptr(p *Properties, base structPointer) int {
   295  	v := structPointer_GetStructPointer(base, p.field)
   296  	if v == nil {
   297  		return 1
   298  	}
   299  	return o.size_struct(p.sprop, v) + 1
   300  }
   301  
   302  // cstruct
   303  func (o *Buffer) enc_substruct(p *Properties, base structPointer) error {
   304  	return o.enc_struct(p.sprop, structPointer(unsafe.Pointer(uintptr(base)+uintptr(p.field))))
   305  }
   306  func (o *Buffer) dec_substruct(p *Properties, base structPointer) error {
   307  	bas := structPointer(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   308  	return o.unmarshalType(p.stype, p.sprop, bas)
   309  }
   310  func (o *Buffer) size_substruct(p *Properties, base structPointer) int {
   311  	return o.size_struct(p.sprop, structPointer(unsafe.Pointer(uintptr(base)+uintptr(p.field))))
   312  }
   313  
   314  // []bool
   315  func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
   316  	v := structPointer_BoolSlice(base, p.field)
   317  	ln := len(*v)
   318  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   319  	o.index += 2
   320  	for i := 0; i < ln; i++ {
   321  		x := 0
   322  		if (*v)[i] {
   323  			x = 1
   324  		}
   325  		o.buf[o.index] = uint8(x)
   326  		o.index += 1
   327  	}
   328  	return nil
   329  }
   330  
   331  func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
   332  	v := structPointer_BoolSlice(base, p.field)
   333  	nb, err := o.readUInt16()
   334  	if err != nil {
   335  		return err
   336  	}
   337  	end := o.index + int(nb)
   338  	if end < o.index || end > len(o.buf) {
   339  		return io.ErrUnexpectedEOF
   340  	}
   341  	*v = make([]bool, int(nb))
   342  	for i := 0; i < int(nb); i++ {
   343  		u := uint8(o.buf[o.index+i])
   344  		(*v)[i] = (u != 0)
   345  	}
   346  	o.index = end
   347  	return nil
   348  }
   349  
   350  func (o *Buffer) size_slice_bool(p *Properties, base structPointer) int {
   351  	v := structPointer_BoolSlice(base, p.field)
   352  	return len(*v)
   353  }
   354  
   355  // []uint16
   356  func (o *Buffer) enc_slice_uint16(p *Properties, base structPointer) error {
   357  	v := (*[]uint16)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   358  	ln := len(*v)
   359  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   360  	o.index += 2
   361  	for i := 0; i < ln; i++ {
   362  		binary.LittleEndian.PutUint16(o.buf[o.index:], (*v)[i])
   363  		o.index += 2
   364  	}
   365  	return nil
   366  }
   367  
   368  func (o *Buffer) dec_slice_uint16(p *Properties, base structPointer) error {
   369  	v := (*[]uint16)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   370  	nb, err := o.readUInt16()
   371  	if err != nil {
   372  		return err
   373  	}
   374  	end := o.index + int(nb)*2
   375  	if end < o.index || end > len(o.buf) {
   376  		return io.ErrUnexpectedEOF
   377  	}
   378  	*v = make([]uint16, int(nb))
   379  	for i := 0; i < int(nb); i++ {
   380  		(*v)[i] = binary.LittleEndian.Uint16(o.buf[o.index+i*2:])
   381  	}
   382  	o.index = end
   383  	return nil
   384  }
   385  
   386  func (o *Buffer) size_slice_uint16(p *Properties, base structPointer) int {
   387  	v := (*[]uint16)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   388  	return len(*v) * 2
   389  }
   390  
   391  // []uint32
   392  func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
   393  	v := (*[]uint32)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   394  	ln := len(*v)
   395  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   396  	o.index += 2
   397  	for i := 0; i < ln; i++ {
   398  		binary.LittleEndian.PutUint32(o.buf[o.index:], (*v)[i])
   399  		o.index += 4
   400  	}
   401  	return nil
   402  }
   403  
   404  func (o *Buffer) dec_slice_uint32(p *Properties, base structPointer) error {
   405  	v := (*[]uint32)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   406  	nb, err := o.readUInt16()
   407  	if err != nil {
   408  		return err
   409  	}
   410  	end := o.index + int(nb)*4
   411  	if end < o.index || end > len(o.buf) {
   412  		return io.ErrUnexpectedEOF
   413  	}
   414  	*v = make([]uint32, int(nb))
   415  	for i := 0; i < int(nb); i++ {
   416  		(*v)[i] = binary.LittleEndian.Uint32(o.buf[o.index+i*4:])
   417  	}
   418  	o.index = end
   419  	return nil
   420  }
   421  
   422  func (o *Buffer) size_slice_uint32(p *Properties, base structPointer) int {
   423  	v := (*[]uint32)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   424  	return len(*v) * 4
   425  }
   426  
   427  // []uint64
   428  func (o *Buffer) enc_slice_uint64(p *Properties, base structPointer) error {
   429  	v := (*[]uint64)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   430  	ln := len(*v)
   431  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   432  	o.index += 2
   433  	for i := 0; i < ln; i++ {
   434  		binary.LittleEndian.PutUint64(o.buf[o.index:], (*v)[i])
   435  		o.index += 8
   436  	}
   437  	return nil
   438  }
   439  
   440  func (o *Buffer) dec_slice_uint64(p *Properties, base structPointer) error {
   441  	v := (*[]uint64)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   442  	nb, err := o.readUInt16()
   443  	if err != nil {
   444  		return err
   445  	}
   446  	end := o.index + int(nb)*8
   447  	if end < o.index || end > len(o.buf) {
   448  		return io.ErrUnexpectedEOF
   449  	}
   450  	*v = make([]uint64, int(nb))
   451  	for i := 0; i < int(nb); i++ {
   452  		(*v)[i] = binary.LittleEndian.Uint64(o.buf[o.index+i*8:])
   453  	}
   454  	o.index = end
   455  	return nil
   456  }
   457  
   458  func (o *Buffer) size_slice_uint64(p *Properties, base structPointer) int {
   459  	v := (*[]uint64)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   460  	return len(*v) * 8
   461  }
   462  
   463  // []string
   464  func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
   465  	v := (*[]string)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   466  	ln := len(*v)
   467  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   468  	o.index += 2
   469  	for i := 0; i < ln; i++ {
   470  		ln2 := len((*v)[i])
   471  		binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln2))
   472  		o.index += 2
   473  		if ln2 > 0 {
   474  			copy(o.buf[o.index:], (*v)[i])
   475  			o.index += ln2
   476  		}
   477  	}
   478  	return nil
   479  }
   480  
   481  func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
   482  	v := (*[]string)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   483  	nb0, err0 := o.readUInt16()
   484  	if err0 != nil {
   485  		return err0
   486  	}
   487  	*v = make([]string, int(nb0))
   488  	for i := 0; i < int(nb0); i++ {
   489  		nb, err := o.readUInt16()
   490  		if err != nil {
   491  			return err
   492  		}
   493  		end := o.index + int(nb)
   494  		if end < o.index || end > len(o.buf) {
   495  			return io.ErrUnexpectedEOF
   496  		}
   497  		(*v)[i] = string(o.buf[o.index:end])
   498  		o.index = end
   499  	}
   500  	return nil
   501  }
   502  
   503  func (o *Buffer) size_slice_string(p *Properties, base structPointer) int {
   504  	v := (*[]string)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   505  	ret := 0
   506  	ln := len(*v)
   507  	for i := 0; i < ln; i++ {
   508  		ret += len((*v)[i]) + 2
   509  	}
   510  	return ret
   511  }
   512  
   513  // []cstruct
   514  func (o *Buffer) enc_slice_substruct(p *Properties, base structPointer) error {
   515  	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   516  	var ln = sliceHeader.Len
   517  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   518  	o.index += 2
   519  	itemsize := int(p.stype.Size())
   520  	for i := 0; i < ln; i++ {
   521  		sv := (structPointer)(unsafe.Pointer(sliceHeader.Data + uintptr(i*itemsize)))
   522  		o.enc_struct(p.sprop, sv)
   523  	}
   524  	return nil
   525  }
   526  
   527  func (o *Buffer) dec_slice_substruct(p *Properties, base structPointer) error {
   528  	nb, err := o.readUInt16()
   529  	if err != nil {
   530  		return err
   531  	}
   532  	if nb == 0 {
   533  		return nil
   534  	}
   535  	itemsize := int(p.stype.Size())
   536  	data := reflect.MakeSlice(p.t, int(nb), int(nb))
   537  	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   538  	sliceHeader.Cap = int(nb)
   539  	sliceHeader.Len = int(nb)
   540  	sliceHeader.Data = data.Pointer()
   541  	for i := 0; i < int(nb); i++ {
   542  		data := (structPointer)(unsafe.Pointer(sliceHeader.Data + uintptr(i*itemsize)))
   543  		o.unmarshalType(p.stype, p.sprop, data)
   544  	}
   545  	return nil
   546  }
   547  
   548  func (o *Buffer) size_slice_substruct(p *Properties, base structPointer) int {
   549  	ret := 0
   550  	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(uintptr(base) + uintptr(p.field)))
   551  	var ln = sliceHeader.Len
   552  	itemsize := int(p.stype.Size())
   553  	for i := 0; i < ln; i++ {
   554  		sv := (structPointer)(sliceHeader.Data + uintptr(i*itemsize))
   555  		ret += o.size_struct(p.sprop, sv)
   556  	}
   557  	return ret
   558  }
   559  
   560  // []struct_ptr
   561  func (o *Buffer) enc_slice_substruct_ptr(p *Properties, base structPointer) error {
   562  	v := structPointer_StructPointerSlice(base, p.field)
   563  	ln := v.Len()
   564  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   565  	o.index += 2
   566  	for i := 0; i < ln; i++ {
   567  		sv := (*v)[i]
   568  		if sv == nil {
   569  			o.buf[o.index] = uint8(0)
   570  			o.index++
   571  		} else {
   572  			o.buf[o.index] = uint8(1)
   573  			o.index++
   574  			o.enc_struct(p.sprop, sv)
   575  		}
   576  	}
   577  	return nil
   578  }
   579  
   580  func (o *Buffer) dec_slice_substruct_ptr(p *Properties, base structPointer) error {
   581  	v := structPointer_StructPointerSlice(base, p.field)
   582  	nb, err := o.readUInt16()
   583  	if err != nil {
   584  		return err
   585  	}
   586  	for j := 0; j < int(nb); j++ {
   587  		i := o.index + 1
   588  		if i < 0 || i > len(o.buf) {
   589  			return io.ErrUnexpectedEOF
   590  		}
   591  		o.index = i
   592  		flag := uint8(o.buf[i-1])
   593  		if flag == 0 {
   594  			v.Append(nil)
   595  		} else {
   596  			bas := toStructPointer(reflect.New(p.stype))
   597  			o.unmarshalType(p.stype, p.sprop, bas)
   598  			v.Append(bas)
   599  		}
   600  	}
   601  	return nil
   602  }
   603  
   604  func (o *Buffer) size_slice_substruct_ptr(p *Properties, base structPointer) int {
   605  	ret := 0
   606  	v := structPointer_StructPointerSlice(base, p.field)
   607  	ln := v.Len()
   608  	for i := 0; i < ln; i++ {
   609  		sv := (*v)[i]
   610  		if sv == nil {
   611  			ret += 1
   612  		} else {
   613  			ret += o.size_struct(p.sprop, sv) + 1
   614  		}
   615  	}
   616  	return ret
   617  }
   618  
   619  // []struct_ptr ignore nil
   620  func (o *Buffer) enc_slice_substruct_ptr_ignore_nil(p *Properties, base structPointer) error {
   621  	v := structPointer_StructPointerSlice(base, p.field)
   622  	ln := v.Len()
   623  	len_index := o.index
   624  	real_ln := 0
   625  	o.index += 2
   626  	for i := 0; i < ln; i++ {
   627  		sv := (*v)[i]
   628  		if sv != nil {
   629  			real_ln++
   630  			o.enc_struct(p.sprop, sv)
   631  		}
   632  	}
   633  	binary.LittleEndian.PutUint16(o.buf[len_index:], uint16(real_ln))
   634  	return nil
   635  }
   636  
   637  func (o *Buffer) dec_slice_substruct_ptr_ignore_nil(p *Properties, base structPointer) error {
   638  	v := structPointer_StructPointerSlice(base, p.field)
   639  	nb, err := o.readUInt16()
   640  	if err != nil {
   641  		return err
   642  	}
   643  	for j := 0; j < int(nb); j++ {
   644  		bas := toStructPointer(reflect.New(p.stype))
   645  		v.Append(bas)
   646  		o.unmarshalType(p.stype, p.sprop, bas)
   647  	}
   648  	return nil
   649  }
   650  
   651  func (o *Buffer) size_slice_substruct_ptr_ignore_nil(p *Properties, base structPointer) int {
   652  	ret := 0
   653  	v := structPointer_StructPointerSlice(base, p.field)
   654  	ln := v.Len()
   655  	for i := 0; i < ln; i++ {
   656  		sv := (*v)[i]
   657  		if sv != nil {
   658  			ret += o.size_struct(p.sprop, sv)
   659  		}
   660  	}
   661  	return ret
   662  }
   663  
   664  // [][]byte
   665  func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
   666  	v := structPointer_BytesSlice(base, p.field)
   667  	ln := len(*v)
   668  	binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln))
   669  	o.index += 2
   670  	for i := 0; i < ln; i++ {
   671  		ln2 := len((*v)[i])
   672  		binary.LittleEndian.PutUint16(o.buf[o.index:], uint16(ln2))
   673  		o.index += 2
   674  		if ln2 > 0 {
   675  			copy(o.buf[o.index:], (*v)[i])
   676  			o.index += ln2
   677  		}
   678  	}
   679  	return nil
   680  }
   681  
   682  func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
   683  	v := structPointer_BytesSlice(base, p.field)
   684  	nb, err := o.readUInt16()
   685  	if err != nil {
   686  		return err
   687  	}
   688  	for i := 0; i < int(nb); i++ {
   689  		nb2, err := o.readUInt16()
   690  		if err != nil {
   691  			return err
   692  		}
   693  
   694  		end := o.index + int(nb2)
   695  		if end < o.index || end > len(o.buf) {
   696  			return io.ErrUnexpectedEOF
   697  		}
   698  		buf := o.buf[o.index:end]
   699  		o.index = end
   700  
   701  		*v = append(*v, buf)
   702  	}
   703  	return nil
   704  }
   705  
   706  func (o *Buffer) size_slice_slice_byte(p *Properties, base structPointer) int {
   707  	v := structPointer_BytesSlice(base, p.field)
   708  	ret := 0
   709  	ln := len(*v)
   710  	for i := 0; i < ln; i++ {
   711  		ret += len((*v)[i]) + 2
   712  	}
   713  	return ret
   714  }
   715  
   716  func (o *Buffer) readUInt16() (uint16, error) {
   717  	i := o.index + 2
   718  	if i < 0 || i > len(o.buf) {
   719  		return 0, io.ErrUnexpectedEOF
   720  	}
   721  	o.index = i
   722  	return binary.LittleEndian.Uint16(o.buf[i-2:]), nil
   723  }
   724  
   725  // [n]byte [n]uint8 [n]int8 [n]bool
   726  func (o *Buffer) enc_array_byte(p *Properties, base structPointer) error {
   727  	ln := p.t.Len()
   728  	if ln > 0 {
   729  		var data []byte
   730  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   731  		sliceHeader.Cap = ln
   732  		sliceHeader.Len = ln
   733  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   734  		copy(o.buf[o.index:], data)
   735  		o.index += ln
   736  	}
   737  	return nil
   738  }
   739  
   740  func (o *Buffer) dec_array_byte(p *Properties, base structPointer) error {
   741  	ln := p.t.Len()
   742  	if ln > 0 {
   743  		end := o.index + ln
   744  		if end < o.index || end > len(o.buf) {
   745  			return io.ErrUnexpectedEOF
   746  		}
   747  		var data []byte
   748  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   749  		sliceHeader.Cap = ln
   750  		sliceHeader.Len = ln
   751  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   752  		copy(data, o.buf[o.index:end])
   753  		o.index = end
   754  	}
   755  	return nil
   756  }
   757  
   758  func (o *Buffer) size_array_byte(p *Properties, base structPointer) int {
   759  	return p.t.Len()
   760  }
   761  
   762  // [n]uint16 [n]int16
   763  func (o *Buffer) enc_array_uint16(p *Properties, base structPointer) error {
   764  	ln := p.t.Len()
   765  	if ln > 0 {
   766  		var data []uint16
   767  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   768  		sliceHeader.Cap = ln
   769  		sliceHeader.Len = ln
   770  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   771  		for i := 0; i < ln; i++ {
   772  			binary.LittleEndian.PutUint16(o.buf[o.index:], data[i])
   773  			o.index += 2
   774  		}
   775  	}
   776  	return nil
   777  }
   778  
   779  func (o *Buffer) dec_array_uint16(p *Properties, base structPointer) error {
   780  	ln := p.t.Len()
   781  	if ln > 0 {
   782  		end := o.index + ln*2
   783  		if end < o.index || end > len(o.buf) {
   784  			return io.ErrUnexpectedEOF
   785  		}
   786  		var data []uint16
   787  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   788  		sliceHeader.Cap = ln
   789  		sliceHeader.Len = ln
   790  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   791  		for i := 0; i < ln; i++ {
   792  			data[i] = binary.LittleEndian.Uint16(o.buf[o.index+i*2:])
   793  		}
   794  		o.index = end
   795  	}
   796  	return nil
   797  }
   798  
   799  func (o *Buffer) size_array_uint16(p *Properties, base structPointer) int {
   800  	return p.t.Len() * 2
   801  }
   802  
   803  // [n]uint32 [n]int32 [n]float32
   804  func (o *Buffer) enc_array_uint32(p *Properties, base structPointer) error {
   805  	ln := p.t.Len()
   806  	if ln > 0 {
   807  		var data []uint32
   808  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   809  		sliceHeader.Cap = ln
   810  		sliceHeader.Len = ln
   811  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   812  		for i := 0; i < ln; i++ {
   813  			binary.LittleEndian.PutUint32(o.buf[o.index:], data[i])
   814  			o.index += 4
   815  		}
   816  	}
   817  	return nil
   818  }
   819  
   820  func (o *Buffer) dec_array_uint32(p *Properties, base structPointer) error {
   821  	ln := p.t.Len()
   822  	if ln > 0 {
   823  		end := o.index + ln*4
   824  		if end < o.index || end > len(o.buf) {
   825  			return io.ErrUnexpectedEOF
   826  		}
   827  		var data []uint32
   828  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   829  		sliceHeader.Cap = ln
   830  		sliceHeader.Len = ln
   831  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   832  		for i := 0; i < ln; i++ {
   833  			data[i] = binary.LittleEndian.Uint32(o.buf[o.index+i*4:])
   834  		}
   835  		o.index = end
   836  	}
   837  	return nil
   838  }
   839  
   840  func (o *Buffer) size_array_uint32(p *Properties, base structPointer) int {
   841  	return p.t.Len() * 4
   842  }
   843  
   844  // [n]uint64 [n]int64 [n]float64
   845  func (o *Buffer) enc_array_uint64(p *Properties, base structPointer) error {
   846  	ln := p.t.Len()
   847  	if ln > 0 {
   848  		var data []uint64
   849  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   850  		sliceHeader.Cap = ln
   851  		sliceHeader.Len = ln
   852  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   853  		for i := 0; i < ln; i++ {
   854  			binary.LittleEndian.PutUint64(o.buf[o.index:], data[i])
   855  			o.index += 8
   856  		}
   857  	}
   858  	return nil
   859  }
   860  
   861  func (o *Buffer) dec_array_uint64(p *Properties, base structPointer) error {
   862  	ln := p.t.Len()
   863  	if ln > 0 {
   864  		end := o.index + ln*8
   865  		if end < o.index || end > len(o.buf) {
   866  			return io.ErrUnexpectedEOF
   867  		}
   868  		var data []uint64
   869  		sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
   870  		sliceHeader.Cap = ln
   871  		sliceHeader.Len = ln
   872  		sliceHeader.Data = uintptr(base) + uintptr(p.field)
   873  		for i := 0; i < ln; i++ {
   874  			data[i] = binary.LittleEndian.Uint64(o.buf[o.index+i*8:])
   875  		}
   876  		o.index = end
   877  	}
   878  	return nil
   879  }
   880  
   881  func (o *Buffer) size_array_uint64(p *Properties, base structPointer) int {
   882  	return p.t.Len() * 8
   883  }
   884  
   885  // [n]cstruct
   886  func (o *Buffer) enc_array_substruct(p *Properties, base structPointer) error {
   887  	ln := p.t.Len()
   888  	if ln > 0 {
   889  		itemsize := int(p.stype.Size())
   890  		for i := 0; i < ln; i++ {
   891  			data := (structPointer)(unsafe.Pointer(uintptr(base) + uintptr(p.field) + uintptr(i*itemsize)))
   892  			o.enc_struct(p.sprop, data)
   893  		}
   894  	}
   895  	return nil
   896  }
   897  
   898  func (o *Buffer) dec_array_substruct(p *Properties, base structPointer) error {
   899  	ln := p.t.Len()
   900  	if ln > 0 {
   901  		itemsize := o.size_substruct(p, base)
   902  		end := o.index + ln*itemsize
   903  		if end < o.index || end > len(o.buf) {
   904  			return io.ErrUnexpectedEOF
   905  		}
   906  		for i := 0; i < ln; i++ {
   907  			data := (structPointer)(unsafe.Pointer(uintptr(base) + uintptr(p.field) + uintptr(i*int(p.stype.Size()))))
   908  			o.unmarshalType(p.stype, p.sprop, data)
   909  		}
   910  		o.index = end
   911  	}
   912  	return nil
   913  }
   914  
   915  func (o *Buffer) size_array_substruct(p *Properties, base structPointer) int {
   916  	return p.t.Len() * o.size_substruct(p, base)
   917  }