LCOV - code coverage report
Current view: top level - frmts/pcidsk - vsi_pcidsk_io.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 54 59 91.5 %
Date: 2025-09-10 17:48:50 Functions: 16 17 94.1 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PCIDSK Database File
       4             :  * Purpose:  PCIDSK SDK compatible IO interface built on VSI.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
       9             :  * Copyright (c) 2010, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_conv.h"
      15             : #include "cpl_multiproc.h"
      16             : #include "pcidsk.h"
      17             : 
      18             : using PCIDSK::IOInterfaces;
      19             : using PCIDSK::PCIDSKInterfaces;
      20             : using PCIDSK::ThrowPCIDSKException;
      21             : using PCIDSK::uint64;
      22             : 
      23             : PCIDSK::EDBFile *GDAL_EDBOpen(const std::string &osFilename,
      24             :                               const std::string &osAccess);
      25             : const PCIDSK::PCIDSKInterfaces *PCIDSK2GetInterfaces();
      26             : 
      27             : class VSI_IOInterface final : public IOInterfaces
      28             : {
      29             :     void *Open(const std::string &filename,
      30             :                const std::string &access) const override;
      31             :     uint64 Seek(void *io_handle, uint64 offset, int whence) const override;
      32             :     uint64 Tell(void *io_handle) const override;
      33             :     uint64 Read(void *buffer, uint64 size, uint64 nmemb,
      34             :                 void *io_hanle) const override;
      35             :     uint64 Write(const void *buffer, uint64 size, uint64 nmemb,
      36             :                  void *io_handle) const override;
      37             :     int Eof(void *io_handle) const override;
      38             :     int Flush(void *io_handle) const override;
      39             :     int Close(void *io_handle) const override;
      40             : 
      41             :     const char *LastError() const;
      42             : };
      43             : 
      44             : /************************************************************************/
      45             : /*                       PCIDSK2GetIOInterfaces()                       */
      46             : /************************************************************************/
      47             : 
      48         260 : const PCIDSK::PCIDSKInterfaces *PCIDSK2GetInterfaces()
      49             : {
      50         260 :     static VSI_IOInterface singleton_vsi_interface;
      51         260 :     static PCIDSKInterfaces singleton_pcidsk2_interfaces;
      52             : 
      53         260 :     singleton_pcidsk2_interfaces.io = &singleton_vsi_interface;
      54         260 :     singleton_pcidsk2_interfaces.OpenEDB = GDAL_EDBOpen;
      55             : 
      56         260 :     return &singleton_pcidsk2_interfaces;
      57             : }
      58             : 
      59             : /************************************************************************/
      60             : /*                                Open()                                */
      61             : /************************************************************************/
      62             : 
      63         389 : void *VSI_IOInterface::Open(const std::string &filename,
      64             :                             const std::string &access) const
      65             : 
      66             : {
      67         389 :     VSILFILE *fp = VSIFOpenL(filename.c_str(), access.c_str());
      68             : 
      69         389 :     if (fp == nullptr)
      70           5 :         ThrowPCIDSKException("Failed to open %s: %s", filename.c_str(),
      71             :                              LastError());
      72             : 
      73         384 :     return fp;
      74             : }
      75             : 
      76             : /************************************************************************/
      77             : /*                                Seek()                                */
      78             : /************************************************************************/
      79             : 
      80       17444 : uint64 VSI_IOInterface::Seek(void *io_handle, uint64 offset, int whence) const
      81             : 
      82             : {
      83       17444 :     VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
      84             : 
      85       17444 :     uint64 result = VSIFSeekL(fp, offset, whence);
      86             : 
      87       17444 :     if (result == static_cast<uint64>(-1))
      88           0 :         ThrowPCIDSKException("Seek(%d,%d): %s", static_cast<int>(offset),
      89             :                              whence, LastError());
      90             : 
      91       17444 :     return result;
      92             : }
      93             : 
      94             : /************************************************************************/
      95             : /*                                Tell()                                */
      96             : /************************************************************************/
      97             : 
      98           1 : uint64 VSI_IOInterface::Tell(void *io_handle) const
      99             : 
     100             : {
     101           1 :     VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
     102             : 
     103           1 :     return VSIFTellL(fp);
     104             : }
     105             : 
     106             : /************************************************************************/
     107             : /*                                Read()                                */
     108             : /************************************************************************/
     109             : 
     110        4998 : uint64 VSI_IOInterface::Read(void *buffer, uint64 size, uint64 nmemb,
     111             :                              void *io_handle) const
     112             : 
     113             : {
     114        4998 :     VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
     115             : 
     116        4998 :     errno = 0;
     117             : 
     118        4998 :     uint64 result = VSIFReadL(buffer, (size_t)size, (size_t)nmemb, fp);
     119             : 
     120        4998 :     if (errno != 0 && result == 0 && nmemb != 0)
     121           0 :         ThrowPCIDSKException("Read(%d): %s", static_cast<int>(size * nmemb),
     122             :                              LastError());
     123             : 
     124        4998 :     return result;
     125             : }
     126             : 
     127             : /************************************************************************/
     128             : /*                               Write()                                */
     129             : /************************************************************************/
     130             : 
     131       13330 : uint64 VSI_IOInterface::Write(const void *buffer, uint64 size, uint64 nmemb,
     132             :                               void *io_handle) const
     133             : 
     134             : {
     135       13330 :     VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
     136             : 
     137       13330 :     errno = 0;
     138             : 
     139       13330 :     uint64 result = VSIFWriteL(buffer, static_cast<size_t>(size),
     140             :                                static_cast<size_t>(nmemb), fp);
     141             : 
     142       13330 :     if (errno != 0 && result == 0 && nmemb != 0)
     143           0 :         ThrowPCIDSKException("Write(%d): %s", static_cast<int>(size * nmemb),
     144             :                              LastError());
     145             : 
     146       13330 :     return result;
     147             : }
     148             : 
     149             : /************************************************************************/
     150             : /*                                Eof()                                 */
     151             : /************************************************************************/
     152             : 
     153           0 : int VSI_IOInterface::Eof(void *io_handle) const
     154             : 
     155             : {
     156           0 :     return VSIFEofL(reinterpret_cast<VSILFILE *>(io_handle));
     157             : }
     158             : 
     159             : /************************************************************************/
     160             : /*                               Flush()                                */
     161             : /************************************************************************/
     162             : 
     163         247 : int VSI_IOInterface::Flush(void *io_handle) const
     164             : 
     165             : {
     166         247 :     return VSIFFlushL(reinterpret_cast<VSILFILE *>(io_handle));
     167             : }
     168             : 
     169             : /************************************************************************/
     170             : /*                               Close()                                */
     171             : /************************************************************************/
     172             : 
     173         384 : int VSI_IOInterface::Close(void *io_handle) const
     174             : 
     175             : {
     176         384 :     return VSIFCloseL(reinterpret_cast<VSILFILE *>(io_handle));
     177             : }
     178             : 
     179             : /************************************************************************/
     180             : /*                             LastError()                              */
     181             : /*                                                                      */
     182             : /*      Return a string representation of the last error.               */
     183             : /************************************************************************/
     184             : 
     185           5 : const char *VSI_IOInterface::LastError() const
     186             : 
     187             : {
     188           5 :     return strerror(errno);
     189             : }
     190             : 
     191             : /************************************************************************/
     192             : /*       If we are using the internal copy of the PCIDSK SDK we need    */
     193             : /*      to provide stub implementations of GetDefaultIOInterfaces()     */
     194             : /*      and GetDefaultMutex()                                           */
     195             : /************************************************************************/
     196             : 
     197             : #ifdef PCIDSK_INTERNAL
     198             : 
     199         642 : const IOInterfaces *PCIDSK::GetDefaultIOInterfaces()
     200             : {
     201         642 :     static VSI_IOInterface singleton_vsi_interface;
     202             : 
     203         642 :     return &singleton_vsi_interface;
     204             : }
     205             : 
     206             : /************************************************************************/
     207             : /*                            CPLThreadMutex                            */
     208             : /************************************************************************/
     209             : 
     210             : class CPLThreadMutex final : public PCIDSK::Mutex
     211             : 
     212             : {
     213             :   private:
     214             :     CPLMutex *hMutex;
     215             : 
     216             :   public:
     217             :     CPLThreadMutex();
     218             :     ~CPLThreadMutex() override;
     219             : 
     220             :     int Acquire(void) override;
     221             :     int Release(void) override;
     222             : };
     223             : 
     224             : /************************************************************************/
     225             : /*                            CPLThreadMutex()                            */
     226             : /************************************************************************/
     227             : 
     228         306 : CPLThreadMutex::CPLThreadMutex()
     229             : 
     230             : {
     231         306 :     hMutex = CPLCreateMutex();
     232         306 :     CPLReleaseMutex(hMutex);  // it is created acquired, but we want it free.
     233         306 : }
     234             : 
     235             : /************************************************************************/
     236             : /*                           ~CPLThreadMutex()                            */
     237             : /************************************************************************/
     238             : 
     239         612 : CPLThreadMutex::~CPLThreadMutex()
     240             : 
     241             : {
     242         306 :     CPLDestroyMutex(hMutex);
     243         612 : }
     244             : 
     245             : /************************************************************************/
     246             : /*                              Release()                               */
     247             : /************************************************************************/
     248             : 
     249       17916 : int CPLThreadMutex::Release()
     250             : 
     251             : {
     252       17916 :     CPLReleaseMutex(hMutex);
     253       17916 :     return 1;
     254             : }
     255             : 
     256             : /************************************************************************/
     257             : /*                              Acquire()                               */
     258             : /************************************************************************/
     259             : 
     260       17916 : int CPLThreadMutex::Acquire()
     261             : 
     262             : {
     263       17916 :     return CPLAcquireMutex(hMutex, 100.0);
     264             : }
     265             : 
     266             : /************************************************************************/
     267             : /*                         DefaultCreateMutex()                         */
     268             : /************************************************************************/
     269             : 
     270         306 : PCIDSK::Mutex *PCIDSK::DefaultCreateMutex(void)
     271             : 
     272             : {
     273         306 :     return new CPLThreadMutex();
     274             : }
     275             : 
     276             : #endif /* def PCIDSK_INTERNAL */

Generated by: LCOV version 1.14