X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a1b82138efe9aacda4e0ad7ce4b1551d624524c4..c43507b0fed02bf204b524b953ce7c9794ed250f:/src/common/ffile.cpp diff --git a/src/common/ffile.cpp b/src/common/ffile.cpp index 69d1c04af8..997bf03d2b 100644 --- a/src/common/ffile.cpp +++ b/src/common/ffile.cpp @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// // Name: ffile.cpp -// Purpose: wxFFile - encapsulates "FILE *" IO stream +// Purpose: wxFFile encapsulates "FILE *" IO stream // Author: Vadim Zeitlin // Modified by: // Created: 14.07.99 // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "ffile.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,9 +24,15 @@ #pragma hdrstop #endif -#if wxUSE_FILE +#if wxUSE_FFILE #ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" +#endif + +#ifdef __WINDOWS__ +#include "wx/msw/mslu.h" #endif #include "wx/ffile.h" @@ -39,90 +41,102 @@ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// seek and tell with large file support if available +// ---------------------------------------------------------------------------- + +#ifdef HAVE_FSEEKO +# define wxFseek fseeko +# define wxFtell ftello +#else +# define wxFseek fseek +# define wxFtell ftell +#endif + // ---------------------------------------------------------------------------- // opening the file // ---------------------------------------------------------------------------- -wxFFile::wxFFile(const wxChar *filename, const char *mode) +wxFFile::wxFFile(const wxChar *filename, const wxChar *mode) { Detach(); (void)Open(filename, mode); } -bool wxFFile::Open(const wxChar *filename, const char *mode) +bool wxFFile::Open(const wxChar *filename, const wxChar *mode) { - wxASSERT_MSG( !m_fp, _T("should close or detach the old file first") ); + wxASSERT_MSG( !m_fp, wxT("should close or detach the old file first") ); - m_fp = fopen(filename, mode); + m_fp = wxFopen(filename, mode); if ( !m_fp ) { wxLogSysError(_("can't open file '%s'"), filename); - return FALSE; + return false; } m_name = filename; - return TRUE; + return true; } bool wxFFile::Close() { if ( IsOpened() ) { - if ( !fclose(m_fp) ) + if ( fclose(m_fp) != 0 ) { wxLogSysError(_("can't close file '%s'"), m_name.c_str()); - return FALSE; + return false; } Detach(); } - return TRUE; + return true; } // ---------------------------------------------------------------------------- // read/write // ---------------------------------------------------------------------------- -bool wxFFile::ReadAll(wxString *str) +bool wxFFile::ReadAll(wxString *str, const wxMBConv& conv) { - wxCHECK_MSG( str, FALSE, _T("invalid parameter") ); - wxCHECK_MSG( IsOpened(), FALSE, _T("can't read from closed file") ); + wxCHECK_MSG( str, false, wxT("invalid parameter") ); + wxCHECK_MSG( IsOpened(), false, wxT("can't read from closed file") ); + wxCHECK_MSG( Length() >= 0, false, wxT("invalid length") ); + size_t length = wx_truncate_cast(size_t, Length()); + wxCHECK_MSG( (wxFileOffset)length == Length(), false, wxT("huge file not supported") ); clearerr(m_fp); - str->Empty(); - str->Alloc(Length()); + wxCharBuffer buf(length + 1); - wxChar buf[1024]; - static const size_t nSize = WXSIZEOF(buf) - 1; // -1 for trailing '\0' - while ( !Eof() ) - { - size_t nRead = fread(buf, sizeof(wxChar), nSize, m_fp); - if ( (nRead < nSize) && Error() ) - { - wxLogSysError(_("Read error on file '%s'"), m_name.c_str()); + // note that real length may be less than file length for text files with DOS EOLs + // ('\r's get dropped by CRT when reading which means that we have + // realLen = fileLen - numOfLinesInTheFile) + length = fread(buf.data(), sizeof(char), length, m_fp); - return FALSE; - } - //else: just EOF + if ( Error() ) + { + wxLogSysError(_("Read error on file '%s'"), m_name.c_str()); - buf[nRead] = 0; - *str += buf; + return false; } - return TRUE; + buf.data()[length] = 0; + *str = wxString(buf, conv); + + return true; } size_t wxFFile::Read(void *pBuf, size_t nCount) { - wxCHECK_MSG( pBuf, FALSE, _T("invalid parameter") ); - wxCHECK_MSG( IsOpened(), FALSE, _T("can't read from closed file") ); + wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") ); + wxCHECK_MSG( IsOpened(), 0, wxT("can't read from closed file") ); size_t nRead = fread(pBuf, 1, nCount, m_fp); if ( (nRead < nCount) && Error() ) @@ -135,8 +149,8 @@ size_t wxFFile::Read(void *pBuf, size_t nCount) size_t wxFFile::Write(const void *pBuf, size_t nCount) { - wxCHECK_MSG( pBuf, FALSE, _T("invalid parameter") ); - wxCHECK_MSG( IsOpened(), FALSE, _T("can't write to closed file") ); + wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") ); + wxCHECK_MSG( IsOpened(), 0, wxT("can't write to closed file") ); size_t nWritten = fwrite(pBuf, 1, nCount, m_fp); if ( nWritten < nCount ) @@ -151,30 +165,32 @@ bool wxFFile::Flush() { if ( IsOpened() ) { - if ( !fflush(m_fp) ) + // fflush returns non-zero on error + // + if ( fflush(m_fp) ) { wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str()); - return FALSE; + return false; } } - return TRUE; + return true; } // ---------------------------------------------------------------------------- // seeking // ---------------------------------------------------------------------------- -bool wxFFile::Seek(long ofs, wxSeekMode mode) +bool wxFFile::Seek(wxFileOffset ofs, wxSeekMode mode) { - wxCHECK_MSG( IsOpened(), FALSE, _T("can't seek on closed file") ); + wxCHECK_MSG( IsOpened(), false, wxT("can't seek on closed file") ); int origin; switch ( mode ) { default: - wxFAIL_MSG(_T("unknown seek mode")); + wxFAIL_MSG(wxT("unknown seek mode")); // still fall through case wxFromStart: @@ -190,38 +206,55 @@ bool wxFFile::Seek(long ofs, wxSeekMode mode) break; } - if ( fseek(m_fp, ofs, origin) != 0 ) +#ifndef HAVE_FSEEKO + if ((long)ofs != ofs) + { + wxLogError(_("Seek error on file '%s' (large files not supported by stdio)"), m_name.c_str()); + + return false; + } + + if ( wxFseek(m_fp, (long)ofs, origin) != 0 ) +#else + if ( wxFseek(m_fp, ofs, origin) != 0 ) +#endif { wxLogSysError(_("Seek error on file '%s'"), m_name.c_str()); - return FALSE; + return false; } - return TRUE; + return true; } -size_t wxFFile::Tell() const +wxFileOffset wxFFile::Tell() const { - long rc = ftell(m_fp); - if ( rc == -1 ) + wxCHECK_MSG( IsOpened(), wxInvalidOffset, + _T("wxFFile::Tell(): file is closed!") ); + + wxFileOffset rc = wxFtell(m_fp); + if ( rc == wxInvalidOffset ) { wxLogSysError(_("Can't find current position in file '%s'"), m_name.c_str()); } - return (size_t)rc; + return rc; } -size_t wxFFile::Length() const +wxFileOffset wxFFile::Length() const { + wxCHECK_MSG( IsOpened(), wxInvalidOffset, + _T("wxFFile::Length(): file is closed!") ); + wxFFile& self = *(wxFFile *)this; // const_cast - size_t posOld = Tell(); - if ( posOld != (size_t)-1 ) + wxFileOffset posOld = Tell(); + if ( posOld != wxInvalidOffset ) { if ( self.SeekEnd() ) { - size_t len = Tell(); + wxFileOffset len = Tell(); (void)self.Seek(posOld); @@ -229,7 +262,7 @@ size_t wxFFile::Length() const } } - return (size_t)-1; + return wxInvalidOffset; } -#endif // wxUSE_FILE +#endif // wxUSE_FFILE