Now the response type is set on routines that produce string or binary output. default tip
authorJustin Bronn <jbronn@geodjango.org>
Wed Nov 19 13:00:39 2008 -0600 (3 years ago)
changeset 877f86525906d
parent 7 ea0eccb43bdc
Now the response type is set on routines that produce string or binary output.
LICENSE
prototypes/errcheck.py
prototypes/geom.py
prototypes/io.py
     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