Compare commits
3 Commits
d6177bec53
...
aec7242e72
Author | SHA1 | Date | |
---|---|---|---|
aec7242e72 | |||
6980156e48 | |||
4b76aeabb9 |
@ -14,6 +14,7 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import io
|
import io
|
||||||
import struct
|
import struct
|
||||||
@ -126,6 +127,10 @@ class CslaBinaryReader:
|
|||||||
# BinaryReader.ReadInt32
|
# BinaryReader.ReadInt32
|
||||||
return struct.unpack('<i', self.stream.read(4))[0]
|
return struct.unpack('<i', self.stream.read(4))[0]
|
||||||
|
|
||||||
|
def read_int64(self):
|
||||||
|
# BinaryReader.ReadInt64
|
||||||
|
return struct.unpack('<q', self.stream.read(8))[0]
|
||||||
|
|
||||||
def read_object(self):
|
def read_object(self):
|
||||||
# CslaBinaryReader.ReadObject
|
# CslaBinaryReader.ReadObject
|
||||||
known_type = self.stream.read(1)[0]
|
known_type = self.stream.read(1)[0]
|
||||||
@ -171,7 +176,10 @@ class CslaBinaryReader:
|
|||||||
return self.read_decimal()
|
return self.read_decimal()
|
||||||
|
|
||||||
if known_type == CslaKnownTypes.DateTime.value:
|
if known_type == CslaKnownTypes.DateTime.value:
|
||||||
raise NotImplementedError()
|
timestamp = self.read_int64() # Number of 100-nanosecond intervals that have elapsed since January 1, 0001 at 00:00:00.000
|
||||||
|
timestamp_unix = timestamp - 621355968000000000 # Subtract unix epoch in .NET ticks - https://gist.github.com/kristopherjohnson/397d0f74213a0087f1a1
|
||||||
|
timestamp_unix /= 10000000 # Convert ticks to seconds (10^9 / 100)
|
||||||
|
return datetime.fromtimestamp(timestamp_unix)
|
||||||
|
|
||||||
if known_type == CslaKnownTypes.String.value:
|
if known_type == CslaKnownTypes.String.value:
|
||||||
return self.read_string()
|
return self.read_string()
|
||||||
@ -197,7 +205,7 @@ class CslaBinaryReader:
|
|||||||
return [self.read_int32() for _ in range(length)]
|
return [self.read_int32() for _ in range(length)]
|
||||||
|
|
||||||
if known_type == CslaKnownTypes.Null.value:
|
if known_type == CslaKnownTypes.Null.value:
|
||||||
raise NotImplementedError()
|
return None
|
||||||
|
|
||||||
if known_type == CslaKnownTypes.StringWithDictionaryKey.value:
|
if known_type == CslaKnownTypes.StringWithDictionaryKey.value:
|
||||||
system_string = self.read_string()
|
system_string = self.read_string()
|
||||||
|
@ -14,10 +14,12 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from decimal import Decimal
|
||||||
import io
|
import io
|
||||||
import struct
|
import struct
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
from .decimal import decimal_to_int32
|
||||||
from .known_types import CslaKnownTypes
|
from .known_types import CslaKnownTypes
|
||||||
from .serialization_info import SerializationInfo
|
from .serialization_info import SerializationInfo
|
||||||
|
|
||||||
@ -95,12 +97,15 @@ class CslaBinaryWriter:
|
|||||||
if isinstance(value, bool):
|
if isinstance(value, bool):
|
||||||
return self.write_object_bool(value)
|
return self.write_object_bool(value)
|
||||||
|
|
||||||
if isinstance(value, bytes):
|
if isinstance(value, Decimal):
|
||||||
return self.write_object_bytearray(value)
|
return self.write_object_decimal(value)
|
||||||
|
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
return self.write_object_string(value)
|
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__))
|
raise NotImplementedError('CslaBinaryWriter.Write not implemented for type {}'.format(type(value).__name__))
|
||||||
|
|
||||||
def write_object_bool(self, value):
|
def write_object_bool(self, value):
|
||||||
@ -113,6 +118,14 @@ class CslaBinaryWriter:
|
|||||||
self.write_int32(len(value))
|
self.write_int32(len(value))
|
||||||
self.stream.write(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):
|
def write_object_int32(self, value):
|
||||||
# CslaBinaryWriter.Write(int)
|
# CslaBinaryWriter.Write(int)
|
||||||
self.stream.write(bytes([CslaKnownTypes.Int32.value]))
|
self.stream.write(bytes([CslaKnownTypes.Int32.value]))
|
||||||
|
@ -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)
|
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():
|
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())
|
# 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')
|
assert int32_to_decimal([0x0, 0x0, 0x0, 0x0]) == Decimal('0')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user