Coverage Report

Created: 2025-06-13 06:30

/src/wxwidgets/include/wx/archive.h
Line
Count
Source (jump to first uncovered line)
1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/archive.h
3
// Purpose:     Streams for archive formats
4
// Author:      Mike Wetherell
5
// Copyright:   (c) 2004 Mike Wetherell
6
// Licence:     wxWindows licence
7
/////////////////////////////////////////////////////////////////////////////
8
9
#ifndef _WX_ARCHIVE_H__
10
#define _WX_ARCHIVE_H__
11
12
#include "wx/defs.h"
13
14
#if wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
15
16
#include "wx/stream.h"
17
#include "wx/filename.h"
18
19
20
/////////////////////////////////////////////////////////////////////////////
21
// wxArchiveNotifier
22
23
class WXDLLIMPEXP_BASE wxArchiveNotifier
24
{
25
public:
26
    virtual ~wxArchiveNotifier() = default;
27
28
    virtual void OnEntryUpdated(class wxArchiveEntry& entry) = 0;
29
};
30
31
32
/////////////////////////////////////////////////////////////////////////////
33
// wxArchiveEntry
34
//
35
// Holds an entry's meta data, such as filename and timestamp.
36
37
class WXDLLIMPEXP_BASE wxArchiveEntry : public wxObject
38
{
39
public:
40
    virtual ~wxArchiveEntry() = default;
41
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;
50
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;
57
58
0
    wxNODISCARD wxArchiveEntry *Clone() const { return DoClone(); }
59
60
    void SetNotifier(wxArchiveNotifier& notifier);
61
0
    virtual void UnsetNotifier() { m_notifier = nullptr; }
62
63
protected:
64
8.26k
    wxArchiveEntry() : m_notifier(nullptr) { }
65
16.0k
    wxArchiveEntry(const wxArchiveEntry& e) : wxObject(e), m_notifier(nullptr) { }
66
67
    virtual void SetOffset(wxFileOffset offset) = 0;
68
    virtual wxArchiveEntry* DoClone() const = 0;
69
70
5.59k
    wxArchiveNotifier *GetNotifier() const { return m_notifier; }
71
    wxArchiveEntry& operator=(const wxArchiveEntry& entry);
72
73
private:
74
    wxArchiveNotifier *m_notifier;
75
76
    wxDECLARE_ABSTRACT_CLASS(wxArchiveEntry);
77
};
78
79
80
/////////////////////////////////////////////////////////////////////////////
81
// wxArchiveInputStream
82
//
83
// GetNextEntry() returns a 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.
87
//
88
// When there are no more entries, GetNextEntry() returns nullptr and sets Eof().
89
90
class WXDLLIMPEXP_BASE wxArchiveInputStream : public wxFilterInputStream
91
{
92
public:
93
    typedef wxArchiveEntry entry_type;
94
95
    virtual ~wxArchiveInputStream() = default;
96
97
    virtual bool OpenEntry(wxArchiveEntry& entry) = 0;
98
    virtual bool CloseEntry() = 0;
99
100
0
    wxArchiveEntry *GetNextEntry()  { return DoGetNextEntry(); }
101
102
0
    virtual char Peek() override  { return wxInputStream::Peek(); }
103
104
protected:
105
    wxArchiveInputStream(wxInputStream& stream, wxMBConv& conv);
106
    wxArchiveInputStream(wxInputStream *stream, wxMBConv& conv);
107
108
    virtual wxArchiveEntry *DoGetNextEntry() = 0;
109
110
29.8k
    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() = default;
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
    wxArchiveOutputStream(wxOutputStream *stream, wxMBConv& conv);
153
154
0
    wxMBConv& GetConv() const { return m_conv; }
155
156
private:
157
    wxMBConv& m_conv;
158
};
159
160
161
/////////////////////////////////////////////////////////////////////////////
162
// wxArchiveIterator
163
//
164
// An input iterator that can be used to transfer an archive's catalog to
165
// a container.
166
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
template <class Arc, class T = typename Arc::entry_type*>
184
class wxArchiveIterator
185
{
186
public:
187
    typedef std::input_iterator_tag iterator_category;
188
    typedef T value_type;
189
    typedef ptrdiff_t difference_type;
190
    typedef T* pointer;
191
    typedef T& reference;
192
193
    wxArchiveIterator() : m_rep(nullptr) { }
194
195
    wxArchiveIterator(Arc& arc) {
196
        typename Arc::entry_type* entry = arc.GetNextEntry();
197
        m_rep = entry ? new Rep(arc, entry) : nullptr;
198
    }
199
200
    wxArchiveIterator(const wxArchiveIterator& it) : m_rep(it.m_rep) {
201
        if (m_rep)
202
            m_rep->AddRef();
203
    }
204
205
    ~wxArchiveIterator() {
206
        if (m_rep)
207
            m_rep->UnRef();
208
    }
209
210
    const T& operator *() const {
211
        return m_rep->GetValue();
212
    }
213
214
    const T* operator ->() const {
215
        return &**this;
216
    }
217
218
    wxArchiveIterator& operator =(const wxArchiveIterator& it) {
219
        if (it.m_rep)
220
            it.m_rep->AddRef();
221
        if (m_rep)
222
            m_rep->UnRef();
223
        m_rep = it.m_rep;
224
        return *this;
225
    }
226
227
    wxArchiveIterator& operator ++() {
228
        m_rep = m_rep->Next();
229
        return *this;
230
    }
231
232
    wxArchiveIterator operator ++(int) {
233
        wxArchiveIterator it(*this);
234
        ++(*this);
235
        return it;
236
    }
237
238
    bool operator ==(const wxArchiveIterator& j) const {
239
        return m_rep == j.m_rep;
240
    }
241
242
    bool operator !=(const wxArchiveIterator& j) const {
243
        return !(*this == j);
244
    }
245
246
private:
247
    class Rep {
248
        Arc& m_arc;
249
        typename Arc::entry_type* m_entry;
250
        T m_value;
251
        int m_ref;
252
253
    public:
254
        Rep(Arc& arc, typename Arc::entry_type* entry)
255
            : m_arc(arc), m_entry(entry), m_value(), m_ref(1) { }
256
        ~Rep()
257
            { delete m_entry; }
258
259
        void AddRef() {
260
            m_ref++;
261
        }
262
263
        void UnRef() {
264
            if (--m_ref == 0)
265
                delete this;
266
        }
267
268
        Rep *Next() {
269
            typename Arc::entry_type* entry = m_arc.GetNextEntry();
270
            if (!entry) {
271
                UnRef();
272
                return nullptr;
273
            }
274
            if (m_ref > 1) {
275
                m_ref--;
276
                return new Rep(m_arc, entry);
277
            }
278
            delete m_entry;
279
            m_entry = entry;
280
            m_value = T();
281
            return this;
282
        }
283
284
        const T& GetValue() {
285
            if (m_entry) {
286
                _wxSetArchiveIteratorValue(m_value, m_entry, m_entry);
287
                m_entry = nullptr;
288
            }
289
            return m_value;
290
        }
291
    } *m_rep;
292
};
293
294
typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter;
295
typedef wxArchiveIterator<wxArchiveInputStream,
296
        std::pair<wxString, wxArchiveEntry*> >  wxArchivePairIter;
