<commit_before>//=============================================================================================================
/**
 * @file     rtfwdsetupwidget.cpp
 * @author   Ruben Dörfel <ruben.doerfel@tu-ilmenau.de>
 * @since    0.1.0
 * @date     May, 2020
 *
 * @section  LICENSE
 *
 * Copyright (C) 2020, Ruben Dörfel. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief    Definition of the RtFwdSetupWidget class.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "rtfwdsetupwidget.h"

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QDebug>

//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace RTFWDPLUGIN;

//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

RtFwdSetupWidget::RtFwdSetupWidget(RtFwd* toolbox, QWidget *parent)
: QWidget(parent)
, m_pRtFwd(toolbox)
{
    m_ui.setupUi(this);

    // init line edits
    m_ui.m_qLineEdit_SolName->setText(m_pRtFwd->m_sSolName);
    m_ui.m_qLineEdit_BemName->setText(m_pRtFwd->m_sBemName);
    m_ui.m_qLineEdit_SourceName->setText(m_pRtFwd->m_sSourceName);
    m_ui.m_qLineEdit_MriName->setText(m_pRtFwd->m_sMriName);
    m_ui.m_qLineEdit_MinDistName->setText(m_pRtFwd->m_sMinDistOutName);
    m_ui.m_qLineEdit_EEGModelFile->setText(m_pRtFwd->m_sEegModelFile);
    m_ui.m_qLineEdit_EEGModelName->setText(m_pRtFwd->m_sEegModelName);

    // init checkboxes
    m_ui.m_check_bDoAll->setChecked(m_pRtFwd->m_bDoAll);
    m_ui.m_check_bIncludeEEG->setChecked(m_pRtFwd->m_bIncludeEEG);
    m_ui.m_check_bIncludeMeg->setChecked(m_pRtFwd->m_bIncludeMEG);
    m_ui.m_check_bComputeGrad->setChecked(m_pRtFwd->m_bComputeGrad);
    m_ui.m_check_bAccurate->setChecked(m_pRtFwd->m_bAccurate);
    m_ui.m_check_bDoAll->setChecked(m_pRtFwd->m_bDoAll);
    m_ui.m_check_bFixedOri->setChecked(m_pRtFwd->m_bFixedOri);
    m_ui.m_check_bFilterSpaces->setChecked(m_pRtFwd->m_bFilterSpaces);
    m_ui.m_check_bMriHeadIdent->setChecked(m_pRtFwd->m_bMriHeadIdent);
    m_ui.m_check_bUseThreads->setChecked(m_pRtFwd->m_bUseThreads);
    m_ui.m_check_bUseEquivEeg->setChecked(m_pRtFwd->m_bUseEquivEeg);

    // init Spin Boxes
    m_ui.m_doubleSpinBox_dMinDist->setValue(m_pRtFwd->m_fMinDist);
    m_ui.m_doubleSpinBox_dEegSphereRad->setValue(m_pRtFwd->m_fEegSphereRad);
    m_ui.m_doubleSpinBox_dVecR0x->setValue(m_pRtFwd->m_vecR0.x());
    m_ui.m_doubleSpinBox_dVecR0y->setValue(m_pRtFwd->m_vecR0.y());
    m_ui.m_doubleSpinBox_dVecR0z->setValue(m_pRtFwd->m_vecR0.z());

    // connec line edits
    connect(m_ui.m_qLineEdit_SolName, &QLineEdit::textChanged, this, &RtFwdSetupWidget::changeSolName);
    connect(m_ui.m_qLineEdit_MinDistName, &QLineEdit::textChanged, this, &RtFwdSetupWidget::changeMinDistName);

    // connec spin boxes
    connect(m_ui.m_doubleSpinBox_dMinDist,static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeMinDist);
    connect(m_ui.m_doubleSpinBox_dEegSphereRad, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereRad);
    connect(m_ui.m_doubleSpinBox_dVecR0x, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereOrigin);
    connect(m_ui.m_doubleSpinBox_dVecR0y, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereOrigin);
    connect(m_ui.m_doubleSpinBox_dVecR0z, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereOrigin);

    // connet Bushbuttons
    connect(m_ui.m_qPushButton_SolNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showFwdDirDialog);
    connect(m_ui.m_qPushButton_BemNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showBemFileDialog);
    connect(m_ui.m_qPushButton_SourceNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showSourceFileDialog);
    connect(m_ui.m_qPushButton_MriNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showMriFileDialog);
    connect(m_ui.m_qPushButton_MinDistOutDialog, &QPushButton::released, this, &RtFwdSetupWidget::showMinDistDirDialog);
    connect(m_ui.m_qPushButton_EEGModelFileDialog, &QPushButton::released, this, &RtFwdSetupWidget::showEEGModelFileDialog);
    connect(m_ui.m_qPushButton_EEGModelNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showEEGModelNameDialog);
}

//=============================================================================================================

void RtFwdSetupWidget::showFwdDirDialog()
{
    m_sSolDir = QFileDialog::getExistingDirectory(this,
                                                  tr("Select Directory to store the forward solution"),
                                                  QString(),
                                                  QFileDialog::ShowDirsOnly
                                                  | QFileDialog::DontResolveSymlinks);

    QString t_sFileName = m_ui.m_qLineEdit_SolName->text();
    m_pRtFwd->m_sSolName = m_sSolDir + "/" + t_sFileName;
    qDebug() << m_pRtFwd->m_sSolName;
}

//=============================================================================================================

void RtFwdSetupWidget::changeSolName()
{
    QString t_sFileName = m_ui.m_qLineEdit_SolName->text();
    m_pRtFwd->m_sSolName = m_sSolDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::showSourceFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select Source Space"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_sSourceName = t_sFileName;
    m_ui.m_qLineEdit_SourceName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showBemFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select Bem Model"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_sBemName = t_sFileName;
    m_ui.m_qLineEdit_BemName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showMriFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select Mri-Head Transformation"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_sMriName = t_sFileName;
    m_ui.m_qLineEdit_MriName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showEEGModelFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select EEG model"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_sEegModelFile = t_sFileName;
    m_ui.m_qLineEdit_EEGModelFile->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showEEGModelNameDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select EEG model name"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_sEegModelName = t_sFileName;
    m_ui.m_qLineEdit_EEGModelName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showMinDistDirDialog()
{
    m_sMinDistDir = QFileDialog::getExistingDirectory(this,
                                                      tr("Select output for omitted source space"),
                                                      QString(),
                                                      QFileDialog::ShowDirsOnly
                                                      | QFileDialog::DontResolveSymlinks);

    QString t_sFileName = m_ui.m_qLineEdit_MinDistName->text();
    m_pRtFwd->m_sMinDistOutName = m_sMinDistDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::changeMinDistName()
{
    QString t_sFileName = m_ui.m_qLineEdit_MinDistName->text();
    m_pRtFwd->m_sMinDistOutName = m_sMinDistDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::changeMinDist()
{
    m_pRtFwd->m_fMinDist = m_ui.m_doubleSpinBox_dMinDist->value();
}
//=============================================================================================================

void RtFwdSetupWidget::changeEEGSphereRad()
{
    m_pRtFwd->m_fEegSphereRad = m_ui.m_doubleSpinBox_dEegSphereRad->value();
}

//=============================================================================================================

void RtFwdSetupWidget::changeEEGSphereOrigin()
{
    m_pRtFwd->m_vecR0.x() = m_ui.m_doubleSpinBox_dVecR0x->value();
    m_pRtFwd->m_vecR0.y() = m_ui.m_doubleSpinBox_dVecR0y->value();
    m_pRtFwd->m_vecR0.z() = m_ui.m_doubleSpinBox_dVecR0z->value();
    std::cout << m_pRtFwd->m_vecR0 << std::endl;
}
//=============================================================================================================

RtFwdSetupWidget::~RtFwdSetupWidget()
{
}
<commit_msg>MAINT: replace write values dirctly to m_pSettings<commit_after>//=============================================================================================================
/**
 * @file     rtfwdsetupwidget.cpp
 * @author   Ruben Dörfel <ruben.doerfel@tu-ilmenau.de>
 * @since    0.1.0
 * @date     May, 2020
 *
 * @section  LICENSE
 *
 * Copyright (C) 2020, Ruben Dörfel. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief    Definition of the RtFwdSetupWidget class.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "rtfwdsetupwidget.h"

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QDebug>

//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace RTFWDPLUGIN;

//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

RtFwdSetupWidget::RtFwdSetupWidget(RtFwd* toolbox, QWidget *parent)
: QWidget(parent)
, m_pRtFwd(toolbox)
{
    m_ui.setupUi(this);

    // init line edits
    m_ui.m_qLineEdit_SolName->setText(m_pRtFwd->m_pFwdSettings->solname);
    m_ui.m_qLineEdit_BemName->setText(m_pRtFwd->m_pFwdSettings->bemname);
    m_ui.m_qLineEdit_SourceName->setText(m_pRtFwd->m_pFwdSettings->srcname);
    m_ui.m_qLineEdit_MriName->setText(m_pRtFwd->m_pFwdSettings->mriname);
    m_ui.m_qLineEdit_MinDistName->setText(m_pRtFwd->m_pFwdSettings->mindistoutname);
    m_ui.m_qLineEdit_EEGModelFile->setText(m_pRtFwd->m_pFwdSettings->eeg_model_file);
    m_ui.m_qLineEdit_EEGModelName->setText(m_pRtFwd->m_pFwdSettings->eeg_model_name);

    // init checkboxes
    m_ui.m_check_bDoAll->setChecked(m_pRtFwd->m_pFwdSettings->do_all);
    m_ui.m_check_bIncludeEEG->setChecked(m_pRtFwd->m_pFwdSettings->include_eeg);
    m_ui.m_check_bIncludeMeg->setChecked(m_pRtFwd->m_pFwdSettings->include_meg);
    m_ui.m_check_bComputeGrad->setChecked(m_pRtFwd->m_pFwdSettings->compute_grad);
    m_ui.m_check_bAccurate->setChecked(m_pRtFwd->m_pFwdSettings->accurate);
    m_ui.m_check_bFixedOri->setChecked(m_pRtFwd->m_pFwdSettings->fixed_ori);
    m_ui.m_check_bFilterSpaces->setChecked(m_pRtFwd->m_pFwdSettings->filter_spaces);
    m_ui.m_check_bMriHeadIdent->setChecked(m_pRtFwd->m_pFwdSettings->mri_head_ident);
    m_ui.m_check_bUseThreads->setChecked(m_pRtFwd->m_pFwdSettings->use_threads);
    m_ui.m_check_bUseEquivEeg->setChecked(m_pRtFwd->m_pFwdSettings->use_equiv_eeg);

    // init Spin Boxes
    m_ui.m_doubleSpinBox_dMinDist->setValue(m_pRtFwd->m_pFwdSettings->mindist);
    m_ui.m_doubleSpinBox_dEegSphereRad->setValue(m_pRtFwd->m_pFwdSettings->eeg_sphere_rad);
    m_ui.m_doubleSpinBox_dVecR0x->setValue(m_pRtFwd->m_pFwdSettings->r0.x());
    m_ui.m_doubleSpinBox_dVecR0y->setValue(m_pRtFwd->m_pFwdSettings->r0.y());
    m_ui.m_doubleSpinBox_dVecR0z->setValue(m_pRtFwd->m_pFwdSettings->r0.z());

    // connec line edits
    connect(m_ui.m_qLineEdit_SolName, &QLineEdit::textChanged, this, &RtFwdSetupWidget::changeSolName);
    connect(m_ui.m_qLineEdit_MinDistName, &QLineEdit::textChanged, this, &RtFwdSetupWidget::changeMinDistName);

    // connec spin boxes
    connect(m_ui.m_doubleSpinBox_dMinDist,static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeMinDist);
    connect(m_ui.m_doubleSpinBox_dEegSphereRad, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereRad);
    connect(m_ui.m_doubleSpinBox_dVecR0x, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereOrigin);
    connect(m_ui.m_doubleSpinBox_dVecR0y, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereOrigin);
    connect(m_ui.m_doubleSpinBox_dVecR0z, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &RtFwdSetupWidget::changeEEGSphereOrigin);

    // connet Bushbuttons
    connect(m_ui.m_qPushButton_SolNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showFwdDirDialog);
    connect(m_ui.m_qPushButton_BemNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showBemFileDialog);
    connect(m_ui.m_qPushButton_SourceNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showSourceFileDialog);
    connect(m_ui.m_qPushButton_MriNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showMriFileDialog);
    connect(m_ui.m_qPushButton_MinDistOutDialog, &QPushButton::released, this, &RtFwdSetupWidget::showMinDistDirDialog);
    connect(m_ui.m_qPushButton_EEGModelFileDialog, &QPushButton::released, this, &RtFwdSetupWidget::showEEGModelFileDialog);
    connect(m_ui.m_qPushButton_EEGModelNameDialog, &QPushButton::released, this, &RtFwdSetupWidget::showEEGModelNameDialog);
}

//=============================================================================================================

void RtFwdSetupWidget::showFwdDirDialog()
{
    m_sSolDir = QFileDialog::getExistingDirectory(this,
                                                  tr("Select Directory to store the forward solution"),
                                                  QString(),
                                                  QFileDialog::ShowDirsOnly
                                                  | QFileDialog::DontResolveSymlinks);

    QString t_sFileName = m_ui.m_qLineEdit_SolName->text();
    m_pRtFwd->m_pFwdSettings->solname = m_sSolDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::changeSolName()
{
    QString t_sFileName = m_ui.m_qLineEdit_SolName->text();
    m_pRtFwd->m_pFwdSettings->solname = m_sSolDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::showSourceFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select Source Space"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_pFwdSettings->srcname = t_sFileName;
    m_ui.m_qLineEdit_SourceName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showBemFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select Bem Model"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_pFwdSettings->bemname = t_sFileName;
    m_ui.m_qLineEdit_BemName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showMriFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select Mri-Head Transformation"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_pFwdSettings->mriname = t_sFileName;
    m_ui.m_qLineEdit_MriName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showEEGModelFileDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select EEG model"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_pFwdSettings->eeg_model_file = t_sFileName;
    m_ui.m_qLineEdit_EEGModelFile->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showEEGModelNameDialog()
{
    QString t_sFileName = QFileDialog::getOpenFileName(this,
                                                       tr("Select EEG model name"),
                                                       QString(),
                                                       tr("Fif Files (*.fif)"));

    m_pRtFwd->m_pFwdSettings->eeg_model_name = t_sFileName;
    m_ui.m_qLineEdit_EEGModelName->setText(t_sFileName);
}

//=============================================================================================================

void RtFwdSetupWidget::showMinDistDirDialog()
{
    m_sMinDistDir = QFileDialog::getExistingDirectory(this,
                                                      tr("Select output for omitted source space"),
                                                      QString(),
                                                      QFileDialog::ShowDirsOnly
                                                      | QFileDialog::DontResolveSymlinks);

    QString t_sFileName = m_ui.m_qLineEdit_MinDistName->text();
    m_pRtFwd->m_pFwdSettings->mindistoutname = m_sMinDistDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::changeMinDistName()
{
    QString t_sFileName = m_ui.m_qLineEdit_MinDistName->text();
    m_pRtFwd->m_pFwdSettings->mindistoutname = m_sMinDistDir + "/" + t_sFileName;
}

//=============================================================================================================

void RtFwdSetupWidget::changeMinDist()
{
    m_pRtFwd->m_pFwdSettings->mindist = m_ui.m_doubleSpinBox_dMinDist->value();
}
//=============================================================================================================

void RtFwdSetupWidget::changeEEGSphereRad()
{
    m_pRtFwd->m_pFwdSettings->eeg_sphere_rad = m_ui.m_doubleSpinBox_dEegSphereRad->value();
}

//=============================================================================================================

void RtFwdSetupWidget::changeEEGSphereOrigin()
{
    m_pRtFwd->m_pFwdSettings->r0.x() = m_ui.m_doubleSpinBox_dVecR0x->value();
    m_pRtFwd->m_pFwdSettings->r0.y() = m_ui.m_doubleSpinBox_dVecR0y->value();
    m_pRtFwd->m_pFwdSettings->r0.z() = m_ui.m_doubleSpinBox_dVecR0z->value();
    std::cout << m_pRtFwd->m_vecR0 << std::endl;
}
//=============================================================================================================

RtFwdSetupWidget::~RtFwdSetupWidget()
{
}
<|endoftext|>


<commit_before>/**
 * (c) 2019 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include <memory>

#include <gtest/gtest.h>

#include <mega/command.h>
#include <mega/json.h>
#include <mega/megaapp.h>
#include <mega/megaclient.h>
#include <mega/types.h>

using namespace std;
using namespace mega;

namespace {

class MockApp_CommandGetRegisteredContacts : public MegaApp
{
public:
    using DataType = vector<tuple<string, string, string>>;

    int mCallCount = 0;
    ErrorCodes mLastError = ErrorCodes::API_EINTERNAL;
    std::unique_ptr<DataType> mRegisteredContacts;

    void getregisteredcontacts_result(const ErrorCodes e, DataType* const data) override
    {
        ++mCallCount;
        mLastError = e;
        if (data)
        {
            mRegisteredContacts = std::unique_ptr<DataType>{new DataType{*data}};
        }
        else
        {
            assert(e != ErrorCodes::API_OK);
        }
    }
};

} // anonymous

TEST(Commands, CommandGetRegisteredContacts_processResult_happyPath)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"foo@mega.co.nz","id":"13","ud":"foo@mega.co.nz"},{"eud":"+64271234567","id":"42","ud":"+64 27 123 4567"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    const vector<tuple<string, string, string>> expected{
        {"foo@mega.co.nz", "13", "foo@mega.co.nz"},
        {"+64271234567", "42", "+64 27 123 4567"},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(expected, *app.mRegisteredContacts);
    ASSERT_EQ((long)jsonLength, std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_onlyOneContact)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"foo@mega.co.nz","id":"13","ud":"foo@mega.co.nz"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    const vector<tuple<string, string, string>> expected{
        {"foo@mega.co.nz", "13", "foo@mega.co.nz"},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(expected, *app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_extraFieldShouldBeIgnored)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"foo@mega.co.nz","id":"13","ud":"foo@mega.co.nz","blah":"42"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    const vector<tuple<string, string, string>> expected{
        {"foo@mega.co.nz", "13", "foo@mega.co.nz"},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(expected, *app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_invalidResponse)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"foo@mega.co.nz","id":"13","blah":"foo@mega.co.nz"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EINTERNAL, app.mLastError);
    ASSERT_EQ(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_errorCodeReceived)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = "-8";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EEXPIRED, app.mLastError);
    ASSERT_EQ(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

namespace {

class MockApp_CommandGetCountryCallingCodes : public MegaApp
{
public:
    using DataType = map<string, vector<string>>;

    int mCallCount = 0;
    ErrorCodes mLastError = ErrorCodes::API_EINTERNAL;
    std::unique_ptr<DataType> mCountryCallingCodes;

    void getcountrycallingcodes_result(const ErrorCodes e, DataType* const data) override
    {
        ++mCallCount;
        mLastError = e;
        if (data)
        {
            mCountryCallingCodes = std::unique_ptr<DataType>{new DataType{*data}};
        }
        else
        {
            assert(e != ErrorCodes::API_OK);
        }
    }
};

} // anonymous

TEST(Commands, CommandGetCountryCallingCodes_processResult_happyPath)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","l":[376]},{"cc":"AE","l":[971,13]},{"cc":"AF","l":[93,13,42]})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    const map<string, vector<string>> expected{
        {"AD", {"376"}},
        {"AE", {"971", "13"}},
        {"AF", {"93", "13", "42"}},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(expected, *app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_onlyOneCountry)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","l":[12,376]})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    const map<string, vector<string>> expected{
        {"AD", {"12", "376"}},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(expected, *app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_extraFieldShouldBeIgnored)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","l":[12,376],"blah":"42"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    const map<string, vector<string>> expected{
        {"AD", {"12", "376"}},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(expected, *app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_invalidResponse)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","blah":[12,376]})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EINTERNAL, app.mLastError);
    ASSERT_EQ(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_errorCodeReceived)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = "-8";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EEXPIRED, app.mLastError);
    ASSERT_EQ(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}
<commit_msg>Fix unit tests for `usabd` command (v:1)<commit_after>/**
 * (c) 2019 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include <memory>

#include <gtest/gtest.h>

#include <mega/command.h>
#include <mega/json.h>
#include <mega/megaapp.h>
#include <mega/megaclient.h>
#include <mega/types.h>

using namespace std;
using namespace mega;

namespace {

class MockApp_CommandGetRegisteredContacts : public MegaApp
{
public:
    using DataType = vector<tuple<string, string, string>>;

    int mCallCount = 0;
    ErrorCodes mLastError = ErrorCodes::API_EINTERNAL;
    std::unique_ptr<DataType> mRegisteredContacts;

    void getregisteredcontacts_result(const ErrorCodes e, DataType* const data) override
    {
        ++mCallCount;
        mLastError = e;
        if (data)
        {
            mRegisteredContacts = std::unique_ptr<DataType>{new DataType{*data}};
        }
        else
        {
            assert(e != ErrorCodes::API_OK);
        }
    }
};

} // anonymous

TEST(Commands, CommandGetRegisteredContacts_processResult_happyPath)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"Zm9vQG1lZ2EuY28ubno","id":"13","ud":"Zm9vQG1lZ2EuY28ubno"},{"eud":"KzY0MjcxMjM0NTY3","id":"42","ud":"KzY0IDI3IDEyMyA0NTY3"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    const vector<tuple<string, string, string>> expected{
        {"foo@mega.co.nz", "13", "foo@mega.co.nz"},
        {"+64271234567", "42", "+64 27 123 4567"},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(expected, *app.mRegisteredContacts);
    ASSERT_EQ((long)jsonLength, std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_onlyOneContact)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"Zm9vQG1lZ2EuY28ubno","id":"13","ud":"Zm9vQG1lZ2EuY28ubno"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    const vector<tuple<string, string, string>> expected{
        {"foo@mega.co.nz", "13", "foo@mega.co.nz"},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(expected, *app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_extraFieldShouldBeIgnored)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"Zm9vQG1lZ2EuY28ubno","id":"13","ud":"Zm9vQG1lZ2EuY28ubno","YmxhaA":"42"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    const vector<tuple<string, string, string>> expected{
        {"foo@mega.co.nz", "13", "foo@mega.co.nz"},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(expected, *app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_invalidResponse)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = R"({"eud":"Zm9vQG1lZ2EuY28ubno","id":"13","YmxhaA":"42"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EINTERNAL, app.mLastError);
    ASSERT_EQ(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetRegisteredContacts_processResult_errorCodeReceived)
{
    MockApp_CommandGetRegisteredContacts app;

    JSON json;
    json.pos = "-8";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetRegisteredContacts::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EEXPIRED, app.mLastError);
    ASSERT_EQ(nullptr, app.mRegisteredContacts);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

namespace {

class MockApp_CommandGetCountryCallingCodes : public MegaApp
{
public:
    using DataType = map<string, vector<string>>;

    int mCallCount = 0;
    ErrorCodes mLastError = ErrorCodes::API_EINTERNAL;
    std::unique_ptr<DataType> mCountryCallingCodes;

    void getcountrycallingcodes_result(const ErrorCodes e, DataType* const data) override
    {
        ++mCallCount;
        mLastError = e;
        if (data)
        {
            mCountryCallingCodes = std::unique_ptr<DataType>{new DataType{*data}};
        }
        else
        {
            assert(e != ErrorCodes::API_OK);
        }
    }
};

} // anonymous

TEST(Commands, CommandGetCountryCallingCodes_processResult_happyPath)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","l":[376]},{"cc":"AE","l":[971,13]},{"cc":"AF","l":[93,13,42]})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    const map<string, vector<string>> expected{
        {"AD", {"376"}},
        {"AE", {"971", "13"}},
        {"AF", {"93", "13", "42"}},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(expected, *app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_onlyOneCountry)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","l":[12,376]})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    const map<string, vector<string>> expected{
        {"AD", {"12", "376"}},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(expected, *app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_extraFieldShouldBeIgnored)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","l":[12,376],"blah":"42"})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    const map<string, vector<string>> expected{
        {"AD", {"12", "376"}},
    };

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_OK, app.mLastError);
    ASSERT_NE(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(expected, *app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_invalidResponse)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = R"({"cc":"AD","blah":[12,376]})";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EINTERNAL, app.mLastError);
    ASSERT_EQ(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}

TEST(Commands, CommandGetCountryCallingCodes_processResult_errorCodeReceived)
{
    MockApp_CommandGetCountryCallingCodes app;

    JSON json;
    json.pos = "-8";
    const auto jsonBegin = json.pos;
    const auto jsonLength = strlen(json.pos);

    CommandGetCountryCallingCodes::processResult(app, json);

    ASSERT_EQ(1, app.mCallCount);
    ASSERT_EQ(API_EEXPIRED, app.mLastError);
    ASSERT_EQ(nullptr, app.mCountryCallingCodes);
    ASSERT_EQ(ptrdiff_t(jsonLength), std::distance(jsonBegin, json.pos)); // assert json has been parsed all the way
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#include "core/do_with.hh"
#include "cql_test_env.hh"
#include "cql3/query_processor.hh"
#include "cql3/query_options.hh"
#include "core/distributed.hh"
#include "core/shared_ptr.hh"
#include "utils/UUID_gen.hh"
#include "message/messaging_service.hh"
#include "service/storage_service.hh"

class in_memory_cql_env : public cql_test_env {
public:
    static auto constexpr ks_name = "ks";
private:
    ::shared_ptr<distributed<database>> _db;
    ::shared_ptr<distributed<cql3::query_processor>> _qp;
    ::shared_ptr<distributed<service::storage_proxy>> _proxy;
private:
    struct core_local_state {
        service::client_state client_state;

        core_local_state()
            : client_state(service::client_state::for_internal_calls()) {
            client_state.set_keyspace(ks_name);
        }

        future<> stop() {
            return make_ready_future<>();
        }
    };
    distributed<core_local_state> _core_local;
private:
    auto make_query_state() {
        return ::make_shared<service::query_state>(_core_local.local().client_state);
    }
public:
    in_memory_cql_env(
        ::shared_ptr<distributed<database>> db,
        ::shared_ptr<distributed<cql3::query_processor>> qp,
        ::shared_ptr<distributed<service::storage_proxy>> proxy)
            : _db(db)
            , _qp(qp)
            , _proxy(proxy)
    { }

    virtual future<::shared_ptr<transport::messages::result_message>> execute_cql(const sstring& text) override {
        auto qs = make_query_state();
        return _qp->local().process(text, *qs, cql3::query_options::DEFAULT).finally([qs] {});
    }

    virtual future<::shared_ptr<transport::messages::result_message>> execute_cql(
        const sstring& text,
        std::unique_ptr<cql3::query_options> qo) override
    {
        auto qs = make_query_state();
        auto& lqo = *qo;
        return _qp->local().process(text, *qs, lqo).finally([qs, qo = std::move(qo)] {});
    }

    virtual future<bytes> prepare(sstring query) override {
        return _qp->invoke_on_all([query, this] (auto& local_qp) {
            auto qs = this->make_query_state();
            return local_qp.prepare(query, *qs).finally([qs] {}).discard_result();
        }).then([query, this] {
            return _qp->local().compute_id(query, ks_name);
        });
    }

    virtual future<::shared_ptr<transport::messages::result_message>> execute_prepared(
        bytes id,
        std::vector<bytes_opt> values) override
    {
        auto prepared = _qp->local().get_prepared(id);
        assert(bool(prepared));
        auto stmt = prepared->statement;
        assert(stmt->get_bound_terms() == values.size());

        int32_t protocol_version = 3;
        auto options = ::make_shared<cql3::query_options>(db::consistency_level::ONE, std::experimental::nullopt, std::move(values), false,
                                                          cql3::query_options::specific_options::DEFAULT, protocol_version, serialization_format::use_32_bit());
        options->prepare(prepared->bound_names);

        auto qs = make_query_state();
        return _qp->local().process_statement(stmt, *qs, *options)
            .finally([options, qs] {});
    }

    virtual future<> create_table(std::function<schema(const sstring&)> schema_maker) override {
        auto id = utils::UUID_gen::get_time_UUID();
        return _db->invoke_on_all([schema_maker, id, this] (database& db) {
            auto cf_schema = make_lw_shared(schema_maker(ks_name));
            cf_schema->set_id(id);
            auto& ks = db.find_keyspace(ks_name);
            auto cfg = ks.make_column_family_config(*cf_schema);
            db.add_column_family(column_family(std::move(cf_schema), std::move(cfg)));
        });
    }

    virtual future<> require_keyspace_exists(const sstring& ks_name) override {
        auto& db = _db->local();
        assert(db.has_keyspace(ks_name));
        return make_ready_future<>();
    }

    virtual future<> require_table_exists(const sstring& ks_name, const sstring& table_name) override {
        auto& db = _db->local();
        assert(db.has_schema(ks_name, table_name));
        return make_ready_future<>();
    }

    virtual future<> require_column_has_value(const sstring& table_name,
                                      std::vector<boost::any> pk,
                                      std::vector<boost::any> ck,
                                      const sstring& column_name,
                                      boost::any expected) override {
        auto& db = _db->local();
        auto& cf = db.find_column_family(ks_name, table_name);
        auto schema = cf.schema();
        auto pkey = partition_key::from_deeply_exploded(*schema, pk);
        auto dk = dht::global_partitioner().decorate_key(*schema, pkey);
        auto shard = db.shard_of(dk._token);
        return _db->invoke_on(shard, [pkey = std::move(pkey),
                                      ck = std::move(ck),
                                      ks_name = std::move(ks_name),
                                      column_name = std::move(column_name),
                                      expected = std::move(expected),
                                      table_name = std::move(table_name)] (database& db) mutable {
          auto& cf = db.find_column_family(ks_name, table_name);
          auto schema = cf.schema();
          return cf.find_partition_slow(pkey).then([schema, ck, column_name, expected] (column_family::const_mutation_partition_ptr p) {
            assert(p != nullptr);
            auto row = p->find_row(clustering_key::from_deeply_exploded(*schema, ck));
            assert(row != nullptr);
            auto col_def = schema->get_column_definition(utf8_type->decompose(column_name));
            assert(col_def != nullptr);
            const atomic_cell_or_collection* cell = row->find_cell(col_def->id);
            if (!cell) {
                assert(((void)"column not set", 0));
            }
            bytes actual;
            if (!col_def->type->is_multi_cell()) {
                auto c = cell->as_atomic_cell();
                assert(c.is_live());
                actual = { c.value().begin(), c.value().end() };
            } else {
                auto c = cell->as_collection_mutation();
                auto type = dynamic_pointer_cast<const collection_type_impl>(col_def->type);
                actual = type->to_value(type->deserialize_mutation_form(c),
                                        serialization_format::internal());
            }
            assert(col_def->type->equal(actual, col_def->type->decompose(expected)));
          });
        });
    }

    virtual database& local_db() override {
        return _db->local();
    }

    future<> start() {
        return _core_local.start().then([this] () {
            auto query = sprint("create keyspace %s with replication = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor' : 1 };", sstring{ks_name});
            return execute_cql(query).discard_result().then([] {
                return make_ready_future<>();
            });
        });
    }

    virtual future<> stop() override {
        return _core_local.stop().then([this] {
            return _qp->stop().then([this] {
                return _proxy->stop().then([this] {
                    return _db->stop().then([] {
                        return locator::i_endpoint_snitch::stop_snitch();
                    });
                });
            });
        });
    }
};

future<> init_once() {
    static bool done = false;
    if (!done) {
        done = true;
        return service::init_storage_service().then([] {
                return net::init_messaging_service("127.0.0.1", db::config::seed_provider_type()).then([] {
                });
        });
    } else {
        return make_ready_future();
    }
}
future<::shared_ptr<cql_test_env>> make_env_for_test() {
    return init_once().then([] {
        using namespace locator;
        return i_endpoint_snitch::create_snitch("org.apache.cassandra.locator.SimpleSnitch").then([] {
            auto db = ::make_shared<distributed<database>>();
            auto cfg = make_lw_shared<db::config>();
            cfg->data_file_directories() = {};
            return db->start(std::move(*cfg)).then([db] {
                auto proxy = ::make_shared<distributed<service::storage_proxy>>();
                auto qp = ::make_shared<distributed<cql3::query_processor>>();
                return proxy->start(std::ref(*db)).then([qp, db, proxy] {
                    return qp->start(std::ref(*proxy), std::ref(*db)).then([db, proxy, qp] {
                        auto env = ::make_shared<in_memory_cql_env>(db, qp, proxy);
                        return env->start().then([env] () -> ::shared_ptr<cql_test_env> {
                            return env;
                        });
                    });
                });
            });
        });
    });
}

future<> do_with_cql_env(std::function<future<>(cql_test_env&)> func) {
    return make_env_for_test().then([func = std::move(func)] (auto e) mutable {
        return do_with(std::move(func), [e] (auto& f) {
            return f(*e);
        }).finally([e] {
            return e->stop().finally([e] {});
        });
    });
}
<commit_msg>tests: Add missing blank line<commit_after>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#include "core/do_with.hh"
#include "cql_test_env.hh"
#include "cql3/query_processor.hh"
#include "cql3/query_options.hh"
#include "core/distributed.hh"
#include "core/shared_ptr.hh"
#include "utils/UUID_gen.hh"
#include "message/messaging_service.hh"
#include "service/storage_service.hh"

class in_memory_cql_env : public cql_test_env {
public:
    static auto constexpr ks_name = "ks";
private:
    ::shared_ptr<distributed<database>> _db;
    ::shared_ptr<distributed<cql3::query_processor>> _qp;
    ::shared_ptr<distributed<service::storage_proxy>> _proxy;
private:
    struct core_local_state {
        service::client_state client_state;

        core_local_state()
            : client_state(service::client_state::for_internal_calls()) {
            client_state.set_keyspace(ks_name);
        }

        future<> stop() {
            return make_ready_future<>();
        }
    };
    distributed<core_local_state> _core_local;
private:
    auto make_query_state() {
        return ::make_shared<service::query_state>(_core_local.local().client_state);
    }
public:
    in_memory_cql_env(
        ::shared_ptr<distributed<database>> db,
        ::shared_ptr<distributed<cql3::query_processor>> qp,
        ::shared_ptr<distributed<service::storage_proxy>> proxy)
            : _db(db)
            , _qp(qp)
            , _proxy(proxy)
    { }

    virtual future<::shared_ptr<transport::messages::result_message>> execute_cql(const sstring& text) override {
        auto qs = make_query_state();
        return _qp->local().process(text, *qs, cql3::query_options::DEFAULT).finally([qs] {});
    }

    virtual future<::shared_ptr<transport::messages::result_message>> execute_cql(
        const sstring& text,
        std::unique_ptr<cql3::query_options> qo) override
    {
        auto qs = make_query_state();
        auto& lqo = *qo;
        return _qp->local().process(text, *qs, lqo).finally([qs, qo = std::move(qo)] {});
    }

    virtual future<bytes> prepare(sstring query) override {
        return _qp->invoke_on_all([query, this] (auto& local_qp) {
            auto qs = this->make_query_state();
            return local_qp.prepare(query, *qs).finally([qs] {}).discard_result();
        }).then([query, this] {
            return _qp->local().compute_id(query, ks_name);
        });
    }

    virtual future<::shared_ptr<transport::messages::result_message>> execute_prepared(
        bytes id,
        std::vector<bytes_opt> values) override
    {
        auto prepared = _qp->local().get_prepared(id);
        assert(bool(prepared));
        auto stmt = prepared->statement;
        assert(stmt->get_bound_terms() == values.size());

        int32_t protocol_version = 3;
        auto options = ::make_shared<cql3::query_options>(db::consistency_level::ONE, std::experimental::nullopt, std::move(values), false,
                                                          cql3::query_options::specific_options::DEFAULT, protocol_version, serialization_format::use_32_bit());
        options->prepare(prepared->bound_names);

        auto qs = make_query_state();
        return _qp->local().process_statement(stmt, *qs, *options)
            .finally([options, qs] {});
    }

    virtual future<> create_table(std::function<schema(const sstring&)> schema_maker) override {
        auto id = utils::UUID_gen::get_time_UUID();
        return _db->invoke_on_all([schema_maker, id, this] (database& db) {
            auto cf_schema = make_lw_shared(schema_maker(ks_name));
            cf_schema->set_id(id);
            auto& ks = db.find_keyspace(ks_name);
            auto cfg = ks.make_column_family_config(*cf_schema);
            db.add_column_family(column_family(std::move(cf_schema), std::move(cfg)));
        });
    }

    virtual future<> require_keyspace_exists(const sstring& ks_name) override {
        auto& db = _db->local();
        assert(db.has_keyspace(ks_name));
        return make_ready_future<>();
    }

    virtual future<> require_table_exists(const sstring& ks_name, const sstring& table_name) override {
        auto& db = _db->local();
        assert(db.has_schema(ks_name, table_name));
        return make_ready_future<>();
    }

    virtual future<> require_column_has_value(const sstring& table_name,
                                      std::vector<boost::any> pk,
                                      std::vector<boost::any> ck,
                                      const sstring& column_name,
                                      boost::any expected) override {
        auto& db = _db->local();
        auto& cf = db.find_column_family(ks_name, table_name);
        auto schema = cf.schema();
        auto pkey = partition_key::from_deeply_exploded(*schema, pk);
        auto dk = dht::global_partitioner().decorate_key(*schema, pkey);
        auto shard = db.shard_of(dk._token);
        return _db->invoke_on(shard, [pkey = std::move(pkey),
                                      ck = std::move(ck),
                                      ks_name = std::move(ks_name),
                                      column_name = std::move(column_name),
                                      expected = std::move(expected),
                                      table_name = std::move(table_name)] (database& db) mutable {
          auto& cf = db.find_column_family(ks_name, table_name);
          auto schema = cf.schema();
          return cf.find_partition_slow(pkey).then([schema, ck, column_name, expected] (column_family::const_mutation_partition_ptr p) {
            assert(p != nullptr);
            auto row = p->find_row(clustering_key::from_deeply_exploded(*schema, ck));
            assert(row != nullptr);
            auto col_def = schema->get_column_definition(utf8_type->decompose(column_name));
            assert(col_def != nullptr);
            const atomic_cell_or_collection* cell = row->find_cell(col_def->id);
            if (!cell) {
                assert(((void)"column not set", 0));
            }
            bytes actual;
            if (!col_def->type->is_multi_cell()) {
                auto c = cell->as_atomic_cell();
                assert(c.is_live());
                actual = { c.value().begin(), c.value().end() };
            } else {
                auto c = cell->as_collection_mutation();
                auto type = dynamic_pointer_cast<const collection_type_impl>(col_def->type);
                actual = type->to_value(type->deserialize_mutation_form(c),
                                        serialization_format::internal());
            }
            assert(col_def->type->equal(actual, col_def->type->decompose(expected)));
          });
        });
    }

    virtual database& local_db() override {
        return _db->local();
    }

    future<> start() {
        return _core_local.start().then([this] () {
            auto query = sprint("create keyspace %s with replication = { 'class' : 'org.apache.cassandra.locator.SimpleStrategy', 'replication_factor' : 1 };", sstring{ks_name});
            return execute_cql(query).discard_result().then([] {
                return make_ready_future<>();
            });
        });
    }

    virtual future<> stop() override {
        return _core_local.stop().then([this] {
            return _qp->stop().then([this] {
                return _proxy->stop().then([this] {
                    return _db->stop().then([] {
                        return locator::i_endpoint_snitch::stop_snitch();
                    });
                });
            });
        });
    }
};

future<> init_once() {
    static bool done = false;
    if (!done) {
        done = true;
        return service::init_storage_service().then([] {
                return net::init_messaging_service("127.0.0.1", db::config::seed_provider_type()).then([] {
                });
        });
    } else {
        return make_ready_future();
    }
}

future<::shared_ptr<cql_test_env>> make_env_for_test() {
    return init_once().then([] {
        using namespace locator;
        return i_endpoint_snitch::create_snitch("org.apache.cassandra.locator.SimpleSnitch").then([] {
            auto db = ::make_shared<distributed<database>>();
            auto cfg = make_lw_shared<db::config>();
            cfg->data_file_directories() = {};
            return db->start(std::move(*cfg)).then([db] {
                auto proxy = ::make_shared<distributed<service::storage_proxy>>();
                auto qp = ::make_shared<distributed<cql3::query_processor>>();
                return proxy->start(std::ref(*db)).then([qp, db, proxy] {
                    return qp->start(std::ref(*proxy), std::ref(*db)).then([db, proxy, qp] {
                        auto env = ::make_shared<in_memory_cql_env>(db, qp, proxy);
                        return env->start().then([env] () -> ::shared_ptr<cql_test_env> {
                            return env;
                        });
                    });
                });
            });
        });
    });
}

future<> do_with_cql_env(std::function<future<>(cql_test_env&)> func) {
    return make_env_for_test().then([func = std::move(func)] (auto e) mutable {
        return do_with(std::move(func), [e] (auto& f) {
            return f(*e);
        }).finally([e] {
            return e->stop().finally([e] {});
        });
    });
}
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#ifndef UNITTEST_SUPPORT_INCLUDED
#define UNITTEST_SUPPORT_INCLUDED

// support functions for unit testing

#include <boost/cstdint.hpp>
#include <string>

// verify if two files are the same
extern bool compare_files(const std::string& file1, const std::string& file2);

struct TestConfig {
    TestConfig();
    static std::string g_data_path;
};

#endif
<commit_msg>added note about FP compares<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#ifndef UNITTEST_SUPPORT_INCLUDED
#define UNITTEST_SUPPORT_INCLUDED

// support functions for unit testing

#include <boost/cstdint.hpp>
#include <string>

// verify if two files are the same
extern bool compare_files(const std::string& file1, const std::string& file2);

struct TestConfig {
    TestConfig();
    static std::string g_data_path;
};

// for comparing to floating point values, use
//   BOOST_CHECK_CLOSE(a,b,perc)
// where perc is a percentage value in the range [0..100] (typically)

#endif
<|endoftext|>


<commit_before>#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include "SearchParser.h"

using namespace xercesc;
using namespace std;

// Error codes

enum {
   ERROR_ARGS = 1,
   ERROR_XERCES_INIT,
   ERROR_PARSE,
   ERROR_EMPTY_DOCUMENT
};

/**
 *  Constructor initializes xerces-C libraries.
 *  The XML tags and attributes which we seek are defined.
 *  The xerces-C DOM parser infrastructure is initialized.
 */

