diff --git a/vendor.conf b/vendor.conf index 3aa99ee0c..62a4e70ed 100644 --- a/vendor.conf +++ b/vendor.conf @@ -32,6 +32,7 @@ github.com/gregjones/httpcache 787624de3eb7bd915c329cba748687a3b22666a6 github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55 github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 +github.com/json-iterator/go 13f86432b882000a51c6e610c620974462691a97 github.com/juju/ratelimit 5b9ff866471762aa2ab2dced63c9fb6f53921342 github.com/mailru/easyjson d5b7844b561a7bc640052f1b935f7b800330d7e0 github.com/Microsoft/go-winio v0.4.4 diff --git a/vendor/github.com/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md index 23a4b57c8..3a0d68098 100644 --- a/vendor/github.com/json-iterator/go/README.md +++ b/vendor/github.com/json-iterator/go/README.md @@ -44,7 +44,9 @@ with ```go import "github.com/json-iterator/go" -jsoniter.Marshal(&data) + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Marshal(&data) ``` Replace @@ -58,7 +60,9 @@ with ```go import "github.com/json-iterator/go" -jsoniter.Unmarshal(input, &data) + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Unmarshal(input, &data) ``` [More documentation](http://jsoniter.com/migrate-from-go-std.html) @@ -76,5 +80,7 @@ Contributors * [thockin](https://github.com/thockin) * [mattn](https://github.com/mattn) * [cch123](https://github.com/cch123) +* [Oleg Shaldybin](https://github.com/olegshaldybin) +* [Jason Toffaletti](https://github.com/toffaletti) Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) diff --git a/vendor/github.com/json-iterator/go/feature_adapter.go b/vendor/github.com/json-iterator/go/feature_adapter.go index edb477c4f..0214b711a 100644 --- a/vendor/github.com/json-iterator/go/feature_adapter.go +++ b/vendor/github.com/json-iterator/go/feature_adapter.go @@ -110,6 +110,7 @@ type Encoder struct { // Encode encode interface{} as JSON to io.Writer func (adapter *Encoder) Encode(val interface{}) error { adapter.stream.WriteVal(val) + adapter.stream.WriteRaw("\n") adapter.stream.Flush() return adapter.stream.Error } @@ -125,3 +126,8 @@ func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { config.EscapeHTML = escapeHTML adapter.stream.cfg = config.Froze().(*frozenConfig) } + +// Valid reports whether data is a valid JSON encoding. +func Valid(data []byte) bool { + return ConfigDefault.Valid(data) +} diff --git a/vendor/github.com/json-iterator/go/feature_any.go b/vendor/github.com/json-iterator/go/feature_any.go index 6733dce4c..87716d1fc 100644 --- a/vendor/github.com/json-iterator/go/feature_any.go +++ b/vendor/github.com/json-iterator/go/feature_any.go @@ -1,6 +1,7 @@ package jsoniter import ( + "errors" "fmt" "io" "reflect" @@ -157,6 +158,8 @@ func (iter *Iterator) readAny() Any { return iter.readArrayAny() case '-': return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} default: return iter.readNumberAny(true) } diff --git a/vendor/github.com/json-iterator/go/feature_config.go b/vendor/github.com/json-iterator/go/feature_config.go index fc055d504..78a2ce1a5 100644 --- a/vendor/github.com/json-iterator/go/feature_config.go +++ b/vendor/github.com/json-iterator/go/feature_config.go @@ -12,23 +12,26 @@ import ( // Config customize how the API should behave. // The API is created from Config by Froze. type Config struct { - IndentionStep int - MarshalFloatWith6Digits bool - EscapeHTML bool - SortMapKeys bool - UseNumber bool - TagKey string + IndentionStep int + MarshalFloatWith6Digits bool + EscapeHTML bool + SortMapKeys bool + UseNumber bool + TagKey string + ValidateJsonRawMessage bool + ObjectFieldMustBeSimpleString bool } type frozenConfig struct { - configBeforeFrozen Config - sortMapKeys bool - indentionStep int - decoderCache unsafe.Pointer - encoderCache unsafe.Pointer - extensions []Extension - streamPool chan *Stream - iteratorPool chan *Iterator + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + decoderCache unsafe.Pointer + encoderCache unsafe.Pointer + extensions []Extension + streamPool chan *Stream + iteratorPool chan *Iterator } // API the public interface of this package. @@ -44,6 +47,8 @@ type API interface { Get(data []byte, path ...interface{}) Any NewEncoder(writer io.Writer) *Encoder NewDecoder(reader io.Reader) *Decoder + Valid(data []byte) bool + RegisterExtension(extension Extension) } // ConfigDefault the default API @@ -53,24 +58,27 @@ var ConfigDefault = Config{ // ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior var ConfigCompatibleWithStandardLibrary = Config{ - EscapeHTML: true, - SortMapKeys: true, + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, }.Froze() // ConfigFastest marshals float with only 6 digits precision var ConfigFastest = Config{ - EscapeHTML: false, - MarshalFloatWith6Digits: true, + EscapeHTML: false, + MarshalFloatWith6Digits: true, // will lose precession + ObjectFieldMustBeSimpleString: true, // do not unescape object field }.Froze() // Froze forge API from config func (cfg Config) Froze() API { // TODO: cache frozen config frozenConfig := &frozenConfig{ - sortMapKeys: cfg.SortMapKeys, - indentionStep: cfg.IndentionStep, - streamPool: make(chan *Stream, 16), - iteratorPool: make(chan *Iterator, 16), + sortMapKeys: cfg.SortMapKeys, + indentionStep: cfg.IndentionStep, + objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, + streamPool: make(chan *Stream, 16), + iteratorPool: make(chan *Iterator, 16), } atomic.StorePointer(&frozenConfig.decoderCache, unsafe.Pointer(&map[string]ValDecoder{})) atomic.StorePointer(&frozenConfig.encoderCache, unsafe.Pointer(&map[string]ValEncoder{})) @@ -83,10 +91,31 @@ func (cfg Config) Froze() API { if cfg.UseNumber { frozenConfig.useNumber() } + if cfg.ValidateJsonRawMessage { + frozenConfig.validateJsonRawMessage() + } frozenConfig.configBeforeFrozen = cfg return frozenConfig } +func (cfg *frozenConfig) validateJsonRawMessage() { + encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { + rawMessage := *(*json.RawMessage)(ptr) + iter := cfg.BorrowIterator([]byte(rawMessage)) + iter.Read() + if iter.Error != nil { + stream.WriteRaw("null") + } else { + cfg.ReturnIterator(iter) + stream.WriteRaw(string(rawMessage)) + } + }, func(ptr unsafe.Pointer) bool { + return false + }} + cfg.addEncoderToCache(reflect.TypeOf((*json.RawMessage)(nil)).Elem(), encoder) + cfg.addEncoderToCache(reflect.TypeOf((*RawMessage)(nil)).Elem(), encoder) +} + func (cfg *frozenConfig) useNumber() { cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { if iter.WhatIsNext() == NumberValue { @@ -104,7 +133,7 @@ func (cfg *frozenConfig) getTagKey() string { return tagKey } -func (cfg *frozenConfig) registerExtension(extension Extension) { +func (cfg *frozenConfig) RegisterExtension(extension Extension) { cfg.extensions = append(cfg.extensions, extension) } @@ -310,3 +339,10 @@ func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { iter := Parse(cfg, reader, 512) return &Decoder{iter} } + +func (cfg *frozenConfig) Valid(data []byte) bool { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.Skip() + return iter.Error == nil +} diff --git a/vendor/github.com/json-iterator/go/feature_iter.go b/vendor/github.com/json-iterator/go/feature_iter.go index 4357d69ba..95ae54fbf 100644 --- a/vendor/github.com/json-iterator/go/feature_iter.go +++ b/vendor/github.com/json-iterator/go/feature_iter.go @@ -77,6 +77,7 @@ type Iterator struct { captureStartedAt int captured []byte Error error + Attachment interface{} // open for customized decoder } // NewIterator creates an empty Iterator instance @@ -167,7 +168,7 @@ func (iter *Iterator) isObjectEnd() bool { if c == '}' { return true } - iter.ReportError("isObjectEnd", "object ended prematurely") + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) return true } @@ -200,8 +201,22 @@ func (iter *Iterator) ReportError(operation string, msg string) { if peekStart < 0 { peekStart = 0 } - iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head, - string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) + peekEnd := iter.head + 10 + if peekEnd > iter.tail { + peekEnd = iter.tail + } + parsing := string(iter.buf[peekStart:peekEnd]) + contextStart := iter.head - 50 + if contextStart < 0 { + contextStart = 0 + } + contextEnd := iter.head + 50 + if contextEnd > iter.tail { + contextEnd = iter.tail + } + context := string(iter.buf[contextStart:contextEnd]) + iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", + operation, msg, iter.head-peekStart, parsing, context) } // CurrentBuffer gets current buffer as string for debugging purpose @@ -210,7 +225,7 @@ func (iter *Iterator) CurrentBuffer() string { if peekStart < 0 { peekStart = 0 } - return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head, + return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) } diff --git a/vendor/github.com/json-iterator/go/feature_iter_array.go b/vendor/github.com/json-iterator/go/feature_iter_array.go index cbc3ec8d1..6188cb457 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_array.go +++ b/vendor/github.com/json-iterator/go/feature_iter_array.go @@ -19,7 +19,7 @@ func (iter *Iterator) ReadArray() (ret bool) { case ',': return true default: - iter.ReportError("ReadArray", "expect [ or , or ] or n, but found: "+string([]byte{c})) + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) return } } @@ -42,7 +42,7 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { c = iter.nextToken() } if c != ']' { - iter.ReportError("ReadArrayCB", "expect ] in the end") + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) return false } return true @@ -53,6 +53,6 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { iter.skipThreeBytes('u', 'l', 'l') return true // null } - iter.ReportError("ReadArrayCB", "expect [ or n, but found: "+string([]byte{c})) + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) return false } diff --git a/vendor/github.com/json-iterator/go/feature_iter_int.go b/vendor/github.com/json-iterator/go/feature_iter_int.go index 886879efd..4781c6393 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_int.go +++ b/vendor/github.com/json-iterator/go/feature_iter_int.go @@ -115,6 +115,7 @@ func (iter *Iterator) ReadUint32() (ret uint32) { func (iter *Iterator) readUint32(c byte) (ret uint32) { ind := intDigits[c] if ind == 0 { + iter.assertInteger() return 0 // single zero } if ind == invalidCharForNumber { @@ -127,12 +128,14 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { ind2 := intDigits[iter.buf[i]] if ind2 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value } i++ ind3 := intDigits[iter.buf[i]] if ind3 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value*10 + uint32(ind2) } //iter.head = i + 1 @@ -141,30 +144,35 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { ind4 := intDigits[iter.buf[i]] if ind4 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value*100 + uint32(ind2)*10 + uint32(ind3) } i++ ind5 := intDigits[iter.buf[i]] if ind5 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) } i++ ind6 := intDigits[iter.buf[i]] if ind6 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) } i++ ind7 := intDigits[iter.buf[i]] if ind7 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) } i++ ind8 := intDigits[iter.buf[i]] if ind8 == invalidCharForNumber { iter.head = i + iter.assertInteger() return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) } i++ @@ -172,6 +180,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) iter.head = i if ind9 == invalidCharForNumber { + iter.assertInteger() return value } } @@ -180,6 +189,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { ind = intDigits[iter.buf[i]] if ind == invalidCharForNumber { iter.head = i + iter.assertInteger() return value } if value > uint32SafeToMultiply10 { @@ -194,6 +204,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { value = (value << 3) + (value << 1) + uint32(ind) } if !iter.loadMore() { + iter.assertInteger() return value } } @@ -226,6 +237,7 @@ func (iter *Iterator) ReadUint64() uint64 { func (iter *Iterator) readUint64(c byte) (ret uint64) { ind := intDigits[c] if ind == 0 { + iter.assertInteger() return 0 // single zero } if ind == invalidCharForNumber { @@ -233,11 +245,73 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) { return } value := uint64(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint64(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint64(ind2)*10 + uint64(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } for { for i := iter.head; i < iter.tail; i++ { ind = intDigits[iter.buf[i]] if ind == invalidCharForNumber { iter.head = i + iter.assertInteger() return value } if value > uint64SafeToMultiple10 { @@ -252,7 +326,14 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) { value = (value << 3) + (value << 1) + uint64(ind) } if !iter.loadMore() { + iter.assertInteger() return value } } } + +func (iter *Iterator) assertInteger() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("assertInteger", "can not decode float as int") + } +} diff --git a/vendor/github.com/json-iterator/go/feature_iter_object.go b/vendor/github.com/json-iterator/go/feature_iter_object.go index 3bdb5576e..dfd91fa60 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_object.go +++ b/vendor/github.com/json-iterator/go/feature_iter_object.go @@ -19,15 +19,33 @@ func (iter *Iterator) ReadObject() (ret string) { c = iter.nextToken() if c == '"' { iter.unreadByte() - return string(iter.readObjectFieldAsBytes()) + if iter.cfg.objectFieldMustBeSimpleString { + return string(iter.readObjectFieldAsBytes()) + } else { + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } } if c == '}' { return "" // end of object } - iter.ReportError("ReadObject", `expect " after {`) + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) return case ',': - return string(iter.readObjectFieldAsBytes()) + if iter.cfg.objectFieldMustBeSimpleString { + return string(iter.readObjectFieldAsBytes()) + } else { + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } case '}': return "" // end of object default: @@ -44,17 +62,34 @@ func (iter *Iterator) readFieldHash() int32 { for i := iter.head; i < iter.tail; i++ { // require ascii string and no escape b := iter.buf[i] - if 'A' <= b && b <= 'Z' { - b += 'a' - 'A' + 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 + } + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return int32(hash) } 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) } + if 'A' <= b && b <= 'Z' { + b += 'a' - 'A' + } hash ^= int64(b) hash *= 0x1000193 } @@ -80,18 +115,38 @@ func calcHash(str string) int32 { // ReadObjectCB read object with callback, the key is ascii only and field name not copied func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { c := iter.nextToken() + var fieldBytes []byte + var field string if c == '{' { c = iter.nextToken() if c == '"' { iter.unreadByte() - field := iter.readObjectFieldAsBytes() - if !callback(iter, *(*string)(unsafe.Pointer(&field))) { + 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})) + } + } + if !callback(iter, field) { return false } c = iter.nextToken() for c == ',' { - field = iter.readObjectFieldAsBytes() - if !callback(iter, *(*string)(unsafe.Pointer(&field))) { + 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})) + } + } + if !callback(iter, field) { return false } c = iter.nextToken() @@ -105,14 +160,14 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { if c == '}' { return true } - iter.ReportError("ReadObjectCB", `expect " after }`) + iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) return false } if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return true // null } - iter.ReportError("ReadObjectCB", `expect { or n`) + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) return false } @@ -125,7 +180,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { iter.unreadByte() field := iter.ReadString() if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field") + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) return false } if !callback(iter, field) { @@ -135,7 +190,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { for c == ',' { field = iter.ReadString() if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field") + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) return false } if !callback(iter, field) { @@ -152,14 +207,14 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { if c == '}' { return true } - iter.ReportError("ReadMapCB", `expect " after }`) + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) return false } if c == 'n' { iter.skipThreeBytes('u', 'l', 'l') return true // null } - iter.ReportError("ReadMapCB", `expect { or n`) + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) return false } @@ -176,7 +231,7 @@ func (iter *Iterator) readObjectStart() bool { iter.skipThreeBytes('u', 'l', 'l') return false } - iter.ReportError("readObjectStart", "expect { or n") + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) return false } @@ -192,7 +247,7 @@ func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { } } if iter.buf[iter.head] != ':' { - iter.ReportError("readObjectFieldAsBytes", "expect : after object field") + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) return } iter.head++ diff --git a/vendor/github.com/json-iterator/go/feature_iter_skip.go b/vendor/github.com/json-iterator/go/feature_iter_skip.go index b008d98c9..f58beb913 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_skip.go +++ b/vendor/github.com/json-iterator/go/feature_iter_skip.go @@ -25,7 +25,7 @@ func (iter *Iterator) ReadBool() (ret bool) { iter.skipFourBytes('a', 'l', 's', 'e') return false } - iter.ReportError("ReadBool", "expect t or f") + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) return } @@ -59,7 +59,9 @@ func (iter *Iterator) stopCapture() []byte { iter.captureStartedAt = -1 iter.captured = nil if len(captured) == 0 { - return remaining + copied := make([]byte, len(remaining)) + copy(copied, remaining) + return copied } captured = append(captured, remaining...) return captured diff --git a/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go index 047d58a4b..8fcdc3b69 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go +++ b/vendor/github.com/json-iterator/go/feature_iter_skip_sloppy.go @@ -1,4 +1,4 @@ -//+build jsoniter-sloppy +//+build jsoniter_sloppy package jsoniter diff --git a/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go b/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go index d26763825..f67bc2e83 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go +++ b/vendor/github.com/json-iterator/go/feature_iter_skip_strict.go @@ -1,4 +1,4 @@ -//+build !jsoniter-sloppy +//+build !jsoniter_sloppy package jsoniter @@ -64,7 +64,7 @@ func (iter *Iterator) trySkipString() bool { } else if c == '\\' { return false } else if c < ' ' { - iter.ReportError("ReadString", + iter.ReportError("trySkipString", fmt.Sprintf(`invalid control character found: %d`, c)) return true // already failed } diff --git a/vendor/github.com/json-iterator/go/feature_iter_string.go b/vendor/github.com/json-iterator/go/feature_iter_string.go index b76460046..adc487ea8 100644 --- a/vendor/github.com/json-iterator/go/feature_iter_string.go +++ b/vendor/github.com/json-iterator/go/feature_iter_string.go @@ -28,7 +28,7 @@ func (iter *Iterator) ReadString() (ret string) { iter.skipThreeBytes('u', 'l', 'l') return "" } - iter.ReportError("ReadString", `expects " or n`) + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) return } @@ -47,7 +47,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) { str = append(str, c) } } - iter.ReportError("ReadString", "unexpected end of input") + iter.ReportError("readStringSlowPath", "unexpected end of input") return } @@ -104,7 +104,7 @@ func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { case 't': str = append(str, '\t') default: - iter.ReportError("ReadString", + iter.ReportError("readEscapedChar", `invalid escape char after \`) return nil } @@ -139,7 +139,7 @@ func (iter *Iterator) ReadStringAsSlice() (ret []byte) { } return copied } - iter.ReportError("ReadString", `expects " or n`) + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) return } @@ -156,7 +156,7 @@ func (iter *Iterator) readU4() (ret rune) { } else if c >= 'A' && c <= 'F' { ret = ret*16 + rune(c-'A'+10) } else { - iter.ReportError("readU4", "expects 0~9 or a~f") + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) return } } diff --git a/vendor/github.com/json-iterator/go/feature_json_number.go b/vendor/github.com/json-iterator/go/feature_json_number.go index 0439f6725..e187b200a 100644 --- a/vendor/github.com/json-iterator/go/feature_json_number.go +++ b/vendor/github.com/json-iterator/go/feature_json_number.go @@ -1,9 +1,25 @@ package jsoniter -import "encoding/json" +import ( + "encoding/json" + "strconv" +) type Number string +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + func CastJsonNumber(val interface{}) (string, bool) { switch typedVal := val.(type) { case json.Number: diff --git a/vendor/github.com/json-iterator/go/feature_pool.go b/vendor/github.com/json-iterator/go/feature_pool.go index 73962bc6f..52d38e685 100644 --- a/vendor/github.com/json-iterator/go/feature_pool.go +++ b/vendor/github.com/json-iterator/go/feature_pool.go @@ -28,6 +28,7 @@ func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { func (cfg *frozenConfig) ReturnStream(stream *Stream) { stream.Error = nil + stream.Attachment = nil select { case cfg.streamPool <- stream: return @@ -48,6 +49,7 @@ func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { iter.Error = nil + iter.Attachment = nil select { case cfg.iteratorPool <- iter: return diff --git a/vendor/github.com/json-iterator/go/feature_reflect.go b/vendor/github.com/json-iterator/go/feature_reflect.go index 05d91b49c..bed7764ed 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect.go +++ b/vendor/github.com/json-iterator/go/feature_reflect.go @@ -72,24 +72,24 @@ func init() { textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() } -type optionalDecoder struct { - valueType reflect.Type - valueDecoder ValDecoder +type OptionalDecoder struct { + ValueType reflect.Type + ValueDecoder ValDecoder } -func (decoder *optionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { +func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { if iter.ReadNil() { *((*unsafe.Pointer)(ptr)) = nil } else { if *((*unsafe.Pointer)(ptr)) == nil { //pointer to null, we have to allocate memory to hold the value - value := reflect.New(decoder.valueType) + value := reflect.New(decoder.ValueType) newPtr := extractInterface(value.Interface()).word - decoder.valueDecoder.Decode(newPtr, iter) + decoder.ValueDecoder.Decode(newPtr, iter) *((*uintptr)(ptr)) = uintptr(newPtr) } else { //reuse existing instance - decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) } } } @@ -113,11 +113,31 @@ func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { } } -type optionalEncoder struct { +type OptionalEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *OptionalEncoder) EncodeInterface(val interface{}, stream *Stream) { + WriteToStream(val, stream, encoder) +} + +func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*unsafe.Pointer)(ptr)) == nil +} + +type optionalMapEncoder struct { valueEncoder ValEncoder } -func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { +func (encoder *optionalMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { if *((*unsafe.Pointer)(ptr)) == nil { stream.WriteNil() } else { @@ -125,15 +145,13 @@ func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { } } -func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) { +func (encoder *optionalMapEncoder) EncodeInterface(val interface{}, stream *Stream) { WriteToStream(val, stream, encoder) } -func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { - if *((*unsafe.Pointer)(ptr)) == nil { - return true - } - return false +func (encoder *optionalMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + p := *((*unsafe.Pointer)(ptr)) + return p == nil || encoder.valueEncoder.IsEmpty(p) } type placeholderEncoder struct { @@ -146,7 +164,7 @@ func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + encoder.getRealEncoder().EncodeInterface(val, stream) } func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { @@ -154,11 +172,11 @@ func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { } func (encoder *placeholderEncoder) getRealEncoder() ValEncoder { - for i := 0; i < 30; i++ { + for i := 0; i < 500; i++ { realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey) _, isPlaceholder := realDecoder.(*placeholderEncoder) if isPlaceholder { - time.Sleep(time.Second) + time.Sleep(10 * time.Millisecond) } else { return realDecoder } @@ -172,11 +190,11 @@ type placeholderDecoder struct { } func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - for i := 0; i < 30; i++ { + for i := 0; i < 500; i++ { realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey) _, isPlaceholder := realDecoder.(*placeholderDecoder) if isPlaceholder { - time.Sleep(time.Second) + time.Sleep(10 * time.Millisecond) } else { realDecoder.Decode(ptr, iter) return @@ -256,7 +274,7 @@ func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { if decoder != nil { return decoder, nil } - decoder = getTypeDecoderFromExtension(typ) + decoder = getTypeDecoderFromExtension(cfg, typ) if decoder != nil { cfg.addDecoderToCache(cacheKey, decoder) return decoder, nil @@ -267,6 +285,9 @@ func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) { for _, extension := range extensions { decoder = extension.DecorateDecoder(typ, decoder) } + for _, extension := range cfg.extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } cfg.addDecoderToCache(cacheKey, decoder) return decoder, err } @@ -289,7 +310,7 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error templateInterface := reflect.New(typ).Elem().Interface() var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} if typ.Kind() == reflect.Ptr { - decoder = &optionalDecoder{typ.Elem(), decoder} + decoder = &OptionalDecoder{typ.Elem(), decoder} } return decoder, nil } @@ -302,7 +323,7 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error templateInterface := reflect.New(typ).Elem().Interface() var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} if typ.Kind() == reflect.Ptr { - decoder = &optionalDecoder{typ.Elem(), decoder} + decoder = &OptionalDecoder{typ.Elem(), decoder} } return decoder, nil } @@ -423,7 +444,7 @@ func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { if encoder != nil { return encoder, nil } - encoder = getTypeEncoderFromExtension(typ) + encoder = getTypeEncoderFromExtension(cfg, typ) if encoder != nil { cfg.addEncoderToCache(cacheKey, encoder) return encoder, nil @@ -434,6 +455,9 @@ func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { for _, extension := range extensions { encoder = extension.DecorateEncoder(typ, encoder) } + for _, extension := range cfg.extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } cfg.addEncoderToCache(cacheKey, encoder) return encoder, err } @@ -452,7 +476,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error return &jsoniterNumberCodec{}, nil } if typ.Implements(marshalerType) { - checkIsEmpty, err := createCheckIsEmpty(typ) + checkIsEmpty, err := createCheckIsEmpty(cfg, typ) if err != nil { return nil, err } @@ -462,12 +486,24 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error checkIsEmpty: checkIsEmpty, } if typ.Kind() == reflect.Ptr { - encoder = &optionalEncoder{encoder} + encoder = &OptionalEncoder{encoder} + } + return encoder, nil + } + if reflect.PtrTo(typ).Implements(marshalerType) { + checkIsEmpty, err := createCheckIsEmpty(cfg, reflect.PtrTo(typ)) + if err != nil { + return nil, err + } + templateInterface := reflect.New(typ).Interface() + var encoder ValEncoder = &marshalerEncoder{ + templateInterface: extractInterface(templateInterface), + checkIsEmpty: checkIsEmpty, } return encoder, nil } if typ.Implements(textMarshalerType) { - checkIsEmpty, err := createCheckIsEmpty(typ) + checkIsEmpty, err := createCheckIsEmpty(cfg, typ) if err != nil { return nil, err } @@ -477,7 +513,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error checkIsEmpty: checkIsEmpty, } if typ.Kind() == reflect.Ptr { - encoder = &optionalEncoder{encoder} + encoder = &OptionalEncoder{encoder} } return encoder, nil } @@ -490,7 +526,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error return createEncoderOfSimpleType(cfg, typ) } -func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { +func createCheckIsEmpty(cfg *frozenConfig, typ reflect.Type) (checkIsEmpty, error) { kind := typ.Kind() switch kind { case reflect.String: @@ -535,9 +571,9 @@ func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { case reflect.Slice: return &sliceEncoder{}, nil case reflect.Map: - return &mapEncoder{}, nil + return encoderOfMap(cfg, typ) case reflect.Ptr: - return &optionalEncoder{}, nil + return &OptionalEncoder{}, nil default: return nil, fmt.Errorf("unsupported type: %v", typ) } @@ -648,7 +684,7 @@ func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) if err != nil { return nil, err } - return &optionalDecoder{elemType, decoder}, nil + return &OptionalDecoder{elemType, decoder}, nil } func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { @@ -657,9 +693,9 @@ func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) if err != nil { return nil, err } - encoder := &optionalEncoder{elemEncoder} + encoder := &OptionalEncoder{elemEncoder} if elemType.Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} + encoder = &OptionalEncoder{encoder} } return encoder, nil } diff --git a/vendor/github.com/json-iterator/go/feature_reflect_array.go b/vendor/github.com/json-iterator/go/feature_reflect_array.go index e23f187b7..d661fb6fe 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_array.go +++ b/vendor/github.com/json-iterator/go/feature_reflect_array.go @@ -21,7 +21,7 @@ func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { return nil, err } if typ.Elem().Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} + encoder = &OptionalEncoder{encoder} } return &arrayEncoder{typ, typ.Elem(), encoder}, nil } diff --git a/vendor/github.com/json-iterator/go/feature_reflect_extension.go b/vendor/github.com/json-iterator/go/feature_reflect_extension.go index 3dd38299d..c129076bc 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_extension.go +++ b/vendor/github.com/json-iterator/go/feature_reflect_extension.go @@ -161,22 +161,31 @@ func RegisterExtension(extension Extension) { extensions = append(extensions, extension) } -func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { - decoder := _getTypeDecoderFromExtension(typ) +func getTypeDecoderFromExtension(cfg *frozenConfig, typ reflect.Type) ValDecoder { + decoder := _getTypeDecoderFromExtension(cfg, typ) if decoder != nil { for _, extension := range extensions { decoder = extension.DecorateDecoder(typ, decoder) } + for _, extension := range cfg.extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } } return decoder } -func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { +func _getTypeDecoderFromExtension(cfg *frozenConfig, typ reflect.Type) ValDecoder { for _, extension := range extensions { decoder := extension.CreateDecoder(typ) if decoder != nil { return decoder } } + for _, extension := range cfg.extensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } typeName := typ.String() decoder := typeDecoders[typeName] if decoder != nil { @@ -185,29 +194,38 @@ func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder { if typ.Kind() == reflect.Ptr { decoder := typeDecoders[typ.Elem().String()] if decoder != nil { - return &optionalDecoder{typ.Elem(), decoder} + return &OptionalDecoder{typ.Elem(), decoder} } } return nil } -func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { - encoder := _getTypeEncoderFromExtension(typ) +func getTypeEncoderFromExtension(cfg *frozenConfig, typ reflect.Type) ValEncoder { + encoder := _getTypeEncoderFromExtension(cfg, typ) if encoder != nil { for _, extension := range extensions { encoder = extension.DecorateEncoder(typ, encoder) } + for _, extension := range cfg.extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } } return encoder } -func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { +func _getTypeEncoderFromExtension(cfg *frozenConfig, typ reflect.Type) ValEncoder { for _, extension := range extensions { encoder := extension.CreateEncoder(typ) if encoder != nil { return encoder } } + for _, extension := range cfg.extensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } typeName := typ.String() encoder := typeEncoders[typeName] if encoder != nil { @@ -216,7 +234,7 @@ func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder { if typ.Kind() == reflect.Ptr { encoder := typeEncoders[typ.Elem().String()] if encoder != nil { - return &optionalEncoder{encoder} + return &OptionalEncoder{encoder} } } return nil @@ -254,7 +272,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err for _, binding := range structDescriptor.Fields { binding.levels = append([]int{i}, binding.levels...) omitempty := binding.Encoder.(*structFieldEncoder).omitempty - binding.Encoder = &optionalEncoder{binding.Encoder} + binding.Encoder = &OptionalEncoder{binding.Encoder} binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty} binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder} binding.Decoder = &structFieldDecoder{&field, binding.Decoder} @@ -269,7 +287,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err if decoder == nil { var err error decoder, err = decoderOfType(cfg, field.Type) - if err != nil { + if len(fieldNames) > 0 && err != nil { return nil, err } } @@ -277,12 +295,13 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err if encoder == nil { var err error encoder, err = encoderOfType(cfg, field.Type) - if err != nil { + if len(fieldNames) > 0 && err != nil { return nil, err } - // map is stored as pointer in the struct - if field.Type.Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} + // map is stored as pointer in the struct, + // and treat nil or empty map as empty field + if encoder != nil && field.Type.Kind() == reflect.Map { + encoder = &optionalMapEncoder{encoder} } } binding := &Binding{ @@ -323,6 +342,9 @@ func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Bin for _, extension := range extensions { extension.UpdateStructDescriptor(structDescriptor) } + for _, extension := range cfg.extensions { + extension.UpdateStructDescriptor(structDescriptor) + } processTags(structDescriptor, cfg) // merge normal & embedded bindings & sort with original order allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) diff --git a/vendor/github.com/json-iterator/go/feature_reflect_native.go b/vendor/github.com/json-iterator/go/feature_reflect_native.go index b37dab3d8..95bd1e87c 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_native.go +++ b/vendor/github.com/json-iterator/go/feature_reflect_native.go @@ -4,6 +4,7 @@ import ( "encoding" "encoding/base64" "encoding/json" + "reflect" "unsafe" ) @@ -31,7 +32,9 @@ type intCodec struct { } func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int)(ptr)) = iter.ReadInt() + if !iter.ReadNil() { + *((*int)(ptr)) = iter.ReadInt() + } } func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -50,7 +53,9 @@ type uintptrCodec struct { } func (codec *uintptrCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uintptr)(ptr)) = uintptr(iter.ReadUint64()) + if !iter.ReadNil() { + *((*uintptr)(ptr)) = uintptr(iter.ReadUint64()) + } } func (codec *uintptrCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -69,7 +74,9 @@ type int8Codec struct { } func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int8)(ptr)) = iter.ReadInt8() + if !iter.ReadNil() { + *((*int8)(ptr)) = iter.ReadInt8() + } } func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -88,7 +95,9 @@ type int16Codec struct { } func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int16)(ptr)) = iter.ReadInt16() + if !iter.ReadNil() { + *((*int16)(ptr)) = iter.ReadInt16() + } } func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -107,7 +116,9 @@ type int32Codec struct { } func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int32)(ptr)) = iter.ReadInt32() + if !iter.ReadNil() { + *((*int32)(ptr)) = iter.ReadInt32() + } } func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -126,7 +137,9 @@ type int64Codec struct { } func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*int64)(ptr)) = iter.ReadInt64() + if !iter.ReadNil() { + *((*int64)(ptr)) = iter.ReadInt64() + } } func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -145,7 +158,10 @@ type uintCodec struct { } func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint)(ptr)) = iter.ReadUint() + if !iter.ReadNil() { + *((*uint)(ptr)) = iter.ReadUint() + return + } } func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -164,7 +180,9 @@ type uint8Codec struct { } func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint8)(ptr)) = iter.ReadUint8() + if !iter.ReadNil() { + *((*uint8)(ptr)) = iter.ReadUint8() + } } func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -183,7 +201,9 @@ type uint16Codec struct { } func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint16)(ptr)) = iter.ReadUint16() + if !iter.ReadNil() { + *((*uint16)(ptr)) = iter.ReadUint16() + } } func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -202,7 +222,9 @@ type uint32Codec struct { } func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint32)(ptr)) = iter.ReadUint32() + if !iter.ReadNil() { + *((*uint32)(ptr)) = iter.ReadUint32() + } } func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -221,7 +243,9 @@ type uint64Codec struct { } func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*uint64)(ptr)) = iter.ReadUint64() + if !iter.ReadNil() { + *((*uint64)(ptr)) = iter.ReadUint64() + } } func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -240,7 +264,9 @@ type float32Codec struct { } func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*float32)(ptr)) = iter.ReadFloat32() + if !iter.ReadNil() { + *((*float32)(ptr)) = iter.ReadFloat32() + } } func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -259,7 +285,9 @@ type float64Codec struct { } func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*float64)(ptr)) = iter.ReadFloat64() + if !iter.ReadNil() { + *((*float64)(ptr)) = iter.ReadFloat64() + } } func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -278,7 +306,9 @@ type boolCodec struct { } func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*bool)(ptr)) = iter.ReadBool() + if !iter.ReadNil() { + *((*bool)(ptr)) = iter.ReadBool() + } } func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -297,7 +327,42 @@ type emptyInterfaceCodec struct { } func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*interface{})(ptr)) = iter.Read() + existing := *((*interface{})(ptr)) + + // Checking for both typed and untyped nil pointers. + if existing != nil && + reflect.TypeOf(existing).Kind() == reflect.Ptr && + !reflect.ValueOf(existing).IsNil() { + + var ptrToExisting interface{} + for { + elem := reflect.ValueOf(existing).Elem() + if elem.Kind() != reflect.Ptr || elem.IsNil() { + break + } + ptrToExisting = existing + existing = elem.Interface() + } + + if iter.ReadNil() { + if ptrToExisting != nil { + nilPtr := reflect.Zero(reflect.TypeOf(ptrToExisting).Elem()) + reflect.ValueOf(ptrToExisting).Elem().Set(nilPtr) + } else { + *((*interface{})(ptr)) = nil + } + } else { + iter.ReadVal(existing) + } + + return + } + + if iter.ReadNil() { + *((*interface{})(ptr)) = nil + } else { + *((*interface{})(ptr)) = iter.Read() + } } func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -309,7 +374,8 @@ func (codec *emptyInterfaceCodec) EncodeInterface(val interface{}, stream *Strea } func (codec *emptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool { - return ptr == nil + emptyInterface := (*emptyInterface)(ptr) + return emptyInterface.typ == nil } type nonEmptyInterfaceCodec struct { @@ -326,15 +392,20 @@ func (codec *nonEmptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) e.typ = nonEmptyInterface.itab.typ e.word = nonEmptyInterface.word iter.ReadVal(&i) + if e.word == nil { + nonEmptyInterface.itab = nil + } nonEmptyInterface.word = e.word } func (codec *nonEmptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) { nonEmptyInterface := (*nonEmptyInterface)(ptr) var i interface{} - e := (*emptyInterface)(unsafe.Pointer(&i)) - e.typ = nonEmptyInterface.itab.typ - e.word = nonEmptyInterface.word + if nonEmptyInterface.itab != nil { + e := (*emptyInterface)(unsafe.Pointer(&i)) + e.typ = nonEmptyInterface.itab.typ + e.word = nonEmptyInterface.word + } stream.WriteVal(i) } @@ -370,7 +441,15 @@ type jsonNumberCodec struct { } func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + switch iter.WhatIsNext() { + case StringValue: + *((*json.Number)(ptr)) = json.Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*json.Number)(ptr)) = "" + default: + *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + } } func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -389,7 +468,15 @@ type jsoniterNumberCodec struct { } func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + switch iter.WhatIsNext() { + case StringValue: + *((*Number)(ptr)) = Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*Number)(ptr)) = "" + default: + *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + } } func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -521,7 +608,7 @@ type stringModeNumberDecoder struct { func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { c := iter.nextToken() if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect "`) + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) return } decoder.elemDecoder.Decode(ptr, iter) @@ -530,7 +617,7 @@ func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterato } c = iter.readByte() if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect "`) + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) return } } @@ -595,7 +682,12 @@ func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { templateInterface := encoder.templateInterface templateInterface.word = ptr realInterface := (*interface{})(unsafe.Pointer(&templateInterface)) - marshaler := (*realInterface).(json.Marshaler) + marshaler, ok := (*realInterface).(json.Marshaler) + if !ok { + stream.WriteVal(nil) + return + } + bytes, err := marshaler.MarshalJSON() if err != nil { stream.Error = err diff --git a/vendor/github.com/json-iterator/go/feature_reflect_slice.go b/vendor/github.com/json-iterator/go/feature_reflect_slice.go index 7377eec7b..51a8daecf 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_slice.go +++ b/vendor/github.com/json-iterator/go/feature_reflect_slice.go @@ -21,7 +21,7 @@ func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { return nil, err } if typ.Elem().Kind() == reflect.Map { - encoder = &optionalEncoder{encoder} + encoder = &OptionalEncoder{encoder} } return &sliceEncoder{typ, typ.Elem(), encoder}, nil } @@ -127,12 +127,10 @@ func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Typ newVal := reflect.MakeSlice(sliceType, newLen, newCap) dst := unsafe.Pointer(newVal.Pointer()) // copy old array into new array - originalBytesCount := uintptr(slice.Len) * elementType.Size() - srcPtr := (*[1 << 30]byte)(slice.Data) - dstPtr := (*[1 << 30]byte)(dst) - for i := uintptr(0); i < originalBytesCount; i++ { - dstPtr[i] = srcPtr[i] - } + originalBytesCount := slice.Len * int(elementType.Size()) + srcSliceHeader := (unsafe.Pointer)(&sliceHeader{slice.Data, originalBytesCount, originalBytesCount}) + dstSliceHeader := (unsafe.Pointer)(&sliceHeader{dst, originalBytesCount, originalBytesCount}) + copy(*(*[]byte)(dstSliceHeader), *(*[]byte)(srcSliceHeader)) slice.Data = dst slice.Len = newLen slice.Cap = newCap diff --git a/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go index b3417fd73..e6ced77c2 100644 --- a/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go +++ b/vendor/github.com/json-iterator/go/feature_reflect_struct_decoder.go @@ -427,8 +427,18 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) if !iter.readObjectStart() { return } - fieldBytes := iter.readObjectFieldAsBytes() - field := *(*string)(unsafe.Pointer(&fieldBytes)) + 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 { iter.Skip() @@ -436,8 +446,16 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) fieldDecoder.Decode(ptr, iter) } for iter.nextToken() == ',' { - fieldBytes = iter.readObjectFieldAsBytes() - field = *(*string)(unsafe.Pointer(&fieldBytes)) + 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 { iter.Skip() diff --git a/vendor/github.com/json-iterator/go/feature_stream.go b/vendor/github.com/json-iterator/go/feature_stream.go index 9c8470a03..97355eb5b 100644 --- a/vendor/github.com/json-iterator/go/feature_stream.go +++ b/vendor/github.com/json-iterator/go/feature_stream.go @@ -4,15 +4,16 @@ import ( "io" ) -// Stream is a io.Writer like object, with JSON specific write functions. +// stream is a io.Writer like object, with JSON specific write functions. // Error is not returned as return value, but stored as Error member on this stream instance. type Stream struct { - cfg *frozenConfig - out io.Writer - buf []byte - n int - Error error - indention int + cfg *frozenConfig + out io.Writer + buf []byte + n int + Error error + indention int + Attachment interface{} // open for customized encoder } // NewStream create new stream instance. @@ -191,6 +192,9 @@ func (stream *Stream) ensure(minimal int) { func (stream *Stream) growAtLeast(minimal int) { if stream.out != nil { stream.Flush() + if stream.Available() >= minimal { + return + } } toGrow := len(stream.buf) if toGrow < minimal { @@ -280,8 +284,7 @@ func (stream *Stream) WriteArrayStart() { // WriteEmptyArray write [] func (stream *Stream) WriteEmptyArray() { - stream.writeByte('[') - stream.writeByte(']') + stream.writeTwoBytes('[', ']') } // WriteArrayEnd write ] with possible indention