[Thuban-commits] r2751 - in branches/WIP-pyshapelib-bramz/libraries: pyshapelib shapelib

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Mar 29 01:30:18 CEST 2007


Author: bramz
Date: 2007-03-29 01:30:15 +0200 (Thu, 29 Mar 2007)
New Revision: 2751

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/shapelibmodule.c
   branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c
   branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h
   branches/WIP-pyshapelib-bramz/libraries/shapelib/shpopen.c
Log:
Added support for Win32 wide character file API.  Unicode filenames are now fully supported on the windows platform: for example exotic filenames like the greek letter pi (u"\u03c0").  However, this needed unofficial modifications in the C++ shapelib library.

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog	2007-03-28 23:30:15 UTC (rev 2751)
@@ -1,3 +1,16 @@
+2007-03-29	Bram de Greve <bram.degreve at intec.ugent.be>
+
+	* shapelibmodule.c, dbflibmodule.c, pyshapelib_common.h: added support for
+	Win32 wide character file API.  Unicode filenames are now fully supported
+	on the windows platform: for example exotic filenames like the greek letter
+	pi (u"\u03c0").  This is mostly mimicked from Python's fileobject.c, and
+	needed some severe changes in the C++ shapelib library to support the wide
+	filename API.  All XOpen and XCreate functions now have XOpenW and XCreateW
+	counterparts plus some common code has been split to XOpenEx and XCreateEx.
+	I hope these modifications might one day end up in an official shapelib
+	release.  Meanwhile, compatibility is guaranteed as the specific Unicode
+	code paths are not compiled if the modifications are not found.
+
 2007-03-22	Bram de Greve <bram.degreve at intec.ugent.be>
 
 	* shapelibmodule.c, dbflibmodule.c: in __init__ of ShapeFile and DBFFile,

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c	2007-03-28 23:30:15 UTC (rev 2751)
@@ -36,20 +36,54 @@
 */
 static int dbffile_init(DBFFileObject* self, PyObject* args, PyObject* kwds)
 {
-	char* file;
+	char* file = NULL;
 	char* mode = "rb";
 	static char *kwlist[] = {"name", "mode", NULL};
-	if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:__init__", kwlist, 
-		Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
-	
-	self->handle = DBFOpen(file, mode);	
+
+	DBFClose(self->handle);
+	self->handle = NULL;
+
+#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
+	if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
+		PyObject *wfile;
+		if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:DBFFile", kwlist, &wfile, &mode)) 
+		{
+			PyObject *wmode = PyUnicode_DecodeASCII(mode, strlen(mode), NULL);
+			if (!wmode) return -1;
+			self->handle = DBFOpenW(PyUnicode_AS_UNICODE(wfile), PyUnicode_AS_UNICODE(wmode));
+			Py_DECREF(wmode);
+			if (!self->handle)
+			{
+				PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
+				return -1;
+			}
+		} 
+		else 
+		{
+			/* Drop the argument parsing error as narrow
+			   strings are also valid. */
+			PyErr_Clear();
+		}
+	}
+#endif
+
 	if (!self->handle)
 	{
-		PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:DBFFile", kwlist, 
+			Py_FileSystemDefaultEncoding, &file, &mode)) return -1;	
+		self->handle = DBFOpen(file, mode);
+
+		if (!self->handle)
+		{
+			PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
+			PyMem_Free(file);
+			return -1;
+		}
+
+		PyMem_Free(file);
 	}
 
-	PyMem_Free(file);
-	return self->handle ? 0 : -1;
+	return 0;
 }
 
 
@@ -489,23 +523,52 @@
 {
 	char* file;
 	DBFFileObject* result;
+	DBFHandle handle = NULL;
+	int wideargument = 0;
+
+#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
+	if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
+		PyObject *wfile;
+		if (PyArg_ParseTuple(args, "U:create", &wfile)) 
+		{
+			wideargument = 1;
+			handle = DBFCreateW(PyUnicode_AS_UNICODE(wfile));
+			if (!handle)
+			{
+				PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
+				return NULL;
+			}
+		} 
+		else 
+		{
+			/* Drop the argument parsing error as narrow
+			   strings are also valid. */
+			PyErr_Clear();
+		}
+	}
+#endif
 	
-	if (!PyArg_ParseTuple(args, "et:create", Py_FileSystemDefaultEncoding, &file)) return NULL;
-	
+	if (!handle)
+	{
+		if (!PyArg_ParseTuple(args, "et:create", Py_FileSystemDefaultEncoding, &file)) return NULL;
+		handle = DBFCreate(file);
+		if (!handle)
+		{
+				PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
+				PyMem_Free(file);
+				return NULL;
+		}
+		PyMem_Free(file);
+	}
+
 	result = PyObject_New(DBFFileObject, &DBFFileType);
 	if (!result)
 	{
+		DBFClose(handle);
 		return PyErr_NoMemory();
 	}
 	
-	result->handle = DBFCreate(file);
-	if (!result->handle)
-	{
-		PyObject_Del((PyObject*)result);
-		PyErr_SetString(PyExc_RuntimeError, "Failed to create DBFFile");
-		return NULL;
-	}
-	
+	result->handle = handle;
 	return (PyObject*) result;
 }
 

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h	2007-03-28 23:30:15 UTC (rev 2751)
@@ -6,6 +6,12 @@
 #include "shapefil.h"
 #include "pyshapelib_api.h"
 
+#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
  */

Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c	2007-03-28 23:30:15 UTC (rev 2751)
@@ -547,22 +547,58 @@
  */
 static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds)
 {
-	char* file;
+	char* file = NULL;
 	char* mode = "rb";
 	static char *kwlist[] = {"name", "mode", NULL};
-	if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:__init__", kwlist, 
-		Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
-	
-	self->handle = SHPOpen(file, mode);
+
+	SHPClose(self->handle);
+	self->handle = NULL;
+
+#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
+	if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
+		PyObject *wfile;
+		if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:ShapeFile", kwlist, &wfile, &mode)) 
+		{
+			PyObject *wmode = PyUnicode_DecodeASCII(mode, strlen(mode), NULL);
+			if (!wmode) return -1;
+			self->handle = SHPOpenW(PyUnicode_AS_UNICODE(wfile), PyUnicode_AS_UNICODE(wmode));
+			Py_DECREF(wmode);
+			if (!self->handle)
+			{
+				PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
+				return -1;
+			}
+		} 
+		else 
+		{
+			/* Drop the argument parsing error as narrow
+			   strings are also valid. */
+			PyErr_Clear();
+		}
+	}
+#endif
+
 	if (!self->handle)
 	{
-		PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
+		if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:ShapeFile", kwlist, 
+			Py_FileSystemDefaultEncoding, &file, &mode)) return -1;	
+		self->handle = SHPOpen(file, mode);
+
+		if (!self->handle)
+		{
+			PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
+			PyMem_Free(file);
+			return -1;
+		}
+
+		PyMem_Free(file);
 	}
 
-	PyMem_Free(file);
-	return self->handle ? 0 : -1;
+	return 0;
 }
 
+
+
 static PyObject* shapefile_close(ShapeFileObject* self)
 {
 	SHPClose(self->handle);
@@ -570,6 +606,8 @@
 	Py_RETURN_NONE;
 }
 
+
+
 static PyObject* shapefile_info(ShapeFileObject* self)
 {
 	SHPHandle handle = self->handle;
@@ -579,6 +617,8 @@
 			handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
 }
 
+
+
 static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args)
 {
 	int index;
@@ -604,6 +644,8 @@
 	return (PyObject*) result;
 }
 
+
+
 static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args)
 {
 	int index, result;
@@ -680,26 +722,52 @@
 	char* file;
 	int type;
 	ShapeFileObject* result;
+	SHPHandle handle = NULL;
+	int wideargument = 0;
+
+#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES)
+	if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
+		PyObject *wfile;
+		if (PyArg_ParseTuple(args, "Ui:create", &wfile, &type)) 
+		{
+			wideargument = 1;
+			handle = SHPCreateW(PyUnicode_AS_UNICODE(wfile), type);
+			if (!handle)
+			{
+				PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile);
+				return NULL;
+			}
+		} 
+		else 
+		{
+			/* Drop the argument parsing error as narrow
+			   strings are also valid. */
+			PyErr_Clear();
+		}
+	}
+#endif
 	
