IGNITE-14057 Support big-endian systems
Fix primitives decoding on big-endian architectures. This closes #7
diff --git a/pyignite/api/binary.py b/pyignite/api/binary.py
index 1d63b49..722001a 100644
--- a/pyignite/api/binary.py
+++ b/pyignite/api/binary.py
@@ -86,7 +86,7 @@
if result.status != 0:
return result
result.value = {
- 'type_exists': response.type_exists
+ 'type_exists': Bool.to_python(response.type_exists)
}
if hasattr(response, 'body'):
result.value.update(body_struct.to_python(response.body))
diff --git a/pyignite/datatypes/internal.py b/pyignite/datatypes/internal.py
index 9fd5d64..9f23ec6 100644
--- a/pyignite/datatypes/internal.py
+++ b/pyignite/datatypes/internal.py
@@ -204,7 +204,7 @@
def parse(
self, client: 'Client'
- ) -> Tuple[ctypes.BigEndianStructure, bytes]:
+ ) -> Tuple[ctypes.LittleEndianStructure, bytes]:
buffer = b''
fields = []
values = {}
diff --git a/pyignite/datatypes/primitive.py b/pyignite/datatypes/primitive.py
index 23d070d..d549fda 100644
--- a/pyignite/datatypes/primitive.py
+++ b/pyignite/datatypes/primitive.py
@@ -14,6 +14,8 @@
# limitations under the License.
import ctypes
+import struct
+import sys
from pyignite.constants import *
from .base import IgniteDataType
@@ -48,13 +50,9 @@
def parse(cls, client: 'Client'):
return cls.c_type, client.recv(ctypes.sizeof(cls.c_type))
- @staticmethod
- def to_python(ctype_object, *args, **kwargs):
- return ctype_object
-
@classmethod
- def from_python(cls, value):
- return bytes(cls.c_type(value))
+ def to_python(cls, ctype_object, *args, **kwargs):
+ return ctype_object
class Byte(Primitive):
@@ -62,36 +60,60 @@
_type_id = TYPE_BYTE
c_type = ctypes.c_byte
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<b", value)
+
class Short(Primitive):
_type_name = NAME_SHORT
_type_id = TYPE_SHORT
c_type = ctypes.c_short
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<h", value)
+
class Int(Primitive):
_type_name = NAME_INT
_type_id = TYPE_INT
c_type = ctypes.c_int
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<i", value)
+
class Long(Primitive):
_type_name = NAME_LONG
_type_id = TYPE_LONG
c_type = ctypes.c_longlong
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<q", value)
+
class Float(Primitive):
_type_name = NAME_FLOAT
_type_id = TYPE_FLOAT
c_type = ctypes.c_float
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<f", value)
+
class Double(Primitive):
_type_name = NAME_DOUBLE
_type_id = TYPE_DOUBLE
c_type = ctypes.c_double
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<d", value)
+
class Char(Primitive):
_type_name = NAME_CHAR
@@ -122,4 +144,12 @@
class Bool(Primitive):
_type_name = NAME_BOOLEAN
_type_id = TYPE_BOOLEAN
- c_type = ctypes.c_bool
+ c_type = ctypes.c_byte # Use c_byte because c_bool throws endianness conversion error on BE systems.
+
+ @classmethod
+ def to_python(cls, ctype_object, *args, **kwargs):
+ return ctype_object != 0
+
+ @classmethod
+ def from_python(cls, value):
+ return struct.pack("<b", 1 if value else 0)
diff --git a/pyignite/datatypes/primitive_objects.py b/pyignite/datatypes/primitive_objects.py
index 0bd0ec6..033ac9e 100644
--- a/pyignite/datatypes/primitive_objects.py
+++ b/pyignite/datatypes/primitive_objects.py
@@ -207,7 +207,7 @@
class BoolObject(DataObject):
_type_name = NAME_BOOLEAN
_type_id = TYPE_BOOLEAN
- c_type = ctypes.c_bool
+ c_type = ctypes.c_byte # Use c_byte because c_bool throws endianness conversion error on BE systems.
type_code = TC_BOOL
pythonic = bool
default = False
@@ -215,3 +215,8 @@
@staticmethod
def hashcode(value: bool, *args, **kwargs) -> int:
return 1231 if value else 1237
+
+ @classmethod
+ def to_python(cls, ctype_object, *args, **kwargs):
+ return ctype_object.value != 0
+
diff --git a/pyignite/queries/response.py b/pyignite/queries/response.py
index 6003959..05a519a 100644
--- a/pyignite/queries/response.py
+++ b/pyignite/queries/response.py
@@ -179,7 +179,7 @@
)
fields += body_class._fields_ + [
('data', data_class),
- ('more', ctypes.c_bool),
+ ('more', ctypes.c_byte),
]
def _create_parse_result(self, conn: Connection, header_class, fields: list, buffer: bytearray):
diff --git a/tests/test_binary.py b/tests/test_binary.py
index 1c051f0..5190a6a 100644
--- a/tests/test_binary.py
+++ b/tests/test_binary.py
@@ -225,7 +225,7 @@
def test_add_schema_to_binary_object(client):
- migrate_cache = client.create_cache('migrate_binary')
+ migrate_cache = client.get_or_create_cache('migrate_binary')
class MyBinaryType(
metaclass=GenericObjectMeta,