Merge branch 'temp-ffile'

Add wxTempFFile class.

Closes #18673.

See https://github.com/wxWidgets/wxWidgets/pull/1739
This commit is contained in:
Vadim Zeitlin
2020-02-23 01:46:51 +01:00
8 changed files with 411 additions and 4 deletions

View File

@@ -31,10 +31,11 @@
#include "wx/crt.h"
#endif
#include "wx/filename.h"
#include "wx/ffile.h"
// ============================================================================
// implementation
// implementation of wxFFile
// ============================================================================
// ----------------------------------------------------------------------------
@@ -296,4 +297,105 @@ bool wxFFile::Error() const
return ferror(m_fp) != 0;
}
// ============================================================================
// implementation of wxTempFFile
// ============================================================================
// ----------------------------------------------------------------------------
// construction
// ----------------------------------------------------------------------------
wxTempFFile::wxTempFFile(const wxString& strName)
{
Open(strName);
}
bool wxTempFFile::Open(const wxString& strName)
{
// we must have an absolute filename because otherwise CreateTempFileName()
// would create the temp file in $TMP (i.e. the system standard location
// for the temp files) which might be on another volume/drive/mount and
// wxRename()ing it later to m_strName from Commit() would then fail
//
// with the absolute filename, the temp file is created in the same
// directory as this one which ensures that wxRename() may work later
wxFileName fn(strName);
if ( !fn.IsAbsolute() )
{
fn.Normalize(wxPATH_NORM_ABSOLUTE);
}
m_strName = fn.GetFullPath();
m_strTemp = wxFileName::CreateTempFileName(m_strName, &m_file);
if ( m_strTemp.empty() )
{
// CreateTempFileName() failed
return false;
}
#ifdef __UNIX__
// the temp file should have the same permissions as the original one
mode_t mode;
wxStructStat st;
if ( stat( (const char*) m_strName.fn_str(), &st) == 0 )
{
mode = st.st_mode;
}
else
{
// file probably didn't exist, just give it the default mode _using_
// user's umask (new files creation should respect umask)
mode_t mask = umask(0777);
mode = 0666 & ~mask;
umask(mask);
}
if ( chmod( (const char*) m_strTemp.fn_str(), mode) == -1 )
{
wxLogSysError(_("Failed to set temporary file permissions"));
}
#endif // Unix
return true;
}
// ----------------------------------------------------------------------------
// destruction
// ----------------------------------------------------------------------------
wxTempFFile::~wxTempFFile()
{
if ( IsOpened() )
Discard();
}
bool wxTempFFile::Commit()
{
m_file.Close();
if ( wxFile::Exists(m_strName) && wxRemove(m_strName) != 0 ) {
wxLogSysError(_("can't remove file '%s'"), m_strName.c_str());
return false;
}
if ( !wxRenameFile(m_strTemp, m_strName) ) {
wxLogSysError(_("can't commit changes to file '%s'"), m_strName.c_str());
return false;
}
return true;
}
void wxTempFFile::Discard()
{
m_file.Close();
if ( wxRemove(m_strTemp) != 0 )
{
wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str());
}
}
#endif // wxUSE_FFILE

View File

@@ -214,6 +214,33 @@ size_t wxTempFileOutputStream::OnSysWrite(const void *buffer, size_t size)
return 0;
}
// ----------------------------------------------------------------------------
// wxTempFFileOutputStream
// ----------------------------------------------------------------------------
wxTempFFileOutputStream::wxTempFFileOutputStream(const wxString& fileName)
{
m_file = new wxTempFFile(fileName);
if (!m_file->IsOpened())
m_lasterror = wxSTREAM_WRITE_ERROR;
}
wxTempFFileOutputStream::~wxTempFFileOutputStream()
{
if (m_file->IsOpened())
Discard();
delete m_file;
}
size_t wxTempFFileOutputStream::OnSysWrite(const void *buffer, size_t size)
{
if (IsOk() && m_file->Write(buffer, size))
return size;
m_lasterror = wxSTREAM_WRITE_ERROR;
return 0;
}
// ----------------------------------------------------------------------------
// wxFileStream
// ----------------------------------------------------------------------------