From: Vadim Zeitlin Date: Mon, 27 Mar 2006 23:27:29 +0000 (+0000) Subject: made wxTextFile work in Unicode; also made it possible to use it with non seekable... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/86948c99a6f0fd177b09b3db0ef702739ec62a27 made wxTextFile work in Unicode; also made it possible to use it with non seekable files git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38399 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/textfile.cpp b/src/common/textfile.cpp index 8a47c35e39..b7ab9e06ca 100644 --- a/src/common/textfile.cpp +++ b/src/common/textfile.cpp @@ -88,39 +88,52 @@ 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 ); + wxASSERT( m_file.IsOpened() && + (m_file.GetKind() != wxFILE_KIND_DISK || m_file.Tell() == 0) ); - char *strBuf, *strPtr, *strEnd; - char ch, chLast = '\0'; - char buf[1024]; - size_t nRead; + char buf[1025]; + wxChar chLast = '\0'; + wxString str; - strPtr = strBuf = new char[1024]; - strEnd = strBuf + 1024; - - do + for ( ;; ) { - nRead = m_file.Read(buf, WXSIZEOF(buf)); - if ( nRead == (size_t)wxInvalidOffset ) + // leave space for trailing NUL + ssize_t nRead = m_file.Read(buf, WXSIZEOF(buf) - 1); + + if ( nRead == wxInvalidOffset ) { // read error (error message already given in wxFile::Read) - delete[] strBuf; return false; } - for (size_t n = 0; n < nRead; n++) + if ( nRead == 0 ) + break; + + buf[nRead] = '\0'; + + // append to the remains of the last block, don't overwrite + str += wxString(buf, conv); + + // the beginning of the current line, changes inside the loop + const wxChar *lineStart = str.begin(); + const wxChar * const end = str.end(); + for ( const wxChar *p = lineStart; p != end; p++ ) { - ch = buf[n]; + const wxChar ch = *p; switch ( ch ) { case '\n': - // Dos/Unix line termination - *strPtr = '\0'; - AddLine(wxString(strBuf, conv), - chLast == '\r' ? wxTextFileType_Dos - : wxTextFileType_Unix); - strPtr = strBuf; - chLast = '\n'; + // could be a DOS or Unix EOL + if ( chLast == '\r' ) + { + AddLine(wxString(lineStart, p - 1), wxTextFileType_Dos); + } + else // bare '\n', Unix style + { + AddLine(wxString(lineStart, p), wxTextFileType_Unix); + } + + lineStart = p + 1; break; case '\r': @@ -128,50 +141,34 @@ bool wxTextFile::OnRead(wxMBConv& conv) { // Mac empty line AddLine(wxEmptyString, wxTextFileType_Mac); + lineStart = p + 1; } - else - chLast = '\r'; + //else: we don't what this is yet -- could be a Mac EOL or + // start of DOS EOL so wait for next char 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; - } + AddLine(wxString(lineStart, p - 1), wxTextFileType_Mac); + lineStart = p; } } + + chLast = ch; } - } while ( nRead == WXSIZEOF(buf) ); + + // remove the part we already processed + str.erase(0, lineStart - str.begin()); + } // anything in the last line? - if ( strPtr != strBuf ) + if ( !str.empty() ) { - *strPtr = '\0'; - AddLine(wxString(strBuf, conv), - wxTextFileType_None); // no line terminator + AddLine(str, wxTextFileType_None); // no line terminator } - delete[] strBuf; return true; }