Skip to content

Commit

Permalink
codec: at start of encode, ensure bufioEncWriter's buffer is not nil
Browse files Browse the repository at this point in the history
We previously introduces a mechanism where calling Release was optional,
and we would implicitly call Release if a full Encode was completed.

Unfortunately, this broke the use-case where an Encoder was used
multiple times in sequence.

We fix this now, by doing what we should have done before i.e. in addition
to calling Release (which nullifies the []byte buffer and returns it to the
pool), we should also grab a buffer from the pool at the beginning of each
Encode call.

Fixes #278
  • Loading branch information
ugorji committed Jan 26, 2019
1 parent 134ccd4 commit 497916c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
23 changes: 23 additions & 0 deletions codec/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2429,6 +2429,25 @@ func doTestMaxDepth(t *testing.T, name string, h Handle) {
}
}

func doTestMultipleEncDec(t *testing.T, name string, h Handle) {
testOnce.Do(testInitAll)
// encode a string multiple times.
// decode it multiple times.
// ensure we get the value each time
var s1 = "ugorji"
var s2 = "nwoke"
var s11, s21 string
var buf bytes.Buffer
e := NewEncoder(&buf, h)
e.MustEncode(s1)
e.MustEncode(s2)
d := NewDecoder(&buf, h)
d.MustDecode(&s11)
d.MustDecode(&s21)
testDeepEqualErr(s1, s11, t, name+"-multiple-encode")
testDeepEqualErr(s2, s21, t, name+"-multiple-encode")
}

// -----------------

func TestJsonDecodeNonStringScalarInStringContext(t *testing.T) {
Expand Down Expand Up @@ -3218,6 +3237,10 @@ func TestSimpleMaxDepth(t *testing.T) {
doTestMaxDepth(t, "simple", testSimpleH)
}

func TestMultipleEncDec(t *testing.T) {
doTestMultipleEncDec(t, "json", testJsonH)
}

// TODO:
//
// Add Tests for the following:
Expand Down
14 changes: 13 additions & 1 deletion codec/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,9 @@ func (z *bufioEncWriter) reset(w io.Writer, bufsize int) {
if bufsize <= 0 {
bufsize = defEncByteBufSize
}
if cap(z.buf) >= bufsize {
if z.buf == nil {
z.buf = z.bytesBufPooler.get(bufsize)
} else if cap(z.buf) >= bufsize {
z.buf = z.buf[:cap(z.buf)]
} else {
z.bytesBufPooler.end() // potentially return old one to pool
Expand Down Expand Up @@ -1471,11 +1473,21 @@ func (e *Encoder) MustEncode(v interface{}) {
}

func (e *Encoder) mustEncode(v interface{}) {
// ensure the bufioEncWriter buffer is not nil (e.g. if Release() was called)
if e.wf != nil && e.wf.buf == nil {
if e.h.WriterBufferSize > 0 {
e.wf.buf = e.wf.bytesBufPooler.get(e.h.WriterBufferSize)
} else {
e.wf.buf = e.wf.bytesBufPooler.get(defEncByteBufSize)
}
}

e.calls++
e.encode(v)
e.e.atEndOfEncode()
e.w.end()
e.calls--

if !e.h.ExplicitRelease && e.calls == 0 {
e.Release()
}
Expand Down
1 change: 1 addition & 0 deletions codec/z_all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ func testNonHandlesGroup(t *testing.T) {
t.Run("TestAtomic", TestAtomic)
t.Run("TestAllEncCircularRef", TestAllEncCircularRef)
t.Run("TestAllAnonCycle", TestAllAnonCycle)
t.Run("TestMultipleEncDec", TestMultipleEncDec)
}

func TestCodecSuite(t *testing.T) {
Expand Down

0 comments on commit 497916c

Please sign in to comment.