diff --git a/shapelib/README.GPSBabel b/shapelib/README.GPSBabel index 73ead7014..a3f953509 100644 --- a/shapelib/README.GPSBabel +++ b/shapelib/README.GPSBabel @@ -1,4 +1,4 @@ -This is a subset of Shapelib v1.4.1 from http://shapelib.maptools.org/ +This is a subset of Shapelib v1.5.0 from http://shapelib.maptools.org/ The source is unmodified. It's subsetted here only to reduce the amount of size in our tree that it takes and to reduce ongoing diff --git a/shapelib/dbfopen.c b/shapelib/dbfopen.c index 148e593a4..218db70cf 100644 --- a/shapelib/dbfopen.c +++ b/shapelib/dbfopen.c @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: dbfopen.c,v 1.92 2016-12-05 18:44:08 erouault Exp $ + * $Id: dbfopen.c,v 1.94 2018-08-16 15:39:07 erouault Exp $ * * Project: Shapelib * Purpose: Implementation of .dbf access API documented in dbf_api.html. @@ -35,6 +35,19 @@ ****************************************************************************** * * $Log: dbfopen.c,v $ + * Revision 1.94 2018-08-16 15:39:07 erouault + * * shpopen.c, dbfopen.c, shptree.c, sbnsearch.c: resyc with GDAL + * internal shapelib. Mostly to allow building those files as C++ + * without warning. Also add FTDate entry in DBFFieldType + * (see https://github.com/OSGeo/gdal/pull/308). And some other + * code cleanups + * + * Revision 1.93 2018-08-16 15:24:46 erouault + * * dbfopen.c: fix a bug where the end of file character was + * written on top of the first character of the first field name + * when deleting a field on a .dbf without records. + * Fixes https://github.com/OSGeo/gdal/issues/863 + * * Revision 1.92 2016-12-05 18:44:08 erouault * * dbfopen.c, shapefil.h: write DBF end-of-file character 0x1A by default. * This behaviour can be controlled with the DBFSetWriteEndOfFileChar() @@ -195,6 +208,13 @@ #include "cpl_string.h" #else +#if defined(WIN32) || defined(_WIN32) +# define STRCASECMP(a,b) (stricmp(a,b)) +# else +#include +# define STRCASECMP(a,b) (strcasecmp(a,b)) +#endif + #if defined(_MSC_VER) # if _MSC_VER < 1900 # define snprintf _snprintf @@ -209,7 +229,7 @@ #define CPLsnprintf snprintf #endif -SHP_CVSID("$Id: dbfopen.c,v 1.92 2016-12-05 18:44:08 erouault Exp $") +SHP_CVSID("$Id: dbfopen.c,v 1.94 2018-08-16 15:39:07 erouault Exp $") #ifndef FALSE # define FALSE 0 @@ -230,6 +250,18 @@ CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused) {} #define CPL_IGNORE_RET_VAL_INT(x) x #endif +#ifdef __cplusplus +#define STATIC_CAST(type,x) static_cast(x) +#define REINTERPRET_CAST(type,x) reinterpret_cast(x) +#define CONST_CAST(type,x) const_cast(x) +#define SHPLIB_NULLPTR nullptr +#else +#define STATIC_CAST(type,x) ((type)(x)) +#define REINTERPRET_CAST(type,x) ((type)(x)) +#define CONST_CAST(type,x) ((type)(x)) +#define SHPLIB_NULLPTR NULL +#endif + /************************************************************************/ /* SfRealloc() */ /* */ @@ -240,10 +272,10 @@ CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused) {} static void * SfRealloc( void * pMem, int nNewSize ) { - if( pMem == NULL ) - return( (void *) malloc(nNewSize) ); + if( pMem == SHPLIB_NULLPTR ) + return malloc(nNewSize); else - return( (void *) realloc(pMem,nNewSize) ); + return realloc(pMem,nNewSize); } /************************************************************************/ @@ -271,19 +303,19 @@ static void DBFWriteHeader(DBFHandle psDBF) abyHeader[0] = 0x03; /* memo field? - just copying */ /* write out update date */ - abyHeader[1] = (unsigned char) psDBF->nUpdateYearSince1900; - abyHeader[2] = (unsigned char) psDBF->nUpdateMonth; - abyHeader[3] = (unsigned char) psDBF->nUpdateDay; + abyHeader[1] = STATIC_CAST(unsigned char, psDBF->nUpdateYearSince1900); + abyHeader[2] = STATIC_CAST(unsigned char, psDBF->nUpdateMonth); + abyHeader[3] = STATIC_CAST(unsigned char, psDBF->nUpdateDay); /* record count preset at zero */ - abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256); - abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256); + abyHeader[8] = STATIC_CAST(unsigned char, psDBF->nHeaderLength % 256); + abyHeader[9] = STATIC_CAST(unsigned char, psDBF->nHeaderLength / 256); - abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256); - abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256); + abyHeader[10] = STATIC_CAST(unsigned char, psDBF->nRecordLength % 256); + abyHeader[11] = STATIC_CAST(unsigned char, psDBF->nRecordLength / 256); - abyHeader[29] = (unsigned char) (psDBF->iLanguageDriver); + abyHeader[29] = STATIC_CAST(unsigned char, psDBF->iLanguageDriver); /* -------------------------------------------------------------------- */ /* Write the initial 32 byte file header, and all the field */ @@ -333,7 +365,7 @@ static int DBFFlushRecord( DBFHandle psDBF ) psDBF->bCurrentRecordModified = FALSE; nRecordOffset = - psDBF->nRecordLength * (SAOffset) psDBF->nCurrentRecord + psDBF->nRecordLength * STATIC_CAST(SAOffset, psDBF->nCurrentRecord) + psDBF->nHeaderLength; if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0 @@ -376,13 +408,13 @@ static int DBFLoadRecord( DBFHandle psDBF, int iRecord ) return FALSE; nRecordOffset = - psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 ) { char szMessage[128]; snprintf( szMessage, sizeof(szMessage), "fseek(%ld) failed on DBF file.", - (long) nRecordOffset ); + STATIC_CAST(long, nRecordOffset) ); psDBF->sHooks.Error( szMessage ); return FALSE; } @@ -422,13 +454,13 @@ DBFUpdateHeader( DBFHandle psDBF ) psDBF->sHooks.FSeek( psDBF->fp, 0, 0 ); psDBF->sHooks.FRead( abyFileHeader, sizeof(abyFileHeader), 1, psDBF->fp ); - abyFileHeader[1] = (unsigned char) psDBF->nUpdateYearSince1900; - abyFileHeader[2] = (unsigned char) psDBF->nUpdateMonth; - abyFileHeader[3] = (unsigned char) psDBF->nUpdateDay; - abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256); - abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256); - abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256); - abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256); + abyFileHeader[1] = STATIC_CAST(unsigned char, psDBF->nUpdateYearSince1900); + abyFileHeader[2] = STATIC_CAST(unsigned char, psDBF->nUpdateMonth); + abyFileHeader[3] = STATIC_CAST(unsigned char, psDBF->nUpdateDay); + abyFileHeader[4] = STATIC_CAST(unsigned char, psDBF->nRecords & 0xFF); + abyFileHeader[5] = STATIC_CAST(unsigned char, (psDBF->nRecords>>8) & 0xFF); + abyFileHeader[6] = STATIC_CAST(unsigned char, (psDBF->nRecords>>16) & 0xFF); + abyFileHeader[7] = STATIC_CAST(unsigned char, (psDBF->nRecords>>24) & 0xFF); psDBF->sHooks.FSeek( psDBF->fp, 0, 0 ); psDBF->sHooks.FWrite( abyFileHeader, sizeof(abyFileHeader), 1, psDBF->fp ); @@ -465,6 +497,26 @@ DBFOpen( const char * pszFilename, const char * pszAccess ) return DBFOpenLL( pszFilename, pszAccess, &sHooks ); } +/************************************************************************/ +/* DBFGetLenWithoutExtension() */ +/************************************************************************/ + +static int DBFGetLenWithoutExtension(const char* pszBasename) +{ + int i; + int nLen = STATIC_CAST(int, strlen(pszBasename)); + for( i = nLen-1; + i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\'; + i-- ) + { + if( pszBasename[i] == '.' ) + { + return i; + } + } + return nLen; +} + /************************************************************************/ /* DBFOpen() */ /* */ @@ -478,10 +530,10 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) DBFHandle psDBF; SAFile pfCPG; unsigned char *pabyBuf; - int nFields, nHeadLen, iField, i; - char *pszBasename, *pszFullname; + int nFields, nHeadLen, iField; + char *pszFullname; int nBufSize = 500; - size_t nFullnameLen; + int nLenWithoutExtension; /* -------------------------------------------------------------------- */ /* We only allow the access strings "rb" and "r+". */ @@ -489,7 +541,7 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0 && strcmp(pszAccess,"r+b") != 0 ) - return( NULL ); + return SHPLIB_NULLPTR; if( strcmp(pszAccess,"r") == 0 ) pszAccess = "rb"; @@ -501,46 +553,36 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszFilename)+5); - strcpy( pszBasename, pszFilename ); - for( i = (int)strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - - nFullnameLen = strlen(pszBasename) + 5; - pszFullname = (char *) malloc(nFullnameLen); - snprintf( pszFullname, nFullnameLen, "%s.dbf", pszBasename ); + nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename); + pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + memcpy(pszFullname, pszFilename, nLenWithoutExtension); + memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5); - psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) ); + psDBF = STATIC_CAST(DBFHandle, calloc( 1, sizeof(DBFInfo) )); psDBF->fp = psHooks->FOpen( pszFullname, pszAccess ); memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) ); - if( psDBF->fp == NULL ) + if( psDBF->fp == SHPLIB_NULLPTR ) { - snprintf( pszFullname, nFullnameLen, "%s.DBF", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".DBF", 5); psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess ); } - snprintf( pszFullname, nFullnameLen, "%s.cpg", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".cpg", 5); pfCPG = psHooks->FOpen( pszFullname, "r" ); - if( pfCPG == NULL ) + if( pfCPG == SHPLIB_NULLPTR ) { - snprintf( pszFullname, nFullnameLen, "%s.CPG", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".CPG", 5); pfCPG = psHooks->FOpen( pszFullname, "r" ); } - free( pszBasename ); free( pszFullname ); - if( psDBF->fp == NULL ) + if( psDBF->fp == SHPLIB_NULLPTR ) { free( psDBF ); if( pfCPG ) psHooks->FClose( pfCPG ); - return( NULL ); + return SHPLIB_NULLPTR; } psDBF->bNoHeader = FALSE; @@ -550,23 +592,23 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Read Table Header info */ /* -------------------------------------------------------------------- */ - pabyBuf = (unsigned char *) malloc(nBufSize); + pabyBuf = STATIC_CAST(unsigned char *, malloc(nBufSize)); if( psDBF->sHooks.FRead( pabyBuf, XBASE_FILEHDR_SZ, 1, psDBF->fp ) != 1 ) { psDBF->sHooks.FClose( psDBF->fp ); if( pfCPG ) psDBF->sHooks.FClose( pfCPG ); free( pabyBuf ); free( psDBF ); - return NULL; + return SHPLIB_NULLPTR; } DBFSetLastModifiedDate(psDBF, pabyBuf[1], pabyBuf[2], pabyBuf[3]); psDBF->nRecords = - pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + (pabyBuf[7] & 0x7f) *256*256*256; + pabyBuf[4]|(pabyBuf[5]<<8)|(pabyBuf[6]<<16)|((pabyBuf[7]&0x7f)<<24); - psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256; - psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11]*256; + psDBF->nHeaderLength = nHeadLen = pabyBuf[8]|(pabyBuf[9]<<8); + psDBF->nRecordLength = pabyBuf[10]|(pabyBuf[11]<<8); psDBF->iLanguageDriver = pabyBuf[29]; if (psDBF->nRecordLength == 0 || nHeadLen < XBASE_FILEHDR_SZ) @@ -575,45 +617,46 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) if( pfCPG ) psDBF->sHooks.FClose( pfCPG ); free( pabyBuf ); free( psDBF ); - return NULL; + return SHPLIB_NULLPTR; } psDBF->nFields = nFields = (nHeadLen - XBASE_FILEHDR_SZ) / XBASE_FLDHDR_SZ; - psDBF->pszCurrentRecord = (char *) malloc(psDBF->nRecordLength); + /* coverity[tainted_data] */ + psDBF->pszCurrentRecord = STATIC_CAST(char *, malloc(psDBF->nRecordLength)); /* -------------------------------------------------------------------- */ /* Figure out the code page from the LDID and CPG */ /* -------------------------------------------------------------------- */ - psDBF->pszCodePage = NULL; + psDBF->pszCodePage = SHPLIB_NULLPTR; if( pfCPG ) { size_t n; memset( pabyBuf, 0, nBufSize); psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG ); - n = strcspn( (char *) pabyBuf, "\n\r" ); + n = strcspn( REINTERPRET_CAST(char *, pabyBuf), "\n\r" ); if( n > 0 ) { pabyBuf[n] = '\0'; - psDBF->pszCodePage = (char *) malloc(n + 1); + psDBF->pszCodePage = STATIC_CAST(char *, malloc(n + 1)); memcpy( psDBF->pszCodePage, pabyBuf, n + 1 ); } psDBF->sHooks.FClose( pfCPG ); } - if( psDBF->pszCodePage == NULL && pabyBuf[29] != 0 ) + if( psDBF->pszCodePage == SHPLIB_NULLPTR && pabyBuf[29] != 0 ) { - snprintf( (char *) pabyBuf, nBufSize, "LDID/%d", psDBF->iLanguageDriver ); - psDBF->pszCodePage = (char *) malloc(strlen((char*)pabyBuf) + 1); - strcpy( psDBF->pszCodePage, (char *) pabyBuf ); + snprintf( REINTERPRET_CAST(char *, pabyBuf), nBufSize, "LDID/%d", psDBF->iLanguageDriver ); + psDBF->pszCodePage = STATIC_CAST(char *, malloc(strlen(REINTERPRET_CAST(char*, pabyBuf)) + 1)); + strcpy( psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf) ); } /* -------------------------------------------------------------------- */ /* Read in Field Definitions */ /* -------------------------------------------------------------------- */ - pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen); - psDBF->pszHeader = (char *) pabyBuf; + pabyBuf = STATIC_CAST(unsigned char *, SfRealloc(pabyBuf,nHeadLen)); + psDBF->pszHeader = REINTERPRET_CAST(char *, pabyBuf); psDBF->sHooks.FSeek( psDBF->fp, XBASE_FILEHDR_SZ, 0 ); if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-XBASE_FILEHDR_SZ, 1, @@ -622,20 +665,26 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) psDBF->sHooks.FClose( psDBF->fp ); free( pabyBuf ); free( psDBF->pszCurrentRecord ); + free( psDBF->pszCodePage ); free( psDBF ); - return NULL; + return SHPLIB_NULLPTR; } - psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields); - psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields); - psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields); - psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields); + psDBF->panFieldOffset = STATIC_CAST(int *, malloc(sizeof(int) * nFields)); + psDBF->panFieldSize = STATIC_CAST(int *, malloc(sizeof(int) * nFields)); + psDBF->panFieldDecimals = STATIC_CAST(int *, malloc(sizeof(int) * nFields)); + psDBF->pachFieldType = STATIC_CAST(char *, malloc(sizeof(char) * nFields)); for( iField = 0; iField < nFields; iField++ ) { unsigned char *pabyFInfo; pabyFInfo = pabyBuf+iField*XBASE_FLDHDR_SZ; + if( pabyFInfo[0] == HEADER_RECORD_TERMINATOR ) + { + psDBF->nFields = iField; + break; + } if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' ) { @@ -657,7 +706,7 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) */ } - psDBF->pachFieldType[iField] = (char) pabyFInfo[11]; + psDBF->pachFieldType[iField] = STATIC_CAST(char, pabyFInfo[11]); if( iField == 0 ) psDBF->panFieldOffset[iField] = 1; else @@ -665,6 +714,15 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1]; } + /* Check that the total width of fields does not exceed the record width */ + if( psDBF->nFields > 0 && + psDBF->panFieldOffset[psDBF->nFields-1] + + psDBF->panFieldSize[psDBF->nFields-1] > psDBF->nRecordLength ) + { + DBFClose( psDBF ); + return SHPLIB_NULLPTR; + } + DBFSetWriteEndOfFileChar( psDBF, TRUE ); return( psDBF ); @@ -677,7 +735,7 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks ) void SHPAPI_CALL DBFClose(DBFHandle psDBF) { - if( psDBF == NULL ) + if( psDBF == SHPLIB_NULLPTR ) return; /* -------------------------------------------------------------------- */ @@ -700,7 +758,7 @@ DBFClose(DBFHandle psDBF) /* -------------------------------------------------------------------- */ psDBF->sHooks.FClose( psDBF->fp ); - if( psDBF->panFieldOffset != NULL ) + if( psDBF->panFieldOffset != SHPLIB_NULLPTR ) { free( psDBF->panFieldOffset ); free( psDBF->panFieldSize ); @@ -708,7 +766,7 @@ DBFClose(DBFHandle psDBF) free( psDBF->pachFieldType ); } - if( psDBF->pszWorkField != NULL ) + if( psDBF->pszWorkField != SHPLIB_NULLPTR ) free( psDBF->pszWorkField ); free( psDBF->pszHeader ); @@ -760,53 +818,42 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook { DBFHandle psDBF; SAFile fp; - char *pszFullname, *pszBasename; - int i, ldid = -1; + char *pszFullname; + int ldid = -1; char chZero = '\0'; - size_t nFullnameLen; + int nLenWithoutExtension; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszFilename)+5); - strcpy( pszBasename, pszFilename ); - for( i = (int)strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - - nFullnameLen = strlen(pszBasename) + 5; - pszFullname = (char *) malloc(nFullnameLen); - snprintf( pszFullname, nFullnameLen, "%s.dbf", pszBasename ); + nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename); + pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + memcpy(pszFullname, pszFilename, nLenWithoutExtension); + memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5); /* -------------------------------------------------------------------- */ /* Create the file. */ /* -------------------------------------------------------------------- */ fp = psHooks->FOpen( pszFullname, "wb" ); - if( fp == NULL ) + if( fp == SHPLIB_NULLPTR ) { - free( pszBasename ); free( pszFullname ); - return( NULL ); + return SHPLIB_NULLPTR; } psHooks->FWrite( &chZero, 1, 1, fp ); psHooks->FClose( fp ); fp = psHooks->FOpen( pszFullname, "rb+" ); - if( fp == NULL ) + if( fp == SHPLIB_NULLPTR ) { - free( pszBasename ); free( pszFullname ); - return( NULL ); + return SHPLIB_NULLPTR; } - snprintf( pszFullname, nFullnameLen, "%s.cpg", pszBasename ); - if( pszCodePage != NULL ) + memcpy(pszFullname + nLenWithoutExtension, ".cpg", 5); + if( pszCodePage != SHPLIB_NULLPTR ) { if( strncmp( pszCodePage, "LDID/", 5 ) == 0 ) { @@ -817,22 +864,21 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook if( ldid < 0 ) { SAFile fpCPG = psHooks->FOpen( pszFullname, "w" ); - psHooks->FWrite( (char*) pszCodePage, strlen(pszCodePage), 1, fpCPG ); + psHooks->FWrite( CONST_CAST(void*, STATIC_CAST(const void*, pszCodePage)), strlen(pszCodePage), 1, fpCPG ); psHooks->FClose( fpCPG ); } } - if( pszCodePage == NULL || ldid >= 0 ) + if( pszCodePage == SHPLIB_NULLPTR || ldid >= 0 ) { psHooks->Remove( pszFullname ); } - free( pszBasename ); free( pszFullname ); /* -------------------------------------------------------------------- */ /* Create the info structure. */ /* -------------------------------------------------------------------- */ - psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo)); + psDBF = STATIC_CAST(DBFHandle, calloc(1,sizeof(DBFInfo))); memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) ); psDBF->fp = fp; @@ -841,23 +887,23 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook psDBF->nRecordLength = 1; psDBF->nHeaderLength = XBASE_FILEHDR_SZ + 1; /* + 1 for HEADER_RECORD_TERMINATOR */ - psDBF->panFieldOffset = NULL; - psDBF->panFieldSize = NULL; - psDBF->panFieldDecimals = NULL; - psDBF->pachFieldType = NULL; - psDBF->pszHeader = NULL; + psDBF->panFieldOffset = SHPLIB_NULLPTR; + psDBF->panFieldSize = SHPLIB_NULLPTR; + psDBF->panFieldDecimals = SHPLIB_NULLPTR; + psDBF->pachFieldType = SHPLIB_NULLPTR; + psDBF->pszHeader = SHPLIB_NULLPTR; psDBF->nCurrentRecord = -1; psDBF->bCurrentRecordModified = FALSE; - psDBF->pszCurrentRecord = NULL; + psDBF->pszCurrentRecord = SHPLIB_NULLPTR; psDBF->bNoHeader = TRUE; psDBF->iLanguageDriver = ldid > 0 ? ldid : 0; - psDBF->pszCodePage = NULL; + psDBF->pszCodePage = SHPLIB_NULLPTR; if( pszCodePage ) { - psDBF->pszCodePage = (char * ) malloc( strlen(pszCodePage) + 1 ); + psDBF->pszCodePage = STATIC_CAST(char *, malloc( strlen(pszCodePage) + 1 )); strcpy( psDBF->pszCodePage, pszCodePage ); } DBFSetLastModifiedDate(psDBF, 95, 7, 26); /* dummy date */ @@ -882,6 +928,8 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName, if( eType == FTLogical ) chNativeType = 'L'; + else if( eType == FTDate ) + chNativeType = 'D'; else if( eType == FTString ) chNativeType = 'C'; else @@ -974,17 +1022,17 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, /* -------------------------------------------------------------------- */ psDBF->nFields++; - psDBF->panFieldOffset = (int *) - SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); + psDBF->panFieldOffset = STATIC_CAST(int *, + SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields )); - psDBF->panFieldSize = (int *) - SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); + psDBF->panFieldSize = STATIC_CAST(int *, + SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields )); - psDBF->panFieldDecimals = (int *) - SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); + psDBF->panFieldDecimals = STATIC_CAST(int *, + SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields )); - psDBF->pachFieldType = (char *) - SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ); + psDBF->pachFieldType = STATIC_CAST(char *, + SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields )); /* -------------------------------------------------------------------- */ /* Assign the new field information fields. */ @@ -1001,8 +1049,8 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, psDBF->nHeaderLength += XBASE_FLDHDR_SZ; psDBF->bUpdated = FALSE; - psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader, - psDBF->nFields*XBASE_FLDHDR_SZ); + psDBF->pszHeader = STATIC_CAST(char *, SfRealloc(psDBF->pszHeader, + psDBF->nFields*XBASE_FLDHDR_SZ)); pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * (psDBF->nFields-1); @@ -1015,20 +1063,20 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, if( chType == 'C' ) { - pszFInfo[16] = (unsigned char) (nWidth % 256); - pszFInfo[17] = (unsigned char) (nWidth / 256); + pszFInfo[16] = STATIC_CAST(unsigned char, nWidth % 256); + pszFInfo[17] = STATIC_CAST(unsigned char, nWidth / 256); } else { - pszFInfo[16] = (unsigned char) nWidth; - pszFInfo[17] = (unsigned char) nDecimals; + pszFInfo[16] = STATIC_CAST(unsigned char, nWidth); + pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals); } /* -------------------------------------------------------------------- */ /* Make the current record buffer appropriately larger. */ /* -------------------------------------------------------------------- */ - psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, - psDBF->nRecordLength); + psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord, + psDBF->nRecordLength)); /* we're done if dealing with new .dbf */ if( psDBF->bNoHeader ) @@ -1039,13 +1087,13 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, /* -------------------------------------------------------------------- */ /* alloc record */ - pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength); + pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); chFieldFill = DBFGetNullCharacter(chType); for (i = psDBF->nRecords-1; i >= 0; --i) { - nRecordOffset = nOldRecordLength * (SAOffset) i + nOldHeaderLength; + nRecordOffset = nOldRecordLength * STATIC_CAST(SAOffset, i) + nOldHeaderLength; /* load record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -1054,7 +1102,7 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, /* set new field's value to NULL */ memset(pszRecord + nOldRecordLength, chFieldFill, nWidth); - nRecordOffset = psDBF->nRecordLength * (SAOffset) i + psDBF->nHeaderLength; + nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, i) + psDBF->nHeaderLength; /* move record to the new place*/ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -1066,7 +1114,7 @@ DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, char ch = END_OF_FILE_CHARACTER; nRecordOffset = - psDBF->nRecordLength * (SAOffset) psDBF->nRecords + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength; psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp ); @@ -1097,24 +1145,24 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, { unsigned char *pabyRec; - void *pReturnField = NULL; + void *pReturnField = SHPLIB_NULLPTR; /* -------------------------------------------------------------------- */ /* Verify selection. */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psDBF->nRecords ) - return( NULL ); + return SHPLIB_NULLPTR; if( iField < 0 || iField >= psDBF->nFields ) - return( NULL ); + return SHPLIB_NULLPTR; /* -------------------------------------------------------------------- */ /* Have we read the record? */ /* -------------------------------------------------------------------- */ if( !DBFLoadRecord( psDBF, hEntity ) ) - return NULL; + return SHPLIB_NULLPTR; - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + pabyRec = REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord); /* -------------------------------------------------------------------- */ /* Ensure we have room to extract the target field. */ @@ -1122,18 +1170,18 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength ) { psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100; - if( psDBF->pszWorkField == NULL ) - psDBF->pszWorkField = (char *) malloc(psDBF->nWorkFieldLength); + if( psDBF->pszWorkField == SHPLIB_NULLPTR ) + psDBF->pszWorkField = STATIC_CAST(char *, malloc(psDBF->nWorkFieldLength)); else - psDBF->pszWorkField = (char *) realloc(psDBF->pszWorkField, - psDBF->nWorkFieldLength); + psDBF->pszWorkField = STATIC_CAST(char *, realloc(psDBF->pszWorkField, + psDBF->nWorkFieldLength)); } /* -------------------------------------------------------------------- */ /* Extract the requested field. */ /* -------------------------------------------------------------------- */ memcpy( psDBF->pszWorkField, - ((const char *) pabyRec) + psDBF->panFieldOffset[iField], + REINTERPRET_CAST(const char *, pabyRec) + psDBF->panFieldOffset[iField], psDBF->panFieldSize[iField] ); psDBF->pszWorkField[psDBF->panFieldSize[iField]] = '\0'; @@ -1176,7 +1224,7 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, } #endif - return( pReturnField ); + return pReturnField; } /************************************************************************/ @@ -1191,12 +1239,12 @@ DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField ) { int *pnValue; - pnValue = (int *) DBFReadAttribute( psDBF, iRecord, iField, 'I' ); + pnValue = STATIC_CAST(int *, DBFReadAttribute( psDBF, iRecord, iField, 'I' )); - if( pnValue == NULL ) + if( pnValue == SHPLIB_NULLPTR ) return 0; else - return( *pnValue ); + return *pnValue; } /************************************************************************/ @@ -1211,12 +1259,12 @@ DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField ) { double *pdValue; - pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); + pdValue = STATIC_CAST(double *, DBFReadAttribute( psDBF, iRecord, iField, 'N' )); - if( pdValue == NULL ) + if( pdValue == SHPLIB_NULLPTR ) return 0.0; else - return( *pdValue ); + return *pdValue ; } /************************************************************************/ @@ -1229,7 +1277,7 @@ const char SHPAPI_CALL1(*) DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField ) { - return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) ); + return STATIC_CAST(const char *, DBFReadAttribute( psDBF, iRecord, iField, 'C' ) ); } /************************************************************************/ @@ -1242,7 +1290,7 @@ const char SHPAPI_CALL1(*) DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField ) { - return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) ); + return STATIC_CAST(const char *, DBFReadAttribute( psDBF, iRecord, iField, 'L' ) ); } @@ -1256,7 +1304,7 @@ static int DBFIsValueNULL( char chType, const char* pszValue ) { int i; - if( pszValue == NULL ) + if( pszValue == SHPLIB_NULLPTR ) return TRUE; switch(chType) @@ -1308,7 +1356,7 @@ DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField ) pszValue = DBFReadStringAttribute( psDBF, iRecord, iField ); - if( pszValue == NULL ) + if( pszValue == SHPLIB_NULLPTR ) return TRUE; return DBFIsValueNULL( psDBF->pachFieldType[iField], pszValue ); @@ -1356,17 +1404,17 @@ DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, if( iField < 0 || iField >= psDBF->nFields ) return( FTInvalid ); - if( pnWidth != NULL ) + if( pnWidth != SHPLIB_NULLPTR ) *pnWidth = psDBF->panFieldSize[iField]; - if( pnDecimals != NULL ) + if( pnDecimals != SHPLIB_NULLPTR ) *pnDecimals = psDBF->panFieldDecimals[iField]; - if( pszFieldName != NULL ) + if( pszFieldName != SHPLIB_NULLPTR ) { int i; - strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*XBASE_FLDHDR_SZ, + strncpy( pszFieldName, STATIC_CAST(char *,psDBF->pszHeader)+iField*XBASE_FLDHDR_SZ, XBASE_FLDNAME_LEN_READ ); pszFieldName[XBASE_FLDNAME_LEN_READ] = '\0'; for( i = XBASE_FLDNAME_LEN_READ - 1; i > 0 && pszFieldName[i] == ' '; i-- ) @@ -1374,7 +1422,10 @@ DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, } if ( psDBF->pachFieldType[iField] == 'L' ) - return( FTLogical); + return( FTLogical ); + + else if( psDBF->pachFieldType[iField] == 'D' ) + return( FTDate ); else if( psDBF->pachFieldType[iField] == 'N' || psDBF->pachFieldType[iField] == 'F' ) @@ -1436,7 +1487,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, if( !DBFLoadRecord( psDBF, hEntity ) ) return FALSE; - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + pabyRec = REINTERPRET_CAST(unsigned char *,psDBF->pszCurrentRecord); psDBF->bCurrentRecordModified = TRUE; psDBF->bUpdated = TRUE; @@ -1446,9 +1497,9 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, /* */ /* Contributed by Jim Matthews. */ /* -------------------------------------------------------------------- */ - if( pValue == NULL ) + if( pValue == SHPLIB_NULLPTR ) { - memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), + memset( pabyRec+psDBF->panFieldOffset[iField], DBFGetNullCharacter(psDBF->pachFieldType[iField]), psDBF->panFieldSize[iField] ); return TRUE; @@ -1465,30 +1516,31 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, { int nWidth = psDBF->panFieldSize[iField]; - if( (int) sizeof(szSField)-2 < nWidth ) + if( STATIC_CAST(int,sizeof(szSField))-2 < nWidth ) nWidth = sizeof(szSField)-2; snprintf( szFormat, sizeof(szFormat), "%%%d.%df", nWidth, psDBF->panFieldDecimals[iField] ); - CPLsnprintf(szSField, sizeof(szSField), szFormat, *((double *) pValue) ); - if( (int) strlen(szSField) > psDBF->panFieldSize[iField] ) + CPLsnprintf(szSField, sizeof(szSField), szFormat, *STATIC_CAST(double *, pValue) ); + szSField[sizeof(szSField)-1] = '\0'; + if( STATIC_CAST(int,strlen(szSField)) > psDBF->panFieldSize[iField] ) { szSField[psDBF->panFieldSize[iField]] = '\0'; nRetResult = FALSE; } - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), + strncpy(REINTERPRET_CAST(char *, pabyRec+psDBF->panFieldOffset[iField]), szSField, strlen(szSField) ); break; } case 'L': if (psDBF->panFieldSize[iField] >= 1 && - (*(char*)pValue == 'F' || *(char*)pValue == 'T')) - *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue; + (*STATIC_CAST(char*,pValue) == 'F' || *STATIC_CAST(char*,pValue) == 'T')) + *(pabyRec+psDBF->panFieldOffset[iField]) = *STATIC_CAST(char*,pValue); break; default: - if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] ) + if( STATIC_CAST(int, strlen(STATIC_CAST(char *,pValue))) > psDBF->panFieldSize[iField] ) { j = psDBF->panFieldSize[iField]; nRetResult = FALSE; @@ -1497,11 +1549,11 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, { memset( pabyRec+psDBF->panFieldOffset[iField], ' ', psDBF->panFieldSize[iField] ); - j = (int)strlen((char *) pValue); + j = STATIC_CAST(int, strlen(STATIC_CAST(char *,pValue))); } - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), - (char *) pValue, j ); + strncpy(REINTERPRET_CAST(char *, pabyRec+psDBF->panFieldOffset[iField]), + STATIC_CAST(const char *, pValue), j ); break; } @@ -1555,22 +1607,22 @@ DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, if( !DBFLoadRecord( psDBF, hEntity ) ) return FALSE; - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + pabyRec = REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord); /* -------------------------------------------------------------------- */ /* Assign all the record fields. */ /* -------------------------------------------------------------------- */ - if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] ) + if( STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue))) > psDBF->panFieldSize[iField] ) j = psDBF->panFieldSize[iField]; else { memset( pabyRec+psDBF->panFieldOffset[iField], ' ', psDBF->panFieldSize[iField] ); - j = (int)strlen((char *) pValue); + j = STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue))); } - strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), - (char *) pValue, j ); + strncpy(REINTERPRET_CAST(char *, pabyRec+psDBF->panFieldOffset[iField]), + STATIC_CAST(const char *, pValue), j ); psDBF->bCurrentRecordModified = TRUE; psDBF->bUpdated = TRUE; @@ -1589,7 +1641,7 @@ DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField, double dValue ) { - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); + return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, &dValue) ) ); } /************************************************************************/ @@ -1605,7 +1657,7 @@ DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField, { double dValue = nValue; - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); + return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, &dValue) ) ); } /************************************************************************/ @@ -1619,7 +1671,7 @@ DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField, const char * pszValue ) { - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) ); + return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, CONST_CAST(char*, pszValue))) ); } /************************************************************************/ @@ -1632,7 +1684,7 @@ int SHPAPI_CALL DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField ) { - return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) ); + return( DBFWriteAttribute( psDBF, iRecord, iField, SHPLIB_NULLPTR ) ); } /************************************************************************/ @@ -1646,7 +1698,7 @@ DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField, const char lValue) { - return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) ); + return( DBFWriteAttribute( psDBF, iRecord, iField, STATIC_CAST(void *, CONST_CAST(char*, &lValue)) ) ); } /************************************************************************/ @@ -1693,7 +1745,7 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ) if( !DBFLoadRecord( psDBF, hEntity ) ) return FALSE; - pabyRec = (unsigned char *) psDBF->pszCurrentRecord; + pabyRec = REINTERPRET_CAST(unsigned char *, psDBF->pszCurrentRecord); memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength ); @@ -1715,12 +1767,12 @@ DBFReadTuple(DBFHandle psDBF, int hEntity ) { if( hEntity < 0 || hEntity >= psDBF->nRecords ) - return( NULL ); + return SHPLIB_NULLPTR; if( !DBFLoadRecord( psDBF, hEntity ) ) - return NULL; + return SHPLIB_NULLPTR; - return (const char *) psDBF->pszCurrentRecord; + return STATIC_CAST(const char *, psDBF->pszCurrentRecord); } /************************************************************************/ @@ -1735,7 +1787,7 @@ DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) DBFHandle newDBF; newDBF = DBFCreateEx ( pszFilename, psDBF->pszCodePage ); - if ( newDBF == NULL ) return ( NULL ); + if ( newDBF == SHPLIB_NULLPTR ) return SHPLIB_NULLPTR; newDBF->nFields = psDBF->nFields; newDBF->nRecordLength = psDBF->nRecordLength; @@ -1743,17 +1795,17 @@ DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) if( psDBF->pszHeader ) { - newDBF->pszHeader = (char *) malloc ( XBASE_FLDHDR_SZ * psDBF->nFields ); + newDBF->pszHeader = STATIC_CAST(char *, malloc ( XBASE_FLDHDR_SZ * psDBF->nFields )); memcpy ( newDBF->pszHeader, psDBF->pszHeader, XBASE_FLDHDR_SZ * psDBF->nFields ); } - newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); + newDBF->panFieldOffset = STATIC_CAST(int *, malloc ( sizeof(int) * psDBF->nFields )); memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); - newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields ); + newDBF->panFieldSize = STATIC_CAST(int *, malloc ( sizeof(int) * psDBF->nFields )); memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); - newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields ); + newDBF->panFieldDecimals = STATIC_CAST(int *, malloc ( sizeof(int) * psDBF->nFields )); memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); - newDBF->pachFieldType = (char *) malloc ( sizeof(char) * psDBF->nFields ); + newDBF->pachFieldType = STATIC_CAST(char *, malloc ( sizeof(char) * psDBF->nFields )); memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(char)*psDBF->nFields ); newDBF->bNoHeader = TRUE; @@ -1790,22 +1842,6 @@ DBFGetNativeFieldType( DBFHandle psDBF, int iField ) return ' '; } -/************************************************************************/ -/* str_to_upper() */ -/************************************************************************/ - -static void str_to_upper (char *string) -{ - int len; - int i = -1; - - len = (int)strlen (string); - - while (++i < len) - if (isalpha(string[i]) && islower(string[i])) - string[i] = (char) toupper ((int)string[i]); -} - /************************************************************************/ /* DBFGetFieldIndex() */ /* */ @@ -1818,23 +1854,13 @@ int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName) { - char name[XBASE_FLDNAME_LEN_READ+1], - name1[XBASE_FLDNAME_LEN_READ+1], - name2[XBASE_FLDNAME_LEN_READ+1]; + char name[XBASE_FLDNAME_LEN_READ+1]; int i; - strncpy(name1, pszFieldName,XBASE_FLDNAME_LEN_READ); - name1[XBASE_FLDNAME_LEN_READ] = '\0'; - str_to_upper(name1); - for( i = 0; i < DBFGetFieldCount(psDBF); i++ ) { - DBFGetFieldInfo( psDBF, i, name, NULL, NULL ); - strncpy(name2,name,XBASE_FLDNAME_LEN_READ); - name2[XBASE_FLDNAME_LEN_READ] = '\0'; - str_to_upper(name2); - - if(!strcmp(name1,name2)) + DBFGetFieldInfo( psDBF, i, name, SHPLIB_NULLPTR, SHPLIB_NULLPTR ); + if(!STRCASECMP(pszFieldName,name)) return(i); } return(-1); @@ -1916,8 +1942,8 @@ int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape, const char SHPAPI_CALL1(*) DBFGetCodePage(DBFHandle psDBF ) { - if( psDBF == NULL ) - return NULL; + if( psDBF == SHPLIB_NULLPTR ) + return SHPLIB_NULLPTR; return psDBF->pszCodePage; } @@ -1961,17 +1987,17 @@ DBFDeleteField(DBFHandle psDBF, int iField) /* resize fields arrays */ psDBF->nFields--; - psDBF->panFieldOffset = (int *) - SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); + psDBF->panFieldOffset = STATIC_CAST(int *, + SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields )); - psDBF->panFieldSize = (int *) - SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); + psDBF->panFieldSize = STATIC_CAST(int *, + SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields )); - psDBF->panFieldDecimals = (int *) - SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); + psDBF->panFieldDecimals = STATIC_CAST(int *, + SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields )); - psDBF->pachFieldType = (char *) - SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ); + psDBF->pachFieldType = STATIC_CAST(char *, + SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields )); /* update header information */ psDBF->nHeaderLength -= XBASE_FLDHDR_SZ; @@ -1982,12 +2008,12 @@ DBFDeleteField(DBFHandle psDBF, int iField) psDBF->pszHeader + (iField+1)*XBASE_FLDHDR_SZ, sizeof(char) * (psDBF->nFields - iField)*XBASE_FLDHDR_SZ); - psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader, - psDBF->nFields*XBASE_FLDHDR_SZ); + psDBF->pszHeader = STATIC_CAST(char *, SfRealloc(psDBF->pszHeader, + psDBF->nFields*XBASE_FLDHDR_SZ)); /* update size of current record appropriately */ - psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, - psDBF->nRecordLength); + psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord, + psDBF->nRecordLength)); /* we're done if we're dealing with not yet created .dbf */ if ( psDBF->bNoHeader && psDBF->nRecords == 0 ) @@ -1998,20 +2024,20 @@ DBFDeleteField(DBFHandle psDBF, int iField) DBFUpdateHeader( psDBF ); /* alloc record */ - pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength); + pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength)); /* shift records to their new positions */ for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++) { nRecordOffset = - nOldRecordLength * (SAOffset) iRecord + nOldHeaderLength; + nOldRecordLength * STATIC_CAST(SAOffset,iRecord) + nOldHeaderLength; /* load record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp ); nRecordOffset = - psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; /* move record in two steps */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -2025,6 +2051,10 @@ DBFDeleteField(DBFHandle psDBF, int iField) if( psDBF->bWriteEndOfFileChar ) { char ch = END_OF_FILE_CHARACTER; + SAOffset nEOFOffset = + psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength; + + psDBF->sHooks.FSeek( psDBF->fp, nEOFOffset, 0 ); psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp ); } @@ -2071,12 +2101,12 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) return FALSE; /* a simple malloc() would be enough, but calloc() helps clang static analyzer */ - panFieldOffsetNew = (int *) calloc(sizeof(int), psDBF->nFields); - panFieldSizeNew = (int *) calloc(sizeof(int), psDBF->nFields); - panFieldDecimalsNew = (int *) calloc(sizeof(int), psDBF->nFields); - pachFieldTypeNew = (char *) calloc(sizeof(char), psDBF->nFields); - pszHeaderNew = (char*) malloc(sizeof(char) * XBASE_FLDHDR_SZ * - psDBF->nFields); + panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); + panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); + panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); + pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields)); + pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * + psDBF->nFields)); /* shuffle fields definitions */ for(i=0; i < psDBF->nFields; i++) @@ -2104,14 +2134,14 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) DBFUpdateHeader( psDBF ); /* alloc record */ - pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength); - pszRecordNew = (char *) malloc(sizeof(char) * psDBF->nRecordLength); + pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); + pszRecordNew = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); /* shuffle fields in records */ for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++) { nRecordOffset = - psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; /* load record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -2219,13 +2249,13 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, if( chType == 'C' ) { - pszFInfo[16] = (unsigned char) (nWidth % 256); - pszFInfo[17] = (unsigned char) (nWidth / 256); + pszFInfo[16] = STATIC_CAST(unsigned char, nWidth % 256); + pszFInfo[17] = STATIC_CAST(unsigned char, nWidth / 256); } else { - pszFInfo[16] = (unsigned char) nWidth; - pszFInfo[17] = (unsigned char) nDecimals; + pszFInfo[16] = STATIC_CAST(unsigned char, nWidth); + pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals); } /* -------------------------------------------------------------------- */ @@ -2237,8 +2267,8 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, psDBF->panFieldOffset[i] += nWidth - nOldWidth; psDBF->nRecordLength += nWidth - nOldWidth; - psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, - psDBF->nRecordLength); + psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord, + psDBF->nRecordLength)); } /* we're done if we're dealing with not yet created .dbf */ @@ -2251,8 +2281,8 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType)) { - char* pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength); - char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1)); + char* pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * nOldRecordLength)); + char* pszOldField = STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1))); /* cppcheck-suppress uninitdata */ pszOldField[nOldWidth] = 0; @@ -2261,7 +2291,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++) { nRecordOffset = - nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + nOldRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; /* load record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -2272,7 +2302,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, if (nWidth != nOldWidth) { - if ((chOldType == 'N' || chOldType == 'F') && pszOldField[0] == ' ') + if ((chOldType == 'N' || chOldType == 'F' || chOldType == 'D') && pszOldField[0] == ' ') { /* Strip leading spaces when truncating a numeric field */ memmove( pszRecord + nOffset, @@ -2294,7 +2324,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, } nRecordOffset = - psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; /* write record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -2306,7 +2336,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, char ch = END_OF_FILE_CHARACTER; nRecordOffset = - psDBF->nRecordLength * (SAOffset) psDBF->nRecords + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength; psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp ); @@ -2318,8 +2348,8 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, } else if (nWidth > nOldWidth) { - char* pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength); - char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1)); + char* pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength)); + char* pszOldField = STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1))); /* cppcheck-suppress uninitdata */ pszOldField[nOldWidth] = 0; @@ -2328,7 +2358,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--) { nRecordOffset = - nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + nOldRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; /* load record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -2366,7 +2396,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, } nRecordOffset = - psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,iRecord) + psDBF->nHeaderLength; /* write record */ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); @@ -2378,7 +2408,7 @@ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName, char ch = END_OF_FILE_CHARACTER; nRecordOffset = - psDBF->nRecordLength * (SAOffset) psDBF->nRecords + psDBF->nHeaderLength; + psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength; psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ); psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp ); diff --git a/shapelib/safileio.c b/shapelib/safileio.c index 533e7ada3..d2c7f581c 100644 --- a/shapelib/safileio.c +++ b/shapelib/safileio.c @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: safileio.c,v 1.5 2016-12-05 12:44:05 erouault Exp $ + * $Id: safileio.c,v 1.6 2018-06-15 19:56:32 erouault Exp $ * * Project: Shapelib * Purpose: Default implementation of file io based on stdio. @@ -34,6 +34,10 @@ ****************************************************************************** * * $Log: safileio.c,v $ + * Revision 1.6 2018-06-15 19:56:32 erouault + * * safileio.c: remove duplicate test. Patch by Jaroslav Fojtik. + * Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2744 + * * Revision 1.5 2016-12-05 12:44:05 erouault * * Major overhaul of Makefile build system to use autoconf/automake. * @@ -70,7 +74,7 @@ #include #include -SHP_CVSID("$Id: safileio.c,v 1.5 2016-12-05 12:44:05 erouault Exp $"); +SHP_CVSID("$Id: safileio.c,v 1.6 2018-06-15 19:56:32 erouault Exp $"); #ifdef SHPAPI_UTF8_HOOKS # ifdef SHPAPI_WINDOWS @@ -236,7 +240,7 @@ SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess ) const wchar_t *pwszFileName, *pwszAccess; pwszFileName = Utf8ToWideChar( pszFilename ); pwszAccess = Utf8ToWideChar( pszAccess ); - if( pwszFileName != NULL && pwszFileName != NULL) + if( pwszFileName != NULL && pwszAccess != NULL) { file = (SAFile) _wfopen( pwszFileName, pwszAccess ); } diff --git a/shapelib/shapefil.h b/shapelib/shapefil.h index 08c645996..199964d42 100644 --- a/shapelib/shapefil.h +++ b/shapelib/shapefil.h @@ -2,7 +2,7 @@ #define SHAPEFILE_H_INCLUDED /****************************************************************************** - * $Id: shapefil.h,v 1.55 2016-12-05 18:44:08 erouault Exp $ + * $Id: shapefil.h,v 1.56 2018-08-16 15:39:07 erouault Exp $ * * Project: Shapelib * Purpose: Primary include file for Shapelib. @@ -38,6 +38,13 @@ ****************************************************************************** * * $Log: shapefil.h,v $ + * Revision 1.56 2018-08-16 15:39:07 erouault + * * shpopen.c, dbfopen.c, shptree.c, sbnsearch.c: resyc with GDAL + * internal shapelib. Mostly to allow building those files as C++ + * without warning. Also add FTDate entry in DBFFieldType + * (see https://github.com/OSGeo/gdal/pull/308). And some other + * code cleanups + * * Revision 1.55 2016-12-05 18:44:08 erouault * * dbfopen.c, shapefil.h: write DBF end-of-file character 0x1A by default. * This behaviour can be controlled with the DBFSetWriteEndOfFileChar() @@ -631,6 +638,7 @@ typedef enum { FTInteger, FTDouble, FTLogical, + FTDate, FTInvalid } DBFFieldType; diff --git a/shapelib/shapelib.html b/shapelib/shapelib.html index 19a433604..fa81f91aa 100644 --- a/shapelib/shapelib.html +++ b/shapelib/shapelib.html @@ -68,9 +68,8 @@

