22 #include <QtCore/QStringList> 
   23 #include <QtCore/QTextCodec> 
   24 #include <QtCore/QTextStream> 
   32 class QCsvReader::Private
 
   36       : mBuilder( builder ), mNotTerminated( true )
 
   38       mTextQuote = QLatin1Char( 
'"' );
 
   39       mDelimiter = QLatin1Char( 
' ' );
 
   41       mCodec = QTextCodec::codecForLocale();
 
   44     void emitBeginLine( uint row );
 
   45     void emitEndLine( uint row );
 
   46     void emitField( 
const QString &data, 
int row, 
int column );
 
   57 void QCsvReader::Private::emitBeginLine( uint row )
 
   59   if ( ( row - mStartRow ) > 0 ) {
 
   64 void QCsvReader::Private::emitEndLine( uint row )
 
   66   if ( ( row - mStartRow ) > 0 ) {
 
   71 void QCsvReader::Private::emitField( 
const QString &data, 
int row, 
int column )
 
   73   if ( ( row - mStartRow ) > 0 ) {
 
   74     mBuilder->field( data, row - mStartRow - 1, column - 1 );
 
   79   : d( new Private( builder ) )
 
  103   State currentState = StartLine;
 
  107   d->mBuilder->begin();
 
  109   if ( !device->isOpen() ) {
 
  110     d->emitBeginLine( row );
 
  111     d->mBuilder->error( i18n(
"Device is not open") );
 
  112     d->emitEndLine( row );
 
  117   QTextStream inputStream( device );
 
  118   inputStream.setCodec( d->mCodec );
 
  151   while ( !inputStream.atEnd() && d->mNotTerminated ) {
 
  152     inputStream >> input;
 
  154     switch ( currentState ) {
 
  156         if ( input == QLatin1Char( 
'\r' ) || input == QLatin1Char( 
'\n' ) ) {
 
  157           currentState = StartLine;
 
  158         } 
else if ( input == d->mTextQuote ) {
 
  159           d->emitBeginLine( row );
 
  160           currentState = QuotedField;
 
  161         } 
else if ( input == d->mDelimiter ) {
 
  162           d->emitBeginLine( row );
 
  163           d->emitField( field, row, column );
 
  165           currentState = EmptyField;
 
  167           d->emitBeginLine( row );
 
  168           field.append( input );
 
  169           currentState = NormalField;
 
  173         if ( input == QLatin1Char( 
'\r' ) || input == QLatin1Char( 
'\n' ) ) {
 
  174           field.append( input );
 
  175           currentState = QuotedField;
 
  176         } 
else if ( input == d->mTextQuote ) {
 
  177           currentState = QuotedFieldEnd;
 
  178         } 
else if ( input == d->mDelimiter ) {
 
  179           field.append( input );
 
  180           currentState = QuotedField;
 
  182           field.append( input );
 
  183           currentState = QuotedField;
 
  187         if ( input == QLatin1Char( 
'\r' ) || input == QLatin1Char( 
'\n' ) ) {
 
  188           d->emitField( field, row, column );
 
  190           d->emitEndLine( row );
 
  193           currentState = StartLine;
 
  194         } 
else if ( input == d->mTextQuote ) {
 
  195           field.append( input );
 
  196           currentState = QuotedField;
 
  197         } 
else if ( input == d->mDelimiter ) {
 
  198           d->emitField( field, row, column );
 
  201           currentState = EmptyField;
 
  203           d->emitField( field, row, column );
 
  206           field.append( input );
 
  207           currentState = EmptyField;
 
  211         if ( input == QLatin1Char( 
'\r' ) || input == QLatin1Char( 
'\n' ) ) {
 
  212           d->emitField( field, row, column );
 
  214           d->emitEndLine( row );
 
  217           currentState = StartLine;
 
  218         } 
else if ( input == d->mTextQuote ) {
 
  219           field.append( input );
 
  220           currentState = NormalField;
 
  221         } 
else if ( input == d->mDelimiter ) {
 
  222           d->emitField( field, row, column );
 
  225           currentState = EmptyField;
 
  227           field.append( input );
 
  228           currentState = NormalField;
 
  232         if ( input == QLatin1Char( 
'\r' ) || input == QLatin1Char( 
'\n' ) ) {
 
  233           d->emitField( QString(), row, column );
 
  235           d->emitEndLine( row );
 
  238           currentState = StartLine;
 
  239         } 
else if ( input == d->mTextQuote ) {
 
  240           currentState = QuotedField;
 
  241         } 
else if ( input == d->mDelimiter ) {
 
  242           d->emitField( QString(), row, column );
 
  244           currentState = EmptyField;
 
  246           field.append( input );
 
  247           currentState = NormalField;
 
  253   if ( currentState != StartLine ) {
 
  254     if ( field.length() > 0 ) {
 
  255       d->emitField( field, row, column );
 
  259     d->emitEndLine( row );
 
  274   return d->mTextQuote;
 
  284   return d->mDelimiter;
 
  309   d->mNotTerminated = 
false;
 
  312 class QCsvStandardBuilder::Private
 
  322     QString mLastErrorString;
 
  325     QList<QStringList> mRows;
 
  328 void QCsvStandardBuilder::Private::init()
 
  333   mLastErrorString.clear();
 
  348   return d->mLastErrorString;
 
  358   return d->mColumnCount;
 
  363   if ( row > d->mRowCount || column > d->mColumnCount || column >= (uint)d->mRows[ row ].count() ) {
 
  367   return d->mRows[ row ][ column ];
 
  377   d->mRows.append( QStringList() );
 
  383   const uint size = d->mRows[ row ].size();
 
  384   if ( column >= size ) {
 
  385     for ( uint i = column; i < size + 1; ++i ) {
 
  386       d->mRows[ row ].append( QString() );
 
  390   d->mRows[ row ][ column ] = 
data;
 
  392   d->mColumnCount = qMax( d->mColumnCount, column + 1 );
 
  405   d->mLastErrorString = errorMsg;
 
  408 #include "qcsvreader.moc" 
void setTextCodec(QTextCodec *textCodec)
Sets the text codec that shall be used for parsing the csv list. 
 
virtual void beginLine()=0
This method is called whenever a new line starts. 
 
~QCsvStandardBuilder()
Destroys the csv standard builder. 
 
void endLine()
This method is called whenever a line ends. 
 
~QCsvReader()
Destroys the csv reader. 
 
QString data(uint row, uint column) const 
Returns the data of the field at the given row and column. 
 
void beginLine()
This method is called whenever a new line starts. 
 
virtual ~QCsvBuilderInterface()
This method is called on the destruction of the interface. 
 
void setDelimiter(const QChar &delimiter)
Sets the character that is used as delimiter for fields. 
 
void setTextQuote(const QChar &textQuote)
Sets the character that is used for quoting. 
 
void setStartRow(uint startRow)
Sets the row from where the parsing shall be started. 
 
void terminate()
Terminates the parsing of the csv data. 
 
QChar textQuote() const 
Returns the character that is used for quoting. 
 
uint rowCount() const 
Returns the number of rows. 
 
bool read(QIODevice *device)
Parses the csv data from device. 
 
void error(const QString &errorMsg)
This method is called whenever an error occurs during parsing. 
 
QChar delimiter() const 
Returns the delimiter that is used as delimiter for fields. 
 
void end()
This method is called at the end of parsing. 
 
void field(const QString &data, uint row, uint column)
This method is called for every parsed field. 
 
uint startRow() const 
Returns the start row. 
 
An interface to build data structures from a CSV file. 
 
QString lastErrorString() const 
Returns the error message of the last error. 
 
QCsvStandardBuilder()
Creates a new csv standard builder. 
 
QTextCodec * textCodec() const 
Returns the text codec that is used for parsing the csv list. 
 
QCsvReader(QCsvBuilderInterface *builder)
Creates a new csv reader. 
 
uint columnCount() const 
Returns the number of columns.