<commit_before>#ifndef named_type_impl_h
#define named_type_impl_h

#include <type_traits>
#include <utility>

// Enable empty base class optimization with multiple inheritance on Visual Studio.
#if defined(_MSC_VER) && _MSC_VER >= 1910
#  define FLUENT_EBCO __declspec(empty_bases)
#else
#  define FLUENT_EBCO
#endif

namespace fluent
{

template<typename T>
using IsNotReference = typename std::enable_if<!std::is_reference<T>::value, void>::type;

template <typename T, typename Parameter, template<typename> class... Skills>
class FLUENT_EBCO NamedType : public Skills<NamedType<T, Parameter, Skills...>>...
{
public:
    using UnderlyingType = T;

    // constructor
    explicit constexpr NamedType(T const& value) : value_(value) {}
    template<typename T_ = T, typename = IsNotReference<T_>>
    explicit constexpr NamedType(T&& value) : value_(std::move(value)) {}

    template <typename T_ = T,
              typename = std::enable_if<std::is_default_constructible<T>::value, void>>
    constexpr NamedType() noexcept(std::is_nothrow_constructible<T>::value) {}

    // get
    constexpr T& get() { return value_; }
    constexpr std::remove_reference_t<T> const& get() const {return value_; }

    // conversions
    using ref = NamedType<T&, Parameter, Skills...>;
    operator ref ()
    {
        return ref(value_);
    }

    struct argument
    {
        NamedType operator=(T&& value) const
        {
            return NamedType(std::forward<T>(value));
        }

        template<typename U>
        NamedType operator=(U&& value) const
        {
            return NamedType(std::forward<U>(value));
        }
        argument() = default;
        argument(argument const&) = delete;
        argument(argument &&) = delete;
        argument& operator=(argument const&) = delete;
        argument& operator=(argument &&) = delete;
    };

private:
    T value_;
};

template<template<typename T> class StrongType, typename T>
constexpr StrongType<T> make_named(T const& value)
{
    return StrongType<T>(value);
}

} // namespace fluent

#endif /* named_type_impl_h */
<commit_msg>Remove default parameter in the enable_if of default construction<commit_after>#ifndef named_type_impl_h
#define named_type_impl_h

#include <type_traits>
#include <utility>

// Enable empty base class optimization with multiple inheritance on Visual Studio.
#if defined(_MSC_VER) && _MSC_VER >= 1910
#  define FLUENT_EBCO __declspec(empty_bases)
#else
#  define FLUENT_EBCO
#endif

namespace fluent
{

template<typename T>
using IsNotReference = typename std::enable_if<!std::is_reference<T>::value, void>::type;

template <typename T, typename Parameter, template<typename> class... Skills>
class FLUENT_EBCO NamedType : public Skills<NamedType<T, Parameter, Skills...>>...
{
public:
    using UnderlyingType = T;

    // constructor
    explicit constexpr NamedType(T const& value) : value_(value) {}
    template<typename T_ = T, typename = IsNotReference<T_>>
    explicit constexpr NamedType(T&& value) : value_(std::move(value)) {}

    template <typename T_ = T,
              typename = std::enable_if<std::is_default_constructible<T>::value>>
    constexpr NamedType() noexcept(std::is_nothrow_constructible<T>::value) {}

    // get
    constexpr T& get() { return value_; }
    constexpr std::remove_reference_t<T> const& get() const {return value_; }

    // conversions
    using ref = NamedType<T&, Parameter, Skills...>;
    operator ref ()
    {
        return ref(value_);
    }

    struct argument
    {
        NamedType operator=(T&& value) const
        {
            return NamedType(std::forward<T>(value));
        }

        template<typename U>
        NamedType operator=(U&& value) const
        {
            return NamedType(std::forward<U>(value));
        }
        argument() = default;
        argument(argument const&) = delete;
        argument(argument &&) = delete;
        argument& operator=(argument const&) = delete;
        argument& operator=(argument &&) = delete;
    };

private:
    T value_;
};

template<template<typename T> class StrongType, typename T>
constexpr StrongType<T> make_named(T const& value)
{
    return StrongType<T>(value);
}

} // namespace fluent

#endif /* named_type_impl_h */
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Bitsend Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "versionbits.h"

#include "consensus/params.h"

const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
    {
        /*.name =*/ "testdummy",
        /*.gbt_force =*/ true,
    },
    {
        /*.name =*/ "csv",
        /*.gbt_force =*/ true,
    },
    {
        /*.name =*/ "segwit",
        /*.gbt_force =*/ true,
    }
};

ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{
	int nPeriod = Period(params);
    int nThreshold = Threshold(params);
    int64_t nTimeStart = BeginTime(params);
    int64_t nTimeTimeout = EndTime(params);
	int64_t nThresholdHeight = Height(params);

	int64_t nHeight = pindexPrev->nHeight;

    // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
    if (pindexPrev != NULL) {
        pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
    }

    // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
    std::vector<const CBlockIndex*> vToCompute;
    while (cache.count(pindexPrev) == 0) {
        if (pindexPrev == NULL) {
            // The genesis block is by definition defined.
            cache[pindexPrev] = THRESHOLD_DEFINED;
            break;
        }
        if (pindexPrev->GetMedianTimePast() < nTimeStart) {
            // Optimization: don't recompute down further, as we know every earlier block will be before the start time
            cache[pindexPrev] = THRESHOLD_DEFINED;
            break;
        }
        vToCompute.push_back(pindexPrev);
        pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
    }

    // At this point, cache[pindexPrev] is known
    assert(cache.count(pindexPrev));
    ThresholdState state = cache[pindexPrev];

    // Now walk forward and compute the state of descendants of pindexPrev
    while (!vToCompute.empty()) {
        ThresholdState stateNext = state;
        pindexPrev = vToCompute.back();
        vToCompute.pop_back();

        switch (state) {
            case THRESHOLD_DEFINED: {
                if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
                    stateNext = THRESHOLD_FAILED;
                } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
                    stateNext = THRESHOLD_STARTED;
                }
                break;
            }
            case THRESHOLD_STARTED: {
                if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
                    stateNext = THRESHOLD_FAILED;
                    break;
                }
                // We need to count
                const CBlockIndex* pindexCount = pindexPrev;
                int count = 0;
                for (int i = 0; i < nPeriod; i++) {
                    if (Condition(pindexCount, params)) {
                        count++;
                    }
                    pindexCount = pindexCount->pprev;
                }
                if (count >= nThreshold ) {
                    stateNext = THRESHOLD_LOCKED_IN;
                }
                break;
            }
            case THRESHOLD_LOCKED_IN: {
                // Always progresses into ACTIVE.
                stateNext = THRESHOLD_ACTIVE;
                break;
            }
            case THRESHOLD_FAILED:
            case THRESHOLD_ACTIVE: {
                // Nothing happens, these are terminal states.
                break;
            }
        }
        cache[pindexPrev] = state = stateNext;
    }

    return state;
	/* int64_t nHeightPrev = Height(params);

	ThresholdState state = THRESHOLD_DEFINED;

	if(pindexPrev->nHeight >= nHeightPrev){
		state = THRESHOLD_ACTIVE;
	}
	//check
	/* if(pindexPrev->nHeight >= nHeightPrev && state != THRESHOLD_ACTIVE){
		//Bug , Please report
		LogPrintf("Bug Warning");
	} *

    return state;  */
}

int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{
    const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);

    // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
    if (initialState == THRESHOLD_DEFINED) {
        return 0;
    }

    const int nPeriod = Period(params);

    // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
    // To ease understanding of the following height calculation, it helps to remember that
    // right now pindexPrev points to the block prior to the block that we are computing for, thus:
    // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
    // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
    // The parent of the genesis block is represented by NULL.
    pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));

    const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);

    while (previousPeriodParent != NULL && GetStateFor(previousPeriodParent, params, cache) == initialState) {
        pindexPrev = previousPeriodParent;
        previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
    }

    // Adjust the result because right now we point to the parent block.
    return pindexPrev->nHeight + 1;
}

namespace
{
/**
 * Class to implement versionbits logic.
 */
class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
private:
    const Consensus::DeploymentPos id;

protected:
    int64_t BeginTime(const Consensus::Params& params) const { return params.vDeployments[id].nStartTime; }
    int64_t EndTime(const Consensus::Params& params) const { return params.vDeployments[id].nTimeout; }
	int64_t Height(const Consensus::Params& params) const { return params.vDeployments[id].nHeight; }
    int Period(const Consensus::Params& params) const { return params.nMinerConfirmationWindow; }
    int Threshold(const Consensus::Params& params) const { return params.nRuleChangeActivationThreshold; }

    bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const
    {
        return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
		//return (pindex->nHeight >= 354490);//current height
    }

public:
    VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
    uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
};

}

ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
{
    return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
}

int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
{
    return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
}

uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
{
    return VersionBitsConditionChecker(pos).Mask(params);
}

void VersionBitsCache::Clear()
{
    for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
        caches[d].clear();
    }
}
<commit_msg>BIP9_Switch: Don't relay on version bits blindly, check if we have ThresholdHeight<commit_after>// Copyright (c) 2016 The Bitsend Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "versionbits.h"

#include "consensus/params.h"

