fully implement nul termination for LINE_READER::ReadLine()
This commit is contained in:
parent
c3924e6fc9
commit
27a02d3226
|
@ -86,10 +86,11 @@ void DSNLEXER::PushReader( LINE_READER* aLineReader )
|
|||
{
|
||||
readerStack.push_back( aLineReader );
|
||||
reader = aLineReader;
|
||||
start = (char*) (*reader);
|
||||
|
||||
// force a new readLine() as first thing.
|
||||
limit = start();
|
||||
next = start();
|
||||
limit = start;
|
||||
next = start;
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,10 +102,11 @@ bool DSNLEXER::PopReader()
|
|||
readerStack.pop_back();
|
||||
|
||||
reader = &readerStack.back();
|
||||
start = (char*) (*reader);
|
||||
|
||||
// force a new readLine() as first thing.
|
||||
limit = start();
|
||||
next = start();
|
||||
limit = start;
|
||||
next = start;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -331,7 +333,7 @@ L_read:
|
|||
goto exit;
|
||||
}
|
||||
|
||||
cur = start();
|
||||
cur = start;
|
||||
|
||||
// skip leading whitespace
|
||||
while( cur<limit && isSpace(*cur) )
|
||||
|
@ -345,8 +347,8 @@ L_read:
|
|||
{
|
||||
// save the entire line, including new line as the current token.
|
||||
// the '#' character may not be at offset zero.
|
||||
curText = start(); // entire line is the token
|
||||
cur = start(); // ensure a good curOffset below
|
||||
curText = start; // entire line is the token
|
||||
cur = start; // ensure a good curOffset below
|
||||
curTok = DSN_COMMENT;
|
||||
head = limit; // do a readLine() on next call in here.
|
||||
goto exit;
|
||||
|
@ -414,7 +416,7 @@ L_read:
|
|||
like: U2-14 or "U2"-"14"
|
||||
This is detectable by a non-space immediately preceeding the dash.
|
||||
*/
|
||||
if( *cur == '-' && cur>start() && !isSpace( cur[-1] ) )
|
||||
if( *cur == '-' && cur>start && !isSpace( cur[-1] ) )
|
||||
{
|
||||
curText = '-';
|
||||
curTok = DSN_DASH;
|
||||
|
@ -535,7 +537,7 @@ L_read:
|
|||
|
||||
exit: // single point of exit, no returns elsewhere please.
|
||||
|
||||
curOffset = cur - start();
|
||||
curOffset = cur - start;
|
||||
|
||||
next = head;
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength )
|
|||
capacity = LINE_READER_LINE_INITIAL_SIZE;
|
||||
|
||||
// but never go above user's aMaxLineLength, and leave space for trailing nul
|
||||
if( capacity > aMaxLineLength-1 )
|
||||
capacity = aMaxLineLength-1;
|
||||
if( capacity > aMaxLineLength+1 )
|
||||
capacity = aMaxLineLength+1;
|
||||
|
||||
line = new char[capacity];
|
||||
|
||||
|
@ -71,9 +71,10 @@ void LINE_READER::expandCapacity( unsigned newsize )
|
|||
// resize the buffer, and copy the original data
|
||||
char* bigger = new char[capacity];
|
||||
|
||||
wxASSERT( capacity >= length );
|
||||
wxASSERT( capacity >= length+1 );
|
||||
|
||||
memcpy( bigger, line, length );
|
||||
bigger[length] = 0;
|
||||
|
||||
delete[] line;
|
||||
line = bigger;
|
||||
|
@ -102,8 +103,8 @@ unsigned FILE_LINE_READER::ReadLine() throw (IOError)
|
|||
if( length == maxLineLength )
|
||||
throw IOError( _("Line length exceeded") );
|
||||
|
||||
// a normal line breaks here, once through
|
||||
if( length < capacity-1 || line[length-1] == '\n' )
|
||||
// a normal line breaks here, once through while loop
|
||||
if( length+1 < capacity || line[length-1] == '\n' )
|
||||
break;
|
||||
|
||||
expandCapacity( capacity * 2 );
|
||||
|
@ -130,12 +131,13 @@ unsigned STRING_LINE_READER::ReadLine() throw (IOError)
|
|||
if( length >= maxLineLength )
|
||||
throw IOError( _("Line length exceeded") );
|
||||
|
||||
if( length > capacity )
|
||||
expandCapacity( length );
|
||||
if( length+1 > capacity )
|
||||
expandCapacity( length+1 );
|
||||
|
||||
wxASSERT( ndx + length <= lines.length() );
|
||||
|
||||
memcpy( line, &source[ndx], length );
|
||||
line[length] = 0;
|
||||
|
||||
++lineNum;
|
||||
ndx += length;
|
||||
|
|
|
@ -78,6 +78,7 @@ enum DSN_SYNTAX_T {
|
|||
*/
|
||||
class DSNLEXER
|
||||
{
|
||||
char* start;
|
||||
char* next;
|
||||
char* limit;
|
||||
|
||||
|
@ -99,20 +100,17 @@ class DSNLEXER
|
|||
const KEYWORD* keywords;
|
||||
unsigned keywordCount;
|
||||
|
||||
/// Use casting char* operator to get start of line, which is dynamic since reader
|
||||
/// can be resizing its buffer at each reader->ReadLine() only.
|
||||
char* start() const { return (char*) (*reader); }
|
||||
|
||||
void init();
|
||||
|
||||
int readLine() throw (IOError)
|
||||
{
|
||||
unsigned len = reader->ReadLine();
|
||||
|
||||
// set next and limit to start() and start() + len.
|
||||
// start() is constant until the next ReadLine(), which could resize and
|
||||
// start may have changed in ReadLine(), which can resize and
|
||||
// relocate reader's line buffer.
|
||||
next = start();
|
||||
start = (*reader);
|
||||
|
||||
next = start;
|
||||
limit = next + len;
|
||||
|
||||
return len;
|
||||
|
|
|
@ -101,12 +101,12 @@ public:
|
|||
/**
|
||||
* Function ReadLine
|
||||
* reads a line of text into the buffer and increments the line number
|
||||
* counter. If the line is larger than the buffer size, then an exception
|
||||
* is thrown.
|
||||
* counter. If the line is larger than aMaxLineLength passed to the
|
||||
* constructor, then an exception is thrown. The line is nul terminated.
|
||||
* @return unsigned - The number of bytes read, 0 at end of file.
|
||||
* @throw IOError only when a line is too long.
|
||||
* @throw IOError when a line is too long.
|
||||
*/
|
||||
virtual unsigned ReadLine() throw (IOError) = 0;
|
||||
virtual unsigned ReadLine() throw( IOError ) = 0;
|
||||
|
||||
/**
|
||||
* Function GetSource
|
||||
|
@ -160,7 +160,7 @@ class FILE_LINE_READER : public LINE_READER
|
|||
{
|
||||
protected:
|
||||
|
||||
FILE* fp; ///< I own this file
|
||||
FILE* fp; ///< I own this file
|
||||
|
||||
public:
|
||||
|
||||
|
@ -181,15 +181,7 @@ public:
|
|||
fclose( fp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ReadLine
|
||||
* reads a line of text into the buffer and increments the line number
|
||||
* counter. If the line is larger than the buffer size, then an exception
|
||||
* is thrown.
|
||||
* @return unsigned - The number of bytes read, 0 at end of file.
|
||||
* @throw IOError only when a line is too long.
|
||||
*/
|
||||
unsigned ReadLine() throw (IOError);
|
||||
unsigned ReadLine() throw( IOError ); // see LINE_READER::ReadLine() description
|
||||
|
||||
/**
|
||||
* Function Rewind
|
||||
|
@ -217,34 +209,26 @@ protected:
|
|||
public:
|
||||
|
||||
/**
|
||||
* Constructor STRING_LINE_READER( const std::string& aString )
|
||||
* Constructor STRING_LINE_READER( const std::string&, const wxString& )
|
||||
*
|
||||
* @param aString is a source string consisting of one or more lines
|
||||
* of text, where multiple lines are separated with a '\n' character.
|
||||
* The last line does not necessarily need a trailing '\n'.
|
||||
*
|
||||
* @param aSource describes the source of aString for error reporting purposes
|
||||
* can be anything meaninful, such as wxT( "cliboard" ).
|
||||
*/
|
||||
STRING_LINE_READER( const std::string& aString, const wxString& aSource ) :
|
||||
LINE_READER( 4096 ),
|
||||
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
|
||||
lines( aString ),
|
||||
ndx( 0 )
|
||||
{
|
||||
// Clipboard text should be nice and _use multiple lines_ so that
|
||||
// we can report _line number_ oriented error messages when parsing.
|
||||
// Therefore a line of 4096 characters max seems more than adequate.
|
||||
source = aSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ReadLine
|
||||
* reads a line of text into the buffer and increments the line number
|
||||
* counter. If the line is larger than the buffer size, then an exception
|
||||
* is thrown.
|
||||
* @return unsigned - The number of bytes read, 0 at end of file.
|
||||
* @throw IOError only when a line is too long.
|
||||
*/
|
||||
unsigned ReadLine() throw (IOError);
|
||||
unsigned ReadLine() throw(IOError); // see LINE_READER::ReadLine() description
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue