Sfoglia il codice sorgente

#68 number to string

Tao Wen 8 anni fa
parent
commit
818ae1331a

+ 28 - 0
extra/fuzzy_decoder.go

@@ -0,0 +1,28 @@
+package extra
+
+import (
+	"github.com/json-iterator/go"
+	"unsafe"
+	"encoding/json"
+)
+
+func RegisterFuzzyDecoders() {
+	jsoniter.RegisterTypeDecoder("string", &FuzzyStringDecoder{})
+}
+
+type FuzzyStringDecoder struct {
+}
+
+func (decoder *FuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+	valueType := iter.WhatIsNext()
+	switch valueType {
+	case jsoniter.Number:
+		var number json.Number
+		iter.ReadVal(&number)
+		*((*string)(ptr)) = string(number)
+	case jsoniter.String:
+		*((*string)(ptr)) = iter.ReadString()
+	default:
+		iter.ReportError("FuzzyStringDecoder", "not number or string")
+	}
+}

+ 25 - 0
extra/fuzzy_decoder_test.go

@@ -0,0 +1,25 @@
+package extra
+
+import (
+	"testing"
+	"github.com/json-iterator/go"
+	"github.com/json-iterator/go/require"
+)
+
+func init() {
+	RegisterFuzzyDecoders()
+}
+
+func Test_int_to_string(t *testing.T) {
+	should := require.New(t)
+	var val string
+	should.Nil(jsoniter.UnmarshalFromString(`100`, &val))
+	should.Equal("100", val)
+}
+
+func Test_float_to_string(t *testing.T) {
+	should := require.New(t)
+	var val string
+	should.Nil(jsoniter.UnmarshalFromString(`12.0`, &val))
+	should.Equal("12.0", val)
+}

+ 11 - 11
feature_config.go

@@ -91,30 +91,30 @@ func (cfg *frozenConfig) registerExtension(extension Extension) {
 type lossyFloat32Encoder struct {
 }
 
-func (encoder *lossyFloat32Encoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteFloat32Lossy(*((*float32)(ptr)))
 }
 
-func (encoder *lossyFloat32Encoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *lossyFloat32Encoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *lossyFloat32Encoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*float32)(ptr)) == 0
 }
 
 type lossyFloat64Encoder struct {
 }
 
-func (encoder *lossyFloat64Encoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteFloat64Lossy(*((*float64)(ptr)))
 }
 
-func (encoder *lossyFloat64Encoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *lossyFloat64Encoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *lossyFloat64Encoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*float64)(ptr)) == 0
 }
 
@@ -129,16 +129,16 @@ func (cfg *frozenConfig) marshalFloatWith6Digits() {
 type htmlEscapedStringEncoder struct {
 }
 
-func (encoder *htmlEscapedStringEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	str := *((*string)(ptr))
 	stream.WriteStringWithHtmlEscaped(str)
 }
 
-func (encoder *htmlEscapedStringEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *htmlEscapedStringEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *htmlEscapedStringEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*string)(ptr)) == ""
 }
 
@@ -237,7 +237,7 @@ func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
 		return nil
 	}
 	if iter.Error == nil {
-		iter.reportError("UnmarshalFromString", "there are bytes left after unmarshal")
+		iter.ReportError("UnmarshalFromString", "there are bytes left after unmarshal")
 	}
 	return iter.Error
 }
@@ -265,7 +265,7 @@ func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
 		return nil
 	}
 	if iter.Error == nil {
-		iter.reportError("Unmarshal", "there are bytes left after unmarshal")
+		iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
 	}
 	return iter.Error
 }

+ 3 - 3
feature_iter.go

@@ -168,7 +168,7 @@ func (iter *Iterator) nextToken() byte {
 	}
 }
 
-func (iter *Iterator) reportError(operation string, msg string) {
+func (iter *Iterator) ReportError(operation string, msg string) {
 	if iter.Error != nil {
 		if iter.Error != io.EOF {
 			return
@@ -238,7 +238,7 @@ func (iter *Iterator) loadMore() bool {
 
 func (iter *Iterator) unreadByte() {
 	if iter.head == 0 {
-		iter.reportError("unreadByte", "unread too many bytes")
+		iter.ReportError("unreadByte", "unread too many bytes")
 		return
 	}
 	iter.head--
@@ -272,7 +272,7 @@ func (iter *Iterator) Read() interface{} {
 		})
 		return obj
 	default:
-		iter.reportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
+		iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
 		return nil
 	}
 }

+ 2 - 2
feature_iter_array.go

@@ -18,7 +18,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
 	}
 }
@@ -45,6 +45,6 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
 		iter.skipFixedBytes(3)
 		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
 }

+ 2 - 2
feature_iter_float.go

@@ -56,7 +56,7 @@ func (iter *Iterator) ReadBigInt() (ret *big.Int) {
 	var success bool
 	ret, success = ret.SetString(str, 10)
 	if !success {
-		iter.reportError("ReadBigInt", "invalid big int")
+		iter.ReportError("ReadBigInt", "invalid big int")
 		return nil
 	}
 	return ret
@@ -147,7 +147,7 @@ load_loop:
 		return
 	}
 	if len(str) == 0 {
-		iter.reportError("readNumberAsString", "invalid number")
+		iter.ReportError("readNumberAsString", "invalid number")
 	}
 	return *(*string)(unsafe.Pointer(&str))
 }

+ 14 - 14
feature_iter_int.go

@@ -38,14 +38,14 @@ func (iter *Iterator) ReadInt8() (ret int8) {
 	if c == '-' {
 		val := iter.readUint32(iter.readByte())
 		if val > int8Max+1 {
-			iter.reportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
+			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
 			return
 		}
 		return -int8(val)
 	} else {
 		val := iter.readUint32(c)
 		if val > int8Max {
-			iter.reportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
+			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
 			return
 		}
 		return int8(val)
@@ -55,7 +55,7 @@ func (iter *Iterator) ReadInt8() (ret int8) {
 func (iter *Iterator) ReadUint8() (ret uint8) {
 	val := iter.readUint32(iter.nextToken())
 	if val > uint8Max {
-		iter.reportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10))
+		iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10))
 		return
 	}
 	return uint8(val)
@@ -66,14 +66,14 @@ func (iter *Iterator) ReadInt16() (ret int16) {
 	if c == '-' {
 		val := iter.readUint32(iter.readByte())
 		if val > int16Max+1 {
-			iter.reportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
+			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
 			return
 		}
 		return -int16(val)
 	} else {
 		val := iter.readUint32(c)
 		if val > int16Max {
-			iter.reportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
+			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
 			return
 		}
 		return int16(val)
@@ -83,7 +83,7 @@ func (iter *Iterator) ReadInt16() (ret int16) {
 func (iter *Iterator) ReadUint16() (ret uint16) {
 	val := iter.readUint32(iter.nextToken())
 	if val > uint16Max {
-		iter.reportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10))
+		iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10))
 		return
 	}
 	return uint16(val)
