Blob Blame History Raw
From 2e610c5da1aca8ef1b109fe8fe8236f7c19b0a8a Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Mon, 21 Feb 2022 09:44:39 -0500
Subject: [PATCH 1/7] =?UTF-8?q?Correct=20(uint32=5Ft*)=E2=86=94(size=5Ft*)?=
 =?UTF-8?q?=20prototype=20mismatch?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In the ctypes binding for Index_CreateWithStream, change the last
parameter from ctypes.POINTER(ctypes.c_uint32) to
ctypes.POINTER(ctypes.c_size_t) for consistency with libspatialindex.

This fixes the test failure on 64-bit big-endian architectures that
prompted #220. Other inconsistencies noted in that issue will be fixed
in additional commits.

https://github.com/Toblerity/rtree/issues/220#issue-1145043392
---
 rtree/core.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rtree/core.py b/rtree/core.py
index ae647f7b..95be034f 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -99,7 +99,7 @@ def free_error_msg_ptr(result, func, cargs):
                             ctypes.POINTER(ctypes.POINTER(ctypes.c_double)),
                             ctypes.POINTER(ctypes.c_uint32),
                             ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)),
-                            ctypes.POINTER(ctypes.c_uint32))
+                            ctypes.POINTER(ctypes.c_size_t))
 
 rt.Index_CreateWithStream.argtypes = [ctypes.c_void_p, NEXTFUNC]
 rt.Index_CreateWithStream.restype = ctypes.c_void_p

From b2a2c80fc8aa50ef02fb48a04b6a1b43aed7cd90 Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Mon, 21 Feb 2022 09:50:30 -0500
Subject: [PATCH 2/7] =?UTF-8?q?Set=20=E2=80=A6.argtypes=20=3D=20[]=20on=20?=
 =?UTF-8?q?all=20=E2=80=A6(void)=20functions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In the libspatialite API, Error_GetLastErrorNum,
Error_GetLastErrorMethod, and Error_GetErrorCount all take no parameters
“…(void)”. Add “….argtypes = []” to the ctypes bindings for
Error_GetLastErrorNum and Error_GetLastErrorMethod to match the other
two. This tells ctypes that they should have no parameters, “…(void)” in
C, rather than unspecified parameters, “…()” in C.'

https://github.com/Toblerity/rtree/issues/220#issuecomment-1046256119
---
 rtree/core.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/rtree/core.py b/rtree/core.py
index 95be034f..180a9773 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -74,12 +74,14 @@ def free_error_msg_ptr(result, func, cargs):
 # load the shared library by looking in likely places
 rt = finder.load()
 
+rt.Error_GetLastErrorNum.argtypes = []
 rt.Error_GetLastErrorNum.restype = ctypes.c_int
 
 rt.Error_GetLastErrorMsg.argtypes = []
 rt.Error_GetLastErrorMsg.restype = ctypes.POINTER(ctypes.c_char)
 rt.Error_GetLastErrorMsg.errcheck = free_error_msg_ptr
 
+rt.Error_GetLastErrorMethod.argtypes = []
 rt.Error_GetLastErrorMethod.restype = ctypes.POINTER(ctypes.c_char)
 rt.Error_GetLastErrorMethod.errcheck = free_returned_char_p
 

From 0b729154141b47f13b4f9bfd0c81c5152a64cb40 Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Mon, 21 Feb 2022 09:59:37 -0500
Subject: [PATCH 3/7] =?UTF-8?q?Correct=20c=5Fuint/c=5Fuint32=E2=86=94c=5Fs?=
 =?UTF-8?q?ize=5Ft=20prototype=20mismatches?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In SIDX_NewBuffer and Index_InsertTPData bindings, fix use of c_uint
(unsigned int) or c_uint32 (uint32_t) for value parameters that should be
c_size_t (size_t) for consistency with the libspatialite C API.

https://github.com/Toblerity/rtree/issues/220#issuecomment-1046256534
---
 rtree/core.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/rtree/core.py b/rtree/core.py
index 180a9773..606786b1 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -518,7 +518,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_GetIndexID.restype = ctypes.c_int64
 rt.IndexProperty_GetIndexID.errcheck = check_value
 
-rt.SIDX_NewBuffer.argtypes = [ctypes.c_uint]
+rt.SIDX_NewBuffer.argtypes = [ctypes.c_size_t]
 rt.SIDX_NewBuffer.restype = ctypes.c_void_p
 rt.SIDX_NewBuffer.errcheck = check_void
 
