X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/68c97af3c39f294259ae5e16633f573ca729bfa1..40dd6c07aacaddf36c4dec2676bf04e1fc2f77f6:/src/common/textfile.cpp diff --git a/src/common/textfile.cpp b/src/common/textfile.cpp index 26053922cd..fd7b30c50e 100644 --- a/src/common/textfile.cpp +++ b/src/common/textfile.cpp @@ -91,93 +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 + // file should be opened and we must be in it's beginning + wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 ); - 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; - } + char *strBuf, *strPtr, *strEnd; + char ch, chLast = '\0'; + char buf[1024]; + int n, nRead; - 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; + strPtr = strBuf = new char[1024]; + strEnd = strBuf + 1024; - 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 - } - } + 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 } - } 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) { wxFileName fn = m_strBufferName; + + // We do NOT want wxPATH_NORM_CASE here, or the case will not + // be preserved. if ( !fn.IsAbsolute() ) - fn.Normalize(); + fn.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | + wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG); - wxTempFile fileTmp(fn.GetFullName()); + wxTempFile fileTmp(fn.GetFullPath()); if ( !fileTmp.IsOpened() ) { wxLogError(_("can't write buffer '%s' to disk."), m_strBufferName.c_str());