Bugs, Maintainance and Support

shapelib.maptools.org. A mailing list for discussion of how to use shapelib, and announcing new releases is -available. To only find out about new releases of Shapelib select the -"Subscribe to new releases" option from the link at -Freshmeat.

+available. To get notification of new releases of Shapelib subscribe to +the project mailing list at https://lists.osgeo.org/pipermail/shapelib/.

Credits

diff --git a/shapelib/shpopen.c b/shapelib/shpopen.c index f9d28c23d..2fcff96da 100644 --- a/shapelib/shpopen.c +++ b/shapelib/shpopen.c @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: shpopen.c,v 1.76 2017-09-10 10:11:36 erouault Exp $ + * $Id: shpopen.c,v 1.78 2019-02-28 15:55:23 erouault Exp $ * * Project: Shapelib * Purpose: Implementation of core Shapefile read/write functions. @@ -35,6 +35,18 @@ ****************************************************************************** * * $Log: shpopen.c,v $ + * Revision 1.78 2019-02-28 15:55:23 erouault + * * shpopen.c: resync with GDAL internal shapelib to avoid being dependent + * on correctness of file size field in .shp. Fixes + * https://lists.osgeo.org/pipermail/gdal-dev/2018-October/049218.html + * + * Revision 1.77 2018-08-16 15:39:07 erouault + * * shpopen.c, dbfopen.c, shptree.c, sbnsearch.c: resyc with GDAL + * internal shapelib. Mostly to allow building those files as C++ + * without warning. Also add FTDate entry in DBFFieldType + * (see https://github.com/OSGeo/gdal/pull/308). And some other + * code cleanups + * * Revision 1.76 2017-09-10 10:11:36 erouault * * shpopen.c: resync with GDAL copy. Make sure to zero terminate all * error messages. And fix regression regarding re-writing the last shape @@ -302,7 +314,7 @@ #include #include -SHP_CVSID("$Id: shpopen.c,v 1.76 2017-09-10 10:11:36 erouault Exp $") +SHP_CVSID("$Id: shpopen.c,v 1.78 2019-02-28 15:55:23 erouault Exp $") typedef unsigned char uchar; @@ -351,6 +363,14 @@ typedef unsigned int int32; static int bBigEndian; #endif +#ifdef __cplusplus +#define STATIC_CAST(type,x) static_cast(x) +#define SHPLIB_NULLPTR nullptr +#else +#define STATIC_CAST(type,x) ((type)(x)) +#define SHPLIB_NULLPTR NULL +#endif + /************************************************************************/ /* SwapWord() */ /* */ @@ -365,9 +385,9 @@ static void SwapWord( int length, void * wordP ) for( i=0; i < length/2; i++ ) { - temp = ((uchar *) wordP)[i]; - ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1]; - ((uchar *) wordP)[length-i-1] = temp; + temp = STATIC_CAST(uchar*, wordP)[i]; + STATIC_CAST(uchar*, wordP)[i] = STATIC_CAST(uchar*, wordP)[length-i-1]; + STATIC_CAST(uchar*, wordP)[length-i-1] = temp; } } @@ -381,10 +401,10 @@ static void SwapWord( int length, void * wordP ) static void * SfRealloc( void * pMem, int nNewSize ) { - if( pMem == NULL ) - return( (void *) malloc(nNewSize) ); + if( pMem == SHPLIB_NULLPTR ) + return malloc(nNewSize); else - return( (void *) realloc(pMem,nNewSize) ); + return realloc(pMem,nNewSize); } /************************************************************************/ @@ -403,7 +423,7 @@ void SHPAPI_CALL SHPWriteHeader( SHPHandle psSHP ) double dValue; int32 *panSHX; - if (psSHP->fpSHX == NULL) + if (psSHP->fpSHX == SHPLIB_NULLPTR) { psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed"); return; @@ -498,8 +518,8 @@ void SHPAPI_CALL SHPWriteHeader( SHPHandle psSHP ) /* -------------------------------------------------------------------- */ /* Write out the .shx contents. */ /* -------------------------------------------------------------------- */ - panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords); - if( panSHX == NULL ) + panSHX = STATIC_CAST(int32 *, malloc(sizeof(int32) * 2 * psSHP->nRecords)); + if( panSHX == SHPLIB_NULLPTR ) { psSHP->sHooks.Error( "Failure allocatin panSHX" ); return; @@ -513,7 +533,7 @@ void SHPAPI_CALL SHPWriteHeader( SHPHandle psSHP ) if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); } - if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) + if( STATIC_CAST(int, psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )) != psSHP->nRecords ) { char szErrorMsg[200]; @@ -548,6 +568,26 @@ SHPOpen( const char * pszLayer, const char * pszAccess ) return SHPOpenLL( pszLayer, pszAccess, &sHooks ); } +/************************************************************************/ +/* SHPGetLenWithoutExtension() */ +/************************************************************************/ + +static int SHPGetLenWithoutExtension(const char* pszBasename) +{ + int i; + int nLen = STATIC_CAST(int, strlen(pszBasename)); + for( i = nLen-1; + i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\'; + i-- ) + { + if( pszBasename[i] == '.' ) + { + return i; + } + } + return nLen; +} + /************************************************************************/ /* SHPOpen() */ /* */ @@ -559,14 +599,14 @@ SHPHandle SHPAPI_CALL SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) { - char *pszFullname, *pszBasename; + char *pszFullname; SHPHandle psSHP; uchar *pabyBuf; int i; double dValue; int bLazySHXLoading = FALSE; - size_t nFullnameLen; + int nLenWithoutExtension; /* -------------------------------------------------------------------- */ /* Ensure the access string is one of the legal ones. We */ @@ -578,7 +618,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) pszAccess = "r+b"; else { - bLazySHXLoading = strchr(pszAccess, 'l') != NULL; + bLazySHXLoading = strchr(pszAccess, 'l') != SHPLIB_NULLPTR; pszAccess = "rb"; } @@ -596,90 +636,85 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ - psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); + psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1)); psSHP->bUpdated = FALSE; memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) ); -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszLayer)+5); - strcpy( pszBasename, pszLayer ); - for( i = (int)strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ - nFullnameLen = strlen(pszBasename) + 5; - pszFullname = (char *) malloc(nFullnameLen); - snprintf( pszFullname, nFullnameLen, "%s.shp", pszBasename ) ; + nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer); + pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + memcpy(pszFullname, pszLayer, nLenWithoutExtension); + memcpy(pszFullname + nLenWithoutExtension, ".shp", 5); psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess ); - if( psSHP->fpSHP == NULL ) + if( psSHP->fpSHP == SHPLIB_NULLPTR ) { - snprintf( pszFullname, nFullnameLen, "%s.SHP", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5); psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess ); } - if( psSHP->fpSHP == NULL ) + if( psSHP->fpSHP == SHPLIB_NULLPTR ) { - size_t nMessageLen = strlen(pszBasename)*2+256; - char *pszMessage = (char *) malloc(nMessageLen); + size_t nMessageLen = strlen(pszFullname)*2+256; + char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen)); + pszFullname[nLenWithoutExtension] = 0; snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.", - pszBasename, pszBasename ); + pszFullname, pszFullname ); psHooks->Error( pszMessage ); free( pszMessage ); free( psSHP ); - free( pszBasename ); free( pszFullname ); - return NULL; + return SHPLIB_NULLPTR; } - snprintf( pszFullname, nFullnameLen, "%s.shx", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".shx", 5); psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess ); - if( psSHP->fpSHX == NULL ) + if( psSHP->fpSHX == SHPLIB_NULLPTR ) { - snprintf( pszFullname, nFullnameLen, "%s.SHX", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".SHX", 5); psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess ); } - if( psSHP->fpSHX == NULL ) + if( psSHP->fpSHX == SHPLIB_NULLPTR ) { - size_t nMessageLen = strlen(pszBasename)*2+256; - char *pszMessage = (char *) malloc(nMessageLen); - snprintf( pszMessage, nMessageLen, "Unable to open %s.shx or %s.SHX." - "Try --config SHAPE_RESTORE_SHX true to restore or create it", - pszBasename, pszBasename ); + size_t nMessageLen = strlen(pszFullname)*2+256; + char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen)); + pszFullname[nLenWithoutExtension] = 0; + snprintf( pszMessage, nMessageLen, "Unable to open %s.shx or %s.SHX. " + "Set SHAPE_RESTORE_SHX config option to YES to restore or " + "create it.", pszFullname, pszFullname ); psHooks->Error( pszMessage ); free( pszMessage ); psSHP->sHooks.FClose( psSHP->fpSHP ); free( psSHP ); - free( pszBasename ); free( pszFullname ); - return( NULL ); + return SHPLIB_NULLPTR ; } free( pszFullname ); - free( pszBasename ); /* -------------------------------------------------------------------- */ /* Read the file size from the SHP file. */ /* -------------------------------------------------------------------- */ - pabyBuf = (uchar *) malloc(100); - psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP ); + pabyBuf = STATIC_CAST(uchar *, malloc(100)); + if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP ) != 1 ) + { + psSHP->sHooks.Error( ".shp file is unreadable, or corrupt." ); + psSHP->sHooks.FClose( psSHP->fpSHP ); + psSHP->sHooks.FClose( psSHP->fpSHX ); + free( pabyBuf ); + free( psSHP ); + + return SHPLIB_NULLPTR ; + } - psSHP->nFileSize = ((unsigned int)pabyBuf[24]<<24)|(pabyBuf[25]<<16)| + psSHP->nFileSize = (STATIC_CAST(unsigned int, pabyBuf[24])<<24)|(pabyBuf[25]<<16)| (pabyBuf[26]<<8)|pabyBuf[27]; if( psSHP->nFileSize < UINT_MAX / 2 ) psSHP->nFileSize *= 2; @@ -701,7 +736,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) free( pabyBuf ); free( psSHP ); - return( NULL ); + return SHPLIB_NULLPTR; } psSHP->nRecords = pabyBuf[27]|(pabyBuf[26]<<8)|(pabyBuf[25]<<16)| @@ -725,7 +760,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) free( psSHP ); free(pabyBuf); - return( NULL ); + return SHPLIB_NULLPTR; } /* If a lot of records are advertized, check that the file is big enough */ @@ -736,9 +771,9 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 2 ); nFileSize = psSHP->sHooks.FTell( psSHP->fpSHX ); if( nFileSize > 100 && - nFileSize/2 < (SAOffset)(psSHP->nRecords * 4 + 50) ) + nFileSize/2 < STATIC_CAST(SAOffset, psSHP->nRecords * 4 + 50) ) { - psSHP->nRecords = (int)((nFileSize - 100) / 8); + psSHP->nRecords = STATIC_CAST(int, (nFileSize - 100) / 8); } psSHP->sHooks.FSeek( psSHP->fpSHX, 100, 0 ); } @@ -786,18 +821,18 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ psSHP->nMaxRecords = psSHP->nRecords; - psSHP->panRecOffset = (unsigned int *) - malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) ); - psSHP->panRecSize = (unsigned int *) - malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) ); + psSHP->panRecOffset = STATIC_CAST(unsigned int *, + malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) )); + psSHP->panRecSize = STATIC_CAST(unsigned int *, + malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) )); if( bLazySHXLoading ) - pabyBuf = NULL; + pabyBuf = SHPLIB_NULLPTR; else - pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) ); + pabyBuf = STATIC_CAST(uchar *, malloc(8 * MAX(1,psSHP->nRecords) )); - if (psSHP->panRecOffset == NULL || - psSHP->panRecSize == NULL || - (!bLazySHXLoading && pabyBuf == NULL)) + if (psSHP->panRecOffset == SHPLIB_NULLPTR || + psSHP->panRecSize == SHPLIB_NULLPTR || + (!bLazySHXLoading && pabyBuf == SHPLIB_NULLPTR)) { char szErrorMsg[200]; @@ -813,17 +848,18 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) if (psSHP->panRecSize) free( psSHP->panRecSize ); if (pabyBuf) free( pabyBuf ); free( psSHP ); - return( NULL ); + return SHPLIB_NULLPTR; } if( bLazySHXLoading ) { memset(psSHP->panRecOffset, 0, sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) ); memset(psSHP->panRecSize, 0, sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) ); + free( pabyBuf ); // sometimes make cppcheck happy, but return( psSHP ); } - if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) + if( STATIC_CAST(int, psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )) != psSHP->nRecords ) { char szErrorMsg[200]; @@ -842,14 +878,14 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) free( pabyBuf ); free( psSHP ); - return( NULL ); + return SHPLIB_NULLPTR; } /* In read-only mode, we can close the SHX now */ if (strcmp(pszAccess, "rb") == 0) { psSHP->sHooks.FClose( psSHP->fpSHX ); - psSHP->fpSHX = NULL; + psSHP->fpSHX = SHPLIB_NULLPTR; } for( i = 0; i < psSHP->nRecords; i++ ) @@ -862,7 +898,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) memcpy( &nLength, pabyBuf + i * 8 + 4, 4 ); if( !bBigEndian ) SwapWord( 4, &nLength ); - if( nOffset > (unsigned int)INT_MAX ) + if( nOffset > STATIC_CAST(unsigned int, INT_MAX) ) { char str[128]; snprintf( str, sizeof(str), @@ -872,9 +908,9 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) psSHP->sHooks.Error( str ); SHPClose(psSHP); free( pabyBuf ); - return NULL; + return SHPLIB_NULLPTR; } - if( nLength > (unsigned int)(INT_MAX / 2 - 4) ) + if( nLength > STATIC_CAST(unsigned int, INT_MAX / 2 - 4) ) { char str[128]; snprintf( str, sizeof(str), @@ -884,7 +920,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) psSHP->sHooks.Error( str ); SHPClose(psSHP); free( pabyBuf ); - return NULL; + return SHPLIB_NULLPTR; } psSHP->panRecOffset[i] = nOffset*2; psSHP->panRecSize[i] = nLength*2; @@ -916,7 +952,7 @@ SHPOpenLLEx( const char * pszLayer, const char * pszAccess, SAHooks *psHooks, } } - return( NULL ); + return SHPLIB_NULLPTR; } /************************************************************************/ @@ -930,18 +966,14 @@ int SHPAPI_CALL SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) { - char *pszFullname, *pszBasename; + char *pszFullname; SAFile fpSHP, fpSHX; uchar *pabyBuf; - int i; - size_t nFullnameLen; + int nLenWithoutExtension; unsigned int nSHPFilesize; - size_t nMessageLen; - char *pszMessage; - unsigned int nCurrentRecordOffset = 0; unsigned int nCurrentSHPOffset = 100; size_t nRealSHXContentSize = 100; @@ -970,51 +1002,41 @@ SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks /* Establish the byte order on this machine. */ /* -------------------------------------------------------------------- */ #if !defined(bBigEndian) - i = 1; - if( *((uchar *) &i) == 1 ) - bBigEndian = FALSE; - else - bBigEndian = TRUE; + { + int i = 1; + if( *((uchar *) &i) == 1 ) + bBigEndian = FALSE; + else + bBigEndian = TRUE; + } #endif -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszLayer)+5); - strcpy( pszBasename, pszLayer ); - for( i = (int)strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - /* -------------------------------------------------------------------- */ /* Open the .shp file. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ - nFullnameLen = strlen(pszBasename) + 5; - pszFullname = (char *) malloc(nFullnameLen); - snprintf( pszFullname, nFullnameLen, "%s.shp", pszBasename ) ; + nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer); + pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + memcpy(pszFullname, pszLayer, nLenWithoutExtension); + memcpy(pszFullname + nLenWithoutExtension, ".shp", 5); fpSHP = psHooks->FOpen(pszFullname, pszAccess ); - if( fpSHP == NULL ) + if( fpSHP == SHPLIB_NULLPTR ) { - snprintf( pszFullname, nFullnameLen, "%s.SHP", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5); fpSHP = psHooks->FOpen(pszFullname, pszAccess ); } - if( fpSHP == NULL ) + if( fpSHP == SHPLIB_NULLPTR ) { - nMessageLen = strlen(pszBasename)*2+256; - pszMessage = (char *) malloc(nMessageLen); + size_t nMessageLen = strlen( pszFullname ) * 2 + 256; + char* pszMessage = STATIC_CAST(char *, malloc( nMessageLen )); + + pszFullname[nLenWithoutExtension] = 0; snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.", - pszBasename, pszBasename ); + pszFullname, pszFullname ); psHooks->Error( pszMessage ); free( pszMessage ); - free( pszBasename ); free( pszFullname ); return( 0 ); @@ -1023,32 +1045,38 @@ SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks /* -------------------------------------------------------------------- */ /* Read the file size from the SHP file. */ /* -------------------------------------------------------------------- */ - pabyBuf = (uchar *) malloc(100); + pabyBuf = STATIC_CAST(uchar *, malloc(100)); psHooks->FRead( pabyBuf, 100, 1, fpSHP ); - nSHPFilesize = ((unsigned int)pabyBuf[24]<<24)|(pabyBuf[25]<<16)| + nSHPFilesize = (STATIC_CAST(unsigned int, pabyBuf[24])<<24)|(pabyBuf[25]<<16)| (pabyBuf[26]<<8)|pabyBuf[27]; if( nSHPFilesize < UINT_MAX / 2 ) nSHPFilesize *= 2; else nSHPFilesize = (UINT_MAX / 2) * 2; - snprintf( pszFullname, nFullnameLen, "%s.shx", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".shx", 5); fpSHX = psHooks->FOpen( pszFullname, pszSHXAccess ); + if( fpSHX == SHPLIB_NULLPTR ) + { + memcpy(pszFullname + nLenWithoutExtension, ".SHX", 5); + fpSHP = psHooks->FOpen(pszFullname, pszAccess ); + } - if( fpSHX == NULL ) + if( fpSHX == SHPLIB_NULLPTR ) { - nMessageLen = strlen( pszBasename ) * 2 + 256; - pszMessage = (char *) malloc( nMessageLen ); - snprintf( pszMessage, nMessageLen, "Error opening file %s.shx for writing", - pszBasename ); + size_t nMessageLen = strlen( pszFullname ) * 2 + 256; + char* pszMessage = STATIC_CAST(char *, malloc( nMessageLen )); + pszFullname[nLenWithoutExtension] = 0; + snprintf( pszMessage, nMessageLen, + "Error opening file %s.shx or %s.SHX for writing", + pszFullname, pszFullname ); psHooks->Error( pszMessage ); free( pszMessage ); psHooks->FClose( fpSHX ); free( pabyBuf ); - free( pszBasename ); free( pszFullname ); return( 0 ); @@ -1058,7 +1086,7 @@ SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks /* Open SHX and create it using SHP file content. */ /* -------------------------------------------------------------------- */ psHooks->FSeek( fpSHP, 100, 0 ); - pabySHXHeader = (char *) malloc ( 100 ); + pabySHXHeader = STATIC_CAST(char *, malloc ( 100 )); memcpy( pabySHXHeader, pabyBuf, 100 ); psHooks->FWrite( pabySHXHeader, 100, 1, fpSHX ); @@ -1090,7 +1118,6 @@ SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks psHooks->FClose( fpSHP ); free( pabySHXHeader ); - free( pszBasename ); free( pszFullname ); return( 0 ); @@ -1107,7 +1134,6 @@ SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks free ( pabyBuf ); free ( pszFullname ); - free ( pszBasename ); free ( pabySHXHeader ); return( 1 ); @@ -1123,7 +1149,7 @@ void SHPAPI_CALL SHPClose(SHPHandle psSHP ) { - if( psSHP == NULL ) + if( psSHP == SHPLIB_NULLPTR ) return; /* -------------------------------------------------------------------- */ @@ -1138,20 +1164,20 @@ SHPClose(SHPHandle psSHP ) free( psSHP->panRecOffset ); free( psSHP->panRecSize ); - if ( psSHP->fpSHX != NULL) + if ( psSHP->fpSHX != SHPLIB_NULLPTR) psSHP->sHooks.FClose( psSHP->fpSHX ); psSHP->sHooks.FClose( psSHP->fpSHP ); - if( psSHP->pabyRec != NULL ) + if( psSHP->pabyRec != SHPLIB_NULLPTR ) { free( psSHP->pabyRec ); } - if( psSHP->pabyObjectBuf != NULL ) + if( psSHP->pabyObjectBuf != SHPLIB_NULLPTR ) { free( psSHP->pabyObjectBuf ); } - if( psSHP->psCachedObject != NULL ) + if( psSHP->psCachedObject != SHPLIB_NULLPTR ) { free( psSHP->psCachedObject ); } @@ -1171,10 +1197,10 @@ void SHPAPI_CALL SHPSetFastModeReadObject( SHPHandle hSHP, int bFastMode ) { if( bFastMode ) { - if( hSHP->psCachedObject == NULL ) + if( hSHP->psCachedObject == SHPLIB_NULLPTR ) { - hSHP->psCachedObject = (SHPObject*) calloc(1, sizeof(SHPObject)); - assert( hSHP->psCachedObject != NULL ); + hSHP->psCachedObject = STATIC_CAST(SHPObject*, calloc(1, sizeof(SHPObject))); + assert( hSHP->psCachedObject != SHPLIB_NULLPTR ); } } @@ -1194,20 +1220,20 @@ SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType, { int i; - if( psSHP == NULL ) + if( psSHP == SHPLIB_NULLPTR ) return; - if( pnEntities != NULL ) + if( pnEntities != SHPLIB_NULLPTR ) *pnEntities = psSHP->nRecords; - if( pnShapeType != NULL ) + if( pnShapeType != SHPLIB_NULLPTR ) *pnShapeType = psSHP->nShapeType; for( i = 0; i < 4; i++ ) { - if( padfMinBound != NULL ) + if( padfMinBound != SHPLIB_NULLPTR ) padfMinBound[i] = psSHP->adBoundsMin[i]; - if( padfMaxBound != NULL ) + if( padfMaxBound != SHPLIB_NULLPTR ) padfMaxBound[i] = psSHP->adBoundsMax[i]; } } @@ -1241,47 +1267,36 @@ SHPHandle SHPAPI_CALL SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks ) { - char *pszBasename = NULL, *pszFullname = NULL; - int i; - SAFile fpSHP = NULL, fpSHX = NULL; + char *pszFullname; + SAFile fpSHP; + SAFile fpSHX = SHPLIB_NULLPTR; uchar abyHeader[100]; int32 i32; double dValue; - size_t nFullnameLen; + int nLenWithoutExtension; /* -------------------------------------------------------------------- */ /* Establish the byte order on this system. */ /* -------------------------------------------------------------------- */ #if !defined(bBigEndian) - i = 1; - if( *((uchar *) &i) == 1 ) - bBigEndian = FALSE; - else - bBigEndian = TRUE; + { + int i = 1; + if( *((uchar *) &i) == 1 ) + bBigEndian = FALSE; + else + bBigEndian = TRUE; + } #endif -/* -------------------------------------------------------------------- */ -/* Compute the base (layer) name. If there is any extension */ -/* on the passed in filename we will strip it off. */ -/* -------------------------------------------------------------------- */ - pszBasename = (char *) malloc(strlen(pszLayer)+5); - strcpy( pszBasename, pszLayer ); - for( i = (int)strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) - pszBasename[i] = '\0'; - /* -------------------------------------------------------------------- */ /* Open the two files so we can write their headers. */ /* -------------------------------------------------------------------- */ - nFullnameLen = strlen(pszBasename) + 5; - pszFullname = (char *) malloc(nFullnameLen); - snprintf( pszFullname, nFullnameLen, "%s.shp", pszBasename ); + nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer); + pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5)); + memcpy(pszFullname, pszLayer, nLenWithoutExtension); + memcpy(pszFullname + nLenWithoutExtension, ".shp", 5); fpSHP = psHooks->FOpen(pszFullname, "wb" ); - if( fpSHP == NULL ) + if( fpSHP == SHPLIB_NULLPTR ) { char szErrorMsg[200]; snprintf( szErrorMsg, sizeof(szErrorMsg), @@ -1292,9 +1307,9 @@ SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks ) goto error; } - snprintf( pszFullname, nFullnameLen, "%s.shx", pszBasename ); + memcpy(pszFullname + nLenWithoutExtension, ".shx", 5); fpSHX = psHooks->FOpen(pszFullname, "wb" ); - if( fpSHX == NULL ) + if( fpSHX == SHPLIB_NULLPTR ) { char szErrorMsg[200]; snprintf( szErrorMsg, sizeof(szErrorMsg), @@ -1304,8 +1319,7 @@ SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks ) goto error; } - free( pszFullname ); pszFullname = NULL; - free( pszBasename ); pszBasename = NULL; + free( pszFullname ); pszFullname = SHPLIB_NULLPTR; /* -------------------------------------------------------------------- */ /* Prepare header block for .shp file. */ @@ -1377,10 +1391,9 @@ SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks ) error: if (pszFullname) free(pszFullname); - if (pszBasename) free(pszBasename); if (fpSHP) psHooks->FClose( fpSHP ); if (fpSHX) psHooks->FClose( fpSHX ); - return NULL; + return SHPLIB_NULLPTR; } /************************************************************************/ @@ -1462,7 +1475,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, SHPObject *psObject; int i, bHasM, bHasZ; - psObject = (SHPObject *) calloc(1,sizeof(SHPObject)); + psObject = STATIC_CAST(SHPObject *, calloc(1,sizeof(SHPObject))); psObject->nSHPType = nSHPType; psObject->nShapeId = nShapeId; psObject->bMeasureIsUsed = FALSE; @@ -1504,20 +1517,20 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, { psObject->nParts = MAX(1,nParts); - psObject->panPartStart = (int *) - calloc(sizeof(int), psObject->nParts); - psObject->panPartType = (int *) - malloc(sizeof(int) * psObject->nParts); + psObject->panPartStart = STATIC_CAST(int *, + calloc(sizeof(int), psObject->nParts)); + psObject->panPartType = STATIC_CAST(int *, + malloc(sizeof(int) * psObject->nParts)); psObject->panPartStart[0] = 0; psObject->panPartType[0] = SHPP_RING; for( i = 0; i < nParts; i++ ) { - if( panPartStart != NULL ) + if( panPartStart != SHPLIB_NULLPTR ) psObject->panPartStart[i] = panPartStart[i]; - if( panPartType != NULL ) + if( panPartType != SHPLIB_NULLPTR ) psObject->panPartType[i] = panPartType[i]; else psObject->panPartType[i] = SHPP_RING; @@ -1533,21 +1546,21 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, if( nVertices > 0 ) { size_t nSize = sizeof(double) * nVertices; - psObject->padfX = (double *) padfX ? malloc(nSize) : - calloc(sizeof(double),nVertices); - psObject->padfY = (double *) padfY ? malloc(nSize) : - calloc(sizeof(double),nVertices); - psObject->padfZ = (double *) padfZ && bHasZ ? malloc(nSize) : - calloc(sizeof(double),nVertices); - psObject->padfM = (double *) padfM && bHasM ? malloc(nSize) : - calloc(sizeof(double),nVertices); - if( padfX != NULL ) + psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) : + calloc(sizeof(double),nVertices)); + psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) : + calloc(sizeof(double),nVertices)); + psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) : + calloc(sizeof(double),nVertices)); + psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) : + calloc(sizeof(double),nVertices)); + if( padfX != SHPLIB_NULLPTR ) memcpy(psObject->padfX, padfX, nSize); - if( padfY != NULL ) + if( padfY != SHPLIB_NULLPTR ) memcpy(psObject->padfY, padfY, nSize); - if( padfZ != NULL && bHasZ ) + if( padfZ != SHPLIB_NULLPTR && bHasZ ) memcpy(psObject->padfZ, padfZ, nSize); - if( padfM != NULL && bHasM ) + if( padfM != SHPLIB_NULLPTR && bHasM ) { memcpy(psObject->padfM, padfM, nSize); psObject->bMeasureIsUsed = TRUE; @@ -1576,8 +1589,8 @@ SHPCreateSimpleObject( int nSHPType, int nVertices, const double * padfZ ) { - return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL, - nVertices, padfX, padfY, padfZ, NULL ) ); + return( SHPCreateObject( nSHPType, -1, 0, SHPLIB_NULLPTR, SHPLIB_NULLPTR, + nVertices, padfX, padfY, padfZ, SHPLIB_NULLPTR ) ); } /************************************************************************/ @@ -1627,15 +1640,15 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) unsigned int* panRecOffsetNew; unsigned int* panRecSizeNew; - panRecOffsetNew = (unsigned int *) - SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * nNewMaxRecords ); - if( panRecOffsetNew == NULL ) + panRecOffsetNew = STATIC_CAST(unsigned int *, + SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * nNewMaxRecords )); + if( panRecOffsetNew == SHPLIB_NULLPTR ) return -1; psSHP->panRecOffset = panRecOffsetNew; - panRecSizeNew = (unsigned int *) - SfRealloc(psSHP->panRecSize,sizeof(unsigned int) * nNewMaxRecords ); - if( panRecSizeNew == NULL ) + panRecSizeNew = STATIC_CAST(unsigned int *, + SfRealloc(psSHP->panRecSize,sizeof(unsigned int) * nNewMaxRecords )); + if( panRecSizeNew == SHPLIB_NULLPTR ) return -1; psSHP->panRecSize = panRecSizeNew; @@ -1645,9 +1658,9 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) /* -------------------------------------------------------------------- */ /* Initialize record. */ /* -------------------------------------------------------------------- */ - pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) - + psObject->nParts * 8 + 128); - if( pabyRec == NULL ) + pabyRec = STATIC_CAST(uchar *, malloc(psObject->nVertices * 4 * sizeof(double) + + psObject->nParts * 8 + 128)); + if( pabyRec == SHPLIB_NULLPTR ) return -1; /* -------------------------------------------------------------------- */ @@ -2031,12 +2044,12 @@ static void* SHPAllocBuffer(unsigned char** pBuffer, int nSize) { unsigned char* pRet; - if( pBuffer == NULL ) + if( pBuffer == SHPLIB_NULLPTR ) return calloc(1, nSize); pRet = *pBuffer; - if( pRet == NULL ) - return NULL; + if( pRet == SHPLIB_NULLPTR ) + return SHPLIB_NULLPTR; (*pBuffer) += nSize; return pRet; @@ -2056,8 +2069,8 @@ static unsigned char* SHPReallocObjectBufIfNecessary ( SHPHandle psSHP, } if( nObjectBufSize > psSHP->nObjectBufSize ) { - pBuffer = (unsigned char*) realloc( psSHP->pabyObjectBuf, nObjectBufSize ); - if( pBuffer != NULL ) + pBuffer = STATIC_CAST(unsigned char*, realloc( psSHP->pabyObjectBuf, nObjectBufSize )); + if( pBuffer != SHPLIB_NULLPTR ) { psSHP->pabyObjectBuf = pBuffer; psSHP->nObjectBufSize = nObjectBufSize; @@ -2089,12 +2102,12 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) /* Validate the record/entity number. */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psSHP->nRecords ) - return( NULL ); + return SHPLIB_NULLPTR; /* -------------------------------------------------------------------- */ /* Read offset/length from SHX loading if necessary. */ /* -------------------------------------------------------------------- */ - if( psSHP->panRecOffset[hEntity] == 0 && psSHP->fpSHX != NULL ) + if( psSHP->panRecOffset[hEntity] == 0 && psSHP->fpSHX != SHPLIB_NULLPTR ) { unsigned int nOffset, nLength; @@ -2109,12 +2122,12 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) str[sizeof(str)-1] = '\0'; psSHP->sHooks.Error( str ); - return NULL; + return SHPLIB_NULLPTR; } if( !bBigEndian ) SwapWord( 4, &nOffset ); if( !bBigEndian ) SwapWord( 4, &nLength ); - if( nOffset > (unsigned int)INT_MAX ) + if( nOffset > STATIC_CAST(unsigned int, INT_MAX) ) { char str[128]; snprintf( str, sizeof(str), @@ -2122,9 +2135,9 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) str[sizeof(str)-1] = '\0'; psSHP->sHooks.Error( str ); - return NULL; + return SHPLIB_NULLPTR; } - if( nLength > (unsigned int)(INT_MAX / 2 - 4) ) + if( nLength > STATIC_CAST(unsigned int, INT_MAX / 2 - 4) ) { char str[128]; snprintf( str, sizeof(str), @@ -2132,7 +2145,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) str[sizeof(str)-1] = '\0'; psSHP->sHooks.Error( str ); - return NULL; + return SHPLIB_NULLPTR; } psSHP->panRecOffset[hEntity] = nOffset*2; @@ -2155,44 +2168,46 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) /* Before allocating too much memory, check that the file is big enough */ /* and do not trust the file size in the header the first time we */ /* need to allocate more than 10 MB */ - if( nNewBufSize >= 10 * 1024 * 1024 && - psSHP->nBufSize < 10 * 1024 * 1024 ) - { - SAOffset nFileSize; - psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 2 ); - nFileSize = psSHP->sHooks.FTell(psSHP->fpSHP); - if( nFileSize >= UINT_MAX ) - psSHP->nFileSize = UINT_MAX; - else - psSHP->nFileSize = (unsigned int)nFileSize; - } - - if( psSHP->panRecOffset[hEntity] >= psSHP->nFileSize || - /* We should normally use nEntitySize instead of*/ - /* psSHP->panRecSize[hEntity] in the below test, but because of */ - /* the case of non conformant .shx files detailed a bit below, */ - /* let be more tolerant */ - psSHP->panRecSize[hEntity] > psSHP->nFileSize - psSHP->panRecOffset[hEntity] ) + if( nNewBufSize >= 10 * 1024 * 1024 ) { - char str[128]; - snprintf( str, sizeof(str), - "Error in fread() reading object of size %d at offset %u from .shp file", - nEntitySize, psSHP->panRecOffset[hEntity] ); - str[sizeof(str)-1] = '\0'; + if( psSHP->nBufSize < 10 * 1024 * 1024 ) + { + SAOffset nFileSize; + psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 2 ); + nFileSize = psSHP->sHooks.FTell(psSHP->fpSHP); + if( nFileSize >= UINT_MAX ) + psSHP->nFileSize = UINT_MAX; + else + psSHP->nFileSize = STATIC_CAST(unsigned int, nFileSize); + } - psSHP->sHooks.Error( str ); - return NULL; + if( psSHP->panRecOffset[hEntity] >= psSHP->nFileSize || + /* We should normally use nEntitySize instead of*/ + /* psSHP->panRecSize[hEntity] in the below test, but because of */ + /* the case of non conformant .shx files detailed a bit below, */ + /* let be more tolerant */ + psSHP->panRecSize[hEntity] > psSHP->nFileSize - psSHP->panRecOffset[hEntity] ) + { + char str[128]; + snprintf( str, sizeof(str), + "Error in fread() reading object of size %d at offset %u from .shp file", + nEntitySize, psSHP->panRecOffset[hEntity] ); + str[sizeof(str)-1] = '\0'; + + psSHP->sHooks.Error( str ); + return SHPLIB_NULLPTR; + } } - pabyRecNew = (uchar *) SfRealloc(psSHP->pabyRec,nNewBufSize); - if (pabyRecNew == NULL) + pabyRecNew = STATIC_CAST(uchar *, SfRealloc(psSHP->pabyRec,nNewBufSize)); + if (pabyRecNew == SHPLIB_NULLPTR) { snprintf( szErrorMsg, sizeof(szErrorMsg), "Not enough memory to allocate requested memory (nNewBufSize=%d). " "Probably broken SHP file", nNewBufSize); szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); - return NULL; + return SHPLIB_NULLPTR; } /* Only set new buffer size after successful alloc */ @@ -2201,9 +2216,9 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) } /* In case we were not able to reallocate the buffer on a previous step */ - if (psSHP->pabyRec == NULL) + if (psSHP->pabyRec == SHPLIB_NULLPTR) { - return NULL; + return SHPLIB_NULLPTR; } /* -------------------------------------------------------------------- */ @@ -2222,10 +2237,10 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) str[sizeof(str)-1] = '\0'; psSHP->sHooks.Error( str ); - return NULL; + return SHPLIB_NULLPTR; } - nBytesRead = (int)psSHP->sHooks.FRead( psSHP->pabyRec, 1, nEntitySize, psSHP->fpSHP ); + nBytesRead = STATIC_CAST(int, psSHP->sHooks.FRead( psSHP->pabyRec, 1, nEntitySize, psSHP->fpSHP )); /* Special case for a shapefile whose .shx content length field is not equal */ /* to the content length field of the .shp, which is a violation of "The */ @@ -2250,7 +2265,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) str[sizeof(str)-1] = '\0'; psSHP->sHooks.Error( str ); - return NULL; + return SHPLIB_NULLPTR; } } else if( nBytesRead != nEntitySize ) @@ -2266,7 +2281,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) str[sizeof(str)-1] = '\0'; psSHP->sHooks.Error( str ); - return NULL; + return SHPLIB_NULLPTR; } if ( 8 + 4 > nEntitySize ) @@ -2276,7 +2291,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) hEntity, nEntitySize); szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); - return NULL; + return SHPLIB_NULLPTR; } memcpy( &nSHPType, psSHP->pabyRec + 8, 4 ); @@ -2291,14 +2306,14 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) { psSHP->sHooks.Error( "Invalid read pattern in fast read mode. " "SHPDestroyObject() should be called." ); - return NULL; + return SHPLIB_NULLPTR; } psShape = psSHP->psCachedObject; memset(psShape, 0, sizeof(SHPObject)); } else - psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); + psShape = STATIC_CAST(SHPObject *, calloc(1,sizeof(SHPObject))); psShape->nShapeId = hEntity; psShape->nSHPType = nSHPType; psShape->bMeasureIsUsed = FALSE; @@ -2316,8 +2331,8 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) { int32 nPoints, nParts; int i, nOffset; - unsigned char* pBuffer = NULL; - unsigned char** ppBuffer = NULL; + unsigned char* pBuffer = SHPLIB_NULLPTR; + unsigned char** ppBuffer = SHPLIB_NULLPTR; if ( 40 + 8 + 4 > nEntitySize ) { @@ -2327,7 +2342,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } /* -------------------------------------------------------------------- */ /* Get the X/Y bounds. */ @@ -2362,7 +2377,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } /* With the previous checks on nPoints and nParts, */ @@ -2387,7 +2402,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } if( psShape->bFastModeReadObject ) @@ -2398,21 +2413,21 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) } psShape->nVertices = nPoints; - psShape->padfX = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); - psShape->padfY = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); - psShape->padfZ = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); - psShape->padfM = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); + psShape->padfX = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); + psShape->padfY = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); + psShape->padfZ = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); + psShape->padfM = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); psShape->nParts = nParts; - psShape->panPartStart = (int *) SHPAllocBuffer(ppBuffer, nParts * sizeof(int)); - psShape->panPartType = (int *) SHPAllocBuffer(ppBuffer, nParts * sizeof(int)); + psShape->panPartStart = STATIC_CAST(int *, SHPAllocBuffer(ppBuffer, nParts * sizeof(int))); + psShape->panPartType = STATIC_CAST(int *, SHPAllocBuffer(ppBuffer, nParts * sizeof(int))); - if (psShape->padfX == NULL || - psShape->padfY == NULL || - psShape->padfZ == NULL || - psShape->padfM == NULL || - psShape->panPartStart == NULL || - psShape->panPartType == NULL) + if (psShape->padfX == SHPLIB_NULLPTR || + psShape->padfY == SHPLIB_NULLPTR || + psShape->padfZ == SHPLIB_NULLPTR || + psShape->padfM == SHPLIB_NULLPTR || + psShape->panPartStart == SHPLIB_NULLPTR || + psShape->panPartType == SHPLIB_NULLPTR) { snprintf(szErrorMsg, sizeof(szErrorMsg), "Not enough memory to allocate requested memory (nPoints=%u, nParts=%u) for shape %d. " @@ -2420,17 +2435,17 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } - for( i = 0; (int32)i < nParts; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nParts; i++ ) psShape->panPartType[i] = SHPP_RING; /* -------------------------------------------------------------------- */ /* Copy out the part array from the record. */ /* -------------------------------------------------------------------- */ memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts ); - for( i = 0; (int32)i < nParts; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nParts; i++ ) { if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); @@ -2446,7 +2461,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1]) { @@ -2456,7 +2471,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } } @@ -2468,7 +2483,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) if( psShape->nSHPType == SHPT_MULTIPATCH ) { memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts ); - for( i = 0; (int32)i < nParts; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nParts; i++ ) { if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); } @@ -2479,7 +2494,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) /* -------------------------------------------------------------------- */ /* Copy out the vertices from the record. */ /* -------------------------------------------------------------------- */ - for( i = 0; (int32)i < nPoints; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ ) { memcpy(psShape->padfX + i, psSHP->pabyRec + nOffset + i * 16, @@ -2508,7 +2523,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); - for( i = 0; (int32)i < nPoints; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); @@ -2519,7 +2534,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) } else if( psShape->bFastModeReadObject ) { - psShape->padfZ = NULL; + psShape->padfZ = SHPLIB_NULLPTR; } /* -------------------------------------------------------------------- */ @@ -2528,7 +2543,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ - if( nEntitySize >= (int)(nOffset + 16 + 8*nPoints) ) + if( nEntitySize >= STATIC_CAST(int, nOffset + 16 + 8*nPoints) ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); @@ -2536,7 +2551,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); - for( i = 0; (int32)i < nPoints; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); @@ -2546,7 +2561,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) } else if( psShape->bFastModeReadObject ) { - psShape->padfM = NULL; + psShape->padfM = SHPLIB_NULLPTR; } } @@ -2559,8 +2574,8 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) { int32 nPoints; int i, nOffset; - unsigned char* pBuffer = NULL; - unsigned char** ppBuffer = NULL; + unsigned char* pBuffer = SHPLIB_NULLPTR; + unsigned char** ppBuffer = SHPLIB_NULLPTR; if ( 44 + 4 > nEntitySize ) { @@ -2570,7 +2585,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); @@ -2585,7 +2600,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } nRequiredSize = 48 + nPoints * 16; @@ -2601,7 +2616,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } if( psShape->bFastModeReadObject ) @@ -2613,15 +2628,15 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) psShape->nVertices = nPoints; - psShape->padfX = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); - psShape->padfY = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); - psShape->padfZ = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); - psShape->padfM = (double *) SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints); + psShape->padfX = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); + psShape->padfY = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); + psShape->padfZ = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); + psShape->padfM = STATIC_CAST(double *, SHPAllocBuffer(ppBuffer, sizeof(double) * nPoints)); - if (psShape->padfX == NULL || - psShape->padfY == NULL || - psShape->padfZ == NULL || - psShape->padfM == NULL) + if (psShape->padfX == SHPLIB_NULLPTR || + psShape->padfY == SHPLIB_NULLPTR || + psShape->padfZ == SHPLIB_NULLPTR || + psShape->padfM == SHPLIB_NULLPTR) { snprintf(szErrorMsg, sizeof(szErrorMsg), "Not enough memory to allocate requested memory (nPoints=%u) for shape %d. " @@ -2629,10 +2644,10 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } - for( i = 0; (int32)i < nPoints; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ ) { memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); @@ -2667,7 +2682,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); - for( i = 0; (int32)i < nPoints; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); @@ -2677,7 +2692,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) nOffset += 16 + 8*nPoints; } else if( psShape->bFastModeReadObject ) - psShape->padfZ = NULL; + psShape->padfZ = SHPLIB_NULLPTR; /* -------------------------------------------------------------------- */ /* If we have a M measure value, then read it now. We assume */ @@ -2685,7 +2700,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ - if( nEntitySize >= (int)(nOffset + 16 + 8*nPoints) ) + if( nEntitySize >= STATIC_CAST(int, nOffset + 16 + 8*nPoints) ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); @@ -2693,7 +2708,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); - for( i = 0; (int32)i < nPoints; i++ ) + for( i = 0; STATIC_CAST(int32, i) < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); @@ -2702,7 +2717,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) psShape->bMeasureIsUsed = TRUE; } else if( psShape->bFastModeReadObject ) - psShape->padfM = NULL; + psShape->padfM = SHPLIB_NULLPTR; } /* ==================================================================== */ @@ -2726,10 +2741,10 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) } else { - psShape->padfX = (double *) calloc(1,sizeof(double)); - psShape->padfY = (double *) calloc(1,sizeof(double)); - psShape->padfZ = (double *) calloc(1,sizeof(double)); - psShape->padfM = (double *) calloc(1,sizeof(double)); + psShape->padfX = STATIC_CAST(double *, calloc(1,sizeof(double))); + psShape->padfY = STATIC_CAST(double *, calloc(1,sizeof(double))); + psShape->padfZ = STATIC_CAST(double *, calloc(1,sizeof(double))); + psShape->padfM = STATIC_CAST(double *, calloc(1,sizeof(double))); } if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize) @@ -2740,7 +2755,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity ) szErrorMsg[sizeof(szErrorMsg)-1] = '\0'; psSHP->sHooks.Error( szErrorMsg ); SHPDestroyObject(psShape); - return NULL; + return SHPLIB_NULLPTR; } memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); @@ -2887,7 +2902,7 @@ void SHPAPI_CALL SHPDestroyObject( SHPObject * psShape ) { - if( psShape == NULL ) + if( psShape == SHPLIB_NULLPTR ) return; if( psShape->bFastModeReadObject ) @@ -2896,23 +2911,114 @@ SHPDestroyObject( SHPObject * psShape ) return; } - if( psShape->padfX != NULL ) + if( psShape->padfX != SHPLIB_NULLPTR ) free( psShape->padfX ); - if( psShape->padfY != NULL ) + if( psShape->padfY != SHPLIB_NULLPTR ) free( psShape->padfY ); - if( psShape->padfZ != NULL ) + if( psShape->padfZ != SHPLIB_NULLPTR ) free( psShape->padfZ ); - if( psShape->padfM != NULL ) + if( psShape->padfM != SHPLIB_NULLPTR ) free( psShape->padfM ); - if( psShape->panPartStart != NULL ) + if( psShape->panPartStart != SHPLIB_NULLPTR ) free( psShape->panPartStart ); - if( psShape->panPartType != NULL ) + if( psShape->panPartType != SHPLIB_NULLPTR ) free( psShape->panPartType ); free( psShape ); } +/************************************************************************/ +/* SHPGetPartVertexCount() */ +/************************************************************************/ + +static int SHPGetPartVertexCount( const SHPObject * psObject, int iPart ) +{ + if( iPart == psObject->nParts-1 ) + return psObject->nVertices - psObject->panPartStart[iPart]; + else + return psObject->panPartStart[iPart+1] - psObject->panPartStart[iPart]; +} + +/************************************************************************/ +/* SHPRewindIsInnerRing() */ +/************************************************************************/ + +static int SHPRewindIsInnerRing( const SHPObject * psObject, + int iOpRing ) +{ +/* -------------------------------------------------------------------- */ +/* Determine if this ring is an inner ring or an outer ring */ +/* relative to all the other rings. For now we assume the */ +/* first ring is outer and all others are inner, but eventually */ +/* we need to fix this to handle multiple island polygons and */ +/* unordered sets of rings. */ +/* */ +/* -------------------------------------------------------------------- */ + + /* Use point in the middle of segment to avoid testing + * common points of rings. + */ + const int iOpRingStart = psObject->panPartStart[iOpRing]; + double dfTestX = ( psObject->padfX[iOpRingStart] + + psObject->padfX[iOpRingStart + 1] ) / 2; + double dfTestY = ( psObject->padfY[iOpRingStart] + + psObject->padfY[iOpRingStart + 1] ) / 2; + + int bInner = FALSE; + int iCheckRing; + for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ ) + { + int nVertStartCheck, nVertCountCheck; + int iEdge; + + if( iCheckRing == iOpRing ) + continue; + + nVertStartCheck = psObject->panPartStart[iCheckRing]; + nVertCountCheck = SHPGetPartVertexCount(psObject, iCheckRing); + + for( iEdge = 0; iEdge < nVertCountCheck; iEdge++ ) + { + int iNext; + + if( iEdge < nVertCountCheck-1 ) + iNext = iEdge+1; + else + iNext = 0; + + /* Rule #1: + * Test whether the edge 'straddles' the horizontal ray from + * the test point (dfTestY,dfTestY) + * The rule #1 also excludes edges colinear with the ray. + */ + if ( ( psObject->padfY[iEdge+nVertStartCheck] < dfTestY + && dfTestY <= psObject->padfY[iNext+nVertStartCheck] ) + || ( psObject->padfY[iNext+nVertStartCheck] < dfTestY + && dfTestY <= psObject->padfY[iEdge+nVertStartCheck] ) ) + { + /* Rule #2: + * Test if edge-ray intersection is on the right from the + * test point (dfTestY,dfTestY) + */ + double const intersect = + ( psObject->padfX[iEdge+nVertStartCheck] + + ( dfTestY - psObject->padfY[iEdge+nVertStartCheck] ) + / ( psObject->padfY[iNext+nVertStartCheck] - + psObject->padfY[iEdge+nVertStartCheck] ) + * ( psObject->padfX[iNext+nVertStartCheck] - + psObject->padfX[iEdge+nVertStartCheck] ) ); + + if (intersect < dfTestX) + { + bInner = !bInner; + } + } + } + } /* for iCheckRing */ + return bInner; +} + /************************************************************************/ /* SHPRewindObject() */ /* */ @@ -2942,100 +3048,33 @@ SHPRewindObject( CPL_UNUSED SHPHandle hSHP, /* -------------------------------------------------------------------- */ for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ ) { - int bInner, iVert, nVertCount, nVertStart, iCheckRing; - double dfSum, dfTestX, dfTestY; - -/* -------------------------------------------------------------------- */ -/* Determine if this ring is an inner ring or an outer ring */ -/* relative to all the other rings. For now we assume the */ -/* first ring is outer and all others are inner, but eventually */ -/* we need to fix this to handle multiple island polygons and */ -/* unordered sets of rings. */ -/* */ -/* -------------------------------------------------------------------- */ - - /* Use point in the middle of segment to avoid testing - * common points of rings. - */ - dfTestX = ( psObject->padfX[psObject->panPartStart[iOpRing]] - + psObject->padfX[psObject->panPartStart[iOpRing] + 1] ) / 2; - dfTestY = ( psObject->padfY[psObject->panPartStart[iOpRing]] - + psObject->padfY[psObject->panPartStart[iOpRing] + 1] ) / 2; - - bInner = FALSE; - for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ ) - { - int iEdge; - - if( iCheckRing == iOpRing ) - continue; - - nVertStart = psObject->panPartStart[iCheckRing]; + int bInner, iVert, nVertCount, nVertStart; + double dfSum; - if( iCheckRing == psObject->nParts-1 ) - nVertCount = psObject->nVertices - - psObject->panPartStart[iCheckRing]; - else - nVertCount = psObject->panPartStart[iCheckRing+1] - - psObject->panPartStart[iCheckRing]; + nVertStart = psObject->panPartStart[iOpRing]; + nVertCount = SHPGetPartVertexCount(psObject, iOpRing); - for( iEdge = 0; iEdge < nVertCount; iEdge++ ) - { - int iNext; + if (nVertCount < 2) + continue; - if( iEdge < nVertCount-1 ) - iNext = iEdge+1; - else - iNext = 0; - - /* Rule #1: - * Test whether the edge 'straddles' the horizontal ray from the test point (dfTestY,dfTestY) - * The rule #1 also excludes edges colinear with the ray. - */ - if ( ( psObject->padfY[iEdge+nVertStart] < dfTestY - && dfTestY <= psObject->padfY[iNext+nVertStart] ) - || ( psObject->padfY[iNext+nVertStart] < dfTestY - && dfTestY <= psObject->padfY[iEdge+nVertStart] ) ) - { - /* Rule #2: - * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY) - */ - double const intersect = - ( psObject->padfX[iEdge+nVertStart] - + ( dfTestY - psObject->padfY[iEdge+nVertStart] ) - / ( psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart] ) - * ( psObject->padfX[iNext+nVertStart] - psObject->padfX[iEdge+nVertStart] ) ); - - if (intersect < dfTestX) - { - bInner = !bInner; - } - } - } - } /* for iCheckRing */ + bInner = SHPRewindIsInnerRing(psObject, iOpRing); /* -------------------------------------------------------------------- */ /* Determine the current order of this ring so we will know if */ /* it has to be reversed. */ /* -------------------------------------------------------------------- */ - nVertStart = psObject->panPartStart[iOpRing]; - - if( iOpRing == psObject->nParts-1 ) - nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing]; - else - nVertCount = psObject->panPartStart[iOpRing+1] - - psObject->panPartStart[iOpRing]; - - if (nVertCount < 2) - continue; - dfSum = psObject->padfX[nVertStart] * (psObject->padfY[nVertStart+1] - psObject->padfY[nVertStart+nVertCount-1]); + dfSum = psObject->padfX[nVertStart] * + (psObject->padfY[nVertStart+1] - + psObject->padfY[nVertStart+nVertCount-1]); for( iVert = nVertStart + 1; iVert < nVertStart+nVertCount-1; iVert++ ) { - dfSum += psObject->padfX[iVert] * (psObject->padfY[iVert+1] - psObject->padfY[iVert-1]); + dfSum += psObject->padfX[iVert] * (psObject->padfY[iVert+1] - + psObject->padfY[iVert-1]); } - dfSum += psObject->padfX[iVert] * (psObject->padfY[nVertStart] - psObject->padfY[iVert-1]); + dfSum += psObject->padfX[iVert] * (psObject->padfY[nVertStart] - + psObject->padfY[iVert-1]); /* -------------------------------------------------------------------- */ /* Reverse if necessary. */