22 #include <QtCore/QStringList>
23 #include <QtCore/QTextCodec>
24 #include <QtCore/QTextStream>
26 #include <KLocalizedString>
32 class QCsvReader::Private
36 : mBuilder( builder ), mNotTerminated( true )
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 ) {
60 mBuilder->beginLine();
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 );
151 while ( !inputStream.
atEnd() && d->mNotTerminated ) {
152 inputStream >> input;
154 switch ( currentState ) {
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 );
169 currentState = NormalField;
175 currentState = QuotedField;
176 }
else if ( input == d->mTextQuote ) {
177 currentState = QuotedFieldEnd;
178 }
else if ( input == d->mDelimiter ) {
180 currentState = QuotedField;
183 currentState = QuotedField;
188 d->emitField( field, row, column );
190 d->emitEndLine( row );
193 currentState = StartLine;
194 }
else if ( input == d->mTextQuote ) {
196 currentState = QuotedField;
197 }
else if ( input == d->mDelimiter ) {
198 d->emitField( field, row, column );
201 currentState = EmptyField;
203 d->emitField( field, row, column );
207 currentState = EmptyField;
212 d->emitField( field, row, column );
214 d->emitEndLine( row );
217 currentState = StartLine;
218 }
else if ( input == d->mTextQuote ) {
220 currentState = NormalField;
221 }
else if ( input == d->mDelimiter ) {
222 d->emitField( field, row, column );
225 currentState = EmptyField;
228 currentState = NormalField;
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;
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
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 ];
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;
void setCodec(QTextCodec *codec)
void setTextCodec(QTextCodec *textCodec)
Sets the text codec that shall be used for parsing the csv list.
QString & append(QChar ch)
~QCsvStandardBuilder()
Destroys the csv standard builder.
void endLine()
This method is called whenever a line ends.
~QCsvReader()
Destroys the csv reader.
QTextCodec * codecForLocale()
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.