-	if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL;
-	
+	if (!handle)
+	{
+		if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL;
+		handle = SHPCreate(file, type);
+		if (!handle)
+		{
+				PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
+				PyMem_Free(file);
+				return NULL;
+		}
+		PyMem_Free(file);
+	}
+
 	result = PyObject_New(ShapeFileObject, &ShapeFileType);
 	if (!result)
 	{
-		PyMem_Free(file);
+		SHPClose(handle);
 		return PyErr_NoMemory();
 	}
 	
-	result->handle = SHPCreate(file, type);
-	PyMem_Free(file);
-	
-	if (!result->handle)
-	{
-		PyObject_Del((PyObject*)result);
-		PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile");
-		return NULL;
-	}
-	
+	result->handle = handle;
 	return (PyObject*) result;
 }
 	

Modified: branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c	2007-03-28 23:30:15 UTC (rev 2751)
@@ -251,6 +251,10 @@
 #  define TRUE		1
 #endif
 
+#if defined(_WIN32) || defined(_WIN64)
+#	define MS_WINDOWS
+#endif
+
 static int	nStringFieldLen = 0;
 static char * pszStringField = NULL;
 
@@ -417,9 +421,8 @@
 DBFOpen( const char * pszFilename, const char * pszAccess )
 
 {
-    DBFHandle		psDBF;
-    unsigned char		*pabyBuf;
-    int			nFields, nHeadLen, nRecLen, iField, i;
+	FILE*		fp;
+    int			i;
     char		*pszBasename, *pszFullname;
 
 /* -------------------------------------------------------------------- */
@@ -453,24 +456,109 @@
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
     sprintf( pszFullname, "%s.dbf", pszBasename );
         
-    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
-    psDBF->fp = fopen( pszFullname, pszAccess );
+    fp = fopen( pszFullname, pszAccess );
 
-    if( psDBF->fp == NULL )
+    if( fp == NULL )
     {
         sprintf( pszFullname, "%s.DBF", pszBasename );
-        psDBF->fp = fopen(pszFullname, pszAccess );
+        fp = fopen(pszFullname, pszAccess );
     }
     
     free( pszBasename );
     free( pszFullname );
-    
-    if( psDBF->fp == NULL )
+
+	return DBFOpenEx( fp );
+}
+
+
+
+/************************************************************************/
+/*                              DBFOpenW()                              */
+/*                                                                      */
+/*      Open a .dbf file with a wide character filename                 */
+/************************************************************************/
+
+#ifdef SHPAPI_HAS_WIDE
+
+DBFHandle SHPAPI_CALL
+DBFOpenW( const wchar_t * pszFilename, const wchar_t * pszAccess )
+
+{
+    FILE*		fp;
+    int			i;
+    wchar_t		*pszBasename, *pszFullname;
+
+/* -------------------------------------------------------------------- */
+/*      We only allow the access strings "rb" and "r+".                  */
+/* -------------------------------------------------------------------- */
+    if( wcscmp(pszAccess,L"r") != 0 && wcscmp(pszAccess,L"r+") != 0 
+        && wcscmp(pszAccess,L"rb") != 0 && wcscmp(pszAccess,L"rb+") != 0
+        && wcscmp(pszAccess,L"r+b") != 0 )
+        return( NULL );
+
+    if( wcscmp(pszAccess,L"r") == 0 )
+        pszAccess = L"rb";
+ 
+    if( wcscmp(pszAccess,L"r+") == 0 )
+        pszAccess = L"rb+";
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszFilename)+5));
+    wcscpy( pszBasename, pszFilename );
+    for( i = wcslen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/'
+	       && pszBasename[i] != L'\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == L'.' )
+        pszBasename[i] = L'\0';
+
+    pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5));
+    swprintf( pszFullname, L"%s.dbf", pszBasename );
+        
+    fp = _wfopen( pszFullname, pszAccess );
+
+    if( fp == NULL )
     {
-        free( psDBF );
-        return( NULL );
+        swprintf( pszFullname, L"%s.DBF", pszBasename );
+        fp = _wfopen(pszFullname, pszAccess );
     }
