tarstrm.h 12 KB

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