Skip to content

Commit 1bcd54e

Browse files
committed
buffer: Add support for length-prefixed bytes/text
Add read_len_prefixed_bytes(), read_len_prefixed_utf8(), and write_len_prefixed_bytes() methods.
1 parent 8a3a4b2 commit 1bcd54e

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

buffer.pxd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ cdef class WriteBuffer:
3636
cdef write_buffer(self, WriteBuffer buf)
3737
cdef write_byte(self, char b)
3838
cdef write_bytes(self, bytes data)
39+
cdef write_len_prefixed_bytes(self, bytes data)
3940
cdef write_bytestring(self, bytes string)
4041
cdef write_str(self, str string, str encoding)
4142
cdef write_utf8(self, str string)
@@ -103,6 +104,9 @@ cdef class ReadBuffer:
103104
cdef inline read_utf8(self):
104105
return self.read_null_str().decode('utf-8')
105106

107+
cdef inline read_len_prefixed_utf8(self):
108+
return self.read_len_prefixed_bytes().decode('utf-8')
109+
106110
cdef feed_data(self, data)
107111
cdef inline _ensure_first_buf(self)
108112
cdef _switch_to_next_buf(self)
@@ -111,6 +115,7 @@ cdef class ReadBuffer:
111115
cdef inline _read_into(self, char *buf, ssize_t nbytes)
112116
cdef inline _read_and_discard(self, ssize_t nbytes)
113117
cdef bytes read_bytes(self, ssize_t nbytes)
118+
cdef bytes read_len_prefixed_bytes(self)
114119
cdef inline int32_t read_int32(self) except? -1
115120
cdef inline int16_t read_int16(self) except? -1
116121
cdef inline read_null_str(self)

buffer.pyx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,19 @@ cdef class WriteBuffer:
154154
cdef write_utf8(self, str string):
155155
self.write_bytestring(string.encode('utf-8'))
156156

157+
cdef write_len_prefixed_bytes(self, bytes data):
158+
# Write a length-prefixed (not NULL-terminated) UTF-8 string.
159+
cdef:
160+
char *buf
161+
ssize_t size
162+
163+
cpython.PyBytes_AsStringAndSize(data, &buf, &size)
164+
if size > _MAXINT32:
165+
raise exceptions.BufferError('string is too large')
166+
# `size` does not account for the NULL at the end.
167+
self.write_int32(<int32_t>size)
168+
self.write_cstr(buf, size)
169+
157170
cdef write_cstr(self, const char *data, ssize_t len):
158171
self._check_readonly()
159172
self._ensure_alloced(len)
@@ -381,6 +394,13 @@ cdef class ReadBuffer:
381394
self._read_into(buf, nbytes)
382395
return result
383396

397+
cdef bytes read_len_prefixed_bytes(self):
398+
cdef int32_t size = self.read_int32()
399+
if size < 0:
400+
raise exceptions.BufferError(
401+
'negative length for a len-prefixed bytes value')
402+
return self.read_bytes(size)
403+
384404
cdef inline char read_byte(self) except? -1:
385405
cdef const char *first_byte
386406

0 commit comments

Comments
 (0)