You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	document public symbols
This commit is contained in:
		| @@ -160,8 +160,8 @@ type tolerateEmptyArrayDecoder struct { | ||||
| func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { | ||||
| 	if iter.WhatIsNext() == jsoniter.Array { | ||||
| 		iter.Skip() | ||||
| 		newIter := iter.Config().BorrowIterator([]byte("{}")) | ||||
| 		defer iter.Config().ReturnIterator(newIter) | ||||
| 		newIter := iter.Pool().BorrowIterator([]byte("{}")) | ||||
| 		defer iter.Pool().ReturnIterator(newIter) | ||||
| 		decoder.valDecoder.Decode(ptr, newIter) | ||||
| 	} else { | ||||
| 		decoder.valDecoder.Decode(ptr, iter) | ||||
| @@ -202,8 +202,8 @@ func (decoder *fuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It | ||||
| 	default: | ||||
| 		iter.ReportError("fuzzyIntegerDecoder", "not number or string") | ||||
| 	} | ||||
| 	newIter := iter.Config().BorrowIterator([]byte(str)) | ||||
| 	defer iter.Config().ReturnIterator(newIter) | ||||
| 	newIter := iter.Pool().BorrowIterator([]byte(str)) | ||||
| 	defer iter.Pool().ReturnIterator(newIter) | ||||
| 	isFloat := strings.IndexByte(str, '.') != -1 | ||||
| 	decoder.fun(isFloat, ptr, newIter) | ||||
| 	if newIter.Error != nil { | ||||
| @@ -222,8 +222,8 @@ func (decoder *fuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It | ||||
| 		*((*float32)(ptr)) = iter.ReadFloat32() | ||||
| 	case jsoniter.String: | ||||
| 		str = iter.ReadString() | ||||
| 		newIter := iter.Config().BorrowIterator([]byte(str)) | ||||
| 		defer iter.Config().ReturnIterator(newIter) | ||||
| 		newIter := iter.Pool().BorrowIterator([]byte(str)) | ||||
| 		defer iter.Pool().ReturnIterator(newIter) | ||||
| 		*((*float32)(ptr)) = newIter.ReadFloat32() | ||||
| 		if newIter.Error != nil { | ||||
| 			iter.Error = newIter.Error | ||||
| @@ -244,8 +244,8 @@ func (decoder *fuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It | ||||
| 		*((*float64)(ptr)) = iter.ReadFloat64() | ||||
| 	case jsoniter.String: | ||||
| 		str = iter.ReadString() | ||||
| 		newIter := iter.Config().BorrowIterator([]byte(str)) | ||||
| 		defer iter.Config().ReturnIterator(newIter) | ||||
| 		newIter := iter.Pool().BorrowIterator([]byte(str)) | ||||
| 		defer iter.Pool().ReturnIterator(newIter) | ||||
| 		*((*float64)(ptr)) = newIter.ReadFloat64() | ||||
| 		if newIter.Error != nil { | ||||
| 			iter.Error = newIter.Error | ||||
|   | ||||
| @@ -1,14 +1,3 @@ | ||||
| // Package jsoniter implements encoding and decoding of JSON as defined in | ||||
| // RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. | ||||
| // Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter | ||||
| // and variable type declarations (if any). | ||||
| // jsoniter interfaces gives 100% compatibility with code using standard lib. | ||||
| // | ||||
| // "JSON and Go" | ||||
| // (https://golang.org/doc/articles/json_and_go.html) | ||||
| // gives a description of how Marshal/Unmarshal operate | ||||
| // between arbitrary or predefined json objects and bytes, | ||||
| // and it applies to jsoniter.Marshal/Unmarshal as well. | ||||
| package jsoniter | ||||
|  | ||||
| import ( | ||||
| @@ -96,7 +85,7 @@ func (adapter *Decoder) Buffered() io.Reader { | ||||
| func (decoder *Decoder) UseNumber() { | ||||
| 	origCfg := decoder.iter.cfg.configBeforeFrozen | ||||
| 	origCfg.UseNumber = true | ||||
| 	decoder.iter.cfg = origCfg.Froze() | ||||
| 	decoder.iter.cfg = origCfg.Froze().(*frozenConfig) | ||||
| } | ||||
|  | ||||
| func NewEncoder(writer io.Writer) *Encoder { | ||||
| @@ -119,6 +108,6 @@ func (adapter *Encoder) SetIndent(prefix, indent string) { | ||||
|  | ||||
| func (adapter *Encoder) SetEscapeHTML(escapeHtml bool) { | ||||
| 	config := adapter.stream.cfg.configBeforeFrozen | ||||
| 	config.EscapeHtml = escapeHtml | ||||
| 	adapter.stream.cfg = config.Froze() | ||||
| 	config.EscapeHTML = escapeHtml | ||||
| 	adapter.stream.cfg = config.Froze().(*frozenConfig) | ||||
| } | ||||
|   | ||||
| @@ -9,10 +9,12 @@ import ( | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // Config customize how the API should behave. | ||||
| // The API is created from Config by Froze. | ||||
| type Config struct { | ||||
| 	IndentionStep           int | ||||
| 	MarshalFloatWith6Digits bool | ||||
| 	EscapeHtml              bool | ||||
| 	EscapeHTML              bool | ||||
| 	SortMapKeys             bool | ||||
| 	UseNumber               bool | ||||
| } | ||||
| @@ -28,7 +30,11 @@ type frozenConfig struct { | ||||
| 	iteratorPool       chan *Iterator | ||||
| } | ||||
|  | ||||
| type Api interface { | ||||
| // API the public interface of this package. | ||||
| // Primary Marshal and Unmarshal. | ||||
| type API interface { | ||||
| 	IteratorPool | ||||
| 	StreamPool | ||||
| 	MarshalToString(v interface{}) (string, error) | ||||
| 	Marshal(v interface{}) ([]byte, error) | ||||
| 	MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) | ||||
| @@ -39,22 +45,25 @@ type Api interface { | ||||
| 	NewDecoder(reader io.Reader) *Decoder | ||||
| } | ||||
|  | ||||
| // ConfigDefault the default API | ||||
| var ConfigDefault = Config{ | ||||
| 	EscapeHtml: true, | ||||
| 	EscapeHTML: true, | ||||
| }.Froze() | ||||
|  | ||||
| // Trying to be 100% compatible with standard library behavior | ||||
| // ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior | ||||
| var ConfigCompatibleWithStandardLibrary = Config{ | ||||
| 	EscapeHtml:  true, | ||||
| 	EscapeHTML:  true, | ||||
| 	SortMapKeys: true, | ||||
| }.Froze() | ||||
|  | ||||
| // ConfigFastest marshals float with only 6 digits precision | ||||
| var ConfigFastest = Config{ | ||||
| 	EscapeHtml:              false, | ||||
| 	EscapeHTML:              false, | ||||
| 	MarshalFloatWith6Digits: true, | ||||
| }.Froze() | ||||
|  | ||||
| func (cfg Config) Froze() *frozenConfig { | ||||
| // Froze forge API from config | ||||
| func (cfg Config) Froze() API { | ||||
| 	// TODO: cache frozen config | ||||
| 	frozenConfig := &frozenConfig{ | ||||
| 		sortMapKeys:   cfg.SortMapKeys, | ||||
| @@ -67,8 +76,8 @@ func (cfg Config) Froze() *frozenConfig { | ||||
| 	if cfg.MarshalFloatWith6Digits { | ||||
| 		frozenConfig.marshalFloatWith6Digits() | ||||
| 	} | ||||
| 	if cfg.EscapeHtml { | ||||
| 		frozenConfig.escapeHtml() | ||||
| 	if cfg.EscapeHTML { | ||||
| 		frozenConfig.escapeHTML() | ||||
| 	} | ||||
| 	if cfg.UseNumber { | ||||
| 		frozenConfig.useNumber() | ||||
| @@ -145,7 +154,7 @@ func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return *((*string)(ptr)) == "" | ||||
| } | ||||
|  | ||||
| func (cfg *frozenConfig) escapeHtml() { | ||||
| func (cfg *frozenConfig) escapeHTML() { | ||||
| 	cfg.addEncoderToCache(reflect.TypeOf((*string)(nil)).Elem(), &htmlEscapedStringEncoder{}) | ||||
| } | ||||
|  | ||||
| @@ -189,18 +198,16 @@ func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder { | ||||
| 	return cache[cacheKey] | ||||
| } | ||||
|  | ||||
| // cleanDecoders cleans decoders registered or cached | ||||
| func (cfg *frozenConfig) cleanDecoders() { | ||||
| 	typeDecoders = map[string]ValDecoder{} | ||||
| 	fieldDecoders = map[string]ValDecoder{} | ||||
| 	*cfg = *cfg.configBeforeFrozen.Froze() | ||||
| 	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) | ||||
| } | ||||
|  | ||||
| // cleanEncoders cleans encoders registered or cached | ||||
| func (cfg *frozenConfig) cleanEncoders() { | ||||
| 	typeEncoders = map[string]ValEncoder{} | ||||
| 	fieldEncoders = map[string]ValEncoder{} | ||||
| 	*cfg = *cfg.configBeforeFrozen.Froze() | ||||
| 	*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) | ||||
| } | ||||
|  | ||||
| func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { | ||||
|   | ||||
| @@ -1,9 +1,3 @@ | ||||
| // | ||||
| // Besides, jsoniter.Iterator provides a different set of interfaces | ||||
| // iterating given bytes/string/reader | ||||
| // and yielding parsed elements one by one. | ||||
| // This set of interfaces reads input as required and gives | ||||
| // better performance. | ||||
| package jsoniter | ||||
|  | ||||
| import ( | ||||
| @@ -11,15 +5,23 @@ import ( | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // ValueType the type for JSON element | ||||
| type ValueType int | ||||
|  | ||||
| const ( | ||||
| 	// Invalid invalid JSON element | ||||
| 	Invalid ValueType = iota | ||||
| 	// String JSON element "string" | ||||
| 	String | ||||
| 	// Number JSON element 100 or 0.10 | ||||
| 	Number | ||||
| 	// Nil JSON element null | ||||
| 	Nil | ||||
| 	// Bool JSON element true or false | ||||
| 	Bool | ||||
| 	// Array JSON element [] | ||||
| 	Array | ||||
| 	// Object JSON element {} | ||||
| 	Object | ||||
| ) | ||||
|  | ||||
| @@ -63,7 +65,8 @@ func init() { | ||||
| 	valueTypes['{'] = Object | ||||
| } | ||||
|  | ||||
| // Iterator is a fast and flexible JSON parser | ||||
| // Iterator is a io.Reader like object, with JSON specific read functions. | ||||
| // Error is not returned as return value, but stored as Error member on this iterator instance. | ||||
| type Iterator struct { | ||||
| 	cfg              *frozenConfig | ||||
| 	reader           io.Reader | ||||
| @@ -75,10 +78,10 @@ type Iterator struct { | ||||
| 	Error            error | ||||
| } | ||||
|  | ||||
| // Create creates an empty Iterator instance | ||||
| func NewIterator(cfg *frozenConfig) *Iterator { | ||||
| // NewIterator creates an empty Iterator instance | ||||
| func NewIterator(cfg API) *Iterator { | ||||
| 	return &Iterator{ | ||||
| 		cfg:    cfg, | ||||
| 		cfg:    cfg.(*frozenConfig), | ||||
| 		reader: nil, | ||||
| 		buf:    nil, | ||||
| 		head:   0, | ||||
| @@ -86,10 +89,10 @@ func NewIterator(cfg *frozenConfig) *Iterator { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Parse parses a json buffer in io.Reader into an Iterator instance | ||||
| func Parse(cfg *frozenConfig, reader io.Reader, bufSize int) *Iterator { | ||||
| // Parse creates an Iterator instance from io.Reader | ||||
| func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { | ||||
| 	return &Iterator{ | ||||
| 		cfg:    cfg, | ||||
| 		cfg:    cfg.(*frozenConfig), | ||||
| 		reader: reader, | ||||
| 		buf:    make([]byte, bufSize), | ||||
| 		head:   0, | ||||
| @@ -97,10 +100,10 @@ func Parse(cfg *frozenConfig, reader io.Reader, bufSize int) *Iterator { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ParseBytes parses a json byte slice into an Iterator instance | ||||
| func ParseBytes(cfg *frozenConfig, input []byte) *Iterator { | ||||
| // ParseBytes creates an Iterator instance from byte array | ||||
| func ParseBytes(cfg API, input []byte) *Iterator { | ||||
| 	return &Iterator{ | ||||
| 		cfg:    cfg, | ||||
| 		cfg:    cfg.(*frozenConfig), | ||||
| 		reader: nil, | ||||
| 		buf:    input, | ||||
| 		head:   0, | ||||
| @@ -108,16 +111,17 @@ func ParseBytes(cfg *frozenConfig, input []byte) *Iterator { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ParseString parses a json string into an Iterator instance | ||||
| func ParseString(cfg *frozenConfig, input string) *Iterator { | ||||
| // ParseString creates an Iterator instance from string | ||||
| func ParseString(cfg API, input string) *Iterator { | ||||
| 	return ParseBytes(cfg, []byte(input)) | ||||
| } | ||||
|  | ||||
| func (iter *Iterator) Config() *frozenConfig { | ||||
| // Pool returns a pool can provide more iterator with same configuration | ||||
| func (iter *Iterator) Pool() IteratorPool { | ||||
| 	return iter.cfg | ||||
| } | ||||
|  | ||||
| // Reset can reset an Iterator instance for another json buffer in io.Reader | ||||
| // Reset reuse iterator instance by specifying another reader | ||||
| func (iter *Iterator) Reset(reader io.Reader) *Iterator { | ||||
| 	iter.reader = reader | ||||
| 	iter.head = 0 | ||||
| @@ -125,7 +129,7 @@ func (iter *Iterator) Reset(reader io.Reader) *Iterator { | ||||
| 	return iter | ||||
| } | ||||
|  | ||||
| // ResetBytes can reset an Iterator instance for another json byte slice | ||||
| // ResetBytes reuse iterator instance by specifying another byte array as input | ||||
| func (iter *Iterator) ResetBytes(input []byte) *Iterator { | ||||
| 	iter.reader = nil | ||||
| 	iter.buf = input | ||||
| @@ -134,7 +138,7 @@ func (iter *Iterator) ResetBytes(input []byte) *Iterator { | ||||
| 	return iter | ||||
| } | ||||
|  | ||||
| // WhatIsNext gets ValueType of relatively next json object | ||||
| // WhatIsNext gets ValueType of relatively next json element | ||||
| func (iter *Iterator) WhatIsNext() ValueType { | ||||
| 	valueType := valueTypes[iter.nextToken()] | ||||
| 	iter.unreadByte() | ||||
| @@ -184,6 +188,7 @@ func (iter *Iterator) nextToken() byte { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReportError record a error in iterator instance with current position. | ||||
| func (iter *Iterator) ReportError(operation string, msg string) { | ||||
| 	if iter.Error != nil { | ||||
| 		if iter.Error != io.EOF { | ||||
| @@ -198,7 +203,7 @@ func (iter *Iterator) ReportError(operation string, msg string) { | ||||
| 		string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) | ||||
| } | ||||
|  | ||||
| // CurrentBuffer gets current buffer as string | ||||
| // CurrentBuffer gets current buffer as string for debugging purpose | ||||
| func (iter *Iterator) CurrentBuffer() string { | ||||
| 	peekStart := iter.head - 10 | ||||
| 	if peekStart < 0 { | ||||
| @@ -261,6 +266,7 @@ func (iter *Iterator) unreadByte() { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Read read the next JSON element as generic interface{}. | ||||
| func (iter *Iterator) Read() interface{} { | ||||
| 	valueType := iter.WhatIsNext() | ||||
| 	switch valueType { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package jsoniter | ||||
|  | ||||
| // ReadArray read array element, tells if the array has more element to read. | ||||
| func (iter *Iterator) ReadArray() (ret bool) { | ||||
| 	c := iter.nextToken() | ||||
| 	switch c { | ||||
| @@ -23,6 +24,7 @@ func (iter *Iterator) ReadArray() (ret bool) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadArrayCB read array with callback | ||||
| func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '[' { | ||||
|   | ||||
| @@ -30,6 +30,7 @@ func init() { | ||||
| 	floatDigits['.'] = dotInNumber | ||||
| } | ||||
|  | ||||
| // ReadBigFloat read big.Float | ||||
| func (iter *Iterator) ReadBigFloat() (ret *big.Float) { | ||||
| 	str := iter.readNumberAsString() | ||||
| 	if iter.Error != nil && iter.Error != io.EOF { | ||||
| @@ -47,6 +48,7 @@ func (iter *Iterator) ReadBigFloat() (ret *big.Float) { | ||||
| 	return val | ||||
| } | ||||
|  | ||||
| // ReadBigInt read big.Int | ||||
| func (iter *Iterator) ReadBigInt() (ret *big.Int) { | ||||
| 	str := iter.readNumberAsString() | ||||
| 	if iter.Error != nil && iter.Error != io.EOF { | ||||
| @@ -62,14 +64,14 @@ func (iter *Iterator) ReadBigInt() (ret *big.Int) { | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| //ReadFloat32 read float32 | ||||
| func (iter *Iterator) ReadFloat32() (ret float32) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '-' { | ||||
| 		return -iter.readPositiveFloat32() | ||||
| 	} else { | ||||
| 		iter.unreadByte() | ||||
| 		return iter.readPositiveFloat32() | ||||
| 	} | ||||
| 	iter.unreadByte() | ||||
| 	return iter.readPositiveFloat32() | ||||
| } | ||||
|  | ||||
| func (iter *Iterator) readPositiveFloat32() (ret float32) { | ||||
| @@ -165,14 +167,14 @@ func (iter *Iterator) readFloat32SlowPath() (ret float32) { | ||||
| 	return float32(val) | ||||
| } | ||||
|  | ||||
| // ReadFloat64 read float64 | ||||
| func (iter *Iterator) ReadFloat64() (ret float64) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '-' { | ||||
| 		return -iter.readPositiveFloat64() | ||||
| 	} else { | ||||
| 		iter.unreadByte() | ||||
| 		return iter.readPositiveFloat64() | ||||
| 	} | ||||
| 	iter.unreadByte() | ||||
| 	return iter.readPositiveFloat64() | ||||
| } | ||||
|  | ||||
| func (iter *Iterator) readPositiveFloat64() (ret float64) { | ||||
|   | ||||
| @@ -20,14 +20,17 @@ func init() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadUint read uint | ||||
| func (iter *Iterator) ReadUint() uint { | ||||
| 	return uint(iter.ReadUint64()) | ||||
| } | ||||
|  | ||||
| // ReadInt read int | ||||
| func (iter *Iterator) ReadInt() int { | ||||
| 	return int(iter.ReadInt64()) | ||||
| } | ||||
|  | ||||
| // ReadInt8 read int8 | ||||
| func (iter *Iterator) ReadInt8() (ret int8) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '-' { | ||||
| @@ -37,16 +40,16 @@ func (iter *Iterator) ReadInt8() (ret int8) { | ||||
| 			return | ||||
| 		} | ||||
| 		return -int8(val) | ||||
| 	} else { | ||||
| 		val := iter.readUint32(c) | ||||
| 		if val > math.MaxInt8 { | ||||
| 			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) | ||||
| 			return | ||||
| 		} | ||||
| 		return int8(val) | ||||
| 	} | ||||
| 	val := iter.readUint32(c) | ||||
| 	if val > math.MaxInt8 { | ||||
| 		iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) | ||||
| 		return | ||||
| 	} | ||||
| 	return int8(val) | ||||
| } | ||||
|  | ||||
| // ReadUint8 read uint8 | ||||
| func (iter *Iterator) ReadUint8() (ret uint8) { | ||||
| 	val := iter.readUint32(iter.nextToken()) | ||||
| 	if val > math.MaxUint8 { | ||||
| @@ -56,6 +59,7 @@ func (iter *Iterator) ReadUint8() (ret uint8) { | ||||
| 	return uint8(val) | ||||
| } | ||||
|  | ||||
| // ReadInt16 read int16 | ||||
| func (iter *Iterator) ReadInt16() (ret int16) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '-' { | ||||
| @@ -65,16 +69,16 @@ func (iter *Iterator) ReadInt16() (ret int16) { | ||||
| 			return | ||||
| 		} | ||||
| 		return -int16(val) | ||||
| 	} else { | ||||
| 		val := iter.readUint32(c) | ||||
| 		if val > math.MaxInt16 { | ||||
| 			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) | ||||
| 			return | ||||
| 		} | ||||
| 		return int16(val) | ||||
| 	} | ||||
| 	val := iter.readUint32(c) | ||||
| 	if val > math.MaxInt16 { | ||||
| 		iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) | ||||
| 		return | ||||
| 	} | ||||
| 	return int16(val) | ||||
| } | ||||
|  | ||||
| // ReadUint16 read uint16 | ||||
| func (iter *Iterator) ReadUint16() (ret uint16) { | ||||
| 	val := iter.readUint32(iter.nextToken()) | ||||
| 	if val > math.MaxUint16 { | ||||
| @@ -84,6 +88,7 @@ func (iter *Iterator) ReadUint16() (ret uint16) { | ||||
| 	return uint16(val) | ||||
| } | ||||
|  | ||||
| // ReadInt32 read int32 | ||||
| func (iter *Iterator) ReadInt32() (ret int32) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '-' { | ||||
| @@ -93,16 +98,16 @@ func (iter *Iterator) ReadInt32() (ret int32) { | ||||
| 			return | ||||
| 		} | ||||
| 		return -int32(val) | ||||
| 	} else { | ||||
| 		val := iter.readUint32(c) | ||||
| 		if val > math.MaxInt32 { | ||||
| 			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) | ||||
| 			return | ||||
| 		} | ||||
| 		return int32(val) | ||||
| 	} | ||||
| 	val := iter.readUint32(c) | ||||
| 	if val > math.MaxInt32 { | ||||
| 		iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) | ||||
| 		return | ||||
| 	} | ||||
| 	return int32(val) | ||||
| } | ||||
|  | ||||
| // ReadUint32 read uint32 | ||||
| func (iter *Iterator) ReadUint32() (ret uint32) { | ||||
| 	return iter.readUint32(iter.nextToken()) | ||||
| } | ||||
| @@ -182,10 +187,9 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { | ||||
| 				if value2 < value { | ||||
| 					iter.ReportError("readUint32", "overflow") | ||||
| 					return | ||||
| 				} else { | ||||
| 					value = value2 | ||||
| 					continue | ||||
| 				} | ||||
| 				value = value2 | ||||
| 				continue | ||||
| 			} | ||||
| 			value = (value << 3) + (value << 1) + uint32(ind) | ||||
| 		} | ||||
| @@ -195,6 +199,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReadInt64 read int64 | ||||
| func (iter *Iterator) ReadInt64() (ret int64) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '-' { | ||||
| @@ -204,16 +209,16 @@ func (iter *Iterator) ReadInt64() (ret int64) { | ||||
| 			return | ||||
| 		} | ||||
| 		return -int64(val) | ||||
| 	} else { | ||||
| 		val := iter.readUint64(c) | ||||
| 		if val > math.MaxInt64 { | ||||
| 			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) | ||||
| 			return | ||||
| 		} | ||||
| 		return int64(val) | ||||
| 	} | ||||
| 	val := iter.readUint64(c) | ||||
| 	if val > math.MaxInt64 { | ||||
| 		iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) | ||||
| 		return | ||||
| 	} | ||||
| 	return int64(val) | ||||
| } | ||||
|  | ||||
| // ReadUint64 read uint64 | ||||
| func (iter *Iterator) ReadUint64() uint64 { | ||||
| 	return iter.readUint64(iter.nextToken()) | ||||
| } | ||||
| @@ -240,10 +245,9 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) { | ||||
| 				if value2 < value { | ||||
| 					iter.ReportError("readUint64", "overflow") | ||||
| 					return | ||||
| 				} else { | ||||
| 					value = value2 | ||||
| 					continue | ||||
| 				} | ||||
| 				value = value2 | ||||
| 				continue | ||||
| 			} | ||||
| 			value = (value << 3) + (value << 1) + uint64(ind) | ||||
| 		} | ||||
|   | ||||
| @@ -6,6 +6,9 @@ import ( | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // ReadObject read one field from object. | ||||
| // If object ended, returns empty string. | ||||
| // Otherwise, returns the field name. | ||||
| func (iter *Iterator) ReadObject() (ret string) { | ||||
| 	c := iter.nextToken() | ||||
| 	switch c { | ||||
| @@ -74,6 +77,7 @@ func calcHash(str string) int32 { | ||||
| 	return int32(hash) | ||||
| } | ||||
|  | ||||
| // 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() | ||||
| 	if c == '{' { | ||||
| @@ -106,6 +110,7 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // ReadMapCB read map with callback, the key can be any string | ||||
| func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '{' { | ||||
|   | ||||
| @@ -29,6 +29,8 @@ func (iter *Iterator) ReadBool() (ret bool) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // SkipAndReturnBytes skip next JSON element, and return its content as []byte. | ||||
| // The []byte can be kept, it is a copy of data. | ||||
| func (iter *Iterator) SkipAndReturnBytes() []byte { | ||||
| 	iter.startCapture(iter.head) | ||||
| 	iter.Skip() | ||||
| @@ -58,10 +60,9 @@ func (iter *Iterator) stopCapture() []byte { | ||||
| 	iter.captured = nil | ||||
| 	if len(captured) == 0 { | ||||
| 		return remaining | ||||
| 	} else { | ||||
| 		captured = append(captured, remaining...) | ||||
| 		return captured | ||||
| 	} | ||||
| 	captured = append(captured, remaining...) | ||||
| 	return captured | ||||
| } | ||||
|  | ||||
| // Skip skips a json object and positions to relatively the next json object | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import ( | ||||
| 	"unicode/utf16" | ||||
| ) | ||||
|  | ||||
| // ReadString read string from iterator | ||||
| func (iter *Iterator) ReadString() (ret string) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '"' { | ||||
| @@ -96,6 +97,8 @@ func (iter *Iterator) readStringSlowPath() (ret string) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // ReadStringAsSlice read string from iterator without copying into string form. | ||||
| // The []byte can not be kept, as it will change after next iterator call. | ||||
| func (iter *Iterator) ReadStringAsSlice() (ret []byte) { | ||||
| 	c := iter.nextToken() | ||||
| 	if c == '"' { | ||||
|   | ||||
| @@ -4,6 +4,18 @@ import ( | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // IteratorPool a thread safe pool of iterators with same configuration | ||||
| type IteratorPool interface { | ||||
| 	BorrowIterator(data []byte) *Iterator | ||||
| 	ReturnIterator(iter *Iterator) | ||||
| } | ||||
|  | ||||
| // StreamPool a thread safe pool of streams with same configuration | ||||
| type StreamPool interface { | ||||
| 	BorrowStream(writer io.Writer) *Stream | ||||
| 	ReturnStream(stream *Stream) | ||||
| } | ||||
|  | ||||
| func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { | ||||
| 	select { | ||||
| 	case stream := <-cfg.streamPool: | ||||
|   | ||||
| @@ -36,6 +36,7 @@ type checkIsEmpty interface { | ||||
| 	IsEmpty(ptr unsafe.Pointer) bool | ||||
| } | ||||
|  | ||||
| // WriteToStream the default implementation for TypeEncoder method EncodeInterface | ||||
| func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) { | ||||
| 	e := (*emptyInterface)(unsafe.Pointer(&val)) | ||||
| 	if e.word == nil { | ||||
| @@ -49,9 +50,6 @@ func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) | ||||
| type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) | ||||
|  | ||||
| var jsonNumberType reflect.Type | ||||
| var jsonRawMessageType reflect.Type | ||||
| var jsoniterRawMessageType reflect.Type | ||||
| @@ -132,9 +130,8 @@ func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) | ||||
| func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	if *((*unsafe.Pointer)(ptr)) == nil { | ||||
| 		return true | ||||
| 	} else { | ||||
| 		return false | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type placeholderEncoder struct { | ||||
| @@ -206,7 +203,7 @@ type nonEmptyInterface struct { | ||||
| 	word unsafe.Pointer | ||||
| } | ||||
|  | ||||
| // Read converts an Iterator instance into go interface, same as json.Unmarshal | ||||
| // ReadVal copy the underlying JSON into go interface, same as json.Unmarshal | ||||
| func (iter *Iterator) ReadVal(obj interface{}) { | ||||
| 	typ := reflect.TypeOf(obj) | ||||
| 	cacheKey := typ.Elem() | ||||
| @@ -219,6 +216,7 @@ func (iter *Iterator) ReadVal(obj interface{}) { | ||||
| 	decoder.Decode(e.word, iter) | ||||
| } | ||||
|  | ||||
| // WriteVal copy the go interface into underlying JSON, same as json.Marshal | ||||
| func (stream *Stream) WriteVal(val interface{}) { | ||||
| 	if nil == val { | ||||
| 		stream.WriteNil() | ||||
| @@ -393,9 +391,8 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error | ||||
| 	case reflect.Interface: | ||||
| 		if typ.NumMethod() == 0 { | ||||
| 			return &emptyInterfaceCodec{}, nil | ||||
| 		} else { | ||||
| 			return &nonEmptyInterfaceCodec{}, nil | ||||
| 		} | ||||
| 		return &nonEmptyInterfaceCodec{}, nil | ||||
| 	case reflect.Struct: | ||||
| 		return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ)) | ||||
| 	case reflect.Array: | ||||
| @@ -517,9 +514,8 @@ func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { | ||||
| 	case reflect.Interface: | ||||
| 		if typ.NumMethod() == 0 { | ||||
| 			return &emptyInterfaceCodec{}, nil | ||||
| 		} else { | ||||
| 			return &nonEmptyInterfaceCodec{}, nil | ||||
| 		} | ||||
| 		return &nonEmptyInterfaceCodec{}, nil | ||||
| 	case reflect.Struct: | ||||
| 		return &structEncoder{}, nil | ||||
| 	case reflect.Array: | ||||
| @@ -617,9 +613,8 @@ func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, | ||||
| 	case reflect.Interface: | ||||
| 		if typ.NumMethod() == 0 { | ||||
| 			return &emptyInterfaceCodec{}, nil | ||||
| 		} else { | ||||
| 			return &nonEmptyInterfaceCodec{}, nil | ||||
| 		} | ||||
| 		return &nonEmptyInterfaceCodec{}, nil | ||||
| 	case reflect.Struct: | ||||
| 		return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ)) | ||||
| 	case reflect.Array: | ||||
| @@ -679,7 +674,6 @@ func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { | ||||
| 	mapInterface := reflect.New(typ).Elem().Interface() | ||||
| 	if cfg.sortMapKeys { | ||||
| 		return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil | ||||
| 	} else { | ||||
| 		return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil | ||||
| 	} | ||||
| 	return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil | ||||
| } | ||||
|   | ||||
| @@ -110,6 +110,11 @@ func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return encoder.isEmptyFunc(ptr) | ||||
| } | ||||
|  | ||||
| // DecoderFunc the function form of TypeDecoder | ||||
| type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) | ||||
| // EncoderFunc the function form of TypeEncoder | ||||
| type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) | ||||
|  | ||||
| // RegisterTypeDecoderFunc register TypeDecoder for a type with function | ||||
| func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { | ||||
| 	typeDecoders[typ] = &funcDecoder{fun} | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package jsoniter | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"io" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| @@ -71,7 +71,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &threeFieldsStructDecoder{typ, | ||||
| 										 fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil | ||||
| 	case 4: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -103,8 +103,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &fourFieldsStructDecoder{typ, | ||||
| 										fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 										fieldName4, fieldDecoder4}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4}, nil | ||||
| 	case 5: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -141,8 +141,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &fiveFieldsStructDecoder{typ, | ||||
| 										fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 										fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil | ||||
| 	case 6: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -184,8 +184,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &sixFieldsStructDecoder{typ, | ||||
| 									   fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 									   fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil | ||||
| 	case 7: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -232,9 +232,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &sevenFieldsStructDecoder{typ, | ||||
| 										 fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 										 fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 										 fieldName7, fieldDecoder7}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 			fieldName7, fieldDecoder7}, nil | ||||
| 	case 8: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -286,9 +286,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &eightFieldsStructDecoder{typ, | ||||
| 										 fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 										 fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 										 fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil | ||||
| 	case 9: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -345,9 +345,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &nineFieldsStructDecoder{typ, | ||||
| 										fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 										fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 										fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil | ||||
| 	case 10: | ||||
| 		var fieldName1 int32 | ||||
| 		var fieldName2 int32 | ||||
| @@ -409,15 +409,14 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder | ||||
| 			} | ||||
| 		} | ||||
| 		return &tenFieldsStructDecoder{typ, | ||||
| 									   fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 									   fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 									   fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, | ||||
| 									   fieldName10, fieldDecoder10}, nil | ||||
| 			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, | ||||
| 			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, | ||||
| 			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, | ||||
| 			fieldName10, fieldDecoder10}, nil | ||||
| 	} | ||||
| 	return &generalStructDecoder{typ, fields}, nil | ||||
| } | ||||
|  | ||||
|  | ||||
| type generalStructDecoder struct { | ||||
| 	typ    reflect.Type | ||||
| 	fields map[string]*structFieldDecoder | ||||
| @@ -911,4 +910,4 @@ func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { | ||||
| 	if iter.Error != nil && iter.Error != io.EOF { | ||||
| 		iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error()) | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import ( | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // Stream is a 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 | ||||
| @@ -19,9 +19,9 @@ type Stream struct { | ||||
| // cfg can be jsoniter.ConfigDefault. | ||||
| // out can be nil if write to internal buffer. | ||||
| // bufSize is the initial size for the internal buffer in bytes. | ||||
| func NewStream(cfg *frozenConfig, out io.Writer, bufSize int) *Stream { | ||||
| func NewStream(cfg API, out io.Writer, bufSize int) *Stream { | ||||
| 	return &Stream{ | ||||
| 		cfg:       cfg, | ||||
| 		cfg:       cfg.(*frozenConfig), | ||||
| 		out:       out, | ||||
| 		buf:       make([]byte, bufSize), | ||||
| 		n:         0, | ||||
| @@ -30,6 +30,11 @@ func NewStream(cfg *frozenConfig, out io.Writer, bufSize int) *Stream { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Pool returns a pool can provide more stream with same configuration | ||||
| func (stream *Stream) Pool() StreamPool { | ||||
| 	return stream.cfg | ||||
| } | ||||
|  | ||||
| // Reset reuse this stream instance by assign a new writer | ||||
| func (stream *Stream) Reset(out io.Writer) { | ||||
| 	stream.out = out | ||||
| @@ -196,7 +201,6 @@ func (stream *Stream) growAtLeast(minimal int) { | ||||
| 	stream.buf = newBuf | ||||
| } | ||||
|  | ||||
|  | ||||
| // WriteRaw write string out without quotes, just like []byte | ||||
| func (stream *Stream) WriteRaw(s string) { | ||||
| 	stream.ensure(len(s)) | ||||
|   | ||||
							
								
								
									
										18
									
								
								jsoniter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								jsoniter.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| // Package jsoniter implements encoding and decoding of JSON as defined in | ||||
| // RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. | ||||
| // Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter | ||||
| // and variable type declarations (if any). | ||||
| // jsoniter interfaces gives 100% compatibility with code using standard lib. | ||||
| // | ||||
| // "JSON and Go" | ||||
| // (https://golang.org/doc/articles/json_and_go.html) | ||||
| // gives a description of how Marshal/Unmarshal operate | ||||
| // between arbitrary or predefined json objects and bytes, | ||||
| // and it applies to jsoniter.Marshal/Unmarshal as well. | ||||
| // | ||||
| // Besides, jsoniter.Iterator provides a different set of interfaces | ||||
| // iterating given bytes/string/reader | ||||
| // and yielding parsed elements one by one. | ||||
| // This set of interfaces reads input as required and gives | ||||
| // better performance. | ||||
| package jsoniter | ||||
| @@ -26,7 +26,7 @@ func Test_new_encoder(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func Test_string_encode_with_std_without_html_escape(t *testing.T) { | ||||
| 	api := Config{EscapeHtml: false}.Froze() | ||||
| 	api := Config{EscapeHTML: false}.Froze() | ||||
| 	should := require.New(t) | ||||
| 	for i := 0; i < utf8.RuneSelf; i++ { | ||||
| 		input := string([]byte{byte(i)}) | ||||
|   | ||||
| @@ -7,25 +7,25 @@ import ( | ||||
| ) | ||||
|  | ||||
| var stringConvertMap = map[string]string{ | ||||
| 	"null":              "", | ||||
| 	"321.1":             "321.1", | ||||
| 	`"1.1"`:             "1.1", | ||||
| 	`"-123.1"`:          "-123.1", | ||||
| 	"0.0":               "0.0", | ||||
| 	"0":                 "0", | ||||
| 	`"0"`:               "0", | ||||
| 	`"0.0"`:             "0.0", | ||||
| 	`"00.0"`:            "00.0", | ||||
| 	"true":              "true", | ||||
| 	"false":             "false", | ||||
| 	`"true"`:            "true", | ||||
| 	`"false"`:           "false", | ||||
| 	`"true123"`:         "true123", | ||||
| 	`"+1"`:              "+1", | ||||
| 	"[]":                "[]", | ||||
| 	"[1,2]":             "[1,2]", | ||||
| 	"{}":                "{}", | ||||
| 	"{1,2}":             "{1,2}", | ||||
| 	"null":                   "", | ||||
| 	"321.1":                  "321.1", | ||||
| 	`"1.1"`:                  "1.1", | ||||
| 	`"-123.1"`:               "-123.1", | ||||
| 	"0.0":                    "0.0", | ||||
| 	"0":                      "0", | ||||
| 	`"0"`:                    "0", | ||||
| 	`"0.0"`:                  "0.0", | ||||
| 	`"00.0"`:                 "00.0", | ||||
| 	"true":                   "true", | ||||
| 	"false":                  "false", | ||||
| 	`"true"`:                 "true", | ||||
| 	`"false"`:                "false", | ||||
| 	`"true123"`:              "true123", | ||||
| 	`"+1"`:                   "+1", | ||||
| 	"[]":                     "[]", | ||||
| 	"[1,2]":                  "[1,2]", | ||||
| 	"{}":                     "{}", | ||||
| 	"{1,2}":                  "{1,2}", | ||||
| 	`{"a":1, "stream":true}`: `{"a":1, "stream":true}`, | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ func Test_customize_type_decoder(t *testing.T) { | ||||
| 		} | ||||
| 		*((*time.Time)(ptr)) = t | ||||
| 	}) | ||||
| 	defer ConfigDefault.cleanDecoders() | ||||
| 	defer ConfigDefault.(*frozenConfig).cleanDecoders() | ||||
| 	val := time.Time{} | ||||
| 	err := Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val) | ||||
| 	if err != nil { | ||||
| @@ -36,7 +36,7 @@ func Test_customize_type_encoder(t *testing.T) { | ||||
| 		t := *((*time.Time)(ptr)) | ||||
| 		stream.WriteString(t.UTC().Format("2006-01-02 15:04:05")) | ||||
| 	}, nil) | ||||
| 	defer ConfigDefault.cleanEncoders() | ||||
| 	defer ConfigDefault.(*frozenConfig).cleanEncoders() | ||||
| 	val := time.Unix(0, 0) | ||||
| 	str, err := MarshalToString(val) | ||||
| 	should.Nil(err) | ||||
| @@ -44,13 +44,13 @@ func Test_customize_type_encoder(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func Test_customize_byte_array_encoder(t *testing.T) { | ||||
| 	ConfigDefault.cleanEncoders() | ||||
| 	ConfigDefault.(*frozenConfig).cleanEncoders() | ||||
| 	should := require.New(t) | ||||
| 	RegisterTypeEncoderFunc("[]uint8", func(ptr unsafe.Pointer, stream *Stream) { | ||||
| 		t := *((*[]byte)(ptr)) | ||||
| 		stream.WriteString(string(t)) | ||||
| 	}, nil) | ||||
| 	defer ConfigDefault.cleanEncoders() | ||||
| 	defer ConfigDefault.(*frozenConfig).cleanEncoders() | ||||
| 	val := []byte("abc") | ||||
| 	str, err := MarshalToString(val) | ||||
| 	should.Nil(err) | ||||
| @@ -73,7 +73,7 @@ func Test_customize_field_decoder(t *testing.T) { | ||||
| 	RegisterFieldDecoderFunc("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *Iterator) { | ||||
| 		*((*string)(ptr)) = strconv.Itoa(iter.ReadInt()) | ||||
| 	}) | ||||
| 	defer ConfigDefault.cleanDecoders() | ||||
| 	defer ConfigDefault.(*frozenConfig).cleanDecoders() | ||||
| 	tom := Tom{} | ||||
| 	err := Unmarshal([]byte(`{"field1": 100}`), &tom) | ||||
| 	if err != nil { | ||||
| @@ -144,7 +144,7 @@ func Test_marshaler_and_encoder(t *testing.T) { | ||||
| 	type TestObject struct { | ||||
| 		Field *timeImplementedMarshaler | ||||
| 	} | ||||
| 	ConfigDefault.cleanEncoders() | ||||
| 	ConfigDefault.(*frozenConfig).cleanEncoders() | ||||
| 	should := require.New(t) | ||||
| 	RegisterTypeEncoderFunc("jsoniter.timeImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) { | ||||
| 		stream.WriteString("hello from encoder") | ||||
| @@ -184,7 +184,7 @@ func Test_unmarshaler_and_decoder(t *testing.T) { | ||||
| 		Field  *ObjectImplementedUnmarshaler | ||||
| 		Field2 string | ||||
| 	} | ||||
| 	ConfigDefault.cleanDecoders() | ||||
| 	ConfigDefault.(*frozenConfig).cleanDecoders() | ||||
| 	should := require.New(t) | ||||
| 	RegisterTypeDecoderFunc("jsoniter.ObjectImplementedUnmarshaler", func(ptr unsafe.Pointer, iter *Iterator) { | ||||
| 		*(*ObjectImplementedUnmarshaler)(ptr) = 10 | ||||
|   | ||||
| @@ -141,8 +141,8 @@ func Test_encode_object_contain_non_empty_interface(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func Test_nil_non_empty_interface(t *testing.T) { | ||||
| 	ConfigDefault.cleanEncoders() | ||||
| 	ConfigDefault.cleanDecoders() | ||||
| 	ConfigDefault.(*frozenConfig).cleanEncoders() | ||||
| 	ConfigDefault.(*frozenConfig).cleanDecoders() | ||||
| 	type TestObject struct { | ||||
| 		Field []MyInterface | ||||
| 	} | ||||
|   | ||||
| @@ -2,9 +2,9 @@ package jsoniter | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"io" | ||||
| 	"testing" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
|  | ||||
| func Test_read_by_one(t *testing.T) { | ||||
|   | ||||
| @@ -127,7 +127,7 @@ func Test_unicode(t *testing.T) { | ||||
| 	should := require.New(t) | ||||
| 	output, _ := MarshalToString(map[string]interface{}{"a": "数字山谷"}) | ||||
| 	should.Equal(`{"a":"数字山谷"}`, output) | ||||
| 	output, _ = Config{EscapeHtml: false}.Froze().MarshalToString(map[string]interface{}{"a": "数字山谷"}) | ||||
| 	output, _ = Config{EscapeHTML: false}.Froze().MarshalToString(map[string]interface{}{"a": "数字山谷"}) | ||||
| 	should.Equal(`{"a":"数字山谷"}`, output) | ||||
| } | ||||
|  | ||||
| @@ -142,7 +142,7 @@ func Test_unicode_and_escape(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func Test_unsafe_unicode(t *testing.T) { | ||||
| 	ConfigDefault.cleanEncoders() | ||||
| 	ConfigDefault.(*frozenConfig).cleanEncoders() | ||||
| 	should := require.New(t) | ||||
| 	output, err := ConfigDefault.MarshalToString("he\u2029\u2028he") | ||||
| 	should.Nil(err) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user