/django/contrib/gis/geos/prototypes/errcheck.py

https://code.google.com/p/mango-py/ · Python · 95 lines · 57 code · 9 blank · 29 comment · 15 complexity · c409a1ac9a93856901dcf96b73aff7ef MD5 · raw file

  1. """
  2. Error checking functions for GEOS ctypes prototype functions.
  3. """
  4. import os
  5. from ctypes import c_void_p, string_at, CDLL
  6. from django.contrib.gis.geos.error import GEOSException
  7. from django.contrib.gis.geos.libgeos import GEOS_VERSION
  8. from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
  9. # Getting the `free` routine used to free the memory allocated for
  10. # string pointers returned by GEOS.
  11. if GEOS_VERSION >= (3, 1, 1):
  12. # In versions 3.1.1 and above, `GEOSFree` was added to the C API
  13. # because `free` isn't always available on all platforms.
  14. free = GEOSFunc('GEOSFree')
  15. free.argtypes = [c_void_p]
  16. free.restype = None
  17. else:
  18. # Getting the `free` routine from the C library of the platform.
  19. if os.name == 'nt':
  20. # On NT, use the MS C library.
  21. libc = CDLL('msvcrt')
  22. else:
  23. # On POSIX platforms C library is obtained by passing None into `CDLL`.
  24. libc = CDLL(None)
  25. free = libc.free
  26. ### ctypes error checking routines ###
  27. def last_arg_byref(args):
  28. "Returns the last C argument's value by reference."
  29. return args[-1]._obj.value
  30. def check_dbl(result, func, cargs):
  31. "Checks the status code and returns the double value passed in by reference."
  32. # Checking the status code
  33. if result != 1: return None
  34. # Double passed in by reference, return its value.
  35. return last_arg_byref(cargs)
  36. def check_geom(result, func, cargs):
  37. "Error checking on routines that return Geometries."
  38. if not result:
  39. raise GEOSException('Error encountered checking Geometry returned from GEOS C function "%s".' % func.__name__)
  40. return result
  41. def check_minus_one(result, func, cargs):
  42. "Error checking on routines that should not return -1."
  43. if result == -1:
  44. raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__)
  45. else:
  46. return result
  47. def check_predicate(result, func, cargs):
  48. "Error checking for unary/binary predicate functions."
  49. val = ord(result) # getting the ordinal from the character
  50. if val == 1: return True
  51. elif val == 0: return False
  52. else:
  53. raise GEOSException('Error encountered on GEOS C predicate function "%s".' % func.__name__)
  54. def check_sized_string(result, func, cargs):
  55. """
  56. Error checking for routines that return explicitly sized strings.
  57. This frees the memory allocated by GEOS at the result pointer.
  58. """
  59. if not result:
  60. raise GEOSException('Invalid string pointer returned by GEOS C function "%s"' % func.__name__)
  61. # A c_size_t object is passed in by reference for the second
  62. # argument on these routines, and its needed to determine the
  63. # correct size.
  64. s = string_at(result, last_arg_byref(cargs))
  65. # Freeing the memory allocated within GEOS
  66. free(result)
  67. return s
  68. def check_string(result, func, cargs):
  69. """
  70. Error checking for routines that return strings.
  71. This frees the memory allocated by GEOS at the result pointer.
  72. """
  73. if not result: raise GEOSException('Error encountered checking string return value in GEOS C function "%s".' % func.__name__)
  74. # Getting the string value at the pointer address.
  75. s = string_at(result)
  76. # Freeing the memory allocated within GEOS
  77. free(result)
  78. return s
  79. def check_zero(result, func, cargs):
  80. "Error checking on routines that should not return 0."
  81. if result == 0:
  82. raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__)
  83. else:
  84. return result