github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_encoder_native_slice.go (about)

     1  package jzon
     2  
     3  import (
     4  	"reflect"
     5  	"unsafe"
     6  )
     7  
     8  type sliceEncoderBuilder struct {
     9  	encoder  *sliceEncoder
    10  	elemType reflect.Type
    11  }
    12  
    13  func newSliceEncoder(typ reflect.Type) *sliceEncoderBuilder {
    14  	elemType := typ.Elem()
    15  	return &sliceEncoderBuilder{
    16  		encoder: &sliceEncoder{
    17  			elemSize: elemType.Size(),
    18  		},
    19  		elemType: elemType,
    20  	}
    21  }
    22  
    23  type sliceEncoder struct {
    24  	elemSize    uintptr
    25  	elemEncoder ValEncoder
    26  }
    27  
    28  func (*sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
    29  	sh := (*sliceHeader)(ptr)
    30  	return sh.Data == 0 || sh.Len == 0
    31  }
    32  
    33  // Disable new -d=checkptr behaviour for Go 1.14
    34  //go:nocheckptr
    35  func (enc *sliceEncoder) Encode(ptr unsafe.Pointer, s *Streamer, _ *EncOpts) {
    36  	if s.Error != nil {
    37  		return
    38  	}
    39  	if ptr == nil {
    40  		s.Null()
    41  		return
    42  	}
    43  	sh := (*sliceHeader)(ptr)
    44  	if sh.Data == 0 {
    45  		s.Null()
    46  		return
    47  	}
    48  	if sh.Len == 0 {
    49  		s.RawString("[]")
    50  		return
    51  	}
    52  	s.ArrayStart()
    53  	curPtr := sh.Data
    54  	for i := 0; i < sh.Len; i++ {
    55  		enc.elemEncoder.Encode(unsafe.Pointer(curPtr), s, nil)
    56  		if s.Error != nil {
    57  			return
    58  		}
    59  		curPtr += enc.elemSize
    60  	}
    61  	s.ArrayEnd()
    62  }