SearchParser::SearchParser()
{
   try
   {
      XMLPlatformUtils::Initialize();  // Initialize Xerces infrastructure
   }
   catch( XMLException& e )
   {
      char* message = XMLString::transcode( e.getMessage() );
      cerr << "XML toolkit initialization error: " << message << endl;
      XMLString::release( &message );
      // throw exception here to return ERROR_XERCES_INIT
   }

   // Tags and attributes used in XML file.
   // Can't call transcode till after Xerces Initialize()
   TAG_root        = XMLString::transcode("feed");
   TAG_status = XMLString::transcode("entry");
   TAG_text = XMLString::transcode("title");
   TAG_user = XMLString::transcode("name");
   TAG_username = XMLString::transcode("uri"); //Using the <uri> instead of <author> get us around some encoding bugs:)
   TAG_image = XMLString::transcode("link");
   TAG_date = XMLString::transcode("published");
   TAG_id = XMLString::transcode("id");
   TAG_error = XMLString::transcode("error");
   ATTR_href = XMLString::transcode("href");

   m_ConfigFileParser = new XercesDOMParser;
   tweetPtr = NULL;
   numberOfEntries = 0;
}

/**
 *  Class destructor frees memory used to hold the XML tag and
 *  attribute definitions. It als terminates use of the xerces-C
 *  framework.
 */