@@ -94,14 +94,14 @@ func (iter *Iterator) ReadInt32() (ret int32) {
 	if c == '-' {
 		val := iter.readUint32(iter.readByte())
 		if val > int32Max+1 {
-			iter.reportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
+			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
 			return
 		}
 		return -int32(val)
 	} else {
 		val := iter.readUint32(c)
 		if val > int32Max {
-			iter.reportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
+			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
 			return
 		}
 		return int32(val)
@@ -118,7 +118,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 		return 0 // single zero
 	}
 	if ind == invalidCharForNumber {
-		iter.reportError("readUint32", "unexpected character: "+string([]byte{byte(ind)}))
+		iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)}))
 		return
 	}
 	value := uint32(ind)
@@ -185,7 +185,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
 			if value > uint32SafeToMultiply10 {
 				value2 := (value << 3) + (value << 1) + uint32(ind)
 				if value2 < value {
-					iter.reportError("readUint32", "overflow")
+					iter.ReportError("readUint32", "overflow")
 					return
 				} else {
 					value = value2
@@ -205,14 +205,14 @@ func (iter *Iterator) ReadInt64() (ret int64) {
 	if c == '-' {
 		val := iter.readUint64(iter.readByte())
 		if val > int64Max+1 {
-			iter.reportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
+			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
 			return
 		}
 		return -int64(val)
 	} else {
 		val := iter.readUint64(c)
 		if val > int64Max {
-			iter.reportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
+			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
 			return
 		}
 		return int64(val)
@@ -229,7 +229,7 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
 		return 0 // single zero
 	}
 	if ind == invalidCharForNumber {
-		iter.reportError("readUint64", "unexpected character: "+string([]byte{byte(ind)}))
+		iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)}))
 		return
 	}
 	value := uint64(ind)
@@ -243,7 +243,7 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
 			if value > uint64SafeToMultiple10 {
 				value2 := (value << 3) + (value << 1) + uint64(ind)
 				if value2 < value {
-					iter.reportError("readUint64", "overflow")
+					iter.ReportError("readUint64", "overflow")
 					return
 				} else {
 					value = value2

+ 13 - 13
feature_iter_object.go

@@ -21,14 +21,14 @@ func (iter *Iterator) ReadObject() (ret string) {
 		if c == '}' {
 			return "" // end of object
 		}
-		iter.reportError("ReadObject", `expect " after {`)
+		iter.ReportError("ReadObject", `expect " after {`)
 		return
 	case ',':
 		return string(iter.readObjectFieldAsBytes())
 	case '}':
 		return "" // end of object
 	default:
-		iter.reportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c})))
+		iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c})))
 		return
 	}
 }
@@ -48,7 +48,7 @@ func (iter *Iterator) readFieldHash() int32 {
 					iter.head = i + 1
 					c = iter.nextToken()
 					if c != ':' {
-						iter.reportError("readFieldHash", `expect :, but found `+string([]byte{c}))
+						iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
 					}
 					return int32(hash)
 				}
@@ -56,12 +56,12 @@ func (iter *Iterator) readFieldHash() int32 {
 				hash *= 0x1000193
 			}
 			if !iter.loadMore() {
-				iter.reportError("readFieldHash", `incomplete field name`)
+				iter.ReportError("readFieldHash", `incomplete field name`)
 				return 0
 			}
 		}
 	}
-	iter.reportError("readFieldHash", `expect ", but found `+string([]byte{c}))
+	iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
 	return 0
 }
 
@@ -95,14 +95,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 }`)
 		return false
 	}
 	if c == 'n' {
 		iter.skipFixedBytes(3)
 		return true // null
 	}
-	iter.reportError("ReadObjectCB", `expect { or n`)
+	iter.ReportError("ReadObjectCB", `expect { or n`)
 	return false
 }
 
@@ -114,7 +114,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")
 				return false
 			}
 			if !callback(iter, field) {
@@ -123,7 +123,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
 			for iter.nextToken() == ',' {
 				field = iter.ReadString()
 				if iter.nextToken() != ':' {
-					iter.reportError("ReadMapCB", "expect : after object field")
+					iter.ReportError("ReadMapCB", "expect : after object field")
 					return false
 				}
 				if !callback(iter, field) {
@@ -135,14 +135,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 }`)
 		return false
 	}
 	if c == 'n' {
 		iter.skipFixedBytes(3)
 		return true // null
 	}
-	iter.reportError("ReadMapCB", `expect { or n`)
+	iter.ReportError("ReadMapCB", `expect { or n`)
 	return false
 }
 
@@ -159,7 +159,7 @@ func (iter *Iterator) readObjectStart() bool {
 		iter.skipFixedBytes(3)
 		return false
 	}
-	iter.reportError("readObjectStart", "expect { or n")
+	iter.ReportError("readObjectStart", "expect { or n")
 	return false
 }
 
@@ -175,7 +175,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")
 		return
 	}
 	iter.head++

+ 6 - 6
feature_iter_skip.go

@@ -25,7 +25,7 @@ func (iter *Iterator) ReadBool() (ret bool) {
 		iter.skipFixedBytes(4)
 		return false
 	}
-	iter.reportError("ReadBool", "expect t or f")
+	iter.ReportError("ReadBool", "expect t or f")
 	return
 }
 
@@ -81,7 +81,7 @@ func (iter *Iterator) Skip() {
 	case '{':
 		iter.skipObject()
 	default:
-		iter.reportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
+		iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
 		return
 	}
 }
@@ -91,7 +91,7 @@ func (iter *Iterator) skipString() {
 		end, escaped := iter.findStringEnd()
 		if end == -1 {
 			if !iter.loadMore() {
-				iter.reportError("skipString", "incomplete string")
+				iter.ReportError("skipString", "incomplete string")
 				return
 			}
 			if escaped {
@@ -175,7 +175,7 @@ func (iter *Iterator) skipArray() {
 			}
 		}
 		if !iter.loadMore() {
-			iter.reportError("skipObject", "incomplete array")
+			iter.ReportError("skipObject", "incomplete array")
 			return
 		}
 	}
@@ -203,7 +203,7 @@ func (iter *Iterator) skipObject() {
 			}
 		}
 		if !iter.loadMore() {
-			iter.reportError("skipObject", "incomplete object")
+			iter.ReportError("skipObject", "incomplete object")
 			return
 		}
 	}
