00001
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
00039 entry->csize = (long)pos() - entry->data;
00040 entry->size = getSize();
00041 putUI(EXTSIG);
00042 putUI(entry->crc);
00043 putUI(entry->csize);
00044 putUI(entry->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);
00058 putUS(VERSIONEXTRACT);
00059 putUS(GENFLAG);
00060 putUS(entry->method);
00061 putUS(entry->time);
00062 putUS(entry->date);
00063 putUI(entry->crc);
00064 putUI(entry->csize);
00065 putUI(entry->size);
00066 putUS(entry->name.length());
00067 putUS(0);
00068 putUS(0);
00069 putUS(0);
00070 putUS(0);
00071 putUI(0);
00072 putUI(entry->offset);
00073 putS(entry->name);
00074
00075
00076 delete entry;
00077 entry = NULL;
00078 }
00079
00080 long dirSize = (long)pos() - dirStart;
00081 putUI(ENDSIG);
00082 putUS(0);
00083 putUS(0);
00084 putUS(entries->size());
00085 putUS(entries->size());
00086 putUI(dirSize);
00087 putUI(dirStart);
00088 putUS(comment.length());
00089 putS(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( <ime );
00114 struct tm *utc = gmtime( <ime );
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);
00120 putUS(VERSIONEXTRACT);
00121 putUS(GENFLAG);
00122 putUS(entry->method);
00123 putUS(entry->time);
00124 putUS(entry->date);
00125 putUI(0x00000000);
00126 putUI(0x00000000);
00127 putUI(0x00000000);
00128 putUS(entry->name.length());
00129 putUS(0);
00130 putS(entry->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 }