]> git.saurik.com Git - wxWidgets.git/blame - include/wx/zipstrm.h
added WM_PRINTCLIENT
[wxWidgets.git] / include / wx / zipstrm.h
CommitLineData
5526e819 1/////////////////////////////////////////////////////////////////////////////
00375592
VZ
2// Name: zipstrm.h
3// Purpose: Streams for Zip files
4// Author: Mike Wetherell
5// RCS-ID: $Id$
6// Copyright: (c) Mike Wetherell
65571936 7// Licence: wxWindows licence
5526e819
VS
8/////////////////////////////////////////////////////////////////////////////
9
00375592
VZ
10#ifndef _WX_WXZIPSTREAM_H__
11#define _WX_WXZIPSTREAM_H__
5526e819 12
12028905 13#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
5279a24d 14#pragma interface "zipstrm.h"
5526e819
VS
15#endif
16
d1af991f 17#include "wx/defs.h"
5526e819 18
00375592 19#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
d1af991f 20
00375592
VZ
21#include "wx/archive.h"
22#include "wx/hashmap.h"
23#include "wx/filename.h"
5526e819 24
5526e819 25
00375592
VZ
26/////////////////////////////////////////////////////////////////////////////
27// constants
28
29// Compression Method, only 0 (store) and 8 (deflate) are supported here
30//
31enum wxZipMethod
32{
33 wxZIP_METHOD_STORE,
34 wxZIP_METHOD_SHRINK,
35 wxZIP_METHOD_REDUCE1,
36 wxZIP_METHOD_REDUCE2,
37 wxZIP_METHOD_REDUCE3,
38 wxZIP_METHOD_REDUCE4,
39 wxZIP_METHOD_IMPLODE,
40 wxZIP_METHOD_TOKENIZE,
41 wxZIP_METHOD_DEFLATE,
42 wxZIP_METHOD_DEFLATE64,
43 wxZIP_METHOD_BZIP2 = 12,
44 wxZIP_METHOD_DEFAULT = 0xffff
45};
46
47// Originating File-System.
48//
49// These are Pkware's values. Note that Info-zip disagree on some of them,
50// most notably NTFS.
51//
52enum wxZipSystem
53{
54 wxZIP_SYSTEM_MSDOS,
55 wxZIP_SYSTEM_AMIGA,
56 wxZIP_SYSTEM_OPENVMS,
57 wxZIP_SYSTEM_UNIX,
58 wxZIP_SYSTEM_VM_CMS,
59 wxZIP_SYSTEM_ATARI_ST,
60 wxZIP_SYSTEM_OS2_HPFS,
61 wxZIP_SYSTEM_MACINTOSH,
62 wxZIP_SYSTEM_Z_SYSTEM,
63 wxZIP_SYSTEM_CPM,
64 wxZIP_SYSTEM_WINDOWS_NTFS,
65 wxZIP_SYSTEM_MVS,
66 wxZIP_SYSTEM_VSE,
67 wxZIP_SYSTEM_ACORN_RISC,
68 wxZIP_SYSTEM_VFAT,
69 wxZIP_SYSTEM_ALTERNATE_MVS,
70 wxZIP_SYSTEM_BEOS,
71 wxZIP_SYSTEM_TANDEM,
72 wxZIP_SYSTEM_OS_400
73};
74
75// Dos/Win file attributes
76//
77enum wxZipAttributes
78{
79 wxZIP_A_RDONLY = 0x01,
80 wxZIP_A_HIDDEN = 0x02,
81 wxZIP_A_SYSTEM = 0x04,
82 wxZIP_A_SUBDIR = 0x10,
83 wxZIP_A_ARCH = 0x20,
84
85 wxZIP_A_MASK = 0x37
86};
87
88// Values for the flags field in the zip headers
89//
90enum wxZipFlags
91{
92 wxZIP_ENCRYPTED = 0x0001,
93 wxZIP_DEFLATE_NORMAL = 0x0000, // normal compression
94 wxZIP_DEFLATE_EXTRA = 0x0002, // extra compression
95 wxZIP_DEFLATE_FAST = 0x0004, // fast compression
96 wxZIP_DEFLATE_SUPERFAST = 0x0006, // superfast compression
97 wxZIP_DEFLATE_MASK = 0x0006,
98 wxZIP_SUMS_FOLLOW = 0x0008, // crc and sizes come after the data
99 wxZIP_ENHANCED = 0x0010,
100 wxZIP_PATCH = 0x0020,
101 wxZIP_STRONG_ENC = 0x0040,
102 wxZIP_UNUSED = 0x0F80,
103 wxZIP_RESERVED = 0xF000
104};
105
106// Forward decls
107//
108class WXDLLIMPEXP_BASE wxZipEntry;
109class WXDLLIMPEXP_BASE wxZipInputStream;
110
111
112/////////////////////////////////////////////////////////////////////////////
113// wxZipNotifier
5526e819 114
00375592 115class WXDLLIMPEXP_BASE wxZipNotifier
5526e819 116{
f6bcfd97 117public:
00375592
VZ
118 virtual ~wxZipNotifier() { }
119
120 virtual void OnEntryUpdated(wxZipEntry& entry) = 0;
121};
122
123
124/////////////////////////////////////////////////////////////////////////////
125// Zip Entry - holds the meta data for a file in the zip
126
127class WXDLLIMPEXP_BASE wxZipEntry : public wxArchiveEntry
128{
129public:
130 wxZipEntry(const wxString& name = wxEmptyString,
131 const wxDateTime& dt = wxDateTime::Now(),
132 wxFileOffset size = wxInvalidOffset);
133 virtual ~wxZipEntry();
134
135 wxZipEntry(const wxZipEntry& entry);
136 wxZipEntry& operator=(const wxZipEntry& entry);
137
138 // Get accessors
139 wxDateTime GetDateTime() const { return m_DateTime; }
140 wxFileOffset GetSize() const { return m_Size; }
141 wxFileOffset GetOffset() const { return m_Offset; }
142 wxString GetInternalName() const { return m_Name; }
143 int GetMethod() const { return m_Method; }
144 int GetFlags() const { return m_Flags; }
145 wxUint32 GetCrc() const { return m_Crc; }
146 wxFileOffset GetCompressedSize() const { return m_CompressedSize; }
147 int GetSystemMadeBy() const { return m_SystemMadeBy; }
148 wxString GetComment() const { return m_Comment; }
149 wxUint32 GetExternalAttributes() const { return m_ExternalAttributes; }
150 wxPathFormat GetInternalFormat() const { return wxPATH_UNIX; }
151 int GetMode() const;
152 const char *GetLocalExtra() const;
153 size_t GetLocalExtraLen() const;
154 const char *GetExtra() const;
155 size_t GetExtraLen() const;
156 wxString GetName(wxPathFormat format = wxPATH_NATIVE) const;
157
158 // is accessors
159 inline bool IsDir() const;
160 inline bool IsText() const;
161 inline bool IsReadOnly() const;
162 inline bool IsMadeByUnix() const;
163
164 // set accessors
165 void SetDateTime(const wxDateTime& dt) { m_DateTime = dt; }
166 void SetSize(wxFileOffset size) { m_Size = size; }
ceefc965 167 void SetMethod(int method) { m_Method = (wxUint16)method; }
00375592
VZ
168 void SetComment(const wxString& comment) { m_Comment = comment; }
169 void SetExternalAttributes(wxUint32 attr ) { m_ExternalAttributes = attr; }
170 void SetSystemMadeBy(int system);
171 void SetMode(int mode);
172 void SetExtra(const char *extra, size_t len);
173 void SetLocalExtra(const char *extra, size_t len);
174
175 inline void SetName(const wxString& name,
176 wxPathFormat format = wxPATH_NATIVE);
177
178 static wxString GetInternalName(const wxString& name,
179 wxPathFormat format = wxPATH_NATIVE,
180 bool *pIsDir = NULL);
181
182 // set is accessors
183 void SetIsDir(bool isDir = true);
184 inline void SetIsReadOnly(bool isReadOnly = true);
185 inline void SetIsText(bool isText = true);
f6bcfd97 186
00375592
VZ
187 wxZipEntry *Clone() const { return ZipClone(); }
188
189 void SetNotifier(wxZipNotifier& notifier);
190 void UnsetNotifier();
f6bcfd97
BP
191
192protected:
00375592
VZ
193 // Internal attributes
194 enum { TEXT_ATTR = 1 };
195
196 // protected Get accessors
197 int GetVersionNeeded() const { return m_VersionNeeded; }
198 wxFileOffset GetKey() const { return m_Key; }
199 int GetVersionMadeBy() const { return m_VersionMadeBy; }
200 int GetDiskStart() const { return m_DiskStart; }
201 int GetInternalAttributes() const { return m_InternalAttributes; }
202
ceefc965 203 void SetVersionNeeded(int version) { m_VersionNeeded = (wxUint16)version; }
00375592 204 void SetOffset(wxFileOffset offset) { m_Offset = offset; }
ceefc965
WS
205 void SetFlags(int flags) { m_Flags = (wxUint16)flags; }
206 void SetVersionMadeBy(int version) { m_VersionMadeBy = (wxUint8)version; }
00375592
VZ
207 void SetCrc(wxUint32 crc) { m_Crc = crc; }
208 void SetCompressedSize(wxFileOffset size) { m_CompressedSize = size; }
209 void SetKey(wxFileOffset offset) { m_Key = offset; }
ceefc965
WS
210 void SetDiskStart(int start) { m_DiskStart = (wxUint16)start; }
211 void SetInternalAttributes(int attr) { m_InternalAttributes = (wxUint16)attr; }
00375592
VZ
212
213 virtual wxZipEntry *ZipClone() const { return new wxZipEntry(*this); }
214
215 void Notify();
f6bcfd97
BP
216
217private:
00375592
VZ
218 wxArchiveEntry* DoClone() const { return ZipClone(); }
219
220 size_t ReadLocal(wxInputStream& stream, wxMBConv& conv);
221 size_t WriteLocal(wxOutputStream& stream, wxMBConv& conv) const;
222
223 size_t ReadCentral(wxInputStream& stream, wxMBConv& conv);
224 size_t WriteCentral(wxOutputStream& stream, wxMBConv& conv) const;
225
226 size_t ReadDescriptor(wxInputStream& stream);
227 size_t WriteDescriptor(wxOutputStream& stream, wxUint32 crc,
228 wxFileOffset compressedSize, wxFileOffset size);
229
230 wxUint8 m_SystemMadeBy; // one of enum wxZipSystem
231 wxUint8 m_VersionMadeBy; // major * 10 + minor
232
233 wxUint16 m_VersionNeeded; // ver needed to extract (20 i.e. v2.0)
234 wxUint16 m_Flags;
235 wxUint16 m_Method; // compression method (one of wxZipMethod)
236 wxDateTime m_DateTime;
237 wxUint32 m_Crc;
238 wxFileOffset m_CompressedSize;
588066b7 239 wxFileOffset m_Size;
00375592
VZ
240 wxString m_Name; // in internal format
241 wxFileOffset m_Key; // the original offset for copied entries
242 wxFileOffset m_Offset; // file offset of the entry
243
244 wxString m_Comment;
245 wxUint16 m_DiskStart; // for multidisk archives, not unsupported
246 wxUint16 m_InternalAttributes; // bit 0 set for text files
247 wxUint32 m_ExternalAttributes; // system specific depends on SystemMadeBy
248
249 class wxZipMemory *m_Extra;
250 class wxZipMemory *m_LocalExtra;
251
252 wxZipNotifier *m_zipnotifier;
253 class wxZipWeakLinks *m_backlink;
f6bcfd97 254
00375592
VZ
255 friend class wxZipInputStream;
256 friend class wxZipOutputStream;
257
258 DECLARE_DYNAMIC_CLASS(wxZipEntry)
259};
260
261
262/////////////////////////////////////////////////////////////////////////////
263// wxZipOutputStream
264
d13a08ab 265WX_DECLARE_LIST_WITH_DECL(wxZipEntry, wx__ZipEntryList, class WXDLLIMPEXP_BASE);
00375592
VZ
266
267class WXDLLIMPEXP_BASE wxZipOutputStream : public wxArchiveOutputStream
268{
269public:
270 wxZipOutputStream(wxOutputStream& stream,
271 int level = -1,
272 wxMBConv& conv = wxConvLocal);
273 virtual ~wxZipOutputStream();
274
275 bool PutNextEntry(wxZipEntry *entry) { return DoCreate(entry); }
276
277 bool PutNextEntry(const wxString& name,
278 const wxDateTime& dt = wxDateTime::Now(),
279 wxFileOffset size = wxInvalidOffset);
280
281 bool PutNextDirEntry(const wxString& name,
282 const wxDateTime& dt = wxDateTime::Now());
283
284 bool CopyEntry(wxZipEntry *entry, wxZipInputStream& inputStream);
285 bool CopyArchiveMetaData(wxZipInputStream& inputStream);
286
287 void Sync();
288 bool CloseEntry();
289 bool Close();
290
291 void SetComment(const wxString& comment) { m_Comment = comment; }
292
293 int GetLevel() const { return m_level; }
294 void SetLevel(int level);
295
296protected:
297 virtual size_t OnSysWrite(const void *buffer, size_t size);
298 virtual wxFileOffset OnSysTell() const { return m_entrySize; }
299
300 struct Buffer { const char *m_data; size_t m_size; };
301 virtual wxOutputStream *OpenCompressor(wxOutputStream& stream,
302 wxZipEntry& entry,
303 const Buffer bufs[]);
304 virtual bool CloseCompressor(wxOutputStream *comp);
305
306 bool IsParentSeekable() const { return m_offsetAdjustment
307 != wxInvalidOffset; }
308
309private:
310 bool PutNextEntry(wxArchiveEntry *entry);
311 bool CopyEntry(wxArchiveEntry *entry, wxArchiveInputStream& stream);
312 bool CopyArchiveMetaData(wxArchiveInputStream& stream);
313
314 bool IsOpened() const { return m_comp || m_pending; }
315
316 bool DoCreate(wxZipEntry *entry, bool raw = false);
317 void CreatePendingEntry(const void *buffer, size_t size);
318 void CreatePendingEntry();
319
320 class wxStoredOutputStream *m_store;
321 class wxZlibOutputStream2 *m_deflate;
322 class wxZipStreamLink *m_backlink;
d13a08ab 323 wx__ZipEntryList m_entries;
00375592
VZ
324 char *m_initialData;
325 size_t m_initialSize;
326 wxZipEntry *m_pending;
327 bool m_raw;
328 wxFileOffset m_headerOffset;
329 size_t m_headerSize;
330 wxFileOffset m_entrySize;
331 wxUint32 m_crcAccumulator;
332 wxOutputStream *m_comp;
333 int m_level;
334 wxFileOffset m_offsetAdjustment;
335 wxString m_Comment;
336
337 DECLARE_NO_COPY_CLASS(wxZipOutputStream)
338};
339
340
341/////////////////////////////////////////////////////////////////////////////
342// wxZipInputStream
343
344class WXDLLIMPEXP_BASE wxZipInputStream : public wxArchiveInputStream
345{
346public:
347 typedef wxZipEntry entry_type;
348
349 wxZipInputStream(wxInputStream& stream, wxMBConv& conv = wxConvLocal);
d13a08ab
MW
350
351#if 1 //WXWIN_COMPATIBILITY_2_6
00375592 352 wxZipInputStream(const wxString& archive, const wxString& file);
d13a08ab
MW
353#endif
354
00375592
VZ
355 virtual ~wxZipInputStream();
356
357 bool OpenEntry(wxZipEntry& entry) { return DoOpen(&entry); }
358 bool CloseEntry();
359
360 wxZipEntry *GetNextEntry();
361
362 wxString GetComment();
363 int GetTotalEntries();
364
365 virtual wxFileOffset GetLength() const { return m_entry.GetSize(); }
366
367protected:
368 size_t OnSysRead(void *buffer, size_t size);
369 wxFileOffset OnSysTell() const { return m_decomp ? m_decomp->TellI() : 0; }
d13a08ab
MW
370
371#if 1 //WXWIN_COMPATIBILITY_2_6
00375592 372 wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
d13a08ab 373#endif
00375592 374
d13a08ab 375 // this protected interface isn't yet finalised
00375592
VZ
376 virtual wxInputStream *OpenDecompressor(wxInputStream& stream);
377 virtual bool CloseDecompressor(wxInputStream *decomp);
378
379private:
380 void Init();
381 wxInputStream& OpenFile(const wxString& archive);
382
383 wxArchiveEntry *DoGetNextEntry() { return GetNextEntry(); }
384
385 bool OpenEntry(wxArchiveEntry& entry);
386
387 wxStreamError ReadLocal(bool readEndRec = false);
388 wxStreamError ReadCentral();
389
390 wxUint32 ReadSignature();
391 bool FindEndRecord();
392 bool LoadEndRecord();
393
394 bool AtHeader() const { return m_headerSize == 0; }
395 bool AfterHeader() const { return m_headerSize > 0 && !m_decomp; }
396 bool IsOpened() const { return m_decomp != NULL; }
397
398 wxZipStreamLink *MakeLink(wxZipOutputStream *out);
399
400 bool DoOpen(wxZipEntry *entry = NULL, bool raw = false);
401 bool OpenDecompressor(bool raw = false);
402
403 class wxStoredInputStream *m_store;
404 class wxZlibInputStream2 *m_inflate;
405 class wxRawInputStream *m_rawin;
406 class wxFFileInputStream *m_ffile;
407 wxZipEntry m_entry;
408 bool m_raw;
409 size_t m_headerSize;
410 wxUint32 m_crcAccumulator;
411 wxInputStream *m_decomp;
412 bool m_parentSeekable;
413 class wxZipWeakLinks *m_weaklinks;
414 class wxZipStreamLink *m_streamlink;
415 wxFileOffset m_offsetAdjustment;
416 wxFileOffset m_position;
417 wxUint32 m_signature;
418 size_t m_TotalEntries;
419 wxString m_Comment;
420
421 friend bool wxZipOutputStream::CopyEntry(
422 wxZipEntry *entry, wxZipInputStream& inputStream);
423 friend bool wxZipOutputStream::CopyArchiveMetaData(
424 wxZipInputStream& inputStream);
22f3361e 425
d13a08ab
MW
426#if 1 //WXWIN_COMPATIBILITY_2_6
427 bool m_allowSeeking;
428 friend class wxZipFSInputStream;
429#endif
430
22f3361e 431 DECLARE_NO_COPY_CLASS(wxZipInputStream)
5526e819
VS
432};
433
434
81f90336
MW
435/////////////////////////////////////////////////////////////////////////////
436// Iterators
437
438#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
439typedef wxArchiveIterator<wxZipInputStream> wxZipIter;
440typedef wxArchiveIterator<wxZipInputStream,
441 std::pair<wxString, wxZipEntry*> > wxZipPairIter;
442#endif
443
444
00375592
VZ
445/////////////////////////////////////////////////////////////////////////////
446// wxZipClassFactory
5526e819 447
00375592
VZ
448class WXDLLIMPEXP_BASE wxZipClassFactory : public wxArchiveClassFactory
449{
450public:
81f90336
MW
451 typedef wxZipEntry entry_type;
452 typedef wxZipInputStream instream_type;
453 typedef wxZipOutputStream outstream_type;
454 typedef wxZipNotifier notifier_type;
455#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
456 typedef wxZipIter iter_type;
457 typedef wxZipPairIter pairiter_type;
458#endif
459
00375592
VZ
460 wxZipEntry *NewEntry() const
461 { return new wxZipEntry; }
462 wxZipInputStream *NewStream(wxInputStream& stream) const
463 { return new wxZipInputStream(stream, GetConv()); }
464 wxZipOutputStream *NewStream(wxOutputStream& stream) const
465 { return new wxZipOutputStream(stream, -1, GetConv()); }
466
467 wxString GetInternalName(const wxString& name,
468 wxPathFormat format = wxPATH_NATIVE) const
469 { return wxZipEntry::GetInternalName(name, format); }
470
471protected:
472 wxArchiveEntry *DoNewEntry() const
473 { return NewEntry(); }
474 wxArchiveInputStream *DoNewStream(wxInputStream& stream) const
475 { return NewStream(stream); }
476 wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const
477 { return NewStream(stream); }
478
479private:
480 DECLARE_DYNAMIC_CLASS(wxZipClassFactory)
481};
482
483
00375592
VZ
484/////////////////////////////////////////////////////////////////////////////
485// wxZipEntry inlines
486
f44eaed6 487inline bool wxZipEntry::IsText() const
00375592
VZ
488{
489 return (m_InternalAttributes & TEXT_ATTR) != 0;
490}
491
f44eaed6 492inline bool wxZipEntry::IsDir() const
00375592
VZ
493{
494 return (m_ExternalAttributes & wxZIP_A_SUBDIR) != 0;
495}
496
f44eaed6 497inline bool wxZipEntry::IsReadOnly() const
00375592
VZ
498{
499 return (m_ExternalAttributes & wxZIP_A_RDONLY) != 0;
500}
501
f44eaed6 502inline bool wxZipEntry::IsMadeByUnix() const
00375592
VZ
503{
504 const int pattern =
505 (1 << wxZIP_SYSTEM_OPENVMS) |
506 (1 << wxZIP_SYSTEM_UNIX) |
507 (1 << wxZIP_SYSTEM_ATARI_ST) |
508 (1 << wxZIP_SYSTEM_ACORN_RISC) |
509 (1 << wxZIP_SYSTEM_BEOS) | (1 << wxZIP_SYSTEM_TANDEM);
510
511 // note: some unix zippers put madeby = dos
512 return (m_SystemMadeBy == wxZIP_SYSTEM_MSDOS
513 && (m_ExternalAttributes & ~0xFFFF))
514 || ((pattern >> m_SystemMadeBy) & 1);
515}
516
f44eaed6 517inline void wxZipEntry::SetIsText(bool isText)
00375592
VZ
518{
519 if (isText)
520 m_InternalAttributes |= TEXT_ATTR;
521 else
522 m_InternalAttributes &= ~TEXT_ATTR;
523}
524
f44eaed6 525inline void wxZipEntry::SetIsReadOnly(bool isReadOnly)
00375592
VZ
526{
527 if (isReadOnly)
528 SetMode(GetMode() & ~0222);
529 else
530 SetMode(GetMode() | 0200);
531}
532
f44eaed6
RN
533inline void wxZipEntry::SetName(const wxString& name,
534 wxPathFormat format /*=wxPATH_NATIVE*/)
00375592
VZ
535{
536 bool isDir;
537 m_Name = GetInternalName(name, format, &isDir);
538 SetIsDir(isDir);
539}
540
541
542#endif // wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
543
544#endif // _WX_WXZIPSTREAM_H__