1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Streams for Tar files
4 // Author: Mike Wetherell
5 // Copyright: (c) 2004 Mike Wetherell
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 #ifndef _WX_WXTARSTREAM_H__
10 #define _WX_WXTARSTREAM_H__
16 #include "wx/archive.h"
17 #include "wx/hashmap.h"
20 /////////////////////////////////////////////////////////////////////////////
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
36 // Archive Formats (use wxTAR_PAX, it's backward compatible)
39 wxTAR_USTAR
, // POSIX.1-1990 tar format
40 wxTAR_PAX
// POSIX.1-2001 tar format
44 /////////////////////////////////////////////////////////////////////////////
47 class WXDLLIMPEXP_BASE wxTarNotifier
50 virtual ~wxTarNotifier() { }
52 virtual void OnEntryUpdated(class wxTarEntry
& entry
) = 0;
56 /////////////////////////////////////////////////////////////////////////////
57 // Tar Entry - hold the meta data for a file in the tar
59 class WXDLLIMPEXP_BASE wxTarEntry
: public wxArchiveEntry
62 wxTarEntry(const wxString
& name
= wxEmptyString
,
63 const wxDateTime
& dt
= wxDateTime::Now(),
64 wxFileOffset size
= wxInvalidOffset
);
65 virtual ~wxTarEntry();
67 wxTarEntry(const wxTarEntry
& entry
);
68 wxTarEntry
& operator=(const wxTarEntry
& entry
);
71 wxString
GetName(wxPathFormat format
= wxPATH_NATIVE
) const;
72 wxString
GetInternalName() const { return m_Name
; }
73 wxPathFormat
GetInternalFormat() const { return wxPATH_UNIX
; }
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
; }
91 bool IsReadOnly() const { return !(m_Mode
& 0222); }
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
; }
110 void SetIsDir(bool isDir
= true);
111 void SetIsReadOnly(bool isReadOnly
= true);
113 static wxString
GetInternalName(const wxString
& name
,
114 wxPathFormat format
= wxPATH_NATIVE
,
115 bool *pIsDir
= NULL
);
117 wxTarEntry
*Clone() const { return new wxTarEntry(*this); }
119 void SetNotifier(wxTarNotifier
& WXUNUSED(notifier
)) { }
122 void SetOffset(wxFileOffset offset
) { m_Offset
= offset
; }
124 virtual wxArchiveEntry
* DoClone() const { return Clone(); }
132 wxFileOffset m_Offset
;
133 wxDateTime m_ModifyTime
;
134 wxDateTime m_AccessTime
;
135 wxDateTime m_CreateTime
;
139 wxString m_GroupName
;
143 friend class wxTarInputStream
;
145 DECLARE_DYNAMIC_CLASS(wxTarEntry
)
149 /////////////////////////////////////////////////////////////////////////////
152 WX_DECLARE_STRING_HASH_MAP(wxString
, wxTarHeaderRecords
);
154 class WXDLLIMPEXP_BASE wxTarInputStream
: public wxArchiveInputStream
157 typedef wxTarEntry entry_type
;
159 wxTarInputStream(wxInputStream
& stream
, wxMBConv
& conv
= wxConvLocal
);
160 wxTarInputStream(wxInputStream
*stream
, wxMBConv
& conv
= wxConvLocal
);
161 virtual ~wxTarInputStream();
163 bool OpenEntry(wxTarEntry
& entry
);
166 wxTarEntry
*GetNextEntry();
168 wxFileOffset
GetLength() const { return m_size
; }
169 bool IsSeekable() const { return m_parent_i_stream
->IsSeekable(); }
172 size_t OnSysRead(void *buffer
, size_t size
);
173 wxFileOffset
OnSysTell() const { return m_pos
; }
174 wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
179 wxArchiveEntry
*DoGetNextEntry() { return GetNextEntry(); }
180 bool OpenEntry(wxArchiveEntry
& entry
);
181 bool IsOpened() const { return m_pos
!= wxInvalidOffset
; }
183 wxStreamError
ReadHeaders();
184 bool ReadExtendedHeader(wxTarHeaderRecords
*& recs
);
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;
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
198 class wxTarHeaderBlock
*m_hdr
;
199 wxTarHeaderRecords
*m_HeaderRecs
;
200 wxTarHeaderRecords
*m_GlobalHeaderRecs
;
202 wxDECLARE_NO_COPY_CLASS(wxTarInputStream
);
206 /////////////////////////////////////////////////////////////////////////////
209 class WXDLLIMPEXP_BASE wxTarOutputStream
: public wxArchiveOutputStream
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();
220 bool PutNextEntry(wxTarEntry
*entry
);
222 bool PutNextEntry(const wxString
& name
,
223 const wxDateTime
& dt
= wxDateTime::Now(),
224 wxFileOffset size
= wxInvalidOffset
);
226 bool PutNextDirEntry(const wxString
& name
,
227 const wxDateTime
& dt
= wxDateTime::Now());
229 bool CopyEntry(wxTarEntry
*entry
, wxTarInputStream
& inputStream
);
230 bool CopyArchiveMetaData(wxTarInputStream
& WXUNUSED(s
)) { return true; }
236 bool IsSeekable() const { return m_parent_o_stream
->IsSeekable(); }
238 void SetBlockingFactor(int factor
) { m_BlockingFactor
= factor
; }
239 int GetBlockingFactor() const { return m_BlockingFactor
; }
242 size_t OnSysWrite(const void *buffer
, size_t size
);
243 wxFileOffset
OnSysTell() const { return m_pos
; }
244 wxFileOffset
OnSysSeek(wxFileOffset pos
, wxSeekMode mode
);
247 void Init(wxTarFormat format
);
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
; }
254 bool WriteHeaders(wxTarEntry
& entry
);
256 wxString
PaxHeaderPath(const wxString
& format
, const wxString
& path
);
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
);
264 wxFileOffset m_pos
; // position within the current entry
265 wxFileOffset m_maxpos
; // max pos written
266 wxFileOffset m_size
; // expected entry size
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
271 wxFileOffset m_tarstart
;// offset within the file to the tar
272 wxFileOffset m_tarsize
; // size of tar so far
275 int m_BlockingFactor
;
278 class wxTarHeaderBlock
*m_hdr
;
279 class wxTarHeaderBlock
*m_hdr2
;
281 size_t m_extendedSize
;
283 bool m_endrecWritten
;
285 wxDECLARE_NO_COPY_CLASS(wxTarOutputStream
);
289 /////////////////////////////////////////////////////////////////////////////
292 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
293 typedef wxArchiveIterator
<wxTarInputStream
> wxTarIter
;
294 typedef wxArchiveIterator
<wxTarInputStream
,
295 std::pair
<wxString
, wxTarEntry
*> > wxTarPairIter
;
299 /////////////////////////////////////////////////////////////////////////////
302 class WXDLLIMPEXP_BASE wxTarClassFactory
: public wxArchiveClassFactory
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
;
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()); }
327 wxString
GetInternalName(const wxString
& name
,
328 wxPathFormat format
= wxPATH_NATIVE
) const
329 { return wxTarEntry::GetInternalName(name
, format
); }
331 const wxChar
* const *GetProtocols(wxStreamProtocolType type
332 = wxSTREAM_PROTOCOL
) const;
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
); }
347 DECLARE_DYNAMIC_CLASS(wxTarClassFactory
)
351 #endif // wxUSE_TARSTREAM
353 #endif // _WX_WXTARSTREAM_H__