const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
    {
        /*.name =*/ "testdummy",
        /*.gbt_force =*/ true,
    },
    {
        /*.name =*/ "csv",
        /*.gbt_force =*/ true,
    },
    {
        /*.name =*/ "segwit",
        /*.gbt_force =*/ true,
    }
};

ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{
	int nPeriod = Period(params);
    int nThreshold = Threshold(params);
    int64_t nTimeStart = BeginTime(params);
    int64_t nTimeTimeout = EndTime(params);
	int64_t nThresholdHeight = Height(params);

	int64_t nHeight = 0;

    // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
    if (pindexPrev != NULL) {
		nHeight = pindexPrev->nHeight;
        pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
    }

    // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
    std::vector<const CBlockIndex*> vToCompute;
    while (cache.count(pindexPrev) == 0) {
        if (pindexPrev == NULL) {
            // The genesis block is by definition defined.
            cache[pindexPrev] = THRESHOLD_DEFINED;
            break;
        }
        if (pindexPrev->GetMedianTimePast() < nTimeStart) {
            // Optimization: don't recompute down further, as we know every earlier block will be before the start time
            cache[pindexPrev] = THRESHOLD_DEFINED;
            break;
        }
        vToCompute.push_back(pindexPrev);
        pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
    }

    // At this point, cache[pindexPrev] is known
    assert(cache.count(pindexPrev));
    ThresholdState state = cache[pindexPrev];

    // Now walk forward and compute the state of descendants of pindexPrev
    while (!vToCompute.empty()) {
        ThresholdState stateNext = state;
        pindexPrev = vToCompute.back();
        vToCompute.pop_back();

        switch (state) {
            case THRESHOLD_DEFINED: {
                if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
                    stateNext = THRESHOLD_FAILED;
                } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
                    stateNext = THRESHOLD_STARTED;
                }
                break;
            }
            case THRESHOLD_STARTED: {
                if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
                    stateNext = THRESHOLD_FAILED;
                    break;
                }
                // We need to count
                const CBlockIndex* pindexCount = pindexPrev;
                int count = 0;
                for (int i = 0; i < nPeriod; i++) {
                    if (Condition(pindexCount, params)) {
                        count++;
                    }
                    pindexCount = pindexCount->pprev;
                }
                if (count >= nThreshold && nHeight >= nThresholdHeight) {
                    stateNext = THRESHOLD_LOCKED_IN;
                }
                break;
            }
            case THRESHOLD_LOCKED_IN: {
                // Always progresses into ACTIVE.
                stateNext = THRESHOLD_ACTIVE;
                break;
            }
            case THRESHOLD_FAILED:
            case THRESHOLD_ACTIVE: {
                // Nothing happens, these are terminal states.
                break;
            }
        }
        cache[pindexPrev] = state = stateNext;
    }

    return state;
	/* int64_t nHeightPrev = Height(params);

	ThresholdState state = THRESHOLD_DEFINED;

	if(pindexPrev->nHeight >= nHeightPrev){
		state = THRESHOLD_ACTIVE;
	}
	//check
	/* if(pindexPrev->nHeight >= nHeightPrev && state != THRESHOLD_ACTIVE){
		//Bug , Please report
		LogPrintf("Bug Warning");
	} *

    return state;  */
}

int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{
    const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);

    // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
    if (initialState == THRESHOLD_DEFINED) {
        return 0;
    }

    const int nPeriod = Period(params);

    // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
    // To ease understanding of the following height calculation, it helps to remember that
    // right now pindexPrev points to the block prior to the block that we are computing for, thus:
    // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
    // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
    // The parent of the genesis block is represented by NULL.
    pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));

    const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);

    while (previousPeriodParent != NULL && GetStateFor(previousPeriodParent, params, cache) == initialState) {
        pindexPrev = previousPeriodParent;
        previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
    }

    // Adjust the result because right now we point to the parent block.
    return pindexPrev->nHeight + 1;
}

namespace
{
/**
 * Class to implement versionbits logic.
 */
class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
private:
    const Consensus::DeploymentPos id;

protected:
    int64_t BeginTime(const Consensus::Params& params) const { return params.vDeployments[id].nStartTime; }
    int64_t EndTime(const Consensus::Params& params) const { return params.vDeployments[id].nTimeout; }
	int64_t Height(const Consensus::Params& params) const { return params.vDeployments[id].nHeight; }
    int Period(const Consensus::Params& params) const { return params.nMinerConfirmationWindow; }
    int Threshold(const Consensus::Params& params) const { return params.nRuleChangeActivationThreshold; }

    bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const
    {
        return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
		//return (pindex->nHeight >= 354490);//current height
    }

public:
    VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
    uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
};

}

ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
{
    return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
}

int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
{
    return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
}

uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
{
    return VersionBitsConditionChecker(pos).Mask(params);
}

void VersionBitsCache::Clear()
{
    for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
        caches[d].clear();
    }
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////
//
// mSIGNA
//
// versioninfo.cpp
//
// Copyright (c) 2013 Eric Lombrozo
// Copyright (c) 2011-2016 Ciphrex Corp.
//
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
//

#include "versioninfo.h"
#include "../BuildInfo.h"

#include <CoinDB/Schema.h>

#include <openssl/opensslv.h>

// Definitions
const QString VERSIONTEXT("0.10.5a");

const QString commitHash(COMMIT_HASH);
const QString shortCommitHash(QString(COMMIT_HASH).left(7));

const uint32_t schemaVersion(SCHEMA_VERSION);
const QString schemaVersionText(QString::number(SCHEMA_VERSION));

const uint32_t openSSLVersionNumber(OPENSSL_VERSION_NUMBER);
const QString openSSLVersionText(OPENSSL_VERSION_TEXT);

// Accessors
const QString& getVersionText() { return VERSIONTEXT; }

const QString& getCommitHash() { return commitHash; }
const QString& getShortCommitHash() { return shortCommitHash; }

uint32_t getSchemaVersion() { return schemaVersion; }
const QString& getSchemaVersionText() { return schemaVersionText; }

uint32_t getOpenSSLVersionNumber() { return openSSLVersionNumber; }
const QString& getOpenSSLVersionText() { return openSSLVersionText; }

<commit_msg>Version bump 0.10.6<commit_after>///////////////////////////////////////////////////////////////////
//
// mSIGNA
//
// versioninfo.cpp
//
// Copyright (c) 2013 Eric Lombrozo
// Copyright (c) 2011-2016 Ciphrex Corp.
//
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
//

#include "versioninfo.h"
#include "../BuildInfo.h"

#include <CoinDB/Schema.h>

#include <openssl/opensslv.h>

// Definitions
const QString VERSIONTEXT("0.10.6");

const QString commitHash(COMMIT_HASH);
const QString shortCommitHash(QString(COMMIT_HASH).left(7));

const uint32_t schemaVersion(SCHEMA_VERSION);
const QString schemaVersionText(QString::number(SCHEMA_VERSION));

const uint32_t openSSLVersionNumber(OPENSSL_VERSION_NUMBER);
const QString openSSLVersionText(OPENSSL_VERSION_TEXT);

// Accessors
const QString& getVersionText() { return VERSIONTEXT; }

const QString& getCommitHash() { return commitHash; }
const QString& getShortCommitHash() { return shortCommitHash; }

uint32_t getSchemaVersion() { return schemaVersion; }
const QString& getSchemaVersionText() { return schemaVersionText; }

uint32_t getOpenSSLVersionNumber() { return openSSLVersionNumber; }
const QString& getOpenSSLVersionText() { return openSSLVersionText; }

<|endoftext|>


<commit_before>#include "interface/usb.h"
#include "can/canread.h"
#include "interface/uart.h"
#include "interface/network.h"
#include "signals.h"
#include "util/log.h"
#include "cJSON.h"
#include "pipeline.h"
#include "util/timer.h"
#include "lights.h"
#include "power.h"
#include "bluetooth.h"
#include "platform_profile.h"
#include "platform/pic32/telit_he910.h"
#include "platform/pic32/server_task.h"
#include "platform/platform.h"
#include "diagnostics.h"
#include "obd2.h"
#include "data_emulator.h"
#include "config.h"
#include "commands/commands.h"
#include "platform/pic32/nvm.h"

#ifdef RTC_SUPPORT
#include "platform/pic32/rtc.h"
#endif

namespace uart = openxc::interface::uart;
namespace network = openxc::interface::network;
namespace ble = openxc::interface::ble;
namespace fs = openxc::interface::fs;

namespace usb = openxc::interface::usb;
namespace lights = openxc::lights;
namespace can = openxc::can;
namespace platform = openxc::platform;
namespace time = openxc::util::time;
namespace signals = openxc::signals;
namespace diagnostics = openxc::diagnostics;
namespace power = openxc::power;
namespace bluetooth = openxc::bluetooth;
namespace commands = openxc::commands;
namespace config = openxc::config;
namespace telit = openxc::telitHE910;
namespace server_task = openxc::server_task;
namespace nvm = openxc::nvm;

using openxc::util::log::debug;
using openxc::signals::getCanBuses;
using openxc::signals::getCanBusCount;
using openxc::signals::getSignals;
using openxc::signals::getMessages;
using openxc::signals::getMessageCount;
using openxc::signals::getSignalCount;
using openxc::pipeline::Pipeline;
using openxc::config::getConfiguration;
using openxc::config::PowerManagement;
using openxc::config::RunLevel;

static bool BUS_WAS_ACTIVE;
static bool SUSPENDED;

/* Public: Update the color and status of a board's light that shows the output
 * interface status. This function is intended to be called each time through
 * the main program loop.
 */
void updateInterfaceLight() {
	//Interface connected = green led enabled/attached
	//Interface disconnected = green led disabled

    #ifdef TELIT_HE910_SUPPORT
    if(telit::connected(getConfiguration()->telit)) {
        lights::enable(lights::LIGHT_A, lights::COLORS.green);
    }
    #elif defined CROSSCHASM_C5_COMMON
    if(getConfiguration()->usb.configured ||
	#if defined CROSSCHASM_C5_BLE
		ble::connected(getConfiguration()->ble) ||
	#endif
		uart::connected(&getConfiguration()->uart)) {
        lights::enable(lights::LIGHT_A, lights::COLORS.green);
    }else {
		lights::disable(lights::LIGHT_A);
    }
    #else
    if(uart::connected(&getConfiguration()->uart)) {
        lights::enable(lights::LIGHT_B, lights::COLORS.blue);
    }
    else if(getConfiguration()->usb.configured){ //if either of the interface are connected
        lights::enable(lights::LIGHT_B, lights::COLORS.green);
    } else {
       lights::disable(lights::LIGHT_B);
    }
    #endif

}

/* Public: Update the color and status of a board's light that shows the status
 * of the CAN bus. This function is intended to be called each time through the
 * main program loop.
 */
void checkBusActivity() {
    bool busActive = false;
    for(int i = 0; i < getCanBusCount(); i++) {
        busActive = busActive || can::busActive(&getCanBuses()[i]);
    }

    if(!BUS_WAS_ACTIVE && busActive) {
        debug("CAN woke up");
        if(getConfiguration()->powerManagement !=
                PowerManagement::OBD2_IGNITION_CHECK) {
            // If we are letting the OBD2 ignition check control power, don't go
            // into ALL_IO just yet - we may have received an OBD-II response
            // saying the engine RPM and vehicle speed are both 0, and we want
            // to go back to sleep. In SILENT_CAN power mode it defaults to
            // ALL_IO at initialization, so this is just a backup.
            // getConfiguration()->desiredRunLevel = RunLevel::ALL_IO;
        }
		#ifdef CROSSCHASM_C5_COMMON
			lights::enable(lights::LIGHT_B, lights::COLORS.blue); //enable red led
		#else
			lights::enable(lights::LIGHT_A, lights::COLORS.blue);
		#endif

        BUS_WAS_ACTIVE = true;
        SUSPENDED = false;
    } else if(!busActive && (BUS_WAS_ACTIVE || (time::uptimeMs() >
            (unsigned long)openxc::can::CAN_ACTIVE_TIMEOUT_S * 1000 &&
            !SUSPENDED))) {
        debug("CAN is quiet");
        #ifdef CROSSCHASM_C5_COMMON
			lights::enable(lights::LIGHT_C, lights::COLORS.red); //enable red led
		#else
			lights::enable(lights::LIGHT_A, lights::COLORS.red);
        #endif

        SUSPENDED = true;
        BUS_WAS_ACTIVE = false;
        #ifdef FS_SUPPORT
        if(fs::getmode() !=  FS_STATE::USB_CONNECTED){
        #endif
        if(getConfiguration()->powerManagement != PowerManagement::ALWAYS_ON) {
            // stay awake at least CAN_ACTIVE_TIMEOUT_S after power on
        #ifdef RTC_SUPPORT
        rtc_timer_ms_deinit();
        #endif
            platform::suspend(&getConfiguration()->pipeline);
        }
#ifdef FS_SUPPORT
        }
#endif
    }
}

