/////////////////////////////////////////////////////////////////////////////
-// Name: zipstrm.cpp
+// Name: src/common/zipstrm.cpp
// Purpose: Streams for Zip files
// Author: Mike Wetherell
// RCS-ID: $Id$
#include "wx/wxprec.h"
#ifdef __BORLANDC__
- #pragma hdrstop
+ #pragma hdrstop
#endif
+#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
+
#ifndef WX_PRECOMP
- #include "wx/defs.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+ #include "wx/utils.h"
#endif
-#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
-
#include "wx/zipstrm.h"
-#include "wx/log.h"
-#include "wx/intl.h"
#include "wx/datstrm.h"
#include "wx/zstream.h"
#include "wx/mstream.h"
-#include "wx/utils.h"
#include "wx/buffer.h"
#include "wx/ptr_scpd.h"
#include "wx/wfstream.h"
//
static wxString ReadString(wxInputStream& stream, wxUint16 len, wxMBConv& conv)
{
+ if (len == 0)
+ return wxEmptyString;
+
#if wxUSE_UNICODE
wxCharBuffer buf(len);
stream.Read(buf.data(), len);
return (n[3] << 24) | (n[2] << 16) | (n[1] << 8) | n[0];
}
+// Decode a little endian wxUint16 number from a character array
+//
+static inline wxUint16 CrackUint16(const char *m)
+{
+ const unsigned char *n = (const unsigned char*)m;
+ return (n[1] << 8) | n[0];
+}
+
// Temporarily lower the logging level in debug mode to avoid a warning
// from SeekI about seeking on a stream with data written back to it.
//
static wxFileOffset QuietSeek(wxInputStream& stream, wxFileOffset pos)
{
-#ifdef __WXDEBUG__
+#if defined(__WXDEBUG__) && wxUSE_LOG
wxLogLevel level = wxLog::GetLogLevel();
wxLog::SetLogLevel(wxLOG_Debug - 1);
wxFileOffset result = stream.SeekI(pos);
wxUint8 wxZipHeader::Read8()
{
wxASSERT(m_pos < m_size);
- return *wx_reinterpret_cast(wxUint8*, m_data + m_pos++);
+ return m_data[m_pos++];
}
wxUint16 wxZipHeader::Read16()
{
wxASSERT(m_pos + 2 <= m_size);
- wxUint16 n = *wx_reinterpret_cast(wxUint16*, m_data + m_pos);
+ wxUint16 n = CrackUint16(m_data + m_pos);
m_pos += 2;
- return wxUINT16_SWAP_ON_BE(n);
+ return n;
}
wxUint32 wxZipHeader::Read32()
{
wxASSERT(m_pos + 4 <= m_size);
- wxUint32 n = *wx_reinterpret_cast(wxUint32*, m_data + m_pos);
+ wxUint32 n = CrackUint32(m_data + m_pos);
m_pos += 4;
- return wxUINT32_SWAP_ON_BE(n);
+ return n;
}
case wxPATH_DOS:
{
wxString name(isDir ? m_Name + _T("\\") : m_Name);
- for (size_t i = name.length() - 1; i > 0; --i)
+ for (size_t i = 0; i < name.length(); i++)
if (name[i] == _T('/'))
name[i] = _T('\\');
return name;
if (m_Crc == SUMS_MAGIC)
{
wxZipHeader buf(stream, 8);
- wxUint32 u1 = buf.GetSize() >= 4 ? buf.Read32() : LOCAL_MAGIC;
+ wxUint32 u1 = buf.GetSize() >= 4 ? buf.Read32() : (wxUint32)LOCAL_MAGIC;
wxUint32 u2 = buf.GetSize() == 8 ? buf.Read32() : 0;
// look for the signature of the following record to decide which
else {
wxLogNull nolog;
wxFileOffset pos = m_parent_i_stream->TellI();
- // FIXME
- //if (pos != wxInvalidOffset)
- if (pos >= 0 && pos <= LONG_MAX)
+ if (pos != wxInvalidOffset)
m_offsetAdjustment = m_position = pos;
return true;
}
return wxSTREAM_EOF;
}
- if (m_signature != LOCAL_MAGIC) {
- wxLogError(_("error reading zip local header"));
- return wxSTREAM_READ_ERROR;
- }
-
- m_headerSize = m_entry.ReadLocal(*m_parent_i_stream, GetConv());
- m_signature = 0;
- m_entry.SetOffset(m_position);
- m_entry.SetKey(m_position);
+ if (m_signature == LOCAL_MAGIC) {
+ m_headerSize = m_entry.ReadLocal(*m_parent_i_stream, GetConv());
+ m_signature = 0;
+ m_entry.SetOffset(m_position);
+ m_entry.SetKey(m_position);
- if (!m_headerSize) {
- return wxSTREAM_READ_ERROR;
- } else {
- m_TotalEntries++;
- return wxSTREAM_NO_ERROR;
+ if (m_headerSize) {
+ m_TotalEntries++;
+ return wxSTREAM_NO_ERROR;
+ }
}
+
+ wxLogError(_("error reading zip local header"));
+ return wxSTREAM_READ_ERROR;
}
wxUint32 wxZipInputStream::ReadSignature()