]> git.saurik.com Git - wxWidgets.git/blob - src/common/zipstrm.cpp
Added chapter on collection and container classes to contents
[wxWidgets.git] / src / common / zipstrm.cpp
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
9 #ifdef __GNUG__
10 #pragma implementation "zipstrm.h"
11 #endif
12
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
21
22 #include "wx/log.h"
23 #include "wx/intl.h"
24 #include "wx/stream.h"
25 #include "wx/wfstream.h"
26 #include "wx/zipstrm.h"
27
28 /* Not the right solution (paths in makefiles) but... */
29 #ifdef __BORLANDC__
30 #include "../common/unzip.h"
31 #else
32 #include "unzip.h"
33 #endif
34
35
36 wxZipInputStream::wxZipInputStream(const wxString& archive, const wxString& file) : wxInputStream()
37 {
38 unz_file_info zinfo;
39
40 m_Pos = 0;
41 m_Size = 0;
42 m_Archive = (void*) unzOpen(archive.mb_str());
43 if (m_Archive == NULL)
44 {
45 m_lasterror = wxStream_READ_ERR;
46 return;
47 }
48 if (unzLocateFile((unzFile)m_Archive, file.mb_str(), 0) != UNZ_OK)
49 {
50 m_lasterror = wxStream_READ_ERR;
51 return;
52 }
53
54 unzGetCurrentFileInfo((unzFile)m_Archive, &zinfo, (char*) NULL, 0, (void*) NULL, 0, (char*) NULL, 0);
55
56 if (unzOpenCurrentFile((unzFile)m_Archive) != UNZ_OK)
57 {
58 m_lasterror = wxStream_READ_ERR;
59 return;
60 }
61 m_Size = (size_t)zinfo.uncompressed_size;
62 }
63
64
65
66 wxZipInputStream::~wxZipInputStream()
67 {
68 if (m_Archive)
69 {
70 if (m_Size != 0)
71 unzCloseCurrentFile((unzFile)m_Archive);
72 unzClose((unzFile)m_Archive);
73 }
74 }
75
76 bool wxZipInputStream::Eof() const
77 {
78 wxASSERT_MSG( m_Pos <= (off_t)m_Size,
79 _T("wxZipInputStream: invalid current position") );
80
81 return m_Pos >= (off_t)m_Size;
82 }
83
84
85 size_t wxZipInputStream::OnSysRead(void *buffer, size_t bufsize)
86 {
87 wxASSERT_MSG( m_Pos <= (off_t)m_Size,
88 _T("wxZipInputStream: invalid current position") );
89
90 if ( m_Pos >= (off_t)m_Size )
91 {
92 m_lasterror = wxStream_EOF;
93 return 0;
94 }
95
96 if (m_Pos + bufsize > m_Size)
97 bufsize = m_Size - m_Pos;
98
99 unzReadCurrentFile((unzFile)m_Archive, buffer, bufsize);
100 m_Pos += bufsize;
101
102 return bufsize;
103 }
104
105
106
107 off_t wxZipInputStream::OnSysSeek(off_t seek, wxSeekMode mode)
108 {
109 off_t nextpos;
110 void *buf;
111
112 switch (mode)
113 {
114 case wxFromCurrent : nextpos = seek + m_Pos; break;
115 case wxFromStart : nextpos = seek; break;
116 case wxFromEnd : nextpos = m_Size - 1 + seek; break;
117 default : nextpos = m_Pos; break; /* just to fool compiler, never happens */
118 }
119
120 // cheated seeking :
121 if (nextpos > m_Pos)
122 {
123 buf = malloc(nextpos - m_Pos);
124 unzReadCurrentFile((unzFile)m_Archive, buf, nextpos - m_Pos);
125 free(buf);
126 }
127 else if (nextpos < m_Pos) {
128 unzCloseCurrentFile((unzFile)m_Archive);
129 if (unzOpenCurrentFile((unzFile)m_Archive) != UNZ_OK)
130 {
131 m_lasterror = wxStream_READ_ERR;
132 return m_Pos;
133 }
134 buf = malloc(nextpos);
135 unzReadCurrentFile((unzFile)m_Archive, buf, nextpos);
136 free(buf);
137 }
138
139 m_Pos = nextpos;
140 return m_Pos;
141 }
142
143 #endif
144 // wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB