filename.cpp

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

CPP
2,162
字号
    }

    wxString volume, path, name, ext;
    bool hasExt;

    // do some consistency checks in debug mode: the name should be really just
    // the filename and the path should be really just a path
#ifdef __WXDEBUG__
    wxString volDummy, pathDummy, nameDummy, extDummy;

    SplitPath(fullname, &volDummy, &pathDummy, &name, &ext, &hasExt, format);

    wxASSERT_MSG( volDummy.empty() && pathDummy.empty(),
                  _T("the file name shouldn't contain the path") );

    SplitPath(fullpath, &volume, &path, &nameDummy, &extDummy, format);

    wxASSERT_MSG( nameDummy.empty() && extDummy.empty(),
                  _T("the path shouldn't contain file name nor extension") );

#else // !__WXDEBUG__
    SplitPath(fullname, NULL /* no volume */, NULL /* no path */,
                        &name, &ext, &hasExt, format);
    SplitPath(fullpath, &volume, &path, NULL, NULL, format);
#endif // __WXDEBUG__/!__WXDEBUG__

    Assign(volume, path, name, ext, hasExt, format);
}

void wxFileName::Assign(const wxString& pathOrig,
                        const wxString& name,
                        const wxString& ext,
                        wxPathFormat format)
{
    wxString volume,
             path;
    SplitVolume(pathOrig, &volume, &path, format);

    Assign(volume, path, name, ext, format);
}

void wxFileName::AssignDir(const wxString& dir, wxPathFormat format)
{
    Assign(dir, wxEmptyString, format);
}

void wxFileName::Clear()
{
    m_dirs.Clear();

    m_volume =
    m_name =
    m_ext = wxEmptyString;

    // we don't have any absolute path for now
    m_relative = true;

    // nor any extension
    m_hasExt = false;
}

/* static */
wxFileName wxFileName::FileName(const wxString& file, wxPathFormat format)
{
    return wxFileName(file, format);
}

/* static */
wxFileName wxFileName::DirName(const wxString& dir, wxPathFormat format)
{
    wxFileName fn;
    fn.AssignDir(dir, format);
    return fn;
}

// ----------------------------------------------------------------------------
// existence tests
// ----------------------------------------------------------------------------

bool wxFileName::FileExists() const
{
    return wxFileName::FileExists( GetFullPath() );
}

bool wxFileName::FileExists( const wxString &file )
{
    return ::wxFileExists( file );
}

bool wxFileName::DirExists() const
{
    return wxFileName::DirExists( GetFullPath() );
}

bool wxFileName::DirExists( const wxString &dir )
{
    return ::wxDirExists( dir );
}

// ----------------------------------------------------------------------------
// CWD and HOME stuff
// ----------------------------------------------------------------------------

void wxFileName::AssignCwd(const wxString& volume)
{
    AssignDir(wxFileName::GetCwd(volume));
}

/* static */
wxString wxFileName::GetCwd(const wxString& volume)
{
    // if we have the volume, we must get the current directory on this drive
    // and to do this we have to chdir to this volume - at least under Windows,
    // I don't know how to get the current drive on another volume elsewhere
    // (TODO)
    wxString cwdOld;
    if ( !volume.empty() )
    {
        cwdOld = wxGetCwd();
        SetCwd(volume + GetVolumeSeparator());
    }

    wxString cwd = ::wxGetCwd();

    if ( !volume.empty() )
    {
        SetCwd(cwdOld);
    }

    return cwd;
}

bool wxFileName::SetCwd()
{
    return wxFileName::SetCwd( GetFullPath() );
}

bool wxFileName::SetCwd( const wxString &cwd )
{
    return ::wxSetWorkingDirectory( cwd );
}

void wxFileName::AssignHomeDir()
{
    AssignDir(wxFileName::GetHomeDir());
}

wxString wxFileName::GetHomeDir()
{
    return ::wxGetHomeDir();
}

#if wxUSE_FILE

void wxFileName::AssignTempFileName(const wxString& prefix, wxFile *fileTemp)
{
    wxString tempname = CreateTempFileName(prefix, fileTemp);
    if ( tempname.empty() )
    {
        // error, failed to get temp file name
        Clear();
    }
    else // ok
    {
        Assign(tempname);
    }
}

