コード例 #1
0
ファイル: template_image.cpp プロジェクト: aivarszo/mapper
bool TemplateImage::WorldFile::load(const QString& path)
{
	QFile file(path);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		loaded = false;
		return false;
	}
	QTextStream text_stream(&file);
	
	bool ok = false;
	double numbers[6];
	for (int i = 0; i < 6; ++i)
	{
		double number = text_stream.readLine().toDouble(&ok);
		if (!ok)
		{
			file.close();
			loaded = false;
			return false;
		}
		numbers[i] = number;
	}
	
	file.close();
	
	pixel_to_world.setMatrix(
		numbers[0], numbers[2], numbers[4],
		numbers[1], numbers[3], numbers[5],
		0, 0, 1);
	pixel_to_world = pixel_to_world.transposed();
	loaded = true;
	return true;
}
コード例 #2
0
ファイル: auto_smzdm.cpp プロジェクト: blacksjt/autobots
void auto_smzdm::onActImportComment()
{
  QString path = QFileDialog::getOpenFileName(this, QStringLiteral("请选择文件路径"), "", QStringLiteral("Txt(*.txt)")); 
  if (path.isEmpty())  //判断用户是否选择了文件
  {
    //emitLogMessage(QStringLiteral("取消打开文件"));
    return;
  }

  QFile file(path);

  if (!file.open(QIODevice::ReadOnly)) {    
    QMessageBox::critical(NULL,  QStringLiteral("提示"), QStringLiteral("无法打开文件"));  
    return ;    
  }  

  QTextStream text_stream(&file);
  //QString str = text_stream.readAll();
  int n_row = 0;
  ui.listWidget_comment_id->clear();

  while(!text_stream.atEnd())
  {
    QString line_str = text_stream.readLine();
    ui.listWidget_comment_id->addItem(new QListWidgetItem(line_str));
  }

  file.close();
}
コード例 #3
0
ファイル: world_file.cpp プロジェクト: sikmir/mapper
bool WorldFile::load(const QString& path)
{
	QFile file(path);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		loaded = false;
		return false;
	}
	QTextStream text_stream(&file);
	
	bool ok = false;
	double parameters[6];
	for (auto& parameter : parameters)
	{
		auto value = text_stream.readLine().toDouble(&ok);
		if (!ok)
		{
			file.close();
			loaded = false;
			return false;
		}
		parameter = value;
	}
	
	file.close();
	
	pixel_to_world.setMatrix(
		parameters[0], parameters[2], parameters[4],
		parameters[1], parameters[3], parameters[5],
		0, 0, 1);
	pixel_to_world = pixel_to_world.transposed();
	loaded = true;
	return true;
}
コード例 #4
0
void SlideshowController::ensure_folder_structure()
{
  // Check for profile folder and create one if it does not exist
  if (!QDir(slideshow_data_model_->profile_folder_path()).exists())
    {
      QDir().mkdir(slideshow_data_model_->profile_folder_path());
    }
  if (!QDir(slideshow_data_model_->main_image_folder_path()).exists())
    {
      QDir().mkdir(slideshow_data_model_->main_image_folder_path());
    }
  // Check for config file and create one if it does not exist
  if (!QFile::exists(slideshow_data_model_->config_file_path()))
    {
       QFile config_file(slideshow_data_model_->config_file_path());
       if (config_file.open(QIODevice::ReadWrite))
         {
           QTextStream text_stream(&config_file);
           save_config_file(slideshow_data_model_->config_file_path());
         }
    }
   /* Qt automatically closes files in
    * this context.
    */
}
コード例 #5
0
ファイル: toutiao_pc_dz.cpp プロジェクト: blacksjt/autobots
void autobots_toutiao::onActImportComment()
{
  QString path = QFileDialog::getOpenFileName(this, QStringLiteral("请选择文件路径"), "", QStringLiteral("Txt(*.txt)")); 
  if (path.isEmpty())  //判断用户是否选择了文件
  {
    //emitLogMessage(QStringLiteral("取消打开文件"));
    return;
  }

  QFile file(path);

  if (!file.open(QIODevice::ReadOnly)) {    
    QMessageBox::critical(NULL, "提示", "无法打开文件");  
    return ;    
  }  

  QTextStream text_stream(&file);
  //QString str = text_stream.readAll();
  int n_row = 0;
  ui.treeWidget_comment_id->clear();
  //m_comment_item_list.clear();
  m_comment_list.clear();

  while(!text_stream.atEnd())
  {
    QString line_str = text_stream.readLine();
    if (!line_str.isEmpty())
    {
      AddToTree(line_str);
    }
  }

  file.close();
}
コード例 #6
0
ファイル: NassiPlugin.cpp プロジェクト: Distrotech/codeblocks
void NassiPlugin::OnInsertCFromDiagram(wxCommandEvent &event)
{
    // check if user can isert an opened diagram
    unsigned idx = 0;
    for ( int i = 0 ; i < Manager::Get()->GetEditorManager()->GetEditorsCount() ; i++ )
    {
        EditorBase *ed = Manager::Get()->GetEditorManager()->GetEditor( i );
        if ( NassiEditorPanel::IsNassiEditor( ed ) )
        {
            NassiEditorPanel *ned = (NassiEditorPanel *)ed;
            if ( event.GetId() == insertCFromDiagram[idx] )
            {
                EditorManager* emngr = Manager::Get()->GetEditorManager();
                if ( !emngr ) return;
                EditorBase *edb = emngr->GetActiveEditor();
                if ( !edb || !edb->IsBuiltinEditor() ) return;
                unsigned int indent = ((cbEditor*)edb)->GetLineIndentInSpaces(); // from current line
                cbStyledTextCtrl *stc = ((cbEditor*)edb)->GetControl();
                if ( !stc ) return;

                wxStringOutputStream ostrstream;
                wxTextOutputStream text_stream(ostrstream);

                if ( !ned ) return;
                ned->GetCSource(text_stream, indent);

                stc->InsertText(wxSCI_INVALID_POSITION, ostrstream.GetString());

            }
            //some comment
            idx++;
        }
    }
}
コード例 #7
0
ファイル: ex6.cpp プロジェクト: dr-c/qt_introduction
void ex6::on_generateButton_clicked()
  {
  qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
  QString string;
  QTextStream text_stream(&string);
  for (int i = 0; i < ui.randomNumberCounter->value(); ++i)
    text_stream << qrand() << " ";
  ui.dataInput->setPlainText(string);
  }
