From 06833eb6d574a33381630a90d9aba871af1f5e30 Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Fri, 12 Dec 2014 14:43:18 -0800 Subject: [PATCH] Fix alignment issues for reading bytes --- capnp/lib/capnp.pyx | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 5810f47..55caf32 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -25,6 +25,8 @@ from operator import attrgetter as _attrgetter import threading as _threading import socket as _socket import random as _random +from libc.stdlib cimport malloc, free +from libc.string cimport memcpy _CAPNP_VERSION_MAJOR = capnp.CAPNP_VERSION_MAJOR _CAPNP_VERSION_MINOR = capnp.CAPNP_VERSION_MINOR @@ -2836,22 +2838,46 @@ cdef class _MultiplePackedMessageReader: def __iter__(self): return self +@cython.internal +cdef class _AlignedBuffer: + cdef char * buf + cdef bint allocated + + # other should also have a length that's a multiple of 8 + def __init__(self, other): + cdef char * other_buf = other + other_len = len(other) + + # malloc is defined as being word aligned + # we don't care about adding NULL terminating character + self.buf = malloc(other_len) + memcpy(self.buf, other_buf, other_len) + self.allocated = True + + def __dealloc__(self): + if self.allocated: + free(self.buf) + @cython.internal cdef class _FlatArrayMessageReader(_MessageReader): cdef object _object_to_pin def __init__(self, buf, traversal_limit_in_words = None, nesting_limit = None): cdef schema_cpp.ReaderOptions opts + cdef _AlignedBuffer aligned if traversal_limit_in_words is not None: opts.traversalLimitInWords = traversal_limit_in_words if nesting_limit is not None: opts.nestingLimit = nesting_limit - cdef const void *ptr - cdef Py_ssize_t sz - PyObject_AsReadBuffer(buf, &ptr, &sz) + sz = len(buf) if sz % 8 != 0: raise ValueError("input length must be a multiple of eight bytes") + + cdef char * ptr = buf + if (ptr) % 8 != 0: + aligned = _AlignedBuffer(buf) + ptr = aligned.buf self._object_to_pin = buf self.thisptr = new schema_cpp.FlatArrayMessageReader(schema_cpp.WordArrayPtr(ptr, sz//8))