Zipios++
zipoutputstreambuf.cpp
Go to the documentation of this file.
1
2#include <time.h>
3
4#include "zipios++/zipios-config.h"
5
6#include <algorithm>
7#include "zipios++/meta-iostreams.h"
8
9#include <zlib.h>
10
12
13namespace zipios {
14
15using std::ios ;
16using std::cerr ;
17using std::endl ;
18//using std::min ;
19
20ZipOutputStreambuf::ZipOutputStreambuf( streambuf *outbuf, bool del_outbuf )
21 : DeflateOutputStreambuf( outbuf, false, del_outbuf ),
22 _open_entry( false ),
23 _open ( true ),
24 _method ( DEFLATED ),
25 _level ( 6 )
26{
27}
28
29
31 if ( ! _open_entry )
32 return ;
33
34 closeStream() ;
35
36 updateEntryHeaderInfo() ;
37 setEntryClosedState( ) ;
38}
39
40
44
45
47 if( ! _open )
48 return ;
49 closeEntry() ;
50 ostream os( _outbuf ) ;
51 writeCentralDirectory( _entries, EndOfCentralDirectory( _zip_comment), os ) ;
52 _open = false ;
53}
54
55
59
60
62 if ( _open_entry )
63 closeEntry() ;
64
65 if ( ! init( _level ) )
66 cerr << "ZipOutputStreambuf::putNextEntry(): init() failed!\n" ;
67
68 _entries.push_back( entry ) ;
69 ZipCDirEntry &ent = _entries.back() ;
70
71 ostream os( _outbuf ) ;
72
73 // Update entry header info
74 ent.setLocalHeaderOffset( os.tellp() ) ;
75 ent.setMethod( _method ) ;
76
77 os << static_cast< ZipLocalEntry >( ent ) ;
78
79 _open_entry = true ;
80}
81
82
83void ZipOutputStreambuf::setComment( const string &comment ) {
84 _zip_comment = comment ;
85}
86
87
89 _level = level ;
90}
91
92
94 _method = method ;
95 if( method == STORED )
96 setLevel( NO_COMPRESSION ) ;
97 else if ( method == DEFLATED ) {
98 if( _level == NO_COMPRESSION )
99 setLevel( DEFAULT_COMPRESSION ) ;
100 } else
101 throw FCollException( "Specified compression method not supported" ) ;
102}
103
104//
105// Protected and private methods
106//
107
108int ZipOutputStreambuf::overflow( int c ) {
109 return DeflateOutputStreambuf::overflow( c ) ;
110// // FIXME: implement
111
112// cout << "ZipOutputStreambuf::overflow() not implemented yet!\n" ;
113// return EOF ;
114}
115
116
117
118int ZipOutputStreambuf::sync() {
119 return DeflateOutputStreambuf::sync() ;
120// // FIXME: implement
121// cout << "ZipOutputStreambuf::sync() not implemented yet!\n" ;
122// return EOF ;
123}
124
125
126
127void ZipOutputStreambuf::setEntryClosedState() {
128 _open_entry = false ;
129 // FIXME: update put pointers to trigger overflow on write. overflow
130 // should then return EOF while _open_entry is false.
131}
132
133
134void ZipOutputStreambuf::updateEntryHeaderInfo() {
135 if ( ! _open_entry )
136 return ;
137
138 ostream os( _outbuf ) ;
139 int curr_pos = os.tellp() ;
140
141 // update fields in _entries.back()
142 ZipCDirEntry &entry = _entries.back() ;
143 entry.setSize( getCount() ) ;
144 entry.setCrc( getCrc32() ) ;
145 entry.setCompressedSize( curr_pos - entry.getLocalHeaderOffset()
146 - entry.getLocalHeaderSize() ) ;
147
148 // Mark Donszelmann: added current date and time
149 time_t ltime;
150 time( &ltime );
151 struct tm *now;
152 now = localtime( &ltime );
153 int dosTime = (now->tm_year - 80) << 25 | (now->tm_mon + 1) << 21 | now->tm_mday << 16 |
154 now->tm_hour << 11 | now->tm_min << 5 | now->tm_sec >> 1;
155 entry.setTime(dosTime);
156
157 // write ZipLocalEntry header to header position
158 os.seekp( entry.getLocalHeaderOffset() ) ;
159 os << static_cast< ZipLocalEntry >( entry ) ;
160 os.seekp( curr_pos ) ;
161}
162
163
164void ZipOutputStreambuf::writeCentralDirectory( const vector< ZipCDirEntry > &entries,
165 EndOfCentralDirectory eocd,
166 ostream &os ) {
167 int cdir_start = os.tellp() ;
168 std::vector< ZipCDirEntry >::const_iterator it ;
169 int cdir_size = 0 ;
170
171 for ( it = entries.begin() ; it != entries.end() ; ++it ) {
172 os << *it ;
173 cdir_size += it->getCDirHeaderSize() ;
174 }
175 eocd.setOffset( cdir_start ) ;
176 eocd.setCDirSize( cdir_size ) ;
177 eocd.setTotalCount( entries.size() ) ;
178 os << eocd ;
179}
180
181} // namespace
182
187/*
188 Zipios++ - a small C++ library that provides easy access to .zip files.
189 Copyright (C) 2000 Thomas Søndergaard
190
191 This library is free software; you can redistribute it and/or
192 modify it under the terms of the GNU Lesser General Public
193 License as published by the Free Software Foundation; either
194 version 2 of the License, or (at your option) any later version.
195
196 This library is distributed in the hope that it will be useful,
197 but WITHOUT ANY WARRANTY; without even the implied warranty of
198 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
199 Lesser General Public License for more details.
200
201 You should have received a copy of the GNU Lesser General Public
202 License along with this library; if not, write to the Free Software
203 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
204*/
DeflateOutputStreambuf is an output stream filter, that deflates the data that is written to it befor...
uint32 getCrc32() const
Returns the CRC32 for the current stream.
uint32 getCount() const
Returns the number of bytes written to the streambuf, that has been processed from the input buffer b...
The end of the Central directory structure.
Definition ziphead.h:159
An FCollException is used to signal a problem with a FileCollection.
Specialization of ZipLocalEntry, that add fields for storing the extra information,...
Definition ziphead.h:102
virtual void setMethod(StorageMethod method)
Sets the storage method field for the entry.
Definition ziphead.cpp:135
ZipOutputStreambuf(streambuf *outbuf, bool del_outbuf=false)
ZipOutputStreambuf constructor.
void setMethod(StorageMethod method)
Sets the compression method to be used.
virtual ~ZipOutputStreambuf()
Destructor.
void closeEntry()
Closes the current entry, and positions the stream read pointer at the beginning of the next entry (i...
void setLevel(int level)
Sets the compression level to be used for subsequent entries.
void finish()
Closes the current entry (if one is open), then writes the Zip Central Directory Structure closing th...
void putNextEntry(const ZipCDirEntry &entry)
Begins writing the next entry.
void setComment(const string &comment)
Sets the global comment for the Zip archive.
StorageMethod
The types used with FileEntry::setMethod and FileEntry::getMethod.
Definition fileentry.h:25
Header file that defines ZipOutputStreambuf.