Add references to parent Builder/Reader objects to prevent segfaults.

This commit is contained in:
Jason Paryani
2013-07-07 18:48:55 -07:00
parent c44b5b3440
commit ea77abc785
3 changed files with 60 additions and 35 deletions

View File

@@ -6,6 +6,8 @@ this_dir = os.path.dirname(__file__)
addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp')) addressbook = capnp.load(os.path.join(this_dir, 'addressbook.capnp'))
print = lambda *x: x print = lambda *x: x
def writeAddressBook(fd): def writeAddressBook(fd):
message = capnp.MallocMessageBuilder() message = capnp.MallocMessageBuilder()
addressBook = message.initRoot(addressbook.AddressBook) addressBook = message.initRoot(addressbook.AddressBook)

View File

@@ -4,6 +4,7 @@ import os
print = lambda *x: x print = lambda *x: x
def writeAddressBook(fd): def writeAddressBook(fd):
addressBook = addressbook.AddressBook() addressBook = addressbook.AddressBook()

View File

@@ -71,8 +71,10 @@ cdef extern from "capnp/list.h" namespace " ::capnp":
cdef class _DynamicListReader: cdef class _DynamicListReader:
cdef C_DynamicList.Reader thisptr cdef C_DynamicList.Reader thisptr
cdef _init(self, C_DynamicList.Reader other): cdef public object _parent
cdef _init(self, C_DynamicList.Reader other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
cpdef _get(self, index): cpdef _get(self, index):
@@ -80,7 +82,7 @@ cdef class _DynamicListReader:
if index >= size: if index >= size:
raise IndexError('Out of bounds') raise IndexError('Out of bounds')
index = index % size index = index % size
return _DynamicValueReader()._init(self.thisptr[index]) return _DynamicValueReader()._init(self.thisptr[index], self._parent)
def __getitem__(self, index): def __getitem__(self, index):
return self._get(index).toPython() return self._get(index).toPython()
@@ -90,8 +92,10 @@ cdef class _DynamicListReader:
cdef class _DynamicListBuilder: cdef class _DynamicListBuilder:
cdef C_DynamicList.Builder thisptr cdef C_DynamicList.Builder thisptr
cdef _init(self, C_DynamicList.Builder other): cdef public object _parent
cdef _init(self, C_DynamicList.Builder other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
#def _init(self, size): #def _init(self, size):
@@ -104,7 +108,7 @@ cdef class _DynamicListBuilder:
raise IndexError('Out of bounds') raise IndexError('Out of bounds')
index = index % size index = index % size
temp = self.thisptr[index] temp = self.thisptr[index]
return toPython(temp) return toPython(temp, self._parent)
def _setitem(self, index, valid_values value): def _setitem(self, index, valid_values value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value)
@@ -152,8 +156,10 @@ cdef class _List_Node_Reader:
cdef class _DynamicValueReader: cdef class _DynamicValueReader:
cdef C_DynamicValue.Reader thisptr cdef C_DynamicValue.Reader thisptr
cdef _init(self, C_DynamicValue.Reader other): cdef public object _parent
cdef _init(self, C_DynamicValue.Reader other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
cpdef int getType(self): cpdef int getType(self):
@@ -175,11 +181,11 @@ cdef class _DynamicValueReader:
temp = self.thisptr.asData() temp = self.thisptr.asData()
return (<char*>temp.begin())[:temp.size()] return (<char*>temp.begin())[:temp.size()]
elif type == capnp.TYPE_LIST: elif type == capnp.TYPE_LIST:
return list(_DynamicListReader()._init(self.thisptr.asList())) return list(_DynamicListReader()._init(self.thisptr.asList(), self._parent))
elif type == capnp.TYPE_STRUCT: elif type == capnp.TYPE_STRUCT:
return _DynamicStructReader()._init(self.thisptr.asStruct()) return _DynamicStructReader()._init(self.thisptr.asStruct(), self._parent)
elif type == capnp.TYPE_UNION: elif type == capnp.TYPE_UNION:
return _DynamicUnionReader()._init(self.thisptr.asUnion()) return _DynamicUnionReader()._init(self.thisptr.asUnion(), self._parent)
elif type == capnp.TYPE_ENUM: elif type == capnp.TYPE_ENUM:
return fixMaybe(self.thisptr.asEnum().getEnumerant()).getProto().getName().cStr() return fixMaybe(self.thisptr.asEnum().getEnumerant()).getProto().getName().cStr()
elif type == capnp.TYPE_VOID: elif type == capnp.TYPE_VOID:
@@ -193,7 +199,7 @@ cdef class _DynamicValueReader:
cdef int getType(C_DynamicValue.Builder & self): cdef int getType(C_DynamicValue.Builder & self):
return self.getType() return self.getType()
cdef toPython(C_DynamicValue.Builder & self): cdef toPython(C_DynamicValue.Builder & self, object parent):
cdef int type = getType(self) cdef int type = getType(self)
if type == capnp.TYPE_BOOL: if type == capnp.TYPE_BOOL:
return self.asBool() return self.asBool()
@@ -209,11 +215,11 @@ cdef toPython(C_DynamicValue.Builder & self):
temp = self.asData() temp = self.asData()
return (<char*>temp.begin())[:temp.size()] return (<char*>temp.begin())[:temp.size()]
elif type == capnp.TYPE_LIST: elif type == capnp.TYPE_LIST:
return list(_DynamicListBuilder()._init(self.asList())) return list(_DynamicListBuilder()._init(self.asList(), parent))
elif type == capnp.TYPE_STRUCT: elif type == capnp.TYPE_STRUCT:
return _DynamicStructBuilder()._init(self.asStruct()) return _DynamicStructBuilder()._init(self.asStruct(), parent)
elif type == capnp.TYPE_UNION: elif type == capnp.TYPE_UNION:
return _DynamicUnionBuilder()._init(self.asUnion()) return _DynamicUnionBuilder()._init(self.asUnion(), parent)
elif type == capnp.TYPE_ENUM: elif type == capnp.TYPE_ENUM:
return fixMaybe(self.asEnum().getEnumerant()).getProto().getName().cStr() return fixMaybe(self.asEnum().getEnumerant()).getProto().getName().cStr()
elif type == capnp.TYPE_VOID: elif type == capnp.TYPE_VOID:
@@ -224,7 +230,7 @@ cdef toPython(C_DynamicValue.Builder & self):
raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library")
cdef toPythonByValue(C_DynamicValue.Builder self): cdef toPythonByValue(C_DynamicValue.Builder self, object parent):
cdef int type = self.getType() cdef int type = self.getType()
if type == capnp.TYPE_BOOL: if type == capnp.TYPE_BOOL:
return self.asBool() return self.asBool()
@@ -240,11 +246,11 @@ cdef toPythonByValue(C_DynamicValue.Builder self):
temp = self.asData() temp = self.asData()
return (<char*>temp.begin())[:temp.size()] return (<char*>temp.begin())[:temp.size()]
elif type == capnp.TYPE_LIST: elif type == capnp.TYPE_LIST:
return list(_DynamicListBuilder()._init(self.asList())) return list(_DynamicListBuilder()._init(self.asList(), parent))
elif type == capnp.TYPE_STRUCT: elif type == capnp.TYPE_STRUCT:
return _DynamicStructBuilder()._init(self.asStruct()) return _DynamicStructBuilder()._init(self.asStruct(), parent)
elif type == capnp.TYPE_UNION: elif type == capnp.TYPE_UNION:
return _DynamicUnionBuilder()._init(self.asUnion()) return _DynamicUnionBuilder()._init(self.asUnion(), parent)
elif type == capnp.TYPE_ENUM: elif type == capnp.TYPE_ENUM:
return fixMaybe(self.asEnum().getEnumerant()).getProto().getName().cStr() return fixMaybe(self.asEnum().getEnumerant()).getProto().getName().cStr()
elif type == capnp.TYPE_VOID: elif type == capnp.TYPE_VOID:
@@ -256,12 +262,14 @@ cdef toPythonByValue(C_DynamicValue.Builder self):
cdef class _DynamicStructReader: cdef class _DynamicStructReader:
cdef C_DynamicStruct.Reader thisptr cdef C_DynamicStruct.Reader thisptr
cdef _init(self, C_DynamicStruct.Reader other): cdef public object _parent
cdef _init(self, C_DynamicStruct.Reader other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
cpdef _get(self, field): cpdef _get(self, field):
return _DynamicValueReader()._init(self.thisptr.get(field)) return _DynamicValueReader()._init(self.thisptr.get(field), self._parent)
def __getattr__(self, field): def __getattr__(self, field):
return self._get(field).toPython() return self._get(field).toPython()
@@ -271,12 +279,14 @@ cdef class _DynamicStructReader:
cdef class _DynamicStructBuilder: cdef class _DynamicStructBuilder:
cdef C_DynamicStruct.Builder thisptr cdef C_DynamicStruct.Builder thisptr
cdef _init(self, C_DynamicStruct.Builder other): cdef public object _parent
cdef _init(self, C_DynamicStruct.Builder other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
def __getattr__(self, field): def __getattr__(self, field):
return toPython(self.thisptr.get(field)) return toPython(self.thisptr.get(field), self._parent)
cdef _setattrInt(self, field, value): cdef _setattrInt(self, field, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value)
@@ -318,18 +328,20 @@ cdef class _DynamicStructBuilder:
cpdef init(self, field, size=None) except +ValueError: cpdef init(self, field, size=None) except +ValueError:
if size is None: if size is None:
return toPythonByValue(self.thisptr.init(field)) return toPythonByValue(self.thisptr.init(field), self._parent)
else: else:
return toPythonByValue(self.thisptr.init(field, size)) return toPythonByValue(self.thisptr.init(field, size), self._parent)
cdef class _DynamicUnionReader: cdef class _DynamicUnionReader:
cdef C_DynamicUnion.Reader thisptr cdef C_DynamicUnion.Reader thisptr
cdef _init(self, C_DynamicUnion.Reader other): cdef public object _parent
cdef _init(self, C_DynamicUnion.Reader other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
cpdef _get(self): cpdef _get(self):
return _DynamicValueReader()._init(self.thisptr.get()) return _DynamicValueReader()._init(self.thisptr.get(), self._parent)
def __getattr__(self, field): def __getattr__(self, field):
return self._get().toPython() # TODO: check that the field is right? return self._get().toPython() # TODO: check that the field is right?
@@ -339,12 +351,14 @@ cdef class _DynamicUnionReader:
cdef class _DynamicUnionBuilder: cdef class _DynamicUnionBuilder:
cdef C_DynamicUnion.Builder thisptr cdef C_DynamicUnion.Builder thisptr
cdef _init(self, C_DynamicUnion.Builder other): cdef public object _parent
cdef _init(self, C_DynamicUnion.Builder other, object parent):
self.thisptr = other self.thisptr = other
self._parent = parent
return self return self
def __getattr__(self, field): def __getattr__(self, field):
return toPython(self.thisptr.get()) # TODO: check that the field is right? return toPython(self.thisptr.get(), self._parent) # TODO: check that the field is right?
cdef _setattrInt(self, field, value): cdef _setattrInt(self, field, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value)
@@ -386,9 +400,9 @@ cdef class _DynamicUnionBuilder:
cpdef init(self, field, size=None) except +ValueError: cpdef init(self, field, size=None) except +ValueError:
if size is None: if size is None:
return toPythonByValue(self.thisptr.init(field)) return toPythonByValue(self.thisptr.init(field), self._parent)
else: else:
return toPythonByValue(self.thisptr.init(field, size)) return toPythonByValue(self.thisptr.init(field, size), self._parent)
cdef class _CodeGeneratorRequestReader: cdef class _CodeGeneratorRequestReader:
cdef C_CodeGeneratorRequest.Reader thisptr cdef C_CodeGeneratorRequest.Reader thisptr
@@ -442,49 +456,57 @@ cdef class MessageBuilder:
cdef schema_cpp.MessageBuilder * thisptr cdef schema_cpp.MessageBuilder * thisptr
def __dealloc__(self): def __dealloc__(self):
del self.thisptr del self.thisptr
def __init__(self):
raise NotImplementedError("This is an abstract base class. You should use MallocMessageBuilder instead")
cpdef initRoot(self, schema): cpdef initRoot(self, schema):
cdef StructSchema s cdef StructSchema s
if hasattr(schema, 'Schema'): if hasattr(schema, 'Schema'):
s = schema.Schema s = schema.Schema
else: else:
s = schema s = schema
return _DynamicStructBuilder()._init(self.thisptr.initRootDynamicStruct(s.thisptr)) return _DynamicStructBuilder()._init(self.thisptr.initRootDynamicStruct(s.thisptr), self)
cpdef getRoot(self, schema): cpdef getRoot(self, schema):
cdef StructSchema s cdef StructSchema s
if hasattr(schema, 'Schema'): if hasattr(schema, 'Schema'):
s = schema.Schema s = schema.Schema
else: else:
s = schema s = schema
return _DynamicStructBuilder()._init(self.thisptr.getRootDynamicStruct(s.thisptr)) return _DynamicStructBuilder()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self)
cdef class MallocMessageBuilder(MessageBuilder): cdef class MallocMessageBuilder(MessageBuilder):
def __cinit__(self): def __cinit__(self):
self.thisptr = new schema_cpp.MallocMessageBuilder() self.thisptr = new schema_cpp.MallocMessageBuilder()
def __init__(self):
pass
cdef class MessageReader: cdef class MessageReader:
cdef schema_cpp.MessageReader * thisptr cdef schema_cpp.MessageReader * thisptr
def __dealloc__(self): def __dealloc__(self):
del self.thisptr del self.thisptr
def __init__(self):
raise NotImplementedError("This is an abstract base class")
cpdef getRootNode(self): cpdef getRootNode(self):
return _NodeReader().init(self.thisptr.getRootNode()) return _NodeReader().init(self.thisptr.getRootNode())
cpdef getRootCodeGeneratorRequest(self): cpdef getRootCodeGeneratorRequest(self):
return _CodeGeneratorRequestReader()._init(self.thisptr.getRootCodeGeneratorRequest()) return _CodeGeneratorRequestReader()._init(self.thisptr.getRootCodeGeneratorRequest())
cpdef getRootDynamicStruct(self, StructSchema schema): cpdef getRootDynamicStruct(self, StructSchema schema):
return _DynamicStructReader()._init(self.thisptr.getRootDynamicStruct(schema.thisptr)) return _DynamicStructReader()._init(self.thisptr.getRootDynamicStruct(schema.thisptr), self)
cpdef getRoot(self, schema): cpdef getRoot(self, schema):
cdef StructSchema s cdef StructSchema s
if hasattr(schema, 'Schema'): if hasattr(schema, 'Schema'):
s = schema.Schema s = schema.Schema
else: else:
s = schema s = schema
return _DynamicStructReader()._init(self.thisptr.getRootDynamicStruct(s.thisptr)) return _DynamicStructReader()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self)
cdef class StreamFdMessageReader(MessageReader): cdef class StreamFdMessageReader(MessageReader):
def __cinit__(self, int fd): def __init__(self, int fd):
self.thisptr = new schema_cpp.StreamFdMessageReader(fd) self.thisptr = new schema_cpp.StreamFdMessageReader(fd)
cdef class PackedFdMessageReader(MessageReader): cdef class PackedFdMessageReader(MessageReader):
def __cinit__(self, int fd): def __init__(self, int fd):
self.thisptr = new schema_cpp.PackedFdMessageReader(fd) self.thisptr = new schema_cpp.PackedFdMessageReader(fd)
def writeMessageToFd(int fd, MessageBuilder m): def writeMessageToFd(int fd, MessageBuilder m):