void initializeAllCan() {
    for(int i = 0; i < getCanBusCount(); i++) {
        CanBus* bus = &(getCanBuses()[i]);

        bool writable = bus->rawWritable ||
            can::signalsWritable(bus, getSignals(), getSignalCount());
        if(getConfiguration()->sendCanAcks) {
            writable = true;
        }
        can::initialize(bus, writable, getCanBuses(), getCanBusCount());
    }
}

/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the uart monitor.
 */
void receiveCan(Pipeline* pipeline, CanBus* bus) {
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        signals::decodeCanMessage(pipeline, bus, &message);
        if(bus->passthroughCanMessages) {
            openxc::can::read::passthroughMessage(bus, &message, getMessages(),
                    getMessageCount(), pipeline);
        }

        bus->lastMessageReceived = time::systemTimeMs();
        ++bus->messagesReceived;

        diagnostics::receiveCanMessage(&getConfiguration()->diagnosticsManager,
                bus, &message, pipeline);
    }
}

void initializeIO() {

    debug("Moving to ALL I/O runlevel");
    #ifdef RTC_SUPPORT
    RTC_Init();
    #endif

    #ifdef FS_SUPPORT
    fs::initialize(getConfiguration()->fs);
    #endif

    usb::initialize(&getConfiguration()->usb);
    uart::initialize(&getConfiguration()->uart);

    #ifdef BLE_SUPPORT
    ble::initialize(getConfiguration()->ble);
    #endif
    #ifdef BLUETOOTH_SUPPORT
    bluetooth::start(&getConfiguration()->uart);
    #endif
    network::initialize(&getConfiguration()->network);
    getConfiguration()->runLevel = RunLevel::ALL_IO;

    debug("ERIC: dummy can init call after uart setup - remove");
    initializeAllCan();
}

void initializeVehicleInterface() {
    #ifdef TELIT_HE910_SUPPORT
    nvm::initialize();
    #endif
    platform::initialize();
    openxc::util::log::initialize();
    time::initialize();
    power::initialize();
    lights::initialize();

    srand(time::systemTimeMs());
    initializeAllCan();

    char descriptor[128];
    config::getFirmwareDescriptor(descriptor, sizeof(descriptor));
    debug("Performing minimal initialization for %s", descriptor);
    BUS_WAS_ACTIVE = false;

    diagnostics::initialize(&getConfiguration()->diagnosticsManager,
            getCanBuses(), getCanBusCount(),
            getConfiguration()->obd2BusAddress);
    signals::initialize(&getConfiguration()->diagnosticsManager);
    getConfiguration()->runLevel = RunLevel::CAN_ONLY;

    if(getConfiguration()->powerManagement ==
            PowerManagement::OBD2_IGNITION_CHECK) {
        getConfiguration()->desiredRunLevel = RunLevel::CAN_ONLY;
    } else {
        getConfiguration()->desiredRunLevel = RunLevel::ALL_IO;
        initializeIO();
    }

    // If we don't delay a little bit, time::elapsed seems to return true no
    // matter what for DEBUG=0 builds.
    time::delayMs(500);
}

void firmwareLoop() {
    if(getConfiguration()->runLevel != RunLevel::ALL_IO &&
            getConfiguration()->desiredRunLevel == RunLevel::ALL_IO) {
        initializeIO();
    }
    for(int i = 0; i < getCanBusCount(); i++) {
        // In normal operation, if no output interface is enabled/attached (e.g.
        // no USB or Bluetooth, the loop will stall here. Deep down in
        // receiveCan when it tries to append messages to the queue it will
        // reach a point where it tries to flush the (full) queue. Since nothing
        // is attached, that will just keep timing out. Just be aware that if
        // you need to modify the firmware to not use any interfaces, you'll
        // have to change that or enable the flush functionality to write to
        // your desired output interface.
        CanBus* bus = &(getCanBuses()[i]);
        receiveCan(&getConfiguration()->pipeline, bus);
        diagnostics::sendRequests(&getConfiguration()->diagnosticsManager, bus);
    }

    diagnostics::obd2::loop(&getConfiguration()->diagnosticsManager);

    if(getConfiguration()->runLevel == RunLevel::ALL_IO) {
        usb::read(&getConfiguration()->usb, usb::handleIncomingMessage);
        #ifdef TELIT_HE910_SUPPORT
        telit::connectionManager(getConfiguration()->telit);
        if(telit::connected(getConfiguration()->telit)) {
            if(getConfiguration()->telit->config.globalPositioningSettings.gpsEnable) {
                telit::getGPSLocation();
            }
            server_task::firmwareCheck(getConfiguration()->telit);
            server_task::flushDataBuffer(getConfiguration()->telit);
            server_task::commandCheck(getConfiguration()->telit);
        }
        #elif defined BLE_SUPPORT
        ble::read(getConfiguration()->ble);
        #else
        uart::read(&getConfiguration()->uart, uart::handleIncomingMessage);
        #endif
        network::read(&getConfiguration()->network,
                network::handleIncomingMessage);
    }

    for(int i = 0; i < getCanBusCount(); i++) {
        can::write::flushOutgoingCanMessageQueue(&getCanBuses()[i]);
    }

    checkBusActivity();
    if(getConfiguration()->runLevel == RunLevel::ALL_IO) {
        updateInterfaceLight();
    }

    signals::loop();

    can::logBusStatistics(getCanBuses(), getCanBusCount());
    openxc::pipeline::logStatistics(&getConfiguration()->pipeline);

    if(getConfiguration()->emulatedData) {
        static bool connected = false;
        if(!connected && openxc::interface::anyConnected()) {
            connected = true;
            openxc::emulator::restart();
        } else if(connected && !openxc::interface::anyConnected()) {
            connected = false;
        }

        if(connected) {
            openxc::emulator::generateFakeMeasurements(
                    &getConfiguration()->pipeline);
        }
    }
    #ifdef FS_SUPPORT
    fs::manager(getConfiguration()->fs);
    #endif
    #ifdef RTC_SUPPORT
    rtc_task();
    #endif
    openxc::pipeline::process(&getConfiguration()->pipeline);
}
<commit_msg>rm debug calls<commit_after>#include "interface/usb.h"
#include "can/canread.h"
#include "interface/uart.h"
#include "interface/network.h"
#include "signals.h"
#include "util/log.h"
#include "cJSON.h"
#include "pipeline.h"
#include "util/timer.h"
#include "lights.h"
#include "power.h"
#include "bluetooth.h"
#include "platform_profile.h"
#include "platform/pic32/telit_he910.h"
#include "platform/pic32/server_task.h"
#include "platform/platform.h"
#include "diagnostics.h"
#include "obd2.h"
#include "data_emulator.h"
#include "config.h"
#include "commands/commands.h"
#include "platform/pic32/nvm.h"

#ifdef RTC_SUPPORT
#include "platform/pic32/rtc.h"
#endif

namespace uart = openxc::interface::uart;
namespace network = openxc::interface::network;
namespace ble = openxc::interface::ble;
namespace fs = openxc::interface::fs;

namespace usb = openxc::interface::usb;
namespace lights = openxc::lights;
namespace can = openxc::can;
namespace platform = openxc::platform;
namespace time = openxc::util::time;
namespace signals = openxc::signals;
namespace diagnostics = openxc::diagnostics;
namespace power = openxc::power;
namespace bluetooth = openxc::bluetooth;
namespace commands = openxc::commands;
namespace config = openxc::config;
namespace telit = openxc::telitHE910;
namespace server_task = openxc::server_task;
namespace nvm = openxc::nvm;

using openxc::util::log::debug;
using openxc::signals::getCanBuses;
using openxc::signals::getCanBusCount;
using openxc::signals::getSignals;
using openxc::signals::getMessages;
using openxc::signals::getMessageCount;
using openxc::signals::getSignalCount;
using openxc::pipeline::Pipeline;
using openxc::config::getConfiguration;
using openxc::config::PowerManagement;
using openxc::config::RunLevel;

static bool BUS_WAS_ACTIVE;
static bool SUSPENDED;

/* Public: Update the color and status of a board's light that shows the output
 * interface status. This function is intended to be called each time through
 * the main program loop.
 */
void updateInterfaceLight() {
	//Interface connected = green led enabled/attached
	//Interface disconnected = green led disabled

    #ifdef TELIT_HE910_SUPPORT
    if(telit::connected(getConfiguration()->telit)) {
        lights::enable(lights::LIGHT_A, lights::COLORS.green);
    }
    #elif defined CROSSCHASM_C5_COMMON
    if(getConfiguration()->usb.configured ||
	#if defined CROSSCHASM_C5_BLE
		ble::connected(getConfiguration()->ble) ||
	#endif
		uart::connected(&getConfiguration()->uart)) {
        lights::enable(lights::LIGHT_A, lights::COLORS.green);
    }else {
		lights::disable(lights::LIGHT_A);
    }
    #else
    if(uart::connected(&getConfiguration()->uart)) {
        lights::enable(lights::LIGHT_B, lights::COLORS.blue);
    }
    else if(getConfiguration()->usb.configured){ //if either of the interface are connected
        lights::enable(lights::LIGHT_B, lights::COLORS.green);
    } else {
       lights::disable(lights::LIGHT_B);
    }
    #endif

}

/* Public: Update the color and status of a board's light that shows the status
 * of the CAN bus. This function is intended to be called each time through the
 * main program loop.
 */
