/[thuban]/branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1611 by jan, Tue Aug 19 21:24:20 2003 UTC revision 2212 by bh, Mon May 17 15:47:57 2004 UTC
# Line 25  Line 25 
25  %{  %{
26  #include "shapefil.h"  #include "shapefil.h"
27    
28    
29    /* Read one attribute from the dbf handle and return it as a new python object
30     *
31     * If an error occurs, set the appropriate Python exception and return
32     * NULL.
33     *
34     * Assume that the values of the record and field arguments are valid.
35     * The name argument will be passed to DBFGetFieldInfo as is and should
36     * thus be either NULL or a pointer to an array of at least 12 chars
37     */
38    static PyObject *
39    do_read_attribute(DBFInfo * handle, int record, int field, char * name)
40    {
41        int type, width;
42        PyObject *value;
43    
44        type = DBFGetFieldInfo(handle, field, name, &width, NULL);
45        /* For strings NULL and the empty string are indistinguishable
46         * in DBF files. We prefer empty strings instead for backwards
47         * compatibility reasons because older wrapper versions returned
48         * emtpy strings as empty strings.
49         */
50        if (type != FTString && DBFIsAttributeNULL(handle, record, field))
51        {
52            value = Py_None;
53            Py_INCREF(value);
54        }
55        else
56        {
57            switch (type)
58            {
59            case FTString:
60            {
61                const char * temp = DBFReadStringAttribute(handle, record, field);
62                if (temp)
63                {
64                    value = PyString_FromString(temp);
65                }
66                else
67                {
68                    PyErr_Format(PyExc_IOError,
69                                 "Can't read value for row %d column %d",
70                                 record, field);
71                    value = NULL;
72                }
73                break;
74            }
75            case FTInteger:
76                value = PyInt_FromLong(DBFReadIntegerAttribute(handle, record,
77                                                               field));
78                break;
79            case FTDouble:
80                value = PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record,
81                                                                  field));
82                break;
83            default:
84                PyErr_Format(PyExc_TypeError, "Invalid field data type %d",
85                             type);
86                value = NULL;
87            }
88        }
89        if (!value)
90            return NULL;
91    
92        return value;
93    }    
94    
95    /* the read_attribute method. Return the value of the given record and
96     * field as a python object of the appropriate type.
97     *
98     * In case of error, set a python exception and return NULL. Since that
99     * value will be returned to the python interpreter as is, the
100     * interpreter should recognize the exception.
101     */
102    
103    static PyObject *
104    DBFInfo_read_attribute(DBFInfo * handle, int record, int field)
105    {
106        if (record < 0 || record >= DBFGetRecordCount(handle))
107        {
108            PyErr_Format(PyExc_ValueError,
109                         "record index %d out of bounds (record count: %d)",
110                         record, DBFGetRecordCount(handle));
111            return NULL;
112        }
113    
114        if (field < 0 || field >= DBFGetFieldCount(handle))
115        {
116            PyErr_Format(PyExc_ValueError,
117                         "field index %d out of bounds (field count: %d)",
118                         field, DBFGetFieldCount(handle));
119            return NULL;
120        }
121    
122        return do_read_attribute(handle, record, field, NULL);
123    }
124        
125    
126  /* the read_record method. Return the record record as a dictionary with  /* the read_record method. Return the record record as a dictionary with
127   * whose keys are the names of the fields, and their values as the   * whose keys are the names of the fields, and their values as the
128   * appropriate Python type.   * appropriate Python type.
# Line 59  DBFInfo_read_record(DBFInfo * handle, in Line 157  DBFInfo_read_record(DBFInfo * handle, in
157      num_fields = DBFGetFieldCount(handle);      num_fields = DBFGetFieldCount(handle);
158      for (i = 0; i < num_fields; i++)      for (i = 0; i < num_fields; i++)
159      {      {
160          type = DBFGetFieldInfo(handle, i, name, &width, NULL);          value = do_read_attribute(handle, record, i, name);
         /* 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, i))  
         {  
             value = Py_None;  
             Py_INCREF(value);  
         }  
         else  
         {  
             switch (type)  
             {  
             case FTString:  
             {  
                 const char * temp = DBFReadStringAttribute(handle, record, i);  
                 if (temp)  
                 {  
                     value = PyString_FromString(temp);  
                 }  
                 else  
                 {  
                     PyErr_Format(PyExc_IOError,  
                                  "Can't read value for row %d column %d",  
                                  record, i);  
                     value = NULL;  
                 }  
                 break;  
             }  
             case FTInteger:  
                 value = PyInt_FromLong(DBFReadIntegerAttribute(handle, record,  
                                                                i));  
                 break;  
             case FTDouble:  
                 value = PyFloat_FromDouble(DBFReadDoubleAttribute(handle,  
                                                                   record, i));  
                 break;  
             default:  
                 PyErr_Format(PyExc_TypeError, "Invalid field data type %d",  
                              type);  
                 value = NULL;  
             }  
         }  
161          if (!value)          if (!value)
162              goto fail;              goto fail;
163    
164          PyDict_SetItemString(dict, name, value);          PyDict_SetItemString(dict, name, value);
165          Py_DECREF(value);          Py_DECREF(value);
166      }      }
167    
168      return dict;      return dict;
169    
170   fail:   fail:
171      Py_XDECREF(dict);      Py_XDECREF(dict);
172      return NULL;      return NULL;
# Line 289  DBFInfo_write_record(DBFHandle handle, i Line 345  DBFInfo_write_record(DBFHandle handle, i
345  %}  %}
346    
347    
348    /* The commit method implementation
349     *
350     * The method relies on the DBFUpdateHeader method which is not
351     * available in shapelib <= 1.2.10.  setup.py defines
352     * HAVE_UPDATE_HEADER's value depending on whether the function is
353     * available in the shapelib version the code is compiled with.
354     */
355    %{
356    static
357    void
358    DBFInfo_commit(DBFHandle handle)
359    {
360    #if HAVE_UPDATE_HEADER
361        DBFUpdateHeader(handle);
362    #endif
363    }
364    %}
365    
366    
367  /*  /*
368   * The SWIG Interface definition.   * The SWIG Interface definition.
369   */   */
# Line 356  DBFInfo_write_record(DBFHandle handle, i Line 431  DBFInfo_write_record(DBFHandle handle, i
431      }      }
432  }  }
433    
434    /* Exception handler for the add_field method */
435    %typemap(python,except) int DBFFile_add_field {
436        $function;
437        if ($source < 0)
438        {
439            SWIG_exception(SWIG_RuntimeError, "add_field failed");
440        }
441    }
442    
443  /* define and use some typemaps for the field_info() method whose  /* define and use some typemaps for the field_info() method whose
444   * C-implementation has three output parameters that are returned   * C-implementation has three output parameters that are returned
# Line 423  typedef        struct Line 506  typedef        struct
506              return DBFInfo_read_record(self->handle, record);              return DBFInfo_read_record(self->handle, record);
507          }          }
508    
509            PyObject * read_attribute(int record, int field) {
510                return DBFInfo_read_attribute(self->handle, record, field);
511            }
512    
513          int add_field(const char * pszFieldName, DBFFieldType eType,          int add_field(const char * pszFieldName, DBFFieldType eType,
514                        int nWidth, int nDecimals) {                        int nWidth, int nDecimals) {
515              return DBFAddField(self->handle, pszFieldName, eType, nWidth,              return DBFAddField(self->handle, pszFieldName, eType, nWidth,
# Line 434  typedef        struct Line 521  typedef        struct
521                                          dict_or_sequence);                                          dict_or_sequence);
522          }          }
523    
524          int commit() {          void commit() {
525              return DBFCommit(self->handle);              DBFInfo_commit(self->handle);
526          }          }
527            /* Delete the commit method from the class if it doesn't have a
528             * real implementation.
529             */
530            %pragma(python) addtomethod="__class__:if not dbflibc._have_commit: del commit"
531    
532      }      }
533  } DBFFile;  } DBFFile;
# Line 482  typedef enum { Line 573  typedef enum {
573    FTDouble,    FTDouble,
574    FTInvalid    FTInvalid
575  } DBFFieldType;  } DBFFieldType;
576    
577    
578    /* Put the value of the HAVE_UPDATE_HEADER preprocessor macro into the
579     * wrapper so that the __class__ pragma above knows when to remove the
580     * commit method
581     */
582    const int _have_commit = HAVE_UPDATE_HEADER;
583    

Legend:
Removed from v.1611  
changed lines
  Added in v.2212

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26