예제 #1
0
modelPoint *parsePoint()
{

	modelPoint *ret = new modelPoint();
	QString strLine = getLine();
	checkEqual(strLine, TOKOBRACE);

	strLine = getLine();
	QString connectedlines = getValue(strLine, TOKCONECTEDLINES);

	strLine = getLine();
	QString connectedextrems = getValue(strLine, TOKCONECTEDEXTREMS);

	strLine = getLine();
	//QString position=getValue(strLine,TOKPOSITION);

	strLine = getLine();
	checkEqual(strLine, TOKCBRACE);

	ret->extrems =
	    connectedextrems.split(TOKCOLON, QString::SkipEmptyParts);
	QStringList t = connectedlines.split(TOKCOLON, QString::SkipEmptyParts);
	QStringList::iterator i;
	QList < int >ls;
	for (i = t.begin(); i != t.end(); ++i)
		ls.append(i->toInt());
	ret->lines = ls;
	return ret;
}
예제 #2
0
modelLine *parseLine()
{

	modelLine *ret = new modelLine();

	QString strLine = getLine();
	checkEqual(strLine, TOKOBRACE);

	strLine = getLine();
	QString source = getValue(strLine, TOKSOURCE);

	strLine = getLine();
	QString sink = getValue(strLine, TOKSINK);

	strLine = getLine();
	//QString pointx=getValue(strLine,TOKPOINTX);

	strLine = getLine();
	//QString pointy=getValue(strLine,TOKPOINTY);

	strLine = getLine();
	checkEqual(strLine, TOKCBRACE);

	QStringList src = source.split(TOKCOLON, QString::SkipEmptyParts);
	ret->sourceType = src.takeFirst().trimmed();
	QStringList::iterator i;
	QList < int >sources;
	for (i = src.begin(); i != src.end(); ++i)
		sources.append(i->toInt());
	ret->sources = sources;

	src = sink.split(TOKCOLON, QString::SkipEmptyParts);
	ret->sinkType = src.takeFirst().trimmed();
	QList < int >sinks;
	for (i = src.begin(); i != src.end(); ++i)
		sinks.append(i->toInt());
	ret->sinks = sinks;
	return ret;

}
예제 #3
0
bool synaxErrorJudger::isAlldataTypeValid(QStringList &data,  vector<pair<int, size_t>> &dataTypeInfo)
{
	QStringList::iterator it;
	for (it = data.begin(); it != data.end(); ++it) {
		*it = it->trimmed();
		if (*it == "") {
			return false;
		}
		bool ok;
		if (it->indexOf('\'') != -1) { //引号'应该是字符或字符串
			it->remove(0, 1).remove(QRegExp("'$"));
			size_t len = it->size();
			if (len < 1 || len > 255) {
				return false;
			}
			else if (len == 1) {
				dataTypeInfo.push_back(pair<int, size_t>(_CHAR, sizeof(char)));
			}
			else {
				dataTypeInfo.push_back(pair<int, size_t>(_STRING, len * sizeof(char)));
			}
		}
		else if (it->indexOf('.') != -1) { //有小数点且不是字符串,应该是float
			it->toFloat(&ok);
			if (!ok) {
				return false;
			}
			else {
				dataTypeInfo.push_back(pair<int, size_t>(_FLOAT, sizeof(float)));
			}
		}
		else { //剩下的应该是int类型
			it->toInt(&ok);
			if (!ok) {
				return false;
			}
			else {
				dataTypeInfo.push_back(pair<int, size_t>(_INT, sizeof(int)));
			}
		}
	}
	return true;
}
예제 #4
0
void synaxErrorJudger::generateCondition()
{
	int begin = sqlExp.indexOf("where") + 5;
	int end = sqlExp.indexOf(QRegExp(";$")) - 1;
	QStringList conditions = sqlExp.mid(begin, end - begin + 1).split("and");
	QStringList::iterator it;
	pair<int, size_t> dataType;
	int logicType;
	string rightSide, leftSide;
	for (it = conditions.begin(); it != conditions.end(); ++it) {	
		*it = it->trimmed();
		if (*it == "") {
			throw QString("Synax Error: Conditions' format is incorrect.");
		}
		int begin = 0;
		int end = it->indexOf(QRegExp("[=><]"))-1;
		rightSide = it->mid(begin, end - begin + 1).trimmed().toStdString();
		begin = end + 1;
		end = it->indexOf(QRegExp("[=><]"), begin + 1);
		if (end - begin > 1 || end == -1) { //如果下一个"=",">","<"号出现在较远处
			end = begin; //说明这个逻辑关系是"=",">","<"而非">=", "<=", "<>" 
		}
		logicType = condition::getLogicTypeFromStr(it->mid(begin, end - begin + 1).toStdString());
		if (logicType == _ERROR) {
			throw QString("Synax Error: The logic arithemtic is invalid.");
		}
		bool ok;
		*it = it->mid(end + 1).trimmed();
		if (it->indexOf(QRegExp("^'")) != -1) { //引号'应该是字符或字符串
			it->remove(0, 1).remove(QRegExp("'$"));
			size_t len = it->size();
			pair<int, size_t> dType;
			Api::cManager.getAttributeDataType(*tblName, rightSide, dType);
			if (len < 1 || len > 255 || len > dType.second) {
				throw QString("Synax Error: The length of string is overflow.");
			}
			else if (len == 1) {
				dataType = pair<int, size_t>(_CHAR, sizeof(char));
			}
			else {
				dataType = pair<int, size_t>(_STRING, dType.second * sizeof(char));
			}
		}
		else if (it->indexOf('.') != -1) { //有小数点且不是字符串,应该是float
			it->toFloat(&ok);
			if (!ok) {
				;
			}
			else {
				dataType = pair<int, size_t>(_FLOAT, sizeof(float));
			}
		}
		else { //剩下的应该是int类型
			it->toInt(&ok);
			if (!ok) {
				;
			}
			else {
				dataType = pair<int, size_t>(_INT, sizeof(int));
			}
		}
		leftSide = it->toStdString();
		if (cond == 0) {
			cond = new vector<condition>;
		}
		cond->push_back(condition(rightSide, logicType, dataType, leftSide));
	}
}
예제 #5
0
void
CLArgsPrivate::parse()
{
    {
        QStringList::iterator it = hasToken( QString::fromUtf8("version"), QString::fromUtf8("v") );
        if ( it != args.end() ) {
            QString msg = QObject::tr("%1 version %2 at commit %3 on branch %4 built on %4").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ).arg( QString::fromUtf8(NATRON_VERSION_STRING) ).arg( QString::fromUtf8(GIT_COMMIT) ).arg( QString::fromUtf8(GIT_BRANCH) ).arg( QString::fromUtf8(__DATE__) );
            std::cout << msg.toStdString() << std::endl;
            error = 1;

            return;
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("help"), QString::fromUtf8("h") );
        if ( it != args.end() ) {
            CLArgs::printUsage( args[0].toStdString() );
            error = 1;

            return;
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("background"), QString::fromUtf8("b") );
        if ( it != args.end() ) {
            isBackground = true;
            args.erase(it);
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("interpreter"), QString::fromUtf8("t") );
        if ( it != args.end() ) {
            isInterpreterMode = true;
            isBackground = true;
            std::cout << QObject::tr("Note: -t argument given, loading in command-line interpreter mode, only Python commands / scripts are accepted").toStdString()
                      << std::endl;
            args.erase(it);
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("render-stats"), QString::fromUtf8("s") );
        if ( it != args.end() ) {
            enableRenderStats = true;
            args.erase(it);
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8(NATRON_BREAKPAD_PROCESS_PID), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                breakpadProcessPID = it->toLongLong();
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the breakpad process executable file path").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8(NATRON_BREAKPAD_PROCESS_EXEC), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                breakpadProcessFilePath = *it;
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the breakpad process executable file path").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8(NATRON_BREAKPAD_CLIENT_FD_ARG), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                breakpadPipeClientID = it->toInt();
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the breakpad pipe client FD").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8(NATRON_BREAKPAD_PIPE_ARG), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                breakpadPipeFilePath = *it;
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the breakpad pipe path").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8(NATRON_BREAKPAD_COM_PIPE_ARG), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                breakpadComPipeFilePath = *it;
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the breakpad communication pipe path").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("export-docs"), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                exportDocsPath = *it;
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the doc dir path").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("IPCpipe"), QString() );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                ipcPipe = *it;
                args.erase(it);
            } else {
                std::cout << QObject::tr("You must specify the IPC pipe filename").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = hasToken( QString::fromUtf8("onload"), QString::fromUtf8("l") );
        if ( it != args.end() ) {
            ++it;
            if ( it != args.end() ) {
                defaultOnProjectLoadedScript = *it;
#ifdef __NATRON_UNIX__
                defaultOnProjectLoadedScript = AppManager::qt_tildeExpansion(defaultOnProjectLoadedScript);
#endif
                QFileInfo fi(defaultOnProjectLoadedScript);
                if ( !fi.exists() ) {
                    std::cout << QObject::tr("WARNING: --onload %1 ignored because the file does not exist.").arg(defaultOnProjectLoadedScript).toStdString() << std::endl;
                    defaultOnProjectLoadedScript.clear();
                } else {
                    defaultOnProjectLoadedScript = fi.canonicalFilePath();
                }

                args.erase(it);
                if ( !defaultOnProjectLoadedScript.endsWith( QString::fromUtf8(".py") ) ) {
                    std::cout << QObject::tr("The optional on project load script must be a Python script (.py).").toStdString() << std::endl;
                    error = 1;

                    return;
                }
            } else {
                std::cout << QObject::tr("--onload or -l specified, you must enter a script filename afterwards.").toStdString() << std::endl;
                error = 1;

                return;
            }
        }
    }

    {
        QStringList::iterator it = findFileNameWithExtension( QString::fromUtf8(NATRON_PROJECT_FILE_EXT) );
        if ( it == args.end() ) {
            it = findFileNameWithExtension( QString::fromUtf8("py") );
            if ( ( it == args.end() ) && !isInterpreterMode && isBackground ) {
                std::cout << QObject::tr("You must specify the filename of a script or %1 project. (.%2)").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ).arg( QString::fromUtf8(NATRON_PROJECT_FILE_EXT) ).toStdString() << std::endl;
                error = 1;

                return;
            }
            isPythonScript = true;
        }
        if ( it != args.end() ) {
            filename = *it;
#ifdef __NATRON_UNIX__
            filename = AppManager::qt_tildeExpansion(filename);
#endif
            QFileInfo fi(filename);
            if ( fi.exists() ) {
                filename = fi.canonicalFilePath();
            }
            args.erase(it);
        }
    }

    //Parse frame range
    for (QStringList::iterator it = args.begin(); it != args.end(); ++it) {
        if ( tryParseMultipleFrameRanges(*it, frameRanges) ) {
            args.erase(it);
            rangeSet = true;
            break;
        }
    }

    //Parse python commands
    for (;; ) {
        QStringList::iterator it = hasToken( QString::fromUtf8("cmd"), QString::fromUtf8("c") );
        if ( it == args.end() ) {
            break;
        }

        if (!isBackground) {
            std::cout << QObject::tr("You cannot use the -c option in interactive mode").toStdString() << std::endl;
            error = 1;

            return;
        }

        QStringList::iterator next = it;
        if ( next != args.end() ) {
            ++next;
        }
        if ( next == args.end() ) {
            std::cout << QObject::tr("You must specify a command when using the -c option").toStdString() << std::endl;
            error = 1;

            return;
        }

        pythonCommands.push_back( next->toStdString() );

        ++next;
        args.erase(it, next);
    } // for (;;)

    //Parse writers
    for (;; ) {
        QStringList::iterator it = hasToken( QString::fromUtf8("writer"), QString::fromUtf8("w") );
        if ( it == args.end() ) {
            break;
        }

        if (!isBackground || isInterpreterMode) {
            std::cout << QObject::tr("You cannot use the -w option in interactive or interpreter mode").toStdString() << std::endl;
            error = 1;

            return;
        }

        QStringList::iterator next = it;
        if ( next != args.end() ) {
            ++next;
        }
        if ( next == args.end() ) {
            std::cout << QObject::tr("You must specify the name of a Write node when using the -w option").toStdString() << std::endl;
            error = 1;

            return;
        }


        //Check that the name is conform to a Python acceptable script name
        std::string pythonConform = NATRON_PYTHON_NAMESPACE::makeNameScriptFriendly( next->toStdString() );
        if (next->toStdString() != pythonConform) {
            std::cout << QObject::tr("The name of the Write node specified is not valid: it cannot contain non alpha-numerical "
                                     "characters and must not start with a digit.").toStdString() << std::endl;
            error = 1;

            return;
        }

        CLArgs::WriterArg w;
        w.name = *next;

        QStringList::iterator nextNext = next;
        if ( nextNext != args.end() ) {
            ++nextNext;
        }
        if ( nextNext != args.end() ) {
            //Check for an optional filename
            if ( !nextNext->startsWith( QChar::fromLatin1('-') ) && !nextNext->startsWith( QString::fromUtf8("--") ) ) {
                w.filename = *nextNext;
#ifdef __NATRON_UNIX__
                w.filename = AppManager::qt_tildeExpansion(w.filename);
#endif
            }
        }

        writers.push_back(w);
        if ( nextNext != args.end() ) {
            ++nextNext;
        }
        args.erase(it, nextNext);
    } // for (;;)


    //Parse readers
    for (;; ) {
        QStringList::iterator it = hasToken( QString::fromUtf8("reader"), QString::fromUtf8("i") );
        if ( it == args.end() ) {
            break;
        }

        if (!isBackground || isInterpreterMode) {
            std::cout << QObject::tr("You cannot use the -i option in interactive or interpreter mode").toStdString() << std::endl;
            error = 1;

            return;
        }

        QStringList::iterator next = it;
        if ( next != args.end() ) {
            ++next;
        }
        if ( next == args.end() ) {
            std::cout << QObject::tr("You must specify the name of a Read node when using the -i option").toStdString() << std::endl;
            error = 1;

            return;
        }


        //Check that the name is conform to a Python acceptable script name
        std::string pythonConform = NATRON_PYTHON_NAMESPACE::makeNameScriptFriendly( next->toStdString() );
        if (next->toStdString() != pythonConform) {
            std::cout << QObject::tr("The name of the Read node specified is not valid: it cannot contain non alpha-numerical "
                                     "characters and must not start with a digit.").toStdString() << std::endl;
            error = 1;

            return;
        }

        CLArgs::ReaderArg r;
        r.name = *next;

        QStringList::iterator nextNext = next;
        if ( nextNext != args.end() ) {
            ++nextNext;
        }
        if ( nextNext == args.end() ) {
            std::cout << QObject::tr("You must specify the filename for the following Read node: ").toStdString()  << r.name.toStdString() << std::endl;
            error = 1;

            return;
        }


        //Check for  filename
        if ( !nextNext->startsWith( QChar::fromLatin1('-') ) && !nextNext->startsWith( QString::fromUtf8("--") ) ) {
            r.filename = *nextNext;
#ifdef __NATRON_UNIX__
            r.filename = AppManager::qt_tildeExpansion(r.filename);
#endif
        } else {
            std::cout << QObject::tr("You must specify the filename for the following Read node: ").toStdString()  << r.name.toStdString() << std::endl;
            error = 1;

            return;
        }


        readers.push_back(r);
        if ( nextNext != args.end() ) {
            ++nextNext;
        }
        args.erase(it, nextNext);
    } // for (;;)

    bool atLeastOneOutput = false;
    ///Parse outputs
    for (;; ) {
        QString indexStr;
        QStringList::iterator it  = hasOutputToken(indexStr);
        if (error > 0) {
            return;
        }
        if ( it == args.end() ) {
            break;
        }

        if (!isBackground) {
            std::cout << QObject::tr("You cannot use the -o option in interactive or interpreter mode").toStdString() << std::endl;
            error = 1;

            return;
        }

        CLArgs::WriterArg w;
        w.name = QString( QString::fromUtf8("Output%1") ).arg(indexStr);
        w.mustCreate = true;
        atLeastOneOutput = true;

        //Check for a mandatory file name
        QStringList::iterator next = it;
        if ( next != args.end() ) {
            ++next;
        }
        if ( next == args.end() ) {
            std::cout << QObject::tr("Filename is not optional with the -o option").toStdString() << std::endl;
            error = 1;

            return;
        }

        //Check for an optional filename
        if ( !next->startsWith( QChar::fromLatin1('-') ) && !next->startsWith( QString::fromUtf8("--") ) ) {
            w.filename = *next;
        }

        writers.push_back(w);

        QStringList::iterator endToErase = next;
        ++endToErase;
        args.erase(it, endToErase);
    }

    if (atLeastOneOutput && !rangeSet) {
        std::cout << QObject::tr("A frame range must be set when using the -o option").toStdString() << std::endl;
        error = 1;

        return;
    }
} // CLArgsPrivate::parse
QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
    : QgsVectorDataProvider( uri ),
    mXFieldIndex( -1 ), mYFieldIndex( -1 ),
    mShowInvalidLines( true )
{
  // Get the file name and mDelimiter out of the uri
  mFileName = uri.left( uri.indexOf( "?" ) );
  // split the string up on & to get the individual parameters
  QStringList parameters = uri.mid( uri.indexOf( "?" ) ).split( "&", QString::SkipEmptyParts );

  QgsDebugMsg( "Parameter count after split on &" + QString::number( parameters.size() ) );

  // get the individual parameters and assign values
  QStringList temp = parameters.filter( "delimiter=" );
  mDelimiter = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
  temp = parameters.filter( "delimiterType=" );
  mDelimiterType = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
  temp = parameters.filter( "xField=" );
  QString xField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
  temp = parameters.filter( "yField=" );
  QString yField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
  // Decode the parts of the uri. Good if someone entered '=' as a delimiter, for instance.
  mFileName  = QUrl::fromPercentEncoding( mFileName.toUtf8() );
  mDelimiter = QUrl::fromPercentEncoding( mDelimiter.toUtf8() );
  mDelimiterType = QUrl::fromPercentEncoding( mDelimiterType.toUtf8() );
  xField    = QUrl::fromPercentEncoding( xField.toUtf8() );
  yField    = QUrl::fromPercentEncoding( yField.toUtf8() );

  QgsDebugMsg( "Data source uri is " + uri );
  QgsDebugMsg( "Delimited text file is: " + mFileName );
  QgsDebugMsg( "Delimiter is: " + mDelimiter );
  QgsDebugMsg( "Delimiter type is: " + mDelimiterType );
  QgsDebugMsg( "xField is: " + xField );
  QgsDebugMsg( "yField is: " + yField );

  // if delimiter contains some special characters, convert them
  if ( mDelimiterType == "regexp" )
    mDelimiterRegexp = QRegExp( mDelimiter );
  else
    mDelimiter.replace( "\\t", "\t" ); // replace "\t" with a real tabulator

  // Set the selection rectangle to null
  mSelectionRectangle = QgsRectangle();
  // assume the layer is invalid until proven otherwise
  mValid = false;
  if ( mFileName.isEmpty() || mDelimiter.isEmpty() || xField.isEmpty() || yField.isEmpty() )
  {
    // uri is invalid so the layer must be too...
    QString( "Data source is invalid" );
    return;
  }

  // check to see that the file exists and perform some sanity checks
  if ( !QFile::exists( mFileName ) )
  {
    QgsDebugMsg( "Data source " + dataSourceUri() + " doesn't exist" );
    return;
  }

  // Open the file and get number of rows, etc. We assume that the
  // file has a header row and process accordingly. Caller should make
  // sure the the delimited file is properly formed.
  mFile = new QFile( mFileName );
  if ( !mFile->open( QIODevice::ReadOnly ) )
  {
    QgsDebugMsg( "Data source " + dataSourceUri() + " could not be opened" );
    delete mFile;
    return;
  }

  // now we have the file opened and ready for parsing

  // set the initial extent
  mExtent = QgsRectangle();

  QMap<int, bool> couldBeInt;
  QMap<int, bool> couldBeDouble;

  mStream = new QTextStream( mFile );
  QString line;
  mNumberFeatures = 0;
  int lineNumber = 0;
  bool firstPoint = true;
  bool hasFields = false;
  while ( !mStream->atEnd() )
  {
    lineNumber++;
    line = mStream->readLine(); // line of text excluding '\n', default local 8 bit encoding.
    if ( !hasFields )
    {
      // Get the fields from the header row and store them in the
      // fields vector
      QgsDebugMsg( "Attempting to split the input line: " + line + " using delimiter " + mDelimiter );

      QStringList fieldList;
      if ( mDelimiterType == "regexp" )
        fieldList = line.split( mDelimiterRegexp );
      else
        fieldList = line.split( mDelimiter );
      QgsDebugMsg( "Split line into " + QString::number( fieldList.size() ) + " parts" );

      // We don't know anything about a text based field other
      // than its name. All fields are assumed to be text
      int fieldPos = 0;
      for ( QStringList::Iterator it = fieldList.begin();
            it != fieldList.end(); ++it )
      {
        QString field = *it;
        if ( field.length() > 0 )
        {
          // for now, let's set field type as text
          attributeFields[fieldPos] = QgsField( *it, QVariant::String, "Text" );

          // check to see if this field matches either the x or y field
          if ( xField == *it )
          {
            QgsDebugMsg( "Found x field: " + ( *it ) );
            mXFieldIndex = fieldPos;
          }
          else if ( yField == *it )
          {
            QgsDebugMsg( "Found y field: " + ( *it ) );
            mYFieldIndex = fieldPos;
          }

          QgsDebugMsg( "Adding field: " + ( *it ) );
          // assume that the field could be integer or double
          couldBeInt.insert( fieldPos, true );
          couldBeDouble.insert( fieldPos, true );
          fieldPos++;
        }
      }
      QgsDebugMsg( "Field count for the delimited text file is " + QString::number( attributeFields.size() ) );
      hasFields = true;
    }
    else if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
    {
      mNumberFeatures++;

      // split the line on the delimiter
      QStringList parts;
      if ( mDelimiterType == "regexp" )
        parts = line.split( mDelimiterRegexp );
      else
        parts = line.split( mDelimiter );

      // Skip malformed lines silently. Report line number with nextFeature()
      if ( attributeFields.size() != parts.size() )
      {
        continue;
      }

      // Get the x and y values, first checking to make sure they
      // aren't null.
      QString sX = parts[mXFieldIndex];
      QString sY = parts[mYFieldIndex];

      bool xOk = true;
      bool yOk = true;
      double x = sX.toDouble( &xOk );
      double y = sY.toDouble( &yOk );

      if ( xOk && yOk )
      {
        if ( !firstPoint )
        {
          mExtent.combineExtentWith( x, y );
        }
        else
        { // Extent for the first point is just the first point
          mExtent.set( x, y, x, y );
          firstPoint = false;
        }
      }

      int i = 0;
      for ( QStringList::iterator it = parts.begin(); it != parts.end(); ++it, ++i )
      {
        // try to convert attribute values to integer and double
        if ( couldBeInt[i] )
        {
          it->toInt( &couldBeInt[i] );
        }
        if ( couldBeDouble[i] )
        {
          it->toDouble( &couldBeDouble[i] );
        }
      }
    }
  }

  // now it's time to decide the types for the fields
  for ( QgsFieldMap::iterator it = attributeFields.begin(); it != attributeFields.end(); ++it )
  {
    if ( couldBeInt[it.key()] )
    {
      it->setType( QVariant::Int );
      it->setTypeName( "integer" );
    }
    else if ( couldBeDouble[it.key()] )
    {
      it->setType( QVariant::Double );
      it->setTypeName( "double" );
    }
  }

  if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
  {
    QgsDebugMsg( "Data store is valid" );
    QgsDebugMsg( "Number of features " + QString::number( mNumberFeatures ) );
    QgsDebugMsg( "Extents " + mExtent.toString() );

    mValid = true;
  }
  else
  {
    QgsDebugMsg( "Data store is invalid. Specified x,y fields do not match those in the database" );
  }
  QgsDebugMsg( "Done checking validity" );

}