@@ -231,7 +231,7 @@ func (iter *Iterator) skipFixedBytes(n int) {
 		more := iter.head - iter.tail
 		if !iter.loadMore() {
 			if more > 0 {
-				iter.reportError("skipFixedBytes", "unexpected end")
+				iter.ReportError("skipFixedBytes", "unexpected end")
 			}
 			return
 		}

+ 7 - 7
feature_iter_string.go

@@ -22,7 +22,7 @@ func (iter *Iterator) ReadString() (ret string) {
 		iter.skipFixedBytes(3)
 		return ""
 	}
-	iter.reportError("ReadString", `expects " or n`)
+	iter.ReportError("ReadString", `expects " or n`)
 	return
 }
 
@@ -45,7 +45,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) {
 						return
 					}
 					if c != '\\' {
-						iter.reportError("ReadString",
+						iter.ReportError("ReadString",
 							`expects \u after utf16 surrogate, but \ not found`)
 						return
 					}
@@ -54,7 +54,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) {
 						return
 					}
 					if c != 'u' && c != 'U' {
-						iter.reportError("ReadString",
+						iter.ReportError("ReadString",
 							`expects \u after utf16 surrogate, but \u not found`)
 						return
 					}
@@ -84,7 +84,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) {
 			case 't':
 				str = append(str, '\t')
 			default:
-				iter.reportError("ReadString",
+				iter.ReportError("ReadString",
 					`invalid escape char after \`)
 				return
 			}
@@ -92,7 +92,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) {
 			str = append(str, c)
 		}
 	}
-	iter.reportError("ReadString", "unexpected end of input")
+	iter.ReportError("ReadString", "unexpected end of input")
 	return
 }
 
@@ -122,7 +122,7 @@ func (iter *Iterator) ReadStringAsSlice() (ret []byte) {
 		}
 		return copied
 	}
-	iter.reportError("ReadString", `expects " or n`)
+	iter.ReportError("ReadString", `expects " or n`)
 	return
 }
 
@@ -139,7 +139,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")
 			return
 		}
 	}

+ 23 - 47
feature_reflect.go

@@ -20,16 +20,16 @@ import (
 // 3. assignment to map, both key and value will be reflect.Value
 // For a simple struct binding, it will be reflect.Value free and allocation free
 type ValDecoder interface {
-	decode(ptr unsafe.Pointer, iter *Iterator)
+	Decode(ptr unsafe.Pointer, iter *Iterator)
 }
 
 // ValEncoder is an internal type registered to cache as needed.
 // Don't confuse jsoniter.ValEncoder with json.Encoder.
 // For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
 type ValEncoder interface {
-	isEmpty(ptr unsafe.Pointer) bool
-	encode(ptr unsafe.Pointer, stream *Stream)
-	encodeInterface(val interface{}, stream *Stream)
+	IsEmpty(ptr unsafe.Pointer) bool
+	Encode(ptr unsafe.Pointer, stream *Stream)
+	EncodeInterface(val interface{}, stream *Stream)
 }
 
 func writeToStream(val interface{}, stream *Stream, encoder ValEncoder) {
@@ -39,39 +39,15 @@ func writeToStream(val interface{}, stream *Stream, encoder ValEncoder) {
 		return
 	}
 	if reflect.TypeOf(val).Kind() == reflect.Ptr {
-		encoder.encode(unsafe.Pointer(&e.word), stream)
+		encoder.Encode(unsafe.Pointer(&e.word), stream)
 	} else {
-		encoder.encode(e.word, stream)
+		encoder.Encode(e.word, stream)
 	}
 }
 
 type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
 type EncoderFunc func(ptr unsafe.Pointer, stream *Stream)
 
-func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.fun(ptr, iter)
-}
-
-type funcEncoder struct {
-	fun         EncoderFunc
-	isEmptyFunc func(ptr unsafe.Pointer) bool
-}
-
-func (encoder *funcEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
-	encoder.fun(ptr, stream)
-}
-
-func (encoder *funcEncoder) encodeInterface(val interface{}, stream *Stream) {
-	writeToStream(val, stream, encoder)
-}
-
-func (encoder *funcEncoder) isEmpty(ptr unsafe.Pointer) bool {
-	if encoder.isEmptyFunc == nil {
-		return false
-	}
-	return encoder.isEmptyFunc(ptr)
-}
-
 var jsonNumberType reflect.Type
 var jsonRawMessageType reflect.Type
 var jsoniterRawMessageType reflect.Type
@@ -95,18 +71,18 @@ type optionalDecoder struct {
 	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)
-			decoder.valueDecoder.decode(unsafe.Pointer(value.Pointer()), iter)
+			decoder.valueDecoder.Decode(unsafe.Pointer(value.Pointer()), iter)
 			*((*uintptr)(ptr)) = value.Pointer()
 		} else {
 			// reuse existing instance
-			decoder.valueDecoder.decode(*((*unsafe.Pointer)(ptr)), iter)
+			decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
 		}
 	}
 }
@@ -115,23 +91,23 @@ type optionalEncoder struct {
 	valueEncoder ValEncoder
 }
 
-func (encoder *optionalEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	if *((*unsafe.Pointer)(ptr)) == nil {
 		stream.WriteNil()
 	} else {
-		encoder.valueEncoder.encode(*((*unsafe.Pointer)(ptr)), stream)
+		encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
 	}
 }
 
-func (encoder *optionalEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *optionalEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	if *((*unsafe.Pointer)(ptr)) == nil {
 		return true
 	} else {
-		return encoder.valueEncoder.isEmpty(*((*unsafe.Pointer)(ptr)))
+		return encoder.valueEncoder.IsEmpty(*((*unsafe.Pointer)(ptr)))
 	}
 }
 
@@ -140,16 +116,16 @@ type placeholderEncoder struct {
 	cacheKey reflect.Type
 }
 
-func (encoder *placeholderEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
-	encoder.getRealEncoder().encode(ptr, stream)
+func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.getRealEncoder().Encode(ptr, stream)
 }
 
-func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *placeholderEncoder) isEmpty(ptr unsafe.Pointer) bool {
-	return encoder.getRealEncoder().isEmpty(ptr)
+func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.getRealEncoder().IsEmpty(ptr)
 }
 
 func (encoder *placeholderEncoder) getRealEncoder() ValEncoder {
@@ -170,14 +146,14 @@ type placeholderDecoder struct {
 	cacheKey reflect.Type
 }
 
-func (decoder *placeholderDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	for i := 0; i < 30; i++ {
 		realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey)
 		_, isPlaceholder := realDecoder.(*placeholderDecoder)
 		if isPlaceholder {
 			time.Sleep(time.Second)
 		} else {
-			realDecoder.decode(ptr, iter)
+			realDecoder.Decode(ptr, iter)
 			return
 		}
 	}
@@ -214,7 +190,7 @@ func (iter *Iterator) ReadVal(obj interface{}) {
 		return
 	}
 	e := (*emptyInterface)(unsafe.Pointer(&obj))
-	decoder.decode(e.word, iter)
+	decoder.Decode(e.word, iter)
 }
 
 func (stream *Stream) WriteVal(val interface{}) {
@@ -229,7 +205,7 @@ func (stream *Stream) WriteVal(val interface{}) {
 		stream.Error = err
 		return
 	}
-	encoder.encodeInterface(val, stream)
+	encoder.EncodeInterface(val, stream)
 }
 
 type prefix string

+ 7 - 7
feature_reflect_array.go

@@ -32,18 +32,18 @@ type arrayEncoder struct {
 	elemEncoder ValEncoder
 }
 
-func (encoder *arrayEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	if ptr == nil {
 		stream.WriteNil()
 		return
 	}
 	stream.WriteArrayStart()
 	elemPtr := uintptr(ptr)
-	encoder.elemEncoder.encode(unsafe.Pointer(elemPtr), stream)
+	encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
 	for i := 1; i < encoder.arrayType.Len(); i++ {
 		stream.WriteMore()
 		elemPtr += encoder.elemType.Size()
-		encoder.elemEncoder.encode(unsafe.Pointer(elemPtr), stream)
+		encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
 	}
 	stream.WriteArrayEnd()
 	if stream.Error != nil && stream.Error != io.EOF {
@@ -51,11 +51,11 @@ func (encoder *arrayEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
 	}
 }
 
-func (encoder *arrayEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *arrayEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *arrayEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return false
 }
 
@@ -65,7 +65,7 @@ type arrayDecoder struct {
 	elemDecoder ValDecoder
 }
 
-func (decoder *arrayDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	decoder.doDecode(ptr, iter)
 	if iter.Error != nil && iter.Error != io.EOF {
 		iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
@@ -76,7 +76,7 @@ func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
 	offset := uintptr(0)
 	for ; iter.ReadArray(); offset += decoder.elemType.Size() {
 		if offset < decoder.arrayType.Size() {
-			decoder.elemDecoder.decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
+			decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
 		} else {
 			iter.Skip()
 		}

+ 23 - 0
feature_reflect_extension.go

@@ -59,6 +59,29 @@ func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
 type funcDecoder struct {
 	fun DecoderFunc
 }
+func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.fun(ptr, iter)
+}
+
+type funcEncoder struct {
+	fun         EncoderFunc
+	isEmptyFunc func(ptr unsafe.Pointer) bool
+}
+
+func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	encoder.fun(ptr, stream)
+}
+
+func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	writeToStream(val, stream, encoder)
+}
+
+func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	if encoder.isEmptyFunc == nil {
+		return false
+	}
+	return encoder.isEmptyFunc(ptr)
+}
 
 func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
 	typeDecoders[typ] = &funcDecoder{fun}

+ 14 - 14
feature_reflect_map.go

@@ -17,7 +17,7 @@ type mapDecoder struct {
 	mapInterface emptyInterface
 }
 
-func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	// dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
 	mapInterface := decoder.mapInterface
 	mapInterface.word = ptr
@@ -28,7 +28,7 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 	}
 	iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
 		elem := reflect.New(decoder.elemType)
-		decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)
+		decoder.elemDecoder.Decode(unsafe.Pointer(elem.Pointer()), iter)
 		// to put into map, we have to use reflection
 		keyType := decoder.keyType
 		switch {
@@ -39,7 +39,7 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 			textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
 			err := textUnmarshaler.UnmarshalText([]byte(keyStr))
 			if err != nil {
-				iter.reportError("read map key as TextUnmarshaler", err.Error())
+				iter.ReportError("read map key as TextUnmarshaler", err.Error())
 				return false
 			}
 			realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
@@ -49,7 +49,7 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 				n, err := strconv.ParseInt(keyStr, 10, 64)
 				if err != nil || reflect.Zero(keyType).OverflowInt(n) {
-					iter.reportError("read map key as int64", "read int64 failed")
+					iter.ReportError("read map key as int64", "read int64 failed")
 					return false
 				}
 				realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
@@ -57,14 +57,14 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 				n, err := strconv.ParseUint(keyStr, 10, 64)
 				if err != nil || reflect.Zero(keyType).OverflowUint(n) {
-					iter.reportError("read map key as uint64", "read uint64 failed")
+					iter.ReportError("read map key as uint64", "read uint64 failed")
 					return false
 				}
 				realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
 				return true
 			}
 		}
-		iter.reportError("read map key", "unexpected map key type "+keyType.String())
+		iter.ReportError("read map key", "unexpected map key type "+keyType.String())
 		return true
 	})
 }
@@ -76,7 +76,7 @@ type mapEncoder struct {
 	mapInterface emptyInterface
 }
 
-func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	mapInterface := encoder.mapInterface
 	mapInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
@@ -90,7 +90,7 @@ func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
 		encodeMapKey(key, stream)
 		stream.writeByte(':')
 		val := realVal.MapIndex(key).Interface()
-		encoder.elemEncoder.encodeInterface(val, stream)
+		encoder.elemEncoder.EncodeInterface(val, stream)
 	}
 	stream.WriteObjectEnd()
 }
@@ -126,11 +126,11 @@ func encodeMapKey(key reflect.Value, stream *Stream) {
 	stream.Error = &json.UnsupportedTypeError{key.Type()}
 }
 
-func (encoder *mapEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *mapEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *mapEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	mapInterface := encoder.mapInterface
 	mapInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
@@ -145,7 +145,7 @@ type sortKeysMapEncoder struct {
 	mapInterface emptyInterface
 }
 
-func (encoder *sortKeysMapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	mapInterface := encoder.mapInterface
 	mapInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
@@ -163,7 +163,7 @@ func (encoder *sortKeysMapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
 		encodeMapKey(key, stream)
 		stream.writeByte(':')
 		val := realVal.MapIndex(key).Interface()
-		encoder.elemEncoder.encodeInterface(val, stream)
+		encoder.elemEncoder.EncodeInterface(val, stream)
 	}
 	stream.WriteObjectEnd()
 }
@@ -177,11 +177,11 @@ func (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
 func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
 func (sv stringValues) get(i int) string   { return sv[i].String() }
 
-func (encoder *sortKeysMapEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *sortKeysMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *sortKeysMapEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	mapInterface := encoder.mapInterface
 	mapInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&mapInterface))

+ 100 - 100
feature_reflect_native.go

@@ -9,296 +9,296 @@ import (
 type stringCodec struct {
 }
 
-func (codec *stringCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*string)(ptr)) = iter.ReadString()
 }
 
