From 4b76aeabb9499c4a2d452ade0fe1e54ce0bf104d Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Mon, 21 Apr 2025 21:46:22 +1000 Subject: [PATCH] Implement write for Decimal (basic implementation) --- csla_binary/binary_writer.py | 17 +++++++++++++++-- csla_binary/decimal.py | 9 +++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/csla_binary/binary_writer.py b/csla_binary/binary_writer.py index bcdea79..3eaf400 100644 --- a/csla_binary/binary_writer.py +++ b/csla_binary/binary_writer.py @@ -14,10 +14,12 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from decimal import Decimal import io import struct from typing import List +from .decimal import decimal_to_int32 from .known_types import CslaKnownTypes from .serialization_info import SerializationInfo @@ -95,12 +97,15 @@ class CslaBinaryWriter: if isinstance(value, bool): return self.write_object_bool(value) - if isinstance(value, bytes): - return self.write_object_bytearray(value) + if isinstance(value, Decimal): + return self.write_object_decimal(value) if isinstance(value, str): return self.write_object_string(value) + if isinstance(value, bytes): + return self.write_object_bytearray(value) + raise NotImplementedError('CslaBinaryWriter.Write not implemented for type {}'.format(type(value).__name__)) def write_object_bool(self, value): @@ -113,6 +118,14 @@ class CslaBinaryWriter: self.write_int32(len(value)) self.stream.write(value) + def write_object_decimal(self, value): + # CslaBinaryWriter.Write(Decimal) + self.stream.write(bytes([CslaKnownTypes.Decimal.value])) + int32_repr = decimal_to_int32(value) + self.write_int32(len(int32_repr)) # Should be 4 always + for part in int32_repr: + self.write_int32(part) + def write_object_int32(self, value): # CslaBinaryWriter.Write(int) self.stream.write(bytes([CslaKnownTypes.Int32.value])) diff --git a/csla_binary/decimal.py b/csla_binary/decimal.py index db471e4..63eacfa 100644 --- a/csla_binary/decimal.py +++ b/csla_binary/decimal.py @@ -47,6 +47,15 @@ def int32_to_decimal(decimal_parts: List[int]) -> Decimal: return Decimal(mantissa * (-1 if sign == 1 else 1)) / (Decimal(10) ** exponent) +def decimal_to_int32(decimal: Decimal) -> List[int]: + # FIXME: Only supports 32-bit integers + if decimal != decimal.to_integral_value(): + raise NotImplementedError('decimal_to_int32 only supports 32-bit integers') + if decimal < Decimal('0') or decimal >= Decimal('2') ** 32: + raise NotImplementedError('decimal_to_int32 only supports 32-bit integers') + + return [int(decimal), 0, 0, 0] + def test_int32_to_decimal(): # https://learn.microsoft.com/en-us/dotnet/api/system.decimal.-ctor?view=net-9.0#system-decimal-ctor(system-int32()) assert int32_to_decimal([0x0, 0x0, 0x0, 0x0]) == Decimal('0')