]> git.saurik.com Git - wxWidgets.git/blame - src/common/zipstrm.cpp
wxUniversal STL-ification.
[wxWidgets.git] / src / common / zipstrm.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: zipstream.cpp
3// Purpose: input stream for ZIP archive access
4// Author: Vaclav Slavik
5// Copyright: (c) 1999 Vaclav Slavik
6// Licence: wxWindows Licence
7/////////////////////////////////////////////////////////////////////////////
8
14f355c2 9#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
5279a24d 10#pragma implementation "zipstrm.h"
5526e819
VS
11#endif
12
d1af991f
RR
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
5526e819 15
d1af991f
RR
16#ifdef __BORLANDC__
17 #pragma hdrstop
5526e819
VS
18#endif
19
e90c1d2a 20#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
d78b3d64 21
d1af991f
RR
22#include "wx/log.h"
23#include "wx/intl.h"
24#include "wx/stream.h"
25#include "wx/wfstream.h"
6001e347 26#include "wx/zipstrm.h"
03c0fc66 27#include "wx/utils.h"
ea4f5235
JS
28
29/* Not the right solution (paths in makefiles) but... */
30#ifdef __BORLANDC__
31#include "../common/unzip.h"
32#else
5526e819 33#include "unzip.h"
ea4f5235
JS
34#endif
35
5526e819 36
5526e819
VS
37wxZipInputStream::wxZipInputStream(const wxString& archive, const wxString& file) : wxInputStream()
38{
39 unz_file_info zinfo;
40
41 m_Pos = 0;
42 m_Size = 0;
f6bcfd97 43 m_Archive = (void*) unzOpen(archive.mb_str());
e90c1d2a 44 if (m_Archive == NULL)
d1af991f 45 {
2b5f62a0 46 m_lasterror = wxSTREAM_READ_ERROR;
5526e819
VS
47 return;
48 }
f6bcfd97 49 if (unzLocateFile((unzFile)m_Archive, file.mb_str(), 0) != UNZ_OK)
d1af991f 50 {
2b5f62a0 51 m_lasterror = wxSTREAM_READ_ERROR;
5526e819
VS
52 return;
53 }
e90c1d2a 54
d1af991f 55 unzGetCurrentFileInfo((unzFile)m_Archive, &zinfo, (char*) NULL, 0, (void*) NULL, 0, (char*) NULL, 0);
5526e819 56
e90c1d2a 57 if (unzOpenCurrentFile((unzFile)m_Archive) != UNZ_OK)
d1af991f 58 {
2b5f62a0 59 m_lasterror = wxSTREAM_READ_ERROR;
5526e819
VS
60 return;
61 }
479cd5de 62 m_Size = (size_t)zinfo.uncompressed_size;
5526e819
VS
63}
64
65
66
67wxZipInputStream::~wxZipInputStream()
68{
e90c1d2a 69 if (m_Archive)
d1af991f 70 {
5526e819
VS
71 if (m_Size != 0)
72 unzCloseCurrentFile((unzFile)m_Archive);
73 unzClose((unzFile)m_Archive);
74 }
75}
76
f6bcfd97
BP
77bool wxZipInputStream::Eof() const
78{
79 wxASSERT_MSG( m_Pos <= (off_t)m_Size,
80 _T("wxZipInputStream: invalid current position") );
81
82 return m_Pos >= (off_t)m_Size;
83}
5526e819
VS
84
85
86size_t wxZipInputStream::OnSysRead(void *buffer, size_t bufsize)
87{
f6bcfd97
BP
88 wxASSERT_MSG( m_Pos <= (off_t)m_Size,
89 _T("wxZipInputStream: invalid current position") );
90
91 if ( m_Pos >= (off_t)m_Size )
92 {
2b5f62a0 93 m_lasterror = wxSTREAM_EOF;
f6bcfd97
BP
94 return 0;
95 }
96
97 if (m_Pos + bufsize > m_Size)
98 bufsize = m_Size - m_Pos;
99
5526e819
VS
100 unzReadCurrentFile((unzFile)m_Archive, buffer, bufsize);
101 m_Pos += bufsize;
f6bcfd97 102
5526e819
VS
103 return bufsize;
104}
105
106
107
108off_t wxZipInputStream::OnSysSeek(off_t seek, wxSeekMode mode)
109{
03c0fc66
VS
110 // NB: since ZIP files don't natively support seeking, we have to
111 // implement a brute force workaround -- reading all the data
112 // between current and the new position (or between beginning of
113 // the file and new position...)
114
5526e819 115 off_t nextpos;
5526e819 116
03c0fc66 117 switch ( mode )
d1af991f 118 {
5526e819
VS
119 case wxFromCurrent : nextpos = seek + m_Pos; break;
120 case wxFromStart : nextpos = seek; break;
121 case wxFromEnd : nextpos = m_Size - 1 + seek; break;
122 default : nextpos = m_Pos; break; /* just to fool compiler, never happens */
123 }
124
03c0fc66
VS
125 size_t toskip = 0;
126 if ( nextpos > m_Pos )
d1af991f 127 {
03c0fc66 128 toskip = nextpos - m_Pos;
5526e819 129 }
03c0fc66
VS
130 else
131 {
5526e819 132 unzCloseCurrentFile((unzFile)m_Archive);
e90c1d2a
VZ
133 if (unzOpenCurrentFile((unzFile)m_Archive) != UNZ_OK)
134 {
2b5f62a0 135 m_lasterror = wxSTREAM_READ_ERROR;
5526e819
VS
136 return m_Pos;
137 }
03c0fc66
VS
138 toskip = nextpos;
139 }
140
141 if ( toskip > 0 )
142 {
143 const size_t BUFSIZE = 4096;
144 size_t sz;
145 char buffer[BUFSIZE];
146 while ( toskip > 0 )
147 {
148 sz = wxMin(toskip, BUFSIZE);
149 unzReadCurrentFile((unzFile)m_Archive, buffer, sz);
150 toskip -= sz;
151 }
5526e819
VS
152 }
153
154 m_Pos = nextpos;
155 return m_Pos;
156}
157
d78b3d64 158#endif
e90c1d2a 159 // wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB