You've already forked json-iterator
mirror of
https://github.com/json-iterator/go.git
synced 2025-06-15 22:50:24 +02:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
3353055b2a | |||
455b3f8bb8 | |||
2a93f9003e | |||
9472474ffd | |||
ad83167dc6 | |||
fff342fd04 | |||
8d6662b81b | |||
a377e2656b | |||
0ac74bba4a | |||
ebe943a4a6 | |||
414d0307c9 | |||
86e9fd72bc |
28
Gopkg.lock
generated
28
Gopkg.lock
generated
@ -2,32 +2,20 @@
|
|||||||
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/davecgh/go-spew"
|
name = "github.com/modern-go/concurrent"
|
||||||
packages = ["spew"]
|
|
||||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
|
||||||
version = "v1.1.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/google/gofuzz"
|
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1"
|
revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/pmezard/go-difflib"
|
name = "github.com/modern-go/reflect2"
|
||||||
packages = ["difflib"]
|
packages = ["."]
|
||||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f"
|
||||||
version = "v1.0.0"
|
version = "1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/stretchr/testify"
|
|
||||||
packages = ["assert","require"]
|
|
||||||
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
|
|
||||||
version = "v1.1.4"
|
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "f8b7cf3941d3792cbbd570bb53c093adaf774334d1162c651565c97a58dc9d09"
|
inputs-digest = "ac7003b5a981716353a43055ab7d4c5357403cb30a60de2dbdeb446c1544beaa"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
13
Gopkg.toml
13
Gopkg.toml
@ -19,15 +19,8 @@
|
|||||||
# name = "github.com/x/y"
|
# name = "github.com/x/y"
|
||||||
# version = "2.4.0"
|
# version = "2.4.0"
|
||||||
|
|
||||||
|
ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"]
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/davecgh/go-spew"
|
name = "github.com/modern-go/reflect2"
|
||||||
version = "1.1.0"
|
version = "1.0.0"
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/google/gofuzz"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/stretchr/testify"
|
|
||||||
version = "1.1.4"
|
|
||||||
|
14
any.go
14
any.go
@ -3,10 +3,11 @@ package jsoniter
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Any generic object representation.
|
// Any generic object representation.
|
||||||
@ -101,6 +102,9 @@ func Wrap(val interface{}) Any {
|
|||||||
case reflect.String:
|
case reflect.String:
|
||||||
return WrapString(val.(string))
|
return WrapString(val.(string))
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return WrapInt32(int32(val.(int)))
|
||||||
|
}
|
||||||
return WrapInt64(int64(val.(int)))
|
return WrapInt64(int64(val.(int)))
|
||||||
case reflect.Int8:
|
case reflect.Int8:
|
||||||
return WrapInt32(int32(val.(int8)))
|
return WrapInt32(int32(val.(int8)))
|
||||||
@ -111,7 +115,15 @@ func Wrap(val interface{}) Any {
|
|||||||
case reflect.Int64:
|
case reflect.Int64:
|
||||||
return WrapInt64(val.(int64))
|
return WrapInt64(val.(int64))
|
||||||
case reflect.Uint:
|
case reflect.Uint:
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return WrapUint32(uint32(val.(uint)))
|
||||||
|
}
|
||||||
return WrapUint64(uint64(val.(uint)))
|
return WrapUint64(uint64(val.(uint)))
|
||||||
|
case reflect.Uintptr:
|
||||||
|
if ptrSize == 32 {
|
||||||
|
return WrapUint32(uint32(val.(uintptr)))
|
||||||
|
}
|
||||||
|
return WrapUint64(uint64(val.(uintptr)))
|
||||||
case reflect.Uint8:
|
case reflect.Uint8:
|
||||||
return WrapUint32(uint32(val.(uint8)))
|
return WrapUint32(uint32(val.(uint8)))
|
||||||
case reflect.Uint16:
|
case reflect.Uint16:
|
||||||
|
@ -3,8 +3,8 @@ package any_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_empty_array_as_any(t *testing.T) {
|
func Test_read_empty_array_as_any(t *testing.T) {
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var boolConvertMap = map[string]bool{
|
var boolConvertMap = map[string]bool{
|
||||||
|
@ -3,8 +3,8 @@ package any_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var floatConvertMap = map[string]float64{
|
var floatConvertMap = map[string]float64{
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var intConvertMap = map[string]int{
|
var intConvertMap = map[string]int{
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package any_tests
|
package any_tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_wrap_map(t *testing.T) {
|
func Test_wrap_map(t *testing.T) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package any_tests
|
package any_tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_null_as_any(t *testing.T) {
|
func Test_read_null_as_any(t *testing.T) {
|
||||||
|
@ -3,8 +3,8 @@ package any_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_object_as_any(t *testing.T) {
|
func Test_read_object_as_any(t *testing.T) {
|
||||||
@ -120,4 +120,4 @@ func Test_object_wrapper_any_get_all(t *testing.T) {
|
|||||||
should.NotContains(any.Keys(), "Field3")
|
should.NotContains(any.Keys(), "Field3")
|
||||||
|
|
||||||
//should.Contains(any.GetObject()["Field1"].GetArray()[0], 1)
|
//should.Contains(any.GetObject()["Field1"].GetArray()[0], 1)
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package any_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var stringConvertMap = map[string]string{
|
var stringConvertMap = map[string]string{
|
||||||
|
@ -3,8 +3,8 @@ package any_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// if must be valid is useless, just drop this test
|
// if must be valid is useless, just drop this test
|
||||||
|
@ -3,8 +3,8 @@ package any_tests
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_wrap_and_valuetype_everything(t *testing.T) {
|
func Test_wrap_and_valuetype_everything(t *testing.T) {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_use_number_for_unmarshal(t *testing.T) {
|
func Test_use_number_for_unmarshal(t *testing.T) {
|
||||||
@ -23,7 +23,6 @@ func Test_customize_float_marshal(t *testing.T) {
|
|||||||
should.Equal("1.234568", str)
|
should.Equal("1.234568", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test_customize_tag_key(t *testing.T) {
|
func Test_customize_tag_key(t *testing.T) {
|
||||||
|
|
||||||
type TestObject struct {
|
type TestObject struct {
|
||||||
@ -45,4 +44,4 @@ func Test_read_large_number_as_interface(t *testing.T) {
|
|||||||
output, err := jsoniter.MarshalToString(val)
|
output, err := jsoniter.MarshalToString(val)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal(`123456789123456789123456789`, output)
|
should.Equal(`123456789123456789123456789`, output)
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"testing"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"io/ioutil"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_disallowUnknownFields(t *testing.T) {
|
func Test_disallowUnknownFields(t *testing.T) {
|
||||||
@ -18,7 +18,6 @@ func Test_disallowUnknownFields(t *testing.T) {
|
|||||||
should.Error(decoder.Decode(&obj))
|
should.Error(decoder.Decode(&obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test_new_decoder(t *testing.T) {
|
func Test_new_decoder(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
decoder1 := json.NewDecoder(bytes.NewBufferString(`[1][2]`))
|
decoder1 := json.NewDecoder(bytes.NewBufferString(`[1][2]`))
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_new_encoder(t *testing.T) {
|
func Test_new_encoder(t *testing.T) {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Standard Encoder has trailing newline.
|
// Standard Encoder has trailing newline.
|
||||||
@ -17,4 +17,4 @@ func TestEncoderHasTrailingNewline(t *testing.T) {
|
|||||||
stdenc := json.NewEncoder(&stdbuf)
|
stdenc := json.NewEncoder(&stdbuf)
|
||||||
stdenc.Encode(1)
|
stdenc.Encode(1)
|
||||||
should.Equal(stdbuf.Bytes(), buf.Bytes())
|
should.Equal(stdbuf.Bytes(), buf.Bytes())
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_marshal_indent(t *testing.T) {
|
func Test_marshal_indent(t *testing.T) {
|
||||||
|
@ -2,10 +2,10 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//func Test_large_file(t *testing.T) {
|
//func Test_large_file(t *testing.T) {
|
||||||
|
63
config.go
63
config.go
@ -2,10 +2,11 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
"unsafe"
|
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
"github.com/modern-go/concurrent"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config customize how the API should behave.
|
// Config customize how the API should behave.
|
||||||
@ -59,6 +60,64 @@ var ConfigFastest = Config{
|
|||||||
ObjectFieldMustBeSimpleString: true, // do not unescape object field
|
ObjectFieldMustBeSimpleString: true, // do not unescape object field
|
||||||
}.Froze()
|
}.Froze()
|
||||||
|
|
||||||
|
|
||||||
|
type frozenConfig struct {
|
||||||
|
configBeforeFrozen Config
|
||||||
|
sortMapKeys bool
|
||||||
|
indentionStep int
|
||||||
|
objectFieldMustBeSimpleString bool
|
||||||
|
onlyTaggedField bool
|
||||||
|
disallowUnknownFields bool
|
||||||
|
decoderCache *concurrent.Map
|
||||||
|
encoderCache *concurrent.Map
|
||||||
|
extensions []Extension
|
||||||
|
streamPool *sync.Pool
|
||||||
|
iteratorPool *sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) initCache() {
|
||||||
|
cfg.decoderCache = concurrent.NewMap()
|
||||||
|
cfg.encoderCache = concurrent.NewMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
|
||||||
|
cfg.decoderCache.Store(cacheKey, decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
|
||||||
|
cfg.encoderCache.Store(cacheKey, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
|
||||||
|
decoder, found := cfg.decoderCache.Load(cacheKey)
|
||||||
|
if found {
|
||||||
|
return decoder.(ValDecoder)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
|
||||||
|
encoder, found := cfg.encoderCache.Load(cacheKey)
|
||||||
|
if found {
|
||||||
|
return encoder.(ValEncoder)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfgCache = &sync.Map{}
|
||||||
|
|
||||||
|
func getFrozenConfigFromCache(cfg Config) *frozenConfig {
|
||||||
|
obj, found := cfgCache.Load(cfg)
|
||||||
|
if found {
|
||||||
|
return obj.(*frozenConfig)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
|
||||||
|
cfgCache.Store(cfg, frozenConfig)
|
||||||
|
}
|
||||||
|
|
||||||
// Froze forge API from config
|
// Froze forge API from config
|
||||||
func (cfg Config) Froze() API {
|
func (cfg Config) Froze() API {
|
||||||
api := &frozenConfig{
|
api := &frozenConfig{
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
//+build go1.9
|
|
||||||
|
|
||||||
package jsoniter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type frozenConfig struct {
|
|
||||||
configBeforeFrozen Config
|
|
||||||
sortMapKeys bool
|
|
||||||
indentionStep int
|
|
||||||
objectFieldMustBeSimpleString bool
|
|
||||||
onlyTaggedField bool
|
|
||||||
disallowUnknownFields bool
|
|
||||||
decoderCache sync.Map
|
|
||||||
encoderCache sync.Map
|
|
||||||
extensions []Extension
|
|
||||||
streamPool *sync.Pool
|
|
||||||
iteratorPool *sync.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) initCache() {
|
|
||||||
cfg.decoderCache = sync.Map{}
|
|
||||||
cfg.encoderCache = sync.Map{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
|
|
||||||
cfg.decoderCache.Store(cacheKey, decoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
|
|
||||||
cfg.encoderCache.Store(cacheKey, encoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
|
|
||||||
decoder, found := cfg.decoderCache.Load(cacheKey)
|
|
||||||
if found {
|
|
||||||
return decoder.(ValDecoder)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
|
|
||||||
encoder, found := cfg.encoderCache.Load(cacheKey)
|
|
||||||
if found {
|
|
||||||
return encoder.(ValEncoder)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var cfgCache = &sync.Map{}
|
|
||||||
|
|
||||||
func getFrozenConfigFromCache(cfg Config) *frozenConfig {
|
|
||||||
obj, found := cfgCache.Load(cfg)
|
|
||||||
if found {
|
|
||||||
return obj.(*frozenConfig)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
|
|
||||||
cfgCache.Store(cfg, frozenConfig)
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
//+build !go1.9
|
|
||||||
|
|
||||||
package jsoniter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type frozenConfig struct {
|
|
||||||
configBeforeFrozen Config
|
|
||||||
sortMapKeys bool
|
|
||||||
indentionStep int
|
|
||||||
objectFieldMustBeSimpleString bool
|
|
||||||
onlyTaggedField bool
|
|
||||||
disallowUnknownFields bool
|
|
||||||
cacheLock *sync.RWMutex
|
|
||||||
decoderCache map[uintptr]ValDecoder
|
|
||||||
encoderCache map[uintptr]ValEncoder
|
|
||||||
extensions []Extension
|
|
||||||
streamPool *sync.Pool
|
|
||||||
iteratorPool *sync.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) initCache() {
|
|
||||||
cfg.cacheLock = &sync.RWMutex{}
|
|
||||||
cfg.decoderCache = map[uintptr]ValDecoder{}
|
|
||||||
cfg.encoderCache = map[uintptr]ValEncoder{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
|
|
||||||
cfg.cacheLock.Lock()
|
|
||||||
cfg.decoderCache[cacheKey] = decoder
|
|
||||||
cfg.cacheLock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
|
|
||||||
cfg.cacheLock.Lock()
|
|
||||||
cfg.encoderCache[cacheKey] = encoder
|
|
||||||
cfg.cacheLock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
|
|
||||||
cfg.cacheLock.RLock()
|
|
||||||
decoder, _ := cfg.decoderCache[cacheKey].(ValDecoder)
|
|
||||||
cfg.cacheLock.RUnlock()
|
|
||||||
return decoder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
|
|
||||||
cfg.cacheLock.RLock()
|
|
||||||
encoder, _ := cfg.encoderCache[cacheKey].(ValEncoder)
|
|
||||||
cfg.cacheLock.RUnlock()
|
|
||||||
return encoder
|
|
||||||
}
|
|
||||||
|
|
||||||
var cfgCacheLock = &sync.RWMutex{}
|
|
||||||
var cfgCache = map[Config]*frozenConfig{}
|
|
||||||
|
|
||||||
func getFrozenConfigFromCache(cfg Config) *frozenConfig {
|
|
||||||
cfgCacheLock.RLock()
|
|
||||||
frozenConfig := cfgCache[cfg]
|
|
||||||
cfgCacheLock.RUnlock()
|
|
||||||
return frozenConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
|
|
||||||
cfgCacheLock.Lock()
|
|
||||||
cfgCache[cfg] = frozenConfig
|
|
||||||
cfgCacheLock.Unlock()
|
|
||||||
}
|
|
@ -3,6 +3,7 @@ package jsoniter
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleMarshal() {
|
func ExampleMarshal() {
|
||||||
@ -93,3 +94,28 @@ func ExampleGet() {
|
|||||||
// Output:
|
// Output:
|
||||||
// Crimson
|
// Crimson
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleMapKey() {
|
||||||
|
hello := MyKey("hello")
|
||||||
|
output, _ := Marshal(map[*MyKey]string{&hello: "world"})
|
||||||
|
fmt.Println(string(output))
|
||||||
|
obj := map[*MyKey]string{}
|
||||||
|
Unmarshal(output, &obj)
|
||||||
|
for k, v := range obj {
|
||||||
|
fmt.Println(*k, v)
|
||||||
|
}
|
||||||
|
// Output:
|
||||||
|
// {"Hello":"world"}
|
||||||
|
// Hel world
|
||||||
|
}
|
||||||
|
|
||||||
|
type MyKey string
|
||||||
|
|
||||||
|
func (m *MyKey) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(strings.Replace(string(*m), "h", "H", -1)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MyKey) UnmarshalText(text []byte) error {
|
||||||
|
*m = MyKey(text[:3])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"unsafe"
|
|
||||||
"time"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_customize_type_decoder(t *testing.T) {
|
func Test_customize_type_decoder(t *testing.T) {
|
||||||
@ -61,7 +61,6 @@ func Test_customize_field_decoder(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test_recursive_empty_interface_customization(t *testing.T) {
|
func Test_recursive_empty_interface_customization(t *testing.T) {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
var obj interface{}
|
var obj interface{}
|
||||||
@ -98,4 +97,4 @@ func Test_read_custom_interface(t *testing.T) {
|
|||||||
err := jsoniter.UnmarshalFromString(`"hello"`, &val)
|
err := jsoniter.UnmarshalFromString(`"hello"`, &val)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal("hello", val.Hello())
|
should.Equal("hello", val.Hello())
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/stretchr/testify/require"
|
"unsafe"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestObject1 struct {
|
type TestObject1 struct {
|
||||||
@ -46,6 +48,53 @@ func Test_customize_field_by_extension(t *testing.T) {
|
|||||||
should.Equal(`{"field-1":100}`, str)
|
should.Equal(`{"field-1":100}`, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_customize_map_key_encoder(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
cfg := jsoniter.Config{}.Froze()
|
||||||
|
cfg.RegisterExtension(&testMapKeyExtension{})
|
||||||
|
m := map[int]int{1: 2}
|
||||||
|
output, err := cfg.MarshalToString(m)
|
||||||
|
should.NoError(err)
|
||||||
|
should.Equal(`{"2":2}`, output)
|
||||||
|
m = map[int]int{}
|
||||||
|
should.NoError(cfg.UnmarshalFromString(output, &m))
|
||||||
|
should.Equal(map[int]int{1: 2}, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
type testMapKeyExtension struct {
|
||||||
|
jsoniter.DummyExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
func (extension *testMapKeyExtension) CreateMapKeyEncoder(typ reflect2.Type) jsoniter.ValEncoder {
|
||||||
|
if typ.Kind() == reflect.Int {
|
||||||
|
return &funcEncoder{
|
||||||
|
fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||||
|
stream.WriteRaw(`"`)
|
||||||
|
stream.WriteInt(*(*int)(ptr) + 1)
|
||||||
|
stream.WriteRaw(`"`)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (extension *testMapKeyExtension) CreateMapKeyDecoder(typ reflect2.Type) jsoniter.ValDecoder {
|
||||||
|
if typ.Kind() == reflect.Int {
|
||||||
|
return &funcDecoder{
|
||||||
|
fun: func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||||
|
i, err := strconv.Atoi(iter.ReadString())
|
||||||
|
if err != nil {
|
||||||
|
iter.ReportError("read map key", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
*(*int)(ptr) = i
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type funcDecoder struct {
|
type funcDecoder struct {
|
||||||
fun jsoniter.DecoderFunc
|
fun jsoniter.DecoderFunc
|
||||||
}
|
}
|
||||||
|
238
extra/binary_as_string_codec.go
Normal file
238
extra/binary_as_string_codec.go
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
package extra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"unsafe"
|
||||||
|
"unicode/utf8"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// safeSet holds the value true if the ASCII character with the given array
|
||||||
|
// position can be represented inside a JSON string without any further
|
||||||
|
// escaping.
|
||||||
|
//
|
||||||
|
// All values are true except for the ASCII control characters (0-31), the
|
||||||
|
// double quote ("), and the backslash character ("\").
|
||||||
|
var safeSet = [utf8.RuneSelf]bool{
|
||||||
|
' ': true,
|
||||||
|
'!': true,
|
||||||
|
'"': false,
|
||||||
|
'#': true,
|
||||||
|
'$': true,
|
||||||
|
'%': true,
|
||||||
|
'&': true,
|
||||||
|
'\'': true,
|
||||||
|
'(': true,
|
||||||
|
')': true,
|
||||||
|
'*': true,
|
||||||
|
'+': true,
|
||||||
|
',': true,
|
||||||
|
'-': true,
|
||||||
|
'.': true,
|
||||||
|
'/': true,
|
||||||
|
'0': true,
|
||||||
|
'1': true,
|
||||||
|
'2': true,
|
||||||
|
'3': true,
|
||||||
|
'4': true,
|
||||||
|
'5': true,
|
||||||
|
'6': true,
|
||||||
|
'7': true,
|
||||||
|
'8': true,
|
||||||
|
'9': true,
|
||||||
|
':': true,
|
||||||
|
';': true,
|
||||||
|
'<': true,
|
||||||
|
'=': true,
|
||||||
|
'>': true,
|
||||||
|
'?': true,
|
||||||
|
'@': true,
|
||||||
|
'A': true,
|
||||||
|
'B': true,
|
||||||
|
'C': true,
|
||||||
|
'D': true,
|
||||||
|
'E': true,
|
||||||
|
'F': true,
|
||||||
|
'G': true,
|
||||||
|
'H': true,
|
||||||
|
'I': true,
|
||||||
|
'J': true,
|
||||||
|
'K': true,
|
||||||
|
'L': true,
|
||||||
|
'M': true,
|
||||||
|
'N': true,
|
||||||
|
'O': true,
|
||||||
|
'P': true,
|
||||||
|
'Q': true,
|
||||||
|
'R': true,
|
||||||
|
'S': true,
|
||||||
|
'T': true,
|
||||||
|
'U': true,
|
||||||
|
'V': true,
|
||||||
|
'W': true,
|
||||||
|
'X': true,
|
||||||
|
'Y': true,
|
||||||
|
'Z': true,
|
||||||
|
'[': true,
|
||||||
|
'\\': false,
|
||||||
|
']': true,
|
||||||
|
'^': true,
|
||||||
|
'_': true,
|
||||||
|
'`': true,
|
||||||
|
'a': true,
|
||||||
|
'b': true,
|
||||||
|
'c': true,
|
||||||
|
'd': true,
|
||||||
|
'e': true,
|
||||||
|
'f': true,
|
||||||
|
'g': true,
|
||||||
|
'h': true,
|
||||||
|
'i': true,
|
||||||
|
'j': true,
|
||||||
|
'k': true,
|
||||||
|
'l': true,
|
||||||
|
'm': true,
|
||||||
|
'n': true,
|
||||||
|
'o': true,
|
||||||
|
'p': true,
|
||||||
|
'q': true,
|
||||||
|
'r': true,
|
||||||
|
's': true,
|
||||||
|
't': true,
|
||||||
|
'u': true,
|
||||||
|
'v': true,
|
||||||
|
'w': true,
|
||||||
|
'x': true,
|
||||||
|
'y': true,
|
||||||
|
'z': true,
|
||||||
|
'{': true,
|
||||||
|
'|': true,
|
||||||
|
'}': true,
|
||||||
|
'~': true,
|
||||||
|
'\u007f': true,
|
||||||
|
}
|
||||||
|
|
||||||
|
var binaryType = reflect2.TypeOfPtr((*[]byte)(nil)).Elem()
|
||||||
|
|
||||||
|
type BinaryAsStringExtension struct {
|
||||||
|
jsoniter.DummyExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
func (extension *BinaryAsStringExtension) CreateEncoder(typ reflect2.Type) jsoniter.ValEncoder {
|
||||||
|
if typ == binaryType {
|
||||||
|
return &binaryAsStringCodec{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (extension *BinaryAsStringExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder {
|
||||||
|
if typ == binaryType {
|
||||||
|
return &binaryAsStringCodec{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type binaryAsStringCodec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *binaryAsStringCodec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||||
|
rawBytes := iter.ReadStringAsSlice()
|
||||||
|
bytes := make([]byte, 0, len(rawBytes))
|
||||||
|
for i := 0; i < len(rawBytes); i++ {
|
||||||
|
b := rawBytes[i]
|
||||||
|
if b == '\\' {
|
||||||
|
b2 := rawBytes[i+1]
|
||||||
|
if b2 != '\\' {
|
||||||
|
iter.ReportError("decode binary as string", `\\x is only supported escape`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b3 := rawBytes[i+2]
|
||||||
|
if b3 != 'x' {
|
||||||
|
iter.ReportError("decode binary as string", `\\x is only supported escape`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b4 := rawBytes[i+3]
|
||||||
|
b5 := rawBytes[i+4]
|
||||||
|
i = i + 4
|
||||||
|
b = readHex(iter, b4, b5)
|
||||||
|
}
|
||||||
|
bytes = append(bytes, b)
|
||||||
|
}
|
||||||
|
*(*[]byte)(ptr) = bytes
|
||||||
|
}
|
||||||
|
func (codec *binaryAsStringCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return len(*((*[]byte)(ptr))) == 0
|
||||||
|
}
|
||||||
|
func (codec *binaryAsStringCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||||
|
newBuffer := writeBytes(stream.Buffer(), *(*[]byte)(ptr))
|
||||||
|
stream.SetBuffer(newBuffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte {
|
||||||
|
var ret byte
|
||||||
|
if b1 >= '0' && b1 <= '9' {
|
||||||
|
ret = b1-'0'
|
||||||
|
} else if b1 >= 'a' && b1 <= 'f' {
|
||||||
|
ret = b1-'a'+10
|
||||||
|
} else {
|
||||||
|
iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1}))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
ret = ret * 16
|
||||||
|
if b2 >= '0' && b2 <= '9' {
|
||||||
|
ret = b2-'0'
|
||||||
|
} else if b2 >= 'a' && b2 <= 'f' {
|
||||||
|
ret = b2-'a'+10
|
||||||
|
} else {
|
||||||
|
iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2}))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
var hex = "0123456789abcdef"
|
||||||
|
|
||||||
|
func writeBytes(space []byte, s []byte) []byte {
|
||||||
|
space = append(space, '"')
|
||||||
|
// write string, the fast path, without utf8 and escape support
|
||||||
|
var i int
|
||||||
|
var c byte
|
||||||
|
for i, c = range s {
|
||||||
|
if c < utf8.RuneSelf && safeSet[c] {
|
||||||
|
space = append(space, c)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i == len(s)-1 {
|
||||||
|
space = append(space, '"')
|
||||||
|
return space
|
||||||
|
}
|
||||||
|
return writeBytesSlowPath(space, s[i:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeBytesSlowPath(space []byte, s []byte) []byte {
|
||||||
|
start := 0
|
||||||
|
// for the remaining parts, we process them char by char
|
||||||
|
var i int
|
||||||
|
var b byte
|
||||||
|
for i, b = range s {
|
||||||
|
if b >= utf8.RuneSelf {
|
||||||
|
space = append(space, '\\', '\\', 'x', hex[b>>4], hex[b&0xF])
|
||||||
|
start = i + 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if safeSet[b] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if start < i {
|
||||||
|
space = append(space, s[start:i]...)
|
||||||
|
}
|
||||||
|
space = append(space, '\\', '\\', 'x', hex[b>>4], hex[b&0xF])
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
if start < len(s) {
|
||||||
|
space = append(space, s[start:]...)
|
||||||
|
}
|
||||||
|
return append(space, '"')
|
||||||
|
}
|
32
extra/binary_as_string_codec_test.go
Normal file
32
extra/binary_as_string_codec_test.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package extra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
jsoniter.RegisterExtension(&BinaryAsStringExtension{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinaryAsStringCodec(t *testing.T) {
|
||||||
|
t.Run("safe set", func(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
output, err := jsoniter.Marshal([]byte("hello"))
|
||||||
|
should.NoError(err)
|
||||||
|
should.Equal(`"hello"`, string(output))
|
||||||
|
var val []byte
|
||||||
|
should.NoError(jsoniter.Unmarshal(output, &val))
|
||||||
|
should.Equal(`hello`, string(val))
|
||||||
|
})
|
||||||
|
t.Run("non safe set", func(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
output, err := jsoniter.Marshal([]byte{1, 2, 3, 15})
|
||||||
|
should.NoError(err)
|
||||||
|
should.Equal(`"\\x01\\x02\\x03\\x0f"`, string(output))
|
||||||
|
var val []byte
|
||||||
|
should.NoError(jsoniter.Unmarshal(output, &val))
|
||||||
|
should.Equal([]byte{1, 2, 3, 15}, val)
|
||||||
|
})
|
||||||
|
}
|
@ -9,7 +9,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"github.com/v2pro/plz/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxUint = ^uint(0)
|
const maxUint = ^uint(0)
|
||||||
@ -183,6 +183,9 @@ func (decoder *fuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Ite
|
|||||||
*((*string)(ptr)) = string(number)
|
*((*string)(ptr)) = string(number)
|
||||||
case jsoniter.StringValue:
|
case jsoniter.StringValue:
|
||||||
*((*string)(ptr)) = iter.ReadString()
|
*((*string)(ptr)) = iter.ReadString()
|
||||||
|
case jsoniter.NilValue:
|
||||||
|
iter.Skip()
|
||||||
|
*((*string)(ptr)) = ""
|
||||||
default:
|
default:
|
||||||
iter.ReportError("fuzzyStringDecoder", "not number or string")
|
iter.ReportError("fuzzyStringDecoder", "not number or string")
|
||||||
}
|
}
|
||||||
@ -208,6 +211,9 @@ func (decoder *fuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It
|
|||||||
} else {
|
} else {
|
||||||
str = "0"
|
str = "0"
|
||||||
}
|
}
|
||||||
|
case jsoniter.NilValue:
|
||||||
|
iter.Skip()
|
||||||
|
str = "0"
|
||||||
default:
|
default:
|
||||||
iter.ReportError("fuzzyIntegerDecoder", "not number or string")
|
iter.ReportError("fuzzyIntegerDecoder", "not number or string")
|
||||||
}
|
}
|
||||||
@ -244,6 +250,9 @@ func (decoder *fuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It
|
|||||||
} else {
|
} else {
|
||||||
*((*float32)(ptr)) = 0
|
*((*float32)(ptr)) = 0
|
||||||
}
|
}
|
||||||
|
case jsoniter.NilValue:
|
||||||
|
iter.Skip()
|
||||||
|
*((*float32)(ptr)) = 0
|
||||||
default:
|
default:
|
||||||
iter.ReportError("fuzzyFloat32Decoder", "not number or string")
|
iter.ReportError("fuzzyFloat32Decoder", "not number or string")
|
||||||
}
|
}
|
||||||
@ -273,7 +282,10 @@ func (decoder *fuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It
|
|||||||
} else {
|
} else {
|
||||||
*((*float64)(ptr)) = 0
|
*((*float64)(ptr)) = 0
|
||||||
}
|
}
|
||||||
|
case jsoniter.NilValue:
|
||||||
|
iter.Skip()
|
||||||
|
*((*float64)(ptr)) = 0
|
||||||
default:
|
default:
|
||||||
iter.ReportError("fuzzyFloat32Decoder", "not number or string")
|
iter.ReportError("fuzzyFloat64Decoder", "not number or string")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,3 +357,35 @@ func Test_bad_case(t *testing.T) {
|
|||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_null_to_string(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
body := []byte(`null`)
|
||||||
|
var message string
|
||||||
|
err := jsoniter.Unmarshal(body, &message)
|
||||||
|
should.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_null_to_int(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
body := []byte(`null`)
|
||||||
|
var message int
|
||||||
|
err := jsoniter.Unmarshal(body, &message)
|
||||||
|
should.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_null_to_float32(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
body := []byte(`null`)
|
||||||
|
var message float32
|
||||||
|
err := jsoniter.Unmarshal(body, &message)
|
||||||
|
should.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_null_to_float64(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
body := []byte(`null`)
|
||||||
|
var message float64
|
||||||
|
err := jsoniter.Unmarshal(body, &message)
|
||||||
|
should.NoError(err)
|
||||||
|
}
|
||||||
|
@ -22,11 +22,17 @@ func init() {
|
|||||||
|
|
||||||
// ReadUint read uint
|
// ReadUint read uint
|
||||||
func (iter *Iterator) ReadUint() uint {
|
func (iter *Iterator) ReadUint() uint {
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return uint(iter.ReadUint32())
|
||||||
|
}
|
||||||
return uint(iter.ReadUint64())
|
return uint(iter.ReadUint64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadInt read int
|
// ReadInt read int
|
||||||
func (iter *Iterator) ReadInt() int {
|
func (iter *Iterator) ReadInt() int {
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return int(iter.ReadInt32())
|
||||||
|
}
|
||||||
return int(iter.ReadInt64())
|
return int(iter.ReadInt64())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package misc_tests
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_empty_array(t *testing.T) {
|
func Test_empty_array(t *testing.T) {
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_true(t *testing.T) {
|
func Test_true(t *testing.T) {
|
||||||
@ -44,4 +44,4 @@ func Test_write_val_bool(t *testing.T) {
|
|||||||
should.Equal(stream.Buffered(), 0)
|
should.Equal(stream.Buffered(), 0)
|
||||||
should.Nil(stream.Error)
|
should.Nil(stream.Error)
|
||||||
should.Equal("true", buf.String())
|
should.Equal("true", buf.String())
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_big_float(t *testing.T) {
|
func Test_read_big_float(t *testing.T) {
|
||||||
|
@ -9,8 +9,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_uint64_invalid(t *testing.T) {
|
func Test_read_uint64_invalid(t *testing.T) {
|
||||||
|
@ -2,10 +2,10 @@ package misc_tests
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"io"
|
"io"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_nil_non_empty_interface(t *testing.T) {
|
func Test_nil_non_empty_interface(t *testing.T) {
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_bad_case(t *testing.T) {
|
func Test_bad_case(t *testing.T) {
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"strings"
|
"strings"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_decode_TextMarshaler_key_map(t *testing.T) {
|
func Test_decode_TextMarshaler_key_map(t *testing.T) {
|
||||||
|
@ -2,9 +2,9 @@ package misc_tests
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Level1 struct {
|
type Level1 struct {
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_null(t *testing.T) {
|
func Test_read_null(t *testing.T) {
|
||||||
|
@ -4,10 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"time"
|
"github.com/stretchr/testify/require"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_empty_object(t *testing.T) {
|
func Test_empty_object(t *testing.T) {
|
||||||
@ -129,4 +129,4 @@ func Test_reader_and_load_more(t *testing.T) {
|
|||||||
decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader)
|
decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(reader)
|
||||||
obj := TestObject{}
|
obj := TestObject{}
|
||||||
should.Nil(decoder.Decode(&obj))
|
should.Nil(decoder.Decode(&obj))
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@ package misc_tests
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_jsoniter_RawMessage(t *testing.T) {
|
func Test_jsoniter_RawMessage(t *testing.T) {
|
||||||
@ -45,18 +45,18 @@ func Test_marshal_invalid_json_raw_message(t *testing.T) {
|
|||||||
func Test_raw_message_memory_not_copied_issue(t *testing.T) {
|
func Test_raw_message_memory_not_copied_issue(t *testing.T) {
|
||||||
jsonStream := `{"name":"xxxxx","bundle_id":"com.zonst.majiang","app_platform":"ios","app_category":"100103", "budget_day":1000,"bidding_min":1,"bidding_max":2,"bidding_type":"CPM", "freq":{"open":true,"type":"day","num":100},"speed":1, "targeting":{"vendor":{"open":true,"list":["zonst"]}, "geo_code":{"open":true,"list":["156110100"]},"app_category":{"open":true,"list":["100101"]}, "day_parting":{"open":true,"list":["100409","100410"]},"device_type":{"open":true,"list":["ipad"]}, "os_version":{"open":true,"list":[10]},"carrier":{"open":true,"list":["mobile"]}, "network":{"open":true,"list":["4G"]}},"url":{"tracking_imp_url":"http://www.baidu.com", "tracking_clk_url":"http://www.baidu.com","jump_url":"http://www.baidu.com","deep_link_url":"http://www.baidu.com"}}`
|
jsonStream := `{"name":"xxxxx","bundle_id":"com.zonst.majiang","app_platform":"ios","app_category":"100103", "budget_day":1000,"bidding_min":1,"bidding_max":2,"bidding_type":"CPM", "freq":{"open":true,"type":"day","num":100},"speed":1, "targeting":{"vendor":{"open":true,"list":["zonst"]}, "geo_code":{"open":true,"list":["156110100"]},"app_category":{"open":true,"list":["100101"]}, "day_parting":{"open":true,"list":["100409","100410"]},"device_type":{"open":true,"list":["ipad"]}, "os_version":{"open":true,"list":[10]},"carrier":{"open":true,"list":["mobile"]}, "network":{"open":true,"list":["4G"]}},"url":{"tracking_imp_url":"http://www.baidu.com", "tracking_clk_url":"http://www.baidu.com","jump_url":"http://www.baidu.com","deep_link_url":"http://www.baidu.com"}}`
|
||||||
type IteratorObject struct {
|
type IteratorObject struct {
|
||||||
Name *string `json:"name"`
|
Name *string `json:"name"`
|
||||||
BundleId *string `json:"bundle_id"`
|
BundleId *string `json:"bundle_id"`
|
||||||
AppCategory *string `json:"app_category"`
|
AppCategory *string `json:"app_category"`
|
||||||
AppPlatform *string `json:"app_platform"`
|
AppPlatform *string `json:"app_platform"`
|
||||||
BudgetDay *float32 `json:"budget_day"`
|
BudgetDay *float32 `json:"budget_day"`
|
||||||
BiddingMax *float32 `json:"bidding_max"`
|
BiddingMax *float32 `json:"bidding_max"`
|
||||||
BiddingMin *float32 `json:"bidding_min"`
|
BiddingMin *float32 `json:"bidding_min"`
|
||||||
BiddingType *string `json:"bidding_type"`
|
BiddingType *string `json:"bidding_type"`
|
||||||
Freq *jsoniter.RawMessage `json:"freq"`
|
Freq *jsoniter.RawMessage `json:"freq"`
|
||||||
Targeting *jsoniter.RawMessage `json:"targeting"`
|
Targeting *jsoniter.RawMessage `json:"targeting"`
|
||||||
Url *jsoniter.RawMessage `json:"url"`
|
Url *jsoniter.RawMessage `json:"url"`
|
||||||
Speed *int `json:"speed" db:"speed"`
|
Speed *int `json:"speed" db:"speed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := &IteratorObject{}
|
obj := &IteratorObject{}
|
||||||
|
@ -2,9 +2,9 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValDecoder is an internal type registered to cache as needed.
|
// ValDecoder is an internal type registered to cache as needed.
|
||||||
|
@ -2,9 +2,9 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
|
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/v2pro/plz/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
"unsafe"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type dynamicEncoder struct {
|
type dynamicEncoder struct {
|
||||||
|
@ -2,12 +2,12 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var typeDecoders = map[string]ValDecoder{}
|
var typeDecoders = map[string]ValDecoder{}
|
||||||
@ -18,8 +18,8 @@ var extensions = []Extension{}
|
|||||||
|
|
||||||
// StructDescriptor describe how should we encode/decode the struct
|
// StructDescriptor describe how should we encode/decode the struct
|
||||||
type StructDescriptor struct {
|
type StructDescriptor struct {
|
||||||
Type reflect2.Type
|
Type reflect2.Type
|
||||||
Fields []*Binding
|
Fields []*Binding
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetField get one field from the descriptor by its name.
|
// GetField get one field from the descriptor by its name.
|
||||||
@ -47,6 +47,8 @@ type Binding struct {
|
|||||||
// Can also rename fields by UpdateStructDescriptor.
|
// Can also rename fields by UpdateStructDescriptor.
|
||||||
type Extension interface {
|
type Extension interface {
|
||||||
UpdateStructDescriptor(structDescriptor *StructDescriptor)
|
UpdateStructDescriptor(structDescriptor *StructDescriptor)
|
||||||
|
CreateMapKeyDecoder(typ reflect2.Type) ValDecoder
|
||||||
|
CreateMapKeyEncoder(typ reflect2.Type) ValEncoder
|
||||||
CreateDecoder(typ reflect2.Type) ValDecoder
|
CreateDecoder(typ reflect2.Type) ValDecoder
|
||||||
CreateEncoder(typ reflect2.Type) ValEncoder
|
CreateEncoder(typ reflect2.Type) ValEncoder
|
||||||
DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
|
DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
|
||||||
@ -61,6 +63,16 @@ type DummyExtension struct {
|
|||||||
func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
|
func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMapKeyDecoder No-op
|
||||||
|
func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapKeyEncoder No-op
|
||||||
|
func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateDecoder No-op
|
// CreateDecoder No-op
|
||||||
func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
||||||
return nil
|
return nil
|
||||||
@ -97,6 +109,16 @@ func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
|
|||||||
return extension[typ]
|
return extension[typ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMapKeyDecoder No-op
|
||||||
|
func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapKeyEncoder No-op
|
||||||
|
func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// DecorateDecoder No-op
|
// DecorateDecoder No-op
|
||||||
func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
|
func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
|
||||||
return decoder
|
return decoder
|
||||||
@ -113,6 +135,16 @@ type DecoderExtension map[reflect2.Type]ValDecoder
|
|||||||
func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
|
func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMapKeyDecoder No-op
|
||||||
|
func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapKeyEncoder No-op
|
||||||
|
func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateDecoder get decoder from map
|
// CreateDecoder get decoder from map
|
||||||
func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
|
||||||
return extension[typ]
|
return extension[typ]
|
||||||
@ -355,8 +387,8 @@ func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
|
|||||||
}
|
}
|
||||||
func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
||||||
structDescriptor := &StructDescriptor{
|
structDescriptor := &StructDescriptor{
|
||||||
Type: typ,
|
Type: typ,
|
||||||
Fields: bindings,
|
Fields: bindings,
|
||||||
}
|
}
|
||||||
for _, extension := range extensions {
|
for _, extension := range extensions {
|
||||||
extension.UpdateStructDescriptor(structDescriptor)
|
extension.UpdateStructDescriptor(structDescriptor)
|
||||||
|
@ -2,9 +2,9 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Number string
|
type Number string
|
||||||
@ -109,4 +109,4 @@ func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
|
|
||||||
func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
return len(*((*Number)(ptr))) == 0
|
return len(*((*Number)(ptr))) == 0
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/v2pro/plz/reflect2"
|
"github.com/modern-go/reflect2"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()
|
var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()
|
||||||
@ -57,4 +57,4 @@ func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream)
|
|||||||
|
|
||||||
func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
return len(*((*RawMessage)(ptr))) == 0
|
return len(*((*RawMessage)(ptr))) == 0
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
|
func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
@ -38,6 +38,12 @@ func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
|
func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
|
for _, extension := range ctx.extensions {
|
||||||
|
decoder := extension.CreateMapKeyDecoder(typ)
|
||||||
|
if decoder != nil {
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
}
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
||||||
@ -70,6 +76,12 @@ func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
|
func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||||
|
for _, extension := range ctx.extensions {
|
||||||
|
encoder := extension.CreateMapKeyEncoder(typ)
|
||||||
|
if encoder != nil {
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
}
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
"unsafe"
|
|
||||||
"encoding"
|
"encoding"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
|
var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
|
||||||
|
@ -2,11 +2,14 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const ptrSize = 32 << uintptr(^uintptr(0)>>63)
|
||||||
|
|
||||||
func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
|
func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||||
if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
|
if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
|
||||||
sliceDecoder := decoderOfSlice(ctx, typ)
|
sliceDecoder := decoderOfSlice(ctx, typ)
|
||||||
@ -24,7 +27,10 @@ func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|||||||
if typeName != "int" {
|
if typeName != "int" {
|
||||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
||||||
}
|
}
|
||||||
return &intCodec{}
|
if strconv.IntSize == 32 {
|
||||||
|
return &int32Codec{}
|
||||||
|
}
|
||||||
|
return &int64Codec{}
|
||||||
case reflect.Int8:
|
case reflect.Int8:
|
||||||
if typeName != "int8" {
|
if typeName != "int8" {
|
||||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
||||||
@ -49,7 +55,10 @@ func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|||||||
if typeName != "uint" {
|
if typeName != "uint" {
|
||||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
||||||
}
|
}
|
||||||
return &uintCodec{}
|
if strconv.IntSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
case reflect.Uint8:
|
case reflect.Uint8:
|
||||||
if typeName != "uint8" {
|
if typeName != "uint8" {
|
||||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
||||||
@ -69,7 +78,10 @@ func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|||||||
if typeName != "uintptr" {
|
if typeName != "uintptr" {
|
||||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
||||||
}
|
}
|
||||||
return &uintptrCodec{}
|
if ptrSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
case reflect.Uint64:
|
case reflect.Uint64:
|
||||||
if typeName != "uint64" {
|
if typeName != "uint64" {
|
||||||
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
||||||
@ -110,7 +122,10 @@ func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|||||||
if typeName != "int" {
|
if typeName != "int" {
|
||||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
|
||||||
}
|
}
|
||||||
return &intCodec{}
|
if strconv.IntSize == 32 {
|
||||||
|
return &int32Codec{}
|
||||||
|
}
|
||||||
|
return &int64Codec{}
|
||||||
case reflect.Int8:
|
case reflect.Int8:
|
||||||
if typeName != "int8" {
|
if typeName != "int8" {
|
||||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
|
||||||
@ -135,7 +150,10 @@ func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|||||||
if typeName != "uint" {
|
if typeName != "uint" {
|
||||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
|
||||||
}
|
}
|
||||||
return &uintCodec{}
|
if strconv.IntSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
case reflect.Uint8:
|
case reflect.Uint8:
|
||||||
if typeName != "uint8" {
|
if typeName != "uint8" {
|
||||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
|
||||||
@ -155,7 +173,10 @@ func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|||||||
if typeName != "uintptr" {
|
if typeName != "uintptr" {
|
||||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
|
||||||
}
|
}
|
||||||
return &uintptrCodec{}
|
if ptrSize == 32 {
|
||||||
|
return &uint32Codec{}
|
||||||
|
}
|
||||||
|
return &uint64Codec{}
|
||||||
case reflect.Uint64:
|
case reflect.Uint64:
|
||||||
if typeName != "uint64" {
|
if typeName != "uint64" {
|
||||||
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
|
||||||
@ -196,40 +217,6 @@ func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
return *((*string)(ptr)) == ""
|
return *((*string)(ptr)) == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
type intCodec struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
||||||
if !iter.ReadNil() {
|
|
||||||
*((*int)(ptr)) = iter.ReadInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
stream.WriteInt(*((*int)(ptr)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *intCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|
||||||
return *((*int)(ptr)) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type uintptrCodec struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *uintptrCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
||||||
if !iter.ReadNil() {
|
|
||||||
*((*uintptr)(ptr)) = uintptr(iter.ReadUint64())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *uintptrCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
stream.WriteUint64(uint64(*((*uintptr)(ptr))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *uintptrCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|
||||||
return *((*uintptr)(ptr)) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type int8Codec struct {
|
type int8Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,24 +285,6 @@ func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
return *((*int64)(ptr)) == 0
|
return *((*int64)(ptr)) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type uintCodec struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
||||||
if !iter.ReadNil() {
|
|
||||||
*((*uint)(ptr)) = iter.ReadUint()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
||||||
stream.WriteUint(*((*uint)(ptr)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (codec *uintCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|
||||||
return *((*uint)(ptr)) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type uint8Codec struct {
|
type uint8Codec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +405,7 @@ func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type base64Codec struct {
|
type base64Codec struct {
|
||||||
sliceType *reflect2.UnsafeSliceType
|
sliceType *reflect2.UnsafeSliceType
|
||||||
sliceDecoder ValDecoder
|
sliceDecoder ValDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +418,7 @@ func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|||||||
case StringValue:
|
case StringValue:
|
||||||
encoding := base64.StdEncoding
|
encoding := base64.StdEncoding
|
||||||
src := iter.SkipAndReturnBytes()
|
src := iter.SkipAndReturnBytes()
|
||||||
src = src[1: len(src)-1]
|
src = src[1 : len(src)-1]
|
||||||
decodedLen := encoding.DecodedLen(len(src))
|
decodedLen := encoding.DecodedLen(len(src))
|
||||||
dst := make([]byte, decodedLen)
|
dst := make([]byte, decodedLen)
|
||||||
len, err := encoding.Decode(dst, src)
|
len, err := encoding.Decode(dst, src)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder {
|
func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
|
@ -2,9 +2,9 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
|
func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
|
@ -2,10 +2,10 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
|
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
@ -995,7 +995,7 @@ func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|||||||
fieldPtr := decoder.field.UnsafeGet(ptr)
|
fieldPtr := decoder.field.UnsafeGet(ptr)
|
||||||
decoder.fieldDecoder.Decode(fieldPtr, iter)
|
decoder.fieldDecoder.Decode(fieldPtr, iter)
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
|
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,4 +1031,4 @@ func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
|||||||
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
|
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
|
func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||||
@ -47,38 +47,12 @@ func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
|
func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
|
||||||
|
encoder := createEncoderOfNative(ctx, typ)
|
||||||
|
if encoder != nil {
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
kind := typ.Kind()
|
kind := typ.Kind()
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.String:
|
|
||||||
return &stringCodec{}
|
|
||||||
case reflect.Int:
|
|
||||||
return &intCodec{}
|
|
||||||
case reflect.Int8:
|
|
||||||
return &int8Codec{}
|
|
||||||
case reflect.Int16:
|
|
||||||
return &int16Codec{}
|
|
||||||
case reflect.Int32:
|
|
||||||
return &int32Codec{}
|
|
||||||
case reflect.Int64:
|
|
||||||
return &int64Codec{}
|
|
||||||
case reflect.Uint:
|
|
||||||
return &uintCodec{}
|
|
||||||
case reflect.Uint8:
|
|
||||||
return &uint8Codec{}
|
|
||||||
case reflect.Uint16:
|
|
||||||
return &uint16Codec{}
|
|
||||||
case reflect.Uint32:
|
|
||||||
return &uint32Codec{}
|
|
||||||
case reflect.Uintptr:
|
|
||||||
return &uintptrCodec{}
|
|
||||||
case reflect.Uint64:
|
|
||||||
return &uint64Codec{}
|
|
||||||
case reflect.Float32:
|
|
||||||
return &float32Codec{}
|
|
||||||
case reflect.Float64:
|
|
||||||
return &float64Codec{}
|
|
||||||
case reflect.Bool:
|
|
||||||
return &boolCodec{}
|
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
return &dynamicEncoder{typ}
|
return &dynamicEncoder{typ}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_skip_number_in_array(t *testing.T) {
|
func Test_skip_number_in_array(t *testing.T) {
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
"github.com/json-iterator/go"
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
|
@ -14,4 +14,4 @@ func init() {
|
|||||||
`"\t"`, // valid
|
`"\t"`, // valid
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,4 @@ func init() {
|
|||||||
`{abc}`, // invalid
|
`{abc}`, // invalid
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,11 @@ func (stream *Stream) Buffer() []byte {
|
|||||||
return stream.buf
|
return stream.buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBuffer allows to append to the internal buffer directly
|
||||||
|
func (stream *Stream) SetBuffer(buf []byte) {
|
||||||
|
stream.buf = buf
|
||||||
|
}
|
||||||
|
|
||||||
// Write writes the contents of p into the buffer.
|
// Write writes the contents of p into the buffer.
|
||||||
// It returns the number of bytes written.
|
// It returns the number of bytes written.
|
||||||
// If nn < len(p), it also returns an error explaining
|
// If nn < len(p), it also returns an error explaining
|
||||||
|
@ -17,16 +17,16 @@ func init() {
|
|||||||
func writeFirstBuf(space []byte, v uint32) []byte {
|
func writeFirstBuf(space []byte, v uint32) []byte {
|
||||||
start := v >> 24
|
start := v >> 24
|
||||||
if start == 0 {
|
if start == 0 {
|
||||||
space = append(space, byte(v >> 16), byte(v >> 8))
|
space = append(space, byte(v>>16), byte(v>>8))
|
||||||
} else if start == 1 {
|
} else if start == 1 {
|
||||||
space = append(space, byte(v >> 8))
|
space = append(space, byte(v>>8))
|
||||||
}
|
}
|
||||||
space = append(space, byte(v))
|
space = append(space, byte(v))
|
||||||
return space
|
return space
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeBuf(buf []byte, v uint32) []byte {
|
func writeBuf(buf []byte, v uint32) []byte {
|
||||||
return append(buf, byte(v >> 16), byte(v >> 8), byte(v))
|
return append(buf, byte(v>>16), byte(v>>8), byte(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteUint8 write uint8 to stream
|
// WriteUint8 write uint8 to stream
|
||||||
@ -91,7 +91,7 @@ func (stream *Stream) WriteUint32(val uint32) {
|
|||||||
stream.buf = writeFirstBuf(stream.buf, digits[q2])
|
stream.buf = writeFirstBuf(stream.buf, digits[q2])
|
||||||
} else {
|
} else {
|
||||||
r3 := q2 - q3*1000
|
r3 := q2 - q3*1000
|
||||||
stream.buf = append(stream.buf, byte(q3 + '0'))
|
stream.buf = append(stream.buf, byte(q3+'0'))
|
||||||
stream.buf = writeBuf(stream.buf, digits[r3])
|
stream.buf = writeBuf(stream.buf, digits[r3])
|
||||||
}
|
}
|
||||||
stream.buf = writeBuf(stream.buf, digits[r2])
|
stream.buf = writeBuf(stream.buf, digits[r2])
|
||||||
|
@ -60,4 +60,4 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type structEmpty struct{}
|
type structEmpty struct{}
|
||||||
type arrayAlis [4]stringAlias
|
type arrayAlis [4]stringAlias
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -26,7 +26,6 @@ func (k *stringKeyType) UnmarshalText(text []byte) error {
|
|||||||
var _ encoding.TextMarshaler = stringKeyType("")
|
var _ encoding.TextMarshaler = stringKeyType("")
|
||||||
var _ encoding.TextUnmarshaler = new(stringKeyType)
|
var _ encoding.TextUnmarshaler = new(stringKeyType)
|
||||||
|
|
||||||
|
|
||||||
type structKeyType struct {
|
type structKeyType struct {
|
||||||
X string
|
X string
|
||||||
}
|
}
|
||||||
@ -41,4 +40,4 @@ func (k *structKeyType) UnmarshalText(text []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ encoding.TextMarshaler = structKeyType{}
|
var _ encoding.TextMarshaler = structKeyType{}
|
||||||
var _ encoding.TextUnmarshaler = &structKeyType{}
|
var _ encoding.TextUnmarshaler = &structKeyType{}
|
||||||
|
@ -3,8 +3,8 @@ package test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"strings"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StringMarshaler string
|
type StringMarshaler string
|
||||||
@ -49,4 +49,4 @@ var _ json.Unmarshaler = new(StringMarshaler)
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
testCases = append(testCases, (*StringMarshaler)(nil))
|
testCases = append(testCases, (*StringMarshaler)(nil))
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"encoding/base64"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type structMarshaler struct {
|
type structMarshaler struct {
|
||||||
|
@ -91,7 +91,6 @@ func (p *jsonMarshaler) UnmarshalJSON(input []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type jsonMarshalerMap map[int]int
|
type jsonMarshalerMap map[int]int
|
||||||
|
|
||||||
func (p *jsonMarshalerMap) MarshalJSON() ([]byte, error) {
|
func (p *jsonMarshalerMap) MarshalJSON() ([]byte, error) {
|
||||||
@ -117,11 +116,10 @@ func (p *textMarshaler) UnmarshalText(input []byte) error {
|
|||||||
|
|
||||||
type textMarshalerMap map[int]int
|
type textMarshalerMap map[int]int
|
||||||
|
|
||||||
|
|
||||||
func (p *textMarshalerMap) MarshalText() ([]byte, error) {
|
func (p *textMarshalerMap) MarshalText() ([]byte, error) {
|
||||||
return []byte(`{}`), nil
|
return []byte(`{}`), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *textMarshalerMap) UnmarshalText(input []byte) error {
|
func (p *textMarshalerMap) UnmarshalText(input []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -230,4 +230,4 @@ type EmbeddedPtrOption struct {
|
|||||||
|
|
||||||
type EmbeddedPtr struct {
|
type EmbeddedPtr struct {
|
||||||
EmbeddedPtrOption `json:","`
|
EmbeddedPtrOption `json:","`
|
||||||
}
|
}
|
||||||
|
@ -192,12 +192,12 @@ type StringFieldNameE struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StringFieldName struct {
|
type StringFieldName struct {
|
||||||
F1 string `json:"F1"`
|
F1 string `json:"F1"`
|
||||||
F2 string `json:"f2"`
|
F2 string `json:"f2"`
|
||||||
F3 string `json:"-"`
|
F3 string `json:"-"`
|
||||||
F4 string `json:"-,"`
|
F4 string `json:"-,"`
|
||||||
F5 string `json:","`
|
F5 string `json:","`
|
||||||
F6 string `json:""`
|
F6 string `json:""`
|
||||||
StringFieldNameE `json:"e"`
|
StringFieldNameE `json:"e"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"encoding"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -2,9 +2,9 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"strings"
|
"strings"
|
||||||
"encoding"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -66,4 +66,4 @@ func (m *structTextMarshaler) UnmarshalText(text []byte) error {
|
|||||||
var _ encoding.TextMarshaler = structTextMarshaler{}
|
var _ encoding.TextMarshaler = structTextMarshaler{}
|
||||||
var _ encoding.TextUnmarshaler = &structTextMarshaler{}
|
var _ encoding.TextUnmarshaler = &structTextMarshaler{}
|
||||||
|
|
||||||
type structTextMarshalerAlias structTextMarshaler
|
type structTextMarshalerAlias structTextMarshaler
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"reflect"
|
|
||||||
"fmt"
|
|
||||||
"github.com/google/gofuzz"
|
|
||||||
"strings"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"encoding/json"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/google/gofuzz"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testCases []interface{}
|
var testCases []interface{}
|
||||||
|
@ -8,13 +8,13 @@ func init() {
|
|||||||
[2]*float64{},
|
[2]*float64{},
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*[0]int)(nil),
|
ptr: (*[0]int)(nil),
|
||||||
input: `[1]`,
|
input: `[1]`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*[1]int)(nil),
|
ptr: (*[1]int)(nil),
|
||||||
input: `[2]`,
|
input: `[2]`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*[1]int)(nil),
|
ptr: (*[1]int)(nil),
|
||||||
input: `[]`,
|
input: `[]`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,16 @@ func init() {
|
|||||||
return &val
|
return &val
|
||||||
}
|
}
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (**interface{})(nil),
|
ptr: (**interface{})(nil),
|
||||||
input: `"hello"`,
|
input: `"hello"`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (**interface{})(nil),
|
ptr: (**interface{})(nil),
|
||||||
input: `1e1`,
|
input: `1e1`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (**interface{})(nil),
|
ptr: (**interface{})(nil),
|
||||||
input: `1.0e1`,
|
input: `1.0e1`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*[]interface{})(nil),
|
ptr: (*[]interface{})(nil),
|
||||||
input: `[1.0e1]`,
|
input: `[1.0e1]`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*struct {
|
ptr: (*struct {
|
||||||
@ -66,12 +66,12 @@ func init() {
|
|||||||
}{"hello"},
|
}{"hello"},
|
||||||
struct {
|
struct {
|
||||||
Field interface{}
|
Field interface{}
|
||||||
}{struct{
|
}{struct {
|
||||||
field chan int
|
field chan int
|
||||||
}{}},
|
}{}},
|
||||||
struct {
|
struct {
|
||||||
Field interface{}
|
Field interface{}
|
||||||
}{struct{
|
}{struct {
|
||||||
Field *int
|
Field *int
|
||||||
}{pInt(100)}},
|
}{pInt(100)}},
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"strconv"
|
"strconv"
|
||||||
"bytes"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"encoding/json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_float(t *testing.T) {
|
func Test_read_float(t *testing.T) {
|
||||||
@ -50,7 +50,6 @@ func Test_read_float(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test_write_float32(t *testing.T) {
|
func Test_write_float32(t *testing.T) {
|
||||||
vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
|
vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
|
||||||
-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
|
-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
|
||||||
@ -127,4 +126,4 @@ func Test_write_float64(t *testing.T) {
|
|||||||
stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
|
stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
|
||||||
stream.WriteFloat64(float64(0.0000001))
|
stream.WriteFloat64(float64(0.0000001))
|
||||||
should.Equal("1e-07", string(stream.Buffer()))
|
should.Equal("1e-07", string(stream.Buffer()))
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ func init() {
|
|||||||
pCloser2("hello"),
|
pCloser2("hello"),
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*[]io.Closer)(nil),
|
ptr: (*[]io.Closer)(nil),
|
||||||
input: "[null]",
|
input: "[null]",
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
obj: func() interface{} {
|
obj: func() interface{} {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"strconv"
|
"strconv"
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
"bytes"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -158,7 +158,6 @@ func Test_read_int64(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test_write_uint8(t *testing.T) {
|
func Test_write_uint8(t *testing.T) {
|
||||||
vals := []uint8{0, 1, 11, 111, 255}
|
vals := []uint8{0, 1, 11, 111, 255}
|
||||||
for _, val := range vals {
|
for _, val := range vals {
|
||||||
@ -417,4 +416,4 @@ func Test_write_int64(t *testing.T) {
|
|||||||
stream.Flush()
|
stream.Flush()
|
||||||
should.Nil(stream.Error)
|
should.Nil(stream.Error)
|
||||||
should.Equal("a4294967295", buf.String())
|
should.Equal("a4294967295", buf.String())
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@ package test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/json-iterator/go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_missing_object_end(t *testing.T) {
|
func Test_missing_object_end(t *testing.T) {
|
||||||
@ -223,4 +223,4 @@ func Test_EmptyInput(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error")
|
t.Errorf("Expected error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -26,16 +26,16 @@ func init() {
|
|||||||
},
|
},
|
||||||
nilMap,
|
nilMap,
|
||||||
&nilMap,
|
&nilMap,
|
||||||
map[string]*json.RawMessage{"hello":pRawMessage(json.RawMessage("[]"))},
|
map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))},
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*map[string]string)(nil),
|
ptr: (*map[string]string)(nil),
|
||||||
input: `{"k\"ey": "val"}`,
|
input: `{"k\"ey": "val"}`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*map[string]string)(nil),
|
ptr: (*map[string]string)(nil),
|
||||||
input: `null`,
|
input: `null`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*map[string]*json.RawMessage)(nil),
|
ptr: (*map[string]*json.RawMessage)(nil),
|
||||||
input: "{\"test\":[{\"key\":\"value\"}]}",
|
input: "{\"test\":[{\"key\":\"value\"}]}",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -17,20 +17,20 @@ func init() {
|
|||||||
tmOfStructInt{},
|
tmOfStructInt{},
|
||||||
&tm2,
|
&tm2,
|
||||||
map[tmOfStruct]int{
|
map[tmOfStruct]int{
|
||||||
tmOfStruct{}: 100,
|
{}: 100,
|
||||||
},
|
},
|
||||||
map[*tmOfStruct]int{
|
map[*tmOfStruct]int{
|
||||||
&tmOfStruct{}: 100,
|
{}: 100,
|
||||||
},
|
},
|
||||||
map[encoding.TextMarshaler]int{
|
map[encoding.TextMarshaler]int{
|
||||||
tm1: 100,
|
tm1: 100,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*tmOfMap)(nil),
|
ptr: (*tmOfMap)(nil),
|
||||||
input: `"{1:2}"`,
|
input: `"{1:2}"`,
|
||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*tmOfMapPtr)(nil),
|
ptr: (*tmOfMapPtr)(nil),
|
||||||
input: `"{1:2}"`,
|
input: `"{1:2}"`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -47,7 +47,6 @@ func (q *jmOfStruct) UnmarshalJSON(value []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type tmOfStruct struct {
|
type tmOfStruct struct {
|
||||||
F2 chan []byte
|
F2 chan []byte
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ func init() {
|
|||||||
json.RawMessage("{}"),
|
json.RawMessage("{}"),
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*json.RawMessage)(nil),
|
ptr: (*json.RawMessage)(nil),
|
||||||
input: `[1,2,3]`,
|
input: `[1,2,3]`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ func init() {
|
|||||||
[]interface{}{"hello"},
|
[]interface{}{"hello"},
|
||||||
nilSlice,
|
nilSlice,
|
||||||
&nilSlice,
|
&nilSlice,
|
||||||
|
selectedMarshalCase{[]byte{1,2,3}},
|
||||||
)
|
)
|
||||||
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
ptr: (*[]string)(nil),
|
ptr: (*[]string)(nil),
|
||||||
@ -13,5 +14,12 @@ func init() {
|
|||||||
}, unmarshalCase{
|
}, unmarshalCase{
|
||||||
ptr: (*[]string)(nil),
|
ptr: (*[]string)(nil),
|
||||||
input: "[]",
|
input: "[]",
|
||||||
|
}, unmarshalCase{
|
||||||
|
ptr: (*[]byte)(nil),
|
||||||
|
input: "[1,2,3]",
|
||||||
|
}, unmarshalCase{
|
||||||
|
ptr: (*[]byte)(nil),
|
||||||
|
input: `"aGVsbG8="`,
|
||||||
|
selected: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"testing"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"encoding/json"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/v2pro/plz/reflect2"
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type unmarshalCase struct {
|
type unmarshalCase struct {
|
||||||
obj func() interface{}
|
obj func() interface{}
|
||||||
ptr interface{}
|
ptr interface{}
|
||||||
input string
|
input string
|
||||||
selected bool
|
selected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ var marshalCases = []interface{}{
|
|||||||
nil,
|
nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
type selectedMarshalCase struct {
|
type selectedMarshalCase struct {
|
||||||
marshalCase interface{}
|
marshalCase interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,4 +77,4 @@ func Test_marshal(t *testing.T) {
|
|||||||
should.Equal(string(output1), string(output2))
|
should.Equal(string(output1), string(output2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user