1package jsoniter 2 3import ( 4 "fmt" 5 "io" 6 "reflect" 7 "unsafe" 8) 9 10func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { 11 decoder, err := decoderOfType(cfg, typ.Elem()) 12 if err != nil { 13 return nil, err 14 } 15 return &arrayDecoder{typ, typ.Elem(), decoder}, nil 16} 17 18func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { 19 encoder, err := encoderOfType(cfg, typ.Elem()) 20 if err != nil { 21 return nil, err 22 } 23 if typ.Elem().Kind() == reflect.Map { 24 encoder = &optionalEncoder{encoder} 25 } 26 return &arrayEncoder{typ, typ.Elem(), encoder}, nil 27} 28 29type arrayEncoder struct { 30 arrayType reflect.Type 31 elemType reflect.Type 32 elemEncoder ValEncoder 33} 34 35func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 36 stream.WriteArrayStart() 37 elemPtr := unsafe.Pointer(ptr) 38 encoder.elemEncoder.Encode(elemPtr, stream) 39 for i := 1; i < encoder.arrayType.Len(); i++ { 40 stream.WriteMore() 41 elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size()) 42 encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) 43 } 44 stream.WriteArrayEnd() 45 if stream.Error != nil && stream.Error != io.EOF { 46 stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) 47 } 48} 49 50func (encoder *arrayEncoder) EncodeInterface(val interface{}, stream *Stream) { 51 // special optimization for interface{} 52 e := (*emptyInterface)(unsafe.Pointer(&val)) 53 if e.word == nil { 54 stream.WriteArrayStart() 55 stream.WriteNil() 56 stream.WriteArrayEnd() 57 return 58 } 59 elemType := encoder.arrayType.Elem() 60 if encoder.arrayType.Len() == 1 && (elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map) { 61 ptr := uintptr(e.word) 62 e.word = unsafe.Pointer(&ptr) 63 } 64 if reflect.TypeOf(val).Kind() == reflect.Ptr { 65 encoder.Encode(unsafe.Pointer(&e.word), stream) 66 } else { 67 encoder.Encode(e.word, stream) 68 } 69} 70 71func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { 72 return false 73} 74 75type arrayDecoder struct { 76 arrayType reflect.Type 77 elemType reflect.Type 78 elemDecoder ValDecoder 79} 80 81func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 82 decoder.doDecode(ptr, iter) 83 if iter.Error != nil && iter.Error != io.EOF { 84 iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) 85 } 86} 87 88func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { 89 offset := uintptr(0) 90 iter.ReadArrayCB(func(iter *Iterator) bool { 91 if offset < decoder.arrayType.Size() { 92 decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter) 93 offset += decoder.elemType.Size() 94 } else { 95 iter.Skip() 96 } 97 return true 98 }) 99} 100