@@ -541,7 +541,7 @@ def free_error_msg_ptr(result, func, cargs):
                                       ctypes.c_double,
                                       ctypes.c_uint32,
                                       ctypes.POINTER(ctypes.c_ubyte),
-                                      ctypes.c_uint32]
+                                      ctypes.c_size_t]
     rt.Index_InsertTPData.restype = ctypes.c_int
     rt.Index_InsertTPData.errcheck = check_return
 

From cd063c406cbdd7e9348fbc2f8a970c47eb34fd05 Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Mon, 21 Feb 2022 10:03:21 -0500
Subject: [PATCH 4/7] Always use c_int to wrap enums
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change IndexProperty_SetIndexType to use c_int instead of c_int32 for
the “enum RTIndexType” parameter, and change
IndexProperty_SetIndexVariant and IndexProperty_SetIndexStorage to use
c_int instead of c_uint32 for their “enum RTIndexVariant” and
“enum RTStorageType” parameters, respectively.

This aligns these prototypes with the prevailing of c_int in these
bindings to wrap enums, elsewhere in the bindings for these particular
enum types, and even in the getters corresponding to these three
particular setters.

https://github.com/Toblerity/rtree/issues/220#issuecomment-1046256648
---
 rtree/core.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/rtree/core.py b/rtree/core.py
index 606786b1..a75d9b8b 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -295,7 +295,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_Destroy.restype = None
 rt.IndexProperty_Destroy.errcheck = check_void_done
 
-rt.IndexProperty_SetIndexType.argtypes = [ctypes.c_void_p, ctypes.c_int32]
+rt.IndexProperty_SetIndexType.argtypes = [ctypes.c_void_p, ctypes.c_int]
 rt.IndexProperty_SetIndexType.restype = ctypes.c_int
 rt.IndexProperty_SetIndexType.errcheck = check_return
 
@@ -311,7 +311,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_GetDimension.restype = ctypes.c_int
 rt.IndexProperty_GetDimension.errcheck = check_value
 
-rt.IndexProperty_SetIndexVariant.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
+rt.IndexProperty_SetIndexVariant.argtypes = [ctypes.c_void_p, ctypes.c_int]
 rt.IndexProperty_SetIndexVariant.restype = ctypes.c_int
 rt.IndexProperty_SetIndexVariant.errcheck = check_return
 
@@ -319,7 +319,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_GetIndexVariant.restype = ctypes.c_int
 rt.IndexProperty_GetIndexVariant.errcheck = check_value
 
-rt.IndexProperty_SetIndexStorage.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
+rt.IndexProperty_SetIndexStorage.argtypes = [ctypes.c_void_p, ctypes.c_int]
 rt.IndexProperty_SetIndexStorage.restype = ctypes.c_int
 rt.IndexProperty_SetIndexStorage.errcheck = check_return
 

From 42a3373abff402e6e06b0e2a74090329bec43bf4 Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Mon, 21 Feb 2022 10:13:17 -0500
Subject: [PATCH 5/7] =?UTF-8?q?Fix=20int=E2=86=94uint32=5Ft=20prototype=20?=
 =?UTF-8?q?mismatches=20in=20property=20getters?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fix a number of ctypes bindings for index property getters in which the
return type was given as c_int (int), but the libspatialite API has
c_uint32 (uint32_t).

https://github.com/Toblerity/rtree/issues/220#issuecomment-1046256746
---
 rtree/core.py | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/rtree/core.py b/rtree/core.py
index a75d9b8b..42007e2b 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -308,7 +308,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetDimension.errcheck = check_return
 
 rt.IndexProperty_GetDimension.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetDimension.restype = ctypes.c_int
+rt.IndexProperty_GetDimension.restype = ctypes.c_uint32
 rt.IndexProperty_GetDimension.errcheck = check_value
 
 rt.IndexProperty_SetIndexVariant.argtypes = [ctypes.c_void_p, ctypes.c_int]
@@ -332,7 +332,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetIndexCapacity.errcheck = check_return
 
 rt.IndexProperty_GetIndexCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetIndexCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetIndexCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetIndexCapacity.errcheck = check_value
 
 rt.IndexProperty_SetLeafCapacity.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
