<commit_before>/*
 * This file is part of ofono-qt
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library 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. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <QtTest/QtTest>
#include <QtCore/QObject>

#include <ofononetworkregistration.h>

#include <QtDebug>

class TestOfonoNetworkRegistration : public QObject
{
    Q_OBJECT

private slots:

    void modeChanged(QString mode)
    {
	qDebug() << "modeChanged" << mode;
    }

    void statusChanged(QString status)
    {
	qDebug() << "statusChanged" << status;
    }

    void locationAreaCodeChanged(uint locationAreaCode)
    {
	qDebug() << "locationAreaCodeChanged" << locationAreaCode;
    }

    void cellIdChanged(uint cellId)
    {
	qDebug() << "cellIdChanged" << cellId;
    }

    void mccChanged(QString mcc)
    {
	qDebug() << "mccChanged" << mcc;
    }

    void mncChanged(QString mnc)
    {
	qDebug() << "mncChanged" << mnc;
    }

    void technologyChanged(QString technology)
    {
	qDebug() << "technologyChanged" << technology;
    }

    void nameChanged(QString name)
    {
	qDebug() << "nameChanged" << name;
    }

    void strengthChanged(uint strength)
    {
	qDebug() << "strengthChanged" << strength;
    }

    void baseStationChanged(QString baseStation)
    {
	qDebug() << "baseStationChanged" << baseStation;
    }

    void registerComplete(bool success)
    {
	qDebug() << "registerComplete:" << success;
    }

    void deregisterComplete(bool success)
    {
	qDebug() << "deregisterComplete:" << success;
    }

    void getOperatorsComplete(bool success, QStringList oplist)
    {
	qDebug() << "getOperatorsComplete:" << success << oplist;
    }

    void scanComplete(bool success, QStringList oplist)
    {
	qDebug() << "scanComplete:" << success << oplist;
    }

    void initTestCase()
    {
	m = new OfonoNetworkRegistration(OfonoModem::AutomaticSelect, QString(), this);

	connect(m, SIGNAL(registerComplete(bool)), this,
		SLOT(registerComplete(bool)));
	connect(m, SIGNAL(deregisterComplete(bool)), this,
		SLOT(deregisterComplete(bool)));
    connect(m, SIGNAL(getOperatorsComplete(bool, QStringList)),
            this, SLOT(getOperatorsComplete(bool, QStringList)));
    connect(m, SIGNAL(scanComplete(bool, QStringList)),
            this, SLOT(scanComplete(bool, QStringList)));

	connect(m, SIGNAL(modeChanged(QString)),
		this, SLOT(modeChanged(QString)));
	connect(m, SIGNAL(statusChanged(QString)),
		this, SLOT(statusChanged(QString)));
	connect(m, SIGNAL(locationAreaCodeChanged(uint)),
		this, SLOT(locationAreaCodeChanged(uint)));
	connect(m, SIGNAL(cellIdChanged(uint)),
		this, SLOT(cellIdChanged(uint)));
	connect(m, SIGNAL(mccChanged(QString)),
		this, SLOT(mccChanged(QString)));
	connect(m, SIGNAL(mncChanged(QString)),
		this, SLOT(mncChanged(QString)));
	connect(m, SIGNAL(technologyChanged(QString)),
		this, SLOT(technologyChanged(QString)));
	connect(m, SIGNAL(nameChanged(QString)),
		this, SLOT(nameChanged(QString)));
	connect(m, SIGNAL(strengthChanged(uint)),
		this, SLOT(strengthChanged(uint)));
	connect(m, SIGNAL(baseStationChanged(QString)),
		this, SLOT(baseStationChanged(QString)));

    }

    void testOfonoNetworkRegistration()
    {
	qDebug() << "mode():" << m->mode();
	qDebug() << "status():" << m->status();
	qDebug() << "lac():" << m->locationAreaCode();
	qDebug() << "cellid():" << m->cellId();
	qDebug() << "mobileCountryCode():" << m->mcc();
	qDebug() << "mobileNetworkCode():" << m->mnc();
	qDebug() << "technology():" << m->technology();
	qDebug() << "name():" << m->name();
	qDebug() << "strength():" << m->strength();
	qDebug() << "baseStation():" << m->baseStation();

	m->getOperators();
	QTest::qWait(5000);

	m->scan();
	QTest::qWait(10000);

	m->deregister();
	QTest::qWait(10000);
	m->registerOp();

	QTest::qWait(120000);
    }

    void cleanupTestCase()
    {

    }

private:
    OfonoNetworkRegistration *m;
};

QTEST_MAIN(TestOfonoNetworkRegistration)
#include "test_ofononetworkregistration.moc"
<commit_msg>Rework network registration test<commit_after>/*
 * This file is part of ofono-qt
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * Contact: Alexander Kanavin <alexander.kanavin@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library 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. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <QtTest/QtTest>
#include <QtCore/QObject>

#include <ofononetworkregistration.h>

#include <QtDebug>

class TestOfonoNetworkRegistration : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase()
    {
	m = new OfonoNetworkRegistration(OfonoModem::ManualSelect, "/phonesim", this);
	QCOMPARE(m->modem()->isValid(), true);

	if (!m->modem()->powered()) {
  	    m->modem()->setPowered(true);
            QTest::qWait(5000);
        }
        if (!m->modem()->online()) {
  	    m->modem()->setOnline(true);
            QTest::qWait(5000);
        }
	QCOMPARE(m->isValid(), true);
    }

    void testOfonoNetworkRegistration()
    {
    	QSignalSpy mode(m, SIGNAL(modeChanged(QString)));
	QSignalSpy status(m, SIGNAL(statusChanged(QString)));
	QSignalSpy lac(m, SIGNAL(locationAreaCodeChanged(uint)));
	QSignalSpy cellId(m, SIGNAL(cellIdChanged(uint)));
	QSignalSpy mcc(m, SIGNAL(mccChanged(QString)));
	QSignalSpy mnc(m, SIGNAL(mncChanged(QString)));
	QSignalSpy tech(m, SIGNAL(technologyChanged(QString)));
	QSignalSpy name(m, SIGNAL(nameChanged(QString)));
	QSignalSpy strength(m, SIGNAL(strengthChanged(uint)));
	QSignalSpy base(m, SIGNAL(baseStationChanged(QString)));

    	QSignalSpy registerS(m, SIGNAL(registerComplete(bool)));
    	QSignalSpy deregister(m, SIGNAL(deregisterComplete(bool)));
    	QSignalSpy scan(m, SIGNAL(scanComplete(bool, QStringList)));
    	QSignalSpy getOp(m, SIGNAL(getOperatorsComplete(bool, QStringList)));

	QVERIFY(m->mode().length() > 0);
	QCOMPARE(m->status(), QString("registered"));
	QCOMPARE(m->mcc(), QString("234"));
	QCOMPARE(m->mnc(), QString("01"));
	QVERIFY(m->name().length() > 0);
	QCOMPARE(m->strength(), uint(100));

	m->scan();
	QTest::qWait(5000);
	QCOMPARE(scan.count(), 1);
	QVariantList scanList = scan.takeFirst();
	QCOMPARE(scanList.at(0).toBool(), true);
	QStringList scanOpList = scanList.at(1).toStringList();
	QVERIFY(scanOpList.count() > 0);

	m->getOperators();
	QTest::qWait(1000);
	QCOMPARE(getOp.count(), 1);
	QVariantList getList = getOp.takeFirst();
	QCOMPARE(getList.at(0).toBool(), true);
	QStringList getOpList = getList.at(1).toStringList();
	QVERIFY(getOpList.count() > 0);
	QCOMPARE(scanOpList, getOpList);

	m->deregister();
	QTest::qWait(1000);
	QCOMPARE(deregister.count(), 1);
	QCOMPARE(deregister.takeFirst().at(0).toBool(), false);
	QCOMPARE(m->errorName(), QString("org.ofono.Error.Failed"));
	QCOMPARE(m->errorMessage(), QString("Operation failed"));
	QCOMPARE(mode.count(), 1);
	QCOMPARE(mode.takeFirst().at(0).toString(), QString("off"));
	m->registerOp();
	QTest::qWait(5000);
	QCOMPARE(registerS.count(), 1);
	QCOMPARE(registerS.takeFirst().at(0).toBool(), true);
	QCOMPARE(mode.count(), 1);
	QCOMPARE(mode.takeFirst().at(0).toString(), QString("auto"));

	m->modem()->setOnline(false);
	QTest::qWait(5000);
	QCOMPARE(m->isValid(), false);
	m->modem()->setOnline(true);
	QTest::qWait(5000);
	QCOMPARE(status.count(), 1);
	QCOMPARE(status.takeFirst().at(0).toString(), QString("registered"));
	QCOMPARE(mcc.count(), 1);
	QCOMPARE(mcc.takeFirst().at(0).toString(), QString("234"));
	QCOMPARE(mnc.count(), 1);
	QCOMPARE(mnc.takeFirst().at(0).toString(), QString("01"));
	QCOMPARE(name.count(), 2);
	QVERIFY(name.takeFirst().at(0).toString().length() > 0);
	QVERIFY(name.takeFirst().at(0).toString().length() > 0);
	QCOMPARE(strength.count(), 1);
	QCOMPARE(strength.takeFirst().at(0).toUInt(), uint(100));
    }

    void cleanupTestCase()
    {

    }

private:
    OfonoNetworkRegistration *m;
};

QTEST_MAIN(TestOfonoNetworkRegistration)
#include "test_ofononetworkregistration.moc"
<|endoftext|>


<commit_before>/*
** Author(s):
**  - Cedric GESTES <gestes@aldebaran-robotics.com>
**
** Copyright (C) 2010 Aldebaran Robotics
*/

#ifndef         QI_API_HPP_
# define        QI_API_HPP_

#ifdef qi_EXPORTS
# if defined _WIN32 || defined __CYGWIN__
#   define QIAPI __declspec(dllexport)
# elif __GNUC__ >= 4
#   define QIAPI __attribute__ ((visibility("default")))
# else
#   define QIAPI
# endif
#else
# if defined _WIN32 || defined __CYGWIN__
#   if defined _WINDLL
#     define QIAPI __declspec(dllimport)
#   else
#     define QIAPI
#   endif
# elif __GNUC__ >= 4
#   define QIAPI __attribute__ ((visibility("default")))
# else
#   define QIAPI
# endif
#endif

#endif    /* !QI_API_HPP_ */
<commit_msg>Added deprecated MACRO<commit_after>/*
** Author(s):
**  - Cedric GESTES <gestes@aldebaran-robotics.com>
**
** Copyright (C) 2010 Aldebaran Robotics
*/

#ifndef         QI_API_HPP_
# define        QI_API_HPP_

// qi_EXPORTSE control which symbols are exported when
// compiled as a SHARED lib.
#ifdef qi_EXPORTS
# if defined _WIN32 || defined __CYGWIN__
#   define QIAPI __declspec(dllexport)
# elif __GNUC__ >= 4
#   define QIAPI __attribute__ ((visibility("default")))
# else
#   define QIAPI
# endif
#else
# if defined _WIN32 || defined __CYGWIN__
#   if defined _WINDLL
#     define QIAPI __declspec(dllimport)
#   else
#     define QIAPI
#   endif
# elif __GNUC__ >= 4
#   define QIAPI __attribute__ ((visibility("default")))
# else
#   define QIAPI
# endif
#endif

// Deprecated
#if defined(__GNUC__)
#define QIAPI_DEPRECATED __attribute__((deprecated))
#else
#define QIAPI_DEPRECATED
#endif