void checkBusActivity() {
    bool busActive = false;
    for(int i = 0; i < getCanBusCount(); i++) {
        busActive = busActive || can::busActive(&getCanBuses()[i]);
    }

    if(!BUS_WAS_ACTIVE && busActive) {
        debug("CAN woke up");
        if(getConfiguration()->powerManagement !=
                PowerManagement::OBD2_IGNITION_CHECK) {
            // If we are letting the OBD2 ignition check control power, don't go
            // into ALL_IO just yet - we may have received an OBD-II response
            // saying the engine RPM and vehicle speed are both 0, and we want
            // to go back to sleep. In SILENT_CAN power mode it defaults to
            // ALL_IO at initialization, so this is just a backup.
            // getConfiguration()->desiredRunLevel = RunLevel::ALL_IO;
        }
		#ifdef CROSSCHASM_C5_COMMON
			lights::enable(lights::LIGHT_B, lights::COLORS.blue); //enable red led
		#else
			lights::enable(lights::LIGHT_A, lights::COLORS.blue);
		#endif

        BUS_WAS_ACTIVE = true;
        SUSPENDED = false;
    } else if(!busActive && (BUS_WAS_ACTIVE || (time::uptimeMs() >
            (unsigned long)openxc::can::CAN_ACTIVE_TIMEOUT_S * 1000 &&
            !SUSPENDED))) {
        debug("CAN is quiet");
        #ifdef CROSSCHASM_C5_COMMON
			lights::enable(lights::LIGHT_C, lights::COLORS.red); //enable red led
		#else
			lights::enable(lights::LIGHT_A, lights::COLORS.red);
        #endif

        SUSPENDED = true;
        BUS_WAS_ACTIVE = false;
        #ifdef FS_SUPPORT
        if(fs::getmode() !=  FS_STATE::USB_CONNECTED){
        #endif
        if(getConfiguration()->powerManagement != PowerManagement::ALWAYS_ON) {
            // stay awake at least CAN_ACTIVE_TIMEOUT_S after power on
        #ifdef RTC_SUPPORT
        rtc_timer_ms_deinit();
        #endif
            platform::suspend(&getConfiguration()->pipeline);
        }
#ifdef FS_SUPPORT
        }
#endif
    }
}

void initializeAllCan() {
    for(int i = 0; i < getCanBusCount(); i++) {
        CanBus* bus = &(getCanBuses()[i]);

        bool writable = bus->rawWritable ||
            can::signalsWritable(bus, getSignals(), getSignalCount());
        if(getConfiguration()->sendCanAcks) {
            writable = true;
        }
        can::initialize(bus, writable, getCanBuses(), getCanBusCount());
    }
}

/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the uart monitor.
 */
void receiveCan(Pipeline* pipeline, CanBus* bus) {
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        signals::decodeCanMessage(pipeline, bus, &message);
        if(bus->passthroughCanMessages) {
            openxc::can::read::passthroughMessage(bus, &message, getMessages(),
                    getMessageCount(), pipeline);
        }

        bus->lastMessageReceived = time::systemTimeMs();
        ++bus->messagesReceived;

        diagnostics::receiveCanMessage(&getConfiguration()->diagnosticsManager,
                bus, &message, pipeline);
    }
}

void initializeIO() {

    debug("Moving to ALL I/O runlevel");
    #ifdef RTC_SUPPORT
    RTC_Init();
    #endif

    #ifdef FS_SUPPORT
    fs::initialize(getConfiguration()->fs);
    #endif

    usb::initialize(&getConfiguration()->usb);
    uart::initialize(&getConfiguration()->uart);

    #ifdef BLE_SUPPORT
    ble::initialize(getConfiguration()->ble);
    #endif
    #ifdef BLUETOOTH_SUPPORT
    bluetooth::start(&getConfiguration()->uart);
    #endif
    network::initialize(&getConfiguration()->network);
    getConfiguration()->runLevel = RunLevel::ALL_IO;

}

void initializeVehicleInterface() {
    #ifdef TELIT_HE910_SUPPORT
    nvm::initialize();
    #endif
    platform::initialize();
    openxc::util::log::initialize();
    time::initialize();
    power::initialize();
    lights::initialize();

    srand(time::systemTimeMs());
    initializeAllCan();

    char descriptor[128];
    config::getFirmwareDescriptor(descriptor, sizeof(descriptor));
    debug("Performing minimal initialization for %s", descriptor);
    BUS_WAS_ACTIVE = false;

    diagnostics::initialize(&getConfiguration()->diagnosticsManager,
            getCanBuses(), getCanBusCount(),
            getConfiguration()->obd2BusAddress);
    signals::initialize(&getConfiguration()->diagnosticsManager);
    getConfiguration()->runLevel = RunLevel::CAN_ONLY;

    if(getConfiguration()->powerManagement ==
            PowerManagement::OBD2_IGNITION_CHECK) {
        getConfiguration()->desiredRunLevel = RunLevel::CAN_ONLY;
    } else {
        getConfiguration()->desiredRunLevel = RunLevel::ALL_IO;
        initializeIO();
    }

    // If we don't delay a little bit, time::elapsed seems to return true no
    // matter what for DEBUG=0 builds.
    time::delayMs(500);
}

void firmwareLoop() {
    if(getConfiguration()->runLevel != RunLevel::ALL_IO &&
            getConfiguration()->desiredRunLevel == RunLevel::ALL_IO) {
        initializeIO();
    }
    for(int i = 0; i < getCanBusCount(); i++) {
        // In normal operation, if no output interface is enabled/attached (e.g.
        // no USB or Bluetooth, the loop will stall here. Deep down in
        // receiveCan when it tries to append messages to the queue it will
        // reach a point where it tries to flush the (full) queue. Since nothing
        // is attached, that will just keep timing out. Just be aware that if
        // you need to modify the firmware to not use any interfaces, you'll
        // have to change that or enable the flush functionality to write to
        // your desired output interface.
        CanBus* bus = &(getCanBuses()[i]);
        receiveCan(&getConfiguration()->pipeline, bus);
        diagnostics::sendRequests(&getConfiguration()->diagnosticsManager, bus);
    }

    diagnostics::obd2::loop(&getConfiguration()->diagnosticsManager);

    if(getConfiguration()->runLevel == RunLevel::ALL_IO) {
        usb::read(&getConfiguration()->usb, usb::handleIncomingMessage);
        #ifdef TELIT_HE910_SUPPORT
        telit::connectionManager(getConfiguration()->telit);
        if(telit::connected(getConfiguration()->telit)) {
            if(getConfiguration()->telit->config.globalPositioningSettings.gpsEnable) {
                telit::getGPSLocation();
            }
            server_task::firmwareCheck(getConfiguration()->telit);
            server_task::flushDataBuffer(getConfiguration()->telit);
            server_task::commandCheck(getConfiguration()->telit);
        }
        #elif defined BLE_SUPPORT
        ble::read(getConfiguration()->ble);
        #else
        uart::read(&getConfiguration()->uart, uart::handleIncomingMessage);
        #endif
        network::read(&getConfiguration()->network,
                network::handleIncomingMessage);
    }

    for(int i = 0; i < getCanBusCount(); i++) {
        can::write::flushOutgoingCanMessageQueue(&getCanBuses()[i]);
    }

    checkBusActivity();
    if(getConfiguration()->runLevel == RunLevel::ALL_IO) {
        updateInterfaceLight();
    }

    signals::loop();

    can::logBusStatistics(getCanBuses(), getCanBusCount());
    openxc::pipeline::logStatistics(&getConfiguration()->pipeline);

    if(getConfiguration()->emulatedData) {
        static bool connected = false;
        if(!connected && openxc::interface::anyConnected()) {
            connected = true;
            openxc::emulator::restart();
        } else if(connected && !openxc::interface::anyConnected()) {
            connected = false;
        }

        if(connected) {
            openxc::emulator::generateFakeMeasurements(
                    &getConfiguration()->pipeline);
        }
    }
    #ifdef FS_SUPPORT
    fs::manager(getConfiguration()->fs);
    #endif
    #ifdef RTC_SUPPORT
    rtc_task();
    #endif
    openxc::pipeline::process(&getConfiguration()->pipeline);
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Jeroen Broekhuizen                              *
 *   jengine.sse@live.nl                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include "bound.h"
#ifndef JENGINE_INLINE
#  include "bound.inl"
#endif

Bound::Bound():
   _p1(),
   _p2(),
   _normal()
{
}

Bound::Bound(const Vector& _p1, const Vector& _p2):
   _p1(_p1),
   _p2(_p2),
   _normal()
{
   calculateNormal();
}

/// \fn Bound::set(int bounds[4])
/// \brief Initialize this bound with its line data and precalculates the normal of this bound.
void Bound::set (int bounds[4])
{
	_p1.x = bounds[0]; _p1.y = bounds[1];
	_p2.x = bounds[2]; _p2.y = bounds[3];

	calculateNormal();
}

void Bound::calculateNormal()
{
   Vector direction = _p2 - _p1;
   _normal.set(-direction.y, direction.x);
   _normal.normalize();
}

float magnitude(const Vector& v1, const Vector& v2)
{
   return (v2 - v1).length();
}

bool Bound::hitTest(const Vector& point, float& distance)
{
   float linelength = magnitude(_p1, _p2);

   float u = ( ( ( point.x - _p1.x ) * ( _p2.x - _p1.x ) ) +
               ( ( point.y - _p1.y ) * ( _p2.y - _p1.y ) ) ) /
            ( linelength * linelength );

   if ( u < 0.0f || u > 1.0f )
     return false;   // closest point does not fall within the line segment

   Vector intersection = _p1 + (_p2 - _p1) * u;
   //intersection.x = _p1.x + U * ( _p2.x - _p1.x );
   //intersection.y = _p1.y + U * ( _p2.y - _p1.y );

   distance = magnitude(point, intersection);

   return true;
}

// http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/, 2005
/// \fn Bound::intersect(const Vector& p3, const Vector& p4, Vector& ip)
/// \brief To calculate the intersection point between a line and this bound call this
/// function. It quickly calculates the exact location on the line where the intersection
/// took place.
/// \param [in] p3 start of the line
/// \param [in] p4 end of the line
/// \param [out] ip intersection point (valid if function returns true)
/// \retval true there was an intersection with this bound
/// \retval false no intersection was detected
bool Bound::intersect (const Vector& p3, const Vector& p4, Vector& ip)
{
	// calculate the denominator
	float denom = float((p4.y-p3.y)*(_p2.x-_p1.x)) - ((p4.x-p3.x)*(_p2.y-_p1.y));
	if (denom == 0)
		return false;

	float x1 = _p1.y-p3.y;
	float x2 = _p1.x-p3.x;

	float ua = (((p4.x-p3.x)*x1) - ((p4.y-p3.y)*x2)) / denom;
	float ub = (((_p2.x-_p1.x)*x1) - ((_p2.y-_p1.y)*x2)) / denom;

	if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
		ip = _p1 + (_p2 - _p1) * ua;
		return true;
	}
	else
		return false;
}

void Bound::move(const Vector& offset)
{
   _p1 += offset;
   _p2 += offset;
}

int Bound::findPoint(const Vector& point)
{
   if ( (point - _p1).length() < 4 )
   {
      return 0;
   }
   else if ( (point - _p2).length() < 4 )
   {
      return 1;
   }

   return -1;
}

void Bound::movePoint(int point, const Vector& offset)
{
   if ( point == 0 )
   {
      _p1 += offset;
   }
   else if ( point == 1 )
   {
      _p2 += offset;
   }

   calculateNormal();
}
<commit_msg>* updated the Bound::intersect function<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Jeroen Broekhuizen                              *
 *   jengine.sse@live.nl                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include "bound.h"
#ifndef JENGINE_INLINE
#  include "bound.inl"
#endif

Bound::Bound():
   _p1(),
   _p2(),
   _normal()
{
}

Bound::Bound(const Vector& _p1, const Vector& _p2):
   _p1(_p1),
   _p2(_p2),
   _normal()
{
   calculateNormal();
}

/// \fn Bound::set(int bounds[4])
/// \brief Initialize this bound with its line data and precalculates the normal of this bound.
void Bound::set (int bounds[4])
{
	_p1.x = bounds[0]; _p1.y = bounds[1];
	_p2.x = bounds[2]; _p2.y = bounds[3];

	calculateNormal();
}

void Bound::calculateNormal()
{
   Vector direction = _p2 - _p1;
   _normal.set(-direction.y, direction.x);
   _normal.normalize();
}

float magnitude(const Vector& v1, const Vector& v2)
{
   return (v2 - v1).length();
}

bool Bound::hitTest(const Vector& point, float& distance)
{
   float linelength = magnitude(_p1, _p2);

   float u = ( ( ( point.x - _p1.x ) * ( _p2.x - _p1.x ) ) +
               ( ( point.y - _p1.y ) * ( _p2.y - _p1.y ) ) ) /
            ( linelength * linelength );

   if ( u < 0.0f || u > 1.0f )
     return false;   // closest point does not fall within the line segment

   Vector intersection = _p1 + (_p2 - _p1) * u;
   //intersection.x = _p1.x + U * ( _p2.x - _p1.x );
   //intersection.y = _p1.y + U * ( _p2.y - _p1.y );

   distance = magnitude(point, intersection);

   return true;
}

// http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/, 2005
/// \fn Bound::intersect(const Vector& p3, const Vector& p4, Vector& ip)
/// \brief To calculate the intersection point between a line and this bound call this
/// function. It quickly calculates the exact location on the line where the intersection
/// took place.
/// \param [in] p3 start of the line
/// \param [in] p4 end of the line
/// \param [out] ip intersection point (valid if function returns true)
/// \retval true there was an intersection with this bound
/// \retval false no intersection was detected
bool Bound::intersect (const Vector& p3, const Vector& p4, Vector& ip)
{
	// calculate the denominator
	float denom = ((p4.y - p3.y) * (_p2.x - _p1.x)) - ((p4.x - p3.x) * (_p2.y - _p1.y));

   float nume_a = (( p4.x - p3.x)  * (_p1.y-p3.y)) - ((p4.y - p3.y) * (_p1.x-p3.x));
   float nume_b = ((_p2.x - _p1.x) * (_p1.y-p3.y)) - ((_p2.y - _p1.y) * (_p1.x-p3.x));

	if ( denom == 0 )
   {
      if( nume_a == 0.0f && nume_b == 0.0f )
      {
         // coincident
      }

		return false; // parallel
   }

   float ua = nume_a / denom;
	float ub = nume_b / denom;

	if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f)
   {
		ip = _p1 + (_p2 - _p1) * ua;
		return true;
	}

   return false;
}

void Bound::move(const Vector& offset)
{
   _p1 += offset;
   _p2 += offset;
}

int Bound::findPoint(const Vector& point)
{
   if ( (point - _p1).length() < 4 )
   {
      return 0;
   }
   else if ( (point - _p2).length() < 4 )
   {
      return 1;
   }

   return -1;
}

void Bound::movePoint(int point, const Vector& offset)
{
   if ( point == 0 )
   {
      _p1 += offset;
   }
   else if ( point == 1 )
   {
      _p2 += offset;
   }

   calculateNormal();
}
<|endoftext|>


<commit_before>/*
	Copyright (c) 2016 Xavier Leclercq

	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.
*/

/*
	Part of this file were copied from the Chart.js project (http://chartjs.org/)
	and translated into C++.

	The files of the Chart.js project have the following copyright and license.

	Copyright (c) 2013-2016 Nick Downie
	Released under the MIT license
	https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/

#include "wxchartgrid.h"
#include "wxchartutilities.h"

wxChartGrid::wxChartGrid(const wxSize &size,
						 const wxVector<wxString> &labels,
						 wxDouble minValue,
						 wxDouble maxValue,
						 const wxChartGridOptions& options)
	: m_options(options), m_mapping(size, labels.size()),
	m_XAxis(labels), m_needsFit(true)
{
	wxDouble graphMinValue;
	wxDouble graphMaxValue;
	wxDouble valueRange = 0;
	wxChartUtilities::CalculateGridRange(minValue, maxValue,
		graphMinValue, graphMaxValue, valueRange, m_steps, m_stepValue);
	m_mapping.SetMinValue(graphMinValue);
	m_mapping.SetMaxValue(graphMaxValue);

	m_YAxis.BuildYLabels(m_mapping.GetMinValue(), m_steps, m_stepValue);
}

bool wxChartGrid::HitTest(const wxPoint &point) const
{
	return false;
}

void wxChartGrid::Draw(wxGraphicsContext &gc)
{
	Fit(m_steps, gc);

	wxDouble yLabelGap = (m_mapping.GetEndPoint() - m_mapping.GetStartPoint()) / m_steps;
	wxDouble xStart = m_mapping.GetLeftPadding();

	m_XAxis.UpdateLabelPositions2();
	m_YAxis.UpdateLabelPositions1();

	if (m_options.ShowHorizontalLines())
	{
		for (size_t i = 1; i < m_YAxis.GetLabels().size(); ++i)
		{
			wxDouble yLabelCenter = m_mapping.GetEndPoint() - (yLabelGap * i);
			wxDouble linePositionY = yLabelCenter;

			wxGraphicsPath path = gc.CreatePath();
			path.MoveToPoint(xStart, linePositionY);
			path.AddLineToPoint(m_mapping.GetSize().GetWidth(), linePositionY);
			path.CloseSubpath();

			wxPen pen1(m_options.GetGridLineColor(), m_options.GetGridLineWidth());
			gc.SetPen(pen1);
			gc.StrokePath(path);
		}
	}

	if (m_options.ShowVerticalLines())
	{
		for (size_t i = 1; i < m_XAxis.GetLabels().size(); ++i)
		{
			wxPoint2DDouble s;
			wxPoint2DDouble t;
			m_XAxis.GetVerticalLinePositions(i, s, t);
			wxDouble linePosition = s.m_x;

			wxGraphicsPath path = gc.CreatePath();
			path.MoveToPoint(linePosition, m_mapping.GetEndPoint());
			path.AddLineToPoint(linePosition, m_mapping.GetStartPoint() - 3);
			path.CloseSubpath();

			wxPen pen1(m_options.GetGridLineColor(), m_options.GetGridLineWidth());
			gc.SetPen(pen1);
			gc.StrokePath(path);
		}
	}

	m_XAxis.Draw2(gc);
	m_YAxis.Draw1(gc);
}

void wxChartGrid::Resize(const wxSize &size)
{
	m_mapping.SetSize(size);
	m_needsFit = true;
}

const wxChartGridMapping& wxChartGrid::GetMapping() const
{
	return m_mapping;
}

void wxChartGrid::Fit(size_t steps,
					  wxGraphicsContext &gc)
{
	if (!m_needsFit)
	{
		return;
	}

	wxDouble startPoint = m_options.GetYAxisOptions().GetFontSize();
	wxDouble endPoint = m_mapping.GetSize().GetHeight() - (m_options.GetYAxisOptions().GetFontSize() + 15) - 5; // -5 to pad labels

	// Apply padding settings to the start and end point.
	//this.startPoint += this.padding;
	//this.endPoint -= this.padding;

	m_YAxis.UpdateLabelSizes(gc);

	m_XAxis.UpdateLabelSizes(gc);
	wxDouble leftPadding = CalculateLeftPadding(m_XAxis.GetLabels(), m_YAxis.GetLabelMaxWidth());
	m_XAxis.Fit(leftPadding, 0, endPoint, m_mapping.GetSize().GetWidth() - leftPadding);
	m_YAxis.Fit(leftPadding, startPoint, endPoint, 0);

	m_mapping.Fit(leftPadding, startPoint, endPoint);

	m_needsFit = false;
}

wxDouble wxChartGrid::CalculateLeftPadding(const wxVector<wxChartLabel> &xLabels,
										   wxDouble yLabelMaxWidth)
{
	// Either the first x label or any of the y labels can be the widest
	// so they are all taken into account to compute the left padding
	wxDouble leftPadding = yLabelMaxWidth;
	if ((xLabels.size() > 0) && ((xLabels[0].GetSize().GetWidth() / 2) > leftPadding))
	{
		leftPadding = (xLabels[0].GetSize().GetWidth() / 2);
	}
	return leftPadding;
}
<commit_msg>Refactoring<commit_after>/*
	Copyright (c) 2016 Xavier Leclercq

	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.
*/

