1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Streams for archive formats
4 // Author: Mike Wetherell
5 // Copyright: (c) 2004 Mike Wetherell
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 #ifndef _WX_ARCHIVE_H__
10 #define _WX_ARCHIVE_H__
14 #if wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
16 #include "wx/stream.h"
17 #include "wx/filename.h"
20 /////////////////////////////////////////////////////////////////////////////
23 class WXDLLIMPEXP_BASE wxArchiveNotifier
26 virtual ~wxArchiveNotifier() { }
28 virtual void OnEntryUpdated(class wxArchiveEntry
& entry
) = 0;
32 /////////////////////////////////////////////////////////////////////////////
35 // Holds an entry's meta data, such as filename and timestamp.
37 class WXDLLIMPEXP_BASE wxArchiveEntry
: public wxObject
40 virtual ~wxArchiveEntry() { }
42 virtual wxDateTime
GetDateTime() const = 0;
43 virtual wxFileOffset
GetSize() const = 0;
44 virtual wxFileOffset
GetOffset() const = 0;
45 virtual bool IsDir() const = 0;
46 virtual bool IsReadOnly() const = 0;
47 virtual wxString
GetInternalName() const = 0;
48 virtual wxPathFormat
GetInternalFormat() const = 0;
49 virtual wxString
GetName(wxPathFormat format
= wxPATH_NATIVE
) const = 0;
51 virtual void SetDateTime(const wxDateTime
& dt
) = 0;
52 virtual void SetSize(wxFileOffset size
) = 0;
53 virtual void SetIsDir(bool isDir
= true) = 0;
54 virtual void SetIsReadOnly(bool isReadOnly
= true) = 0;
55 virtual void SetName(const wxString
& name
,
56 wxPathFormat format
= wxPATH_NATIVE
) = 0;
58 wxArchiveEntry
*Clone() const { return DoClone(); }
60 void SetNotifier(wxArchiveNotifier
& notifier
);
61 virtual void UnsetNotifier() { m_notifier
= NULL
; }
64 wxArchiveEntry() : m_notifier(NULL
) { }
65 wxArchiveEntry(const wxArchiveEntry
& e
) : wxObject(e
), m_notifier(NULL
) { }
67 virtual void SetOffset(wxFileOffset offset
) = 0;
68 virtual wxArchiveEntry
* DoClone() const = 0;
70 wxArchiveNotifier
*GetNotifier() const { return m_notifier
; }
71 wxArchiveEntry
& operator=(const wxArchiveEntry
& entry
);
74 wxArchiveNotifier
*m_notifier
;
76 DECLARE_ABSTRACT_CLASS(wxArchiveEntry
)
80 /////////////////////////////////////////////////////////////////////////////
81 // wxArchiveInputStream
83 // GetNextEntry() returns an wxArchiveEntry object containing the meta-data
84 // for the next entry in the archive (and gives away ownership). Reading from
85 // the wxArchiveInputStream then returns the entry's data. Eof() becomes true
86 // after an attempt has been made to read past the end of the entry's data.
88 // When there are no more entries, GetNextEntry() returns NULL and sets Eof().
90 class WXDLLIMPEXP_BASE wxArchiveInputStream
: public wxFilterInputStream
93 typedef wxArchiveEntry entry_type
;
95 virtual ~wxArchiveInputStream() { }
97 virtual bool OpenEntry(wxArchiveEntry
& entry
) = 0;
98 virtual bool CloseEntry() = 0;
100 wxArchiveEntry
*GetNextEntry() { return DoGetNextEntry(); }
102 virtual char Peek() { return wxInputStream::Peek(); }
105 wxArchiveInputStream(wxInputStream
& stream
, wxMBConv
& conv
);
106 wxArchiveInputStream(wxInputStream
*stream
, wxMBConv
& conv
);
108 virtual wxArchiveEntry
*DoGetNextEntry() = 0;
110 wxMBConv
& GetConv() const { return m_conv
; }
117 /////////////////////////////////////////////////////////////////////////////
118 // wxArchiveOutputStream
120 // PutNextEntry is used to create a new entry in the output archive, then
121 // the entry's data is written to the wxArchiveOutputStream.
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.
126 // The overload 'bool PutNextEntry(wxArchiveEntry *entry)' takes ownership
127 // of the entry object.
129 class WXDLLIMPEXP_BASE wxArchiveOutputStream
: public wxFilterOutputStream
132 virtual ~wxArchiveOutputStream() { }
134 virtual bool PutNextEntry(wxArchiveEntry
*entry
) = 0;
136 virtual bool PutNextEntry(const wxString
& name
,
137 const wxDateTime
& dt
= wxDateTime::Now(),
138 wxFileOffset size
= wxInvalidOffset
) = 0;
140 virtual bool PutNextDirEntry(const wxString
& name
,
141 const wxDateTime
& dt
= wxDateTime::Now()) = 0;
143 virtual bool CopyEntry(wxArchiveEntry
*entry
,
144 wxArchiveInputStream
& stream
) = 0;
146 virtual bool CopyArchiveMetaData(wxArchiveInputStream
& stream
) = 0;
148 virtual bool CloseEntry() = 0;
151 wxArchiveOutputStream(wxOutputStream
& stream
, wxMBConv
& conv
);
152 wxArchiveOutputStream(wxOutputStream
*stream
, wxMBConv
& conv
);
154 wxMBConv
& GetConv() const { return m_conv
; }
161 /////////////////////////////////////////////////////////////////////////////
164 // An input iterator that can be used to transfer an archive's catalog to
167 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
171 template <class X
, class Y
> inline
172 void _wxSetArchiveIteratorValue(
173 X
& val
, Y entry
, void *WXUNUSED(d
))
177 template <class X
, class Y
, class Z
> inline
178 void _wxSetArchiveIteratorValue(
179 std::pair
<X
, Y
>& val
, Z entry
, Z
WXUNUSED(d
))
181 val
= std::make_pair(X(entry
->GetInternalName()), Y(entry
));
184 #if defined _MSC_VER && _MSC_VER < 1300
185 template <class Arc
, class T
= Arc::entry_type
*>
187 template <class Arc
, class T
= typename
Arc::entry_type
*>
189 class wxArchiveIterator
192 typedef std::input_iterator_tag iterator_category
;
193 typedef T value_type
;
194 typedef ptrdiff_t difference_type
;
196 typedef T
& reference
;
198 wxArchiveIterator() : m_rep(NULL
) { }
200 wxArchiveIterator(Arc
& arc
) {
201 typename
Arc::entry_type
* entry
= arc
.GetNextEntry();
202 m_rep
= entry
? new Rep(arc
, entry
) : NULL
;
205 wxArchiveIterator(const wxArchiveIterator
& it
) : m_rep(it
.m_rep
) {
210 ~wxArchiveIterator() {
215 const T
& operator *() const {
216 return m_rep
->GetValue();
219 const T
* operator ->() const {
223 wxArchiveIterator
& operator =(const wxArchiveIterator
& it
) {
232 wxArchiveIterator
& operator ++() {
233 m_rep
= m_rep
->Next();
237 wxArchiveIterator
operator ++(int) {
238 wxArchiveIterator
it(*this);
243 bool operator ==(const wxArchiveIterator
& j
) const {
244 return m_rep
== j
.m_rep
;
247 bool operator !=(const wxArchiveIterator
& j
) const {
248 return !(*this == j
);
254 typename
Arc::entry_type
* m_entry
;
259 Rep(Arc
& arc
, typename
Arc::entry_type
* entry
)
260 : m_arc(arc
), m_entry(entry
), m_value(), m_ref(1) { }
274 typename
Arc::entry_type
* entry
= m_arc
.GetNextEntry();
281 return new Rep(m_arc
, entry
);
289 const T
& GetValue() {
291 _wxSetArchiveIteratorValue(m_value
, m_entry
, m_entry
);
299 typedef wxArchiveIterator
<wxArchiveInputStream
> wxArchiveIter
;
300 typedef wxArchiveIterator
<wxArchiveInputStream
,
301 std::pair
<wxString
, wxArchiveEntry
*> > wxArchivePairIter
;
303 #endif // wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
306 /////////////////////////////////////////////////////////////////////////////
307 // wxArchiveClassFactory
309 // A wxArchiveClassFactory instance for a particular archive type allows
310 // the creation of the other classes that may be needed.
312 void WXDLLIMPEXP_BASE
wxUseArchiveClasses();
314 class WXDLLIMPEXP_BASE wxArchiveClassFactory
: public wxFilterClassFactoryBase
317 typedef wxArchiveEntry entry_type
;
318 typedef wxArchiveInputStream instream_type
;
319 typedef wxArchiveOutputStream outstream_type
;
320 typedef wxArchiveNotifier notifier_type
;
321 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
322 typedef wxArchiveIter iter_type
;
323 typedef wxArchivePairIter pairiter_type
;
326 virtual ~wxArchiveClassFactory() { }
328 wxArchiveEntry
*NewEntry() const
329 { return DoNewEntry(); }
330 wxArchiveInputStream
*NewStream(wxInputStream
& stream
) const
331 { return DoNewStream(stream
); }
332 wxArchiveOutputStream
*NewStream(wxOutputStream
& stream
) const
333 { return DoNewStream(stream
); }
334 wxArchiveInputStream
*NewStream(wxInputStream
*stream
) const
335 { return DoNewStream(stream
); }
336 wxArchiveOutputStream
*NewStream(wxOutputStream
*stream
) const
337 { return DoNewStream(stream
); }
339 virtual wxString
GetInternalName(
340 const wxString
& name
,
341 wxPathFormat format
= wxPATH_NATIVE
) const = 0;
343 // FIXME-UTF8: remove these from this file, they are used for ANSI
345 void SetConv(wxMBConv
& conv
) { m_pConv
= &conv
; }
346 wxMBConv
& GetConv() const
347 { if (m_pConv
) return *m_pConv
; else return wxConvLocal
; }
349 static const wxArchiveClassFactory
*Find(const wxString
& protocol
,
350 wxStreamProtocolType type
351 = wxSTREAM_PROTOCOL
);
353 static const wxArchiveClassFactory
*GetFirst();
354 const wxArchiveClassFactory
*GetNext() const { return m_next
; }
356 void PushFront() { Remove(); m_next
= sm_first
; sm_first
= this; }
360 // old compilers don't support covarient returns, so 'Do' methods are
361 // used to simulate them
362 virtual wxArchiveEntry
*DoNewEntry() const = 0;
363 virtual wxArchiveInputStream
*DoNewStream(wxInputStream
& stream
) const = 0;
364 virtual wxArchiveOutputStream
*DoNewStream(wxOutputStream
& stream
) const = 0;
365 virtual wxArchiveInputStream
*DoNewStream(wxInputStream
*stream
) const = 0;
366 virtual wxArchiveOutputStream
*DoNewStream(wxOutputStream
*stream
) const = 0;
368 wxArchiveClassFactory() : m_pConv(NULL
), m_next(this) { }
369 wxArchiveClassFactory
& operator=(const wxArchiveClassFactory
& WXUNUSED(f
))
374 static wxArchiveClassFactory
*sm_first
;
375 wxArchiveClassFactory
*m_next
;
377 DECLARE_ABSTRACT_CLASS(wxArchiveClassFactory
)
380 #endif // wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
382 #endif // _WX_ARCHIVE_H__