-func (codec *stringCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	str := *((*string)(ptr))
 	stream.WriteString(str)
 }
 
-func (codec *stringCodec) encodeInterface(val interface{}, stream *Stream) {
+func (codec *stringCodec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, codec)
 }
 
-func (codec *stringCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*string)(ptr)) == ""
 }
 
 type intCodec struct {
 }
 
-func (codec *intCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*int)(ptr)) = iter.ReadInt()
 }
 
-func (codec *intCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteInt(*((*int)(ptr)))
 }
 
-func (encoder *intCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *intCodec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *intCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *intCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*int)(ptr)) == 0
 }
 
 type int8Codec struct {
 }
 
-func (codec *int8Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*int8)(ptr)) = iter.ReadInt8()
 }
 
-func (codec *int8Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteInt8(*((*int8)(ptr)))
 }
 
-func (encoder *int8Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *int8Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *int8Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*int8)(ptr)) == 0
 }
 
 type int16Codec struct {
 }
 
-func (codec *int16Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*int16)(ptr)) = iter.ReadInt16()
 }
 
-func (codec *int16Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteInt16(*((*int16)(ptr)))
 }
 
-func (encoder *int16Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *int16Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *int16Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*int16)(ptr)) == 0
 }
 
 type int32Codec struct {
 }
 
-func (codec *int32Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*int32)(ptr)) = iter.ReadInt32()
 }
 
-func (codec *int32Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteInt32(*((*int32)(ptr)))
 }
 
-func (encoder *int32Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *int32Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *int32Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*int32)(ptr)) == 0
 }
 
 type int64Codec struct {
 }
 
-func (codec *int64Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*int64)(ptr)) = iter.ReadInt64()
 }
 
-func (codec *int64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteInt64(*((*int64)(ptr)))
 }
 
-func (encoder *int64Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *int64Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *int64Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*int64)(ptr)) == 0
 }
 
 type uintCodec struct {
 }
 
-func (codec *uintCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*uint)(ptr)) = iter.ReadUint()
 }
 
-func (codec *uintCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteUint(*((*uint)(ptr)))
 }
 
-func (encoder *uintCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *uintCodec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *uintCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *uintCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*uint)(ptr)) == 0
 }
 
 type uint8Codec struct {
 }
 
-func (codec *uint8Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*uint8)(ptr)) = iter.ReadUint8()
 }
 
-func (codec *uint8Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteUint8(*((*uint8)(ptr)))
 }
 
-func (encoder *uint8Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *uint8Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *uint8Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*uint8)(ptr)) == 0
 }
 
 type uint16Codec struct {
 }
 
-func (decoder *uint16Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*uint16)(ptr)) = iter.ReadUint16()
 }
 
-func (codec *uint16Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteUint16(*((*uint16)(ptr)))
 }
 
-func (encoder *uint16Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *uint16Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *uint16Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*uint16)(ptr)) == 0
 }
 
 type uint32Codec struct {
 }
 
-func (codec *uint32Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*uint32)(ptr)) = iter.ReadUint32()
 }
 
-func (codec *uint32Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteUint32(*((*uint32)(ptr)))
 }
 
-func (encoder *uint32Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *uint32Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *uint32Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*uint32)(ptr)) == 0
 }
 
 type uint64Codec struct {
 }
 
-func (codec *uint64Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*uint64)(ptr)) = iter.ReadUint64()
 }
 
-func (codec *uint64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteUint64(*((*uint64)(ptr)))
 }
 
-func (encoder *uint64Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *uint64Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *uint64Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*uint64)(ptr)) == 0
 }
 
 type float32Codec struct {
 }
 
-func (codec *float32Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*float32)(ptr)) = iter.ReadFloat32()
 }
 
-func (codec *float32Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteFloat32(*((*float32)(ptr)))
 }
 
-func (encoder *float32Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *float32Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *float32Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*float32)(ptr)) == 0
 }
 
 type float64Codec struct {
 }
 
-func (codec *float64Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*float64)(ptr)) = iter.ReadFloat64()
 }
 
-func (codec *float64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteFloat64(*((*float64)(ptr)))
 }
 
-func (encoder *float64Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *float64Codec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *float64Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return *((*float64)(ptr)) == 0
 }
 
 type boolCodec struct {
 }
 
-func (codec *boolCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*bool)(ptr)) = iter.ReadBool()
 }
 
-func (codec *boolCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteBool(*((*bool)(ptr)))
 }
 
-func (encoder *boolCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *boolCodec) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (codec *boolCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return !(*((*bool)(ptr)))
 }
 
 type emptyInterfaceCodec struct {
 }
 
-func (codec *emptyInterfaceCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*interface{})(ptr)) = iter.Read()
 }
 
-func (codec *emptyInterfaceCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteVal(*((*interface{})(ptr)))
 }
 
-func (encoder *emptyInterfaceCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *emptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) {
 	stream.WriteVal(val)
 }
 
-func (codec *emptyInterfaceCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *emptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return ptr == nil
 }
 
 type nonEmptyInterfaceCodec struct {
 }
 
-func (codec *nonEmptyInterfaceCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *nonEmptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	nonEmptyInterface := (*nonEmptyInterface)(ptr)
 	if nonEmptyInterface.itab == nil {
-		iter.reportError("read non-empty interface", "do not know which concrete type to decode to")
+		iter.ReportError("read non-empty interface", "do not know which concrete type to decode to")
 		return
 	}
 	var i interface{}
@@ -309,7 +309,7 @@ func (codec *nonEmptyInterfaceCodec) decode(ptr unsafe.Pointer, iter *Iterator)
 	nonEmptyInterface.word = e.word
 }
 
-func (codec *nonEmptyInterfaceCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *nonEmptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	nonEmptyInterface := (*nonEmptyInterface)(ptr)
 	var i interface{}
 	e := (*emptyInterface)(unsafe.Pointer(&i))
@@ -318,11 +318,11 @@ func (codec *nonEmptyInterfaceCodec) encode(ptr unsafe.Pointer, stream *Stream)
 	stream.WriteVal(i)
 }
 
-func (encoder *nonEmptyInterfaceCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *nonEmptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) {
 	stream.WriteVal(val)
 }
 