SearchParser::~SearchParser()
{
   delete m_ConfigFileParser;
   XMLString::release( &TAG_root );
   XMLString::release( &TAG_status );
   XMLString::release( &TAG_text );
   XMLString::release( &TAG_username );
   XMLString::release( &TAG_user );
   XMLString::release( &TAG_image);
   XMLString::release( &TAG_date );
   XMLString::release( &TAG_id );
   XMLString::release( &TAG_error );
   try
   {
      XMLPlatformUtils::Terminate();  // Terminate Xerces
   }
   catch( xercesc::XMLException& e )
   {
      char* message = xercesc::XMLString::transcode( e.getMessage() );

      cerr << "XML ttolkit teardown error: " << message << endl;
      XMLString::release( &message );
   }

   for(int i = 0; i < numberOfEntries; i++) {
   		delete tweetPtr[i];
   }
   delete tweetPtr;
}

int SearchParser::count() {
	return numberOfEntries;
}

HTTweet** SearchParser::getTweets() {

	return tweetPtr;
}

/**
 *  This function:
 *  - Tests the access and availability of the XML configuration file.
 *  - Configures the xerces-c DOM parser.
 *  - Reads and extracts the pertinent information from the XML config file.
 *
 *  @param in configFile The text string name of the HLA configuration file.
 */

