plugin/Zip now supports storing uncompressed files

git-svn-id: svn://ultimatepp.org/upp/trunk@9548 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2016-02-29 17:29:34 +00:00
parent 0db1b4237b
commit e953bcbd18
6 changed files with 73 additions and 25 deletions

View file

@ -36,16 +36,22 @@ void Zip::FileHeader(const char *path, Time tm)
done += 5*2 + 5*4 + f.path.GetCount();
}
void Zip::BeginFile(const char *path, Time tm)
void Zip::BeginFile(const char *path, Time tm, bool deflate)
{
ASSERT(!IsFileOpened());
pipeZLib.Create();
pipeZLib->WhenOut = THISBACK(PutCompressed);
pipeZLib->GZip(false).CRC().NoHeader().Compress();
if(deflate) {
pipeZLib.Create();
pipeZLib->WhenOut = THISBACK(PutCompressed);
pipeZLib->GZip(false).CRC().NoHeader().Compress();
}
else {
crc32.Clear();
uncompressed = true;
}
File& f = file.Add();
f.version = 21;
f.gpflag = 0x8;
f.method = 8;
f.method = deflate ? 8 : 0;
f.crc = 0;
f.csize = 0;
f.usize = 0;
@ -53,9 +59,9 @@ void Zip::BeginFile(const char *path, Time tm)
if (zip->IsError()) WhenError();
}
void Zip::BeginFile(OutFilterStream& oz, const char *path, Time tm)
void Zip::BeginFile(OutFilterStream& oz, const char *path, Time tm, bool deflate)
{
BeginFile(path, tm);
BeginFile(path, tm, deflate);
oz.Filter = THISBACK(Put);
oz.End = THISBACK(EndFile);
}
@ -64,7 +70,12 @@ void Zip::Put(const void *ptr, int size)
{
ASSERT(IsFileOpened());
File& f = file.Top();
pipeZLib->Put(ptr, size);
if(f.method == 0) {
PutCompressed(ptr, size);
crc32.Put(ptr, size);
}
else
pipeZLib->Put(ptr, size);
f.usize += size;
}
@ -74,27 +85,50 @@ void Zip::EndFile()
return;
File& f = file.Top();
ASSERT(f.gpflag & 0x8);
pipeZLib->End();
zip->Put32le(f.crc = pipeZLib->GetCRC());
if(f.method == 0)
zip->Put32le(f.crc = crc32);
else {
pipeZLib->End();
zip->Put32le(f.crc = pipeZLib->GetCRC());
}
zip->Put32le(f.csize);
zip->Put32le(f.usize);
done += 3*4;
pipeZLib.Clear();
if (zip->IsError()) WhenError();
uncompressed = false;
if(zip->IsError()) WhenError();
}
void Zip::PutCompressed(const void *ptr, int size)
{
ASSERT(IsFileOpened());
zip->Put(ptr, size);
if (zip->IsError()) WhenError();
if (zip->IsError()) WhenError();
done += size;
file.Top().csize += size;
}
void Zip::WriteFile(const void *ptr, int size, const char *path, Gate2<int, int> progress, Time tm)
void Zip::WriteFile(const void *ptr, int size, const char *path, Gate2<int, int> progress, Time tm, bool deflate)
{
ASSERT(!IsFileOpened());
if(!deflate) {
BeginFile(path, tm, deflate);
int done = 0;
while(done < size) {
if(progress(done, size))
return;
int chunk = min(size - done, 65536);
Put((byte *)ptr + done, chunk);
if(zip->IsError()) {
WhenError();
return;
}
done += chunk;
}
EndFile();
return;
}
// following code could be implemented using BeginFile/Put/EndFile, but be conservative, keep proven code
File& f = file.Add();
StringStream ss;
MemReadStream ms(ptr, size);
@ -118,12 +152,12 @@ void Zip::WriteFile(const void *ptr, int size, const char *path, Gate2<int, int>
FileHeader(path, tm);
zip->Put(r, f.csize);
done += f.csize;
if (zip->IsError()) WhenError();
if (zip->IsError()) WhenError();
}
void Zip::WriteFile(const String& s, const char *path, Gate2<int, int> progress, Time tm)
void Zip::WriteFile(const String& s, const char *path, Gate2<int, int> progress, Time tm, bool deflate)
{
WriteFile(~s, s.GetCount(), path, progress, tm);
WriteFile(~s, s.GetCount(), path, progress, tm, deflate);
}
void Zip::Create(Stream& out)
@ -177,12 +211,14 @@ Zip::Zip()
{
done = 0;
zip = NULL;
uncompressed = false;
}
Zip::Zip(Stream& out)
{
done = 0;
zip = NULL;
uncompressed = false;
Create(out);
}