#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)
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;
+}
/////////////////////////////////////////////////////////////////////////////
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),
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);
ds >> nameLen >> extraLen >> commentLen
>> m_DiskStart >> m_InternalAttributes >> m_ExternalAttributes;
SetOffset(ds.Read32());
-
+
SetName(ReadString(stream, nameLen, conv), wxPATH_UNIX);
if (extraLen || GetExtraLen()) {
ds << commentLen << m_DiskStart << m_InternalAttributes
<< m_ExternalAttributes << (wxUint32)GetOffset();
-
+
stream.Write(name, nameLen);
if (extraLen)
stream.Write(GetExtra(), extraLen);
size_t wxZipEntry::ReadDescriptor(wxInputStream& stream)
{
wxDataInputStream ds(stream);
-
+
m_Crc = ds.Read32();
m_CompressedSize = ds.Read32();
m_Size = ds.Read32();
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))
delete m_ffile;
m_weaklinks->Release(this);
-
+
if (m_streamlink)
m_streamlink->Release(this);
}
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;
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.
//
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;
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;
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)
}
return wxSTREAM_EOF;
}
-
+
if (m_signature != LOCAL_MAGIC) {
wxLogError(_("error reading zip local header"));
return wxSTREAM_READ_ERROR;
// 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;
//
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
{
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);
m_offsetAdjustment(wxInvalidOffset)
{
}
-
+
wxZipOutputStream::~wxZipOutputStream()
{
Close();
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);
}
}