diff --git a/feature_iter_object.go b/feature_iter_object.go index 887e070..ebd3da8 100644 --- a/feature_iter_object.go +++ b/feature_iter_object.go @@ -45,62 +45,63 @@ func (iter *Iterator) ReadObject() (ret string) { } } -func (iter *Iterator) readFieldHash() int32 { +// CaseInsensitive +func (iter *Iterator) readFieldHash() int64 { hash := int64(0x811c9dc5) c := iter.nextToken() - if c == '"' { - for { - for i := iter.head; i < iter.tail; i++ { - // require ascii string and no escape - b := iter.buf[i] - if !iter.cfg.objectFieldMustBeSimpleString && b == '\\' { - iter.head = i - for _, b := range iter.readStringSlowPath() { - if 'A' <= b && b <= 'Z' { - b += 'a' - 'A' - } - hash ^= int64(b) - hash *= 0x1000193 + if c != '"' { + iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) + return 0 + } + for { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + b := iter.buf[i] + if b == '\\' { + iter.head = i + for _, b := range iter.readStringSlowPath() { + if 'A' <= b && b <= 'Z' { + b += 'a' - 'A' } - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) - return 0 - } - return int32(hash) + hash ^= int64(b) + hash *= 0x1000193 } - if b == '"' { - iter.head = i + 1 - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) - return 0 - } - return int32(hash) + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 } - if 'A' <= b && b <= 'Z' { - b += 'a' - 'A' - } - hash ^= int64(b) - hash *= 0x1000193 + return hash } - if !iter.loadMore() { - iter.ReportError("readFieldHash", `incomplete field name`) - return 0 + if b == '"' { + iter.head = i + 1 + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash } + if 'A' <= b && b <= 'Z' { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + if !iter.loadMore() { + iter.ReportError("readFieldHash", `incomplete field name`) + return 0 } } - iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) - return 0 } -func calcHash(str string) int32 { +func calcHash(str string) int64 { hash := int64(0x811c9dc5) for _, b := range str { hash ^= int64(unicode.ToLower(b)) hash *= 0x1000193 } - return int32(hash) + return int64(hash) } // ReadObjectCB read object with callback, the key is ascii only and field name not copied diff --git a/feature_reflect_object.go b/feature_reflect_object.go index 0e801fb..65c8805 100644 --- a/feature_reflect_object.go +++ b/feature_reflect_object.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "reflect" - "strings" "unsafe" ) @@ -97,7 +96,7 @@ func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDeco } fields := map[string]*structFieldDecoder{} for k, binding := range bindings { - fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) + fields[k] = binding.Decoder.(*structFieldDecoder) } return createStructDecoder(cfg, typ, fields) } diff --git a/feature_reflect_struct_decoder.go b/feature_reflect_struct_decoder.go index 3336949..4d03b35 100644 --- a/feature_reflect_struct_decoder.go +++ b/feature_reflect_struct_decoder.go @@ -12,7 +12,7 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] if cfg.disallowUnknownFields { return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} } - knownHash := map[int32]struct{}{ + knownHash := map[int64]struct{}{ 0: {}, } switch len(fields) { @@ -29,8 +29,8 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} } case 2: - var fieldHash1 int32 - var fieldHash2 int32 + var fieldHash1 int64 + var fieldHash2 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder for fieldName, fieldDecoder := range fields { @@ -50,9 +50,9 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] } return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} case 3: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -79,10 +79,10 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName2, fieldDecoder2, fieldName3, fieldDecoder3} case 4: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -114,11 +114,11 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName3, fieldDecoder3, fieldName4, fieldDecoder4} case 5: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -155,12 +155,12 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName4, fieldDecoder4, fieldName5, fieldDecoder5} case 6: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -202,13 +202,13 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName5, fieldDecoder5, fieldName6, fieldDecoder6} case 7: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -255,14 +255,14 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName6, fieldDecoder6, fieldName7, fieldDecoder7} case 8: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 - var fieldName8 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -314,15 +314,15 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName7, fieldDecoder7, fieldName8, fieldDecoder8} case 9: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 - var fieldName8 int32 - var fieldName9 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -379,16 +379,16 @@ func createStructDecoder(cfg *frozenConfig, typ reflect.Type, fields map[string] fieldName8, fieldDecoder8, fieldName9, fieldDecoder9} case 10: - var fieldName1 int32 - var fieldName2 int32 - var fieldName3 int32 - var fieldName4 int32 - var fieldName5 int32 - var fieldName6 int32 - var fieldName7 int32 - var fieldName8 int32 - var fieldName9 int32 - var fieldName10 int32 + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldName10 int64 var fieldDecoder1 *structFieldDecoder var fieldDecoder2 *structFieldDecoder var fieldDecoder3 *structFieldDecoder @@ -463,52 +463,51 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) if !iter.readObjectStart() { return } - var fieldBytes []byte - var field string - if iter.cfg.objectFieldMustBeSimpleString { - fieldBytes = iter.readObjectFieldAsBytes() - field = *(*string)(unsafe.Pointer(&fieldBytes)) - } else { - field = iter.ReadString() - c := iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - } - fieldDecoder := decoder.fields[strings.ToLower(field)] - if fieldDecoder == nil { - if decoder.disallowUnknownFields { - iter.ReportError("ReadObject", "found unknown field: "+field) - iter.Skip() - return - } - iter.Skip() - } else { - fieldDecoder.Decode(ptr, iter) - } + decoder.decodeOneField(ptr, iter) for iter.nextToken() == ',' { - field = iter.ReadString() - c := iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - fieldDecoder = decoder.fields[strings.ToLower(field)] - if fieldDecoder == nil { - if decoder.disallowUnknownFields { - iter.ReportError("ReadObject", "found unknown field: "+field) - iter.Skip() - return - } - iter.Skip() - } else { - fieldDecoder.Decode(ptr, iter) - } + decoder.decodeOneField(ptr, iter) } if iter.Error != nil && iter.Error != io.EOF { iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) } } +func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { + var field string + var fieldDecoder *structFieldDecoder + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes := iter.ReadStringAsSlice() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } else { + field = iter.ReadString() + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } + if fieldDecoder == nil { + msg := "found unknown field: " + field + if decoder.disallowUnknownFields { + iter.ReportError("ReadObject", msg) + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + iter.Skip() + return + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + fieldDecoder.Decode(ptr, iter) +} + type skipObjectDecoder struct { typ reflect.Type } @@ -524,7 +523,7 @@ func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { type oneFieldStructDecoder struct { typ reflect.Type - fieldHash int32 + fieldHash int64 fieldDecoder *structFieldDecoder } @@ -549,9 +548,9 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) type twoFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder } @@ -579,11 +578,11 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator type threeFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder } @@ -613,13 +612,13 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat type fourFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder } @@ -651,15 +650,15 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato type fiveFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder } @@ -693,17 +692,17 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato type sixFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder } @@ -739,19 +738,19 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator type sevenFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder } @@ -789,21 +788,21 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat type eightFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder - fieldHash8 int32 + fieldHash8 int64 fieldDecoder8 *structFieldDecoder } @@ -843,23 +842,23 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat type nineFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder - fieldHash8 int32 + fieldHash8 int64 fieldDecoder8 *structFieldDecoder - fieldHash9 int32 + fieldHash9 int64 fieldDecoder9 *structFieldDecoder } @@ -901,25 +900,25 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato type tenFieldsStructDecoder struct { typ reflect.Type - fieldHash1 int32 + fieldHash1 int64 fieldDecoder1 *structFieldDecoder - fieldHash2 int32 + fieldHash2 int64 fieldDecoder2 *structFieldDecoder - fieldHash3 int32 + fieldHash3 int64 fieldDecoder3 *structFieldDecoder - fieldHash4 int32 + fieldHash4 int64 fieldDecoder4 *structFieldDecoder - fieldHash5 int32 + fieldHash5 int64 fieldDecoder5 *structFieldDecoder - fieldHash6 int32 + fieldHash6 int64 fieldDecoder6 *structFieldDecoder - fieldHash7 int32 + fieldHash7 int64 fieldDecoder7 *structFieldDecoder - fieldHash8 int32 + fieldHash8 int64 fieldDecoder8 *structFieldDecoder - fieldHash9 int32 + fieldHash9 int64 fieldDecoder9 *structFieldDecoder - fieldHash10 int32 + fieldHash10 int64 fieldDecoder10 *structFieldDecoder } diff --git a/type_tests/struct_field_case_test.go b/type_tests/struct_field_case_test.go index 8e912cc..567f290 100644 --- a/type_tests/struct_field_case_test.go +++ b/type_tests/struct_field_case_test.go @@ -1,12 +1,12 @@ package test func init() { - //testCases = append(testCases, - // (*struct { - // Upper bool `json:"M"` - // Lower bool `json:"m"` - // })(nil), - //) + testCases = append(testCases, + (*struct { + Upper bool `json:"M"` + Lower bool `json:"m"` + })(nil), + ) asymmetricTestCases = append(asymmetricTestCases, [][2]interface{}{ { (*struct {