1 : /**********************************************************************
2 : * $Id: cpl_vsil_stdout.cpp 21906 2011-03-06 16:41:27Z rouault $
3 : *
4 : * Project: CPL - Common Portability Library
5 : * Purpose: Implement VSI large file api for stdout
6 : * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
7 : *
8 : **********************************************************************
9 : * Copyright (c) 2010, Even Rouault
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 OR
22 : * 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_port.h"
31 : #include "cpl_error.h"
32 : #include "cpl_vsi_virtual.h"
33 :
34 : #include <stdio.h>
35 : #ifdef WIN32
36 : #include <io.h>
37 : #include <fcntl.h>
38 : #endif
39 :
40 : CPL_CVSID("$Id: cpl_vsil_stdout.cpp 21906 2011-03-06 16:41:27Z rouault $");
41 :
42 : /************************************************************************/
43 : /* ==================================================================== */
44 : /* VSIStdoutFilesystemHandler */
45 : /* ==================================================================== */
46 : /************************************************************************/
47 :
48 : class VSIStdoutFilesystemHandler : public VSIFilesystemHandler
49 2638 : {
50 : public:
51 : virtual VSIVirtualHandle *Open( const char *pszFilename,
52 : const char *pszAccess);
53 : virtual int Stat( const char *pszFilename, VSIStatBufL *pStatBuf, int nFlags );
54 : };
55 :
56 : /************************************************************************/
57 : /* ==================================================================== */
58 : /* VSIStdoutHandle */
59 : /* ==================================================================== */
60 : /************************************************************************/
61 :
62 : class VSIStdoutHandle : public VSIVirtualHandle
63 8 : {
64 : public:
65 :
66 : virtual int Seek( vsi_l_offset nOffset, int nWhence );
67 : virtual vsi_l_offset Tell();
68 : virtual size_t Read( void *pBuffer, size_t nSize, size_t nMemb );
69 : virtual size_t Write( const void *pBuffer, size_t nSize, size_t nMemb );
70 : virtual int Eof();
71 : virtual int Flush();
72 : virtual int Close();
73 : };
74 :
75 : /************************************************************************/
76 : /* Seek() */
77 : /************************************************************************/
78 :
79 0 : int VSIStdoutHandle::Seek( vsi_l_offset nOffset, int nWhence )
80 :
81 : {
82 0 : CPLError(CE_Failure, CPLE_NotSupported, "Seek() unsupported on /vsistdout");
83 0 : return -1;
84 : }
85 :
86 : /************************************************************************/
87 : /* Tell() */
88 : /************************************************************************/
89 :
90 0 : vsi_l_offset VSIStdoutHandle::Tell()
91 : {
92 0 : return ftell(stdout);
93 : }
94 :
95 : /************************************************************************/
96 : /* Flush() */
97 : /************************************************************************/
98 :
99 0 : int VSIStdoutHandle::Flush()
100 :
101 : {
102 0 : return fflush( stdout );
103 : }
104 :
105 : /************************************************************************/
106 : /* Read() */
107 : /************************************************************************/
108 :
109 0 : size_t VSIStdoutHandle::Read( void * pBuffer, size_t nSize, size_t nCount )
110 :
111 : {
112 0 : CPLError(CE_Failure, CPLE_NotSupported, "Read() unsupported on /vsistdout");
113 0 : return 0;
114 : }
115 :
116 : /************************************************************************/
117 : /* Write() */
118 : /************************************************************************/
119 :
120 34 : size_t VSIStdoutHandle::Write( const void * pBuffer, size_t nSize,
121 : size_t nCount )
122 :
123 : {
124 34 : return fwrite(pBuffer, nSize, nCount, stdout);
125 : }
126 :
127 : /************************************************************************/
128 : /* Eof() */
129 : /************************************************************************/
130 :
131 0 : int VSIStdoutHandle::Eof()
132 :
133 : {
134 0 : return feof(stdout);
135 : }
136 :
137 : /************************************************************************/
138 : /* Close() */
139 : /************************************************************************/
140 :
141 4 : int VSIStdoutHandle::Close()
142 :
143 : {
144 4 : return 0;
145 : }
146 :
147 : /************************************************************************/
148 : /* ==================================================================== */
149 : /* VSIStdoutFilesystemHandler */
150 : /* ==================================================================== */
151 : /************************************************************************/
152 :
153 : /************************************************************************/
154 : /* Open() */
155 : /************************************************************************/
156 :
157 : VSIVirtualHandle *
158 4 : VSIStdoutFilesystemHandler::Open( const char *pszFilename,
159 : const char *pszAccess )
160 :
161 : {
162 4 : if ( strchr(pszAccess, 'r') != NULL ||
163 : strchr(pszAccess, '+') != NULL )
164 : {
165 : CPLError(CE_Failure, CPLE_NotSupported,
166 0 : "Read or update mode not supported on /vsistdout");
167 0 : return NULL;
168 : }
169 :
170 : #ifdef WIN32
171 : if ( strchr(pszAccess, 'b') != NULL )
172 : setmode( fileno( stdout ), O_BINARY );
173 : #endif
174 :
175 4 : return new VSIStdoutHandle;
176 : }
177 :
178 : /************************************************************************/
179 : /* Stat() */
180 : /************************************************************************/
181 :
182 6 : int VSIStdoutFilesystemHandler::Stat( const char * pszFilename,
183 : VSIStatBufL * pStatBuf,
184 : int nFlags )
185 :
186 : {
187 6 : memset( pStatBuf, 0, sizeof(VSIStatBufL) );
188 :
189 6 : return -1;
190 : }
191 :
192 :
193 :
194 : /************************************************************************/
195 : /* ==================================================================== */
196 : /* VSIStdoutRedirectFilesystemHandler */
197 : /* ==================================================================== */
198 : /************************************************************************/
199 :
200 : class VSIStdoutRedirectFilesystemHandler : public VSIFilesystemHandler
201 2638 : {
202 : public:
203 : virtual VSIVirtualHandle *Open( const char *pszFilename,
204 : const char *pszAccess);
205 : virtual int Stat( const char *pszFilename, VSIStatBufL *pStatBuf, int nFlags );
206 : };
207 :
208 : /************************************************************************/
209 : /* ==================================================================== */
210 : /* VSIStdoutRedirectHandle */
211 : /* ==================================================================== */
212 : /************************************************************************/
213 :
214 : class VSIStdoutRedirectHandle : public VSIVirtualHandle
215 : {
216 : VSIVirtualHandle* poHandle;
217 : public:
218 : VSIStdoutRedirectHandle(VSIVirtualHandle* poHandle);
219 : ~VSIStdoutRedirectHandle();
220 :
221 : virtual int Seek( vsi_l_offset nOffset, int nWhence );
222 : virtual vsi_l_offset Tell();
223 : virtual size_t Read( void *pBuffer, size_t nSize, size_t nMemb );
224 : virtual size_t Write( const void *pBuffer, size_t nSize, size_t nMemb );
225 : virtual int Eof();
226 : virtual int Flush();
227 : virtual int Close();
228 : };
229 :
230 : /************************************************************************/
231 : /* VSIStdoutRedirectHandle() */
232 : /************************************************************************/
233 :
234 8 : VSIStdoutRedirectHandle::VSIStdoutRedirectHandle(VSIVirtualHandle* poHandle)
235 : {
236 8 : this->poHandle = poHandle;
237 8 : }
238 :
239 : /************************************************************************/
240 : /* ~VSIStdoutRedirectHandle() */
241 : /************************************************************************/
242 :
243 8 : VSIStdoutRedirectHandle::~VSIStdoutRedirectHandle()
244 : {
245 8 : delete poHandle;
246 8 : }
247 :
248 : /************************************************************************/
249 : /* Seek() */
250 : /************************************************************************/
251 :
252 0 : int VSIStdoutRedirectHandle::Seek( vsi_l_offset nOffset, int nWhence )
253 :
254 : {
255 0 : CPLError(CE_Failure, CPLE_NotSupported, "Seek() unsupported on /vsistdout_redirect");
256 0 : return -1;
257 : }
258 :
259 : /************************************************************************/
260 : /* Tell() */
261 : /************************************************************************/
262 :
263 542 : vsi_l_offset VSIStdoutRedirectHandle::Tell()
264 : {
265 542 : return poHandle->Tell();
266 : }
267 :
268 : /************************************************************************/
269 : /* Flush() */
270 : /************************************************************************/
271 :
272 4 : int VSIStdoutRedirectHandle::Flush()
273 :
274 : {
275 4 : return poHandle->Flush();
276 : }
277 :
278 : /************************************************************************/
279 : /* Read() */
280 : /************************************************************************/
281 :
282 0 : size_t VSIStdoutRedirectHandle::Read( void * pBuffer, size_t nSize, size_t nCount )
283 :
284 : {
285 0 : CPLError(CE_Failure, CPLE_NotSupported, "Read() unsupported on /vsistdout_redirect");
286 0 : return 0;
287 : }
288 :
289 : /************************************************************************/
290 : /* Write() */
291 : /************************************************************************/
292 :
293 566 : size_t VSIStdoutRedirectHandle::Write( const void * pBuffer, size_t nSize,
294 : size_t nCount )
295 :
296 : {
297 566 : return poHandle->Write(pBuffer, nSize, nCount);
298 : }
299 :
300 : /************************************************************************/
301 : /* Eof() */
302 : /************************************************************************/
303 :
304 0 : int VSIStdoutRedirectHandle::Eof()
305 :
306 : {
307 0 : return poHandle->Eof();
308 : }
309 :
310 : /************************************************************************/
311 : /* Close() */
312 : /************************************************************************/
313 :
314 8 : int VSIStdoutRedirectHandle::Close()
315 :
316 : {
317 8 : return poHandle->Close();
318 : }
319 :
320 : /************************************************************************/
321 : /* ==================================================================== */
322 : /* VSIStdoutRedirectFilesystemHandler */
323 : /* ==================================================================== */
324 : /************************************************************************/
325 :
326 : /************************************************************************/
327 : /* Open() */
328 : /************************************************************************/
329 :
330 : VSIVirtualHandle *
331 8 : VSIStdoutRedirectFilesystemHandler::Open( const char *pszFilename,
332 : const char *pszAccess )
333 :
334 : {
335 8 : if ( strchr(pszAccess, 'r') != NULL ||
336 : strchr(pszAccess, '+') != NULL )
337 : {
338 : CPLError(CE_Failure, CPLE_NotSupported,
339 0 : "Read or update mode not supported on /vsistdout_redirect");
340 0 : return NULL;
341 : }
342 :
343 : VSIVirtualHandle* poHandle = (VSIVirtualHandle* )VSIFOpenL(
344 8 : pszFilename + strlen("/vsistdout_redirect/"), pszAccess);
345 8 : if (poHandle == NULL)
346 0 : return NULL;
347 :
348 8 : return new VSIStdoutRedirectHandle(poHandle);
349 : }
350 :
351 : /************************************************************************/
352 : /* Stat() */
353 : /************************************************************************/
354 :
355 16 : int VSIStdoutRedirectFilesystemHandler::Stat( const char * pszFilename,
356 : VSIStatBufL * pStatBuf,
357 : int nFlags )
358 :
359 : {
360 16 : memset( pStatBuf, 0, sizeof(VSIStatBufL) );
361 :
362 16 : return -1;
363 : }
364 :
365 : /************************************************************************/
366 : /* VSIInstallStdoutHandler() */
367 : /************************************************************************/
368 :
369 : /**
370 : * \brief Install /vsistdout/ file system handler
371 : *
372 : * A special file handler is installed that allows writing to the standard
373 : * output stream.
374 : *
375 : * The file operations available are of course limited to Write().
376 : *
377 : * @since GDAL 1.8.0
378 : */
379 :
380 1341 : void VSIInstallStdoutHandler()
381 :
382 : {
383 1341 : VSIFileManager::InstallHandler( "/vsistdout/", new VSIStdoutFilesystemHandler );
384 2682 : VSIFileManager::InstallHandler( "/vsistdout_redirect/", new VSIStdoutRedirectFilesystemHandler );
385 1341 : }
|