#endif    /* !QI_API_HPP_ */
<|endoftext|>


<commit_before>/*
   Copyright (C) 2017 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library 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.  See the GNU
   Lesser General Public License for more details.

 */

#include <QObject>

#include "AccountStorage.hpp"
#include "ClientConnection.hpp"
#include "ClientDhLayer.hpp"
#include "ClientRpcLayer.hpp"
#include "ClientSettings.hpp"
#include "CClientTcpTransport.hpp"
#include "Utils.hpp"
#include "SendPackageHelper.hpp"
#include "TelegramNamespace.hpp"
#include "TelegramUtils.hpp"
#include "CAppInformation.hpp"

#include <QTest>
#include <QSignalSpy>
#include <QLoggingCategory>

using namespace Telegram;

CAppInformation *getAppInfo()
{
    static CAppInformation *appInfo = nullptr;
    if (!appInfo) {
        appInfo = new CAppInformation();
        appInfo->setAppId(14617);
        appInfo->setAppHash(QLatin1String("e17ac360fd072f83d5d08db45ce9a121"));
        appInfo->setAppVersion(QLatin1String("0.1"));
        appInfo->setDeviceInfo(QLatin1String("pc"));
        appInfo->setOsInfo(QLatin1String("GNU/Linux"));
        appInfo->setLanguageCode(QLatin1String("en"));
    }
    return appInfo;
}

class tst_toOfficial : public QObject
{
    Q_OBJECT
public:
    explicit tst_toOfficial(QObject *parent = nullptr);

private slots:
    void testClientDhLayer();
};

class TestSendPackageHelper : public BaseSendPackageHelper
{
public:
    explicit TestSendPackageHelper(CTelegramTransport *transport) :
        BaseSendPackageHelper(),
        m_transport(transport)
    {
    }

    quint64 newMessageId(bool isReply) override
    {
        Q_UNUSED(isReply)
        quint64 ts = TelegramUtils::formatTimeStamp(QDateTime::currentMSecsSinceEpoch());
        ts &= ~quint64(3);
        return m_transport->getNewMessageId(ts);
    }

    void sendPackage(const QByteArray &package) override
    {
        return m_transport->sendPackage(package);
    }

protected:
    CTelegramTransport *m_transport;
};

tst_toOfficial::tst_toOfficial(QObject *parent) :
    QObject(parent)
{
    QLoggingCategory::setFilterRules(QStringLiteral("telegram.*.debug=true"));
}

void tst_toOfficial::testClientDhLayer()
{
    const auto serverConfig = Client::Settings::defaultServerConfiguration();
    QVERIFY(!serverConfig.isEmpty());
    const DcOption firstServer = serverConfig.first();
    Client::TcpTransport *transport = new Client::TcpTransport(this);

    TestSendPackageHelper *sendHelper = new TestSendPackageHelper(transport);
    Client::DhLayer *dhLayer = new Client::DhLayer(this);
    dhLayer->setSendPackageHelper(sendHelper);
    dhLayer->setServerRsaKey(Utils::loadHardcodedKey());

    connect(transport, &Client::TcpTransport::packageReceived, [dhLayer](const QByteArray &package) {
        if (package.size() == sizeof(quint32)) {
            qint32 errorCode = *(reinterpret_cast<const qint32 *>(package.constData()));
            qWarning() << "Error:" << errorCode;
            return;
        }
        if (package.size() < 8) {
            qWarning() << "Received package is too small to process:" << package.toHex();
            return;
        }
        const quint64 *authKeyIdBytes = reinterpret_cast<const quint64*>(package.constData());
        if (*authKeyIdBytes) {
            qDebug() << "Received a package for RPC Layer";
//            rpcLayer->processPackage(package);
        } else {
            qDebug() << "Received a plain package for DH Layer";
            dhLayer->processPlainPackage(package);
        }
    });

    transport->connectToHost(firstServer.address, firstServer.port);
    QTRY_VERIFY(transport->state() == QAbstractSocket::ConnectedState);

    dhLayer->init();

    PendingRpcOperation *operationReqPq = dhLayer->requestPqAuthorization();
    QTRY_VERIFY(operationReqPq->isFinished());
    QVERIFY(operationReqPq->isSucceeded());
    QVERIFY(dhLayer->acceptPqAuthorization(operationReqPq->replyData()));

    PendingRpcOperation *operationReqDhParams = dhLayer->requestDhParameters();
    QTRY_VERIFY(operationReqDhParams->isFinished());
    QVERIFY(operationReqDhParams->isSucceeded());
    QVERIFY(dhLayer->acceptDhAnswer(operationReqDhParams->replyData()));

    PendingRpcOperation *operationSetClientDHParams = dhLayer->requestDhGenerationResult();
    QTRY_VERIFY(operationSetClientDHParams->isFinished());
    QVERIFY(operationSetClientDHParams->isSucceeded());
    QVERIFY(dhLayer->processServerDhAnswer(operationSetClientDHParams->replyData()));
}

QTEST_GUILESS_MAIN(tst_toOfficial)

#include "tst_toOfficial.moc"
<commit_msg>Tests/tst_toOfficial: Fix DH layer usage<commit_after>/*
   Copyright (C) 2017 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library 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.  See the GNU
   Lesser General Public License for more details.

 */

#include <QObject>

#include "AccountStorage.hpp"
#include "ClientConnection.hpp"
#include "ClientDhLayer.hpp"
#include "ClientRpcLayer.hpp"
#include "ClientSettings.hpp"
#include "CClientTcpTransport.hpp"
#include "Utils.hpp"
#include "SendPackageHelper.hpp"
#include "TelegramNamespace.hpp"
#include "TelegramUtils.hpp"
#include "CAppInformation.hpp"

#include <QTest>
#include <QSignalSpy>
#include <QLoggingCategory>

using namespace Telegram;

CAppInformation *getAppInfo()
{
    static CAppInformation *appInfo = nullptr;
    if (!appInfo) {
        appInfo = new CAppInformation();
        appInfo->setAppId(14617);
        appInfo->setAppHash(QLatin1String("e17ac360fd072f83d5d08db45ce9a121"));
        appInfo->setAppVersion(QLatin1String("0.1"));
        appInfo->setDeviceInfo(QLatin1String("pc"));
        appInfo->setOsInfo(QLatin1String("GNU/Linux"));
        appInfo->setLanguageCode(QLatin1String("en"));
    }
    return appInfo;
}

class tst_toOfficial : public QObject
{
    Q_OBJECT
public:
    explicit tst_toOfficial(QObject *parent = nullptr);

private slots:
    void testClientDhLayer();
};

class TestSendPackageHelper : public BaseSendPackageHelper
{
public:
    explicit TestSendPackageHelper(CTelegramTransport *transport) :
        BaseSendPackageHelper(),
        m_transport(transport)
    {
    }

    quint64 newMessageId(bool isReply) override
    {
        Q_UNUSED(isReply)
        quint64 ts = TelegramUtils::formatTimeStamp(QDateTime::currentMSecsSinceEpoch());
        ts &= ~quint64(3);
        return m_transport->getNewMessageId(ts);
    }

    void sendPackage(const QByteArray &package) override
    {
        return m_transport->sendPackage(package);
    }

protected:
    CTelegramTransport *m_transport;
};

tst_toOfficial::tst_toOfficial(QObject *parent) :
    QObject(parent)
{
    QLoggingCategory::setFilterRules(QStringLiteral("telegram.*.debug=true"));
}

void tst_toOfficial::testClientDhLayer()
{
    const auto serverConfig = Client::Settings::defaultServerConfiguration();
    QVERIFY(!serverConfig.isEmpty());
    const DcOption firstServer = serverConfig.first();
    Client::TcpTransport *transport = new Client::TcpTransport(this);

    TestSendPackageHelper *sendHelper = new TestSendPackageHelper(transport);
    Client::DhLayer *dhLayer = new Client::DhLayer(this);
    dhLayer->setSendPackageHelper(sendHelper);
    dhLayer->setServerRsaKey(Utils::loadHardcodedKey());

    connect(transport, &Client::TcpTransport::packageReceived, [dhLayer](const QByteArray &package) {
        if (package.size() == sizeof(quint32)) {
            qint32 errorCode = *(reinterpret_cast<const qint32 *>(package.constData()));
            qWarning() << "Error:" << errorCode;
            return;
        }
        if (package.size() < 8) {
            qWarning() << "Received package is too small to process:" << package.toHex();
            return;
        }
        const quint64 *authKeyIdBytes = reinterpret_cast<const quint64*>(package.constData());
        if (*authKeyIdBytes) {
            qDebug() << "Received a package for RPC Layer";
//            rpcLayer->processPackage(package);
        } else {
            qDebug() << "Received a plain package for DH Layer";
            dhLayer->processPlainPackage(package);
        }
    });

    transport->connectToHost(firstServer.address, firstServer.port);
    QTRY_VERIFY(transport->state() == QAbstractSocket::ConnectedState);

    PendingRpcOperation *operationReqPq = dhLayer->requestPqAuthorization();
    QTRY_VERIFY(operationReqPq->isFinished());
    QVERIFY(operationReqPq->isSucceeded());
    QVERIFY(dhLayer->acceptPqAuthorization(operationReqPq->replyData()));

    PendingRpcOperation *operationReqDhParams = dhLayer->requestDhParameters();
    QTRY_VERIFY(operationReqDhParams->isFinished());
    QVERIFY(operationReqDhParams->isSucceeded());
    QVERIFY(dhLayer->acceptDhAnswer(operationReqDhParams->replyData()));

    dhLayer->generateDh();

    PendingRpcOperation *operationSetClientDHParams = dhLayer->requestDhGenerationResult();
    QTRY_VERIFY(operationSetClientDHParams->isFinished());
    QVERIFY(operationSetClientDHParams->isSucceeded());
    QVERIFY(dhLayer->processServerDhAnswer(operationSetClientDHParams->replyData()));
}

QTEST_GUILESS_MAIN(tst_toOfficial)

#include "tst_toOfficial.moc"
<|endoftext|>


<commit_before>#include <assert.h>
#include <iostream>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include "Options.hpp"

namespace fs = boost::filesystem;
namespace po = boost::program_options;

using cclyzer::ast_exporter::Options;

Options::Options(int argc, char* argv[])
{
    const std::string appName = fs::basename(argv[0]);
    fs::path outdir;

    // Define and parse the program options
    po::options_description genericOpts("Options");

    genericOpts.add_options()
        ("help,h", "Print help message")
        ("out-dir,o", po::value<fs::path>(&outdir)->required(),
         "Output directory for AST in JSON form")
        ("recursive,r", "Recurse into input directories")
        ("force,f", "Remove existing contents of output directory");

    // hidden options group - don't show in help
    po::options_description hiddenOpts("hidden options");
    hiddenOpts.add_options()
        ("input-files", po::value<std::vector<fs::path> >()->required(),
         "C/C++ source input files");

    po::options_description cmdline_options;
    cmdline_options.add(genericOpts).add(hiddenOpts);

    // positional arguments
    po::positional_options_description positionalOptions;
    positionalOptions.add("input-files", -1);

    po::variables_map vm;

    try {
        po::store(
            po::command_line_parser(argc, argv)
            .options(cmdline_options)
            .positional(positionalOptions)
            .run(),
            vm);

        // --help option
        if (vm.count("help"))
        {
            std::cout << "Usage: " << appName
                      << " [OPTIONS] INPUT_FILE...\n\n" << genericOpts;

            exit(EXIT_SUCCESS);
        }

        // may throw error
        po::notify(vm);
    }
    catch(boost::program_options::required_option& e) {
        std::cerr << e.what() << " from option: " << e.get_option_name() << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }
    catch(boost::program_options::error& e) {
        std::cerr << e.what() << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }

    // Sanity checks
    assert(vm.count("out-dir"));
    assert(vm.count("input-files"));

    // Compute input files and create output directories
    std::vector<fs::path> paths = vm["input-files"].as<std::vector<fs::path> >();
    set_output_dir(outdir, vm.count("force"));
    set_input_files(paths.begin(), paths.end(), vm.count("recursive"));
}