+    
+    free( pszBasename );
+    free( pszFullname );
 
+	return DBFOpenEx( fp );
+}
+
+#endif
+
+
+
+/************************************************************************/
+/*                              DBFOpenEx()                             */
+/*                                                                      */
+/*      Open a .dbf file from a freshly opened FILE                     */
+/************************************************************************/
+   
+DBFHandle SHPAPI_CALL
+DBFOpenEx( FILE* fp )
+
+{
+    unsigned char	*pabyBuf;
+    int			nFields, nHeadLen, nRecLen, iField;
+	DBFHandle	psDBF = NULL;
+
+	if( fp == NULL )
+	{
+		return( NULL );
+	}
+
+    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
+	psDBF->fp = fp;
+
     psDBF->bNoHeader = FALSE;
     psDBF->nCurrentRecord = -1;
     psDBF->bCurrentRecordModified = FALSE;
@@ -607,7 +695,6 @@
 DBFCreate( const char * pszFilename )
 
 {
-    DBFHandle	psDBF;
     FILE	*fp;
     char	*pszFullname, *pszBasename;
     int		i;
@@ -646,7 +733,80 @@
 
     free( pszFullname );
 
+	return DBFCreateEx( fp );
+}
+
+
+
+/************************************************************************/
+/*                             DBFCreateW()                             */
+/*                                                                      */
+/*      Create a new .dbf file with a wide character filename           */
+/************************************************************************/
+
+#ifdef SHPAPI_HAS_WIDE
+
+DBFHandle SHPAPI_CALL
+DBFCreateW( const wchar_t * pszFilename )
+
+{
+    FILE	*fp;
+    wchar_t	*pszFullname, *pszBasename;
+    int		i;
+
 /* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszFilename)+5));
+    wcscpy( pszBasename, pszFilename );
+    for( i = wcslen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/'
+	       && pszBasename[i] != L'\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == L'.' )
+        pszBasename[i] = L'\0';
+
+    pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5));
+    swprintf( pszFullname, L"%s.dbf", pszBasename );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*      Create the file.                                                */
+/* -------------------------------------------------------------------- */
+    fp = _wfopen( pszFullname, L"wb" );
+    if( fp == NULL )
+        return( NULL );
+
+    fputc( 0, fp );
+    fclose( fp );
+
+    fp = _wfopen( pszFullname, L"rb+" );
+    if( fp == NULL )
+        return( NULL );
+
+    free( pszFullname );
+
+	return DBFCreateEx( fp );
+}
+
+#endif
+
+
+/************************************************************************/
+/*                             DBFCreateEx()                            */
+/*                                                                      */
+/*      Create a new .dbf file from a freshly created file              */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreateEx( FILE* fp )
+
+{
+    DBFHandle	psDBF;
+
+/* -------------------------------------------------------------------- */
 /*	Create the info structure.					*/
 /* -------------------------------------------------------------------- */
     psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
@@ -672,6 +832,8 @@
     return( psDBF );
 }
 
+
+
 /************************************************************************/
 /*                            DBFAddField()                             */
 /*                                                                      */
@@ -1499,6 +1661,54 @@
     DBFHandle	newDBF;
 
    newDBF = DBFCreate ( pszFilename );
+   if ( newDBF == NULL ) return ( NULL );
+
+   DBFCloneEmptyEx( psDBF, newDBF );
+
+   DBFClose( newDBF );      
+   newDBF = DBFOpen ( pszFilename, "rb+" );
+
+   return ( newDBF );
+}
+
+
+
+
+/************************************************************************/
+/*                          DBFCloneEmptyW                              */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+#ifdef SHPAPI_HAS_WIDE
+
+DBFHandle SHPAPI_CALL
+DBFCloneEmptyW(DBFHandle psDBF, const wchar_t * pszFilename ) 
+{
+    DBFHandle	newDBF;
+
+   newDBF = DBFCreateW ( pszFilename );
+   if ( newDBF == NULL ) return ( NULL );
+
+   DBFCloneEmptyEx( psDBF, newDBF );
+
+   DBFClose( newDBF );      
+   newDBF = DBFOpenW ( pszFilename, L"rb+" );
+
+   return ( newDBF );
+}
+
+#endif
+
+/************************************************************************/
+/*                          DBFCloneEmptyEx()                           */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+void SHPAPI_CALL
+DBFCloneEmptyEx(DBFHandle psDBF, DBFHandle newDBF) 
+{
    if ( newDBF == NULL ) return ( NULL ); 
    
    newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
@@ -1521,11 +1731,6 @@
    newDBF->bUpdated = TRUE;
    
    DBFWriteHeader ( newDBF );
-   DBFClose ( newDBF );
-   
-   newDBF = DBFOpen ( pszFilename, "rb+" );
-
-   return ( newDBF );
 }
 
 /************************************************************************/

Modified: branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/shapelib/shapefil.h	2007-03-28 23:30:15 UTC (rev 2751)
@@ -173,6 +173,10 @@
 extern "C" {
 #endif
 
+#if defined(_WIN32) || defined(_WIN64)
+#define SHPAPI_HAS_WIDE
+#endif
+
 /************************************************************************/
 /*                        Configuration options.                        */
 /************************************************************************/
@@ -329,7 +333,18 @@
       SHPOpen( const char * pszShapeFile, const char * pszAccess );
 SHPHandle SHPAPI_CALL
       SHPCreate( const char * pszShapeFile, int nShapeType );
+#ifdef SHPAPI_HAS_WIDE
+SHPHandle SHPAPI_CALL
+      SHPOpenW( const wchar_t * pszShapeFile, const wchar_t * pszAccess );
+SHPHandle SHPAPI_CALL
+      SHPCreateW( const wchar_t * pszShapeFile, int nShapeType );
+#endif
+SHPHandle SHPAPI_CALL
+      SHPOpenEx( FILE * pfSHP, FILE * pfSHX );
 void SHPAPI_CALL
+      SHPCreateEx( FILE * pfSHP, FILE * pfSHX, int nShapeType );
+
+void SHPAPI_CALL
       SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
                   double * padfMinBound, double * padfMaxBound );
 
@@ -406,6 +421,12 @@
       SHPWriteTree( SHPTree *hTree, const char * pszFilename );
 SHPTree SHPAPI_CALL
       SHPReadTree( const char * pszFilename );
+#ifdef SHPAPI_HAS_WIDE
+int	SHPAPI_CALL
+      SHPWriteTreeW( SHPTree *hTree, const wchar_t * pszFilename );
+SHPTree SHPAPI_CALL
+      SHPReadTreeW( const wchar_t * pszFilename );
+#endif
 
 int	SHPAPI_CALL
       SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
@@ -472,6 +493,16 @@
       DBFOpen( const char * pszDBFFile, const char * pszAccess );
 DBFHandle SHPAPI_CALL
       DBFCreate( const char * pszDBFFile );
+#ifdef SHPAPI_HAS_WIDE
+DBFHandle SHPAPI_CALL
+      DBFOpenW( const wchar_t * pszDBFFile, const wchar_t * pszAccess );
+DBFHandle SHPAPI_CALL
+      DBFCreateW( const wchar_t * pszDBFFile );
+#endif
+DBFHandle SHPAPI_CALL
+      DBFOpenEx( FILE* pf );
+DBFHandle SHPAPI_CALL
+      DBFCreateEx( FILE* pf );
 
 int	SHPAPI_CALL
       DBFGetFieldCount( DBFHandle psDBF );
@@ -524,7 +555,13 @@
 
 DBFHandle SHPAPI_CALL
       DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
