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