github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_encoder_native_array.go (about) 1 package jzon 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 // special array (empty) 9 type emptyArrayEncoder struct{} 10 11 func (*emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { 12 return true 13 } 14 15 func (*emptyArrayEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) { 16 if ptr == nil { 17 s.Null() 18 return 19 } 20 s.RawString("[]") 21 } 22 23 type arrayEncoderBuilder struct { 24 encoder *arrayEncoder 25 elemType reflect.Type 26 elemRType rtype 27 } 28 29 func newArrayEncoder(typ reflect.Type) *arrayEncoderBuilder { 30 elemType := typ.Elem() 31 return &arrayEncoderBuilder{ 32 encoder: &arrayEncoder{ 33 elemSize: elemType.Size(), 34 length: typ.Len(), 35 }, 36 elemType: elemType, 37 elemRType: rtypeOfType(elemType), 38 } 39 } 40 41 type arrayEncoder struct { 42 encoder ValEncoder 43 elemSize uintptr 44 length int 45 } 46 47 func (enc *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { 48 return false 49 } 50 51 func (enc *arrayEncoder) Encode(ptr unsafe.Pointer, s *Streamer, _ *EncOpts) { 52 if ptr == nil { 53 s.Null() 54 return 55 } 56 s.ArrayStart() 57 i := 0 58 for { 59 enc.encoder.Encode(ptr, s, nil) 60 if s.Error != nil { 61 return 62 } 63 i++ 64 if i == enc.length { 65 break 66 } 67 ptr = add(ptr, enc.elemSize, "i < enc.length") 68 } 69 s.ArrayEnd() 70 }