zipoutputstreambuf.cpp
Go to the documentation of this file.
#include <time.h>
#include "zipios++/zipios-config.h"
#include <algorithm>
#include "zipios++/meta-iostreams.h"
#include <zlib.h>
#include "zipios++/zipoutputstreambuf.h"
namespace zipios {
using std::ios ;
using std::cerr ;
using std::endl ;
//using std::min ;
ZipOutputStreambuf::ZipOutputStreambuf( streambuf *outbuf, bool del_outbuf )
: DeflateOutputStreambuf( outbuf, false, del_outbuf ),
_open_entry( false ),
_open ( true ),
_method ( DEFLATED ),
_level ( 6 )
{
}
void ZipOutputStreambuf::closeEntry() {
if ( ! _open_entry )
return ;
closeStream() ;
updateEntryHeaderInfo() ;
setEntryClosedState( ) ;
}
void ZipOutputStreambuf::close() {
finish() ;
}
void ZipOutputStreambuf::finish() {
if( ! _open )
return ;
closeEntry() ;
ostream os( _outbuf ) ;
writeCentralDirectory( _entries, EndOfCentralDirectory( _zip_comment), os ) ;
_open = false ;
}
ZipOutputStreambuf::~ZipOutputStreambuf() {
finish() ;
}
void ZipOutputStreambuf::putNextEntry( const ZipCDirEntry &entry ) {
if ( _open_entry )
closeEntry() ;
if ( ! init( _level ) )
cerr << "ZipOutputStreambuf::putNextEntry(): init() failed!\n" ;
_entries.push_back( entry ) ;
ZipCDirEntry &ent = _entries.back() ;
ostream os( _outbuf ) ;
// Update entry header info
ent.setLocalHeaderOffset( os.tellp() ) ;
ent.setMethod( _method ) ;
os << static_cast< ZipLocalEntry >( ent ) ;
_open_entry = true ;
}
void ZipOutputStreambuf::setComment( const string &comment ) {
_zip_comment = comment ;
}
void ZipOutputStreambuf::setLevel( int level ) {
_level = level ;
}
void ZipOutputStreambuf::setMethod( StorageMethod method ) {
_method = method ;
if( method == STORED )
setLevel( NO_COMPRESSION ) ;
else if ( method == DEFLATED ) {
if( _level == NO_COMPRESSION )
setLevel( DEFAULT_COMPRESSION ) ;
} else
throw FCollException( "Specified compression method not supported" ) ;
}
//
// Protected and private methods
//
int ZipOutputStreambuf::overflow( int c ) {
return DeflateOutputStreambuf::overflow( c ) ;
// // FIXME: implement
// cout << "ZipOutputStreambuf::overflow() not implemented yet!\n" ;
// return EOF ;
}
int ZipOutputStreambuf::sync() {
return DeflateOutputStreambuf::sync() ;
// // FIXME: implement
// cout << "ZipOutputStreambuf::sync() not implemented yet!\n" ;
// return EOF ;
}
void ZipOutputStreambuf::setEntryClosedState() {
_open_entry = false ;
// FIXME: update put pointers to trigger overflow on write. overflow
// should then return EOF while _open_entry is false.
}
void ZipOutputStreambuf::updateEntryHeaderInfo() {
if ( ! _open_entry )
return ;
ostream os( _outbuf ) ;
int curr_pos = os.tellp() ;
// update fields in _entries.back()
ZipCDirEntry &entry = _entries.back() ;
entry.setSize( getCount() ) ;
entry.setCrc( getCrc32() ) ;
entry.setCompressedSize( curr_pos - entry.getLocalHeaderOffset()
- entry.getLocalHeaderSize() ) ;
// Mark Donszelmann: added current date and time
time_t ltime;
time( &ltime );
struct tm *now;
now = localtime( &ltime );
int dosTime = (now->tm_year - 80) << 25 | (now->tm_mon + 1) << 21 | now->tm_mday << 16 |
now->tm_hour << 11 | now->tm_min << 5 | now->tm_sec >> 1;
entry.setTime(dosTime);
// write ZipLocalEntry header to header position
os.seekp( entry.getLocalHeaderOffset() ) ;
os << static_cast< ZipLocalEntry >( entry ) ;
os.seekp( curr_pos ) ;
}
void ZipOutputStreambuf::writeCentralDirectory( const vector< ZipCDirEntry > &entries,
EndOfCentralDirectory eocd,
ostream &os ) {
int cdir_start = os.tellp() ;
std::vector< ZipCDirEntry >::const_iterator it ;
int cdir_size = 0 ;
for ( it = entries.begin() ; it != entries.end() ; ++it ) {
os << *it ;
cdir_size += it->getCDirHeaderSize() ;
}
eocd.setOffset( cdir_start ) ;
eocd.setCDirSize( cdir_size ) ;
eocd.setTotalCount( entries.size() ) ;
os << eocd ;
}
} // namespace
/*
Zipios++ - a small C++ library that provides easy access to .zip files.
Copyright (C) 2000 Thomas Søndergaard
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
zipios::DeflateOutputStreambuf::getCrc32
uint32 getCrc32() const
Returns the CRC32 for the current stream.
Definition deflateoutputstreambuf.h:49
zipios::DeflateOutputStreambuf::DeflateOutputStreambuf
DeflateOutputStreambuf(streambuf *outbuf, bool user_init=false, bool del_outbuf=false)
DeflateOutputStreambuf constructor.
Definition deflateoutputstreambuf.cpp:18
zipios::DeflateOutputStreambuf::getCount
uint32 getCount() const
Returns the number of bytes written to the streambuf, that has been processed from the input buffer b...
Definition deflateoutputstreambuf.h:55
zipios::EndOfCentralDirectory
The end of the Central directory structure.
Definition ziphead.h:159
zipios::FCollException
An FCollException is used to signal a problem with a FileCollection.
Definition fcollexceptions.h:31
zipios::ZipCDirEntry
Specialization of ZipLocalEntry, that add fields for storing the extra information,...
Definition ziphead.h:102
zipios::ZipLocalEntry::setMethod
virtual void setMethod(StorageMethod method)
Sets the storage method field for the entry.
Definition ziphead.cpp:135
zipios::ZipOutputStreambuf::ZipOutputStreambuf
ZipOutputStreambuf(streambuf *outbuf, bool del_outbuf=false)
ZipOutputStreambuf constructor.
Definition zipoutputstreambuf.cpp:20
zipios::ZipOutputStreambuf::setMethod
void setMethod(StorageMethod method)
Sets the compression method to be used.
Definition zipoutputstreambuf.cpp:93
zipios::ZipOutputStreambuf::~ZipOutputStreambuf
virtual ~ZipOutputStreambuf()
Destructor.
Definition zipoutputstreambuf.cpp:56
zipios::ZipOutputStreambuf::close
void close()
Calls finish.
Definition zipoutputstreambuf.cpp:41
zipios::ZipOutputStreambuf::closeEntry
void closeEntry()
Closes the current entry, and positions the stream read pointer at the beginning of the next entry (i...
Definition zipoutputstreambuf.cpp:30
zipios::ZipOutputStreambuf::setLevel
void setLevel(int level)
Sets the compression level to be used for subsequent entries.
Definition zipoutputstreambuf.cpp:88
zipios::ZipOutputStreambuf::finish
void finish()
Closes the current entry (if one is open), then writes the Zip Central Directory Structure closing th...
Definition zipoutputstreambuf.cpp:46
zipios::ZipOutputStreambuf::putNextEntry
void putNextEntry(const ZipCDirEntry &entry)
Begins writing the next entry.
Definition zipoutputstreambuf.cpp:61
zipios::ZipOutputStreambuf::setComment
void setComment(const string &comment)
Sets the global comment for the Zip archive.
Definition zipoutputstreambuf.cpp:83
zipios::StorageMethod
StorageMethod
The types used with FileEntry::setMethod and FileEntry::getMethod.
Definition fileentry.h:25
zipoutputstreambuf.h
Header file that defines ZipOutputStreambuf.