commit 9501ba82a3fe8710f7a988cb6d98e1b5df664998
parent b9a557e24cfc5fe028d884ea7bfe78e3ed7cee93
Author: francoispqt <francois@parquet.ninja>
Date: Sat, 28 Apr 2018 16:58:30 +0800
enhance readding from io.Reader, make sure buffer grows when needed, add some tests and avoid calling usless check for pooled decoder
Diffstat:
12 files changed, 347 insertions(+), 72 deletions(-)
diff --git a/decode.go b/decode.go
@@ -14,11 +14,11 @@ import (
// overflows the target type, UnmarshalArray skips that field and completes the unmarshaling as best it can.
func UnmarshalArray(data []byte, v UnmarshalerArray) error {
dec := BorrowDecoder(nil, 0)
+ defer dec.Release()
dec.data = make([]byte, len(data))
copy(dec.data, data)
dec.length = len(data)
_, err := dec.decodeArray(v)
- defer dec.Release()
if err != nil {
return err
}
@@ -36,11 +36,11 @@ func UnmarshalArray(data []byte, v UnmarshalerArray) error {
// overflows the target type, UnmarshalObject skips that field and completes the unmarshaling as best it can.
func UnmarshalObject(data []byte, v UnmarshalerObject) error {
dec := BorrowDecoder(nil, 0)
+ defer dec.Release()
dec.data = make([]byte, len(data))
copy(dec.data, data)
dec.length = len(data)
_, err := dec.decodeObject(v)
- defer dec.Release()
if err != nil {
return err
}
@@ -147,12 +147,6 @@ type UnmarshalerArray interface {
UnmarshalArray(*Decoder) error
}
-// UnmarshalerStream is the interface to implement for a slice, an array or a slice
-// to decode a line delimited JSON to.
-type UnmarshalerStream interface {
- UnmarshalStream(*StreamDecoder) error
-}
-
// A Decoder reads and decodes JSON values from an input stream.
type Decoder struct {
data []byte
@@ -171,30 +165,30 @@ type Decoder struct {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) Decode(v interface{}) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
switch vt := v.(type) {
case *string:
- return dec.DecodeString(vt)
+ return dec.decodeString(vt)
case *int:
- return dec.DecodeInt(vt)
+ return dec.decodeInt(vt)
case *int32:
- return dec.DecodeInt32(vt)
+ return dec.decodeInt32(vt)
case *uint32:
- return dec.DecodeUint32(vt)
+ return dec.decodeUint32(vt)
case *int64:
- return dec.DecodeInt64(vt)
+ return dec.decodeInt64(vt)
case *uint64:
- return dec.DecodeUint64(vt)
+ return dec.decodeUint64(vt)
case *float64:
- return dec.DecodeFloat64(vt)
+ return dec.decodeFloat64(vt)
case *bool:
- return dec.DecodeBool(vt)
+ return dec.decodeBool(vt)
case UnmarshalerObject:
- _, err := dec.DecodeObject(vt)
+ _, err := dec.decodeObject(vt)
return err
case UnmarshalerArray:
- _, err := dec.DecodeArray(vt)
+ _, err := dec.decodeArray(vt)
return err
default:
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, reflect.TypeOf(vt).String()))
@@ -290,9 +284,18 @@ func isDigit(b byte) bool {
func (dec *Decoder) read() bool {
if dec.r != nil {
- // idea is to append data from reader at the end
+ // if we reach the end, double the buffer to ensure there's always more space
+ if len(dec.data) == dec.length {
+ nLen := dec.length * 2
+ Buf := make([]byte, nLen, nLen)
+ copy(Buf, dec.data)
+ dec.data = Buf
+ }
n, err := dec.r.Read(dec.data[dec.length:])
- if err != nil || n == 0 {
+ if err != nil {
+ dec.err = err
+ return false
+ } else if n == 0 {
return false
}
dec.length = dec.length + n
diff --git a/decode_array.go b/decode_array.go
@@ -9,11 +9,12 @@ import (
// v must implement UnmarshalerArray.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
-func (dec *Decoder) DecodeArray(arr UnmarshalerArray) (int, error) {
+func (dec *Decoder) DecodeArray(arr UnmarshalerArray) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
- return dec.decodeArray(arr)
+ _, err := dec.decodeArray(arr)
+ return err
}
func (dec *Decoder) decodeArray(arr UnmarshalerArray) (int, error) {
// not an array not an error, but do not know what to do
diff --git a/decode_array_test.go b/decode_array_test.go
@@ -1,6 +1,7 @@
package gojay
import (
+ "strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -169,3 +170,22 @@ func TestDecoderSliceInvalidJSON(t *testing.T) {
assert.NotNil(t, err, "Err must not be nil as JSON is invalid")
assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'")
}
+
+func TestDecoderSliceDecoderAPI(t *testing.T) {
+ json := `["string","string1"]`
+ testArr := testSliceStrings{}
+ dec := NewDecoder(strings.NewReader(json))
+ err := dec.DecodeArray(&testArr)
+ assert.Nil(t, err, "Err must be nil")
+ assert.Len(t, testArr, 2, "testArr should be of len 2")
+ assert.Equal(t, "string", testArr[0], "testArr[0] should be 'string'")
+ assert.Equal(t, "string1", testArr[1], "testArr[1] should be 'string1'")
+}
+
+func TestDecoderSliceDecoderAPIError(t *testing.T) {
+ testArr := testSliceInts{}
+ dec := NewDecoder(strings.NewReader(`hello`))
+ err := dec.DecodeArray(&testArr)
+ assert.NotNil(t, err, "Err must not be nil as JSON is invalid")
+ assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'")
+}
diff --git a/decode_bool.go b/decode_bool.go
@@ -7,7 +7,7 @@ import "fmt"
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeBool(v *bool) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeBool(v)
}
diff --git a/decode_number.go b/decode_number.go
@@ -58,7 +58,7 @@ func init() {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeInt(v *int) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeInt(v)
}
@@ -108,7 +108,7 @@ func (dec *Decoder) decodeInt(v *int) error {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeInt32(v *int32) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeInt32(v)
}
@@ -158,7 +158,7 @@ func (dec *Decoder) decodeInt32(v *int32) error {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeUint32(v *uint32) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeUint32(v)
}
@@ -210,7 +210,7 @@ func (dec *Decoder) decodeUint32(v *uint32) error {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeInt64(v *int64) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeInt64(v)
}
@@ -261,7 +261,7 @@ func (dec *Decoder) decodeInt64(v *int64) error {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeUint64(v *uint64) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeUint64(v)
}
@@ -312,7 +312,7 @@ func (dec *Decoder) decodeUint64(v *uint64) error {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeFloat64(v *float64) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeFloat64(v)
}
diff --git a/decode_number_test.go b/decode_number_test.go
@@ -55,6 +55,18 @@ func TestDecoderIntOverfow(t *testing.T) {
assert.NotNil(t, err, "Err must not be nil as int is overflowing")
assert.Equal(t, 0, v, "v must be equal to 0")
}
+func TestDecoderIntPoolError(t *testing.T) {
+ result := int(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeInt(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
func TestDecoderIntOverfow2(t *testing.T) {
json := []byte(`92233720368547758089`)
var v int
@@ -119,6 +131,18 @@ func TestDecoderInt32Overflow2(t *testing.T) {
assert.NotNil(t, err, "err must not be nil as int32 overflows")
assert.IsType(t, InvalidTypeError(""), err, "err must be of type InvalidTypeError")
}
+func TestDecoderInt32PoolError(t *testing.T) {
+ result := int32(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeInt32(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
func TestDecoderUint32Basic(t *testing.T) {
json := []byte(`124`)
@@ -170,6 +194,18 @@ func TestDecoderUint32Overflow2(t *testing.T) {
assert.NotNil(t, err, "err must not be nil as uint32 overflows")
assert.IsType(t, InvalidTypeError(""), err, "err must be of type InvalidTypeError")
}
+func TestDecoderUint32PoolError(t *testing.T) {
+ result := uint32(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeUint32(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
func TestDecoderInt64Basic(t *testing.T) {
json := []byte(`124`)
@@ -227,6 +263,18 @@ func TestDecoderInt64Overflow2(t *testing.T) {
assert.NotNil(t, err, "err must not be nil as int64 overflows")
assert.IsType(t, InvalidTypeError(""), err, "err must be of type InvalidTypeError")
}
+func TestDecoderInt64PoolError(t *testing.T) {
+ result := int64(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeInt64(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
func TestDecoderUint64Basic(t *testing.T) {
json := []byte(`124`)
var v uint64
@@ -276,7 +324,18 @@ func TestDecoderUint64Overflow2(t *testing.T) {
assert.NotNil(t, err, "err must not be nil as int32 overflows")
assert.IsType(t, InvalidTypeError(""), err, "err must be of type InvalidTypeError")
}
-
+func TestDecoderUint64PoolError(t *testing.T) {
+ result := uint64(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeUint64(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
func TestDecoderFloatBasic(t *testing.T) {
json := []byte(`100.11`)
var v float64
@@ -308,3 +367,15 @@ func TestDecoderFloatInvalidJSON(t *testing.T) {
assert.NotNil(t, err, "Err must not be nil as JSON is invalid")
assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'")
}
+func TestDecoderFloatPoolError(t *testing.T) {
+ result := float64(1)
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeFloat64(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
diff --git a/decode_object.go b/decode_object.go
@@ -10,15 +10,16 @@ import (
// v must implement UnmarshalerObject.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
-func (dec *Decoder) DecodeObject(j UnmarshalerObject) (int, error) {
+func (dec *Decoder) DecodeObject(j UnmarshalerObject) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
- return dec.decodeObject(j)
+ _, err := dec.decodeObject(j)
+ return err
}
func (dec *Decoder) decodeObject(j UnmarshalerObject) (int, error) {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
keys := j.NKeys()
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
diff --git a/decode_object_test.go b/decode_object_test.go
@@ -1,6 +1,7 @@
package gojay
import (
+ "strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -75,6 +76,27 @@ func (t *TestObj) NKeys() int {
return 8
}
+func assertResult(t *testing.T, v *TestObj, err error) {
+ assert.Nil(t, err, "Err must be nil")
+ assert.Equal(t, 245, v.test, "v.test must be equal to 245")
+ assert.Equal(t, 246, v.test2, "v.test2 must be equal to 246")
+ assert.Equal(t, "string", v.test3, "v.test3 must be equal to 'string'")
+ assert.Equal(t, "complex string with spaces and some slashes\"", v.test4, "v.test4 must be equal to 'string'")
+ assert.Equal(t, -1.15657654376543, v.test5, "v.test5 must be equal to 1.15")
+ assert.Len(t, v.testArr, 2, "v.testArr must be of len 2")
+
+ assert.Equal(t, 121, v.testSubObj.test3, "v.testSubObj.test3 must be equal to 121")
+ assert.Equal(t, 122, v.testSubObj.test4, "v.testSubObj.test4 must be equal to 122")
+ assert.Equal(t, "string", v.testSubObj.test5, "v.testSubObj.test5 must be equal to 'string'")
+ assert.Equal(t, 150, v.testSubObj.testSubSubObj.test3, "v.testSubObj.testSubSubObj.test3 must be equal to 150")
+ assert.Equal(t, 150, v.testSubObj.testSubSubObj2.test3, "v.testSubObj.testSubSubObj2.test3 must be equal to 150")
+
+ assert.Equal(t, 122, v.testSubObj2.test3, "v.testSubObj2.test3 must be equal to 121")
+ assert.Equal(t, 123, v.testSubObj2.test4, "v.testSubObj2.test4 must be equal to 122")
+ assert.Equal(t, "string", v.testSubObj2.test5, "v.testSubObj2.test5 must be equal to 'string'")
+ assert.Equal(t, 151, v.testSubObj2.testSubSubObj.test3, "v.testSubObj2.testSubSubObj.test must be equal to 150")
+}
+
func TestDecoderObject(t *testing.T) {
json := []byte(`{
"test": 245,
@@ -118,24 +140,7 @@ func TestDecoderObject(t *testing.T) {
}`)
v := &TestObj{}
err := Unmarshal(json, v)
- assert.Nil(t, err, "Err must be nil")
- assert.Equal(t, 245, v.test, "v.test must be equal to 245")
- assert.Equal(t, 246, v.test2, "v.test2 must be equal to 246")
- assert.Equal(t, "string", v.test3, "v.test3 must be equal to 'string'")
- assert.Equal(t, "complex string with spaces and some slashes\"", v.test4, "v.test4 must be equal to 'string'")
- assert.Equal(t, -1.15657654376543, v.test5, "v.test5 must be equal to 1.15")
- assert.Len(t, v.testArr, 2, "v.testArr must be of len 2")
-
- assert.Equal(t, 121, v.testSubObj.test3, "v.testSubObj.test3 must be equal to 121")
- assert.Equal(t, 122, v.testSubObj.test4, "v.testSubObj.test4 must be equal to 122")
- assert.Equal(t, "string", v.testSubObj.test5, "v.testSubObj.test5 must be equal to 'string'")
- assert.Equal(t, 150, v.testSubObj.testSubSubObj.test3, "v.testSubObj.testSubSubObj.test3 must be equal to 150")
- assert.Equal(t, 150, v.testSubObj.testSubSubObj2.test3, "v.testSubObj.testSubSubObj2.test3 must be equal to 150")
-
- assert.Equal(t, 122, v.testSubObj2.test3, "v.testSubObj2.test3 must be equal to 121")
- assert.Equal(t, 123, v.testSubObj2.test4, "v.testSubObj2.test4 must be equal to 122")
- assert.Equal(t, "string", v.testSubObj2.test5, "v.testSubObj2.test5 must be equal to 'string'")
- assert.Equal(t, 151, v.testSubObj2.testSubSubObj.test3, "v.testSubObj2.testSubSubObj.test must be equal to 150")
+ assertResult(t, v, err)
}
func TestDecodeObjectNull(t *testing.T) {
@@ -245,7 +250,7 @@ func TestDecodeObjectPartial(t *testing.T) {
"testSkipNumber": 123.23
}`)
dec.length = len(dec.data)
- _, err := dec.DecodeObject(&result)
+ err := dec.DecodeObject(&result)
assert.Nil(t, err, "err should be nil")
assert.NotEqual(t, len(dec.data), dec.cursor)
}
@@ -259,7 +264,75 @@ func TestDecoderObjectInvalidJSON(t *testing.T) {
"testSkipString": "testInvalidJSON\\\\
}`)
dec.length = len(dec.data)
- _, err := dec.DecodeObject(&result)
+ err := dec.DecodeObject(&result)
+ assert.NotNil(t, err, "Err must not be nil as JSON is invalid")
+ assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'")
+}
+
+func TestDecoderObjectPoolError(t *testing.T) {
+ result := jsonDecodePartial{}
+ dec := NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ _ = dec.DecodeObject(&result)
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
+
+func TestDecoderObjectDecoderAPI(t *testing.T) {
+ json := `{
+ "test": 245,
+ "test2": 246,
+ "test3": "string",
+ "test4": "complex string with spaces and some slashes\"",
+ "test5": -1.15657654376543,
+ "testNull": null,
+ "testArr": [
+ {
+ "test": 245,
+ "test2": 246
+ },
+ {
+ "test": 245,
+ "test2": 246
+ }
+ ],
+ "testSubObj": {
+ "test": 121,
+ "test2": 122,
+ "testNull": null,
+ "testSubSubObj": {
+ "test": 150,
+ "testNull": null
+ },
+ "testSubSubObj2": {
+ "test": 150
+ },
+ "test3": "string"
+ "testNull": null,
+ },
+ "testSubObj2": {
+ "test": 122,
+ "test3": "string"
+ "testSubSubObj": {
+ "test": 151
+ },
+ "test2": 123
+ }
+ }`
+ v := &TestObj{}
+ dec := NewDecoder(strings.NewReader(json))
+ err := dec.DecodeObject(v)
+ assertResult(t, v, err)
+}
+
+func TestDecoderObjectDecoderAPIError(t *testing.T) {
+ testArr := testSliceInts{}
+ dec := NewDecoder(strings.NewReader(`hello`))
+ err := dec.DecodeArray(&testArr)
assert.NotNil(t, err, "Err must not be nil as JSON is invalid")
assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'")
}
diff --git a/decode_stream.go b/decode_stream.go
@@ -4,6 +4,12 @@ import (
"time"
)
+// UnmarshalerStream is the interface to implement for a slice, an array or a slice
+// to decode a line delimited JSON to.
+type UnmarshalerStream interface {
+ UnmarshalStream(*StreamDecoder) error
+}
+
// Stream is a struct holding the Stream api
var Stream = stream{}
@@ -25,7 +31,7 @@ type StreamDecoder struct {
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *StreamDecoder) DecodeStream(c UnmarshalerStream) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
if dec.r == nil {
dec.err = NoReaderError("No reader given to decode stream")
diff --git a/decode_stream_pool_test.go b/decode_stream_pool_test.go
@@ -0,0 +1,100 @@
+package gojay
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestDecodeStreamBorrow(t *testing.T) {
+ // we override the pool chan
+ streamDecPool = make(chan *StreamDecoder, 1)
+ // add one decoder to the channel
+ dec := Stream.NewDecoder(nil)
+ streamDecPool <- dec
+ // borrow one decoder to the channel
+ nDec := Stream.BorrowDecoder(nil, 0)
+ // make sure they are the same
+ assert.Equal(t, dec, nDec, "decoder added to the pool and new decoder should be the same")
+}
+
+func TestDecodeStreamBorrow1(t *testing.T) {
+ // we override the pool chan
+ streamDecPool = make(chan *StreamDecoder, 1)
+ // add one decoder to the channel
+ dec := Stream.NewDecoder(nil)
+ streamDecPool <- dec
+ // reset streamDecPool
+ streamDecPool = make(chan *StreamDecoder, 1)
+ // borrow one decoder to the channel
+ nDec := Stream.BorrowDecoder(nil, 0)
+ // make sure they are the same
+ assert.NotEqual(t, dec, nDec, "decoder added to the pool and new decoder should be the same")
+}
+func TestDecodeStreamBorrow2(t *testing.T) {
+ // we override the pool chan
+ streamDecPool = make(chan *StreamDecoder, 1)
+ // add one decoder to the channel
+ dec := Stream.NewDecoder(nil)
+ dec.data = make([]byte, 128)
+ streamDecPool <- dec
+ // borrow one decoder to the channel
+ nDec := Stream.BorrowDecoder(nil, 512)
+ // make sure they are the same
+ assert.Equal(t, dec, nDec, "decoder added to the pool and new decoder should be the same")
+ assert.Equal(t, 512, len(nDec.data), "len of dec.data should be 512")
+}
+func TestDecodeStreamBorrow3(t *testing.T) {
+ // we override the pool chan
+ streamDecPool = make(chan *StreamDecoder, 16)
+ // borrow one decoder to the channel
+ nDec := Stream.BorrowDecoder(nil, 512)
+ // make sure they are the same
+ assert.Equal(t, 512, len(nDec.data), "len of dec.data should be 512")
+}
+
+func TestDecodeStreamDecodePooledDecoderError(t *testing.T) {
+ // we override the pool chan
+ dec := Stream.NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ var v = 0
+ dec.Decode(&v)
+ // make sure it fails if this is called
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
+
+func TestDecodeStreamDecodePooledDecoderError1(t *testing.T) {
+ // we override the pool chan
+ dec := Stream.NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ var v = testSliceStrings{}
+ dec.DecodeArray(&v)
+ // make sure they are the same
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
+
+func TestDecodeStreamDecodePooledDecoderError2(t *testing.T) {
+ // we override the pool chan
+ dec := Stream.NewDecoder(nil)
+ dec.Release()
+ defer func() {
+ err := recover()
+ assert.NotNil(t, err, "err shouldnot be nil")
+ assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError")
+ assert.Equal(t, "Invalid usage of pooled decoder", err.(InvalidUsagePooledDecoderError).Error(), "err should be of type InvalidUsagePooledDecoderError")
+ }()
+ var v = TestObj{}
+ dec.DecodeObject(&v)
+ // make sure they are the same
+ assert.True(t, false, "should not be called as decoder should have panicked")
+}
diff --git a/decode_string.go b/decode_string.go
@@ -10,7 +10,7 @@ import (
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeString(v *string) error {
if dec.isPooled == 1 {
- panic(InvalidUsagePooledDecoderError("Invalid usagee of pooled decoder"))
+ panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeString(v)
}
diff --git a/decode_unsafe.go b/decode_unsafe.go
@@ -15,10 +15,10 @@ type decUnsafe struct{}
func (u decUnsafe) UnmarshalArray(data []byte, v UnmarshalerArray) error {
dec := BorrowDecoder(nil, 0)
+ defer dec.Release()
dec.data = data
dec.length = len(data)
- _, err := dec.DecodeArray(v)
- dec.Release()
+ _, err := dec.decodeArray(v)
if err != nil {
return err
}
@@ -30,10 +30,10 @@ func (u decUnsafe) UnmarshalArray(data []byte, v UnmarshalerArray) error {
func (u decUnsafe) UnmarshalObject(data []byte, v UnmarshalerObject) error {
dec := BorrowDecoder(nil, 0)
+ defer dec.Release()
dec.data = data
dec.length = len(data)
- _, err := dec.DecodeObject(v)
- dec.Release()
+ _, err := dec.decodeObject(v)
if err != nil {
return err
}
@@ -51,52 +51,52 @@ func (u decUnsafe) Unmarshal(data []byte, v interface{}) error {
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeString(vt)
+ err = dec.decodeString(vt)
case *int:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeInt(vt)
+ err = dec.decodeInt(vt)
case *int32:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeInt32(vt)
+ err = dec.decodeInt32(vt)
case *uint32:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeUint32(vt)
+ err = dec.decodeUint32(vt)
case *int64:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeInt64(vt)
+ err = dec.decodeInt64(vt)
case *uint64:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeUint64(vt)
+ err = dec.decodeUint64(vt)
case *float64:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeFloat64(vt)
+ err = dec.decodeFloat64(vt)
case *bool:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- err = dec.DecodeBool(vt)
+ err = dec.decodeBool(vt)
case UnmarshalerObject:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- _, err = dec.DecodeObject(vt)
+ _, err = dec.decodeObject(vt)
case UnmarshalerArray:
dec = BorrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
- _, err = dec.DecodeArray(vt)
+ _, err = dec.decodeArray(vt)
default:
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, reflect.TypeOf(vt).String()))
}