Changeset 13274

Show
Ignore:
Timestamp:
12/06/07 09:00:51 (7 months ago)
Author:
warmerdam
Message:

upgrade to use preliminary SAHooks versions of shapelib

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/ogr/ogrsf_frmts/shape/GNUmakefile

    r9372 r13274  
    33include ../../../GDALmake.opt 
    44 
    5 OBJ     =       shape2ogr.o shpopen.o dbfopen.o shptree.o
     5OBJ     =       shape2ogr.o shpopen.o dbfopen.o shptree.o shp_vsi.o
    66                ogrshapedriver.o ogrshapedatasource.o ogrshapelayer.o 
    77 
    8 CPPFLAGS        :=      -DUSE_CPL -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) 
     8CPPFLAGS :=     -DSAOffset=vsi_l_offset -DUSE_CPL \ 
     9                -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS)  
    910 
    1011default:        $(O_OBJ) 
  • trunk/gdal/ogr/ogrsf_frmts/shape/dbfopen.c

    r12050 r13274  
    11/****************************************************************************** 
    2  * $Id: dbfopen.c,v 1.73 2007/09/03 19:48:11 fwarmerdam Exp $ 
     2 * $Id: dbfopen.c,v 1.74 2007/12/06 07:00:25 fwarmerdam Exp $ 
    33 * 
    44 * Project:  Shapelib 
     
    3535 * 
    3636 * $Log: dbfopen.c,v $ 
     37 * Revision 1.74  2007/12/06 07:00:25  fwarmerdam 
     38 * dbfopen now using SAHooks for fileio 
     39 * 
    3740 * Revision 1.73  2007/09/03 19:48:11  fwarmerdam 
    3841 * move DBFReadAttribute() static dDoubleField into dbfinfo 
     
    109112#include <string.h> 
    110113 
    111 SHP_CVSID("$Id: dbfopen.c,v 1.73 2007/09/03 19:48:11 fwarmerdam Exp $") 
     114SHP_CVSID("$Id: dbfopen.c,v 1.74 2007/12/06 07:00:25 fwarmerdam Exp $") 
    112115 
    113116#ifndef FALSE 
     
    177180/*      descriptions.                                                   */ 
    178181/* -------------------------------------------------------------------- */ 
    179     fseek( psDBF->fp, 0, 0 ); 
    180     fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp ); 
    181     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 ); 
    182186 
    183187/* -------------------------------------------------------------------- */ 
     
    189193 
    190194        cNewline = 0x0d; 
    191         fwrite( &cNewline, 1, 1, psDBF->fp ); 
     195        psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp ); 
    192196    } 
    193197} 
     
    202206 
    203207{ 
    204     int               nRecordOffset; 
     208    SAOffset  nRecordOffset; 
    205209 
    206210    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 ) 
     
    208212        psDBF->bCurrentRecordModified = FALSE; 
    209213 
    210         nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord  
    211                                                      + psDBF->nHeaderLength; 
    212  
    213         if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0  
    214             || fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength,  
    215                        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 ) 
    216222        { 
    217223#ifdef USE_CPL 
     
    239245    if( psDBF->nCurrentRecord != iRecord ) 
    240246    { 
    241         int nRecordOffset; 
     247        SAOffset nRecordOffset; 
    242248 
    243249        if( !DBFFlushRecord( psDBF ) ) 
    244250            return FALSE; 
    245251 
    246         nRecordOffset = psDBF->nRecordLength * iRecord + psDBF->nHeaderLength; 
    247  
    248         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 ) 
    249256        { 
    250257#ifdef USE_CPL 
    251258            CPLError( CE_Failure, CPLE_FileIO, 
    252                       "fseek(%d) failed on DBF file.\n", 
    253                       nRecordOffset ); 
     259                      "fseek(%ld) failed on DBF file.\n", 
     260                      (long) nRecordOffset ); 
    254261#else 
    255             fprintf( stderr, "fseek(%d) failed on DBF file.\n", 
    256                      nRecordOffset ); 
     262            fprintf( stderr, "fseek(%ld) failed on DBF file.\n", 
     263                     (long) nRecordOffset ); 
    257264#endif 
    258265            return FALSE; 
    259266        } 
    260267 
    261         if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,  
    262                    1, psDBF->fp ) != 1 ) 
     268        if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord,  
     269                                 psDBF->nRecordLength, 1, psDBF->fp ) != 1 ) 
    263270        { 
    264271#ifdef USE_CPL 
     
    294301    DBFFlushRecord( psDBF ); 
    295302 
    296     fseek( psDBF->fp, 0, 0 ); 
    297     fread( abyFileHeader, 32, 1, psDBF->fp ); 
     303    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 ); 
     304    psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp ); 
    298305     
    299306    abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256); 
     
    302309    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256); 
    303310     
    304     fseek( psDBF->fp, 0, 0 ); 
    305     fwrite( abyFileHeader, 32, 1, psDBF->fp ); 
    306  
    307     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 ); 
    308315} 
    309316 
     
    318325 
    319326{ 
     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{ 
    320344    DBFHandle           psDBF; 
    321     unsigned char              *pabyBuf; 
     345    unsigned char       *pabyBuf; 
    322346    int                 nFields, nHeadLen, iField, i; 
    323347    char                *pszBasename, *pszFullname; 
     
    355379         
    356380    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) ); 
    357     psDBF->fp = fopen( pszFullname, pszAccess ); 
     381    psDBF->fp = psHooks->FOpen( pszFullname, pszAccess ); 
     382    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) ); 
    358383 
    359384    if( psDBF->fp == NULL ) 
    360385    { 
    361386        sprintf( pszFullname, "%s.DBF", pszBasename ); 
    362         psDBF->fp = fopen(pszFullname, pszAccess ); 
     387        psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess ); 
    363388    } 
    364389     
     
    380405/* -------------------------------------------------------------------- */ 
    381406    pabyBuf = (unsigned char *) malloc(500); 
    382     if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 ) 
    383     { 
    384         fclose( psDBF->fp ); 
     407    if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 ) 
     408    { 
     409        psDBF->sHooks.FClose( psDBF->fp ); 
    385410        free( pabyBuf ); 
    386411        free( psDBF ); 
     
    405430    psDBF->pszHeader = (char *) pabyBuf; 
    406431 
    407     fseek( psDBF->fp, 32, 0 ); 
    408     if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 ) 
    409     { 
    410         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 ); 
    411436        free( pabyBuf ); 
    412437        free( psDBF->pszCurrentRecord ); 
     
    482507/*      Close, and free resources.                                      */ 
    483508/* -------------------------------------------------------------------- */ 
    484     fclose( psDBF->fp ); 
     509    psDBF->sHooks.FClose( psDBF->fp ); 
    485510 
    486511    if( psDBF->panFieldOffset != NULL ) 
     
    511536 
    512537{ 
     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{ 
    513555    DBFHandle   psDBF; 
    514     FILE       *fp; 
     556    SAFile     fp; 
    515557    char        *pszFullname, *pszBasename; 
    516558    int         i; 
     559    char chZero = '\0'; 
    517560 
    518561/* -------------------------------------------------------------------- */ 
     
    537580/*      Create the file.                                                */ 
    538581/* -------------------------------------------------------------------- */ 
    539     fp = fopen( pszFullname, "wb" ); 
     582    fp = psHooks->FOpen( pszFullname, "wb" ); 
    540583    if( fp == NULL ) 
    541584        return( NULL ); 
    542  
    543     fputc( 0, fp ); 
    544     fclose( fp ); 
    545  
    546     fp = fopen( pszFullname, "rb+" ); 
     585     
     586    psHooks->FWrite( &chZero, 1, 1, fp ); 
     587    psHooks->FClose( fp ); 
     588 
     589    fp = psHooks->FOpen( pszFullname, "rb+" ); 
    547590    if( fp == NULL ) 
    548591        return( NULL ); 
     
    555598    psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo)); 
    556599 
     600    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) ); 
    557601    psDBF->fp = fp; 
    558602    psDBF->nRecords = 0; 
  • trunk/gdal/ogr/ogrsf_frmts/shape/makefile.vc

    r6927 r13274  
    11 
    22OBJ     =       shape2ogr.obj shpopen.obj dbfopen.obj ogrshapedriver.obj \ 
    3                 ogrshapedatasource.obj ogrshapelayer.obj shptree.obj 
    4 EXTRAFLAGS =    -I.. -I..\.. /DSHAPELIB_DLLEXPORT -DUSE_CPL 
     3                ogrshapedatasource.obj ogrshapelayer.obj shptree.obj \ 
     4                shp_vsi.obj 
     5EXTRAFLAGS =    -I.. -I..\.. /DSHAPELIB_DLLEXPORT \ 
     6                -DUSE_CPL -DSAOffset=vsi_l_offset  
    57 
    68GDAL_ROOT       =       ..\..\.. 
  • trunk/gdal/ogr/ogrsf_frmts/shape/ogrshapelayer.cpp

    r12930 r13274  
    758758/*      Update .shp header.                                             */ 
    759759/* -------------------------------------------------------------------- */ 
    760     nStartPos = ftell( hSHP->fpSHP ); 
    761  
    762     if( fseek( hSHP->fpSHP, 0, SEEK_SET ) != 0 
    763         || fread( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) 
     760    nStartPos = hSHP->sHooks.FTell( hSHP->fpSHP ); 
     761 
     762    if( hSHP->sHooks.FSeek( hSHP->fpSHP, 0, SEEK_SET ) != 0 
     763        || hSHP->sHooks.FRead( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) 
    764764        return FALSE; 
    765765 
    766766    *((GInt32 *) (abyHeader + 32)) = CPL_LSBWORD32( nNewGeomType ); 
    767767 
    768     if( fseek( hSHP->fpSHP, 0, SEEK_SET ) != 0 
    769         || fwrite( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) 
     768    if( hSHP->sHooks.FSeek( hSHP->fpSHP, 0, SEEK_SET ) != 0 
     769        || hSHP->sHooks.FWrite( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) 
    770770        return FALSE; 
    771771 
    772     if( fseek( hSHP->fpSHP, nStartPos, SEEK_SET ) != 0 ) 
     772    if( hSHP->sHooks.FSeek( hSHP->fpSHP, nStartPos, SEEK_SET ) != 0 ) 
    773773        return FALSE; 
    774774 
     
    776776/*      Update .shx header.                                             */ 
    777777/* -------------------------------------------------------------------- */ 
    778     nStartPos = ftell( hSHP->fpSHX ); 
    779  
    780     if( fseek( hSHP->fpSHX, 0, SEEK_SET ) != 0 
    781         || fread( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) 
     778    nStartPos = hSHP->sHooks.FTell( hSHP->fpSHX ); 
     779     
     780    if( hSHP->sHooks.FSeek( hSHP->fpSHX, 0, SEEK_SET ) != 0 
     781        || hSHP->sHooks.FRead( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) 
    782782        return FALSE; 
    783783 
    784784    *((GInt32 *) (abyHeader + 32)) = CPL_LSBWORD32( nNewGeomType ); 
    785785 
    786     if( fseek( hSHP->fpSHX, 0, SEEK_SET ) != 0 
    787         || fwrite( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) 
     786    if( hSHP->sHooks.FSeek( hSHP->fpSHX, 0, SEEK_SET ) != 0 
     787        || hSHP->sHooks.FWrite( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) 
    788788        return FALSE; 
    789789 
    790     if( fseek( hSHP->fpSHX, nStartPos, SEEK_SET ) != 0 ) 
     790    if( hSHP->sHooks.FSeek( hSHP->fpSHX, nStartPos, SEEK_SET ) != 0 ) 
    791791        return FALSE; 
    792792 
     
    819819    if( hSHP != NULL ) 
    820820    { 
    821         fflush( hSHP->fpSHP ); 
    822         fflush( hSHP->fpSHX ); 
     821        hSHP->sHooks.FFlush( hSHP->fpSHP ); 
     822        hSHP->sHooks.FFlush( hSHP->fpSHX ); 
    823823    } 
    824824 
    825825    if( hDBF != NULL ) 
    826         fflush( hDBF->fp ); 
     826        hDBF->sHooks.FFlush( hDBF->fp ); 
    827827 
    828828    return OGRERR_NONE; 
  • trunk/gdal/ogr/ogrsf_frmts/shape/shapefil.h

    r12930 r13274  
    3838 * 
    3939 * $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 * 
    4046 * Revision 1.38  2007/11/21 22:39:56  fwarmerdam 
    4147 * close shx file in readonly mode (GDAL #1956) 
     
    99105#ifdef USE_CPL 
    100106#include "cpl_error.h" 
     107#include "cpl_vsi.h" 
    101108#endif 
    102109 
     
    121128/* -------------------------------------------------------------------- */ 
    122129#define DISABLE_MULTIPATCH_MEASURE 
    123  
     130     
    124131/* -------------------------------------------------------------------- */ 
    125132/*      SHPAPI_CALL                                                     */ 
     
    179186#  define SHP_CVSID(string) 
    180187#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 ); 
    181211 
    182212/************************************************************************/ 
     
    185215typedef struct 
    186216{ 
    187     FILE        *fpSHP; 
    188     FILE        *fpSHX; 
     217    SAHooks sHooks; 
     218 
     219    SAFile      fpSHP; 
     220    SAFile      fpSHX; 
    189221 
    190222    int         nShapeType;                             /* SHPT_* */ 
     
    281313      SHPOpen( const char * pszShapeFile, const char * pszAccess ); 
    282314SHPHandle SHPAPI_CALL 
     315      SHPOpenLL( const char *pszShapeFile, const char *pszAccess,  
     316                 SAHooks *psHooks ); 
     317SHPHandle SHPAPI_CALL 
    283318      SHPCreate( const char * pszShapeFile, int nShapeType ); 
     319SHPHandle SHPAPI_CALL 
     320      SHPCreateLL( const char * pszShapeFile, int nShapeType, 
     321                   SAHooks *psHooks ); 
    284322void SHPAPI_CALL 
    285323      SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, 
     
    395433typedef struct 
    396434{ 
    397     FILE        *fp; 
     435    SAHooks sHooks; 
     436 
     437    SAFile      fp; 
    398438 
    399439    int         nRecords; 
     
    434474#define XBASE_FLDHDR_SZ       32 
    435475 
     476 
    436477DBFHandle SHPAPI_CALL 
    437478      DBFOpen( const char * pszDBFFile, const char * pszAccess ); 
    438479DBFHandle SHPAPI_CALL 
     480      DBFOpenLL( const char * pszDBFFile, const char * pszAccess, 
     481                 SAHooks *psHooks ); 
     482DBFHandle SHPAPI_CALL 
    439483      DBFCreate( const char * pszDBFFile ); 
     484DBFHandle SHPAPI_CALL 
     485      DBFCreateLL( const char * pszDBFFile, SAHooks *psHooks ); 
    440486 
    441487int     SHPAPI_CALL 
  • trunk/gdal/ogr/ogrsf_frmts/shape/shpopen.c

    r12930 r13274  
    11/****************************************************************************** 
    2  * $Id: shpopen.c,v 1.55 2007/11/21 22:39:56 fwarmerdam Exp $ 
     2 * $Id: shpopen.c,v 1.57 2007/12/06 07:00:25 fwarmerdam Exp $ 
    33 * 
    44 * Project:  Shapelib 
     
    3535 * 
    3636 * $Log: shpopen.c,v $ 
     37 * Revision 1.57  2007/12/06 07:00:25  fwarmerdam 
     38 * dbfopen now using SAHooks for fileio 
     39 * 
     40 * Revision 1.56  2007/12/04 20:37:56  fwarmerdam 
     41 * preliminary implementation of hooks api for io and errors 
     42 * 
    3743 * Revision 1.55  2007/11/21 22:39:56  fwarmerdam 
    3844 * close shx file in readonly mode (GDAL #1956) 
     
    220226#include <stdio.h> 
    221227 
    222 SHP_CVSID("$Id: shpopen.c,v 1.55 2007/11/21 22:39:56 fwarmerdam Exp $") 
     228SHP_CVSID("$Id: shpopen.c,v 1.57 2007/12/06 07:00:25 fwarmerdam Exp $") 
    223229 
    224230typedef unsigned char uchar; 
     
    298304    if (psSHP->fpSHX == NULL) 
    299305    { 
    300 #ifdef USE_CPL 
    301         CPLError( CE_Failure, CPLE_NotSupported,  
    302                   "SHPWriteHeader failed : SHX file is closed"); 
    303 #endif 
     306        psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed"); 
    304307        return; 
    305308    } 
     
    361364/*      Write .shp file header.                                         */ 
    362365/* -------------------------------------------------------------------- */ 
    363     if( fseek( psSHP->fpSHP, 0, 0 ) != 0  
    364         || fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 ) 
    365     { 
    366 #ifdef USE_CPL 
    367         CPLError( CE_Failure, CPLE_OpenFailed,  
    368                   "Failure writing .shp header (%s)", VSIStrerror( errno ) ); 
    369 #endif 
     366    if( psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 0 ) != 0  
     367        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 ) 
     368    { 
     369        psSHP->sHooks.Error( "Failure writing .shp header" ); 
    370370        return; 
    371371    } 
     
    378378    if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); 
    379379     
    380     if( fseek( psSHP->fpSHX, 0, 0 ) != 0  
    381         || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 ) 
    382     { 
    383 #ifdef USE_CPL 
    384         CPLError( CE_Failure, CPLE_OpenFailed,  
    385                   "Failure writing .shx header (%s)", VSIStrerror( errno ) ); 
    386 #endif 
     380    if( psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 0 ) != 0  
     381        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 ) 
     382    { 
     383        psSHP->sHooks.Error( "Failure writing .shx header" ); 
    387384        return; 
    388385    } 
     
    401398    } 
    402399 
    403     if( (int)fwrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )  
     400    if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )  
    404401        != psSHP->nRecords ) 
    405402    { 
    406 #ifdef USE_CPL 
    407         CPLError( CE_Failure, CPLE_OpenFailed,  
    408                   "Failure writing .shx contents (%s)", VSIStrerror( errno ) ); 
    409 #endif 
     403        psSHP->sHooks.Error( "Failure writing .shx contents" ); 
    410404    } 
    411405 
     
    415409/*      Flush to disk.                                                  */ 
    416410/* -------------------------------------------------------------------- */ 
    417     fflush( psSHP->fpSHP ); 
    418     fflush( psSHP->fpSHX ); 
     411    psSHP->sHooks.FFlush( psSHP->fpSHP ); 
     412    psSHP->sHooks.FFlush( psSHP->fpSHX ); 
    419413} 
    420414 
    421415/************************************************************************/ 
    422 /*                              shpopen()                               */ 
     416/*                              SHPOpen()                               */ 
     417/************************************************************************/ 
     418 
     419SHPHandle SHPAPI_CALL 
     420SHPOpen( const char * pszLayer, const char * pszAccess ) 
     421 
     422
     423    SAHooks sHooks; 
     424 
     425    SASetupDefaultHooks( &sHooks ); 
     426 
     427    return SHPOpenLL( pszLayer, pszAccess, &sHooks ); 
     428
     429 
     430/************************************************************************/ 
     431/*                              SHPOpen()                               */ 
    423432/*                                                                      */ 
    424433/*      Open the .shp and .shx files based on the basename of the       */ 
     
    427436    
    428437SHPHandle SHPAPI_CALL 
    429 SHPOpen( const char * pszLayer, const char * pszAccess ) 
     438SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) 
    430439 
    431440{ 
     
    463472 
    464473    psSHP->bUpdated = FALSE; 
     474    memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) ); 
    465475 
    466476/* -------------------------------------------------------------------- */ 
     
    483493/* -------------------------------------------------------------------- */ 
    484494    pszFullname = (char *) malloc(strlen(pszBasename) + 5); 
    485     sprintf( pszFullname, "%s.shp", pszBasename )
    486     psSHP->fpSHP = fopen(pszFullname, pszAccess ); 
     495    sprintf( pszFullname, "%s.shp", pszBasename )
     496    psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess ); 
    487497    if( psSHP->fpSHP == NULL ) 
    488498    { 
    489499        sprintf( pszFullname, "%s.SHP", pszBasename ); 
    490         psSHP->fpSHP = fopen(pszFullname, pszAccess ); 
     500        psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess ); 
    491501    } 
    492502     
     
    505515 
    506516    sprintf( pszFullname, "%s.shx", pszBasename ); 
    507     psSHP->fpSHX = fopen(pszFullname, pszAccess ); 
     517    psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess ); 
    508518    if( psSHP->fpSHX == NULL ) 
    509519    { 
    510520        sprintf( pszFullname, "%s.SHX", pszBasename ); 
    511         psSHP->fpSHX = fopen(pszFullname, pszAccess ); 
     521        psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess ); 
    512522    } 
    513523     
     
    519529                  pszBasename, pszBasename ); 
    520530#endif 
    521         fclose( psSHP->fpSHP ); 
     531        psSHP->sHooks.FClose( psSHP->fpSHP ); 
    522532        free( psSHP ); 
    523533        free( pszBasename ); 
     
    533543/* -------------------------------------------------------------------- */ 
    534544    pabyBuf = (uchar *) malloc(100); 
    535     fread( pabyBuf, 100, 1, psSHP->fpSHP ); 
     545    psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP ); 
    536546 
    537547    psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256 
     
    543553/*  Read SHX file Header info                                           */ 
    544554/* -------------------------------------------------------------------- */ 
    545     if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1  
     555    if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1  
    546556        || pabyBuf[0] != 0  
    547557        || pabyBuf[1] != 0  
     
    549559        || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) 
    550560    { 
    551 #ifdef USE_CPL 
    552         CPLError( CE_Failure, CPLE_AppDefined,  
    553                   ".shx file is unreadable, or corrupt." ); 
    554 #endif 
    555         fclose( psSHP->fpSHP ); 
    556         fclose( psSHP->fpSHX ); 
     561        psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." ); 
     562        psSHP->sHooks.FClose( psSHP->fpSHP ); 
     563        psSHP->sHooks.FClose( psSHP->fpSHX ); 
    557564        free( psSHP ); 
    558565 
     
    568575    if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) 
    569576    { 
    570 #ifdef USE_CPL 
    571         CPLError( CE_Failure, CPLE_AppDefined,  
    572                   "Record count in .shp header is %d, which seems\n" 
    573                   "unreasonable.  Assuming header is corrupt.", 
     577        char szError[200]; 
     578         
     579        sprintf( szError,  
     580                 "Record count in .shp header is %d, which seems\n" 
     581                 "unreasonable.  Assuming header is corrupt.", 
    574582                  psSHP->nRecords ); 
    575 #endif 
    576         fclose( psSHP->fpSHP ); 
    577         fclose( psSHP->fpSHX ); 
     583        psSHP->sHooks.Error( szError );                                 
     584        psSHP->sHooks.FClose( psSHP->fpSHP ); 
     585        psSHP->sHooks.FClose( psSHP->fpSHX ); 
    578586        free( psSHP ); 
    579587        free(pabyBuf); 
     
    635643        pabyBuf == NULL) 
    636644    { 
    637 #ifdef USE_CPL 
    638         CPLError(CE_Failure, CPLE_AppDefined, 
    639                  "Not enough memory to allocate requested memory (nRecords=%d, nParts=%d). " 
    640                   "Probably broken SHP file", psSHP->nRecords ); 
    641 #endif 
    642         fclose( psSHP->fpSHP ); 
    643         fclose( psSHP->fpSHX ); 
     645        char szError[200]; 
     646 
     647        sprintf(szError,  
     648                "Not enough memory to allocate requested memory (nRecords=%d).\n" 
     649                "Probably broken SHP file",  
     650                psSHP->nRecords ); 
     651        psSHP->sHooks.Error( szError ); 
     652        psSHP->sHooks.FClose( psSHP->fpSHP ); 
     653        psSHP->sHooks.FClose( psSHP->fpSHX ); 
    644654        if (psSHP->panRecOffset) free( psSHP->panRecOffset ); 
    645655        if (psSHP->panRecSize) free( psSHP->panRecSize ); 
     
    649659    } 
    650660 
    651     if( (int) fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )  
     661    if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )  
    652662                        != psSHP->nRecords ) 
    653663    { 
    654 #ifdef USE_CPL 
    655         CPLError( CE_Failure, CPLE_AppDefined,  
    656                   "Failed to read all values for %d records in .shx file.", 
    657                   psSHP->nRecords ); 
    658 #endif 
     664        char szError[200]; 
     665 
     666        sprintf( szError,  
     667                 "Failed to read all values for %d records in .shx file.", 
     668                 psSHP->nRecords ); 
     669        psSHP->sHooks.Error( szError ); 
     670 
    659671        /* SHX is short or unreadable for some reason. */ 
    660         fclose( psSHP->fpSHP ); 
    661         fclose( psSHP->fpSHX ); 
     672        psSHP->sHooks.FClose( psSHP->fpSHP ); 
     673        psSHP->sHooks.FClose( psSHP->fpSHX ); 
    662674        free( psSHP->panRecOffset ); 
    663675        free( psSHP->panRecSize ); 
     
    671683    if (strcmp(pszAccess, "rb") == 0) 
    672684    { 
    673         fclose( psSHP->fpSHX ); 
     685        psSHP->sHooks.FClose( psSHP->fpSHX ); 
    674686        psSHP->fpSHX = NULL; 
    675687    } 
     
    719731 
    720732    if ( psSHP->fpSHX != NULL) 
    721         fclose( psSHP->fpSHX ); 
    722     fclose( psSHP->fpSHP ); 
     733        psSHP->sHooks.FClose( psSHP->fpSHX ); 
     734    psSHP->sHooks.FClose( psSHP->fpSHP ); 
    723735 
    724736    if( psSHP->pabyRec != NULL ) 
     
    772784 
    773785{ 
     786    SAHooks sHooks; 
     787 
     788    SASetupDefaultHooks( &sHooks ); 
     789 
     790    return SHPCreateLL( pszLayer, nShapeType, &sHooks ); 
     791} 
     792 
     793/************************************************************************/ 
     794/*                             SHPCreate()                              */ 
     795/*                                                                      */ 
     796/*      Create a new shape file and return a handle to the open         */ 
     797/*      shape file with read/write access.                              */ 
     798/************************************************************************/ 
     799 
     800SHPHandle SHPAPI_CALL 
     801SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks ) 
     802 
     803{ 
    774804    char        *pszBasename, *pszFullname; 
    775805    int         i; 
    776     FILE       *fpSHP, *fpSHX; 
     806    SAFile     fpSHP, fpSHX; 
    777807    uchar       abyHeader[100]; 
    778808    int32       i32; 
     
    807837    pszFullname = (char *) malloc(strlen(pszBasename) + 5); 
    808838    sprintf( pszFullname, "%s.shp", pszBasename ); 
    809     fpSHP = fopen(pszFullname, "wb" ); 
     839    fpSHP = psHooks->FOpen(pszFullname, "wb" ); 
    810840    if( fpSHP == NULL ) 
    811841    { 
    812 #ifdef USE_CPL 
    813         CPLError( CE_Failure, CPLE_AppDefined,  
    814                   "Failed to create file %s.", 
    815                   pszFullname ); 
    816 #endif 
     842        psHooks->Error( "Failed to create file .shp file." ); 
    817843        return( NULL ); 
    818844    } 
    819845 
    820846    sprintf( pszFullname, "%s.shx", pszBasename ); 
    821     fpSHX = fopen(pszFullname, "wb" ); 
     847    fpSHX = psHooks->FOpen(pszFullname, "wb" ); 
    822848    if( fpSHX == NULL ) 
    823849    { 
    824 #ifdef USE_CPL 
    825         CPLError( CE_Failure, CPLE_AppDefined,  
    826                   "Failed to create file %s.", 
    827                   pszFullname ); 
    828 #endif 
     850        psHooks->Error( "Failed to create file .shx file." ); 
    829851        return( NULL ); 
    830852    } 
     
    863885/*      Write .shp file header.                                         */ 
    864886/* -------------------------------------------------------------------- */ 
    865     if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 ) 
    866     { 
    867 #ifdef USE_CPL 
    868         CPLError( CE_Failure, CPLE_AppDefined,  
    869                   "Failed to write .shp header." ); 
    870 #endif 
     887    if( psHooks->FWrite( abyHeader, 100, 1, fpSHP ) != 1 ) 
     888    { 
     889        psHooks->Error( "Failed to write .shp header." ); 
    871890        return NULL; 
    872891    } 
     
    879898    if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); 
    880899     
    881     if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 ) 
    882     { 
    883 #ifdef USE_CPL 
    884         CPLError( CE_Failure, CPLE_AppDefined,  
    885                   "Failed to write .shx header." ); 
    886 #endif 
     900    if( psHooks->FWrite( abyHeader, 100, 1, fpSHX ) != 1 ) 
     901    { 
     902        psHooks->Error( "Failed to write .shx header." ); 
    887903        return NULL; 
    888904    } 
     
    891907/*      Close the files, and then open them as regular existing files.  */ 
    892908/* -------------------------------------------------------------------- */ 
    893     fclose( fpSHP ); 
    894     fclose( fpSHX ); 
    895  
    896     return( SHPOpen( pszLayer, "r+b" ) ); 
     909    psHooks->FClose( fpSHP ); 
     910    psHooks->FClose( fpSHX ); 
     911 
     912    return( SHPOpenLL( pszLayer, "r+b", psHooks ) ); 
    897913} 
    898914 
     
    10371053 
    10381054        if( psObject->panPartStart[0] != 0 ) 
    1039         { 
    1040 #ifdef USE_CPL 
    1041             CPLError( CE_Failure, CPLE_AppDefined, 
    1042                       "panPartStart[0] != 0, patching internally.  Please fix your code!\n" ); 
    1043 #else 
    1044             fprintf( stderr, "panPartStart[0] != 0, patching internally.  Please fix your code!\n" ); 
    1045 #endif 
    10461055            psObject->panPartStart[0] = 0; 
    1047         } 
    10481056    } 
    10491057 
     
    14271435/*      Write out record.                                               */ 
    14281436/* -------------------------------------------------------------------- */ 
    1429     if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 
    1430         || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) 
    1431     { 
    1432 #ifdef USE_CPL 
    1433         CPLError( CE_Failure, CPLE_FileIO,  
    1434                 "Error in fseek() or fwrite() writing object to .shp file." ); 
    1435 #endif 
     1437    if( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 
     1438        || psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) 
     1439    { 
     1440        psSHP->sHooks.Error( "Error in psSHP->sHooks.FSeek() or fwrite() writing object to .shp file." ); 
    14361441        free( pabyRec ); 
    14371442        return -1; 
     
    15071512        if (psSHP->pabyRec == NULL) 
    15081513        { 
    1509 #ifdef USE_CPL 
    1510             CPLError(CE_Failure, CPLE_AppDefined, 
     1514            char szError[200]; 
     1515 
     1516            sprintf( szError,  
    15111517                     "Not enough memory to allocate requested memory (nBufSize=%d). " 
    15121518                     "Probably broken SHP file", psSHP->nBufSize ); 
    1513 #endif 
     1519            psSHP->sHooks.Error( szError ); 
    15141520            return NULL; 
    15151521        } 
     
    15191525/*      Read the record.                                                */ 
    15201526/* -------------------------------------------------------------------- */ 
    1521     if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0  
    1522         || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1,  
     1527    if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0  
     1528        || psSHP->sHooks.FRead( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1,  
    15231529                  psSHP->fpSHP ) != 1 ) 
    15241530    { 
     
    15281534         */ 
    15291535 
    1530 #ifdef USE_CPL 
    1531         CPLDebug( "Shape", "Error in fseek() or fread() reading object from .shp file." ); 
    1532 #endif 
     1536        psSHP->sHooks.Error( "Error in fseek() or fread() reading object from .shp file." ); 
    15331537        return NULL; 
    15341538    }