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 }