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
This commit is contained in:
Vadim Zeitlin
2006-03-27 23:27:29 +00:00
parent 4ae776b767
commit 86948c99a6

View File

@@ -88,39 +88,52 @@ bool wxTextFile::OnClose()
bool wxTextFile::OnRead(wxMBConv& conv) bool wxTextFile::OnRead(wxMBConv& conv)
{ {
// file should be opened and we must be in it's beginning // 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 buf[1025];
char ch, chLast = '\0'; wxChar chLast = '\0';
char buf[1024]; wxString str;
size_t nRead;
strPtr = strBuf = new char[1024]; for ( ;; )
strEnd = strBuf + 1024;
do
{ {
nRead = m_file.Read(buf, WXSIZEOF(buf)); // leave space for trailing NUL
if ( nRead == (size_t)wxInvalidOffset ) ssize_t nRead = m_file.Read(buf, WXSIZEOF(buf) - 1);
if ( nRead == wxInvalidOffset )
{ {
// read error (error message already given in wxFile::Read) // read error (error message already given in wxFile::Read)
delete[] strBuf;
return false; 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 ) switch ( ch )
{ {
case '\n': case '\n':
// Dos/Unix line termination // could be a DOS or Unix EOL
*strPtr = '\0'; if ( chLast == '\r' )
AddLine(wxString(strBuf, conv), {
chLast == '\r' ? wxTextFileType_Dos AddLine(wxString(lineStart, p - 1), wxTextFileType_Dos);
: wxTextFileType_Unix); }
strPtr = strBuf; else // bare '\n', Unix style
chLast = '\n'; {
AddLine(wxString(lineStart, p), wxTextFileType_Unix);
}
lineStart = p + 1;
break; break;
case '\r': case '\r':
@@ -128,50 +141,34 @@ bool wxTextFile::OnRead(wxMBConv& conv)
{ {
// Mac empty line // Mac empty line
AddLine(wxEmptyString, wxTextFileType_Mac); AddLine(wxEmptyString, wxTextFileType_Mac);
lineStart = p + 1;
} }
else //else: we don't what this is yet -- could be a Mac EOL or
chLast = '\r'; // start of DOS EOL so wait for next char
break; break;
default: default:
if ( chLast == '\r' ) if ( chLast == '\r' )
{ {
// Mac line termination // Mac line termination
*strPtr = '\0'; AddLine(wxString(lineStart, p - 1), wxTextFileType_Mac);
AddLine(wxString(strBuf, conv), wxTextFileType_Mac); lineStart = p;
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? chLast = ch;
if ( strPtr != strBuf ) }
{
*strPtr = '\0'; // remove the part we already processed
AddLine(wxString(strBuf, conv), str.erase(0, lineStart - str.begin());
wxTextFileType_None); // no line terminator }
// anything in the last line?
if ( !str.empty() )
{
AddLine(str, wxTextFileType_None); // no line terminator
} }
delete[] strBuf;
return true; return true;
} }