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 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "cpl_conv.h"
31 : #include "cpl_multiproc.h"
32 : #include "pcidsk.h"
33 :
34 : using PCIDSK::IOInterfaces;
35 : using PCIDSK::PCIDSKInterfaces;
36 : using PCIDSK::ThrowPCIDSKException;
37 : using PCIDSK::uint64;
38 :
39 : PCIDSK::EDBFile *GDAL_EDBOpen(const std::string &osFilename,
40 : const std::string &osAccess);
41 : const PCIDSK::PCIDSKInterfaces *PCIDSK2GetInterfaces();
42 :
43 : class VSI_IOInterface : public IOInterfaces
44 : {
45 : virtual void *Open(const std::string &filename,
46 : std::string access) const override;
47 : virtual uint64 Seek(void *io_handle, uint64 offset,
48 : int whence) const override;
49 : virtual uint64 Tell(void *io_handle) const override;
50 : virtual uint64 Read(void *buffer, uint64 size, uint64 nmemb,
51 : void *io_hanle) const override;
52 : virtual uint64 Write(const void *buffer, uint64 size, uint64 nmemb,
53 : void *io_handle) const override;
54 : virtual int Eof(void *io_handle) const override;
55 : virtual int Flush(void *io_handle) const override;
56 : virtual int Close(void *io_handle) const override;
57 :
58 : const char *LastError() const;
59 : };
60 :
61 : /************************************************************************/
62 : /* PCIDSK2GetIOInterfaces() */
63 : /************************************************************************/
64 :
65 260 : const PCIDSK::PCIDSKInterfaces *PCIDSK2GetInterfaces()
66 : {
67 260 : static VSI_IOInterface singleton_vsi_interface;
68 260 : static PCIDSKInterfaces singleton_pcidsk2_interfaces;
69 :
70 260 : singleton_pcidsk2_interfaces.io = &singleton_vsi_interface;
71 260 : singleton_pcidsk2_interfaces.OpenEDB = GDAL_EDBOpen;
72 :
73 260 : return &singleton_pcidsk2_interfaces;
74 : }
75 :
76 : /************************************************************************/
77 : /* Open() */
78 : /************************************************************************/
79 :
80 388 : void *VSI_IOInterface::Open(const std::string &filename,
81 : std::string access) const
82 :
83 : {
84 388 : VSILFILE *fp = VSIFOpenL(filename.c_str(), access.c_str());
85 :
86 388 : if (fp == nullptr)
87 5 : ThrowPCIDSKException("Failed to open %s: %s", filename.c_str(),
88 : LastError());
89 :
90 383 : return fp;
91 : }
92 :
93 : /************************************************************************/
94 : /* Seek() */
95 : /************************************************************************/
96 :
97 17280 : uint64 VSI_IOInterface::Seek(void *io_handle, uint64 offset, int whence) const
98 :
99 : {
100 17280 : VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
101 :
102 17280 : uint64 result = VSIFSeekL(fp, offset, whence);
103 :
104 17280 : if (result == static_cast<uint64>(-1))
105 0 : ThrowPCIDSKException("Seek(%d,%d): %s", static_cast<int>(offset),
106 : whence, LastError());
107 :
108 17280 : return result;
109 : }
110 :
111 : /************************************************************************/
112 : /* Tell() */
113 : /************************************************************************/
114 :
115 1 : uint64 VSI_IOInterface::Tell(void *io_handle) const
116 :
117 : {
118 1 : VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
119 :
120 1 : return VSIFTellL(fp);
121 : }
122 :
123 : /************************************************************************/
124 : /* Read() */
125 : /************************************************************************/
126 :
127 4982 : uint64 VSI_IOInterface::Read(void *buffer, uint64 size, uint64 nmemb,
128 : void *io_handle) const
129 :
130 : {
131 4982 : VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
132 :
133 4982 : errno = 0;
134 :
135 4982 : uint64 result = VSIFReadL(buffer, (size_t)size, (size_t)nmemb, fp);
136 :
137 4982 : if (errno != 0 && result == 0 && nmemb != 0)
138 0 : ThrowPCIDSKException("Read(%d): %s", static_cast<int>(size * nmemb),
139 : LastError());
140 :
141 4982 : return result;
142 : }
143 :
144 : /************************************************************************/
145 : /* Write() */
146 : /************************************************************************/
147 :
148 13181 : uint64 VSI_IOInterface::Write(const void *buffer, uint64 size, uint64 nmemb,
149 : void *io_handle) const
150 :
151 : {
152 13181 : VSILFILE *fp = reinterpret_cast<VSILFILE *>(io_handle);
153 :
154 13181 : errno = 0;
155 :
156 13181 : uint64 result = VSIFWriteL(buffer, static_cast<size_t>(size),
157 : static_cast<size_t>(nmemb), fp);
158 :
159 13181 : if (errno != 0 && result == 0 && nmemb != 0)
160 0 : ThrowPCIDSKException("Write(%d): %s", static_cast<int>(size * nmemb),
161 : LastError());
162 :
163 13181 : return result;
164 : }
165 :
166 : /************************************************************************/
167 : /* Eof() */
168 : /************************************************************************/
169 :
170 0 : int VSI_IOInterface::Eof(void *io_handle) const
171 :
172 : {
173 0 : return VSIFEofL(reinterpret_cast<VSILFILE *>(io_handle));
174 : }
175 :
176 : /************************************************************************/
177 : /* Flush() */
178 : /************************************************************************/
179 :
180 242 : int VSI_IOInterface::Flush(void *io_handle) const
181 :
182 : {
183 242 : return VSIFFlushL(reinterpret_cast<VSILFILE *>(io_handle));
184 : }
185 :
186 : /************************************************************************/
187 : /* Close() */
188 : /************************************************************************/
189 :
190 383 : int VSI_IOInterface::Close(void *io_handle) const
191 :
192 : {
193 383 : return VSIFCloseL(reinterpret_cast<VSILFILE *>(io_handle));
194 : }
195 :
196 : /************************************************************************/
197 : /* LastError() */
198 : /* */
199 : /* Return a string representation of the last error. */
200 : /************************************************************************/
201 :
202 5 : const char *VSI_IOInterface::LastError() const
203 :
204 : {
205 5 : return strerror(errno);
206 : }
207 :
208 : /************************************************************************/
209 : /* If we are using the internal copy of the PCIDSK SDK we need */
210 : /* to provide stub implementations of GetDefaultIOInterfaces() */
211 : /* and GetDefaultMutex() */
212 : /************************************************************************/
213 :
214 : #ifdef PCIDSK_INTERNAL
215 :
216 641 : const IOInterfaces *PCIDSK::GetDefaultIOInterfaces()
217 : {
218 641 : static VSI_IOInterface singleton_vsi_interface;
219 :
220 641 : return &singleton_vsi_interface;
221 : }
222 :
223 : /************************************************************************/
224 : /* CPLThreadMutex */
225 : /************************************************************************/
226 :
227 : class CPLThreadMutex : public PCIDSK::Mutex
228 :
229 : {
230 : private:
231 : CPLMutex *hMutex;
232 :
233 : public:
234 : CPLThreadMutex();
235 : ~CPLThreadMutex();
236 :
237 : int Acquire(void) override;
238 : int Release(void) override;
239 : };
240 :
241 : /************************************************************************/
242 : /* CPLThreadMutex() */
243 : /************************************************************************/
244 :
245 306 : CPLThreadMutex::CPLThreadMutex()
246 :
247 : {
248 306 : hMutex = CPLCreateMutex();
249 306 : CPLReleaseMutex(hMutex); // it is created acquired, but we want it free.
250 306 : }
251 :
252 : /************************************************************************/
253 : /* ~CPLThreadMutex() */
254 : /************************************************************************/
255 :
256 612 : CPLThreadMutex::~CPLThreadMutex()
257 :
258 : {
259 306 : CPLDestroyMutex(hMutex);
260 612 : }
261 :
262 : /************************************************************************/
263 : /* Release() */
264 : /************************************************************************/
265 :
266 17750 : int CPLThreadMutex::Release()
267 :
268 : {
269 17750 : CPLReleaseMutex(hMutex);
270 17750 : return 1;
271 : }
272 :
273 : /************************************************************************/
274 : /* Acquire() */
275 : /************************************************************************/
276 :
277 17750 : int CPLThreadMutex::Acquire()
278 :
279 : {
280 17750 : return CPLAcquireMutex(hMutex, 100.0);
281 : }
282 :
283 : /************************************************************************/
284 : /* DefaultCreateMutex() */
285 : /************************************************************************/
286 :
287 306 : PCIDSK::Mutex *PCIDSK::DefaultCreateMutex(void)
288 :
289 : {
290 306 : return new CPLThreadMutex();
291 : }
292 :
293 : #endif /* def PCIDSK_INTERNAL */
|