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-05-04 12:52:34 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #include "shp_vsi.h"
      32             : #include "cpl_error.h"
      33             : #include "cpl_conv.h"
      34             : #include "cpl_vsi_error.h"
      35             : #include <limits.h>
      36             : 
      37             : typedef struct
      38             : {
      39             :     VSILFILE *fp;
      40             :     char *pszFilename;
      41             :     int bEnforce2GBLimit;
      42             :     int bHasWarned2GB;
      43             :     SAOffset nCurOffset;
      44             : } OGRSHPDBFFile;
      45             : 
      46             : /************************************************************************/
      47             : /*                         VSI_SHP_GetVSIL()                            */
      48             : /************************************************************************/
      49             : 
      50       80249 : VSILFILE *VSI_SHP_GetVSIL(SAFile file)
      51             : {
      52       80249 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
      53       80249 :     return pFile->fp;
      54             : }
      55             : 
      56             : /************************************************************************/
      57             : /*                        VSI_SHP_GetFilename()                         */
      58             : /************************************************************************/
      59             : 
      60         156 : const char *VSI_SHP_GetFilename(SAFile file)
      61             : {
      62         156 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
      63         156 :     return pFile->pszFilename;
      64             : }
      65             : 
      66             : /************************************************************************/
      67             : /*                         VSI_SHP_OpenInternal()                       */
      68             : /************************************************************************/
      69             : 
      70       25544 : static SAFile VSI_SHP_OpenInternal(const char *pszFilename,
      71             :                                    const char *pszAccess, int bEnforce2GBLimit)
      72             : 
      73             : {
      74             :     OGRSHPDBFFile *pFile;
      75       25544 :     VSILFILE *fp = VSIFOpenExL(pszFilename, pszAccess, TRUE);
      76       25544 :     if (fp == NULL)
      77       10962 :         return NULL;
      78       14582 :     pFile = (OGRSHPDBFFile *)CPLCalloc(1, sizeof(OGRSHPDBFFile));
      79       14582 :     pFile->fp = fp;
      80       14582 :     pFile->pszFilename = CPLStrdup(pszFilename);
      81       14582 :     pFile->bEnforce2GBLimit = bEnforce2GBLimit;
      82       14582 :     pFile->nCurOffset = 0;
      83       14582 :     return (SAFile)pFile;
      84             : }
      85             : 
      86             : /************************************************************************/
      87             : /*                            VSI_SHP_Open()                            */
      88             : /************************************************************************/
      89             : 
      90       25544 : static SAFile VSI_SHP_Open(const char *pszFilename, const char *pszAccess,
      91             :                            void *userData)
      92             : 
      93             : {
      94             :     (void)userData;
      95       25544 :     return VSI_SHP_OpenInternal(pszFilename, pszAccess, FALSE);
      96             : }
      97             : 
      98             : /************************************************************************/
      99             : /*                        VSI_SHP_Open2GBLimit()                        */
     100             : /************************************************************************/
     101             : 
     102           0 : static SAFile VSI_SHP_Open2GBLimit(const char *pszFilename,
     103             :                                    const char *pszAccess, void *userData)
     104             : 
     105             : {
     106             :     (void)userData;
     107           0 :     return VSI_SHP_OpenInternal(pszFilename, pszAccess, TRUE);
     108             : }
     109             : 
     110             : /************************************************************************/
     111             : /*                            VSI_SHP_Read()                            */
     112             : /************************************************************************/
     113             : 
     114     2671580 : static SAOffset VSI_SHP_Read(void *p, SAOffset size, SAOffset nmemb,
     115             :                              SAFile file)
     116             : 
     117             : {
     118     2671580 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     119             :     SAOffset ret =
     120     2671580 :         (SAOffset)VSIFReadL(p, (size_t)size, (size_t)nmemb, pFile->fp);
     121     2671580 :     pFile->nCurOffset += ret * size;
     122     2671580 :     return ret;
     123             : }
     124             : 
     125             : /************************************************************************/
     126             : /*                      VSI_SHP_WriteMoreDataOK()                       */
     127             : /************************************************************************/
     128             : 
     129      413471 : int VSI_SHP_WriteMoreDataOK(SAFile file, SAOffset nExtraBytes)
     130             : {
     131      413471 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     132      413471 :     if (pFile->nCurOffset + nExtraBytes > INT_MAX)
     133             :     {
     134           0 :         if (pFile->bEnforce2GBLimit)
     135             :         {
     136           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     137             :                      "2GB file size limit reached for %s", pFile->pszFilename);
     138           0 :             return FALSE;
     139             :         }
     140           0 :         else if (!pFile->bHasWarned2GB)
     141             :         {
     142           0 :             pFile->bHasWarned2GB = TRUE;
     143           0 :             CPLError(CE_Warning, CPLE_AppDefined,
     144             :                      "2GB file size limit reached for %s. "
     145             :                      "Going on, but might cause compatibility issues with "
     146             :                      "third party software",
     147             :                      pFile->pszFilename);
     148             :         }
     149             :     }
     150             : 
     151      413471 :     return TRUE;
     152             : }
     153             : 
     154             : /************************************************************************/
     155             : /*                           VSI_SHP_Write()                            */
     156             : /************************************************************************/
     157             : 
     158      336224 : static SAOffset VSI_SHP_Write(const void *p, SAOffset size, SAOffset nmemb,
     159             :                               SAFile file)
     160             : 
     161             : {
     162      336224 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     163             :     SAOffset ret;
     164      336224 :     if (!VSI_SHP_WriteMoreDataOK(file, size * nmemb))
     165           0 :         return 0;
     166      336224 :     ret = (SAOffset)VSIFWriteL(p, (size_t)size, (size_t)nmemb, pFile->fp);
     167      336224 :     pFile->nCurOffset += ret * size;
     168      336224 :     return ret;
     169             : }
     170             : 
     171             : /************************************************************************/
     172             : /*                            VSI_SHP_Seek()                            */
     173             : /************************************************************************/
     174             : 
     175      812416 : static SAOffset VSI_SHP_Seek(SAFile file, SAOffset offset, int whence)
     176             : 
     177             : {
     178      812416 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     179      812416 :     SAOffset ret = (SAOffset)VSIFSeekL(pFile->fp, (vsi_l_offset)offset, whence);
     180      812416 :     if (whence == 0 && ret == 0)
     181      452046 :         pFile->nCurOffset = offset;
     182             :     else
     183      360370 :         pFile->nCurOffset = (SAOffset)VSIFTellL(pFile->fp);
     184      812416 :     return ret;
     185             : }
     186             : 
     187             : /************************************************************************/
     188             : /*                            VSI_SHP_Tell()                            */
     189             : /************************************************************************/
     190             : 
     191      160820 : static SAOffset VSI_SHP_Tell(SAFile file)
     192             : 
     193             : {
     194      160820 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     195      160820 :     return (SAOffset)pFile->nCurOffset;
     196             : }
     197             : 
     198             : /************************************************************************/
     199             : /*                           VSI_SHP_Flush()                            */
     200             : /************************************************************************/
     201             : 
     202        6011 : static int VSI_SHP_Flush(SAFile file)
     203             : 
     204             : {
     205        6011 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     206        6011 :     return VSIFFlushL(pFile->fp);
     207             : }
     208             : 
     209             : /************************************************************************/
     210             : /*                           VSI_SHP_Close()                            */
     211             : /************************************************************************/
     212             : 
     213       14566 : static int VSI_SHP_Close(SAFile file)
     214             : 
     215             : {
     216       14566 :     OGRSHPDBFFile *pFile = (OGRSHPDBFFile *)file;
     217       14566 :     int ret = VSIFCloseL(pFile->fp);
     218       14566 :     CPLFree(pFile->pszFilename);
     219       14566 :     CPLFree(pFile);
     220       14566 :     return ret;
     221             : }
     222             : 
     223             : /************************************************************************/
     224             : /*                              SADError()                              */
     225             : /************************************************************************/
     226             : 
     227         343 : static void VSI_SHP_Error(const char *message)
     228             : 
     229             : {
     230         343 :     CPLError(CE_Failure, CPLE_AppDefined, "%s", message);
     231         343 : }
     232             : 
     233             : /************************************************************************/
     234             : /*                           VSI_SHP_Remove()                           */
     235             : /************************************************************************/
     236             : 
     237        1577 : static int VSI_SHP_Remove(const char *pszFilename, void *userData)
     238             : 
     239             : {
     240             :     (void)userData;
     241        1577 :     return VSIUnlink(pszFilename);
     242             : }
     243             : 
     244             : /************************************************************************/
     245             : /*                        SASetupDefaultHooks()                         */
     246             : /************************************************************************/
     247             : 
     248        3337 : void SASetupDefaultHooks(SAHooks *psHooks)
     249             : 
     250             : {
     251        3337 :     psHooks->FOpen = VSI_SHP_Open;
     252        3337 :     psHooks->FRead = VSI_SHP_Read;
     253        3337 :     psHooks->FWrite = VSI_SHP_Write;
     254        3337 :     psHooks->FSeek = VSI_SHP_Seek;
     255        3337 :     psHooks->FTell = VSI_SHP_Tell;
     256        3337 :     psHooks->FFlush = VSI_SHP_Flush;
     257        3337 :     psHooks->FClose = VSI_SHP_Close;
     258        3337 :     psHooks->Remove = VSI_SHP_Remove;
     259             : 
     260        3337 :     psHooks->Error = VSI_SHP_Error;
     261        3337 :     psHooks->Atof = CPLAtof;
     262        3337 :     psHooks->pvUserData = NULL;
     263        3337 : }
     264             : 
     265             : /************************************************************************/
     266             : /*                         VSI_SHP_GetHook()                            */
     267             : /************************************************************************/
     268             : 
     269             : static const SAHooks sOGRHook = {
     270             :     VSI_SHP_Open,  VSI_SHP_Read,  VSI_SHP_Write, VSI_SHP_Seek,
     271             :     VSI_SHP_Tell,  VSI_SHP_Flush, VSI_SHP_Close, VSI_SHP_Remove,
     272             :     VSI_SHP_Error, CPLAtof,       NULL};
     273             : 
     274             : static const SAHooks sOGRHook2GBLimit = {
     275             :     VSI_SHP_Open2GBLimit, VSI_SHP_Read,  VSI_SHP_Write, VSI_SHP_Seek,
     276             :     VSI_SHP_Tell,         VSI_SHP_Flush, VSI_SHP_Close, VSI_SHP_Remove,
     277             :     VSI_SHP_Error,        CPLAtof,       NULL};
     278             : 
     279       10051 : const SAHooks *VSI_SHP_GetHook(int b2GBLimit)
     280             : {
     281       10051 :     return (b2GBLimit) ? &sOGRHook2GBLimit : &sOGRHook;
     282             : }

Generated by: LCOV version 1.14