...

Source file src/github.com/json-iterator/go/reflect_slice.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 decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
    11  	sliceType := typ.(*reflect2.UnsafeSliceType)
    12  	decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
    13  	return &sliceDecoder{sliceType, decoder}
    14  }
    15  
    16  func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder {
    17  	sliceType := typ.(*reflect2.UnsafeSliceType)
    18  	encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
    19  	return &sliceEncoder{sliceType, encoder}
    20  }
    21  
    22  type sliceEncoder struct {
    23  	sliceType   *reflect2.UnsafeSliceType
    24  	elemEncoder ValEncoder
    25  }
    26  
    27  func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
    28  	if encoder.sliceType.UnsafeIsNil(ptr) {
    29  		stream.WriteNil()
    30  		return
    31  	}
    32  	length := encoder.sliceType.UnsafeLengthOf(ptr)
    33  	if length == 0 {
    34  		stream.WriteEmptyArray()
    35  		return
    36  	}
    37  	stream.WriteArrayStart()
    38  	encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream)
    39  	for i := 1; i < length; i++ {
    40  		stream.WriteMore()
    41  		elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i)
    42  		encoder.elemEncoder.Encode(elemPtr, stream)
    43  	}
    44  	stream.WriteArrayEnd()
    45  	if stream.Error != nil && stream.Error != io.EOF {
    46  		stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
    47  	}
    48  }
    49  
    50  func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
    51  	return encoder.sliceType.UnsafeLengthOf(ptr) == 0
    52  }
    53  
    54  type sliceDecoder struct {
    55  	sliceType   *reflect2.UnsafeSliceType
    56  	elemDecoder ValDecoder
    57  }
    58  
    59  func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
    60  	decoder.doDecode(ptr, iter)
    61  	if iter.Error != nil && iter.Error != io.EOF {
    62  		iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
    63  	}
    64  }
    65  
    66  func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
    67  	c := iter.nextToken()
    68  	sliceType := decoder.sliceType
    69  	if c == 'n' {
    70  		iter.skipThreeBytes('u', 'l', 'l')
    71  		sliceType.UnsafeSetNil(ptr)
    72  		return
    73  	}
    74  	if c != '[' {
    75  		iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c}))
    76  		return
    77  	}
    78  	c = iter.nextToken()
    79  	if c == ']' {
    80  		sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0))
    81  		return
    82  	}
    83  	iter.unreadByte()
    84  	sliceType.UnsafeGrow(ptr, 1)
    85  	elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
    86  	decoder.elemDecoder.Decode(elemPtr, iter)
    87  	length := 1
    88  	for c = iter.nextToken(); c == ','; c = iter.nextToken() {
    89  		idx := length
    90  		length += 1
    91  		sliceType.UnsafeGrow(ptr, length)
    92  		elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
    93  		decoder.elemDecoder.Decode(elemPtr, iter)
    94  	}
    95  	if c != ']' {
    96  		iter.ReportError("decode slice", "expect ], but found "+string([]byte{c}))
    97  		return
    98  	}
    99  }
   100  

View as plain text