Now the response type is set on routines that produce string or binary output.
1.1 --- a/LICENSE Tue Nov 11 11:53:02 2008 -0600
1.2 +++ b/LICENSE Wed Nov 19 13:00:39 2008 -0600
1.3 @@ -1,4 +1,4 @@
1.4 -Copyright (c) 2007, Justin Bronn
1.5 +Copyright (c) 2007, 2008, Justin Bronn
1.6 All rights reserved.
1.7
1.8 Redistribution and use in source and binary forms, with or without modification,
2.1 --- a/prototypes/errcheck.py Tue Nov 11 11:53:02 2008 -0600
2.2 +++ b/prototypes/errcheck.py Wed Nov 19 13:00:39 2008 -0600
2.3 @@ -48,22 +48,31 @@
2.4 raise GEOSException('Error encountered on GEOS C predicate function "%s".' % func.__name__)
2.5
2.6 def check_sized_string(result, func, cargs):
2.7 - "Error checking for routines that return explicitly sized strings."
2.8 + """
2.9 + Error checking for routines that return explicitly sized strings.
2.10 +
2.11 + This frees the memory allocated by GEOS at the result pointer.
2.12 + """
2.13 if not result:
2.14 raise GEOSException('Invalid string pointer returned by GEOS C function "%s"' % func.__name__)
2.15 # A c_size_t object is passed in by reference for the second
2.16 # argument on these routines, and its needed to determine the
2.17 # correct size.
2.18 s = string_at(result, last_arg_byref(cargs))
2.19 + # Freeing the memory allocated within GEOS
2.20 libc.free(result)
2.21 return s
2.22
2.23 def check_string(result, func, cargs):
2.24 - "Error checking for routines that return strings."
2.25 + """
2.26 + Error checking for routines that return strings.
2.27 +
2.28 + This frees the memory allocated by GEOS at the result pointer.
2.29 + """
2.30 if not result: raise GEOSException('Error encountered checking string return value in GEOS C function "%s".' % func.__name__)
2.31 # Getting the string value at the pointer address.
2.32 s = string_at(result)
2.33 - # Freeing the memory allocated by the GEOS library.
2.34 + # Freeing the memory allocated within GEOS
2.35 libc.free(result)
2.36 return s
2.37
2.38 @@ -73,4 +82,3 @@
2.39 raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__)
2.40 else:
2.41 return result
2.42 -
3.1 --- a/prototypes/geom.py Tue Nov 11 11:53:02 2008 -0600
3.2 +++ b/prototypes/geom.py Wed Nov 19 13:00:39 2008 -0600
3.3 @@ -1,8 +1,21 @@
3.4 -from ctypes import c_char_p, c_int, c_size_t, c_uint, POINTER
3.5 +from ctypes import c_char_p, c_int, c_size_t, c_ubyte, c_uint, POINTER
3.6 from django.contrib.gis.geos.libgeos import lgeos, CS_PTR, GEOM_PTR
3.7 from django.contrib.gis.geos.prototypes.errcheck import \
3.8 check_geom, check_minus_one, check_sized_string, check_string, check_zero
3.9
3.10 +# This is the return type used by binary output (WKB, HEX) routines.
3.11 +c_uchar_p = POINTER(c_ubyte)
3.12 +
3.13 +# We create a simple subclass of c_char_p here because when the response
3.14 +# type is set to c_char_p, you get a _Python_ string and there's no way
3.15 +# to access the string's address inside the error checking function.
3.16 +# In other words, you can't free the memory allocated inside GEOS. Previously,
3.17 +# the return type would just be omitted and the integer address would be
3.18 +# used -- but this allows us to be specific in the function definition and
3.19 +# keeps the reference so it may be free'd.
3.20 +class geos_char_p(c_char_p):
3.21 + pass
3.22 +
3.23 ### ctypes generation functions ###
3.24 def bin_constructor(func):
3.25 "Generates a prototype for binary construction (HEX, WKB) GEOS routines."
3.26 @@ -16,6 +29,7 @@
3.27 "Generates a prototype for the routines that return a a sized string."
3.28 func.argtypes = [GEOM_PTR, POINTER(c_size_t)]
3.29 func.errcheck = check_sized_string
3.30 + func.restype = c_uchar_p
3.31 return func
3.32
3.33 def geom_output(func, argtypes):
3.34 @@ -41,21 +55,14 @@
3.35
3.36 def string_from_geom(func):
3.37 "Argument is a Geometry, return type is a string."
3.38 - # We do _not_ specify an argument type because we want just an
3.39 - # address returned from the function.
3.40 func.argtypes = [GEOM_PTR]
3.41 + func.restype = geos_char_p
3.42 func.errcheck = check_string
3.43 return func
3.44
3.45 ### ctypes prototypes ###
3.46
3.47 -# TODO: Tell all users to use GEOS 3.0.0, instead of the release
3.48 -# candidates, and use the new Reader and Writer APIs (e.g.,
3.49 -# GEOSWKT[Reader|Writer], GEOSWKB[Reader|Writer]). A good time
3.50 -# to do this will be when Refractions releases a Windows PostGIS
3.51 -# installer using GEOS 3.0.0.
3.52 -
3.53 -# Creation routines from WKB, HEX, WKT
3.54 +# Deprecated creation routines from WKB, HEX, WKT
3.55 from_hex = bin_constructor(lgeos.GEOSGeomFromHEX_buf)
3.56 from_wkb = bin_constructor(lgeos.GEOSGeomFromWKB_buf)
3.57 from_wkt = geom_output(lgeos.GEOSGeomFromWKT, [c_char_p])
4.1 --- a/prototypes/io.py Tue Nov 11 11:53:02 2008 -0600
4.2 +++ b/prototypes/io.py Wed Nov 19 13:00:39 2008 -0600
4.3 @@ -1,6 +1,7 @@
4.4 from ctypes import c_char_p, c_int, c_char, c_size_t, Structure, POINTER
4.5 from django.contrib.gis.geos.libgeos import lgeos, GEOM_PTR
4.6 from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string, check_sized_string
4.7 +from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p
4.8
4.9 ### The WKB/WKT Reader/Writer structures and pointers ###
4.10 class WKTReader_st(Structure): pass
4.11 @@ -34,6 +35,7 @@
4.12
4.13 wkt_writer_write = lgeos.GEOSWKTWriter_write
4.14 wkt_writer_write.argtypes = [WKT_WRITE_PTR, GEOM_PTR]
4.15 +wkt_writer_write.restype = geos_char_p
4.16 wkt_writer_write.errcheck = check_string
4.17
4.18 ### WKBReader routines ###
4.19 @@ -44,6 +46,11 @@
4.20 wkb_reader_destroy.argtypes = [WKB_READ_PTR]
4.21
4.22 def wkb_read_func(func):
4.23 + # Although the function definitions take `const unsigned char *`
4.24 + # as their parameter, we use c_char_p here so the function may
4.25 + # take Python strings directly as parameters. Inside Python there
4.26 + # is not a difference between signed and unsigned characters, so
4.27 + # it is not a problem.
4.28 func.argtypes = [WKB_READ_PTR, c_char_p, c_size_t]
4.29 func.restype = GEOM_PTR
4.30 func.errcheck = check_geom
4.31 @@ -62,6 +69,7 @@
4.32 # WKB Writing prototypes.
4.33 def wkb_write_func(func):
4.34 func.argtypes = [WKB_WRITE_PTR, GEOM_PTR, POINTER(c_size_t)]
4.35 + func.restype = c_uchar_p
4.36 func.errcheck = check_sized_string
4.37 return func
4.38