]>
git.saurik.com Git - wxWidgets.git/blob - src/common/fs_zip.cpp
136cbb9d3729c7ef47eac0d1b8087b3c41339689
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     ZIP file system 
   4 // Author:      Vaclav Slavik 
   5 // Copyright:   (c) 1999 Vaclav Slavik 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "fs_zip.h" 
  16 #include "wx/wxprec.h" 
  22 #if wxUSE_FILESYSTEM && wxUSE_FS_ZIP && wxUSE_ZIPSTREAM && wxUSE_ZLIB 
  29 #include "wx/filesys.h" 
  30 #include "wx/wfstream.h" 
  31 #include "wx/zipstrm.h" 
  32 #include "wx/fs_zip.h" 
  35 //---------------------------------------------------------------------------- 
  37 //---------------------------------------------------------------------------- 
  41 wxZipFSHandler::wxZipFSHandler() : wxFileSystemHandler() 
  44     m_ZipFile 
= m_Pattern 
= m_BaseDir 
= wxEmptyString
; 
  45     m_AllowDirs 
= m_AllowFiles 
= true; 
  51 wxZipFSHandler::~wxZipFSHandler() 
  54         CloseArchive(m_Archive
); 
  61 void wxZipFSHandler::CloseArchive(wxZipInputStream 
*archive
) 
  63     wxInputStream 
*stream 
= archive
->GetFilterInputStream(); 
  70 bool wxZipFSHandler::CanOpen(const wxString
& location
) 
  72     wxString p 
= GetProtocol(location
); 
  73     return (p 
== wxT("zip")) && 
  74            (GetProtocol(GetLeftLocation(location
)) == wxT("file")); 
  80 wxFSFile
* wxZipFSHandler::OpenFile(wxFileSystem
& WXUNUSED(fs
), const wxString
& location
) 
  82     wxString right 
= GetRightLocation(location
); 
  83     wxString left 
= GetLeftLocation(location
); 
  86     if (GetProtocol(left
) != wxT("file")) 
  88         wxLogError(_("ZIP handler currently supports only local files!")); 
  92     if (right
.Contains(wxT("./"))) 
  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
); 
 100     if (right
.GetChar(0) == wxT('/')) right 
= right
.Mid(1); 
 102     wxFileName leftFilename 
= wxFileSystem::URLToFileName(left
); 
 104     s 
= new wxZipInputStream(leftFilename
.GetFullPath(), right
); 
 107         return new wxFSFile(s
, 
 108                             left 
+ wxT("#zip:") + right
, 
 109                             GetMimeTypeFromExt(location
), 
 112                             , wxDateTime(wxFileModificationTime(left
)) 
 113 #endif // wxUSE_DATETIME 
 123 wxString 
wxZipFSHandler::FindFirst(const wxString
& spec
, int flags
) 
 125     wxString right 
= GetRightLocation(spec
); 
 126     wxString left 
= GetLeftLocation(spec
); 
 128     if (right
.Last() == wxT('/')) right
.RemoveLast(); 
 132         CloseArchive(m_Archive
); 
 136     if (GetProtocol(left
) != wxT("file")) 
 138         wxLogError(_("ZIP handler currently supports only local files!")); 
 139         return wxEmptyString
; 
 145             m_AllowDirs 
= false, m_AllowFiles 
= true; break; 
 147             m_AllowDirs 
= true, m_AllowFiles 
= false; break; 
 149             m_AllowDirs 
= m_AllowFiles 
= true; break; 
 153     wxString nativename 
= wxFileSystem::URLToFileName(m_ZipFile
).GetFullPath(); 
 155     wxFFileInputStream 
*fs 
= new wxFFileInputStream(nativename
); 
 157         m_Archive 
= new wxZipInputStream(*fs
); 
 161     m_Pattern 
= right
.AfterLast(wxT('/')); 
 162     m_BaseDir 
= right
.BeforeLast(wxT('/')); 
 169             m_DirsFound 
= new wxLongToLongHashMap(); 
 173     return wxEmptyString
; 
 178 wxString 
wxZipFSHandler::FindNext() 
 180     if (!m_Archive
) return wxEmptyString
; 
 186 wxString 
wxZipFSHandler::DoFind() 
 188     wxString namestr
, dir
, filename
; 
 189     wxString match 
= wxEmptyString
; 
 191     while (match 
== wxEmptyString
) 
 193         wxZipEntry 
*entry 
= m_Archive
->GetNextEntry(); 
 196             CloseArchive(m_Archive
); 
 200         namestr 
= entry
->GetName(wxPATH_UNIX
); 
 205             dir 
= namestr
.BeforeLast(wxT('/')); 
 206             while (!dir
.IsEmpty()) 
 209                 for (size_t i 
= 0; i 
< dir
.Length(); i
++) key 
+= (wxUChar
)dir
[i
]; 
 210                 wxLongToLongHashMap::iterator it 
= m_DirsFound
->find(key
); 
 211                 if (it 
== m_DirsFound
->end()) 
 213                     (*m_DirsFound
)[key
] = 1; 
 214                     filename 
= dir
.AfterLast(wxT('/')); 
 215                     dir 
= dir
.BeforeLast(wxT('/')); 
 216                     if (!filename
.IsEmpty() && m_BaseDir 
== dir 
&& 
 217                                 wxMatchWild(m_Pattern
, filename
, false)) 
 218                         match 
= m_ZipFile 
+ wxT("#zip:") + dir 
+ wxT("/") + filename
; 
 221                     break; // already tranversed 
 225         filename 
= namestr
.AfterLast(wxT('/')); 
 226         dir 
= namestr
.BeforeLast(wxT('/')); 
 227         if (m_AllowFiles 
&& !filename
.IsEmpty() && m_BaseDir 
== dir 
&& 
 228                             wxMatchWild(m_Pattern
, filename
, false)) 
 229             match 
= m_ZipFile 
+ wxT("#zip:") + namestr
; 
 238       //wxUSE_FILESYSTEM && wxUSE_FS_ZIP && wxUSE_ZIPSTREAM