]>
git.saurik.com Git - wxWidgets.git/blob - src/common/fs_zip.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: ZIP file system
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
16 #include "wx/wxprec.h"
22 #if wxUSE_FILESYSTEM && wxUSE_FS_ZIP && wxUSE_ZIPSTREAM
29 #include "wx/filesys.h"
30 #include "wx/zipstrm.h"
31 #include "wx/fs_zip.h"
33 /* Not the right solution (paths in makefiles) but... */
35 #include "../common/unzip.h"
41 //--------------------------------------------------------------------------------
43 //--------------------------------------------------------------------------------
47 wxZipFSHandler::wxZipFSHandler() : wxFileSystemHandler()
50 m_ZipFile
= m_Pattern
= m_BaseDir
= wxEmptyString
;
51 m_AllowDirs
= m_AllowFiles
= TRUE
;
57 wxZipFSHandler::~wxZipFSHandler()
60 unzClose((unzFile
)m_Archive
);
67 bool wxZipFSHandler::CanOpen(const wxString
& location
)
69 wxString p
= GetProtocol(location
);
70 return (p
== wxT("zip"));
76 wxFSFile
* wxZipFSHandler::OpenFile(wxFileSystem
& WXUNUSED(fs
), const wxString
& location
)
78 wxString right
= GetRightLocation(location
);
79 wxString left
= GetLeftLocation(location
);
82 if (GetProtocol(left
) != wxT("file"))
84 wxLogError(_("ZIP handler currently supports only local files!"));
88 s
= new wxZipInputStream(left
, right
);
89 if (s
&& (s
->LastError() == wxStream_NOERROR
))
91 return new wxFSFile(s
,
92 left
+ wxT("#zip:") + right
,
93 GetMimeTypeFromExt(location
),
95 wxDateTime(wxFileModificationTime(left
)));
104 wxString
wxZipFSHandler::FindFirst(const wxString
& spec
, int flags
)
106 wxString right
= GetRightLocation(spec
);
107 wxString left
= GetLeftLocation(spec
);
109 if (right
.Last() == wxT('/')) right
.RemoveLast();
113 unzClose((unzFile
)m_Archive
);
117 if (GetProtocol(left
) != wxT("file"))
119 wxLogError(_("ZIP handler currently supports only local files!"));
120 return wxEmptyString
;
126 m_AllowDirs
= FALSE
, m_AllowFiles
= TRUE
; break;
128 m_AllowDirs
= TRUE
, m_AllowFiles
= FALSE
; break;
130 m_AllowDirs
= m_AllowFiles
= TRUE
; break;
134 m_Archive
= (void*) unzOpen(m_ZipFile
.mb_str());
135 m_Pattern
= right
.AfterLast(wxT('/'));
136 m_BaseDir
= right
.BeforeLast(wxT('/'));
140 if (unzGoToFirstFile((unzFile
)m_Archive
) != UNZ_OK
)
142 unzClose((unzFile
)m_Archive
);
150 m_DirsFound
= new wxHashTableLong();
155 return wxEmptyString
;
160 wxString
wxZipFSHandler::FindNext()
162 if (!m_Archive
) return wxEmptyString
;
168 wxString
wxZipFSHandler::DoFind()
170 static char namebuf
[1024]; // char, not wxChar!
172 wxString namestr
, dir
, filename
;
173 wxString match
= wxEmptyString
;
175 while (match
== wxEmptyString
)
177 unzGetCurrentFileInfo((unzFile
)m_Archive
, NULL
, namebuf
, 1024, NULL
, 0, NULL
, 0);
178 for (c
= namebuf
; *c
; c
++) if (*c
== wxT('\\')) *c
= wxT('/');
183 dir
= namestr
.BeforeLast(wxT('/'));
184 while (!dir
.IsEmpty())
187 for (size_t i
= 0; i
< dir
.Length(); i
++) key
+= (wxUChar
)dir
[i
];
188 if (m_DirsFound
->Get(key
) == wxNOT_FOUND
)
190 m_DirsFound
->Put(key
, 1);
191 filename
= dir
.AfterLast(wxT('/'));
192 dir
= dir
.BeforeLast(wxT('/'));
193 if (!filename
.IsEmpty() && m_BaseDir
== dir
&&
194 wxMatchWild(m_Pattern
, filename
, FALSE
))
195 match
= m_ZipFile
+ wxT("#zip:") + dir
+ wxT("/") + filename
;
198 break; // already tranversed
202 filename
= namestr
.AfterLast(wxT('/'));
203 dir
= namestr
.BeforeLast(wxT('/'));
204 if (m_AllowFiles
&& !filename
.IsEmpty() && m_BaseDir
== dir
&&
205 wxMatchWild(m_Pattern
, filename
, FALSE
))
206 match
= m_ZipFile
+ wxT("#zip:") + namestr
;
208 if (unzGoToNextFile((unzFile
)m_Archive
) != UNZ_OK
)
210 unzClose((unzFile
)m_Archive
);
222 //wxUSE_FILESYSTEM && wxUSE_FS_ZIP && wxUSE_ZIPSTREAM