vendor the latest json-iterator

This commit is contained in:
Chao Xu 2018-06-10 16:48:43 -07:00
parent 5aa8d690a1
commit dd69be30a5
16 changed files with 66 additions and 47 deletions

4
Godeps/Godeps.json generated
View File

@ -2029,8 +2029,8 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Comment": "1.1.3-16-g2ddf6d7", "Comment": "1.1.3-22-gf2b4162",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/jteeuwen/go-bindata", "ImportPath": "github.com/jteeuwen/go-bindata",

View File

@ -36,7 +36,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/modern-go/concurrent", "ImportPath": "github.com/modern-go/concurrent",

View File

@ -532,7 +532,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/mailru/easyjson/buffer", "ImportPath": "github.com/mailru/easyjson/buffer",

View File

@ -92,7 +92,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/modern-go/concurrent", "ImportPath": "github.com/modern-go/concurrent",

View File

@ -504,7 +504,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/mailru/easyjson/buffer", "ImportPath": "github.com/mailru/easyjson/buffer",

View File

@ -156,7 +156,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/modern-go/concurrent", "ImportPath": "github.com/modern-go/concurrent",

View File

@ -216,7 +216,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/mailru/easyjson/buffer", "ImportPath": "github.com/mailru/easyjson/buffer",

View File

@ -76,7 +76,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/modern-go/concurrent", "ImportPath": "github.com/modern-go/concurrent",

View File

@ -208,7 +208,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/mailru/easyjson/buffer", "ImportPath": "github.com/mailru/easyjson/buffer",

View File

@ -92,7 +92,7 @@
}, },
{ {
"ImportPath": "github.com/json-iterator/go", "ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" "Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
}, },
{ {
"ImportPath": "github.com/modern-go/concurrent", "ImportPath": "github.com/modern-go/concurrent",

View File

@ -1,6 +1,12 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/json-iterator/go"
packages = ["."]
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
version = "1.1.3"
[[projects]] [[projects]]
name = "github.com/modern-go/concurrent" name = "github.com/modern-go/concurrent"
packages = ["."] packages = ["."]
@ -16,6 +22,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "ac7003b5a981716353a43055ab7d4c5357403cb30a60de2dbdeb446c1544beaa" inputs-digest = "56a0b9e9e61d2bc8af5e1b68537401b7f4d60805eda3d107058f3171aa5cf793"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -2,12 +2,13 @@ package jsoniter
import ( import (
"encoding/json" "encoding/json"
"github.com/modern-go/concurrent"
"github.com/modern-go/reflect2"
"io" "io"
"reflect" "reflect"
"sync" "sync"
"unsafe" "unsafe"
"github.com/modern-go/concurrent"
"github.com/modern-go/reflect2"
) )
// Config customize how the API should behave. // Config customize how the API should behave.
@ -23,6 +24,7 @@ type Config struct {
OnlyTaggedField bool OnlyTaggedField bool
ValidateJsonRawMessage bool ValidateJsonRawMessage bool
ObjectFieldMustBeSimpleString bool ObjectFieldMustBeSimpleString bool
CaseSensitive bool
} }
// API the public interface of this package. // API the public interface of this package.
@ -75,6 +77,7 @@ type frozenConfig struct {
extensions []Extension extensions []Extension
streamPool *sync.Pool streamPool *sync.Pool
iteratorPool *sync.Pool iteratorPool *sync.Pool
caseSensitive bool
} }
func (cfg *frozenConfig) initCache() { func (cfg *frozenConfig) initCache() {
@ -128,6 +131,7 @@ func (cfg Config) Froze() API {
objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
onlyTaggedField: cfg.OnlyTaggedField, onlyTaggedField: cfg.OnlyTaggedField,
disallowUnknownFields: cfg.DisallowUnknownFields, disallowUnknownFields: cfg.DisallowUnknownFields,
caseSensitive: cfg.CaseSensitive,
} }
api.streamPool = &sync.Pool{ api.streamPool = &sync.Pool{
New: func() interface{} { New: func() interface{} {

View File

@ -60,7 +60,7 @@ func (iter *Iterator) readFieldHash() int64 {
if b == '\\' { if b == '\\' {
iter.head = i iter.head = i
for _, b := range iter.readStringSlowPath() { for _, b := range iter.readStringSlowPath() {
if 'A' <= b && b <= 'Z' { if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
b += 'a' - 'A' b += 'a' - 'A'
} }
hash ^= int64(b) hash ^= int64(b)
@ -82,7 +82,7 @@ func (iter *Iterator) readFieldHash() int64 {
} }
return hash return hash
} }
if 'A' <= b && b <= 'Z' { if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
b += 'a' - 'A' b += 'a' - 'A'
} }
hash ^= int64(b) hash ^= int64(b)
@ -95,10 +95,14 @@ func (iter *Iterator) readFieldHash() int64 {
} }
} }
func calcHash(str string) int64 { func calcHash(str string, caseSensitive bool) int64 {
hash := int64(0x811c9dc5) hash := int64(0x811c9dc5)
for _, b := range str { for _, b := range str {
hash ^= int64(unicode.ToLower(b)) if caseSensitive {
hash ^= int64(b)
} else {
hash ^= int64(unicode.ToLower(b))
}
hash *= 0x1000193 hash *= 0x1000193
} }
return int64(hash) return int64(hash)

View File

@ -2,9 +2,10 @@ package jsoniter
import ( import (
"fmt" "fmt"
"github.com/modern-go/reflect2"
"reflect" "reflect"
"unsafe" "unsafe"
"github.com/modern-go/reflect2"
) )
// ValDecoder is an internal type registered to cache as needed. // ValDecoder is an internal type registered to cache as needed.
@ -40,6 +41,14 @@ type ctx struct {
decoders map[reflect2.Type]ValDecoder decoders map[reflect2.Type]ValDecoder
} }
func (b *ctx) caseSensitive() bool {
if b.frozenConfig == nil {
// default is case-insensitive
return false
}
return b.frozenConfig.caseSensitive
}
func (b *ctx) append(prefix string) *ctx { func (b *ctx) append(prefix string) *ctx {
return &ctx{ return &ctx{
frozenConfig: b.frozenConfig, frozenConfig: b.frozenConfig,

View File

@ -1,7 +1,6 @@
package jsoniter package jsoniter
import ( import (
"bytes"
"encoding/base64" "encoding/base64"
"reflect" "reflect"
"strconv" "strconv"
@ -418,20 +417,11 @@ func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
} }
switch iter.WhatIsNext() { switch iter.WhatIsNext() {
case StringValue: case StringValue:
encoding := base64.StdEncoding src := iter.ReadString()
src := iter.SkipAndReturnBytes() dst, err := base64.StdEncoding.DecodeString(src)
// New line characters (\r and \n) are ignored.
// Refer to https://golang.org/pkg/encoding/base64/#Encoding.Decode
src = bytes.Replace(src, []byte(`\r`), []byte{}, -1)
src = bytes.Replace(src, []byte(`\n`), []byte{}, -1)
src = src[1 : len(src)-1]
decodedLen := encoding.DecodedLen(len(src))
dst := make([]byte, decodedLen)
len, err := encoding.Decode(dst, src)
if err != nil { if err != nil {
iter.ReportError("decode base64", err.Error()) iter.ReportError("decode base64", err.Error())
} else { } else {
dst = dst[:len]
codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst))
} }
case ArrayValue: case ArrayValue:

View File

@ -2,10 +2,11 @@ package jsoniter
import ( import (
"fmt" "fmt"
"github.com/modern-go/reflect2"
"io" "io"
"strings" "strings"
"unsafe" "unsafe"
"github.com/modern-go/reflect2"
) )
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
@ -31,11 +32,15 @@ func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
for k, binding := range bindings { for k, binding := range bindings {
fields[k] = binding.Decoder.(*structFieldDecoder) fields[k] = binding.Decoder.(*structFieldDecoder)
} }
for k, binding := range bindings {
if _, found := fields[strings.ToLower(k)]; !found { if !ctx.caseSensitive() {
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) for k, binding := range bindings {
if _, found := fields[strings.ToLower(k)]; !found {
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
}
} }
} }
return createStructDecoder(ctx, typ, fields) return createStructDecoder(ctx, typ, fields)
} }
@ -46,12 +51,13 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
knownHash := map[int64]struct{}{ knownHash := map[int64]struct{}{
0: {}, 0: {},
} }
switch len(fields) { switch len(fields) {
case 0: case 0:
return &skipObjectDecoder{typ} return &skipObjectDecoder{typ}
case 1: case 1:
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -65,7 +71,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder1 *structFieldDecoder var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder var fieldDecoder2 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -88,7 +94,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder2 *structFieldDecoder var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder var fieldDecoder3 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -119,7 +125,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder3 *structFieldDecoder var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder var fieldDecoder4 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -156,7 +162,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder4 *structFieldDecoder var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder var fieldDecoder5 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -199,7 +205,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder5 *structFieldDecoder var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder var fieldDecoder6 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -248,7 +254,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder6 *structFieldDecoder var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder var fieldDecoder7 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -303,7 +309,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder7 *structFieldDecoder var fieldDecoder7 *structFieldDecoder
var fieldDecoder8 *structFieldDecoder var fieldDecoder8 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -364,7 +370,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder8 *structFieldDecoder var fieldDecoder8 *structFieldDecoder
var fieldDecoder9 *structFieldDecoder var fieldDecoder9 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -431,7 +437,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder9 *structFieldDecoder var fieldDecoder9 *structFieldDecoder
var fieldDecoder10 *structFieldDecoder var fieldDecoder10 *structFieldDecoder
for fieldName, fieldDecoder := range fields { for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName) fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash] _, known := knownHash[fieldHash]
if known { if known {
return &generalStructDecoder{typ, fields, false} return &generalStructDecoder{typ, fields, false}
@ -513,13 +519,13 @@ func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *It
fieldBytes := iter.ReadStringAsSlice() fieldBytes := iter.ReadStringAsSlice()
field = *(*string)(unsafe.Pointer(&fieldBytes)) field = *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder = decoder.fields[field] fieldDecoder = decoder.fields[field]
if fieldDecoder == nil { if fieldDecoder == nil && !iter.cfg.caseSensitive {
fieldDecoder = decoder.fields[strings.ToLower(field)] fieldDecoder = decoder.fields[strings.ToLower(field)]
} }
} else { } else {
field = iter.ReadString() field = iter.ReadString()
fieldDecoder = decoder.fields[field] fieldDecoder = decoder.fields[field]
if fieldDecoder == nil { if fieldDecoder == nil && !iter.cfg.caseSensitive {
fieldDecoder = decoder.fields[strings.ToLower(field)] fieldDecoder = decoder.fields[strings.ToLower(field)]
} }
} }