commit 0c193f63bd46ccde98855af3f3991e84e3f1dcce
parent 616be9049f4ae57a2c17a3f1340b91d15589ef4a
Author: Francois Parquet <francois.parquet@gmail.com>
Date: Thu, 3 May 2018 00:52:34 +0800
Merge pull request #15 from francoispqt/update/improve-io-reader
improve io.Reader handling in decoder, handling EOF error and retrying
Diffstat:
3 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/decode.go b/decode.go
@@ -291,12 +291,16 @@ func (dec *Decoder) read() bool {
copy(Buf, dec.data)
dec.data = Buf
}
- n, err := dec.r.Read(dec.data[dec.length:])
- if err != nil {
- dec.err = err
- return false
- } else if n == 0 {
- return false
+ var n int
+ var err error
+ for n == 0 {
+ n, err = dec.r.Read(dec.data[dec.length:])
+ if err != nil {
+ if err != io.EOF {
+ dec.err = err
+ }
+ return false
+ }
}
dec.length = dec.length + n
return true
@@ -305,10 +309,9 @@ func (dec *Decoder) read() bool {
}
func (dec *Decoder) nextChar() byte {
- for dec.cursor < dec.length || dec.read() {
+ for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
- dec.cursor = dec.cursor + 1
continue
}
d := dec.data[dec.cursor]
diff --git a/decode_stream.go b/decode_stream.go
@@ -63,6 +63,7 @@ func (dec *StreamDecoder) DecodeStream(c UnmarshalerStream) error {
return nil
}
}
+ close(dec.done)
return InvalidJSONError("Invalid JSON while parsing line delimited JSON")
}
diff --git a/decode_stream_test.go b/decode_stream_test.go
@@ -2,6 +2,8 @@ package gojay
import (
"context"
+ "errors"
+ "io"
"testing"
"time"
@@ -310,6 +312,20 @@ loop:
testCase.expectations(dec.Err(), result, t)
}
+func TestStreamDecodingErr(t *testing.T) {
+ testChan := ChannelStreamStrings(make(chan *string))
+ dec := Stream.NewDecoder(&StreamReaderErr{})
+ // start decoding (will block the goroutine until something is written to the ReadWriter)
+ go dec.DecodeStream(testChan)
+ select {
+ case <-dec.Done():
+ assert.NotNil(t, dec.Err(), "dec.Err() should not be nil")
+ case <-testChan:
+ assert.True(t, false, "should not be called")
+ }
+
+}
+
type ChannelStreamStrings chan *string
func (c ChannelStreamStrings) UnmarshalStream(dec *StreamDecoder) error {
@@ -355,10 +371,16 @@ func (r *StreamReader) Read(b []byte) (int, error) {
n := copy(b, v)
return n, nil
case <-r.done:
- return 0, nil
+ return 0, io.EOF
}
}
+type StreamReaderErr struct{}
+
+func (r *StreamReaderErr) Read(b []byte) (int, error) {
+ return 0, errors.New("Test Error")
+}
+
// Deadline test
func TestStreamDecodingDeadline(t *testing.T) {
dec := Stream.NewDecoder(&StreamReader{})