File: overview_archive.html

package info (click to toggle)
wxpython3.0 3.0.2.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 482,760 kB
  • ctags: 518,293
  • sloc: cpp: 2,127,226; python: 294,045; makefile: 51,942; ansic: 19,033; sh: 3,013; xml: 1,629; perl: 17
file content (326 lines) | stat: -rw-r--r-- 43,449 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>wxWidgets: Archive Formats</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="extra_stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="page_container">
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0" style="width: 100%;">
 <tbody>
 <tr>
  <td id="projectlogo">
    <a href="http://www.wxwidgets.org/" target="_new">
      <img alt="wxWidgets" src="logo.png"/>
    </a>
  </td>
  <td style="padding-left: 0.5em; text-align: right;">
   <span id="projectnumber">Version: 3.0.2</span>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- Generated by Doxygen 1.8.2 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Categories</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="index.html">Documentation</a></li><li class="navelem"><a class="el" href="page_topics.html">Programming Guides</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Archive Formats </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#overview_archive_create">Creating an Archive</a></li>
<li class="level1"><a href="#overview_archive_extract">Extracting an Archive</a></li>
<li class="level1"><a href="#overview_archive_modify">Modifying an Archive</a></li>
<li class="level1"><a href="#overview_archive_byname">Looking Up an Archive Entry by Name</a></li>
<li class="level1"><a href="#overview_archive_generic">Generic Archive Programming</a></li>
<li class="level1"><a href="#overview_archive_noseek">Archives on Non-Seekable Streams</a><ul><li class="level2"><a href="#overview_archive_noseek_entrysize">PutNextEntry and the Entry Size</a></li>
<li class="level2"><a href="#overview_archive_noseek_weak">GetNextEntry and the Weak Reference Mechanism</a></li>
<li class="level2"><a href="#overview_archive_noseek_notifier">wxArchiveNotifier</a></li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><p>The archive classes handle archive formats such as zip, tar, rar and cab.</p>
<p>Currently wxZip, wxTar and wxZlib classes are included.</p>
<p>For each archive type, there are the following classes (using zip here as an example):</p>
<ul>
<li><a class="el" href="classwx_zip_input_stream.html" title="Input stream for reading zip files.">wxZipInputStream</a>: Input stream </li>
<li><a class="el" href="classwx_zip_output_stream.html" title="Output stream for writing zip files.">wxZipOutputStream</a>: Output stream </li>
<li><a class="el" href="classwx_zip_entry.html" title="Holds the meta-data for an entry in a zip.">wxZipEntry</a>: Holds meta-data for an entry (e.g. filename, timestamp, etc.)</li>
</ul>
<p>There are also abstract wxArchive classes that can be used to write code that can handle any of the archive types, see <a class="el" href="overview_archive.html#overview_archive_generic">Generic Archive Programming</a>.</p>
<p>Also see <a class="el" href="classwx_file_system.html" title="This class provides an interface for opening files on different file systems.">wxFileSystem</a> for a higher level interface that can handle archive files in a generic way.</p>
<p>The classes are designed to handle archives on both seekable streams such as disk files, or non-seekable streams such as pipes and sockets (see <a class="el" href="overview_archive.html#overview_archive_noseek">Archives on Non-Seekable Streams</a>).</p>
<h1><a class="anchor" id="overview_archive_create"></a>
Creating an Archive</h1>
<p>Call <a class="el" href="classwx_archive_output_stream.html#a4a5dd11b0dbd57b78a94315c9e841ceb" title="Takes ownership of entry and uses it to create a new entry in the archive.">wxArchiveOutputStream::PutNextEntry()</a> to create each new entry in the archive, then write the entry's data. Another call to PutNextEntry() closes the current entry and begins the next. For example:</p>
<div class="fragment"><div class="line"><a class="code" href="classwx_f_file_output_stream.html" title="This class represents data written to a file.">wxFFileOutputStream</a> out(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>));</div>
<div class="line"><a class="code" href="classwx_zip_output_stream.html" title="Output stream for writing zip files.">wxZipOutputStream</a> zip(out);</div>
<div class="line"><a class="code" href="classwx_text_output_stream.html" title="This class provides functions that write text data using an output stream, allowing you to write text...">wxTextOutputStream</a> txt(zip);</div>
<div class="line"><a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a> sep(<a class="code" href="classwx_file_name.html#ad6f9ae274e12729fc5689128ea94d16e" title="Returns the usually used path separator for this format.">wxFileName::GetPathSeparator</a>());</div>
<div class="line"></div>
<div class="line">zip.PutNextEntry(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;entry1.txt&quot;</span>));</div>
<div class="line">txt &lt;&lt; <a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;Some text for entry1.txt\n&quot;</span>);</div>
<div class="line"></div>
<div class="line">zip.PutNextEntry(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;subdir&quot;</span>) + sep + <a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;entry2.txt&quot;</span>));</div>
<div class="line">txt &lt;&lt; <a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;Some text for subdir/entry2.txt\n&quot;</span>);</div>
</div><!-- fragment --><p>The name of each entry can be a full path, which makes it possible to store entries in subdirectories.</p>
<h1><a class="anchor" id="overview_archive_extract"></a>
Extracting an Archive</h1>
<p><a class="el" href="classwx_archive_input_stream.html#a87615df48e5f57305aa360098f5dae26" title="Closes the current entry if one is open, then reads the meta-data for the next entry and returns it i...">wxArchiveInputStream::GetNextEntry()</a> returns a pointer to entry object containing the meta-data for the next entry in the archive (and gives away ownership).</p>
<p>Reading from the input stream then returns the entry's data. Eof() becomes <span class="literal">true</span> after an attempt has been made to read past the end of the entry's data.</p>
<p>When there are no more entries, GetNextEntry() returns <span class="literal">NULL</span> and sets Eof().</p>
<div class="fragment"><div class="line">auto_ptr&lt;wxZipEntry&gt; entry;</div>
<div class="line"></div>
<div class="line"><a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a> in(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>));</div>
<div class="line"><a class="code" href="classwx_zip_input_stream.html" title="Input stream for reading zip files.">wxZipInputStream</a> zip(in);</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">while</span> (entry.reset(zip.GetNextEntry()), entry.get() != NULL)</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// access meta-data</span></div>
<div class="line">    <a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a> name = entry-&gt;GetName();</div>
<div class="line">    <span class="comment">// read &#39;zip&#39; to access the entry&#39;s data</span></div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="overview_archive_modify"></a>
Modifying an Archive</h1>
<p>To modify an existing archive, write a new copy of the archive to a new file, making any necessary changes along the way and transferring any unchanged entries using <a class="el" href="classwx_archive_output_stream.html#acf19a29865cca24282fd163a20a4b137" title="Takes ownership of entry and uses it to create a new entry in the archive.">wxArchiveOutputStream::CopyEntry()</a>.</p>
<p>For archive types which compress entry data, CopyEntry() is likely to be much more efficient than transferring the data using Read() and Write() since it will copy them without decompressing and recompressing them.</p>
<p>In general modifications are not possible without rewriting the archive, though it may be possible in some limited cases. Even then, rewriting the archive is usually a better choice since a failure can be handled without losing the whole archive. <a class="el" href="classwx_temp_file_output_stream.html" title="wxTempFileOutputStream is an output stream based on wxTempFile.">wxTempFileOutputStream</a> can be helpful to do this.</p>
<p>For example to delete all entries matching the pattern "*.txt":</p>
<div class="fragment"><div class="line">auto_ptr&lt;wxFFileInputStream&gt; in(<span class="keyword">new</span> <a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a>(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>)));</div>
<div class="line"><a class="code" href="classwx_temp_file_output_stream.html" title="wxTempFileOutputStream is an output stream based on wxTempFile.">wxTempFileOutputStream</a> out(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>));</div>
<div class="line"></div>
<div class="line"><a class="code" href="classwx_zip_input_stream.html" title="Input stream for reading zip files.">wxZipInputStream</a> inzip(*in);</div>
<div class="line"><a class="code" href="classwx_zip_output_stream.html" title="Output stream for writing zip files.">wxZipOutputStream</a> outzip(out);</div>
<div class="line"></div>
<div class="line">auto_ptr&lt;wxZipEntry&gt; entry;</div>
<div class="line"></div>
<div class="line"><span class="comment">// transfer any meta-data for the archive as a whole (the zip comment</span></div>
<div class="line"><span class="comment">// in the case of zip)</span></div>
<div class="line">outzip.CopyArchiveMetaData(inzip);</div>
<div class="line"></div>
<div class="line"><span class="comment">// call CopyEntry for each entry except those matching the pattern</span></div>
<div class="line"><span class="keywordflow">while</span> (entry.reset(inzip.GetNextEntry()), entry.get() != NULL)</div>
<div class="line">    <span class="keywordflow">if</span> (!entry-&gt;GetName().Matches(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;*.txt&quot;</span>)))</div>
<div class="line">        <span class="keywordflow">if</span> (!outzip.CopyEntry(entry.release(), inzip))</div>
<div class="line">            <span class="keywordflow">break</span>;</div>
<div class="line"></div>
<div class="line"><span class="comment">// close the input stream by releasing the pointer to it, do this</span></div>
<div class="line"><span class="comment">// before closing the output stream so that the file can be replaced</span></div>
<div class="line">in.reset();</div>
<div class="line"></div>
<div class="line"><span class="comment">// you can check for success as follows</span></div>
<div class="line"><span class="keywordtype">bool</span> success = inzip.Eof() &amp;&amp; outzip.Close() &amp;&amp; out.Commit();</div>
</div><!-- fragment --><h1><a class="anchor" id="overview_archive_byname"></a>
Looking Up an Archive Entry by Name</h1>
<p>Also see <a class="el" href="classwx_file_system.html" title="This class provides an interface for opening files on different file systems.">wxFileSystem</a> for a higher level interface that is more convenient for accessing archive entries by name.</p>
<p>To open just one entry in an archive, the most efficient way is to simply search for it linearly by calling <a class="el" href="classwx_archive_input_stream.html#a87615df48e5f57305aa360098f5dae26" title="Closes the current entry if one is open, then reads the meta-data for the next entry and returns it i...">wxArchiveInputStream::GetNextEntry()</a> until the required entry is found. This works both for archives on seekable and non-seekable streams.</p>
<p>The format of filenames in the archive is likely to be different from the local filename format. For example zips and tars use unix style names, with forward slashes as the path separator, and absolute paths are not allowed. So if on Windows the file "C:\MYDIR\MYFILE.TXT" is stored, then when reading the entry back <a class="el" href="classwx_archive_entry.html#a7f7c8fc858136626dcdf1865e646cef9" title="Returns the entry&#39;s name, by default in the native format.">wxArchiveEntry::GetName()</a> will return "MYDIR\MYFILE.TXT". The conversion into the internal format and back has lost some information.</p>
<p>So to avoid ambiguity when searching for an entry matching a local name, it is better to convert the local name to the archive's internal format and search for that:</p>
<div class="fragment"><div class="line">auto_ptr&lt;wxZipEntry&gt; entry;</div>
<div class="line"></div>
<div class="line"><span class="comment">// convert the local name we are looking for into the internal format</span></div>
<div class="line"><a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a> name = <a class="code" href="classwx_zip_entry.html#a74d8509df7beb653ab2e22c05f0cdb3d" title="Returns the entry&#39;s filename in the internal format used within the archive.">wxZipEntry::GetInternalName</a>(localname);</div>
<div class="line"></div>
<div class="line"><span class="comment">// open the zip</span></div>
<div class="line"><a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a> in(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>));</div>
<div class="line"><a class="code" href="classwx_zip_input_stream.html" title="Input stream for reading zip files.">wxZipInputStream</a> zip(in);</div>
<div class="line"></div>
<div class="line"><span class="comment">// call GetNextEntry() until the required internal name is found</span></div>
<div class="line"><span class="keywordflow">do</span></div>
<div class="line">{</div>
<div class="line">    entry.reset(zip.GetNextEntry());</div>
<div class="line">}</div>
<div class="line"><span class="keywordflow">while</span> (entry.get() != NULL &amp;&amp; entry-&gt;GetInternalName() != name);</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">if</span> (entry.get() != NULL)</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// read the entry&#39;s data...</span></div>
<div class="line">}</div>
</div><!-- fragment --><p>To access several entries randomly, it is most efficient to transfer the entire catalogue of entries to a container such as a std::map or a <a class="el" href="classwx_hash_map.html" title="This is a simple, type-safe, and reasonably efficient hash map class, whose interface is a subset of ...">wxHashMap</a> then entries looked up by name can be opened using the <a class="el" href="classwx_archive_input_stream.html#abb0e2896bbb5b50b7cef95cfdd8fb8e5" title="Closes the current entry if one is open, then opens the entry specified by the wxArchiveEntry object...">wxArchiveInputStream::OpenEntry()</a> method.</p>
<div class="fragment"><div class="line">WX_DECLARE_STRING_HASH_MAP(<a class="code" href="classwx_zip_entry.html" title="Holds the meta-data for an entry in a zip.">wxZipEntry</a>*, ZipCatalog);</div>
<div class="line">ZipCatalog::iterator it;</div>
<div class="line"><a class="code" href="classwx_zip_entry.html" title="Holds the meta-data for an entry in a zip.">wxZipEntry</a> *entry;</div>
<div class="line">ZipCatalog cat;</div>
<div class="line"></div>
<div class="line"><span class="comment">// open the zip</span></div>
<div class="line"><a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a> in(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>));</div>
<div class="line"><a class="code" href="classwx_zip_input_stream.html" title="Input stream for reading zip files.">wxZipInputStream</a> zip(in);</div>
<div class="line"></div>
<div class="line"><span class="comment">// load the zip catalog</span></div>
<div class="line"><span class="keywordflow">while</span> ((entry = zip.GetNextEntry()) != NULL)</div>
<div class="line">{</div>
<div class="line">    <a class="code" href="classwx_zip_entry.html" title="Holds the meta-data for an entry in a zip.">wxZipEntry</a>*&amp; current = cat[entry-&gt;<a class="code" href="classwx_zip_entry.html#aab5dd8f5bb2d47d2532facd2f1629f25" title="A static member that translates a filename into the internal format used within the archive...">GetInternalName</a>()];</div>
<div class="line">    <span class="comment">// some archive formats can have multiple entries with the same name</span></div>
<div class="line">    <span class="comment">// (e.g. tar) though it is an error in the case of zip</span></div>
<div class="line">    <span class="keyword">delete</span> current;</div>
<div class="line">    current = entry;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">// open an entry by name</span></div>
<div class="line"><span class="keywordflow">if</span> ((it = cat.find(<a class="code" href="classwx_zip_entry.html#a74d8509df7beb653ab2e22c05f0cdb3d" title="Returns the entry&#39;s filename in the internal format used within the archive.">wxZipEntry::GetInternalName</a>(localname))) != cat.end())</div>
<div class="line">{</div>
<div class="line">    zip.OpenEntry(*it-&gt;second);</div>
<div class="line">    <span class="comment">// ... now read entry&#39;s data</span></div>
<div class="line">}</div>
</div><!-- fragment --><p>To open more than one entry simultaneously you need more than one underlying stream on the same archive:</p>
<div class="fragment"><div class="line"><span class="comment">// opening another entry without closing the first requires another</span></div>
<div class="line"><span class="comment">// input stream for the same file</span></div>
<div class="line"><a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a> in2(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;test.zip&quot;</span>));</div>
<div class="line"><a class="code" href="classwx_zip_input_stream.html" title="Input stream for reading zip files.">wxZipInputStream</a> zip2(in2);</div>
<div class="line"><span class="keywordflow">if</span> ((it = cat.find(<a class="code" href="classwx_zip_entry.html#a74d8509df7beb653ab2e22c05f0cdb3d" title="Returns the entry&#39;s filename in the internal format used within the archive.">wxZipEntry::GetInternalName</a>(local2))) != cat.end())</div>
<div class="line">    zip2.OpenEntry(*it-&gt;second);</div>
</div><!-- fragment --><h1><a class="anchor" id="overview_archive_generic"></a>
Generic Archive Programming</h1>
<p>Also see <a class="el" href="classwx_file_system.html" title="This class provides an interface for opening files on different file systems.">wxFileSystem</a> for a higher level interface that can handle archive files in a generic way.</p>
<p>The specific archive classes, such as the wxZip classes, inherit from the following abstract classes which can be used to write code that can handle any of the archive types:</p>
<ul>
<li><a class="el" href="classwx_archive_input_stream.html" title="This is an abstract base class which serves as a common interface to archive input streams such as wx...">wxArchiveInputStream</a>: Input stream </li>
<li><a class="el" href="classwx_archive_output_stream.html" title="This is an abstract base class which serves as a common interface to archive output streams such as w...">wxArchiveOutputStream</a>: Output stream </li>
<li><a class="el" href="classwx_archive_entry.html" title="This is an abstract base class which serves as a common interface to archive entry classes such as wx...">wxArchiveEntry</a>: Holds the meta-data for an entry (e.g. filename)</li>
</ul>
<p>In order to able to write generic code it's necessary to be able to create instances of the classes without knowing which archive type is being used.</p>
<p>To allow this there is a class factory for each archive type, derived from <a class="el" href="classwx_archive_class_factory.html" title="Allows the creation of streams to handle archive formats such as zip and tar.">wxArchiveClassFactory</a>, that can create the other classes.</p>
<p>For example, given wxArchiveClassFactory* factory, streams and entries can be created like this:</p>
<div class="fragment"><div class="line"><span class="comment">// create streams without knowing their type</span></div>
<div class="line">auto_ptr&lt;wxArchiveInputStream&gt; inarc(factory-&gt;NewStream(in));</div>
<div class="line">auto_ptr&lt;wxArchiveOutputStream&gt; outarc(factory-&gt;NewStream(out));</div>
<div class="line"></div>
<div class="line"><span class="comment">// create an empty entry object</span></div>
<div class="line">auto_ptr&lt;wxArchiveEntry&gt; entry(factory-&gt;NewEntry());</div>
</div><!-- fragment --><p>For the factory itself, the static member <a class="el" href="classwx_archive_class_factory.html#ad9f083561596ee377cea71a0125d3c3b" title="A static member that finds a factory that can handle a given protocol, MIME type or file extension...">wxArchiveClassFactory::Find()</a> can be used to find a class factory that can handle a given file extension or mime type. For example, given <em>filename:</em> </p>
<div class="fragment"><div class="line"><span class="keyword">const</span> <a class="code" href="classwx_archive_class_factory.html" title="Allows the creation of streams to handle archive formats such as zip and tar.">wxArchiveClassFactory</a> *factory;</div>
<div class="line">factory = <a class="code" href="classwx_archive_class_factory.html#ad9f083561596ee377cea71a0125d3c3b" title="A static member that finds a factory that can handle a given protocol, MIME type or file extension...">wxArchiveClassFactory::Find</a>(filename, <a class="code" href="interface_2wx_2stream_8h.html#af43964582cc2e87658bf792727dceff8a6a7551247424d0c62b240da47daee204" title="File extensions the stream handles.">wxSTREAM_FILEEXT</a>);</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">if</span> (factory)</div>
<div class="line">    stream = factory-&gt;<a class="code" href="classwx_archive_class_factory.html#a658607861fc4bd7a8e787a8de35e89fb" title="Create a new input or output stream to read or write an archive.">NewStream</a>(<span class="keyword">new</span> <a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a>(filename));</div>
</div><!-- fragment --><p><em>Find()</em> does not give away ownership of the returned pointer, so it does not need to be deleted.</p>
<p>There are similar class factories for the filter streams that handle the compression and decompression of a single stream, such as wxGzipInputStream. These can be found using <a class="el" href="classwx_filter_class_factory.html#a689a3e8a0ea3bd8678f020cfb723f54f" title="A static member that finds a factory that can handle a given protocol, MIME type, HTTP encoding or fi...">wxFilterClassFactory::Find()</a>.</p>
<p>For example, to list the contents of archive <em>filename:</em> </p>
<div class="fragment"><div class="line">auto_ptr&lt;wxInputStream&gt; in(<span class="keyword">new</span> <a class="code" href="classwx_f_file_input_stream.html" title="This class represents data read in from a file.">wxFFileInputStream</a>(filename));</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">if</span> (in-&gt;IsOk())</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// look for a filter handler, e.g. for &#39;.gz&#39;</span></div>
<div class="line">    <span class="keyword">const</span> <a class="code" href="classwx_filter_class_factory.html" title="Allows the creation of filter streams to handle compression formats such as gzip and bzip2...">wxFilterClassFactory</a> *fcf;</div>
<div class="line">    fcf = <a class="code" href="classwx_filter_class_factory.html#a689a3e8a0ea3bd8678f020cfb723f54f" title="A static member that finds a factory that can handle a given protocol, MIME type, HTTP encoding or fi...">wxFilterClassFactory::Find</a>(filename, <a class="code" href="interface_2wx_2stream_8h.html#af43964582cc2e87658bf792727dceff8a6a7551247424d0c62b240da47daee204" title="File extensions the stream handles.">wxSTREAM_FILEEXT</a>);</div>
<div class="line">    <span class="keywordflow">if</span> (fcf)</div>
<div class="line">    {</div>
<div class="line">        in.reset(fcf-&gt;<a class="code" href="classwx_filter_class_factory.html#a8e6dae81ce0b876db269f74b299b5132" title="Create a new input or output stream to decompress or compress a given stream.">NewStream</a>(in.release()));</div>
<div class="line">        <span class="comment">// pop the extension, so if it was &#39;.tar.gz&#39; it is now just &#39;.tar&#39;</span></div>
<div class="line">        filename = fcf-&gt;<a class="code" href="classwx_filter_class_factory.html#a5b47b516bb16010f5647a2079bdbb0aa" title="Remove the file extension of location if it is one of the file extensions handled by this factory...">PopExtension</a>(filename);</div>
<div class="line">    }</div>
<div class="line"></div>
<div class="line">    <span class="comment">// look for a archive handler, e.g. for &#39;.zip&#39; or &#39;.tar&#39;</span></div>
<div class="line">    <span class="keyword">const</span> <a class="code" href="classwx_archive_class_factory.html" title="Allows the creation of streams to handle archive formats such as zip and tar.">wxArchiveClassFactory</a> *acf;</div>
<div class="line">    acf = <a class="code" href="classwx_archive_class_factory.html#ad9f083561596ee377cea71a0125d3c3b" title="A static member that finds a factory that can handle a given protocol, MIME type or file extension...">wxArchiveClassFactory::Find</a>(filename, <a class="code" href="interface_2wx_2stream_8h.html#af43964582cc2e87658bf792727dceff8a6a7551247424d0c62b240da47daee204" title="File extensions the stream handles.">wxSTREAM_FILEEXT</a>);</div>
<div class="line">    <span class="keywordflow">if</span> (acf)</div>
<div class="line">    {</div>
<div class="line">        auto_ptr&lt;wxArchiveInputStream&gt; arc(acf-&gt;<a class="code" href="classwx_archive_class_factory.html#a658607861fc4bd7a8e787a8de35e89fb" title="Create a new input or output stream to read or write an archive.">NewStream</a>(in.release()));</div>
<div class="line">        auto_ptr&lt;wxArchiveEntry&gt; entry;</div>
<div class="line"></div>
<div class="line">        <span class="comment">// list the contents of the archive</span></div>
<div class="line">        <span class="keywordflow">while</span> ((entry.reset(arc-&gt;GetNextEntry())), entry.get() != NULL)</div>
<div class="line">            std::wcout &lt;&lt; entry-&gt;<a class="code" href="classwx_archive_entry.html#a7f7c8fc858136626dcdf1865e646cef9" title="Returns the entry&#39;s name, by default in the native format.">GetName</a>().<a class="code" href="classwx_string.html#a6418ec90c6d4ffe0b05702be1b35df4f" title="Returns a lightweight intermediate class which is in turn implicitly convertible to both const char* ...">c_str</a>() &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;</div>
<div class="line">    }</div>
<div class="line">    <span class="keywordflow">else</span></div>
<div class="line">    {</div>
<div class="line">        <a class="code" href="group__group__funcmacro__log.html#ga0dd3c633f990f794e76065c9a7af4c87" title="The functions to use for error messages, i.e.">wxLogError</a>(<a class="code" href="group__group__funcmacro__string.html#ga437ea6ba615b75dac8603e96ec864160" title="This macro can be used with character and string literals (in other words, &#39;x&#39; or &quot;foo&quot;) to automatic...">wxT</a>(<span class="stringliteral">&quot;can&#39;t handle &#39;%s&#39;&quot;</span>), filename.c_str());</div>
<div class="line">    }</div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="overview_archive_noseek"></a>
Archives on Non-Seekable Streams</h1>
<p>In general, handling archives on non-seekable streams is done in the same way as for seekable streams, with a few caveats.</p>
<p>The main limitation is that accessing entries randomly using <a class="el" href="classwx_archive_input_stream.html#abb0e2896bbb5b50b7cef95cfdd8fb8e5" title="Closes the current entry if one is open, then opens the entry specified by the wxArchiveEntry object...">wxArchiveInputStream::OpenEntry()</a> is not possible, the entries can only be accessed sequentially in the order they are stored within the archive.</p>
<p>For each archive type, there will also be other limitations which will depend on the order the entries' meta-data is stored within the archive. These are not too difficult to deal with, and are outlined below.</p>
<h2><a class="anchor" id="overview_archive_noseek_entrysize"></a>
PutNextEntry and the Entry Size</h2>
<p>When writing archives, some archive formats store the entry size before the entry's data (tar has this limitation, zip doesn't). In this case the entry's size must be passed to <a class="el" href="classwx_archive_output_stream.html#a4a5dd11b0dbd57b78a94315c9e841ceb" title="Takes ownership of entry and uses it to create a new entry in the archive.">wxArchiveOutputStream::PutNextEntry()</a> or an error occurs.</p>
<p>This is only an issue on non-seekable streams, since otherwise the archive output stream can seek back and fix up the header once the size of the entry is known.</p>
<p>For generic programming, one way to handle this is to supply the size whenever it is known, and rely on the error message from the output stream when the operation is not supported.</p>
<h2><a class="anchor" id="overview_archive_noseek_weak"></a>
GetNextEntry and the Weak Reference Mechanism</h2>
<p>Some archive formats do not store all an entry's meta-data before the entry's data (zip is an example). In this case, when reading from a non-seekable stream, <a class="el" href="classwx_archive_input_stream.html#a87615df48e5f57305aa360098f5dae26" title="Closes the current entry if one is open, then reads the meta-data for the next entry and returns it i...">wxArchiveInputStream::GetNextEntry()</a> can only return a partially populated <a class="el" href="classwx_archive_entry.html" title="This is an abstract base class which serves as a common interface to archive entry classes such as wx...">wxArchiveEntry</a> object - not all the fields are set.</p>
<p>The input stream then keeps a weak reference to the entry object and updates it when more meta-data becomes available. A weak reference being one that does not prevent you from deleting the <a class="el" href="classwx_archive_entry.html" title="This is an abstract base class which serves as a common interface to archive entry classes such as wx...">wxArchiveEntry</a> object - the input stream only attempts to update it if it is still around.</p>
<p>The documentation for each archive entry type gives the details of what meta-data becomes available and when. For generic programming, when the worst case must be assumed, you can rely on all the fields of <a class="el" href="classwx_archive_entry.html" title="This is an abstract base class which serves as a common interface to archive entry classes such as wx...">wxArchiveEntry</a> being fully populated when GetNextEntry() returns, with the following exceptions:</p>
<ul>
<li><a class="el" href="classwx_archive_entry.html#a05d8c0618a80cb1ada5c37a58042ec32" title="Returns the size of the entry&#39;s data in bytes.">wxArchiveEntry::GetSize()</a>: Guaranteed to be available after the entry has been read to <a class="el" href="classwx_input_stream.html#a177bb52eb500be28c8d41f959b0fb6be" title="Returns true after an attempt has been made to read past the end of the stream.">wxInputStream::Eof()</a>, or <a class="el" href="classwx_archive_input_stream.html#a091c14b91d891de1014a53251dc7835e" title="Closes the current entry.">wxArchiveInputStream::CloseEntry()</a> has been called. </li>
<li><a class="el" href="classwx_archive_entry.html#abe30c2532550d23136cf6e1390007073" title="Returns true if the entry is a read-only file.">wxArchiveEntry::IsReadOnly()</a>: Guaranteed to be available after the end of the archive has been reached, i.e. after GetNextEntry() returns <span class="literal">NULL</span> and Eof() is <span class="literal">true</span>.</li>
</ul>
<p>This mechanism allows <a class="el" href="classwx_archive_output_stream.html#acf19a29865cca24282fd163a20a4b137" title="Takes ownership of entry and uses it to create a new entry in the archive.">wxArchiveOutputStream::CopyEntry()</a> to always fully preserve entries' meta-data. No matter what order order the meta-data occurs within the archive, the input stream will always have read it before the output stream must write it.</p>
<h2><a class="anchor" id="overview_archive_noseek_notifier"></a>
wxArchiveNotifier</h2>
<p>Notifier objects can be used to get a notification whenever an input stream updates a <a class="el" href="classwx_archive_entry.html" title="This is an abstract base class which serves as a common interface to archive entry classes such as wx...">wxArchiveEntry</a> object's data via the weak reference mechanism.</p>
<p>Consider the following code which renames an entry in an archive. This is the usual way to modify an entry's meta-data, simply set the required field before writing it with <a class="el" href="classwx_archive_output_stream.html#acf19a29865cca24282fd163a20a4b137" title="Takes ownership of entry and uses it to create a new entry in the archive.">wxArchiveOutputStream::CopyEntry()</a>:</p>
<div class="fragment"><div class="line">auto_ptr&lt;wxArchiveInputStream&gt; arc(factory-&gt;<a class="code" href="classwx_archive_class_factory.html#a658607861fc4bd7a8e787a8de35e89fb" title="Create a new input or output stream to read or write an archive.">NewStream</a>(in));</div>
<div class="line">auto_ptr&lt;wxArchiveOutputStream&gt; outarc(factory-&gt;<a class="code" href="classwx_archive_class_factory.html#a658607861fc4bd7a8e787a8de35e89fb" title="Create a new input or output stream to read or write an archive.">NewStream</a>(out));</div>
<div class="line">auto_ptr&lt;wxArchiveEntry&gt; entry;</div>
<div class="line"></div>
<div class="line">outarc-&gt;CopyArchiveMetaData(*arc);</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">while</span> (entry.reset(arc-&gt;GetNextEntry()), entry.get() != NULL)</div>
<div class="line">{</div>
<div class="line">    <span class="keywordflow">if</span> (entry-&gt;GetName() == from)</div>
<div class="line">        entry-&gt;SetName(to);</div>
<div class="line">    <span class="keywordflow">if</span> (!outarc-&gt;CopyEntry(entry.release(), *arc))</div>
<div class="line">        <span class="keywordflow">break</span>;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">bool</span> success = arc-&gt;Eof() &amp;&amp; outarc-&gt;Close();</div>
</div><!-- fragment --><p>However, for non-seekable streams, this technique cannot be used for fields such as <a class="el" href="classwx_archive_entry.html#abe30c2532550d23136cf6e1390007073" title="Returns true if the entry is a read-only file.">wxArchiveEntry::IsReadOnly()</a>, which are not necessarily set when <a class="el" href="classwx_archive_input_stream.html#a87615df48e5f57305aa360098f5dae26" title="Closes the current entry if one is open, then reads the meta-data for the next entry and returns it i...">wxArchiveInputStream::GetNextEntry()</a> returns.</p>
<p>In this case a <a class="el" href="classwx_archive_notifier.html" title="If you need to know when a wxArchiveInputStream updates a wxArchiveEntry object, you can create a not...">wxArchiveNotifier</a> can be used:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyNotifier : <span class="keyword">public</span> <a class="code" href="classwx_archive_notifier.html" title="If you need to know when a wxArchiveInputStream updates a wxArchiveEntry object, you can create a not...">wxArchiveNotifier</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    <span class="keywordtype">void</span> <a class="code" href="classwx_archive_notifier.html#aabc8d85fc2f85b38a761e3b4ccf74f5a" title="This method must be overridden in your derived class.">OnEntryUpdated</a>(<a class="code" href="classwx_archive_entry.html" title="This is an abstract base class which serves as a common interface to archive entry classes such as wx...">wxArchiveEntry</a>&amp; entry) { entry.<a class="code" href="classwx_archive_entry.html#a0ed675785f6d0ddaf36664951f4430b6" title="Sets this entry as a read-only file.">SetIsReadOnly</a>(<span class="keyword">false</span>); }</div>
<div class="line">};</div>
</div><!-- fragment --><p>The meta-data changes are done in your notifier's <a class="el" href="classwx_archive_notifier.html#aabc8d85fc2f85b38a761e3b4ccf74f5a" title="This method must be overridden in your derived class.">wxArchiveNotifier::OnEntryUpdated()</a> method, then <a class="el" href="classwx_archive_entry.html#a14fe1a270dbb1d0e9a76e2c3c8dd32a8" title="Sets the notifier (see wxArchiveNotifier) for this entry.">wxArchiveEntry::SetNotifier()</a> is called before CopyEntry():</p>
<div class="fragment"><div class="line">auto_ptr&lt;wxArchiveInputStream&gt; arc(factory-&gt;<a class="code" href="classwx_archive_class_factory.html#a658607861fc4bd7a8e787a8de35e89fb" title="Create a new input or output stream to read or write an archive.">NewStream</a>(in));</div>
<div class="line">auto_ptr&lt;wxArchiveOutputStream&gt; outarc(factory-&gt;<a class="code" href="classwx_archive_class_factory.html#a658607861fc4bd7a8e787a8de35e89fb" title="Create a new input or output stream to read or write an archive.">NewStream</a>(out));</div>
<div class="line">auto_ptr&lt;wxArchiveEntry&gt; entry;</div>
<div class="line">MyNotifier notifier;</div>
<div class="line"></div>
<div class="line">outarc-&gt;CopyArchiveMetaData(*arc);</div>
<div class="line"></div>
<div class="line"><span class="keywordflow">while</span> (entry.reset(arc-&gt;GetNextEntry()), entry.get() != NULL)</div>
<div class="line">{</div>
<div class="line">    entry-&gt;SetNotifier(notifier);</div>
<div class="line">    <span class="keywordflow">if</span> (!outarc-&gt;CopyEntry(entry.release(), *arc))</div>
<div class="line">        <span class="keywordflow">break</span>;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">bool</span> success = arc-&gt;Eof() &amp;&amp; outarc-&gt;Close();</div>
</div><!-- fragment --><p>SetNotifier() calls OnEntryUpdated() immediately, then the input stream calls it again whenever it sets more fields in the entry. Since OnEntryUpdated() will be called at least once, this technique always works even when it is not strictly necessary to use it. For example, changing the entry name can be done this way too and it works on seekable streams as well as non-seekable. </p>
</div></div><!-- contents -->

<address class="footer">
	<small>
		Generated on Thu Nov 27 2014 13:46:42 for wxWidgets by <a href="http://www.doxygen.org/index.html" target="_new">Doxygen</a> 1.8.2
	</small>
</address>
<script src="wxwidgets.js" type="text/javascript"></script>
</div><!-- #page_container -->
</body>
</html>