Fix bug in to_bytes_packed when packed size > unpacked size.
This commit is contained in:
@@ -33,7 +33,7 @@ cdef extern from "../helpers/rpcHelper.h":
|
|||||||
PyPromise connectServer(TaskSet &, PyRestorer &, AsyncIoContext *, StringPtr)
|
PyPromise connectServer(TaskSet &, PyRestorer &, AsyncIoContext *, StringPtr)
|
||||||
|
|
||||||
cdef extern from "../helpers/serialize.h":
|
cdef extern from "../helpers/serialize.h":
|
||||||
ByteArray messageToPackedBytes(MessageBuilder &)
|
ByteArray messageToPackedBytes(MessageBuilder &, size_t wordCount)
|
||||||
|
|
||||||
cdef extern from "../helpers/asyncHelper.h":
|
cdef extern from "../helpers/asyncHelper.h":
|
||||||
void waitNeverDone(WaitScope&)
|
void waitNeverDone(WaitScope&)
|
||||||
|
|||||||
@@ -4,16 +4,10 @@
|
|||||||
#include "capnp/dynamic.h"
|
#include "capnp/dynamic.h"
|
||||||
#include "capnp/serialize-packed.h"
|
#include "capnp/serialize-packed.h"
|
||||||
|
|
||||||
kj::Array< ::capnp::byte> messageToPackedBytes(capnp::MessageBuilder & message)
|
kj::Array< ::capnp::byte> messageToPackedBytes(capnp::MessageBuilder & message, size_t wordCount)
|
||||||
{
|
{
|
||||||
auto segments = message.getSegmentsForOutput();
|
|
||||||
size_t totalSize = segments.size() / 2 + 1;
|
|
||||||
|
|
||||||
for (auto& segment: segments) {
|
kj::Array<capnp::byte> result = kj::heapArray<capnp::byte>(wordCount * 8);
|
||||||
totalSize += segment.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
kj::Array<capnp::byte> result = kj::heapArray<capnp::byte>(totalSize * 8);
|
|
||||||
kj::ArrayOutputStream out(result.asPtr());
|
kj::ArrayOutputStream out(result.asPtr());
|
||||||
capnp::writePackedMessage(out, message);
|
capnp::writePackedMessage(out, message);
|
||||||
return heapArray(out.getArray()); // TODO: make this non-copying somehow
|
return heapArray(out.getArray()); // TODO: make this non-copying somehow
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ from .capnp.includes.types cimport *
|
|||||||
cdef extern from "capnp/common.h" namespace " ::capnp":
|
cdef extern from "capnp/common.h" namespace " ::capnp":
|
||||||
enum Void:
|
enum Void:
|
||||||
VOID " ::capnp::VOID"
|
VOID " ::capnp::VOID"
|
||||||
|
cdef cppclass MessageSize:
|
||||||
|
uint64_t wordCount
|
||||||
|
uint capCount
|
||||||
|
|
||||||
cdef extern from "capnp/common.h":
|
cdef extern from "capnp/common.h":
|
||||||
int CAPNP_VERSION_MAJOR
|
int CAPNP_VERSION_MAJOR
|
||||||
@@ -214,11 +217,13 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
|||||||
bint has(char *) except +reraise_kj_exception
|
bint has(char *) except +reraise_kj_exception
|
||||||
StructSchema getSchema()
|
StructSchema getSchema()
|
||||||
Maybe[StructSchema.Field] which()
|
Maybe[StructSchema.Field] which()
|
||||||
|
MessageSize totalSize()
|
||||||
cppclass Pipeline:
|
cppclass Pipeline:
|
||||||
Pipeline()
|
Pipeline()
|
||||||
Pipeline(Pipeline &)
|
Pipeline(Pipeline &)
|
||||||
DynamicValueForward.Pipeline get(char *)
|
DynamicValueForward.Pipeline get(char *)
|
||||||
StructSchema getSchema()
|
StructSchema getSchema()
|
||||||
|
|
||||||
cdef cppclass DynamicStruct_Builder" ::capnp::DynamicStruct::Builder": # Need to flatten this class out, since nested C++ classes cause havoc with cython fused types
|
cdef cppclass DynamicStruct_Builder" ::capnp::DynamicStruct::Builder": # Need to flatten this class out, since nested C++ classes cause havoc with cython fused types
|
||||||
DynamicStruct_Builder()
|
DynamicStruct_Builder()
|
||||||
DynamicStruct_Builder(DynamicStruct_Builder &)
|
DynamicStruct_Builder(DynamicStruct_Builder &)
|
||||||
@@ -232,6 +237,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
|||||||
void adopt(char *, DynamicOrphan) except +reraise_kj_exception
|
void adopt(char *, DynamicOrphan) except +reraise_kj_exception
|
||||||
DynamicOrphan disown(char *)
|
DynamicOrphan disown(char *)
|
||||||
DynamicStruct.Reader asReader()
|
DynamicStruct.Reader asReader()
|
||||||
|
MessageSize totalSize()
|
||||||
|
|
||||||
cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
cdef extern from "capnp/dynamic.h" namespace " ::capnp":
|
||||||
cdef cppclass DynamicCapability:
|
cdef cppclass DynamicCapability:
|
||||||
|
|||||||
@@ -837,6 +837,14 @@ cdef class _DynamicEnumField:
|
|||||||
def __call__(self):
|
def __call__(self):
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
|
cdef class _MessageSize:
|
||||||
|
cdef public uint64_t word_count
|
||||||
|
cdef public uint cap_count
|
||||||
|
|
||||||
|
def __init__(self, uint64_t word_count, uint cap_count):
|
||||||
|
self.word_count = word_count
|
||||||
|
self.cap_count = cap_count
|
||||||
|
|
||||||
cdef class _DynamicStructReader:
|
cdef class _DynamicStructReader:
|
||||||
"""Reads Cap'n Proto structs
|
"""Reads Cap'n Proto structs
|
||||||
|
|
||||||
@@ -911,6 +919,11 @@ cdef class _DynamicStructReader:
|
|||||||
builder = _MallocMessageBuilder()
|
builder = _MallocMessageBuilder()
|
||||||
return builder.set_root(self)
|
return builder.set_root(self)
|
||||||
|
|
||||||
|
property total_size:
|
||||||
|
def __get__(self):
|
||||||
|
size = self.thisptr.totalSize()
|
||||||
|
return _MessageSize(size.wordCount, size.capCount)
|
||||||
|
|
||||||
cdef class _DynamicStructBuilder:
|
cdef class _DynamicStructBuilder:
|
||||||
"""Builds Cap'n Proto structs
|
"""Builds Cap'n Proto structs
|
||||||
|
|
||||||
@@ -992,12 +1005,26 @@ cdef class _DynamicStructBuilder:
|
|||||||
self._is_written = True
|
self._is_written = True
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
cpdef to_bytes_packed(_DynamicStructBuilder self) except +reraise_kj_exception:
|
cpdef _to_bytes_packed_helper(_DynamicStructBuilder self, word_count) except +reraise_kj_exception:
|
||||||
self._check_write()
|
|
||||||
cdef _MessageBuilder builder = self._parent
|
cdef _MessageBuilder builder = self._parent
|
||||||
array = helpers.messageToPackedBytes(deref(builder.thisptr))
|
array = helpers.messageToPackedBytes(deref(builder.thisptr), word_count)
|
||||||
cdef const char* ptr = <const char *>array.begin()
|
cdef const char* ptr = <const char *>array.begin()
|
||||||
cdef bytes ret = ptr[:array.size()]
|
cdef bytes ret = ptr[:array.size()]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
cpdef to_bytes_packed(_DynamicStructBuilder self) except +reraise_kj_exception:
|
||||||
|
self._check_write()
|
||||||
|
word_count = self.total_size.word_count + 2
|
||||||
|
|
||||||
|
try:
|
||||||
|
ret = self._to_bytes_packed_helper(word_count)
|
||||||
|
except Exception as e:
|
||||||
|
if 'backing array was not large enough' in str(e):
|
||||||
|
word_count *= 2
|
||||||
|
ret = self._to_bytes_packed_helper(word_count)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
self._is_written = True
|
self._is_written = True
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -1147,6 +1174,11 @@ cdef class _DynamicStructBuilder:
|
|||||||
def to_dict(self, verbose=False):
|
def to_dict(self, verbose=False):
|
||||||
return _to_dict(self, verbose)
|
return _to_dict(self, verbose)
|
||||||
|
|
||||||
|
property total_size:
|
||||||
|
def __get__(self):
|
||||||
|
size = self.thisptr.totalSize()
|
||||||
|
return _MessageSize(size.wordCount, size.capCount)
|
||||||
|
|
||||||
cdef class _DynamicStructPipeline:
|
cdef class _DynamicStructPipeline:
|
||||||
"""Reads Cap'n Proto structs
|
"""Reads Cap'n Proto structs
|
||||||
|
|
||||||
@@ -1742,9 +1774,9 @@ cdef class _Restorer:
|
|||||||
|
|
||||||
cdef class _TwoPartyVatNetwork:
|
cdef class _TwoPartyVatNetwork:
|
||||||
cdef Own[C_TwoPartyVatNetwork] thisptr
|
cdef Own[C_TwoPartyVatNetwork] thisptr
|
||||||
cdef _FdAsyncIoStream stream
|
cdef _AsyncIoStream stream
|
||||||
|
|
||||||
cdef _init(self, _FdAsyncIoStream stream, Side side):
|
cdef _init(self, _AsyncIoStream stream, Side side):
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.thisptr = makeTwoPartyVatNetwork(deref(stream.thisptr), side)
|
self.thisptr = makeTwoPartyVatNetwork(deref(stream.thisptr), side)
|
||||||
return self
|
return self
|
||||||
@@ -1769,7 +1801,7 @@ cdef class TwoPartyClient:
|
|||||||
cdef public _TwoPartyVatNetwork _network
|
cdef public _TwoPartyVatNetwork _network
|
||||||
cdef public object _orig_stream
|
cdef public object _orig_stream
|
||||||
cdef public _Restorer _restorer
|
cdef public _Restorer _restorer
|
||||||
cdef public _FdAsyncIoStream _stream
|
cdef public _AsyncIoStream _stream
|
||||||
|
|
||||||
def __init__(self, socket, restorer=None):
|
def __init__(self, socket, restorer=None):
|
||||||
if isinstance(socket, basestring):
|
if isinstance(socket, basestring):
|
||||||
@@ -1849,7 +1881,7 @@ cdef class TwoPartyServer:
|
|||||||
cdef public _TwoPartyVatNetwork _network
|
cdef public _TwoPartyVatNetwork _network
|
||||||
cdef public object _orig_stream, _server_socket, _disconnect_promise
|
cdef public object _orig_stream, _server_socket, _disconnect_promise
|
||||||
cdef public _Restorer _restorer
|
cdef public _Restorer _restorer
|
||||||
cdef public _FdAsyncIoStream _stream
|
cdef public _AsyncIoStream _stream
|
||||||
cdef object _port
|
cdef object _port
|
||||||
cdef public object port_promise
|
cdef public object port_promise
|
||||||
cdef capnp.TaskSet * _task_set
|
cdef capnp.TaskSet * _task_set
|
||||||
@@ -1908,8 +1940,10 @@ cdef class TwoPartyServer:
|
|||||||
|
|
||||||
# TODO: add restore functionality here?
|
# TODO: add restore functionality here?
|
||||||
|
|
||||||
cdef class _FdAsyncIoStream:
|
cdef class _AsyncIoStream:
|
||||||
cdef Own[AsyncIoStream] thisptr
|
cdef Own[AsyncIoStream] thisptr
|
||||||
|
|
||||||
|
cdef class _FdAsyncIoStream(_AsyncIoStream):
|
||||||
cdef _EventLoop _event_loop
|
cdef _EventLoop _event_loop
|
||||||
|
|
||||||
def __init__(self, int fd):
|
def __init__(self, int fd):
|
||||||
@@ -1919,6 +1953,10 @@ cdef class _FdAsyncIoStream:
|
|||||||
self._event_loop = C_DEFAULT_EVENT_LOOP_GETTER()
|
self._event_loop = C_DEFAULT_EVENT_LOOP_GETTER()
|
||||||
self.thisptr = self._event_loop.wrapSocketFd(fd)
|
self.thisptr = self._event_loop.wrapSocketFd(fd)
|
||||||
|
|
||||||
|
cdef class PyAsyncIoStream(_AsyncIoStream):
|
||||||
|
def __init__(self, int fd):
|
||||||
|
pass
|
||||||
|
|
||||||
cdef class PromiseFulfillerPair:
|
cdef class PromiseFulfillerPair:
|
||||||
cdef Own[C_PromiseFulfillerPair] thisptr
|
cdef Own[C_PromiseFulfillerPair] thisptr
|
||||||
cdef public bint is_consumed
|
cdef public bint is_consumed
|
||||||
|
|||||||
Reference in New Issue
Block a user