mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
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:
parent
0db1b4237b
commit
e953bcbd18
6 changed files with 73 additions and 25 deletions
|
|
@ -45,7 +45,7 @@ void Crc32Stream::Out(const void *ptr, dword count)
|
|||
crc = crc32(crc, (byte *)ptr, count);
|
||||
}
|
||||
|
||||
Crc32Stream::Crc32Stream()
|
||||
void Crc32Stream::Clear()
|
||||
{
|
||||
crc = crc32(0, NULL, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ class Crc32Stream : public OutStream {
|
|||
public:
|
||||
dword Finish() { Flush(); return crc; }
|
||||
operator dword() { return Finish(); }
|
||||
void Clear();
|
||||
|
||||
Crc32Stream();
|
||||
Crc32Stream() { Clear(); }
|
||||
};
|
||||
|
||||
dword CRC32(const void *ptr, dword count);
|
||||
|
|
@ -63,7 +64,7 @@ public:
|
|||
String GetGZipName() const { return gzip_name; }
|
||||
String GetGZipComment() const { return gzip_comment; }
|
||||
|
||||
Zlib& GZip(bool gzip_ = true) { gzip = gzip_; return *this; }
|
||||
Zlib& GZip(bool gzip_ = true) { gzip = gzip_; return *this; }
|
||||
Zlib& Header(bool hdr_ = true) { hdr = hdr_; return *this; }
|
||||
Zlib& NoHeader() { return Header(false); }
|
||||
Zlib& CRC(bool b = true) { docrc = b; return *this; }
|
||||
|
|
|
|||
9
uppsrc/plugin/z/build_info.h
Normal file
9
uppsrc/plugin/z/build_info.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#define bmYEAR 2016
|
||||
#define bmMONTH 2
|
||||
#define bmDAY 6
|
||||
#define bmHOUR 23
|
||||
#define bmMINUTE 2
|
||||
#define bmSECOND 31
|
||||
#define bmTIME Time(2016, 2, 6, 23, 2, 31)
|
||||
#define bmMACHINE "MAIN"
|
||||
#define bmUSER "cxl"
|
||||
|
|
@ -29,7 +29,7 @@ void UnZip::ReadDir()
|
|||
offset = zip->Get32le(); //offset of start of central directory with respect to the starting disk number
|
||||
int commentlen = zip->Get16le();
|
||||
if(zip->GetPos() + commentlen == zipsize)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
pos--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ class Zip {
|
|||
dword done;
|
||||
|
||||
One<Zlib> pipeZLib;
|
||||
Crc32Stream crc32; // for uncompressed files
|
||||
bool uncompressed;
|
||||
|
||||
void WriteFile0(const void *ptr, int size, const char *path, Gate2<int, int> progress, Time tm, int method);
|
||||
|
||||
|
|
@ -117,15 +119,15 @@ class Zip {
|
|||
public:
|
||||
Callback WhenError;
|
||||
|
||||
void BeginFile(const char *path, Time tm = GetSysTime());
|
||||
void BeginFile(OutFilterStream& oz, const char *path, Time tm = GetSysTime());
|
||||
void BeginFile(const char *path, Time tm = GetSysTime(), bool deflate = true);
|
||||
void BeginFile(OutFilterStream& oz, const char *path, Time tm = GetSysTime(), bool deflate = true);
|
||||
void Put(const void *data, int size);
|
||||
void EndFile();
|
||||
bool IsFileOpened() const { return pipeZLib; }
|
||||
bool IsFileOpened() const { return pipeZLib || uncompressed; }
|
||||
|
||||
void WriteFolder(const char *path, Time tm);
|
||||
void WriteFile(const void *ptr, int size, const char *path, Gate2<int, int> progress = false, Time tm = GetSysTime());
|
||||
void WriteFile(const String& s, const char *path, Gate2<int, int> progress = false, Time tm = GetSysTime());
|
||||
void WriteFile(const void *ptr, int size, const char *path, Gate2<int, int> progress = false, Time tm = GetSysTime(), bool deflate = true);
|
||||
void WriteFile(const String& s, const char *path, Gate2<int, int> progress = false, Time tm = GetSysTime(), bool deflate = true);
|
||||
|
||||
void Create(Stream& out);
|
||||
void Finish();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue