[Thuban-commits] r2742 - in branches/WIP-pyshapelib-bramz: . libraries/pyshapelib

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Wed Mar 14 17:26:16 CET 2007


Author: bramz
Date: 2007-03-14 17:26:14 +0100 (Wed, 14 Mar 2007)
New Revision: 2742

Added:
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
Removed:
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.i
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.py
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib_wrap.c
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c
Modified:
   branches/WIP-pyshapelib-bramz/ChangeLog
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
   branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py
   branches/WIP-pyshapelib-bramz/setup.py
Log:
pyshapelib: rewritten dbflib to use hand-crafted Python bindings instead of SWIG generated ones.


Modified: branches/WIP-pyshapelib-bramz/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-bramz/ChangeLog	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/ChangeLog	2007-03-14 16:26:14 UTC (rev 2742)
@@ -1,3 +1,8 @@
+2007-03-14 Bram de Greve <bram.degreve at intec.ugent.be>
+
+	* setup.py : updated in order to use the new dbflib C module in place
+	of the old SWIG one
+
 2007-03-12 Didrik Pinte <dpinte at itae.be>
 
 	* setup.py : updated in order to use the new pyshapelib C module in place

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog	2007-03-14 16:26:14 UTC (rev 2742)
@@ -1,5 +1,18 @@
-2007-03-12  Bram de Greve <bram.degreve at gmail.com>
+2007-03-14  Bram de Greve <bram.degreve at intec.ugent.be>
 
+	* dbflibmodule.c, dbflib.i: replaced dbflib.i by dbflibmodule.c to use
+	hand-crafted Python bindings instead of SWIG generated ones
+	
+	* shapelibmodule.c, shapelib.c: Renamed shapelib.c to shapelibmodule.c
+	to match style of dbflibmodule.c and shptreemodule.c.  Changed some
+	(well, most) names to match same style.
+	
+	* pyshapelib_common.h: do all necessary includes here
+	
+	* setup.py: updated building of dbflib.
+	
+2007-03-13  Bram de Greve <bram.degreve at intec.ugent.be>
+
 	* shapelib.c, shapelib_common.h: Added part_types() to SHPObject to
 	return tuple of part types. Added __repr__ operators to return a 
 	string that can reconstruct the object using eval()
@@ -7,7 +20,7 @@
 	* pytest.py: Added tests for part_types() and __repr__.  
 	Humanized the output a bit.
 
-2007-03-12  Bram de Greve <bram.degreve at gmail.com>
+2007-03-12  Bram de Greve <bram.degreve at intec.ugent.be>
 
 	* shapelib.c, shapelib.i: replaced shapelib.i by shapelib.c to use 
 	hand-crafted Python bindings instead of SWIG generated ones.

Deleted: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.i
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.i	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.i	2007-03-14 16:26:14 UTC (rev 2742)
@@ -1,597 +0,0 @@
-/* SWIG (www.swig.org) interface file for the dbf interface of shapelib
- *
- * At the moment (Dec 2000) this file is only useful to generate Python
- * bindings. Invoke swig as follows:
- *
- *	swig -python -shadow dbflib.i
- *
- * to generate dbflib_wrap.c and dbflib.py. dbflib_wrap.c defines a
- * bunch of Python-functions that wrap the appripriate dbflib functions
- * and dbflib.py contains an object oriented wrapper around
- * dbflib_wrap.c.
- *
- * This module defines one object type: DBFFile.
- */
-
-/* this is the dbflib module */
-%module dbflib
-
-/* first a %{,%} block. These blocks are copied verbatim to the
- * dbflib_wrap.c file and are not parsed by SWIG. This is the place to
- * import headerfiles and define helper-functions that are needed by the
- * automatically generated wrappers.
- */
-
-%{
-#include "shapefil.h"
-
-
-/* Read one attribute from the dbf handle and return it as a new python object
- *
- * If an error occurs, set the appropriate Python exception and return
- * NULL.
- *
- * Assume that the values of the record and field arguments are valid.
- * The name argument will be passed to DBFGetFieldInfo as is and should
- * thus be either NULL or a pointer to an array of at least 12 chars
- */
-static PyObject *
-do_read_attribute(DBFInfo * handle, int record, int field, char * name)
-{
-    int type, width;
-    PyObject *value;
-
-    type = DBFGetFieldInfo(handle, field, name, &width, NULL);
-    /* For strings NULL and the empty string are indistinguishable
-     * in DBF files. We prefer empty strings instead for backwards
-     * compatibility reasons because older wrapper versions returned
-     * emtpy strings as empty strings.
-     */
-    if (type != FTString && DBFIsAttributeNULL(handle, record, field))
-    {
-	value = Py_None;
-	Py_INCREF(value);
-    }
-    else
-    {
-	switch (type)
-	{
-	case FTString:
-	{
-	    const char * temp = DBFReadStringAttribute(handle, record, field);
-	    if (temp)
-	    {
-		value = PyString_FromString(temp);
-	    }
-	    else
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "Can't read value for row %d column %d",
-			     record, field);
-		value = NULL;
-	    }
-	    break;
-	}
-	case FTInteger:
-	    value = PyInt_FromLong(DBFReadIntegerAttribute(handle, record,
-							   field));
-	    break;
-	case FTDouble:
-	    value = PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record,
-							      field));
-	    break;
-	default:
-	    PyErr_Format(PyExc_TypeError, "Invalid field data type %d",
-			 type);
-	    value = NULL;
-	}
-    }
-    if (!value)
-	return NULL;
-
-    return value;
-}    
-
-/* the read_attribute method. Return the value of the given record and
- * field as a python object of the appropriate type.
- * 
- * In case of error, set a python exception and return NULL. Since that
- * value will be returned to the python interpreter as is, the
- * interpreter should recognize the exception.
- */
-
-static PyObject *
-DBFInfo_read_attribute(DBFInfo * handle, int record, int field)
-{
-    if (record < 0 || record >= DBFGetRecordCount(handle))
-    {
-	PyErr_Format(PyExc_ValueError,
-		     "record index %d out of bounds (record count: %d)",
-		     record, DBFGetRecordCount(handle));
-	return NULL;
-    }
-
-    if (field < 0 || field >= DBFGetFieldCount(handle))
-    {
-	PyErr_Format(PyExc_ValueError,
-		     "field index %d out of bounds (field count: %d)",
-		     field, DBFGetFieldCount(handle));
-	return NULL;
-    }
-
-    return do_read_attribute(handle, record, field, NULL);
-}
-    
-
-/* the read_record method. Return the record record as a dictionary with
- * whose keys are the names of the fields, and their values as the
- * appropriate Python type.
- * 
- * In case of error, set a python exception and return NULL. Since that
- * value will be returned to the python interpreter as is, the
- * interpreter should recognize the exception.
- */
-
-static PyObject *
-DBFInfo_read_record(DBFInfo * handle, int record)
-{
-    int num_fields;
-    int i;
-    int type, width;
-    char name[12];
-    PyObject *dict;
-    PyObject *value;
-
-    if (record < 0 || record >= DBFGetRecordCount(handle))
-    {
-	PyErr_Format(PyExc_ValueError,
-		     "record index %d out of bounds (record count: %d)",
-		     record, DBFGetRecordCount(handle));
-	return NULL;
-    }
-
-    dict = PyDict_New();
-    if (!dict)
-	return NULL;
-	
-    num_fields = DBFGetFieldCount(handle);
-    for (i = 0; i < num_fields; i++)
-    {
-	value = do_read_attribute(handle, record, i, name);
-	if (!value)
-	    goto fail;
-
-	PyDict_SetItemString(dict, name, value);
-	Py_DECREF(value);
-    }
-
-    return dict;
-
- fail:
-    Py_XDECREF(dict);
-    return NULL;
-}
-
-/* the write_record method. Write the record record given wither as a
- * dictionary or a sequence (i.e. a list or a tuple).
- *
- * If it's a dictionary the keys must be the names of the fields and
- * their value must have a suitable type. Only the fields actually
- * contained in the dictionary are written. Fields for which there's no
- * item in the dict are not modified.
- *
- * If it's a sequence, all fields must be present in the right order.
- *
- * In case of error, set a python exception and return NULL. Since that
- * value will be returned to the python interpreter as is, the
- * interpreter should recognize the exception.
- *
- * The method is implemented with two c-functions, write_field to write
- * a single field and DBFInfo_write_record as the front-end.
- */
-
-
-/* write a single field of a record. */
-static int
-write_field(DBFHandle handle, int record, int field, int type,
-	    PyObject * value)
-{
-    char * string_value;
-    int int_value;
-    double double_value;
-
-    if (value == Py_None)
-    {
-	if (!DBFWriteNULLAttribute(handle, record, field))
-	{
-	    PyErr_Format(PyExc_IOError,
-			 "can't write NULL field %d of record %d",
-			 field, record);
-	    return 0;
-	}
-    }
-    else
-    {
-	switch (type)
-	{
-	case FTString:
-	    string_value = PyString_AsString(value);
-	    if (!string_value)
-		return 0;
-	    if (!DBFWriteStringAttribute(handle, record, field, string_value))
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "can't write field %d of record %d",
-			     field, record);
-		return 0;
-	    }
-	    break;
-
-	case FTInteger:
-	    int_value = PyInt_AsLong(value);
-	    if (int_value == -1 && PyErr_Occurred())
-		return 0;
-	    if (!DBFWriteIntegerAttribute(handle, record, field, int_value))
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "can't write field %d of record %d",
-			     field, record);
-		return 0;
-	    }
-	    break;
-
-	case FTDouble:
-	    double_value = PyFloat_AsDouble(value);
-	    if (double_value == -1 && PyErr_Occurred())
-		return 0;
-	    if (!DBFWriteDoubleAttribute(handle, record, field, double_value))
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "can't write field %d of record %d",
-			     field, record);
-		return 0;
-	    }
-	    break;
-
-	default:
-	    PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
-	    return 0;
-	}
-    }
-
-    return 1;
-}
-
-static
-PyObject *
-DBFInfo_write_record(DBFHandle handle, int record, PyObject *record_object)
-{
-    int num_fields;
-    int i, length;
-    int type, width;
-    char name[12];
-    PyObject * value = NULL;
-
-    num_fields = DBFGetFieldCount(handle);
-
-    /* We used to use PyMapping_Check to test whether record_object is a
-     * dictionary like object instead of PySequence_Check to test
-     * whether it's a sequence. Unfortunately in Python 2.3
-     * PyMapping_Check returns true for lists and tuples too so the old
-     * approach doesn't work anymore.
-     */
-    if (PySequence_Check(record_object))
-    {
-	/* It's a sequence object. Iterate through all items in the
-	 * sequence and write them to the appropriate field.
-	 */
-	length = PySequence_Length(record_object);
-	if (length != num_fields)
-	{
-	    PyErr_SetString(PyExc_TypeError,
-			    "record must have one item for each field");
-	    goto fail;
-	}
-	for (i = 0; i < length; i++)
-	{
-	    type = DBFGetFieldInfo(handle, i, name, &width, NULL); 
-	    value = PySequence_GetItem(record_object, i);
-	    if (value)
-	    {
-		if (!write_field(handle, record, i, type, value))
-		    goto fail;
-		Py_DECREF(value);
-	    }
-	    else
-	    {
-		goto fail;
-	    }
-	}
-    }
-    else
-    {
-	/* It's a dictionary-like object. Iterate over the names of the
-         * known fields and write the corresponding item
-	 */
-	for (i = 0; i < num_fields; i++)
-	{
-	    type = DBFGetFieldInfo(handle, i, name, &width, NULL);
-
-	    /* if the dictionary has the key name write that object to
-	     * the appropriate field, other wise just clear the python
-	     * exception and do nothing.
-	     */
-	    value = PyMapping_GetItemString(record_object, name);
-	    if (value)
-	    {
-		if (!write_field(handle, record, i, type, value))
-		    goto fail;
-		Py_DECREF(value);
-	    }
-	    else
-	    {
-		PyErr_Clear();
-	    }
-	}
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-
- fail:
-    Py_XDECREF(value);
-    return NULL;
-}
-%}
-
-
-/* The commit method implementation
- *
- * The method relies on the DBFUpdateHeader method which is not
- * available in shapelib <= 1.2.10.  setup.py defines
- * HAVE_UPDATE_HEADER's value depending on whether the function is
- * available in the shapelib version the code is compiled with.
- */
-%{
-static
-void
-DBFInfo_commit(DBFHandle handle)
-{
-#if HAVE_UPDATE_HEADER
-    DBFUpdateHeader(handle);
-#endif
-}
-%} 
-
-
-/*
- * The SWIG Interface definition.
- */
-
-/* include some common SWIG type definitions and standard exception
-   handling code */
-%include typemaps.i
-%include exception.i
-
-/* As for ShapeFile in shapelib.i, We define a new C-struct that holds
- * the DBFHandle. This is mainly done so we can separate the close()
- * method from the destructor but it also helps with exception handling.
- *
- * After the DBFFile has been opened or created the handle is not NULL.
- * The close() method closes the file and sets handle to NULL as an
- * indicator that the file has been closed.
- */
-
-%{
-    typedef struct {
-	DBFHandle handle;
-    } DBFFile;
-%}
-
-
-/* The first argument to the DBFFile methods is a DBFFile pointer.
- * We have to check whether handle is not NULL in most methods but not
- * all. In the destructor and the close method, it's OK for handle to be
- * NULL. We achieve this by checking whether the preprocessor macro
- * NOCHECK_$name is defined. SWIG replaces $name with the name of the
- * function for which the code is inserted. In the %{,%}-block below we
- * define the macros for the destructor and the close() method.
- */
-
-%typemap(python,check) DBFFile *{
-%#ifndef NOCHECK_$name
-    if (!$target || !$target->handle)
-	SWIG_exception(SWIG_TypeError, "dbffile already closed");
-%#endif
-}
-
-%{
-#define NOCHECK_delete_DBFFile
-#define NOCHECK_DBFFile_close
-%}
-
-
-/* An exception handle for the constructor and the module level open()
- * and create() functions.
- *
- * Annoyingly, we *have* to put braces around the SWIG_exception()
- * calls, at least in the python case, because of the way the macro is
- * written. Of course, always putting braces around the branches of an
- * if-statement is often considered good practice.
- */
-%typemap(python,except) DBFFile * {
-    $function;
-    if (!$source)
-    {
-    	SWIG_exception(SWIG_MemoryError, "no memory");
-    }
-    else if (!$source->handle)
-    {
-	SWIG_exception(SWIG_IOError, "$name failed");
-    }
-}
-
-/* Exception handler for the add_field method */
-%typemap(python,except) int DBFFile_add_field {
-    $function;
-    if ($source < 0)
-    {
-    	SWIG_exception(SWIG_RuntimeError, "add_field failed");
-    }
-}
-
-/* define and use some typemaps for the field_info() method whose
- * C-implementation has three output parameters that are returned
- * through pointers passed into the function. SWIG already has
- * definitions for common types such as int* and we can use those for
- * the last two parameters:
- */
-
-%apply int * OUTPUT { int * output_width }
-%apply int * OUTPUT { int * output_decimals }
-
-/* the fieldname has to be defined manually: */
-%typemap(python,ignore) char *fieldname_out(char temp[12]) {
-    $target = temp;
-}
-
-%typemap(python,argout) char *fieldname_out() {
-    PyObject * string = PyString_FromString($source);
-    $target = t_output_helper($target,string);
-}
-
-
-
-/*
- * The SWIG-version of the DBFFile struct 
- */
-
-typedef	struct
-{
-    %addmethods {
-	DBFFile(const char *file, const char * mode = "rb") {
-	    DBFFile * self = malloc(sizeof(DBFFile));
-	    if (self)
-		self->handle = DBFOpen(file, mode);
-	    return self;
-	}
-	    
-	~DBFFile() {
-	    if (self->handle)
-		DBFClose(self->handle);
-	    free(self);
-	}
-
-	void close() {
-	    if (self->handle)
-		DBFClose(self->handle);
-	    self->handle = NULL;
-	}
-
-	int field_count() {
-	    return DBFGetFieldCount(self->handle);
-	}
-
-	int record_count() {
-	    return DBFGetRecordCount(self->handle);
-	}
-
-	int field_info(int iField, char * fieldname_out,
-		       int * output_width, int * output_decimals) {
-	    return DBFGetFieldInfo(self->handle, iField, fieldname_out,
-				   output_width, output_decimals);
-	}
-	    
-	PyObject * read_record(int record) {
-	    return DBFInfo_read_record(self->handle, record);
-	}
-
-	PyObject * read_attribute(int record, int field) {
-	    return DBFInfo_read_attribute(self->handle, record, field);
-	}
-
-	int add_field(const char * pszFieldName, DBFFieldType eType,
-		      int nWidth, int nDecimals) {
-	    return DBFAddField(self->handle, pszFieldName, eType, nWidth,
-			       nDecimals);
-	}
-
-	PyObject *write_record(int record, PyObject *dict_or_sequence) {
-	    return DBFInfo_write_record(self->handle, record,
-					dict_or_sequence);
-	}
-
-	void commit() {
-	    DBFInfo_commit(self->handle);
-	}
-	/* Delete the commit method from the class if it doesn't have a
-	 * real implementation.
-	 */
-	%pragma(python) addtomethod="__class__:if not dbflibc._have_commit: del commit"
-
-	/* The __del__ method generated by the old SWIG version we're
-	 * tries to access self.thisown which may not be set at all when
-	 * there was an exception during construction.  Therefore we
-	 * override it with our own version.
-	 * FIXME: It would be better to upgrade to a newer SWIG version
-	 * or to get rid of SWIG entirely.
-	 */
-	%pragma(python) addtoclass = "
-    def __del__(self,dbflibc=dbflibc):
-        if getattr(self, 'thisown', 0):
-            dbflibc.delete_DBFFile(self)
-    "
-
-
-    }
-} DBFFile;
-
-
-/*
- * Two module level functions, open() and create() that correspond to
- * DBFOpen and DBFCreate respectively. open() is equivalent to the
- * DBFFile constructor.
- */
-
-
-%{
-    DBFFile * open_DBFFile(const char * file, const char * mode)
-    {
-	DBFFile * self = malloc(sizeof(DBFFile));
-	if (self)
-	    self->handle = DBFOpen(file, mode);
-	return self;
-    }
-%}
-
-%name(open) %new DBFFile * open_DBFFile(const char * file,
-					const char * mode = "rb");
-
-%{
-    DBFFile * create_DBFFile(const char * file)
-    {
-	DBFFile * self = malloc(sizeof(DBFFile));
-	if (self)
-	    self->handle = DBFCreate(file);
-	return self;
-    }
-%}
-%name(create) %new DBFFile * create_DBFFile(const char * file);
-
-
-
-/* constant definitions copied from shapefil.h */
-typedef enum {
-  FTString,
-  FTInteger,
-  FTDouble,
-  FTInvalid
-} DBFFieldType;
-
-
-/* Put the value of the HAVE_UPDATE_HEADER preprocessor macro into the
- * wrapper so that the __class__ pragma above knows when to remove the
- * commit method
- */
-const int _have_commit = HAVE_UPDATE_HEADER;
-

