mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
suport encode map[interface{}]interface{}
This commit is contained in:
parent
39acec93e0
commit
ca39e5af3e
@ -2,12 +2,12 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/modern-go/concurrent"
|
||||||
"github.com/modern-go/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/modern-go/concurrent"
|
|
||||||
"reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config customize how the API should behave.
|
// Config customize how the API should behave.
|
||||||
@ -63,7 +63,6 @@ var ConfigFastest = Config{
|
|||||||
ObjectFieldMustBeSimpleString: true, // do not unescape object field
|
ObjectFieldMustBeSimpleString: true, // do not unescape object field
|
||||||
}.Froze()
|
}.Froze()
|
||||||
|
|
||||||
|
|
||||||
type frozenConfig struct {
|
type frozenConfig struct {
|
||||||
configBeforeFrozen Config
|
configBeforeFrozen Config
|
||||||
sortMapKeys bool
|
sortMapKeys bool
|
||||||
|
@ -2,8 +2,8 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/modern-go/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -2,9 +2,9 @@ package extra
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"unsafe"
|
|
||||||
"unicode/utf8"
|
|
||||||
"github.com/modern-go/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
|
"unicode/utf8"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// safeSet holds the value true if the ASCII character with the given array
|
// safeSet holds the value true if the ASCII character with the given array
|
||||||
@ -171,18 +171,18 @@ func (codec *binaryAsStringCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.St
|
|||||||
func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte {
|
func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte {
|
||||||
var ret byte
|
var ret byte
|
||||||
if b1 >= '0' && b1 <= '9' {
|
if b1 >= '0' && b1 <= '9' {
|
||||||
ret = b1-'0'
|
ret = b1 - '0'
|
||||||
} else if b1 >= 'a' && b1 <= 'f' {
|
} else if b1 >= 'a' && b1 <= 'f' {
|
||||||
ret = b1-'a'+10
|
ret = b1 - 'a' + 10
|
||||||
} else {
|
} else {
|
||||||
iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1}))
|
iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1}))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
ret = ret * 16
|
ret = ret * 16
|
||||||
if b2 >= '0' && b2 <= '9' {
|
if b2 >= '0' && b2 <= '9' {
|
||||||
ret = b2-'0'
|
ret = b2 - '0'
|
||||||
} else if b2 >= 'a' && b2 <= 'f' {
|
} else if b2 >= 'a' && b2 <= 'f' {
|
||||||
ret = b2-'a'+10
|
ret = b2 - 'a' + 10
|
||||||
} else {
|
} else {
|
||||||
iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2}))
|
iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2}))
|
||||||
return 0
|
return 0
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package extra
|
package extra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -31,3 +31,14 @@ func Test_read_map_with_reader(t *testing.T) {
|
|||||||
should.Equal(m2, m1)
|
should.Equal(m2, m1)
|
||||||
should.Equal("1.0.76", m1["note"].(map[string]interface{})["CoreServices"].(map[string]interface{})["version_name"])
|
should.Equal("1.0.76", m1["note"].(map[string]interface{})["CoreServices"].(map[string]interface{})["version_name"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_map_eface_of_eface(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
output, err := json.MarshalToString(map[interface{}]interface{}{
|
||||||
|
"1": 2,
|
||||||
|
3: "4",
|
||||||
|
})
|
||||||
|
should.NoError(err)
|
||||||
|
should.Equal(`{"1":2,"3":"4"}`, output)
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package jsoniter
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/modern-go/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -107,6 +108,9 @@ func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|||||||
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if typ.Kind() == reflect.Interface {
|
||||||
|
return &dynamicMapKeyEncoder{ctx, typ}
|
||||||
|
}
|
||||||
return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +207,21 @@ func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dynamicMapKeyEncoder struct {
|
||||||
|
ctx *ctx
|
||||||
|
valType reflect2.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
obj := encoder.valType.UnsafeIndirect(ptr)
|
||||||
|
encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
obj := encoder.valType.UnsafeIndirect(ptr)
|
||||||
|
return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
|
||||||
|
}
|
||||||
|
|
||||||
type mapEncoder struct {
|
type mapEncoder struct {
|
||||||
mapType *reflect2.UnsafeMapType
|
mapType *reflect2.UnsafeMapType
|
||||||
keyEncoder ValEncoder
|
keyEncoder ValEncoder
|
||||||
@ -253,6 +272,9 @@ func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
subStream.buf = make([]byte, 0, 64)
|
subStream.buf = make([]byte, 0, 64)
|
||||||
key, elem := mapIter.UnsafeNext()
|
key, elem := mapIter.UnsafeNext()
|
||||||
encoder.keyEncoder.Encode(key, subStream)
|
encoder.keyEncoder.Encode(key, subStream)
|
||||||
|
if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
|
||||||
|
stream.Error = subStream.Error
|
||||||
|
}
|
||||||
encodedKey := subStream.Buffer()
|
encodedKey := subStream.Buffer()
|
||||||
subIter.ResetBytes(encodedKey)
|
subIter.ResetBytes(encodedKey)
|
||||||
decodedKey := subIter.ReadString()
|
decodedKey := subIter.ReadString()
|
||||||
|
@ -6,7 +6,7 @@ func init() {
|
|||||||
[]interface{}{"hello"},
|
[]interface{}{"hello"},
|
||||||
nilSlice,
|
nilSlice,
|
||||||
&nilSlice,
|
&nilSlice,
|
||||||
selectedMarshalCase{[]byte{1,2,3}},
|
[]byte{1, 2, 3},
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*[]string)(nil),
|
ptr: (*[]string)(nil),
|
||||||
@ -20,6 +20,5 @@ func init() {
|
|||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*[]byte)(nil),
|
ptr: (*[]byte)(nil),
|
||||||
input: `"aGVsbG8="`,
|
input: `"aGVsbG8="`,
|
||||||
selected: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/modern-go/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user