X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9298c435cf9b3f5112de555c46c52c51f1d284bb..217c78b80b34f31b4341d6257e28077255d6eb93:/src/common/textfile.cpp diff --git a/src/common/textfile.cpp b/src/common/textfile.cpp index adf3aa659b..fd7b30c50e 100644 --- a/src/common/textfile.cpp +++ b/src/common/textfile.cpp @@ -31,13 +31,14 @@ #if wxUSE_TEXTFILE #ifndef WX_PRECOMP - #include "wx/string.h" - #include "wx/intl.h" - #include "wx/file.h" - #include "wx/log.h" + #include "wx/string.h" + #include "wx/intl.h" + #include "wx/file.h" + #include "wx/log.h" #endif #include "wx/textfile.h" +#include "wx/filename.h" // ============================================================================ // wxTextFile class implementation @@ -61,20 +62,22 @@ bool wxTextFile::OnExists() const bool wxTextFile::OnOpen(const wxString &strBufferName, wxTextBufferOpenMode OpenMode) { - wxFile::OpenMode FileOpenMode = wxFile::read; - - switch (OpenMode) - { + wxFile::OpenMode FileOpenMode; + + switch ( OpenMode ) + { + default: + wxFAIL_MSG( _T("unknown open mode in wxTextFile::Open") ); + // fall through + case ReadAccess : FileOpenMode = wxFile::read; break; + case WriteAccess : FileOpenMode = wxFile::write; break; - default : - wxASSERT(0); // Should not happen. - break; - } + } return m_file.Open(strBufferName.c_str(), FileOpenMode); } @@ -88,89 +91,106 @@ bool wxTextFile::OnClose() bool wxTextFile::OnRead(wxMBConv& conv) { - // file should be opened and we must be in it's beginning - wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 ); - -#if wxUSE_UNICODE - char conv_mbBuf[2]; - wchar_t conv_wcBuf[2]; - conv_mbBuf[1] = 0; -#else - (void)conv; -#endif - - wxString str; - char ch, chLast = '\0'; - char buf[1024]; - int n, nRead; - do { - nRead = m_file.Read(buf, WXSIZEOF(buf)); - if ( nRead == wxInvalidOffset ) { - // read error (error message already given in wxFile::Read) - return FALSE; + // file should be opened and we must be in it's beginning + wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 ); + + char *strBuf, *strPtr, *strEnd; + char ch, chLast = '\0'; + char buf[1024]; + int n, nRead; + + strPtr = strBuf = new char[1024]; + strEnd = strBuf + 1024; + + do + { + nRead = m_file.Read(buf, WXSIZEOF(buf)); + if ( nRead == wxInvalidOffset ) + { + // read error (error message already given in wxFile::Read) + delete[] strBuf; + return FALSE; + } + + for (n = 0; n < nRead; n++) + { + ch = buf[n]; + switch ( ch ) + { + case '\n': + // Dos/Unix line termination + *strPtr = '\0'; + AddLine(wxString(strBuf, conv), + chLast == '\r' ? wxTextFileType_Dos + : wxTextFileType_Unix); + strPtr = strBuf; + chLast = '\n'; + break; + + case '\r': + if ( chLast == '\r' ) + { + // Mac empty line + AddLine(wxEmptyString, wxTextFileType_Mac); + } + else + chLast = '\r'; + break; + + default: + if ( chLast == '\r' ) + { + // Mac line termination + *strPtr = '\0'; + AddLine(wxString(strBuf, conv), wxTextFileType_Mac); + chLast = ch; + strPtr = strBuf; + *(strPtr++) = ch; + } + else + { + // add to the current line + *(strPtr++) = ch; + if ( strPtr == strEnd ) + { + // we must allocate more memory + size_t size = strEnd - strBuf; + char *newBuf = new char[size + 1024]; + memcpy(newBuf, strBuf, size); + delete[] strBuf; + strBuf = newBuf; + strEnd = strBuf + size + 1024; + strPtr = strBuf + size; + } + } + } + } + } while ( nRead == WXSIZEOF(buf) ); + + // anything in the last line? + if ( strPtr != strBuf ) + { + *strPtr = '\0'; + AddLine(wxString(strBuf, conv), + wxTextFileType_None); // no line terminator } - for ( n = 0; n < nRead; n++ ) { - ch = buf[n]; - switch ( ch ) { - case '\n': - // Dos/Unix line termination - AddLine(str, chLast == '\r' ? wxTextFileType_Dos - : wxTextFileType_Unix); - str.Empty(); - chLast = '\n'; - break; - - case '\r': - if ( chLast == '\r' ) { - // Mac empty line - AddLine(wxEmptyString, wxTextFileType_Mac); - } - else - chLast = '\r'; - break; - - default: - if ( chLast == '\r' ) { - // Mac line termination - AddLine(str, wxTextFileType_Mac); - chLast = ch; -#if wxUSE_UNICODE - conv_mbBuf[0] = ch; - if (conv.MB2WC(conv_wcBuf, conv_mbBuf, 2) == (size_t)-1) - conv_wcBuf[0] = ch; - str = conv_wcBuf[0]; -#else - str = ch; -#endif - } - else { - // add to the current line -#if wxUSE_UNICODE - conv_mbBuf[0] = ch; - if (conv.MB2WC(conv_wcBuf, conv_mbBuf, 2) == (size_t)-1) - conv_wcBuf[0] = ch; - str += conv_wcBuf[0]; -#else - str += ch; -#endif - } - } - } - } while ( nRead == WXSIZEOF(buf) ); - - // anything in the last line? - if ( !str.IsEmpty() ) { - AddLine(str, wxTextFileType_None); // no line terminator - } - - return TRUE; + delete[] strBuf; + return TRUE; } bool wxTextFile::OnWrite(wxTextFileType typeNew, wxMBConv& conv) { - wxTempFile fileTmp(m_strBufferName); + wxFileName fn = m_strBufferName; + + // We do NOT want wxPATH_NORM_CASE here, or the case will not + // be preserved. + if ( !fn.IsAbsolute() ) + fn.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | + wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG); + + wxTempFile fileTmp(fn.GetFullPath()); if ( !fileTmp.IsOpened() ) { wxLogError(_("can't write buffer '%s' to disk."), m_strBufferName.c_str());