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  }