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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2754 - (show annotations)
Wed Apr 11 19:04:12 2007 UTC (17 years, 10 months ago) by bramz
File MIME type: text/plain
File size: 24938 byte(s)
Bug fix: in dbffile_add_field, the exception must be cleared if the first PyArg_ParseTuple fails.
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"
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 ------------------------------------------------------------------------------------------------------- */
92
93 typedef struct {
94 PyObject_HEAD
95 DBFHandle handle;
96 } DBFFileObject;
97
98
99
100 /* allocator
101 */
102 static PyObject* dbffile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
103 {
104 DBFFileObject* self;
105 self = (DBFFileObject*) type->tp_alloc(type, 0);
106 self->handle = NULL;
107 return (PyObject*) self;
108 }
109
110
111
112 /* deallocator
113 */
114 static void dbffile_dealloc(DBFFileObject* self)
115 {
116 DBFClose(self->handle);
117 self->handle = NULL;
118 self->ob_type->tp_free((PyObject*)self);
119 }
120
121
122
123 /* constructor
124 */
125 static int dbffile_init(DBFFileObject* self, PyObject* args, PyObject* kwds)
126 {
127 char* file = NULL;
128 char* mode = "rb";
129 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 if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:DBFFile", kwlist,
161 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 return 0;
175 }
176
177
178
179 static PyObject* dbffile_close(DBFFileObject* self)
180 {
181 DBFClose(self->handle);
182 self->handle = NULL;
183 Py_RETURN_NONE;
184 }
185
186
187
188 static PyObject* dbffile_field_count(DBFFileObject* self)
189 {
190 return PyInt_FromLong((long)DBFGetFieldCount(self->handle));
191 }
192
193
194
195 static PyObject* dbffile_record_count(DBFFileObject* self)
196 {
197 return PyInt_FromLong((long)DBFGetRecordCount(self->handle));
198 }
199
200
201
202 static PyObject* dbffile_field_info(DBFFileObject* self, PyObject* args)
203 {
204 char field_name[12];
205 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;
209
210 field_name[0] = '\0';
211 field_type = DBFGetFieldInfo(self->handle, field, field_name, &width, &decimals);
212 name_object = decode_string(self->handle, field_name);
213
214 return Py_BuildValue("iOii", field_type, name_object, width, decimals);
215 }
216
217
218
219 static PyObject* dbffile_add_field(DBFFileObject* self, PyObject* args)
220 {
221 PyObject *oname = NULL, *name = NULL;
222 int type, width, decimals;
223 int field;
224
225 if (!PyArg_ParseTuple(args, "Uiii:add_field", &oname, &type, &width, &decimals))
226 {
227 PyErr_Clear();
228 if (!PyArg_ParseTuple(args, "Siii:add_field", &oname, &type, &width, &decimals)) return NULL;
229 }
230
231 name = encode_string(self->handle, oname);
232 if (!name) return NULL;
233
234 field = DBFAddField(self->handle, PyString_AsString(name), (DBFFieldType)type, width, decimals);
235 Py_DECREF(name);
236
237 if (field < 0)
238 {
239 PyErr_SetString(PyExc_ValueError, "Failed to add field due to inappropriate field definition");
240 return NULL;
241 }
242 return PyInt_FromLong((long)field);
243 }
244
245
246
247 /* Read one attribute from the dbf handle and return it as a new python object
248 *
249 * If an error occurs, set the appropriate Python exception and return
250 * NULL.
251 *
252 * Assume that the values of the record and field arguments are valid.
253 * The name argument will be passed to DBFGetFieldInfo as is and should
254 * thus be either NULL or a pointer to an array of at least 12 chars
255 */
256 static PyObject* do_read_attribute(DBFHandle handle, int record, int field, char * name)
257 {
258 int type, width;
259 const char* string;
260 type = DBFGetFieldInfo(handle, field, name, &width, NULL);
261
262 /* For strings NULL and the empty string are indistinguishable
263 * in DBF files. We prefer empty strings instead for backwards
264 * compatibility reasons because older wrapper versions returned
265 * emtpy strings as empty strings.
266 */
267 if (type != FTString && DBFIsAttributeNULL(handle, record, field))
268 {
269 Py_RETURN_NONE;
270 }
271 else
272 {
273 switch (type)
274 {
275 case FTString:
276 string = DBFReadStringAttribute(handle, record, field);
277 if (string) return decode_string(handle, string);
278
279 case FTInteger:
280 return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));
281
282 case FTDouble:
283 return PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, field));
284
285 case FTLogical:
286 string = DBFReadLogicalAttribute(handle, record, field);
287 if (string)
288 {
289 switch (string[0])
290 {
291 case 'F':
292 case 'N':
293 Py_RETURN_FALSE;
294 case 'T':
295 case 'Y':
296 Py_RETURN_TRUE;
297 }
298 }
299 break;
300
301 default:
302 PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
303 return NULL;
304 }
305 }
306
307 PyErr_Format(PyExc_IOError, "Can't read value for row %d column %d", record, field);
308 return NULL;
309 }
310
311
312
313 /* the read_attribute method. Return the value of the given record and
314 * field as a python object of the appropriate type.
315 */
316 static PyObject* dbffile_read_attribute(DBFFileObject* self, PyObject* args)
317 {
318 int record, field;
319
320 if (!PyArg_ParseTuple(args, "ii:read_field", &record, &field)) return NULL;
321
322 if (record < 0 || record >= DBFGetRecordCount(self->handle))
323 {
324 PyErr_Format(PyExc_ValueError,
325 "record index %d out of bounds (record count: %d)",
326 record, DBFGetRecordCount(self->handle));
327 return NULL;
328 }
329
330 if (field < 0 || field >= DBFGetFieldCount(self->handle))
331 {
332 PyErr_Format(PyExc_ValueError,
333 "field index %d out of bounds (field count: %d)",
334 field, DBFGetFieldCount(self->handle));
335 return NULL;
336 }
337
338 return do_read_attribute(self->handle, record, field, NULL);
339 }
340
341
342
343 /* the read_record method. Return the record record as a dictionary with
344 * whose keys are the names of the fields, and their values as the
345 * appropriate Python type.
346 */
347 static PyObject* dbffile_read_record(DBFFileObject* self, PyObject* args)
348 {
349 int record;
350 int num_fields;
351 int i;
352 char name[12];
353 PyObject *dict;
354 PyObject *value = NULL;
355
356 if (!PyArg_ParseTuple(args, "i:read_record", &record)) return NULL;
357
358 if (record < 0 || record >= DBFGetRecordCount(self->handle))
359 {
360 PyErr_Format(PyExc_ValueError,
361 "record index %d out of bounds (record count: %d)",
362 record, DBFGetRecordCount(self->handle));
363 return NULL;
364 }
365
366 dict = PyDict_New();
367 if (!dict) return NULL;
368
369 num_fields = DBFGetFieldCount(self->handle);
370 for (i = 0; i < num_fields; i++)
371 {
372 value = do_read_attribute(self->handle, record, i, name);
373 if (!value || PyDict_SetItemString(dict, name, value) < 0) goto fail;
374 Py_DECREF(value);
375 value = NULL;
376 }
377
378 return dict;
379
380 fail:
381 Py_XDECREF(value);
382 Py_DECREF(dict);
383 return NULL;
384 }
385
386
387
388 /* write a single field of a record. */
389 static int do_write_attribute(DBFHandle handle, int record, int field, int type, PyObject* value)
390 {
391 PyObject* string_value = NULL;
392 int int_value;
393 double double_value;
394 int logical_value;
395
396 if (value == Py_None)
397 {
398 if (DBFWriteNULLAttribute(handle, record, field)) return 1;
399 }
400 else
401 {
402 switch (type)
403 {
404 case FTString:
405 string_value = encode_string(handle, value);
406 if (!string_value) return 0;
407 if (DBFWriteStringAttribute(handle, record, field, PyString_AsString(string_value)))
408 {
409 Py_DECREF(string_value);
410 return 1;
411 }
412 Py_DECREF(string_value);
413 break;
414
415 case FTInteger:
416 int_value = PyInt_AsLong(value);
417 if (int_value == -1 && PyErr_Occurred()) return 0;
418 if (DBFWriteIntegerAttribute(handle, record, field, int_value)) return 1;
419 break;
420
421 case FTDouble:
422 double_value = PyFloat_AsDouble(value);
423 if (double_value == -1 && PyErr_Occurred()) return 0;
424 if (DBFWriteDoubleAttribute(handle, record, field, double_value)) return 1;
425 break;
426
427 case FTLogical:
428 logical_value = PyObject_IsTrue(value);
429 if (logical_value == -1) return 0;
430 if (DBFWriteLogicalAttribute(handle, record, field, logical_value ? 'T' : 'F')) return 1;
431 break;
432
433 default:
434 PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
435 return 0;
436 }
437 }
438
439 PyErr_Format(PyExc_IOError, "can't write field %d of record %d", field, record);
440 return 0;
441 }
442
443
444
445 static PyObject* dbffile_write_attribute(DBFFileObject* self, PyObject* args)
446 {
447 int record, field;
448 PyObject* value;
449 int type;
450
451 if (!PyArg_ParseTuple(args, "iiO:write_attribute", &record, &field, &value)) return NULL;
452
453 if (field < 0 || field >= DBFGetFieldCount(self->handle))
454 {
455 PyErr_Format(PyExc_ValueError,
456 "field index %d out of bounds (field count: %d)",
457 field, DBFGetFieldCount(self->handle));
458 return NULL;
459 }
460
461 type = DBFGetFieldInfo(self->handle, field, NULL, NULL, NULL);
462 if (!do_write_attribute(self->handle, record, field, type, value)) return NULL;
463 Py_RETURN_NONE;
464 }
465
466
467
468 static PyObject* dbffile_write_record(DBFFileObject* self, PyObject* args)
469 {
470 int record;
471 PyObject* record_object;
472 int i, num_fields;
473
474 int type;
475 char name[12];
476 PyObject* value = NULL;
477
478 if (!PyArg_ParseTuple(args, "iO:write_record", &record, &record_object)) return NULL;
479
480 num_fields = DBFGetFieldCount(self->handle);
481
482 /* mimic ShapeFile functionality where id = -1 means appending */
483 if (record == -1)
484 {
485 record = num_fields;
486 }
487
488 if (PySequence_Check(record_object))
489 {
490 /* It's a sequence object. Iterate through all items in the
491 * sequence and write them to the appropriate field.
492 */
493 if (PySequence_Length(record_object) != num_fields)
494 {
495 PyErr_SetString(PyExc_TypeError, "record must have one item for each field");
496 return NULL;
497 }
498 for (i = 0; i < num_fields; ++i)
499 {
500 type = DBFGetFieldInfo(self->handle, i, NULL, NULL, NULL);
501 value = PySequence_GetItem(record_object, i);
502 if (!value) return NULL;
503 if (!do_write_attribute(self->handle, record, i, type, value))
504 {
505 Py_DECREF(value);
506 return NULL;
507 }
508 Py_DECREF(value);
509 }
510 }
511 else
512 {
513 /* It's a dictionary-like object. Iterate over the names of the
514 * known fields and write the corresponding item
515 */
516 for (i = 0; i < num_fields; ++i)
517 {
518 name[0] = '\0';
519 type = DBFGetFieldInfo(self->handle, i, name, NULL, NULL);
520 value = PyDict_GetItemString(record_object, name);
521 if (value && !do_write_attribute(self->handle, record, i, type, value)) return NULL;
522 }
523 }
524
525 return PyInt_FromLong((long)record);
526 }
527
528
529
530 static PyObject* dbffile_repr(DBFFileObject* self)
531 {
532 /* TODO: it would be nice to do something like "dbflib.DBFFile(filename, mode)" instead */
533 return PyString_FromFormat("<dbflib.DBFFile object at %p>", self->handle);
534 }
535
536
537
538 /* The commit method implementation
539 *
540 * The method relies on the DBFUpdateHeader method which is not
541 * available in shapelib <= 1.2.10. setup.py defines
542 * HAVE_UPDATE_HEADER's value depending on whether the function is
543 * available in the shapelib version the code is compiled with.
544 */
545 #if HAVE_UPDATE_HEADER
546 static PyObject* dbffile_commit(DBFFileObject* self)
547 {
548 DBFUpdateHeader(self->handle);
549 Py_RETURN_NONE;
550 }
551 #endif
552
553
554 #if HAVE_LANGUAGE_DRIVER
555
556 static PyObject* dbffile_language_driver(DBFFileObject* self, void* closure)
557 {
558 return PyInt_FromLong((long)self->handle->nLanguageDriver);
559 }
560
561 #endif
562
563
564 static struct PyMethodDef dbffile_methods[] =
565 {
566 {"close", (PyCFunction)dbffile_close, METH_NOARGS,
567 "close() -> None\n\n"
568 "closes DBFFile"},
569 {"field_count", (PyCFunction)dbffile_field_count, METH_NOARGS,
570 "field_count() -> integer\n\n"
571 "returns number of fields currently defined"},
572 {"record_count", (PyCFunction)dbffile_record_count, METH_NOARGS,
573 "record_count() -> integer\n\n"
574 "returns number of records that currently exist"},
575 {"field_info", (PyCFunction)dbffile_field_info, METH_VARARGS,
576 "field_info(field_index) -> (type, name, width, decimals)\n\n"
577 "returns info of a field as a tuple with:\n"
578 "- type: the type of the field corresponding to the integer value of one "
579 " of the constants FTString, FTInteger, ...\n"
580 "- name: the name of the field as a string\n"
581 "- width: the width of the field as a number of characters\n"
582 "- decimals: the number of decimal digits" },
583 {"add_field", (PyCFunction)dbffile_add_field, METH_VARARGS,
584 "add_field(type, name, width, decimals) -> field_index\n\n"
585 "adds a new field and returns field index if successful\n"
586 "- type: the type of the field corresponding to the integer value of one "
587 " of the constants FTString, FTInteger, ...\n"
588 "- name: the name of the field as a string\n"
589 "- width: the width of the field as a number of characters\n"
590 "- decimals: the number of decimal digits" },
591 {"read_attribute", (PyCFunction)dbffile_read_attribute, METH_VARARGS,
592 "read_attribute(record_index, field_index) -> value\n\n"
593 "returns the value of one field of a record"},
594 {"read_record", (PyCFunction)dbffile_read_record, METH_VARARGS,
595 "read_record(record_index) -> dict\n\n"
596 "returns an entire record as a dictionary of field names and values"},
597 {"write_attribute", (PyCFunction)dbffile_write_attribute, METH_VARARGS,
598 "write_attribute(record_index, field_index, new_value)\n"
599 "writes a single field of a record"},
600 {"write_record", (PyCFunction)dbffile_write_record, METH_VARARGS,
601 "write_record(record_index, record) -> record_index\n\n"
602 "Writes an entire record as a dict or a sequence, and return index of record\n"
603 "Record can either be a dictionary in which case the keys are used as field names, "
604 "or a sequence that must have an item for every field (length = field_count())"},
605 #if HAVE_UPDATE_HEADER
606 {"commit", (PyCFunction)dbffile_commit, METH_NOARGS,
607 "commit() -> None"},
608 #endif
609 {NULL}
610 };
611
612
613
614 static struct PyGetSetDef dbffile_getsetters[] =
615 {
616 #if HAVE_LANGUAGE_DRIVER
617 {"language_driver", (getter)dbffile_language_driver, NULL, "Language Driver ID (read-only)" },
618 #endif
619 {NULL}
620 };
621
622
623
624 static PyTypeObject DBFFileType = PYSHAPELIB_DEFINE_TYPE(DBFFileObject, dbffile, "shapelib.DBFFile", 0);
625
626
627
628 /* --- dbflib -------------------------------------------------------------------------------------------------------- */
629
630 static PyObject* dbflib_open(PyObject* module, PyObject* args)
631 {
632 return PyObject_CallObject((PyObject*)&DBFFileType, args);
633 }
634
635
636
637 static PyObject* dbflib_create(PyObject* module, PyObject* args)
638 {
639 char* file;
640 DBFFileObject* result;
641 DBFHandle handle = NULL;
642 int wideargument = 0;
643
644 #if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
645 if (GetVersion() < 0x80000000) { /* On NT, so wide API available */
646 PyObject *wfile;
647 if (PyArg_ParseTuple(args, "U:create", &wfile))
648 {
649 wideargument = 1;
650 handle = DBFCreateW(PyUnicode_AS_UNICODE(wfile));
651 if (!handle)
652 {
653 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
654 return NULL;
655 }
656 }
657 else
658 {
659 /* Drop the argument parsing error as narrow
660 strings are also valid. */
661 PyErr_Clear();
662 }
663 }
664 #endif
665
666 if (!handle)
667 {
668 if (!PyArg_ParseTuple(args, "et:create", Py_FileSystemDefaultEncoding, &file)) return NULL;
669 handle = DBFCreate(file);
670 if (!handle)
671 {
672 PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
673 PyMem_Free(file);
674 return NULL;
675 }
676 PyMem_Free(file);
677 }
678
679 result = PyObject_New(DBFFileObject, &DBFFileType);
680 if (!result)
681 {
682 DBFClose(handle);
683 return PyErr_NoMemory();
684 }
685
686 result->handle = handle;
687 return (PyObject*) result;
688 }
689
690
691
692 #if HAVE_LANGUAGE_DRIVER
693
694 /** translate a numeric Language Driver ID to the name of Python's codec.
695 */
696 static PyObject* dbflib_language_driver_codec(PyObject* module, PyObject* args)
697 {
698 int ldid;
699 if (!PyArg_ParseTuple(args, "i:language_driver_name", &ldid)) return NULL;
700 if (ldid < 0 || ldid >= PYSHAPELIB_NUM_LANGUAGE_DRIVERS || !codecs[ldid])
701 {
702 PyErr_SetString(PyExc_ValueError, "invalid driver id");
703 return NULL;
704 }
705 return PyString_FromString(codecs[ldid]);
706 }
707
708 /** translate a numeric Language Driver ID to a string represting its constant.
709 */
710 static PyObject* dbflib_language_driver_name(PyObject* module, PyObject* args)
711 {
712 int ldid;
713 if (!PyArg_ParseTuple(args, "i:language_driver_name", &ldid)) return NULL;
714 if (ldid < 0 || ldid >= PYSHAPELIB_NUM_LANGUAGE_DRIVERS || !drivers[ldid])
715 {
716 PyErr_SetString(PyExc_ValueError, "invalid driver id");
717 return NULL;
718 }
719 return PyString_FromString(drivers[ldid]);
720 }
721
722 #endif
723
724
725
726 static struct PyMethodDef dbflib_methods[] =
727 {
728 {"open", (PyCFunction)dbflib_open, METH_VARARGS,
729 "open(name [, mode]) -> DBFFile\n\n"
730 "opens a DBFFile" },
731 {"create", (PyCFunction)dbflib_create, METH_VARARGS,
732 "create(name [, language_driver]) -> DBFFile\n\n"
733 "create a DBFFile " },
734 #if HAVE_LANGUAGE_DRIVER
735 {"language_driver_codec", (PyCFunction)dbflib_language_driver_codec, METH_VARARGS,
736 "language_driver_codec(driver_id) -> string\n\n"
737 "translate language driver id into the name of the Python's codec used as code page." },
738 {"language_driver_name", (PyCFunction)dbflib_language_driver_name, METH_VARARGS,
739 "language_driver_name(driver_id) -> string\n\n"
740 "translate language driver id into a string." },
741 #endif
742 {NULL}
743 };
744
745
746 PyMODINIT_FUNC initdbflib(void)
747 {
748 int i;
749
750 PyObject* module = Py_InitModule("dbflib", dbflib_methods);
751 if (!module) return;
752
753 PYSHAPELIB_ADD_TYPE(DBFFileType, "DBFFile");
754
755 PYSHAPELIB_ADD_CONSTANT(FTString);
756 PYSHAPELIB_ADD_CONSTANT(FTInteger);
757 PYSHAPELIB_ADD_CONSTANT(FTDouble);
758 PYSHAPELIB_ADD_CONSTANT(FTLogical);
759 PYSHAPELIB_ADD_CONSTANT(FTInvalid);
760 PyModule_AddIntConstant(module, "_have_commit", HAVE_UPDATE_HEADER);
761
762 #if HAVE_LANGUAGE_DRIVER
763 /* table compiled from these resources:
764 * http://www.clicketyclick.dk/databases/xbase/format/dbf.html
765 * http://www.esrinl.com/content/file.asp?id=307
766 * http://msdn2.microsoft.com/en-us/library/aa975345(VS.71).aspx
767 */
768 for (i = 0; i < PYSHAPELIB_NUM_LANGUAGE_DRIVERS; ++i)
769 {
770 codecs[i] = NULL;
771 drivers[i] = NULL;
772 }
773 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x00, "cp1252", "NOT_SET");
774 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x01, "cp437", "DOS_USA");
775 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x02, "cp850", "DOS_INTERNATIONAL");
776 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x03, "cp1252", "WINDOWS_ANSI");
777 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x04, "mac_roman", "STANDARD_MACINTOSH");
778 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x08, "cp865", "DANISH_OEM");
779 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x09, "cp437", "DUTCH_OEM");
780 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0a, "cp850", "DUTCH_OEM_2");
781 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0b, "cp437", "FINNISH_OEM");
782 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0d, "cp437", "FRENCH_OEM");
783 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0e, "cp850", "FRENCH_OEM_2");
784 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0f, "cp437", "GERMAN_OEM");
785 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x10, "cp850", "GERMAN_OEM_2");
786 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x11, "cp437", "ITALIAN_OEM");
787 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x12, "cp850", "ITALIAN_OEM_2");
788 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x13, "cp932", "JAPANESE_SHIFT_JIS");
789 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x14, "cp850", "SPANISH_OEM_2");
790 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x15, "cp437", "SWEDISH_OEM");
791 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x16, "cp850", "SWEDISH_OEM_2");
792 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x17, "cp865", "NORWEGIAN_OEM");
793 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x18, "cp437", "SPANISH_OEM");
794 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x19, "cp437", "ENGLISH_BRITAIN_OEM");
795 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1a, "cp850", "ENGLISH_BRITAIN_OEM_2");
796 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0b, "cp437", "ENGLISH_US_OEM");
797 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1c, "cp863", "FRENCH_CANADA_OEM");
798 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1d, "cp850", "FRENCH_OEM_2");
799 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1f, "cp852", "CZECH_OEM");
800 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x22, "cp852", "HUNGARIAN_OEM");
801 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x23, "cp852", "POLISH_OEM");
802 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x24, "cp860", "PORTUGUESE_OEM");
803 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x25, "cp850", "PORTUGUESE_OEM_2");
804 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x26, "cp866", "RUSSIAN_OEM");
805 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x37, "cp850", "ENGLISH_US_OEM_2");
806 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x40, "cp852", "ROMANIAN_OEM");
807 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4d, "cp936", "CHINESE_GBK_PRC");
808 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4e, "cp949", "KOREAN_ANSI_OEM);");
809 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4f, "cp950", "CHINESE_BIG5_TAIWAN");
810 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x50, "cp874", "THAI_ANSI_OEM");
811 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x57, "cp1252", "ESRI_ANSI");
812 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x58, "cp1252", "WESTERN_EUROPEAN_ANSI");
813 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x59, "cp1252", "SPANISH_ANSI");
814 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x64, "cp852", "EASTERN_EUROPEAN_MSDOS");
815 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x65, "cp866", "RUSSIAN_MSDOS");
816 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x66, "cp865", "NORDIC_MSDOS");
817 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x67, "cp861", "ICELANDIC_MSDOS");
818 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x68, "cp895", "CZECH_MSDOS");
819 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x69, "cp620", "POLISH_MSDOS");
820 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6a, "cp737", "GREEK_MSDOS");
821 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6b, "cp857", "TURKISH_MSDOS");
822 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6c, "cp863", "FRENCH_CANADA_MSDOS");
823 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x78, "cp950", "TAIWAN_BIG5");
824 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x79, "cp949", "HANGUL_WANSUG");
825 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7a, "cp936", "PRC_GBK");
826 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7b, "cp932", "JAPANESE_SHIFT_JIS");
827 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7c, "cp874", "THAI_WINDOWS_MSDOS");
828 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7d, "cp1255", "HEBREW_WINDOWS");
829 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7e, "cp1256", "ARABIC_WINDOWS");
830 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x86, "cp737", "GREEK_OEM");
831 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x87, "cp852", "SLOVENIAN_OEM");
832 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x88, "cp857", "TURKISH_OEM");
833 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x96, "mac_cyrillic", "RUSSIAN_MACINTOSH");
834 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x97, "mac_latin2", "EASTERN_EUROPEAN_MACINTOSH");
835 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x98, "mac_greek", "GREEK_MACINTOSH");
836 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xc8, "cp1250", "EASTERN_EUROPEAN_WINDOWS");
837 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xc9, "cp1251", "RUSSIAN_WINDOWS");
838 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xca, "cp1254", "TURKISH_WINDOWS");
839 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xcb, "cp1253", "GREEK_WINDOWS");
840 PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xcc, "cp1257", "BALTIC_WINDOWS");
841 #endif
842
843 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26