Commit fe24c62f authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb/zeo: Factor-out tuple handling into encoding

Handle pickled lists as valid input when decoding tuples.
parent dc419056
...@@ -98,7 +98,7 @@ func pktDecodeZ(pkb *pktBuf) (msg, error) { ...@@ -98,7 +98,7 @@ func pktDecodeZ(pkb *pktBuf) (msg, error) {
return m, err return m, err
} }
tpkt, ok := xpkt.(pickle.Tuple) // XXX also list? tpkt, ok := encoding('Z').asTuple(xpkt)
if !ok { if !ok {
return m, derrf("got %T; expected tuple", xpkt) return m, derrf("got %T; expected tuple", xpkt)
} }
...@@ -134,6 +134,41 @@ func derrf(format string, argv ...interface{}) error { ...@@ -134,6 +134,41 @@ func derrf(format string, argv ...interface{}) error {
// ---- retrieve/put objects from/into msg.arg ---- // ---- retrieve/put objects from/into msg.arg ----
// tuple represents py tuple.
type tuple []interface{}
// Tuple converts t into corresponding object appropriate for encoding e.
func (e encoding) Tuple(t tuple) pickle.Tuple {
switch e {
default:
panic("bug")
case 'Z':
// pickle: -> pickle.Tuple
return pickle.Tuple(t)
}
}
// asTuple tries to retrieve tuple from corresponding object decoded via encoding e.
func (e encoding) asTuple(xt interface{}) (tuple, bool) {
switch e {
default:
panic("bug")
case 'Z':
// pickle: tuples are represented by pickle.Tuple; lists as []interface{}
switch t := xt.(type) {
case pickle.Tuple:
return tuple(t), true
case []interface{}:
return tuple(t), true
default:
return tuple(nil), false
}
}
}
// xuint64Unpack tries to decode packed 8-byte string as bigendian uint64 // xuint64Unpack tries to decode packed 8-byte string as bigendian uint64
func (e encoding) xuint64Unpack(xv interface{}) (uint64, bool) { func (e encoding) xuint64Unpack(xv interface{}) (uint64, bool) {
switch e { switch e {
......
...@@ -86,7 +86,7 @@ func (z *zeo) Load(ctx context.Context, xid zodb.Xid) (buf *mem.Buf, serial zodb ...@@ -86,7 +86,7 @@ func (z *zeo) Load(ctx context.Context, xid zodb.Xid) (buf *mem.Buf, serial zodb
} }
// (data, serial, next_serial | None) // (data, serial, next_serial | None)
res, ok := xres.(pickle.Tuple) res, ok := enc.asTuple(xres)
if !ok || len(res) != 3 { if !ok || len(res) != 3 {
return nil, 0, rpc.ereplyf("got %#v; expect 3-tuple", res) return nil, 0, rpc.ereplyf("got %#v; expect 3-tuple", res)
} }
...@@ -140,7 +140,7 @@ type rpc struct { ...@@ -140,7 +140,7 @@ type rpc struct {
// rpcExcept represents generic exception // rpcExcept represents generic exception
type rpcExcept struct { type rpcExcept struct {
exc string exc string
argv []interface{} argv tuple
} }
func (r *rpcExcept) Error() string { func (r *rpcExcept) Error() string {
...@@ -175,7 +175,7 @@ func (r rpc) call(ctx context.Context, argv ...interface{}) (interface{}, error) ...@@ -175,7 +175,7 @@ func (r rpc) call(ctx context.Context, argv ...interface{}) (interface{}, error)
// //
// well-known exceptions are mapped to corresponding well-known errors - e.g. // well-known exceptions are mapped to corresponding well-known errors - e.g.
// POSKeyError -> zodb.NoObjectError, and rest are returned wrapper into rpcExcept. // POSKeyError -> zodb.NoObjectError, and rest are returned wrapper into rpcExcept.
func (r rpc) excError(exc string, argv []interface{}) error { func (r rpc) excError(exc string, argv tuple) error {
// translate well-known exceptions // translate well-known exceptions
switch exc { switch exc {
case "ZODB.POSException.POSKeyError": case "ZODB.POSException.POSKeyError":
...@@ -204,13 +204,13 @@ func (r rpc) excError(exc string, argv []interface{}) error { ...@@ -204,13 +204,13 @@ func (r rpc) excError(exc string, argv []interface{}) error {
func (r rpc) zeo5Error(arg interface{}) error { func (r rpc) zeo5Error(arg interface{}) error {
enc := r.zlink.enc enc := r.zlink.enc
// ('type', (arg1, arg2, arg3, ...)) // ('type', (arg1, arg2, arg3, ...))
texc, ok := arg.(pickle.Tuple) texc, ok := enc.asTuple(arg)
if !ok || len(texc) != 2 { if !ok || len(texc) != 2 {
return r.ereplyf("except5: got %#v; expect 2-tuple", arg) return r.ereplyf("except5: got %#v; expect 2-tuple", arg)
} }
exc, ok1 := enc.asString(texc[0]) exc, ok1 := enc.asString(texc[0])
argv, ok2 := texc[1].(pickle.Tuple) argv, ok2 := enc.asTuple(texc[1])
if !(ok1 && ok2) { if !(ok1 && ok2) {
return r.ereplyf("except5: got (%T, %T); expect (str, tuple)", texc...) return r.ereplyf("except5: got (%T, %T); expect (str, tuple)", texc...)
} }
...@@ -277,7 +277,7 @@ func (r rpc) zeo4Error(arg interface{}) error { ...@@ -277,7 +277,7 @@ func (r rpc) zeo4Error(arg interface{}) error {
argv = args argv = args
} }
return r.excError(exc, argv) return r.excError(exc, tuple(argv))
} }
// isPyExceptClass returns whether klass represents python exception // isPyExceptClass returns whether klass represents python exception
......
...@@ -30,8 +30,6 @@ import ( ...@@ -30,8 +30,6 @@ import (
"net" "net"
"sync" "sync"
pickle "github.com/kisielk/og-rek"
"github.com/someonegg/gocontainer/rbuf" "github.com/someonegg/gocontainer/rbuf"
"lab.nexedi.com/kirr/go123/xbytes" "lab.nexedi.com/kirr/go123/xbytes"
"lab.nexedi.com/kirr/go123/xerr" "lab.nexedi.com/kirr/go123/xerr"
...@@ -188,7 +186,7 @@ func (zl *zLink) Call(ctx context.Context, method string, argv ...interface{}) ( ...@@ -188,7 +186,7 @@ func (zl *zLink) Call(ctx context.Context, method string, argv ...interface{}) (
msgid: callID, msgid: callID,
flags: 0, flags: 0,
method: method, method: method,
arg: pickle.Tuple(argv), arg: zl.enc.Tuple(argv),
}) })
// ok, pkt is ready to go // ok, pkt is ready to go
......
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