mirror of
https://github.com/json-iterator/go.git
synced 2025-05-31 22:24:53 +02:00
suport encode interface
This commit is contained in:
parent
ce1a1f1e98
commit
9b587c0f22
@ -185,7 +185,7 @@ func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any {
|
|||||||
func (iter *Iterator) readArrayAny(reusableIter *Iterator) Any {
|
func (iter *Iterator) readArrayAny(reusableIter *Iterator) Any {
|
||||||
level := 1
|
level := 1
|
||||||
lazyBuf := make([]byte, 1, 32)
|
lazyBuf := make([]byte, 1, 32)
|
||||||
lazyBuf[0] = '{'
|
lazyBuf[0] = '['
|
||||||
for {
|
for {
|
||||||
start := iter.head
|
start := iter.head
|
||||||
for i := iter.head; i < iter.tail; i++ {
|
for i := iter.head; i < iter.tail; i++ {
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
type arrayLazyAny struct {
|
type arrayLazyAny struct {
|
||||||
baseAny
|
baseAny
|
||||||
buf []byte
|
buf []byte
|
||||||
@ -231,3 +235,26 @@ func (any *arrayLazyAny) IterateArray() (func() (Any, bool), bool) {
|
|||||||
}
|
}
|
||||||
}, true
|
}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) GetArray() []Any {
|
||||||
|
any.fillCache()
|
||||||
|
return any.cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) SetArray(newList []Any) bool {
|
||||||
|
any.fillCache()
|
||||||
|
any.cache = newList
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) WriteTo(stream *Stream) {
|
||||||
|
if len(any.remaining) == len(any.buf) {
|
||||||
|
// nothing has been parsed yet
|
||||||
|
stream.WriteRaw(*(*string)(unsafe.Pointer(&any.buf)))
|
||||||
|
} else {
|
||||||
|
any.fillCache()
|
||||||
|
stream.WriteVal(any.cache)
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,10 @@ func (any *intLazyAny) ToString() string {
|
|||||||
return *(*string)(unsafe.Pointer(&any.buf))
|
return *(*string)(unsafe.Pointer(&any.buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *intLazyAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteRaw(*(*string)(unsafe.Pointer(&any.buf)))
|
||||||
|
}
|
||||||
|
|
||||||
type intAny struct {
|
type intAny struct {
|
||||||
baseAny
|
baseAny
|
||||||
err error
|
err error
|
||||||
|
@ -272,4 +272,14 @@ func (any *objectLazyAny) SetObject(val map[string]Any) bool {
|
|||||||
any.fillCache()
|
any.fillCache()
|
||||||
any.cache = val
|
any.cache = val
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) WriteTo(stream *Stream) {
|
||||||
|
if len(any.remaining) == len(any.buf) {
|
||||||
|
// nothing has been parsed yet
|
||||||
|
stream.WriteRaw(*(*string)(unsafe.Pointer(&any.buf)))
|
||||||
|
} else {
|
||||||
|
any.fillCache()
|
||||||
|
stream.WriteVal(any.cache)
|
||||||
|
}
|
||||||
}
|
}
|
@ -20,8 +20,19 @@ For a simple struct binding, it will be reflect.Value free and allocation free
|
|||||||
type Decoder interface {
|
type Decoder interface {
|
||||||
decode(ptr unsafe.Pointer, iter *Iterator)
|
decode(ptr unsafe.Pointer, iter *Iterator)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Encoder interface {
|
type Encoder interface {
|
||||||
encode(ptr unsafe.Pointer, stream *Stream)
|
encode(ptr unsafe.Pointer, stream *Stream)
|
||||||
|
encodeInterface(val interface{}, stream *Stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteToStream(val interface{}, stream *Stream, encoder Encoder) {
|
||||||
|
e := (*emptyInterface)(unsafe.Pointer(&val))
|
||||||
|
if reflect.TypeOf(val).Kind() == reflect.Ptr {
|
||||||
|
encoder.encode(unsafe.Pointer(&e.word), stream)
|
||||||
|
} else {
|
||||||
|
encoder.encode(e.word, stream)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
|
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
|
||||||
@ -44,6 +55,10 @@ func (encoder *funcEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
encoder.fun(ptr, stream)
|
encoder.fun(ptr, stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *funcEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
var DECODERS unsafe.Pointer
|
var DECODERS unsafe.Pointer
|
||||||
var ENCODERS unsafe.Pointer
|
var ENCODERS unsafe.Pointer
|
||||||
|
|
||||||
@ -52,6 +67,7 @@ var fieldDecoders map[string]Decoder
|
|||||||
var typeEncoders map[string]Encoder
|
var typeEncoders map[string]Encoder
|
||||||
var fieldEncoders map[string]Encoder
|
var fieldEncoders map[string]Encoder
|
||||||
var extensions []ExtensionFunc
|
var extensions []ExtensionFunc
|
||||||
|
var anyType reflect.Type
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
typeDecoders = map[string]Decoder{}
|
typeDecoders = map[string]Decoder{}
|
||||||
@ -61,10 +77,7 @@ func init() {
|
|||||||
extensions = []ExtensionFunc{}
|
extensions = []ExtensionFunc{}
|
||||||
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
|
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
|
||||||
atomic.StorePointer(&ENCODERS, unsafe.Pointer(&map[string]Encoder{}))
|
atomic.StorePointer(&ENCODERS, unsafe.Pointer(&map[string]Encoder{}))
|
||||||
RegisterTypeEncoder("*jsoniter.intAny", func(ptr unsafe.Pointer, stream *Stream) {
|
anyType = reflect.TypeOf((*Any)(nil)).Elem()
|
||||||
val := *(**intAny)(ptr)
|
|
||||||
val.WriteTo(stream)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
|
func addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
|
||||||
@ -170,6 +183,10 @@ func (encoder *optionalEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *optionalEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type mapDecoder struct {
|
type mapDecoder struct {
|
||||||
mapType reflect.Type
|
mapType reflect.Type
|
||||||
elemType reflect.Type
|
elemType reflect.Type
|
||||||
@ -212,12 +229,15 @@ func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
}
|
}
|
||||||
stream.WriteObjectField(key.String())
|
stream.WriteObjectField(key.String())
|
||||||
val := realVal.MapIndex(key).Interface()
|
val := realVal.MapIndex(key).Interface()
|
||||||
e := (*emptyInterface)(unsafe.Pointer(&val))
|
encoder.elemEncoder.encodeInterface(val, stream)
|
||||||
encoder.elemEncoder.encode(e.word, stream)
|
|
||||||
}
|
}
|
||||||
stream.WriteObjectEnd()
|
stream.WriteObjectEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *mapEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type mapInterfaceEncoder struct {
|
type mapInterfaceEncoder struct {
|
||||||
mapType reflect.Type
|
mapType reflect.Type
|
||||||
elemType reflect.Type
|
elemType reflect.Type
|
||||||
@ -243,6 +263,10 @@ func (encoder *mapInterfaceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteObjectEnd()
|
stream.WriteObjectEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *mapInterfaceEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
// emptyInterface is the header for an interface{} value.
|
// emptyInterface is the header for an interface{} value.
|
||||||
type emptyInterface struct {
|
type emptyInterface struct {
|
||||||
typ *struct{}
|
typ *struct{}
|
||||||
@ -285,13 +309,7 @@ func (stream *Stream) WriteVal(val interface{}) {
|
|||||||
cachedEncoder = encoder
|
cachedEncoder = encoder
|
||||||
addEncoderToCache(cacheKey, encoder)
|
addEncoderToCache(cacheKey, encoder)
|
||||||
}
|
}
|
||||||
|
cachedEncoder.encodeInterface(val, stream)
|
||||||
e := (*emptyInterface)(unsafe.Pointer(&val))
|
|
||||||
if typ.Kind() == reflect.Ptr {
|
|
||||||
cachedEncoder.encode(unsafe.Pointer(&e.word), stream)
|
|
||||||
} else {
|
|
||||||
cachedEncoder.encode(e.word, stream)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type prefix string
|
type prefix string
|
||||||
@ -365,6 +383,9 @@ func decoderOfType(typ reflect.Type) (Decoder, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func encoderOfType(typ reflect.Type) (Encoder, error) {
|
func encoderOfType(typ reflect.Type) (Encoder, error) {
|
||||||
|
if typ.ConvertibleTo(anyType) {
|
||||||
|
return &anyCodec{}, nil
|
||||||
|
}
|
||||||
typeName := typ.String()
|
typeName := typ.String()
|
||||||
typeEncoder := typeEncoders[typeName]
|
typeEncoder := typeEncoders[typeName]
|
||||||
if typeEncoder != nil {
|
if typeEncoder != nil {
|
||||||
@ -442,14 +463,15 @@ func decoderOfMap(typ reflect.Type) (Decoder, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func encoderOfMap(typ reflect.Type) (Encoder, error) {
|
func encoderOfMap(typ reflect.Type) (Encoder, error) {
|
||||||
encoder, err := encoderOfType(typ.Elem())
|
elemType := typ.Elem()
|
||||||
|
encoder, err := encoderOfType(elemType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mapInterface := reflect.New(typ).Elem().Interface()
|
mapInterface := reflect.New(typ).Elem().Interface()
|
||||||
if typ.Elem().Kind() == reflect.Interface {
|
if elemType.Kind() == reflect.Interface && elemType.NumMethod() == 0 {
|
||||||
return &mapInterfaceEncoder{typ, typ.Elem(), encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
|
return &mapInterfaceEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
|
||||||
} else {
|
} else {
|
||||||
return &mapEncoder{typ, typ.Elem(), encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
|
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,10 @@ func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *sliceEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type sliceDecoder struct {
|
type sliceDecoder struct {
|
||||||
sliceType reflect.Type
|
sliceType reflect.Type
|
||||||
elemType reflect.Type
|
elemType reflect.Type
|
||||||
|
@ -15,6 +15,10 @@ func (codec *stringCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteString(*((*string)(ptr)))
|
stream.WriteString(*((*string)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *stringCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type intCodec struct {
|
type intCodec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +30,10 @@ func (codec *intCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteInt(*((*int)(ptr)))
|
stream.WriteInt(*((*int)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *intCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type int8Codec struct {
|
type int8Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +45,10 @@ func (codec *int8Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteInt8(*((*int8)(ptr)))
|
stream.WriteInt8(*((*int8)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *int8Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type int16Codec struct {
|
type int16Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +60,10 @@ func (codec *int16Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteInt16(*((*int16)(ptr)))
|
stream.WriteInt16(*((*int16)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *int16Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type int32Codec struct {
|
type int32Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +75,10 @@ func (codec *int32Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteInt32(*((*int32)(ptr)))
|
stream.WriteInt32(*((*int32)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *int32Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type int64Codec struct {
|
type int64Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +90,10 @@ func (codec *int64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteInt64(*((*int64)(ptr)))
|
stream.WriteInt64(*((*int64)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *int64Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type uintCodec struct {
|
type uintCodec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +105,10 @@ func (codec *uintCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteUint(*((*uint)(ptr)))
|
stream.WriteUint(*((*uint)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *uintCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type uint8Codec struct {
|
type uint8Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +120,10 @@ func (codec *uint8Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteUint8(*((*uint8)(ptr)))
|
stream.WriteUint8(*((*uint8)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *uint8Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type uint16Codec struct {
|
type uint16Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,10 +131,14 @@ func (decoder *uint16Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
|
|||||||
*((*uint16)(ptr)) = iter.ReadUint16()
|
*((*uint16)(ptr)) = iter.ReadUint16()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (decoder *uint16Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
func (codec *uint16Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
stream.WriteUint16(*((*uint16)(ptr)))
|
stream.WriteUint16(*((*uint16)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *uint16Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type uint32Codec struct {
|
type uint32Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +150,10 @@ func (codec *uint32Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteUint32(*((*uint32)(ptr)))
|
stream.WriteUint32(*((*uint32)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *uint32Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type uint64Codec struct {
|
type uint64Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +165,10 @@ func (codec *uint64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteUint64(*((*uint64)(ptr)))
|
stream.WriteUint64(*((*uint64)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *uint64Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type float32Codec struct {
|
type float32Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +180,10 @@ func (codec *float32Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteFloat32(*((*float32)(ptr)))
|
stream.WriteFloat32(*((*float32)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *float32Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type float64Codec struct {
|
type float64Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +195,10 @@ func (codec *float64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteFloat64(*((*float64)(ptr)))
|
stream.WriteFloat64(*((*float64)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *float64Codec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type boolCodec struct {
|
type boolCodec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +210,10 @@ func (codec *boolCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteBool(*((*bool)(ptr)))
|
stream.WriteBool(*((*bool)(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *boolCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
type interfaceCodec struct {
|
type interfaceCodec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +225,25 @@ func (codec *interfaceCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteVal(*((*interface{})(ptr)))
|
stream.WriteVal(*((*interface{})(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *interfaceCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
type anyCodec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *anyCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
*((*Any)(ptr)) = iter.ReadAny()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *anyCodec) encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
(*((*Any)(ptr))).WriteTo(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *anyCodec) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
(val.(Any)).WriteTo(stream)
|
||||||
|
}
|
||||||
|
|
||||||
type stringNumberDecoder struct {
|
type stringNumberDecoder struct {
|
||||||
elemDecoder Decoder
|
elemDecoder Decoder
|
||||||
}
|
}
|
||||||
|
@ -405,6 +405,10 @@ func (encoder *structFieldEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *structFieldEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type structEncoder struct {
|
type structEncoder struct {
|
||||||
firstField *structFieldEncoder
|
firstField *structFieldEncoder
|
||||||
@ -421,9 +425,18 @@ func (encoder *structEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
stream.WriteObjectEnd()
|
stream.WriteObjectEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *structEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type emptyStructEncoder struct {
|
type emptyStructEncoder struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (encoder *emptyStructEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
func (encoder *emptyStructEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
stream.WriteEmptyObject()
|
stream.WriteEmptyObject()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *emptyStructEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
}
|
}
|
@ -82,13 +82,23 @@ func Test_read_array_with_any_iterator(t *testing.T) {
|
|||||||
should.Equal([]int{1, 2}, elements)
|
should.Equal([]int{1, 2}, elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_array_any_get(t *testing.T) {
|
func Test_array_lazy_any_get(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
any, err := UnmarshalAnyFromString("[1,[2,3],4]")
|
any, err := UnmarshalAnyFromString("[1,[2,3],4]")
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal(3, any.Get(1,1).ToInt())
|
should.Equal(3, any.Get(1,1).ToInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_array_lazy_any_set(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
any, err := UnmarshalAnyFromString("[1,[2,3],4]")
|
||||||
|
should.Nil(err)
|
||||||
|
any.GetArray()[0] = WrapInt64(2)
|
||||||
|
str, err := MarshalToString(any)
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal("[2,[2,3],4]", str)
|
||||||
|
}
|
||||||
|
|
||||||
func Test_invalid_array(t *testing.T) {
|
func Test_invalid_array(t *testing.T) {
|
||||||
_, err := UnmarshalAnyFromString("[")
|
_, err := UnmarshalAnyFromString("[")
|
||||||
if err == nil || err == io.EOF {
|
if err == nil || err == io.EOF {
|
||||||
|
@ -152,7 +152,9 @@ func Test_object_lazy_any_set(t *testing.T) {
|
|||||||
any, err := UnmarshalAnyFromString(`{"a":{"b":{"c":"d"}}}`)
|
any, err := UnmarshalAnyFromString(`{"a":{"b":{"c":"d"}}}`)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
any.GetObject()["a"] = WrapInt64(1)
|
any.GetObject()["a"] = WrapInt64(1)
|
||||||
should.Equal(`{"a":1}`, any.ToString())
|
str, err := MarshalToString(any)
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(`{"a":1}`, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_write_object(t *testing.T) {
|
func Test_write_object(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user