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 }