* DSNLEXER now owns an abstract LINE_READER by pointer so that polymorphism
    can be used in alternative LINE_READERS.
  * Write FILE_LINE_READER and STRING_LINE_READER.  The latter can be used
    to parse text coming from the clipboard or other string source.
This commit is contained in:
dickelbeck 2010-03-03 06:13:46 +00:00
parent a800351eab
commit 2decdbdd14
4 changed files with 120 additions and 26 deletions

View File

@ -4,6 +4,15 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-Mar-3 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++common
* DSNLEXER now owns an abstract LINE_READER by pointer so that polymorphism
can be used in alternative LINE_READERS.
* Write FILE_LINE_READER and STRING_LINE_READER. The latter can be used
to parse text coming from the clipboard or other string source.
2010-Feb-20 UPDATE Dick Hollenbeck <dick@softplc.com> 2010-Feb-20 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++common ++common

View File

@ -51,7 +51,7 @@ static int compare( const void* a1, const void* a2 )
DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename, DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ) const KEYWORD* aKeywordTable, unsigned aKeywordCount )
{ {
reader = new LINE_READER( aFile, 4096 ); reader = new FILE_LINE_READER( aFile, 4096 );
keywords = aKeywordTable; keywords = aKeywordTable;
keywordCount = aKeywordCount; keywordCount = aKeywordCount;

View File

@ -34,9 +34,8 @@
//-----<LINE_READER>------------------------------------------------------ //-----<LINE_READER>------------------------------------------------------
LINE_READER::LINE_READER( FILE* aFile, unsigned aMaxLineLength ) LINE_READER::LINE_READER( unsigned aMaxLineLength )
{ {
fp = aFile;
lineNum = 0; lineNum = 0;
maxLineLength = aMaxLineLength; maxLineLength = aMaxLineLength;
@ -50,7 +49,14 @@ LINE_READER::LINE_READER( FILE* aFile, unsigned aMaxLineLength )
} }
int LINE_READER::ReadLine() throw (IOError) FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, unsigned aMaxLineLength ) :
LINE_READER( aMaxLineLength )
{
fp = aFile;
}
int FILE_LINE_READER::ReadLine() throw (IOError)
{ {
const char* p = fgets( line, capacity, fp ); const char* p = fgets( line, capacity, fp );
@ -73,6 +79,35 @@ int LINE_READER::ReadLine() throw (IOError)
} }
int STRING_LINE_READER::ReadLine() throw (IOError)
{
size_t nlOffset = source.find( '\n', ndx );
size_t advance;
if( nlOffset == std::string::npos )
advance = source.length() - ndx;
else
advance = nlOffset - ndx + 1; // include the newline, so +1
if( advance )
{
if( advance >= maxLineLength )
throw IOError( _("Line length exceeded") );
wxASSERT( ndx + advance <= source.length() );
memcpy( line, &source[ndx], advance );
line[advance] = 0;
length = advance;
++lineNum;
ndx += advance;
}
return advance;
}
//-----<OUTPUTFORMATTER>---------------------------------------------------- //-----<OUTPUTFORMATTER>----------------------------------------------------

View File

@ -70,37 +70,21 @@ struct IOError
class LINE_READER class LINE_READER
{ {
protected: protected:
FILE* fp;
int lineNum;
unsigned maxLineLength;
unsigned length; unsigned length;
int lineNum;
char* line; char* line;
unsigned maxLineLength;
unsigned capacity; unsigned capacity;
public: public:
LINE_READER( unsigned aMaxLineLength );
/** virtual ~LINE_READER()
* Constructor LINE_READER
* takes an open FILE and the size of the desired line buffer.
* @param aFile An open file in "ascii" mode, not binary mode.
* @param aMaxLineLength The number of bytes to use in the line buffer.
*/
LINE_READER( FILE* aFile, unsigned aMaxLineLength );
~LINE_READER()
{ {
delete[] line; delete[] line;
} }
/*
int CharAt( int aNdx )
{
if( (unsigned) aNdx < capacity )
return (char) (unsigned char) line[aNdx];
return -1;
}
*/
/** /**
* Function ReadLine * Function ReadLine
@ -110,7 +94,7 @@ public:
* @return int - The number of bytes read, 0 at end of file. * @return int - The number of bytes read, 0 at end of file.
* @throw IOError only when a line is too long. * @throw IOError only when a line is too long.
*/ */
int ReadLine() throw (IOError); virtual int ReadLine() throw (IOError) = 0;
operator char* () operator char* ()
{ {
@ -129,6 +113,72 @@ public:
}; };
/**
* Class FILE_LINE_READER
* is a LINE_READER that reads from an open file. File must be already open
* so that this class can exist without and UI policy.
*/
class FILE_LINE_READER : public LINE_READER
{
protected:
FILE* fp; ///< no ownership, no close on destruction
public:
/**
* Constructor LINE_READER
* takes an open FILE and the size of the desired line buffer.
* @param aFile An open file in "ascii" mode, not binary mode.
* @param aMaxLineLength The number of bytes to use in the line buffer.
*/
FILE_LINE_READER( FILE* aFile, unsigned aMaxLineLength );
/**
* 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 int - The number of bytes read, 0 at end of file.
* @throw IOError only when a line is too long.
*/
int ReadLine() throw (IOError);
};
/**
* Class STRING_LINE_READER
* is a LINE_READER that reads from a multiline 8 bit wide std::string
*/
class STRING_LINE_READER : public LINE_READER
{
protected:
std::string source;
size_t ndx;
public:
STRING_LINE_READER( const std::string& aString ) :
LINE_READER( 4096 ),
source( 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.
}
/**
* 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 int - The number of bytes read, 0 at end of file.
* @throw IOError only when a line is too long.
*/
int ReadLine() throw (IOError);
};
/** /**
* Class OUTPUTFORMATTER * Class OUTPUTFORMATTER