gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

reflect_array.go (2652B)


      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 }