Deleted: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.py
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.py	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.py	2007-03-14 16:26:14 UTC (rev 2742)
@@ -1,76 +0,0 @@
-# This file was created automatically by SWIG.
-import dbflibc
-class DBFFile:
-    def __init__(self,*args):
-        self.this = apply(dbflibc.new_DBFFile,args)
-        self.thisown = 1
-
-    def __del__(self,dbflibc=dbflibc):
-        if self.thisown == 1 :
-            dbflibc.delete_DBFFile(self)
-    def close(*args):
-        val = apply(dbflibc.DBFFile_close,args)
-        return val
-    def field_count(*args):
-        val = apply(dbflibc.DBFFile_field_count,args)
-        return val
-    def record_count(*args):
-        val = apply(dbflibc.DBFFile_record_count,args)
-        return val
-    def field_info(*args):
-        val = apply(dbflibc.DBFFile_field_info,args)
-        return val
-    def read_record(*args):
-        val = apply(dbflibc.DBFFile_read_record,args)
-        return val
-    def read_attribute(*args):
-        val = apply(dbflibc.DBFFile_read_attribute,args)
-        return val
-    def add_field(*args):
-        val = apply(dbflibc.DBFFile_add_field,args)
-        return val
-    def write_record(*args):
-        val = apply(dbflibc.DBFFile_write_record,args)
-        return val
-    def commit(*args):
-        val = apply(dbflibc.DBFFile_commit,args)
-        return val
-    def __repr__(self):
-        return "<C DBFFile instance at %s>" % (self.this,)
-    if not dbflibc._have_commit: del commit
-    
-    def __del__(self,dbflibc=dbflibc):
-        if getattr(self, 'thisown', 0):
-            dbflibc.delete_DBFFile(self)
-    
-class DBFFilePtr(DBFFile):
-    def __init__(self,this):
-        self.this = this
-        self.thisown = 0
-        self.__class__ = DBFFile
-
-
-
-
-
-#-------------- FUNCTION WRAPPERS ------------------
-
-def open(*args, **kwargs):
-    val = apply(dbflibc.open,args,kwargs)
-    if val: val = DBFFilePtr(val); val.thisown = 1
-    return val
-
-def create(*args, **kwargs):
-    val = apply(dbflibc.create,args,kwargs)
-    if val: val = DBFFilePtr(val); val.thisown = 1
-    return val
-
-
-
-#-------------- VARIABLE WRAPPERS ------------------
-
-FTString = dbflibc.FTString
-FTInteger = dbflibc.FTInteger
-FTDouble = dbflibc.FTDouble
-FTInvalid = dbflibc.FTInvalid
-_have_commit = dbflibc._have_commit

