Commit d695e2f1 authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb: Try to support bytes for OID

Since ZODB 5.4 OID is encoded as bytes, not str:

	https://github.com/zopefoundation/ZODB/commit/12ee41c473

Try to support both str and bytes on decoding, as we need to support all
ZODB versions.
parent 42118074
// Copyright (C) 2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Copyright (C) 2017-2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
......@@ -23,7 +23,11 @@
package pickletools
import (
"encoding/binary"
"fmt"
"math/big"
pickle "github.com/kisielk/og-rek"
)
// Xint64 tries to convert unpickled value to int64.
......@@ -41,3 +45,34 @@ func Xint64(xv interface{}) (v int64, ok bool) {
return 0, false
}
// Xstrbytes verifies and extacts str|bytes from unpickled value.
func Xstrbytes(x interface{}) (string, error) {
var s string
switch x := x.(type) {
default:
return "", fmt.Errorf("expect str|bytes; got %T", x)
case string:
s = x
case pickle.Bytes:
s = string(x)
}
return s, nil
}
// Xstrbytes8 verifies and extracts [8](str|bytes) from unpickled value as big-endian u64.
func Xstrbytes8(x interface{}) (uint64, error) {
s, err := Xstrbytes(x)
if err != nil {
return 0, err
}
if len(s) != 8 {
return 0, fmt.Errorf("expect [8]bytes; got [%d]bytes", len(s))
}
return binary.BigEndian.Uint64([]byte(s)), nil
}
......@@ -22,11 +22,12 @@ package zodb
import (
"bytes"
"encoding/binary"
"fmt"
"strings"
pickle "github.com/kisielk/og-rek"
"lab.nexedi.com/kirr/neo/go/zodb/internal/pickletools"
"lab.nexedi.com/kirr/go123/xerr"
)
......@@ -232,20 +233,17 @@ func xpyclass(xklass interface{}) (_ pickle.Class, err error) {
}
// xoid verifies and extracts oid from unpickled value.
//
// TODO +zobdpickle.binary support
func xoid(x interface{}) (_ Oid, err error) {
defer xerr.Context(&err, "oid")
s, ok := x.(string)
if !ok {
return InvalidOid, fmt.Errorf("expect str; got %T", x)
}
if len(s) != 8 {
return InvalidOid, fmt.Errorf("expect [8]str; got [%d]str", len(s))
// ZODB >= 5.4 encodes oid as bytes; before - as str:
// https://github.com/zopefoundation/ZODB/commit/12ee41c473
v, err := pickletools.Xstrbytes8(x)
if err != nil {
return InvalidOid, err
}
return Oid(binary.BigEndian.Uint64([]byte(s))), nil
return Oid(v), nil
}
// pyclassPath returns full path for a python class.
......
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