1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-20 11:28:49 +02:00

Make case sensitivity optional. Fix

https://github.com/kubernetes/kubernetes/issues/64612
This commit is contained in:
Chao Xu 2018-06-07 18:36:06 -07:00
parent 8744d7c5c7
commit b92cf78708
5 changed files with 43 additions and 19 deletions

8
Gopkg.lock generated
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

@ -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 {
@ -51,7 +52,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
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 +66,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 +89,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 +120,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 +157,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 +200,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 +249,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 +304,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 +365,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 +432,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}