template<typename FileIt> void
Options::set_input_files(FileIt file_begin, FileIt file_end, bool shouldRecurse)
{
    // Delete old contents
    inputFiles.clear();

    // Iterate over every given path
    for (FileIt it = file_begin; it != file_end; ++it)
    {
        fs::path path = *it;

        // Check for existence
        if (!fs::exists(path)) {
            std::cerr << "Path does not exist: " << path << std::endl;
            exit(ERROR_IN_COMMAND_LINE);
        }

        // Add normal files
        if (!fs::is_directory(path)) {
            inputFiles.push_back(path);
            continue;
        }

        if (!shouldRecurse) {
            std::cerr << "Input directory given, without -r option: "
                      << path << std::endl;

            exit(ERROR_IN_COMMAND_LINE);
        }

        // Recurse into directories
        for (fs::recursive_directory_iterator iter(path), end; iter != end; ++iter)
        {
            if (!fs::is_directory(iter->path()))
                inputFiles.push_back(iter->path());
        }
    }
}

void
Options::set_output_dir(fs::path path, bool shouldForce)
{
    // Create non-existing directory
    if (!fs::exists(path))
        fs::create_directory(path);

    if (!fs::is_directory(path)) {
        std::cerr << "Not a directory: " << path << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }

    // Remove old contents
    if (shouldForce) {
        for (fs::directory_iterator end, it(path); it != end; ++it)
            remove_all(it->path());
    }

    // Ensure output directory is empty
    if (!fs::is_empty(path)) {
        std::cerr << "Directory not empty: " << path << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }

    // Store output directory (CHECK: should we canonicalize path)
    outdir = path;
}
<commit_msg>Ignore non-C/C++ files in AST export<commit_after>#include <assert.h>
#include <iostream>

#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include "Options.hpp"

namespace fs = boost::filesystem;
namespace po = boost::program_options;

using cclyzer::ast_exporter::Options;
using boost::to_lower;

Options::Options(int argc, char* argv[])
{
    const std::string appName = fs::basename(argv[0]);
    fs::path outdir;

    // Define and parse the program options
    po::options_description genericOpts("Options");

    genericOpts.add_options()
        ("help,h", "Print help message")
        ("out-dir,o", po::value<fs::path>(&outdir)->required(),
         "Output directory for AST in JSON form")
        ("recursive,r", "Recurse into input directories")
        ("force,f", "Remove existing contents of output directory");

    // hidden options group - don't show in help
    po::options_description hiddenOpts("hidden options");
    hiddenOpts.add_options()
        ("input-files", po::value<std::vector<fs::path> >()->required(),
         "C/C++ source input files");

    po::options_description cmdline_options;
    cmdline_options.add(genericOpts).add(hiddenOpts);

    // positional arguments
    po::positional_options_description positionalOptions;
    positionalOptions.add("input-files", -1);

    po::variables_map vm;

    try {
        po::store(
            po::command_line_parser(argc, argv)
            .options(cmdline_options)
            .positional(positionalOptions)
            .run(),
            vm);

        // --help option
        if (vm.count("help"))
        {
            std::cout << "Usage: " << appName
                      << " [OPTIONS] INPUT_FILE...\n\n" << genericOpts;

            exit(EXIT_SUCCESS);
        }

        // may throw error
        po::notify(vm);
    }
    catch(boost::program_options::required_option& e) {
        std::cerr << e.what() << " from option: " << e.get_option_name() << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }
    catch(boost::program_options::error& e) {
        std::cerr << e.what() << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }

    // Sanity checks
    assert(vm.count("out-dir"));
    assert(vm.count("input-files"));

    // Compute input files and create output directories
    std::vector<fs::path> paths = vm["input-files"].as<std::vector<fs::path> >();
    set_output_dir(outdir, vm.count("force"));
    set_input_files(paths.begin(), paths.end(), vm.count("recursive"));
}

template<typename FileIt> void
Options::set_input_files(FileIt file_begin, FileIt file_end, bool shouldRecurse)
{
    // Delete old contents
    inputFiles.clear();

    // Iterate over every given path
    for (FileIt it = file_begin; it != file_end; ++it)
    {
        fs::path path = *it;

        // Check for existence
        if (!fs::exists(path)) {
            std::cerr << "Path does not exist: " << path << std::endl;
            exit(ERROR_IN_COMMAND_LINE);
        }

        // Add normal files
        if (!fs::is_directory(path)) {
            inputFiles.push_back(path);
            continue;
        }

        if (!shouldRecurse) {
            std::cerr << "Input directory given, without -r option: "
                      << path << std::endl;

            exit(ERROR_IN_COMMAND_LINE);
        }

        // Recurse into directories
        for (fs::recursive_directory_iterator iter(path), end; iter != end; ++iter)
        {
            const fs::path& p = iter->path();

            // Skip directories
            if (fs::is_directory(p))
                continue;

            // Skip non C/C++ files
            if (!p.has_extension())
                continue;

            std::string extension = p.extension().string();

            // Downcase extension
            to_lower(extension);

            if (extension != ".c"   &&
                extension != ".cc"  &&
                extension != ".cp"  &&
                extension != ".cpp" &&
                extension != ".cxx" &&
                extension != ".c++" &&
                extension != ".h"   &&
                extension != ".hpp")
            {
                continue;
            }

            inputFiles.push_back(iter->path());
        }
    }
}

void
Options::set_output_dir(fs::path path, bool shouldForce)
{
    // Create non-existing directory
    if (!fs::exists(path))
        fs::create_directory(path);

    if (!fs::is_directory(path)) {
        std::cerr << "Not a directory: " << path << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }

    // Remove old contents
    if (shouldForce) {
        for (fs::directory_iterator end, it(path); it != end; ++it)
            remove_all(it->path());
    }

    // Ensure output directory is empty
    if (!fs::is_empty(path)) {
        std::cerr << "Directory not empty: " << path << std::endl;
        exit(ERROR_IN_COMMAND_LINE);
    }

    // Store output directory (CHECK: should we canonicalize path)
    outdir = path;
}
<|endoftext|>


<commit_before>#ifndef _SDD_DD_SUM_HH_
#define _SDD_DD_SUM_HH_

#include <initializer_list>
#include <type_traits> // enable_if, is_same
#include <unordered_map>
#include <vector>

#include "sdd/internal_manager_fwd.hh"
#include "sdd/dd/context_fwd.hh"
#include "sdd/dd/definition.hh"
#include "sdd/dd/nary.hh"
#include "sdd/dd/operations_fwd.hh"
#include "sdd/dd/square_union.hh"
#include "sdd/util/hash.hh"
#include "sdd/util/boost_flat_map_no_warnings.hh"
#include "sdd/util/boost_flat_set_no_warnings.hh"
#include "sdd/values/empty.hh"
#include "sdd/values/values_traits.hh"

namespace sdd { namespace dd {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief The sum operation in the cache.
template <typename C>
struct LIBSDD_ATTRIBUTE_PACKED sum_op_impl
{
  /// @brief The textual representation of the union operator.
  static constexpr char symbol = '+';

  /// @brief Perform the SDD union algorithm.
  ///
  /// It's a so-called 'n-ary' union in the sense that we don't create intermediary SDD.
  /// Also, a lot of tests permit to break loops as soon as possible.
  template <typename InputIterator, typename NodeType>
  static
  typename std::enable_if< std::is_same<NodeType, hierarchical_node<C>>::value
                         or not values::values_traits<typename C::Values>::fast_iterable
                         , SDD<C>>::type
  work(InputIterator begin, InputIterator end, context<C>& cxt)
  {
    using node_type = NodeType;
    using valuation_type = typename node_type::valuation_type;

    auto operands_cit = begin;
    const auto operands_end = end;

    // Get the first operand as a node, we need it to initialize the algorithm.
    const node_type& head = mem::variant_cast<node_type>(**operands_cit);

    // Type of the list of successors for a valuation, to be merged with the union operation
    // right before calling the square union.
    using sum_builder_type = sum_builder<C, SDD<C>>;

    /// @todo Use Boost.Intrusive to save on memory allocations?
    // List all the successors for each valuation in the final alpha.
    std::unordered_map<valuation_type, sum_builder_type> res(head.size());

    // Needed to temporarily store arcs erased from res and arcs from the alpha visited in
    // the loop (B).
    std::vector<std::pair<valuation_type, sum_builder_type>> save;
    save.reserve(head.size());

    // Used in test (F).
    std::vector<std::pair<valuation_type, sum_builder_type>> remainder;
    remainder.reserve(head.size());

    // Initialize res with the alpha of the first operand.
    for (auto& arc : head)
    {
      sum_builder_type succs;
      succs.add(arc.successor());
      res.emplace(arc.valuation(), std::move(succs));
    }

    // (A).
    for (++operands_cit; operands_cit != operands_end; ++operands_cit)
    {
      // Throw a Top if operands are incompatible (different types or different variables).
      check_compatibility(*begin, *operands_cit);

      const auto res_end = res.end();

      const node_type& node = mem::variant_cast<node_type>(**operands_cit);
      const auto alpha_end = node.end();

      // (B). For each arc of the current operand.
      for (auto alpha_cit = node.begin(); alpha_cit != alpha_end; ++alpha_cit)
      {
        // The current valuation may be modified, we need a copy.
        valuation_type current_val = alpha_cit->valuation();
        const SDD<C> current_succ = alpha_cit->successor();

        // Initialize the start of the next search.
        auto res_cit = res.begin();

        // (C). While the current valuation is not empty, test it against arcs in res.
        while (not values::empty_values(current_val) and res_cit != res_end)
        {
          const valuation_type& res_val = res_cit->first;
          sum_builder_type& res_succs = res_cit->second;

          // (D).
          if (current_val == res_val) // Same valuations.
          {
            save.emplace_back(res_val, std::move(res_succs));
            save.back().second.add(current_succ);
            const auto to_erase = res_cit;
            ++res_cit;
            res.erase(to_erase);
            // Avoid useless insertion or temporary variables.
            goto equality;
          }

          intersection_builder<C, valuation_type> inter_builder;
          inter_builder.add(current_val);
          inter_builder.add(res_val);
          const valuation_type inter = intersection(cxt, std::move(inter_builder));

          // (E). The current valuation and the current arc from res have a common part.
          if (not values::empty_values(inter))
          {
            save.emplace_back(inter, res_succs);
            save.back().second.add(current_succ);

            // (F).
            valuation_type diff = difference(cxt, res_val, inter);
            if (not values::empty_values(diff))
            {
              // (res_val - inter) can't be in intersection, but we need to keep it
              // for the next arcs of the current alpha. So we put in a temporary storage.
              // It will be added back in res when we have finished with the current valuation.
              remainder.emplace_back(std::move(diff), std::move(res_succs));
            }

            // We won't need the current arc of res for the current val, we already have the
            // common part. Now, the current valuation has to be tested against the next arcs
            // of res.
            const auto to_erase = res_cit;
            ++res_cit;
            res.erase(to_erase);

            // (G). The current valuation is completely included in the current arc of res.
            if (current_val == inter)
            {
              // We can move to the next arc of the current operand.
              break;
            }

            // Continue with what remains of val. if val is empy, the loop will stop at the
            // next iteration.
            current_val = difference(cxt, current_val, inter);
          }
          else // (H). Empty intersection, lookup for next possible common parts.
          {
            ++res_cit;
          }
        } // While we're not at the end of res and val is not empty.

        // (I). For val or a part of val (it could have been modified during the previous
        // loop), we didn't find an intersection with any arc of res.
        if (not values::empty_values(current_val))
        {
          sum_builder_type succs;
          succs.add(current_succ);
          save.emplace_back(std::move(current_val), std::move(succs));
        }

        // Both arcs had the same valuation.
        equality:;

        // Reinject all parts that were removed in (F).
        for (auto& rem : remainder)
        {
          res.emplace(std::move(rem.first), std::move(rem.second));
        }
        remainder.clear();

      } // For each arc of the current operand.

      // Reinject all parts that were removed from res (all parts that have a non-empty
      // intersection with the current alpha) and all parts of the current alpha that have an
      // empty intersection with all the parts of res.
      res.insert(save.begin(), save.end());

      // We still need save.
      save.clear();
    } // End of iteration on operands.

    square_union<C, valuation_type> su;
    su.reserve(res.size());
    for (auto& arc : res)
    {
      // construct an operand for the square union: (successors union) --> valuation
      su.add(sum(cxt, std::move(arc.second)), arc.first);
    }

    return SDD<C>(head.variable(), su(cxt));
  }