-func (codec *nonEmptyInterfaceCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (codec *nonEmptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	nonEmptyInterface := (*nonEmptyInterface)(ptr)
 	return nonEmptyInterface.word == nil
 }
@@ -330,83 +330,83 @@ func (codec *nonEmptyInterfaceCodec) isEmpty(ptr unsafe.Pointer) bool {
 type anyCodec struct {
 }
 
-func (codec *anyCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*Any)(ptr)) = iter.ReadAny()
 }
 
-func (codec *anyCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	(*((*Any)(ptr))).WriteTo(stream)
 }
 
-func (encoder *anyCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *anyCodec) EncodeInterface(val interface{}, stream *Stream) {
 	(val.(Any)).WriteTo(stream)
 }
 
-func (encoder *anyCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return (*((*Any)(ptr))).Size() == 0
 }
 
 type jsonNumberCodec struct {
 }
 
-func (codec *jsonNumberCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
 }
 
-func (codec *jsonNumberCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteRaw(string(*((*json.Number)(ptr))))
 }
 
-func (encoder *jsonNumberCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *jsonNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
 	stream.WriteRaw(string(val.(json.Number)))
 }
 
-func (encoder *jsonNumberCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return len(*((*json.Number)(ptr))) == 0
 }
 
 type jsonRawMessageCodec struct {
 }
 
-func (codec *jsonRawMessageCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
 }
 
-func (codec *jsonRawMessageCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
 }
 
-func (encoder *jsonRawMessageCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *jsonRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) {
 	stream.WriteRaw(string(val.(json.RawMessage)))
 }
 
-func (encoder *jsonRawMessageCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return len(*((*json.RawMessage)(ptr))) == 0
 }
 
 type jsoniterRawMessageCodec struct {
 }
 
-func (codec *jsoniterRawMessageCodec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
 }
 
-func (codec *jsoniterRawMessageCodec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteRaw(string(*((*RawMessage)(ptr))))
 }
 
-func (encoder *jsoniterRawMessageCodec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *jsoniterRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) {
 	stream.WriteRaw(string(val.(RawMessage)))
 }
 
-func (encoder *jsoniterRawMessageCodec) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return len(*((*RawMessage)(ptr))) == 0
 }
 
 type base64Codec struct {
 }
 
-func (codec *base64Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	encoding := base64.StdEncoding
 	src := iter.SkipAndReturnBytes()
 	src = src[1 : len(src)-1]
@@ -414,13 +414,13 @@ func (codec *base64Codec) decode(ptr unsafe.Pointer, iter *Iterator) {
 	dst := make([]byte, decodedLen)
 	_, err := encoding.Decode(dst, src)
 	if err != nil {
-		iter.reportError("decode base64", err.Error())
+		iter.ReportError("decode base64", err.Error())
 	} else {
 		*((*[]byte)(ptr)) = dst
 	}
 }
 
-func (codec *base64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
+func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
 	encoding := base64.StdEncoding
 	stream.writeByte('"')
 	src := *((*[]byte)(ptr))
@@ -431,7 +431,7 @@ func (codec *base64Codec) encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.writeByte('"')
 }
 
-func (encoder *base64Codec) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *base64Codec) EncodeInterface(val interface{}, stream *Stream) {
 	encoding := base64.StdEncoding
 	stream.writeByte('"')
 	src := val.([]byte)
@@ -442,7 +442,7 @@ func (encoder *base64Codec) encodeInterface(val interface{}, stream *Stream) {
 	stream.writeByte('"')
 }
 
-func (encoder *base64Codec) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return len(*((*[]byte)(ptr))) == 0
 }
 
@@ -450,19 +450,19 @@ type stringModeDecoder struct {
 	elemDecoder ValDecoder
 }
 
-func (decoder *stringModeDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *stringModeDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	c := iter.nextToken()
 	if c != '"' {
-		iter.reportError("stringModeDecoder", `expect "`)
+		iter.ReportError("stringModeDecoder", `expect "`)
 		return
 	}
-	decoder.elemDecoder.decode(ptr, iter)
+	decoder.elemDecoder.Decode(ptr, iter)
 	if iter.Error != nil {
 		return
 	}
 	c = iter.readByte()
 	if c != '"' {
-		iter.reportError("stringModeDecoder", `expect "`)
+		iter.ReportError("stringModeDecoder", `expect "`)
 		return
 	}
 }
@@ -471,25 +471,25 @@ type stringModeEncoder struct {
 	elemEncoder ValEncoder
 }
 
-func (encoder *stringModeEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *stringModeEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.writeByte('"')
-	encoder.elemEncoder.encode(ptr, stream)
+	encoder.elemEncoder.Encode(ptr, stream)
 	stream.writeByte('"')
 }
 
-func (encoder *stringModeEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *stringModeEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *stringModeEncoder) isEmpty(ptr unsafe.Pointer) bool {
-	return encoder.elemEncoder.isEmpty(ptr)
+func (encoder *stringModeEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.elemEncoder.IsEmpty(ptr)
 }
 
 type marshalerEncoder struct {
 	templateInterface emptyInterface
 }
 
-func (encoder *marshalerEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	templateInterface := encoder.templateInterface
 	templateInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
@@ -501,11 +501,11 @@ func (encoder *marshalerEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
 		stream.Write(bytes)
 	}
 }
-func (encoder *marshalerEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *marshalerEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *marshalerEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	templateInterface := encoder.templateInterface
 	templateInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
@@ -522,7 +522,7 @@ type unmarshalerDecoder struct {
 	templateInterface emptyInterface
 }
 
-func (decoder *unmarshalerDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	templateInterface := decoder.templateInterface
 	templateInterface.word = ptr
 	realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
@@ -530,6 +530,6 @@ func (decoder *unmarshalerDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
 	bytes := iter.SkipAndReturnBytes()
 	err := unmarshaler.UnmarshalJSON(bytes)
 	if err != nil {
-		iter.reportError("unmarshaler", err.Error())
+		iter.ReportError("unmarshaler", err.Error())
 	}
 }

+ 85 - 85
feature_reflect_object.go

@@ -463,7 +463,7 @@ type generalStructDecoder struct {
 	fields map[string]*structFieldDecoder
 }
 
-func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
@@ -473,7 +473,7 @@ func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator)
 	if fieldDecoder == nil {
 		iter.Skip()
 	} else {
-		fieldDecoder.decode(ptr, iter)
+		fieldDecoder.Decode(ptr, iter)
 	}
 	for iter.nextToken() == ',' {
 		fieldBytes = iter.readObjectFieldAsBytes()
@@ -482,7 +482,7 @@ func (decoder *generalStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator)
 		if fieldDecoder == nil {
 			iter.Skip()
 		} else {
-			fieldDecoder.decode(ptr, iter)
+			fieldDecoder.Decode(ptr, iter)
 		}
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
@@ -494,7 +494,7 @@ type skipDecoder struct {
 	typ reflect.Type
 }
 
-func (decoder *skipDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *skipDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	iter.Skip()
 	if iter.Error != nil && iter.Error != io.EOF {
 		iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
@@ -507,13 +507,13 @@ type oneFieldStructDecoder struct {
 	fieldDecoder *structFieldDecoder
 }
 
-func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		if iter.readFieldHash() == decoder.fieldHash {
-			decoder.fieldDecoder.decode(ptr, iter)
+			decoder.fieldDecoder.Decode(ptr, iter)
 		} else {
 			iter.Skip()
 		}
@@ -534,16 +534,16 @@ type twoFieldsStructDecoder struct {
 	fieldDecoder2 *structFieldDecoder
 }
 
-func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -566,18 +566,18 @@ type threeFieldsStructDecoder struct {
 	fieldDecoder3 *structFieldDecoder
 }
 
-func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -602,20 +602,20 @@ type fourFieldsStructDecoder struct {
 	fieldDecoder4 *structFieldDecoder
 }
 
-func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -642,22 +642,22 @@ type fiveFieldsStructDecoder struct {
 	fieldDecoder5 *structFieldDecoder
 }
 
-func (decoder *fiveFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		case decoder.fieldHash5:
-			decoder.fieldDecoder5.decode(ptr, iter)
+			decoder.fieldDecoder5.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -686,24 +686,24 @@ type sixFieldsStructDecoder struct {
 	fieldDecoder6 *structFieldDecoder
 }
 
-func (decoder *sixFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		case decoder.fieldHash5:
-			decoder.fieldDecoder5.decode(ptr, iter)
+			decoder.fieldDecoder5.Decode(ptr, iter)
 		case decoder.fieldHash6:
-			decoder.fieldDecoder6.decode(ptr, iter)
+			decoder.fieldDecoder6.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -734,26 +734,26 @@ type sevenFieldsStructDecoder struct {
 	fieldDecoder7 *structFieldDecoder
 }
 
-func (decoder *sevenFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		case decoder.fieldHash5:
-			decoder.fieldDecoder5.decode(ptr, iter)
+			decoder.fieldDecoder5.Decode(ptr, iter)
 		case decoder.fieldHash6:
-			decoder.fieldDecoder6.decode(ptr, iter)
+			decoder.fieldDecoder6.Decode(ptr, iter)
 		case decoder.fieldHash7:
-			decoder.fieldDecoder7.decode(ptr, iter)
+			decoder.fieldDecoder7.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -786,28 +786,28 @@ type eightFieldsStructDecoder struct {
 	fieldDecoder8 *structFieldDecoder
 }
 
-func (decoder *eightFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		case decoder.fieldHash5:
-			decoder.fieldDecoder5.decode(ptr, iter)
+			decoder.fieldDecoder5.Decode(ptr, iter)
 		case decoder.fieldHash6:
-			decoder.fieldDecoder6.decode(ptr, iter)
+			decoder.fieldDecoder6.Decode(ptr, iter)
 		case decoder.fieldHash7:
-			decoder.fieldDecoder7.decode(ptr, iter)
+			decoder.fieldDecoder7.Decode(ptr, iter)
 		case decoder.fieldHash8:
-			decoder.fieldDecoder8.decode(ptr, iter)
+			decoder.fieldDecoder8.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -842,30 +842,30 @@ type nineFieldsStructDecoder struct {
 	fieldDecoder9 *structFieldDecoder
 }
 
-func (decoder *nineFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		case decoder.fieldHash5:
-			decoder.fieldDecoder5.decode(ptr, iter)
+			decoder.fieldDecoder5.Decode(ptr, iter)
 		case decoder.fieldHash6:
-			decoder.fieldDecoder6.decode(ptr, iter)
+			decoder.fieldDecoder6.Decode(ptr, iter)
 		case decoder.fieldHash7:
-			decoder.fieldDecoder7.decode(ptr, iter)
+			decoder.fieldDecoder7.Decode(ptr, iter)
 		case decoder.fieldHash8:
-			decoder.fieldDecoder8.decode(ptr, iter)
+			decoder.fieldDecoder8.Decode(ptr, iter)
 		case decoder.fieldHash9:
-			decoder.fieldDecoder9.decode(ptr, iter)
+			decoder.fieldDecoder9.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -902,32 +902,32 @@ type tenFieldsStructDecoder struct {
 	fieldDecoder10 *structFieldDecoder
 }
 
-func (decoder *tenFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	if !iter.readObjectStart() {
 		return
 	}
 	for {
 		switch iter.readFieldHash() {
 		case decoder.fieldHash1:
-			decoder.fieldDecoder1.decode(ptr, iter)
+			decoder.fieldDecoder1.Decode(ptr, iter)
 		case decoder.fieldHash2:
-			decoder.fieldDecoder2.decode(ptr, iter)
+			decoder.fieldDecoder2.Decode(ptr, iter)
 		case decoder.fieldHash3:
-			decoder.fieldDecoder3.decode(ptr, iter)
+			decoder.fieldDecoder3.Decode(ptr, iter)
 		case decoder.fieldHash4:
-			decoder.fieldDecoder4.decode(ptr, iter)
+			decoder.fieldDecoder4.Decode(ptr, iter)
 		case decoder.fieldHash5:
-			decoder.fieldDecoder5.decode(ptr, iter)
+			decoder.fieldDecoder5.Decode(ptr, iter)
 		case decoder.fieldHash6:
-			decoder.fieldDecoder6.decode(ptr, iter)
+			decoder.fieldDecoder6.Decode(ptr, iter)
 		case decoder.fieldHash7:
-			decoder.fieldDecoder7.decode(ptr, iter)
+			decoder.fieldDecoder7.Decode(ptr, iter)
 		case decoder.fieldHash8:
-			decoder.fieldDecoder8.decode(ptr, iter)
+			decoder.fieldDecoder8.Decode(ptr, iter)
 		case decoder.fieldHash9:
-			decoder.fieldDecoder9.decode(ptr, iter)
+			decoder.fieldDecoder9.Decode(ptr, iter)
 		case decoder.fieldHash10:
-			decoder.fieldDecoder10.decode(ptr, iter)
+			decoder.fieldDecoder10.Decode(ptr, iter)
 		default:
 			iter.Skip()
 		}
@@ -945,9 +945,9 @@ type structFieldDecoder struct {
 	fieldDecoder ValDecoder
 }
 
-func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	fieldPtr := uintptr(ptr) + decoder.field.Offset
-	decoder.fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter)
+	decoder.fieldDecoder.Decode(unsafe.Pointer(fieldPtr), iter)
 	if iter.Error != nil && iter.Error != io.EOF {
 		iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
 	}
@@ -959,45 +959,45 @@ type structFieldEncoder struct {
 	omitempty    bool
 }
 
-func (encoder *structFieldEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	fieldPtr := uintptr(ptr) + encoder.field.Offset
-	encoder.fieldEncoder.encode(unsafe.Pointer(fieldPtr), stream)
+	encoder.fieldEncoder.Encode(unsafe.Pointer(fieldPtr), stream)
 	if stream.Error != nil && stream.Error != io.EOF {
 		stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
 	}
 }
 
-func (encoder *structFieldEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *structFieldEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	fieldPtr := uintptr(ptr) + encoder.field.Offset
-	return encoder.fieldEncoder.isEmpty(unsafe.Pointer(fieldPtr))
+	return encoder.fieldEncoder.IsEmpty(unsafe.Pointer(fieldPtr))
 }
 
 type structEncoder struct {
 	fields map[string]*structFieldEncoder
 }
 
-func (encoder *structEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteObjectStart()
 	isNotFirst := false
 	for fieldName, field := range encoder.fields {
-		if field.omitempty && field.isEmpty(ptr) {
+		if field.omitempty && field.IsEmpty(ptr) {
 			continue
 		}
 		if isNotFirst {
 			stream.WriteMore()
 		}
 		stream.WriteObjectField(fieldName)
-		field.encode(ptr, stream)
+		field.Encode(ptr, stream)
 		isNotFirst = true
 	}
 	stream.WriteObjectEnd()
 }
 
-func (encoder *structEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	var encoderToUse ValEncoder
 	encoderToUse = encoder
 	if len(encoder.fields) == 1 {
@@ -1024,9 +1024,9 @@ func (encoder *structEncoder) encodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoderToUse)
 }
 
-func (encoder *structEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	for _, field := range encoder.fields {
-		if !field.isEmpty(ptr) {
+		if !field.IsEmpty(ptr) {
 			return false
 		}
 	}
@@ -1036,14 +1036,14 @@ func (encoder *structEncoder) isEmpty(ptr unsafe.Pointer) bool {
 type emptyStructEncoder struct {
 }
 
-func (encoder *emptyStructEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.WriteEmptyObject()
 }
 
-func (encoder *emptyStructEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *emptyStructEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return true
 }

+ 11 - 11
feature_reflect_slice.go

@@ -32,7 +32,7 @@ type sliceEncoder struct {
 	elemEncoder ValEncoder
 }
 
-func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	slice := (*sliceHeader)(ptr)
 	if slice.Data == nil {
 		stream.WriteNil()
@@ -44,11 +44,11 @@ func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
 	}
 	stream.WriteArrayStart()
 	elemPtr := uintptr(slice.Data)
-	encoder.elemEncoder.encode(unsafe.Pointer(elemPtr), stream)
+	encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
 	for i := 1; i < slice.Len; i++ {
 		stream.WriteMore()
 		elemPtr += encoder.elemType.Size()
-		encoder.elemEncoder.encode(unsafe.Pointer(elemPtr), stream)
+		encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
 	}
 	stream.WriteArrayEnd()
 	if stream.Error != nil && stream.Error != io.EOF {
@@ -56,11 +56,11 @@ func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
 	}
 }
 
-func (encoder *sliceEncoder) encodeInterface(val interface{}, stream *Stream) {
+func (encoder *sliceEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	writeToStream(val, stream, encoder)
 }
 
-func (encoder *sliceEncoder) isEmpty(ptr unsafe.Pointer) bool {
+func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	slice := (*sliceHeader)(ptr)
 	return slice.Len == 0
 }
@@ -78,7 +78,7 @@ type sliceHeader struct {
 	Cap  int
 }
 
-func (decoder *sliceDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	decoder.doDecode(ptr, iter)
 	if iter.Error != nil && iter.Error != io.EOF {
 		iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
@@ -92,30 +92,30 @@ func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
 		return
 	}
 	offset := uintptr(0)
-	decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
+	decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
 	if !iter.ReadArray() {
 		slice.Len = 1
 		return
 	}
 	offset += decoder.elemType.Size()
-	decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
+	decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
 	if !iter.ReadArray() {
 		slice.Len = 2
 		return
 	}
 	offset += decoder.elemType.Size()
-	decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
+	decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
 	if !iter.ReadArray() {
 		slice.Len = 3
 		return
 	}
 	offset += decoder.elemType.Size()
-	decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
+	decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
 	slice.Len = 4
 	for iter.ReadArray() {
 		growOne(slice, decoder.sliceType, decoder.elemType)
 		offset += decoder.elemType.Size()
-		decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
+		decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
 	}
 }
 

+ 2 - 2
jsoniter_nested_test.go

@@ -28,14 +28,14 @@ func Test_nested(t *testing.T) {
 					case "world":
 						l2.World = iter.ReadString()
 					default:
-						iter.reportError("bind l2", "unexpected field: "+l2Field)
+						iter.ReportError("bind l2", "unexpected field: "+l2Field)
 					}
 				}
 				l2Array = append(l2Array, l2)
 			}
 			l1.Hello = l2Array
 		default:
-			iter.reportError("bind l1", "unexpected field: "+l1Field)
+			iter.ReportError("bind l1", "unexpected field: "+l1Field)
 		}
 	}
 	if !reflect.DeepEqual(l1, Level1{

+ 11 - 1
jsoniter_object_test.go

@@ -56,7 +56,7 @@ func Test_two_field(t *testing.T) {
 		case "field2":
 			iter.ReadInt64()
 		default:
-			iter.reportError("bind object", "unexpected field")
+			iter.ReportError("bind object", "unexpected field")
 		}
 	}
 }
@@ -206,6 +206,16 @@ func Test_decode_struct_field_with_tag(t *testing.T) {
 	should.Equal(100, obj.Field3)
 }
 
+func Test_decode_struct_field_with_tag_string(t *testing.T) {
+	should := require.New(t)
+type TestObject struct {
+	Field1 int    `json:",string"`
+}
+	obj := TestObject{Field1: 100}
+	should.Nil(UnmarshalFromString(`{"Field1": "100"}`, &obj))
+	should.Equal(100, obj.Field1)
+}
+
 func Test_write_val_zero_field_struct(t *testing.T) {
 	should := require.New(t)
 	type TestObject struct {