Zipios++
zipinputstreambuf.cpp
Go to the documentation of this file.
1 
2 #include "zipios++/zipios-config.h"
3 
4 #include <algorithm>
5 #include "zipios++/meta-iostreams.h"
6 
7 #include <zlib.h>
8 
10 #include "zipios_common.h"
11 
12 namespace zipios {
13 
14 using std::ios ;
15 using std::cerr ;
16 using std::endl ;
17 
18 ZipInputStreambuf::ZipInputStreambuf( streambuf *inbuf, int s_pos, bool del_inbuf )
19  : InflateInputStreambuf( inbuf, s_pos, del_inbuf ),
20  _open_entry( false )
21 {
23 
24  if ( ! entry->isValid() ) {
25  ; // FIXME: throw something?
26  }
27 }
28 
30  if ( ! _open_entry )
31  return ;
32 
33  // check if we're positioned correctly, otherwise position us correctly
34  int position = _inbuf->pubseekoff(0, ios::cur,
35  ios::in);
36  if ( position != _data_start + static_cast< int >( _curr_entry.getCompressedSize() ) )
37  _inbuf->pubseekoff(_data_start + _curr_entry.getCompressedSize(),
38  ios::beg, ios::in) ;
39 
40 }
41 
43 }
44 
46  if ( _open_entry )
47  closeEntry() ;
48 
49  // read the zip local header
50  istream is( _inbuf ) ; // istream does not destroy the streambuf.
51  is.exceptions(istream::eofbit | istream::failbit | istream::badbit);
52  is >> _curr_entry ;
53  if ( _curr_entry.isValid() ) {
54  _data_start = _inbuf->pubseekoff(0, ios::cur,
55  ios::in);
56  if ( _curr_entry.getMethod() == DEFLATED ) {
57  _open_entry = true ;
58  reset() ; // reset inflatestream data structures
59 // cerr << "deflated" << endl ;
60  } else if ( _curr_entry.getMethod() == STORED ) {
61  _open_entry = true ;
62  _remain = _curr_entry.getSize() ;
63  // Force underflow on first read:
64  setg( &( _outvec[ 0 ] ),
65  &( _outvec[ 0 ] ) + _outvecsize,
66  &( _outvec[ 0 ] ) + _outvecsize ) ;
67 // cerr << "stored" << endl ;
68  } else {
69  _open_entry = false ; // Unsupported compression format.
70  throw FCollException( "Unsupported compression format" ) ;
71  }
72  } else {
73  _open_entry = false ;
74  }
75 
76  if ( _curr_entry.isValid() && _curr_entry.trailingDataDescriptor() )
77  throw FCollException( "Trailing data descriptor in zip file not supported" ) ;
78  return new ZipLocalEntry( _curr_entry ) ;
79 }
80 
81 
83 }
84 
85 
86 int ZipInputStreambuf::underflow() {
87  if ( ! _open_entry )
88  return EOF ; // traits_type::eof()
89  if ( _curr_entry.getMethod() == DEFLATED )
90  return InflateInputStreambuf::underflow() ;
91 
92  // Ok, we're are stored, so we handle it ourselves.
93  int num_b = min( _remain, _outvecsize ) ;
94  int g = _inbuf->sgetn( &(_outvec[ 0 ] ) , num_b ) ;
95  setg( &( _outvec[ 0 ] ),
96  &( _outvec[ 0 ] ),
97  &( _outvec[ 0 ] ) + g ) ;
98  _remain -= g ;
99  if ( g > 0 )
100  return static_cast< unsigned char >( *gptr() ) ;
101  else
102  return EOF ; // traits_type::eof()
103 }
104 
105 
106 // FIXME: We need to check somew
107 //
108 // // gp_bitfield bit 3 is one, if the length of the zip entry
109 // // is stored in a trailer.
110 // if ( is->good && ( _curr_entry.gp_bitfield & 4 ) != 1 )
111 // return true ;
112 // else {
113 // is->clear() ;
114 // return false ;
115 // }
116 
117 
118 } // namespace
119 
124 /*
125  Zipios++ - a small C++ library that provides easy access to .zip files.
126  Copyright (C) 2000 Thomas Søndergaard
127 
128  This library is free software; you can redistribute it and/or
129  modify it under the terms of the GNU Lesser General Public
130  License as published by the Free Software Foundation; either
131  version 2 of the License, or (at your option) any later version.
132 
133  This library is distributed in the hope that it will be useful,
134  but WITHOUT ANY WARRANTY; without even the implied warranty of
135  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
136  Lesser General Public License for more details.
137 
138  You should have received a copy of the GNU Lesser General Public
139  License along with this library; if not, write to the Free Software
140  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
141 */