ZipOutputStreamBuffer.cc

Go to the documentation of this file.
00001 // Copyright FreeHEP, 2005.
00002 
00003 #include <iostream>
00004 #include <ctime>
00005 #include <vector>
00006 
00007 #include "cheprep/ZipOutputStream.h"
00008 #include "cheprep/ZipOutputStreamBuffer.h"
00009 #include "cheprep/ZipEntry.h"
00010 
00015 namespace cheprep {
00016 
00017     ZipOutputStreamBuffer::ZipOutputStreamBuffer(std::streambuf* aBuffer)
00018         : DeflateOutputStreamBuffer(aBuffer), 
00019           comment("") {
00020         
00021         closed = false;
00022         entry = NULL;
00023         
00024         entries = new std::vector<ZipEntry*>();
00025     }
00026 
00027     int ZipOutputStreamBuffer::overflow(int c) {
00028         return DeflateOutputStreamBuffer::overflow(c);
00029     }
00030             
00031     void ZipOutputStreamBuffer::closeEntry() {
00032         if (closed) return;
00033         if (entry == NULL) return;
00034         
00035         finish();
00036                 
00037         entry->crc = getCRC();
00038         // NOTE: pos()::operator- is ambiguous on gcc 4.0, so convert to long first
00039         entry->csize = (long)pos() - entry->data;
00040         entry->size = getSize();
00041         putUI(EXTSIG);
00042         putUI(entry->crc);            // crc
00043         putUI(entry->csize);          // compressed size
00044         putUI(entry->size);           // uncompressed size
00045         entry = NULL;
00046     }
00047 
00048 
00049     void ZipOutputStreamBuffer::close() {
00050         if (closed) return;
00051         closeEntry();
00052         
00053         long dirStart = pos();
00054         for (std::vector<ZipEntry*>::iterator i=entries->begin(); i != entries->end(); i++) {
00055             entry = *i;
00056             putUI(CENSIG);
00057             putUS(VERSIONMADE);                   // made by version
00058             putUS(VERSIONEXTRACT);                // extraction version
00059             putUS(GENFLAG);                       // general purpose bit flag
00060             putUS(entry->method);                 // compression method
00061             putUS(entry->time);                   // time
00062             putUS(entry->date);                   // date
00063             putUI(entry->crc);                    // crc
00064             putUI(entry->csize);                  // compressed size
00065             putUI(entry->size);                   // uncompressed size
00066             putUS(entry->name.length());          // file name length
00067             putUS(0);                             // extra field length
00068             putUS(0);                             // file comment length
00069             putUS(0);                             // disk number start
00070             putUS(0);                             // internal file attributes
00071             putUI(0);                             // external file attributes
00072             putUI(entry->offset);                 // relative offset of local file header
00073             putS(entry->name);                    // file name
00074             
00075             // delete entry
00076             delete entry;
00077             entry = NULL;
00078         }
00079         // NOTE: pos()::operator- is ambiguous on gcc 4.0, so convert to long first
00080         long dirSize = (long)pos() - dirStart;
00081         putUI(ENDSIG);
00082         putUS(0);                             // number of this disk
00083         putUS(0);                             // number of the disk with the start of central directory
00084         putUS(entries->size());               // total number of entries in the central directory of this disk
00085         putUS(entries->size());               // total number of entries in the central directory
00086         putUI(dirSize);                       // size of the central directory
00087         putUI(dirStart);                      // offset of the start of central directory with respect to the starting disk number
00088         putUS(comment.length());              // .ZIP file comment length
00089         putS(comment);                        // .ZIP file comment
00090         
00091         delete entries;
00092         entries = NULL;
00093         closed = true;
00094     }
00095 
00096     void ZipOutputStreamBuffer::putNextEntry(const std::string& name, bool compress) {
00097         if (closed) return;
00098         
00099         closeEntry();
00100 
00101 #ifdef CHEPREP_NO_ZLIB
00102         compress = false;
00103 #endif
00104         init(compress);
00105 
00106         entry = new ZipEntry();
00107         entries->push_back(entry);
00108         
00109         entry->name = name;
00110         entry->method = compress ? 8 : 0;
00111         
00112         time_t ltime;
00113         time( &ltime );
00114         struct tm *utc = gmtime( &ltime );
00115         entry->date = (utc->tm_year - 80) << 9 | (utc->tm_mon + 1) << 5 | utc->tm_mday;
00116         entry->time = utc->tm_hour << 11 | utc->tm_min << 5 | utc->tm_sec >> 1;
00117 
00118         entry->offset = (long)pos();
00119         putUI(LOCSIG);                        // signature
00120         putUS(VERSIONEXTRACT);                // extraction version
00121         putUS(GENFLAG);                       // general purpose bit flag
00122         putUS(entry->method);                 // compression method
00123         putUS(entry->time);                   // time
00124         putUS(entry->date);                   // date
00125         putUI(0x00000000);                    // crc ATEND
00126         putUI(0x00000000);                    // compressed size ATEND
00127         putUI(0x00000000);                    // uncompressed size ATEND
00128         putUS(entry->name.length());          // file name length
00129         putUS(0);                             // extra field length
00130         putS(entry->name);                    // file name
00131         entry->data = (long)pos();
00132         entry->crc = 0;
00133     }
00134             
00135     void ZipOutputStreamBuffer::setComment(const std::string& c) {
00136         if (closed) return;
00137         comment = c;        
00138     }
00139 
00140     ZipOutputStreamBuffer::~ZipOutputStreamBuffer() {
00141         close();
00142     }
00143 
00144 } // cheprep

Generated on Mon May 27 17:50:37 2013 for Geant4 by  doxygen 1.4.7