...

Source file src/github.com/json-iterator/go/reflect_array.go

Documentation: github.com/json-iterator/go

     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  

View as plain text