/*
	Part of this file were copied from the Chart.js project (http://chartjs.org/)
	and translated into C++.

	The files of the Chart.js project have the following copyright and license.

	Copyright (c) 2013-2016 Nick Downie
	Released under the MIT license
	https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/

#include "wxchartgrid.h"
#include "wxchartutilities.h"

wxChartGrid::wxChartGrid(const wxSize &size,
						 const wxVector<wxString> &labels,
						 wxDouble minValue,
						 wxDouble maxValue,
						 const wxChartGridOptions& options)
	: m_options(options), m_mapping(size, labels.size()),
	m_XAxis(labels), m_needsFit(true)
{
	wxDouble graphMinValue;
	wxDouble graphMaxValue;
	wxDouble valueRange = 0;
	wxChartUtilities::CalculateGridRange(minValue, maxValue,
		graphMinValue, graphMaxValue, valueRange, m_steps, m_stepValue);
	m_mapping.SetMinValue(graphMinValue);
	m_mapping.SetMaxValue(graphMaxValue);

	m_YAxis.BuildYLabels(m_mapping.GetMinValue(), m_steps, m_stepValue);
}

bool wxChartGrid::HitTest(const wxPoint &point) const
{
	return false;
}

void wxChartGrid::Draw(wxGraphicsContext &gc)
{
	Fit(m_steps, gc);

	wxDouble yLabelGap = (m_mapping.GetEndPoint() - m_mapping.GetStartPoint()) / m_steps;
	wxDouble xStart = m_mapping.GetLeftPadding();

	if (m_options.ShowHorizontalLines())
	{
		for (size_t i = 1; i < m_YAxis.GetLabels().size(); ++i)
		{
			wxDouble yLabelCenter = m_mapping.GetEndPoint() - (yLabelGap * i);
			wxDouble linePositionY = yLabelCenter;

			wxGraphicsPath path = gc.CreatePath();
			path.MoveToPoint(xStart, linePositionY);
			path.AddLineToPoint(m_mapping.GetSize().GetWidth(), linePositionY);
			path.CloseSubpath();

			wxPen pen1(m_options.GetGridLineColor(), m_options.GetGridLineWidth());
			gc.SetPen(pen1);
			gc.StrokePath(path);
		}
	}

	if (m_options.ShowVerticalLines())
	{
		for (size_t i = 1; i < m_XAxis.GetLabels().size(); ++i)
		{
			wxPoint2DDouble s;
			wxPoint2DDouble t;
			m_XAxis.GetVerticalLinePositions(i, s, t);
			wxDouble linePosition = s.m_x;

			wxGraphicsPath path = gc.CreatePath();
			path.MoveToPoint(linePosition, m_mapping.GetEndPoint());
			path.AddLineToPoint(linePosition, m_mapping.GetStartPoint() - 3);
			path.CloseSubpath();

			wxPen pen1(m_options.GetGridLineColor(), m_options.GetGridLineWidth());
			gc.SetPen(pen1);
			gc.StrokePath(path);
		}
	}

	m_XAxis.Draw2(gc);
	m_YAxis.Draw1(gc);
}

void wxChartGrid::Resize(const wxSize &size)
{
	m_mapping.SetSize(size);
	m_needsFit = true;
}

const wxChartGridMapping& wxChartGrid::GetMapping() const
{
	return m_mapping;
}

void wxChartGrid::Fit(size_t steps,
					  wxGraphicsContext &gc)
{
	if (!m_needsFit)
	{
		return;
	}

	wxDouble startPoint = m_options.GetYAxisOptions().GetFontSize();
	wxDouble endPoint = m_mapping.GetSize().GetHeight() - (m_options.GetYAxisOptions().GetFontSize() + 15) - 5; // -5 to pad labels

	// Apply padding settings to the start and end point.
	//this.startPoint += this.padding;
	//this.endPoint -= this.padding;

	m_YAxis.UpdateLabelSizes(gc);

	m_XAxis.UpdateLabelSizes(gc);
	wxDouble leftPadding = CalculateLeftPadding(m_XAxis.GetLabels(), m_YAxis.GetLabelMaxWidth());
	m_XAxis.Fit(leftPadding, 0, endPoint, m_mapping.GetSize().GetWidth() - leftPadding);
	m_YAxis.Fit(leftPadding, startPoint, endPoint, 0);

	m_XAxis.UpdateLabelPositions2();
	m_YAxis.UpdateLabelPositions1();

	m_mapping.Fit(leftPadding, startPoint, endPoint);

	m_needsFit = false;
}

wxDouble wxChartGrid::CalculateLeftPadding(const wxVector<wxChartLabel> &xLabels,
										   wxDouble yLabelMaxWidth)
{
	// Either the first x label or any of the y labels can be the widest
	// so they are all taken into account to compute the left padding
	wxDouble leftPadding = yLabelMaxWidth;
	if ((xLabels.size() > 0) && ((xLabels[0].GetSize().GetWidth() / 2) > leftPadding))
	{
		leftPadding = (xLabels[0].GetSize().GetWidth() / 2);
	}
	return leftPadding;
}
<|endoftext|>


<commit_before>// This file is part of the "libxzero" project
//   (c) 2009-2015 Christian Parpart <https://github.com/christianparpart>
//   (c) 2014-2015 Paul Asmuth <https://github.com/paulasmuth>
//
// libxzero is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include <xzero/Base64.h>

namespace xzero {

const char Base64::base64_[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/";

/* aaaack but it's fast and const should make it shared text page. */
const unsigned char Base64::pr2six_[256] = {
    /* ASCII table */
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
    61, 64, 64, 64, 64, 64, 64, 64, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64,
    64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
    43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64};

int Base64::encodeLength(int sourceLength) {
  return ((sourceLength + 2) / 3 * 4) + 1;
}

std::string Base64::encode(const std::string &text) {
  return encode((const unsigned char *)text.data(), text.size());
}

std::string Base64::encode(const Buffer &buffer) {
  return encode((const unsigned char *)buffer.data(), buffer.size());
}

std::string Base64::encode(const unsigned char *buffer, int ALength) {
  const int len = ALength;
  const unsigned char *string = buffer;

  char *encoded = new char[encodeLength(ALength) + 1];

  int i;
  char *p = encoded;
  for (i = 0; i < len - 2; i += 3) {
    *p++ = base64_[(string[i] >> 2) & 0x3F];
    *p++ =
        base64_[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)];
    *p++ = base64_[((string[i + 1] & 0xF) << 2) |
                   ((int)(string[i + 2] & 0xC0) >> 6)];
    *p++ = base64_[string[i + 2] & 0x3F];
  }

  if (i < len) {
    *p++ = base64_[(string[i] >> 2) & 0x3F];
    if (i == (len - 1)) {
      *p++ = base64_[((string[i] & 0x3) << 4)];
      *p++ = '=';
    } else {
      *p++ = base64_[((string[i] & 0x3) << 4) |
                     ((int)(string[i + 1] & 0xF0) >> 4)];
      *p++ = base64_[((string[i + 1] & 0xF) << 2)];
    }
    *p++ = '=';
  }
  //*p++ = '\0';
  int outlen = p - encoded;

  return std::string(encoded, outlen);
}

int Base64::decodeLength(const std::string &buffer) {
  return decodeLength(buffer.c_str());
}

int Base64::decodeLength(const char *buffer) {
  const unsigned char *bufin = (const unsigned char *)buffer;

  while (pr2six_[*(bufin++)] <= 63)
    ;
  int nprbytes = (bufin - (const unsigned char *)buffer) - 1;
  int nbytesdecoded = ((nprbytes + 3) / 4) * 3;

  return nbytesdecoded + 1;
}

Buffer Base64::decode(const std::string &value) {
  Buffer result;
  result.reserve(decodeLength(value));

  int len = decode(value.c_str(), (unsigned char *)result.data());

  result.resize(len);

  return result;
}

Buffer Base64::decode(const BufferRef &input) {
  size_t decodeLen = decodeLength(input.str().c_str());
  Buffer output;
  output.reserve(1 + decodeLen);
  output.resize(output.capacity());

  size_t nbleft = 0;
  for (auto i = input.cbegin(), e = input.cend();
       i != e && pr2six_[static_cast<int>(*i)] != 64; ++i)
    ++nbleft;

  const unsigned char *inp = (const unsigned char *)&input[0];
  unsigned char *outp = (unsigned char *)&output[0];

  while (nbleft > 4) {
    *outp++ = (unsigned char)(pr2six_[inp[0]] << 2 | pr2six_[inp[1]] >> 4);
    *outp++ = (unsigned char)(pr2six_[inp[1]] << 4 | pr2six_[inp[2]] >> 2);
    *outp++ = (unsigned char)(pr2six_[inp[2]] << 6 | pr2six_[inp[3]]);
    inp += 4;
    nbleft -= 4;
  }

  if (nbleft > 1) {
    *outp++ = (unsigned char)(pr2six_[inp[0]] << 2 | pr2six_[inp[1]] >> 4);

    if (nbleft > 2) {
      *outp++ = (unsigned char)(pr2six_[inp[1]] << 4 | pr2six_[inp[2]] >> 2);

      if (nbleft > 3) {
        *outp++ = (unsigned char)(pr2six_[inp[2]] << 6 | pr2six_[inp[3]]);
      }
    }
  }

  decodeLen -= (4 - nbleft) & 3;
  output.resize(decodeLen - 1);

  return std::move(output);
}

int Base64::decode(const char *input, unsigned char *output) {
  const char *bufcoded = input;
  unsigned char *bufplain = output;

  const unsigned char *bufin;
  unsigned char *bufout;

  bufin = (const unsigned char *)bufcoded;
  while (pr2six_[*(bufin++)] <= 63)
    ;
  int nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
  int nbytesdecoded = (((int)nprbytes + 3) / 4) * 3;

  bufout = (unsigned char *)bufplain;
  bufin = (const unsigned char *)bufcoded;

  while (nprbytes > 4) {
    *(bufout++) =
        (unsigned char)(pr2six_[*bufin] << 2 | pr2six_[bufin[1]] >> 4);
    *(bufout++) =
        (unsigned char)(pr2six_[bufin[1]] << 4 | pr2six_[bufin[2]] >> 2);
    *(bufout++) = (unsigned char)(pr2six_[bufin[2]] << 6 | pr2six_[bufin[3]]);
    bufin += 4;
    nprbytes -= 4;
  }

  /* Note: (nprbytes == 1) would be an error, so just ingore that case */
  if (nprbytes > 1) {
    *(bufout++) =
        (unsigned char)(pr2six_[*bufin] << 2 | pr2six_[bufin[1]] >> 4);

    if (nprbytes > 2) {
      *(bufout++) =
          (unsigned char)(pr2six_[bufin[1]] << 4 | pr2six_[bufin[2]] >> 2);

      if (nprbytes > 3) {
        *(bufout++) =
            (unsigned char)(pr2six_[bufin[2]] << 6 | pr2six_[bufin[3]]);
      }
    }
  }

  nbytesdecoded -= (4 - (int)nprbytes) & 3;

  return nbytesdecoded;
}

}  // namespace xzero
<commit_msg>[base] Base64: code reformatting<commit_after>// This file is part of the "libxzero" project
//   (c) 2009-2015 Christian Parpart <https://github.com/christianparpart>
//   (c) 2014-2015 Paul Asmuth <https://github.com/paulasmuth>
//
// libxzero is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include <xzero/Base64.h>

