Skip to content

Commit b92cf78

Browse files
author
Chao Xu
committed
Make case sensitivity optional. Fix
kubernetes/kubernetes#64612
1 parent 8744d7c commit b92cf78

File tree

5 files changed

+43
-19
lines changed

5 files changed

+43
-19
lines changed

Gopkg.lock

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package jsoniter
22

33
import (
44
"encoding/json"
5-
"github.com/modern-go/concurrent"
6-
"github.com/modern-go/reflect2"
75
"io"
86
"reflect"
97
"sync"
108
"unsafe"
9+
10+
"github.com/modern-go/concurrent"
11+
"github.com/modern-go/reflect2"
1112
)
1213

1314
// Config customize how the API should behave.
@@ -23,6 +24,7 @@ type Config struct {
2324
OnlyTaggedField bool
2425
ValidateJsonRawMessage bool
2526
ObjectFieldMustBeSimpleString bool
27+
CaseSensitive bool
2628
}
2729

2830
// API the public interface of this package.
@@ -75,6 +77,7 @@ type frozenConfig struct {
7577
extensions []Extension
7678
streamPool *sync.Pool
7779
iteratorPool *sync.Pool
80+
caseSensitive bool
7881
}
7982

8083
func (cfg *frozenConfig) initCache() {
@@ -128,6 +131,7 @@ func (cfg Config) Froze() API {
128131
objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
129132
onlyTaggedField: cfg.OnlyTaggedField,
130133
disallowUnknownFields: cfg.DisallowUnknownFields,
134+
caseSensitive: cfg.CaseSensitive,
131135
}
132136
api.streamPool = &sync.Pool{
133137
New: func() interface{} {

iter_object.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func (iter *Iterator) readFieldHash() int64 {
6060
if b == '\\' {
6161
iter.head = i
6262
for _, b := range iter.readStringSlowPath() {
63-
if 'A' <= b && b <= 'Z' {
63+
if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
6464
b += 'a' - 'A'
6565
}
6666
hash ^= int64(b)
@@ -82,7 +82,7 @@ func (iter *Iterator) readFieldHash() int64 {
8282
}
8383
return hash
8484
}
85-
if 'A' <= b && b <= 'Z' {
85+
if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
8686
b += 'a' - 'A'
8787
}
8888
hash ^= int64(b)
@@ -95,10 +95,14 @@ func (iter *Iterator) readFieldHash() int64 {
9595
}
9696
}
9797

98-
func calcHash(str string) int64 {
98+
func calcHash(str string, caseSensitive bool) int64 {
9999
hash := int64(0x811c9dc5)
100100
for _, b := range str {
101-
hash ^= int64(unicode.ToLower(b))
101+
if caseSensitive {
102+
hash ^= int64(b)
103+
} else {
104+
hash ^= int64(unicode.ToLower(b))
105+
}
102106
hash *= 0x1000193
103107
}
104108
return int64(hash)

reflect.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package jsoniter
22

33
import (
44
"fmt"
5-
"github.com/modern-go/reflect2"
65
"reflect"
76
"unsafe"
7+
8+
"github.com/modern-go/reflect2"
89
)
910

1011
// ValDecoder is an internal type registered to cache as needed.
@@ -40,6 +41,14 @@ type ctx struct {
4041
decoders map[reflect2.Type]ValDecoder
4142
}
4243

44+
func (b *ctx) caseSensitive() bool {
45+
if b.frozenConfig == nil {
46+
// default is case-insensitive
47+
return false
48+
}
49+
return b.frozenConfig.caseSensitive
50+
}
51+
4352
func (b *ctx) append(prefix string) *ctx {
4453
return &ctx{
4554
frozenConfig: b.frozenConfig,

reflect_struct_decoder.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package jsoniter
22

33
import (
44
"fmt"
5-
"github.com/modern-go/reflect2"
65
"io"
76
"strings"
87
"unsafe"
8+
9+
"github.com/modern-go/reflect2"
910
)
1011

1112
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
@@ -51,7 +52,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
5152
return &skipObjectDecoder{typ}
5253
case 1:
5354
for fieldName, fieldDecoder := range fields {
54-
fieldHash := calcHash(fieldName)
55+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
5556
_, known := knownHash[fieldHash]
5657
if known {
5758
return &generalStructDecoder{typ, fields, false}
@@ -65,7 +66,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
6566
var fieldDecoder1 *structFieldDecoder
6667
var fieldDecoder2 *structFieldDecoder
6768
for fieldName, fieldDecoder := range fields {
68-
fieldHash := calcHash(fieldName)
69+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
6970
_, known := knownHash[fieldHash]
7071
if known {
7172
return &generalStructDecoder{typ, fields, false}
@@ -88,7 +89,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
8889
var fieldDecoder2 *structFieldDecoder
8990
var fieldDecoder3 *structFieldDecoder
9091
for fieldName, fieldDecoder := range fields {
91-
fieldHash := calcHash(fieldName)
92+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
9293
_, known := knownHash[fieldHash]
9394
if known {
9495
return &generalStructDecoder{typ, fields, false}
@@ -119,7 +120,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
119120
var fieldDecoder3 *structFieldDecoder
120121
var fieldDecoder4 *structFieldDecoder
121122
for fieldName, fieldDecoder := range fields {
122-
fieldHash := calcHash(fieldName)
123+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
123124
_, known := knownHash[fieldHash]
124125
if known {
125126
return &generalStructDecoder{typ, fields, false}
@@ -156,7 +157,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
156157
var fieldDecoder4 *structFieldDecoder
157158
var fieldDecoder5 *structFieldDecoder
158159
for fieldName, fieldDecoder := range fields {
159-
fieldHash := calcHash(fieldName)
160+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
160161
_, known := knownHash[fieldHash]
161162
if known {
162163
return &generalStructDecoder{typ, fields, false}
@@ -199,7 +200,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
199200
var fieldDecoder5 *structFieldDecoder
200201
var fieldDecoder6 *structFieldDecoder
201202
for fieldName, fieldDecoder := range fields {
202-
fieldHash := calcHash(fieldName)
203+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
203204
_, known := knownHash[fieldHash]
204205
if known {
205206
return &generalStructDecoder{typ, fields, false}
@@ -248,7 +249,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
248249
var fieldDecoder6 *structFieldDecoder
249250
var fieldDecoder7 *structFieldDecoder
250251
for fieldName, fieldDecoder := range fields {
251-
fieldHash := calcHash(fieldName)
252+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
252253
_, known := knownHash[fieldHash]
253254
if known {
254255
return &generalStructDecoder{typ, fields, false}
@@ -303,7 +304,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
303304
var fieldDecoder7 *structFieldDecoder
304305
var fieldDecoder8 *structFieldDecoder
305306
for fieldName, fieldDecoder := range fields {
306-
fieldHash := calcHash(fieldName)
307+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
307308
_, known := knownHash[fieldHash]
308309
if known {
309310
return &generalStructDecoder{typ, fields, false}
@@ -364,7 +365,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
364365
var fieldDecoder8 *structFieldDecoder
365366
var fieldDecoder9 *structFieldDecoder
366367
for fieldName, fieldDecoder := range fields {
367-
fieldHash := calcHash(fieldName)
368+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
368369
_, known := knownHash[fieldHash]
369370
if known {
370371
return &generalStructDecoder{typ, fields, false}
@@ -431,7 +432,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
431432
var fieldDecoder9 *structFieldDecoder
432433
var fieldDecoder10 *structFieldDecoder
433434
for fieldName, fieldDecoder := range fields {
434-
fieldHash := calcHash(fieldName)
435+
fieldHash := calcHash(fieldName, ctx.caseSensitive())
435436
_, known := knownHash[fieldHash]
436437
if known {
437438
return &generalStructDecoder{typ, fields, false}

0 commit comments

Comments
 (0)