filesys.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 565 行 · 第 1/2 页

CPP
565
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        filesys.cpp
// Purpose:     wxFileSystem class - interface for opening files
// Author:      Vaclav Slavik
// Copyright:   (c) 1999 Vaclav Slavik
// CVS-ID:      $Id: filesys.cpp,v 1.60 2005/02/01 19:37:35 ABX Exp $
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "filesys.h"
#endif

#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif


#if wxUSE_FILESYSTEM

#include "wx/wfstream.h"
#include "wx/module.h"
#include "wx/filesys.h"
#include "wx/mimetype.h"
#include "wx/filename.h"
#include "wx/log.h"


//--------------------------------------------------------------------------------
// wxFileSystemHandler
//--------------------------------------------------------------------------------

IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler, wxObject)


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 wxFileSystemHandler::GetProtocol(const wxString& location) const
{
    wxString s = wxEmptyString;
    int i, l = location.Length();
    bool fnd = false;

    for (i = l-1; (i >= 0) && ((location[i] != wxT('#')) || (!fnd)); i--) {
        if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = true;
    }
    if (!fnd) return wxT("file");
    for (++i; (i < l) && (location[i] != wxT(':')); i++) s << location[i];
    return s;
}


wxString wxFileSystemHandler::GetLeftLocation(const wxString& location) const
{
    int i;
    bool fnd = false;

    for (i = location.Length()-1; i >= 0; i--) {
        if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = true;
        else if (fnd && (location[i] == wxT('#'))) return location.Left(i);
    }
    return wxEmptyString;
}

wxString wxFileSystemHandler::GetRightLocation(const wxString& location) const
{
    int i, l = location.Length();
    int l2 = l + 1;

    for (i = l-1;
         (i >= 0) &&
         ((location[i] != wxT(':')) || (i == 1) || (location[i-2] == wxT(':')));
         i--)
    {
        if (location[i] == wxT('#')) l2 = i + 1;
    }
    if (i == 0) return wxEmptyString;
    else return location.Mid(i + 1, l2 - i - 2);
}

wxString wxFileSystemHandler::GetAnchor(const wxString& location) const
{
    wxChar c;
    int l = location.Length();

    for (int i = l-1; i >= 0; i--) {
        c = location[i];
        if (c == wxT('#')) return location.Right(l-i-1);
        else if ((c == wxT('.')) || (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':'))) return wxEmptyString;
    }
    return wxEmptyString;
}


wxString wxFileSystemHandler::FindFirst(const wxString& WXUNUSED(spec),
                                        int WXUNUSED(flags))
{
    return wxEmptyString;
}

wxString wxFileSystemHandler::FindNext()
{
    return wxEmptyString;
}

//--------------------------------------------------------------------------------
// wxLocalFSHandler
//--------------------------------------------------------------------------------


wxString wxLocalFSHandler::ms_root;

bool wxLocalFSHandler::CanOpen(const wxString& location)
{
    return GetProtocol(location) == wxT("file");
}

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 wxLocalFSHandler::FindFirst(const wxString& spec, int flags)
{
    wxFileName fn = wxFileSystem::URLToFileName(GetRightLocation(spec));
    return wxFindFirstFile(ms_root + fn.GetFullPath(), flags);
}

wxString wxLocalFSHandler::FindNext()
{
    return wxFindNextFile();
}



//-----------------------------------------------------------------------------
// wxFileSystem
//-----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS(wxFileSystem, wxObject)
IMPLEMENT_ABSTRACT_CLASS(wxFSFile, wxObject)


wxList wxFileSystem::m_Handlers;


static wxString MakeCorrectPath(const wxString& path)
{
    wxString p(path);
    wxString r;
    int i, j, cnt;

    cnt = p.Length();
    for (i = 0; i < cnt; i++)
      if (p.GetChar(i) == wxT('\\')) p.GetWritableChar(i) = wxT('/'); // Want to be windows-safe

    if (p.Left(2) == wxT("./")) { p = p.Mid(2); cnt -= 2; }

    if (cnt < 3) return p;

    r << p.GetChar(0) << p.GetChar(1);

    // skip trailing ../.., if any
    for (i = 2; i < cnt && (p.GetChar(i) == wxT('/') || p.GetChar(i) == wxT('.')); i++) r << p.GetChar(i);

    // remove back references: translate dir1/../dir2 to dir2
    for (; i < cnt; i++)
    {
        r << p.GetChar(i);
        if (p.GetChar(i) == wxT('/') && p.GetChar(i-1) == wxT('.') && p.GetChar(i-2) == wxT('.'))
        {
            for (j = r.Length() - 2; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
            if (j >= 0 && r.GetChar(j) != wxT(':'))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?