1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-27 08:30:57 +02:00
json-iterator/reflect_array.go

105 lines
2.6 KiB
Go
Raw Normal View History

2017-01-07 01:49:50 +02:00
package jsoniter
import (
2017-06-19 17:43:53 +02:00
"fmt"
2018-02-28 11:09:30 +02:00
"github.com/modern-go/reflect2"
2017-06-19 17:43:53 +02:00
"io"
2017-06-06 17:27:00 +02:00
"unsafe"
2017-01-07 01:49:50 +02:00
)
2018-02-22 04:12:08 +02:00
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
arrayType := typ.(*reflect2.UnsafeArrayType)
decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
return &arrayDecoder{arrayType, decoder}
2017-01-09 13:48:57 +02:00
}
2018-02-22 04:12:08 +02:00
func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
arrayType := typ.(*reflect2.UnsafeArrayType)
if arrayType.Len() == 0 {
return emptyArrayEncoder{}
}
2018-02-22 04:12:08 +02:00
encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
return &arrayEncoder{arrayType, encoder}
2017-01-09 13:48:57 +02:00
}
type emptyArrayEncoder struct{}
func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteEmptyArray()
}
func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return true
}
2017-06-19 17:43:28 +02:00
type arrayEncoder struct {
2018-02-22 04:12:08 +02:00
arrayType *reflect2.UnsafeArrayType
elemEncoder ValEncoder
2017-01-09 13:48:57 +02:00
}
2017-06-20 09:11:01 +02:00
func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
2017-01-09 13:48:57 +02:00
stream.WriteArrayStart()
2017-07-09 05:24:26 +02:00
elemPtr := unsafe.Pointer(ptr)
encoder.elemEncoder.Encode(elemPtr, stream)
2017-06-19 17:43:28 +02:00
for i := 1; i < encoder.arrayType.Len(); i++ {
2017-01-09 13:48:57 +02:00
stream.WriteMore()
2018-02-22 04:12:08 +02:00
elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
encoder.elemEncoder.Encode(elemPtr, stream)
2017-01-09 13:48:57 +02:00
}
stream.WriteArrayEnd()
if stream.Error != nil && stream.Error != io.EOF {
2017-06-19 17:43:28 +02:00
stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
2017-01-09 13:48:57 +02:00
}
}
2017-06-20 09:11:01 +02:00
func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
2017-06-19 17:43:28 +02:00
return false
2017-03-08 17:38:25 +02:00
}
2017-06-19 17:43:28 +02:00
type arrayDecoder struct {
2018-02-22 04:12:08 +02:00
arrayType *reflect2.UnsafeArrayType
elemDecoder ValDecoder
2017-01-07 01:49:50 +02:00
}
2017-06-20 09:11:01 +02:00
func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
2017-01-07 01:49:50 +02:00
decoder.doDecode(ptr, iter)
if iter.Error != nil && iter.Error != io.EOF {
2017-06-19 17:43:28 +02:00
iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
2017-01-07 01:49:50 +02:00
}
}
2017-06-19 17:43:28 +02:00
func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
2018-02-22 04:12:08 +02:00
c := iter.nextToken()
arrayType := decoder.arrayType
if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l')
return
}
if c != '[' {
iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
return
}
c = iter.nextToken()
if c == ']' {
return
}
iter.unreadByte()
elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
decoder.elemDecoder.Decode(elemPtr, iter)
length := 1
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
if length >= arrayType.Len() {
2017-06-19 17:43:28 +02:00
iter.Skip()
2018-02-22 04:12:08 +02:00
continue
2017-01-07 01:49:50 +02:00
}
2018-02-22 04:12:08 +02:00
idx := length
length += 1
elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
decoder.elemDecoder.Decode(elemPtr, iter)
}
if c != ']' {
iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
return
}
2017-06-06 17:27:00 +02:00
}