X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/076e07b60bde6dd90e687e7a0861ea81ce1ef7fe..8cbc59fe84f046685b873cf58f6c56debe59de1c:/src/common/zipstrm.cpp diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index 6116b8e0c5..a3af2d6246 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -14,22 +14,22 @@ #pragma hdrstop #endif -#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM +#if wxUSE_ZIPSTREAM + +#include "wx/zipstrm.h" #ifndef WX_PRECOMP + #include "wx/hashmap.h" #include "wx/intl.h" #include "wx/log.h" #include "wx/utils.h" #endif -#include "wx/zipstrm.h" #include "wx/datstrm.h" #include "wx/zstream.h" #include "wx/mstream.h" -#include "wx/buffer.h" -#include "wx/ptr_scpd.h" +#include "wx/scopedptr.h" #include "wx/wfstream.h" -#include "wx/link.h" #include "zlib.h" // value for the 'version needed to extract' field (20 means 2.0) @@ -77,8 +77,6 @@ enum { IMPLEMENT_DYNAMIC_CLASS(wxZipEntry, wxArchiveEntry) IMPLEMENT_DYNAMIC_CLASS(wxZipClassFactory, wxArchiveClassFactory) -wxFORCE_LINK_THIS_MODULE(zipstrm) - ///////////////////////////////////////////////////////////////////////////// // Helpers @@ -139,6 +137,34 @@ static wxFileOffset QuietSeek(wxInputStream& stream, wxFileOffset pos) } +///////////////////////////////////////////////////////////////////////////// +// Class factory + +static wxZipClassFactory g_wxZipClassFactory; + +wxZipClassFactory::wxZipClassFactory() +{ + if (this == &g_wxZipClassFactory) + PushFront(); +} + +const wxChar * const * +wxZipClassFactory::GetProtocols(wxStreamProtocolType type) const +{ + static const wxChar *protocols[] = { _T("zip"), NULL }; + static const wxChar *mimetypes[] = { _T("application/zip"), NULL }; + static const wxChar *fileexts[] = { _T(".zip"), _T(".htb"), NULL }; + static const wxChar *empty[] = { NULL }; + + switch (type) { + case wxSTREAM_PROTOCOL: return protocols; + case wxSTREAM_MIMETYPE: return mimetypes; + case wxSTREAM_FILEEXT: return fileexts; + default: return empty; + } +} + + ///////////////////////////////////////////////////////////////////////////// // Read a zip header @@ -179,13 +205,13 @@ wxZipHeader::wxZipHeader(wxInputStream& stream, size_t size) m_ok = m_size == size; } -wxUint8 wxZipHeader::Read8() +inline wxUint8 wxZipHeader::Read8() { wxASSERT(m_pos < m_size); return m_data[m_pos++]; } -wxUint16 wxZipHeader::Read16() +inline wxUint16 wxZipHeader::Read16() { wxASSERT(m_pos + 2 <= m_size); wxUint16 n = CrackUint16(m_data + m_pos); @@ -193,7 +219,7 @@ wxUint16 wxZipHeader::Read16() return n; } -wxUint32 wxZipHeader::Read32() +inline wxUint32 wxZipHeader::Read32() { wxASSERT(m_pos + 4 <= m_size); wxUint32 n = CrackUint32(m_data + m_pos); @@ -225,7 +251,7 @@ private: wxFileOffset m_pos; wxFileOffset m_len; - DECLARE_NO_COPY_CLASS(wxStoredInputStream) + wxDECLARE_NO_COPY_CLASS(wxStoredInputStream); }; wxStoredInputStream::wxStoredInputStream(wxInputStream& stream) @@ -271,7 +297,7 @@ protected: private: wxFileOffset m_pos; - DECLARE_NO_COPY_CLASS(wxStoredOutputStream) + wxDECLARE_NO_COPY_CLASS(wxStoredOutputStream); }; size_t wxStoredOutputStream::OnSysWrite(const void *buffer, size_t size) @@ -333,7 +359,7 @@ private: size_t m_start; size_t m_end; - DECLARE_NO_COPY_CLASS(wxTeeInputStream) + wxDECLARE_NO_COPY_CLASS(wxTeeInputStream); }; wxTeeInputStream::wxTeeInputStream(wxInputStream& stream) @@ -429,7 +455,7 @@ private: enum { BUFSIZE = 8192 }; wxCharBuffer m_dummy; - DECLARE_NO_COPY_CLASS(wxRawInputStream) + wxDECLARE_NO_COPY_CLASS(wxRawInputStream); }; wxRawInputStream::wxRawInputStream(wxInputStream& stream) @@ -614,7 +640,7 @@ static void Unique(wxZipMemory*& zm, size_t size) // Collection of weak references to entries WX_DECLARE_HASH_MAP(long, wxZipEntry*, wxIntegerHash, - wxIntegerEqual, wx__OffsetZipEntryMap); + wxIntegerEqual, wxOffsetZipEntryMap_); class wxZipWeakLinks { @@ -635,10 +661,10 @@ public: private: ~wxZipWeakLinks() { wxASSERT(IsEmpty()); } - typedef wx__OffsetZipEntryMap::key_type key_type; + typedef wxOffsetZipEntryMap_::key_type key_type; int m_ref; - wx__OffsetZipEntryMap m_entries; + wxOffsetZipEntryMap_ m_entries; wxSUPPRESS_GCC_PRIVATE_DTOR_WARNING(wxZipWeakLinks) }; @@ -652,7 +678,7 @@ wxZipWeakLinks *wxZipWeakLinks::AddEntry(wxZipEntry *entry, wxFileOffset key) wxZipEntry *wxZipWeakLinks::GetEntry(wxFileOffset key) const { - wx__OffsetZipEntryMap::const_iterator it = + wxOffsetZipEntryMap_::const_iterator it = m_entries.find(wx_truncate_cast(key_type, key)); return it != m_entries.end() ? it->second : NULL; } @@ -978,7 +1004,7 @@ size_t wxZipEntry::ReadLocal(wxInputStream& stream, wxMBConv& conv) size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const { wxString unixName = GetName(wxPATH_UNIX); - const wxWX2MBbuf name_buf = conv.cWX2MB(unixName); + const wxWX2MBbuf name_buf = unixName.mb_str(conv); const char *name = name_buf; if (!name) name = ""; wxUint16 nameLen = wx_truncate_cast(wxUint16, strlen(name)); @@ -1054,12 +1080,12 @@ size_t wxZipEntry::ReadCentral(wxInputStream& stream, wxMBConv& conv) size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const { wxString unixName = GetName(wxPATH_UNIX); - const wxWX2MBbuf name_buf = conv.cWX2MB(unixName); + const wxWX2MBbuf name_buf = unixName.mb_str(conv); const char *name = name_buf; if (!name) name = ""; wxUint16 nameLen = wx_truncate_cast(wxUint16, strlen(name)); - const wxWX2MBbuf comment_buf = conv.cWX2MB(m_Comment); + const wxWX2MBbuf comment_buf = m_Comment.mb_str(conv); const char *comment = comment_buf; if (!comment) comment = ""; wxUint16 commentLen = wx_truncate_cast(wxUint16, strlen(comment)); @@ -1209,7 +1235,7 @@ wxZipEndRec::wxZipEndRec() bool wxZipEndRec::Write(wxOutputStream& stream, wxMBConv& conv) const { - const wxWX2MBbuf comment_buf = conv.cWX2MB(m_Comment); + const wxWX2MBbuf comment_buf = m_Comment.mb_str(conv); const char *comment = comment_buf; if (!comment) comment = ""; wxUint16 commentLen = (wxUint16)strlen(comment); @@ -1279,8 +1305,8 @@ private: // Input stream // leave the default wxZipEntryPtr free for users -wxDECLARE_SCOPED_PTR(wxZipEntry, wx__ZipEntryPtr) -wxDEFINE_SCOPED_PTR (wxZipEntry, wx__ZipEntryPtr) +wxDECLARE_SCOPED_PTR(wxZipEntry, wxZipEntryPtr_) +wxDEFINE_SCOPED_PTR (wxZipEntry, wxZipEntryPtr_) // constructor // @@ -1291,7 +1317,14 @@ wxZipInputStream::wxZipInputStream(wxInputStream& stream, Init(); } -#if 1 //WXWIN_COMPATIBILITY_2_6 +wxZipInputStream::wxZipInputStream(wxInputStream *stream, + wxMBConv& conv /*=wxConvLocal*/) + : wxArchiveInputStream(stream, conv) +{ + Init(); +} + +#if WXWIN_COMPATIBILITY_2_6 && wxUSE_FFILE // Part of the compatibility constructor, which has been made inline to // avoid a problem with it not being exported by mingw 3.2.3 @@ -1302,10 +1335,11 @@ void wxZipInputStream::Init(const wxString& file) wxLogNull nolog; Init(); m_allowSeeking = true; - m_ffile = wx_static_cast(wxFFileInputStream*, m_parent_i_stream); - wx__ZipEntryPtr entry; + wxFFileInputStream *ffile; + ffile = static_cast(m_parent_i_stream); + wxZipEntryPtr_ entry; - if (m_ffile->Ok()) { + if (ffile->Ok()) { do { entry.reset(GetNextEntry()); } @@ -1316,13 +1350,13 @@ void wxZipInputStream::Init(const wxString& file) m_lasterror = wxSTREAM_READ_ERROR; } -wxInputStream& wxZipInputStream::OpenFile(const wxString& archive) +wxInputStream* wxZipInputStream::OpenFile(const wxString& archive) { wxLogNull nolog; - return *new wxFFileInputStream(archive); + return new wxFFileInputStream(archive); } -#endif // WXWIN_COMPATIBILITY_2_6 +#endif // WXWIN_COMPATIBILITY_2_6 && wxUSE_FFILE void wxZipInputStream::Init() { @@ -1340,8 +1374,7 @@ void wxZipInputStream::Init() m_signature = 0; m_TotalEntries = 0; m_lasterror = m_parent_i_stream->GetLastError(); - m_ffile = NULL; -#if 1 //WXWIN_COMPATIBILITY_2_6 +#if WXWIN_COMPATIBILITY_2_6 m_allowSeeking = false; #endif } @@ -1353,7 +1386,6 @@ wxZipInputStream::~wxZipInputStream() delete m_store; delete m_inflate; delete m_rawin; - delete m_ffile; m_weaklinks->Release(this); @@ -1431,11 +1463,13 @@ bool wxZipInputStream::LoadEndRecord() m_TotalEntries = endrec.GetTotalEntries(); m_Comment = endrec.GetComment(); + wxUint32 magic = m_TotalEntries ? CENTRAL_MAGIC : END_MAGIC; + // Now find the central-directory. we have the file offset of // the CD, so look there first. if (m_parent_i_stream->SeekI(endrec.GetOffset()) != wxInvalidOffset && - ReadSignature() == CENTRAL_MAGIC) { - m_signature = CENTRAL_MAGIC; + ReadSignature() == magic) { + m_signature = magic; m_position = endrec.GetOffset(); m_offsetAdjustment = 0; return true; @@ -1445,8 +1479,8 @@ bool wxZipInputStream::LoadEndRecord() // to a self extractor, so take the CD size (also in endrec), subtract // it from the file offset of the end-central-directory and look there. if (m_parent_i_stream->SeekI(endPos - endrec.GetSize()) - != wxInvalidOffset && ReadSignature() == CENTRAL_MAGIC) { - m_signature = CENTRAL_MAGIC; + != wxInvalidOffset && ReadSignature() == magic) { + m_signature = magic; m_position = endPos - endrec.GetSize(); m_offsetAdjustment = m_position - endrec.GetOffset(); return true; @@ -1524,7 +1558,7 @@ wxZipEntry *wxZipInputStream::GetNextEntry() if (!IsOk()) return NULL; - wx__ZipEntryPtr entry(new wxZipEntry(m_entry)); + wxZipEntryPtr_ entry(new wxZipEntry(m_entry)); entry->m_backlink = m_weaklinks->AddEntry(entry.get(), entry->GetKey()); return entry.release(); } @@ -1851,7 +1885,7 @@ size_t wxZipInputStream::OnSysRead(void *buffer, size_t size) return count; } -#if 1 //WXWIN_COMPATIBILITY_2_6 +#if WXWIN_COMPATIBILITY_2_6 // Borrowed from VS's zip stream (c) 1999 Vaclav Slavik // @@ -1923,32 +1957,46 @@ wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) // Output stream #include "wx/listimpl.cpp" -WX_DEFINE_LIST(wx__ZipEntryList) +WX_DEFINE_LIST(wxZipEntryList_) wxZipOutputStream::wxZipOutputStream(wxOutputStream& stream, int level /*=-1*/, wxMBConv& conv /*=wxConvLocal*/) - : wxArchiveOutputStream(stream, conv), - m_store(new wxStoredOutputStream(stream)), - m_deflate(NULL), - m_backlink(NULL), - m_initialData(new char[OUTPUT_LATENCY]), - m_initialSize(0), - m_pending(NULL), - m_raw(false), - m_headerOffset(0), - m_headerSize(0), - m_entrySize(0), - m_comp(NULL), - m_level(level), - m_offsetAdjustment(wxInvalidOffset) + : wxArchiveOutputStream(stream, conv) { + Init(level); +} + +wxZipOutputStream::wxZipOutputStream(wxOutputStream *stream, + int level /*=-1*/, + wxMBConv& conv /*=wxConvLocal*/) + : wxArchiveOutputStream(stream, conv) +{ + Init(level); +} + +void wxZipOutputStream::Init(int level) +{ + m_store = new wxStoredOutputStream(*m_parent_o_stream); + m_deflate = NULL; + m_backlink = NULL; + m_initialData = new char[OUTPUT_LATENCY]; + m_initialSize = 0; + m_pending = NULL; + m_raw = false; + m_headerOffset = 0; + m_headerSize = 0; + m_entrySize = 0; + m_comp = NULL; + m_level = level; + m_offsetAdjustment = wxInvalidOffset; + m_endrecWritten = false; } wxZipOutputStream::~wxZipOutputStream() { Close(); - WX_CLEAR_LIST(wx__ZipEntryList, m_entries); + WX_CLEAR_LIST(wxZipEntryList_, m_entries); delete m_store; delete m_deflate; delete m_pending; @@ -1977,7 +2025,7 @@ bool wxZipOutputStream::PutNextDirEntry( bool wxZipOutputStream::CopyEntry(wxZipEntry *entry, wxZipInputStream& inputStream) { - wx__ZipEntryPtr e(entry); + wxZipEntryPtr_ e(entry); return inputStream.DoOpen(e.get(), true) && @@ -2003,7 +2051,7 @@ bool wxZipOutputStream::CopyEntry(wxArchiveEntry *entry, return false; } - return CopyEntry(zipEntry, wx_static_cast(wxZipInputStream&, stream)); + return CopyEntry(zipEntry, static_cast(stream)); } bool wxZipOutputStream::CopyArchiveMetaData(wxZipInputStream& inputStream) @@ -2017,7 +2065,7 @@ bool wxZipOutputStream::CopyArchiveMetaData(wxZipInputStream& inputStream) bool wxZipOutputStream::CopyArchiveMetaData(wxArchiveInputStream& stream) { - return CopyArchiveMetaData(wx_static_cast(wxZipInputStream&, stream)); + return CopyArchiveMetaData(static_cast(stream)); } void wxZipOutputStream::SetLevel(int level) @@ -2147,7 +2195,7 @@ bool wxZipOutputStream::CloseCompressor(wxOutputStream *comp) void wxZipOutputStream::CreatePendingEntry(const void *buffer, size_t size) { wxASSERT(IsOk() && m_pending && !m_comp); - wx__ZipEntryPtr spPending(m_pending); + wxZipEntryPtr_ spPending(m_pending); m_pending = NULL; Buffer bufs[] = { @@ -2188,7 +2236,7 @@ void wxZipOutputStream::CreatePendingEntry(const void *buffer, size_t size) void wxZipOutputStream::CreatePendingEntry() { wxASSERT(IsOk() && m_pending && !m_comp); - wx__ZipEntryPtr spPending(m_pending); + wxZipEntryPtr_ spPending(m_pending); m_pending = NULL; m_lasterror = wxSTREAM_WRITE_ERROR; @@ -2242,8 +2290,12 @@ bool wxZipOutputStream::Close() { CloseEntry(); - if (m_lasterror == wxSTREAM_WRITE_ERROR || m_entries.size() == 0) + if (m_lasterror == wxSTREAM_WRITE_ERROR + || (m_entries.size() == 0 && m_endrecWritten)) + { + wxFilterOutputStream::Close(); return false; + } wxZipEndRec endrec; @@ -2252,7 +2304,7 @@ bool wxZipOutputStream::Close() endrec.SetOffset(m_headerOffset); endrec.SetComment(m_Comment); - wx__ZipEntryList::iterator it; + wxZipEntryList_::iterator it; wxFileOffset size = 0; for (it = m_entries.begin(); it != m_entries.end(); ++it) { @@ -2265,7 +2317,9 @@ bool wxZipOutputStream::Close() endrec.Write(*m_parent_o_stream, GetConv()); m_lasterror = m_parent_o_stream->GetLastError(); - if (!IsOk()) + m_endrecWritten = true; + + if (!wxFilterOutputStream::Close() || !IsOk()) return false; m_lasterror = wxSTREAM_EOF; return true; @@ -2374,4 +2428,4 @@ size_t wxZipOutputStream::OnSysWrite(const void *buffer, size_t size) return m_comp->LastWrite(); } -#endif // wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM +#endif // wxUSE_ZIPSTREAM