namespace xzero {

const char Base64::base64_[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/";

/* aaaack but it's fast and const should make it shared text page. */
const unsigned char Base64::pr2six_[256] = {
    /* ASCII table */
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, //   0..15
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, //  16..31
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, //  32..47
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, //  48..63
    64, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, //  64..95
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, //  80..95
    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //  96..111
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, // 112..127
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 128..143
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 144..150
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 160..175
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 176..191
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 192..207
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 208..223
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 224..239
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 240..255
};

int Base64::encodeLength(int sourceLength) {
  return ((sourceLength + 2) / 3 * 4) + 1;
}

std::string Base64::encode(const std::string &text) {
  return encode((const unsigned char *)text.data(), text.size());
}

std::string Base64::encode(const Buffer &buffer) {
  return encode((const unsigned char *)buffer.data(), buffer.size());
}

std::string Base64::encode(const unsigned char *buffer, int ALength) {
  const int len = ALength;
  const unsigned char *string = buffer;

  char *encoded = new char[encodeLength(ALength) + 1];

  int i;
  char *p = encoded;
  for (i = 0; i < len - 2; i += 3) {
    *p++ = base64_[(string[i] >> 2) & 0x3F];
    *p++ = base64_[((string[i] & 0x3) << 4) |
                   ((int)(string[i + 1] & 0xF0) >> 4)];
    *p++ = base64_[((string[i + 1] & 0xF) << 2) |
                   ((int)(string[i + 2] & 0xC0) >> 6)];
    *p++ = base64_[string[i + 2] & 0x3F];
  }

  if (i < len) {
    *p++ = base64_[(string[i] >> 2) & 0x3F];
    if (i == (len - 1)) {
      *p++ = base64_[((string[i] & 0x3) << 4)];
      *p++ = '=';
    } else {
      *p++ = base64_[((string[i] & 0x3) << 4) |
                     ((int)(string[i + 1] & 0xF0) >> 4)];
      *p++ = base64_[((string[i + 1] & 0xF) << 2)];
    }
    *p++ = '=';
  }
  //*p++ = '\0';
  int outlen = p - encoded;

  return std::string(encoded, outlen);
}

int Base64::decodeLength(const std::string &buffer) {
  return decodeLength(buffer.c_str());
}

int Base64::decodeLength(const char *buffer) {
  const unsigned char *bufin = (const unsigned char *)buffer;

  while (pr2six_[*(bufin++)] <= 63)
    ;
  int nprbytes = (bufin - (const unsigned char *)buffer) - 1;
  int nbytesdecoded = ((nprbytes + 3) / 4) * 3;

  return nbytesdecoded + 1;
}

Buffer Base64::decode(const std::string& value) {
  Buffer result;
  result.reserve(decodeLength(value));

  int len = decode(value.c_str(), (unsigned char *)result.data());

  result.resize(len);

  return result;
}

Buffer Base64::decode(const BufferRef &input) {
  size_t decodeLen = decodeLength(input.str().c_str());
  Buffer output;
  output.reserve(1 + decodeLen);
  output.resize(output.capacity());

  size_t nbleft = 0;
  for (auto i = input.cbegin(), e = input.cend();
       i != e && pr2six_[static_cast<int>(*i)] != 64; ++i)
    ++nbleft;

  const unsigned char *inp = (const unsigned char *)&input[0];
  unsigned char *outp = (unsigned char *)&output[0];

  while (nbleft > 4) {
    *outp++ = (unsigned char)(pr2six_[inp[0]] << 2 | pr2six_[inp[1]] >> 4);
    *outp++ = (unsigned char)(pr2six_[inp[1]] << 4 | pr2six_[inp[2]] >> 2);
    *outp++ = (unsigned char)(pr2six_[inp[2]] << 6 | pr2six_[inp[3]]);
    inp += 4;
    nbleft -= 4;
  }

  if (nbleft > 1) {
    *outp++ = (unsigned char)(pr2six_[inp[0]] << 2 | pr2six_[inp[1]] >> 4);

    if (nbleft > 2) {
      *outp++ = (unsigned char)(pr2six_[inp[1]] << 4 | pr2six_[inp[2]] >> 2);

      if (nbleft > 3) {
        *outp++ = (unsigned char)(pr2six_[inp[2]] << 6 | pr2six_[inp[3]]);
      }
    }
  }

  decodeLen -= (4 - nbleft) & 3;
  output.resize(decodeLen - 1);

  return std::move(output);
}

int Base64::decode(const char *input, unsigned char *output) {
  const char *bufcoded = input;
  unsigned char *bufplain = output;

  const unsigned char *bufin;
  unsigned char *bufout;

  bufin = (const unsigned char *)bufcoded;
  while (pr2six_[*(bufin++)] <= 63)
    ;
  int nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
  int nbytesdecoded = (((int)nprbytes + 3) / 4) * 3;

  bufout = (unsigned char *)bufplain;
  bufin = (const unsigned char *)bufcoded;

  while (nprbytes > 4) {
    *(bufout++) =
        (unsigned char)(pr2six_[*bufin] << 2 | pr2six_[bufin[1]] >> 4);
    *(bufout++) =
        (unsigned char)(pr2six_[bufin[1]] << 4 | pr2six_[bufin[2]] >> 2);
    *(bufout++) = (unsigned char)(pr2six_[bufin[2]] << 6 | pr2six_[bufin[3]]);
    bufin += 4;
    nprbytes -= 4;
  }

  /* Note: (nprbytes == 1) would be an error, so just ingore that case */
  if (nprbytes > 1) {
    *(bufout++) =
        (unsigned char)(pr2six_[*bufin] << 2 | pr2six_[bufin[1]] >> 4);

    if (nprbytes > 2) {
      *(bufout++) =
          (unsigned char)(pr2six_[bufin[1]] << 4 | pr2six_[bufin[2]] >> 2);

      if (nprbytes > 3) {
        *(bufout++) =
            (unsigned char)(pr2six_[bufin[2]] << 6 | pr2six_[bufin[3]]);
      }
    }
  }

  nbytesdecoded -= (4 - (int)nprbytes) & 3;

  return nbytesdecoded;
}

}  // namespace xzero
<|endoftext|>


<commit_before>
#include "tools.hpp"
#include "logger.hpp"

#include <iostream>
#include <fstream>
#include <set>
#include <unordered_set>

#include <boost/program_options.hpp>

int main(int argc, char* argv[]) {
  using namespace Clustering::Tools;
  namespace b_po = boost::program_options;
  b_po::variables_map args;
  b_po::options_description desc (std::string(argv[0]).append(
    "\n\n"
    "build network information from density based clustering."
    "\n"
    "options"));
  desc.add_options()
    ("help,h", b_po::bool_switch()->default_value(false), "show this help.")
    // optional
    ("basename,b", b_po::value<std::string>()->default_value("clust.\%0.1f"),
          "(optional): basename of input files (default: clust.\%0.1f).")
    ("min", b_po::value<float>()->default_value(0.1f, "0.1"), "(optional): minimum free energy (default: 0.1).")
    ("max", b_po::value<float>()->default_value(8.0f, "8.0"), "(optional): maximum free energy (default: 8.0).")
    ("step", b_po::value<float>()->default_value(0.1f, "0.1"), "(optional): minimum free energy (default: 0.1).")
    ("minpop,p", b_po::value<std::size_t>()->default_value(1),
          "(optional): minimum population of node to be considered for network (default: 1).")
    // defaults
    ("verbose,v", b_po::bool_switch()->default_value(false), "verbose mode: print runtime information to STDOUT.")
  ;
  // parse cmd arguments
  try {
    b_po::store(b_po::command_line_parser(argc, argv).options(desc).run(), args);
    b_po::notify(args);
  } catch (b_po::error& e) {
    if ( ! args["help"].as<bool>()) {
      std::cout << "\n" << e.what() << "\n\n" << std::endl;
    }
    std::cout << desc << std::endl;
    return 2;
  }
  if (args["help"].as<bool>()) {
    std::cout << desc << std::endl;
    return 1;
  }
  // setup general flags / options
  Clustering::verbose = args["verbose"].as<bool>();

  float d_min = args["min"].as<float>();
  float d_max = args["max"].as<float>();
  float d_step = args["step"].as<float>();
  std::string basename = args["basename"].as<std::string>();
  std::string remapped_name = "remapped_" + basename;
  std::size_t minpop = args["minpop"].as<std::size_t>();

  std::set<std::pair<std::size_t, std::size_t>> network;
  std::map<std::size_t, std::size_t> pops;
  std::map<std::size_t, float> free_energies;

  std::vector<std::size_t> cl_next = read_clustered_trajectory(stringprintf(basename, d_min));
  std::vector<std::size_t> cl_now;
  std::size_t max_id;
  std::size_t n_rows = cl_next.size();
  for (float d=d_min; d < d_max; d += d_step) {
    Clustering::logger(std::cout) << "free energy level: " << d << std::endl;
    cl_now = cl_next;
    write_clustered_trajectory(stringprintf(remapped_name, d), cl_now);
    max_id = *std::max_element(cl_now.begin(), cl_now.end());
    cl_next = read_clustered_trajectory(stringprintf(basename, d + d_step));
    for (std::size_t i=0; i < n_rows; ++i) {
      if (cl_next[i] != 0) {
        cl_next[i] += max_id;
        if (cl_now[i] != 0) {
          network.insert({cl_next[i], cl_now[i]});
          ++pops[cl_now[i]];
          free_energies[cl_now[i]] = d;
        }
      }
    }
  }
  // handle last trajectory
  Clustering::logger(std::cout) << "free energy level: " << stringprintf("%0.2f", d_max) << std::endl;
  cl_now = cl_next;
  write_clustered_trajectory(stringprintf(remapped_name, d_max), cl_now);
  for (std::size_t i=0; i < n_rows; ++i) {
    if (cl_now[i] != 0) {
      ++pops[cl_now[i]];
      free_energies[cl_now[i]] = d_max;
    }
  }
  // if minpop given: delete nodes and edges not fulfilling min. population criterium
  if (minpop > 1) {
    Clustering::logger(std::cout) << "cleaning from low pop. states ..." << std::endl;
    std::unordered_set<std::size_t> removals;
    auto pop_it = pops.begin();
    Clustering::logger(std::cout) << "  ... search nodes to remove" << std::endl;
    while (pop_it != pops.end()) {
      if (pop_it->second < minpop) {
        removals.insert(pop_it->first);
        pops.erase(pop_it++); // as above
      } else {
        ++pop_it;
      }
    }
    Clustering::logger(std::cout) << "  ... search edges to remove" << std::endl;
    auto net_it = network.begin();
    while (net_it != network.end()) {
      std::size_t a = net_it->first;
      std::size_t b = net_it->second;
      if (removals.count(a) > 0 || removals.count(b) > 0) {
        network.erase(net_it++);
      } else {
        ++net_it;
      }
    }
    Clustering::logger(std::cout) << "  ... finished." << std::endl;
  }
  // save network links
  {
    Clustering::logger(std::cout) << "saving links" << std::endl;
    std::ofstream ofs("network_links.dat");
    if (ofs.fail()) {
      std::cerr << "error: cannot open file 'network_links.dat'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      for (auto p: network) {
        ofs << p.first << " " << p.second << "\n";
      }
    }
  }
  // save node info
  {
    Clustering::logger(std::cout) << "saving nodes" << std::endl;
    std::ofstream ofs("network_nodes.dat");
    if (ofs.fail()) {
      std::cerr << "error: cannot open file 'network_nodes.dat'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      for (auto node_pop: pops) {
        std::size_t key = node_pop.first;
        ofs << key << " " << free_energies[key] << " " << node_pop.second << "\n";
      }
    }
  }
  // save network 'leafs', i.e. end nodes
  std::set<std::size_t> leafs;
  {
    Clustering::logger(std::cout) << "saving leafs, i.e. tree end nodes" << std::endl;
    std::ofstream ofs("network_leafs.dat");
    if (ofs.fail()) {
      std::cerr << "error: cannot open file 'network_leafs.dat'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      std::set<std::size_t> srcs;
      for (auto from_to: network) {
        std::size_t src = from_to.first;
        std::size_t target = from_to.second;
        srcs.insert(src);
        if ( ! srcs.count(target)) {
          leafs.insert(target);
        }
        if (leafs.count(src)) {
          leafs.erase(src);
        }
      }
      for (std::size_t leaf: leafs) {
        ofs << leaf << "\n";
      }
    }
  }
  // save end-node traj
  {
    Clustering::logger(std::cout) << "saving end-node trajectory for seeding" << std::endl;
    std::ofstream ofs("network_end_node_traj.dat");
    if (ofs.fail()) {
      std::cerr << "error: cannot open file 'network_end_node_traj.dat' for writing." << std::endl;
      exit(EXIT_FAILURE);
    } else {
      std::vector<std::size_t> traj(n_rows);
      for (float d=d_min; d < d_max+d_step; d += d_step) {
        std::vector<std::size_t> cl_now = read_clustered_trajectory(stringprintf(remapped_name, d));
        for (std::size_t i=0; i < n_rows; ++i) {
          if (leafs.count(cl_now[i])) {
            traj[i] = cl_now[i];
          }
        }
      }
      for (std::size_t i: traj) {
        ofs << i << "\n";
      }
    }
  }
  return 0;
}

