ultimatepp/uppsrc/plugin/zip/zip.h
User0755 f7233ea69b
plugin/zip: Zip64 support for UnZip and fixes for Zip (#194)
plugin/zip: zip64 fixes and unzip64 (thanks Tom)
2024-03-24 14:16:39 +01:00

177 lines
4.4 KiB
C++

#ifndef _zip_zip_h
#define _zip_zip_h
#include <Core/Core.h>
namespace Upp {
class UnZip {
struct File : Moveable<File> {
word bit;
String path;
dword time;
int method;
dword crc;
qword csize;
qword usize;
int64 offset;
};
Stream *zip;
bool error;
Vector<File> file;
int current;
void ReadDir();
static Time GetZipTime(dword time);
public:
bool IsEof() const { return current >= file.GetCount(); }
operator bool() const { return !IsEof() && !IsError(); }
bool IsError() const { return error; }
void ClearError() { error = false; }
int GetCount() const { return file.GetCount(); }
String GetPath(int i) const { return file[i].path; }
bool IsFolder(int i) const { return *file[i].path.Last() == '/'; }
bool IsFile(int i) const { return !IsFolder(i); }
int64 GetLength(int i) const { return file[i].usize; }
Time GetTime(int i) const { return GetZipTime(file[i].time); }
void Seek(int i) { ASSERT(i >= 0 && i < file.GetCount()); current = i; }
bool IsFolder() const { return IsFolder(current); }
bool IsFile() const { return !IsFolder(); }
String GetPath() const { return GetPath(current); }
int64 GetLength() const { return GetLength(current); }
Time GetTime() const { return GetTime(current); }
void Skip() { current++; }
void SkipFile() { current++; }
bool ReadFile(Stream& out, Gate<int, int> progress = Null);
String ReadFile(Gate<int, int> progress = Null);
String ReadFile(const char *path, Gate<int, int> progress = Null);
void Create(Stream& in);
void Close() { file.Clear(); zip->Close(); }
UnZip(Stream& in);
UnZip();
virtual ~UnZip();
};
class FileUnZip : public UnZip {
FileIn zip;
public:
bool Create(const char *name);
FileUnZip(const char *name) { Create(name); }
FileUnZip() {}
};
class MemUnZip : public UnZip {
MemReadStream zip;
public:
void Create(const void *ptr, int count);
MemUnZip(const void *ptr, int count) { Create(ptr, count); }
MemUnZip();
};
class StringUnZip : public UnZip {
StringStream zip;
public:
void Create(const String& s);
StringUnZip(const String& s) { Create(s); }
StringUnZip();
};
class Zip {
Stream *zip;
struct File {
String path;
dword time;
int version;
int gpflag;
int method;
bool zip64;
dword crc;
qword csize;
qword usize;
};
Array<File> file;
qword done;
One<Zlib> pipeZLib;
Crc32Stream crc32; // for uncompressed files
bool uncompressed;
void WriteFile0(const void *ptr, int size, const char *path, Gate<int, int> progress, Time tm, int method);
void FileHeader(const char *path, Time tm);
void PutCompressed(const void *data, int size);
typedef Zip CLASSNAME;
public:
Callback WhenError;
void BeginFile(const char *path, Time tm = GetSysTime(), bool deflate = true, bool zip64 = false);
void BeginFile(OutFilterStream& oz, const char *path, Time tm = GetSysTime(), bool deflate = true, bool zip64 = false);
void Put(const void *data, int size);
void Put64(const void *data, int64 size);
void EndFile();
bool IsFileOpened() const { return pipeZLib || uncompressed; }
void WriteFolder(const char *path, Time tm = GetSysTime());
void WriteFile(const void *ptr, int size, const char *path, Gate<int, int> progress = Null, Time tm = GetSysTime(), bool deflate = true);
void WriteFile(const String& s, const char *path, Gate<int, int> progress = Null, Time tm = GetSysTime(), bool deflate = true);
void Create(Stream& out);
void Finish();
bool IsError() { return zip && zip->IsError(); }
qword GetLength() const { return done; }
Zip();
Zip(Stream& out);
virtual ~Zip();
};
class FileZip : public Zip {
FileOut zip;
public:
bool Create(const char *name);
bool Finish();
FileZip(const char *name) { Create(name); }
FileZip() {}
~FileZip() { Finish(); }
};
class StringZip : public Zip {
StringStream zip;
public:
void Create();
String Finish();
StringZip() { Create(); }
};
}
#endif