Commit 43b13845 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent e7a6e2f3
......@@ -40,55 +40,28 @@ import (
// for format description.
type PyData []byte
// xoid verifies and extracts oid from unpickled value.
//
// XXX +zobdpickle.binary support
// XXX -> shared place
func xoid(x interface{}) (Oid, error) {
s, ok := x.(string)
if !ok {
return InvalidOid, fmt.Errorf("xoid: expect str; got %T", x)
}
if len(s) != 8 {
return InvalidOid, fmt.Errorf("xoid: expect [8]str; got [%d]str", len(s))
}
return Oid(binary.BigEndian.Uint64([]byte(s))), nil
}
// loadref loads persistent references resolving them through jar.
//
// https://github.com/zopefoundation/ZODB/blob/a89485c1/src/ZODB/serialize.py#L80
// ClassName returns fully-qualified python class name used for object type.
//
// XXX place?
func (jar *Connection) loadref(ref pickle.Ref) (_ interface{}, err error) {
defer xerr.Context(&err, "loadref")
// TODO add support for ref formats besides (oid, class)
t, ok := ref.Pid.(pickle.Tuple)
if !ok {
return nil, fmt.Errorf("expect (); got %T", ref.Pid)
}
if len(t) != 2 {
return nil, fmt.Errorf("expect (oid, class); got [%d]()", len(t))
}
oid, err := xoid(t[0])
// The format is "module.class".
// If pickle decoding fails - "?.?" is returned.
func (d PyData) ClassName() string {
// see ObjectReader.getClassName & get_pickle_metadata in zodb/py
p := pickle.NewDecoder(bytes.NewReader([]byte(d)))
xklass, err := p.Decode()
if err != nil {
return nil, err // XXX err ctx
return "?.?"
}
pyclass, err := normPyClass(t[1])
klass, err := normPyClass(xklass)
if err != nil {
return nil, err // XXX err ctx
return "?.?"
}
class := pyclassPath(pyclass)
return jar.get(class, oid)
return pyclassPath(klass)
}
// TODO PyData.referencesf
// decode decodes raw ZODB python data into Python class and state.
//
// jar is used to resolve persistent references.
......@@ -118,27 +91,39 @@ func (d PyData) decode(jar *Connection) (pyclass pickle.Class, pystate interface
return klass, state, nil
}
// ClassName returns fully-qualified python class name used for object type.
// loadref loads persistent references resolving them through jar.
//
// The format is "module.class".
// If pickle decoding fails - "?.?" is returned.
func (d PyData) ClassName() string {
// see ObjectReader.getClassName & get_pickle_metadata in zodb/py
p := pickle.NewDecoder(bytes.NewReader([]byte(d)))
xklass, err := p.Decode()
// https://github.com/zopefoundation/ZODB/blob/a89485c1/src/ZODB/serialize.py#L80
func (jar *Connection) loadref(ref pickle.Ref) (_ interface{}, err error) {
defer xerr.Context(&err, "loadref")
// TODO add support for ref formats besides (oid, class)
t, ok := ref.Pid.(pickle.Tuple)
if !ok {
return nil, fmt.Errorf("expect (); got %T", ref.Pid)
}
if len(t) != 2 {
return nil, fmt.Errorf("expect (oid, class); got [%d]()", len(t))
}
oid, err := xoid(t[0])
if err != nil {
return "?.?"
return nil, err // XXX err ctx
}
klass, err := normPyClass(xklass)
pyclass, err := normPyClass(t[1])
if err != nil {
return "?.?"
return nil, err // XXX err ctx
}
return pyclassPath(klass)
class := pyclassPath(pyclass)
return jar.get(class, oid)
}
var errInvalidPyClass = errors.New("invalid py class description")
// normPyClass normalizes py class that has just been decoded from a serialized
......@@ -178,3 +163,26 @@ func normPyClass(xklass interface{}) (pickle.Class, error) {
return pickle.Class{}, errInvalidPyClass
}
// pyclassPath returns full path for a python class.
//
// for example class "ABC" in module "wendelin.lib" has its full path as "wendelin.lib.ABC".
func pyclassPath(pyclass pickle.Class) string {
return pyclass.Module + "." + pyclass.Name
}
// xoid verifies and extracts oid from unpickled value.
//
// XXX +zobdpickle.binary support
// XXX -> shared place
func xoid(x interface{}) (Oid, error) {
s, ok := x.(string)
if !ok {
return InvalidOid, fmt.Errorf("xoid: expect str; got %T", x)
}
if len(s) != 8 {
return InvalidOid, fmt.Errorf("xoid: expect [8]str; got [%d]str", len(s))
}
return Oid(binary.BigEndian.Uint64([]byte(s))), nil
}
......@@ -20,14 +20,10 @@
package zodb
// Support for python objects/data in ZODB.
// XXX + PyData.referencesf ?
import (
"context"
"lab.nexedi.com/kirr/go123/mem"
pickle "github.com/kisielk/og-rek"
)
// PyStateful is the interface describing in-RAM object whose data state can be
......@@ -72,15 +68,6 @@ func pySetState(obj PyStateful, objClass string, state *mem.Buf, jar *Connection
// ----------------------------------------
// pyclassPath returns full path for a python class.
//
// for example class "ABC" in module "wendelin.lib" has its full path as "wendelin.lib.ABC".
func pyclassPath(pyclass pickle.Class) string {
return pyclass.Module + "." + pyclass.Name
}
// loadpy loads object specified by oid and decodes it as a ZODB Python object.
//
// loadpy does not create any in-RAM object associated with Connection.
......
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