|
1 """ |
|
2 Error checking functions for GEOS ctypes prototype functions. |
|
3 """ |
|
4 import os |
|
5 from ctypes import string_at, CDLL |
|
6 from ctypes.util import find_library |
|
7 from django.contrib.gis.geos.error import GEOSException |
|
8 |
|
9 # Getting the C library, needed to free the string pointers |
|
10 # returned from GEOS. |
|
11 if os.name == 'nt': |
|
12 libc_name = 'msvcrt' |
|
13 else: |
|
14 libc_name = 'libc' |
|
15 libc = CDLL(find_library(libc_name)) |
|
16 |
|
17 ### ctypes error checking routines ### |
|
18 def last_arg_byref(args): |
|
19 "Returns the last C argument's by reference value." |
|
20 return args[-1]._obj.value |
|
21 |
|
22 def check_dbl(result, func, cargs): |
|
23 "Checks the status code and returns the double value passed in by reference." |
|
24 # Checking the status code |
|
25 if result != 1: return None |
|
26 # Double passed in by reference, return its value. |
|
27 return last_arg_byref(cargs) |
|
28 |
|
29 def check_geom(result, func, cargs): |
|
30 "Error checking on routines that return Geometries." |
|
31 if not result: |
|
32 raise GEOSException('Error encountered checking Geometry returned from GEOS C function "%s".' % func.__name__) |
|
33 return result |
|
34 |
|
35 def check_minus_one(result, func, cargs): |
|
36 "Error checking on routines that should not return -1." |
|
37 if result == -1: |
|
38 raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__) |
|
39 else: |
|
40 return result |
|
41 |
|
42 def check_predicate(result, func, cargs): |
|
43 "Error checking for unary/binary predicate functions." |
|
44 val = ord(result) # getting the ordinal from the character |
|
45 if val == 1: return True |
|
46 elif val == 0: return False |
|
47 else: |
|
48 raise GEOSException('Error encountered on GEOS C predicate function "%s".' % func.__name__) |
|
49 |
|
50 def check_sized_string(result, func, cargs): |
|
51 "Error checking for routines that return explicitly sized strings." |
|
52 if not result: |
|
53 raise GEOSException('Invalid string pointer returned by GEOS C function "%s"' % func.__name__) |
|
54 # A c_size_t object is passed in by reference for the second |
|
55 # argument on these routines, and its needed to determine the |
|
56 # correct size. |
|
57 s = string_at(result, last_arg_byref(cargs)) |
|
58 libc.free(result) |
|
59 return s |
|
60 |
|
61 def check_string(result, func, cargs): |
|
62 "Error checking for routines that return strings." |
|
63 if not result: raise GEOSException('Error encountered checking string return value in GEOS C function "%s".' % func.__name__) |
|
64 # Getting the string value at the pointer address. |
|
65 s = string_at(result) |
|
66 # Freeing the memory allocated by the GEOS library. |
|
67 libc.free(result) |
|
68 return s |
|
69 |
|
70 def check_zero(result, func, cargs): |
|
71 "Error checking on routines that should not return 0." |
|
72 if result == 0: |
|
73 raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__) |
|
74 else: |
|
75 return result |
|
76 |