You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

generation.py 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. """
  2. This module contains functions that generate ctypes prototypes for the
  3. GDAL routines.
  4. """
  5. from ctypes import POINTER, c_char_p, c_double, c_int, c_int64, c_void_p
  6. from functools import partial
  7. from django.contrib.gis.gdal.prototypes.errcheck import (
  8. check_arg_errcode, check_const_string, check_errcode, check_geom,
  9. check_geom_offset, check_pointer, check_srs, check_str_arg, check_string,
  10. )
  11. class gdal_char_p(c_char_p):
  12. pass
  13. def double_output(func, argtypes, errcheck=False, strarg=False, cpl=False):
  14. "Generate a ctypes function that returns a double value."
  15. func.argtypes = argtypes
  16. func.restype = c_double
  17. if errcheck:
  18. func.errcheck = partial(check_arg_errcode, cpl=cpl)
  19. if strarg:
  20. func.errcheck = check_str_arg
  21. return func
  22. def geom_output(func, argtypes, offset=None):
  23. """
  24. Generate a function that returns a Geometry either by reference
  25. or directly (if the return_geom keyword is set to True).
  26. """
  27. # Setting the argument types
  28. func.argtypes = argtypes
  29. if not offset:
  30. # When a geometry pointer is directly returned.
  31. func.restype = c_void_p
  32. func.errcheck = check_geom
  33. else:
  34. # Error code returned, geometry is returned by-reference.
  35. func.restype = c_int
  36. def geomerrcheck(result, func, cargs):
  37. return check_geom_offset(result, func, cargs, offset)
  38. func.errcheck = geomerrcheck
  39. return func
  40. def int_output(func, argtypes, errcheck=None):
  41. "Generate a ctypes function that returns an integer value."
  42. func.argtypes = argtypes
  43. func.restype = c_int
  44. if errcheck:
  45. func.errcheck = errcheck
  46. return func
  47. def int64_output(func, argtypes):
  48. "Generate a ctypes function that returns a 64-bit integer value."
  49. func.argtypes = argtypes
  50. func.restype = c_int64
  51. return func
  52. def srs_output(func, argtypes):
  53. """
  54. Generate a ctypes prototype for the given function with
  55. the given C arguments that returns a pointer to an OGR
  56. Spatial Reference System.
  57. """
  58. func.argtypes = argtypes
  59. func.restype = c_void_p
  60. func.errcheck = check_srs
  61. return func
  62. def const_string_output(func, argtypes, offset=None, decoding=None, cpl=False):
  63. func.argtypes = argtypes
  64. if offset:
  65. func.restype = c_int
  66. else:
  67. func.restype = c_char_p
  68. def _check_const(result, func, cargs):
  69. res = check_const_string(result, func, cargs, offset=offset, cpl=cpl)
  70. if res and decoding:
  71. res = res.decode(decoding)
  72. return res
  73. func.errcheck = _check_const
  74. return func
  75. def string_output(func, argtypes, offset=-1, str_result=False, decoding=None):
  76. """
  77. Generate a ctypes prototype for the given function with the
  78. given argument types that returns a string from a GDAL pointer.
  79. The `const` flag indicates whether the allocated pointer should
  80. be freed via the GDAL library routine VSIFree -- but only applies
  81. only when `str_result` is True.
  82. """
  83. func.argtypes = argtypes
  84. if str_result:
  85. # Use subclass of c_char_p so the error checking routine
  86. # can free the memory at the pointer's address.
  87. func.restype = gdal_char_p
  88. else:
  89. # Error code is returned
  90. func.restype = c_int
  91. # Dynamically defining our error-checking function with the
  92. # given offset.
  93. def _check_str(result, func, cargs):
  94. res = check_string(result, func, cargs, offset=offset, str_result=str_result)
  95. if res and decoding:
  96. res = res.decode(decoding)
  97. return res
  98. func.errcheck = _check_str
  99. return func
  100. def void_output(func, argtypes, errcheck=True, cpl=False):
  101. """
  102. For functions that don't only return an error code that needs to
  103. be examined.
  104. """
  105. if argtypes:
  106. func.argtypes = argtypes
  107. if errcheck:
  108. # `errcheck` keyword may be set to False for routines that
  109. # return void, rather than a status code.
  110. func.restype = c_int
  111. func.errcheck = partial(check_errcode, cpl=cpl)
  112. else:
  113. func.restype = None
  114. return func
  115. def voidptr_output(func, argtypes, errcheck=True):
  116. "For functions that return c_void_p."
  117. func.argtypes = argtypes
  118. func.restype = c_void_p
  119. if errcheck:
  120. func.errcheck = check_pointer
  121. return func
  122. def chararray_output(func, argtypes, errcheck=True):
  123. """For functions that return a c_char_p array."""
  124. func.argtypes = argtypes
  125. func.restype = POINTER(c_char_p)
  126. if errcheck:
  127. func.errcheck = check_pointer
  128. return func