]> git.saurik.com Git - wxWidgets.git/blame - src/common/fs_zip.cpp
[ 1067084 ] fs_zip.cpp assertion fix
[wxWidgets.git] / src / common / fs_zip.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: fs_zip.cpp
3// Purpose: ZIP file system
4// Author: Vaclav Slavik
5// Copyright: (c) 1999 Vaclav Slavik
de0702d0 6// CVS-ID: $Id$
65571936 7// Licence: wxWindows licence
5526e819
VS
8/////////////////////////////////////////////////////////////////////////////
9
10
de0702d0 11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
c3f4609e 13#pragma implementation "fs_zip.h"
5526e819
VS
14#endif
15
3096bd2f 16#include "wx/wxprec.h"
5526e819 17
2b5f62a0 18#ifdef __BORLANDC__
5526e819
VS
19#pragma hdrstop
20#endif
21
9777274a 22#if wxUSE_FILESYSTEM && wxUSE_FS_ZIP && wxUSE_ZIPSTREAM && wxUSE_ZLIB
e3e717ec 23
5526e819 24#ifndef WXPRECOMP
04dbb646
VZ
25 #include "wx/intl.h"
26 #include "wx/log.h"
5526e819
VS
27#endif
28
29#include "wx/filesys.h"
00375592 30#include "wx/wfstream.h"
6001e347 31#include "wx/zipstrm.h"
5526e819
VS
32#include "wx/fs_zip.h"
33
aaa66113 34
ddaf5566 35//----------------------------------------------------------------------------
5526e819 36// wxZipFSHandler
ddaf5566 37//----------------------------------------------------------------------------
5526e819
VS
38
39
40
aaa66113
VS
41wxZipFSHandler::wxZipFSHandler() : wxFileSystemHandler()
42{
43 m_Archive = NULL;
44 m_ZipFile = m_Pattern = m_BaseDir = wxEmptyString;
a62848fd 45 m_AllowDirs = m_AllowFiles = true;
de0702d0 46 m_DirsFound = NULL;
aaa66113
VS
47}
48
49
50
51wxZipFSHandler::~wxZipFSHandler()
52{
505710ca 53 if (m_Archive)
00375592 54 CloseArchive(m_Archive);
de0702d0
VS
55 if (m_DirsFound)
56 delete m_DirsFound;
aaa66113
VS
57}
58
59
60
00375592
VZ
61void wxZipFSHandler::CloseArchive(wxZipInputStream *archive)
62{
63 wxInputStream *stream = archive->GetFilterInputStream();
64 delete archive;
65 delete stream;
66}
67
68
69
5526e819
VS
70bool wxZipFSHandler::CanOpen(const wxString& location)
71{
72 wxString p = GetProtocol(location);
505710ca 73 return (p == wxT("zip")) &&
08b50c2c 74 (GetProtocol(GetLeftLocation(location)) == wxT("file"));
5526e819
VS
75}
76
77
78
79
80wxFSFile* wxZipFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
81{
82 wxString right = GetRightLocation(location);
83 wxString left = GetLeftLocation(location);
84 wxInputStream *s;
85
505710ca 86 if (GetProtocol(left) != wxT("file"))
095472c0
VS
87 {
88 wxLogError(_("ZIP handler currently supports only local files!"));
5526e819
VS
89 return NULL;
90 }
91
ddaf5566
VS
92 if (right.Contains(wxT("./")))
93 {
94 if (right.GetChar(0) != wxT('/')) right = wxT('/') + right;
95 wxFileName rightPart(right, wxPATH_UNIX);
96 rightPart.Normalize(wxPATH_NORM_DOTS, wxT("/"), wxPATH_UNIX);
97 right = rightPart.GetFullPath(wxPATH_UNIX);
98 }
a62848fd 99
505710ca
KB
100 if (right.GetChar(0) == wxT('/')) right = right.Mid(1);
101
9548c49a 102 wxFileName leftFilename = wxFileSystem::URLToFileName(left);
2b5f62a0 103
9548c49a 104 s = new wxZipInputStream(leftFilename.GetFullPath(), right);
2b5f62a0 105 if (s && s->IsOk() )
095472c0 106 {
5526e819 107 return new wxFSFile(s,
58c837a4 108 left + wxT("#zip:") + right,
5526e819 109 GetMimeTypeFromExt(location),
e2b87f38
VZ
110 GetAnchor(location)
111#if wxUSE_DATETIME
112 , wxDateTime(wxFileModificationTime(left))
113#endif // wxUSE_DATETIME
114 );
5526e819 115 }
3ca6a5f0
BP
116
117 delete s;
118 return NULL;
5526e819
VS
119}
120
121
122
aaa66113
VS
123wxString wxZipFSHandler::FindFirst(const wxString& spec, int flags)
124{
125 wxString right = GetRightLocation(spec);
126 wxString left = GetLeftLocation(spec);
505710ca 127
aaa66113
VS
128 if (right.Last() == wxT('/')) right.RemoveLast();
129
505710ca 130 if (m_Archive)
095472c0 131 {
00375592 132 CloseArchive(m_Archive);
aaa66113
VS
133 m_Archive = NULL;
134 }
135
de0702d0
VS
136 if (GetProtocol(left) != wxT("file"))
137 {
138 wxLogError(_("ZIP handler currently supports only local files!"));
aaa66113 139 return wxEmptyString;
de0702d0 140 }
aaa66113 141
505710ca 142 switch (flags)
095472c0 143 {
505710ca 144 case wxFILE:
a62848fd 145 m_AllowDirs = false, m_AllowFiles = true; break;
505710ca 146 case wxDIR:
a62848fd 147 m_AllowDirs = true, m_AllowFiles = false; break;
505710ca 148 default:
a62848fd 149 m_AllowDirs = m_AllowFiles = true; break;
aaa66113
VS
150 }
151
152 m_ZipFile = left;
9548c49a 153 wxString nativename = wxFileSystem::URLToFileName(m_ZipFile).GetFullPath();
e06cac58
RN
154
155 wxFFileInputStream *fs = new wxFFileInputStream(nativename);
156 if (fs->Ok())
157 m_Archive = new wxZipInputStream(*fs);
158 else
159 delete fs;
160
aaa66113
VS
161 m_Pattern = right.AfterLast(wxT('/'));
162 m_BaseDir = right.BeforeLast(wxT('/'));
163
505710ca 164 if (m_Archive)
095472c0 165 {
00375592 166 if (m_AllowDirs)
de0702d0 167 {
00375592
VZ
168 delete m_DirsFound;
169 m_DirsFound = new wxLongToLongHashMap();
de0702d0 170 }
00375592 171 return DoFind();
aaa66113 172 }
095472c0 173 return wxEmptyString;
aaa66113
VS
174}
175
176
177
178wxString wxZipFSHandler::FindNext()
5526e819 179{
aaa66113
VS
180 if (!m_Archive) return wxEmptyString;
181 return DoFind();
5526e819
VS
182}
183
aaa66113
VS
184
185
186wxString wxZipFSHandler::DoFind()
187{
de0702d0 188 wxString namestr, dir, filename;
aaa66113 189 wxString match = wxEmptyString;
aaa66113
VS
190
191 while (match == wxEmptyString)
192 {
00375592
VZ
193 wxZipEntry *entry = m_Archive->GetNextEntry();
194 if (!entry)
195 {
196 CloseArchive(m_Archive);
197 m_Archive = NULL;
198 break;
199 }
200 namestr = entry->GetName(wxPATH_UNIX);
201 delete entry;
aaa66113 202
de0702d0 203 if (m_AllowDirs)
095472c0 204 {
505710ca 205 dir = namestr.BeforeLast(wxT('/'));
de0702d0
VS
206 while (!dir.IsEmpty())
207 {
208 long key = 0;
209 for (size_t i = 0; i < dir.Length(); i++) key += (wxUChar)dir[i];
ba8c1601
MB
210 wxLongToLongHashMap::iterator it = m_DirsFound->find(key);
211 if (it == m_DirsFound->end())
de0702d0 212 {
d8771ac7 213 (*m_DirsFound)[key] = 1;
de0702d0
VS
214 filename = dir.AfterLast(wxT('/'));
215 dir = dir.BeforeLast(wxT('/'));
216 if (!filename.IsEmpty() && m_BaseDir == dir &&
a62848fd 217 wxMatchWild(m_Pattern, filename, false))
de0702d0
VS
218 match = m_ZipFile + wxT("#zip:") + dir + wxT("/") + filename;
219 }
505710ca 220 else
de0702d0
VS
221 break; // already tranversed
222 }
aaa66113 223 }
de0702d0
VS
224
225 filename = namestr.AfterLast(wxT('/'));
226 dir = namestr.BeforeLast(wxT('/'));
227 if (m_AllowFiles && !filename.IsEmpty() && m_BaseDir == dir &&
a62848fd 228 wxMatchWild(m_Pattern, filename, false))
de0702d0 229 match = m_ZipFile + wxT("#zip:") + namestr;
aaa66113 230 }
505710ca 231
aaa66113
VS
232 return match;
233}
234
235
236
505710ca 237#endif
24528b0c 238 //wxUSE_FILESYSTEM && wxUSE_FS_ZIP && wxUSE_ZIPSTREAM