Merge branch 'temp-ffile'
Add wxTempFFile class. Closes #18673. See https://github.com/wxWidgets/wxWidgets/pull/1739
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user