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