Deleted: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib_wrap.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib_wrap.c	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib_wrap.c	2007-03-14 16:26:14 UTC (rev 2742)
@@ -1,1431 +0,0 @@
-/* ----------------------------------------------------------------------------
- * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3u-20020503-1857 (Alpha 5)
- * And later MANUALLY edited at the end.
- * 
- * This file is not intended to be easily readable and contains a number of 
- * coding conventions designed to improve portability and efficiency. Do not make
- * changes to this file unless you know what you are doing--modify the SWIG 
- * interface file instead. 
- * ----------------------------------------------------------------------------- */
-
-#define SWIGPYTHON
-/***********************************************************************
- * common.swg
- *
- *     This file contains generic SWIG runtime support for pointer
- *     type checking as well as a few commonly used macros to control
- *     external linkage.
- *
- * Author : David Beazley (beazley at cs.uchicago.edu)
- *
- * Copyright (c) 1999-2000, The University of Chicago
- * 
- * This file may be freely redistributed without license or fee provided
- * this copyright message remains intact.
- ************************************************************************/
-
-#include <string.h>
-
-#if defined(_WIN32) || defined(__WIN32__)
-#       if defined(_MSC_VER)
-#               if defined(STATIC_LINKED)
-#                       define SWIGEXPORT(a) a
-#               else
-#                       define SWIGEXPORT(a) __declspec(dllexport) a
-#               endif
-#       else
-#               if defined(__BORLANDC__)
-#                       define SWIGEXPORT(a) a _export
-#               else
-#                       define SWIGEXPORT(a) a
-#       endif
-#endif
-#else
-#       define SWIGEXPORT(a) a
-#endif
-
-#ifdef SWIG_GLOBAL
-#define SWIGRUNTIME(a) SWIGEXPORT(a)
-#else
-#define SWIGRUNTIME(a) static a
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct swig_type_info {
-  char  *name;                 
-  void *(*converter)(void *);
-  char  *str;
-  struct swig_type_info  *next;
-  struct swig_type_info  *prev;
-} swig_type_info;
-
-#ifdef SWIG_NOINCLUDE
-SWIGEXPORT(swig_type_info *) SWIG_TypeRegister(swig_type_info *);
-SWIGEXPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *);
-SWIGEXPORT(void *) SWIG_TypeCast(swig_type_info *, void *);
-#else
-
-static swig_type_info *swig_type_list = 0;
-
-/* Register a type mapping with the type-checking */
-SWIGRUNTIME(swig_type_info *)
-SWIG_TypeRegister(swig_type_info *ti)
-{
-  swig_type_info *tc, *head, *ret, *next;
-  /* Check to see if this type has already been registered */
-  tc = swig_type_list;
-  while (tc) {
-    if (strcmp(tc->name, ti->name) == 0) {
-      /* Already exists in the table.  Just add additional types to the list */
-      head = tc;
-      next = tc->next;
-      goto l1;
-    }
-    tc = tc->prev;
-  }
-  head = ti;
-  next = 0;
-
-  /* Place in list */
-  ti->prev = swig_type_list;
-  swig_type_list = ti;
-
-  /* Build linked lists */
- l1:
-  ret = head;
-  tc = ti + 1;
-  /* Patch up the rest of the links */
-  while (tc->name) {
-    head->next = tc;
-    tc->prev = head;
-    head = tc;
-    tc++;
-  }
-  head->next = next;
-  return ret;
-}
-
-/* Check the typename */
-SWIGRUNTIME(swig_type_info *) 
-SWIG_TypeCheck(char *c, swig_type_info *ty)
-{
-  swig_type_info *s;
-  if (!ty) return 0;        /* Void pointer */
-  s = ty->next;             /* First element always just a name */
-  while (s) {
-    if (strcmp(s->name,c) == 0) {
-      if (s == ty->next) return s;
-      /* Move s to the top of the linked list */
-      s->prev->next = s->next;
-      if (s->next) {
-	s->next->prev = s->prev;
-      }
-      /* Insert s as second element in the list */
-      s->next = ty->next;
-      if (ty->next) ty->next->prev = s;
-      ty->next = s;
-      return s;
-    }
-    s = s->next;
-  }
-  return 0;
-}
-
-/* Cast a pointer (needed for C++ inheritance */
-SWIGRUNTIME(void *) 
-SWIG_TypeCast(swig_type_info *ty, void *ptr) 
-{
-  if ((!ty) || (!ty->converter)) return ptr;
-  return (*ty->converter)(ptr);
-}
-
-/* Search for a swig_type_info structure */
-SWIGRUNTIME(void *)
-SWIG_TypeQuery(const char *name) {
-  swig_type_info *ty = swig_type_list;
-  while (ty) {
-    if (ty->str && (strcmp(name,ty->str) == 0)) return ty;
-    if (ty->name && (strcmp(name,ty->name) == 0)) return ty;
-    ty = ty->prev;
-  }
-  return 0;
-}
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-/***********************************************************************
- * python.swg
- *
- *     This file contains the runtime support for Python modules
- *     and includes code for managing global variables and pointer
- *     type checking.
- *
- * Author : David Beazley (beazley at cs.uchicago.edu)
- ************************************************************************/
-
-#include <stdlib.h>
-#include "Python.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SWIG_PY_INT     1
-#define SWIG_PY_FLOAT   2
-#define SWIG_PY_STRING  3
-#define SWIG_PY_POINTER 4
-
-/* Constant information structure */
-typedef struct swig_const_info {
-    int type;
-    char *name;
-    long lvalue;
-    double dvalue;
-    void   *pvalue;
-    swig_type_info **ptype;
-} swig_const_info;
-
-#ifdef SWIG_NOINCLUDE
-
-SWIGEXPORT(PyObject *)        SWIG_newvarlink();
-SWIGEXPORT(void)              SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *));
-SWIGEXPORT(int)               SWIG_ConvertPtr(PyObject *, void **, swig_type_info *, int);
-SWIGEXPORT(void)              SWIG_MakePtr(char *c, void *, swig_type_info *);
-SWIGEXPORT(PyObject *)        SWIG_NewPointerObj(void *, swig_type_info *);
-SWIGEXPORT(void)              SWIG_InstallConstants(PyObject *d, swig_const_info constants[]);
-
-#else
-
-/* -----------------------------------------------------------------------------
- * global variable support code.
- * ----------------------------------------------------------------------------- */
-
-typedef struct swig_globalvar {   
-  char       *name;                  /* Name of global variable */
-  PyObject *(*get_attr)(void);       /* Return the current value */
-  int       (*set_attr)(PyObject *); /* Set the value */
-  struct swig_globalvar *next;
-} swig_globalvar;
-
-typedef struct swig_varlinkobject {
-  PyObject_HEAD
-  swig_globalvar *vars;
-} swig_varlinkobject;
-
-static PyObject *
-swig_varlink_repr(swig_varlinkobject *v) {
-  v = v;
-  return PyString_FromString("<Global variables>");
-}
-
-static int
-swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) {
-  swig_globalvar  *var;
-  flags = flags;
-  fprintf(fp,"Global variables { ");
-  for (var = v->vars; var; var=var->next) {
-    fprintf(fp,"%s", var->name);
-    if (var->next) fprintf(fp,", ");
-  }
-  fprintf(fp," }\n");
-  return 0;
-}
-
-static PyObject *
-swig_varlink_getattr(swig_varlinkobject *v, char *n) {
-  swig_globalvar *var = v->vars;
-  while (var) {
-    if (strcmp(var->name,n) == 0) {
-      return (*var->get_attr)();
-    }
-    var = var->next;
-  }
-  PyErr_SetString(PyExc_NameError,"Unknown C global variable");
-  return NULL;
-}
-
-static int
-swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
-  swig_globalvar *var = v->vars;
-  while (var) {
-    if (strcmp(var->name,n) == 0) {
-      return (*var->set_attr)(p);
-    }
-    var = var->next;
-  }
-  PyErr_SetString(PyExc_NameError,"Unknown C global variable");
-  return 1;
-}
-
-statichere PyTypeObject varlinktype = {
-  PyObject_HEAD_INIT(0)              
-  0,
-  "swigvarlink",                      /* Type name    */
-  sizeof(swig_varlinkobject),         /* Basic size   */
-  0,                                  /* Itemsize     */
-  0,                                  /* Deallocator  */ 
-  (printfunc) swig_varlink_print,     /* Print        */
-  (getattrfunc) swig_varlink_getattr, /* get attr     */
-  (setattrfunc) swig_varlink_setattr, /* Set attr     */
-  0,                                  /* tp_compare   */
-  (reprfunc) swig_varlink_repr,       /* tp_repr      */    
-  0,                                  /* tp_as_number */
-  0,                                  /* tp_as_mapping*/
-  0,                                  /* tp_hash      */
-};
-
-/* Create a variable linking object for use later */
-SWIGRUNTIME(PyObject *)
-SWIG_newvarlink(void) {
-  swig_varlinkobject *result = 0;
-  result = PyMem_NEW(swig_varlinkobject,1);
-  varlinktype.ob_type = &PyType_Type;    /* Patch varlinktype into a PyType */
-  result->ob_type = &varlinktype;
-  result->vars = 0;
-  result->ob_refcnt = 0;
-  Py_XINCREF((PyObject *) result);
-  return ((PyObject*) result);
-}
-
-SWIGRUNTIME(void)
-SWIG_addvarlink(PyObject *p, char *name,
-	   PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
-  swig_varlinkobject *v;
-  swig_globalvar *gv;
-  v= (swig_varlinkobject *) p;
-  gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
-  gv->name = (char *) malloc(strlen(name)+1);
-  strcpy(gv->name,name);
-  gv->get_attr = get_attr;
-  gv->set_attr = set_attr;
-  gv->next = v->vars;
-  v->vars = gv;
-}
-/* Convert a pointer value */
-SWIGRUNTIME(int)
-SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) {
-  unsigned long p;
-  register int d;
-  swig_type_info *tc;
-  char  *c;
-  static PyObject *SWIG_this = 0;
-  int    newref = 0;
-
-  if (!obj || (obj == Py_None)) {
-    *ptr = 0;
-    return 0;
-  }
-#ifdef SWIG_COBJECT_TYPES
-  if (!(PyCObject_Check(obj))) {
-    if (!SWIG_this)
-      SWIG_this = PyString_InternFromString("this");
-    obj = PyObject_GetAttr(obj,SWIG_this);
-    newref = 1;
-    if (!obj) goto type_error;
-    if (!PyCObject_Check(obj)) {
-      Py_DECREF(obj);
-      goto type_error;
-    }
-  } 
-  *ptr = PyCObject_AsVoidPtr(obj);
-  c = (char *) PyCObject_GetDesc(obj);
-  if (newref) Py_DECREF(obj);
-  goto cobject;
-#else
-  if (!(PyString_Check(obj))) {
-    if (!SWIG_this)
-      SWIG_this = PyString_InternFromString("this");
-    obj = PyObject_GetAttr(obj,SWIG_this);
-    newref = 1;
-    if (!obj) goto type_error;
-    if (!PyString_Check(obj)) {
-      Py_DECREF(obj);
-      goto type_error;
-    }
-  } 
-  c = PyString_AsString(obj);
-  p = 0;
-  /* Pointer values must start with leading underscore */
-  if (*c != '_') {
-    *ptr = (void *) 0;
-    if (strcmp(c,"NULL") == 0) {
-      if (newref) Py_DECREF(obj);
-      return 0;
-    } else {
-      if (newref) Py_DECREF(obj);
-      goto type_error;
-    }
-  }
-  c++;
-  /* Extract hex value from pointer */
-  while ((d = *c)) {
-    if ((d >= '0') && (d <= '9'))
-      p = (p << 4) + (d - '0');
-    else if ((d >= 'a') && (d <= 'f'))
-      p = (p << 4) + (d - ('a'-10));
-    else
-      break; 
-    c++;
-  }
-  *ptr = (void *) p;
-  if (newref) Py_DECREF(obj);
-#endif
-
-#ifdef SWIG_COBJECT_TYPES
-cobject:
-#endif
-
-  if (ty) {
-    tc = SWIG_TypeCheck(c,ty);
-    if (!tc) goto type_error;
-    *ptr = SWIG_TypeCast(tc,(void*)p);
-  }
-  return 0;
-
-type_error:
-
-  if (flags) {
-    if (ty) {
-      char *temp = (char *) malloc(64+strlen(ty->name));
-      sprintf(temp,"Type error. Expected %s", ty->name);
-      PyErr_SetString(PyExc_TypeError, temp);
-      free((char *) temp);
-    } else {
-      PyErr_SetString(PyExc_TypeError,"Expected a pointer");
-    }
-  }
-  return -1;
-}
-
-/* Take a pointer and convert it to a string */
-SWIGRUNTIME(void) 
-SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) {
-  static char hex[17] = "0123456789abcdef";
-  unsigned long p, s;
-  char result[32], *r; 
-  r = result;
-  p = (unsigned long) ptr;
-  if (p > 0) {
-    while (p > 0) {
-      s = p & 0xf;
-      *(r++) = hex[s];
-      p = p >> 4;
-    }
-    *r = '_';
-    while (r >= result)
-      *(c++) = *(r--);
-    strcpy (c, ty->name);
-  } else {
-    strcpy (c, "NULL");
-  }
-}
-
-/* Create a new pointer object */
-SWIGRUNTIME(PyObject *)
-SWIG_NewPointerObj(void *ptr, swig_type_info *type) {
-  char result[512];
-  PyObject *robj;
-  if (!ptr) {
-    Py_INCREF(Py_None);
-    return Py_None;
-  }
-#ifdef SWIG_COBJECT_TYPES
-  robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, type->name, NULL);
-#else
-  SWIG_MakePtr(result,ptr,type);
-  robj = PyString_FromString(result);
-#endif
-  return robj;
-}
-
-/* Install Constants */
-SWIGRUNTIME(void)
-SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) {
-  int i;
-  PyObject *obj;
-  for (i = 0; constants[i].type; i++) {
-    switch(constants[i].type) {
-    case SWIG_PY_INT:
-      obj = PyInt_FromLong(constants[i].lvalue);
-      break;
-    case SWIG_PY_FLOAT:
-      obj = PyFloat_FromDouble(constants[i].dvalue);
-      break;
-    case SWIG_PY_STRING:
-      obj = PyString_FromString((char *) constants[i].pvalue);
-      break;
-    case SWIG_PY_POINTER:
-      obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype);
-      break;
-    default:
-      obj = 0;
-      break;
-    }
-    if (obj) {
-      PyDict_SetItemString(d,constants[i].name,obj);
-      Py_DECREF(obj);
-    }
-  }
-}
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-/* -------- TYPES TABLE (BEGIN) -------- */
-
-#define  SWIGTYPE_p_DBFFile swig_types[0] 
-static swig_type_info *swig_types[2];
-
-/* -------- TYPES TABLE (END) -------- */
-
-
-/*-----------------------------------------------
-              @(target):= dbflibc.so
-  ------------------------------------------------*/
-#define SWIG_init    initdbflibc
-
-#define SWIG_name    "dbflibc"
-
-#include "shapefil.h"
-
-
-/* Read one attribute from the dbf handle and return it as a new python object
- *
- * If an error occurs, set the appropriate Python exception and return
- * NULL.
- *
- * Assume that the values of the record and field arguments are valid.
- * The name argument will be passed to DBFGetFieldInfo as is and should
- * thus be either NULL or a pointer to an array of at least 12 chars
- */
-static PyObject *
-do_read_attribute(DBFInfo * handle, int record, int field, char * name)
-{
-    int type, width;
-    PyObject *value;
-
-    type = DBFGetFieldInfo(handle, field, name, &width, NULL);
-    /* For strings NULL and the empty string are indistinguishable
-     * in DBF files. We prefer empty strings instead for backwards
-     * compatibility reasons because older wrapper versions returned
-     * emtpy strings as empty strings.
-     */
-    if (type != FTString && DBFIsAttributeNULL(handle, record, field))
-    {
-	value = Py_None;
-	Py_INCREF(value);
-    }
-    else
-    {
-	switch (type)
-	{
-	case FTString:
-	{
-	    const char * temp = DBFReadStringAttribute(handle, record, field);
-	    if (temp)
-	    {
-		value = PyString_FromString(temp);
-	    }
-	    else
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "Can't read value for row %d column %d",
-			     record, field);
-		value = NULL;
-	    }
-	    break;
-	}
-	case FTInteger:
-	    value = PyInt_FromLong(DBFReadIntegerAttribute(handle, record,
-							   field));
-	    break;
-	case FTDouble:
-	    value = PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record,
-							      field));
-	    break;
-	default:
-	    PyErr_Format(PyExc_TypeError, "Invalid field data type %d",
-			 type);
-	    value = NULL;
-	}
-    }
-    if (!value)
-	return NULL;
-
-    return value;
-}    
-
-/* the read_attribute method. Return the value of the given record and
- * field as a python object of the appropriate type.
- * 
- * In case of error, set a python exception and return NULL. Since that
- * value will be returned to the python interpreter as is, the
- * interpreter should recognize the exception.
- */
-
-static PyObject *
-DBFInfo_read_attribute(DBFInfo * handle, int record, int field)
-{
-    if (record < 0 || record >= DBFGetRecordCount(handle))
-    {
-	PyErr_Format(PyExc_ValueError,
-		     "record index %d out of bounds (record count: %d)",
-		     record, DBFGetRecordCount(handle));
-	return NULL;
-    }
-
-    if (field < 0 || field >= DBFGetFieldCount(handle))
-    {
-	PyErr_Format(PyExc_ValueError,
-		     "field index %d out of bounds (field count: %d)",
-		     field, DBFGetFieldCount(handle));
-	return NULL;
-    }
-
-    return do_read_attribute(handle, record, field, NULL);
-}
-    
-
-/* the read_record method. Return the record record as a dictionary with
- * whose keys are the names of the fields, and their values as the
- * appropriate Python type.
- * 
- * In case of error, set a python exception and return NULL. Since that
- * value will be returned to the python interpreter as is, the
- * interpreter should recognize the exception.
- */
-
-static PyObject *
-DBFInfo_read_record(DBFInfo * handle, int record)
-{
-    int num_fields;
-    int i;
-    int type, width;
-    char name[12];
-    PyObject *dict;
-    PyObject *value;
-
-    if (record < 0 || record >= DBFGetRecordCount(handle))
-    {
-	PyErr_Format(PyExc_ValueError,
-		     "record index %d out of bounds (record count: %d)",
-		     record, DBFGetRecordCount(handle));
-	return NULL;
-    }
-
-    dict = PyDict_New();
-    if (!dict)
-	return NULL;
-	
-    num_fields = DBFGetFieldCount(handle);
-    for (i = 0; i < num_fields; i++)
-    {
-	value = do_read_attribute(handle, record, i, name);
-	if (!value)
-	    goto fail;
-
-	PyDict_SetItemString(dict, name, value);
-	Py_DECREF(value);
-    }
-
-    return dict;
-
- fail:
-    Py_XDECREF(dict);
-    return NULL;
-}
-
-/* the write_record method. Write the record record given wither as a
- * dictionary or a sequence (i.e. a list or a tuple).
- *
- * If it's a dictionary the keys must be the names of the fields and
- * their value must have a suitable type. Only the fields actually
- * contained in the dictionary are written. Fields for which there's no
- * item in the dict are not modified.
- *
- * If it's a sequence, all fields must be present in the right order.
- *
- * In case of error, set a python exception and return NULL. Since that
- * value will be returned to the python interpreter as is, the
- * interpreter should recognize the exception.
- *
- * The method is implemented with two c-functions, write_field to write
- * a single field and DBFInfo_write_record as the front-end.
- */
-
-
-/* write a single field of a record. */
-static int
-write_field(DBFHandle handle, int record, int field, int type,
-	    PyObject * value)
-{
-    char * string_value;
-    int int_value;
-    double double_value;
-
-    if (value == Py_None)
-    {
-	if (!DBFWriteNULLAttribute(handle, record, field))
-	{
-	    PyErr_Format(PyExc_IOError,
-			 "can't write NULL field %d of record %d",
-			 field, record);
-	    return 0;
-	}
-    }
-    else
-    {
-	switch (type)
-	{
-	case FTString:
-	    string_value = PyString_AsString(value);
-	    if (!string_value)
-		return 0;
-	    if (!DBFWriteStringAttribute(handle, record, field, string_value))
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "can't write field %d of record %d",
-			     field, record);
-		return 0;
-	    }
-	    break;
-
-	case FTInteger:
-	    int_value = PyInt_AsLong(value);
-	    if (int_value == -1 && PyErr_Occurred())
-		return 0;
-	    if (!DBFWriteIntegerAttribute(handle, record, field, int_value))
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "can't write field %d of record %d",
-			     field, record);
-		return 0;
-	    }
-	    break;
-
-	case FTDouble:
-	    double_value = PyFloat_AsDouble(value);
-	    if (double_value == -1 && PyErr_Occurred())
-		return 0;
-	    if (!DBFWriteDoubleAttribute(handle, record, field, double_value))
-	    {
-		PyErr_Format(PyExc_IOError,
-			     "can't write field %d of record %d",
-			     field, record);
-		return 0;
-	    }
-	    break;
-
-	default:
-	    PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
-	    return 0;
-	}
-    }
-
-    return 1;
-}
-
-static
-PyObject *
-DBFInfo_write_record(DBFHandle handle, int record, PyObject *record_object)
-{
-    int num_fields;
-    int i, length;
-    int type, width;
-    char name[12];
-    PyObject * value = NULL;
-
-    num_fields = DBFGetFieldCount(handle);
-
-    /* We used to use PyMapping_Check to test whether record_object is a
-     * dictionary like object instead of PySequence_Check to test
-     * whether it's a sequence. Unfortunately in Python 2.3
-     * PyMapping_Check returns true for lists and tuples too so the old
-     * approach doesn't work anymore.
-     */
-    if (PySequence_Check(record_object))
-    {
-	/* It's a sequence object. Iterate through all items in the
-	 * sequence and write them to the appropriate field.
-	 */
-	length = PySequence_Length(record_object);
-	if (length != num_fields)
-	{
-	    PyErr_SetString(PyExc_TypeError,
-			    "record must have one item for each field");
-	    goto fail;
-	}
-	for (i = 0; i < length; i++)
-	{
-	    type = DBFGetFieldInfo(handle, i, name, &width, NULL); 
-	    value = PySequence_GetItem(record_object, i);
-	    if (value)
-	    {
-		if (!write_field(handle, record, i, type, value))
-		    goto fail;
-		Py_DECREF(value);
-	    }
-	    else
-	    {
-		goto fail;
-	    }
-	}
-    }
-    else
-    {
-	/* It's a dictionary-like object. Iterate over the names of the
-         * known fields and write the corresponding item
-	 */
-	for (i = 0; i < num_fields; i++)
-	{
-	    type = DBFGetFieldInfo(handle, i, name, &width, NULL);
-
-	    /* if the dictionary has the key name write that object to
-	     * the appropriate field, other wise just clear the python
-	     * exception and do nothing.
-	     */
-	    value = PyMapping_GetItemString(record_object, name);
-	    if (value)
-	    {
-		if (!write_field(handle, record, i, type, value))
-		    goto fail;
-		Py_DECREF(value);
-	    }
-	    else
-	    {
-		PyErr_Clear();
-	    }
-	}
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-
- fail:
-    Py_XDECREF(value);
-    return NULL;
-}
-
-static
-void
-DBFInfo_commit(DBFHandle handle)
-{
-#if HAVE_UPDATE_HEADER
-    DBFUpdateHeader(handle);
-#endif
-}
-
-static PyObject* l_output_helper(PyObject* target, PyObject* o) {
-    PyObject*   o2;
-    if (!target) {                   
-        target = o;
-    } else if (target == Py_None) {  
-        Py_DECREF(Py_None);
-        target = o;
-    } else {                         
-        if (!PyList_Check(target)) {
-            o2 = target;
-            target = PyList_New(0);
-            PyList_Append(target, o2);
-	    Py_XDECREF(o2);
-        }
-        PyList_Append(target,o);
-	Py_XDECREF(o);
-    }
-    return target;
-}
-
-static PyObject* t_output_helper(PyObject* target, PyObject* o) {
-    PyObject*   o2;
-    PyObject*   o3;
-
-    if (!target) {                   
-        target = o;
-    } else if (target == Py_None) {  
-        Py_DECREF(Py_None);
-        target = o;
-    } else {                         
-        if (!PyTuple_Check(target)) {
-            o2 = target;
-            target = PyTuple_New(1);
-            PyTuple_SetItem(target, 0, o2);
-        }
-        o3 = PyTuple_New(1);            
-        PyTuple_SetItem(o3, 0, o);      
-
-        o2 = target;
-        target = PySequence_Concat(o2, o3); 
-        Py_DECREF(o2);                      
-        Py_DECREF(o3);
-    }
-    return target;
-}
-
-#define  SWIG_MemoryError    1
-#define  SWIG_IOError        2
-#define  SWIG_RuntimeError   3
-#define  SWIG_IndexError     4
-#define  SWIG_TypeError      5
-#define  SWIG_DivisionByZero 6
-#define  SWIG_OverflowError  7
-#define  SWIG_SyntaxError    8
-#define  SWIG_ValueError     9
-#define  SWIG_SystemError   10
-#define  SWIG_UnknownError  99
-
-static void _SWIG_exception(int code, char *msg) {
-  switch(code) {
-  case SWIG_MemoryError:
-    PyErr_SetString(PyExc_MemoryError,msg);
-    break;
-  case SWIG_IOError:
-    PyErr_SetString(PyExc_IOError,msg);
-    break;
-  case SWIG_RuntimeError:
-    PyErr_SetString(PyExc_RuntimeError,msg);
-    break;
-  case SWIG_IndexError:
-    PyErr_SetString(PyExc_IndexError,msg);
-    break;
-  case SWIG_TypeError:
-    PyErr_SetString(PyExc_TypeError,msg);
-    break;
-  case SWIG_DivisionByZero:
-    PyErr_SetString(PyExc_ZeroDivisionError,msg);
-    break;
-  case SWIG_OverflowError:
-    PyErr_SetString(PyExc_OverflowError,msg);
-    break;
-  case SWIG_SyntaxError:
-    PyErr_SetString(PyExc_SyntaxError,msg);
-    break;
-  case SWIG_ValueError:
-    PyErr_SetString(PyExc_ValueError,msg);
-    break;
-  case SWIG_SystemError:
-    PyErr_SetString(PyExc_SystemError,msg);
-    break;
-  default:
-    PyErr_SetString(PyExc_RuntimeError,msg);
-    break;
-  }
-}
-
-#define SWIG_exception(a,b) { _SWIG_exception(a,b); return NULL; }
-
-    typedef struct {
-	DBFHandle handle;
-    } DBFFile;
-
-#define NOCHECK_delete_DBFFile
-#define NOCHECK_DBFFile_close
-
-    DBFFile * open_DBFFile(const char * file, const char * mode)
-    {
-	DBFFile * self = malloc(sizeof(DBFFile));
-	if (self)
-	    self->handle = DBFOpen(file, mode);
-	return self;
-    }
-
-    DBFFile * create_DBFFile(const char * file)
-    {
-	DBFFile * self = malloc(sizeof(DBFFile));
-	if (self)
-	    self->handle = DBFCreate(file);
-	return self;
-    }
-#ifdef __cplusplus
-extern "C" {
-#endif
-static PyObject *_wrap_open(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    char *arg0 ;
-    char *arg1 = "rb" ;
-    DBFFile *result ;
-    
-    if(!PyArg_ParseTuple(args,"s|s:open",&arg0,&arg1)) return NULL;
-    {
-        result = (DBFFile *)open_DBFFile((char const *)arg0,(char const *)arg1);
-        ;
-        if (!result)
-        {
-            SWIG_exception(SWIG_MemoryError, "no memory");
-        }
-        else if (!result->handle)
-        {
-            SWIG_exception(SWIG_IOError, "open_DBFFile failed");
-        }
-    }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_DBFFile);
-    return resultobj;
-}
-
-
-static PyObject *_wrap_create(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    char *arg0 ;
-    DBFFile *result ;
-    
-    if(!PyArg_ParseTuple(args,"s:create",&arg0)) return NULL;
-    {
-        result = (DBFFile *)create_DBFFile((char const *)arg0);
-        ;
-        if (!result)
-        {
-            SWIG_exception(SWIG_MemoryError, "no memory");
-        }
-        else if (!result->handle)
-        {
-            SWIG_exception(SWIG_IOError, "create_DBFFile failed");
-        }
-    }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_DBFFile);
-    return resultobj;
-}
-
-
-DBFFile * new_DBFFile(char const *file,char const *mode) {
-    {
-        DBFFile * self = malloc(sizeof(DBFFile));
-        if (self)
-        self->handle = DBFOpen(file, mode);
-        return self;
-    }
-}
-
-
-static PyObject *_wrap_new_DBFFile(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    char *arg0 ;
-    char *arg1 = "rb" ;
-    DBFFile *result ;
-    
-    if(!PyArg_ParseTuple(args,"s|s:new_DBFFile",&arg0,&arg1)) return NULL;
-    {
-        result = (DBFFile *)new_DBFFile((char const *)arg0,(char const *)arg1);
-        ;
-        if (!result)
-        {
-            SWIG_exception(SWIG_MemoryError, "no memory");
-        }
-        else if (!result->handle)
-        {
-            SWIG_exception(SWIG_IOError, "new_DBFFile failed");
-        }
-    }resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_DBFFile);
-    return resultobj;
-}
-
-
-void  delete_DBFFile(DBFFile *self) {
-    {
-        if (self->handle)
-        DBFClose(self->handle);
-        free(self);
-    }
-}
-
-
-static PyObject *_wrap_delete_DBFFile(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    PyObject * argo0 =0 ;
-    
-    if(!PyArg_ParseTuple(args,"O:delete_DBFFile",&argo0)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_delete_DBFFile
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    delete_DBFFile(arg0);
-    Py_INCREF(Py_None);
-    resultobj = Py_None;
-    return resultobj;
-}
-
-
-void  DBFFile_close(DBFFile *self) {
-    {
-        if (self->handle)
-        DBFClose(self->handle);
-        self->handle = NULL;
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_close(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    PyObject * argo0 =0 ;
-    
-    if(!PyArg_ParseTuple(args,"O:DBFFile_close",&argo0)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_close
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    DBFFile_close(arg0);
-    Py_INCREF(Py_None);
-    resultobj = Py_None;
-    return resultobj;
-}
-
-
-int  DBFFile_field_count(DBFFile *self) {
-    {
-        return DBFGetFieldCount(self->handle);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_field_count(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    PyObject * argo0 =0 ;
-    int result ;
-    
-    if(!PyArg_ParseTuple(args,"O:DBFFile_field_count",&argo0)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_field_count
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    result = (int )DBFFile_field_count(arg0);
-    resultobj = PyInt_FromLong((long)result);
-    return resultobj;
-}
-
-
-int  DBFFile_record_count(DBFFile *self) {
-    {
-        return DBFGetRecordCount(self->handle);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_record_count(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    PyObject * argo0 =0 ;
-    int result ;
-    
-    if(!PyArg_ParseTuple(args,"O:DBFFile_record_count",&argo0)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_record_count
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    result = (int )DBFFile_record_count(arg0);
-    resultobj = PyInt_FromLong((long)result);
-    return resultobj;
-}
-
-
-int  DBFFile_field_info(DBFFile *self,int iField,char *fieldname_out,int *output_width,int *output_decimals) {
-    {
-        return DBFGetFieldInfo(self->handle, iField, fieldname_out,
-        output_width, output_decimals);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_field_info(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    int arg1 ;
-    char *arg2 ;
-    int *arg3 ;
-    int *arg4 ;
-    char temp[12] ;
-    int temp0 ;
-    int temp1 ;
-    PyObject * argo0 =0 ;
-    int result ;
-    
-    {
-        arg2 = temp;
-    }
-    {
-        arg3 = &temp0;
-    }
-    {
-        arg4 = &temp1;
-    }
-    if(!PyArg_ParseTuple(args,"Oi:DBFFile_field_info",&argo0,&arg1)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_field_info
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    result = (int )DBFFile_field_info(arg0,arg1,arg2,arg3,arg4);
-    resultobj = PyInt_FromLong((long)result);
-    {
-        PyObject * string = PyString_FromString(arg2);
-        resultobj = t_output_helper(resultobj,string);
-    }
-    {
-        PyObject *o;
-        o = PyInt_FromLong((long) (*arg3));
-        resultobj = t_output_helper(resultobj, o);
-    }
-    {
-        PyObject *o;
-        o = PyInt_FromLong((long) (*arg4));
-        resultobj = t_output_helper(resultobj, o);
-    }
-    return resultobj;
-}
-
-
-PyObject * DBFFile_read_record(DBFFile *self,int record) {
-    {
-        return DBFInfo_read_record(self->handle, record);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_read_record(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    int arg1 ;
-    PyObject * argo0 =0 ;
-    PyObject *result ;
-    
-    if(!PyArg_ParseTuple(args,"Oi:DBFFile_read_record",&argo0,&arg1)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_read_record
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    result = (PyObject *)DBFFile_read_record(arg0,arg1);
-    {
-        resultobj = result;
-    }
-    return resultobj;
-}
-
-
-PyObject * DBFFile_read_attribute(DBFFile *self,int record,int field) {
-    {
-        return DBFInfo_read_attribute(self->handle, record, field);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_read_attribute(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    int arg1 ;
-    int arg2 ;
-    PyObject * argo0 =0 ;
-    PyObject *result ;
-    
-    if(!PyArg_ParseTuple(args,"Oii:DBFFile_read_attribute",&argo0,&arg1,&arg2)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_read_attribute
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    result = (PyObject *)DBFFile_read_attribute(arg0,arg1,arg2);
-    {
-        resultobj = result;
-    }
-    return resultobj;
-}
-
-
-int  DBFFile_add_field(DBFFile *self,char const *pszFieldName,DBFFieldType eType,int nWidth,int nDecimals) {
-    {
-        return DBFAddField(self->handle, pszFieldName, eType, nWidth,
-        nDecimals);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_add_field(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    char *arg1 ;
-    int arg2 ;
-    int arg3 ;
-    int arg4 ;
-    PyObject * argo0 =0 ;
-    int result ;
-    
-    if(!PyArg_ParseTuple(args,"Osiii:DBFFile_add_field",&argo0,&arg1,&arg2,&arg3,&arg4)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_add_field
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    {
-        result = (int )DBFFile_add_field(arg0,(char const *)arg1,(DBFFieldType )arg2,arg3,arg4);
-        ;
-        if (result < 0)
-        {
-            SWIG_exception(SWIG_RuntimeError, "add_field failed");
-        }
-    }resultobj = PyInt_FromLong((long)result);
-    return resultobj;
-}
-
-
-PyObject * DBFFile_write_record(DBFFile *self,int record,PyObject *dict_or_sequence) {
-    {
-        return DBFInfo_write_record(self->handle, record,
-        dict_or_sequence);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_write_record(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    int arg1 ;
-    PyObject *arg2 ;
-    PyObject * argo0 =0 ;
-    PyObject * obj2  = 0 ;
-    PyObject *result ;
-    
-    if(!PyArg_ParseTuple(args,"OiO:DBFFile_write_record",&argo0,&arg1,&obj2)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        arg2 = obj2;
-    }
-    {
-        #ifndef NOCHECK_DBFFile_write_record
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    result = (PyObject *)DBFFile_write_record(arg0,arg1,arg2);
-    {
-        resultobj = result;
-    }
-    return resultobj;
-}
-
-
-void  DBFFile_commit(DBFFile *self) {
-    {
-        DBFInfo_commit(self->handle);
-    }
-}
-
-
-static PyObject *_wrap_DBFFile_commit(PyObject *self, PyObject *args) {
-    PyObject *resultobj;
-    DBFFile *arg0 ;
-    PyObject * argo0 =0 ;
-    
-    if(!PyArg_ParseTuple(args,"O:DBFFile_commit",&argo0)) return NULL;
-    if ((SWIG_ConvertPtr(argo0,(void **) &arg0,SWIGTYPE_p_DBFFile,1)) == -1) return NULL;
-    {
-        #ifndef NOCHECK_DBFFile_commit
-        if (!arg0 || !arg0->handle)
-        SWIG_exception(SWIG_TypeError, "dbffile already closed");
-        #endif
-    }
-    DBFFile_commit(arg0);
-    Py_INCREF(Py_None);
-    resultobj = Py_None;
-    return resultobj;
-}
-
-
-static PyMethodDef dbflibcMethods[] = {
-	 { "open", _wrap_open, METH_VARARGS },
-	 { "create", _wrap_create, METH_VARARGS },
-	 { "new_DBFFile", _wrap_new_DBFFile, METH_VARARGS },
-	 { "delete_DBFFile", _wrap_delete_DBFFile, METH_VARARGS },
-	 { "DBFFile_close", _wrap_DBFFile_close, METH_VARARGS },
-	 { "DBFFile_field_count", _wrap_DBFFile_field_count, METH_VARARGS },
-	 { "DBFFile_record_count", _wrap_DBFFile_record_count, METH_VARARGS },
-	 { "DBFFile_field_info", _wrap_DBFFile_field_info, METH_VARARGS },
-	 { "DBFFile_read_record", _wrap_DBFFile_read_record, METH_VARARGS },
-	 { "DBFFile_read_attribute", _wrap_DBFFile_read_attribute, METH_VARARGS },
-	 { "DBFFile_add_field", _wrap_DBFFile_add_field, METH_VARARGS },
-	 { "DBFFile_write_record", _wrap_DBFFile_write_record, METH_VARARGS },
-	 { "DBFFile_commit", _wrap_DBFFile_commit, METH_VARARGS },
-	 { NULL, NULL }
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
-
-static swig_type_info _swigt__p_DBFFile[] = {{"_p_DBFFile", 0, "DBFFile *"},{"_p_DBFFile"},{0}};
-
-static swig_type_info *swig_types_initial[] = {
-_swigt__p_DBFFile, 
-0
-};
-
-
-/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
-
-static swig_const_info swig_const_table[] = {
-    { SWIG_PY_INT,     "FTString", (long) FTString, 0, 0, 0},
-    { SWIG_PY_INT,     "FTInteger", (long) FTInteger, 0, 0, 0},
-    { SWIG_PY_INT,     "FTDouble", (long) FTDouble, 0, 0, 0},
-    { SWIG_PY_INT,     "FTInvalid", (long) FTInvalid, 0, 0, 0},
-    { SWIG_PY_INT,     "_have_commit", (long) HAVE_UPDATE_HEADER, 0, 0, 0},
-{0}};
-
-static PyObject *SWIG_globals;
-#ifdef __cplusplus
-extern "C" 
-#endif
-SWIGEXPORT(void) initdbflibc(void) {
-    PyObject *m, *d;
-    int i;
-    SWIG_globals = SWIG_newvarlink();
-    m = Py_InitModule("dbflibc", dbflibcMethods);
-    d = PyModule_GetDict(m);
-    for (i = 0; swig_types_initial[i]; i++) {
-        swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);
-    }
-    SWIG_InstallConstants(d,swig_const_table);
-
-#   if PY_VERSION_HEX >=0x02040000 
-    /* because we are in a python module now, we can give out
-     * pointers to python's locale agonistic function 
-     * XXX this clearly is a hack
-     */
-    DBFSetatof_function(&PyOS_ascii_atof);
-#   endif
-
-}
-

Copied: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c (from rev 2741, branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.i)
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflib.i	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c	2007-03-14 16:26:14 UTC (rev 2742)
@@ -0,0 +1,515 @@
+#include "pyshapelib_common.h"
+
+/* --- DBFFile ------------------------------------------------------------------------------------------------------- */
+
+typedef struct {
+	PyObject_HEAD
+	DBFHandle handle;
+} DBFFileObject;
+
+
+
+/* allocator 
+*/
+static PyObject* dbffile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+	DBFFileObject* self;	
+	self = (DBFFileObject*) type->tp_alloc(type, 0);
+	self->handle = NULL;
+	return (PyObject*) self;
+}
+
+
+
+/* deallocator
+*/
+static void dbffile_dealloc(DBFFileObject* self)
+{
+	DBFClose(self->handle);
+	self->handle = NULL;
+	self->ob_type->tp_free((PyObject*)self);
+}
+
+
+
+/* constructor
+*/
+static int dbffile_init(DBFFileObject* self, PyObject* args, PyObject* kwds)
+{
+	char* file;
+	char* mode = "rb";
+	if (kwds != NULL && PyDict_Size(kwds) > 0)
+	{
+		PyErr_Format(PyExc_TypeError, "dbflib.DBFFile.__init__ takes no keyword arguments");
+		return -1;
+	}
+	if (!PyArg_ParseTuple(args, "s|s", &file, &mode)) return -1;
+	
+	self->handle = DBFOpen(file, mode);
+	return self->handle ? 0 : -1;
+}
+
+
+
+static PyObject* dbffile_close(DBFFileObject* self)
+{
+	DBFClose(self->handle);
+	self->handle = NULL;
+	Py_RETURN_NONE;
+}
+
+
+
+static PyObject* dbffile_field_count(DBFFileObject* self)
+{
+	return PyInt_FromLong((long)DBFGetFieldCount(self->handle));
+}
+
+
+
+static PyObject* dbffile_record_count(DBFFileObject* self)
+{
+	return PyInt_FromLong((long)DBFGetRecordCount(self->handle));
+}
+
+
+
+static PyObject* dbffile_field_info(DBFFileObject* self, PyObject* args)
+{
+	char field_name[12];
+	int field, width = 0, decimals = 0, field_type;
+	
+	if (!PyArg_ParseTuple(args, "i", &field)) return NULL;
+	
+	field_name[0] = '\0';
+	field_type = DBFGetFieldInfo(self->handle, field, field_name, &width, &decimals);
+	
+	return Py_BuildValue("isii", field_type, field_name, width, decimals);
+}
+
+
+
+static PyObject* dbffile_add_field(DBFFileObject* self, PyObject* args)
+{
+	char* name;
+	int type, width, decimals;
+	int field;
+	
+	if (!PyArg_ParseTuple(args, "siii", &name, &type, &width, &decimals)) return NULL;
+	
+	field = DBFAddField(self->handle, name, (DBFFieldType)type, width, decimals);
+	
+	if (field < 0)
+	{
+		PyErr_SetString(PyExc_ValueError, "Failed to add field due to inappropriate field definition");
+		return NULL;
+	}
+	return PyInt_FromLong((long)field);
+}
+
+
+
+/* Read one attribute from the dbf handle and return it as a new python object
+*
+* If an error occurs, set the appropriate Python exception and return
+* NULL.
+*
+* Assume that the values of the record and field arguments are valid.
+* The name argument will be passed to DBFGetFieldInfo as is and should
+* thus be either NULL or a pointer to an array of at least 12 chars
+*/
+static PyObject* do_read_attribute(DBFHandle handle, int record, int field, char * name)
+{
+	int type, width;
+	const char* temp;
+	type = DBFGetFieldInfo(handle, field, name, &width, NULL);
+	
+	/* For strings NULL and the empty string are indistinguishable
+	* in DBF files. We prefer empty strings instead for backwards
+	* compatibility reasons because older wrapper versions returned
+	* emtpy strings as empty strings.
+	*/
+	if (type != FTString && DBFIsAttributeNULL(handle, record, field))
+	{
+		Py_RETURN_NONE;
+	}
+	else
+	{
+		switch (type)
+		{
+		case FTString:
+			temp = DBFReadStringAttribute(handle, record, field);
+			if (!temp)
+			{
+				PyErr_Format(PyExc_IOError,
+						"Can't read value for row %d column %d",
+						record, field);
+				return NULL;
+			}
+			return PyString_FromString(temp);
+
+		case FTInteger:
+			return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));
+
+		case FTDouble:
+			return PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, field));
+
+		default:
+			PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
+			return NULL;
+		}
+	}
+}    
+
+
+
+/* the read_attribute method. Return the value of the given record and
+* field as a python object of the appropriate type.
+*/
+static PyObject* dbffile_read_attribute(DBFFileObject* self, PyObject* args)
+{
+	int record, field;
+
+	if (!PyArg_ParseTuple(args, "ii", &record, &field)) return NULL;
+	
+	if (record < 0 || record >= DBFGetRecordCount(self->handle))
+	{
+		PyErr_Format(PyExc_ValueError,
+				"record index %d out of bounds (record count: %d)",
+				record, DBFGetRecordCount(self->handle));
+		return NULL;
+	}
+
+	if (field < 0 || field >= DBFGetFieldCount(self->handle))
+	{
+		PyErr_Format(PyExc_ValueError,
+				"field index %d out of bounds (field count: %d)",
+				field, DBFGetFieldCount(self->handle));
+		return NULL;
+	}
+
+	return do_read_attribute(self->handle, record, field, NULL);
+}
+
+
+
+/* the read_record method. Return the record record as a dictionary with
+* whose keys are the names of the fields, and their values as the
+* appropriate Python type.
+*/
+static PyObject* dbffile_read_record(DBFFileObject* self, PyObject* args)
+{
+	int record;
+	int num_fields;
+	int i;
+	char name[12];
+	PyObject *dict;
+	PyObject *value = NULL;
+
+	if (!PyArg_ParseTuple(args, "i", &record)) return NULL;
+
+	if (record < 0 || record >= DBFGetRecordCount(self->handle))
+	{
+		PyErr_Format(PyExc_ValueError,
+			"record index %d out of bounds (record count: %d)",
+			record, DBFGetRecordCount(self->handle));
+		return NULL;
+	}
+
+	dict = PyDict_New();
+	if (!dict) return NULL;
+	
+	num_fields = DBFGetFieldCount(self->handle);
+	for (i = 0; i < num_fields; i++)
+	{
+		value = do_read_attribute(self->handle, record, i, name);
+		if (!value || PyDict_SetItemString(dict, name, value) < 0) goto fail;
+		Py_DECREF(value);
+		value = NULL;
+	}
+
+	return dict;
+
+fail:
+	Py_XDECREF(value);
+	Py_DECREF(dict);
+	return NULL;
+}
+
+
+
+/* write a single field of a record. */
+static int do_write_field(DBFHandle handle, int record, int field, int type, PyObject* value)
+{
+	char * string_value;
+	int int_value;
+	double double_value;
+
+	if (value == Py_None)
+	{
+		if (!DBFWriteNULLAttribute(handle, record, field))
+		{
+			PyErr_Format(PyExc_IOError,
+				"can't write NULL field %d of record %d",
+				field, record);
+			return 0;
+		}
+	}
+	else
+	{
+		switch (type)
+		{
+		case FTString:
+			string_value = PyString_AsString(value);
+			if (!string_value) return 0;
+			if (!DBFWriteStringAttribute(handle, record, field, string_value))
+			{
+				PyErr_Format(PyExc_IOError,
+						"can't write field %d of record %d",
+						field, record);
+				return 0;
+			}
+			break;
+
+		case FTInteger:
+			int_value = PyInt_AsLong(value);
+			if (int_value == -1 && PyErr_Occurred()) return 0;
+			if (!DBFWriteIntegerAttribute(handle, record, field, int_value))
+			{
+				PyErr_Format(PyExc_IOError,
+						"can't write field %d of record %d",
+						field, record);
+				return 0;
+			}
+			break;
+
+		case FTDouble:
+			double_value = PyFloat_AsDouble(value);
+			if (double_value == -1 && PyErr_Occurred()) return 0;
+			if (!DBFWriteDoubleAttribute(handle, record, field, double_value))
+			{
+				PyErr_Format(PyExc_IOError,
+						"can't write field %d of record %d",
+						field, record);
+				return 0;
+			}
+			break;
+
+		default:
+			PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+
+
+static PyObject* dbffile_write_field(DBFFileObject* self, PyObject* args)
+{
+	int record, field;
+	PyObject* value;
+	int type;
+
+	if (!PyArg_ParseTuple(args, "iiO", &record, &field, &value)) return NULL;
+	
+	if (field < 0 || field >= DBFGetFieldCount(self->handle))
+	{
+		PyErr_Format(PyExc_ValueError,
+				"field index %d out of bounds (field count: %d)",
+				field, DBFGetFieldCount(self->handle));
+		return NULL;
+	}
+
+	type = DBFGetFieldInfo(self->handle, field, NULL, NULL, NULL);
+	if (!do_write_field(self->handle, record, field, type, value)) return NULL;
+	Py_RETURN_NONE;
+}
+
+
+
+static PyObject* dbffile_write_record(DBFFileObject* self, PyObject* args)
+{
+	int record;
+	PyObject* record_object;
+	int i, num_fields;
+	
+	int type;
+	char name[12];
+	PyObject* value = NULL;
+	
+	if (!PyArg_ParseTuple(args, "iO", &record, &record_object)) return NULL;
+	
+	num_fields = DBFGetFieldCount(self->handle);
+	
+	/* mimic ShapeFile functionality where id = -1 means appending */
+	if (record == -1)
+	{
+		record = num_fields;
+	}
+
+	if (PySequence_Check(record_object))
+	{
+		/* It's a sequence object. Iterate through all items in the
+		* sequence and write them to the appropriate field.
+		*/
+		if (PySequence_Length(record_object) != num_fields)
+		{
+			PyErr_SetString(PyExc_TypeError, "record must have one item for each field");
+			return NULL;
+		}
+		for (i = 0; i < num_fields; ++i)
+		{
+			type = DBFGetFieldInfo(self->handle, i, NULL, NULL, NULL); 
+			value = PySequence_GetItem(record_object, i);
+			if (!value) return NULL;
+			if (!do_write_field(self->handle, record, i, type, value)) 
+			{
+				Py_DECREF(value);
+				return NULL;
+			}
+			Py_DECREF(value);
+		}
+	}
+	else
+	{
+		/* It's a dictionary-like object. Iterate over the names of the
+		* known fields and write the corresponding item
+		*/
+		for (i = 0; i < num_fields; ++i)
+		{
+			name[0] = '\0';
+			type = DBFGetFieldInfo(self->handle, i, name, NULL, NULL);
+			value = PyDict_GetItemString(record_object, name);
+			if (value && !do_write_field(self->handle, record, i, type, value)) return NULL;
+		}
+	}
+	
+	return PyInt_FromLong((long)record);
+}
+
+
+
+static PyObject* dbffile_repr(DBFFileObject* self)
+{
+	/* TODO: it would be nice to do something like "dbflib.DBFFile(filename, mode)" instead */
+	return PyString_FromFormat("<dbflib.DBFFile object at %p>", self->handle);
+}
+
+
+
+/* The commit method implementation
+*
+* The method relies on the DBFUpdateHeader method which is not
+* available in shapelib <= 1.2.10.  setup.py defines
+* HAVE_UPDATE_HEADER's value depending on whether the function is
+* available in the shapelib version the code is compiled with.
+*/
+#if HAVE_UPDATE_HEADER
+static PyObject* dbffile_commit(DBFFileObject* self)
+{
+	DBFUpdateHeader(self->handle);
+	Py_RETURN_NONE;
+}
+#endif
+
+
+
+static struct PyMethodDef dbffile_methods[] = 
+{
+	{"close", (PyCFunction)dbffile_close, METH_NOARGS, "close DBFFile"},
+	{"field_count", (PyCFunction)dbffile_field_count, METH_NOARGS, "return number of fields currently defined"},
+	{"record_count", (PyCFunction)dbffile_record_count, METH_NOARGS, "return number of records that currently exist"},
+	{"field_info", (PyCFunction)dbffile_field_info, METH_VARARGS, 
+		"returns info of a field as a tuple (type, name, width, decimals) with:\n"
+		"-type: the type of the field corresponding to the integer value of one of the constants FTString, FTInteger, ...\n"
+		"-name: the name of the field as a string\n"
+		"-width: the width of the field as a number of characters\n"
+		"-decimals: the number of decimal digits" },
+	{"add_field", (PyCFunction)dbffile_add_field, METH_VARARGS,
+		"adds a new field and returns field index if successful\n"
+		"-type: the type of the field corresponding to the integer value of one of the constants FTString, FTInteger, ...\n"
+		"-name: the name of the field as a string\n"
+		"-width: the width of the field as a number of characters\n"
+		"-decimals: the number of decimal digits" },
+	{"read_attribute", (PyCFunction)dbffile_read_attribute, METH_VARARGS, "return the value of one field of a record"},
+	{"read_record", (PyCFunction)dbffile_read_record, METH_VARARGS, "return an entire record as a dict of field names and values"},
+	{"write_field", (PyCFunction)dbffile_write_field, METH_VARARGS, "write a single field of a record"},
+	{"write_record", (PyCFunction)dbffile_write_record, METH_VARARGS, "write an entire record as a dict or a sequence"},
+#if HAVE_UPDATE_HEADER
+	{"commit", (PyCFunction)dbffile_read_record, METH_NOARGS, NULL},
+#endif
+	{NULL}
+};
+
+
+
+static struct PyGetSetDef dbffile_getsetters[] = 
+{
+	{NULL}
+};
+
+
+
+static PyTypeObject DBFFileType = PYSHAPELIB_DEFINE_TYPE(DBFFileObject, dbffile, "shapelib.DBFFile", 0);
+
+
+
+/* --- dbflib -------------------------------------------------------------------------------------------------------- */
+
+static PyObject* dbflib_open(PyObject* module, PyObject* args)
+{
+	return PyObject_CallObject((PyObject*)&DBFFileType, args);
+}
+
+
+
+static PyObject* dbflib_create(PyObject* module, PyObject* args)
+{
+	char* file;
+	DBFFileObject* result;
+	
+	if (!PyArg_ParseTuple(args, "s", &file)) return NULL;
+	
+	result = PyObject_New(DBFFileObject, &DBFFileType);
+	if (!result)
+	{
+		return PyErr_NoMemory();
+	}
+	
+	result->handle = DBFCreate(file);
+	if (!result->handle)
+	{
+		PyObject_Del((PyObject*)result);
+		PyErr_SetString(PyExc_RuntimeError, "Failed to create DBFFile");
+		return NULL;
+	}
+	
+	return (PyObject*) result;
+}
+
+
+
+static struct PyMethodDef dbflib_methods[] = 
+{
+	{"open", (PyCFunction)dbflib_open, METH_VARARGS, "open a DBFFile" },
+	{"create", (PyCFunction)dbflib_create, METH_VARARGS, "create a DBFFile" },
+	{NULL}
+};
+
+
+
+PyMODINIT_FUNC initdbflib(void)
+{
+	PyObject* module = Py_InitModule("dbflib", dbflib_methods);
+	if (!module) return;
+	
+	PYSHAPELIB_ADD_TYPE(DBFFileType, "DBFFile");
+	
+	PYSHAPELIB_ADD_CONSTANT(FTString);
+	PYSHAPELIB_ADD_CONSTANT(FTInteger);
+	PYSHAPELIB_ADD_CONSTANT(FTDouble);
+	PYSHAPELIB_ADD_CONSTANT(FTInvalid);
+	PyModule_AddIntConstant(module, "_have_commit", HAVE_UPDATE_HEADER);
+}

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h	2007-03-14 16:26:14 UTC (rev 2742)
@@ -3,6 +3,8 @@
 
 #include <Python.h>
 #include <structmember.h>
+#include "shapefil.h"
+#include "pyshapelib_api.h"
 
 /* helper to export constants (macros) to Python.
  * The constant in Python will have the same name as in C
@@ -12,50 +14,50 @@
 /* helper to define the type object.
  *
  * This assumes quite a few things about different things being available and their name.
- * For example, if type = Foo, then there should be a deallocation function called Foo_dealloc.
+ * For example, if prefix = foo, then there should be a deallocation function called foo_dealloc.
  * See the macro itself for other examples.
  */
-#define PYSHAPELIB_DEFINE_TYPE(type, name, doc) \
+#define PYSHAPELIB_DEFINE_TYPE(object, prefix, name, doc) \
 { \
 		PyObject_HEAD_INIT(NULL) \
-		0,								/*ob_size*/ \
-		name,							/*tp_name*/ \
-		sizeof(type),					/*tp_basicsize*/ \
-		0,								/*tp_itemsize*/ \
-		(destructor) type ## _dealloc,	/*tp_dealloc*/ \
-		0,								/*tp_print*/ \
-		0,								/*tp_getattr*/ \
-		0,								/*tp_setattr*/ \
-		0,								/*tp_compare*/ \
-		(reprfunc) type ## _repr,		/*tp_repr*/ \
-		0,								/*tp_as_number*/ \
-		0,								/*tp_as_sequence*/ \
-		0,								/*tp_as_mapping*/ \
-		0,								/*tp_hash */ \
-		0,								/*tp_call*/ \
-		0,								/*tp_str*/ \
-		0,								/*tp_getattro*/ \
-		0,								/*tp_setattro*/ \
-		0,								/*tp_as_buffer*/ \
-		Py_TPFLAGS_DEFAULT,				/*tp_flags*/ \
-		doc,							/* tp_doc */ \
-		0,								/* tp_traverse */ \
-		0,								/* tp_clear */ \
-		0,								/* tp_richcompare */ \
-		0,								/* tp_weaklistoffset */ \
-		0,								/* tp_iter */ \
-		0,								/* tp_iternext */ \
-		type ## _methods,				/* tp_methods */ \
-		0,								/* tp_members */ \
-		type ## _getsetters,			/* tp_getset */ \
-		0,								/* tp_base */ \
-		0,								/* tp_dict */ \
-		0,								/* tp_descr_get */ \
-		0,								/* tp_descr_set */ \
-		0,								/* tp_dictoffset */ \
-		(initproc) type ## _init,		/* tp_init */ \
-		0,								/* tp_alloc */ \
-		type ## _new,					/* tp_new */ \
+		0,									/*ob_size*/ \
+		name,								/*tp_name*/ \
+		sizeof(object),						/*tp_basicsize*/ \
+		0,									/*tp_itemsize*/ \
+		(destructor) prefix ## _dealloc,	/*tp_dealloc*/ \
+		0,									/*tp_print*/ \
+		0,									/*tp_getattr*/ \
+		0,									/*tp_setattr*/ \
+		0,									/*tp_compare*/ \
+		(reprfunc) prefix ## _repr,			/*tp_repr*/ \
+		0,									/*tp_as_number*/ \
+		0,									/*tp_as_sequence*/ \
+		0,									/*tp_as_mapping*/ \
+		0,									/*tp_hash */ \
+		0,									/*tp_call*/ \
+		0,									/*tp_str*/ \
+		0,									/*tp_getattro*/ \
+		0,									/*tp_setattro*/ \
+		0,									/*tp_as_buffer*/ \
+		Py_TPFLAGS_DEFAULT,					/*tp_flags*/ \
+		doc,								/* tp_doc */ \
+		0,									/* tp_traverse */ \
+		0,									/* tp_clear */ \
+		0,									/* tp_richcompare */ \
+		0,									/* tp_weaklistoffset */ \
+		0,									/* tp_iter */ \
+		0,									/* tp_iternext */ \
+		prefix ## _methods,					/* tp_methods */ \
+		0,									/* tp_members */ \
+		prefix ## _getsetters,				/* tp_getset */ \
+		0,									/* tp_base */ \
+		0,									/* tp_dict */ \
+		0,									/* tp_descr_get */ \
+		0,									/* tp_descr_set */ \
+		0,									/* tp_dictoffset */ \
+		(initproc) prefix ## _init,			/* tp_init */ \
+		0,									/* tp_alloc */ \
+		prefix ## _new,						/* tp_new */ \
 	} \
 	/**/
 

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py	2007-03-14 16:26:14 UTC (rev 2742)
@@ -48,15 +48,15 @@
         return [("HAVE_UPDATE_HEADER", "0")]
 
 extensions = [Extension("shapelib",
-                        ["shapelib.c",
+                        ["shapelibmodule.c",
                          shp_dir + "/shpopen.c",
                          shp_dir + "/shptree.c"],
                         include_dirs = [shp_dir]),
               Extension("shptree",
                         ["shptreemodule.c"],
                         include_dirs = [shp_dir]),
-              Extension("dbflibc",
-                        ["dbflib_wrap.c",
+              Extension("dbflib",
+                        ["dbflibmodule.c",
                          shp_dir + "/dbfopen.c"],
                         include_dirs = [shp_dir],
                         define_macros = dbf_macros())]
@@ -67,6 +67,5 @@
       author = "Bernhard Herzog",
       author_email = "bh at intevation.de",
       url = "ftp:intevation.de/users/bh",
-      py_modules = ["dbflib"],
       ext_modules = extensions)
 

Deleted: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c	2007-03-14 16:26:14 UTC (rev 2742)
@@ -1,613 +0,0 @@
-#include "shapefil.h"
-#include "pyshapelib_common.h"
-#include "pyshapelib_api.h"
-
-/* --- SHPObject ----------------------------------------------------------------------------------------------------- */
-
-typedef struct
-{
-	PyObject_HEAD
-	SHPObject* shpObject;
-}
-PySHPObject;
-
-/* allocator
- */
-static PyObject* PySHPObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
-	PySHPObject* self;	
-	self = (PySHPObject*) type->tp_alloc(type, 0);
-	self->shpObject = NULL;
-	return (PyObject*) self;
-}
-
-/* deallocator
- */
-static void PySHPObject_dealloc(PySHPObject* self)
-{
-	SHPDestroyObject(self->shpObject);
-	self->shpObject = NULL;
-	self->ob_type->tp_free((PyObject*)self);
-}
-
-/* The constructor of SHPObject. parts is a list of lists of tuples
-* describing the parts and their vertices just likethe output of the
-* vertices() method. part_type_list is the list of part-types and may
-* be NULL. For the meaning of the part-types and their default value
-* see the Shaplib documentation.
-*/
-static int PySHPObject_init(PySHPObject* self, PyObject* args, PyObject* kwds)
-{
-	int type;
-	int id;
-	PyObject* parts = NULL; 
-	PyObject* part_type_list = NULL;
-	
-	int num_parts;
-	int num_vertices;
-	int part_start;
-	
-	double* xs = NULL;
-	double* ys = NULL;
-	int* part_starts = NULL;
-	int* part_types = NULL;
-	
-	int i;
-	int return_code = -1;
-	
-	/* first, unpack parameters */
-	if (kwds != NULL && PyDict_Size(kwds) > 0)
-	{
-		PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
-		return -1;
-	}
-	if (!PyArg_ParseTuple(args, "iiO|O", &type, &id, &parts, &part_type_list)) return -1;
-
-	if (!PySequence_Check(parts))
-	{
-		PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
-		return -1;
-	}
-	num_parts = PySequence_Length(parts);
-	if (num_parts < 0)
-	{
-		PyErr_SetString(PyExc_TypeError, "cannot determine length of parts");
-		return -1;
-	}
-	
-	/* parts and part_types have to have the same lengths */
-	if (part_type_list == Py_None)
-	{
-		Py_DECREF(part_type_list);
-		part_type_list = NULL;
-	}
-	if (part_type_list)
-	{
-		if (!PySequence_Check(parts))
-		{
-			PyErr_SetString(PyExc_TypeError, "part_type_list is not a sequence");
-			return -1;
-		}
-		if (PySequence_Length(part_type_list) != num_parts)
-		{
-			PyErr_SetString(PyExc_TypeError, "parts and part_types have to have the same lengths");
-			return -1;
-		}
-	}
-
-	/* determine how many vertices there are altogether */
-	num_vertices = 0;
-	for (i = 0; i < num_parts; ++i)
-	{
-		PyObject* part = PySequence_ITEM(parts, i);
-		if (!PySequence_Check(part))
-		{
-			PyErr_SetString(PyExc_TypeError, "at least one item in parts is not a sequence");
-			Py_DECREF(part);
-			return -1;
-		}
-		num_vertices += PySequence_Length(part);
-		Py_DECREF(part);
-	}
-
-	/* allocate the memory for the various arrays and check for memory errors */
-	xs = malloc(num_vertices * sizeof(double));
-	ys = malloc(num_vertices * sizeof(double));
-	part_starts = malloc(num_parts * sizeof(int));
-	part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
-
-	if (!xs || !ys || !part_starts || (part_type_list && !part_types))
-	{
-		PyErr_NoMemory();
-		goto exit;
-	}
-
-	/* convert the part types */
-	if (part_type_list)
-	{
-		for (i = 0; i < num_parts; i++)
-		{
-			PyObject* otype = PySequence_ITEM(part_type_list, i);
-			part_types[i] = PyInt_AsLong(otype);
-			Py_DECREF(otype);
-			if (part_types[i] < 0)
-			{
-				PyErr_SetString(PyExc_TypeError, "at least one item in part_type_list is not an integer or is negative");
-				goto exit;
-			}
-		}
-	}
-
-	/* convert the list of parts */
-	part_start = 0;
-	for (i = 0; i < num_parts; ++i)
-	{
-		int j, length;
-		
-		PyObject* part = PySequence_ITEM(parts, i);
-		length = PySequence_Length(part);
-		part_starts[i] = part_start;
-
-		for (j = 0; j < length; ++j)
-		{
-			PyObject* vertex = PySequence_ITEM(part, j);
-			if (!PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j))
-			{
-				PyErr_SetString(PyExc_TypeError, "at least one part contains an vertex that's not a tuple of two doubles");
-				Py_DECREF(vertex);
-				Py_DECREF(part);
-				goto exit;
-			}
-			Py_DECREF(vertex);
-		}
-		Py_DECREF(part);
-		part_start += length;
-	}
-
-	self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, NULL, NULL);
-	return_code = 0;
-	
-exit:
-	free(xs);
-	free(ys);
-	free(part_starts);
-	free(part_types);
-	return return_code;
-}
-
-/*
-* The extents() method of SHPObject.
-*
-* Return the extents as a tuple of two 4-element lists with the min.
-* and max. values of x, y, z, m.
-*/
-static PyObject* PySHPObject_extents(PySHPObject* self)
-{
-	SHPObject* object = self->shpObject;
-	return Py_BuildValue("(dddd)(dddd)",
-			object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin, 
-			object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax);
-}
-
-
-/*
-* The vertices() method of SHPObject.
-*
-* Return the x and y coords of the vertices as a list of lists of
-* tuples.
-*/
-
-static PyObject* build_vertex_list(SHPObject *object, int index, int length);
-
-static PyObject* PySHPObject_vertices(PySHPObject* self)
-{
-	PyObject *result = NULL;
-	PyObject *part = NULL;
-	int part_idx, vertex_idx;
-	int length = 0;
-	SHPObject* object = self->shpObject;
-
-	if (object->nParts > 0)
-	{
-		/* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */
-	
-		result = PyList_New(object->nParts);
-		if (!result)
-			return NULL;
-
-		for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
-		{
-			if (part_idx < object->nParts - 1)
-			length = (object->panPartStart[part_idx + 1]
-				- object->panPartStart[part_idx]);
-			else
-			length = object->nVertices - object->panPartStart[part_idx];
-			
-			part = build_vertex_list(object, vertex_idx, length);
-			if (!part)
-			goto fail;
-
-			if (PyList_SetItem(result, part_idx, part) < 0)
-			goto fail;
-
-			vertex_idx += length;
-		}
-	}
-	else
-	{
-		/* only one part. usual for SHPT_POINT */
-		result = build_vertex_list(object, 0, object->nVertices);
-	}
-
-	return result;
-
-fail:
-	Py_XDECREF(part);
-	Py_DECREF(result);
-	return NULL;
-}
-
-
-/* Return the length coordinates of the shape object starting at vertex
-* index as a Python-list of tuples. Helper function for
-* SHPObject_vertices.
-*/
-static PyObject* build_vertex_list(SHPObject *object, int index, int length)
-{
-	int i;
-	PyObject * list;
-	PyObject * vertex = NULL;
-
-	list = PyList_New(length);
-	if (!list)
-		return NULL;
-
-	for (i = 0; i < length; i++, index++)
-	{
-		vertex = Py_BuildValue("dd", object->padfX[index],
-					object->padfY[index]);
-		if (!vertex)
-			goto fail;
-		if (PyList_SetItem(list, i, vertex) < 0)
-			goto fail;
-	}
-
-	return list;
-
-fail:
-	Py_XDECREF(vertex);
-	Py_DECREF(list);
-	return NULL;
-}
-
-
-
-static PyObject* PySHPObject_part_types(PySHPObject* self)
-{
-	int i;
-	PyObject* result = NULL;
-	SHPObject* object = self->shpObject;
-	
-	if (object->nParts == 0 || object->panPartType == 0)
-	{
-		Py_RETURN_NONE;
-	}
-	
-	result = PyTuple_New(object->nParts);
-	if (!result) return NULL;
-	
-	for (i = 0; i < object->nParts; ++i)
-	{
-		/* PyTuple_SetItem steals a reference */
-		PyObject* part_type = PyInt_FromLong((long)object->panPartType[i]);
-		if (!part_type || PyTuple_SetItem(result, i, part_type) < 0) goto fail;
-	}	
-	return result;
-	
-fail:
-	Py_DECREF(result);
-	return NULL;
-}
-
-
-
-static PyObject* PySHPObject_type(PySHPObject* self, void* closure)
-{
-	return PyInt_FromLong(self->shpObject->nSHPType);
-}
-
-
-
-static PyObject* PySHPObject_id(PySHPObject* self, void* closure)
-{
-	return PyInt_FromLong(self->shpObject->nShapeId);
-}
-
-
-
-/* return a string that can be feeded to eval() to reconstruct the object,
- * assuming a proper context
- */
-static PyObject* PySHPObject_repr(PySHPObject* self)
-{
-	PyObject* format = NULL;
-	PyObject* args = NULL;
-	PyObject* result = NULL;
-	
-	format = PyString_FromString("shapelib.SHPObject(%i, %i, %s, %s)");
-	if (!format) return NULL;
-
-	args = Py_BuildValue("iiNN", 
-		self->shpObject->nSHPType, 
-		self->shpObject->nShapeId,
-		PySHPObject_vertices(self), 
-		PySHPObject_part_types(self));
-	if (!args) 
-	{
-		Py_DECREF(format);
-		return NULL;
-	}
-	
-	result = PyString_Format(format, args);
-	Py_DECREF(args);
-	Py_DECREF(format);
-	return result;
-}
-
-
-
-static PyMethodDef PySHPObject_methods[] = 
-{
-	{"extents", (PyCFunction)PySHPObject_extents, METH_NOARGS, NULL},
-	{"vertices", (PyCFunction)PySHPObject_vertices, METH_NOARGS, NULL},
-	{"part_types", (PyCFunction)PySHPObject_part_types, METH_NOARGS, NULL},
-	{NULL}
-};
-
-static PyGetSetDef PySHPObject_getsetters[] = 
-{
-	{"type", (getter)PySHPObject_type, NULL, NULL },
-	{"id", (getter)PySHPObject_id, NULL, NULL },
-	{NULL}
-};
-
-static PyTypeObject PySHPObjectType = PYSHAPELIB_DEFINE_TYPE(PySHPObject, "shapelib.SHPObject", 0);
-
-
-/* --- ShapeFile ----------------------------------------------------------------------------------------------------- */
-
-typedef struct
-{
-	PyObject_HEAD
-	SHPHandle handle;
-}
-PyShapeFile;
-
-/* allocator 
- */
-static PyObject* PyShapeFile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
-	PyShapeFile* self;	
-	self = (PyShapeFile*) type->tp_alloc(type, 0);
-	self->handle = NULL;
-	return (PyObject*) self;
-}
-
-/* constructor
- */
-static int PyShapeFile_init(PyShapeFile* self, PyObject* args, PyObject* kwds)
-{
-	char* file;
-	char* mode = "rb";
-	if (kwds != NULL && PyDict_Size(kwds) > 0)
-	{
-		PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
-		return -1;
-	}
-	if (!PyArg_ParseTuple(args, "s|s", &file, &mode)) return -1;
-	
-	self->handle = SHPOpen(file, mode);
-	return self->handle ? 0 : -1;
-}
-
-static PyObject* PyShapeFile_close(PyShapeFile* self)
-{
-	SHPClose(self->handle);
-	self->handle = NULL;
-	Py_RETURN_NONE;
-}
-
-/* destructor
- */
-static void PyShapeFile_dealloc(PyShapeFile* self)
-{
-	PyShapeFile_close(self);
-	self->ob_type->tp_free((PyObject*)self);
-}
-
-static PyObject* PyShapeFile_info(PyShapeFile* self)
-{
-	SHPHandle handle = self->handle;
-	return Py_BuildValue("ii(dddd)(dddd)",
-			handle->nRecords, handle->nShapeType,
-			handle->adBoundsMin[0], handle->adBoundsMin[1], handle->adBoundsMin[2], handle->adBoundsMin[3],
-			handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
-}
-
-static PyObject* PyShapeFile_read_object(PyShapeFile* self, PyObject* args)
-{
-	int index;
-	SHPObject* object;
-	PySHPObject* result;
-	
-	if (!PyArg_ParseTuple(args, "i", &index)) return NULL;
-	
-	object = SHPReadObject(self->handle, index);	
-	if (!object)
-	{
-		PyErr_SetString(PyExc_RuntimeError, "failed to read object");
-		return NULL;
-	}
-	
-	result = PyObject_New(PySHPObject, &PySHPObjectType);
-	if (!result)
-	{
-		return PyErr_NoMemory();
-	}
-	
-	result->shpObject = object;
-	return (PyObject*) result;
-}
-
-static PyObject* PyShapeFile_write_object(PyShapeFile* self, PyObject* args)
-{
-	int index, result;
-	PyObject* object;
-	
-	if (!PyArg_ParseTuple(args, "iO", &index, &object)) return NULL;
-	
-	if (!PyObject_IsInstance(object, (PyObject*)&PySHPObjectType))
-	{
-		PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");
-		return NULL;
-	}
-	
-	result = SHPWriteObject(self->handle, index, ((PySHPObject*)object)->shpObject);
-	if (result < 0)
-	{
-		PyErr_SetString(PyExc_RuntimeError, "failed to write object");
-		return NULL;
-	}
-	return PyInt_FromLong((long)result);
-}
-
-static PyObject* PyShapeFile_cobject(PyShapeFile* self)
-{
-	return PyCObject_FromVoidPtr(self->handle, NULL);
-}
-
-static PyObject* PyShapeFile_repr(PyShapeFile* self)
-{
-	/* TODO: it would be nice to do something like "shapelib.ShapeFile(filename, mode)" instead */
-	return PyString_FromFormat("<shapelib.ShapeFile object at %p>", self->handle);
-}
-
-static PyMethodDef PyShapeFile_methods[] = 
-{
-	{"close", (PyCFunction)PyShapeFile_close, METH_NOARGS, "close the shape file" },
-	{"info", (PyCFunction)PyShapeFile_info, METH_NOARGS, 
-		"Return a tuple (NUM_SHAPES, TYPE, MIN, MAX) where NUM_SHAPES is the number of shapes in the file, TYPE is the "
-		"shape type and MIN and MAX are 4-element tuples with the min. and max. values of the data." },
-	{"read_object", (PyCFunction)PyShapeFile_read_object, METH_VARARGS, "Return object number i" },
-	{"write_object", (PyCFunction)PyShapeFile_write_object, METH_VARARGS, "Write an object"},
-	{"cobject", (PyCFunction)PyShapeFile_cobject, METH_NOARGS, "Return the shapelib SHPHandle as a Python CObject"},
-	{NULL}
-};
-
-static PyGetSetDef PyShapeFile_getsetters[] = 
-{
-	{NULL}
-};
-
-static PyTypeObject PyShapeFileType = PYSHAPELIB_DEFINE_TYPE(PyShapeFile, "shapelib.ShapeFile", 0);
-
-/* --- shapelib ------------------------------------------------------------------------------------------------------ */
-
-static PyObject* shapelib_open(PyObject* module, PyObject* args)
-{
-	return PyObject_CallObject((PyObject*)&PyShapeFileType, args);
-}
-
-static PyObject* shapelib_create(PyObject* module, PyObject* args)
-{
-	char* file;
-	int type;
-	PyShapeFile* result;
-	
-	if (!PyArg_ParseTuple(args, "si", &file, &type)) return NULL;
-	
-	result = PyObject_New(PyShapeFile, &PyShapeFileType);
-	if (!result)
-	{
-		return PyErr_NoMemory();
-	}
-	
-	result->handle = SHPCreate(file, type);
-	if (!result->handle)
-	{
-		PyObject_Del((PyObject*)result);
-		PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile");
-		return NULL;
-	}
-	
-	return (PyObject*) result;
-}
-	
-static PyShapeLibAPI shapelib_the_api = 
-{
-	SHPReadObject,
-	SHPDestroyObject,
-	SHPCreateTree,
-	SHPDestroyTree,
-	SHPTreeFindLikelyShapes
-};
-
-static PyObject* shapelib_c_api(PyObject* module) 
-{
-	return PyCObject_FromVoidPtr(&shapelib_the_api, NULL);
-}
-
-static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
-{
-	int type;
-	if (!PyArg_ParseTuple(args, "i", &type)) return NULL;
-	return PyString_FromString(SHPTypeName(type));
-}
-
-static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
-{
-	int type;
-	if (!PyArg_ParseTuple(args, "i", &type)) return NULL;
-	return PyString_FromString(SHPPartTypeName(type));
-}
-
-static PyMethodDef shapelib_methods[] = 
-{
-	{"open", (PyCFunction)shapelib_open, METH_VARARGS, "open a ShapeFile" },
-	{"create", (PyCFunction)shapelib_create, METH_VARARGS, "create a ShapeFile" },
-	{"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, "get C API of shapelib" },
-	{"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, "return type as string" },
-	{"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, "return part type as string" },
-	{NULL}
-};
-
-PyMODINIT_FUNC initshapelib(void)
-{
-	PyObject* module = Py_InitModule("shapelib", shapelib_methods);
-	if (!module) return;
-	
-	PYSHAPELIB_ADD_TYPE(PySHPObjectType, "SHPObject");
-	PYSHAPELIB_ADD_TYPE(PyShapeFileType, "ShapeFile");
-	
-	PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_ARC);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGON);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINT);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_POINTZ);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_ARCZ);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONZ);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTZ);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_POINTM);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_ARCM);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONM);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTM);
-	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPATCH);
-	PYSHAPELIB_ADD_CONSTANT(SHPP_TRISTRIP);
-	PYSHAPELIB_ADD_CONSTANT(SHPP_TRIFAN);
-	PYSHAPELIB_ADD_CONSTANT(SHPP_OUTERRING);
-	PYSHAPELIB_ADD_CONSTANT(SHPP_INNERRING);
-	PYSHAPELIB_ADD_CONSTANT(SHPP_FIRSTRING);
-	PYSHAPELIB_ADD_CONSTANT(SHPP_RING);
-}
-

Copied: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c (from rev 2741, branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c)
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c	2007-03-14 16:26:14 UTC (rev 2742)
@@ -0,0 +1,611 @@
+#include "pyshapelib_common.h"
+
+/* --- SHPObject ----------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+	PyObject_HEAD
+	SHPObject* shpObject;
+}
+SHPObjectObject;
+
+/* allocator
+ */
+static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+	SHPObjectObject* self;	
+	self = (SHPObjectObject*) type->tp_alloc(type, 0);
+	self->shpObject = NULL;
+	return (PyObject*) self;
+}
+
+/* deallocator
+ */
+static void shpobject_dealloc(SHPObjectObject* self)
+{
+	SHPDestroyObject(self->shpObject);
+	self->shpObject = NULL;
+	self->ob_type->tp_free((PyObject*)self);
+}
+
+/* The constructor of SHPObject. parts is a list of lists of tuples
+* describing the parts and their vertices just likethe output of the
+* vertices() method. part_type_list is the list of part-types and may
+* be NULL. For the meaning of the part-types and their default value
+* see the Shaplib documentation.
+*/
+static int shpobject_init(SHPObjectObject* self, PyObject* args, PyObject* kwds)
+{
+	int type;
+	int id;
+	PyObject* parts = NULL; 
+	PyObject* part_type_list = NULL;
+	
+	int num_parts;
+	int num_vertices;
+	int part_start;
+	
+	double* xs = NULL;
+	double* ys = NULL;
+	int* part_starts = NULL;
+	int* part_types = NULL;
+	
+	int i;
+	int return_code = -1;
+	
+	/* first, unpack parameters */
+	if (kwds != NULL && PyDict_Size(kwds) > 0)
+	{
+		PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
+		return -1;
+	}
+	if (!PyArg_ParseTuple(args, "iiO|O", &type, &id, &parts, &part_type_list)) return -1;
+
+	if (!PySequence_Check(parts))
+	{
+		PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
+		return -1;
+	}
+	num_parts = PySequence_Length(parts);
+	if (num_parts < 0)
+	{
+		PyErr_SetString(PyExc_TypeError, "cannot determine length of parts");
+		return -1;
+	}
+	
+	/* parts and part_types have to have the same lengths */
+	if (part_type_list == Py_None)
+	{
+		Py_DECREF(part_type_list);
+		part_type_list = NULL;
+	}
+	if (part_type_list)
+	{
+		if (!PySequence_Check(parts))
+		{
+			PyErr_SetString(PyExc_TypeError, "part_type_list is not a sequence");
+			return -1;
+		}
+		if (PySequence_Length(part_type_list) != num_parts)
+		{
+			PyErr_SetString(PyExc_TypeError, "parts and part_types have to have the same lengths");
+			return -1;
+		}
+	}
+
+	/* determine how many vertices there are altogether */
+	num_vertices = 0;
+	for (i = 0; i < num_parts; ++i)
+	{
+		PyObject* part = PySequence_ITEM(parts, i);
+		if (!PySequence_Check(part))
+		{
+			PyErr_SetString(PyExc_TypeError, "at least one item in parts is not a sequence");
+			Py_DECREF(part);
+			return -1;
+		}
+		num_vertices += PySequence_Length(part);
+		Py_DECREF(part);
+	}
+
+	/* allocate the memory for the various arrays and check for memory errors */
+	xs = malloc(num_vertices * sizeof(double));
+	ys = malloc(num_vertices * sizeof(double));
+	part_starts = malloc(num_parts * sizeof(int));
+	part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
+
+	if (!xs || !ys || !part_starts || (part_type_list && !part_types))
+	{
+		PyErr_NoMemory();
+		goto exit;
+	}
+
+	/* convert the part types */
+	if (part_type_list)
+	{
+		for (i = 0; i < num_parts; i++)
+		{
+			PyObject* otype = PySequence_ITEM(part_type_list, i);
+			part_types[i] = PyInt_AsLong(otype);
+			Py_DECREF(otype);
+			if (part_types[i] < 0)
+			{
+				PyErr_SetString(PyExc_TypeError, "at least one item in part_type_list is not an integer or is negative");
+				goto exit;
+			}
+		}
+	}
+
+	/* convert the list of parts */
+	part_start = 0;
+	for (i = 0; i < num_parts; ++i)
+	{
+		int j, length;
+		
+		PyObject* part = PySequence_ITEM(parts, i);
+		length = PySequence_Length(part);
+		part_starts[i] = part_start;
+
+		for (j = 0; j < length; ++j)
+		{
+			PyObject* vertex = PySequence_ITEM(part, j);
+			if (!PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j))
+			{
+				PyErr_SetString(PyExc_TypeError, "at least one part contains an vertex that's not a tuple of two doubles");
+				Py_DECREF(vertex);
+				Py_DECREF(part);
+				goto exit;
+			}
+			Py_DECREF(vertex);
+		}
+		Py_DECREF(part);
+		part_start += length;
+	}
+
+	self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, NULL, NULL);
+	return_code = 0;
+	
+exit:
+	free(xs);
+	free(ys);
+	free(part_starts);
+	free(part_types);
+	return return_code;
+}
+
+/*
+* The extents() method of SHPObject.
+*
+* Return the extents as a tuple of two 4-element lists with the min.
+* and max. values of x, y, z, m.
+*/
+static PyObject* shpobject_extents(SHPObjectObject* self)
+{
+	SHPObject* object = self->shpObject;
+	return Py_BuildValue("(dddd)(dddd)",
+			object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin, 
+			object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax);
+}
+
+
+/*
+* The vertices() method of SHPObject.
+*
+* Return the x and y coords of the vertices as a list of lists of
+* tuples.
+*/
+
+static PyObject* build_vertex_list(SHPObject *object, int index, int length);
+
+static PyObject* shpobject_vertices(SHPObjectObject* self)
+{
+	PyObject *result = NULL;
+	PyObject *part = NULL;
+	int part_idx, vertex_idx;
+	int length = 0;
+	SHPObject* object = self->shpObject;
+
+	if (object->nParts > 0)
+	{
+		/* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */
+	
+		result = PyList_New(object->nParts);
+		if (!result)
+			return NULL;
+
+		for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
+		{
+			if (part_idx < object->nParts - 1)
+			length = (object->panPartStart[part_idx + 1]
+				- object->panPartStart[part_idx]);
+			else
+			length = object->nVertices - object->panPartStart[part_idx];
+			
+			part = build_vertex_list(object, vertex_idx, length);
+			if (!part)
+			goto fail;
+
+			if (PyList_SetItem(result, part_idx, part) < 0)
+			goto fail;
+
+			vertex_idx += length;
+		}
+	}
+	else
+	{
+		/* only one part. usual for SHPT_POINT */
+		result = build_vertex_list(object, 0, object->nVertices);
+	}
+
+	return result;
+
+fail:
+	Py_XDECREF(part);
+	Py_DECREF(result);
+	return NULL;
+}
+
+
+/* Return the length coordinates of the shape object starting at vertex
+* index as a Python-list of tuples. Helper function for
+* SHPObject_vertices.
+*/
+static PyObject* build_vertex_list(SHPObject *object, int index, int length)
+{
+	int i;
+	PyObject * list;
+	PyObject * vertex = NULL;
+
+	list = PyList_New(length);
+	if (!list)
+		return NULL;
+
+	for (i = 0; i < length; i++, index++)
+	{
+		vertex = Py_BuildValue("dd", object->padfX[index],
+					object->padfY[index]);
+		if (!vertex)
+			goto fail;
+		if (PyList_SetItem(list, i, vertex) < 0)
+			goto fail;
+	}
+
+	return list;
+
+fail:
+	Py_XDECREF(vertex);
+	Py_DECREF(list);
+	return NULL;
+}
+
+
+
+static PyObject* shpobject_part_types(SHPObjectObject* self)
+{
+	int i;
+	PyObject* result = NULL;
+	SHPObject* object = self->shpObject;
+	
+	if (object->nParts == 0 || object->panPartType == 0)
+	{
+		Py_RETURN_NONE;
+	}
+	
+	result = PyTuple_New(object->nParts);
+	if (!result) return NULL;
+	
+	for (i = 0; i < object->nParts; ++i)
+	{
+		/* PyTuple_SetItem steals a reference */
+		PyObject* part_type = PyInt_FromLong((long)object->panPartType[i]);
+		if (!part_type || PyTuple_SetItem(result, i, part_type) < 0) goto fail;
+	}	
+	return result;
+	
+fail:
+	Py_DECREF(result);
+	return NULL;
+}
+
+
+
+static PyObject* shpobject_type(SHPObjectObject* self, void* closure)
+{
+	return PyInt_FromLong(self->shpObject->nSHPType);
+}
+
+
+
+static PyObject* shpobject_id(SHPObjectObject* self, void* closure)
+{
+	return PyInt_FromLong(self->shpObject->nShapeId);
+}
+
+
+
+/* return a string that can be feeded to eval() to reconstruct the object,
+ * assuming a proper context
+ */
+static PyObject* shpobject_repr(SHPObjectObject* self)
+{
+	PyObject* format = NULL;
+	PyObject* args = NULL;
+	PyObject* result = NULL;
+	
+	format = PyString_FromString("shapelib.SHPObject(%i, %i, %s, %s)");
+	if (!format) return NULL;
+
+	args = Py_BuildValue("iiNN", 
+		self->shpObject->nSHPType, 
+		self->shpObject->nShapeId,
+		shpobject_vertices(self), 
+		shpobject_part_types(self));
+	if (!args) 
+	{
+		Py_DECREF(format);
+		return NULL;
+	}
+	
+	result = PyString_Format(format, args);
+	Py_DECREF(args);
+	Py_DECREF(format);
+	return result;
+}
+
+
+
+static struct PyMethodDef shpobject_methods[] = 
+{
+	{"extents", (PyCFunction)shpobject_extents, METH_NOARGS, NULL},
+	{"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS, NULL},
+	{"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS, NULL},
+	{NULL}
+};
+
+static struct PyGetSetDef shpobject_getsetters[] = 
+{
+	{"type", (getter)shpobject_type, NULL, NULL },
+	{"id", (getter)shpobject_id, NULL, NULL },
+	{NULL}
+};
+
+static PyTypeObject SHPObjectType = PYSHAPELIB_DEFINE_TYPE(SHPObjectObject, shpobject, "shapelib.SHPObject", 0);
+
+
+/* --- ShapeFile ----------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+	PyObject_HEAD
+	SHPHandle handle;
+}
+ShapeFileObject;
+
+/* allocator 
+ */
+static PyObject* shapefile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+	ShapeFileObject* self;	
+	self = (ShapeFileObject*) type->tp_alloc(type, 0);
+	self->handle = NULL;
+	return (PyObject*) self;
+}
+
+/* destructor
+*/
+static void shapefile_dealloc(ShapeFileObject* self)
+{
+	SHPClose(self->handle);
+	self->ob_type->tp_free((PyObject*)self);
+}
+
+/* constructor
+ */
+static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds)
+{
+	char* file;
+	char* mode = "rb";
+	if (kwds != NULL && PyDict_Size(kwds) > 0)
+	{
+		PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
+		return -1;
+	}
+	if (!PyArg_ParseTuple(args, "s|s", &file, &mode)) return -1;
+	
+	self->handle = SHPOpen(file, mode);
+	return self->handle ? 0 : -1;
+}
+
+static PyObject* shapefile_close(ShapeFileObject* self)
+{
+	SHPClose(self->handle);
+	self->handle = NULL;
+	Py_RETURN_NONE;
+}
+
+static PyObject* shapefile_info(ShapeFileObject* self)
+{
+	SHPHandle handle = self->handle;
+	return Py_BuildValue("ii(dddd)(dddd)",
+			handle->nRecords, handle->nShapeType,
+			handle->adBoundsMin[0], handle->adBoundsMin[1], handle->adBoundsMin[2], handle->adBoundsMin[3],
+			handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
+}
+
+static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args)
+{
+	int index;
+	SHPObject* object;
+	SHPObjectObject* result;
+	
+	if (!PyArg_ParseTuple(args, "i", &index)) return NULL;
+	
+	object = SHPReadObject(self->handle, index);	
+	if (!object)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "failed to read object");
+		return NULL;
+	}
+	
+	result = PyObject_New(SHPObjectObject, &SHPObjectType);
+	if (!result)
+	{
+		return PyErr_NoMemory();
+	}
+	
+	result->shpObject = object;
+	return (PyObject*) result;
+}
+
+static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args)
+{
+	int index, result;
+	PyObject* object;
+	
+	if (!PyArg_ParseTuple(args, "iO", &index, &object)) return NULL;
+	
+	if (!PyObject_IsInstance(object, (PyObject*)&SHPObjectType))
+	{
+		PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");
+		return NULL;
+	}
+	
+	result = SHPWriteObject(self->handle, index, ((SHPObjectObject*)object)->shpObject);
+	if (result < 0)
+	{
+		PyErr_SetString(PyExc_RuntimeError, "failed to write object");
+		return NULL;
+	}
+	return PyInt_FromLong((long)result);
+}
+
+static PyObject* shapefile_cobject(ShapeFileObject* self)
+{
+	return PyCObject_FromVoidPtr(self->handle, NULL);
+}
+
+static PyObject* shapefile_repr(ShapeFileObject* self)
+{
+	/* TODO: it would be nice to do something like "shapelib.ShapeFile(filename, mode)" instead */
+	return PyString_FromFormat("<shapelib.ShapeFile object at %p>", self->handle);
+}
+
+static struct PyMethodDef shapefile_methods[] = 
+{
+	{"close", (PyCFunction)shapefile_close, METH_NOARGS, "close the shape file" },
+	{"info", (PyCFunction)shapefile_info, METH_NOARGS, 
+		"Return a tuple (NUM_SHAPES, TYPE, MIN, MAX) where NUM_SHAPES is the number of shapes in the file, TYPE is the "
+		"shape type and MIN and MAX are 4-element tuples with the min. and max. values of the data." },
+	{"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS, "Return object number i" },
+	{"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS, "Write an object"},
+	{"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS, "Return the shapelib SHPHandle as a Python CObject"},
+	{NULL}
+};
+
+static struct PyGetSetDef shapefile_getsetters[] = 
+{
+	{NULL}
+};
+
+static PyTypeObject ShapeFileType = PYSHAPELIB_DEFINE_TYPE(ShapeFileObject, shapefile, "shapelib.ShapeFile", 0);
+
+/* --- shapelib ------------------------------------------------------------------------------------------------------ */
+
+static PyObject* shapelib_open(PyObject* module, PyObject* args)
+{
+	return PyObject_CallObject((PyObject*)&ShapeFileType, args);
+}
+
+static PyObject* shapelib_create(PyObject* module, PyObject* args)
+{
+	char* file;
+	int type;
+	ShapeFileObject* result;
+	
+	if (!PyArg_ParseTuple(args, "si", &file, &type)) return NULL;
+	
+	result = PyObject_New(ShapeFileObject, &ShapeFileType);
+	if (!result)
+	{
+		return PyErr_NoMemory();
+	}
+	
+	result->handle = SHPCreate(file, type);
+	if (!result->handle)
+	{
+		PyObject_Del((PyObject*)result);
+		PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile");
+		return NULL;
+	}
+	
+	return (PyObject*) result;
+}
+	
+static PyShapeLibAPI shapelib_the_api = 
+{
+	SHPReadObject,
+	SHPDestroyObject,
+	SHPCreateTree,
+	SHPDestroyTree,
+	SHPTreeFindLikelyShapes
+};
+
+static PyObject* shapelib_c_api(PyObject* module) 
+{
+	return PyCObject_FromVoidPtr(&shapelib_the_api, NULL);
+}
+
+static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
+{
+	int type;
+	if (!PyArg_ParseTuple(args, "i", &type)) return NULL;
+	return PyString_FromString(SHPTypeName(type));
+}
+
+static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
+{
+	int type;
+	if (!PyArg_ParseTuple(args, "i", &type)) return NULL;
+	return PyString_FromString(SHPPartTypeName(type));
+}
+
+static struct PyMethodDef shapelib_methods[] = 
+{
+	{"open", (PyCFunction)shapelib_open, METH_VARARGS, "open a ShapeFile" },
+	{"create", (PyCFunction)shapelib_create, METH_VARARGS, "create a ShapeFile" },
+	{"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, "get C API of shapelib" },
+	{"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, "return type as string" },
+	{"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, "return part type as string" },
+	{NULL}
+};
+
+PyMODINIT_FUNC initshapelib(void)
+{
+	PyObject* module = Py_InitModule("shapelib", shapelib_methods);
+	if (!module) return;
+	
+	PYSHAPELIB_ADD_TYPE(SHPObjectType, "SHPObject");
+	PYSHAPELIB_ADD_TYPE(ShapeFileType, "ShapeFile");
+	
+	PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_ARC);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGON);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINT);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_POINTZ);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_ARCZ);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONZ);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTZ);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_POINTM);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_ARCM);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONM);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTM);
+	PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPATCH);
+	PYSHAPELIB_ADD_CONSTANT(SHPP_TRISTRIP);
+	PYSHAPELIB_ADD_CONSTANT(SHPP_TRIFAN);
+	PYSHAPELIB_ADD_CONSTANT(SHPP_OUTERRING);
+	PYSHAPELIB_ADD_CONSTANT(SHPP_INNERRING);
+	PYSHAPELIB_ADD_CONSTANT(SHPP_FIRSTRING);
+	PYSHAPELIB_ADD_CONSTANT(SHPP_RING);
+}
+

Modified: branches/WIP-pyshapelib-bramz/setup.py
===================================================================
--- branches/WIP-pyshapelib-bramz/setup.py	2007-03-13 23:30:41 UTC (rev 2741)
+++ branches/WIP-pyshapelib-bramz/setup.py	2007-03-14 16:26:14 UTC (rev 2742)
@@ -270,21 +270,20 @@
 #
 
 extensions.append(Extension("Lib.shapelib",
-                            [ext_dir + "/pyshapelib/shapelib.c",
+                            [ext_dir + "/pyshapelib/shapelibmodule.c",
                              shp_dir + "/shpopen.c",
                              shp_dir + "/shptree.c"],
                             include_dirs = [shp_dir]))
 extensions.append(Extension("Lib.shptree",
                             [ext_dir + "/pyshapelib/shptreemodule.c"],
                             include_dirs = [shp_dir]))
-extensions.append(Extension("Lib.dbflibc",
-                            [ext_dir + "/pyshapelib/dbflib_wrap.c",
+extensions.append(Extension("Lib.dbflib",
+                            [ext_dir + "/pyshapelib/dbflibmodule.c",
                              shp_dir + "/dbfopen.c"],
                             include_dirs = [shp_dir],
                             define_macros = [("HAVE_UPDATE_HEADER", "1")]))
-for name in ("shapelib", "dbflib"):
-    py_modules.append(ext_dir + "/pyshapelib/" + name)
 
+
 #
 # PROJ4 bindings are also distributed with thuban
 #



More information about the Thuban-commits mailing list