]> git.saurik.com Git - wxWidgets.git/blame - include/wx/archive.h
Prevent seg fault for older GTK+
[wxWidgets.git] / include / wx / archive.h
CommitLineData
00375592 1/////////////////////////////////////////////////////////////////////////////
ce7208d4 2// Name: wx/archive.h
00375592
VZ
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
00375592
VZ
13#include "wx/defs.h"
14
9e8e867f 15#if wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
00375592
VZ
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;
ce7208d4 58
00375592
VZ
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) { }
f44eaed6 66 wxArchiveEntry(const wxArchiveEntry& e) : wxObject(e), m_notifier(NULL) { }
00375592
VZ
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() { }
ce7208d4 97
00375592
VZ
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(); }
ce7208d4 104
00375592
VZ
105protected:
106 wxArchiveInputStream(wxInputStream& stream, wxMBConv& conv);
1b79dad4 107 wxArchiveInputStream(wxInputStream *stream, wxMBConv& conv);
00375592
VZ
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.
ce7208d4 126//
00375592
VZ
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;
00375592
VZ
150
151protected:
152 wxArchiveOutputStream(wxOutputStream& stream, wxMBConv& conv);
1b79dad4 153 wxArchiveOutputStream(wxOutputStream *stream, wxMBConv& conv);
00375592
VZ
154
155 wxMBConv& GetConv() const { return m_conv; }
156
157private:
158 wxMBConv& m_conv;
159};
160
161
00375592
VZ
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
f44eaed6
RN
172template <class X, class Y> inline
173void _wxSetArchiveIteratorValue(
00375592
VZ
174 X& val, Y entry, void *WXUNUSED(d))
175{
176 val = X(entry);
177}
f44eaed6
RN
178template <class X, class Y, class Z> inline
179void _wxSetArchiveIteratorValue(
00375592
VZ
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
f44eaed6 190class wxArchiveIterator
00375592
VZ
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 }
ce7208d4 210
00375592
VZ
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
f44eaed6
RN
244 bool operator ==(const wxArchiveIterator& j) const {
245 return m_rep == j.m_rep;
00375592
VZ
246 }
247
f44eaed6 248 bool operator !=(const wxArchiveIterator& j) const {
95662a83 249 return !(*this == j);
00375592
VZ
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;
ce7208d4 258
00375592
VZ
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; }
ce7208d4 264
00375592
VZ
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) {
ce7208d4 281 m_ref--;
00375592
VZ
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
81f90336
MW
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
1b79dad4
MW
313void WXDLLIMPEXP_BASE wxUseArchiveClasses();
314
315class WXDLLIMPEXP_BASE wxArchiveClassFactory : public wxFilterClassFactoryBase
81f90336
MW
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); }
1b79dad4
MW
335 wxArchiveInputStream *NewStream(wxInputStream *stream) const
336 { return DoNewStream(stream); }
337 wxArchiveOutputStream *NewStream(wxOutputStream *stream) const
338 { return DoNewStream(stream); }
81f90336
MW
339
340 virtual wxString GetInternalName(
341 const wxString& name,
342 wxPathFormat format = wxPATH_NATIVE) const = 0;
343
5487ff0f
VS
344 // FIXME-UTF8: remove these from this file, they are used for ANSI
345 // build only
81f90336 346 void SetConv(wxMBConv& conv) { m_pConv = &conv; }
80e62471
MW
347 wxMBConv& GetConv() const
348 { if (m_pConv) return *m_pConv; else return wxConvLocal; }
81f90336 349
86501081 350 static const wxArchiveClassFactory *Find(const wxString& protocol,
1b79dad4
MW
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
81f90336 360protected:
eedf3bcb
MW
361 // old compilers don't support covarient returns, so 'Do' methods are
362 // used to simulate them
81f90336
MW
363 virtual wxArchiveEntry *DoNewEntry() const = 0;
364 virtual wxArchiveInputStream *DoNewStream(wxInputStream& stream) const = 0;
365 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const = 0;
1b79dad4
MW
366 virtual wxArchiveInputStream *DoNewStream(wxInputStream *stream) const = 0;
367 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const = 0;
81f90336 368
80e62471 369 wxArchiveClassFactory() : m_pConv(NULL), m_next(this) { }
81f90336
MW
370 wxArchiveClassFactory& operator=(const wxArchiveClassFactory& WXUNUSED(f))
371 { return *this; }
372
373private:
374 wxMBConv *m_pConv;
1b79dad4
MW
375 static wxArchiveClassFactory *sm_first;
376 wxArchiveClassFactory *m_next;
81f90336
MW
377
378 DECLARE_ABSTRACT_CLASS(wxArchiveClassFactory)
379};
380
9e8e867f 381#endif // wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
00375592
VZ
382
383#endif // _WX_ARCHIVE_H__