PDA

View Full Version : Problem creating zip archive with QtIOCompressor



TorAn
12th November 2010, 17:54
Recently I asked the question about creating an archive file with QtIOCompressor solution.
(original thread) (http://www.qtcentre.org/threads/35881-How-to-archieve-files-with-QtIOCompressor?highlight=qtiocompressor)

Now I am trying to create a "missing link", i.e create a rudimentary archieve using iocompressor that matches the "ziplist" example in this solution. Example in the solution accepts an existing zip file and uncompresses it. What attracted me to this example is that I fed it with the "standard" zip file and it successfully read it. So, I decided to take the "uncompress" logic from the example and reverse it to create the archive. Results are verified with the example. The code fragment follows:


void createArchive()
{
QFile archive(_path);
archive.open(QIODevice::WriteOnly);
QDataStream st (&archive);
st.setByteOrder(QDataStream::LittleEndian);

QDateTime dt = QDateTime::currentDateTime();
quint32 tdstamp = dt.toTime_t ();

for (std::vector<std::string>::iterator it = _files.begin(); it != _files.end(); ++it)
{
quint32 signature, crc, compSize, unCompSize;
quint16 extractVersion, bitFlag, compMethod, modTime, modDate;
quint16 nameLen, extraLen;

signature = 0x04034b50;
extractVersion = 20;
bitFlag = 2;
compMethod = 8;
extraLen = 0;
modTime = 23818;
modDate = 15248;

QString itfpath (it->c_str());
QFileInfo finfo(it->c_str());
QString fname = finfo.fileName();

QFile curfile(itfpath);
if (! curfile.open(QIODevice::ReadOnly))
return;
QByteArray curba = curfile.readAll();
curfile.close();

unCompSize = curba.length();
crc = qChecksum(curba, unCompSize);
QByteArray compressedFile;
QBuffer buffer(&compressedFile);
QtIOCompressor qtcmp(&buffer);
qtcmp.setStreamFormat(QtIOCompressor::RawZipFormat );
qtcmp.open(QIODevice::WriteOnly);
// compress file into the buffer
qtcmp.write(curba);
compSize = compressedFile.length();
nameLen = fname.length();

// uncompressed logic taken from the example in the solution
// st >> extractVersion >> bitFlag >> compMethod;
// s >> modTime >> modDate >> crc >> compSize >> unCompSize;
// s >> nameLen >> extraLen;
st << signature << extractVersion << bitFlag << compMethod << modTime << modDate;
st << /*tdstamp <<*/ crc << compSize << unCompSize << nameLen << extraLen;

st.writeRawData(fname.toAscii(), nameLen);
st.writeRawData(compressedFile, compSize);
}
archive.flush();
archive.close();
}

the problem with the code, as far as I can tell, is this: when writing the compressed part into the output datastream the returned value of "compressed" stream does not match the lengh of the subsequent uncompress when I run the subsequent uncompress in the example.

I will appreciate any help/advise to make it work. Thanks.