Commit 90bef817 authored by Kamil Kisiel's avatar Kamil Kisiel Committed by GitHub

Merge pull request #26 from navytux/fix1

Misc fixes (error + opStop handling)
parents 28bae785 995fce81
...@@ -29,9 +29,12 @@ func NewEncoder(w io.Writer) *Encoder { ...@@ -29,9 +29,12 @@ func NewEncoder(w io.Writer) *Encoder {
// Encode writes the pickle encoding of v to w, the encoder's writer // Encode writes the pickle encoding of v to w, the encoder's writer
func (e *Encoder) Encode(v interface{}) error { func (e *Encoder) Encode(v interface{}) error {
rv := reflectValueOf(v) rv := reflectValueOf(v)
e.encode(rv) err := e.encode(rv)
e.w.Write([]byte{opStop}) if err != nil {
return nil return err
}
_, err = e.w.Write([]byte{opStop})
return err
} }
func (e *Encoder) encode(rv reflect.Value) error { func (e *Encoder) encode(rv reflect.Value) error {
......
...@@ -2,6 +2,7 @@ package ogórek ...@@ -2,6 +2,7 @@ package ogórek
import ( import (
"bytes" "bytes"
"io"
"reflect" "reflect"
"testing" "testing"
) )
...@@ -38,7 +39,10 @@ func TestEncode(t *testing.T) { ...@@ -38,7 +39,10 @@ func TestEncode(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
p := &bytes.Buffer{} p := &bytes.Buffer{}
e := NewEncoder(p) e := NewEncoder(p)
e.Encode(tt.input) err := e.Encode(tt.input)
if err != nil {
t.Errorf("%s: encode error: %v", tt.name, err)
}
d := NewDecoder(bytes.NewReader(p.Bytes())) d := NewDecoder(bytes.NewReader(p.Bytes()))
output, _ := d.Decode() output, _ := d.Decode()
...@@ -52,5 +56,35 @@ func TestEncode(t *testing.T) { ...@@ -52,5 +56,35 @@ func TestEncode(t *testing.T) {
t.Errorf("%s: got\n%q\n expected\n%q", tt.name, output, want) t.Errorf("%s: got\n%q\n expected\n%q", tt.name, output, want)
} }
for l := int64(p.Len())-1; l >= 0; l-- {
p.Reset()
e := NewEncoder(LimitWriter(p, l))
err = e.Encode(tt.input)
if err != io.EOF {
t.Errorf("%s: encoder did not handle write error @%v: got %#v", tt.name, l, err)
}
}
}
}
// like io.LimitedReader but for writes
// XXX it would be good to have it in stdlib
type LimitedWriter struct {
W io.Writer
N int64
}
func (l *LimitedWriter) Write(p []byte) (n int, err error) {
if l.N <= 0 {
return 0, io.EOF
} }
if int64(len(p)) > l.N {
p = p[0:l.N]
}
n, err = l.W.Write(p)
l.N -= int64(n)
return
} }
func LimitWriter(w io.Writer, n int64) io.Writer { return &LimitedWriter{w, n} }
...@@ -119,20 +119,23 @@ func NewDecoder(r io.Reader) Decoder { ...@@ -119,20 +119,23 @@ func NewDecoder(r io.Reader) Decoder {
func (d Decoder) Decode() (interface{}, error) { func (d Decoder) Decode() (interface{}, error) {
insn := 0 insn := 0
loop:
for { for {
insn++
key, err := d.r.ReadByte() key, err := d.r.ReadByte()
if err == io.EOF { if err != nil {
break if err == io.EOF && insn != 0 {
} else if err != nil { err = io.ErrUnexpectedEOF
}
return nil, err return nil, err
} }
insn++
switch key { switch key {
case opMark: case opMark:
d.mark() d.mark()
case opStop: case opStop:
break break loop
case opPop: case opPop:
d.pop() d.pop()
case opPopMark: case opPopMark:
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment