reflect_array.go raw

   1  package jsoniter
   2  
   3  import (
   4  	"fmt"
   5  	"github.com/modern-go/reflect2"
   6  	"io"
   7  	"unsafe"
   8  )
   9  
  10  func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
  11  	arrayType := typ.(*reflect2.UnsafeArrayType)
  12  	decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
  13  	return &arrayDecoder{arrayType, decoder}
  14  }
  15  
  16  func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
  17  	arrayType := typ.(*reflect2.UnsafeArrayType)
  18  	if arrayType.Len() == 0 {
  19  		return emptyArrayEncoder{}
  20  	}
  21  	encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
  22  	return &arrayEncoder{arrayType, encoder}
  23  }
  24  
  25  type emptyArrayEncoder struct{}
  26  
  27  func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  28  	stream.WriteEmptyArray()
  29  }
  30  
  31  func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  32  	return true
  33  }
  34  
  35  type arrayEncoder struct {
  36  	arrayType   *reflect2.UnsafeArrayType
  37  	elemEncoder ValEncoder
  38  }
  39  
  40  func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  41  	stream.WriteArrayStart()
  42  	elemPtr := unsafe.Pointer(ptr)
  43  	encoder.elemEncoder.Encode(elemPtr, stream)
  44  	for i := 1; i < encoder.arrayType.Len(); i++ {
  45  		stream.WriteMore()
  46  		elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
  47  		encoder.elemEncoder.Encode(elemPtr, stream)
  48  	}
  49  	stream.WriteArrayEnd()
  50  	if stream.Error != nil && stream.Error != io.EOF {
  51  		stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
  52  	}
  53  }
  54  
  55  func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  56  	return false
  57  }
  58  
  59  type arrayDecoder struct {
  60  	arrayType   *reflect2.UnsafeArrayType
  61  	elemDecoder ValDecoder
  62  }
  63  
  64  func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  65  	decoder.doDecode(ptr, iter)
  66  	if iter.Error != nil && iter.Error != io.EOF {
  67  		iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
  68  	}
  69  }
  70  
  71  func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  72  	c := iter.nextToken()
  73  	arrayType := decoder.arrayType
  74  	if c == 'n' {
  75  		iter.skipThreeBytes('u', 'l', 'l')
  76  		return
  77  	}
  78  	if c != '[' {
  79  		iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
  80  		return
  81  	}
  82  	c = iter.nextToken()
  83  	if c == ']' {
  84  		return
  85  	}
  86  	iter.unreadByte()
  87  	elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
  88  	decoder.elemDecoder.Decode(elemPtr, iter)
  89  	length := 1
  90  	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
  91  		if length >= arrayType.Len() {
  92  			iter.Skip()
  93  			continue
  94  		}
  95  		idx := length
  96  		length += 1
  97  		elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
  98  		decoder.elemDecoder.Decode(elemPtr, iter)
  99  	}
 100  	if c != ']' {
 101  		iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
 102  		return
 103  	}
 104  }
 105