wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { // location has Unix path separators wxString right = GetRightLocation(location); wxFileName fn = wxFileSystem::URLToFileName(right); wxString fullpath = ms_root + fn.GetFullPath(); if (!wxFileExists(fullpath)) return NULL; // we need to check whether we can really read from this file, otherwise // wxFSFile is not going to work #if wxUSE_FFILE wxFFileInputStream *is = new wxFFileInputStream(fullpath); #elif wxUSE_FILE wxFileInputStream *is = new wxFileInputStream(fullpath); #else #error One of wxUSE_FILE or wxUSE_FFILE must be set to 1 for wxFSHandler to work #endif if ( !is->IsOk() ) { delete is; return NULL; } return new wxFSFile(is, location, wxEmptyString, GetAnchor(location) #if wxUSE_DATETIME ,wxDateTime(wxFileModificationTime(fullpath)) #endif // wxUSE_DATETIME ); }
/** * Doku see wxFileSystemHandler */ wxString wxChmFSHandler::FindFirst(const wxString& spec, int flags) { wxString right = GetRightLocation(spec); wxString left = GetLeftLocation(spec); wxString nativename = wxFileSystem::URLToFileName(left).GetFullPath(); if ( GetProtocol(left) != _T("file") ) { wxLogError(_("CHM handler currently supports only local files!")); return wxEmptyString; } m_chm = new wxChmTools(wxFileName(nativename)); m_pattern = right.AfterLast(_T('/')); wxString m_found = m_chm->Find(m_pattern); // now fake around hhp-files which are not existing in projects... if (m_found.empty() && m_pattern.Contains(_T(".hhp")) && !m_pattern.Contains(_T(".hhp.cached"))) { m_found.Printf(_T("%s#chm:%s.hhp"), left.c_str(), m_pattern.BeforeLast(_T('.')).c_str()); } return m_found; }
wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { // location has Unix path separators wxString right = GetRightLocation(location); wxFileName fn = wxFileSystem::URLToFileName(right); wxString fullpath = ms_root + fn.GetFullPath(); if (!wxFileExists(fullpath)) return (wxFSFile*) NULL; // we need to check whether we can really read from this file, otherwise // wxFSFile is not going to work wxFFileInputStream *is = new wxFFileInputStream(fullpath); if ( !is->Ok() ) { delete is; return (wxFSFile*) NULL; } return new wxFSFile(is, right, GetMimeTypeFromExt(location), GetAnchor(location) #if wxUSE_DATETIME ,wxDateTime(wxFileModificationTime(fullpath)) #endif // wxUSE_DATETIME ); }
wxString wxArchiveFSHandler::FindFirst(const wxString& spec, int flags) { wxString right = GetRightLocation(spec); wxString left = GetLeftLocation(spec); wxString protocol = GetProtocol(spec); wxString key = left + wxT("#") + protocol + wxT(":"); if (!right.empty() && right.Last() == wxT('/')) right.RemoveLast(); if (!m_cache) m_cache = new wxArchiveFSCache; const wxArchiveClassFactory *factory; factory = wxArchiveClassFactory::Find(protocol); if (!factory) return wxEmptyString; m_Archive = m_cache->Get(key); if (!m_Archive) { wxFSFile *leftFile = m_fs.OpenFile(left); if (!leftFile) return wxEmptyString; m_Archive = m_cache->Add(key, *factory, leftFile->DetachStream()); delete leftFile; } m_FindEntry = NULL; switch (flags) { case wxFILE: m_AllowDirs = false, m_AllowFiles = true; break; case wxDIR: m_AllowDirs = true, m_AllowFiles = false; break; default: m_AllowDirs = m_AllowFiles = true; break; } m_ZipFile = key; m_Pattern = right.AfterLast(wxT('/')); m_BaseDir = right.BeforeLast(wxT('/')); if (m_BaseDir.StartsWith(wxT("/"))) m_BaseDir = m_BaseDir.Mid(1); if (m_Archive) { if (m_AllowDirs) { delete m_DirsFound; m_DirsFound = new wxArchiveFilenameHashMap(); if (right.empty()) // allow "/" to match the archive root return spec; } return DoFind(); } return wxEmptyString; }
wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags) { wxFileName fn = wxFileSystem::URLToFileName(GetRightLocation(spec)); const wxString found = wxFindFirstFile(ms_root + fn.GetFullPath(), flags); if ( found.empty() ) return found; return wxFileSystem::FileNameToURL(found); }
wxFSFile* wxChmFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { wxString right = GetRightLocation(location); wxString left = GetLeftLocation(location); wxInputStream *s; int index; if ( GetProtocol(left) != _T("file") ) { wxLogError(_("CHM handler currently supports only local files!")); return NULL; } // Work around javascript wxString tmp = wxString(right); if ( tmp.MakeLower().Contains(_T("javascipt")) && tmp.Contains(_T("\'")) ) { right = right.AfterFirst(_T('\'')).BeforeLast(_T('\'')); } // now work on the right location if (right.Contains(_T(".."))) { wxFileName abs(right); abs.MakeAbsolute(_T("/")); right = abs.GetFullPath(); } // a workaround for absolute links to root if ( (index=right.Index(_T("//"))) != wxNOT_FOUND ) { right=wxString(right.Mid(index+1)); wxLogWarning(_("Link contained '//', converted to absolute link.")); } wxFileName leftFilename = wxFileSystem::URLToFileName(left); // Open a stream to read the content of the chm-file s = new wxChmInputStream(leftFilename.GetFullPath(), right, true); wxString mime = GetMimeTypeFromExt(location); if ( s ) { return new wxFSFile(s, left + _T("#chm:") + right, mime, GetAnchor(location), wxDateTime(wxFileModificationTime(left))); } delete s; return NULL; }
wxFSFile* wxZipFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { wxString right = GetRightLocation(location); wxString left = GetLeftLocation(location); wxZipInputStream *s; if (right.Contains(wxT("./"))) { if (right.GetChar(0) != wxT('/')) right = wxT('/') + right; wxFileName rightPart(right, wxPATH_UNIX); rightPart.Normalize(wxPATH_NORM_DOTS, wxT("/"), wxPATH_UNIX); right = rightPart.GetFullPath(wxPATH_UNIX); } if (right.GetChar(0) == wxT('/')) right = right.Mid(1); // a new wxFileSystem object is needed here to avoid infinite recursion wxFSFile *leftFile = wxFileSystem().OpenFile(left); if (!leftFile) return NULL; s = new wxZipFSInputStream(leftFile); if (s && s->IsOk()) { bool found = false; while (!found) { wxZipEntry *ent = s->GetNextEntry(); if (!ent) break; if (ent->GetInternalName() == right) found = true; delete ent; } if (found) return new wxFSFile(s, left + wxT("#zip:") + right, GetMimeTypeFromExt(location), GetAnchor(location) #if wxUSE_DATETIME , wxDateTime(wxFileModificationTime(left)) #endif // wxUSE_DATETIME ); } delete s; return NULL; }
wxString wxZipFSHandler::FindFirst(const wxString& spec, int flags) { wxString right = GetRightLocation(spec); wxString left = GetLeftLocation(spec); if (!right.empty() && right.Last() == wxT('/')) right.RemoveLast(); if (m_Archive) { delete m_Archive; m_Archive = NULL; } switch (flags) { case wxFILE: m_AllowDirs = false, m_AllowFiles = true; break; case wxDIR: m_AllowDirs = true, m_AllowFiles = false; break; default: m_AllowDirs = m_AllowFiles = true; break; } m_ZipFile = left; wxFSFile *leftFile = wxFileSystem().OpenFile(left); if (leftFile) m_Archive = new wxZipFSInputStream(leftFile); m_Pattern = right.AfterLast(wxT('/')); m_BaseDir = right.BeforeLast(wxT('/')); if (m_BaseDir.StartsWith(wxT("/"))) m_BaseDir = m_BaseDir.Mid(1); if (m_Archive) { if (m_AllowDirs) { delete m_DirsFound; m_DirsFound = new wxZipFilenameHashMap(); if (right.empty()) // allow "/" to match the archive root return spec; } return DoFind(); } return wxEmptyString; }
wxFSFile* wxFilterFSHandler::OpenFile( wxFileSystem& fs, const wxString& location) { wxString right = GetRightLocation(location); if (!right.empty()) return NULL; wxString protocol = GetProtocol(location); const wxFilterClassFactory *factory = wxFilterClassFactory::Find(protocol); if (!factory) return NULL; wxString left = GetLeftLocation(location); wxFSFilePtr leftFile(fs.OpenFile(left)); if (!leftFile.get()) return NULL; wxInputStreamPtr leftStream(leftFile->DetachStream()); if (!leftStream.get() || !leftStream->IsOk()) return NULL; wxInputStreamPtr stream(factory->NewStream(leftStream.release())); // The way compressed streams are supposed to be served is e.g.: // Content-type: application/postscript // Content-encoding: gzip // So the mime type should be just the mime type of the lhs. However check // whether the mime type is that of this compression format (e.g. // application/gzip). If so pop any extension and try GetMimeTypeFromExt, // e.g. if it were '.ps.gz' pop the '.gz' and try looking up '.ps' wxString mime = leftFile->GetMimeType(); if (factory->CanHandle(mime, wxSTREAM_MIMETYPE)) mime = GetMimeTypeFromExt(factory->PopExtension(left)); return new wxFSFile(stream.release(), left + wxT("#") + protocol + wxT(":") + right, mime, GetAnchor(location) #if wxUSE_DATETIME , leftFile->GetModificationTime() #endif // wxUSE_DATETIME ); }
wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { wxMemoryFSHash::const_iterator i = m_Hash.find(GetRightLocation(location)); if ( i == m_Hash.end() ) return NULL; const wxMemoryFSFile * const obj = i->second; return new wxFSFile ( new wxMemoryInputStream(obj->m_Data, obj->m_Len), location, obj->m_MimeType, GetAnchor(location) #if wxUSE_DATETIME , obj->m_Time #endif // wxUSE_DATETIME ); }
wxString wxMemoryFSHandlerBase::FindFirst(const wxString& url, int flags) { if ( (flags & wxDIR) && !(flags & wxFILE) ) { // we only store files, not directories, so we don't risk finding // anything return wxString(); } const wxString spec = GetRightLocation(url); if ( spec.find_first_of("?*") == wxString::npos ) { // simple case: there are no wildcard characters so we can return // either 0 or 1 results and we can find the potential match quickly return m_Hash.count(spec) ? url : wxString(); } //else: deal with wildcards in FindNext() m_findArgument = spec; m_findIter = m_Hash.begin(); return FindNext(); }
wxString RightLocation(const wxString& p) { return GetRightLocation(p); }
wxFSFile* wxArchiveFSHandler::OpenFile( wxFileSystem& WXUNUSED(fs), const wxString& location) { wxString right = GetRightLocation(location); wxString left = GetLeftLocation(location); wxString protocol = GetProtocol(location); wxString key = left + wxT("#") + protocol + wxT(":"); if (right.Contains(wxT("./"))) { if (right.GetChar(0) != wxT('/')) right = wxT('/') + right; wxFileName rightPart(right, wxPATH_UNIX); rightPart.Normalize(wxPATH_NORM_DOTS, wxT("/"), wxPATH_UNIX); right = rightPart.GetFullPath(wxPATH_UNIX); } if (right.GetChar(0) == wxT('/')) right = right.Mid(1); if (!m_cache) m_cache = new wxArchiveFSCache; const wxArchiveClassFactory *factory; factory = wxArchiveClassFactory::Find(protocol); if (!factory) return NULL; wxArchiveFSCacheData *cached = m_cache->Get(key); if (!cached) { wxFSFile *leftFile = m_fs.OpenFile(left); if (!leftFile) return NULL; cached = m_cache->Add(key, *factory, leftFile->DetachStream()); delete leftFile; } wxArchiveEntry *entry = cached->Get(right); if (!entry) return NULL; wxInputStream *leftStream = cached->NewStream(); if (!leftStream) { wxFSFile *leftFile = m_fs.OpenFile(left); if (!leftFile) return NULL; leftStream = leftFile->DetachStream(); delete leftFile; } wxArchiveInputStream *s = factory->NewStream(leftStream); if ( !s ) return NULL; s->OpenEntry(*entry); if (!s->IsOk()) { delete s; return NULL; } #if WXWIN_COMPATIBILITY_2_6 && wxUSE_ZIPSTREAM if (factory->IsKindOf(CLASSINFO(wxZipClassFactory))) ((wxZipInputStream*)s)->m_allowSeeking = true; #endif // WXWIN_COMPATIBILITY_2_6 return new wxFSFile(s, key + right, wxEmptyString, GetAnchor(location) #if wxUSE_DATETIME , entry->GetDateTime() #endif // wxUSE_DATETIME ); }
/* static */ wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location) { wxString ext, mime; wxString loc = GetRightLocation(location); wxChar c; int l = loc.length(), l2; l2 = l; for (int i = l-1; i >= 0; i--) { c = loc[(unsigned int) i]; if ( c == wxT('#') ) l2 = i + 1; if ( c == wxT('.') ) { ext = loc.Right(l2-i-1); break; } if ( (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':')) ) return wxEmptyString; } #if wxUSE_MIMETYPE static bool s_MinimalMimeEnsured = false; // Don't use mime types manager if the application doesn't need it and it would be // cause an unacceptable delay, especially on startup. #if wxUSE_SYSTEM_OPTIONS if ( !wxSystemOptions::GetOptionInt(wxT("filesys.no-mimetypesmanager")) ) #endif { if (!s_MinimalMimeEnsured) { static const wxFileTypeInfo fallbacks[] = { wxFileTypeInfo(wxT("image/jpeg"), wxEmptyString, wxEmptyString, wxT("JPEG image (from fallback)"), wxT("jpg"), wxT("jpeg"), wxT("JPG"), wxT("JPEG"), wxNullPtr), wxFileTypeInfo(wxT("image/gif"), wxEmptyString, wxEmptyString, wxT("GIF image (from fallback)"), wxT("gif"), wxT("GIF"), wxNullPtr), wxFileTypeInfo(wxT("image/png"), wxEmptyString, wxEmptyString, wxT("PNG image (from fallback)"), wxT("png"), wxT("PNG"), wxNullPtr), wxFileTypeInfo(wxT("image/bmp"), wxEmptyString, wxEmptyString, wxT("windows bitmap image (from fallback)"), wxT("bmp"), wxT("BMP"), wxNullPtr), wxFileTypeInfo(wxT("text/html"), wxEmptyString, wxEmptyString, wxT("HTML document (from fallback)"), wxT("htm"), wxT("html"), wxT("HTM"), wxT("HTML"), wxNullPtr), // must terminate the table with this! wxFileTypeInfo() }; wxTheMimeTypesManager->AddFallbacks(fallbacks); s_MinimalMimeEnsured = true; } wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); if ( !ft || !ft -> GetMimeType(&mime) ) { mime = wxEmptyString; } delete ft; return mime; } else #endif { if ( ext.IsSameAs(wxT("htm"), false) || ext.IsSameAs(wxT("html"), false) ) return wxT("text/html"); if ( ext.IsSameAs(wxT("jpg"), false) || ext.IsSameAs(wxT("jpeg"), false) ) return wxT("image/jpeg"); if ( ext.IsSameAs(wxT("gif"), false) ) return wxT("image/gif"); if ( ext.IsSameAs(wxT("png"), false) ) return wxT("image/png"); if ( ext.IsSameAs(wxT("bmp"), false) ) return wxT("image/bmp"); return wxEmptyString; } }
wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location) { wxString ext, mime; wxString loc = GetRightLocation(location); wxChar c; int l = loc.length(), l2; l2 = l; for (int i = l-1; i >= 0; i--) { c = loc[(unsigned int) i]; if ( c == wxT('#') ) l2 = i + 1; if ( c == wxT('.') ) { ext = loc.Right(l2-i-1); break; } if ( (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':')) ) return wxEmptyString; } #if wxUSE_MIMETYPE static bool s_MinimalMimeEnsured = false; if (!s_MinimalMimeEnsured) { static const wxFileTypeInfo fallbacks[] = { wxFileTypeInfo(_T("image/jpeg"), wxEmptyString, wxEmptyString, _T("JPEG image (from fallback)"), _T("jpg"), _T("jpeg"), _T("JPG"), _T("JPEG"), NULL), wxFileTypeInfo(_T("image/gif"), wxEmptyString, wxEmptyString, _T("GIF image (from fallback)"), _T("gif"), _T("GIF"), NULL), wxFileTypeInfo(_T("image/png"), wxEmptyString, wxEmptyString, _T("PNG image (from fallback)"), _T("png"), _T("PNG"), NULL), wxFileTypeInfo(_T("image/bmp"), wxEmptyString, wxEmptyString, _T("windows bitmap image (from fallback)"), _T("bmp"), _T("BMP"), NULL), wxFileTypeInfo(_T("text/html"), wxEmptyString, wxEmptyString, _T("HTML document (from fallback)"), _T("htm"), _T("html"), _T("HTM"), _T("HTML"), NULL), // must terminate the table with this! wxFileTypeInfo() }; wxTheMimeTypesManager->AddFallbacks(fallbacks); s_MinimalMimeEnsured = true; } wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); if ( !ft || !ft -> GetMimeType(&mime) ) { mime = wxEmptyString; } delete ft; return mime; #else if ( ext.IsSameAs(wxT("htm"), false) || ext.IsSameAs(_T("html"), false) ) return wxT("text/html"); if ( ext.IsSameAs(wxT("jpg"), false) || ext.IsSameAs(_T("jpeg"), false) ) return wxT("image/jpeg"); if ( ext.IsSameAs(wxT("gif"), false) ) return wxT("image/gif"); if ( ext.IsSameAs(wxT("png"), false) ) return wxT("image/png"); if ( ext.IsSameAs(wxT("bmp"), false) ) return wxT("image/bmp"); return wxEmptyString; #endif }
wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags) { wxFileName fn = wxFileSystem::URLToFileName(GetRightLocation(spec)); return wxFindFirstFile(ms_root + fn.GetFullPath(), flags); }