@@ -340,7 +340,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetLeafCapacity.errcheck = check_return
 
 rt.IndexProperty_GetLeafCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetLeafCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetLeafCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetLeafCapacity.errcheck = check_value
 
 rt.IndexProperty_SetPagesize.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
@@ -348,7 +348,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetPagesize.errcheck = check_return
 
 rt.IndexProperty_GetPagesize.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetPagesize.restype = ctypes.c_int
+rt.IndexProperty_GetPagesize.restype = ctypes.c_uint32
 rt.IndexProperty_GetPagesize.errcheck = check_value
 
 rt.IndexProperty_SetLeafPoolCapacity.argtypes = \
@@ -357,7 +357,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetLeafPoolCapacity.errcheck = check_return
 
 rt.IndexProperty_GetLeafPoolCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetLeafPoolCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetLeafPoolCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetLeafPoolCapacity.errcheck = check_value
 
 rt.IndexProperty_SetIndexPoolCapacity.argtypes = \
@@ -366,7 +366,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetIndexPoolCapacity.errcheck = check_return
 
 rt.IndexProperty_GetIndexPoolCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetIndexPoolCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetIndexPoolCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetIndexPoolCapacity.errcheck = check_value
 
 rt.IndexProperty_SetRegionPoolCapacity.argtypes = \
@@ -375,7 +375,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetRegionPoolCapacity.errcheck = check_return
 
 rt.IndexProperty_GetRegionPoolCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetRegionPoolCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetRegionPoolCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetRegionPoolCapacity.errcheck = check_value
 
 rt.IndexProperty_SetPointPoolCapacity.argtypes = \
@@ -384,7 +384,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetPointPoolCapacity.errcheck = check_return
 
 rt.IndexProperty_GetPointPoolCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetPointPoolCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetPointPoolCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetPointPoolCapacity.errcheck = check_value
 
 rt.IndexProperty_SetBufferingCapacity.argtypes = \
@@ -393,7 +393,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetBufferingCapacity.errcheck = check_return
 
 rt.IndexProperty_GetBufferingCapacity.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetBufferingCapacity.restype = ctypes.c_int
+rt.IndexProperty_GetBufferingCapacity.restype = ctypes.c_uint32
 rt.IndexProperty_GetBufferingCapacity.errcheck = check_value
 
 rt.IndexProperty_SetEnsureTightMBRs.argtypes = \
@@ -402,7 +402,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetEnsureTightMBRs.errcheck = check_return
 
 rt.IndexProperty_GetEnsureTightMBRs.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetEnsureTightMBRs.restype = ctypes.c_int
+rt.IndexProperty_GetEnsureTightMBRs.restype = ctypes.c_uint32
 rt.IndexProperty_GetEnsureTightMBRs.errcheck = check_value
 
 rt.IndexProperty_SetOverwrite.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
@@ -410,7 +410,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetOverwrite.errcheck = check_return
 
 rt.IndexProperty_GetOverwrite.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetOverwrite.restype = ctypes.c_int
+rt.IndexProperty_GetOverwrite.restype = ctypes.c_uint32
 rt.IndexProperty_GetOverwrite.errcheck = check_value
 
 rt.IndexProperty_SetNearMinimumOverlapFactor.argtypes = \
@@ -419,7 +419,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetNearMinimumOverlapFactor.errcheck = check_return
 
 rt.IndexProperty_GetNearMinimumOverlapFactor.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetNearMinimumOverlapFactor.restype = ctypes.c_int
+rt.IndexProperty_GetNearMinimumOverlapFactor.restype = ctypes.c_uint32
 rt.IndexProperty_GetNearMinimumOverlapFactor.errcheck = check_value
 
 rt.IndexProperty_SetWriteThrough.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
@@ -427,7 +427,7 @@ def free_error_msg_ptr(result, func, cargs):
 rt.IndexProperty_SetWriteThrough.errcheck = check_return
 
 rt.IndexProperty_GetWriteThrough.argtypes = [ctypes.c_void_p]
-rt.IndexProperty_GetWriteThrough.restype = ctypes.c_int
+rt.IndexProperty_GetWriteThrough.restype = ctypes.c_uint32
 rt.IndexProperty_GetWriteThrough.errcheck = check_value
 
 rt.IndexProperty_SetFillFactor.argtypes = [ctypes.c_void_p, ctypes.c_double]

