Coverage Report

Created: 2025-11-15 08:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/pcidsk/vsi_pcidsk_io.cpp
Line
Count
Source
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
const PCIDSK::PCIDSKInterfaces *PCIDSK2GetInterfaces()
49
33.7k
{
50
33.7k
    static VSI_IOInterface singleton_vsi_interface;
51
33.7k
    static PCIDSKInterfaces singleton_pcidsk2_interfaces;
52
53
33.7k
    singleton_pcidsk2_interfaces.io = &singleton_vsi_interface;
54
33.7k
    singleton_pcidsk2_interfaces.OpenEDB = GDAL_EDBOpen;
55
56
33.7k
    return &singleton_pcidsk2_interfaces;
57
33.7k
}
58
59
/************************************************************************/
60
/*                                Open()                                */
61
/************************************************************************/
62
63
void *VSI_IOInterface::Open(const std::string &filename,
64
                            const std::string &access) const
65
66
1.38M
{
67
1.38M
    VSILFILE *fp = VSIFOpenL(filename.c_str(), access.c_str());
68
69
1.38M
    if (fp == nullptr)
70
1.19M
        ThrowPCIDSKException("Failed to open %s: %s", filename.c_str(),
71
1.19M
                             LastError());
72
73
1.38M
    return fp;
74
1.38M
}
75
76
/************************************************************************/
77
/*                                Seek()                                */
78
/************************************************************************/
79
80
uint64 VSI_IOInterface::Seek(void *io_handle, uint64 offset, int whence) const
81
82
1.18M
{
83
1.18M
    VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
84
85
1.18M
    uint64 result = VSIFSeekL(fp, offset, whence);
86
87
1.18M
    if (result == static_cast<uint64>(-1))
88
26
        ThrowPCIDSKException("Seek(%d,%d): %s", static_cast<int>(offset),
89
26
                             whence, LastError());
90
91
1.18M
    return result;
92
1.18M
}
93
94
/************************************************************************/
95
/*                                Tell()                                */
96
/************************************************************************/
97
98
uint64 VSI_IOInterface::Tell(void *io_handle) const
99
100
1.00k
{
101
1.00k
    VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
102
103
1.00k
    return VSIFTellL(fp);
104
1.00k
}
105
106
/************************************************************************/
107
/*                                Read()                                */
108
/************************************************************************/
109
110
uint64 VSI_IOInterface::Read(void *buffer, uint64 size, uint64 nmemb,
111
                             void *io_handle) const
112
113
1.12M
{
114
1.12M
    VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
115
116
1.12M
    errno = 0;
117
118
1.12M
    uint64 result = VSIFReadL(buffer, (size_t)size, (size_t)nmemb, fp);
119
120
1.12M
    if (errno != 0 && result == 0 && nmemb != 0)
121
0
        ThrowPCIDSKException("Read(%d): %s", static_cast<int>(size * nmemb),
122
0
                             LastError());
123
124
1.12M
    return result;
125
1.12M
}
126
127
/************************************************************************/
128
/*                               Write()                                */
129
/************************************************************************/
130
131
uint64 VSI_IOInterface::Write(const void *buffer, uint64 size, uint64 nmemb,
132
                              void *io_handle) const
133
134
89.3k
{
135
89.3k
    VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
136
137
89.3k
    errno = 0;
138
139
89.3k
    uint64 result = VSIFWriteL(buffer, static_cast<size_t>(size),
140
89.3k
                               static_cast<size_t>(nmemb), fp);
141
142
89.3k
    if (errno != 0 && result == 0 && nmemb != 0)
143
0
        ThrowPCIDSKException("Write(%d): %s", static_cast<int>(size * nmemb),
144
0
                             LastError());
145
146
89.3k
    return result;
147
89.3k
}
148
149
/************************************************************************/
150
/*                                Eof()                                 */
151
/************************************************************************/
152
153
int VSI_IOInterface::Eof(void *io_handle) const
154
155
0
{
156
0
    return VSIFEofL(reinterpret_cast<VSILFILE *>(io_handle));
157
0
}
158
159
/************************************************************************/
160
/*                               Flush()                                */
161
/************************************************************************/
162
163
int VSI_IOInterface::Flush(void *io_handle) const
164
165
978
{
166
978
    return VSIFFlushL(reinterpret_cast<VSILFILE *>(io_handle));
167
978
}
168
169
/************************************************************************/
170
/*                               Close()                                */
171
/************************************************************************/
172
173
int VSI_IOInterface::Close(void *io_handle) const
174
175
192k
{
176
192k
    return VSIFCloseL(reinterpret_cast<VSILFILE *>(io_handle));
177
192k
}
178
179
/************************************************************************/
180
/*                             LastError()                              */
181
/*                                                                      */
182
/*      Return a string representation of the last error.               */
183
/************************************************************************/
184
185
const char *VSI_IOInterface::LastError() const
186
187
1.19M
{
188
1.19M
    return strerror(errno);
189
1.19M
}
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
const IOInterfaces *PCIDSK::GetDefaultIOInterfaces()
200
67.7k
{
201
67.7k
    static VSI_IOInterface singleton_vsi_interface;
202
203
67.7k
    return &singleton_vsi_interface;
204
67.7k
}
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
CPLThreadMutex::CPLThreadMutex()
229
230
34.1k
{
231
34.1k
    hMutex = CPLCreateMutex();
232
34.1k
    CPLReleaseMutex(hMutex);  // it is created acquired, but we want it free.
233
34.1k
}
234
235
/************************************************************************/
236
/*                           ~CPLThreadMutex()                            */
237
/************************************************************************/
238
239
CPLThreadMutex::~CPLThreadMutex()
240
241
34.1k
{
242
34.1k
    CPLDestroyMutex(hMutex);
243
34.1k
}
244
245
/************************************************************************/
246
/*                              Release()                               */
247
/************************************************************************/
248
249
int CPLThreadMutex::Release()
250
251
1.22M
{
252
1.22M
    CPLReleaseMutex(hMutex);
253
1.22M
    return 1;
254
1.22M
}
255
256
/************************************************************************/
257
/*                              Acquire()                               */
258
/************************************************************************/
259
260
int CPLThreadMutex::Acquire()
261
262
1.22M
{
263
1.22M
    return CPLAcquireMutex(hMutex, 100.0);
264
1.22M
}
265
266
/************************************************************************/
267
/*                         DefaultCreateMutex()                         */
268
/************************************************************************/
269
270
PCIDSK::Mutex *PCIDSK::DefaultCreateMutex(void)
271
272
34.1k
{
273
34.1k
    return new CPLThreadMutex();
274
34.1k
}
275
276
#endif /* def PCIDSK_INTERNAL */