X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f8fbc92bdb84f34fc7306266b116ebd2da28c950..9c2a1d53c01e17ff3c35710a0fe0999d9a3832b4:/src/common/zipstrm.cpp diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index 4aa752940c..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; +} ///////////////////////////////////////////////////////////////////////////// @@ -589,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), @@ -903,7 +907,7 @@ size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const ds << m_VersionNeeded << m_Flags << m_Method; ds.Write32(GetDateTime().GetAsDOS()); - + ds.Write32(m_Crc); ds.Write32(m_CompressedSize != wxInvalidOffset ? (wxUint32)m_CompressedSize : 0); ds.Write32(m_Size != wxInvalidOffset ? (wxUint32)m_Size : 0); @@ -938,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()) { @@ -986,7 +990,7 @@ size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const ds << commentLen << m_DiskStart << m_InternalAttributes << m_ExternalAttributes << (wxUint32)GetOffset(); - + stream.Write(name, nameLen); if (extraLen) stream.Write(GetExtra(), extraLen); @@ -1003,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(); @@ -1015,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)) @@ -1237,7 +1241,7 @@ wxZipInputStream::~wxZipInputStream() delete m_ffile; m_weaklinks->Release(this); - + if (m_streamlink) m_streamlink->Release(this); } @@ -1321,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; @@ -1329,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. @@ -1351,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; @@ -1379,7 +1386,7 @@ bool wxZipInputStream::FindEndRecord() 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; @@ -1463,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) @@ -1499,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; @@ -1550,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; @@ -1739,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 @@ -1754,11 +1766,11 @@ wxFileOffset wxZipInputStream::OnSysSeek(wxFileOffset seek, wxSeekMode mode) { case wxFromCurrent : nextpos = seek + pos; break; case wxFromStart : nextpos = seek; break; - case wxFromEnd : nextpos = GetLength() - 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 = (size_t)(nextpos - pos); @@ -1818,7 +1830,7 @@ wxZipOutputStream::wxZipOutputStream(wxOutputStream& stream, m_offsetAdjustment(wxInvalidOffset) { } - + wxZipOutputStream::~wxZipOutputStream() { Close(); @@ -1917,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); } }