LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/shape - shp_vsi.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 72 81 88.9 %
Date: 2024-11-21 22:18:42 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  OpenGIS Simple Features Reference Implementation
       5             :  * Purpose:  IO Redirection via VSI services for shp/dbf io.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2007,  Frank Warmerdam
      10             :  * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "shp_vsi.h"
      16             : #include "cpl_error.h"
      17             : #include "cpl_conv.h"
      18             : #include "cpl_vsi_error.h"
      19             : #include <limits.h>
      20             : 
      21             : #include "shapefil_private.h"
      22             : 
      23             : typedef struct
      24             : {
      25             :     VSILFILE *fp;
      26             :     char *pszFilename;
      27             :     int bEnforce2GBLimit;
      28             :     int bHasWarned2GB;
      29             :     SAOffset nCurOffset;
      30             : } OGRSHPDBFFile;
      31             : 
      32             : /************************************************************************/
      33             : /*                         VSI_SHP_OpenInternal()                       */
      34             : /************************************************************************/
      35             : 
      36       25720 : static SAFile VSI_SHP_OpenInternal(const char *pszFilename,
      37             :                                    const char *pszAccess, int bEnforce2GBLimit)
      38             : 
      39             : {
      40             :     OGRSHPDBFFile *pFile;
      41       25720 :     VSILFILE *fp = VSIFOpenExL(pszFilename, pszAccess, TRUE);
      42       25720 :     if (fp == SHPLIB_NULLPTR)
      43       11032 :         return SHPLIB_NULLPTR;
      44       14688 :     pFile = (OGRSHPDBFFile *)CPLCalloc(1, sizeof(OGRSHPDBFFile));
      45       14688 :     pFile->fp = fp;
      46       14688 :     pFile->pszFilename = CPLStrdup(pszFilename);
      47       14688 :     pFile->bEnforce2GBLimit = bEnforce2GBLimit;
      48       14688 :     pFile->nCurOffset = 0;
      49       14688 :     return (SAFile)pFile;
      50             : }
      51             : 
      52             : /************************************************************************/
      53             : /*                            VSI_SHP_Open()                            */
      54             : /************************************************************************/
      55             : 
      56       25720 : static SAFile VSI_SHP_Open(const char *pszFilename, const char *pszAccess,
      57             :                            void *userData)
      58             : 
      59             : {
      60             :     (void)userData;
      61       25720 :     return VSI_SHP_OpenInternal(pszFilename, pszAccess, FALSE);
      62             : }
      63             : 
      64             : /************************************************************************/
      65             : /*                            VSI_SHP_Read()                            */
      66             : /************************************************************************/
      67             : 
      68     2669850 : static SAOffset VSI_SHP_Read(void *p, SAOffset size, SAOffset nmemb,
      69             :                              SAFile file)
      70             : 
      71             : {
      72     2669850 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
      73             :     SAOffset ret =
      74     2669850 :         (SAOffset)VSIFReadL(p, (size_t)size, (size_t)nmemb, pFile->fp);
      75     2669850 :     pFile->nCurOffset += ret * size;
      76     2669850 :     return ret;
      77             : }
      78             : 
      79             : /************************************************************************/
      80             : /*                      VSI_SHP_WriteMoreDataOK()                       */
      81             : /************************************************************************/
      82             : 
      83      349983 : int VSI_SHP_WriteMoreDataOK(SAFile file, SAOffset nExtraBytes)
      84             : {
      85      349983 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
      86      349983 :     if (pFile->nCurOffset + nExtraBytes > INT_MAX)
      87             :     {
      88           0 :         if (pFile->bEnforce2GBLimit)
      89             :         {
      90           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      91             :                      "2GB file size limit reached for %s", pFile->pszFilename);
      92           0 :             return FALSE;
      93             :         }
      94           0 :         else if (!pFile->bHasWarned2GB)
      95             :         {
      96           0 :             pFile->bHasWarned2GB = TRUE;
      97           0 :             CPLError(CE_Warning, CPLE_AppDefined,
      98             :                      "2GB file size limit reached for %s. "
      99             :                      "Going on, but might cause compatibility issues with "
     100             :                      "third party software",
     101             :                      pFile->pszFilename);
     102             :         }
     103             :     }
     104             : 
     105      349983 :     return TRUE;
     106             : }
     107             : 
     108             : /************************************************************************/
     109             : /*                           VSI_SHP_Write()                            */
     110             : /************************************************************************/
     111             : 
     112      288623 : static SAOffset VSI_SHP_Write(const void *p, SAOffset size, SAOffset nmemb,
     113             :                               SAFile file)
     114             : 
     115             : {
     116      288623 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     117             :     SAOffset ret;
     118      288623 :     if (!VSI_SHP_WriteMoreDataOK(file, size * nmemb))
     119           0 :         return 0;
     120      288623 :     ret = (SAOffset)VSIFWriteL(p, (size_t)size, (size_t)nmemb, pFile->fp);
     121      288623 :     pFile->nCurOffset += ret * size;
     122      288623 :     return ret;
     123             : }
     124             : 
     125             : /************************************************************************/
     126             : /*                            VSI_SHP_Seek()                            */
     127             : /************************************************************************/
     128             : 
     129      796268 : static SAOffset VSI_SHP_Seek(SAFile file, SAOffset offset, int whence)
     130             : 
     131             : {
     132      796268 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     133      796268 :     SAOffset ret = (SAOffset)VSIFSeekL(pFile->fp, (vsi_l_offset)offset, whence);
     134      796268 :     if (whence == 0 && ret == 0)
     135      436090 :         pFile->nCurOffset = offset;
     136             :     else
     137      360178 :         pFile->nCurOffset = (SAOffset)VSIFTellL(pFile->fp);
     138      796268 :     return ret;
     139             : }
     140             : 
     141             : /************************************************************************/
     142             : /*                            VSI_SHP_Tell()                            */
     143             : /************************************************************************/
     144             : 
     145      129046 : static SAOffset VSI_SHP_Tell(SAFile file)
     146             : 
     147             : {
     148      129046 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     149      129046 :     return (SAOffset)pFile->nCurOffset;
     150             : }
     151             : 
     152             : /************************************************************************/
     153             : /*                           VSI_SHP_Flush()                            */
     154             : /************************************************************************/
     155             : 
     156        6039 : static int VSI_SHP_Flush(SAFile file)
     157             : 
     158             : {
     159        6039 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     160        6039 :     return VSIFFlushL(pFile->fp);
     161             : }
     162             : 
     163             : /************************************************************************/
     164             : /*                           VSI_SHP_Close()                            */
     165             : /************************************************************************/
     166             : 
     167       14688 : static int VSI_SHP_Close(SAFile file)
     168             : 
     169             : {
     170       14688 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     171       14688 :     int ret = VSIFCloseL(pFile->fp);
     172       14688 :     CPLFree(pFile->pszFilename);
     173       14688 :     CPLFree(pFile);
     174       14688 :     return ret;
     175             : }
     176             : 
     177             : /************************************************************************/
     178             : /*                              SADError()                              */
     179             : /************************************************************************/
     180             : 
     181         344 : static void VSI_SHP_Error(const char *message)
     182             : 
     183             : {
     184         344 :     CPLError(CE_Failure, CPLE_AppDefined, "%s", message);
     185         344 : }
     186             : 
     187             : /************************************************************************/
     188             : /*                           VSI_SHP_Remove()                           */
     189             : /************************************************************************/
     190             : 
     191        1581 : static int VSI_SHP_Remove(const char *pszFilename, void *userData)
     192             : 
     193             : {
     194             :     (void)userData;
     195        1581 :     return VSIUnlink(pszFilename);
     196             : }
     197             : 
     198             : /************************************************************************/
     199             : /*                        SASetupDefaultHooks()                         */
     200             : /************************************************************************/
     201             : 
     202        3341 : void SASetupDefaultHooks(SAHooks *psHooks)
     203             : 
     204             : {
     205        3341 :     psHooks->FOpen = VSI_SHP_Open;
     206        3341 :     psHooks->FRead = VSI_SHP_Read;
     207        3341 :     psHooks->FWrite = VSI_SHP_Write;
     208        3341 :     psHooks->FSeek = VSI_SHP_Seek;
     209        3341 :     psHooks->FTell = VSI_SHP_Tell;
     210        3341 :     psHooks->FFlush = VSI_SHP_Flush;
     211        3341 :     psHooks->FClose = VSI_SHP_Close;
     212        3341 :     psHooks->Remove = VSI_SHP_Remove;
     213             : 
     214        3341 :     psHooks->Error = VSI_SHP_Error;
     215        3341 :     psHooks->Atof = CPLAtof;
     216        3341 :     psHooks->pvUserData = SHPLIB_NULLPTR;
     217        3341 : }
     218             : 
     219             : #ifndef SHP_VSI_ONLY_SETUP_HOOKS
     220             : 
     221             : /************************************************************************/
     222             : /*                         VSI_SHP_GetVSIL()                            */
     223             : /************************************************************************/
     224             : 
     225      190508 : VSILFILE *VSI_SHP_GetVSIL(SAFile file)
     226             : {
     227      190508 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     228      190508 :     return pFile->fp;
     229             : }
     230             : 
     231             : /************************************************************************/
     232             : /*                        VSI_SHP_GetFilename()                         */
     233             : /************************************************************************/
     234             : 
     235         156 : const char *VSI_SHP_GetFilename(SAFile file)
     236             : {
     237         156 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     238         156 :     return pFile->pszFilename;
     239             : }
     240             : 
     241             : /************************************************************************/
     242             : /*                        VSI_SHP_Open2GBLimit()                        */
     243             : /************************************************************************/
     244             : 
     245           0 : static SAFile VSI_SHP_Open2GBLimit(const char *pszFilename,
     246             :                                    const char *pszAccess, void *userData)
     247             : 
     248             : {
     249             :     (void)userData;
     250           0 :     return VSI_SHP_OpenInternal(pszFilename, pszAccess, TRUE);
     251             : }
     252             : 
     253             : /************************************************************************/
     254             : /*                         VSI_SHP_GetHook()                            */
     255             : /************************************************************************/
     256             : 
     257             : static const SAHooks sOGRHook = {
     258             :     VSI_SHP_Open,  VSI_SHP_Read,  VSI_SHP_Write, VSI_SHP_Seek,
     259             :     VSI_SHP_Tell,  VSI_SHP_Flush, VSI_SHP_Close, VSI_SHP_Remove,
     260             :     VSI_SHP_Error, CPLAtof,       NULL};
     261             : 
     262             : static const SAHooks sOGRHook2GBLimit = {
     263             :     VSI_SHP_Open2GBLimit, VSI_SHP_Read,  VSI_SHP_Write, VSI_SHP_Seek,
     264             :     VSI_SHP_Tell,         VSI_SHP_Flush, VSI_SHP_Close, VSI_SHP_Remove,
     265             :     VSI_SHP_Error,        CPLAtof,       NULL};
     266             : 
     267       10123 : const SAHooks *VSI_SHP_GetHook(int b2GBLimit)
     268             : {
     269       10123 :     return (b2GBLimit) ? &sOGRHook2GBLimit : &sOGRHook;
     270             : }
     271             : 
     272             : #endif

Generated by: LCOV version 1.14