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.