<commit_msg>some cleanup work<commit_after>
#include "tools.hpp"
#include "logger.hpp"

#include <iostream>
#include <fstream>
#include <set>
#include <unordered_set>

#include <boost/program_options.hpp>

namespace {

void
save_network_links(std::string fname,
                   std::set<std::pair<std::size_t, std::size_t>> network) {
  Clustering::logger(std::cout) << "saving links" << std::endl;
  std::ofstream ofs(fname);
  if (ofs.fail()) {
    std::cerr << "error: cannot open file '" << fname << "' for writing." << std::endl;
    exit(EXIT_FAILURE);
  } else {
    for (auto p: network) {
      ofs << p.first << " " << p.second << "\n";
    }
  }
}

void
save_node_info(std::string fname,
               std::map<std::size_t, float> free_energies,
               std::map<std::size_t, std::size_t> pops) {
  Clustering::logger(std::cout) << "saving nodes" << std::endl;
  std::ofstream ofs(fname);
  if (ofs.fail()) {
    std::cerr << "error: cannot open file '" << fname << "' for writing." << std::endl;
    exit(EXIT_FAILURE);
  } else {
    for (auto node_pop: pops) {
      std::size_t key = node_pop.first;
      ofs << key << " " << free_energies[key] << " " << node_pop.second << "\n";
    }
  }
}

std::set<std::size_t>
compute_and_save_leaves(std::string fname,
                        std::set<std::pair<std::size_t, std::size_t>> network) {
  Clustering::logger(std::cout) << "saving leaves, i.e. tree end nodes" << std::endl;
  std::set<std::size_t> leaves;
  std::ofstream ofs(fname);
  if (ofs.fail()) {
    std::cerr << "error: cannot open file '" << fname << "' for writing." << std::endl;
    exit(EXIT_FAILURE);
  } else {
    std::set<std::size_t> srcs;
    for (auto from_to: network) {
      std::size_t src = from_to.first;
      std::size_t target = from_to.second;
      srcs.insert(src);
      if ( ! srcs.count(target)) {
        leaves.insert(target);
      }
      if (leaves.count(src)) {
        leaves.erase(src);
      }
    }
    for (std::size_t leaf: leaves) {
      ofs << leaf << "\n";
    }
  }
  return leaves;
}

void
save_traj_of_leaves(std::string fname,
                    std::set<std::size_t> leaves,
                    float d_min,
                    float d_max,
                    float d_step,
                    std::string remapped_name,
                    std::size_t n_rows) {
  Clustering::logger(std::cout) << "saving end-node trajectory for seeding" << std::endl;
  std::ofstream ofs(fname);
  if (ofs.fail()) {
    std::cerr << "error: cannot open file '" << fname << "' for writing." << std::endl;
    exit(EXIT_FAILURE);
  } else {
    std::vector<std::size_t> traj(n_rows);
    for (float d=d_min; d < d_max+d_step; d += d_step) {
      std::vector<std::size_t> cl_now = Clustering::Tools::read_clustered_trajectory(
                                          Clustering::Tools::stringprintf(remapped_name, d));
      for (std::size_t i=0; i < n_rows; ++i) {
        if (leaves.count(cl_now[i])) {
          traj[i] = cl_now[i];
        }
      }
    }
    for (std::size_t i: traj) {
      ofs << i << "\n";
    }
  }
}

} // end local namespace

int main(int argc, char* argv[]) {
  using namespace Clustering::Tools;
  namespace b_po = boost::program_options;
  b_po::variables_map args;
  b_po::options_description desc (std::string(argv[0]).append(
    "\n\n"
    "build network information from density based clustering."
    "\n"
    "options"));
  desc.add_options()
    ("help,h", b_po::bool_switch()->default_value(false), "show this help.")
    // optional
    ("basename,b", b_po::value<std::string>()->default_value("clust.\%0.1f"),
          "(optional): basename of input files (default: clust.\%0.1f).")
    ("min", b_po::value<float>()->default_value(0.1f, "0.1"), "(optional): minimum free energy (default: 0.1).")
    ("max", b_po::value<float>()->default_value(8.0f, "8.0"), "(optional): maximum free energy (default: 8.0).")
    ("step", b_po::value<float>()->default_value(0.1f, "0.1"), "(optional): minimum free energy (default: 0.1).")
    ("minpop,p", b_po::value<std::size_t>()->default_value(1),
          "(optional): minimum population of node to be considered for network (default: 1).")
    // defaults
    ("verbose,v", b_po::bool_switch()->default_value(false), "verbose mode: print runtime information to STDOUT.")
  ;
  // parse cmd arguments
  try {
    b_po::store(b_po::command_line_parser(argc, argv).options(desc).run(), args);
    b_po::notify(args);
  } catch (b_po::error& e) {
    if ( ! args["help"].as<bool>()) {
      std::cout << "\n" << e.what() << "\n\n" << std::endl;
    }
    std::cout << desc << std::endl;
    return 2;
  }
  if (args["help"].as<bool>()) {
    std::cout << desc << std::endl;
    return 1;
  }
  // setup general flags / options
  Clustering::verbose = args["verbose"].as<bool>();

  float d_min = args["min"].as<float>();
  float d_max = args["max"].as<float>();
  float d_step = args["step"].as<float>();
  std::string basename = args["basename"].as<std::string>();
  std::string remapped_name = "remapped_" + basename;
  std::size_t minpop = args["minpop"].as<std::size_t>();

  std::set<std::pair<std::size_t, std::size_t>> network;
  std::map<std::size_t, std::size_t> pops;
  std::map<std::size_t, float> free_energies;

  std::vector<std::size_t> cl_next = read_clustered_trajectory(stringprintf(basename, d_min));
  std::vector<std::size_t> cl_now;
  std::size_t max_id;
  std::size_t n_rows = cl_next.size();
  // do remapping of states to give every state a unique id.
  // this is nevessary, since every initially clustered trajectory
  // at different thresholds uses the same ids starting with 0.
  for (float d=d_min; d < d_max; d += d_step) {
    Clustering::logger(std::cout) << "free energy level: " << d << std::endl;
    cl_now = cl_next;
    write_clustered_trajectory(stringprintf(remapped_name, d), cl_now);
    max_id = *std::max_element(cl_now.begin(), cl_now.end());
    cl_next = read_clustered_trajectory(stringprintf(basename, d + d_step));
    for (std::size_t i=0; i < n_rows; ++i) {
      if (cl_next[i] != 0) {
        cl_next[i] += max_id;
        if (cl_now[i] != 0) {
          network.insert({cl_next[i], cl_now[i]});
          ++pops[cl_now[i]];
          free_energies[cl_now[i]] = d;
        }
      }
    }
  }
  // handle last trajectory
  Clustering::logger(std::cout) << "free energy level: " << stringprintf("%0.2f", d_max) << std::endl;
  cl_now = cl_next;
  write_clustered_trajectory(stringprintf(remapped_name, d_max), cl_now);
  for (std::size_t i=0; i < n_rows; ++i) {
    if (cl_now[i] != 0) {
      ++pops[cl_now[i]];
      free_energies[cl_now[i]] = d_max;
    }
  }
  // if minpop given: delete nodes and edges not fulfilling min. population criterium
  if (minpop > 1) {
    Clustering::logger(std::cout) << "cleaning from low pop. states ..." << std::endl;
    std::unordered_set<std::size_t> removals;
    auto pop_it = pops.begin();
    Clustering::logger(std::cout) << "  ... search nodes to remove" << std::endl;
    while (pop_it != pops.end()) {
      if (pop_it->second < minpop) {
        removals.insert(pop_it->first);
        pops.erase(pop_it++); // as above
      } else {
        ++pop_it;
      }
    }
    Clustering::logger(std::cout) << "  ... search edges to remove" << std::endl;
    auto net_it = network.begin();
    while (net_it != network.end()) {
      std::size_t a = net_it->first;
      std::size_t b = net_it->second;
      if (removals.count(a) > 0 || removals.count(b) > 0) {
        network.erase(net_it++);
      } else {
        ++net_it;
      }
    }
    Clustering::logger(std::cout) << "  ... finished." << std::endl;
  }
  // save links (i.e. edges) as two-column ascii in a child -> parent manner
  save_network_links("network_links.dat", network);
  // save id, population and free energy of nodes
  save_node_info("network_nodes.dat", free_energies, pops);
  // compute and directly save network end-nodes (i.e. leaves of the network-tree)
  std::set<std::size_t> leaves = compute_and_save_leaves("network_leaves.dat", network);
  // save the trajectory consisting of the 'leaf-states'.
  // all non-leaf states are kept as non-assignment state '0'.
  save_traj_of_leaves("network_end_node_traj.dat", leaves, d_min, d_max, d_step, remapped_name, n_rows);
  return 0;
}

<|endoftext|>


<commit_before><commit_msg>fmt for std::exception<commit_after><|endoftext|>


<commit_before><commit_msg>remove FIXME/TODO since the llvm bug has been fixed<commit_after><|endoftext|>