[Thuban-commits] r2752 - in branches/WIP-pyshapelib-bramz/libraries: pyshapelib shapelib
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Apr 11 01:45:01 CEST 2007
Author: bramz
Date: 2007-04-11 01:45:00 +0200 (Wed, 11 Apr 2007)
New Revision: 2752
Modified:
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py
branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c
branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h
Log:
attempt to add support for Unicode and Language Driver ID (LDID) support in dbflib
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog 2007-03-28 23:30:15 UTC (rev 2751)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog 2007-04-10 23:45:00 UTC (rev 2752)
@@ -1,3 +1,30 @@
+2007-04-11 Bram de Greve <bram.degreve at intec.ugent.be>
+
+ * dbflibmodule.c, pyshapelib_common.h, setup.py: attempt to add support for
+ Unicode and Language Driver ID (LDID) support in dbflib. Before the strings
+ are send to the underlying shapelib, they are encoded using the code page
+ specified by the database's LDID if present. To know this LDID requires
+ some unofficial modifications to maptools' shapelib. Backwards
+ compatibility is ensured by detecting if this field is present and setting
+ HAVE_LANGUAGE_DRIVER accordingly in setup.py. In absence of the LDID,
+ dbflib assumes a Windows ANSI codepage (cp1252).
+ New or modified functions/attributes of the DBFFile class:
+ - read_record(...), DBFFile.read_attribute(...): modified, now return
+ Unicode strings.
+ - write_record(...) and write_field(...): modified, now accept both regular
+ and Unicode strings but both are encoded.
+ - language_driver (read-only): new, the numerical value of the LDID
+ (exists only if HAVE_LANGUAGE_DRIVER == 1)
+ New or modified functions/constants of the dbflib module:
+ - language_driver_codec(...): added, translates a numerical LDID into the
+ string name of the Python codec used to encode/decode the strings.
+ (exists only if HAVE_LANGUAGE_DRIVER == 1)
+ - language_driver_name(...): added, translates a numerical LDID into a string
+ representing the corresponding constant.
+ (exists only if HAVE_LANGUAGE_DRIVER == 1)
+ - LDID_NOT_SET, LDID_DOS_USA, ...: constants representing language drivers.
+ (existsonly if HAVE_LANGUAGE_DRIVER == 1)
+
2007-03-29 Bram de Greve <bram.degreve at intec.ugent.be>
* shapelibmodule.c, dbflibmodule.c, pyshapelib_common.h: added support for
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c 2007-03-28 23:30:15 UTC (rev 2751)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c 2007-04-10 23:45:00 UTC (rev 2752)
@@ -1,5 +1,93 @@
+/* Copyright (c) 2001, 2002, 2007 by Intevation GmbH
+ * Authors:
+ * Bram de Greve <bram.degreve at intec.ugent.be>
+ * Bernhard Herzog <bh at intevation.de>
+ *
+ * This program is free software under the GPL (>=v2)
+ * Read the file COPYING coming with Thuban for details.
+ */
+
#include "pyshapelib_common.h"
+/* UNICODE & LANGUAGE DRIVER SUPPORT FOR DBFLIB
+ *
+ * When writing Unicode objects to a dbflib database, the unicode has to be
+ * encoded in 8-bit characters using a code page. This code page is indentified
+ * by the Language Driver ID (LDID) field in the database header.
+ *
+ * At this moment, this need unofficial modifications of the maptools shapelib
+ * library because they do not read the LDID. No patch has been submitted yet,
+ * but the version contained in the Thuban source tree incorporates the required
+ * modifications.
+ *
+ * pyshapelib is designed to compile with either the patched or unpatched shapelib
+ * by defining HAVE_LANGUAGE_DRIVER as true or false respectively. In the latter
+ * case, a Windows ANSI code page (cp1252) is assumed
+ */
+ #if HAVE_LANGUAGE_DRIVER
+
+#define PYSHAPELIB_NUM_LANGUAGE_DRIVERS 256
+
+#define PYSHAPELIB_ADD_LANGUAGE_DRIVER(ldid, codec, name)\
+ codecs[ldid] = codec;\
+ drivers[ldid] = "LDID_" name;\
+ PyModule_AddIntConstant(module, "LDID_" name, ldid)
+
+static char* codecs[PYSHAPELIB_NUM_LANGUAGE_DRIVERS];
+static char* drivers[PYSHAPELIB_NUM_LANGUAGE_DRIVERS];
+
+#endif
+
+
+
+/** Determine name of Python's built-in codec
+ */
+static char* get_codec(DBFHandle handle)
+{
+#if HAVE_LANGUAGE_DRIVER
+ if (!codecs[handle->nLanguageDriver])
+ {
+ PyErr_Format(PyExc_ValueError, "Language Driver ID %d not recognized", handle->nLanguageDriver);
+ }
+ return codecs[handle->nLanguageDriver];
+#else
+ return "cp1252";
+#endif
+}
+
+
+
+/** decode to unicode object
+ */
+static PyObject* decode_string(DBFHandle handle, const char* string)
+{
+ char* codec = get_codec(handle);
+ if (!codec) return NULL;
+ return PyUnicode_Decode(string, strlen(string), codec, NULL);
+}
+
+/** encode unicode object to normal Python string object
+ */
+static PyObject* encode_string(DBFHandle handle, PyObject* string)
+{
+ char* codec = get_codec(handle);
+ if (!codec) return NULL;
+
+ if (PyString_Check(string))
+ {
+ return PyString_AsEncodedObject(string, codec, NULL);
+ }
+ if (PyUnicode_Check(string))
+ {
+ return PyUnicode_AsEncodedString(string, codec, NULL);
+ }
+
+ PyErr_SetString(PyExc_TypeError, "value is neither a string or unicode object");
+ return NULL;
+}
+
+
+
/* --- DBFFile ------------------------------------------------------------------------------------------------------- */
typedef struct {
@@ -158,7 +246,7 @@
static PyObject* do_read_attribute(DBFHandle handle, int record, int field, char * name)
{
int type, width;
- const char* temp;
+ const char* string;
type = DBFGetFieldInfo(handle, field, name, &width, NULL);
/* For strings NULL and the empty string are indistinguishable
@@ -175,8 +263,8 @@
switch (type)
{
case FTString:
- temp = DBFReadStringAttribute(handle, record, field);
- if (temp) return PyString_FromString(temp);
+ string = DBFReadStringAttribute(handle, record, field);
+ if (string) return decode_string(handle, string);
case FTInteger:
return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));
@@ -185,10 +273,10 @@
return PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, field));
case FTLogical:
- temp = DBFReadLogicalAttribute(handle, record, field);
- if (temp)
+ string = DBFReadLogicalAttribute(handle, record, field);
+ if (string)
{
- switch (temp[0])
+ switch (string[0])
{
case 'F':
case 'N':
@@ -290,6 +378,7 @@
/* write a single field of a record. */
static int do_write_field(DBFHandle handle, int record, int field, int type, PyObject* value)
{
+ PyObject* encoded_string = NULL;
char * string_value;
int int_value;
double double_value;
@@ -304,9 +393,20 @@
switch (type)
{
case FTString:
- string_value = PyString_AsString(value);
- if (!string_value) return 0;
- if (DBFWriteStringAttribute(handle, record, field, string_value)) return 1;
+ encoded_string = encode_string(handle, value);
+ if (!encoded_string) return 0;
+ string_value = PyString_AsString(encoded_string);
+ if (!string_value)
+ {
+ Py_DECREF(encoded_string);
+ return 0;
+ }
+ if (DBFWriteStringAttribute(handle, record, field, string_value))
+ {
+ Py_DECREF(encoded_string);
+ return 1;
+ }
+ Py_DECREF(encoded_string);
break;
case FTInteger:
@@ -448,7 +548,16 @@
#endif
+#if HAVE_LANGUAGE_DRIVER
+static PyObject* dbffile_language_driver(DBFFileObject* self, void* closure)
+{
+ return PyInt_FromLong((long)self->handle->nLanguageDriver);
+}
+
+#endif
+
+
static struct PyMethodDef dbffile_methods[] =
{
{"close", (PyCFunction)dbffile_close, METH_NOARGS,
@@ -501,6 +610,9 @@
static struct PyGetSetDef dbffile_getsetters[] =
{
+#if HAVE_LANGUAGE_DRIVER
+ {"language_driver", (getter)dbffile_language_driver, NULL, "Language Driver ID (read-only)" },
+#endif
{NULL}
};
@@ -574,21 +686,64 @@
+#if HAVE_LANGUAGE_DRIVER
+
+/** translate a numeric Language Driver ID to the name of Python's codec.
+ */
+static PyObject* dbflib_language_driver_codec(PyObject* module, PyObject* args)
+{
+ int ldid;
+ if (!PyArg_ParseTuple(args, "i:language_driver_name", &ldid)) return NULL;
+ if (ldid < 0 || ldid >= PYSHAPELIB_NUM_LANGUAGE_DRIVERS || !codecs[ldid])
+ {
+ PyErr_SetString(PyExc_ValueError, "invalid driver id");
+ return NULL;
+ }
+ return PyString_FromString(codecs[ldid]);
+}
+
+/** translate a numeric Language Driver ID to a string represting its constant.
+ */
+static PyObject* dbflib_language_driver_name(PyObject* module, PyObject* args)
+{
+ int ldid;
+ if (!PyArg_ParseTuple(args, "i:language_driver_name", &ldid)) return NULL;
+ if (ldid < 0 || ldid >= PYSHAPELIB_NUM_LANGUAGE_DRIVERS || !drivers[ldid])
+ {
+ PyErr_SetString(PyExc_ValueError, "invalid driver id");
+ return NULL;
+ }
+ return PyString_FromString(drivers[ldid]);
+}
+
+#endif
+
+
+
static struct PyMethodDef dbflib_methods[] =
{
{"open", (PyCFunction)dbflib_open, METH_VARARGS,
"open(name [, mode]) -> DBFFile\n\n"
"opens a DBFFile" },
{"create", (PyCFunction)dbflib_create, METH_VARARGS,
- "create(name) -> DBFFile\n\n"
- "create a DBFFile" },
+ "create(name [, language_driver]) -> DBFFile\n\n"
+ "create a DBFFile " },
+#if HAVE_LANGUAGE_DRIVER
+ {"language_driver_codec", (PyCFunction)dbflib_language_driver_codec, METH_VARARGS,
+ "language_driver_codec(driver_id) -> string\n\n"
+ "translate language driver id into the name of the Python's codec used as code page." },
+ {"language_driver_name", (PyCFunction)dbflib_language_driver_name, METH_VARARGS,
+ "language_driver_name(driver_id) -> string\n\n"
+ "translate language driver id into a string." },
+#endif
{NULL}
};
-
PyMODINIT_FUNC initdbflib(void)
{
+ int i;
+
PyObject* module = Py_InitModule("dbflib", dbflib_methods);
if (!module) return;
@@ -600,4 +755,86 @@
PYSHAPELIB_ADD_CONSTANT(FTLogical);
PYSHAPELIB_ADD_CONSTANT(FTInvalid);
PyModule_AddIntConstant(module, "_have_commit", HAVE_UPDATE_HEADER);
+
+#if HAVE_LANGUAGE_DRIVER
+ /* table compiled from these resources:
+ * http://www.clicketyclick.dk/databases/xbase/format/dbf.html
+ * http://www.esrinl.com/content/file.asp?id=307
+ * http://msdn2.microsoft.com/en-us/library/aa975345(VS.71).aspx
+ */
+ for (i = 0; i < PYSHAPELIB_NUM_LANGUAGE_DRIVERS; ++i)
+ {
+ codecs[i] = NULL;
+ drivers[i] = NULL;
+ }
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x00, "cp1252", "NOT_SET");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x01, "cp437", "DOS_USA");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x02, "cp850", "DOS_INTERNATIONAL");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x03, "cp1252", "WINDOWS_ANSI");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x04, "mac_roman", "STANDARD_MACINTOSH");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x08, "cp865", "DANISH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x09, "cp437", "DUTCH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0a, "cp850", "DUTCH_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0b, "cp437", "FINNISH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0d, "cp437", "FRENCH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0e, "cp850", "FRENCH_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0f, "cp437", "GERMAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x10, "cp850", "GERMAN_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x11, "cp437", "ITALIAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x12, "cp850", "ITALIAN_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x13, "cp932", "JAPANESE_SHIFT_JIS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x14, "cp850", "SPANISH_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x15, "cp437", "SWEDISH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x16, "cp850", "SWEDISH_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x17, "cp865", "NORWEGIAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x18, "cp437", "SPANISH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x19, "cp437", "ENGLISH_BRITAIN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1a, "cp850", "ENGLISH_BRITAIN_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x0b, "cp437", "ENGLISH_US_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1c, "cp863", "FRENCH_CANADA_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1d, "cp850", "FRENCH_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x1f, "cp852", "CZECH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x22, "cp852", "HUNGARIAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x23, "cp852", "POLISH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x24, "cp860", "PORTUGUESE_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x25, "cp850", "PORTUGUESE_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x26, "cp866", "RUSSIAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x37, "cp850", "ENGLISH_US_OEM_2");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x40, "cp852", "ROMANIAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4d, "cp936", "CHINESE_GBK_PRC");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4e, "cp949", "KOREAN_ANSI_OEM);");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x4f, "cp950", "CHINESE_BIG5_TAIWAN");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x50, "cp874", "THAI_ANSI_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x57, "cp1252", "ESRI_ANSI");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x58, "cp1252", "WESTERN_EUROPEAN_ANSI");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x59, "cp1252", "SPANISH_ANSI");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x64, "cp852", "EASTERN_EUROPEAN_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x65, "cp866", "RUSSIAN_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x66, "cp865", "NORDIC_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x67, "cp861", "ICELANDIC_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x68, "cp895", "CZECH_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x69, "cp620", "POLISH_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6a, "cp737", "GREEK_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6b, "cp857", "TURKISH_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x6c, "cp863", "FRENCH_CANADA_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x78, "cp950", "TAIWAN_BIG5");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x79, "cp949", "HANGUL_WANSUG");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7a, "cp936", "PRC_GBK");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7b, "cp932", "JAPANESE_SHIFT_JIS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7c, "cp874", "THAI_WINDOWS_MSDOS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7d, "cp1255", "HEBREW_WINDOWS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x7e, "cp1256", "ARABIC_WINDOWS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x86, "cp737", "GREEK_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x87, "cp852", "SLOVENIAN_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x88, "cp857", "TURKISH_OEM");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x96, "mac_cyrillic", "RUSSIAN_MACINTOSH");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x97, "mac_latin2", "EASTERN_EUROPEAN_MACINTOSH");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0x98, "mac_greek", "GREEK_MACINTOSH");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xc8, "cp1250", "EASTERN_EUROPEAN_WINDOWS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xc9, "cp1251", "RUSSIAN_WINDOWS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xca, "cp1254", "TURKISH_WINDOWS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xcb, "cp1253", "GREEK_WINDOWS");
+ PYSHAPELIB_ADD_LANGUAGE_DRIVER(0xcc, "cp1257", "BALTIC_WINDOWS");
+#endif
+
}
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h 2007-03-28 23:30:15 UTC (rev 2751)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h 2007-04-10 23:45:00 UTC (rev 2752)
@@ -1,84 +1,106 @@
-#ifndef PYSHAPELIB_H
-#define PYSHAPELIB_H
-
-#include <Python.h>
-#include <structmember.h>
-#include "shapefil.h"
-#include "pyshapelib_api.h"
-
+/* Copyright (c) 2007 by Intevation GmbH
+ * Authors:
+ * Bram de Greve <bram.degreve at intec.ugent.be>
+ *
+ * This program is free software under the GPL (>=v2)
+ * Read the file COPYING coming with Thuban for details.
+ */
+
+#ifndef PYSHAPELIB_H
+#define PYSHAPELIB_H
+
+#include <Python.h>
+#include <structmember.h>
+#include "shapefil.h"
+#include "pyshapelib_api.h"
+
+/* WIDE-CHARACTER FILENAME SUPPORT FOR WINDOWS
+ *
+ * pyshapelib can support full Unicode strings as filename on the Windows platform
+ * trough the wide-character version of the Win API. At this moment, however, this
+ * needs unofficial modifications to the shapelib library to be able to use this API.
+ *
+ * A ticket has been made in the maptools Bugzilla with patches for the 1.2.10 release
+ * of shapelib: http://bugzilla.maptools.org/show_bug.cgi?id=1692
+ *
+ * The version of shapelib that is contained in the thuban source tree already contains
+ * these modifications.
+ */
#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
/* Need GetVersion to see if on NT so safe to use _wfopen */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
-
-/* helper to export constants (macros) to Python.
- * The constant in Python will have the same name as in C
- */
-#define PYSHAPELIB_ADD_CONSTANT(constant) PyModule_AddIntConstant(module, #constant, constant)
-
-/* helper to define the type object.
- *
- * This assumes quite a few things about different things being available and their name.
- * For example, if prefix = foo, then there should be a deallocation function called foo_dealloc.
- * See the macro itself for other examples.
- */
-#define PYSHAPELIB_DEFINE_TYPE(object, prefix, name, doc) \
-{ \
- PyObject_HEAD_INIT(NULL) \
- 0, /*ob_size*/ \
- name, /*tp_name*/ \
- sizeof(object), /*tp_basicsize*/ \
- 0, /*tp_itemsize*/ \
- (destructor) prefix ## _dealloc, /*tp_dealloc*/ \
- 0, /*tp_print*/ \
- 0, /*tp_getattr*/ \
- 0, /*tp_setattr*/ \
- 0, /*tp_compare*/ \
- (reprfunc) prefix ## _repr, /*tp_repr*/ \
- 0, /*tp_as_number*/ \
- 0, /*tp_as_sequence*/ \
- 0, /*tp_as_mapping*/ \
- 0, /*tp_hash */ \
- 0, /*tp_call*/ \
- 0, /*tp_str*/ \
- 0, /*tp_getattro*/ \
- 0, /*tp_setattro*/ \
- 0, /*tp_as_buffer*/ \
- Py_TPFLAGS_DEFAULT, /*tp_flags*/ \
- doc, /* tp_doc */ \
- 0, /* tp_traverse */ \
- 0, /* tp_clear */ \
- 0, /* tp_richcompare */ \
- 0, /* tp_weaklistoffset */ \
- 0, /* tp_iter */ \
- 0, /* tp_iternext */ \
- prefix ## _methods, /* tp_methods */ \
- 0, /* tp_members */ \
- prefix ## _getsetters, /* tp_getset */ \
- 0, /* tp_base */ \
- 0, /* tp_dict */ \
- 0, /* tp_descr_get */ \
- 0, /* tp_descr_set */ \
- 0, /* tp_dictoffset */ \
- (initproc) prefix ## _init, /* tp_init */ \
- 0, /* tp_alloc */ \
- prefix ## _new, /* tp_new */ \
- } \
- /**/
-
-/* helper to add type to module.
- * Does a bit of the tedious bookkeeping for us
- */
-#define PYSHAPELIB_ADD_TYPE(type, name) \
- type.ob_type = &PyType_Type; \
- if (PyType_Ready(&type) >= 0) \
- { \
- Py_INCREF(&type); \
- PyModule_AddObject(module, name, (PyObject*)&type); \
- }
-
-#define PYSHAPELIB_NO_DATA_LIMIT 1e-38
-#define PYSHAPELIB_NO_DATA 0
-
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/* helper to export constants (macros) to Python.
+ * The constant in Python will have the same name as in C
+ */
+#define PYSHAPELIB_ADD_CONSTANT(constant) PyModule_AddIntConstant(module, #constant, constant)
+
+/* helper to define the type object.
+ *
+ * This assumes quite a few things about different things being available and their name.
+ * For example, if prefix = foo, then there should be a deallocation function called foo_dealloc.
+ * See the macro itself for other examples.
+ */
+#define PYSHAPELIB_DEFINE_TYPE(object, prefix, name, doc) \
+{ \
+ PyObject_HEAD_INIT(NULL) \
+ 0, /*ob_size*/ \
+ name, /*tp_name*/ \
+ sizeof(object), /*tp_basicsize*/ \
+ 0, /*tp_itemsize*/ \
+ (destructor) prefix ## _dealloc, /*tp_dealloc*/ \
+ 0, /*tp_print*/ \
+ 0, /*tp_getattr*/ \
+ 0, /*tp_setattr*/ \
+ 0, /*tp_compare*/ \
+ (reprfunc) prefix ## _repr, /*tp_repr*/ \
+ 0, /*tp_as_number*/ \
+ 0, /*tp_as_sequence*/ \
+ 0, /*tp_as_mapping*/ \
+ 0, /*tp_hash */ \
+ 0, /*tp_call*/ \
+ 0, /*tp_str*/ \
+ 0, /*tp_getattro*/ \
+ 0, /*tp_setattro*/ \
+ 0, /*tp_as_buffer*/ \
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/ \
+ doc, /* tp_doc */ \
+ 0, /* tp_traverse */ \
+ 0, /* tp_clear */ \
+ 0, /* tp_richcompare */ \
+ 0, /* tp_weaklistoffset */ \
+ 0, /* tp_iter */ \
+ 0, /* tp_iternext */ \
+ prefix ## _methods, /* tp_methods */ \
+ 0, /* tp_members */ \
+ prefix ## _getsetters, /* tp_getset */ \
+ 0, /* tp_base */ \
+ 0, /* tp_dict */ \
+ 0, /* tp_descr_get */ \
+ 0, /* tp_descr_set */ \
+ 0, /* tp_dictoffset */ \
+ (initproc) prefix ## _init, /* tp_init */ \
+ 0, /* tp_alloc */ \
+ prefix ## _new, /* tp_new */ \
+ } \
+ /**/
+
+/* helper to add type to module.
+ * Does a bit of the tedious bookkeeping for us
+ */
+#define PYSHAPELIB_ADD_TYPE(type, name) \
+ type.ob_type = &PyType_Type; \
+ if (PyType_Ready(&type) >= 0) \
+ { \
+ Py_INCREF(&type); \
+ PyModule_AddObject(module, name, (PyObject*)&type); \
+ }
+
+#define PYSHAPELIB_NO_DATA_LIMIT 1e-38
+#define PYSHAPELIB_NO_DATA 0
+
#endif
\ No newline at end of file
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py 2007-03-28 23:30:15 UTC (rev 2751)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/setup.py 2007-04-10 23:45:00 UTC (rev 2752)
@@ -21,51 +21,60 @@
# filenames exclusively, so we use posix conventions when making
# filenames for distutils.
for shp_dir in ["..", "../shapelib", "../../../../../../shapelib"]:
- if (os.path.isdir(convert_path(shp_dir))
- and os.path.exists(os.path.join(convert_path(shp_dir), "shpopen.c"))):
- # shp_dir contains shpopen.c, so assume it's the directory with
- # the shapefile library to use
- break
+ if (os.path.isdir(convert_path(shp_dir))
+ and os.path.exists(os.path.join(convert_path(shp_dir), "shpopen.c"))):
+ # shp_dir contains shpopen.c, so assume it's the directory with
+ # the shapefile library to use
+ break
else:
- print >>sys.stderr, "no shapelib directory found"
- sys.exit(1)
+ print >>sys.stderr, "no shapelib directory found"
+ sys.exit(1)
def dbf_macros():
- """Return the macros to define when compiling the dbflib wrapper.
+ """Return the macros to define when compiling the dbflib wrapper.
- The returned list specifies one macro, HAVE_UPDATE_HEADER, which is
- '1' if the dbflib version we will be compiling with has the
- DBFUpdateHeader function and '0' otherwise. To check whether
- DBFUpdateHeader is available, we scan shapefil.h for the string
- 'DBFUpdateHeader'.
- """
- f = open(convert_path(shp_dir + "/shapefil.h"))
- contents = f.read()
- f.close()
- if contents.find("DBFUpdateHeader") >= 0:
- return [("HAVE_UPDATE_HEADER", "1")]
- else:
- return [("HAVE_UPDATE_HEADER", "0")]
+ The returned list specifies following macros:
+ - HAVE_UPDATE_HEADER, which is
+ '1' if the dbflib version we will be compiling with has the
+ DBFUpdateHeader function and '0' otherwise. To check whether
+ DBFUpdateHeader is available, we scan shapefil.h for the string
+ 'DBFUpdateHeader'.
+ - HAVE_LANGUAGE_DRIVER, whics is '1' if the dbflib version we will
+ compiling with has the nLanguageDriver field in DBFInfo and '0' otherwise.
+ Again, shapefil.h is scanned to check this.
+ """
+ f = open(convert_path(shp_dir + "/shapefil.h"))
+ contents = f.read()
+ f.close()
+
+ def have(keyword):
+ if keyword in contents:
+ return "1"
+ return 0
+
+ return [
+ ("HAVE_UPDATE_HEADER", have("DBFUpdateHeader")),
+ ("HAVE_LANGUAGE_DRIVER", have("nLanguageDriver"))]
extensions = [Extension("shapelib",
- ["shapelibmodule.c",
- shp_dir + "/shpopen.c",
- shp_dir + "/shptree.c"],
- include_dirs = [shp_dir]),
- Extension("shptree",
- ["shptreemodule.c"],
- include_dirs = [shp_dir]),
- Extension("dbflib",
- ["dbflibmodule.c",
- shp_dir + "/dbfopen.c"],
- include_dirs = [shp_dir],
- define_macros = dbf_macros())]
+ ["shapelibmodule.c",
+ shp_dir + "/shpopen.c",
+ shp_dir + "/shptree.c"],
+ include_dirs = [shp_dir]),
+ Extension("shptree",
+ ["shptreemodule.c"],
+ include_dirs = [shp_dir]),
+ Extension("dbflib",
+ ["dbflibmodule.c",
+ shp_dir + "/dbfopen.c"],
+ include_dirs = [shp_dir],
+ define_macros = dbf_macros())]
setup(name = "pyshapelib",
- version = "0.3",
- description = "Python bindings for shapelib",
- author = "Bernhard Herzog",
- author_email = "bh at intevation.de",
- url = "ftp:intevation.de/users/bh",
- ext_modules = extensions)
+ version = "0.3",
+ description = "Python bindings for shapelib",
+ author = "Bernhard Herzog",
+ author_email = "bh at intevation.de",
+ url = "ftp:intevation.de/users/bh",
+ ext_modules = extensions)
Modified: branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c 2007-03-28 23:30:15 UTC (rev 2751)
+++ branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c 2007-04-10 23:45:00 UTC (rev 2752)
@@ -339,6 +339,8 @@
abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
+ abyHeader[29] = (unsigned char) (psDBF->nLanguageDriver);
+
/* -------------------------------------------------------------------- */
/* Write the initial 32 byte file header, and all the field */
/* descriptions. */
@@ -580,6 +582,7 @@
psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
+ psDBF->nLanguageDriver = pabyBuf[29];
psDBF->nFields = nFields = (nHeadLen - 32) / 32;
@@ -828,6 +831,7 @@
psDBF->pszCurrentRecord = NULL;
psDBF->bNoHeader = TRUE;
+ psDBF->nLanguageDriver = 0x03; // ANSI
return( psDBF );
}
@@ -1709,7 +1713,7 @@
void SHPAPI_CALL
DBFCloneEmptyEx(DBFHandle psDBF, DBFHandle newDBF)
{
- if ( newDBF == NULL ) return ( NULL );
+ if ( newDBF == NULL ) return;
newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
Modified: branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h 2007-03-28 23:30:15 UTC (rev 2751)
+++ branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h 2007-04-10 23:45:00 UTC (rev 2752)
@@ -471,6 +471,7 @@
int bNoHeader;
int bUpdated;
+ int nLanguageDriver;
} DBFInfo;
typedef DBFInfo * DBFHandle;
More information about the Thuban-commits
mailing list