1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: wx/tarstrm.h 3 // Purpose: Streams for Tar files 4 // Author: Mike Wetherell 5 // RCS-ID: $Id: tarstrm.h 43887 2006-12-09 22:28:11Z MW $ 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: ~wxTarNotifier()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; GetInternalName()72 wxString GetInternalName() const { return m_Name; } GetInternalFormat()73 wxPathFormat GetInternalFormat() const { return wxPATH_UNIX; } 74 int GetMode() const; GetUserId()75 int GetUserId() const { return m_UserId; } GetGroupId()76 int GetGroupId() const { return m_GroupId; } GetSize()77 wxFileOffset GetSize() const { return m_Size; } GetOffset()78 wxFileOffset GetOffset() const { return m_Offset; } GetDateTime()79 wxDateTime GetDateTime() const { return m_ModifyTime; } GetAccessTime()80 wxDateTime GetAccessTime() const { return m_AccessTime; } GetCreateTime()81 wxDateTime GetCreateTime() const { return m_CreateTime; } GetTypeFlag()82 int GetTypeFlag() const { return m_TypeFlag; } GetLinkName()83 wxString GetLinkName() const { return m_LinkName; } GetUserName()84 wxString GetUserName() const { return m_UserName; } GetGroupName()85 wxString GetGroupName() const { return m_GroupName; } GetDevMajor()86 int GetDevMajor() const { return m_DevMajor; } GetDevMinor()87 int GetDevMinor() const { return m_DevMinor; } 88 89 // is accessors 90 bool IsDir() const; IsReadOnly()91 bool IsReadOnly() const { return !(m_Mode & 0222); } 92 93 // set accessors 94 void SetName(const wxString& name, wxPathFormat format = wxPATH_NATIVE); SetUserId(int id)95 void SetUserId(int id) { m_UserId = id; } SetGroupId(int id)96 void SetGroupId(int id) { m_GroupId = id; } 97 void SetMode(int mode); SetSize(wxFileOffset size)98 void SetSize(wxFileOffset size) { m_Size = size; } SetDateTime(const wxDateTime & dt)99 void SetDateTime(const wxDateTime& dt) { m_ModifyTime = dt; } SetAccessTime(const wxDateTime & dt)100 void SetAccessTime(const wxDateTime& dt) { m_AccessTime = dt; } SetCreateTime(const wxDateTime & dt)101 void SetCreateTime(const wxDateTime& dt) { m_CreateTime = dt; } SetTypeFlag(int type)102 void SetTypeFlag(int type) { m_TypeFlag = type; } SetLinkName(const wxString & link)103 void SetLinkName(const wxString& link) { m_LinkName = link; } SetUserName(const wxString & user)104 void SetUserName(const wxString& user) { m_UserName = user; } SetGroupName(const wxString & group)105 void SetGroupName(const wxString& group) { m_GroupName = group; } SetDevMajor(int dev)106 void SetDevMajor(int dev) { m_DevMajor = dev; } SetDevMinor(int 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 Clone()117 wxTarEntry *Clone() const { return new wxTarEntry(*this); } 118 SetNotifier(wxTarNotifier & WXUNUSED (notifier))119 void SetNotifier(wxTarNotifier& WXUNUSED(notifier)) { } 120 121 private: SetOffset(wxFileOffset offset)122 void SetOffset(wxFileOffset offset) { m_Offset = offset; } 123 DoClone()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 GetLength()168 wxFileOffset GetLength() const { return m_size; } IsSeekable()169 bool IsSeekable() const { return m_parent_i_stream->IsSeekable(); } 170 171 protected: 172 size_t OnSysRead(void *buffer, size_t size); OnSysTell()173 wxFileOffset OnSysTell() const { return m_pos; } 174 wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode); 175 176 private: 177 void Init(); 178 DoGetNextEntry()179 wxArchiveEntry *DoGetNextEntry() { return GetNextEntry(); } 180 bool OpenEntry(wxArchiveEntry& entry); IsOpened()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); CopyArchiveMetaData(wxTarInputStream & WXUNUSED (s))230 bool CopyArchiveMetaData(wxTarInputStream& WXUNUSED(s)) { return true; } 231 232 void Sync(); 233 bool CloseEntry(); 234 bool Close(); 235 IsSeekable()236 bool IsSeekable() const { return m_parent_o_stream->IsSeekable(); } 237 SetBlockingFactor(int factor)238 void SetBlockingFactor(int factor) { m_BlockingFactor = factor; } GetBlockingFactor()239 int GetBlockingFactor() const { return m_BlockingFactor; } 240 241 protected: 242 size_t OnSysWrite(const void *buffer, size_t size); OnSysTell()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); CopyArchiveMetaData(wxArchiveInputStream & WXUNUSED (s))251 bool CopyArchiveMetaData(wxArchiveInputStream& WXUNUSED(s)) { return true; } IsOpened()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 284 DECLARE_NO_COPY_CLASS(wxTarOutputStream) 285 }; 286 287 288 ///////////////////////////////////////////////////////////////////////////// 289 // Iterators 290 291 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR 292 typedef wxArchiveIterator<wxTarInputStream> wxTarIter; 293 typedef wxArchiveIterator<wxTarInputStream, 294 std::pair<wxString, wxTarEntry*> > wxTarPairIter; 295 #endif 296 297 298 ///////////////////////////////////////////////////////////////////////////// 299 // wxTarClassFactory 300 301 class WXDLLIMPEXP_BASE wxTarClassFactory : public wxArchiveClassFactory 302 { 303 public: 304 typedef wxTarEntry entry_type; 305 typedef wxTarInputStream instream_type; 306 typedef wxTarOutputStream outstream_type; 307 typedef wxTarNotifier notifier_type; 308 #if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR 309 typedef wxTarIter iter_type; 310 typedef wxTarPairIter pairiter_type; 311 #endif 312 313 wxTarClassFactory(); 314 NewEntry()315 wxTarEntry *NewEntry() const 316 { return new wxTarEntry; } NewStream(wxInputStream & stream)317 wxTarInputStream *NewStream(wxInputStream& stream) const 318 { return new wxTarInputStream(stream, GetConv()); } NewStream(wxOutputStream & stream)319 wxTarOutputStream *NewStream(wxOutputStream& stream) const 320 { return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); } NewStream(wxInputStream * stream)321 wxTarInputStream *NewStream(wxInputStream *stream) const 322 { return new wxTarInputStream(stream, GetConv()); } NewStream(wxOutputStream * stream)323 wxTarOutputStream *NewStream(wxOutputStream *stream) const 324 { return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); } 325 326 wxString GetInternalName(const wxString& name, 327 wxPathFormat format = wxPATH_NATIVE) const 328 { return wxTarEntry::GetInternalName(name, format); } 329 330 const wxChar * const *GetProtocols(wxStreamProtocolType type 331 = wxSTREAM_PROTOCOL) const; 332 333 protected: DoNewEntry()334 wxArchiveEntry *DoNewEntry() const 335 { return NewEntry(); } DoNewStream(wxInputStream & stream)336 wxArchiveInputStream *DoNewStream(wxInputStream& stream) const 337 { return NewStream(stream); } DoNewStream(wxOutputStream & stream)338 wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const 339 { return NewStream(stream); } DoNewStream(wxInputStream * stream)340 wxArchiveInputStream *DoNewStream(wxInputStream *stream) const 341 { return NewStream(stream); } DoNewStream(wxOutputStream * stream)342 wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const 343 { return NewStream(stream); } 344 345 private: 346 DECLARE_DYNAMIC_CLASS(wxTarClassFactory) 347 }; 348 349 350 #endif // wxUSE_TARSTREAM 351 352 #endif // _WX_WXTARSTREAM_H__ 353