- 
+#ifdef DBFAPI_HAS_WIDE
+DBFHandle SHPAPI_CALL
+      DBFCloneEmptyW(DBFHandle psDBF, const wchar_t * pszFilename );
+#endif
+void SHPAPI_CALL
+      DBFCloneEmptyEx(DBFHandle psDBF, DBFHandle newDBF );
+
 void	SHPAPI_CALL
       DBFClose( DBFHandle hDBF );
 void    SHPAPI_CALL

Modified: branches/WIP-pyshapelib-bramz/libraries/shapelib/shpopen.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/shapelib/shpopen.c	2007-03-22 20:35:08 UTC (rev 2750)
+++ branches/WIP-pyshapelib-bramz/libraries/shapelib/shpopen.c	2007-03-28 23:30:15 UTC (rev 2751)
@@ -423,11 +423,8 @@
 
 {
     char		*pszFullname, *pszBasename;
-    SHPHandle		psSHP;
-    
-    uchar		*pabyBuf;
+    FILE		*fpSHP, *fpSHX;
     int			i;
-    double		dValue;
     
 /* -------------------------------------------------------------------- */
 /*      Ensure the access string is one of the legal ones.  We          */
@@ -450,13 +447,6 @@
         bBigEndian = TRUE;
 
 /* -------------------------------------------------------------------- */
-/*	Initialize the info structure.					*/
-/* -------------------------------------------------------------------- */
-    psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
-
-    psSHP->bUpdated = FALSE;
-
-/* -------------------------------------------------------------------- */
 /*	Compute the base (layer) name.  If there is any extension	*/
 /*	on the passed in filename we will strip it off.			*/
 /* -------------------------------------------------------------------- */
@@ -476,43 +466,41 @@
 /* -------------------------------------------------------------------- */
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
     sprintf( pszFullname, "%s.shp", pszBasename );
-    psSHP->fpSHP = fopen(pszFullname, pszAccess );
-    if( psSHP->fpSHP == NULL )
+    fpSHP = fopen(pszFullname, pszAccess );
+    if( fpSHP == NULL )
     {
         sprintf( pszFullname, "%s.SHP", pszBasename );
-        psSHP->fpSHP = fopen(pszFullname, pszAccess );
+        fpSHP = fopen(pszFullname, pszAccess );
     }
     
-    if( psSHP->fpSHP == NULL )
+    if( fpSHP == NULL )
     {
 #ifdef USE_CPL
         CPLError( CE_Failure, CPLE_OpenFailed, 
                   "Unable to open %s.shp or %s.SHP.", 
                   pszBasename, pszBasename );
 #endif
-        free( psSHP );
         free( pszBasename );
         free( pszFullname );
         return( NULL );
     }
 
     sprintf( pszFullname, "%s.shx", pszBasename );
-    psSHP->fpSHX = fopen(pszFullname, pszAccess );
-    if( psSHP->fpSHX == NULL )
+    fpSHX = fopen(pszFullname, pszAccess );
+    if( fpSHX == NULL )
     {
         sprintf( pszFullname, "%s.SHX", pszBasename );
-        psSHP->fpSHX = fopen(pszFullname, pszAccess );
+        fpSHX = fopen(pszFullname, pszAccess );
     }
     
-    if( psSHP->fpSHX == NULL )
+    if( fpSHX == NULL )
     {
 #ifdef USE_CPL
         CPLError( CE_Failure, CPLE_OpenFailed, 
                   "Unable to open %s.shx or %s.SHX.", 
                   pszBasename, pszBasename );
 #endif
-        fclose( psSHP->fpSHP );
-        free( psSHP );
+        fclose( fpSHP );
         free( pszBasename );
         free( pszFullname );
         return( NULL );
@@ -521,7 +509,139 @@
     free( pszFullname );
     free( pszBasename );
 
+	return SHPOpenEx( fpSHP, fpSHX );
+}
+
+
+/************************************************************************/
+/*                              SHPOpenW()                              */
+/*                                                                      */
+/*      Open the .shp and .shx files based on the basename of the       */
+/*      files or either file name, for wide character filenames         */
+/************************************************************************/
+   
+#ifdef SHPAPI_HAS_WIDE
+
+SHPHandle SHPAPI_CALL
+SHPOpenW( const wchar_t * pszLayer, const wchar_t * pszAccess )
+
+{
+    wchar_t		*pszFullname, *pszBasename;
+    FILE		*fpSHP, *fpSHX;
+    int			i;
+    
 /* -------------------------------------------------------------------- */
+/*      Ensure the access string is one of the legal ones.  We          */
+/*      ensure the result string indicates binary to avoid common       */
+/*      problems on Windows.                                            */
+/* -------------------------------------------------------------------- */
+    if( wcscmp(pszAccess,L"rb+") == 0 || wcscmp(pszAccess,L"r+b") == 0
+        || wcscmp(pszAccess,L"r+") == 0 )
+        pszAccess = L"r+b";
+    else
+        pszAccess = L"rb";
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszLayer)+5));
+    wcscpy( pszBasename, pszLayer );
+    for( i = wcslen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/'
+	       && pszBasename[i] != L'\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == L'.' )
+        pszBasename[i] = L'\0';
+
+/* -------------------------------------------------------------------- */
+/*	Open the .shp and .shx files.  Note that files pulled from	*/
+/*	a PC to Unix with upper case filenames won't work!		*/
+/* -------------------------------------------------------------------- */
+    pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5));
+    swprintf( pszFullname, L"%s.shp", pszBasename );
+    fpSHP = _wfopen(pszFullname, pszAccess );
+    if( fpSHP == NULL )
+    {
+        swprintf( pszFullname, L"%s.SHP", pszBasename );
+        fpSHP = _wfopen(pszFullname, pszAccess );
+    }
+    
+    if( fpSHP == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Unable to open .shp file." );
+#endif
+        free( pszBasename );
+        free( pszFullname );
+        return( NULL );
+    }
+
+    swprintf( pszFullname, L"%s.shx", pszBasename );
+    fpSHX = _wfopen(pszFullname, pszAccess );
+    if( fpSHX == NULL )
+    {
+        swprintf( pszFullname, L"%s.SHX", pszBasename );
+        fpSHX = _wfopen(pszFullname, pszAccess );
+    }
+    
+    if( fpSHX == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Unable to open .shx file." );
+#endif
+        fclose( fpSHP );
+        free( pszBasename );
+        free( pszFullname );
+        return( NULL );
+    }
+
+    free( pszFullname );
+    free( pszBasename );
+
+	return SHPOpenEx( fpSHP, fpSHX );
+}
+
+#endif
+
+/************************************************************************/
+/*                              shpopen()                               */
+/*                                                                      */
+/*      Open the .shp and .shx files based on the basename of the       */
+/*      files or either file name.                                      */
+/************************************************************************/
+   
+SHPHandle SHPAPI_CALL
+SHPOpenEx( FILE * fpSHP, FILE * fpSHX )
+{
+    SHPHandle	psSHP;
+    uchar		*pabyBuf;
+    int			i;
+    double		dValue;
+    
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.			*/
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((uchar *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*	Initialize the info structure.					*/
+/* -------------------------------------------------------------------- */
+    psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
+
+	psSHP->fpSHP = fpSHP;
+	psSHP->fpSHX = fpSHX;
+    psSHP->bUpdated = FALSE;
+
+
+/* -------------------------------------------------------------------- */
 /*  Read the file size from the SHP file.				*/
 /* -------------------------------------------------------------------- */
     pabyBuf = (uchar *) malloc(100);
@@ -738,18 +858,6 @@
     char	*pszBasename, *pszFullname;
     int		i;
     FILE	*fpSHP, *fpSHX;
-    uchar     	abyHeader[100];
-    int32	i32;
-    double	dValue;
-    
-/* -------------------------------------------------------------------- */
-/*      Establish the byte order on this system.                        */
-/* -------------------------------------------------------------------- */
-    i = 1;
-    if( *((uchar *) &i) == 1 )
-        bBigEndian = FALSE;
-    else
-        bBigEndian = TRUE;
 
 /* -------------------------------------------------------------------- */
 /*	Compute the base (layer) name.  If there is any extension	*/
@@ -796,7 +904,116 @@
     free( pszFullname );
     free( pszBasename );
 
+	SHPCreateEx( fpSHP, fpSHX, nShapeType );
+
 /* -------------------------------------------------------------------- */
+/*      Close the files, and then open them as regular existing files.  */
+/* -------------------------------------------------------------------- */
+    fclose( fpSHP );
+    fclose( fpSHX );
+
+    return( SHPOpen( pszLayer, "r+b" ) );
+}
+
+#ifdef SHPAPI_HAS_WIDE
+
+/************************************************************************/
+/*                             SHPCreate()                              */
+/*                                                                      */
+/*      Create a new shape file and return a handle to the open         */
+/*      shape file with read/write access.                              */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPCreateW( const wchar_t * pszLayer, int nShapeType )
+
+{
+    wchar_t	*pszBasename, *pszFullname;
+    int		i;
+    FILE	*fpSHP, *fpSHX;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszLayer)+5));
+    wcscpy( pszBasename, pszLayer );
+    for( i = wcslen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/'
+	       && pszBasename[i] != L'\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == L'.' )
+        pszBasename[i] = L'\0';
+
+/* -------------------------------------------------------------------- */
+/*      Open the two files so we can write their headers.               */
+/* -------------------------------------------------------------------- */
+    pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5));
+    swprintf( pszFullname, L"%s.shp", pszBasename );
+    fpSHP = _wfopen(pszFullname, L"wb" );
+    if( fpSHP == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to create file." );
+#endif
+        return( NULL );
+    }
+
+    swprintf( pszFullname, L"%s.shx", pszBasename );
+    fpSHX = _wfopen(pszFullname, L"wb" );
+    if( fpSHX == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to create file." );
+#endif
+        return( NULL );
+    }
+
+    free( pszFullname );
+    free( pszBasename );
+
+	SHPCreateEx( fpSHP, fpSHX, nShapeType );
+
+/* -------------------------------------------------------------------- */
+/*      Close the files, and then open them as regular existing files.  */
+/* -------------------------------------------------------------------- */
+    fclose( fpSHP );
+    fclose( fpSHX );
+
+    return( SHPOpenW( pszLayer, L"r+b" ) );
+}
+
+#endif
+
+/************************************************************************/
+/*                             SHPCreateEx()                            */
+/*                                                                      */
+/*      Create a new shape file and return a handle to the open         */
+/*      shape file with read/write access.                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPCreateEx( FILE * fpSHP, FILE * fpSHX, int nShapeType )
+
+{
+    int		i;
+    uchar     	abyHeader[100];
+    int32	i32;
+    double	dValue;
+    
+/* -------------------------------------------------------------------- */
+/*      Establish the byte order on this system.                        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((uchar *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
 /*      Prepare header block for .shp file.                             */
 /* -------------------------------------------------------------------- */
     for( i = 0; i < 100; i++ )
@@ -832,7 +1049,7 @@
         CPLError( CE_Failure, CPLE_AppDefined, 
                   "Failed to write .shp header." );
 #endif
-        return NULL;
+        return;
     }
 
 /* -------------------------------------------------------------------- */
@@ -848,18 +1065,11 @@
         CPLError( CE_Failure, CPLE_AppDefined, 
                   "Failed to write .shx header." );
 #endif
-        return NULL;
+        return;
     }
+}
 
-/* -------------------------------------------------------------------- */
-/*      Close the files, and then open them as regular existing files.  */
-/* -------------------------------------------------------------------- */
-    fclose( fpSHP );
-    fclose( fpSHX );
 
-    return( SHPOpen( pszLayer, "r+b" ) );
-}
-
 /************************************************************************/
 /*                           _SHPSetBounds()                            */
 /*                                                                      */



More information about the Thuban-commits mailing list