Add tar streams.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42505 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
c81c3d2db2
commit
dd1462c3f9
349
include/wx/tarstrm.h
Normal file
349
include/wx/tarstrm.h
Normal file
@ -0,0 +1,349 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tarstrm.h
|
||||
// Purpose: Streams for Tar files
|
||||
// Author: Mike Wetherell
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2004 Mike Wetherell
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_WXTARSTREAM_H__
|
||||
#define _WX_WXTARSTREAM_H__
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_TARSTREAM
|
||||
|
||||
#include "wx/archive.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Constants
|
||||
|
||||
// TypeFlag values
|
||||
enum {
|
||||
wxTAR_REGTYPE = '0', // regular file
|
||||
wxTAR_LNKTYPE = '1', // hard link
|
||||
wxTAR_SYMTYPE = '2', // symbolic link
|
||||
wxTAR_CHRTYPE = '3', // character special
|
||||
wxTAR_BLKTYPE = '4', // block special
|
||||
wxTAR_DIRTYPE = '5', // directory
|
||||
wxTAR_FIFOTYPE = '6', // named pipe
|
||||
wxTAR_CONTTYPE = '7' // contiguous file
|
||||
};
|
||||
|
||||
// Archive Formats (use wxTAR_PAX, it's backward compatible)
|
||||
enum wxTarFormat
|
||||
{
|
||||
wxTAR_USTAR, // POSIX.1-1990 tar format
|
||||
wxTAR_PAX // POSIX.1-2001 tar format
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// wxTarNotifier
|
||||
|
||||
class wxTarNotifier
|
||||
{
|
||||
public:
|
||||
virtual ~wxTarNotifier() { }
|
||||
|
||||
virtual void OnEntryUpdated(class wxTarEntry& entry) = 0;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Tar Entry - hold the meta data for a file in the tar
|
||||
|
||||
class wxTarEntry : public wxArchiveEntry
|
||||
{
|
||||
public:
|
||||
wxTarEntry(const wxString& name = wxEmptyString,
|
||||
const wxDateTime& dt = wxDateTime::Now(),
|
||||
wxFileOffset size = wxInvalidOffset);
|
||||
virtual ~wxTarEntry();
|
||||
|
||||
wxTarEntry(const wxTarEntry& entry);
|
||||
wxTarEntry& operator=(const wxTarEntry& entry);
|
||||
|
||||
// Get accessors
|
||||
wxString GetName(wxPathFormat format = wxPATH_NATIVE) const;
|
||||
wxString GetInternalName() const { return m_Name; }
|
||||
wxPathFormat GetInternalFormat() const { return wxPATH_UNIX; }
|
||||
int GetMode() const;
|
||||
int GetUserId() const { return m_UserId; }
|
||||
int GetGroupId() const { return m_GroupId; }
|
||||
wxFileOffset GetSize() const { return m_Size; }
|
||||
wxFileOffset GetOffset() const { return m_Offset; }
|
||||
wxDateTime GetDateTime() const { return m_ModifyTime; }
|
||||
wxDateTime GetAccessTime() const { return m_AccessTime; }
|
||||
wxDateTime GetCreateTime() const { return m_CreateTime; }
|
||||
int GetTypeFlag() const { return m_TypeFlag; }
|
||||
wxString GetLinkName() const { return m_LinkName; }
|
||||
wxString GetUserName() const { return m_UserName; }
|
||||
wxString GetGroupName() const { return m_GroupName; }
|
||||
int GetDevMajor() const { return m_DevMajor; }
|
||||
int GetDevMinor() const { return m_DevMinor; }
|
||||
|
||||
// is accessors
|
||||
bool IsDir() const;
|
||||
bool IsReadOnly() const { return !(m_Mode & 0222); }
|
||||
|
||||
// set accessors
|
||||
void SetName(const wxString& name, wxPathFormat format = wxPATH_NATIVE);
|
||||
void SetUserId(int id) { m_UserId = id; }
|
||||
void SetGroupId(int id) { m_GroupId = id; }
|
||||
void SetMode(int mode);
|
||||
void SetSize(wxFileOffset size) { m_Size = size; }
|
||||
void SetDateTime(const wxDateTime& dt) { m_ModifyTime = dt; }
|
||||
void SetAccessTime(const wxDateTime& dt) { m_AccessTime = dt; }
|
||||
void SetCreateTime(const wxDateTime& dt) { m_CreateTime = dt; }
|
||||
void SetTypeFlag(int type) { m_TypeFlag = type; }
|
||||
void SetLinkName(const wxString& link) { m_LinkName = link; }
|
||||
void SetUserName(const wxString& user) { m_UserName = user; }
|
||||
void SetGroupName(const wxString& group) { m_GroupName = group; }
|
||||
void SetDevMajor(int dev) { m_DevMajor = dev; }
|
||||
void SetDevMinor(int dev) { m_DevMinor = dev; }
|
||||
|
||||
// set is accessors
|
||||
void SetIsDir(bool isDir = true);
|
||||
void SetIsReadOnly(bool isReadOnly = true);
|
||||
|
||||
static wxString GetInternalName(const wxString& name,
|
||||
wxPathFormat format = wxPATH_NATIVE,
|
||||
bool *pIsDir = NULL);
|
||||
|
||||
wxTarEntry *Clone() const { return new wxTarEntry(*this); }
|
||||
|
||||
void SetNotifier(wxTarNotifier& WXUNUSED(notifier)) { }
|
||||
|
||||
private:
|
||||
void SetOffset(wxFileOffset offset) { m_Offset = offset; }
|
||||
|
||||
virtual wxArchiveEntry* DoClone() const { return Clone(); }
|
||||
|
||||
wxString m_Name;
|
||||
int m_Mode;
|
||||
bool m_IsModeSet;
|
||||
int m_UserId;
|
||||
int m_GroupId;
|
||||
wxFileOffset m_Size;
|
||||
wxFileOffset m_Offset;
|
||||
wxDateTime m_ModifyTime;
|
||||
wxDateTime m_AccessTime;
|
||||
wxDateTime m_CreateTime;
|
||||
wxChar m_TypeFlag;
|
||||
wxString m_LinkName;
|
||||
wxString m_UserName;
|
||||
wxString m_GroupName;
|
||||
int m_DevMajor;
|
||||
int m_DevMinor;
|
||||
|
||||
friend class wxTarInputStream;
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxTarEntry)
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// wxTarInputStream
|
||||
|
||||
class wxTarInputStream : public wxArchiveInputStream
|
||||
{
|
||||
public:
|
||||
typedef wxTarEntry entry_type;
|
||||
|
||||
wxTarInputStream(wxInputStream& stream, wxMBConv& conv = wxConvLocal);
|
||||
wxTarInputStream(wxInputStream *stream, wxMBConv& conv = wxConvLocal);
|
||||
virtual ~wxTarInputStream();
|
||||
|
||||
bool OpenEntry(wxTarEntry& entry);
|
||||
bool CloseEntry();
|
||||
|
||||
wxTarEntry *GetNextEntry();
|
||||
|
||||
wxFileOffset GetLength() const { return m_size; }
|
||||
bool IsSeekable() const { return m_parent_i_stream->IsSeekable(); }
|
||||
|
||||
protected:
|
||||
size_t OnSysRead(void *buffer, size_t size);
|
||||
wxFileOffset OnSysTell() const { return m_pos; }
|
||||
wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
wxArchiveEntry *DoGetNextEntry() { return GetNextEntry(); }
|
||||
bool OpenEntry(wxArchiveEntry& entry);
|
||||
bool IsOpened() const { return m_pos != wxInvalidOffset; }
|
||||
|
||||
wxStreamError ReadHeaders();
|
||||
bool ReadExtendedHeader(class wxTarHeaderRecords*& recs);
|
||||
|
||||
wxString GetExtendedHeader(const wxString& key) const;
|
||||
wxString GetHeaderPath() const;
|
||||
wxFileOffset GetHeaderNumber(int id) const;
|
||||
wxString GetHeaderString(int id) const;
|
||||
wxDateTime GetHeaderDate(const wxString& key) const;
|
||||
|
||||
wxFileOffset m_pos; // position within the current entry
|
||||
wxFileOffset m_offset; // offset to the start of the entry's data
|
||||
wxFileOffset m_size; // size of the current entry's data
|
||||
|
||||
int m_sumType;
|
||||
int m_tarType;
|
||||
class wxTarHeaderBlock *m_hdr;
|
||||
class wxTarHeaderRecords *m_HeaderRecs;
|
||||
class wxTarHeaderRecords *m_GlobalHeaderRecs;
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxTarInputStream)
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// wxTarOutputStream
|
||||
|
||||
class wxTarOutputStream : public wxArchiveOutputStream
|
||||
{
|
||||
public:
|
||||
wxTarOutputStream(wxOutputStream& stream,
|
||||
wxTarFormat format = wxTAR_PAX,
|
||||
wxMBConv& conv = wxConvLocal);
|
||||
wxTarOutputStream(wxOutputStream *stream,
|
||||
wxTarFormat format = wxTAR_PAX,
|
||||
wxMBConv& conv = wxConvLocal);
|
||||
virtual ~wxTarOutputStream();
|
||||
|
||||
bool PutNextEntry(wxTarEntry *entry);
|
||||
|
||||
bool PutNextEntry(const wxString& name,
|
||||
const wxDateTime& dt = wxDateTime::Now(),
|
||||
wxFileOffset size = wxInvalidOffset);
|
||||
|
||||
bool PutNextDirEntry(const wxString& name,
|
||||
const wxDateTime& dt = wxDateTime::Now());
|
||||
|
||||
bool CopyEntry(wxTarEntry *entry, wxTarInputStream& inputStream);
|
||||
bool CopyArchiveMetaData(wxTarInputStream& WXUNUSED(s)) { return true; }
|
||||
|
||||
void Sync();
|
||||
bool CloseEntry();
|
||||
bool Close();
|
||||
|
||||
bool IsSeekable() const { return m_parent_o_stream->IsSeekable(); }
|
||||
|
||||
void SetBlockingFactor(int factor) { m_BlockingFactor = factor; }
|
||||
int GetBlockingFactor() const { return m_BlockingFactor; }
|
||||
|
||||
protected:
|
||||
size_t OnSysWrite(const void *buffer, size_t size);
|
||||
wxFileOffset OnSysTell() const { return m_pos; }
|
||||
wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
|
||||
|
||||
private:
|
||||
void Init(wxTarFormat format);
|
||||
|
||||
bool PutNextEntry(wxArchiveEntry *entry);
|
||||
bool CopyEntry(wxArchiveEntry *entry, wxArchiveInputStream& stream);
|
||||
bool CopyArchiveMetaData(wxArchiveInputStream& WXUNUSED(s)) { return true; }
|
||||
bool IsOpened() const { return m_pos != wxInvalidOffset; }
|
||||
|
||||
bool WriteHeaders(wxTarEntry& entry);
|
||||
bool ModifyHeader();
|
||||
wxString PaxHeaderPath(const wxString& format, const wxString& path);
|
||||
|
||||
void SetExtendedHeader(const wxString& key, const wxString& value);
|
||||
void SetHeaderPath(const wxString& name);
|
||||
bool SetHeaderNumber(int id, wxFileOffset n);
|
||||
void SetHeaderString(int id, const wxString& str);
|
||||
void SetHeaderDate(const wxString& key, const wxDateTime& datetime);
|
||||
|
||||
wxFileOffset m_pos; // position within the current entry
|
||||
wxFileOffset m_maxpos; // max pos written
|
||||
wxFileOffset m_size; // expected entry size
|
||||
|
||||
wxFileOffset m_headpos; // offset within the file to the entry's header
|
||||
wxFileOffset m_datapos; // offset within the file to the entry's data
|
||||
|
||||
wxFileOffset m_tarstart;// offset within the file to the tar
|
||||
wxFileOffset m_tarsize; // size of tar so far
|
||||
|
||||
bool m_pax;
|
||||
int m_BlockingFactor;
|
||||
wxUint32 m_chksum;
|
||||
bool m_large;
|
||||
class wxTarHeaderBlock *m_hdr;
|
||||
class wxTarHeaderBlock *m_hdr2;
|
||||
char *m_extendedHdr;
|
||||
size_t m_extendedSize;
|
||||
wxString m_badfit;
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxTarOutputStream)
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Iterators
|
||||
|
||||
#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
|
||||
typedef wxArchiveIterator<wxTarInputStream> wxTarIter;
|
||||
typedef wxArchiveIterator<wxTarInputStream,
|
||||
std::pair<wxString, wxTarEntry*> > wxTarPairIter;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// wxTarClassFactory
|
||||
|
||||
class wxTarClassFactory : public wxArchiveClassFactory
|
||||
{
|
||||
public:
|
||||
typedef wxTarEntry entry_type;
|
||||
typedef wxTarInputStream instream_type;
|
||||
typedef wxTarOutputStream outstream_type;
|
||||
typedef wxTarNotifier notifier_type;
|
||||
#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
|
||||
typedef wxTarIter iter_type;
|
||||
typedef wxTarPairIter pairiter_type;
|
||||
#endif
|
||||
|
||||
wxTarClassFactory();
|
||||
|
||||
wxTarEntry *NewEntry() const
|
||||
{ return new wxTarEntry; }
|
||||
wxTarInputStream *NewStream(wxInputStream& stream) const
|
||||
{ return new wxTarInputStream(stream, GetConv()); }
|
||||
wxTarOutputStream *NewStream(wxOutputStream& stream) const
|
||||
{ return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); }
|
||||
wxTarInputStream *NewStream(wxInputStream *stream) const
|
||||
{ return new wxTarInputStream(stream, GetConv()); }
|
||||
wxTarOutputStream *NewStream(wxOutputStream *stream) const
|
||||
{ return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); }
|
||||
|
||||
wxString GetInternalName(const wxString& name,
|
||||
wxPathFormat format = wxPATH_NATIVE) const
|
||||
{ return wxTarEntry::GetInternalName(name, format); }
|
||||
|
||||
const wxChar * const *GetProtocols(wxStreamProtocolType type
|
||||
= wxSTREAM_PROTOCOL) const;
|
||||
|
||||
protected:
|
||||
wxArchiveEntry *DoNewEntry() const
|
||||
{ return NewEntry(); }
|
||||
wxArchiveInputStream *DoNewStream(wxInputStream& stream) const
|
||||
{ return NewStream(stream); }
|
||||
wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const
|
||||
{ return NewStream(stream); }
|
||||
wxArchiveInputStream *DoNewStream(wxInputStream *stream) const
|
||||
{ return NewStream(stream); }
|
||||
wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const
|
||||
{ return NewStream(stream); }
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxTarClassFactory)
|
||||
};
|
||||
|
||||
|
||||
#endif // wxUSE_TARSTREAM
|
||||
|
||||
#endif // _WX_WXTARSTREAM_H__
|
1457
src/common/tarstrm.cpp
Normal file
1457
src/common/tarstrm.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user