Changeset 30804


Ignore:
Timestamp:
Mar 30, 2008, 2:21:48 AM (16 years ago)
Author:
neteler
Message:

sync'ed to GDAL SVN-trunk: gdal/ogr/ogrsf_frmts/shape/

Location:
grass/trunk/lib/external/shapelib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • grass/trunk/lib/external/shapelib/README

    r24719 r30804  
    33
    44Last update
     5* taken from GDAL 1.5.1-SVN (Sun Mar 30 11:20:43 CEST 2008)
    56* taken from GDAL 1.5.0-CVS (Wed Sep  5 13:48:48 CEST 2007)
    6 
    77* taken from GDAL 1.3.2-CVS (Sat Jun 17 22:08:04 CEST 2006)
    88
    99Additional fixes:
    10  - dbfopen.c
     10 - dbfopen.c (around line 1013)
    1111   GDAL bug #809 (http://trac.osgeo.org/gdal/ticket/809)
    1212
  • grass/trunk/lib/external/shapelib/dbfopen.c

    r24719 r30804  
    3434 ******************************************************************************
    3535 *
    36  * $Log$
    37  * Revision 1.9  2007-09-05 11:50:23  markus
    38  * SHAPELIB copy updated
     36 * $Log: dbfopen.c,v $
     37 * Revision 1.74  2007/12/06 07:00:25  fwarmerdam
     38 * dbfopen now using SAHooks for fileio
    3939 *
    4040 * Revision 1.73  2007/09/03 19:48:11  fwarmerdam
     
    180180/*      descriptions.                                                   */
    181181/* -------------------------------------------------------------------- */
    182     fseek( psDBF->fp, 0, 0 );
    183     fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
    184     fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
     182    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
     183    psDBF->sHooks.FWrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
     184    psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields,
     185                          psDBF->fp );
    185186
    186187/* -------------------------------------------------------------------- */
     
    192193
    193194        cNewline = 0x0d;
    194         fwrite( &cNewline, 1, 1, psDBF->fp );
     195        psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
    195196    }
    196197}
     
    205206
    206207{
    207     int         nRecordOffset;
     208    SAOffset    nRecordOffset;
    208209
    209210    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
     
    211212        psDBF->bCurrentRecordModified = FALSE;
    212213
    213         nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord
    214                                                      + psDBF->nHeaderLength;
    215 
    216         if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0
    217             || fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength,
    218                        1, psDBF->fp ) != 1 )
     214        nRecordOffset =
     215            psDBF->nRecordLength * (SAOffset) psDBF->nCurrentRecord
     216            + psDBF->nHeaderLength;
     217
     218        if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0
     219            || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord,
     220                                     psDBF->nRecordLength,
     221                                     1, psDBF->fp ) != 1 )
    219222        {
    220223#ifdef USE_CPL
     
    242245    if( psDBF->nCurrentRecord != iRecord )
    243246    {
    244         int nRecordOffset;
     247        SAOffset nRecordOffset;
    245248
    246249        if( !DBFFlushRecord( psDBF ) )
    247250            return FALSE;
    248251
    249         nRecordOffset = psDBF->nRecordLength * iRecord + psDBF->nHeaderLength;
    250 
    251         if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
     252        nRecordOffset =
     253            psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
     254
     255        if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
    252256        {
    253257#ifdef USE_CPL
    254258            CPLError( CE_Failure, CPLE_FileIO,
    255                       "fseek(%d) failed on DBF file.\n",
    256                       nRecordOffset );
     259                      "fseek(%ld) failed on DBF file.\n",
     260                      (long) nRecordOffset );
    257261#else
    258             fprintf( stderr, "fseek(%d) failed on DBF file.\n",
    259                      nRecordOffset );
     262            fprintf( stderr, "fseek(%ld) failed on DBF file.\n",
     263                     (long) nRecordOffset );
    260264#endif
    261265            return FALSE;
    262266        }
    263267
    264         if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,
    265                    1, psDBF->fp ) != 1 )
     268        if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord,
     269                                 psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
    266270        {
    267271#ifdef USE_CPL
     
    297301    DBFFlushRecord( psDBF );
    298302
    299     fseek( psDBF->fp, 0, 0 );
    300     fread( abyFileHeader, 32, 1, psDBF->fp );
     303    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
     304    psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp );
    301305   
    302306    abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
     
    305309    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
    306310   
    307     fseek( psDBF->fp, 0, 0 );
    308     fwrite( abyFileHeader, 32, 1, psDBF->fp );
    309 
    310     fflush( psDBF->fp );
     311    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
     312    psDBF->sHooks.FWrite( abyFileHeader, 32, 1, psDBF->fp );
     313
     314    psDBF->sHooks.FFlush( psDBF->fp );
    311315}
    312316
     
    321325
    322326{
     327    SAHooks sHooks;
     328
     329    SASetupDefaultHooks( &sHooks );
     330
     331    return DBFOpenLL( pszFilename, pszAccess, &sHooks );
     332}
     333
     334/************************************************************************/
     335/*                              DBFOpen()                               */
     336/*                                                                      */
     337/*      Open a .dbf file.                                               */
     338/************************************************************************/
     339   
     340DBFHandle SHPAPI_CALL
     341DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
     342
     343{
    323344    DBFHandle           psDBF;
    324     unsigned char               *pabyBuf;
     345    unsigned char       *pabyBuf;
    325346    int                 nFields, nHeadLen, iField, i;
    326347    char                *pszBasename, *pszFullname;
     
    358379       
    359380    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
    360     psDBF->fp = fopen( pszFullname, pszAccess );
     381    psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
     382    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
    361383
    362384    if( psDBF->fp == NULL )
    363385    {
    364386        sprintf( pszFullname, "%s.DBF", pszBasename );
    365         psDBF->fp = fopen(pszFullname, pszAccess );
     387        psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
    366388    }
    367389   
     
    383405/* -------------------------------------------------------------------- */
    384406    pabyBuf = (unsigned char *) malloc(500);
    385     if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
    386     {
    387         fclose( psDBF->fp );
     407    if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
     408    {
     409        psDBF->sHooks.FClose( psDBF->fp );
    388410        free( pabyBuf );
    389411        free( psDBF );
     
    408430    psDBF->pszHeader = (char *) pabyBuf;
    409431
    410     fseek( psDBF->fp, 32, 0 );
    411     if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
    412     {
    413         fclose( psDBF->fp );
     432    psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
     433    if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
     434    {
     435        psDBF->sHooks.FClose( psDBF->fp );
    414436        free( pabyBuf );
    415437        free( psDBF->pszCurrentRecord );
     
    485507/*      Close, and free resources.                                      */
    486508/* -------------------------------------------------------------------- */
    487     fclose( psDBF->fp );
     509    psDBF->sHooks.FClose( psDBF->fp );
    488510
    489511    if( psDBF->panFieldOffset != NULL )
     
    514536
    515537{
     538    SAHooks sHooks;
     539
     540    SASetupDefaultHooks( &sHooks );
     541
     542    return DBFCreateLL( pszFilename, &sHooks );
     543}
     544
     545/************************************************************************/
     546/*                             DBFCreate()                              */
     547/*                                                                      */
     548/*      Create a new .dbf file.                                         */
     549/************************************************************************/
     550
     551DBFHandle SHPAPI_CALL
     552DBFCreateLL( const char * pszFilename, SAHooks *psHooks )
     553
     554{
    516555    DBFHandle   psDBF;
    517     FILE        *fp;
     556    SAFile      fp;
    518557    char        *pszFullname, *pszBasename;
    519558    int         i;
     559    char chZero = '\0';
    520560
    521561/* -------------------------------------------------------------------- */
     
    540580/*      Create the file.                                                */
    541581/* -------------------------------------------------------------------- */
    542     fp = fopen( pszFullname, "wb" );
     582    fp = psHooks->FOpen( pszFullname, "wb" );
    543583    if( fp == NULL )
    544584        return( NULL );
    545 
    546     fputc( 0, fp );
    547     fclose( fp );
    548 
    549     fp = fopen( pszFullname, "rb+" );
     585   
     586    psHooks->FWrite( &chZero, 1, 1, fp );
     587    psHooks->FClose( fp );
     588
     589    fp = psHooks->FOpen( pszFullname, "rb+" );
    550590    if( fp == NULL )
    551591        return( NULL );
     
    558598    psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo));
    559599
     600    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
    560601    psDBF->fp = fp;
    561602    psDBF->nRecords = 0;
  • grass/trunk/lib/external/shapelib/shapefil.h

    r24719 r30804  
    3737 ******************************************************************************
    3838 *
    39  * $Log$
    40  * Revision 1.6  2007-09-05 11:50:23  markus
    41  * SHAPELIB copy updated
     39 * $Log: shapefil.h,v $
     40 * Revision 1.40  2007/12/06 07:00:25  fwarmerdam
     41 * dbfopen now using SAHooks for fileio
     42 *
     43 * Revision 1.39  2007/12/04 20:37:56  fwarmerdam
     44 * preliminary implementation of hooks api for io and errors
     45 *
     46 * Revision 1.38  2007/11/21 22:39:56  fwarmerdam
     47 * close shx file in readonly mode (GDAL #1956)
     48 *
     49 * Revision 1.37  2007/10/27 03:31:14  fwarmerdam
     50 * limit default depth of tree to 12 levels (gdal ticket #1594)
     51 *
     52 * Revision 1.36  2007/09/10 23:33:15  fwarmerdam
     53 * Upstreamed support for visibility flag in SHPAPI_CALL for the needs
     54 * of GDAL (gdal ticket #1810).
    4255 *
    4356 * Revision 1.35  2007/09/03 19:48:10  fwarmerdam
     
    92105#ifdef USE_CPL
    93106#include "cpl_error.h"
     107#include "cpl_vsi.h"
    94108#endif
    95109
     
    114128/* -------------------------------------------------------------------- */
    115129#define DISABLE_MULTIPATCH_MEASURE
    116 
     130   
    117131/* -------------------------------------------------------------------- */
    118132/*      SHPAPI_CALL                                                     */
     
    150164
    151165#ifndef SHPAPI_CALL
    152 #  define SHPAPI_CALL
     166#  if defined(USE_GCC_VISIBILITY_FLAG)
     167#    define SHPAPI_CALL     __attribute__ ((visibility("default")))
     168#    define SHPAPI_CALL1(x) __attribute__ ((visibility("default")))     x
     169#  else
     170#    define SHPAPI_CALL
     171#  endif
    153172#endif
    154173
     
    167186#  define SHP_CVSID(string)
    168187#endif
     188   
     189/* -------------------------------------------------------------------- */
     190/*      IO/Error hook functions.                                        */
     191/* -------------------------------------------------------------------- */
     192typedef int *SAFile;
     193
     194#ifndef SAOffset
     195typedef unsigned long SAOffset;
     196#endif
     197
     198typedef struct {
     199    SAFile     (*FOpen) ( const char *filename, const char *path);
     200    SAOffset   (*FRead) ( void *p, SAOffset size, SAOffset nmemb, SAFile file);
     201    SAOffset   (*FWrite)( void *p, SAOffset size, SAOffset nmemb, SAFile file);
     202    SAOffset   (*FSeek) ( SAFile file, SAOffset offset, int whence );
     203    SAOffset   (*FTell) ( SAFile file );
     204    int        (*FFlush)( SAFile file );
     205    int        (*FClose)( SAFile file );
     206
     207    void       (*Error) ( const char *message );
     208} SAHooks;
     209
     210void SHPAPI_CALL SASetupDefaultHooks( SAHooks *psHooks );
    169211
    170212/************************************************************************/
     
    173215typedef struct
    174216{
    175     FILE        *fpSHP;
    176     FILE        *fpSHX;
     217    SAHooks sHooks;
     218
     219    SAFile      fpSHP;
     220    SAFile      fpSHX;
    177221
    178222    int         nShapeType;                             /* SHPT_* */
     
    263307/*      SHP API Prototypes                                              */
    264308/* -------------------------------------------------------------------- */
     309
     310/* If pszAccess is read-only, the fpSHX field of the returned structure */
     311/* will be NULL as it is not necessary to keep the SHX file open */
    265312SHPHandle SHPAPI_CALL
    266313      SHPOpen( const char * pszShapeFile, const char * pszAccess );
    267314SHPHandle SHPAPI_CALL
     315      SHPOpenLL( const char *pszShapeFile, const char *pszAccess,
     316                 SAHooks *psHooks );
     317SHPHandle SHPAPI_CALL
    268318      SHPCreate( const char * pszShapeFile, int nShapeType );
     319SHPHandle SHPAPI_CALL
     320      SHPCreateLL( const char * pszShapeFile, int nShapeType,
     321                   SAHooks *psHooks );
    269322void SHPAPI_CALL
    270323      SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
     
    310363#define MAX_SUBNODE     4
    311364
     365/* upper limit of tree levels for automatic estimation */
     366#define MAX_DEFAULT_TREE_DEPTH 12
     367
    312368typedef struct shape_tree_node
    313369{
     
    377433typedef struct
    378434{
    379     FILE        *fp;
     435    SAHooks sHooks;
     436
     437    SAFile      fp;
    380438
    381439    int         nRecords;
     
    416474#define XBASE_FLDHDR_SZ       32
    417475
     476
    418477DBFHandle SHPAPI_CALL
    419478      DBFOpen( const char * pszDBFFile, const char * pszAccess );
    420479DBFHandle SHPAPI_CALL
     480      DBFOpenLL( const char * pszDBFFile, const char * pszAccess,
     481                 SAHooks *psHooks );
     482DBFHandle SHPAPI_CALL
    421483      DBFCreate( const char * pszDBFFile );
     484DBFHandle SHPAPI_CALL
     485      DBFCreateLL( const char * pszDBFFile, SAHooks *psHooks );
    422486
    423487int     SHPAPI_CALL
  • grass/trunk/lib/external/shapelib/shpopen.c

    r24719 r30804  
    3434 ******************************************************************************
    3535 *
    36  * $Log$
    37  * Revision 1.7  2007-09-05 11:50:23  markus
    38  * SHAPELIB copy updated
     36 * $Log: shpopen.c,v $
     37 * Revision 1.59  2008/03/14 05:25:31  fwarmerdam
     38 * Correct crash on buggy geometries (gdal #2218)
     39 *
     40 * Revision 1.58  2008/01/08 23:28:26  bram
     41 * on line 2095, use a float instead of a double to avoid a compiler warning
     42 *
     43 * Revision 1.57  2007/12/06 07:00:25  fwarmerdam
     44 * dbfopen now using SAHooks for fileio
     45 *
     46 * Revision 1.56  2007/12/04 20:37:56  fwarmerdam
     47 * preliminary implementation of hooks api for io and errors
     48 *
     49 * Revision 1.55  2007/11/21 22:39:56  fwarmerdam
     50 * close shx file in readonly mode (GDAL #1956)
     51 *
     52 * Revision 1.54  2007/11/15 00:12:47  mloskot
     53 * Backported recent changes from GDAL (Ticket #1415) to Shapelib.
     54 *
     55 * Revision 1.53  2007/11/14 22:31:08  fwarmerdam
     56 * checks after mallocs to detect for corrupted/voluntary broken shapefiles.
     57 * http://trac.osgeo.org/gdal/ticket/1991
     58 *
     59 * Revision 1.52  2007/06/21 15:58:33  fwarmerdam
     60 * fix for SHPRewindObject when rings touch at one vertex (gdal #976)
    3961 *
    4062 * Revision 1.51  2006/09/04 15:24:01  fwarmerdam
     
    209231#include <string.h>
    210232#include <stdio.h>
    211 #ifdef USE_CPL
    212 #include <cpl_vsi.h>
    213 #endif
    214233
    215234SHP_CVSID("$Id$")
     
    288307    double      dValue;
    289308    int32       *panSHX;
     309   
     310    if (psSHP->fpSHX == NULL)
     311    {
     312        psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed");
     313        return;
     314    }
    290315
    291316/* -------------------------------------------------------------------- */
     
    345370/*      Write .shp file header.                                         */
    346371/* -------------------------------------------------------------------- */
    347     if( fseek( psSHP->fpSHP, 0, 0 ) != 0
    348         || fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
    349     {
    350 #ifdef USE_CPL
    351         CPLError( CE_Failure, CPLE_OpenFailed,
    352                   "Failure writing .shp header (%s)", VSIStrerror( errno ) );
    353 #endif
     372    if( psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 0 ) != 0
     373        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
     374    {
     375        psSHP->sHooks.Error( "Failure writing .shp header" );
    354376        return;
    355377    }
     
    362384    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
    363385   
    364     if( fseek( psSHP->fpSHX, 0, 0 ) != 0
    365         || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
    366     {
    367 #ifdef USE_CPL
    368         CPLError( CE_Failure, CPLE_OpenFailed,
    369                   "Failure writing .shx header (%s)", VSIStrerror( errno ) );
    370 #endif
     386    if( psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 0 ) != 0
     387        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
     388    {
     389        psSHP->sHooks.Error( "Failure writing .shx header" );
    371390        return;
    372391    }
     
    385404    }
    386405
    387     if( (int)fwrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )
     406    if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )
    388407        != psSHP->nRecords )
    389408    {
    390 #ifdef USE_CPL
    391         CPLError( CE_Failure, CPLE_OpenFailed,
    392                   "Failure writing .shx contents (%s)", VSIStrerror( errno ) );
    393 #endif
     409        psSHP->sHooks.Error( "Failure writing .shx contents" );
    394410    }
    395411
     
    399415/*      Flush to disk.                                                  */
    400416/* -------------------------------------------------------------------- */
    401     fflush( psSHP->fpSHP );
    402     fflush( psSHP->fpSHX );
     417    psSHP->sHooks.FFlush( psSHP->fpSHP );
     418    psSHP->sHooks.FFlush( psSHP->fpSHX );
    403419}
    404420
    405421/************************************************************************/
    406 /*                              shpopen()                               */
     422/*                              SHPOpen()                               */
     423/************************************************************************/
     424
     425SHPHandle SHPAPI_CALL
     426SHPOpen( const char * pszLayer, const char * pszAccess )
     427
     428{
     429    SAHooks sHooks;
     430
     431    SASetupDefaultHooks( &sHooks );
     432
     433    return SHPOpenLL( pszLayer, pszAccess, &sHooks );
     434}
     435
     436/************************************************************************/
     437/*                              SHPOpen()                               */
    407438/*                                                                      */
    408439/*      Open the .shp and .shx files based on the basename of the       */
     
    411442   
    412443SHPHandle SHPAPI_CALL
    413 SHPOpen( const char * pszLayer, const char * pszAccess )
     444SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks )
    414445
    415446{
     
    447478
    448479    psSHP->bUpdated = FALSE;
     480    memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
    449481
    450482/* -------------------------------------------------------------------- */
     
    467499/* -------------------------------------------------------------------- */
    468500    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
    469     sprintf( pszFullname, "%s.shp", pszBasename );
    470     psSHP->fpSHP = fopen(pszFullname, pszAccess );
     501    sprintf( pszFullname, "%s.shp", pszBasename ) ;
     502    psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
    471503    if( psSHP->fpSHP == NULL )
    472504    {
    473505        sprintf( pszFullname, "%s.SHP", pszBasename );
    474         psSHP->fpSHP = fopen(pszFullname, pszAccess );
     506        psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
    475507    }
    476508   
     
    489521
    490522    sprintf( pszFullname, "%s.shx", pszBasename );
    491     psSHP->fpSHX = fopen(pszFullname, pszAccess );
     523    psSHP->fpSHX =  psSHP->sHooks.FOpen(pszFullname, pszAccess );
    492524    if( psSHP->fpSHX == NULL )
    493525    {
    494526        sprintf( pszFullname, "%s.SHX", pszBasename );
    495         psSHP->fpSHX = fopen(pszFullname, pszAccess );
     527        psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
    496528    }
    497529   
     
    503535                  pszBasename, pszBasename );
    504536#endif
    505         fclose( psSHP->fpSHP );
     537        psSHP->sHooks.FClose( psSHP->fpSHP );
    506538        free( psSHP );
    507539        free( pszBasename );
     
    517549/* -------------------------------------------------------------------- */
    518550    pabyBuf = (uchar *) malloc(100);
    519     fread( pabyBuf, 100, 1, psSHP->fpSHP );
     551    psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
    520552
    521553    psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
     
    527559/*  Read SHX file Header info                                           */
    528560/* -------------------------------------------------------------------- */
    529     if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1
     561    if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1
    530562        || pabyBuf[0] != 0
    531563        || pabyBuf[1] != 0
     
    533565        || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
    534566    {
    535 #ifdef USE_CPL
    536         CPLError( CE_Failure, CPLE_AppDefined,
    537                   ".shx file is unreadable, or corrupt." );
    538 #endif
    539         fclose( psSHP->fpSHP );
    540         fclose( psSHP->fpSHX );
     567        psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
     568        psSHP->sHooks.FClose( psSHP->fpSHP );
     569        psSHP->sHooks.FClose( psSHP->fpSHX );
    541570        free( psSHP );
    542571
     
    552581    if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
    553582    {
    554 #ifdef USE_CPL
    555         CPLError( CE_Failure, CPLE_AppDefined,
    556                   "Record count in .shp header is %d, which seems\n"
    557                   "unreasonable.  Assuming header is corrupt.",
     583        char szError[200];
     584       
     585        sprintf( szError,
     586                 "Record count in .shp header is %d, which seems\n"
     587                 "unreasonable.  Assuming header is corrupt.",
    558588                  psSHP->nRecords );
    559 #endif
    560         fclose( psSHP->fpSHP );
    561         fclose( psSHP->fpSHX );
     589        psSHP->sHooks.Error( szError );                               
     590        psSHP->sHooks.FClose( psSHP->fpSHP );
     591        psSHP->sHooks.FClose( psSHP->fpSHX );
    562592        free( psSHP );
     593        free(pabyBuf);
    563594
    564595        return( NULL );
     
    612643    psSHP->panRecSize =
    613644        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
    614 
    615645    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
    616     if( (int) fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )
     646
     647    if (psSHP->panRecOffset == NULL ||
     648        psSHP->panRecSize == NULL ||
     649        pabyBuf == NULL)
     650    {
     651        char szError[200];
     652
     653        sprintf(szError,
     654                "Not enough memory to allocate requested memory (nRecords=%d).\n"
     655                "Probably broken SHP file",
     656                psSHP->nRecords );
     657        psSHP->sHooks.Error( szError );
     658        psSHP->sHooks.FClose( psSHP->fpSHP );
     659        psSHP->sHooks.FClose( psSHP->fpSHX );
     660        if (psSHP->panRecOffset) free( psSHP->panRecOffset );
     661        if (psSHP->panRecSize) free( psSHP->panRecSize );
     662        if (pabyBuf) free( pabyBuf );
     663        free( psSHP );
     664        return( NULL );
     665    }
     666
     667    if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )
    617668                        != psSHP->nRecords )
    618669    {
    619 #ifdef USE_CPL
    620         CPLError( CE_Failure, CPLE_AppDefined,
    621                   "Failed to read all values for %d records in .shx file.",
    622                   psSHP->nRecords );
    623 #endif
     670        char szError[200];
     671
     672        sprintf( szError,
     673                 "Failed to read all values for %d records in .shx file.",
     674                 psSHP->nRecords );
     675        psSHP->sHooks.Error( szError );
     676
    624677        /* SHX is short or unreadable for some reason. */
    625         fclose( psSHP->fpSHP );
    626         fclose( psSHP->fpSHX );
     678        psSHP->sHooks.FClose( psSHP->fpSHP );
     679        psSHP->sHooks.FClose( psSHP->fpSHX );
    627680        free( psSHP->panRecOffset );
    628681        free( psSHP->panRecSize );
     682        free( pabyBuf );
    629683        free( psSHP );
    630684
    631685        return( NULL );
     686    }
     687   
     688    /* In read-only mode, we can close the SHX now */
     689    if (strcmp(pszAccess, "rb") == 0)
     690    {
     691        psSHP->sHooks.FClose( psSHP->fpSHX );
     692        psSHP->fpSHX = NULL;
    632693    }
    633694
     
    675736    free( psSHP->panRecSize );
    676737
    677     fclose( psSHP->fpSHX );
    678     fclose( psSHP->fpSHP );
     738    if ( psSHP->fpSHX != NULL)
     739        psSHP->sHooks.FClose( psSHP->fpSHX );
     740    psSHP->sHooks.FClose( psSHP->fpSHP );
    679741
    680742    if( psSHP->pabyRec != NULL )
     
    728790
    729791{
     792    SAHooks sHooks;
     793
     794    SASetupDefaultHooks( &sHooks );
     795
     796    return SHPCreateLL( pszLayer, nShapeType, &sHooks );
     797}
     798
     799/************************************************************************/
     800/*                             SHPCreate()                              */
     801/*                                                                      */
     802/*      Create a new shape file and return a handle to the open         */
     803/*      shape file with read/write access.                              */
     804/************************************************************************/
     805
     806SHPHandle SHPAPI_CALL
     807SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks )
     808
     809{
    730810    char        *pszBasename, *pszFullname;
    731811    int         i;
    732     FILE        *fpSHP, *fpSHX;
     812    SAFile      fpSHP, fpSHX;
    733813    uchar       abyHeader[100];
    734814    int32       i32;
     
    763843    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
    764844    sprintf( pszFullname, "%s.shp", pszBasename );
    765     fpSHP = fopen(pszFullname, "wb" );
     845    fpSHP = psHooks->FOpen(pszFullname, "wb" );
    766846    if( fpSHP == NULL )
    767847    {
    768 #ifdef USE_CPL
    769         CPLError( CE_Failure, CPLE_AppDefined,
    770                   "Failed to create file %s.",
    771                   pszFullname );
    772 #endif
     848        psHooks->Error( "Failed to create file .shp file." );
    773849        return( NULL );
    774850    }
    775851
    776852    sprintf( pszFullname, "%s.shx", pszBasename );
    777     fpSHX = fopen(pszFullname, "wb" );
     853    fpSHX = psHooks->FOpen(pszFullname, "wb" );
    778854    if( fpSHX == NULL )
    779855    {
    780 #ifdef USE_CPL
    781         CPLError( CE_Failure, CPLE_AppDefined,
    782                   "Failed to create file %s.",
    783                   pszFullname );
    784 #endif
     856        psHooks->Error( "Failed to create file .shx file." );
    785857        return( NULL );
    786858    }
     
    819891/*      Write .shp file header.                                         */
    820892/* -------------------------------------------------------------------- */
    821     if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 )
    822     {
    823 #ifdef USE_CPL
    824         CPLError( CE_Failure, CPLE_AppDefined,
    825                   "Failed to write .shp header." );
    826 #endif
     893    if( psHooks->FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
     894    {
     895        psHooks->Error( "Failed to write .shp header." );
    827896        return NULL;
    828897    }
     
    835904    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
    836905   
    837     if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 )
    838     {
    839 #ifdef USE_CPL
    840         CPLError( CE_Failure, CPLE_AppDefined,
    841                   "Failed to write .shx header." );
    842 #endif
     906    if( psHooks->FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
     907    {
     908        psHooks->Error( "Failed to write .shx header." );
    843909        return NULL;
    844910    }
     
    847913/*      Close the files, and then open them as regular existing files.  */
    848914/* -------------------------------------------------------------------- */
    849     fclose( fpSHP );
    850     fclose( fpSHX );
    851 
    852     return( SHPOpen( pszLayer, "r+b" ) );
     915    psHooks->FClose( fpSHP );
     916    psHooks->FClose( fpSHX );
     917
     918    return( SHPOpenLL( pszLayer, "r+b", psHooks ) );
    853919}
    854920
     
    9931059
    9941060        if( psObject->panPartStart[0] != 0 )
    995         {
    996 #ifdef USE_CPL
    997             CPLError( CE_Failure, CPLE_AppDefined,
    998                       "panPartStart[0] != 0, patching internally.  Please fix your code!\n" );
    999 #else
    1000             fprintf( stderr, "panPartStart[0] != 0, patching internally.  Please fix your code!\n" );
    1001 #endif
    10021061            psObject->panPartStart[0] = 0;
    1003         }
    10041062    }
    10051063
     
    13831441/*      Write out record.                                               */
    13841442/* -------------------------------------------------------------------- */
    1385     if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
    1386         || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
    1387     {
    1388 #ifdef USE_CPL
    1389         CPLError( CE_Failure, CPLE_FileIO,
    1390                 "Error in fseek() or fwrite() writing object to .shp file." );
    1391 #endif
     1443    if( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
     1444        || psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
     1445    {
     1446        psSHP->sHooks.Error( "Error in psSHP->sHooks.FSeek() or fwrite() writing object to .shp file." );
    13921447        free( pabyRec );
    13931448        return -1;
     
    14461501
    14471502{
     1503    int                  nEntitySize, nRequiredSize;
    14481504    SHPObject           *psShape;
     1505    char                 pszErrorMsg[128];
    14491506
    14501507/* -------------------------------------------------------------------- */
     
    14571514/*      Ensure our record buffer is large enough.                       */
    14581515/* -------------------------------------------------------------------- */
    1459     if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
    1460     {
    1461         psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
    1462         psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
     1516    nEntitySize = psSHP->panRecSize[hEntity]+8;
     1517    if( nEntitySize > psSHP->nBufSize )
     1518    {
     1519        psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
     1520        if (psSHP->pabyRec == NULL)
     1521        {
     1522            char szError[200];
     1523
     1524            /* Reallocate previous successfull size for following features */
     1525            psSHP->pabyRec = malloc(psSHP->nBufSize);
     1526
     1527            sprintf( szError,
     1528                     "Not enough memory to allocate requested memory (nBufSize=%d). "
     1529                     "Probably broken SHP file", psSHP->nBufSize );
     1530            psSHP->sHooks.Error( szError );
     1531            return NULL;
     1532        }
     1533
     1534        /* Only set new buffer size after successfull alloc */
     1535        psSHP->nBufSize = nEntitySize;
     1536    }
     1537
     1538    /* In case we were not able to reallocate the buffer on a previous step */
     1539    if (psSHP->pabyRec == NULL)
     1540    {
     1541        return NULL;
    14631542    }
    14641543
     
    14661545/*      Read the record.                                                */
    14671546/* -------------------------------------------------------------------- */
    1468     if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0
    1469         || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1,
     1547    if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0
     1548        || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1,
    14701549                  psSHP->fpSHP ) != 1 )
    14711550    {
     
    14751554         */
    14761555
    1477 #ifdef USE_CPL
    1478         CPLDebug( "Shape", "Error in fseek() or fread() reading object from .shp file." );
    1479 #endif
     1556        psSHP->sHooks.Error( "Error in fseek() or fread() reading object from .shp file." );
    14801557        return NULL;
    14811558    }
     
    14881565    psShape->bMeasureIsUsed = FALSE;
    14891566
     1567    if ( 8 + 4 > nEntitySize )
     1568    {
     1569        snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
     1570                    hEntity, nEntitySize);
     1571        psSHP->sHooks.Error( pszErrorMsg );
     1572        SHPDestroyObject(psShape);
     1573        return NULL;
     1574    }
    14901575    memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
     1576
    14911577    if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
    14921578
     
    15041590        int             i, nOffset;
    15051591
     1592        if ( 40 + 8 + 4 > nEntitySize )
     1593        {
     1594            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
     1595                     hEntity, nEntitySize);
     1596            psSHP->sHooks.Error( pszErrorMsg );
     1597            SHPDestroyObject(psShape);
     1598            return NULL;
     1599        }
    15061600/* -------------------------------------------------------------------- */
    15071601/*      Get the X/Y bounds.                                             */
     
    15261620        if( bBigEndian ) SwapWord( 4, &nPoints );
    15271621        if( bBigEndian ) SwapWord( 4, &nParts );
     1622
     1623        if (nPoints < 0 || nParts < 0 ||
     1624            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
     1625        {
     1626            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
     1627                        hEntity, nPoints, nParts);
     1628            psSHP->sHooks.Error( pszErrorMsg );
     1629            SHPDestroyObject(psShape);
     1630            return NULL;
     1631        }
     1632       
     1633        /* With the previous checks on nPoints and nParts, */
     1634        /* we should not overflow here and after */
     1635        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
     1636        nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
     1637        if ( psShape->nSHPType == SHPT_POLYGONZ
     1638            || psShape->nSHPType == SHPT_ARCZ
     1639            || psShape->nSHPType == SHPT_MULTIPATCH )
     1640        {
     1641            nRequiredSize += 16 + 8 * nPoints;
     1642        }
     1643        if( psShape->nSHPType == SHPT_MULTIPATCH )
     1644        {
     1645            nRequiredSize += 4 * nParts;
     1646        }
     1647        if (nRequiredSize > nEntitySize)
     1648        {
     1649            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
     1650                        hEntity, nPoints, nParts, nEntitySize);
     1651            psSHP->sHooks.Error( pszErrorMsg );
     1652            SHPDestroyObject(psShape);
     1653            return NULL;
     1654        }
    15281655
    15291656        psShape->nVertices = nPoints;
     
    15361663        psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
    15371664        psShape->panPartType = (int *) calloc(nParts,sizeof(int));
     1665       
     1666        if (psShape->padfX == NULL ||
     1667            psShape->padfY == NULL ||
     1668            psShape->padfZ == NULL ||
     1669            psShape->padfM == NULL ||
     1670            psShape->panPartStart == NULL ||
     1671            psShape->panPartType == NULL)
     1672        {
     1673            snprintf(pszErrorMsg, 128,
     1674                     "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
     1675                     "Probably broken SHP file", hEntity, nPoints, nParts );
     1676            psSHP->sHooks.Error( pszErrorMsg );
     1677            SHPDestroyObject(psShape);
     1678            return NULL;
     1679        }
    15381680
    15391681        for( i = 0; i < nParts; i++ )
     
    15471689        {
    15481690            if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
     1691
     1692            /* We check that the offset is inside the vertex array */
     1693            if (psShape->panPartStart[i] < 0 ||
     1694                psShape->panPartStart[i] >= psShape->nVertices)
     1695            {
     1696                snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
     1697                         hEntity, i, psShape->panPartStart[i], psShape->nVertices);
     1698                psSHP->sHooks.Error( pszErrorMsg );
     1699                SHPDestroyObject(psShape);
     1700                return NULL;
     1701            }
     1702            if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
     1703            {
     1704                snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
     1705                         hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]);
     1706                psSHP->sHooks.Error( pszErrorMsg );
     1707                SHPDestroyObject(psShape);
     1708                return NULL;
     1709            }
    15491710        }
    15501711
     
    16131774/*      (options), and the M shapes.                                    */
    16141775/* -------------------------------------------------------------------- */
    1615         if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
     1776        if( nEntitySize >= nOffset + 16 + 8*nPoints )
    16161777        {
    16171778            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
     
    16411802        int             i, nOffset;
    16421803
     1804        if ( 44 + 4 > nEntitySize )
     1805        {
     1806            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
     1807                     hEntity, nEntitySize);
     1808            psSHP->sHooks.Error( pszErrorMsg );
     1809            SHPDestroyObject(psShape);
     1810            return NULL;
     1811        }
    16431812        memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
     1813
    16441814        if( bBigEndian ) SwapWord( 4, &nPoints );
    16451815
     1816        if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
     1817        {
     1818            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d",
     1819                     hEntity, nPoints);
     1820            psSHP->sHooks.Error( pszErrorMsg );
     1821            SHPDestroyObject(psShape);
     1822            return NULL;
     1823        }
     1824
     1825        nRequiredSize = 48 + nPoints * 16;
     1826        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
     1827        {
     1828            nRequiredSize += 16 + nPoints * 8;
     1829        }
     1830        if (nRequiredSize > nEntitySize)
     1831        {
     1832            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
     1833                     hEntity, nPoints, nEntitySize);
     1834            psSHP->sHooks.Error( pszErrorMsg );
     1835            SHPDestroyObject(psShape);
     1836            return NULL;
     1837        }
     1838       
    16461839        psShape->nVertices = nPoints;
    16471840        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
     
    16491842        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
    16501843        psShape->padfM = (double *) calloc(nPoints,sizeof(double));
     1844
     1845        if (psShape->padfX == NULL ||
     1846            psShape->padfY == NULL ||
     1847            psShape->padfZ == NULL ||
     1848            psShape->padfM == NULL)
     1849        {
     1850            snprintf(pszErrorMsg, 128,
     1851                     "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
     1852                     "Probably broken SHP file", hEntity, nPoints );
     1853            psSHP->sHooks.Error( pszErrorMsg );
     1854            SHPDestroyObject(psShape);
     1855            return NULL;
     1856        }
    16511857
    16521858        for( i = 0; i < nPoints; i++ )
     
    17011907/*      (options), and the M shapes.                                    */
    17021908/* -------------------------------------------------------------------- */
    1703         if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
     1909        if( nEntitySize >= nOffset + 16 + 8*nPoints )
    17041910        {
    17051911            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
     
    17341940        psShape->padfM = (double *) calloc(1,sizeof(double));
    17351941
     1942        if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize)
     1943        {
     1944            snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
     1945                     hEntity, nEntitySize);
     1946            psSHP->sHooks.Error( pszErrorMsg );
     1947            SHPDestroyObject(psShape);
     1948            return NULL;
     1949        }
    17361950        memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
    17371951        memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
     
    17601974/*      (options), and the M shapes.                                    */
    17611975/* -------------------------------------------------------------------- */
    1762         if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
     1976        if( nEntitySize >= nOffset + 8 )
    17631977        {
    17641978            memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
     
    19862200                    * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
    19872201                    */
    1988                     float const intersect =
     2202                    double const intersect =
    19892203                        ( psObject->padfX[iEdge+nVertStart]
    19902204                          + ( dfTestY - psObject->padfY[iEdge+nVertStart] )
Note: See TracChangeset for help on using the changeset viewer.