]> git.saurik.com Git - wxWidgets.git/blob - include/wx/archive.h
Fixed ReadLine missing last character from text files with no final newline.
[wxWidgets.git] / include / wx / archive.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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
108 virtual wxArchiveEntry *DoGetNextEntry() = 0;
109
110 wxMBConv& GetConv() const { return m_conv; }
111
112 private:
113 wxMBConv& m_conv;
114 };
115
116
117 /////////////////////////////////////////////////////////////////////////////
118 // wxArchiveOutputStream
119 //
120 // PutNextEntry is used to create a new entry in the output archive, then
121 // the entry's data is written to the wxArchiveOutputStream.
122 //
123 // Only one entry can be open for output at a time; another call to
124 // PutNextEntry closes the current entry and begins the next.
125 //
126 // The overload 'bool PutNextEntry(wxArchiveEntry *entry)' takes ownership
127 // of the entry object.
128
129 class WXDLLIMPEXP_BASE wxArchiveOutputStream : public wxFilterOutputStream
130 {
131 public:
132 virtual ~wxArchiveOutputStream() { }
133
134 virtual bool PutNextEntry(wxArchiveEntry *entry) = 0;
135
136 virtual bool PutNextEntry(const wxString& name,
137 const wxDateTime& dt = wxDateTime::Now(),
138 wxFileOffset size = wxInvalidOffset) = 0;
139
140 virtual bool PutNextDirEntry(const wxString& name,
141 const wxDateTime& dt = wxDateTime::Now()) = 0;
142
143 virtual bool CopyEntry(wxArchiveEntry *entry,
144 wxArchiveInputStream& stream) = 0;
145
146 virtual bool CopyArchiveMetaData(wxArchiveInputStream& stream) = 0;
147
148 virtual bool CloseEntry() = 0;
149
150 protected:
151 wxArchiveOutputStream(wxOutputStream& stream, wxMBConv& conv);
152
153 wxMBConv& GetConv() const { return m_conv; }
154
155 private:
156 wxMBConv& m_conv;
157 };
158
159
160 /////////////////////////////////////////////////////////////////////////////
161 // wxArchiveIterator
162 //
163 // An input iterator that can be used to transfer an archive's catalog to
164 // a container.
165
166 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
167 #include <iterator>
168 #include <utility>
169
170 template <class X, class Y> inline
171 void _wxSetArchiveIteratorValue(
172 X& val, Y entry, void *WXUNUSED(d))
173 {
174 val = X(entry);
175 }
176 template <class X, class Y, class Z> inline
177 void _wxSetArchiveIteratorValue(
178 std::pair<X, Y>& val, Z entry, Z WXUNUSED(d))
179 {
180 val = std::make_pair(X(entry->GetInternalName()), Y(entry));
181 }
182
183 #if defined _MSC_VER && _MSC_VER < 1300
184 template <class Arc, class T = Arc::entry_type*>
185 #else
186 template <class Arc, class T = typename Arc::entry_type*>
187 #endif
188 class wxArchiveIterator
189 {
190 public:
191 typedef std::input_iterator_tag iterator_category;
192 typedef T value_type;
193 typedef ptrdiff_t difference_type;
194 typedef T* pointer;
195 typedef T& reference;
196
197 wxArchiveIterator() : m_rep(NULL) { }
198
199 wxArchiveIterator(Arc& arc) {
200 typename Arc::entry_type* entry = arc.GetNextEntry();
201 m_rep = entry ? new Rep(arc, entry) : NULL;
202 }
203
204 wxArchiveIterator(const wxArchiveIterator& it) : m_rep(it.m_rep) {
205 if (m_rep)
206 m_rep->AddRef();
207 }
208
209 ~wxArchiveIterator() {
210 if (m_rep)
211 m_rep->UnRef();
212 }
213
214 const T& operator *() const {
215 return m_rep->GetValue();
216 }
217
218 const T* operator ->() const {
219 return &**this;
220 }
221
222 wxArchiveIterator& operator =(const wxArchiveIterator& it) {
223 if (it.m_rep)
224 it.m_rep.AddRef();
225 if (m_rep)
226 m_rep.UnRef();
227 m_rep = it.m_rep;
228 return *this;
229 }
230
231 wxArchiveIterator& operator ++() {
232 m_rep = m_rep->Next();
233 return *this;
234 }
235
236 wxArchiveIterator operator ++(int) {
237 wxArchiveIterator it(*this);
238 ++(*this);
239 return it;
240 }
241
242 bool operator ==(const wxArchiveIterator& j) const {
243 return m_rep == j.m_rep;
244 }
245
246 bool operator !=(const wxArchiveIterator& j) const {
247 return !(*this == j);
248 }
249
250 private:
251 class Rep {
252 Arc& m_arc;
253 typename Arc::entry_type* m_entry;
254 T m_value;
255 int m_ref;
256
257 public:
258 Rep(Arc& arc, typename Arc::entry_type* entry)
259 : m_arc(arc), m_entry(entry), m_value(), m_ref(1) { }
260 ~Rep()
261 { delete m_entry; }
262
263 void AddRef() {
264 m_ref++;
265 }
266
267 void UnRef() {
268 if (--m_ref == 0)
269 delete this;
270 }
271
272 Rep *Next() {
273 typename Arc::entry_type* entry = m_arc.GetNextEntry();
274 if (!entry) {
275 UnRef();
276 return NULL;
277 }
278 if (m_ref > 1) {
279 m_ref--;
280 return new Rep(m_arc, entry);
281 }
282 delete m_entry;
283 m_entry = entry;
284 m_value = T();
285 return this;
286 }
287
288 const T& GetValue() {
289 if (m_entry) {
290 _wxSetArchiveIteratorValue(m_value, m_entry, m_entry);
291 m_entry = NULL;
292 }
293 return m_value;
294 }
295 } *m_rep;
296 };
297
298 typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter;
299 typedef wxArchiveIterator<wxArchiveInputStream,
300 std::pair<wxString, wxArchiveEntry*> > wxArchivePairIter;
301
302 #endif // wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
303
304
305 /////////////////////////////////////////////////////////////////////////////
306 // wxArchiveClassFactory
307 //
308 // A wxArchiveClassFactory instance for a particular archive type allows
309 // the creation of the other classes that may be needed.
310
311 class WXDLLIMPEXP_BASE wxArchiveClassFactory : public wxObject
312 {
313 public:
314 typedef wxArchiveEntry entry_type;
315 typedef wxArchiveInputStream instream_type;
316 typedef wxArchiveOutputStream outstream_type;
317 typedef wxArchiveNotifier notifier_type;
318 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
319 typedef wxArchiveIter iter_type;
320 typedef wxArchivePairIter pairiter_type;
321 #endif
322
323 virtual ~wxArchiveClassFactory() { }
324
325 wxArchiveEntry *NewEntry() const
326 { return DoNewEntry(); }
327 wxArchiveInputStream *NewStream(wxInputStream& stream) const
328 { return DoNewStream(stream); }
329 wxArchiveOutputStream *NewStream(wxOutputStream& stream) const
330 { return DoNewStream(stream); }
331
332 virtual wxString GetInternalName(
333 const wxString& name,
334 wxPathFormat format = wxPATH_NATIVE) const = 0;
335
336 void SetConv(wxMBConv& conv) { m_pConv = &conv; }
337 wxMBConv& GetConv() const { return *m_pConv; }
338
339 protected:
340 // old compilers don't support covarient returns, so 'Do' methods are
341 // used to simulate them
342 virtual wxArchiveEntry *DoNewEntry() const = 0;
343 virtual wxArchiveInputStream *DoNewStream(wxInputStream& stream) const = 0;
344 virtual wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const = 0;
345
346 wxArchiveClassFactory() : m_pConv(&wxConvLocal) { }
347 wxArchiveClassFactory& operator=(const wxArchiveClassFactory& WXUNUSED(f))
348 { return *this; }
349
350 private:
351 wxMBConv *m_pConv;
352
353 DECLARE_ABSTRACT_CLASS(wxArchiveClassFactory)
354 };
355
356 #endif // wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
357
358 #endif // _WX_ARCHIVE_H__