1///////////////////////////////////////////////////////////////////////////// 2// Name: wx/archive.h 3// Purpose: Streams for archive formats 4// Author: Mike Wetherell 5// RCS-ID: $Id: archive.h 43445 2006-11-16 14:30:20Z MW $ 6// Copyright: (c) 2004 Mike Wetherell 7// Licence: wxWindows licence 8///////////////////////////////////////////////////////////////////////////// 9 10#ifndef _WX_ARCHIVE_H__ 11#define _WX_ARCHIVE_H__ 12 13#include "wx/defs.h" 14 15#if wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS 16 17#include "wx/stream.h" 18#include "wx/filename.h" 19 20 21///////////////////////////////////////////////////////////////////////////// 22// wxArchiveNotifier 23 24class WXDLLIMPEXP_BASE wxArchiveNotifier 25{ 26public: 27 virtual ~wxArchiveNotifier() { } 28 29 virtual void OnEntryUpdated(class wxArchiveEntry& entry) = 0; 30}; 31 32 33///////////////////////////////////////////////////////////////////////////// 34// wxArchiveEntry 35// 36// Holds an entry's meta data, such as filename and timestamp. 37 38class WXDLLIMPEXP_BASE wxArchiveEntry : public wxObject 39{ 40public: 41 virtual ~wxArchiveEntry() { } 42 43 virtual wxDateTime GetDateTime() const = 0; 44 virtual wxFileOffset GetSize() const = 0; 45 virtual wxFileOffset GetOffset() const = 0; 46 virtual bool IsDir() const = 0; 47 virtual bool IsReadOnly() const = 0; 48 virtual wxString GetInternalName() const = 0; 49 virtual wxPathFormat GetInternalFormat() const = 0; 50 virtual wxString GetName(wxPathFormat format = wxPATH_NATIVE) const = 0; 51 52 virtual void SetDateTime(const wxDateTime& dt) = 0; 53 virtual void SetSize(wxFileOffset size) = 0; 54 virtual void SetIsDir(bool isDir = true) = 0; 55 virtual void SetIsReadOnly(bool isReadOnly = true) = 0; 56 virtual void SetName(const wxString& name, 57 wxPathFormat format = wxPATH_NATIVE) = 0; 58 59 wxArchiveEntry *Clone() const { return DoClone(); } 60 61 void SetNotifier(wxArchiveNotifier& notifier); 62 virtual void UnsetNotifier() { m_notifier = NULL; } 63 64protected: 65 wxArchiveEntry() : m_notifier(NULL) { } 66 wxArchiveEntry(const wxArchiveEntry& e) : wxObject(e), m_notifier(NULL) { } 67 68 virtual void SetOffset(wxFileOffset offset) = 0; 69 virtual wxArchiveEntry* DoClone() const = 0; 70 71 wxArchiveNotifier *GetNotifier() const { return m_notifier; } 72 wxArchiveEntry& operator=(const wxArchiveEntry& entry); 73 74private: 75 wxArchiveNotifier *m_notifier; 76 77 DECLARE_ABSTRACT_CLASS(wxArchiveEntry) 78}; 79 80 81///////////////////////////////////////////////////////////////////////////// 82// wxArchiveInputStream 83// 84// GetNextEntry() returns an wxArchiveEntry object containing the meta-data 85// for the next entry in the archive (and gives away ownership). Reading from 86// the wxArchiveInputStream then returns the entry's data. Eof() becomes true 87// after an attempt has been made to read past the end of the entry's data. 88// 89// When there are no more entries, GetNextEntry() returns NULL and sets Eof(). 90 91class WXDLLIMPEXP_BASE wxArchiveInputStream : public wxFilterInputStream 92{ 93public: 94 typedef wxArchiveEntry entry_type; 95 96 virtual ~wxArchiveInputStream() { } 97 98 virtual bool OpenEntry(wxArchiveEntry& entry) = 0; 99 virtual bool CloseEntry() = 0; 100 101 wxArchiveEntry *GetNextEntry() { return DoGetNextEntry(); } 102 103 virtual char Peek() { return wxInputStream::Peek(); } 104 105protected: 106 wxArchiveInputStream(wxInputStream& stream, wxMBConv& conv); 107 wxArchiveInputStream(wxInputStream *stream, wxMBConv& conv); 108 109 virtual wxArchiveEntry *DoGetNextEntry() = 0; 110 111 wxMBConv& GetConv() const { return m_conv; } 112 113private: 114 wxMBConv& m_conv; 115}; 116 117 118///////////////////////////////////////////////////////////////////////////// 119// wxArchiveOutputStream 120// 121// PutNextEntry is used to create a new entry in the output archive, then 122// the entry's data is written to the wxArchiveOutputStream. 123// 124// Only one entry can be open for output at a time; another call to 125// PutNextEntry closes the current entry and begins the next. 126// 127// The overload 'bool PutNextEntry(wxArchiveEntry *entry)' takes ownership 128// of the entry object. 129 130class WXDLLIMPEXP_BASE wxArchiveOutputStream : public wxFilterOutputStream 131{ 132public: 133 virtual ~wxArchiveOutputStream() { } 134 135 virtual bool PutNextEntry(wxArchiveEntry *entry) = 0; 136 137 virtual bool PutNextEntry(const wxString& name, 138 const wxDateTime& dt = wxDateTime::Now(), 139 wxFileOffset size = wxInvalidOffset) = 0; 140 141 virtual bool PutNextDirEntry(const wxString& name, 142 const wxDateTime& dt = wxDateTime::Now()) = 0; 143 144 virtual bool CopyEntry(wxArchiveEntry *entry, 145 wxArchiveInputStream& stream) = 0; 146 147 virtual bool CopyArchiveMetaData(wxArchiveInputStream& stream) = 0; 148 149 virtual bool CloseEntry() = 0; 150 151protected: 152 wxArchiveOutputStream(wxOutputStream& stream, wxMBConv& conv); 153 wxArchiveOutputStream(wxOutputStream *stream, wxMBConv& conv); 154 155 wxMBConv& GetConv() const { return m_conv; } 156 157private: 158 wxMBConv& m_conv; 159}; 160 161 162///////////////////////////////////////////////////////////////////////////// 163// wxArchiveIterator 164// 165// An input iterator that can be used to transfer an archive's catalog to 166// a container. 167 168#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR 169#include <iterator> 170#include <utility> 171 172template <class X, class Y> inline 173void _wxSetArchiveIteratorValue( 174 X& val, Y entry, void *WXUNUSED(d)) 175{ 176 val = X(entry); 177} 178template <class X, class Y, class Z> inline 179void _wxSetArchiveIteratorValue( 180 std::pair<X, Y>& val, Z entry, Z WXUNUSED(d)) 181{ 182 val = std::make_pair(X(entry->GetInternalName()), Y(entry)); 183} 184 185#if defined _MSC_VER && _MSC_VER < 1300 186template <class Arc, class T = Arc::entry_type*> 187#else 188template <class Arc, class T = typename Arc::entry_type*> 189#endif 190class wxArchiveIterator 191{ 192public: 193 typedef std::input_iterator_tag iterator_category; 194 typedef T value_type; 195 typedef ptrdiff_t difference_type; 196 typedef T* pointer; 197 typedef T& reference; 198 199 wxArchiveIterator() : m_rep(NULL) { } 200 201 wxArchiveIterator(Arc& arc) { 202 typename Arc::entry_type* entry = arc.GetNextEntry(); 203 m_rep = entry ? new Rep(arc, entry) : NULL; 204 } 205 206 wxArchiveIterator(const wxArchiveIterator& it) : m_rep(it.m_rep) { 207 if (m_rep) 208 m_rep->AddRef(); 209 } 210 211 ~wxArchiveIterator() { 212 if (m_rep) 213 m_rep->UnRef(); 214 } 215 216 const T& operator *() const { 217 return m_rep->GetValue(); 218 } 219 220 const T* operator ->() const { 221 return &**this; 222 } 223 224 wxArchiveIterator& operator =(const wxArchiveIterator& it) { 225 if (it.m_rep) 226 it.m_rep.AddRef(); 227 if (m_rep) 228 m_rep.UnRef(); 229 m_rep = it.m_rep; 230 return *this; 231 } 232 233 wxArchiveIterator& operator ++() { 234 m_rep = m_rep->Next(); 235 return *this; 236 } 237 238 wxArchiveIterator operator ++(int) { 239 wxArchiveIterator it(*this); 240 ++(*this); 241 return it; 242 } 243 244 bool operator ==(const wxArchiveIterator& j) const { 245 return m_rep == j.m_rep; 246 } 247 248 bool operator !=(const wxArchiveIterator& j) const { 249 return !(*this == j); 250 } 251 252private: 253 class Rep { 254 Arc& m_arc; 255 typename Arc::entry_type* m_entry; 256 T m_value; 257 int m_ref; 258 259 public: 260 Rep(Arc& arc, typename Arc::entry_type* entry) 261 : m_arc(arc), m_entry(entry), m_value(), m_ref(1) { } 262 ~Rep() 263 { delete m_entry; } 264 265 void AddRef() { 266 m_ref++; 267 } 268 269 void UnRef() { 270 if (--m_ref == 0) 271 delete this; 272 } 273 274 Rep *Next() { 275 typename Arc::entry_type* entry = m_arc.GetNextEntry(); 276 if (!entry) { 277 UnRef(); 278 return NULL; 279 } 280 if (m_ref > 1) { 281 m_ref--; 282 return new Rep(m_arc, entry); 283 } 284 delete m_entry; 285 m_entry = entry; 286 m_value = T(); 287 return this; 288 } 289 290 const T& GetValue() { 291 if (m_entry) { 292 _wxSetArchiveIteratorValue(m_value, m_entry, m_entry); 293 m_entry = NULL; 294 } 295 return m_value; 296 } 297 } *m_rep; 298}; 299 300typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter; 301typedef wxArchiveIterator<wxArchiveInputStream, 302 std::pair<wxString, wxArchiveEntry*> > wxArchivePairIter; 303 304#endif // wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR 305 306 307///////////////////////////////////////////////////////////////////////////// 308// wxArchiveClassFactory 309// 310// A wxArchiveClassFactory instance for a particular archive type allows 311// the creation of the other classes that may be needed. 312 313void WXDLLIMPEXP_BASE wxUseArchiveClasses(); 314 315class WXDLLIMPEXP_BASE wxArchiveClassFactory : public wxFilterClassFactoryBase 316{ 317public: 318 typedef wxArchiveEntry entry_type; 319 typedef wxArchiveInputStream instream_type; 320 typedef wxArchiveOutputStream outstream_type; 321 typedef wxArchiveNotifier notifier_type; 322#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR 323 typedef wxArchiveIter iter_type; 324 typedef wxArchivePairIter pairiter_type; 325#endif 326 327 virtual ~wxArchiveClassFactory() { } 328 329 wxArchiveEntry *NewEntry() const 330 { return DoNewEntry(); } 331 wxArchiveInputStream *NewStream(wxInputStream& stream) const 332 { return DoNewStream(stream); } 333 wxArchiveOutputStream *NewStream(wxOutputStream& stream) const 334 { return DoNewStream(stream); } 335 wxArchiveInputStream *NewStream(wxInputStream *stream) const 336 { return DoNewStream(stream); } 337 wxArchiveOutputStream *NewStream(wxOutputStream *stream) const 338 { return DoNewStream(stream); } 339 340 virtual wxString GetInternalName( 341 const wxString& name, 342 wxPathFormat format = wxPATH_NATIVE) const = 0; 343 344 void SetConv(wxMBConv& conv) { m_pConv = &conv; } 345 wxMBConv& GetConv() const 346 { if (m_pConv) return *m_pConv; else return wxConvLocal; } 347 348 static const wxArchiveClassFactory *Find(const wxChar *protocol, 349 wxStreamProtocolType type 350 = wxSTREAM_PROTOCOL); 351 352 static const wxArchiveClassFactory *GetFirst(); 353 const wxArchiveClassFactory *GetNext() const { return m_next; } 354 355 void PushFront() { Remove(); m_next = sm_first; sm_first = this; } 356 void Remove(); 357 358protected: 359 // old compilers don't support covarient returns, so 'Do' methods are 360 // used to simulate them 361 virtual wxArchiveEntry *DoNewEntry() const = 0; 362 virtual wxArchiveInputStream *DoNewStream(wxInputStream& stream) const = 0; 363 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const = 0; 364 virtual wxArchiveInputStream *DoNewStream(wxInputStream *stream) const = 0; 365 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const = 0; 366 367 wxArchiveClassFactory() : m_pConv(NULL), m_next(this) { } 368 wxArchiveClassFactory& operator=(const wxArchiveClassFactory& WXUNUSED(f)) 369 { return *this; } 370 371private: 372 wxMBConv *m_pConv; 373 static wxArchiveClassFactory *sm_first; 374 wxArchiveClassFactory *m_next; 375 376 DECLARE_ABSTRACT_CLASS(wxArchiveClassFactory) 377}; 378 379#endif // wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS 380 381#endif // _WX_ARCHIVE_H__ 382