/[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 2753 - (show annotations)
Wed Apr 11 18:57:04 2007 UTC (17 years, 10 months ago) by bramz
File MIME type: text/plain
File size: 24913 byte(s)
Expanded Unicode support to field names (formely it was only available for string values in the records.  
Renamed the write_field function to write_attribute to be symmetric with the read_attribute function that already existed.
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 && !PyArg_ParseTuple(args, "Siii:add_field", &oname, &type, &width, &decimals)) return NULL;
227
228 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)
235 {
236 PyErr_SetString(PyExc_ValueError, "Failed to add field due to inappropriate field definition");
237 return NULL;
238 }
239 return PyInt_FromLong((long)field);
240 }
241
242
243
244 /* Read one attribute from the dbf handle and return it as a new python object
245 *
246 * If an error occurs, set the appropriate Python exception and return
247 * NULL.
248 *
249 * Assume that the values of the record and field arguments are valid.
250 * The name argument will be passed to DBFGetFieldInfo as is and should
251 * thus be either NULL or a pointer to an array of at least 12 chars
252 */
253 static PyObject* do_read_attribute(DBFHandle handle, int record, int field, char * name)
254 {
255 int type, width;
256 const char* string;
257 type = DBFGetFieldInfo(handle, field, name, &width, NULL);
258
259 /* For strings NULL and the empty string are indistinguishable
260 * in DBF files. We prefer empty strings instead for backwards
261 * compatibility reasons because older wrapper versions returned
262 * emtpy strings as empty strings.
263 */
264 if (type != FTString && DBFIsAttributeNULL(handle, record, field))
265 {
266 Py_RETURN_NONE;
267 }
268 else
269 {
270 switch (type)
271 {
272 case FTString:
273 string = DBFReadStringAttribute(handle, record, field);
274 if (string) return decode_string(handle, string);
275
276 case FTInteger:
277 return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));
278
279 case FTDouble:
280 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:
299 PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
300 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
309
310 /* the read_attribute method. Return the value of the given record and
311 * field as a python object of the appropriate type.
312 */
313 static PyObject* dbffile_read_attribute(DBFFileObject* self, PyObject* args)
314 {
315 int record, field;
316
317 if (!PyArg_ParseTuple(args, "ii:read_field", &record, &field)) return NULL;
318
319 if (record < 0 || record >= DBFGetRecordCount(self->handle))
320 {
321 PyErr_Format(PyExc_ValueError,
322 "record index %d out of bounds (record count: %d)",
323 record, DBFGetRecordCount(self->handle));
324 return NULL;
325 }
326
327 if (field < 0 || field >= DBFGetFieldCount(self->handle))
328 {
329 PyErr_Format(PyExc_ValueError,
330 "field index %d out of bounds (field count: %d)",
331 field, DBFGetFieldCount(self->handle));
332 return NULL;
333 }
334
335 return do_read_attribute(self->handle, record, field, NULL);
336 }
337
338
339
340 /* the read_record method. Return the record record as a dictionary with
341 * whose keys are the names of the fields, and their values as the
342 * appropriate Python type.
343 */
344 static PyObject* dbffile_read_record(DBFFileObject* self, PyObject* args)
345 {
346 int record;
347 int num_fields;
348 int i;
349 char name[12];
350 PyObject *dict;
351 PyObject *value = NULL;
352
353 if (!PyArg_ParseTuple(args, "i:read_record", &record)) return NULL;
354
355 if (record < 0 || record >= DBFGetRecordCount(self->handle))
356 {
357 PyErr_Format(PyExc_ValueError,
358 "record index %d out of bounds (record count: %d)",
359 record, DBFGetRecordCount(self->handle));
360 return NULL;
361 }
362
363 dict = PyDict_New();
364 if (!dict) return NULL;
365
366 num_fields = DBFGetFieldCount(self->handle);
367 for (i = 0; i < num_fields; i++)
368 {
369 value = do_read_attribute(self->handle, record, i, name);
370 if (!value || PyDict_SetItemString(dict, name, value) < 0) goto fail;
371 Py_DECREF(value);
372 value = NULL;
373 }
374
375 return dict;
376
377 fail:
378 Py_XDECREF(value);
379 Py_DECREF(dict);
380 return NULL;
381 }
382
383
384
385 /* write a single field of a record. */
386 static int do_write_attribute(DBFHandle handle, int record, int field, int type, PyObject* value)
387 {
388 PyObject* string_value = NULL;
389 int int_value;
390 double double_value;
391 int logical_value;
392
393 if (value == Py_None)
394 {
395 if (DBFWriteNULLAttribute(handle, record, field)) return 1;
396 }
397 else
398 {
399 switch (type)
400 {
401 case FTString:
402 string_value = encode_string(handle, value);
403 if (!string_value) return 0;
404 if (DBFWriteStringAttribute(handle, record, field, PyString_AsString(string_value)))
405 {
406 Py_DECREF(string_value);
407 return 1;
408 }
409 Py_DECREF(string_value);
410 break;
411
412 case FTInteger:
413 int_value = PyInt_AsLong(value);
414 if (int_value == -1 && PyErr_Occurred()) return 0;
415 if (DBFWriteIntegerAttribute(handle, record, field, int_value)) return 1;
416 break;
417
418 case FTDouble:
419 double_value = PyFloat_AsDouble(value);
420 if (double_value == -1 && PyErr_Occurred()) return 0;
421 if (DBFWriteDoubleAttribute(handle, record, field, double_value)) return 1;
422 break;
423
424 case FTLogical:
425 logical_value = PyObject_IsTrue(value);
426 if (logical_value == -1) return 0;
427 if (DBFWriteLogicalAttribute(handle, record, field, logical_value ? 'T' : 'F')) return 1;
428 break;
429
430 default:
431 PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
432 return 0;
433 }
434 }
435
436 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_attribute(DBFFileObject* self, PyObject* args)
443 {
444 int record, field;
445 PyObject* value;
446 int type;
447
448 if (!PyArg_ParseTuple(args, "iiO:write_attribute", &record, &field, &value)) return NULL;
449
450 if (field < 0 || field >= DBFGetFieldCount(self->handle))
451 {
452 PyErr_Format(PyExc_ValueError,
453 "field index %d out of bounds (field count: %d)",
454 field, DBFGetFieldCount(self->handle));
455 return NULL;
456 }
457
458 type = DBFGetFieldInfo(self->handle, field, NULL, NULL, NULL);
459 if (!do_write_attribute(self->handle, record, field, type, value)) return NULL;
460 Py_RETURN_NONE;
461 }
462
463
464
465 static PyObject* dbffile_write_record(DBFFileObject* self, PyObject* args)
466 {
467 int record;
468 PyObject* record_object;
469 int i, num_fields;
470
471 int type;
472 char name[12];
473 PyObject* value = NULL;
474
475 if (!PyArg_ParseTuple(args, "iO:write_record", &record, &record_object)) return NULL;
476
477 num_fields = DBFGetFieldCount(self->handle);
478
479 /* mimic ShapeFile functionality where id = -1 means appending */
480 if (record == -1)
481 {
482 record = num_fields;
483 }
484
485 if (PySequence_Check(record_object))
486 {
487 /* It's a sequence object. Iterate through all items in the
488 * sequence and write them to the appropriate field.
489 */
490 if (PySequence_Length(record_object) != num_fields)
491 {
492 PyErr_SetString(PyExc_TypeError, "record must have one item for each field");
493 return NULL;
494 }
495 for (i = 0; i < num_fields; ++i)
496 {
497 type = DBFGetFieldInfo(self->handle, i, NULL, NULL, NULL);
498 value = PySequence_GetItem(record_object, i);
499 if (!value) return NULL;
500 if (!do_write_attribute(self->handle, record, i, type, value))
501 {
502 Py_DECREF(value);
503 return NULL;
504 }
505 Py_DECREF(value);
506 }
507 }
508 else
509 {
510 /* It's a dictionary-like object. Iterate over the names of the
511 * known fields and write the corresponding item
512 */
513 for (i = 0; i < num_fields; ++i)
514 {
515 name[0] = '\0';
516 type = DBFGetFieldInfo(self->handle, i, name, NULL, NULL);
517 value = PyDict_GetItemString(record_object, name);
518 if (value && !do_write_attribute(self->handle, record, i, type, value)) return NULL;
519 }
520 }
521
522 return PyInt_FromLong((long)record);
523 }
524
525
526
527 static PyObject* dbffile_repr(DBFFileObject* self)
528 {
529 /* TODO: it would be nice to do something like "dbflib.DBFFile(filename, mode)" instead */
530 return PyString_FromFormat("<dbflib.DBFFile object at %p>", self->handle);
531 }
532
533
534
535 /* The commit method implementation
536 *
537 * The method relies on the DBFUpdateHeader method which is not
538 * available in shapelib <= 1.2.10. setup.py defines
539 * HAVE_UPDATE_HEADER's value depending on whether the function is
540 * available in the shapelib version the code is compiled with.
541 */
542 #if HAVE_UPDATE_HEADER
543 static PyObject* dbffile_commit(DBFFileObject* self)
544 {
545 DBFUpdateHeader(self->handle);
546 Py_RETURN_NONE;
547 }
548 #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[] =
562 {
563 {"close", (PyCFunction)dbffile_close, METH_NOARGS,
564 "close() -> None\n\n"
565 "closes DBFFile"},
566 {"field_count", (PyCFunction)dbffile_field_count, METH_NOARGS,
567 "field_count() -> integer\n\n"
568 "returns number of fields currently defined"},
569 {"record_count", (PyCFunction)dbffile_record_count, METH_NOARGS,
570 "record_count() -> integer\n\n"
571 "returns number of records that currently exist"},
572 {"field_info", (PyCFunction)dbffile_field_info, METH_VARARGS,
573 "field_info(field_index) -> (type, name, width, decimals)\n\n"
574 "returns info of a field as a tuple with:\n"
575 "- type: the type of the field corresponding to the integer value of one "
576 " of the constants FTString, FTInteger, ...\n"
577 "- name: the name of the field as a string\n"
578 "- 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,
581 "add_field(type, name, width, decimals) -> field_index\n\n"
582 "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 "
584 " of the constants FTString, FTInteger, ...\n"
585 "- name: the name of the field as a string\n"
586 "- 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,
589 "read_attribute(record_index, field_index) -> value\n\n"
590 "returns the value of one field of a record"},
591 {"read_record", (PyCFunction)dbffile_read_record, METH_VARARGS,
592 "read_record(record_index) -> dict\n\n"
593 "returns an entire record as a dictionary of field names and values"},
594 {"write_attribute", (PyCFunction)dbffile_write_attribute, METH_VARARGS,
595 "write_attribute(record_index, field_index, new_value)\n"
596 "writes a single field of a record"},
597 {"write_record", (PyCFunction)dbffile_write_record, METH_VARARGS,
598 "write_record(record_index, record) -> record_index\n\n"
599 "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, "
601 "or a sequence that must have an item for every field (length = field_count())"},
602 #if HAVE_UPDATE_HEADER
603 {"commit", (PyCFunction)dbffile_commit, METH_NOARGS,
604 "commit() -> None"},
605 #endif
606 {NULL}
607 };
608
609
610
611 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}
617 };
618
619
620
621 static PyTypeObject DBFFileType = PYSHAPELIB_DEFINE_TYPE(DBFFileObject, dbffile, "shapelib.DBFFile", 0);
622
623
624
625 /* --- dbflib -------------------------------------------------------------------------------------------------------- */
626
627 static PyObject* dbflib_open(PyObject* module, PyObject* args)
628 {
629 return PyObject_CallObject((PyObject*)&DBFFileType, args);
630 }
631
632
633
634 static PyObject* dbflib_create(PyObject* module, PyObject* args)
635 {
636 char* file;
637 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 (!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);
677 if (!result)
678 {
679 DBFClose(handle);
680 return PyErr_NoMemory();
681 }
682
683 result->handle = handle;
684 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 PyErr_SetString(PyExc_ValueError, "invalid driver id");
700 return NULL;
701 }
702 return PyString_FromString(codecs[ldid]);
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[] =
724 {
725 {"open", (PyCFunction)dbflib_open, METH_VARARGS,
726 "open(name [, mode]) -> DBFFile\n\n"
727 "opens a DBFFile" },
728 {"create", (PyCFunction)dbflib_create, METH_VARARGS,
729 "create(name [, language_driver]) -> DBFFile\n\n"
730 "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}
740 };
741
742
743 PyMODINIT_FUNC initdbflib(void)
744 {
745 int i;
746
747 PyObject* module = Py_InitModule("dbflib", dbflib_methods);
748 if (!module) return;
749
750 PYSHAPELIB_ADD_TYPE(DBFFileType, "DBFFile");
751
752 PYSHAPELIB_ADD_CONSTANT(FTString);
753 PYSHAPELIB_ADD_CONSTANT(FTInteger);
754 PYSHAPELIB_ADD_CONSTANT(FTDouble);
755 PYSHAPELIB_ADD_CONSTANT(FTLogical);
756 PYSHAPELIB_ADD_CONSTANT(FTInvalid);
757 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 }

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26