X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5410f5728d75f905375c2b05944b11fc92a74aa4..0306e73e630bce45a3f56a0616559250fcb8c05e:/src/common/zipstrm.cpp diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index 3a533fcb93..4282806175 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -28,7 +28,7 @@ #include "wx/datstrm.h" #include "wx/zstream.h" #include "wx/mstream.h" -#include "wx/ptr_scpd.h" +#include "wx/scopedptr.h" #include "wx/wfstream.h" #include "zlib.h" @@ -125,7 +125,7 @@ static inline wxUint16 CrackUint16(const char *m) // static wxFileOffset QuietSeek(wxInputStream& stream, wxFileOffset pos) { -#if defined(__WXDEBUG__) && wxUSE_LOG +#if wxUSE_LOG wxLogLevel level = wxLog::GetLogLevel(); wxLog::SetLogLevel(wxLOG_Debug - 1); wxFileOffset result = stream.SeekI(pos); @@ -140,7 +140,7 @@ static wxFileOffset QuietSeek(wxInputStream& stream, wxFileOffset pos) ///////////////////////////////////////////////////////////////////////////// // Class factory -wxZipClassFactory g_wxZipClassFactory; +static wxZipClassFactory g_wxZipClassFactory; wxZipClassFactory::wxZipClassFactory() { @@ -151,16 +151,16 @@ wxZipClassFactory::wxZipClassFactory() 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 *protocols[] = { wxT("zip"), NULL }; + static const wxChar *mimetypes[] = { wxT("application/zip"), NULL }; + static const wxChar *fileexts[] = { wxT(".zip"), wxT(".htb"), NULL }; static const wxChar *empty[] = { NULL }; switch (type) { - case wxSTREAM_PROTOCOL: return protocols; - case wxSTREAM_MIMETYPE: return mimetypes; - case wxSTREAM_FILEEXTENSION: return fileexts; - default: return empty; + case wxSTREAM_PROTOCOL: return protocols; + case wxSTREAM_MIMETYPE: return mimetypes; + case wxSTREAM_FILEEXT: return fileexts; + default: return empty; } } @@ -200,18 +200,18 @@ wxZipHeader::wxZipHeader(wxInputStream& stream, size_t size) m_pos(0), m_ok(false) { - wxCHECK_RET(size <= sizeof(m_data), _T("buffer too small")); + wxCHECK_RET(size <= sizeof(m_data), wxT("buffer too small")); m_size = stream.Read(m_data, size).LastRead(); 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); @@ -219,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); @@ -251,7 +251,7 @@ private: wxFileOffset m_pos; wxFileOffset m_len; - DECLARE_NO_COPY_CLASS(wxStoredInputStream) + wxDECLARE_NO_COPY_CLASS(wxStoredInputStream); }; wxStoredInputStream::wxStoredInputStream(wxInputStream& stream) @@ -297,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) @@ -359,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) @@ -455,7 +455,7 @@ private: enum { BUFSIZE = 8192 }; wxCharBuffer m_dummy; - DECLARE_NO_COPY_CLASS(wxRawInputStream) + wxDECLARE_NO_COPY_CLASS(wxRawInputStream); }; wxRawInputStream::wxRawInputStream(wxInputStream& stream) @@ -786,15 +786,15 @@ wxString wxZipEntry::GetName(wxPathFormat format /*=wxPATH_NATIVE*/) const switch (wxFileName::GetFormat(format)) { case wxPATH_DOS: { - wxString name(isDir ? m_Name + _T("\\") : m_Name); + wxString name(isDir ? m_Name + wxT("\\") : m_Name); for (size_t i = 0; i < name.length(); i++) - if (name[i] == _T('/')) - name[i] = _T('\\'); + if (name[i] == wxT('/')) + name[i] = wxT('\\'); return name; } case wxPATH_UNIX: - return isDir ? m_Name + _T("/") : m_Name; + return isDir ? m_Name + wxT("/") : m_Name; default: ; @@ -834,9 +834,9 @@ wxString wxZipEntry::GetInternalName(const wxString& name, while (!internal.empty() && *internal.begin() == '/') internal.erase(0, 1); - while (!internal.empty() && internal.compare(0, 2, _T("./")) == 0) + while (!internal.empty() && internal.compare(0, 2, wxT("./")) == 0) internal.erase(0, 2); - if (internal == _T(".") || internal == _T("..")) + if (internal == wxT(".") || internal == wxT("..")) internal = wxEmptyString; return internal; @@ -1004,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)); @@ -1080,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)); @@ -1235,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); @@ -1269,7 +1269,9 @@ bool wxZipEndRec::Read(wxInputStream& stream, wxMBConv& conv) if (m_DiskNumber != 0 || m_StartDisk != 0 || m_EntriesHere != m_TotalEntries) + { wxLogWarning(_("assuming this is a multi-part zip concatenated")); + } return true; } @@ -1336,7 +1338,7 @@ void wxZipInputStream::Init(const wxString& file) Init(); m_allowSeeking = true; wxFFileInputStream *ffile; - ffile = wx_static_cast(wxFFileInputStream*, m_parent_i_stream); + ffile = static_cast(m_parent_i_stream); wxZipEntryPtr_ entry; if (ffile->Ok()) { @@ -1374,7 +1376,7 @@ void wxZipInputStream::Init() m_signature = 0; m_TotalEntries = 0; m_lasterror = m_parent_i_stream->GetLastError(); -#if WXWIN_COMPATIBILITY_2_6 && wxUSE_FFILE +#if WXWIN_COMPATIBILITY_2_6 m_allowSeeking = false; #endif } @@ -1463,11 +1465,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; @@ -1477,8 +1481,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; @@ -1870,20 +1874,26 @@ size_t wxZipInputStream::OnSysRead(void *buffer, size_t size) m_lasterror = wxSTREAM_READ_ERROR; if (m_entry.GetSize() != TellI()) + { wxLogError(_("reading zip stream (entry %s): bad length"), m_entry.GetName().c_str()); + } else if (m_crcAccumulator != m_entry.GetCrc()) + { wxLogError(_("reading zip stream (entry %s): bad crc"), m_entry.GetName().c_str()); + } else + { m_lasterror = wxSTREAM_EOF; + } } } return count; } -#if WXWIN_COMPATIBILITY_2_6 && wxUSE_FFILE +#if WXWIN_COMPATIBILITY_2_6 // Borrowed from VS's zip stream (c) 1999 Vaclav Slavik // @@ -1948,7 +1958,7 @@ wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) return pos; } -#endif // WXWIN_COMPATIBILITY_2_6 && wxUSE_FFILE +#endif // WXWIN_COMPATIBILITY_2_6 ///////////////////////////////////////////////////////////////////////////// @@ -1988,6 +1998,7 @@ void wxZipOutputStream::Init(int level) m_comp = NULL; m_level = level; m_offsetAdjustment = wxInvalidOffset; + m_endrecWritten = false; } wxZipOutputStream::~wxZipOutputStream() @@ -2048,7 +2059,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) @@ -2062,7 +2073,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) @@ -2287,7 +2298,9 @@ 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; } @@ -2312,7 +2325,8 @@ bool wxZipOutputStream::Close() endrec.Write(*m_parent_o_stream, GetConv()); m_lasterror = m_parent_o_stream->GetLastError(); - + m_endrecWritten = true; + if (!wxFilterOutputStream::Close() || !IsOk()) return false; m_lasterror = wxSTREAM_EOF;