1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Streams for Tar files
4 // Author: Mike Wetherell
6 // Copyright: (c) 2004 Mike Wetherell
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #ifndef _WX_WXTARSTREAM_H__
11 #define _WX_WXTARSTREAM_H__
17 #include "wx/archive.h"
20 /////////////////////////////////////////////////////////////////////////////
25 wxTAR_REGTYPE
= '0', // regular file
26 wxTAR_LNKTYPE
= '1', // hard link
27 wxTAR_SYMTYPE
= '2', // symbolic link
28 wxTAR_CHRTYPE
= '3', // character special
29 wxTAR_BLKTYPE
= '4', // block special
30 wxTAR_DIRTYPE
= '5', // directory
31 wxTAR_FIFOTYPE
= '6', // named pipe
32 wxTAR_CONTTYPE
= '7' // contiguous file
35 // Archive Formats (use wxTAR_PAX, it's backward compatible)
38 wxTAR_USTAR
, // POSIX.1-1990 tar format
39 wxTAR_PAX
// POSIX.1-2001 tar format
43 /////////////////////////////////////////////////////////////////////////////
46 class WXDLLIMPEXP_BASE wxTarNotifier
49 virtual ~wxTarNotifier() { }
51 virtual void OnEntryUpdated(class wxTarEntry
& entry
) = 0;
55 /////////////////////////////////////////////////////////////////////////////
56 // Tar Entry - hold the meta data for a file in the tar
58 class WXDLLIMPEXP_BASE wxTarEntry
: public wxArchiveEntry
61 wxTarEntry(const wxString
& name
= wxEmptyString
,
62 const wxDateTime
& dt
= wxDateTime::Now(),
63 wxFileOffset size
= wxInvalidOffset
);
64 virtual ~wxTarEntry();
66 wxTarEntry(const wxTarEntry
& entry
);
67 wxTarEntry
& operator=(const wxTarEntry
& entry
);
70 wxString
GetName(wxPathFormat format
= wxPATH_NATIVE
) const;
71 wxString
GetInternalName() const { return m_Name
; }
72 wxPathFormat
GetInternalFormat() const { return wxPATH_UNIX
; }
74 int GetUserId() const { return m_UserId
; }
75 int GetGroupId() const { return m_GroupId
; }
76 wxFileOffset
GetSize() const { return m_Size
; }
77 wxFileOffset
GetOffset() const { return m_Offset
; }
78 wxDateTime
GetDateTime() const { return m_ModifyTime
; }
79 wxDateTime
GetAccessTime() const { return m_AccessTime
; }
80 wxDateTime
GetCreateTime() const { return m_CreateTime
; }
81 int GetTypeFlag() const { return m_TypeFlag
; }
82 wxString
GetLinkName() const { return m_LinkName
; }
83 wxString
GetUserName() const { return m_UserName
; }
84 wxString
GetGroupName() const { return m_GroupName
; }
85 int GetDevMajor() const { return m_DevMajor
; }
86 int GetDevMinor() const { return m_DevMinor
; }
90 bool IsReadOnly() const { return !(m_Mode
& 0222); }
93 void SetName(const wxString
& name
, wxPathFormat format
= wxPATH_NATIVE
);
94 void SetUserId(int id
) { m_UserId
= id
; }
95 void SetGroupId(int id
) { m_GroupId
= id
; }
96 void SetMode(int mode
);
97 void SetSize(wxFileOffset size
) { m_Size
= size
; }
98 void SetDateTime(const wxDateTime
& dt
) { m_ModifyTime
= dt
; }
99 void SetAccessTime(const wxDateTime
& dt
) { m_AccessTime
= dt
; }
100 void SetCreateTime(const wxDateTime
& dt
) { m_CreateTime
= dt
; }
101 void SetTypeFlag(int type
) { m_TypeFlag
= type
; }
102 void SetLinkName(const wxString
& link
) { m_LinkName
= link
; }
103 void SetUserName(const wxString
& user
) { m_UserName
= user
; }
104 void SetGroupName(const wxString
& group
) { m_GroupName
= group
; }
105 void SetDevMajor(int dev
) { m_DevMajor
= dev
; }
106 void SetDevMinor(int dev
) { m_DevMinor
= dev
; }
109 void SetIsDir(bool isDir
= true);
110 void SetIsReadOnly(bool isReadOnly
= true);
112 static wxString
GetInternalName(const wxString
& name
,
113 wxPathFormat format
= wxPATH_NATIVE
,
114 bool *pIsDir
= NULL
);
116 wxTarEntry
*Clone() const { return new wxTarEntry(*this); }
118 void SetNotifier(wxTarNotifier
& WXUNUSED(notifier
)) { }
121 void SetOffset(wxFileOffset offset
) { m_Offset
= offset
; }
123 virtual wxArchiveEntry
* DoClone() const { return Clone(); }
131 wxFileOffset m_Offset
;
132 wxDateTime m_ModifyTime
;
133 wxDateTime m_AccessTime
;
134 wxDateTime m_CreateTime
;
138 wxString m_GroupName
;
142 friend class wxTarInputStream
;
144 DECLARE_DYNAMIC_CLASS(wxTarEntry
)
148 /////////////////////////////////////////////////////////////////////////////
151 WX_DECLARE_STRING_HASH_MAP(wxString
, wxTarHeaderRecords
);
153 class WXDLLIMPEXP_BASE wxTarInputStream
: public wxArchiveInputStream
156 typedef wxTarEntry entry_type
;
158 wxTarInputStream(wxInputStream
& stream
, wxMBConv
& conv
= wxConvLocal
);
159 wxTarInputStream(wxInputStream
*stream
, wxMBConv
& conv
= wxConvLocal
);
160 virtual ~wxTarInputStream();
162 bool OpenEntry(wxTarEntry
& entry
);
165 wxTarEntry
*GetNextEntry();
167 wxFileOffset
GetLength() const { return m_size
; }
168 bool IsSeekable() const { return m_parent_i_stream
->IsSeekable(); }
171 size_t OnSysRead(void *buffer
, size_t size
);
172 wxFileOffset
OnSysTell() const { return m_pos
; }
173 wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
178 wxArchiveEntry
*DoGetNextEntry() { return GetNextEntry(); }
179 bool OpenEntry(wxArchiveEntry
& entry
);
180 bool IsOpened() const { return m_pos
!= wxInvalidOffset
; }
182 wxStreamError
ReadHeaders();
183 bool ReadExtendedHeader(wxTarHeaderRecords
*& recs
);
185 wxString
GetExtendedHeader(const wxString
& key
) const;
186 wxString
GetHeaderPath() const;
187 wxFileOffset
GetHeaderNumber(int id
) const;
188 wxString
GetHeaderString(int id
) const;
189 wxDateTime
GetHeaderDate(const wxString
& key
) const;
191 wxFileOffset m_pos
; // position within the current entry
192 wxFileOffset m_offset
; // offset to the start of the entry's data
193 wxFileOffset m_size
; // size of the current entry's data
197 class wxTarHeaderBlock
*m_hdr
;
198 wxTarHeaderRecords
*m_HeaderRecs
;
199 wxTarHeaderRecords
*m_GlobalHeaderRecs
;
201 DECLARE_NO_COPY_CLASS(wxTarInputStream
)
205 /////////////////////////////////////////////////////////////////////////////
208 class WXDLLIMPEXP_BASE wxTarOutputStream
: public wxArchiveOutputStream
211 wxTarOutputStream(wxOutputStream
& stream
,
212 wxTarFormat format
= wxTAR_PAX
,
213 wxMBConv
& conv
= wxConvLocal
);
214 wxTarOutputStream(wxOutputStream
*stream
,
215 wxTarFormat format
= wxTAR_PAX
,
216 wxMBConv
& conv
= wxConvLocal
);
217 virtual ~wxTarOutputStream();
219 bool PutNextEntry(wxTarEntry
*entry
);
221 bool PutNextEntry(const wxString
& name
,
222 const wxDateTime
& dt
= wxDateTime::Now(),
223 wxFileOffset size
= wxInvalidOffset
);
225 bool PutNextDirEntry(const wxString
& name
,
226 const wxDateTime
& dt
= wxDateTime::Now());
228 bool CopyEntry(wxTarEntry
*entry
, wxTarInputStream
& inputStream
);
229 bool CopyArchiveMetaData(wxTarInputStream
& WXUNUSED(s
)) { return true; }
235 bool IsSeekable() const { return m_parent_o_stream
->IsSeekable(); }
237 void SetBlockingFactor(int factor
) { m_BlockingFactor
= factor
; }
238 int GetBlockingFactor() const { return m_BlockingFactor
; }
241 size_t OnSysWrite(const void *buffer
, size_t size
);
242 wxFileOffset
OnSysTell() const { return m_pos
; }
243 wxFileOffset
OnSysSeek(wxFileOffset pos
, wxSeekMode mode
);
246 void Init(wxTarFormat format
);
248 bool PutNextEntry(wxArchiveEntry
*entry
);
249 bool CopyEntry(wxArchiveEntry
*entry
, wxArchiveInputStream
& stream
);
250 bool CopyArchiveMetaData(wxArchiveInputStream
& WXUNUSED(s
)) { return true; }
251 bool IsOpened() const { return m_pos
!= wxInvalidOffset
; }
253 bool WriteHeaders(wxTarEntry
& entry
);
255 wxString
PaxHeaderPath(const wxString
& format
, const wxString
& path
);
257 void SetExtendedHeader(const wxString
& key
, const wxString
& value
);
258 void SetHeaderPath(const wxString
& name
);
259 bool SetHeaderNumber(int id
, wxFileOffset n
);
260 void SetHeaderString(int id
, const wxString
& str
);
261 void SetHeaderDate(const wxString
& key
, const wxDateTime
& datetime
);
263 wxFileOffset m_pos
; // position within the current entry
264 wxFileOffset m_maxpos
; // max pos written
265 wxFileOffset m_size
; // expected entry size
267 wxFileOffset m_headpos
; // offset within the file to the entry's header
268 wxFileOffset m_datapos
; // offset within the file to the entry's data
270 wxFileOffset m_tarstart
;// offset within the file to the tar
271 wxFileOffset m_tarsize
; // size of tar so far
274 int m_BlockingFactor
;
277 class wxTarHeaderBlock
*m_hdr
;
278 class wxTarHeaderBlock
*m_hdr2
;
280 size_t m_extendedSize
;
283 DECLARE_NO_COPY_CLASS(wxTarOutputStream
)
287 /////////////////////////////////////////////////////////////////////////////
290 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
291 typedef wxArchiveIterator
<wxTarInputStream
> wxTarIter
;
292 typedef wxArchiveIterator
<wxTarInputStream
,
293 std::pair
<wxString
, wxTarEntry
*> > wxTarPairIter
;
297 /////////////////////////////////////////////////////////////////////////////
300 class WXDLLIMPEXP_BASE wxTarClassFactory
: public wxArchiveClassFactory
303 typedef wxTarEntry entry_type
;
304 typedef wxTarInputStream instream_type
;
305 typedef wxTarOutputStream outstream_type
;
306 typedef wxTarNotifier notifier_type
;
307 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
308 typedef wxTarIter iter_type
;
309 typedef wxTarPairIter pairiter_type
;
314 wxTarEntry
*NewEntry() const
315 { return new wxTarEntry
; }
316 wxTarInputStream
*NewStream(wxInputStream
& stream
) const
317 { return new wxTarInputStream(stream
, GetConv()); }
318 wxTarOutputStream
*NewStream(wxOutputStream
& stream
) const
319 { return new wxTarOutputStream(stream
, wxTAR_PAX
, GetConv()); }
320 wxTarInputStream
*NewStream(wxInputStream
*stream
) const
321 { return new wxTarInputStream(stream
, GetConv()); }
322 wxTarOutputStream
*NewStream(wxOutputStream
*stream
) const
323 { return new wxTarOutputStream(stream
, wxTAR_PAX
, GetConv()); }
325 wxString
GetInternalName(const wxString
& name
,
326 wxPathFormat format
= wxPATH_NATIVE
) const
327 { return wxTarEntry::GetInternalName(name
, format
); }
329 const wxChar
* const *GetProtocols(wxStreamProtocolType type
330 = wxSTREAM_PROTOCOL
) const;
333 wxArchiveEntry
*DoNewEntry() const
334 { return NewEntry(); }
335 wxArchiveInputStream
*DoNewStream(wxInputStream
& stream
) const
336 { return NewStream(stream
); }
337 wxArchiveOutputStream
*DoNewStream(wxOutputStream
& stream
) const
338 { return NewStream(stream
); }
339 wxArchiveInputStream
*DoNewStream(wxInputStream
*stream
) const
340 { return NewStream(stream
); }
341 wxArchiveOutputStream
*DoNewStream(wxOutputStream
*stream
) const
342 { return NewStream(stream
); }
345 DECLARE_DYNAMIC_CLASS(wxTarClassFactory
)
349 #endif // wxUSE_TARSTREAM
351 #endif // _WX_WXTARSTREAM_H__