297
298
299
/////////////////////////////////////////////////////////////////////////////
300
// wxArchiveClassFactory
301
//
302
// A wxArchiveClassFactory instance for a particular archive type allows
303
// the creation of the other classes that may be needed.
304
305
void WXDLLIMPEXP_BASE wxUseArchiveClasses();
306
307
class WXDLLIMPEXP_BASE wxArchiveClassFactory : public wxFilterClassFactoryBase
308
{
309
public:
310
    typedef wxArchiveEntry        entry_type;
311
    typedef wxArchiveInputStream  instream_type;
312
    typedef wxArchiveOutputStream outstream_type;
313
    typedef wxArchiveNotifier     notifier_type;
314
    typedef wxArchiveIter         iter_type;
315
    typedef wxArchivePairIter     pairiter_type;
316
317
    virtual ~wxArchiveClassFactory() = default;
318
319
    wxArchiveEntry *NewEntry() const
320
0
        { return DoNewEntry(); }
321
    wxArchiveInputStream *NewStream(wxInputStream& stream) const
322
0
        { return DoNewStream(stream); }
323
    wxArchiveOutputStream *NewStream(wxOutputStream& stream) const
324
0
        { return DoNewStream(stream); }
325
    wxArchiveInputStream *NewStream(wxInputStream *stream) const
326
0
        { return DoNewStream(stream); }
327
    wxArchiveOutputStream *NewStream(wxOutputStream *stream) const
328
0
        { return DoNewStream(stream); }
329
330
    virtual wxString GetInternalName(
331
        const wxString& name,
332
        wxPathFormat format = wxPATH_NATIVE) const = 0;
333
334
0
    void SetConv(wxMBConv& conv) { m_pConv = &conv; }
335
    wxMBConv& GetConv() const
336
0
        { if (m_pConv) return *m_pConv; else return wxConvLocal; }
337
338
    static const wxArchiveClassFactory *Find(const wxString& protocol,
339
                                             wxStreamProtocolType type
340
                                             = wxSTREAM_PROTOCOL);
341
342
    static const wxArchiveClassFactory *GetFirst();
343
0
    const wxArchiveClassFactory *GetNext() const { return m_next; }
344
345
2
    void PushFront() { Remove(); m_next = sm_first; sm_first = this; }
346
    void Remove();
347
348
protected:
349
    // old compilers don't support covarient returns, so 'Do' methods are
350
    // used to simulate them
351
    virtual wxArchiveEntry        *DoNewEntry() const = 0;
352
    virtual wxArchiveInputStream  *DoNewStream(wxInputStream& stream) const = 0;
353
    virtual wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const = 0;
354
    virtual wxArchiveInputStream  *DoNewStream(wxInputStream *stream) const = 0;
355
    virtual wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const = 0;
356
357
2
    wxArchiveClassFactory() : m_pConv(nullptr), m_next(this) { }
358
    wxArchiveClassFactory& operator=(const wxArchiveClassFactory& WXUNUSED(f))
359
0
        { return *this; }
360
361
private:
362
    wxMBConv *m_pConv;
363
    static wxArchiveClassFactory *sm_first;
364
    wxArchiveClassFactory *m_next;
365
366
    wxDECLARE_ABSTRACT_CLASS(wxArchiveClassFactory);
367
};
368
369
#endif // wxUSE_STREAMS && wxUSE_ARCHIVE_STREAMS
370
371
#endif // _WX_ARCHIVE_H__