void SearchParser::readData(const char *xmlData)
        throw( std::runtime_error )
{
   // Configure DOM parser.

   m_ConfigFileParser->setValidationScheme( XercesDOMParser::Val_Never );
   m_ConfigFileParser->setDoNamespaces( false );
   m_ConfigFileParser->setDoSchema( false );
   m_ConfigFileParser->setLoadExternalDTD( false );

   try
   {
   		// Creating a memory buffer inputsource for the parser
   		const char *chId = std::string("TimeLineData").c_str();
   		MemBufInputSource memSource((XMLByte *)xmlData, (XMLSize_t)strlen(xmlData)*sizeof(char), chId);

   		std::cout << "Passing buffer to parser" << std::endl;
      m_ConfigFileParser->parse( memSource );

      // no need to free this pointer - owned by the parent parser object
      DOMDocument* xmlDoc = m_ConfigFileParser->getDocument();

      // Get the top-level element: NAme is "root". No attributes for "root"

      DOMElement* elementRoot = xmlDoc->getDocumentElement();
      if( !elementRoot ) {
      		string theName("HaikuTwitter");
      		string theText("Could not retrieve data. Please check your internet connection.");
      		string theUrl("error");
      		string theDate("");
      		tweetPtr = new HTTweet*[1];
      		tweetPtr[0] = new HTTweet(theName, theText, theUrl, theDate);
      		numberOfEntries++;
      		return;
      }

      // Parse XML file for tags of interest: "error"
		DOMNodeList* statusNodes = elementRoot->getElementsByTagName(TAG_error);

		for(XMLSize_t i = 0; i < statusNodes->getLength(); i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_error))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		/*Transcode to UTF-8*/
            		XMLTransService::Codes resValue;
            		XMLByte utf8String[150];
            		XMLSize_t blabla = 0;
            		XMLTranscoder *t = XMLPlatformUtils::fgTransService->makeNewTranscoderFor("UTF-8", resValue, 150);
            		t->transcodeTo(textNode->getWholeText(), (XMLSize_t)150, utf8String, (XMLSize_t)150, blabla, XMLTranscoder::UnRep_Throw);
            		delete t;
            		string textString((char *)utf8String);
					string theName("HaikuTwitter");
      				string theUrl("error");
      				string theDate("");
      				tweetPtr = new HTTweet*[1];
      				tweetPtr[0] = new HTTweet(theName, textString, theUrl, theDate);
      				numberOfEntries++;
      				return;
            	}
         	}
		}

      // Parse XML file for tags of interest: "text"
		statusNodes = elementRoot->getElementsByTagName(TAG_text);
		XMLSize_t nodeCount = statusNodes->getLength();
		tweetPtr = new HTTweet*[nodeCount];

		for(XMLSize_t i = 1; i < nodeCount; i++) { //We skip first item (item 0), not interested in atom main title
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_text))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		/*Transcode to UTF-8*/
            		XMLTransService::Codes resValue;
            		XMLByte utf8String[150];
            		XMLSize_t blabla = 0;
            		XMLTranscoder *t = XMLPlatformUtils::fgTransService->makeNewTranscoderFor("UTF-8", resValue, 150);
            		t->transcodeTo(textNode->getWholeText(), (XMLSize_t)150, utf8String, (XMLSize_t)150, blabla, XMLTranscoder::UnRep_Throw);
            		delete t;

            		string textString((char *)utf8String);
            		textString.erase(textString.length()-5, 5); //Last three chars is garbage!
            		tweetPtr[numberOfEntries] = new HTTweet();
            		tweetPtr[numberOfEntries]->setText(textString);
            		numberOfEntries++;
            	}
         	}
		}

		nodeCount--; //Because we skipped item(0)

		// Parse XML file for tags of interest: "id"
		statusNodes = elementRoot->getElementsByTagName(TAG_id);

		for(XMLSize_t i = 0; i < nodeCount; i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_id))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		char *rawString = XMLString::transcode(textNode->getWholeText());
            		//Remove last character, holds ugly symbol.
            		//rawString[strlen(rawString)-5] = '\0';

            		tweetPtr[i]->setId(atoi(rawString));
            		delete rawString;
            	}
         	}
		}

		// Parse XML file for tags of interest: "screen_name"
		statusNodes = elementRoot->getElementsByTagName(TAG_username);

		for(XMLSize_t i = 0; i < nodeCount; i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_username))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		char *rawString = XMLString::transcode(textNode->getWholeText());

            		/*Remove last 11 or 9 characters, junk.*/
            		if(i < nodeCount-1)
            			rawString[strlen(rawString)-11] = '\0';
            		else
            			rawString[strlen(rawString)-9] = '\0';

            		string textString(rawString+19); //Skip "http://twitter.com/" and we've got the username

            		tweetPtr[i]->setScreenName(textString);
            		delete rawString;
            	}
         	}
		}

		// Parse XML file for tags of interest: "link"
		statusNodes = elementRoot->getElementsByTagName(TAG_image);
		//Result will give us 5 links in header that we don't care about.
		//If there is more than 14 entries, we will get a link to the next page, so skip that too.
		int skipCount = 5;
		if(nodeCount > 14)
			skipCount++;

		for(XMLSize_t i = skipCount; i < (nodeCount*2)+skipCount; i+=2) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_image))
            	{
            		const XMLCh* href = currentElement->getAttribute(ATTR_href);
            		char *rawString = XMLString::transcode(href);

            		string textString(rawString);
            		tweetPtr[(i-skipCount)/2]->setProfileImageUrl(textString);
            		delete rawString;
            	}
         	}
		}

		// Parse XML file for tags of interest: "published"
		statusNodes = elementRoot->getElementsByTagName(TAG_date);

		for(XMLSize_t i = 0; i < nodeCount; i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_date))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		char *rawString = XMLString::transcode(textNode->getWholeText());
            		//Remove last character, holds ugly symbol.
            		rawString[strlen(rawString)-3] = '\0';

            		string textString(rawString);
            		tweetPtr[i]->setPublishedDate(textString);
            		delete rawString;
            	}
         	}
		}
   }
   catch( xercesc::XMLException& e )
   {
      char* message = xercesc::XMLString::transcode( e.getMessage() );
      ostringstream errBuf;
      errBuf << "Error parsing file: " << message << flush;
      XMLString::release( &message );
   }
   std::cout << "Done parsing XML" << std::endl;
}
<commit_msg>Fixed bug that crashed the app when parsing for profile images on certain searches.<commit_after>#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include "SearchParser.h"

