瀏覽代碼

document public symbols

Tao Wen 8 年之前
父節點
當前提交
f0487718f6

+ 8 - 8
extra/fuzzy_decoder.go

@@ -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

+ 3 - 14
feature_adapter.go

@@ -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)
 }

+ 21 - 14
feature_config.go

@@ -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) {

+ 29 - 23
feature_iter.go

@@ -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 {

+ 2 - 0
feature_iter_array.go

@@ -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 == '[' {

+ 8 - 6
feature_iter_float.go

@@ -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) {

+ 38 - 34
feature_iter_int.go

@@ -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)
 		}

+ 5 - 0
feature_iter_object.go

@@ -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 == '{' {

+ 4 - 3
feature_iter_skip.go

@@ -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

+ 3 - 0
feature_iter_string.go

@@ -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 == '"' {

+ 12 - 0
feature_pool.go

@@ -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:

+ 8 - 14
feature_reflect.go

@@ -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
 }

+ 5 - 0
feature_reflect_extension.go

@@ -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}

+ 23 - 24
feature_reflect_struct_decoder.go

@@ -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())
 	}
-}
+}

+ 8 - 4
feature_stream.go

@@ -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 - 0
jsoniter.go

@@ -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

+ 1 - 1
jsoniter_1dot8_only_test.go

@@ -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)})

+ 19 - 19
jsoniter_any_string_test.go

@@ -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}`,
 }
 

+ 7 - 7
jsoniter_customize_test.go

@@ -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

+ 2 - 2
jsoniter_interface_test.go

@@ -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
 	}

+ 1 - 1
jsoniter_io_test.go

@@ -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) {

+ 2 - 2
jsoniter_string_test.go

@@ -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)