  /// @brief Linear union of flat SDDs whose valuation are "fast iterable".
  template <typename InputIterator, typename NodeType>
  static
  typename std::enable_if< std::is_same<NodeType, flat_node<C>>::value
                         and values::values_traits<typename C::Values>::fast_iterable
                         , SDD<C>>::type
  work(InputIterator begin, InputIterator end, context<C>& cxt)
  {
    const auto& variable = mem::variant_cast<flat_node<C>>(**begin).variable();

    using values_type      = typename C::Values;
    using values_builder   = typename values::values_traits<values_type>::builder;
    using value_type       = typename values_type::value_type;
    using sum_builder_type = sum_builder<C, SDD<C>>;
    boost::container::flat_map<value_type, sum_builder_type> value_to_succ;
    value_to_succ.reserve(std::distance(begin, end) * 2);

    auto cit = begin;
    for (; cit != end; ++cit)
    {
      check_compatibility(*begin, *cit);

      const auto& node = mem::variant_cast<flat_node<C>>(**cit);
      for (const auto& arc : node)
      {
        const SDD<C> succ = arc.successor();
        for (const auto& value : arc.valuation())
        {
          const auto search = value_to_succ.find(value);
          if (search == value_to_succ.end())
          {
            value_to_succ.emplace_hint(search, value, sum_builder_type({succ}));
          }
          else
          {
            search->second.add(succ);
          }
        }
      }
    }

    boost::container::flat_map<SDD<C>, values_builder> succ_to_value;
    succ_to_value.reserve(value_to_succ.size());
    for (auto& value_succs : value_to_succ)
    {
      const SDD<C> succ = sum(cxt, std::move(value_succs.second));
      const auto search = succ_to_value.find(succ);
      if (search == succ_to_value.end())
      {
        values_builder tmp;
        tmp.insert(value_succs.first);
        succ_to_value.emplace_hint(search, succ, std::move(tmp));
      }
      else
      {
        search->second.insert(value_succs.first);
      }
    }

    alpha_builder<C, values_type> alpha;
    alpha.reserve(succ_to_value.size());
    for (auto& succ_values : succ_to_value)
    {
      alpha.add(values_type(std::move(succ_values.second)), succ_values.first);
    }

    return SDD<C>(variable, std::move(alpha));
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Add an arc to the operands of the sum operation.
///
/// This implementation is meant to be used as a policy by nary_builder which doesn't know how
/// to add an arc.
template <typename C, typename Valuation>
struct sum_builder_impl
{
  template <typename Container>
  void
  add(Container& set, Valuation&& operand)
  {
    if (not values::empty_values(operand))
    {
      set.insert(std::move(operand));
    }
  }

  template <typename Container>
  void
  add(Container& set, const Valuation& operand)
  {
    if (not values::empty_values(operand))
    {
      set.insert(operand);
    }
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief   The sum operation of a set of SDD.
/// @related sdd::SDD
template <typename C>
inline
SDD<C>
sum(context<C>& cxt, sum_builder<C, SDD<C>>&& builder)
{
  if (builder.empty())
  {
    return zero<C>();
  }
  else if (builder.size() == 1)
  {
    return *builder.begin();
  }
  return cxt.sum_cache()(sum_op<C>(builder));
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief   The sum operation of a set of values.
/// @details A wrapper around the implementation of sum provided by Values.
template <typename C, typename Values>
inline
Values
sum(context<C>&, sum_builder<C, Values>&& builder)
{
  if (builder.empty())
  {
    return Values();
  }
  else if (builder.size() == 1)
  {
    return *builder.begin();
  }
  else
  {
    auto cit = builder.begin();
    const auto end = builder.end();
    Values result = *cit;
    for (++cit; cit != end; ++cit)
    {
      typename C::Values tmp = sum(result, *cit);
      using std::swap;
      swap(tmp, result);
    }
    return result;
  }
}

} // namespace dd

/*------------------------------------------------------------------------------------------------*/

/// @brief Perform the union of two SDD.
/// @related SDD
template <typename C>
inline
SDD<C>
operator+(const SDD<C>& lhs, const SDD<C>& rhs)
{
  return dd::sum(global<C>().sdd_context, {lhs, rhs});
}

/// @brief Perform the union of two SDD.
/// @related SDD
template <typename C>
inline
SDD<C>&
operator+=(SDD<C>& lhs, const SDD<C>& rhs)
{
  SDD<C> tmp = dd::sum(global<C>().sdd_context, {lhs, rhs});
  using std::swap;
  swap(tmp, lhs);
  return lhs;
}

/// @brief Perform the union of an iterable container of SDD.
/// @related SDD
template <typename C, typename InputIterator>
SDD<C>
inline
sum(InputIterator begin, InputIterator end)
{
  dd::sum_builder<C, SDD<C>> builder;
  for (; begin != end; ++begin)
  {
    builder.add(*begin);
  }
  return dd::sum(global<C>().sdd_context, std::move(builder));
}

/// @brief Perform the union of an initializer list of SDD.
/// @related SDD
template <typename C>
SDD<C>
inline
sum(std::initializer_list<SDD<C>> operands)
{
  return sum<C>(std::begin(operands), std::end(operands));
}

/*------------------------------------------------------------------------------------------------*/

} // namespace sdd

#endif // _SDD_DD_SUM_HH_
<commit_msg>Comments.<commit_after>#ifndef _SDD_DD_SUM_HH_
#define _SDD_DD_SUM_HH_

#include <initializer_list>
#include <type_traits> // enable_if, is_same
#include <unordered_map>
#include <vector>

#include "sdd/internal_manager_fwd.hh"
#include "sdd/dd/context_fwd.hh"
#include "sdd/dd/definition.hh"
#include "sdd/dd/nary.hh"
#include "sdd/dd/operations_fwd.hh"
#include "sdd/dd/square_union.hh"
#include "sdd/util/hash.hh"
#include "sdd/util/boost_flat_map_no_warnings.hh"
#include "sdd/util/boost_flat_set_no_warnings.hh"
#include "sdd/values/empty.hh"
#include "sdd/values/values_traits.hh"

namespace sdd { namespace dd {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief The sum operation in the cache.
template <typename C>
struct LIBSDD_ATTRIBUTE_PACKED sum_op_impl
{
  /// @brief The textual representation of the union operator.
  static constexpr char symbol = '+';

  /// @brief Perform the SDD union algorithm.
  ///
  /// It's a so-called 'n-ary' union in the sense that we don't create intermediary SDD.
  /// Also, a lot of tests permit to break loops as soon as possible.
  template <typename InputIterator, typename NodeType>
  static
  typename std::enable_if< std::is_same<NodeType, hierarchical_node<C>>::value
                         or not values::values_traits<typename C::Values>::fast_iterable
                         , SDD<C>>::type
  work(InputIterator begin, InputIterator end, context<C>& cxt)
  {
    using node_type = NodeType;
    using valuation_type = typename node_type::valuation_type;

    auto operands_cit = begin;
    const auto operands_end = end;

    // Get the first operand as a node, we need it to initialize the algorithm.
    const node_type& head = mem::variant_cast<node_type>(**operands_cit);

    // Type of the list of successors for a valuation, to be merged with the union operation
    // right before calling the square union.
    using sum_builder_type = sum_builder<C, SDD<C>>;

    /// @todo Use Boost.Intrusive to save on memory allocations?
    // List all the successors for each valuation in the final alpha.
    std::unordered_map<valuation_type, sum_builder_type> res(head.size());

    // Needed to temporarily store arcs erased from res and arcs from the alpha visited in
    // the loop (B).
    std::vector<std::pair<valuation_type, sum_builder_type>> save;
    save.reserve(head.size());

    // Used in test (F).
    std::vector<std::pair<valuation_type, sum_builder_type>> remainder;
    remainder.reserve(head.size());

    // Initialize res with the alpha of the first operand.
    for (auto& arc : head)
    {
      sum_builder_type succs;
      succs.add(arc.successor());
      res.emplace(arc.valuation(), std::move(succs));
    }

    // (A).
    for (++operands_cit; operands_cit != operands_end; ++operands_cit)
    {
      // Throw a Top if operands are incompatible (different types or different variables).
      check_compatibility(*begin, *operands_cit);

      const auto res_end = res.end();

      const node_type& node = mem::variant_cast<node_type>(**operands_cit);
      const auto alpha_end = node.end();

      // (B). For each arc of the current operand.
      for (auto alpha_cit = node.begin(); alpha_cit != alpha_end; ++alpha_cit)
      {
        // The current valuation may be modified, we need a copy.
        valuation_type current_val = alpha_cit->valuation();
        const SDD<C> current_succ = alpha_cit->successor();

        // Initialize the start of the next search.
        auto res_cit = res.begin();

        // (C). While the current valuation is not empty, test it against arcs in res.
        while (not values::empty_values(current_val) and res_cit != res_end)
        {
          const valuation_type& res_val = res_cit->first;
          sum_builder_type& res_succs = res_cit->second;

          // (D).
          if (current_val == res_val) // Same valuations.
          {
            save.emplace_back(res_val, std::move(res_succs));
            save.back().second.add(current_succ);
            const auto to_erase = res_cit;
            ++res_cit;
            res.erase(to_erase);
            // Avoid useless insertion or temporary variables.
            goto equality;
          }

          intersection_builder<C, valuation_type> inter_builder;
          inter_builder.add(current_val);
          inter_builder.add(res_val);
          const valuation_type inter = intersection(cxt, std::move(inter_builder));

          // (E). The current valuation and the current arc from res have a common part.
          if (not values::empty_values(inter))
          {
            save.emplace_back(inter, res_succs);
            save.back().second.add(current_succ);

            // (F).
            valuation_type diff = difference(cxt, res_val, inter);
            if (not values::empty_values(diff))
            {
              // (res_val - inter) can't be in intersection, but we need to keep it
              // for the next arcs of the current alpha. So we put it in a temporary storage.
              // It will be added back in res when we have finished with the current valuation.
              remainder.emplace_back(std::move(diff), std::move(res_succs));
            }

            // We won't need the current arc of res for the current val, we already have the
            // common part. Now, the current valuation has to be tested against the next arcs
            // of res.
            const auto to_erase = res_cit;
            ++res_cit;
            res.erase(to_erase);

            // (G). The current valuation is completely included in the current arc of res.
            if (current_val == inter)
            {
              // We can move to the next arc of the current operand.
              break;
            }

            // Continue with what remains of val. If val is empty, the loop will stop at the
            // next iteration.
            current_val = difference(cxt, current_val, inter);
          }
          else // (H). Empty intersection, lookup for next possible common parts.
          {
            ++res_cit;
          }
        } // While we're not at the end of res and val is not empty.

        // (I). For val or a part of val (it could have been modified during the previous
        // loop), we didn't find an intersection with any arc of res.
        if (not values::empty_values(current_val))
        {
          sum_builder_type succs;
          succs.add(current_succ);
          save.emplace_back(std::move(current_val), std::move(succs));
        }

        // Both arcs had the same valuation.
        equality:;

        // Reinject all parts that were removed in (F).
        for (auto& rem : remainder)
        {
          res.emplace(std::move(rem.first), std::move(rem.second));
        }
        remainder.clear();

      } // For each arc of the current operand.

      // Reinject all parts that were removed from res (all parts that have a non-empty
      // intersection with the current alpha) and all parts of the current alpha that have an
      // empty intersection with all the parts of res.
      res.insert(save.begin(), save.end());

      // We still need save.
      save.clear();
    } // End of iteration on operands.

    square_union<C, valuation_type> su;
    su.reserve(res.size());
    for (auto& arc : res)
    {
      // construct an operand for the square union: (successors union) --> valuation
      su.add(sum(cxt, std::move(arc.second)), arc.first);
    }

    return SDD<C>(head.variable(), su(cxt));
  }

  /// @brief Linear union of flat SDDs whose valuation are "fast iterable".
  template <typename InputIterator, typename NodeType>
  static
  typename std::enable_if< std::is_same<NodeType, flat_node<C>>::value
                         and values::values_traits<typename C::Values>::fast_iterable
                         , SDD<C>>::type
  work(InputIterator begin, InputIterator end, context<C>& cxt)
  {
    const auto& variable = mem::variant_cast<flat_node<C>>(**begin).variable();

    using values_type      = typename C::Values;
    using values_builder   = typename values::values_traits<values_type>::builder;
    using value_type       = typename values_type::value_type;
    using sum_builder_type = sum_builder<C, SDD<C>>;
    boost::container::flat_map<value_type, sum_builder_type> value_to_succ;
    value_to_succ.reserve(std::distance(begin, end) * 2);

    auto cit = begin;
    for (; cit != end; ++cit)
    {
      check_compatibility(*begin, *cit);

      const auto& node = mem::variant_cast<flat_node<C>>(**cit);
      for (const auto& arc : node)
      {
        const SDD<C> succ = arc.successor();
        for (const auto& value : arc.valuation())
        {
          const auto search = value_to_succ.find(value);
          if (search == value_to_succ.end())
          {
            value_to_succ.emplace_hint(search, value, sum_builder_type({succ}));
          }
          else
          {
            search->second.add(succ);
          }
        }
      }
    }

    boost::container::flat_map<SDD<C>, values_builder> succ_to_value;
    succ_to_value.reserve(value_to_succ.size());
    for (auto& value_succs : value_to_succ)
    {
      const SDD<C> succ = sum(cxt, std::move(value_succs.second));
      const auto search = succ_to_value.find(succ);
      if (search == succ_to_value.end())
      {
        values_builder tmp;
        tmp.insert(value_succs.first);
        succ_to_value.emplace_hint(search, succ, std::move(tmp));
      }
      else
      {
        search->second.insert(value_succs.first);
      }
    }

    alpha_builder<C, values_type> alpha;
    alpha.reserve(succ_to_value.size());
    for (auto& succ_values : succ_to_value)
    {
      alpha.add(values_type(std::move(succ_values.second)), succ_values.first);
    }

    return SDD<C>(variable, std::move(alpha));
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Add an arc to the operands of the sum operation.
///
/// This implementation is meant to be used as a policy by nary_builder which doesn't know how
/// to add an arc.
template <typename C, typename Valuation>
struct sum_builder_impl
{
  template <typename Container>
  void
  add(Container& set, Valuation&& operand)
  {
    if (not values::empty_values(operand))
    {
      set.insert(std::move(operand));
    }
  }

  template <typename Container>
  void
  add(Container& set, const Valuation& operand)
  {
    if (not values::empty_values(operand))
    {
      set.insert(operand);
    }
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief   The sum operation of a set of SDD.
/// @related sdd::SDD
template <typename C>
inline
SDD<C>
sum(context<C>& cxt, sum_builder<C, SDD<C>>&& builder)
{
  if (builder.empty())
  {
    return zero<C>();
  }
  else if (builder.size() == 1)
  {
    return *builder.begin();
  }
  return cxt.sum_cache()(sum_op<C>(builder));
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief   The sum operation of a set of values.
/// @details A wrapper around the implementation of sum provided by Values.
template <typename C, typename Values>
inline
Values
sum(context<C>&, sum_builder<C, Values>&& builder)
{
  if (builder.empty())
  {
    return Values();
  }
  else if (builder.size() == 1)
  {
    return *builder.begin();
  }
  else
  {
    auto cit = builder.begin();
    const auto end = builder.end();
    Values result = *cit;
    for (++cit; cit != end; ++cit)
    {
      typename C::Values tmp = sum(result, *cit);
      using std::swap;
      swap(tmp, result);
    }
    return result;
  }
}

} // namespace dd

/*------------------------------------------------------------------------------------------------*/

/// @brief Perform the union of two SDD.
/// @related SDD
template <typename C>
inline
SDD<C>
operator+(const SDD<C>& lhs, const SDD<C>& rhs)
{
  return dd::sum(global<C>().sdd_context, {lhs, rhs});
}

/// @brief Perform the union of two SDD.
/// @related SDD
template <typename C>
inline
SDD<C>&
operator+=(SDD<C>& lhs, const SDD<C>& rhs)
{
  SDD<C> tmp = dd::sum(global<C>().sdd_context, {lhs, rhs});
  using std::swap;
  swap(tmp, lhs);
  return lhs;
}

/// @brief Perform the union of an iterable container of SDD.
/// @related SDD
template <typename C, typename InputIterator>
SDD<C>
inline
sum(InputIterator begin, InputIterator end)
{
  dd::sum_builder<C, SDD<C>> builder;
  for (; begin != end; ++begin)
  {
    builder.add(*begin);
  }
  return dd::sum(global<C>().sdd_context, std::move(builder));
}

/// @brief Perform the union of an initializer list of SDD.
/// @related SDD
template <typename C>
SDD<C>
inline
sum(std::initializer_list<SDD<C>> operands)
{
  return sum<C>(std::begin(operands), std::end(operands));
}

/*------------------------------------------------------------------------------------------------*/

} // namespace sdd

#endif // _SDD_DD_SUM_HH_
<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP(".features.item_raw_score_feature");
#include "item_raw_score_feature.h"
#include "valuefeature.h"
#include "utils.h"

using namespace search::fef;

namespace search {
namespace features {

void
ItemRawScoreExecutor::execute(MatchData &data)
{
    feature_t output = 0.0;
    for (uint32_t i = 0; i < _handles.size(); ++i) {
        const TermFieldMatchData *tfmd = data.resolveTermField(_handles[i]);
        if (tfmd->getDocId() == data.getDocId()) {
            output += tfmd->getRawScore();
        }
    }
    *data.resolveFeature(outputs()[0]) = output;
}

//-----------------------------------------------------------------------------

void
SimpleItemRawScoreExecutor::execute(MatchData &data)
{
    feature_t output = 0.0;
    const TermFieldMatchData *tfmd = data.resolveTermField(_handle);
    if (tfmd->getDocId() == data.getDocId()) {
        output = tfmd->getRawScore();
    }
    *data.resolveFeature(outputs()[0]) = output;
}

//-----------------------------------------------------------------------------

bool
ItemRawScoreBlueprint::setup(const IIndexEnvironment &,
                             const ParameterList &params)
{
    _label = params[0].getValue();
    describeOutput("out", "raw score for the given query item");
    return true;
}

FeatureExecutor::LP
ItemRawScoreBlueprint::createExecutor(const IQueryEnvironment &queryEnv) const
{
    HandleVector handles = resolve(queryEnv, _label);
    if (handles.size() == 1) {
        return FeatureExecutor::LP(new SimpleItemRawScoreExecutor(handles[0]));
    } else if (handles.size() == 0) {
        return FeatureExecutor::LP(new SingleZeroValueExecutor());
    } else {
        return FeatureExecutor::LP(new ItemRawScoreExecutor(handles));
    }
}

ItemRawScoreBlueprint::HandleVector
ItemRawScoreBlueprint::resolve(const search::fef::IQueryEnvironment &env,
                               const vespalib::string &label)
{
    HandleVector handles;
    const ITermData *term = util::getTermByLabel(env, label);
    if (term != nullptr) {
    for (uint32_t i(0), m(term->numFields()); i < m; ++i) {
        TermFieldHandle handle = term->field(i).getHandle();
        if (handle != IllegalHandle) {
            handles.push_back(handle);
        }
    }
    return handles;
}

} // namespace features
} // namespace search
<commit_msg>Repair the last incomplete commit<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP(".features.item_raw_score_feature");
#include "item_raw_score_feature.h"
#include "valuefeature.h"
#include "utils.h"

using namespace search::fef;

namespace search {
namespace features {

void
ItemRawScoreExecutor::execute(MatchData &data)
{
    feature_t output = 0.0;
    for (uint32_t i = 0; i < _handles.size(); ++i) {
        const TermFieldMatchData *tfmd = data.resolveTermField(_handles[i]);
        if (tfmd->getDocId() == data.getDocId()) {
            output += tfmd->getRawScore();
        }
    }
    *data.resolveFeature(outputs()[0]) = output;
}

//-----------------------------------------------------------------------------

void
SimpleItemRawScoreExecutor::execute(MatchData &data)
{
    feature_t output = 0.0;
    const TermFieldMatchData *tfmd = data.resolveTermField(_handle);
    if (tfmd->getDocId() == data.getDocId()) {
        output = tfmd->getRawScore();
    }
    *data.resolveFeature(outputs()[0]) = output;
}

//-----------------------------------------------------------------------------

bool
ItemRawScoreBlueprint::setup(const IIndexEnvironment &,
                             const ParameterList &params)
{
    _label = params[0].getValue();
    describeOutput("out", "raw score for the given query item");
    return true;
}

FeatureExecutor::LP
ItemRawScoreBlueprint::createExecutor(const IQueryEnvironment &queryEnv) const
{
    HandleVector handles = resolve(queryEnv, _label);
    if (handles.size() == 1) {
        return FeatureExecutor::LP(new SimpleItemRawScoreExecutor(handles[0]));
    } else if (handles.size() == 0) {
        return FeatureExecutor::LP(new SingleZeroValueExecutor());
    } else {
        return FeatureExecutor::LP(new ItemRawScoreExecutor(handles));
    }
}

ItemRawScoreBlueprint::HandleVector
ItemRawScoreBlueprint::resolve(const search::fef::IQueryEnvironment &env,
                               const vespalib::string &label)
{
    HandleVector handles;
    const ITermData *term = util::getTermByLabel(env, label);
    if (term != nullptr) {
        uint32_t numFields(term->numFields());
        for (uint32_t i(0); i < numFields; ++i) {
            TermFieldHandle handle = term->field(i).getHandle();
            if (handle != IllegalHandle) {
                handles.push_back(handle);
            }
        }
    }
    return handles;
}

} // namespace features
} // namespace search
<|endoftext|>


<commit_before>/*
 * Author: Ivan De Cesaris <ivan.de.cesaris@intel.com>
 * Copyright (c) 2015 - 2017 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/* Digital output
 * Write values to a gpio digital output pin.
 */

#include <mraa.hpp>
#include <iostream>
#include <unistd.h>

// Define the following if using a Grove Pi Shield
#define USING_GROVE_PI_SHIELD
using namespace std;
using namespace mraa;

int main()
{
	int gpioPin = 13;
	string unknownPlatformMessage = "This sample uses the MRAA/UPM library for I/O access, "
    		"you are running it on an unrecognized platform. "
			"You may need to modify the MRAA/UPM initialization code to "
			"ensure it works properly on your platform.\n\n";

	// check which board we are running on
	Platform platform = getPlatformType();
	switch (platform) {
		case INTEL_UP2:
#ifdef USING_GROVE_PI_SHIELD
			gpioPin = 4 + 512; // D4 Connector (512 offset needed for the shield)
			break;
#endif
		case INTEL_UP:
		case INTEL_EDISON_FAB_C:
		case INTEL_GALILEO_GEN2:
			break;
		case INTEL_MINNOWBOARD_MAX: // Same for Minnowboard Turbot
			gpioPin = 104;
			break;
		case INTEL_JOULE_EXPANSION:
			gpioPin = 101;
			break;
		default:
	        cerr << unknownPlatformMessage;
	}
#ifdef USING_GROVE_PI_SHIELD
	addSubplatform(GROVEPI, "0");
#endif
	// check if running as root
	int euid = geteuid();
	if (euid) {
		cerr << "This project uses Mraa I/O operations, but you're not running as 'root'.\n"
				"The IO operations below might fail.\n"
				"See the project's Readme for more info.\n\n";
	}

	// create a GPIO object from MRAA for the pin	Gpio * d_pin = new Gpio (gpioPin);
	Gpio* d_pin = new Gpio(gpioPin);
	if (d_pin == NULL) {
		cerr << "MRAA couldn't initialize GPIO, exiting." << endl;
		return MRAA_ERROR_UNSPECIFIED;
	}
	// set the pin as output
	if (d_pin->dir(DIR_OUT) != SUCCESS) {
		cerr << "Can't set digital pin as output, exiting" << endl;
		return MRAA_ERROR_UNSPECIFIED;
	}

	// loop forever toggling the digital output every second
	for(;;) {
		d_pin->write(0);
		sleep(1);
		d_pin->write(1);
		sleep(1);
	}

	return SUCCESS;
}
<commit_msg>Remove Stray comment<commit_after>/*
 * Author: Ivan De Cesaris <ivan.de.cesaris@intel.com>
 * Copyright (c) 2015 - 2017 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/* Digital output
 * Write values to a gpio digital output pin.
 */

#include <mraa.hpp>
#include <iostream>
#include <unistd.h>

// Define the following if using a Grove Pi Shield
#define USING_GROVE_PI_SHIELD
using namespace std;
using namespace mraa;

int main()
{
	int gpioPin = 13;
	string unknownPlatformMessage = "This sample uses the MRAA/UPM library for I/O access, "
    		"you are running it on an unrecognized platform. "
			"You may need to modify the MRAA/UPM initialization code to "
			"ensure it works properly on your platform.\n\n";

	// check which board we are running on
	Platform platform = getPlatformType();
	switch (platform) {
		case INTEL_UP2:
#ifdef USING_GROVE_PI_SHIELD
			gpioPin = 4 + 512; // D4 Connector (512 offset needed for the shield)
			break;
#endif
		case INTEL_UP:
		case INTEL_EDISON_FAB_C:
		case INTEL_GALILEO_GEN2:
			break;
		case INTEL_MINNOWBOARD_MAX: // Same for Minnowboard Turbot
			gpioPin = 104;
			break;
		case INTEL_JOULE_EXPANSION:
			gpioPin = 101;
			break;
		default:
	        cerr << unknownPlatformMessage;
	}
#ifdef USING_GROVE_PI_SHIELD
	addSubplatform(GROVEPI, "0");
#endif
	// check if running as root
	int euid = geteuid();
	if (euid) {
		cerr << "This project uses Mraa I/O operations, but you're not running as 'root'.\n"
				"The IO operations below might fail.\n"
				"See the project's Readme for more info.\n\n";
	}

	// create a GPIO object from MRAA for the pin
	Gpio* d_pin = new Gpio(gpioPin);
	if (d_pin == NULL) {
		cerr << "MRAA couldn't initialize GPIO, exiting." << endl;
		return MRAA_ERROR_UNSPECIFIED;
	}
	// set the pin as output
	if (d_pin->dir(DIR_OUT) != SUCCESS) {
		cerr << "Can't set digital pin as output, exiting" << endl;
		return MRAA_ERROR_UNSPECIFIED;
	}

	// loop forever toggling the digital output every second
	for(;;) {
		d_pin->write(0);
		sleep(1);
		d_pin->write(1);
		sleep(1);
	}

	return SUCCESS;
}
<|endoftext|>


<commit_before>
#include <iostream>
#include "mpi.h"
#include "tree.h"
#include <cstring>

#define DLLEXPORT extern "C"
using namespace std;

struct MessageTree{
	int id;
  	int split_id[MAX_NODE_SIZE];
  	Value split_value[MAX_NODE_SIZE];

  	MessageTree( RegTree &t);
  	RegTree &ToRegTree();
};

MessageTree::MessageTree(RegTree &t){
	id = t.id;
	memcpy(split_id, & t.split_id[0], t.split_id.size() * sizeof(t.split_id[0]));
	memcpy(split_value, & t.split_value[0], t.split_value.size() * sizeof(t.split_value[0]));
}

RegTree & MessageTree::ToRegTree(void){
	RegTree *reg_tree= new RegTree{
		id,
		new vector<int>(split_id, split_id + sizeof split_id / sizeof split_id[0]),
		new vector<Value>(split_value, split_value + sizeof split_value / sizeof split_value[0])
	};

	return *reg_tree;
}

// this is only a test of python interface
DLLEXPORT int run(){
	int myrank, comm_sz;

    cout << "success \n";
    return 1;
}

void Master(int round, int comm_sz){
	int total_tree = round*(comm_sz-1);
	int current_count=0;
	MPI_Status stat;
	//local tree
	vector<MessageTree> trees;
	while (current_count<=total_tree){
		MessageTree *new_tree= new MessageTree;

		MPI_Recv(&new_tree, 1, MPI_TREE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);

		int remote_count = new_tree.id;
		int target_rank = stat.MPI_SOURCE;
		cout << "master receive tree from " << target_rank << "\n";
		current_count += 1;
		new_tree.id = current_count;
		tree.appendTree(new_tree);

		int send_count = current_count - remote_count;
		//send tree count here
		MPI_Send(&send_count, 1, MPI_INT, target_rank,0,MPI_COMM_WORLD);

		//for loop to send trees
		for(int i= remote_count+1; i<current_count+1; i++){
			MPI_Send(&(tree[i]), 1, MPI_TREE, target_rank, 0, MPI_COMM_WORLD);
		}

	}

}

void Worker(int round, int myrank, int comm_sz){
	int local_count=0;
	VecTree vec_tree
	for (int i=0; i<round;i++){
		//call train local here
		RegTree tree = new RegTree;//TrainLocal();
		MessageTree message_tree = MessageTree(tree);
		cout << "worker send tree"<< "\n";
		message_tree.id=local_count;
		MPI_Send(&new_tree, 1, MPI_TREE, 0, 0, MPI_COMM_WORLD);

		int receive_count;
		MPI_Recv(&receive_count, 1, MPI_INT, 0,0,MPI_COMM_WORLD);
		cout << "worker receive count"<< "\n";
		for (int i=local_count; i < local_count+receive_count; i++){
			MPI_Recv(&message_tree, 1, MPI_TREE, 0,0,MPI_COMM_WORLD);
			cout << "worker receive tree"<< "\n";
			vec_tree.push_back(message_tree.ToRegTree());
		}
		local_count=message_tree.id;
	}
}

DLLEXPORT int Dabtree(int round){
	int myrank, comm_sz;
	cout << "start project"<< "\n";
	MPI_Init(NULL,NULL);
	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

	//create mpi tree type
	MessageTree m;
	MPI_Datatype types[3]={MPI_INT,MPI_INT,MPI_INT};
	int bls[3] = {1,MAX_NODE_SIZE,MAX_NODE_SIZE};
	MPI_Aint disps[3];
	disps[0]=0;
	disps[1]=int(&(m.split_id[0])-(int*)&m)*sizeof(int);
	disps[2]=int(&(m.split_value[0])-(int*)&m)*sizeof(int);
	MPI_Datatype MPI_TREE
	MPI_Type_create_struct(3,bls,disps,types,&MPI_TREE);
	MPI_Type_commit(&MPI_TREE);
	cout << "start working"<< "\n";
	if (myrank==0){
		Master(round,comm_sz);
	}
	else{
		Worker(round,myrank,comm_sz);
	}

    cout << "success \n";

    MPI_Type_free(&MPI_TREE);
    MPI_Finalize();
    return 0;
}

<commit_msg>fixed some bugs<commit_after>
#include <iostream>
#include "mpi.h"
#include "tree.h"
#include <cstring>

#define DLLEXPORT extern "C"
using namespace std;

struct MessageTree{
	int id;
  	int split_id[MAX_NODE_SIZE];
  	Value split_value[MAX_NODE_SIZE];
  	MessageTree();
  	MessageTree( RegTree &t);
  	RegTree &ToRegTree();
};

MessageTree::MessageTree(RegTree &t){
	id = t.id;
	memcpy(split_id, & t.split_id[0], t.split_id.size() * sizeof(t.split_id[0]));
	memcpy(split_value, & t.split_value[0], t.split_value.size() * sizeof(t.split_value[0]));
}

RegTree & MessageTree::ToRegTree(void){
	auto reg_tree= new RegTree{
		id,
		new vector<int>(split_id, split_id + sizeof split_id / sizeof split_id[0]),
		new vector<Value>(split_value, split_value + sizeof split_value / sizeof split_value[0])
	};

	return reg_tree;
}

// this is only a test of python interface
DLLEXPORT int run(){
	int myrank, comm_sz;

    cout << "success \n";
    return 1;
}

void Master(int round, int comm_sz);
void Worker(int round, int myrank, int comm_sz);

DLLEXPORT int Dabtree(int round){
	int myrank, comm_sz;
	cout << "start project"<< "\n";
	MPI_Init(NULL,NULL);
	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

	//create mpi tree type
	MessageTree m;
	MPI_Datatype types[3]={MPI_INT,MPI_INT,MPI_INT};
	int bls[3] = {1,MAX_NODE_SIZE,MAX_NODE_SIZE};
	MPI_Aint disps[3];
	disps[0]=0;
	disps[1]=int(&(m.split_id[0])-(int*)&m)*sizeof(int);
	disps[2]=int(&(m.split_value[0])-(int*)&m)*sizeof(int);
	MPI_Datatype MPI_TREE
	MPI_Type_create_struct(3,bls,disps,types,&MPI_TREE);
	MPI_Type_commit(&MPI_TREE);
	cout << "start working"<< "\n";
	if (myrank==0){
		Master(round,comm_sz);
	}
	else{
		Worker(round,myrank,comm_sz);
	}

    cout << "success \n";

    MPI_Type_free(&MPI_TREE);
    MPI_Finalize();
    return 0;
}

void Master(int round, int comm_sz){
	int total_tree = round*(comm_sz-1);
	int current_count=0;
	MPI_Status stat;
	//local tree
	vector<MessageTree> trees;
	while (current_count<=total_tree){
		MessageTree *new_tree= new MessageTree();

		MPI_Recv(new_tree, 1, MPI_TREE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);

		int remote_count = new_tree->id;
		int target_rank = stat.MPI_SOURCE;
		cout << "master receive tree from " << target_rank << "\n";
		current_count += 1;
		new_tree->id = current_count;
		trees.push_back(&new_tree);

		int send_count = current_count - remote_count;
		//send tree count here
		MPI_Send(&send_count, 1, MPI_INT, target_rank,0,MPI_COMM_WORLD);

		//for loop to send trees
		for(int i= remote_count+1; i<current_count+1; i++){
			MPI_Send(&(tree[i]), 1, MPI_TREE, target_rank, 0, MPI_COMM_WORLD);
		}

	}

}

void Worker(int round, int myrank, int comm_sz){
	int local_count=0;
	VecTree vec_tree
	for (int i=0; i<round;i++){
		//call train local here
		RegTree *tree = new RegTree;//TrainLocal();
		MessageTree *message_tree = new MessageTree(&tree);
		cout << "worker send tree"<< "\n";
		message_tree->id=local_count;
		MPI_Send(message_tree, 1, MPI_TREE, 0, 0, MPI_COMM_WORLD);

		int receive_count;
		MPI_Recv(&receive_count, 1, MPI_INT, 0,0,MPI_COMM_WORLD);
		cout << "worker receive count"<< "\n";
		for (int i=local_count; i < local_count+receive_count; i++){
			MPI_Recv(message_tree, 1, MPI_TREE, 0,0,MPI_COMM_WORLD);
			cout << "worker receive tree"<< "\n";
			vec_tree.push_back(message_tree->ToRegTree());
		}
		local_count=message_tree->id;
	}
}

<|endoftext|>


<commit_before>//=====================================================================//
/*!	@file
	@brief	ethernet class
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "ethernet.hpp"

namespace net {

	T_IPV4EP ethernet::remoteIPV4EP_;
	char ethernet::UDPrecvBuf_[UDP_RCV_DAT_DATAREAD_MAXIMUM];

	uint8_t ethernet::byteq_buf[RING_SIZ];
	byteq_hdl_t	ethernet::hdl_;
	byteq_hdl_t	ethernet::hdl_forSize_;
	uint8_t ethernet::byteq_buf_forSize_[RING_SIZ_forSize];    /* sizeQueBody 1024 >> 2 = 256 */
}

extern "C" {

	int t4_udp_callback(uint32_t cepid, int32_t fncd , void *p_parblk) {
		return net::ethernet::udp_callback(cepid, fncd , p_parblk);
	}

}
<commit_msg>delete a file<commit_after><|endoftext|>


<commit_before>/*
 * opencog/cogserver/server/ListRequest.cc
 *
 * Copyright (C) 2008 by OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "ListRequest.h"

#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atoms/base/ClassServer.h>
#include <opencog/atoms/base/types.h>
#include <opencog/cogserver/server/CogServer.h>

using namespace opencog;

ListRequest::ListRequest(CogServer& cs) : Request(cs)
{
}

ListRequest::~ListRequest()
{
    logger().debug("[ListRequest] destructor");
}

bool ListRequest::syntaxError()
{
    _error << "invalid syntax" << std::endl;
    sendError();
    return false;
}

bool ListRequest::execute()
{
    std::string name = "";
    Type type = NOTYPE;
    long max_size = -1;
    Handle handle = Handle::UNDEFINED;
    bool subtypes = false;
    AtomSpace& as = _cogserver.getAtomSpace();

    if (_parameters.empty()) {
        _error << "Error: option required" << std::endl;
        sendError();
        return false;
    }

    std::list<std::string>::const_iterator it;
    for (it = _parameters.begin(); it != _parameters.end(); ++it) {
        if (*it == "-a") { // list everything
            type = NOTYPE;
            handle = Handle::UNDEFINED;
            subtypes = false;
            break;
        } else if (*it == "-n")  { // filter by name
            ++it;
            if (it == _parameters.end()) return syntaxError();
            name.assign(*it);
        } else if (*it == "-t") { // filter by type, excluding subtypes
            ++it;
            if (it == _parameters.end()) return syntaxError();
            type = classserver().getType(it->c_str());
            if (type == NOTYPE) {
                _error << "Error: Invalid type" << std::endl;
                sendError();
                return false;
            }
        } else if (*it == "-T") { // filter by type, including subtypes
            ++it;
            if (it == _parameters.end()) return syntaxError();
            type = classserver().getType(it->c_str());
            if (type == NOTYPE) {
                _error << "invalid type" << std::endl;
                sendError();
                return false;
            }
            subtypes = true;
        } else if (*it == "-m") { // list only the N first atoms
            ++it;
            if (it == _parameters.end()) return syntaxError();
            max_size = atol(it->c_str());
        } else {
            _error << "Error: unknown option \"" << *it <<"\"" << std::endl;
            sendError();
            return false;
        }
    }
    if (name != "" && type != NOTYPE) { // filter by name & type
        classserver().foreachRecursive(
            [&](Type t)->void {
                 try {
                     Handle h(as.get_handle(t, name));
                     if (h) _handles.push_back(h);
                 } catch (const std::exception& e) {}
            }, type);

    } else if (name != "") {     // filter by name
        classserver().foreachRecursive(
            [&](Type t)->void {
                 try {
                     Handle h(as.get_handle(t, name));
                     if (h) _handles.push_back(h);
                 } catch (const std::exception& e) {}
            }, NODE);

    } else if (type != NOTYPE) { // filter by type
        as.get_handles_by_type(std::back_inserter(_handles), type, subtypes);
    } else {
        as.get_handles_by_type(back_inserter(_handles), ATOM, true);
    }

    // Remove the bottom handles
    if (max_size > 0 && max_size < (long)_handles.size())
        _handles.resize(max_size);

    sendOutput();
    return true;
}

void ListRequest::sendOutput()
{
    std::ostringstream oss;
    for (const Handle& h : _handles) {
        oss << h->to_string() << std::endl;
    }
    send(oss.str());
}

void ListRequest::sendError()
{
    _error << "Supported options:" << std::endl;
    _error << "-a          List all atoms" << std::endl;
    _error << "-h handle   List given handle" << std::endl;
    _error << "-n name     List all atoms with name" << std::endl;
    _error << "-t type     List all atoms of type" << std::endl;
    _error << "-T type     List all atoms with type or subtype" << std::endl;
    _error << "-m type     List all atoms up to a specified size" << std::endl;
    _error << "Options may be combined" << std::endl;
    send(_error.str());
}
<commit_msg>There is no -h option<commit_after>/*
 * opencog/cogserver/server/ListRequest.cc
 *
 * Copyright (C) 2008 by OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "ListRequest.h"

#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atoms/base/ClassServer.h>
#include <opencog/atoms/base/types.h>
#include <opencog/cogserver/server/CogServer.h>

using namespace opencog;

ListRequest::ListRequest(CogServer& cs) : Request(cs)
{
}

ListRequest::~ListRequest()
{
    logger().debug("[ListRequest] destructor");
}

bool ListRequest::syntaxError()
{
    _error << "invalid syntax" << std::endl;
    sendError();
    return false;
}

bool ListRequest::execute()
{
    std::string name = "";
    Type type = NOTYPE;
    long max_size = -1;
    Handle handle = Handle::UNDEFINED;
    bool subtypes = false;
    AtomSpace& as = _cogserver.getAtomSpace();

    if (_parameters.empty()) {
        _error << "Error: option required" << std::endl;
        sendError();
        return false;
    }

    std::list<std::string>::const_iterator it;
    for (it = _parameters.begin(); it != _parameters.end(); ++it) {
        if (*it == "-a") { // list everything
            type = NOTYPE;
            handle = Handle::UNDEFINED;
            subtypes = false;
            break;
        } else if (*it == "-n")  { // filter by name
            ++it;
            if (it == _parameters.end()) return syntaxError();
            name.assign(*it);
        } else if (*it == "-t") { // filter by type, excluding subtypes
            ++it;
            if (it == _parameters.end()) return syntaxError();
            type = classserver().getType(it->c_str());
            if (type == NOTYPE) {
                _error << "Error: Invalid type" << std::endl;
                sendError();
                return false;
            }
        } else if (*it == "-T") { // filter by type, including subtypes
            ++it;
            if (it == _parameters.end()) return syntaxError();
            type = classserver().getType(it->c_str());
            if (type == NOTYPE) {
                _error << "invalid type" << std::endl;
                sendError();
                return false;
            }
            subtypes = true;
        } else if (*it == "-m") { // list only the N first atoms
            ++it;
            if (it == _parameters.end()) return syntaxError();
            max_size = atol(it->c_str());
        } else {
            _error << "Error: unknown option \"" << *it <<"\"" << std::endl;
            sendError();
            return false;
        }
    }
    if (name != "" && type != NOTYPE) { // filter by name & type
        classserver().foreachRecursive(
            [&](Type t)->void {
                 try {
                     Handle h(as.get_handle(t, name));
                     if (h) _handles.push_back(h);
                 } catch (const std::exception& e) {}
            }, type);

    } else if (name != "") {     // filter by name
        classserver().foreachRecursive(
            [&](Type t)->void {
                 try {
                     Handle h(as.get_handle(t, name));
                     if (h) _handles.push_back(h);
                 } catch (const std::exception& e) {}
            }, NODE);

    } else if (type != NOTYPE) { // filter by type
        as.get_handles_by_type(std::back_inserter(_handles), type, subtypes);
    } else {
        as.get_handles_by_type(back_inserter(_handles), ATOM, true);
    }

    // Remove the bottom handles
    if (max_size > 0 && max_size < (long)_handles.size())
        _handles.resize(max_size);

    sendOutput();
    return true;
}

void ListRequest::sendOutput()
{
    std::ostringstream oss;
    for (const Handle& h : _handles) {
        oss << h->to_string() << std::endl;
    }
    send(oss.str());
}

void ListRequest::sendError()
{
    _error << "Supported options:" << std::endl;
    _error << "-a          List all atoms" << std::endl;
    _error << "-n name     List all atoms with name" << std::endl;
    _error << "-t type     List all atoms of type" << std::endl;
    _error << "-T type     List all atoms with type or subtype" << std::endl;
    _error << "-m type     List all atoms up to a specified size" << std::endl;
    _error << "Options may be combined" << std::endl;
    send(_error.str());
}
<|endoftext|>


<commit_before>#include <thread>
#include <vector>

#include "a_devdiag.h"
#include "netstructures.h"
#include "tracepacket.h"

void a_devdiag() {
	pcap_if_t* alldevs;
	char errbuf[PCAP_ERRBUF_SIZE];

	if (pcap_findalldevs(&alldevs, errbuf) == -1) {
		printf("Could not find all network devices: %s\n", errbuf);
		exit(1);
	}

	int i = 0;
	pcap_if_t* d;
	for (d = alldevs; d; d = d->next) {
		printf("%d. %s", ++i, d->name);
		if (d->description) {
			printf(" - %s\n\n", d->description);
		}
	}

	int inum;
	printf("Enter the interface number (1-%d): ", i);
	scanf_s("%d", &inum);
	if (inum < 0 || inum > i) {
		printf("Number out of range!\n");
		exit(1);
	}

	for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);

	pcap_t* adhandle;
	if ((adhandle = pcap_open_live(d->name, 65536, 1, 500, errbuf)) == NULL) {
		printf("Unable to open the network adapter! %s is not supported by WinPcap\n", d->name);
		pcap_freealldevs(alldevs);
		exit(1);
	}

	if (pcap_datalink(adhandle) != DLT_EN10MB) {
		printf("Not using an ethernet device: output may not always be correct.\n");
	}

	u_int netmask;
	if (d->addresses != NULL) {
		netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
	}
	else {
		netmask = 0xffffff;
	}

	struct bpf_program fcode;
	char a_packetfilter[] = "ip and udp";
	if (pcap_compile(adhandle, &fcode, a_packetfilter, 1, netmask) < 0) {
		printf("Unable to compile packet filter!\n");
		pcap_freealldevs(alldevs);
		exit(1);
	}

	if (pcap_setfilter(adhandle, &fcode) < 0) {
		printf("Unable to set packet filter!\n");
		pcap_freealldevs(alldevs);
		exit(1);
	}

	pcap_freealldevs(alldevs);
	printf("\nStarting active diagnostics...\n\n");

	std::thread concurrent(cprocess);

	printf("Started PCAP processing...\n\n");
	currentpacket.count = 0;
	pcap_loop(adhandle, INFINITE, a_packethandler, NULL);
}

std::vector<tracepacket> pbuffer;

void cprocess() {
	char fullscreen[2000];
	char* templine = (char*)malloc(sizeof(char) * 80);//80 characters per line

	printf("Started concurrent processing - interval: %d\n\n", TRACE_PRINT_DELAY);
	bool activity_flag = false;
	while (true) {
		if (!pbuffer.empty()) {
			activity_flag = true;
			tracepacket packet = pbuffer.front();
			printf("Packet %i:\n", packet.count);
			printf("\t%s\n", packet.directionstring);
			printf("\tTimestamp: %s\n", packet.timestr);
			printf("\tDatagram length: %f\n", packet.d_len);
			printf("\tPayload length: %f\n", packet.size_payload);
			printf("\tTotal length: %f\n", packet.t_len);
			printf("\tPayload:\n\t-----------------\n\t%s\n\t-----------------\n", packet.payload);
			pbuffer.erase(pbuffer.begin());
			std::this_thread::sleep_for(std::chrono::milliseconds(TRACE_PRINT_DELAY));
		}
		else {
			if (activity_flag) {
				activity_flag = false;
				printf("No more packets! PCAP probably dropped some packets or the device lost connection.\n");
			}
		}
	}
}

void a_packethandler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
	struct tm ltime;
	char timestr[16];
	ip_header* ip;
	udp_header* udp;
	tcp_header* tcp;
	u_int ip_len;
	u_int tcp_len;
	u_short sport, dport;
	time_t local_tv_sec;
	const u_char* payload;

	(VOID)(param);

	local_tv_sec = header->ts.tv_sec;
	localtime_s(&ltime, &local_tv_sec);
	strftime(timestr, sizeof(timestr), "%H:%M:%S", &ltime);
	char* timestr_f = (char*)malloc(sizeof(char) * 16);
	snprintf(timestr_f, 16, "%s,%.6d", timestr, header->ts.tv_usec);

	ip = (ip_header*)(pkt_data + ETH_SIZE);
	ip_len = IP_HL(ip) * 4;

	udp = (udp_header*)((u_char *)ip + ip_len);
	tcp = (tcp_header*)(pkt_data + ETH_SIZE + ip_len);
	tcp_len = TH_OFF(tcp) * 4;

	payload = (u_char*)(pkt_data + ETH_SIZE + ip_len + tcp_len);

	sport = ntohs(udp->sport);
	dport = ntohs(udp->dport);

	//define current
	currentpacket.payload = payload;
	currentpacket.size_payload = ntohs(ip->tlen) - (ip_len + tcp_len);
	currentpacket.count = currentpacket.count + 1;
	currentpacket.timestr = timestr_f;
	currentpacket.d_len = header->len;
	currentpacket.t_len = ip->tlen;

	//define src and dest IPs
	src.byte1 = ip->saddr.byte1;
	src.byte2 = ip->saddr.byte2;
	src.byte3 = ip->saddr.byte3;
	src.byte4 = ip->saddr.byte4;
	src.port = sport;

	dest.byte1 = ip->daddr.byte1;
	dest.byte2 = ip->daddr.byte2;
	dest.byte3 = ip->daddr.byte3;
	dest.byte4 = ip->daddr.byte4;
	dest.port = dport;

	currentpacket.directionstring = src + dest;

	pbuffer.push_back(currentpacket);
}<commit_msg>Added fullscreen debug flag temporarily<commit_after>#include <thread>
#include <vector>

#include "a_devdiag.h"
#include "netstructures.h"
#include "tracepacket.h"

void a_devdiag() {
	pcap_if_t* alldevs;
	char errbuf[PCAP_ERRBUF_SIZE];

	if (pcap_findalldevs(&alldevs, errbuf) == -1) {
		printf("Could not find all network devices: %s\n", errbuf);
		exit(1);
	}

	int i = 0;
	pcap_if_t* d;
	for (d = alldevs; d; d = d->next) {
		printf("%d. %s", ++i, d->name);
		if (d->description) {
			printf(" - %s\n\n", d->description);
		}
	}

	int inum;
	printf("Enter the interface number (1-%d): ", i);
	scanf_s("%d", &inum);
	if (inum < 0 || inum > i) {
		printf("Number out of range!\n");
		exit(1);
	}

	for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);

	pcap_t* adhandle;
	if ((adhandle = pcap_open_live(d->name, 65536, 1, 500, errbuf)) == NULL) {
		printf("Unable to open the network adapter! %s is not supported by WinPcap\n", d->name);
		pcap_freealldevs(alldevs);
		exit(1);
	}

	if (pcap_datalink(adhandle) != DLT_EN10MB) {
		printf("Not using an ethernet device: output may not always be correct.\n");
	}

	u_int netmask;
	if (d->addresses != NULL) {
		netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
	}
	else {
		netmask = 0xffffff;
	}

	struct bpf_program fcode;
	char a_packetfilter[] = "ip and udp";
	if (pcap_compile(adhandle, &fcode, a_packetfilter, 1, netmask) < 0) {
		printf("Unable to compile packet filter!\n");
		pcap_freealldevs(alldevs);
		exit(1);
	}

	if (pcap_setfilter(adhandle, &fcode) < 0) {
		printf("Unable to set packet filter!\n");
		pcap_freealldevs(alldevs);
		exit(1);
	}

	pcap_freealldevs(alldevs);
	printf("\nStarting active diagnostics...\n\n");

	std::thread concurrent(cprocess);

	printf("Started PCAP processing...\n\n");
	currentpacket.count = 0;
	pcap_loop(adhandle, INFINITE, a_packethandler, NULL);
}

std::vector<tracepacket> pbuffer;

//#define FULLSCREEN

void cprocess() {
	char fullscreen[2000] = {'\0'};
	char* templine = (char*)malloc(sizeof(char) * 80);//80 characters per line

	printf("Started concurrent processing - interval: %d\n\n", TRACE_PRINT_DELAY);
	bool activity_flag = false;
	while (true) {
		if (!pbuffer.empty()) {
			activity_flag = true;
			tracepacket packet = pbuffer.front();
#ifdef FULLSCREEN
			snprintf(fullscreen, 80, "Packet %i:\n", packet.count);
			snprintf(fullscreen, 80, "\t%s\n", packet.directionstring);
			snprintf(fullscreen, 80, "\tTimestamp: %s\n", packet.timestr);
			snprintf(fullscreen, 80, "\tDatagram length: %f\n", packet.d_len);
			snprintf(fullscreen, 80, "\tPayload length: %f\n", packet.size_payload);
			snprintf(fullscreen, 80, "\tTotal length: %f\n", packet.t_len);
			snprintf(fullscreen, 80, "\tPayload:\n\t-----------------\n\t%s\n\t-----------------\n", packet.payload);
#else
			printf("Packet %i:\n", packet.count);
			printf("\t%s\n", packet.directionstring);
			printf("\tTimestamp: %s\n", packet.timestr);
			printf("\tDatagram length: %f\n", packet.d_len);
			printf("\tPayload length: %f\n", packet.size_payload);
			printf("\tTotal length: %f\n", packet.t_len);
			printf("\tPayload:\n\t-----------------\n\t%s\n\t-----------------\n", packet.payload);
#endif
			pbuffer.erase(pbuffer.begin());
			std::this_thread::sleep_for(std::chrono::milliseconds(TRACE_PRINT_DELAY));
		}
		else {
			if (activity_flag) {
				activity_flag = false;
				printf("No more packets! PCAP probably dropped some packets or the device lost connection.\n");
			}
		}
	}
}

void a_packethandler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
	struct tm ltime;
	char timestr[16];
	ip_header* ip;
	udp_header* udp;
	tcp_header* tcp;
	u_int ip_len;
	u_int tcp_len;
	u_short sport, dport;
	time_t local_tv_sec;
	const u_char* payload;

	(VOID)(param);

	local_tv_sec = header->ts.tv_sec;
	localtime_s(&ltime, &local_tv_sec);
	strftime(timestr, sizeof(timestr), "%H:%M:%S", &ltime);
	char* timestr_f = (char*)malloc(sizeof(char) * 16);
	snprintf(timestr_f, 16, "%s,%.6d", timestr, header->ts.tv_usec);

	ip = (ip_header*)(pkt_data + ETH_SIZE);
	ip_len = IP_HL(ip) * 4;

	udp = (udp_header*)((u_char *)ip + ip_len);
	tcp = (tcp_header*)(pkt_data + ETH_SIZE + ip_len);
	tcp_len = TH_OFF(tcp) * 4;

	payload = (u_char*)(pkt_data + ETH_SIZE + ip_len + tcp_len);

	sport = ntohs(udp->sport);
	dport = ntohs(udp->dport);

	//define current
	currentpacket.payload = payload;
	currentpacket.size_payload = ntohs(ip->tlen) - (ip_len + tcp_len);
	currentpacket.count = currentpacket.count + 1;
	currentpacket.timestr = timestr_f;
	currentpacket.d_len = header->len;
	currentpacket.t_len = ip->tlen;

	//define src and dest IPs
	src.byte1 = ip->saddr.byte1;
	src.byte2 = ip->saddr.byte2;
	src.byte3 = ip->saddr.byte3;
	src.byte4 = ip->saddr.byte4;
	src.port = sport;

	dest.byte1 = ip->daddr.byte1;
	dest.byte2 = ip->daddr.byte2;
	dest.byte3 = ip->daddr.byte3;
	dest.byte4 = ip->daddr.byte4;
	dest.port = dport;

	currentpacket.directionstring = src + dest;

	pbuffer.push_back(currentpacket);
}<|endoftext|>