X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1370b1d01658da0e16d252871c4b3585c834b9f1..068b764a5a7cc2929b1fd8ea5643f43b5cbc8762:/src/common/zipstrm.cpp diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index c6b966fa30..37448574f6 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -34,7 +34,6 @@ #include "wx/buffer.h" #include "wx/ptr_scpd.h" #include "wx/wfstream.h" -#include "wx/html/forcelnk.h" #include "zlib.h" // value for the 'version needed to extract' field (20 means 2.0) @@ -82,7 +81,12 @@ enum { IMPLEMENT_DYNAMIC_CLASS(wxZipEntry, wxArchiveEntry) IMPLEMENT_DYNAMIC_CLASS(wxZipClassFactory, wxArchiveClassFactory) -FORCE_LINK_ME(zipstrm) +//FORCE_LINK_ME(zipstrm) +int _wx_link_dummy_func_zipstrm(); +int _wx_link_dummy_func_zipstrm() +{ + return 1; +} ///////////////////////////////////////////////////////////////////////////// @@ -146,7 +150,7 @@ public: void Close() { m_pos = 0; m_lasterror = wxSTREAM_NO_ERROR; } virtual char Peek() { return wxInputStream::Peek(); } - virtual size_t GetSize() const { return m_len; } + virtual wxFileOffset GetLength() const { return m_len; } protected: virtual size_t OnSysRead(void *buffer, size_t size); @@ -168,7 +172,7 @@ wxStoredInputStream::wxStoredInputStream(wxInputStream& stream) size_t wxStoredInputStream::OnSysRead(void *buffer, size_t size) { - size_t count = wxMin(size, m_len - m_pos + (size_t)0); + size_t count = wxMin(size, (size_t)(m_len - m_pos)); count = m_parent_i_stream->Read(buffer, count).LastRead(); m_pos += count; @@ -470,7 +474,6 @@ class wxZipMemory { public: wxZipMemory() : m_data(NULL), m_size(0), m_capacity(0), m_ref(1) { } - ~wxZipMemory() { delete m_data; } wxZipMemory *AddRef() { m_ref++; return this; } void Release() { if (--m_ref == 0) delete this; } @@ -482,6 +485,7 @@ public: wxZipMemory *Unique(size_t size); private: + ~wxZipMemory() { delete m_data; } char *m_data; size_t m_size; @@ -548,7 +552,6 @@ class wxZipWeakLinks { public: wxZipWeakLinks() : m_ref(1) { } - ~wxZipWeakLinks() { wxASSERT(IsEmpty()); } void Release(const wxZipInputStream* WXUNUSED(x)) { if (--m_ref == 0) delete this; } @@ -556,11 +559,13 @@ public: { RemoveEntry(key); if (--m_ref == 0) delete this; } wxZipWeakLinks *AddEntry(wxZipEntry *entry, wxFileOffset key); - void RemoveEntry(wxFileOffset key) { m_entries.erase(key); } + void RemoveEntry(wxFileOffset key) + { m_entries.erase((_wxOffsetZipEntryMap::key_type)key); } wxZipEntry *GetEntry(wxFileOffset key) const; bool IsEmpty() const { return m_entries.empty(); } private: + ~wxZipWeakLinks() { wxASSERT(IsEmpty()); } int m_ref; _wxOffsetZipEntryMap m_entries; @@ -568,14 +573,15 @@ private: wxZipWeakLinks *wxZipWeakLinks::AddEntry(wxZipEntry *entry, wxFileOffset key) { - m_entries[key] = entry; + m_entries[(_wxOffsetZipEntryMap::key_type)key] = entry; m_ref++; return this; } wxZipEntry *wxZipWeakLinks::GetEntry(wxFileOffset key) const { - _wxOffsetZipEntryMap::const_iterator it = m_entries.find(key); + _wxOffsetZipEntryMap::const_iterator it = + m_entries.find((_wxOffsetZipEntryMap::key_type)key); return it != m_entries.end() ? it->second : NULL; } @@ -587,7 +593,7 @@ wxZipEntry::wxZipEntry( const wxString& name /*=wxEmptyString*/, const wxDateTime& dt /*=wxDateTime::Now()*/, wxFileOffset size /*=wxInvalidOffset*/) - : + : m_SystemMadeBy(wxZIP_SYSTEM_MSDOS), m_VersionMadeBy(wxMAJOR_VERSION * 10 + wxMINOR_VERSION), m_VersionNeeded(VERSION_NEEDED_TO_EXTRACT), @@ -620,7 +626,8 @@ wxZipEntry::~wxZipEntry() } wxZipEntry::wxZipEntry(const wxZipEntry& e) - : m_SystemMadeBy(e.m_SystemMadeBy), + : wxArchiveEntry(e), + m_SystemMadeBy(e.m_SystemMadeBy), m_VersionMadeBy(e.m_VersionMadeBy), m_VersionNeeded(e.m_VersionNeeded), m_Flags(e.m_Flags), @@ -638,7 +645,7 @@ wxZipEntry::wxZipEntry(const wxZipEntry& e) m_ExternalAttributes(e.m_ExternalAttributes), m_Extra(AddRef(e.m_Extra)), m_LocalExtra(AddRef(e.m_LocalExtra)), - m_zipnotifier(e.m_zipnotifier), + m_zipnotifier(NULL), m_backlink(NULL) { } @@ -664,7 +671,7 @@ wxZipEntry& wxZipEntry::operator=(const wxZipEntry& e) m_ExternalAttributes = e.m_ExternalAttributes; Copy(m_Extra, e.m_Extra); Copy(m_LocalExtra, e.m_LocalExtra); - m_zipnotifier = e.m_zipnotifier; + m_zipnotifier = NULL; if (m_backlink) { m_backlink->Release(m_Key); m_backlink = NULL; @@ -741,7 +748,7 @@ void wxZipEntry::SetSystemMadeBy(int system) int mode = GetMode(); bool wasUnix = IsMadeByUnix(); - m_SystemMadeBy = system; + m_SystemMadeBy = (wxUint8)system; if (!wasUnix && IsMadeByUnix()) { SetIsDir(IsDir()); @@ -894,19 +901,19 @@ size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const const wxWX2MBbuf name_buf = conv.cWX2MB(unixName); const char *name = name_buf; if (!name) name = ""; - wxUint16 nameLen = strlen(name); + wxUint16 nameLen = (wxUint16)strlen(name); wxDataOutputStream ds(stream); ds << m_VersionNeeded << m_Flags << m_Method; ds.Write32(GetDateTime().GetAsDOS()); - + ds.Write32(m_Crc); - ds.Write32(m_CompressedSize != wxInvalidOffset ? m_CompressedSize : 0); - ds.Write32(m_Size != wxInvalidOffset ? m_Size : 0); + ds.Write32(m_CompressedSize != wxInvalidOffset ? (wxUint32)m_CompressedSize : 0); + ds.Write32(m_Size != wxInvalidOffset ? (wxUint32)m_Size : 0); ds << nameLen; - wxUint16 extraLen = GetLocalExtraLen(); + wxUint16 extraLen = (wxUint16)GetLocalExtraLen(); ds.Write16(extraLen); stream.Write(name, nameLen); @@ -935,7 +942,7 @@ size_t wxZipEntry::ReadCentral(wxInputStream& stream, wxMBConv& conv) ds >> nameLen >> extraLen >> commentLen >> m_DiskStart >> m_InternalAttributes >> m_ExternalAttributes; SetOffset(ds.Read32()); - + SetName(ReadString(stream, nameLen, conv), wxPATH_UNIX); if (extraLen || GetExtraLen()) { @@ -958,32 +965,32 @@ size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const const wxWX2MBbuf name_buf = conv.cWX2MB(unixName); const char *name = name_buf; if (!name) name = ""; - wxUint16 nameLen = strlen(name); + wxUint16 nameLen = (wxUint16)strlen(name); const wxWX2MBbuf comment_buf = conv.cWX2MB(m_Comment); const char *comment = comment_buf; if (!comment) comment = ""; - wxUint16 commentLen = strlen(comment); + wxUint16 commentLen = (wxUint16)strlen(comment); - wxUint16 extraLen = GetExtraLen(); + wxUint16 extraLen = (wxUint16)GetExtraLen(); wxDataOutputStream ds(stream); ds << CENTRAL_MAGIC << m_VersionMadeBy << m_SystemMadeBy; - ds.Write16(GetVersionNeeded()); - ds.Write16(GetFlags()); - ds.Write16(GetMethod()); + ds.Write16((wxUint16)GetVersionNeeded()); + ds.Write16((wxUint16)GetFlags()); + ds.Write16((wxUint16)GetMethod()); ds.Write32(GetDateTime().GetAsDOS()); ds.Write32(GetCrc()); - ds.Write32(GetCompressedSize()); - ds.Write32(GetSize()); + ds.Write32((wxUint32)GetCompressedSize()); + ds.Write32((wxUint32)GetSize()); ds.Write16(nameLen); ds.Write16(extraLen); ds << commentLen << m_DiskStart << m_InternalAttributes << m_ExternalAttributes << (wxUint32)GetOffset(); - + stream.Write(name, nameLen); if (extraLen) stream.Write(GetExtra(), extraLen); @@ -1000,7 +1007,7 @@ size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const size_t wxZipEntry::ReadDescriptor(wxInputStream& stream) { wxDataInputStream ds(stream); - + m_Crc = ds.Read32(); m_CompressedSize = ds.Read32(); m_Size = ds.Read32(); @@ -1012,7 +1019,7 @@ size_t wxZipEntry::ReadDescriptor(wxInputStream& stream) stream.Read(buf, sizeof(buf)); wxUint32 u1 = CrackUint32(buf); wxUint32 u2 = CrackUint32(buf + 4); - + // look for the signature of the following record to decide which if ((u1 == LOCAL_MAGIC || u1 == CENTRAL_MAGIC) && (u2 != LOCAL_MAGIC && u2 != CENTRAL_MAGIC)) @@ -1024,7 +1031,7 @@ size_t wxZipEntry::ReadDescriptor(wxInputStream& stream) { // it's an info-zip record as expected stream.Ungetch(buf + 4, sizeof(buf) - 4); - m_Crc = m_CompressedSize; + m_Crc = (wxUint32)m_CompressedSize; m_CompressedSize = m_Size; m_Size = u1; return SUMS_SIZE + 4; @@ -1044,8 +1051,8 @@ size_t wxZipEntry::WriteDescriptor(wxOutputStream& stream, wxUint32 crc, wxDataOutputStream ds(stream); ds.Write32(crc); - ds.Write32(compressedSize); - ds.Write32(size); + ds.Write32((wxUint32)compressedSize); + ds.Write32((wxUint32)size); return SUMS_SIZE; } @@ -1067,10 +1074,10 @@ public: wxFileOffset GetOffset() const { return m_Offset; } wxString GetComment() const { return m_Comment; } - void SetDiskNumber(int num) { m_DiskNumber = num; } - void SetStartDisk(int num) { m_StartDisk = num; } - void SetEntriesHere(int num) { m_EntriesHere = num; } - void SetTotalEntries(int num) { m_TotalEntries = num; } + void SetDiskNumber(int num) { m_DiskNumber = (wxUint16)num; } + void SetStartDisk(int num) { m_StartDisk = (wxUint16)num; } + void SetEntriesHere(int num) { m_EntriesHere = (wxUint16)num; } + void SetTotalEntries(int num) { m_TotalEntries = (wxUint16)num; } void SetSize(wxFileOffset size) { m_Size = (wxUint32)size; } void SetOffset(wxFileOffset offset) { m_Offset = (wxUint32)offset; } void SetComment(const wxString& comment) { m_Comment = comment; } @@ -1103,7 +1110,7 @@ bool wxZipEndRec::Write(wxOutputStream& stream, wxMBConv& conv) const const wxWX2MBbuf comment_buf = conv.cWX2MB(m_Comment); const char *comment = comment_buf; if (!comment) comment = ""; - wxUint16 commentLen = strlen(comment); + wxUint16 commentLen = (wxUint16)strlen(comment); wxDataOutputStream ds(stream); @@ -1144,7 +1151,6 @@ class wxZipStreamLink { public: wxZipStreamLink(wxZipOutputStream *stream) : m_ref(1), m_stream(stream) { } - ~wxZipStreamLink() { } wxZipStreamLink *AddRef() { m_ref++; return this; } wxZipOutputStream *GetOutputStream() const { return m_stream; } @@ -1155,6 +1161,7 @@ public: { m_stream = NULL; if (--m_ref == 0) delete this; } private: + ~wxZipStreamLink() { } int m_ref; wxZipOutputStream *m_stream; @@ -1234,7 +1241,7 @@ wxZipInputStream::~wxZipInputStream() delete m_ffile; m_weaklinks->Release(this); - + if (m_streamlink) m_streamlink->Release(this); } @@ -1318,7 +1325,7 @@ bool wxZipInputStream::LoadEndRecord() m_Comment = endrec.GetComment(); // Now find the central-directory. we have the file offset of - // the CD, so look there first. + // the CD, so look there first. if (m_parent_i_stream->SeekI(endrec.GetOffset()) != wxInvalidOffset && ReadSignature() == CENTRAL_MAGIC) { m_signature = CENTRAL_MAGIC; @@ -1326,7 +1333,7 @@ bool wxZipInputStream::LoadEndRecord() m_offsetAdjustment = 0; return true; } - + // If it's not there, then it could be that the zip has been appended // 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. @@ -1348,8 +1355,11 @@ bool wxZipInputStream::LoadEndRecord() // bool wxZipInputStream::FindEndRecord() { + if (!m_parent_i_stream->IsSeekable()) + return false; + // usually it's 22 bytes in size and the last thing in the file - { + { wxLogNull nolog; if (m_parent_i_stream->SeekI(-END_SIZE, wxFromEnd) == wxInvalidOffset) return false; @@ -1373,10 +1383,10 @@ bool wxZipInputStream::FindEndRecord() wxFileOffset minpos = wxMax(pos - 65535L, 0); while (pos > minpos) { - size_t len = pos - wxMax(pos - (BUFSIZE - 3), minpos); + size_t len = (size_t)(pos - wxMax(pos - (BUFSIZE - 3), minpos)); memcpy(buf.data() + len, buf, 3); pos -= len; - + if (m_parent_i_stream->SeekI(pos, wxFromStart) == wxInvalidOffset || m_parent_i_stream->Read(buf.data(), len).LastRead() != len) return false; @@ -1460,7 +1470,7 @@ wxStreamError wxZipInputStream::ReadLocal(bool readEndRec /*=false*/) while (m_signature == CENTRAL_MAGIC) { if (m_weaklinks->IsEmpty() && m_streamlink == NULL) return wxSTREAM_EOF; - + m_position += m_entry.ReadCentral(*m_parent_i_stream, GetConv()); m_signature = 0; if (m_parent_i_stream->GetLastError() == wxSTREAM_READ_ERROR) @@ -1496,7 +1506,7 @@ wxStreamError wxZipInputStream::ReadLocal(bool readEndRec /*=false*/) } return wxSTREAM_EOF; } - + if (m_signature != LOCAL_MAGIC) { wxLogError(_("error reading zip local header")); return wxSTREAM_READ_ERROR; @@ -1547,9 +1557,9 @@ bool wxZipInputStream::DoOpen(wxZipEntry *entry, bool raw) // can only open the current entry on a non-seekable stream wxCHECK(m_parentSeekable, false); } - + m_lasterror = wxSTREAM_READ_ERROR; - + if (entry) m_entry = *entry; @@ -1736,7 +1746,12 @@ size_t wxZipInputStream::OnSysRead(void *buffer, size_t size) // wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) { - if (!m_ffile || AtHeader()) + if (!m_ffile) + return wxInvalidOffset; + if (!IsOpened()) + if ((AtHeader() && !DoOpen()) || !OpenDecompressor()) + m_lasterror = wxSTREAM_READ_ERROR; + if (!IsOk()) return wxInvalidOffset; // NB: since ZIP files don't natively support seeking, we have to @@ -1751,14 +1766,14 @@ wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) { case wxFromCurrent : nextpos = seek + pos; break; case wxFromStart : nextpos = seek; break; - case wxFromEnd : nextpos = GetSize() - 1 + seek; break; + case wxFromEnd : nextpos = GetLength() + seek; break; default : nextpos = pos; break; /* just to fool compiler, never happens */ } - size_t toskip; + size_t toskip wxDUMMY_INITIALIZE(0); if ( nextpos >= pos ) { - toskip = nextpos - pos; + toskip = (size_t)(nextpos - pos); } else { @@ -1769,7 +1784,7 @@ wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) m_lasterror = wxSTREAM_READ_ERROR; return pos; } - toskip = nextpos; + toskip = (size_t)nextpos; } if ( toskip > 0 ) @@ -1793,7 +1808,7 @@ wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) ///////////////////////////////////////////////////////////////////////////// // Output stream -#include +#include "wx/listimpl.cpp" WX_DEFINE_LIST(_wxZipEntryList); wxZipOutputStream::wxZipOutputStream(wxOutputStream& stream, @@ -1815,7 +1830,7 @@ wxZipOutputStream::wxZipOutputStream(wxOutputStream& stream, m_offsetAdjustment(wxInvalidOffset) { } - + wxZipOutputStream::~wxZipOutputStream() { Close(); @@ -1914,15 +1929,19 @@ bool wxZipOutputStream::DoCreate(wxZipEntry *entry, bool raw /*=false*/) ds << LOCAL_MAGIC; // and if this is the first entry test for seekability - if (m_headerOffset == 0) { + if (m_headerOffset == 0 && m_parent_o_stream->IsSeekable()) { +#if wxUSE_LOG bool logging = wxLog::IsEnabled(); wxLogNull nolog; +#endif // wxUSE_LOG wxFileOffset here = m_parent_o_stream->TellO(); if (here != wxInvalidOffset && here >= 4) { if (m_parent_o_stream->SeekO(here - 4) == here - 4) { m_offsetAdjustment = here - 4; +#if wxUSE_LOG wxLog::EnableLogging(logging); +#endif // wxUSE_LOG m_parent_o_stream->SeekO(here); } } @@ -2191,7 +2210,8 @@ bool wxZipOutputStream::CloseEntry() } m_headerOffset += m_headerSize + compressedSize; - m_headerSize = m_entrySize = 0; + m_headerSize = 0; + m_entrySize = 0; m_store->Close(); m_raw = false;