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