1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        zipstrm.h
3 // Purpose:     interface of wxZipNotifier
4 // Author:      wxWidgets team
5 // Licence:     wxWindows licence
6 /////////////////////////////////////////////////////////////////////////////
7 
8 
9 
10 /// Compression Method, only 0 (store) and 8 (deflate) are supported here
11 enum wxZipMethod
12 {
13     wxZIP_METHOD_STORE,
14     wxZIP_METHOD_SHRINK,
15     wxZIP_METHOD_REDUCE1,
16     wxZIP_METHOD_REDUCE2,
17     wxZIP_METHOD_REDUCE3,
18     wxZIP_METHOD_REDUCE4,
19     wxZIP_METHOD_IMPLODE,
20     wxZIP_METHOD_TOKENIZE,
21     wxZIP_METHOD_DEFLATE,
22     wxZIP_METHOD_DEFLATE64,
23     wxZIP_METHOD_BZIP2 = 12,
24     wxZIP_METHOD_DEFAULT = 0xffff
25 };
26 
27 /// Originating File-System.
28 ///
29 /// These are Pkware's values. Note that Info-zip disagree on some of them,
30 /// most notably NTFS.
31 enum wxZipSystem
32 {
33     wxZIP_SYSTEM_MSDOS,
34     wxZIP_SYSTEM_AMIGA,
35     wxZIP_SYSTEM_OPENVMS,
36     wxZIP_SYSTEM_UNIX,
37     wxZIP_SYSTEM_VM_CMS,
38     wxZIP_SYSTEM_ATARI_ST,
39     wxZIP_SYSTEM_OS2_HPFS,
40     wxZIP_SYSTEM_MACINTOSH,
41     wxZIP_SYSTEM_Z_SYSTEM,
42     wxZIP_SYSTEM_CPM,
43     wxZIP_SYSTEM_WINDOWS_NTFS,
44     wxZIP_SYSTEM_MVS,
45     wxZIP_SYSTEM_VSE,
46     wxZIP_SYSTEM_ACORN_RISC,
47     wxZIP_SYSTEM_VFAT,
48     wxZIP_SYSTEM_ALTERNATE_MVS,
49     wxZIP_SYSTEM_BEOS,
50     wxZIP_SYSTEM_TANDEM,
51     wxZIP_SYSTEM_OS_400
52 };
53 
54 /// Dos/Win file attributes
55 enum wxZipAttributes
56 {
57     wxZIP_A_RDONLY = 0x01,
58     wxZIP_A_HIDDEN = 0x02,
59     wxZIP_A_SYSTEM = 0x04,
60     wxZIP_A_SUBDIR = 0x10,
61     wxZIP_A_ARCH   = 0x20,
62 
63     wxZIP_A_MASK   = 0x37
64 };
65 
66 /// Values for the flags field in the zip headers
67 enum wxZipFlags
68 {
69     wxZIP_ENCRYPTED         = 0x0001,
70     wxZIP_DEFLATE_NORMAL    = 0x0000,   // normal compression
71     wxZIP_DEFLATE_EXTRA     = 0x0002,   // extra compression
72     wxZIP_DEFLATE_FAST      = 0x0004,   // fast compression
73     wxZIP_DEFLATE_SUPERFAST = 0x0006,   // superfast compression
74     wxZIP_DEFLATE_MASK      = 0x0006,
75     wxZIP_SUMS_FOLLOW       = 0x0008,   // crc and sizes come after the data
76     wxZIP_ENHANCED          = 0x0010,
77     wxZIP_PATCH             = 0x0020,
78     wxZIP_STRONG_ENC        = 0x0040,
79     wxZIP_UNUSED            = 0x0F80,
80     wxZIP_RESERVED          = 0xF000
81 };
82 
83 
84 /**
85     @class wxZipNotifier
86 
87     If you need to know when a wxZipInputStream updates a wxZipEntry,
88     you can create a notifier by deriving from this abstract base class,
89     overriding wxZipNotifier::OnEntryUpdated().
90 
91     An instance of your notifier class can then be assigned to wxZipEntry
92     objects, using wxZipEntry::SetNotifier().
93 
94     Setting a notifier is not usually necessary. It is used to handle
95     certain cases when modifying an zip in a pipeline (i.e. between
96     non-seekable streams).
97     See @ref overview_archive_noseek.
98 
99     @library{wxbase}
100     @category{archive,streams}
101 
102     @see @ref overview_archive_noseek, wxZipEntry, wxZipInputStream, wxZipOutputStream
103 */
104 class wxZipNotifier
105 {
106 public:
107     /**
108         Override this to receive notifications when an wxZipEntry object changes.
109     */
110     virtual void OnEntryUpdated(wxZipEntry& entry) = 0;
111 };
112 
113 
114 
115 /**
116     @class wxZipEntry
117 
118     Holds the meta-data for an entry in a zip.
119 
120     @section zipentry_avail Field availability
121 
122     When reading a zip from a stream that is seekable, wxZipEntry::GetNextEntry()
123     returns a fully populated wxZipEntry object except for wxZipEntry::GetLocalExtra().
124     wxZipEntry::GetLocalExtra() becomes available when the entry is opened, either by
125     calling wxZipInputStream::OpenEntry() or by making an attempt to read the entry's data.
126 
127     For zips on non-seekable streams, the following fields are always available
128     when wxZipEntry::GetNextEntry() returns:
129     - wxZipEntry::GetDateTime
130     - wxZipEntry::GetInternalFormat
131     - wxZipEntry::GetInternalName
132     - wxZipEntry::GetFlags
133     - wxZipEntry::GetLocalExtra
134     - wxZipEntry::GetMethod
135     - wxZipEntry::GetName
136     - wxZipEntry::GetOffset
137     - wxZipEntry::IsDir
138 
139     The following fields are also usually available when GetNextEntry() returns,
140     however, if the zip was also written to a non-seekable stream the zipper is
141     permitted to store them after the entry's data. In that case they become
142     available when the entry's data has been read to Eof(), or CloseEntry()
143     has been called. (GetFlags() & wxZIP_SUMS_FOLLOW) != 0 indicates that
144     one or more of these come after the data:
145     - wxZipEntry::GetCompressedSize
146     - wxZipEntry::GetCrc
147     - wxZipEntry::GetSize
148 
149     The following are stored at the end of the zip, and become available when the
150     end of the zip has been reached, i.e. after GetNextEntry() returns @NULL
151     and Eof() is true:
152     - wxZipEntry::GetComment
153     - wxZipEntry::GetExternalAttributes
154     - wxZipEntry::GetExtra
155     - wxZipEntry::GetMode
156     - wxZipEntry::GetSystemMadeBy
157     - wxZipEntry::IsReadOnly
158     - wxZipEntry::IsMadeByUnix
159     - wxZipEntry::IsText
160 
161     @library{wxbase}
162     @category{archive,streams}
163 
164     @see @ref overview_archive, wxZipInputStream, wxZipOutputStream, wxZipNotifier
165 */
166 class wxZipEntry : public wxArchiveEntry
167 {
168 public:
169     wxZipEntry(const wxString& name = wxEmptyString,
170                const wxDateTime& dt = Now(),
171                wxFileOffset size = wxInvalidOffset);
172 
173     /**
174         Copy constructor.
175     */
176     wxZipEntry(const wxZipEntry& entry);
177 
178     /**
179         Make a copy of this entry.
180     */
181     wxZipEntry* Clone() const;
182 
183     //@{
184     /**
185         Gets and sets the short comment for this entry.
186     */
187     wxString GetComment() const;
188     void SetComment(const wxString& comment);
189     //@}
190 
191     //@{
192     /**
193         The low 8 bits are always the DOS/Windows file attributes for this entry.
194         The values of these attributes are given in the enumeration ::wxZipAttributes.
195 
196         The remaining bits can store platform specific permission bits or
197         attributes, and their meaning depends on the value of SetSystemMadeBy().
198         If IsMadeByUnix() is @true then the high 16 bits are unix mode bits.
199 
200         The following other accessors access these bits:
201         - IsReadOnly() / SetIsReadOnly()
202         - IsDir() / SetIsDir()
203         - GetMode() / SetMode()
204     */
205     wxUint32 GetExternalAttributes() const;
206     void SetExternalAttributes(wxUint32 attr);
207     //@}
208 
209     //@{
210     /**
211         The extra field from the entry's central directory record.
212 
213         The extra field is used to store platform or application specific
214         data. See Pkware's document 'appnote.txt' for information on its format.
215     */
216     const char* GetExtra() const;
217     size_t GetExtraLen() const;
218     void SetExtra(const char* extra, size_t len);
219     //@}
220 
221     //@{
222     /**
223         The extra field from the entry's local record.
224 
225         The extra field is used to store platform or application specific
226         data. See Pkware's document 'appnote.txt' for information on its format.
227     */
228     const char* GetLocalExtra() const;
229     size_t GetLocalExtraLen() const;
230     void SetLocalExtra(const char* extra, size_t len);
231     //@}
232 
233     //@{
234     /**
235         The compression method.
236         The enumeration ::wxZipMethod lists the possible values.
237 
238         The default constructor sets this to @c wxZIP_METHOD_DEFAULT,
239         which allows wxZipOutputStream to choose the method when writing the entry.
240     */
241     int GetMethod() const;
242     void SetMethod(int method);
243     //@}
244 
245     //@{
246     /**
247         If IsMadeByUnix() is true then returns the unix permission bits stored
248         in GetExternalAttributes(). Otherwise synthesises them from the DOS attributes.
249     */
250     int GetMode() const;
251 
252     /**
253         Sets the DOS attributes in GetExternalAttributes() to be consistent with
254         the @a mode given.
255 
256         If IsMadeByUnix() is @true then also stores @a mode in GetExternalAttributes().
257         Note that the default constructor sets GetSystemMadeBy() to
258         @c wxZIP_SYSTEM_MSDOS by default. So to be able to store unix
259         permissions when creating zips, call SetSystemMadeBy(wxZIP_SYSTEM_UNIX).
260     */
261     void SetMode(int mode);
262     //@}
263 
264     //@{
265     /**
266         The originating file-system.
267 
268         The default constructor sets this to @c wxZIP_SYSTEM_MSDOS.
269         Set it to @c wxZIP_SYSTEM_UNIX in order to be able to store unix
270         permissions using SetMode().
271     */
272     int GetSystemMadeBy() const;
273     void SetSystemMadeBy(int system);
274     //@}
275 
276     /**
277         The compressed size of this entry in bytes.
278     */
279     wxFileOffset GetCompressedSize() const;
280 
281     /**
282         CRC32 for this entry's data.
283     */
284     wxUint32 GetCrc() const;
285 
286     /**
287         Returns a combination of the bits flags in the enumeration @c wxZipFlags.
288     */
289     int GetFlags() const;
290 
291     //@{
292     /**
293         A static member that translates a filename into the internal format used
294         within the archive. If the third parameter is provided, the bool pointed
295         to is set to indicate whether the name looks like a directory name
296         (i.e. has a trailing path separator).
297 
298         @see @ref overview_archive_byname
299     */
300     wxString GetInternalName(const wxString& name,
301                             wxPathFormat format = wxPATH_NATIVE,
302                             bool* pIsDir = NULL);
303     /**
304         Returns the entry's filename in the internal format used within the archive.
305         The name can include directory components, i.e. it can be a full path.
306 
307         The names of directory entries are returned without any trailing path separator.
308         This gives a canonical name that can be used in comparisons.
309     */
310     wxString GetInternalName() const;
311     //@}
312 
313     /**
314         Returns @true if GetSystemMadeBy() is a flavour of unix.
315     */
316     bool IsMadeByUnix() const;
317 
318     //@{
319     /**
320         Indicates that this entry's data is text in an 8-bit encoding.
321     */
322     bool IsText() const;
323     void SetIsText(bool isText = true);
324     //@}
325 
326     //@{
327     /**
328         Sets the notifier (see wxZipNotifier) for this entry.
329         Whenever the wxZipInputStream updates this entry, it will then invoke
330         the associated notifier's wxZipNotifier::OnEntryUpdated() method.
331 
332         Setting a notifier is not usually necessary. It is used to handle
333         certain cases when modifying an zip in a pipeline (i.e. between
334         non-seekable streams).
335 
336         @see @ref overview_archive_noseek, wxZipNotifier
337     */
338     void SetNotifier(wxZipNotifier& notifier);
339     void UnsetNotifier();
340     //@}
341 
342     /**
343         Assignment operator.
344     */
345     wxZipEntry& operator=(const wxZipEntry& entry);
346 };
347 
348 
349 /**
350     @class wxZipInputStream
351 
352     Input stream for reading zip files.
353 
354     wxZipInputStream::GetNextEntry() returns a wxZipEntry object containing the
355     meta-data for the next entry in the zip (and gives away ownership).
356     Reading from the wxZipInputStream then returns the entry's data.
357     Eof() becomes @true after an attempt has been made to read past the end of
358     the entry's data.
359     When there are no more entries, GetNextEntry() returns @NULL and sets Eof().
360 
361     Note that in general zip entries are not seekable, and
362     wxZipInputStream::SeekI() always returns ::wxInvalidOffset.
363 
364     @library{wxbase}
365     @category{archive,streams}
366 
367     @see @ref overview_archive, wxZipEntry, wxZipOutputStream
368 */
369 class wxZipInputStream : public wxArchiveInputStream
370 {
371 public:
372 
373     //@{
374     /**
375         Constructor. In a Unicode build the second parameter @a conv is used to
376         translate the filename and comment fields into Unicode.
377         It has no effect on the stream's data.
378         If the parent stream is passed as a pointer then the new filter stream
379         takes ownership of it. If it is passed by reference then it does not.
380     */
381     wxZipInputStream(wxInputStream& stream,
382                      wxMBConv& conv = wxConvLocal);
383     wxZipInputStream(wxInputStream* stream,
384                      wxMBConv& conv = wxConvLocal);
385     //@}
386 
387     /**
388         @deprecated
389         Compatibility constructor (requires WXWIN_COMPATIBILITY_2_6).
390         When this constructor is used, an emulation of seeking is
391         switched on for compatibility with previous versions. Note however,
392         that it is deprecated.
393     */
394     wxZipInputStream(const wxString& archive,
395                      const wxString& file);
396 
397     /**
398         Closes the current entry.
399         On a non-seekable stream reads to the end of the current entry first.
400     */
401     bool CloseEntry();
402 
403     /**
404         Returns the zip comment.
405 
406         This is stored at the end of the zip, therefore when reading a zip
407         from a non-seekable stream, it returns the empty string until the end
408         of the zip has been reached, i.e. when GetNextEntry() returns @NULL.
409     */
410     wxString GetComment();
411 
412     /**
413         Closes the current entry if one is open, then reads the meta-data for
414         the next entry and returns it in a wxZipEntry object, giving away ownership.
415         The stream is then open and can be read.
416     */
417     wxZipEntry* GetNextEntry();
418 
419     /**
420         For a zip on a seekable stream returns the total number of entries in
421         the zip. For zips on non-seekable streams returns the number of entries
422         returned so far by GetNextEntry().
423     */
424     int GetTotalEntries();
425 
426     /**
427         Closes the current entry if one is open, then opens the entry specified
428         by the @a entry object.
429 
430         @a entry should be from the same zip file, and the zip should
431         be on a seekable stream.
432 
433         @see overview_archive_byname
434     */
435     bool OpenEntry(wxZipEntry& entry);
436 };
437 
438 
439 
440 /**
441     @class wxZipClassFactory
442 
443     Class factory for the zip archive format.
444     See the base class for details.
445 
446     @library{wxbase}
447     @category{archive,streams}
448 
449     @see @ref overview_archive,
450          @ref overview_archive_generic,
451          wxZipEntry, wxZipInputStream, wxZipOutputStream
452 */
453 class wxZipClassFactory : public wxArchiveClassFactory
454 {
455 public:
456 
457 };
458 
459 
460 
461 /**
462     @class wxZipOutputStream
463 
464     Output stream for writing zip files.
465 
466     wxZipOutputStream::PutNextEntry() is used to create a new entry in the
467     output zip, then the entry's data is written to the wxZipOutputStream.
468     Another call to wxZipOutputStream::PutNextEntry() closes the current
469     entry and begins the next.
470 
471     @library{wxbase}
472     @category{archive,streams}
473 
474     @see @ref overview_archive, wxZipEntry, wxZipInputStream
475 */
476 class wxZipOutputStream : public wxArchiveOutputStream
477 {
478 public:
479     //@{
480     /**
481         Constructor.
482 
483         @a level is the compression level to use.
484         It can be a value between 0 and 9 or -1 to use the default value
485         which currently is equivalent to 6.
486 
487         If the parent stream is passed as a pointer then the new filter stream
488         takes ownership of it. If it is passed by reference then it does not.
489         In a Unicode build the third parameter @a conv is used to translate
490         the filename and comment fields to an 8-bit encoding.
491         It has no effect on the stream's data.
492     */
493     wxZipOutputStream(wxOutputStream& stream, int level = -1,
494                       wxMBConv& conv = wxConvLocal);
495     wxZipOutputStream(wxOutputStream* stream, int level = -1,
496                       wxMBConv& conv = wxConvLocal);
497     //@}
498 
499     /**
500         The destructor calls Close() to finish writing the zip if it has
501         not been called already.
502     */
503     virtual ~wxZipOutputStream();
504 
505     /**
506         Finishes writing the zip, returning @true if successful.
507         Called by the destructor if not called explicitly.
508     */
509     bool Close();
510 
511     /**
512         Close the current entry.
513         It is called implicitly whenever another new entry is created with CopyEntry()
514         or PutNextEntry(), or when the zip is closed.
515     */
516     bool CloseEntry();
517 
518     /**
519         Transfers the zip comment from the wxZipInputStream
520         to this output stream.
521     */
522     bool CopyArchiveMetaData(wxZipInputStream& inputStream);
523 
524     /**
525         Takes ownership of @a entry and uses it to create a new entry
526         in the zip. @a entry is then opened in @a inputStream and its contents
527         copied to this stream.
528 
529         CopyEntry() is much more efficient than transferring the data using
530         Read() and Write() since it will copy them without decompressing and
531         recompressing them.
532 
533         For zips on seekable streams, @a entry must be from the same zip file
534         as @a inputStream. For non-seekable streams, @a entry must also be the
535         last thing read from @a inputStream.
536     */
537     bool CopyEntry(wxZipEntry* entry, wxZipInputStream& inputStream);
538 
539     //@{
540     /**
541         Set the compression level that will be used the next time an entry is
542         created.
543 
544         It can be a value between 0 and 9 or -1 to use the default value
545         which currently is equivalent to 6.
546     */
547     int GetLevel() const;
548     void SetLevel(int level);
549     //@}
550 
551     /**
552         Create a new directory entry (see wxArchiveEntry::IsDir) with the given
553         name and timestamp.
554 
555         PutNextEntry() can also be used to create directory entries, by supplying
556         a name with a trailing path separator.
557     */
558     bool PutNextDirEntry(const wxString& name,
559                          const wxDateTime& dt = wxDateTime::Now());
560 
561     //@{
562     /**
563         Takes ownership of @a entry and uses it to create a new entry in the zip.
564     */
565     bool PutNextEntry(wxZipEntry* entry);
566 
567     /**
568         Create a new entry with the given name, timestamp and size.
569     */
570     bool PutNextEntry(const wxString& name,
571                       const wxDateTime& dt = wxDateTime::Now(),
572                       wxFileOffset size = wxInvalidOffset);
573     //@}
574 
575     /**
576         Sets a comment for the zip as a whole.
577         It is written at the end of the zip.
578     */
579     void SetComment(const wxString& comment);
580 };
581 
582