OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGzStream.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // gzstream, C++ iostream classes wrapping the zlib compression library.
3 // Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // ============================================================================
19 //
20 // File : gzstream.C
21 // Revision : $Revision: 17195 $
22 // Revision_date : $Date: 2010-04-23 13:32:18 -0400 (Fri, 23 Apr 2010) $
23 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner
24 //
25 // Standard streambuf implementation following Nicolai Josuttis, "The
26 // Standard C++ Library".
27 // ============================================================================
28 
30 
31 #if OSSIM_HAS_LIBZ
32 #include <zlib.h>
33 
34 #include <iostream>
35 #include <fstream>
36 #include <cstring> // for memcpy
37 
38 
39 // --------------------------------------
40 // class ossimGzStreamBuf:
41 // --------------------------------------
42 
43 
44 struct ossimGzStreamBuf::PrivateData
45 {
46  gzFile file; // file handle for compressed file
47 };
48 // ----------------------------------------------------------------------------
49 // Internal classes to implement gzstream. See header file for user classes.
50 // ----------------------------------------------------------------------------
51 ossimGzStreamBuf::ossimGzStreamBuf()
52  : prvtData(new PrivateData()),
53  opened(false),
54  mode(0) // ??? (drb)
55 {
56 
57  setp( buffer, buffer + (bufferSize-1));
58  setg( buffer + 4, // beginning of putback area
59  buffer + 4, // read position
60  buffer + 4); // end position
61  // ASSERT: both input & output capabilities will not be used together
62 }
63 
64 ossimGzStreamBuf::~ossimGzStreamBuf()
65 {
66  close();
67  if(prvtData)
68  {
69  delete prvtData;
70  prvtData = 0;
71  }
72 }
73 
74 bool ossimGzStreamBuf::is_open() const
75 {
76  return opened;
77 }
78 
79 ossimGzStreamBuf* ossimGzStreamBuf::open( const char* name, int open_mode)
80 {
81  if ( is_open())
82  {
83  return (ossimGzStreamBuf*)0;
84  }
85  mode = open_mode;
86  // no append nor read/write mode
87  if ((mode & std::ios::ate) || (mode & std::ios::app)
88  || ((mode & std::ios::in) && (mode & std::ios::out)))
89  {
90  return (ossimGzStreamBuf*)0;
91  }
92 
93  char fmode[10];
94  char* fmodeptr = fmode;
95  if ( mode & std::ios::in)
96  {
97  *fmodeptr++ = 'r';
98  }
99  else if ( mode & std::ios::out)
100  {
101  *fmodeptr++ = 'w';
102  }
103  *fmodeptr++ = 'b';
104  *fmodeptr = '\0';
105  prvtData->file = gzopen( name, fmode);
106  if (prvtData->file == 0)
107  {
108  return (ossimGzStreamBuf*)0;
109  }
110  opened = true;
111  return this;
112 }
113 
114 ossimGzStreamBuf * ossimGzStreamBuf::close()
115 {
116  if ( is_open())
117  {
118  sync();
119  opened = false;
120  if ( gzclose( prvtData->file) == Z_OK)
121  {
122  return this;
123  }
124  }
125  return (ossimGzStreamBuf*)0;
126 }
127 
128 std::streamsize ossimGzStreamBuf::xsgetn(char_type* __s,
129  std::streamsize n)
130 {
131  int num = gzread( prvtData->file, __s, n);
132 
133  if (num <= 0) // ERROR or EOF
134  return EOF;
135 
136  return num;
137 }
138 
139 int ossimGzStreamBuf::underflow()
140 {
141  // used for input buffer only
142  if ( gptr() && ( gptr() < egptr()))
143  return * reinterpret_cast<unsigned char *>( gptr());
144 
145  if ( ! (mode & std::ios::in) || ! opened)
146  return EOF;
147  // Josuttis' implementation of inbuf
148  int n_putback = gptr() - eback();
149  if ( n_putback > 4)
150  n_putback = 4;
151  memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
152 
153  int num = gzread( prvtData->file, buffer+4, bufferSize-4);
154  if (num <= 0) // ERROR or EOF
155  return EOF;
156 
157  // reset buffer pointers
158  setg( buffer + (4 - n_putback), // beginning of putback area
159  buffer + 4, // read position
160  buffer + 4 + num); // end of buffer
161 
162  // return next character
163  return * reinterpret_cast<unsigned char *>( gptr());
164 }
165 
166 int ossimGzStreamBuf::flush_buffer()
167 {
168  // Separate the writing of the buffer from overflow() and
169  // sync() operation.
170  int w = pptr() - pbase();
171  if ( gzwrite( prvtData->file, pbase(), w) != w)
172  return EOF;
173  pbump( -w);
174  return w;
175 }
176 
177 int ossimGzStreamBuf::overflow( int c) { // used for output buffer only
178  if ( ! ( mode & std::ios::out) || ! opened)
179  return EOF;
180  if (c != EOF) {
181  *pptr() = c;
182  pbump(1);
183  }
184  if ( flush_buffer() == EOF)
185  return EOF;
186  return c;
187 }
188 
189 int ossimGzStreamBuf::sync() {
190  // Changed to use flush_buffer() instead of overflow( EOF)
191  // which caused improper behavior with std::endl and flush(),
192  // bug reported by Vincent Ricard.
193  if ( pptr() && pptr() > pbase()) {
194  if ( flush_buffer() == EOF)
195  return -1;
196  }
197  return 0;
198 }
199 
200 ossimGzStreamBuf::pos_type ossimGzStreamBuf::seekoff(off_type t,
201  std::ios_base::seekdir dir,
202  std::ios_base::openmode /* omode */)
203 {
204  int whence = 0;
205  switch(dir)
206  {
207  case std::ios::beg:
208  {
209  whence = SEEK_SET;
210  break;
211  }
212  case std::ios::end:
213  {
214  whence = SEEK_END;
215  break;
216  }
217  case std::ios::cur:
218  {
219  whence = SEEK_CUR;
220  break;
221  }
222  default:
223  {
224  whence = SEEK_CUR;
225  break;
226  }
227  }
228 
229  return gzseek(prvtData->file, t, whence);
230 }
231 
232 // ossimGzStreamBuf::pos_type ossimGzStreamBuf::seekpos(pos_type posType,
233 // std::ios_base::openmode)
234 // {
235 // int whence = 0;
236 // switch(posType)
237 // {
238 // case std::ios::beg:
239 // {
240 // whence = SEEK_SET;
241 // break;
242 // }
243 // case std::ios::end:
244 // {
245 // whence = SEEK_END;
246 // break;
247 // }
248 // case std::ios::cur:
249 // {
250 // whence = SEEK_CUR;
251 // break;
252 // }
253 // default:
254 // {
255 // whence = SEEK_CUR;
256 // break;
257 // }
258 // }
259 
260 // return gzseek(file, t, whence);
261 // }
262 
263 // --------------------------------------
264 // class ossimGzStreamBase:
265 // --------------------------------------
266 
267 
268 ossimIgzStream::ossimIgzStream()
269  : ossimIFStream()
270 {
271  init(&buf);
272 }
273 
274 ossimIgzStream::ossimIgzStream( const char* name,
275  std::ios_base::openmode mode )
276  : ossimIFStream()
277 {
278  init(&buf);
279  open(name, mode);
280 }
281 
282 ossimIgzStream::~ossimIgzStream()
283 {
284  buf.close();
285 }
286 
287 ossimGzStreamBuf* ossimIgzStream::rdbuf()
288 {
289  return &buf;
290 }
291 
292 void ossimIgzStream::open( const char* name,
293  std::ios_base::openmode mode )
294 {
295  if ( ! buf.open( name, mode))
296  {
297  clear( rdstate() | std::ios::badbit);
298  }
299 }
300 
301 void ossimIgzStream::close()
302 {
303  if ( buf.is_open())
304  {
305  if ( !buf.close())
306  {
307  clear( rdstate() | std::ios::badbit);
308  }
309  }
310 }
311 
312 bool ossimIgzStream::is_open()const
313 {
314  return buf.is_open();
315 }
316 
317 bool ossimIgzStream::isCompressed()const
318 {
319  return true;
320 }
321 
322 ossimOgzStream::ossimOgzStream()
323  : ossimOFStream()
324 {
325  init(&buf);
326 }
327 
328 ossimOgzStream::ossimOgzStream( const char* /* name */,
329  std::ios_base::openmode /* mode */)
330  : ossimOFStream()
331 {
332  init(&buf);
333 }
334 
335 ossimOgzStream::~ossimOgzStream()
336 {
337  buf.close();
338 }
339 
340 ossimGzStreamBuf* ossimOgzStream::rdbuf()
341 {
342  return &buf;
343 }
344 
345 void ossimOgzStream::open( const char* name,
346  std::ios_base::openmode mode )
347 {
348  if ( ! buf.open( name, mode))
349  {
350  clear( rdstate() | std::ios::badbit);
351  }
352 }
353 
354 void ossimOgzStream::close()
355 {
356  if ( buf.is_open())
357  {
358  if ( !buf.close())
359  {
360  clear( rdstate() | std::ios::badbit);
361  }
362  }
363 }
364 
365 bool ossimOgzStream::is_open()const
366 {
367  return buf.is_open();
368 }
369 
370 bool ossimOgzStream::isCompressed()const
371 {
372  return true;
373 }
374 
375 // ============================================================================
376 // EOF //
377 #endif // OSSIM_HAS_LIBZ
os2<< "> n<< " > nendobj n