コード例 #8
0
ファイル: imagpnm.cpp プロジェクト: erwincoumans/wxWidgets
void Skip_Comment(wxInputStream &stream)
{
    wxTextInputStream text_stream(stream);

    if (stream.Peek()==wxT('#'))
    {
        text_stream.ReadLine();
        Skip_Comment(stream);
    }
}
コード例 #9
0
ファイル: ex6.cpp プロジェクト: dr-c/qt_introduction
void ex6::receiveSortingResult(QVector<int>* ip_result)
  {
  ui.manipulatingButton->setText("&Start sorting");
  ui.progressBar->setValue(ip_result->size());

  QString string;
  QTextStream text_stream(&string);
  for (int i = 0; i < ip_result->size(); ++i)
    text_stream << ip_result->operator[](i) << " ";
  ui.dataResult->setPlainText(string);
  }
コード例 #10
0
void reteneitor3000::crearTexto(){
  QFile text_file("/tmp/reteneitor3000");

  qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
  if (text_file.open(QIODevice::WriteOnly)){
    QTextStream text_stream(&text_file);
    text_stream << ui->texto->toPlainText();
  }
  else
    error("No se pudo crear archivo temporal");
  text_file.close();
}
コード例 #11
0
ファイル: imagpnm.cpp プロジェクト: erwincoumans/wxWidgets
bool wxPNMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
{
    wxTextOutputStream text_stream(stream);

    //text_stream << "P6" << endl
    //<< image->GetWidth() << " " << image->GetHeight() << endl
    //<< "255" << endl;
    text_stream << wxT("P6\n") << image->GetWidth() << wxT(" ") << image->GetHeight() << wxT("\n255\n");
    stream.Write(image->GetData(),3*image->GetWidth()*image->GetHeight());

    return stream.IsOk();
}
コード例 #12
0
void auto_dirvers_fatie::onActImportComment()
{
	QString path = QFileDialog::getOpenFileName(this, QStringLiteral("请选择文件路径"), "", QStringLiteral("Txt(*.txt)"));
	if (path.isEmpty())  //判断用户是否选择了文件
	{
		//emitLogMessage(QStringLiteral("取消打开文件"));
		return;
	}

	QFile file(path);

	if (!file.open(QIODevice::ReadOnly)) {
		QMessageBox::critical(NULL, "提示", "无法打开文件");
		return;
	}

	QTextStream text_stream(&file);
	
	if (ui.tabWidget_comments->currentIndex() == 0)
	{
		ui.listWidget_comment_id1->clear();

		while (!text_stream.atEnd())
		{
			QString line_str = text_stream.readLine();
			ui.listWidget_comment_id1->addItem(new QListWidgetItem(line_str));
		}
	}
	else if(ui.tabWidget_comments->currentIndex() == 1)
	{
		ui.listWidget_comment_id2->clear();

		while (!text_stream.atEnd())
		{
			QString line_str = text_stream.readLine();
			ui.listWidget_comment_id2->addItem(new QListWidgetItem(line_str));
		}
	}
	else
	{
		ui.listWidget_comment_id3->clear();

		while (!text_stream.atEnd())
		{
			QString line_str = text_stream.readLine();
			ui.listWidget_comment_id3->addItem(new QListWidgetItem(line_str));
		}
	}


	file.close();
}
コード例 #13
0
void Indicadores::UpdateLog(QString file)
{
    QString Path=QCoreApplication::applicationDirPath().toLatin1();
    QFile text_file(Path + "/Logs/" + file ); // link the text file with the QFile object

    if (text_file.open(QIODevice::ReadOnly)) // try to open the file. Mode: Read only
    {
        QTextStream text_stream(&text_file); // set the interface for reading the text
        TLog->setText(text_stream.readAll());
    }

    text_file.close();  // close the file
}
コード例 #14
0
ファイル: EXPORT.cpp プロジェクト: icekittenxx/SKproject_0420
void EXPORT::ExportToTxt(QString file_name, QSqlTableModel *model, QString table_name)
{
    QFile file(file_name);
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);

    QString message = "";

    int col_size = model->columnCount();
    int row_size = model->rowCount();
    QVector<QString> head_data;

    QString head_message = "";
    for(int i = 0; i < col_size; i ++)
    {
        if(i)
        {
            head_message += ",";
        }
        head_data.push_back(model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
        QString temp = "";
        QString temp2 = QString::fromUtf8(head_data[i].toUtf8().data());
        temp.sprintf("%s", temp2.toUtf8().data());
        head_message += temp;
    }
    message += head_message;
    message += "\n";

    for(int i = 0; i < row_size; i ++)
    {
        for(int j = 0; j < col_size; j ++)
        {
            QModelIndex index = model->index(i, j);
            QString val = model->data(index).toString();

            QString temp = "";
            QString temp2 = QString::fromUtf8(val.toUtf8().data());
            temp.sprintf("%s", temp2.toUtf8().data());
            message += temp;
            if(j < col_size - 1)
            {
                message += ",";
            }
        }
        message += "\n";
    }

    text_stream << message;
    file.close();
}
コード例 #15
0
ファイル: VoiceCommands.cpp プロジェクト: Phog/VoiceCommander
void VoiceCommands::parse_text(const std::string &text) throw()
{
    std::stringstream text_stream(text);
    
    // Skip to the appropriate position
    std::string word;
    for (int i = 0; i < m_num_parsed_words; ++i)
    {
        text_stream >> word;
        if (!text_stream.good())
            return;
    }
    
    int word_location = m_num_parsed_words - 1;  
    while (text_stream.good())
    { 
        text_stream >> word;
        word_location++;

        word = to_lower(remove_punctuation(word));
        bool found_trigger = false;
        for (std::string trigger : m_trigger_list[m_trigger_index])
        {
            if (trigger == word)
            {
                found_trigger = true;
                break;
            }
        }
        
        // If we haven't yet found the trigger word, panic and move to the next state.            
        if (word_location >= m_trigger_locations[m_trigger_index] + MAX_WORD_OFFSET)
            found_trigger = true;

        if (found_trigger)
        {
            m_num_parsed_words = std::min(m_trigger_locations[m_trigger_index] + MAX_WORD_OFFSET,
                                          word_location) + 1;
            
            m_active_state  = m_state_list[m_trigger_index];
            m_trigger_index = std::min(static_cast<int>(m_state_list.size() - 1),
                                       1 + m_trigger_index);
            break;
        }
    }
}
コード例 #16
0
void auto_dirvers_fatie::onActFromTxt()
{
	QString path = QFileDialog::getOpenFileName(this, QStringLiteral("请选择文件路径"), "", QStringLiteral("Txt(*.txt)"));
	if (path.isEmpty())  //判断用户是否选择了文件
	{
		//emitLogMessage(QStringLiteral("取消打开文件"));
		return;
	}

	QFile file(path);

	if (!file.open(QIODevice::ReadOnly)) {
		QMessageBox::critical(NULL, "提示", "无法打开文件");
		return;
	}

	QTextStream text_stream(&file);
	//QString str = text_stream.readAll();
	int n_row = 0;
	ui.tableWidget_account_id->clearContents();
	ui.tableWidget_account_id->setRowCount(0);
	m_account_list.clear();
	m_account_order = 0;
	m_account_row_list.clear();

	while (!text_stream.atEnd())
	{
		QString line_str = text_stream.readLine();

		QStringList str_list = line_str.split("----");

		if (str_list.size() >= 2)
		{
			ui.tableWidget_account_id->setRowCount(ui.tableWidget_account_id->rowCount() + 1);
			QString name = str_list[0];
			QString password = str_list[1];
			QTableWidgetItem* item = new QTableWidgetItem(name);
			ui.tableWidget_account_id->setItem(n_row, 0, item);
			item = new QTableWidgetItem(password);
			ui.tableWidget_account_id->setItem(n_row, 1, item);
			n_row++;
		}
	}

	file.close();
}
コード例 #17
0
ファイル: doc.cpp プロジェクト: EdgarTx/wx
wxInputStream& DrawingDocument::LoadObject(wxInputStream& stream)
{
    wxDocument::LoadObject(stream);

    wxTextInputStream text_stream( stream );

    wxInt32 n = 0;
    text_stream >> n;

    for (int i = 0; i < n; i++)
    {
        DoodleSegment *segment = new DoodleSegment;
        segment->LoadObject(stream);
        doodleSegments.Append(segment);
    }

    return stream;
}
コード例 #18
0
ファイル: main.cpp プロジェクト: ypvk/WebSearch
void customMessageHandler(QtMsgType type, const char *msg)
{
    static QMutex mutex;
    mutex.lock();

    QString text;
    switch(type)
    {
    case QtDebugMsg:
        text = QString("Debug:");
        break;

    case QtWarningMsg:
        text = QString("Warning:");
        break;

    case QtCriticalMsg:
        text = QString("Critical:");
        break;

    case QtFatalMsg:
        text = QString("Fatal:");
    }

    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QString current_date = QString("(%1)").arg(current_date_time);
    QString message = QString("%1 %2 %3").arg(text).arg(current_date).arg(msg);

    QFile file("log.txt");
    if (file.size() > 104857600)//size large than 100M split
    {
        QString filedate = QDateTime::currentDateTime().toString("yyyy-MM-dd--hh-mm-ss");
        file.rename(QString("log_%1.txt").arg(filedate));
        file.setFileName("log.txt");
    }
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);
    text_stream.setCodec(QTextCodec::codecForName("System"));
    text_stream << message << "\r\n";
    file.flush();
    file.close();

    mutex.unlock();
}
コード例 #19
0
ファイル: doc.cpp プロジェクト: EdgarTx/wx
wxInputStream &DoodleSegment::LoadObject(wxInputStream& stream)
{
    wxTextInputStream text_stream( stream );

    wxInt32 n = 0;
    text_stream >> n;

    for (int i = 0; i < n; i++)
    {
        DoodleLine *line = new DoodleLine;
        text_stream >> line->x1 >>
                    line->y1 >>
                    line->x2 >>
                    line->y2;
        lines.Append(line);
    }

    return stream;
}
コード例 #20
0
ファイル: doc.cpp プロジェクト: EdgarTx/wx
wxOutputStream &DoodleSegment::SaveObject(wxOutputStream& stream)
{
    wxTextOutputStream text_stream( stream );

    wxInt32 n = lines.GetCount();
    text_stream << n << _T('\n');

    wxList::compatibility_iterator node = lines.GetFirst();
    while (node)
    {
        DoodleLine *line = (DoodleLine *)node->GetData();
        text_stream << line->x1 << _T(" ") <<
                    line->y1 << _T(" ") <<
                    line->x2 << _T(" ") <<
                    line->y2 << _T("\n");
        node = node->GetNext();
    }

    return stream;
}
コード例 #21
0
ファイル: log.cpp プロジェクト: KevinHzj/UltraSoundProject
/*!
 * \brief outputMessage
 * \param type
 * \param context
 * \param msg
 *
 */
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static QMutex mutex;
    mutex.lock();

    QString text;
    switch(type)
    {
    case QtDebugMsg:
        text = QString("Debug:");
        break;

    case QtWarningMsg:
        text = QString("Warning:");
        break;

    case QtCriticalMsg:
        text = QString("Critical:");
        break;

    case QtFatalMsg:
        text = QString("Fatal:");
        break;
    default:
        text = QString("undefine: ");
    }

    QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
    QString current_date = QString("(%1)").arg(current_date_time);
    QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);

    QFile file("rocherlog.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);
    text_stream << message << "\r\n";
    file.flush();
    file.close();

    mutex.unlock();
}
コード例 #22
0
ファイル: doc.cpp プロジェクト: EdgarTx/wx
wxOutputStream& DrawingDocument::SaveObject(wxOutputStream& stream)
{
    wxDocument::SaveObject(stream);

    wxTextOutputStream text_stream( stream );

    wxInt32 n = doodleSegments.GetCount();
    text_stream << n << _T('\n');

    wxList::compatibility_iterator node = doodleSegments.GetFirst();
    while (node)
    {
        DoodleSegment *segment = (DoodleSegment *)node->GetData();
        segment->SaveObject(stream);
        text_stream << _T('\n');

        node = node->GetNext();
    }

    return stream;
}
コード例 #23
0
ファイル: mainwindow.cpp プロジェクト: mansrz/Sudoku
void MainWindow::on_actionCargar_partida_triggered()
{
    SimpleCrypt processSimpleCrypt(89473829);

    int i,j;
    QString linea;
    QStringList listaLinea;

    QFile file("../savedGame.sud");
    file.open(QIODevice::Text | QIODevice::ReadOnly);
    QTextStream text_stream(&file);

    for (i=0;i<9;i++){
        for (j=0;j<9;j++){
            linea = text_stream.readLine();
            linea = processSimpleCrypt.decryptToString(linea);
            listaLinea = linea.split(",");
            creacionNumeros(i*9+j, listaLinea[0].toInt(), i, j, !listaLinea[2].toInt());
            if (listaLinea[1].toInt()!=-1){
                numeros[i*9+j]->editarBoton(listaLinea[1].toInt());
            }
        }

    }

    connect(sgnlMprNumero, SIGNAL (mapped (int)), SLOT (obtenerCasilla(int)));

    creacionBotones();
    inicializarTimer();

    ui->btnLlenar->setEnabled(false);
    ui->btnFinalizar->setEnabled(true);

    file.flush();

    //close the file
    file.close();

}
コード例 #24
0
ファイル: imagpnm.cpp プロジェクト: erwincoumans/wxWidgets
bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
{
    wxUint32  width, height;
    wxUint16  maxval;
    char      c(0);

    image->Destroy();

    /*
     * Read the PNM header
     */

    wxBufferedInputStream buf_stream(stream);
    wxTextInputStream text_stream(buf_stream);

    Skip_Comment(buf_stream);
    if (buf_stream.GetC()==wxT('P')) c=buf_stream.GetC();

    switch (c)
    {
        case wxT('2'): // ASCII Grey
        case wxT('3'): // ASCII RGB
        case wxT('5'): // RAW Grey
        case wxT('6'): break;
        default:
            if (verbose)
            {
                wxLogError(_("PNM: File format is not recognized."));
            }
            return false;
    }

    text_stream.ReadLine(); // for the \n
    Skip_Comment(buf_stream);
    text_stream >> width >> height ;
    Skip_Comment(buf_stream);
    text_stream >> maxval;

    //cout << line << " " << width << " " << height << " " << maxval << endl;
    image->Create( width, height );
    unsigned char *ptr = image->GetData();
    if (!ptr)
    {
        if (verbose)
        {
           wxLogError( _("PNM: Couldn't allocate memory.") );
        }
        return false;
    }


    if (c=='2') // Ascii GREY
    {
        wxUint32 value, size=width*height;
        for (wxUint32 i=0; i<size; ++i)
        {
            value=text_stream.Read32();
            if ( maxval != 255 )
                value = (255 * value)/maxval;
            *ptr++=(unsigned char)value; // R
            *ptr++=(unsigned char)value; // G
            *ptr++=(unsigned char)value; // B
            if ( !buf_stream )
            {
                if (verbose)
                {
                    wxLogError(_("PNM: File seems truncated."));
                }
                return false;
            }
        }
    }
    if (c=='3') // Ascii RBG
    {
        wxUint32 value, size=3*width*height;
        for (wxUint32 i=0; i<size; ++i)
          {
            //this is very slow !!!
            //I wonder how we can make any better ?
            value=text_stream.Read32();
            if ( maxval != 255 )
                value = (255 * value)/maxval;
            *ptr++=(unsigned char)value;

            if ( !buf_stream )
              {
                if (verbose)
                {
                    wxLogError(_("PNM: File seems truncated."));
                }
                return false;
              }
          }
    }
    if (c=='5') // Raw GREY
    {
        wxUint32 size=width*height;
        unsigned char value;
        for (wxUint32 i=0; i<size; ++i)
        {
            buf_stream.Read(&value,1);
            if ( maxval != 255 )
                value = (255 * value)/maxval;
            *ptr++=value; // R
            *ptr++=value; // G
            *ptr++=value; // B
            if ( !buf_stream )
            {
                if (verbose)
                {
                    wxLogError(_("PNM: File seems truncated."));
                }
                return false;
            }
        }
    }

    if ( c=='6' ) // Raw RGB
    {
        buf_stream.Read(ptr, 3*width*height);
        if ( maxval != 255 )
        {
            for ( unsigned i = 0; i < 3*width*height; i++ )
                ptr[i] = (255 * ptr[i])/maxval;
        }
    }

    image->SetMask( false );

    const wxStreamError err = buf_stream.GetLastError();
    return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
}
コード例 #25
0
ファイル: setty.hpp プロジェクト: yzsolt/setty-cpp
        /** Main Setty constructor, parses the given text. */
        Setty(const std::string& text) :
            m_text(text)
        {

			std::stringstream text_stream(std::move(text));
			std::string line;

			bool empty_line_allowed = true;

			// Iterate over the lines
			while (std::getline(text_stream, line)) {

				m_line++;

				m_count = 0; // Character count of the currently parsed unit (section/key/value)
				m_tab_count = 0;

				bool found_whitespace = false; // Found whitespace after key name and before value

				size_t line_length = line.length();
				
				// Handle CRLF line endings
				if (!line.empty() && line[line.length() - 1] == '\r') {
					line_length--;
				}

				// Iterate over the characters in the current line
				for (m_at = 0; m_at < line_length; m_at++) {

					char c = line[m_at];

					// Count indentation
					if (m_count == 0 && m_state != State::SINGLE_VALUE) {

						if (c == '\t') {
							m_tab_count++;
							continue;
						} else if (c == ' ') {
							throw ParseException("Only tabs allowed for indentation.", m_line, m_at);
						}

					}

					bool end_of_line = (m_at == line_length - 1);

					switch (m_state) {

						case State::UNKNOWN: {

							if (m_count == 0) {

								switch (c) {

									case '#':
										m_state = State::COMMENT;
										m_count++;
										break;

									case '}':
										if (end_of_line) {
											_handle_section_end();
										}
										break;

									default:
										m_count++;
								}

							} else {

								switch (c) {

									case ' ': {

										std::string section = line.substr(m_at - m_count, m_count);

										if (!_is_valid_name(section)) {
											throw ParseException("Invalid section name.", m_line, _get_true_at());
										}

										for (const auto& node : m_current_section->m_children) {
											if (node->m_name == section) {
												throw ParseException("Two sections/keys with the same name in the same scope aren't allowed.", m_line, _get_true_at());
											}
										}

										Node* new_node = new Node;

										new_node->m_type = Node::Type::SECTION;
										new_node->m_name = section;
										new_node->m_parent = m_current_section;

										m_current_section->m_children.push_back(std::unique_ptr<Node>(new_node));
										m_current_section = new_node;

										m_state = State::SECTION_START;

									} break;

									case ':': {

										std::string key = line.substr(m_at - m_count, m_count);

										if (!_is_valid_name(key)) {
											throw ParseException("Invalid key name.", m_line, _get_true_at());
										}

										if (m_tab_count != m_depth) {
											throw ParseException("Key is not indented correctly.", m_line, m_at);
										}

										_save_key(key);

										if (end_of_line) {
											m_depth++;
											m_current_key->m_type = Node::Type::LIST;
											empty_line_allowed = false;
											m_state = State::LIST_VALUE;
										} else {
											m_state = State::SINGLE_VALUE;
											m_count = 0;
										}

									} break;

									case '\t':
										continue;
										break;

									default:
										m_count++;

								}

							}

						} break;

						case State::COMMENT: {
							if (end_of_line) {
								m_state = State::UNKNOWN;
							}
							continue;
						} break;

						case State::SECTION_START: {

							switch (c) {

								case '{': {

									if (!end_of_line) {
										throw ParseException("Section opening must be followed by a new line.", m_line, m_at);
									}

									m_open_section_count++;
									m_depth++;
									m_state = State::UNKNOWN;

								} break;

								default:
									throw ParseException("Expected section opening, got something else.", m_line, m_at);

							}

						} break;

						case State::SINGLE_VALUE: {

							if (_is_whitespace(c)) {

								found_whitespace = true;

								if (m_count == 0 && end_of_line) {
									throw ParseException("Empty values are not allowed.", m_line, m_at);
								}

							} else {

								if (found_whitespace) {

									m_count++;

									if (end_of_line) {
										m_current_key->m_content.push_back(line.substr(m_at + 1 - m_count, m_count));
										m_state = State::UNKNOWN;
									}

								} else {
									throw ParseException("Key name must be followed by at least one space or tab.", m_line, m_at);
								}

							}

						} break;

						case State::LIST_VALUE: {

							m_count++;

							if (end_of_line) {

								if (m_count == 1 && c == '}') {
									m_depth--; // Decrement to key depth
									_handle_section_end();
									continue;
								}

								if (m_tab_count != m_depth) {
									throw ParseException("List value is not indented correctly.", m_line, m_at);
								}

								m_current_key->m_content.push_back(line.substr(m_at - m_count, m_count));

							}

						} break;

					}

				}

				if (m_count == 0 && !empty_line_allowed) {
					throw ParseException("An empty line is not allowed here.", m_line, m_at);
				}

			}

            if (m_count > 0) {
                throw ParseException("Unknown symbol.", m_line, m_at); // Playing with overflow
            }

            if (m_open_section_count > 0) {
                throw ParseException("There are unclosed sections.", m_line, m_at);
            }

        }