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