def test_unpack_uint32(): a = 12 b = 2**31 + 1 buf = struct.pack('II', a, b) assert unpack_uint32(buf, 0) == a assert unpack_uint32(buf, 4) == b buf = b'abc' pytest.raises(IndexError, "unpack_uint32(buf, 0)")
def _load_buffer_single_segment(f): # fast path for the single-segment case. In this scenario, we don't # even need to compute the padding as we know that we read exactly 4+4 # bytes buf = f.read(4) # # The cost of the len(buf) checks is ~7-8% on CPython, but I don't know # how to avoid it. However, it's negligible on PyPy if len(buf) < 4: raise ValueError("Unexpected EOF when reading the header") message_size = unpack_uint32(buf, 0) message_lenght = message_size * 8 buf = f.read(message_lenght) if len(buf) < message_lenght: raise ValueError("Unexpected EOF: expected %d bytes, got only %s. " "Segment size: %s" % (message_lenght, len(buf), message_size)) return Segment(buf)
def _load_message(f): # read the total number of segments buf = f.read(4) if len(buf) < 4: raise EOFError("No message to load") n = unpack_uint32(buf, 0) + 1 if n == 1: capnp_buf = _load_buffer_single_segment(f) # fast path else: capnp_buf = _load_buffer_multiple_segments(f, n) # slow path # # from the capnproto docs: # # The first word of the first segment of the message is always a # pointer pointing to the message's root struct. # # Thus, the root of the message is equivalent to a struct with # data_size==0 and ptrs_size==1 return struct_from_buffer(Struct, capnp_buf, 0, data_size=0, ptrs_size=1)