Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 24 additions & 50 deletions cassandra/deserializers.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,9 @@ cdef class _DesSingleParamType(_DesParameterizedType):

cdef class DesListType(_DesSingleParamType):
cdef deserialize(self, Buffer *buf, int protocol_version):
cdef uint16_t v2_and_below = 2
cdef int32_t v3_and_above = 3

if protocol_version >= 3:
result = _deserialize_list_or_set[int32_t](
v3_and_above, buf, protocol_version, self.deserializer)
else:
result = _deserialize_list_or_set[uint16_t](
v2_and_below, buf, protocol_version, self.deserializer)
result = _deserialize_list_or_set(
buf, protocol_version, self.deserializer)

return result

Expand All @@ -225,60 +219,49 @@ cdef class DesSetType(DesListType):
return util.sortedset(DesListType.deserialize(self, buf, protocol_version))


ctypedef fused itemlen_t:
uint16_t # protocol <= v2
int32_t # protocol >= v3

cdef list _deserialize_list_or_set(itemlen_t dummy_version,
Buffer *buf, int protocol_version,
cdef list _deserialize_list_or_set(Buffer *buf, int protocol_version,
Deserializer deserializer):
"""
Deserialize a list or set.

The 'dummy' parameter is needed to make fused types work, so that
we can specialize on the protocol version.
"""
cdef Buffer itemlen_buf
cdef Buffer elem_buf

cdef itemlen_t numelements
cdef int32_t numelements
cdef int offset
cdef list result = []

_unpack_len[itemlen_t](buf, 0, &numelements)
offset = sizeof(itemlen_t)
_unpack_len(buf, 0, &numelements)
offset = sizeof(int32_t)
protocol_version = max(3, protocol_version)
for _ in range(numelements):
subelem[itemlen_t](buf, &elem_buf, &offset, dummy_version)
subelem(buf, &elem_buf, &offset)
result.append(from_binary(deserializer, &elem_buf, protocol_version))

return result


cdef inline int subelem(
Buffer *buf, Buffer *elem_buf, int* offset, itemlen_t dummy) except -1:
Buffer *buf, Buffer *elem_buf, int* offset) except -1:
"""
Read the next element from the buffer: first read the size (in bytes) of the
element, then fill elem_buf with a newly sliced buffer of this size (and the
right offset).
"""
cdef itemlen_t elemlen
cdef int32_t elemlen

_unpack_len[itemlen_t](buf, offset[0], &elemlen)
offset[0] += sizeof(itemlen_t)
_unpack_len(buf, offset[0], &elemlen)
offset[0] += sizeof(int32_t)
slice_buffer(buf, elem_buf, offset[0], elemlen)
offset[0] += elemlen
return 0


cdef int _unpack_len(Buffer *buf, int offset, itemlen_t *output) except -1:
cdef int _unpack_len(Buffer *buf, int offset, int32_t *output) except -1:
cdef Buffer itemlen_buf
slice_buffer(buf, &itemlen_buf, offset, sizeof(itemlen_t))
slice_buffer(buf, &itemlen_buf, offset, sizeof(int32_t))

if itemlen_t is uint16_t:
output[0] = unpack_num[uint16_t](&itemlen_buf)
else:
output[0] = unpack_num[int32_t](&itemlen_buf)
output[0] = unpack_num[int32_t](&itemlen_buf)

return 0

Expand All @@ -295,42 +278,33 @@ cdef class DesMapType(_DesParameterizedType):
self.val_deserializer = self.deserializers[1]

cdef deserialize(self, Buffer *buf, int protocol_version):
cdef uint16_t v2_and_below = 0
cdef int32_t v3_and_above = 0
key_type, val_type = self.cqltype.subtypes

if protocol_version >= 3:
result = _deserialize_map[int32_t](
v3_and_above, buf, protocol_version,
self.key_deserializer, self.val_deserializer,
key_type, val_type)
else:
result = _deserialize_map[uint16_t](
v2_and_below, buf, protocol_version,
self.key_deserializer, self.val_deserializer,
key_type, val_type)
result = _deserialize_map(
buf, protocol_version,
self.key_deserializer, self.val_deserializer,
key_type, val_type)

return result


cdef _deserialize_map(itemlen_t dummy_version,
Buffer *buf, int protocol_version,
cdef _deserialize_map(Buffer *buf, int protocol_version,
Deserializer key_deserializer, Deserializer val_deserializer,
key_type, val_type):
cdef Buffer key_buf, val_buf
cdef Buffer itemlen_buf

cdef itemlen_t numelements
cdef int32_t numelements
cdef int offset
cdef list result = []

_unpack_len[itemlen_t](buf, 0, &numelements)
offset = sizeof(itemlen_t)
_unpack_len(buf, 0, &numelements)
offset = sizeof(int32_t)
themap = util.OrderedMapSerializedKey(key_type, protocol_version)
protocol_version = max(3, protocol_version)
for _ in range(numelements):
subelem[itemlen_t](buf, &key_buf, &offset, dummy_version)
subelem[itemlen_t](buf, &val_buf, &offset, numelements)
subelem(buf, &key_buf, &offset)
subelem(buf, &val_buf, &offset)
key = from_binary(key_deserializer, &key_buf, protocol_version)
val = from_binary(val_deserializer, &val_buf, protocol_version)
themap._insert_unchecked(key, to_bytes(&key_buf), val)
Expand Down
Loading