/* static */
wxString
wxFileName::CreateTempFileName(const wxString& prefix, wxFile *fileTemp)
{
    wxString path, dir, name;

    // use the directory specified by the prefix
    SplitPath(prefix, &dir, &name, NULL /* extension */);

    if (dir.empty())
    {
        dir = wxGetenv(_T("TMPDIR"));
        if (dir.empty())
        {
            dir = wxGetenv(_T("TMP"));
            if (dir.empty())
            {
                dir = wxGetenv(_T("TEMP"));
            }
        }
    }

#if defined(__WXWINCE__)
    if (dir.empty())
    {
        // FIXME. Create \temp dir?
        if (DirExists(wxT("\\temp")))
            dir = wxT("\\temp");
    }
    path = dir + wxT("\\") + name;
    int i = 1;
    while (FileExists(path))
    {
        path = dir + wxT("\\") + name ;
        path << i;
        i ++;
    }

#elif defined(__WINDOWS__) && !defined(__WXMICROWIN__)

    if ( dir.empty() )
    {
        if ( !::GetTempPath(MAX_PATH, wxStringBuffer(dir, MAX_PATH + 1)) )
        {
            wxLogLastError(_T("GetTempPath"));
        }

        if ( dir.empty() )
        {
            // GetTempFileName() fails if we pass it an empty string
            dir = _T('.');
        }
    }
    else // we have a dir to create the file in
    {
        // ensure we use only the back slashes as GetTempFileName(), unlike all
        // the other APIs, is picky and doesn't accept the forward ones
        dir.Replace(_T("/"), _T("\\"));
    }

    if ( !::GetTempFileName(dir, name, 0, wxStringBuffer(path, MAX_PATH + 1)) )
    {
        wxLogLastError(_T("GetTempFileName"));

        path.clear();
    }

#else // !Windows
    if ( dir.empty() )
    {
        // default
#if defined(__DOS__) || defined(__OS2__)
        dir = _T(".");
#elif defined(__WXMAC__)
        dir = wxMacFindFolder(short(kOnSystemDisk), kTemporaryFolderType, kCreateFolder);
#else
        dir = _T("/tmp");
#endif
    }

    path = dir;

    if ( !wxEndsWithPathSeparator(dir) &&
            (name.empty() || !wxIsPathSeparator(name[0u])) )
    {
        path += wxFILE_SEP_PATH;
    }

    path += name;

#if defined(HAVE_MKSTEMP)
    // scratch space for mkstemp()
    path += _T("XXXXXX");

    // we need to copy the path to the buffer in which mkstemp() can modify it
    wxCharBuffer buf( wxConvFile.cWX2MB( path ) );

    // cast is safe because the string length doesn't change
    int fdTemp = mkstemp( (char*)(const char*) buf );
    if ( fdTemp == -1 )
    {
        // this might be not necessary as mkstemp() on most systems should have
        // already done it but it doesn't hurt neither...
        path.clear();
    }
    else // mkstemp() succeeded
    {
        path = wxConvFile.cMB2WX( (const char*) buf );

        // avoid leaking the fd
        if ( fileTemp )
        {
            fileTemp->Attach(fdTemp);
        }
        else
        {
            close(fdTemp);
        }
    }
#else // !HAVE_MKSTEMP

#ifdef HAVE_MKTEMP
    // same as above
    path += _T("XXXXXX");

    wxCharBuffer buf = wxConvFile.cWX2MB( path );
    if ( !mktemp( (const char*) buf ) )
    {
        path.clear();
    }
    else
    {
        path = wxConvFile.cMB2WX( (const char*) buf );
    }
#else // !HAVE_MKTEMP (includes __DOS__)
    // generate the unique file name ourselves
    #if !defined(__DOS__) && !defined(__PALMOS__) && (!defined(__MWERKS__) || defined(__DARWIN__) )
    path << (unsigned int)getpid();
    #endif

    wxString pathTry;

    static const size_t numTries = 1000;
    for ( size_t n = 0; n < numTries; n++ )
    {
        // 3 hex digits is enough for numTries == 1000 < 4096
        pathTry = path + wxString::Format(_T("%.03x"), (unsigned int) n);
        if ( !FileExists(pathTry) )
        {
            break;
        }

        pathTry.clear();
    }

    path = pathTry;
#endif // HAVE_MKTEMP/!HAVE_MKTEMP

#endif // HAVE_MKSTEMP/!HAVE_MKSTEMP

#endif // Windows/!Windows

    if ( path.empty() )
    {
        wxLogSysError(_("Failed to create a temporary file name"));
    }
    else if ( fileTemp && !fileTemp->IsOpened() )
    {
        // open the file - of course, there is a race condition here, this is
        // why we always prefer using mkstemp()...
        //
        // NB: GetTempFileName() under Windows creates the file, so using
        //     write_excl there would fail
        if ( !fileTemp->Open(path,
#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
                             wxFile::write,
#else
                             wxFile::write_excl,
#endif
                             wxS_IRUSR | wxS_IWUSR) )
        {
            // FIXME: If !ok here should we loop and try again with another
            //        file name?  That is the standard recourse if open(O_EXCL)
            //        fails, though of course it should be protected against
            //        possible infinite looping too.

            wxLogError(_("Failed to open temporary file."));

            path.clear();
        }
    }

    return path;
}

#endif // wxUSE_FILE

// ----------------------------------------------------------------------------
// directory operations
// ----------------------------------------------------------------------------

bool wxFileName::Mkdir( int perm, int flags )
{
    return wxFileName::Mkdir( GetFullPath(), perm, flags );
}

bool wxFileName::Mkdir( const wxString& dir, int perm, int flags )
{
    if ( flags & wxPATH_MKDIR_FULL )
    {
        // split the path in components
        wxFileName filename;
        filename.AssignDir(dir);

        wxString currPath;
        if ( filename.HasVolume())
        {
            currPath << wxGetVolumeString(filename.GetVolume(), wxPATH_NATIVE);
        }

        wxArrayString dirs = filename.GetDirs();
        size_t count = dirs.GetCount();
        for ( size_t i = 0; i < count; i++ )
        {
            if ( i > 0 ||
#if defined(__WXMAC__) && !defined(__DARWIN__)
            // relative pathnames are exactely the other way round under mac...
                !filename.IsAbsolute()
#else
                filename.IsAbsolute()
#endif
            )
                currPath += wxFILE_SEP_PATH;
            currPath += dirs[i];

            if (!DirExists(currPath))
            {
                if (!wxMkdir(currPath, perm))
                {
                    // no need to try creating further directories
                    return false;
                }
            }
        }

        return true;

    }

    return ::wxMkdir( dir, perm );
}

bool wxFileName::Rmdir()
{
    return wxFileName::Rmdir( GetFullPath() );
}

bool wxFileName::Rmdir( const wxString &dir )
{
    return ::wxRmdir( dir );
}

// ----------------------------------------------------------------------------
// path normalization
// ----------------------------------------------------------------------------

⌨️ 快捷键说明

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