Merge branch 'develop' of git://github.com/amluto/capnpc-python-cpp into amluto-develop

Conflicts:
	capnp/capnp.pyx
This commit is contained in:
Jason Paryani
2013-09-03 14:34:43 -07:00
3 changed files with 70 additions and 3 deletions

View File

@@ -9,7 +9,7 @@
cimport cython
cimport capnp_cpp as capnp
cimport schema_cpp
from capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, fixMaybe, getEnumString, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan
from capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, fixMaybe, getEnumString, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, WordArrayPtr
from schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode
from cython.operator cimport dereference as deref
@@ -40,6 +40,9 @@ ctypedef fused _DynamicSetterClasses:
C_DynamicList.Builder
C_DynamicStruct.Builder
cdef extern from "Python.h":
cdef int PyObject_AsReadBuffer(object, void** b, Py_ssize_t* c)
def _make_enum(enum_name, *sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
reverse = dict((value, key) for key, value in enums.iteritems())
@@ -587,6 +590,22 @@ cdef class _DynamicStructBuilder:
raise ValueError("You can only call write() on the message's root struct.")
_write_packed_message_to_fd(file.fileno(), self._parent)
def to_bytes(_DynamicStructBuilder self):
"""Returns the struct's containing message as a Python bytes object in the unpacked binary format.
This is inefficient; it makes several copies.
:rtype: bytes
:Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
"""
if not self._isRoot:
raise ValueError("You can only call write() on the message's root struct.")
cdef _MessageBuilder builder = self._parent
array = schema_cpp.messageToFlatArray(deref(builder.thisptr))
cdef const char* ptr = <const char *>array.begin()
return ptr[:8*array.size()]
cdef _get(self, field):
return to_python_builder(self.thisptr.get(field), self._parent)
@@ -927,7 +946,16 @@ cdef class SchemaParser:
reader = _PackedFdMessageReader(file.fileno())
return reader.get_root(bound_local_module)
return helper
def new_message(bound_local_module):
def make_from_bytes(local_module):
def from_bytes(buf):
"""Returns a Reader for the unpacked object in buf.
:type buf: buffer
:param buf: Any Python object that supports the readable buffer interface. If buf is mutable, then changes to the object will be reflected in the returned Reader, which may be surprising. If buf is an ordinary bytes object, then there should be no concern."""
reader = _FlatArrayMessageReader(buf)
return reader.get_root(local_module)
return from_bytes
def new_message(local_module):
def helper():
builder = _MallocMessageBuilder()
return builder.init_root(bound_local_module)
@@ -959,6 +987,7 @@ cdef class SchemaParser:
local_module.read_packed = read_packed(local_module)
local_module.new_message = new_message(local_module)
local_module.from_dict = from_dict(local_module)
local_module.from_bytes = make_from_bytes(local_module)
local_module.Reader = Reader
local_module.Builder = Builder
elif proto.isConst:
@@ -1170,6 +1199,18 @@ cdef class _PackedFdMessageReader(_MessageReader):
def __init__(self, int fd):
self.thisptr = new schema_cpp.PackedFdMessageReader(fd)
@cython.internal
cdef class _FlatArrayMessageReader(_MessageReader):
cdef object _object_to_pin
def __init__(self, buf):
cdef const void *ptr
cdef Py_ssize_t sz
PyObject_AsReadBuffer(buf, &ptr, &sz)
if sz % 8 != 0:
raise ValueError("input length must be a multiple of eight bytes")
self._object_to_pin = buf
self.thisptr = new schema_cpp.FlatArrayMessageReader(capnp.WordArrayPtr(<capnp.word*>ptr, sz//8))
def _write_message_to_fd(int fd, _MessageBuilder message):
"""Serialize a Cap'n Proto message to a file descriptor

View File

@@ -11,6 +11,8 @@ from libcpp cimport bool as cbool
cdef extern from "capnp/common.h" namespace " ::capnp":
enum Void:
VOID " ::capnp::VOID"
cdef cppclass word:
pass
cdef extern from "kj/string.h" namespace " ::kj":
cdef cppclass StringPtr:
@@ -31,6 +33,23 @@ cdef extern from "kj/common.h" namespace " ::kj":
size_t size()
T& operator[](size_t index)
# Cython can't handle ArrayPtr[word] as a function argument
cdef cppclass WordArrayPtr "::kj::ArrayPtr<::capnp::word>":
WordArrayPtr()
WordArrayPtr(word *, size_t size)
size_t size()
word& operator[](size_t index)
cdef extern from "kj/array.h" namespace " ::kj":
cdef cppclass Array[T]:
T* begin()
size_t size()
# Cython can't handle Array[word] as a function argument
cdef cppclass WordArray "::kj::Array<::capnp::word>":
word* begin()
size_t size()
cdef extern from "capnp/schema.h" namespace " ::capnp":
cdef cppclass Schema:
Node.Reader getProto() except +

View File

@@ -5,6 +5,7 @@
from libc.stdint cimport *
from capnp_cpp cimport DynamicOrphan
cimport capnp_cpp
ctypedef unsigned int uint
ctypedef uint8_t UInt8
ctypedef uint16_t UInt16
@@ -695,11 +696,17 @@ cdef extern from "capnp/serialize.h" namespace " ::capnp":
StreamFdMessageReader(int)
StreamFdMessageReader(int, ReaderOptions)
cdef cppclass FlatArrayMessageReader(MessageReader):
FlatArrayMessageReader(capnp_cpp.WordArrayPtr array)
FlatArrayMessageReader(capnp_cpp.WordArrayPtr array, ReaderOptions)
void writeMessageToFd(int, MessageBuilder&)
capnp_cpp.WordArray messageToFlatArray(MessageBuilder &)
cdef extern from "capnp/serialize-packed.h" namespace " ::capnp":
cdef cppclass PackedFdMessageReader(MessageReader):
PackedFdMessageReader(int)
StreamFdMessageReader(int, ReaderOptions)
void writePackedMessageToFd(int, MessageBuilder&)
void writePackedMessageToFd(int, MessageBuilder&)