Commit 98fb1987 authored by Kirill Smelkov's avatar Kirill Smelkov Committed by Kamil Kisiel

encoder: Fix Ref wrt protocol version

- we can use BINPERSID only if protocol >= 1
- we can use text PERSID only if protocol < 4 and Ref string does not
  contain \n - else encoding have to fail.

Tests for Ref encoding at protocols 3 & 4 will follow after string
encoding is fixed.
parent 33d1926f
......@@ -2,6 +2,7 @@ package ogórek
import (
"encoding/binary"
"errors"
"fmt"
"io"
"math"
......@@ -383,17 +384,25 @@ func (e *Encoder) encodeClass(v *Class) error {
return e.emit(opStackGlobal)
}
var errP0PersIDStringLineOnly = errors.New(`protocol 0: persistent ID must be string without \n`)
func (e *Encoder) encodeRef(v *Ref) error {
if pids, ok := v.Pid.(string); ok && !strings.Contains(pids, "\n") {
return e.emitf("%c%s\n", opPersid, pids)
} else {
// XXX we can use opBinpersid only if .protocol >= 1
err := e.encode(reflectValueOf(v.Pid))
if err != nil {
return err
// protocol 0: pid must be string without \n
if e.config.Protocol == 0 {
pids, ok := v.Pid.(string)
if !ok || strings.Contains(pids, "\n") {
return errP0PersIDStringLineOnly
}
return e.emit(opBinpersid)
return e.emitf("%c%s\n", opPersid, pids)
}
// protocol >= 1: we can use opBinpersid which allows arbitrary object as argument
err := e.encode(reflectValueOf(v.Pid))
if err != nil {
return err
}
return e.emit(opBinpersid)
}
func (e *Encoder) encodeStruct(st reflect.Value) error {
......
......@@ -238,12 +238,17 @@ var tests = []TestEntry{
I("cfoo\nbar\nS'bing'\n\x85R.")), // GLOBAL + STRING + TUPLE1 + REDUCE
X(`persref("abc")`, Ref{"abc"},
P0("Pabc\n.")), // PERSID
P0("Pabc\n."), // PERSID
P12("U\x03abcQ.")), // SHORT_BINSTRING + BINPERSID
X(`persref("abc\nd")`, Ref{"abc\nd"},
P12("U\x05abc\ndQ.")), // SHORT_BINSTRING + BINPERSID
P0(errP0PersIDStringLineOnly), // cannot be encoded
P12("U\x05abc\ndQ.")), // SHORT_BINSTRING + BINPERSID
X(`persref((1, 2))`, Ref{Tuple{int64(1), int64(2)}},
P0(errP0PersIDStringLineOnly), // cannot be encoded
P1("(K\x01K\x02tQ."), // MARK + BININT1 + TUPLE + BINPERSID
P2_("K\x01K\x02\x86Q."), // BININT1 + TUPLE2 + BINPERSID
I("(I1\nI2\ntQ.")),
// decode only
......@@ -584,7 +589,7 @@ func TestPersistentRefs(t *testing.T) {
}
dconf := &DecoderConfig{PersistentLoad: loadref}
econf := &EncoderConfig{PersistentRef: getref}
econf := &EncoderConfig{PersistentRef: getref, Protocol: 1}
testv := []struct {
input string
......
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