]> git.saurik.com Git - wxWidgets.git/blob - include/wx/archive.h
cd8438972dd2a01ae2b114bbc520f0a18486a6b3
[wxWidgets.git] / include / wx / archive.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/archive.h
3 // Purpose: Streams for archive formats
4 // Author: Mike Wetherell
5 // RCS-ID: $Id$
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
24 class WXDLLIMPEXP_BASE wxArchiveNotifier
25 {
26 public:
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
38 class WXDLLIMPEXP_BASE wxArchiveEntry : public wxObject
39 {
40 public:
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
64 protected:
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
74 private:
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
91 class WXDLLIMPEXP_BASE wxArchiveInputStream : public wxFilterInputStream
92 {
93 public:
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
105 protected:
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
113 private:
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
130 class WXDLLIMPEXP_BASE wxArchiveOutputStream : public wxFilterOutputStream
131 {
132 public:
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
151 protected:
152 wxArchiveOutputStream(wxOutputStream& stream, wxMBConv& conv);
153 wxArchiveOutputStream(wxOutputStream *stream, wxMBConv& conv);
154
155 wxMBConv& GetConv() const { return m_conv; }
156
157 private:
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
172 template <class X, class Y> inline
173 void _wxSetArchiveIteratorValue(
174 X& val, Y entry, void *WXUNUSED(d))
175 {
176 val = X(entry);
177 }
178 template <class X, class Y, class Z> inline
179 void _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
186 template <class Arc, class T = Arc::entry_type*>
187 #else
188 template <class Arc, class T = typename Arc::entry_type*>
189 #endif
190 class wxArchiveIterator
191 {
192 public:
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 this->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
252 private:
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
300 typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter;
301 typedef 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
313 void WXDLLIMPEXP_BASE wxUseArchiveClasses();
314
315 class WXDLLIMPEXP_BASE wxArchiveClassFactory : public wxFilterClassFactoryBase
316 {
317 public:
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 // FIXME-UTF8: remove these from this file, they are used for ANSI
345 // build only
346 void SetConv(wxMBConv& conv) { m_pConv = &conv; }
347 wxMBConv& GetConv() const
348 { if (m_pConv) return *m_pConv; else return wxConvLocal; }
349
350 static const wxArchiveClassFactory *Find(const wxString& protocol,
351 wxStreamProtocolType type
352 = wxSTREAM_PROTOCOL);
353
354 static const wxArchiveClassFactory *GetFirst();
355 const wxArchiveClassFactory *GetNext() const { return m_next; }
356
357 void PushFront() { Remove(); m_next = sm_first; sm_first = this; }
358 void Remove();
359
360 protected:
361 // old compilers don't support covarient returns, so 'Do' methods are
362 // used to simulate them
363 virtual wxArchiveEntry *DoNewEntry() const = 0;
364 virtual wxArchiveInputStream *DoNewStream(wxInputStream& stream) const = 0;
365 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const = 0;
366 virtual wxArchiveInputStream *DoNewStream(wxInputStream *stream) const = 0;
367 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const = 0;
368
369 wxArchiveClassFactory() : m_pConv(NULL), m_next(this) { }
370 wxArchiveClassFactory& operator=(const wxArchiveClassFactory& WXUNUSED(f))
371 { return *this; }
372
373 private:
374 wxMBConv *m_pConv;
375 static wxArchiveClassFactory *sm_first;
376 wxArchiveClassFactory *m_next;
377
378 DECLARE_ABSTRACT_CLASS(wxArchiveClassFactory)
379 };
380
381 #endif // wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
382
383 #endif // _WX_ARCHIVE_H__