wxWidgets/include/wx/tarstrm.h

354 lines
13 KiB
C
Raw Normal View History

/////////////////////////////////////////////////////////////////////////////
// Name: wx/tarstrm.h
// Purpose: Streams for Tar files
// Author: Mike Wetherell
// 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"
#include "wx/hashmap.h"
/////////////////////////////////////////////////////////////////////////////
// Constants
// TypeFlag values
enum wxTarType
{
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 WXDLLIMPEXP_BASE wxTarNotifier
{
public:
virtual ~wxTarNotifier() { }
virtual void OnEntryUpdated(class wxTarEntry& entry) = 0;
};
/////////////////////////////////////////////////////////////////////////////
// Tar Entry - hold the meta data for a file in the tar
class WXDLLIMPEXP_BASE 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 wxOVERRIDE;
wxString GetInternalName() const wxOVERRIDE { return m_Name; }
wxPathFormat GetInternalFormat() const wxOVERRIDE { return wxPATH_UNIX; }
int GetMode() const;
int GetUserId() const { return m_UserId; }
int GetGroupId() const { return m_GroupId; }
wxFileOffset GetSize() const wxOVERRIDE { return m_Size; }
wxFileOffset GetOffset() const wxOVERRIDE { return m_Offset; }
wxDateTime GetDateTime() const wxOVERRIDE { 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 wxOVERRIDE;
bool IsReadOnly() const wxOVERRIDE { return !(m_Mode & 0222); }
// set accessors
void SetName(const wxString& name, wxPathFormat format = wxPATH_NATIVE) wxOVERRIDE;
void SetUserId(int id) { m_UserId = id; }
void SetGroupId(int id) { m_GroupId = id; }
void SetMode(int mode);
void SetSize(wxFileOffset size) wxOVERRIDE { m_Size = size; }
void SetDateTime(const wxDateTime& dt) wxOVERRIDE { 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) wxOVERRIDE;
void SetIsReadOnly(bool isReadOnly = true) wxOVERRIDE;
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) wxOVERRIDE { m_Offset = offset; }
virtual wxArchiveEntry* DoClone() const wxOVERRIDE { 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;
int m_TypeFlag;
wxString m_LinkName;
wxString m_UserName;
wxString m_GroupName;
int m_DevMajor;
int m_DevMinor;
friend class wxTarInputStream;
wxDECLARE_DYNAMIC_CLASS(wxTarEntry);
};
/////////////////////////////////////////////////////////////////////////////
// wxTarInputStream
WX_DECLARE_STRING_HASH_MAP(wxString, wxTarHeaderRecords);
class WXDLLIMPEXP_BASE 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() wxOVERRIDE;
wxTarEntry *GetNextEntry();
wxFileOffset GetLength() const wxOVERRIDE { return m_size; }
bool IsSeekable() const wxOVERRIDE { return m_parent_i_stream->IsSeekable(); }
protected:
size_t OnSysRead(void *buffer, size_t size) wxOVERRIDE;
wxFileOffset OnSysTell() const wxOVERRIDE { return m_pos; }
wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode) wxOVERRIDE;
private:
void Init();
wxArchiveEntry *DoGetNextEntry() wxOVERRIDE { return GetNextEntry(); }
bool OpenEntry(wxArchiveEntry& entry) wxOVERRIDE;
bool IsOpened() const { return m_pos != wxInvalidOffset; }
wxStreamError ReadHeaders();
bool ReadExtendedHeader(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;
wxTarHeaderRecords *m_HeaderRecs;
wxTarHeaderRecords *m_GlobalHeaderRecs;
wxDECLARE_NO_COPY_CLASS(wxTarInputStream);
};
/////////////////////////////////////////////////////////////////////////////
// wxTarOutputStream
class WXDLLIMPEXP_BASE 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) wxOVERRIDE;
bool PutNextDirEntry(const wxString& name,
const wxDateTime& dt = wxDateTime::Now()) wxOVERRIDE;
bool CopyEntry(wxTarEntry *entry, wxTarInputStream& inputStream);
bool CopyArchiveMetaData(wxTarInputStream& WXUNUSED(s)) { return true; }
void Sync() wxOVERRIDE;
bool CloseEntry() wxOVERRIDE;
bool Close() wxOVERRIDE;
bool IsSeekable() const wxOVERRIDE { 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) wxOVERRIDE;
wxFileOffset OnSysTell() const wxOVERRIDE { return m_pos; }
wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode) wxOVERRIDE;
private:
void Init(wxTarFormat format);
bool PutNextEntry(wxArchiveEntry *entry) wxOVERRIDE;
bool CopyEntry(wxArchiveEntry *entry, wxArchiveInputStream& stream) wxOVERRIDE;
bool CopyArchiveMetaData(wxArchiveInputStream& WXUNUSED(s)) wxOVERRIDE { 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;
bool m_endrecWritten;
wxDECLARE_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 WXDLLIMPEXP_BASE 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 wxOVERRIDE
{ return wxTarEntry::GetInternalName(name, format); }
const wxChar * const *GetProtocols(wxStreamProtocolType type
= wxSTREAM_PROTOCOL) const wxOVERRIDE;
protected:
wxArchiveEntry *DoNewEntry() const wxOVERRIDE
{ return NewEntry(); }
wxArchiveInputStream *DoNewStream(wxInputStream& stream) const wxOVERRIDE
{ return NewStream(stream); }
wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const wxOVERRIDE
{ return NewStream(stream); }
wxArchiveInputStream *DoNewStream(wxInputStream *stream) const wxOVERRIDE
{ return NewStream(stream); }
wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const wxOVERRIDE
{ return NewStream(stream); }
private:
wxDECLARE_DYNAMIC_CLASS(wxTarClassFactory);
};
#endif // wxUSE_TARSTREAM
#endif // _WX_WXTARSTREAM_H__