using namespace xercesc;
using namespace std;

// Error codes

enum {
   ERROR_ARGS = 1,
   ERROR_XERCES_INIT,
   ERROR_PARSE,
   ERROR_EMPTY_DOCUMENT
};

/**
 *  Constructor initializes xerces-C libraries.
 *  The XML tags and attributes which we seek are defined.
 *  The xerces-C DOM parser infrastructure is initialized.
 */

SearchParser::SearchParser()
{
   try
   {
      XMLPlatformUtils::Initialize();  // Initialize Xerces infrastructure
   }
   catch( XMLException& e )
   {
      char* message = XMLString::transcode( e.getMessage() );
      cerr << "XML toolkit initialization error: " << message << endl;
      XMLString::release( &message );
      // throw exception here to return ERROR_XERCES_INIT
   }

   // Tags and attributes used in XML file.
   // Can't call transcode till after Xerces Initialize()
   TAG_root        = XMLString::transcode("feed");
   TAG_status = XMLString::transcode("entry");
   TAG_text = XMLString::transcode("title");
   TAG_user = XMLString::transcode("name");
   TAG_username = XMLString::transcode("uri"); //Using the <uri> instead of <author> get us around some encoding bugs:)
   TAG_image = XMLString::transcode("link");
   TAG_date = XMLString::transcode("published");
   TAG_id = XMLString::transcode("id");
   TAG_error = XMLString::transcode("error");
   ATTR_href = XMLString::transcode("href");

   m_ConfigFileParser = new XercesDOMParser;
   tweetPtr = NULL;
   numberOfEntries = 0;
}

