]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Added proper binary integer decoding in cython
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 10 May 2020 10:30:36 +0000 (22:30 +1200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 10 May 2020 12:30:10 +0000 (00:30 +1200)
psycopg3/types/endian.pxd [new file with mode: 0644]
psycopg3/types/numeric.pyx

diff --git a/psycopg3/types/endian.pxd b/psycopg3/types/endian.pxd
new file mode 100644 (file)
index 0000000..cf7592d
--- /dev/null
@@ -0,0 +1,22 @@
+# convert values  between host and big-/little-endian byte order
+# http://man7.org/linux/man-pages/man3/endian.3.html
+
+from libc.stdint cimport uint16_t, uint32_t, uint64_t
+
+
+cdef extern from "<endian.h>" nogil:
+
+    cdef uint16_t htobe16(uint16_t host_16bits)
+    cdef uint16_t htole16(uint16_t host_16bits)
+    cdef uint16_t be16toh(uint16_t big_endian_16bits)
+    cdef uint16_t le16toh(uint16_t little_endian_16bits)
+
+    cdef uint32_t htobe32(uint32_t host_32bits)
+    cdef uint32_t htole32(uint32_t host_32bits)
+    cdef uint32_t be32toh(uint32_t big_endian_32bits)
+    cdef uint32_t le32toh(uint32_t little_endian_32bits)
+
+    cdef uint64_t htobe64(uint64_t host_64bits)
+    cdef uint64_t htole64(uint64_t host_64bits)
+    cdef uint64_t be64toh(uint64_t big_endian_64bits)
+    cdef uint64_t le64toh(uint64_t little_endian_64bits)
index 10a1ff8bad135f2c46d3d8e083d44fdc0d9d31ef..7faa564fd57fe7bf42e0da48d41fefeab9e41427 100644 (file)
@@ -1,3 +1,6 @@
+from libc.stdint cimport *
+from psycopg3.types.endian cimport be16toh, be32toh, be64toh
+
 from cpython.long cimport (
     PyLong_FromLong, PyLong_FromLongLong, PyLong_FromUnsignedLong)
 
@@ -6,31 +9,19 @@ cdef object load_int_text(const char *data, size_t length, void *context):
     return int(data)
 
 cdef object load_int2_binary(const char *data, size_t length, void *context):
-    return PyLong_FromLong(unpack_int16(data, 2))
+    return PyLong_FromLong(<int16_t>be16toh((<uint16_t *>data)[0]))
 
 cdef object load_int4_binary(const char *data, size_t length, void *context):
-    return PyLong_FromLong(unpack_int32(data, 4))
+    return PyLong_FromLong(<int32_t>be32toh((<uint32_t *>data)[0]))
 
 cdef object load_int8_binary(const char *data, size_t length, void *context):
-    return PyLong_FromLongLong(unpack_int64(data, 8))
+    return PyLong_FromLongLong(<int64_t>be64toh((<uint64_t *>data)[0]))
 
 cdef object load_oid_binary(const char *data, size_t length, void *context):
-    return PyLong_FromUnsignedLong(unpack_uint32(data, 4))
+    return PyLong_FromUnsignedLong(be32toh((<uint32_t *>data)[0]))
 
 cdef object load_bool_binary(const char *data, size_t length, void *context):
     if data[0]:
         return True
     else:
         return False
-
-cdef long unpack_int16(const char *data, size_t length):
-    return 0
-
-cdef long unpack_int32(const char *data, size_t length):
-    return 0
-
-cdef long unpack_uint32(const char *data, size_t length):
-    return 0
-
-cdef long long unpack_int64(const char *data, size_t length):
-    return 0