m_linesTail = NULL;
// read the entire stream contents in memory
- wxString str;
- {
- static const size_t chunkLen = 1024;
+ wxWxCharBuffer cbuf;
+ static const size_t chunkLen = 1024;
- wxMemoryBuffer buf(chunkLen);
- do
- {
- inStream.Read(buf.GetAppendBuf(chunkLen), chunkLen);
- buf.UngetAppendBuf(inStream.LastRead());
+ wxMemoryBuffer buf(chunkLen);
+ do
+ {
+ inStream.Read(buf.GetAppendBuf(chunkLen), chunkLen);
+ buf.UngetAppendBuf(inStream.LastRead());
- const wxStreamError err = inStream.GetLastError();
+ const wxStreamError err = inStream.GetLastError();
- if ( err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF )
- {
- wxLogError(_("Error reading config options."));
- break;
- }
+ if ( err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF )
+ {
+ wxLogError(_("Error reading config options."));
+ break;
}
- while ( !inStream.Eof() );
+ }
+ while ( !inStream.Eof() );
#if wxUSE_UNICODE
- size_t len;
- str = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen(), &len);
- if ( !len && buf.GetDataLen() )
- {
- wxLogError(_("Failed to read config options."));
- }
+ size_t len;
+ cbuf = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen(), &len);
+ if ( !len && buf.GetDataLen() )
+ {
+ wxLogError(_("Failed to read config options."));
+ }
#else // !wxUSE_UNICODE
- // no need for conversion
- str.assign((char *)buf.GetData(), buf.GetDataLen());
+ // no need for conversion
+ cbuf = wxCharBuffer::CreateNonOwned((char *)buf.GetData());
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
- }
- // translate everything to the current (platform-dependent) line
- // termination character
- str = wxTextBuffer::Translate(str);
-
+ // now break it into lines
wxMemoryText memText;
-
- // Now we can add the text to the memory text. To do this we extract line
- // by line from the translated string, until we've reached the end.
- //
- // VZ: all this is horribly inefficient, we should do the translation on
- // the fly in one pass saving both memory and time (TODO)
-
- const wxChar *pEOL = wxTextBuffer::GetEOL(wxTextBuffer::typeDefault);
- const size_t EOLLen = wxStrlen(pEOL);
-
- int posLineStart = str.Find(pEOL);
- while ( posLineStart != -1 )
+ for ( const wxChar *s = cbuf; ; ++s )
{
- wxString line(str.Left(posLineStart));
+ const wxChar *e = s;
+ while ( *e != '\0' && *e != '\n' && *e != '\r' )
+ ++e;
- memText.AddLine(line);
+ // notice that we throw away the original EOL kind here, maybe we
+ // should preserve it?
+ memText.AddLine(wxString(s, e));
- str = str.Mid(posLineStart + EOLLen);
+ if ( *e == '\0' )
+ break;
- posLineStart = str.Find(pEOL);
- }
+ // skip the second EOL byte if it's a DOS one
+ if ( *e == '\r' && e[1] == '\n' )
+ ++e;
- // also add whatever we have left in the translated string.
- if ( !str.empty() )
- memText.AddLine(str);
+ s = e;
+ }
// Finally we can parse it all.
Parse(memText, true /* local */);
// undo FilterOutValue
static wxString FilterInValue(const wxString& str)
{
- wxString strResult;
- strResult.Alloc(str.Len());
+ wxString strResult;
+ if ( str.empty() )
+ return strResult;
- bool bQuoted = !str.empty() && str[0] == '"';
+ strResult.reserve(str.length());
- for ( size_t n = bQuoted ? 1 : 0; n < str.Len(); n++ ) {
- if ( str[n] == wxT('\\') ) {
- switch ( str[++n].GetValue() ) {
- case wxT('n'):
- strResult += wxT('\n');
- break;
+ wxString::const_iterator i = str.begin();
+ const bool bQuoted = *i == '"';
+ if ( bQuoted )
+ ++i;
- case wxT('r'):
- strResult += wxT('\r');
- break;
+ for ( const wxString::const_iterator end = str.end(); i != end; ++i )
+ {
+ if ( *i == wxT('\\') )
+ {
+ if ( ++i == end )
+ {
+ wxLogWarning(_("trailing backslash ignored in '%s'"), str.c_str());
+ break;
+ }
- case wxT('t'):
- strResult += wxT('\t');
- break;
+ switch ( (*i).GetValue() )
+ {
+ case wxT('n'):
+ strResult += wxT('\n');
+ break;
- case wxT('\\'):
- strResult += wxT('\\');
- break;
+ case wxT('r'):
+ strResult += wxT('\r');
+ break;
- case wxT('"'):
- strResult += wxT('"');
- break;
- }
- }
- else {
- if ( str[n] != wxT('"') || !bQuoted )
- strResult += str[n];
- else if ( n != str.Len() - 1 ) {
- wxLogWarning(_("unexpected \" at position %d in '%s'."),
- n, str.c_str());
- }
- //else: it's the last quote of a quoted string, ok
+ case wxT('t'):
+ strResult += wxT('\t');
+ break;
+
+ case wxT('\\'):
+ strResult += wxT('\\');
+ break;
+
+ case wxT('"'):
+ strResult += wxT('"');
+ break;
+ }
+ }
+ else // not a backslash
+ {
+ if ( *i != wxT('"') || !bQuoted )
+ {
+ strResult += *i;
+ }
+ else if ( i != end - 1 )
+ {
+ wxLogWarning(_("unexpected \" at position %d in '%s'."),
+ i - str.begin(), str.c_str());
+ }
+ //else: it's the last quote of a quoted string, ok
+ }
}
- }
- return strResult;
+ return strResult;
}
// quote the string before writing it to file