/**
 *  Class destructor frees memory used to hold the XML tag and
 *  attribute definitions. It als terminates use of the xerces-C
 *  framework.
 */

SearchParser::~SearchParser()
{
   delete m_ConfigFileParser;
   XMLString::release( &TAG_root );
   XMLString::release( &TAG_status );
   XMLString::release( &TAG_text );
   XMLString::release( &TAG_username );
   XMLString::release( &TAG_user );
   XMLString::release( &TAG_image);
   XMLString::release( &TAG_date );
   XMLString::release( &TAG_id );
   XMLString::release( &TAG_error );
   try
   {
      XMLPlatformUtils::Terminate();  // Terminate Xerces
   }
   catch( xercesc::XMLException& e )
   {
      char* message = xercesc::XMLString::transcode( e.getMessage() );

      cerr << "XML ttolkit teardown error: " << message << endl;
      XMLString::release( &message );
   }

   for(int i = 0; i < numberOfEntries; i++) {
   		delete tweetPtr[i];
   }
   delete tweetPtr;
}

int SearchParser::count() {
	return numberOfEntries;
}

HTTweet** SearchParser::getTweets() {

	return tweetPtr;
}

/**
 *  This function:
 *  - Tests the access and availability of the XML configuration file.
 *  - Configures the xerces-c DOM parser.
 *  - Reads and extracts the pertinent information from the XML config file.
 *
 *  @param in configFile The text string name of the HLA configuration file.
 */

