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"
18 #include "wx/hashmap.h"
21 /////////////////////////////////////////////////////////////////////////////
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
37 // Archive Formats (use wxTAR_PAX, it's backward compatible)
40 wxTAR_USTAR
, // POSIX.1-1990 tar format
41 wxTAR_PAX
// POSIX.1-2001 tar format
45 /////////////////////////////////////////////////////////////////////////////
48 class WXDLLIMPEXP_BASE wxTarNotifier
51 virtual ~wxTarNotifier() { }
53 virtual void OnEntryUpdated(class wxTarEntry
& entry
) = 0;
57 /////////////////////////////////////////////////////////////////////////////
58 // Tar Entry - hold the meta data for a file in the tar
60 class WXDLLIMPEXP_BASE wxTarEntry
: public wxArchiveEntry
63 wxTarEntry(const wxString
& name
= wxEmptyString
,
64 const wxDateTime
& dt
= wxDateTime::Now(),
65 wxFileOffset size
= wxInvalidOffset
);
66 virtual ~wxTarEntry();
68 wxTarEntry(const wxTarEntry
& entry
);
69 wxTarEntry
& operator=(const wxTarEntry
& entry
);
72 wxString
GetName(wxPathFormat format
= wxPATH_NATIVE
) const;
73 wxString
GetInternalName() const { return m_Name
; }
74 wxPathFormat
GetInternalFormat() const { return wxPATH_UNIX
; }
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
; }
92 bool IsReadOnly() const { return !(m_Mode
& 0222); }
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
; }
111 void SetIsDir(bool isDir
= true);
112 void SetIsReadOnly(bool isReadOnly
= true);
114 static wxString
GetInternalName(const wxString
& name
,
115 wxPathFormat format
= wxPATH_NATIVE
,
116 bool *pIsDir
= NULL
);
118 wxTarEntry
*Clone() const { return new wxTarEntry(*this); }
120 void SetNotifier(wxTarNotifier
& WXUNUSED(notifier
)) { }
123 void SetOffset(wxFileOffset offset
) { m_Offset
= offset
; }
125 virtual wxArchiveEntry
* DoClone() const { return Clone(); }
133 wxFileOffset m_Offset
;
134 wxDateTime m_ModifyTime
;
135 wxDateTime m_AccessTime
;
136 wxDateTime m_CreateTime
;
140 wxString m_GroupName
;
144 friend class wxTarInputStream
;
146 DECLARE_DYNAMIC_CLASS(wxTarEntry
)
150 /////////////////////////////////////////////////////////////////////////////
153 WX_DECLARE_STRING_HASH_MAP(wxString
, wxTarHeaderRecords
);
155 class WXDLLIMPEXP_BASE wxTarInputStream
: public wxArchiveInputStream
158 typedef wxTarEntry entry_type
;
160 wxTarInputStream(wxInputStream
& stream
, wxMBConv
& conv
= wxConvLocal
);
161 wxTarInputStream(wxInputStream
*stream
, wxMBConv
& conv
= wxConvLocal
);
162 virtual ~wxTarInputStream();
164 bool OpenEntry(wxTarEntry
& entry
);
167 wxTarEntry
*GetNextEntry();
169 wxFileOffset
GetLength() const { return m_size
; }
170 bool IsSeekable() const { return m_parent_i_stream
->IsSeekable(); }
173 size_t OnSysRead(void *buffer
, size_t size
);
174 wxFileOffset
OnSysTell() const { return m_pos
; }
175 wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
180 wxArchiveEntry
*DoGetNextEntry() { return GetNextEntry(); }
181 bool OpenEntry(wxArchiveEntry
& entry
);
182 bool IsOpened() const { return m_pos
!= wxInvalidOffset
; }
184 wxStreamError
ReadHeaders();
185 bool ReadExtendedHeader(wxTarHeaderRecords
*& recs
);
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;
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
199 class wxTarHeaderBlock
*m_hdr
;
200 wxTarHeaderRecords
*m_HeaderRecs
;
201 wxTarHeaderRecords
*m_GlobalHeaderRecs
;
203 DECLARE_NO_COPY_CLASS(wxTarInputStream
)
207 /////////////////////////////////////////////////////////////////////////////
210 class WXDLLIMPEXP_BASE wxTarOutputStream
: public wxArchiveOutputStream
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();
221 bool PutNextEntry(wxTarEntry
*entry
);
223 bool PutNextEntry(const wxString
& name
,
224 const wxDateTime
& dt
= wxDateTime::Now(),
225 wxFileOffset size
= wxInvalidOffset
);
227 bool PutNextDirEntry(const wxString
& name
,
228 const wxDateTime
& dt
= wxDateTime::Now());
230 bool CopyEntry(wxTarEntry
*entry
, wxTarInputStream
& inputStream
);
231 bool CopyArchiveMetaData(wxTarInputStream
& WXUNUSED(s
)) { return true; }
237 bool IsSeekable() const { return m_parent_o_stream
->IsSeekable(); }
239 void SetBlockingFactor(int factor
) { m_BlockingFactor
= factor
; }
240 int GetBlockingFactor() const { return m_BlockingFactor
; }
243 size_t OnSysWrite(const void *buffer
, size_t size
);
244 wxFileOffset
OnSysTell() const { return m_pos
; }
245 wxFileOffset
OnSysSeek(wxFileOffset pos
, wxSeekMode mode
);
248 void Init(wxTarFormat format
);
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
; }
255 bool WriteHeaders(wxTarEntry
& entry
);
257 wxString
PaxHeaderPath(const wxString
& format
, const wxString
& path
);
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
);
265 wxFileOffset m_pos
; // position within the current entry
266 wxFileOffset m_maxpos
; // max pos written
267 wxFileOffset m_size
; // expected entry size
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
272 wxFileOffset m_tarstart
;// offset within the file to the tar
273 wxFileOffset m_tarsize
; // size of tar so far
276 int m_BlockingFactor
;
279 class wxTarHeaderBlock
*m_hdr
;
280 class wxTarHeaderBlock
*m_hdr2
;
282 size_t m_extendedSize
;
284 bool m_endrecWritten
;
286 DECLARE_NO_COPY_CLASS(wxTarOutputStream
)
290 /////////////////////////////////////////////////////////////////////////////
293 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
294 typedef wxArchiveIterator
<wxTarInputStream
> wxTarIter
;
295 typedef wxArchiveIterator
<wxTarInputStream
,
296 std::pair
<wxString
, wxTarEntry
*> > wxTarPairIter
;
300 /////////////////////////////////////////////////////////////////////////////
303 class WXDLLIMPEXP_BASE wxTarClassFactory
: public wxArchiveClassFactory
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
;
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()); }
328 wxString
GetInternalName(const wxString
& name
,
329 wxPathFormat format
= wxPATH_NATIVE
) const
330 { return wxTarEntry::GetInternalName(name
, format
); }
332 const wxChar
* const *GetProtocols(wxStreamProtocolType type
333 = wxSTREAM_PROTOCOL
) const;
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
); }
348 DECLARE_DYNAMIC_CLASS(wxTarClassFactory
)
352 #endif // wxUSE_TARSTREAM
354 #endif // _WX_WXTARSTREAM_H__