1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        archive.h
3 // Purpose:     interface of wxArchive* classes
4 // Author:      wxWidgets team
5 // Licence:     wxWindows licence
6 /////////////////////////////////////////////////////////////////////////////
7 
8 /**
9     @class wxArchiveInputStream
10 
11     This is an abstract base class which serves as a common interface to
12     archive input streams such as wxZipInputStream.
13 
14     wxArchiveInputStream::GetNextEntry returns an wxArchiveEntry object containing
15     the meta-data for the next entry in the archive (and gives away ownership).
16 
17     Reading from the wxArchiveInputStream then returns the entry's data. Eof()
18     becomes @true after an attempt has been made to read past the end of the
19     entry's data.
20 
21     When there are no more entries, GetNextEntry() returns @NULL and sets Eof().
22 
23     @library{wxbase}
24     @category{archive,streams}
25 
26     @see @ref overview_archive, wxArchiveEntry, wxArchiveOutputStream
27 */
28 class wxArchiveInputStream : public wxFilterInputStream
29 {
30 public:
31     /**
32         Closes the current entry. On a non-seekable stream reads to the end of
33         the current entry first.
34     */
35     virtual bool CloseEntry() = 0;
36 
37     /**
38         Closes the current entry if one is open, then reads the meta-data for
39         the next entry and returns it in a wxArchiveEntry object, giving away
40         ownership. Reading this wxArchiveInputStream then returns the entry's data.
41     */
42     wxArchiveEntry* GetNextEntry();
43 
44     /**
45         Closes the current entry if one is open, then opens the entry specified
46         by the wxArchiveEntry object.
47 
48         @a entry must be from the same archive file that this wxArchiveInputStream
49         is reading, and it must be reading it from a seekable stream.
50     */
51     virtual bool OpenEntry(wxArchiveEntry& entry) = 0;
52 };
53 
54 
55 
56 /**
57     @class wxArchiveOutputStream
58 
59     This is an abstract base class which serves as a common interface to
60     archive output streams such as wxZipOutputStream.
61 
62     wxArchiveOutputStream::PutNextEntry is used to create a new entry in the
63     output archive, then the entry's data is written to the wxArchiveOutputStream.
64     Another call to PutNextEntry() closes the current entry and begins the next.
65 
66     @library{wxbase}
67     @category{archive,streams}
68 
69     @see @ref overview_archive, wxArchiveEntry, wxArchiveInputStream
70 */
71 class wxArchiveOutputStream : public wxFilterOutputStream
72 {
73 public:
74     /**
75         Calls Close() if it has not already been called.
76     */
77     virtual ~wxArchiveOutputStream();
78 
79     /**
80         Closes the archive, returning @true if it was successfully written.
81         Called by the destructor if not called explicitly.
82 
83         @see wxOutputStream::Close()
84     */
85     virtual bool Close();
86 
87     /**
88         Close the current entry.
89         It is called implicitly whenever another new entry is created with CopyEntry()
90         or PutNextEntry(), or when the archive is closed.
91     */
92     virtual bool CloseEntry() = 0;
93 
94     /**
95         Some archive formats have additional meta-data that applies to the archive
96         as a whole.
97         For example in the case of zip there is a comment, which is stored at the end
98         of the zip file.  CopyArchiveMetaData() can be used to transfer such information
99         when writing a modified copy of an archive.
100 
101         Since the position of the meta-data can vary between the various archive
102         formats, it is best to call CopyArchiveMetaData() before transferring
103         the entries.  The wxArchiveOutputStream will then hold on to the meta-data
104         and write it at the correct point in the output file.
105 
106         When the input archive is being read from a non-seekable stream, the
107         meta-data may not be available when CopyArchiveMetaData() is called,
108         in which case the two streams set up a link and transfer the data
109         when it becomes available.
110     */
111     virtual bool CopyArchiveMetaData(wxArchiveInputStream& stream) = 0;
112 
113     /**
114         Takes ownership of @a entry and uses it to create a new entry in the
115         archive. @a entry is then opened in the input stream @a stream
116         and its contents copied to this stream.
117 
118         For archive types which compress entry data, CopyEntry() is likely to be
119         much more efficient than transferring the data using Read() and Write()
120         since it will copy them without decompressing and recompressing them.
121 
122         @a entry must be from the same archive file that @a stream is
123         accessing. For non-seekable streams, @a entry must also be the last
124         thing read from @a stream.
125     */
126     virtual bool CopyEntry(wxArchiveEntry* entry,
127                            wxArchiveInputStream& stream) = 0;
128 
129     /**
130         Create a new directory entry (see wxArchiveEntry::IsDir) with the given
131         name and timestamp.
132 
133         PutNextEntry() can also be used to create directory entries, by supplying
134         a name with a trailing path separator.
135     */
136     virtual bool PutNextDirEntry(const wxString& name,
137                                  const wxDateTime& dt = wxDateTime::Now()) = 0;
138 
139     /**
140         Takes ownership of entry and uses it to create a new entry in the archive.
141         The entry's data can then be written by writing to this wxArchiveOutputStream.
142     */
143     virtual bool PutNextEntry(wxArchiveEntry* entry) = 0;
144 
145     /**
146         Create a new entry with the given name, timestamp and size. The entry's
147         data can then be written by writing to this wxArchiveOutputStream.
148     */
149     virtual bool PutNextEntry(const wxString& name,
150                               const wxDateTime& dt = wxDateTime::Now(),
151                               wxFileOffset size = wxInvalidOffset) = 0;
152 };
153 
154 
155 
156 /**
157     @class wxArchiveEntry
158 
159     This is an abstract base class which serves as a common interface to
160     archive entry classes such as wxZipEntry.
161     These hold the meta-data (filename, timestamp, etc.), for entries
162     in archive files such as zips and tars.
163 
164     @section archiveentry_nonseekable About non-seekable streams
165 
166     This information applies only when reading archives from non-seekable streams.
167     When the stream is seekable GetNextEntry() returns a fully populated wxArchiveEntry.
168     See @ref overview_archive_noseek for more information.
169 
170     For generic programming, when the worst case must be assumed, you can rely on
171     all the fields of wxArchiveEntry being fully populated when
172     wxArchiveInputStream::GetNextEntry() returns, with the following exceptions:
173 
174     @li GetSize(): guaranteed to be available after the entry has been read to Eof(),
175         or CloseEntry() has been called;
176     @li IsReadOnly(): guaranteed to be available after the end of the archive has
177         been reached, i.e. after GetNextEntry() returns NULL and Eof() is true.
178 
179     @library{wxbase}
180     @category{archive,streams}
181 
182     @see @ref overview_archive, @ref overview_archive_generic,
183          wxArchiveInputStream, wxArchiveOutputStream, wxArchiveNotifier
184 */
185 class wxArchiveEntry : public wxObject
186 {
187 public:
188     /**
189         Returns a copy of this entry object.
190     */
191     wxArchiveEntry* Clone() const;
192 
193     /**
194         Gets the entry's timestamp.
195     */
196     virtual wxDateTime GetDateTime() const = 0;
197 
198     /**
199         Sets the entry's timestamp.
200     */
201     virtual void SetDateTime(const wxDateTime& dt) = 0;
202 
203     /**
204         Returns the entry's name, by default in the native format.
205         The name can include directory components, i.e. it can be a full path.
206 
207         If this is a directory entry, (i.e. if IsDir() is @true) then the
208         returned string is the name with a trailing path separator.
209     */
210     virtual wxString GetName(wxPathFormat format = wxPATH_NATIVE) const = 0;
211 
212     /**
213         Sets the entry's name.
214         Setting a name with a trailing path separator sets IsDir().
215 
216         @see GetName()
217     */
218     virtual void SetName(const wxString& name,
219                          wxPathFormat format = wxPATH_NATIVE) = 0;
220 
221     /**
222         Returns the size of the entry's data in bytes.
223     */
224     virtual wxFileOffset GetSize() const = 0;
225 
226     /**
227         Sets the size of the entry's data in bytes.
228     */
229     virtual void SetSize(wxFileOffset size) = 0;
230 
231     /**
232         Returns the path format used internally within the archive to store
233         filenames.
234     */
235     virtual wxPathFormat GetInternalFormat() const = 0;
236 
237     /**
238         Returns the entry's filename in the internal format used within the
239         archive. The name can include directory components, i.e. it can be a
240         full path.
241 
242         The names of directory entries are returned without any trailing path
243         separator. This gives a canonical name that can be used in comparisons.
244 
245         @see @ref overview_archive_byname
246     */
247     virtual wxString GetInternalName() const = 0;
248 
249     /**
250         Returns a numeric value unique to the entry within the archive.
251     */
252     virtual wxFileOffset GetOffset() const = 0;
253 
254     /**
255         Returns @true if this is a directory entry.
256 
257         Directory entries are entries with no data, which are used to store
258         the meta-data of directories. They also make it possible for completely
259         empty directories to be stored.
260 
261         @note
262         The names of entries within an archive can be complete paths, and
263         unarchivers typically create whatever directories are necessary as they
264         restore files, even if the archive contains no explicit directory entries.
265     */
266     virtual bool IsDir() const = 0;
267 
268     /**
269         Marks this entry as a directory if @a isDir is @true. See IsDir() for more info.
270     */
271     virtual void SetIsDir(bool isDir = true) = 0;
272 
273     /**
274         Returns @true if the entry is a read-only file.
275     */
276     virtual bool IsReadOnly() const = 0;
277 
278     /**
279         Sets this entry as a read-only file.
280     */
281     virtual void SetIsReadOnly(bool isReadOnly = true) = 0;
282 
283     /**
284         Sets the notifier (see wxArchiveNotifier) for this entry.
285 
286         Whenever the wxArchiveInputStream updates this entry, it will then invoke
287         the associated notifier's wxArchiveNotifier::OnEntryUpdated method.
288 
289         Setting a notifier is not usually necessary. It is used to handle
290         certain cases when modifying an archive in a pipeline (i.e. between
291         non-seekable streams).
292     */
293     void SetNotifier(wxArchiveNotifier& notifier);
294 
295     /**
296         Unsets the notifier eventually attached to this entry.
297     */
298     virtual void UnsetNotifier();
299 };
300 
301 
302 
303 /**
304     @class wxArchiveClassFactory
305 
306     Allows the creation of streams to handle archive formats such as zip and tar.
307 
308     For example, given a filename you can search for a factory that will
309     handle it and create a stream to read it:
310 
311     @code
312         factory = wxArchiveClassFactory::Find(filename, wxSTREAM_FILEEXT);
313         if (factory)
314             stream = factory->NewStream(new wxFFileInputStream(filename));
315     @endcode
316 
317     wxArchiveClassFactory::Find can also search for a factory by MIME type
318     or wxFileSystem protocol.
319 
320     The available factories can be enumerated using
321     wxArchiveClassFactory::GetFirst() and wxArchiveClassFactory::GetNext().
322 
323     @library{wxbase}
324     @category{archive,streams}
325 
326     @see @ref overview_archive, @ref overview_archive_generic, wxArchiveEntry,
327          wxArchiveInputStream, wxArchiveOutputStream, wxFilterClassFactory
328 */
329 class wxArchiveClassFactory : public wxObject
330 {
331 public:
332     /**
333         Returns @true if this factory can handle the given protocol, MIME type
334         or file extension.
335 
336         When using wxSTREAM_FILEEXT for the second parameter, the first parameter
337         can be a complete filename rather than just an extension.
338     */
339     bool CanHandle(const wxString& protocol,
340                    wxStreamProtocolType type = wxSTREAM_PROTOCOL) const;
341 
342     /**
343         A static member that finds a factory that can handle a given protocol, MIME
344         type or file extension.  Returns a pointer to the class factory if found, or
345         @NULL otherwise. It does not give away ownership of the factory.
346 
347         When using wxSTREAM_FILEEXT for the second parameter, the first parameter
348         can be a complete filename rather than just an extension.
349     */
350     static const wxArchiveClassFactory* Find(const wxString& protocol,
351             wxStreamProtocolType type = wxSTREAM_PROTOCOL);
352 
353     /**
354         Returns the wxMBConv object that the created streams will use when
355         translating meta-data. The initial default, set by the constructor,
356         is wxConvLocal.
357     */
358     wxMBConv& GetConv() const;
359 
360     /**
361         Sets the wxMBConv object that the created streams will use when
362         translating meta-data.
363     */
364     void SetConv(wxMBConv& conv);
365 
366     //@{
367     /**
368         GetFirst and GetNext can be used to enumerate the available factories.
369         For example, to list them:
370 
371         @code
372         wxString list;
373         const wxArchiveClassFactory *factory = wxArchiveClassFactory::GetFirst();
374 
375         while (factory) {
376             list << factory->GetProtocol() << wxT("\n");
377             factory = factory->GetNext();
378         }
379         @endcode
380 
381         GetFirst() and GetNext() return a pointer to a factory or @NULL if no more
382         are available. They do not give away ownership of the factory.
383     */
384     static const wxArchiveClassFactory* GetFirst();
385     const wxArchiveClassFactory* GetNext() const;
386     //@}
387 
388     /**
389         Calls the static GetInternalName() function for the archive entry type,
390         for example wxZipEntry::GetInternalName.
391     */
392     virtual wxString GetInternalName(const wxString& name,
393                                      wxPathFormat format = wxPATH_NATIVE) const = 0;
394 
395     /**
396         Returns the wxFileSystem protocol supported by this factory.
397         Equivalent to @code wxString(*GetProtocols()) @endcode.
398     */
399     wxString GetProtocol() const;
400 
401     /**
402         Returns the protocols, MIME types or file extensions supported by this
403         factory, as an array of null terminated strings.
404 
405         It does not give away ownership of the array or strings.
406         For example, to list the file extensions a factory supports:
407 
408         @code
409         wxString list;
410         const wxChar *const *p;
411 
412         for (p = factory->GetProtocols(wxSTREAM_FILEEXT); *p; p++)
413             list << *p << wxT("\n");
414         @endcode
415     */
416     virtual const wxChar** GetProtocols(wxStreamProtocolType type = wxSTREAM_PROTOCOL) const = 0;
417 
418     /**
419         Create a new wxArchiveEntry object of the appropriate type.
420     */
421     wxArchiveEntry* NewEntry() const;
422 
423     //@{
424     /**
425         Create a new input or output stream to read or write an archive.
426 
427         If the parent stream is passed as a pointer then the new archive stream
428         takes ownership of it. If it is passed by reference then it does not.
429     */
430     wxArchiveInputStream* NewStream(wxInputStream& stream) const;
431     wxArchiveOutputStream* NewStream(wxOutputStream& stream) const;
432     wxArchiveInputStream* NewStream(wxInputStream* stream) const;
433     wxArchiveOutputStream* NewStream(wxOutputStream* stream) const;
434     //@}
435 
436     /**
437         Adds this class factory to the list returned by GetFirst() or GetNext().
438 
439         It is not necessary to do this to use the archive streams. It is usually
440         used when implementing streams, typically the implementation will
441         add a static instance of its factory class.
442 
443         It can also be used to change the order of a factory already in the list,
444         bringing it to the front. This isn't a thread safe operation
445         so can't be done when other threads are running that will be using the list.
446         The list does not take ownership of the factory.
447     */
448     void PushFront();
449 
450     /**
451         Removes this class factory from the list returned by GetFirst() and GetNext().
452 
453         Removing from the list isn't a thread safe operation so can't be done when
454         other threads are running that will be using the list.
455         The list does not own the factories, so removing a factory does not delete it.
456     */
457     void Remove();
458 };
459 
460 
461 
462 /**
463     @class wxArchiveNotifier
464 
465     If you need to know when a wxArchiveInputStream updates a wxArchiveEntry
466     object, you can create a notifier by deriving from this abstract base class,
467     overriding wxArchiveNotifier::OnEntryUpdated.
468 
469     An instance of your notifier class can then be assigned to the wxArchiveEntry
470     object using wxArchiveEntry::SetNotifier.
471     Your OnEntryUpdated() method will then be invoked whenever the input
472     stream updates the entry.
473 
474     Setting a notifier is not usually necessary. It is used to handle
475     certain cases when modifying an archive in a pipeline (i.e. between
476     non-seekable streams).
477     See @ref overview_archive_noseek.
478 
479     @library{wxbase}
480     @category{archive,streams}
481 
482     @see @ref overview_archive_noseek, wxArchiveEntry, wxArchiveInputStream,
483          wxArchiveOutputStream
484 */
485 class wxArchiveNotifier
486 {
487 public:
488     /**
489         This method must be overridden in your derived class.
490     */
491     virtual void OnEntryUpdated(wxArchiveEntry& entry) = 0;
492 };
493 
494 
495 
496 /**
497     @class wxArchiveIterator
498 
499     An input iterator template class that can be used to transfer an archive's
500     catalogue to a container. It is only available if wxUSE_STL is set to 1
501     in setup.h, and the uses for it outlined below require a compiler which
502     supports member templates.
503 
504     @code
505     template<class Arc, class T = typename Arc::entry_type*>
506     class wxArchiveIterator
507     {
508         // this constructor creates an 'end of sequence' object
509         wxArchiveIterator();
510 
511         // template parameter 'Arc' should be the type of an archive input stream
512         wxArchiveIterator(Arc& arc) {
513             // ...
514         }
515     };
516     @endcode
517 
518     The first template parameter should be the type of archive input stream
519     (e.g. wxArchiveInputStream) and the second can either be a pointer to an entry
520     (e.g. wxArchiveEntry*), or a string/pointer pair
521     (e.g. std::pair<wxString,wxArchiveEntry*>).
522 
523     The @c wx/archive.h header defines the following typedefs:
524 
525     @code
526     typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter;
527 
528     typedef wxArchiveIterator<wxArchiveInputStream,
529             std::pair<wxString, wxArchiveEntry*> > wxArchivePairIter;
530     @endcode
531 
532     The header for any implementation of this interface should define similar
533     typedefs for its types, for example in @c wx/zipstrm.h there is:
534 
535     @code
536     typedef wxArchiveIterator<wxZipInputStream> wxZipIter;
537 
538     typedef wxArchiveIterator<wxZipInputStream,
539              std::pair<wxString, wxZipEntry*> > wxZipPairIter;
540     @endcode
541 
542     Transferring the catalogue of an archive @e arc to a vector @e cat,
543     can then be done something like this:
544 
545     @code
546         std::vector<wxArchiveEntry*> cat((wxArchiveIter)arc, wxArchiveIter());
547     @endcode
548 
549     When the iterator is dereferenced, it gives away ownership of an entry
550     object. So in the above example, when you have finished with @e cat
551     you must delete the pointers it contains.
552 
553     If you have smart pointers with normal copy semantics (i.e. not auto_ptr
554     or wxScopedPtr), then you can create an iterator  which uses them instead.
555 
556     For example, with a smart pointer class for zip entries @e ZipEntryPtr:
557 
558     @code
559     typedef std::vector<ZipEntryPtr> ZipCatalog;
560     typedef wxArchiveIterator<wxZipInputStream, ZipEntryPtr> ZipIter;
561     ZipCatalog cat((ZipIter)zip, ZipIter());
562     @endcode
563 
564     Iterators that return std::pair objects can be used to populate a std::multimap,
565     to allow entries to be looked up by name.
566     The string is initialised using the wxArchiveEntry object's
567     wxArchiveEntry::GetInternalName function.
568 
569     @code
570     typedef std::multimap<wxString, wxZipEntry*> ZipCatalog;
571     ZipCatalog cat((wxZipPairIter)zip, wxZipPairIter());
572     @endcode
573 
574     Note that this iterator also gives away ownership of an entry
575     object each time it is dereferenced. So in the above example, when
576     you have finished with @e cat you must delete the pointers it contains.
577 
578     Or if you have them, a pair containing a smart pointer can be used
579     (again @e ZipEntryPtr), no worries about ownership:
580 
581     @code
582     typedef std::multimap<wxString, ZipEntryPtr> ZipCatalog;
583     typedef wxArchiveIterator<wxZipInputStream,
584                 std::pair<wxString, ZipEntryPtr> > ZipPairIter;
585     ZipCatalog cat((ZipPairIter)zip, ZipPairIter());
586     @endcode
587 
588     @library{wxbase}
589     @category{archive,streams}
590 
591     @see wxArchiveEntry, wxArchiveInputStream, wxArchiveOutputStream
592 */
593 class wxArchiveIterator
594 {
595 public:
596     /**
597         Default constructor.
598     */
599     wxArchiveIterator();
600 
601     /**
602         Construct the iterator that returns all the entries in the archive input
603         stream @a arc.
604     */
605     wxArchiveIterator(Arc& arc);
606 
607     /**
608         Returns an entry object from the archive input stream, giving away
609         ownership.
610     */
611     const T operator*() const;
612 
613     //@{
614     /**
615         Position the input iterator at the next entry in the archive input stream.
616     */
617     wxArchiveIterator operator++();
618     wxArchiveIterator operator++(int);
619     //@}
620 };
621 
622