]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: wx/tarstrm.h | |
3 | // Purpose: Streams for Tar files | |
4 | // Author: Mike Wetherell | |
5 | // RCS-ID: $Id$ | |
6 | // Copyright: (c) 2004 Mike Wetherell | |
7 | // Licence: wxWindows licence | |
8 | ///////////////////////////////////////////////////////////////////////////// | |
9 | ||
10 | #ifndef _WX_WXTARSTREAM_H__ | |
11 | #define _WX_WXTARSTREAM_H__ | |
12 | ||
13 | #include "wx/defs.h" | |
14 | ||
15 | #if wxUSE_TARSTREAM | |
16 | ||
17 | #include "wx/archive.h" | |
18 | #include "wx/hashmap.h" | |
19 | ||
20 | ||
21 | ///////////////////////////////////////////////////////////////////////////// | |
22 | // Constants | |
23 | ||
24 | // TypeFlag values | |
25 | enum wxTarType | |
26 | { | |
27 | wxTAR_REGTYPE = '0', // regular file | |
28 | wxTAR_LNKTYPE = '1', // hard link | |
29 | wxTAR_SYMTYPE = '2', // symbolic link | |
30 | wxTAR_CHRTYPE = '3', // character special | |
31 | wxTAR_BLKTYPE = '4', // block special | |
32 | wxTAR_DIRTYPE = '5', // directory | |
33 | wxTAR_FIFOTYPE = '6', // named pipe | |
34 | wxTAR_CONTTYPE = '7' // contiguous file | |
35 | }; | |
36 | ||
37 | // Archive Formats (use wxTAR_PAX, it's backward compatible) | |
38 | enum wxTarFormat | |
39 | { | |
40 | wxTAR_USTAR, // POSIX.1-1990 tar format | |
41 | wxTAR_PAX // POSIX.1-2001 tar format | |
42 | }; | |
43 | ||
44 | ||
45 | ///////////////////////////////////////////////////////////////////////////// | |
46 | // wxTarNotifier | |
47 | ||
48 | class WXDLLIMPEXP_BASE wxTarNotifier | |
49 | { | |
50 | public: | |
51 | virtual ~wxTarNotifier() { } | |
52 | ||
53 | virtual void OnEntryUpdated(class wxTarEntry& entry) = 0; | |
54 | }; | |
55 | ||
56 | ||
57 | ///////////////////////////////////////////////////////////////////////////// | |
58 | // Tar Entry - hold the meta data for a file in the tar | |
59 | ||
60 | class WXDLLIMPEXP_BASE wxTarEntry : public wxArchiveEntry | |
61 | { | |
62 | public: | |
63 | wxTarEntry(const wxString& name = wxEmptyString, | |
64 | const wxDateTime& dt = wxDateTime::Now(), | |
65 | wxFileOffset size = wxInvalidOffset); | |
66 | virtual ~wxTarEntry(); | |
67 | ||
68 | wxTarEntry(const wxTarEntry& entry); | |
69 | wxTarEntry& operator=(const wxTarEntry& entry); | |
70 | ||
71 | // Get accessors | |
72 | wxString GetName(wxPathFormat format = wxPATH_NATIVE) const; | |
73 | wxString GetInternalName() const { return m_Name; } | |
74 | wxPathFormat GetInternalFormat() const { return wxPATH_UNIX; } | |
75 | int GetMode() const; | |
76 | int GetUserId() const { return m_UserId; } | |
77 | int GetGroupId() const { return m_GroupId; } | |
78 | wxFileOffset GetSize() const { return m_Size; } | |
79 | wxFileOffset GetOffset() const { return m_Offset; } | |
80 | wxDateTime GetDateTime() const { return m_ModifyTime; } | |
81 | wxDateTime GetAccessTime() const { return m_AccessTime; } | |
82 | wxDateTime GetCreateTime() const { return m_CreateTime; } | |
83 | int GetTypeFlag() const { return m_TypeFlag; } | |
84 | wxString GetLinkName() const { return m_LinkName; } | |
85 | wxString GetUserName() const { return m_UserName; } | |
86 | wxString GetGroupName() const { return m_GroupName; } | |
87 | int GetDevMajor() const { return m_DevMajor; } | |
88 | int GetDevMinor() const { return m_DevMinor; } | |
89 | ||
90 | // is accessors | |
91 | bool IsDir() const; | |
92 | bool IsReadOnly() const { return !(m_Mode & 0222); } | |
93 | ||
94 | // set accessors | |
95 | void SetName(const wxString& name, wxPathFormat format = wxPATH_NATIVE); | |
96 | void SetUserId(int id) { m_UserId = id; } | |
97 | void SetGroupId(int id) { m_GroupId = id; } | |
98 | void SetMode(int mode); | |
99 | void SetSize(wxFileOffset size) { m_Size = size; } | |
100 | void SetDateTime(const wxDateTime& dt) { m_ModifyTime = dt; } | |
101 | void SetAccessTime(const wxDateTime& dt) { m_AccessTime = dt; } | |
102 | void SetCreateTime(const wxDateTime& dt) { m_CreateTime = dt; } | |
103 | void SetTypeFlag(int type) { m_TypeFlag = type; } | |
104 | void SetLinkName(const wxString& link) { m_LinkName = link; } | |
105 | void SetUserName(const wxString& user) { m_UserName = user; } | |
106 | void SetGroupName(const wxString& group) { m_GroupName = group; } | |
107 | void SetDevMajor(int dev) { m_DevMajor = dev; } | |
108 | void SetDevMinor(int dev) { m_DevMinor = dev; } | |
109 | ||
110 | // set is accessors | |
111 | void SetIsDir(bool isDir = true); | |
112 | void SetIsReadOnly(bool isReadOnly = true); | |
113 | ||
114 | static wxString GetInternalName(const wxString& name, | |
115 | wxPathFormat format = wxPATH_NATIVE, | |
116 | bool *pIsDir = NULL); | |
117 | ||
118 | wxTarEntry *Clone() const { return new wxTarEntry(*this); } | |
119 | ||
120 | void SetNotifier(wxTarNotifier& WXUNUSED(notifier)) { } | |
121 | ||
122 | private: | |
123 | void SetOffset(wxFileOffset offset) { m_Offset = offset; } | |
124 | ||
125 | virtual wxArchiveEntry* DoClone() const { return Clone(); } | |
126 | ||
127 | wxString m_Name; | |
128 | int m_Mode; | |
129 | bool m_IsModeSet; | |
130 | int m_UserId; | |
131 | int m_GroupId; | |
132 | wxFileOffset m_Size; | |
133 | wxFileOffset m_Offset; | |
134 | wxDateTime m_ModifyTime; | |
135 | wxDateTime m_AccessTime; | |
136 | wxDateTime m_CreateTime; | |
137 | int m_TypeFlag; | |
138 | wxString m_LinkName; | |
139 | wxString m_UserName; | |
140 | wxString m_GroupName; | |
141 | int m_DevMajor; | |
142 | int m_DevMinor; | |
143 | ||
144 | friend class wxTarInputStream; | |
145 | ||
146 | DECLARE_DYNAMIC_CLASS(wxTarEntry) | |
147 | }; | |
148 | ||
149 | ||
150 | ///////////////////////////////////////////////////////////////////////////// | |
151 | // wxTarInputStream | |
152 | ||
153 | WX_DECLARE_STRING_HASH_MAP(wxString, wxTarHeaderRecords); | |
154 | ||
155 | class WXDLLIMPEXP_BASE wxTarInputStream : public wxArchiveInputStream | |
156 | { | |
157 | public: | |
158 | typedef wxTarEntry entry_type; | |
159 | ||
160 | wxTarInputStream(wxInputStream& stream, wxMBConv& conv = wxConvLocal); | |
161 | wxTarInputStream(wxInputStream *stream, wxMBConv& conv = wxConvLocal); | |
162 | virtual ~wxTarInputStream(); | |
163 | ||
164 | bool OpenEntry(wxTarEntry& entry); | |
165 | bool CloseEntry(); | |
166 | ||
167 | wxTarEntry *GetNextEntry(); | |
168 | ||
169 | wxFileOffset GetLength() const { return m_size; } | |
170 | bool IsSeekable() const { return m_parent_i_stream->IsSeekable(); } | |
171 | ||
172 | protected: | |
173 | size_t OnSysRead(void *buffer, size_t size); | |
174 | wxFileOffset OnSysTell() const { return m_pos; } | |
175 | wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode); | |
176 | ||
177 | private: | |
178 | void Init(); | |
179 | ||
180 | wxArchiveEntry *DoGetNextEntry() { return GetNextEntry(); } | |
181 | bool OpenEntry(wxArchiveEntry& entry); | |
182 | bool IsOpened() const { return m_pos != wxInvalidOffset; } | |
183 | ||
184 | wxStreamError ReadHeaders(); | |
185 | bool ReadExtendedHeader(wxTarHeaderRecords*& recs); | |
186 | ||
187 | wxString GetExtendedHeader(const wxString& key) const; | |
188 | wxString GetHeaderPath() const; | |
189 | wxFileOffset GetHeaderNumber(int id) const; | |
190 | wxString GetHeaderString(int id) const; | |
191 | wxDateTime GetHeaderDate(const wxString& key) const; | |
192 | ||
193 | wxFileOffset m_pos; // position within the current entry | |
194 | wxFileOffset m_offset; // offset to the start of the entry's data | |
195 | wxFileOffset m_size; // size of the current entry's data | |
196 | ||
197 | int m_sumType; | |
198 | int m_tarType; | |
199 | class wxTarHeaderBlock *m_hdr; | |
200 | wxTarHeaderRecords *m_HeaderRecs; | |
201 | wxTarHeaderRecords *m_GlobalHeaderRecs; | |
202 | ||
203 | wxDECLARE_NO_COPY_CLASS(wxTarInputStream); | |
204 | }; | |
205 | ||
206 | ||
207 | ///////////////////////////////////////////////////////////////////////////// | |
208 | // wxTarOutputStream | |
209 | ||
210 | class WXDLLIMPEXP_BASE wxTarOutputStream : public wxArchiveOutputStream | |
211 | { | |
212 | public: | |
213 | wxTarOutputStream(wxOutputStream& stream, | |
214 | wxTarFormat format = wxTAR_PAX, | |
215 | wxMBConv& conv = wxConvLocal); | |
216 | wxTarOutputStream(wxOutputStream *stream, | |
217 | wxTarFormat format = wxTAR_PAX, | |
218 | wxMBConv& conv = wxConvLocal); | |
219 | virtual ~wxTarOutputStream(); | |
220 | ||
221 | bool PutNextEntry(wxTarEntry *entry); | |
222 | ||
223 | bool PutNextEntry(const wxString& name, | |
224 | const wxDateTime& dt = wxDateTime::Now(), | |
225 | wxFileOffset size = wxInvalidOffset); | |
226 | ||
227 | bool PutNextDirEntry(const wxString& name, | |
228 | const wxDateTime& dt = wxDateTime::Now()); | |
229 | ||
230 | bool CopyEntry(wxTarEntry *entry, wxTarInputStream& inputStream); | |
231 | bool CopyArchiveMetaData(wxTarInputStream& WXUNUSED(s)) { return true; } | |
232 | ||
233 | void Sync(); | |
234 | bool CloseEntry(); | |
235 | bool Close(); | |
236 | ||
237 | bool IsSeekable() const { return m_parent_o_stream->IsSeekable(); } | |
238 | ||
239 | void SetBlockingFactor(int factor) { m_BlockingFactor = factor; } | |
240 | int GetBlockingFactor() const { return m_BlockingFactor; } | |
241 | ||
242 | protected: | |
243 | size_t OnSysWrite(const void *buffer, size_t size); | |
244 | wxFileOffset OnSysTell() const { return m_pos; } | |
245 | wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode); | |
246 | ||
247 | private: | |
248 | void Init(wxTarFormat format); | |
249 | ||
250 | bool PutNextEntry(wxArchiveEntry *entry); | |
251 | bool CopyEntry(wxArchiveEntry *entry, wxArchiveInputStream& stream); | |
252 | bool CopyArchiveMetaData(wxArchiveInputStream& WXUNUSED(s)) { return true; } | |
253 | bool IsOpened() const { return m_pos != wxInvalidOffset; } | |
254 | ||
255 | bool WriteHeaders(wxTarEntry& entry); | |
256 | bool ModifyHeader(); | |
257 | wxString PaxHeaderPath(const wxString& format, const wxString& path); | |
258 | ||
259 | void SetExtendedHeader(const wxString& key, const wxString& value); | |
260 | void SetHeaderPath(const wxString& name); | |
261 | bool SetHeaderNumber(int id, wxFileOffset n); | |
262 | void SetHeaderString(int id, const wxString& str); | |
263 | void SetHeaderDate(const wxString& key, const wxDateTime& datetime); | |
264 | ||
265 | wxFileOffset m_pos; // position within the current entry | |
266 | wxFileOffset m_maxpos; // max pos written | |
267 | wxFileOffset m_size; // expected entry size | |
268 | ||
269 | wxFileOffset m_headpos; // offset within the file to the entry's header | |
270 | wxFileOffset m_datapos; // offset within the file to the entry's data | |
271 | ||
272 | wxFileOffset m_tarstart;// offset within the file to the tar | |
273 | wxFileOffset m_tarsize; // size of tar so far | |
274 | ||
275 | bool m_pax; | |
276 | int m_BlockingFactor; | |
277 | wxUint32 m_chksum; | |
278 | bool m_large; | |
279 | class wxTarHeaderBlock *m_hdr; | |
280 | class wxTarHeaderBlock *m_hdr2; | |
281 | char *m_extendedHdr; | |
282 | size_t m_extendedSize; | |
283 | wxString m_badfit; | |
284 | bool m_endrecWritten; | |
285 | ||
286 | wxDECLARE_NO_COPY_CLASS(wxTarOutputStream); | |
287 | }; | |
288 | ||
289 | ||
290 | ///////////////////////////////////////////////////////////////////////////// | |
291 | // Iterators | |
292 | ||
293 | #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR | |
294 | typedef wxArchiveIterator<wxTarInputStream> wxTarIter; | |
295 | typedef wxArchiveIterator<wxTarInputStream, | |
296 | std::pair<wxString, wxTarEntry*> > wxTarPairIter; | |
297 | #endif | |
298 | ||
299 | ||
300 | ///////////////////////////////////////////////////////////////////////////// | |
301 | // wxTarClassFactory | |
302 | ||
303 | class WXDLLIMPEXP_BASE wxTarClassFactory : public wxArchiveClassFactory | |
304 | { | |
305 | public: | |
306 | typedef wxTarEntry entry_type; | |
307 | typedef wxTarInputStream instream_type; | |
308 | typedef wxTarOutputStream outstream_type; | |
309 | typedef wxTarNotifier notifier_type; | |
310 | #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR | |
311 | typedef wxTarIter iter_type; | |
312 | typedef wxTarPairIter pairiter_type; | |
313 | #endif | |
314 | ||
315 | wxTarClassFactory(); | |
316 | ||
317 | wxTarEntry *NewEntry() const | |
318 | { return new wxTarEntry; } | |
319 | wxTarInputStream *NewStream(wxInputStream& stream) const | |
320 | { return new wxTarInputStream(stream, GetConv()); } | |
321 | wxTarOutputStream *NewStream(wxOutputStream& stream) const | |
322 | { return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); } | |
323 | wxTarInputStream *NewStream(wxInputStream *stream) const | |
324 | { return new wxTarInputStream(stream, GetConv()); } | |
325 | wxTarOutputStream *NewStream(wxOutputStream *stream) const | |
326 | { return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); } | |
327 | ||
328 | wxString GetInternalName(const wxString& name, | |
329 | wxPathFormat format = wxPATH_NATIVE) const | |
330 | { return wxTarEntry::GetInternalName(name, format); } | |
331 | ||
332 | const wxChar * const *GetProtocols(wxStreamProtocolType type | |
333 | = wxSTREAM_PROTOCOL) const; | |
334 | ||
335 | protected: | |
336 | wxArchiveEntry *DoNewEntry() const | |
337 | { return NewEntry(); } | |
338 | wxArchiveInputStream *DoNewStream(wxInputStream& stream) const | |
339 | { return NewStream(stream); } | |
340 | wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const | |
341 | { return NewStream(stream); } | |
342 | wxArchiveInputStream *DoNewStream(wxInputStream *stream) const | |
343 | { return NewStream(stream); } | |
344 | wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const | |
345 | { return NewStream(stream); } | |
346 | ||
347 | private: | |
348 | DECLARE_DYNAMIC_CLASS(wxTarClassFactory) | |
349 | }; | |
350 | ||
351 | ||
352 | #endif // wxUSE_TARSTREAM | |
353 | ||
354 | #endif // _WX_WXTARSTREAM_H__ |