From 70338ed3bf65c9d396781f9aa43a842eb01bd33f Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Mon, 21 Feb 2022 10:15:50 -0500
Subject: [PATCH 6/7] Fix incomplete binding for Index_TPIntersects_count

Add argument types and error checking callback.

https://github.com/Toblerity/rtree/issues/220#issuecomment-1046256780
---
 rtree/core.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/rtree/core.py b/rtree/core.py
index 42007e2b..040c2170 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -594,6 +594,8 @@ def free_error_msg_ptr(result, func, cargs):
                                             ctypes.c_double,
                                             ctypes.c_uint32,
                                             ctypes.POINTER(ctypes.c_uint64)]
+    rt.Index_TPIntersects_count.restype = ctypes.c_int
+    rt.Index_TPIntersects_count.errcheck = check_return
 
     rt.Index_TPNearestNeighbors_id.argtypes = [
         ctypes.c_void_p,

From 2c7a33cb09b4a2884d58cef65187444dfa6f65bb Mon Sep 17 00:00:00 2001
From: "Benjamin A. Beasley" <code@musicinmybrain.net>
Date: Tue, 22 Feb 2022 09:16:16 -0500
Subject: [PATCH 7/7] Work around libspatialite ABI change in 1.9.0

---
 rtree/core.py | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/rtree/core.py b/rtree/core.py
index 040c2170..888a8955 100644
--- a/rtree/core.py
+++ b/rtree/core.py
@@ -74,6 +74,10 @@ def free_error_msg_ptr(result, func, cargs):
 # load the shared library by looking in likely places
 rt = finder.load()
 
+rt.SIDX_Version.argtypes = []
+rt.SIDX_Version.restype = ctypes.POINTER(ctypes.c_char)
+rt.SIDX_Version.errcheck = free_returned_char_p  # type: ignore
+
 rt.Error_GetLastErrorNum.argtypes = []
 rt.Error_GetLastErrorNum.restype = ctypes.c_int
 
@@ -95,13 +99,26 @@ def free_error_msg_ptr(result, func, cargs):
 rt.Index_Create.restype = ctypes.c_void_p
 rt.Index_Create.errcheck = check_void
 
-NEXTFUNC = ctypes.CFUNCTYPE(ctypes.c_int,
-                            ctypes.POINTER(ctypes.c_int64),
-                            ctypes.POINTER(ctypes.POINTER(ctypes.c_double)),
-                            ctypes.POINTER(ctypes.POINTER(ctypes.c_double)),
-                            ctypes.POINTER(ctypes.c_uint32),
-                            ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)),
-                            ctypes.POINTER(ctypes.c_size_t))
+_nDataLength_size_t = True
+try:
+    _major, _minor, _patch = (
+        int(part) for part in rt.SIDX_Version().decode("ascii").split(".")
+    )
+except (ValueError, UnicodeDecodeError):
+    pass  # weird version; assume latest ABI
+else:
+    if (_major, _minor, _patch) < (1, 9, 0):
+        # Headers had size_t*, but implementation had uint32_t*
+        _nDataLength_size_t = False
+NEXTFUNC = ctypes.CFUNCTYPE(
+    ctypes.c_int,
+    ctypes.POINTER(ctypes.c_int64),
+    ctypes.POINTER(ctypes.POINTER(ctypes.c_double)),
+    ctypes.POINTER(ctypes.POINTER(ctypes.c_double)),
+    ctypes.POINTER(ctypes.c_uint32),
+    ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)),
+    ctypes.POINTER(ctypes.c_size_t if _nDataLength_size_t else ctypes.c_uint32),
+)
 
 rt.Index_CreateWithStream.argtypes = [ctypes.c_void_p, NEXTFUNC]
 rt.Index_CreateWithStream.restype = ctypes.c_void_p
@@ -525,10 +542,6 @@ def free_error_msg_ptr(result, func, cargs):
 rt.SIDX_DeleteBuffer.argtypes = [ctypes.c_void_p]
 rt.SIDX_DeleteBuffer.restype = None
 
-rt.SIDX_Version.argtypes = []
-rt.SIDX_Version.restype = ctypes.POINTER(ctypes.c_char)
-rt.SIDX_Version.errcheck = free_returned_char_p
-
 # TPR-Tree API
 try:
     rt.Index_InsertTPData.argtypes = [ctypes.c_void_p,