void SearchParser::readData(const char *xmlData)
        throw( std::runtime_error )
{
   // Configure DOM parser.

   m_ConfigFileParser->setValidationScheme( XercesDOMParser::Val_Never );
   m_ConfigFileParser->setDoNamespaces( false );
   m_ConfigFileParser->setDoSchema( false );
   m_ConfigFileParser->setLoadExternalDTD( false );

   try
   {
   		// Creating a memory buffer inputsource for the parser
   		const char *chId = std::string("TimeLineData").c_str();
   		MemBufInputSource memSource((XMLByte *)xmlData, (XMLSize_t)strlen(xmlData)*sizeof(char), chId);

   		std::cout << "Passing buffer to parser" << std::endl;
      m_ConfigFileParser->parse( memSource );

      // no need to free this pointer - owned by the parent parser object
      DOMDocument* xmlDoc = m_ConfigFileParser->getDocument();

      // Get the top-level element: NAme is "root". No attributes for "root"

      DOMElement* elementRoot = xmlDoc->getDocumentElement();
      if( !elementRoot ) {
      		string theName("HaikuTwitter");
      		string theText("Could not retrieve data. Please check your internet connection.");
      		string theUrl("error");
      		string theDate("");
      		tweetPtr = new HTTweet*[1];
      		tweetPtr[0] = new HTTweet(theName, theText, theUrl, theDate);
      		numberOfEntries++;
      		return;
      }

      // Parse XML file for tags of interest: "error"
		DOMNodeList* statusNodes = elementRoot->getElementsByTagName(TAG_error);

		for(XMLSize_t i = 0; i < statusNodes->getLength(); i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_error))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		/*Transcode to UTF-8*/
            		XMLTransService::Codes resValue;
            		XMLByte utf8String[150];
            		XMLSize_t blabla = 0;
            		XMLTranscoder *t = XMLPlatformUtils::fgTransService->makeNewTranscoderFor("UTF-8", resValue, 150);
            		t->transcodeTo(textNode->getWholeText(), (XMLSize_t)150, utf8String, (XMLSize_t)150, blabla, XMLTranscoder::UnRep_Throw);
            		delete t;
            		string textString((char *)utf8String);
					string theName("HaikuTwitter");
      				string theUrl("error");
      				string theDate("");
      				tweetPtr = new HTTweet*[1];
      				tweetPtr[0] = new HTTweet(theName, textString, theUrl, theDate);
      				numberOfEntries++;
      				return;
            	}
         	}
		}

      // Parse XML file for tags of interest: "text"
		statusNodes = elementRoot->getElementsByTagName(TAG_text);
		XMLSize_t nodeCount = statusNodes->getLength();
		tweetPtr = new HTTweet*[nodeCount];

		for(XMLSize_t i = 1; i < nodeCount; i++) { //We skip first item (item 0), not interested in atom main title
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_text))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		/*Transcode to UTF-8*/
            		XMLTransService::Codes resValue;
            		XMLByte utf8String[150];
            		XMLSize_t blabla = 0;
            		XMLTranscoder *t = XMLPlatformUtils::fgTransService->makeNewTranscoderFor("UTF-8", resValue, 150);
            		t->transcodeTo(textNode->getWholeText(), (XMLSize_t)150, utf8String, (XMLSize_t)150, blabla, XMLTranscoder::UnRep_Throw);
            		delete t;

            		string textString((char *)utf8String);
            		textString.erase(textString.length()-5, 5); //Last three chars is garbage!
            		tweetPtr[numberOfEntries] = new HTTweet();
            		tweetPtr[numberOfEntries]->setText(textString);
            		numberOfEntries++;
            	}
         	}
		}

		nodeCount--; //Because we skipped item(0)

		// Parse XML file for tags of interest: "id"
		statusNodes = elementRoot->getElementsByTagName(TAG_id);

		for(XMLSize_t i = 0; i < nodeCount; i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_id))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		char *rawString = XMLString::transcode(textNode->getWholeText());
            		//Remove last character, holds ugly symbol.
            		//rawString[strlen(rawString)-5] = '\0';

            		tweetPtr[i]->setId(atoi(rawString));
            		delete rawString;
            	}
         	}
		}

		// Parse XML file for tags of interest: "screen_name"
		statusNodes = elementRoot->getElementsByTagName(TAG_username);

		for(XMLSize_t i = 0; i < nodeCount; i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_username))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		char *rawString = XMLString::transcode(textNode->getWholeText());

            		/*Remove last 11 or 9 characters, junk.*/
            		if(i < nodeCount-1)
            			rawString[strlen(rawString)-11] = '\0';
            		else
            			rawString[strlen(rawString)-9] = '\0';

            		string textString(rawString+19); //Skip "http://twitter.com/"... and we've got the username:)

            		tweetPtr[i]->setScreenName(textString);
            		delete rawString;
            	}
         	}
		}

		// Parse XML file for tags of interest: "link"
		statusNodes = elementRoot->getElementsByTagName(TAG_image);
		//Result will give us 5 links in header that we don't care about.
		int skipCount = 5;

		for(XMLSize_t i = skipCount; i < (nodeCount*2)+skipCount; i+=2) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_image))
            	{
            		const XMLCh* href = currentElement->getAttribute(ATTR_href);
            		char *rawString = XMLString::transcode(href);

            		string textString(rawString);
            		if(textString.find("statuses", 0) != std::string::npos) { //There was an extra link the header
            			i--; //Step back
            			skipCount++; //Skip the extra header link.
            		}
            		else
            			tweetPtr[(i-skipCount)/2]->setProfileImageUrl(textString);
            		delete rawString;
            	}
         	}
		}

		// Parse XML file for tags of interest: "published"
		statusNodes = elementRoot->getElementsByTagName(TAG_date);

		for(XMLSize_t i = 0; i < nodeCount; i++) {
			DOMNode* currentNode = statusNodes->item(i);
         	if( currentNode->getNodeType() &&  // true is not NULL
            	currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
         	{
            	// Found node which is an Element. Re-cast node as element
            	DOMElement* currentElement
                	        = dynamic_cast< xercesc::DOMElement* >( currentNode );
            	if( XMLString::equals(currentElement->getTagName(), TAG_date))
            	{
            		DOMText* textNode
            				= dynamic_cast< xercesc::DOMText* >( currentElement->getChildNodes()->item(0) );

            		char *rawString = XMLString::transcode(textNode->getWholeText());
            		//Remove last character, holds ugly symbol.
            		rawString[strlen(rawString)-3] = '\0';

            		string textString(rawString);
            		tweetPtr[i]->setPublishedDate(textString);
            		delete rawString;
            	}
         	}
		}
   }
   catch( xercesc::XMLException& e )
   {
      char* message = xercesc::XMLString::transcode( e.getMessage() );
      ostringstream errBuf;
      errBuf << "Error parsing file: " << message << flush;
      XMLString::release( &message );
   }
   std::cout << "Done parsing XML" << std::endl;
}
<|endoftext|>