diff --git a/hazelcast/serialization/input.py b/hazelcast/serialization/input.py index cd982cd10d..3d873659a0 100644 --- a/hazelcast/serialization/input.py +++ b/hazelcast/serialization/input.py @@ -147,10 +147,10 @@ def read_string(self): length = self.read_int() if length == NULL_ARRAY_LENGTH: return None - result = bytearray(length) - if length > 0: - self.read_into(result, 0, length) - return result.decode("utf-8") + self._check_available(self._pos, length) + result = self._buffer[self._pos : self._pos + length].decode("utf-8") + self._pos += length + return result def read_byte_array(self): length = self.read_int() @@ -163,28 +163,28 @@ def read_byte_array(self): return result def read_i8_array(self) -> typing.List[int]: - return self._read_array_fnc(self.read_byte) + return self._bulk_read(BYTE_SIZE_IN_BYTES, "b") def read_boolean_array(self): - return self._read_array_fnc(self.read_boolean) + return self._bulk_read(BOOLEAN_SIZE_IN_BYTES, "?") def read_char_array(self): return self._read_array_fnc(self.read_char) def read_int_array(self): - return self._read_array_fnc(self.read_int) + return self._bulk_read(INT_SIZE_IN_BYTES, "i") def read_long_array(self): - return self._read_array_fnc(self.read_long) + return self._bulk_read(LONG_SIZE_IN_BYTES, "q") def read_double_array(self): - return self._read_array_fnc(self.read_double) + return self._bulk_read(DOUBLE_SIZE_IN_BYTES, "d") def read_float_array(self): - return self._read_array_fnc(self.read_float) + return self._bulk_read(FLOAT_SIZE_IN_BYTES, "f") def read_short_array(self): - return self._read_array_fnc(self.read_short) + return self._bulk_read(SHORT_SIZE_IN_BYTES, "h") def read_string_array(self): return self._read_array_fnc(self.read_string) @@ -215,7 +215,18 @@ def read_utf(self): def read_utf_array(self): return self.read_string_array() - # HELPERS + def _bulk_read(self, item_size, fmt_char): + length = self.read_int() + if length == NULL_ARRAY_LENGTH: + return None + + nbytes = length * item_size + self._check_available(self._pos, nbytes) + endian = ">" if self._is_big_endian else "<" + result = list(struct.unpack_from(f"{endian}{length}{fmt_char}", self._buffer, self._pos)) + self._pos += nbytes + return result + def _check_available(self, position, size): if position < 0: raise ValueError diff --git a/hazelcast/serialization/output.py b/hazelcast/serialization/output.py index 445b755a6b..79ee30bb07 100644 --- a/hazelcast/serialization/output.py +++ b/hazelcast/serialization/output.py @@ -1,5 +1,3 @@ -import typing - from hazelcast.serialization.api import * from hazelcast.serialization.bits import * @@ -157,28 +155,28 @@ def write_byte_array(self, val): self._pos += _len def write_signed_byte_array(self, val: typing.List[int]) -> None: - self._write_array_fnc(val, self.write_signed_byte) + self._bulk_write(val, BYTE_SIZE_IN_BYTES, "b") def write_boolean_array(self, val): - self._write_array_fnc(val, self.write_boolean) + self._bulk_write(val, BOOLEAN_SIZE_IN_BYTES, "?") def write_char_array(self, val): self._write_array_fnc(val, self.write_char) def write_int_array(self, val): - self._write_array_fnc(val, self.write_int) + self._bulk_write(val, INT_SIZE_IN_BYTES, "i") def write_long_array(self, val): - self._write_array_fnc(val, self.write_long) + self._bulk_write(val, LONG_SIZE_IN_BYTES, "q") def write_double_array(self, val): - self._write_array_fnc(val, self.write_double) + self._bulk_write(val, DOUBLE_SIZE_IN_BYTES, "d") def write_float_array(self, val): - self._write_array_fnc(val, self.write_float) + self._bulk_write(val, FLOAT_SIZE_IN_BYTES, "f") def write_short_array(self, val): - self._write_array_fnc(val, self.write_short) + self._bulk_write(val, SHORT_SIZE_IN_BYTES, "h") def write_string_array(self, val): self._write_array_fnc(val, self.write_string) @@ -204,8 +202,9 @@ def set_position(self, position): self._pos = position def write_zero_bytes(self, count): - for _ in range(0, count): - self._write(0) + self._ensure_available(count) + self._buffer[self._pos : self._pos + count] = bytes(count) + self._pos += count def write_utf(self, val): self.write_string(val) @@ -213,7 +212,16 @@ def write_utf(self, val): def write_utf_array(self, val): self.write_string_array(val) - # HELPERS + def _bulk_write(self, val, item_size, fmt_char): + length = len(val) if val is not None else NULL_ARRAY_LENGTH + self.write_int(length) + if length > 0: + nbytes = length * item_size + self._ensure_available(nbytes) + endian = ">" if self._is_big_endian else "<" + struct.pack_into(f"{endian}{length}{fmt_char}", self._buffer, self._pos, *val) + self._pos += nbytes + def _write_array_fnc(self, val, item_write_fnc): _len = len(val) if val is not None else NULL_ARRAY_LENGTH self.write_int(_len)