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':
{
// 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;
}