/[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 2744 by bramz, Thu Mar 15 13:48:58 2007 UTC revision 2753 by bramz, Wed Apr 11 18:57:04 2007 UTC
# Line 1  Line 1 
1    /* Copyright (c) 2001, 2002, 2007 by Intevation GmbH
2     * Authors:
3     * Bram de Greve <[email protected]>
4     * Bernhard Herzog <[email protected]>
5     *
6     * This program is free software under the GPL (>=v2)
7     * Read the file COPYING coming with Thuban for details.
8     */
9    
10  #include "pyshapelib_common.h"  #include "pyshapelib_common.h"
11    
12    /* UNICODE & LANGUAGE DRIVER SUPPORT FOR DBFLIB
13     *
14     * When writing Unicode objects to a dbflib database, the unicode has to be
15     * encoded in 8-bit characters using a code page.  This code page is indentified
16     * by the Language Driver ID (LDID) field in the database header.
17     *
18     * At this moment, this need unofficial modifications of the maptools shapelib
19     * library because they do not read the LDID.  No patch has been submitted yet,
20     * but the version contained in the Thuban source tree incorporates the required
21     * modifications.
22     *
23     * pyshapelib is designed to compile with either the patched or unpatched shapelib
24     * by defining HAVE_LANGUAGE_DRIVER as true or false respectively.  In the latter
25     * case, a Windows ANSI code page (cp1252) is assumed
26     */
27     #if HAVE_LANGUAGE_DRIVER
28    
29    #define PYSHAPELIB_NUM_LANGUAGE_DRIVERS 256
30    
31    #define PYSHAPELIB_ADD_LANGUAGE_DRIVER(ldid, codec, name)\
32            codecs[ldid] = codec;\
33            drivers[ldid] = "LDID_" name;\
34            PyModule_AddIntConstant(module, "LDID_" name, ldid)
35    
36    static char* codecs[PYSHAPELIB_NUM_LANGUAGE_DRIVERS];
37    static char* drivers[PYSHAPELIB_NUM_LANGUAGE_DRIVERS];
38    
39    #endif
40    
41    
42    
43    /** Determine name of Python's built-in codec
44     */
45    static char* get_codec(DBFHandle handle)
46    {
47    #if HAVE_LANGUAGE_DRIVER
48            if (!codecs[handle->nLanguageDriver])
49            {
50                    PyErr_Format(PyExc_ValueError, "Language Driver ID %d not recognized", handle->nLanguageDriver);
51            }
52            return codecs[handle->nLanguageDriver];
53    #else
54            return "cp1252";
55    #endif
56    }
57    
58    
59    
60    /** decode to unicode object
61     */
62    static PyObject* decode_string(DBFHandle handle, const char* string)
63    {
64            char* codec = get_codec(handle);
65            if (!codec) return NULL;
66            return PyUnicode_Decode(string, strlen(string), codec, NULL);
67    }
68    
69    /** encode unicode object to normal Python string object
70     */
71    static PyObject* encode_string(DBFHandle handle, PyObject* string)
72    {
73            char* codec = get_codec(handle);
74            if (!codec) return NULL;
75    
76            if (PyString_Check(string))
77            {
78                    return PyString_AsEncodedObject(string, codec, NULL);
79            }
80            if (PyUnicode_Check(string))
81            {
82                    return PyUnicode_AsEncodedString(string, codec, NULL);
83            }
84    
85            PyErr_SetString(PyExc_TypeError, "value is neither a string or unicode object");
86            return NULL;
87    }
88    
89    
90    
91  /* --- DBFFile ------------------------------------------------------------------------------------------------------- */  /* --- DBFFile ------------------------------------------------------------------------------------------------------- */
92    
93  typedef struct {  typedef struct {
# Line 36  static void dbffile_dealloc(DBFFileObjec Line 124  static void dbffile_dealloc(DBFFileObjec
124  */  */
125  static int dbffile_init(DBFFileObject* self, PyObject* args, PyObject* kwds)  static int dbffile_init(DBFFileObject* self, PyObject* args, PyObject* kwds)
126  {  {
127          char* file;          char* file = NULL;
128          char* mode = "rb";          char* mode = "rb";
129          if (kwds != NULL && PyDict_Size(kwds) > 0)          static char *kwlist[] = {"name", "mode", NULL};
130    
131            DBFClose(self->handle);
132            self->handle = NULL;
133    
134    #if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
135            if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
136                    PyObject *wfile;
137                    if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:DBFFile", kwlist, &wfile, &mode))
138                    {
139                            PyObject *wmode = PyUnicode_DecodeASCII(mode, strlen(mode), NULL);
140                            if (!wmode) return -1;
141                            self->handle = DBFOpenW(PyUnicode_AS_UNICODE(wfile), PyUnicode_AS_UNICODE(wmode));
142                            Py_DECREF(wmode);
143                            if (!self->handle)
144                            {
145                                    PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
146                                    return -1;
147                            }
148                    }
149                    else
150                    {
151                            /* Drop the argument parsing error as narrow
152                               strings are also valid. */
153                            PyErr_Clear();
154                    }
155            }
156    #endif
157    
158            if (!self->handle)
159          {          {
160                  PyErr_Format(PyExc_TypeError, "dbflib.DBFFile.__init__ takes no keyword arguments");                  if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:DBFFile", kwlist,
161                  return -1;                          Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
162                    self->handle = DBFOpen(file, mode);
163    
164                    if (!self->handle)
165                    {
166                            PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
167                            PyMem_Free(file);
168                            return -1;
169                    }
170    
171                    PyMem_Free(file);
172          }          }
173    
174          if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1;          return 0;
           
         self->handle = DBFOpen(file, mode);  
         PyMem_Free(file);  
           
         return self->handle ? 0 : -1;  
175  }  }
176    
177    
# Line 81  static PyObject* dbffile_field_info(DBFF Line 203  static PyObject* dbffile_field_info(DBFF
203  {  {
204          char field_name[12];          char field_name[12];
205          int field, width = 0, decimals = 0, field_type;          int field, width = 0, decimals = 0, field_type;
206            PyObject* name_object = NULL;
207                    
208          if (!PyArg_ParseTuple(args, "i:field_info", &field)) return NULL;          if (!PyArg_ParseTuple(args, "i:field_info", &field)) return NULL;
209                    
210          field_name[0] = '\0';          field_name[0] = '\0';
211          field_type = DBFGetFieldInfo(self->handle, field, field_name, &width, &decimals);          field_type = DBFGetFieldInfo(self->handle, field, field_name, &width, &decimals);
212            name_object = decode_string(self->handle, field_name);
213                    
214          return Py_BuildValue("isii", field_type, field_name, width, decimals);          return Py_BuildValue("iOii", field_type, name_object, width, decimals);
215  }  }
216    
217    
218    
219  static PyObject* dbffile_add_field(DBFFileObject* self, PyObject* args)  static PyObject* dbffile_add_field(DBFFileObject* self, PyObject* args)
220  {  {
221          char* name;          PyObject *oname = NULL, *name = NULL;
222          int type, width, decimals;          int type, width, decimals;
223          int field;          int field;
224                    
225          if (!PyArg_ParseTuple(args, "siii:add_field", &name, &type, &width, &decimals)) return NULL;          if (!PyArg_ParseTuple(args, "Uiii:add_field", &oname, &type, &width, &decimals)
226                    && !PyArg_ParseTuple(args, "Siii:add_field", &oname, &type, &width, &decimals)) return NULL;
227                    
228          field = DBFAddField(self->handle, name, (DBFFieldType)type, width, decimals);          name = encode_string(self->handle, oname);
229            if (!name) return NULL;
230    
231            field = DBFAddField(self->handle, PyString_AsString(name), (DBFFieldType)type, width, decimals);
232            Py_DECREF(name);
233                    
234          if (field < 0)          if (field < 0)
235          {          {
# Line 124  static PyObject* dbffile_add_field(DBFFi Line 253  static PyObject* dbffile_add_field(DBFFi
253  static PyObject* do_read_attribute(DBFHandle handle, int record, int field, char * name)  static PyObject* do_read_attribute(DBFHandle handle, int record, int field, char * name)
254  {  {
255          int type, width;          int type, width;
256          const char* temp;          const char* string;
257          type = DBFGetFieldInfo(handle, field, name, &width, NULL);          type = DBFGetFieldInfo(handle, field, name, &width, NULL);
258                    
259          /* For strings NULL and the empty string are indistinguishable          /* For strings NULL and the empty string are indistinguishable
# Line 141  static PyObject* do_read_attribute(DBFHa Line 270  static PyObject* do_read_attribute(DBFHa
270                  switch (type)                  switch (type)
271                  {                  {
272                  case FTString:                  case FTString:
273                          temp = DBFReadStringAttribute(handle, record, field);                          string = DBFReadStringAttribute(handle, record, field);
274                          if (!temp)                          if (string) return decode_string(handle, string);
                         {  
                                 PyErr_Format(PyExc_IOError,  
                                                 "Can't read value for row %d column %d",  
                                                 record, field);  
                                 return NULL;  
                         }  
                         return PyString_FromString(temp);  
275    
276                  case FTInteger:                  case FTInteger:
277                          return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));                          return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));
278    
279                  case FTDouble:                  case FTDouble:
280                          return PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, field));                          return PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, field));
281                            
282                    case FTLogical:
283                            string = DBFReadLogicalAttribute(handle, record, field);
284                            if (string)
285                            {
286                                    switch (string[0])
287                                    {
288                                    case 'F':
289                                    case 'N':
290                                            Py_RETURN_FALSE;
291                                    case 'T':
292                                    case 'Y':
293                                            Py_RETURN_TRUE;
294                                    }
295                            }
296                            break;
297    
298                  default:                  default:
299                          PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);                          PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
300                          return NULL;                          return NULL;
301                  }                  }
302          }          }
303            
304            PyErr_Format(PyExc_IOError,     "Can't read value for row %d column %d", record, field);
305            return NULL;
306  }      }    
307    
308    
# Line 242  fail: Line 383  fail:
383    
384    
385  /* write a single field of a record. */  /* write a single field of a record. */
386  static int do_write_field(DBFHandle handle, int record, int field, int type, PyObject* value)  static int do_write_attribute(DBFHandle handle, int record, int field, int type, PyObject* value)
387  {  {
388          char * string_value;          PyObject* string_value = NULL;
389          int int_value;          int int_value;
390          double double_value;          double double_value;
391            int logical_value;
392    
393          if (value == Py_None)          if (value == Py_None)
394          {          {
395                  if (!DBFWriteNULLAttribute(handle, record, field))                  if (DBFWriteNULLAttribute(handle, record, field)) return 1;
                 {  
                         PyErr_Format(PyExc_IOError,  
                                 "can't write NULL field %d of record %d",  
                                 field, record);  
                         return 0;  
                 }  
396          }          }
397          else          else
398          {          {
399                  switch (type)                  switch (type)
400                  {                  {
401                  case FTString:                  case FTString:
402                          string_value = PyString_AsString(value);                          string_value = encode_string(handle, value);
403                          if (!string_value) return 0;                          if (!string_value) return 0;
404                          if (!DBFWriteStringAttribute(handle, record, field, string_value))                          if (DBFWriteStringAttribute(handle, record, field, PyString_AsString(string_value)))
405                          {                          {
406                                  PyErr_Format(PyExc_IOError,                                  Py_DECREF(string_value);
407                                                  "can't write field %d of record %d",                                  return 1;
                                                 field, record);  
                                 return 0;  
408                          }                          }
409                            Py_DECREF(string_value);
410                          break;                          break;
411    
412                  case FTInteger:                  case FTInteger:
413                          int_value = PyInt_AsLong(value);                          int_value = PyInt_AsLong(value);
414                          if (int_value == -1 && PyErr_Occurred()) return 0;                          if (int_value == -1 && PyErr_Occurred()) return 0;
415                          if (!DBFWriteIntegerAttribute(handle, record, field, int_value))                          if (DBFWriteIntegerAttribute(handle, record, field, int_value)) return 1;
                         {  
                                 PyErr_Format(PyExc_IOError,  
                                                 "can't write field %d of record %d",  
                                                 field, record);  
                                 return 0;  
                         }  
416                          break;                          break;
417    
418                  case FTDouble:                  case FTDouble:
419                          double_value = PyFloat_AsDouble(value);                          double_value = PyFloat_AsDouble(value);
420                          if (double_value == -1 && PyErr_Occurred()) return 0;                          if (double_value == -1 && PyErr_Occurred()) return 0;
421                          if (!DBFWriteDoubleAttribute(handle, record, field, double_value))                          if (DBFWriteDoubleAttribute(handle, record, field, double_value)) return 1;
422                          {                          break;
423                                  PyErr_Format(PyExc_IOError,                          
424                                                  "can't write field %d of record %d",                  case FTLogical:
425                                                  field, record);                          logical_value = PyObject_IsTrue(value);
426                                  return 0;                          if (logical_value == -1) return 0;
427                          }                          if (DBFWriteLogicalAttribute(handle, record, field, logical_value ? 'T' : 'F')) return 1;
428                          break;                          break;
429    
430                  default:                  default:
# Line 304  static int do_write_field(DBFHandle hand Line 433  static int do_write_field(DBFHandle hand
433                  }                  }
434          }          }
435    
436          return 1;          PyErr_Format(PyExc_IOError,     "can't write field %d of record %d", field, record);
437            return 0;
438  }  }
439    
440    
441    
442  static PyObject* dbffile_write_field(DBFFileObject* self, PyObject* args)  static PyObject* dbffile_write_attribute(DBFFileObject* self, PyObject* args)
443  {  {
444          int record, field;          int record, field;
445          PyObject* value;          PyObject* value;
446          int type;          int type;
447    
448          if (!PyArg_ParseTuple(args, "iiO:write_field", &record, &field, &value)) return NULL;          if (!PyArg_ParseTuple(args, "iiO:write_attribute", &record, &field, &value)) return NULL;
449                    
450          if (field < 0 || field >= DBFGetFieldCount(self->handle))          if (field < 0 || field >= DBFGetFieldCount(self->handle))
451          {          {
# Line 326  static PyObject* dbffile_write_field(DBF Line 456  static PyObject* dbffile_write_field(DBF
456          }          }
457    
458          type = DBFGetFieldInfo(self->handle, field, NULL, NULL, NULL);          type = DBFGetFieldInfo(self->handle, field, NULL, NULL, NULL);
459          if (!do_write_field(self->handle, record, field, type, value)) return NULL;          if (!do_write_attribute(self->handle, record, field, type, value)) return NULL;
460          Py_RETURN_NONE;          Py_RETURN_NONE;
461  }  }
462    
# Line 367  static PyObject* dbffile_write_record(DB Line 497  static PyObject* dbffile_write_record(DB
497                          type = DBFGetFieldInfo(self->handle, i, NULL, NULL, NULL);                          type = DBFGetFieldInfo(self->handle, i, NULL, NULL, NULL);
498                          value = PySequence_GetItem(record_object, i);                          value = PySequence_GetItem(record_object, i);
499                          if (!value) return NULL;                          if (!value) return NULL;
500                          if (!do_write_field(self->handle, record, i, type, value))                          if (!do_write_attribute(self->handle, record, i, type, value))
501                          {                          {
502                                  Py_DECREF(value);                                  Py_DECREF(value);
503                                  return NULL;                                  return NULL;
# Line 385  static PyObject* dbffile_write_record(DB Line 515  static PyObject* dbffile_write_record(DB
515                          name[0] = '\0';                          name[0] = '\0';
516                          type = DBFGetFieldInfo(self->handle, i, name, NULL, NULL);                          type = DBFGetFieldInfo(self->handle, i, name, NULL, NULL);
517                          value = PyDict_GetItemString(record_object, name);                          value = PyDict_GetItemString(record_object, name);
518                          if (value && !do_write_field(self->handle, record, i, type, value)) return NULL;                          if (value && !do_write_attribute(self->handle, record, i, type, value)) return NULL;
519                  }                  }
520          }          }
521                    
# Line 418  static PyObject* dbffile_commit(DBFFileO Line 548  static PyObject* dbffile_commit(DBFFileO
548  #endif  #endif
549    
550    
551    #if HAVE_LANGUAGE_DRIVER
552    
553    static PyObject* dbffile_language_driver(DBFFileObject* self, void* closure)
554    {
555            return PyInt_FromLong((long)self->handle->nLanguageDriver);
556    }
557    
558    #endif
559    
560    
561  static struct PyMethodDef dbffile_methods[] =  static struct PyMethodDef dbffile_methods[] =
562  {  {
563          {"close", (PyCFunction)dbffile_close, METH_NOARGS,          {"close", (PyCFunction)dbffile_close, METH_NOARGS,
564                  "close()\n"                  "close() -> None\n\n"
565                  "close DBFFile"},                  "closes DBFFile"},
566          {"field_count", (PyCFunction)dbffile_field_count, METH_NOARGS,          {"field_count", (PyCFunction)dbffile_field_count, METH_NOARGS,
567                  "field_count()\n"                  "field_count() -> integer\n\n"
568                  "returns number of fields currently defined"},                  "returns number of fields currently defined"},
569          {"record_count", (PyCFunction)dbffile_record_count, METH_NOARGS,          {"record_count", (PyCFunction)dbffile_record_count, METH_NOARGS,
570                  "record_count()\n"                  "record_count() -> integer\n\n"
571                  "returns number of records that currently exist"},                  "returns number of records that currently exist"},
572          {"field_info", (PyCFunction)dbffile_field_info, METH_VARARGS,          {"field_info", (PyCFunction)dbffile_field_info, METH_VARARGS,
573                  "field_info(field_index)\n"                  "field_info(field_index) -> (type, name, width, decimals)\n\n"
574                  "returns info of a field as a tuple (type, name, width, decimals) with:\n"                  "returns info of a field as a tuple with:\n"
575                  "-type: the type of the field corresponding to the integer value of one of the constants FTString, FTInteger, ...\n"                  "- type: the type of the field corresponding to the integer value of one "
576                  "-name: the name of the field as a string\n"                  " of the constants FTString, FTInteger, ...\n"
577                  "-width: the width of the field as a number of characters\n"                  "- name: the name of the field as a string\n"
578                  "-decimals: the number of decimal digits" },                  "- width: the width of the field as a number of characters\n"
579                    "- decimals: the number of decimal digits" },
580          {"add_field", (PyCFunction)dbffile_add_field, METH_VARARGS,          {"add_field", (PyCFunction)dbffile_add_field, METH_VARARGS,
581                  "add_field(type, name, width, decimals)\n"                  "add_field(type, name, width, decimals) -> field_index\n\n"
582                  "adds a new field and returns field index if successful\n"                  "adds a new field and returns field index if successful\n"
583                  "-type: the type of the field corresponding to the integer value of one of the constants FTString, FTInteger, ...\n"                  "- type: the type of the field corresponding to the integer value of one "
584                  "-name: the name of the field as a string\n"                  " of the constants FTString, FTInteger, ...\n"
585                  "-width: the width of the field as a number of characters\n"                  "- name: the name of the field as a string\n"
586                  "-decimals: the number of decimal digits" },                  "- width: the width of the field as a number of characters\n"
587                    "- decimals: the number of decimal digits" },
588          {"read_attribute", (PyCFunction)dbffile_read_attribute, METH_VARARGS,          {"read_attribute", (PyCFunction)dbffile_read_attribute, METH_VARARGS,
589                  "read_attribute(record_index, field_index)\n"                  "read_attribute(record_index, field_index) -> value\n\n"
590                  "return the value of one field of a record"},                  "returns the value of one field of a record"},
591          {"read_record", (PyCFunction)dbffile_read_record, METH_VARARGS,          {"read_record", (PyCFunction)dbffile_read_record, METH_VARARGS,
592                  "read_record(record_index)\n"                  "read_record(record_index) -> dict\n\n"
593                  "return an entire record as a dict of field names and values"},                  "returns an entire record as a dictionary of field names and values"},
594          {"write_field", (PyCFunction)dbffile_write_field, METH_VARARGS,          {"write_attribute", (PyCFunction)dbffile_write_attribute, METH_VARARGS,
595                  "write_field(record_index, field_index, new_value)\n"                  "write_attribute(record_index, field_index, new_value)\n"
596                  "write a single field of a record"},                  "writes a single field of a record"},
597          {"write_record", (PyCFunction)dbffile_write_record, METH_VARARGS,          {"write_record", (PyCFunction)dbffile_write_record, METH_VARARGS,
598                  "write_record(record_index, record)\n"                  "write_record(record_index, record) -> record_index\n\n"
599                  "write an entire record as a dict or a sequence\n"                  "Writes an entire record as a dict or a sequence, and return index of record\n"
600                  "record can either be a dictionary in which case the keys are used as field names, "                  "Record can either be a dictionary in which case the keys are used as field names, "
601                  "or a sequence that must have an item for every field (length = field_count())"},                  "or a sequence that must have an item for every field (length = field_count())"},
602  #if HAVE_UPDATE_HEADER  #if HAVE_UPDATE_HEADER
603          {"commit", (PyCFunction)dbffile_read_record, METH_NOARGS,          {"commit", (PyCFunction)dbffile_commit, METH_NOARGS,
604                  "commit()"},                  "commit() -> None"},
605  #endif  #endif
606          {NULL}          {NULL}
607  };  };
# Line 469  static struct PyMethodDef dbffile_method Line 610  static struct PyMethodDef dbffile_method
610    
611  static struct PyGetSetDef dbffile_getsetters[] =  static struct PyGetSetDef dbffile_getsetters[] =
612  {  {
613    #if HAVE_LANGUAGE_DRIVER
614            {"language_driver", (getter)dbffile_language_driver, NULL, "Language Driver ID (read-only)" },
615    #endif
616          {NULL}          {NULL}
617  };  };
618    
# Line 491  static PyObject* dbflib_create(PyObject* Line 635  static PyObject* dbflib_create(PyObject*
635  {  {
636          char* file;          char* file;
637          DBFFileObject* result;          DBFFileObject* result;
638            DBFHandle handle = NULL;
639            int wideargument = 0;
640    
641    #if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
642            if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
643                    PyObject *wfile;
644                    if (PyArg_ParseTuple(args, "U:create", &wfile))
645                    {
646                            wideargument = 1;
647                            handle = DBFCreateW(PyUnicode_AS_UNICODE(wfile));
648                            if (!handle)
649                            {
650                                    PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
651                                    return NULL;
652                            }
653                    }
654                    else
655                    {
656                            /* Drop the argument parsing error as narrow
657                               strings are also valid. */
658                            PyErr_Clear();
659                    }
660            }
661    #endif
662                    
663          if (!PyArg_ParseTuple(args, "et:create", Py_FileSystemDefaultEncoding, &file)) return NULL;          if (!handle)
664                    {
665                    if (!PyArg_ParseTuple(args, "et:create", Py_FileSystemDefaultEncoding, &file)) return NULL;
666                    handle = DBFCreate(file);
667                    if (!handle)
668                    {
669                                    PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
670                                    PyMem_Free(file);
671                                    return NULL;
672                    }
673                    PyMem_Free(file);
674            }
675    
676          result = PyObject_New(DBFFileObject, &DBFFileType);          result = PyObject_New(DBFFileObject, &DBFFileType);
677          if (!result)          if (!result)
678          {          {
679                    DBFClose(handle);
680                  return PyErr_NoMemory();                  return PyErr_NoMemory();
681          }          }
682                    
683          result->handle = DBFCreate(file);          result->handle = handle;
684          if (!result->handle)          return (PyObject*) result;
685    }
686    
687    
688    
689    #if HAVE_LANGUAGE_DRIVER
690    
691    /** translate a numeric Language Driver ID to the name of Python's codec.
692     */
693    static PyObject* dbflib_language_driver_codec(PyObject* module, PyObject* args)
694    {
695            int ldid;
696            if (!PyArg_ParseTuple(args, "i:language_driver_name", &ldid)) return NULL;
697            if (ldid < 0 || ldid >= PYSHAPELIB_NUM_LANGUAGE_DRIVERS || !codecs[ldid])
698          {          {
699                  PyObject_Del((PyObject*)result);                  PyErr_SetString(PyExc_ValueError, "invalid driver id");
                 PyErr_SetString(PyExc_RuntimeError, "Failed to create DBFFile");  
700                  return NULL;                  return NULL;
701          }          }
702                    return PyString_FromString(codecs[ldid]);
         return (PyObject*) result;  
703  }  }
704    
705    /** translate a numeric Language Driver ID to a string represting its constant.
706     */
707    static PyObject* dbflib_language_driver_name(PyObject* module, PyObject* args)
708    {
709            int ldid;
710            if (!PyArg_ParseTuple(args, "i:language_driver_name", &ldid)) return NULL;
711            if (ldid < 0 || ldid >= PYSHAPELIB_NUM_LANGUAGE_DRIVERS || !drivers[ldid])
712            {
713                    PyErr_SetString(PyExc_ValueError, "invalid driver id");
714                    return NULL;
715            }
716            return PyString_FromString(drivers[ldid]);
717    }
718    
719    #endif
720    
721    
722    
723  static struct PyMethodDef dbflib_methods[] =  static struct PyMethodDef dbflib_methods[] =
724  {  {
725          {"open", (PyCFunction)dbflib_open, METH_VARARGS,          {"open", (PyCFunction)dbflib_open, METH_VARARGS,
726                  "open(filename [, mode])\n"                  "open(name [, mode]) -> DBFFile\n\n"
727                  "open a DBFFile" },                  "opens a DBFFile" },
728          {"create", (PyCFunction)dbflib_create, METH_VARARGS,          {"create", (PyCFunction)dbflib_create, METH_VARARGS,
729                  "create(filename)\n"                  "create(name [, language_driver]) -> DBFFile\n\n"
730                  "create a DBFFile" },                  "create a DBFFile " },
731    #if HAVE_LANGUAGE_DRIVER
732            {"language_driver_codec", (PyCFunction)dbflib_language_driver_codec, METH_VARARGS,
733                    "language_driver_codec(driver_id) -> string\n\n"
734                    "translate language driver id into the name of the Python's codec used as code page." },
735            {"language_driver_name", (PyCFunction)dbflib_language_driver_name, METH_VARARGS,
736                    "language_driver_name(driver_id) -> string\n\n"
737                    "translate language driver id into a string." },
738    #endif
739          {NULL}          {NULL}
740  };  };
741    
742    
   
743  PyMODINIT_FUNC initdbflib(void)  PyMODINIT_FUNC initdbflib(void)
744  {  {
745            int i;
746    
747          PyObject* module = Py_InitModule("dbflib", dbflib_methods);          PyObject* module = Py_InitModule("dbflib", dbflib_methods);
748          if (!module) return;          if (!module) return;
749                    
# Line 536  PyMODINIT_FUNC initdbflib(void) Line 752  PyMODINIT_FUNC initdbflib(void)
752          PYSHAPELIB_ADD_CONSTANT(FTString);          PYSHAPELIB_ADD_CONSTANT(FTString);
753          PYSHAPELIB_ADD_CONSTANT(FTInteger);          PYSHAPELIB_ADD_CONSTANT(FTInteger);
754          PYSHAPELIB_ADD_CONSTANT(FTDouble);          PYSHAPELIB_ADD_CONSTANT(FTDouble);
755            PYSHAPELIB_ADD_CONSTANT(FTLogical);
756          PYSHAPELIB_ADD_CONSTANT(FTInvalid);          PYSHAPELIB_ADD_CONSTANT(FTInvalid);
757          PyModule_AddIntConstant(module, "_have_commit", HAVE_UPDATE_HEADER);          PyModule_AddIntConstant(module, "_have_commit", HAVE_UPDATE_HEADER);
758    
759    #if HAVE_LANGUAGE_DRIVER
760            /* table compiled from these resources:
761             * http://www.clicketyclick.dk/databases/xbase/format/dbf.html
762             * http://www.esrinl.com/content/file.asp?id=307
763             * http://msdn2.microsoft.com/en-us/library/aa975345(VS.71).aspx
764             */
765            for (i = 0; i < PYSHAPELIB_NUM_LANGUAGE_DRIVERS; ++i)
766            {
767                    codecs[i] = NULL;
768                    drivers[i] = NULL;
769            }
770            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x00, "cp1252", "NOT_SET");
771            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x01, "cp437", "DOS_USA");
772            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x02, "cp850", "DOS_INTERNATIONAL");
773            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x03, "cp1252", "WINDOWS_ANSI");
774            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x04, "mac_roman", "STANDARD_MACINTOSH");
775            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x08, "cp865", "DANISH_OEM");
776            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x09, "cp437", "DUTCH_OEM");
777            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0a, "cp850", "DUTCH_OEM_2");
778            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0b, "cp437", "FINNISH_OEM");
779            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0d, "cp437", "FRENCH_OEM");
780            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0e, "cp850", "FRENCH_OEM_2");
781            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0f, "cp437", "GERMAN_OEM");
782            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x10, "cp850", "GERMAN_OEM_2");
783            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x11, "cp437", "ITALIAN_OEM");
784            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x12, "cp850", "ITALIAN_OEM_2");
785            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x13, "cp932", "JAPANESE_SHIFT_JIS");
786            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x14, "cp850", "SPANISH_OEM_2");
787            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x15, "cp437", "SWEDISH_OEM");
788            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x16, "cp850", "SWEDISH_OEM_2");
789            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x17, "cp865", "NORWEGIAN_OEM");
790            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x18, "cp437", "SPANISH_OEM");
791            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x19, "cp437", "ENGLISH_BRITAIN_OEM");
792            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1a, "cp850", "ENGLISH_BRITAIN_OEM_2");
793            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0b, "cp437", "ENGLISH_US_OEM");
794            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1c, "cp863", "FRENCH_CANADA_OEM");
795            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1d, "cp850", "FRENCH_OEM_2");
796            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1f, "cp852", "CZECH_OEM");
797            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x22, "cp852", "HUNGARIAN_OEM");
798            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x23, "cp852", "POLISH_OEM");
799            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x24, "cp860", "PORTUGUESE_OEM");
800            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x25, "cp850", "PORTUGUESE_OEM_2");
801            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x26, "cp866", "RUSSIAN_OEM");
802            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x37, "cp850", "ENGLISH_US_OEM_2");
803            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x40, "cp852", "ROMANIAN_OEM");
804            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4d, "cp936", "CHINESE_GBK_PRC");
805            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4e, "cp949", "KOREAN_ANSI_OEM);");
806            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4f, "cp950", "CHINESE_BIG5_TAIWAN");
807            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x50, "cp874", "THAI_ANSI_OEM");
808            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x57, "cp1252", "ESRI_ANSI");
809            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x58, "cp1252", "WESTERN_EUROPEAN_ANSI");
810            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x59, "cp1252", "SPANISH_ANSI");
811            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x64, "cp852", "EASTERN_EUROPEAN_MSDOS");
812            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x65, "cp866", "RUSSIAN_MSDOS");
813            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x66, "cp865", "NORDIC_MSDOS");
814            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x67, "cp861", "ICELANDIC_MSDOS");
815            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x68, "cp895", "CZECH_MSDOS");
816            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x69, "cp620", "POLISH_MSDOS");
817            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6a, "cp737", "GREEK_MSDOS");
818            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6b, "cp857", "TURKISH_MSDOS");
819            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6c, "cp863", "FRENCH_CANADA_MSDOS");
820            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x78, "cp950", "TAIWAN_BIG5");
821            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x79, "cp949", "HANGUL_WANSUG");
822            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7a, "cp936", "PRC_GBK");
823            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7b, "cp932", "JAPANESE_SHIFT_JIS");
824            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7c, "cp874", "THAI_WINDOWS_MSDOS");
825            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7d, "cp1255", "HEBREW_WINDOWS");
826            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7e, "cp1256", "ARABIC_WINDOWS");
827            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x86, "cp737", "GREEK_OEM");
828            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x87, "cp852", "SLOVENIAN_OEM");
829            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x88, "cp857", "TURKISH_OEM");
830            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x96, "mac_cyrillic", "RUSSIAN_MACINTOSH");
831            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x97, "mac_latin2", "EASTERN_EUROPEAN_MACINTOSH");
832            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x98, "mac_greek", "GREEK_MACINTOSH");
833            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xc8, "cp1250", "EASTERN_EUROPEAN_WINDOWS");
834            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xc9, "cp1251", "RUSSIAN_WINDOWS");
835            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xca, "cp1254", "TURKISH_WINDOWS");
836            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xcb, "cp1253", "GREEK_WINDOWS");
837            PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xcc, "cp1257", "BALTIC_WINDOWS");
838    #endif
839    
840  }  }

Legend:
Removed from v.2744  
changed lines
  Added in v.2753

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26