#ifndef _zip_zip_h #define _zip_zip_h #include namespace Upp { class UnZip { struct File : Moveable { word bit; String path; dword time; int method; dword crc; qword csize; qword usize; int64 offset; }; Stream *zip; bool error; Vector 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 progress = Null); String ReadFile(Gate progress = Null); String ReadFile(const char *path, Gate 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; qword done; One pipeZLib; Crc32Stream crc32; // for uncompressed files bool uncompressed; void WriteFile0(const void *ptr, int size, const char *path, Gate 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 progress = Null, Time tm = GetSysTime(), bool deflate = true); void WriteFile(const String& s, const char *path, Gate 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