<commit_before>/*******************************************************************************
 * Copyright 2016 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/

#include "ibmras/monitoring/agent/threads/WorkerThread.h"
#include "ibmras/monitoring/agent/Agent.h"
#include "ibmras/common/logging.h"

namespace ibmras {
namespace monitoring {
namespace agent {
namespace threads {

extern IBMRAS_DECLARE_LOGGER;
IBMRAS_DEFINE_LOGGER("WorkerThread");

WorkerThread::WorkerThread(pullsource* pullSource) : semaphore(0, 1, pullSource->header.name), data(threadEntry, cleanUp), countdown(0) {
	source = pullSource;
	running = false;
	stopped = true;
	data.setArgs(this);
}

void WorkerThread::start() {
	IBMRAS_DEBUG_1(fine, "Starting worker thread for %s", source->header.name);
	running = true;
	stopped = false;
	ibmras::common::port::createThread(&data);
}

void WorkerThread::stop() {
	running = false;
	semaphore.inc();
	IBMRAS_DEBUG_1(debug, "Worker thread for %s stopped", source->header.name);
}

void* WorkerThread::cleanUp(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->stop();
	return NULL;
}

void* WorkerThread::threadEntry(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->processLoop();
	ibmras::common::port::exitThread(NULL);
	return NULL;
}

void WorkerThread::process(bool immediate) {
    IBMRAS_DEBUG_2(finest, "Worker thread process for %s, countdown is %d", source->header.name, countdown);
	if ((immediate && countdown > 120) || (countdown == 0)) {
		semaphore.inc();
		countdown = source->pullInterval;
	} else {
		countdown--;
	}
}

bool WorkerThread::isStopped() {
	return stopped;
}

void* WorkerThread::processLoop() {
	IBMRAS_DEBUG_1(finest, "Worker thread started for %s", source->header.name);
	Agent* agent = Agent::getInstance();
	while (running) {
		if (semaphore.wait(1) && running) {
			IBMRAS_DEBUG_1(fine, "Pulling data from source %s", source->header.name);
			monitordata* data = source->callback();
			if (data != NULL) {
				if (data->size > 0) {
					IBMRAS_DEBUG_2(finest, "%d bytes of data pulled from source %s", data->size, source->header.name);
					agent->addData(data); /* put pulled data on queue for processing */
				}
				source->complete(data);
			}
		}
	}

	source->complete(NULL);
	stopped = true;
	IBMRAS_DEBUG_1(finest, "Worker thread for %s exiting process loop", source->header.name);
	return NULL;
}

}
}
}
} /* end of namespace threads */

<commit_msg>Remove logger definition in WorkerThreads<commit_after>/*******************************************************************************
 * Copyright 2016 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/

#include "ibmras/monitoring/agent/threads/WorkerThread.h"
#include "ibmras/monitoring/agent/Agent.h"
#include "ibmras/common/logging.h"

namespace ibmras {
namespace monitoring {
namespace agent {
namespace threads {

extern IBMRAS_DECLARE_LOGGER;

WorkerThread::WorkerThread(pullsource* pullSource) : semaphore(0, 1, pullSource->header.name), data(threadEntry, cleanUp), countdown(0) {
	source = pullSource;
	running = false;
	stopped = true;
	data.setArgs(this);
}

void WorkerThread::start() {
	IBMRAS_DEBUG_1(fine, "Starting worker thread for %s", source->header.name);
	running = true;
	stopped = false;
	ibmras::common::port::createThread(&data);
}

void WorkerThread::stop() {
	running = false;
	semaphore.inc();
	IBMRAS_DEBUG_1(debug, "Worker thread for %s stopped", source->header.name);
}

void* WorkerThread::cleanUp(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->stop();
	return NULL;
}

void* WorkerThread::threadEntry(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->processLoop();
	ibmras::common::port::exitThread(NULL);
	return NULL;
}

void WorkerThread::process(bool immediate) {
    IBMRAS_DEBUG_2(finest, "Worker thread process for %s, countdown is %d", source->header.name, countdown);
	if ((immediate && countdown > 120) || (countdown == 0)) {
		semaphore.inc();
		countdown = source->pullInterval;
	} else {
		countdown--;
	}
}

bool WorkerThread::isStopped() {
	return stopped;
}

void* WorkerThread::processLoop() {
	IBMRAS_DEBUG_1(finest, "Worker thread started for %s", source->header.name);
	Agent* agent = Agent::getInstance();
	while (running) {
		if (semaphore.wait(1) && running) {
			IBMRAS_DEBUG_1(fine, "Pulling data from source %s", source->header.name);
			monitordata* data = source->callback();
			if (data != NULL) {
				if (data->size > 0) {
					IBMRAS_DEBUG_2(finest, "%d bytes of data pulled from source %s", data->size, source->header.name);
					agent->addData(data); /* put pulled data on queue for processing */
				}
				source->complete(data);
			}
		}
	}

	source->complete(NULL);
	stopped = true;
	IBMRAS_DEBUG_1(finest, "Worker thread for %s exiting process loop", source->header.name);
	return NULL;
}

}
}
}
} /* end of namespace threads */
<|endoftext|>


<commit_before>// Time:  O(n), n is the number of the integers.
// Space: O(h), h is the depth of the nested lists.

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */

// Using stack and iterator.
class NestedIterator {
public:
    using IT = vector<NestedInteger>::const_iterator;
    NestedIterator(vector<NestedInteger> &nestedList) {
        nodes_.emplace(nestedList.cbegin(), nestedList.cend());
    }

    int next() {
        return (nodes_.top().first++)->getInteger();
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto& cur = nodes_.top();
            if (cur.first == cur.second) {
                nodes_.pop();
            } else if (cur.first->isInteger()) {
                return true;
            } else {
                auto& nestedList = cur.first->getList();
                ++cur.first;
                nodes_.emplace(nestedList.cbegin(), nestedList.cend());
            }
        }
        return false;
    }

private:
    stack<pair<IT, IT>> nodes_;
};

// Time:  O(n)
// Space: O(n)
// Using stack.
class NestedIterator2 {
public:
    NestedIterator2(vector<NestedInteger> &nestedList) {
        for (int i = static_cast<int>(nestedList.size()) - 1; i >= 0; --i) {
            nodes_.emplace(&nestedList[i]);
        }
    }

    int next() {
        auto result = nodes_.top()->getInteger();
        nodes_.pop();
        return result;
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto *cur = nodes_.top();
            if (cur->isInteger()) {
                return true;
            }
            nodes_.pop();
            auto& children = cur->getList();
            for (int i = static_cast<int>(children.size()) - 1; i >= 0; --i) {
                nodes_.emplace(&children[i]);
            }
        }
        return false;
    }

private:
    stack<NestedInteger *> nodes_;
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

<commit_msg>Update flatten-nested-list-iterator.cpp<commit_after>// Time:  O(n), n is the number of the integers.
// Space: O(h), h is the depth of the nested lists.

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */

// Using stack and iterator.
class NestedIterator {
public:
    using IT = vector<NestedInteger>::const_iterator;
    NestedIterator(vector<NestedInteger> &nestedList) {
        depth_.emplace(nestedList.cbegin(), nestedList.cend());
    }

    int next() {
        return (depth_.top().first++)->getInteger();
    }

    bool hasNext() {
        while (!depth_.empty()) {
            auto& cur = depth_.top();
            if (cur.first == cur.second) {
                depth_.pop();
            } else if (cur.first->isInteger()) {
                return true;
            } else {
                auto& nestedList = cur.first->getList();
                ++cur.first;
                depth_.emplace(nestedList.cbegin(), nestedList.cend());
            }
        }
        return false;
    }

private:
    stack<pair<IT, IT>> depth_;
};

// Time:  O(n)
// Space: O(n)
// Using stack.
class NestedIterator2 {
public:
    NestedIterator2(vector<NestedInteger> &nestedList) {
        for (int i = static_cast<int>(nestedList.size()) - 1; i >= 0; --i) {
            nodes_.emplace(&nestedList[i]);
        }
    }

    int next() {
        auto result = nodes_.top()->getInteger();
        nodes_.pop();
        return result;
    }

    bool hasNext() {
        while (!nodes_.empty()) {
            auto *cur = nodes_.top();
            if (cur->isInteger()) {
                return true;
            }
            nodes_.pop();
            auto& children = cur->getList();
            for (int i = static_cast<int>(children.size()) - 1; i >= 0; --i) {
                nodes_.emplace(&children[i]);
            }
        }
        return false;
    }

private:
    stack<NestedInteger *> nodes_;
};

/**
 * Your NestedIterator object will be instantiated and called as such:
 * NestedIterator i(nestedList);
 * while (i.hasNext()) cout << i.next();
 */

<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(1)

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        if (nums.empty()) {
            return {};
        }

        vector<int> left_product(nums.size());

        left_product[0] = 1;
        for (int i = 1; i < nums.size(); ++i) {
            left_product[i] = left_product[i - 1] * nums[i - 1];
        }

        int right_product = 1;
        for (int i = nums.size() - 2; i >= 0; --i) {
            right_product *= nums[i + 1];
            left_product[i] = left_product[i] * right_product;
        }

        return left_product;
    }
};
<commit_msg>Update product-of-array-except-self.cpp<commit_after>// Time:  O(n)
// Space: O(1)

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        if (nums.empty()) {
            return {};
        }

        vector<int> left_product(nums.size());

        left_product[0] = 1;
        for (int i = 1; i < nums.size(); ++i) {
            left_product[i] = left_product[i - 1] * nums[i - 1];
        }

        int right_product = 1;
        for (int i = static_cast<int>(nums.size()) - 2; i >= 0; --i) {
            right_product *= nums[i + 1];
            left_product[i] = left_product[i] * right_product;
        }

        return left_product;
    }
};
<|endoftext|>


<commit_before>
#include <string>
#include <algorithm>

#include "flame/linear.h"
#include "flame/state/vector.h"
#include "flame/state/matrix.h"

#define sqr(x)  ((x)*(x))
#define cube(x) ((x)*(x)*(x))

// Phase-space units.
#if false
    // Use [m, rad, m, rad, rad, eV/u].
    #define MtoMM 1e0
#else
    // Use [mm, rad, mm, rad, rad, MeV/u].
    #define MtoMM 1e3
#endif

MatrixState::MatrixState(const Config& c)
    :StateBase(c)
    ,state(boost::numeric::ublas::identity_matrix<double>(maxsize))
{
    try{
        const std::vector<double>& I = c.get<std::vector<double> >("initial");
        if(I.size()>state.data().size())
            throw std::invalid_argument("Initial state size too big");
        std::copy(I.begin(), I.end(), state.data().begin());
    }catch(key_error&){
        // default to identity
    }catch(boost::bad_any_cast&){
        throw std::invalid_argument("'initial' has wrong type (must be vector)");
    }
}

MatrixState::~MatrixState() {}

MatrixState::MatrixState(const MatrixState& o, clone_tag t)
    :StateBase(o, t)
    ,state(o.state)
{}

void MatrixState::assign(const StateBase& other)
{
    const MatrixState *O = dynamic_cast<const MatrixState*>(&other);
    if(!O)
        throw std::invalid_argument("Can't assign State: incompatible types");
    state = O->state;
    StateBase::assign(other);
}

void MatrixState::show(std::ostream& strm, int level) const
{
    strm<<"State: "<<state<<"\n";
}

bool MatrixState::getArray(unsigned idx, ArrayInfo& Info) {
    if(idx==0) {
        Info.name = "state";
        Info.ptr = &state(0,0);
        Info.type = ArrayInfo::Double;
        Info.ndim = 2;
        Info.dim[0] = state.size1();
        Info.dim[1] = state.size2();
        Info.stride[0] = sizeof(double)*state.size1();
        Info.stride[1] = sizeof(double);
        return true;
    }
    return StateBase::getArray(idx-1, Info);
}

VectorState::VectorState(const Config& c)
    :StateBase(c)
    ,state(maxsize, 0.0)
{
    try{
        const std::vector<double>& I = c.get<std::vector<double> >("initial");
        if(I.size()>state.size())
            throw std::invalid_argument("Initial state size too big");
        std::copy(I.begin(), I.end(), state.begin());
    }catch(key_error&){
    }catch(boost::bad_any_cast&){
    }
}

VectorState::~VectorState() {}

VectorState::VectorState(const VectorState& o, clone_tag t)
    :StateBase(o, t)
    ,state(o.state)
{}

void VectorState::assign(const StateBase& other)
{
    const VectorState *O = dynamic_cast<const VectorState*>(&other);
    if(!O)
        throw std::invalid_argument("Can't assign State: incompatible types");
    state = O->state;
    StateBase::assign(other);
}

void VectorState::show(std::ostream& strm) const
{
    strm<<"State: "<<state<<"\n";
}

bool VectorState::getArray(unsigned idx, ArrayInfo& Info) {
    if(idx==0) {
        Info.name = "state";
        Info.ptr = &state(0);
        Info.type = ArrayInfo::Double;
        Info.ndim = 1;
        Info.dim[0] = state.size();
        Info.stride[0] = sizeof(double);
        return true;
    }
    return StateBase::getArray(idx-1, Info);
}

namespace {

template<typename Base>
void Get2by2Matrix(const double L, const double K, const unsigned ind, typename Base::value_t &M)
{
    // Transport matrix for one plane for a Quadrupole.
    double sqrtK,
           psi,
           cs,
           sn;

    if (K > 0e0) {
        // Focusing.
        sqrtK = sqrt(K);
        psi = sqrtK*L;
        cs = ::cos(psi);
        sn = ::sin(psi);

        M(ind, ind) = M(ind+1, ind+1) = cs;
        if (sqrtK != 0e0)
            M(ind, ind+1) = sn/sqrtK;
        else
            M(ind, ind+1) = L;
        if (sqrtK != 0e0)
            M(ind+1, ind) = -sqrtK*sn;
        else
            M(ind+1, ind) = 0e0;
    } else {
        // Defocusing.
        sqrtK = sqrt(-K);
        psi = sqrtK*L;
        cs = ::cosh(psi);
        sn = ::sinh(psi);

        M(ind, ind) = M(ind+1, ind+1) = cs;
        if (sqrtK != 0e0)
            M(ind, ind+1) = sn/sqrtK;
        else
            M(ind, ind+1) = L;
        if (sqrtK != 0e0)
            M(ind+1, ind) = sqrtK*sn;
        else
            M(ind+1, ind) = 0e0;
    }
}

template<typename Base>
struct ElementSource : public Base
{
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementSource(const Config& c)
        :base_t(c), istate(c)
    {}

    virtual void advance(StateBase& s)
    {
        state_t& ST = static_cast<state_t&>(s);
        // Replace state with our initial values
        ST.assign(istate);
    }

    virtual void show(std::ostream& strm, int level) const
    {
        ElementVoid::show(strm, level);
        strm<<"Initial: "<<istate.state<<"\n";
    }

    state_t istate;
    // note that 'transfer' is not used by this element type

    virtual ~ElementSource() {}

    virtual const char* type_name() const {return "source";}
};

template<typename Base>
struct ElementMark : public Base
{
    // Transport (identity) matrix for a Marker.
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementMark(const Config& c)
        :base_t(c)
    {
//        double L = c.get<double>("L", 0e0);

        // Identity matrix.
    }
    virtual ~ElementMark() {}

    virtual const char* type_name() const {return "marker";}
};

template<typename Base>
struct ElementDrift : public Base
{
    // Transport matrix for a Drift.
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementDrift(const Config& c)
        :base_t(c)
    {
        double L = c.get<double>("L")*MtoMM; // Convert from [m] to [mm].

        this->transfer(state_t::PS_X, state_t::PS_PX) = L;
        this->transfer(state_t::PS_Y, state_t::PS_PY) = L;
        // For total path length.
//        this->transfer(state_t::PS_S, state_t::PS_S)  = L;
    }
    virtual ~ElementDrift() {}

    virtual const char* type_name() const {return "drift";}
};

template<typename Base>
struct ElementSBend : public Base
{
    // Transport matrix for a Gradient Sector Bend (cylindrical coordinates).
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementSBend(const Config& c)
        :base_t(c)
    {
        double L   = c.get<double>("L")*MtoMM,
               phi = c.get<double>("phi"),               // [rad].
               rho = L/phi,
               K   = c.get<double>("K", 0e0)/sqr(MtoMM), // [1/m^2].
               Kx  = K + 1e0/sqr(rho),
               Ky  = -K;

        // Horizontal plane.
        Get2by2Matrix<Base>(L, Kx, (unsigned)state_t::PS_X, this->transfer);
        // Vertical plane.
        Get2by2Matrix<Base>(L, Ky, (unsigned)state_t::PS_Y, this->transfer);
        // Longitudinal plane.
//        this->transfer(state_t::PS_S,  state_t::PS_S) = L;
    }
    virtual ~ElementSBend() {}

    virtual const char* type_name() const {return "sbend";}
};

template<typename Base>
struct ElementQuad : public Base
{
    // Transport matrix for a Quadrupole; K = B2/Brho.
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementQuad(const Config& c)
        :base_t(c)
    {
        double L = c.get<double>("L")*MtoMM,
               //B2 = c.get<double>("B2"),
               K = c.get<double>("K", 0e0)/sqr(MtoMM);

        // Horizontal plane.
        Get2by2Matrix<Base>(L,  K, (unsigned)state_t::PS_X, this->transfer);
        // Vertical plane.
        Get2by2Matrix<Base>(L, -K, (unsigned)state_t::PS_Y, this->transfer);
        // Longitudinal plane.
        // For total path length.
//        this->transfer(state_t::PS_S, state_t::PS_S) = L;
    }
    virtual ~ElementQuad() {}

    virtual const char* type_name() const {return "quadrupole";}
};

template<typename Base>
struct ElementSolenoid : public Base
{
    // Transport (identity) matrix for a Solenoid; K = B0/(2 Brho).
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementSolenoid(const Config& c)
        :base_t(c)
    {
        double L = c.get<double>("L")*MtoMM,      // Convert from [m] to [mm].
//               B = c.get<double>("B"),
               K = c.get<double>("K", 0e0)/MtoMM, // Convert from [m] to [mm].
               C = ::cos(K*L),
               S = ::sin(K*L);

        this->transfer(state_t::PS_X, state_t::PS_X)
                = this->transfer(state_t::PS_PX, state_t::PS_PX)
                = this->transfer(state_t::PS_Y, state_t::PS_Y)
                = this->transfer(state_t::PS_PY, state_t::PS_PY)
                = sqr(C);

        if (K != 0e0)
            this->transfer(state_t::PS_X, state_t::PS_PX) = S*C/K;
        else
            this->transfer(state_t::PS_X, state_t::PS_PX) = L;
        this->transfer(state_t::PS_X, state_t::PS_Y) = S*C;
        if (K != 0e0)
            this->transfer(state_t::PS_X, state_t::PS_PY) = sqr(S)/K;
        else
            this->transfer(state_t::PS_X, state_t::PS_PY) = 0e0;

        this->transfer(state_t::PS_PX, state_t::PS_X) = -K*S*C;
        this->transfer(state_t::PS_PX, state_t::PS_Y) = -K*sqr(S);
        this->transfer(state_t::PS_PX, state_t::PS_PY) = S*C;

        this->transfer(state_t::PS_Y, state_t::PS_X) = -S*C;
        if (K != 0e0)
            this->transfer(state_t::PS_Y, state_t::PS_PX) = -sqr(S)/K;
        else
            this->transfer(state_t::PS_Y, state_t::PS_PX) = 0e0;
        if (K != 0e0)
            this->transfer(state_t::PS_Y, state_t::PS_PY) = S*C/K;
        else
            this->transfer(state_t::PS_Y, state_t::PS_PY) = L;

        this->transfer(state_t::PS_PY, state_t::PS_X) = K*sqr(S);
        this->transfer(state_t::PS_PY, state_t::PS_PX) = -S*C;
        this->transfer(state_t::PS_PY, state_t::PS_Y) = -K*S*C;

        // Longitudinal plane.
        // For total path length.
//        this->transfer(state_t::PS_S, state_t::PS_S) = L;
    }
    virtual ~ElementSolenoid() {}

    virtual const char* type_name() const {return "solenoid";}
};

template<typename Base>
struct ElementGeneric : public Base
{
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementGeneric(const Config& c)
        :base_t(c)
    {
        std::vector<double> I = c.get<std::vector<double> >("transfer");
        if(I.size()>this->transfer.data().size())
            throw std::invalid_argument("Initial transfer size too big");
        std::copy(I.begin(), I.end(), this->transfer.data().begin());
    }
    virtual ~ElementGeneric() {}

    virtual const char* type_name() const {return "generic";}
};

} // namespace

void registerLinear()
{
    Machine::registerState<VectorState>("Vector");
    Machine::registerState<MatrixState>("TransferMatrix");

    Machine::registerElement<ElementSource<LinearElementBase<VectorState>   > >("Vector",         "source");
    Machine::registerElement<ElementSource<LinearElementBase<MatrixState>   > >("TransferMatrix", "source");

    Machine::registerElement<ElementMark<LinearElementBase<VectorState>     > >("Vector",         "marker");
    Machine::registerElement<ElementMark<LinearElementBase<MatrixState>     > >("TransferMatrix", "marker");

    Machine::registerElement<ElementDrift<LinearElementBase<VectorState>    > >("Vector",         "drift");
    Machine::registerElement<ElementDrift<LinearElementBase<MatrixState>    > >("TransferMatrix", "drift");

    Machine::registerElement<ElementSBend<LinearElementBase<VectorState>    > >("Vector",         "sbend");
    Machine::registerElement<ElementSBend<LinearElementBase<MatrixState>    > >("TransferMatrix", "sbend");

    Machine::registerElement<ElementQuad<LinearElementBase<VectorState>     > >("Vector",         "quadrupole");
    Machine::registerElement<ElementQuad<LinearElementBase<MatrixState>     > >("TransferMatrix", "quadrupole");

    Machine::registerElement<ElementSolenoid<LinearElementBase<VectorState> > >("Vector",         "solenoid");
    Machine::registerElement<ElementSolenoid<LinearElementBase<MatrixState> > >("TransferMatrix", "solenoid");

    Machine::registerElement<ElementGeneric<LinearElementBase<VectorState>  > >("Vector",         "generic");
    Machine::registerElement<ElementGeneric<LinearElementBase<MatrixState>  > >("TransferMatrix", "generic");
}
<commit_msg>linear.cpp: don't require L, use from ElementVoid<commit_after>
#include <string>
#include <algorithm>

#include "flame/linear.h"
#include "flame/state/vector.h"
#include "flame/state/matrix.h"

#define sqr(x)  ((x)*(x))
#define cube(x) ((x)*(x)*(x))

// Phase-space units.
#if false
    // Use [m, rad, m, rad, rad, eV/u].
    #define MtoMM 1e0
#else
    // Use [mm, rad, mm, rad, rad, MeV/u].
    #define MtoMM 1e3
#endif

MatrixState::MatrixState(const Config& c)
    :StateBase(c)
    ,state(boost::numeric::ublas::identity_matrix<double>(maxsize))
{
    try{
        const std::vector<double>& I = c.get<std::vector<double> >("initial");
        if(I.size()>state.data().size())
            throw std::invalid_argument("Initial state size too big");
        std::copy(I.begin(), I.end(), state.data().begin());
    }catch(key_error&){
        // default to identity
    }catch(boost::bad_any_cast&){
        throw std::invalid_argument("'initial' has wrong type (must be vector)");
    }
}

MatrixState::~MatrixState() {}

MatrixState::MatrixState(const MatrixState& o, clone_tag t)
    :StateBase(o, t)
    ,state(o.state)
{}

void MatrixState::assign(const StateBase& other)
{
    const MatrixState *O = dynamic_cast<const MatrixState*>(&other);
    if(!O)
        throw std::invalid_argument("Can't assign State: incompatible types");
    state = O->state;
    StateBase::assign(other);
}

void MatrixState::show(std::ostream& strm, int level) const
{
    strm<<"State: "<<state<<"\n";
}

bool MatrixState::getArray(unsigned idx, ArrayInfo& Info) {
    if(idx==0) {
        Info.name = "state";
        Info.ptr = &state(0,0);
        Info.type = ArrayInfo::Double;
        Info.ndim = 2;
        Info.dim[0] = state.size1();
        Info.dim[1] = state.size2();
        Info.stride[0] = sizeof(double)*state.size1();
        Info.stride[1] = sizeof(double);
        return true;
    }
    return StateBase::getArray(idx-1, Info);
}

VectorState::VectorState(const Config& c)
    :StateBase(c)
    ,state(maxsize, 0.0)
{
    try{
        const std::vector<double>& I = c.get<std::vector<double> >("initial");
        if(I.size()>state.size())
            throw std::invalid_argument("Initial state size too big");
        std::copy(I.begin(), I.end(), state.begin());
    }catch(key_error&){
    }catch(boost::bad_any_cast&){
    }
}

VectorState::~VectorState() {}

VectorState::VectorState(const VectorState& o, clone_tag t)
    :StateBase(o, t)
    ,state(o.state)
{}

void VectorState::assign(const StateBase& other)
{
    const VectorState *O = dynamic_cast<const VectorState*>(&other);
    if(!O)
        throw std::invalid_argument("Can't assign State: incompatible types");
    state = O->state;
    StateBase::assign(other);
}

void VectorState::show(std::ostream& strm) const
{
    strm<<"State: "<<state<<"\n";
}

bool VectorState::getArray(unsigned idx, ArrayInfo& Info) {
    if(idx==0) {
        Info.name = "state";
        Info.ptr = &state(0);
        Info.type = ArrayInfo::Double;
        Info.ndim = 1;
        Info.dim[0] = state.size();
        Info.stride[0] = sizeof(double);
        return true;
    }
    return StateBase::getArray(idx-1, Info);
}

namespace {

template<typename Base>
void Get2by2Matrix(const double L, const double K, const unsigned ind, typename Base::value_t &M)
{
    // Transport matrix for one plane for a Quadrupole.
    double sqrtK,
           psi,
           cs,
           sn;

    if (K > 0e0) {
        // Focusing.
        sqrtK = sqrt(K);
        psi = sqrtK*L;
        cs = ::cos(psi);
        sn = ::sin(psi);

        M(ind, ind) = M(ind+1, ind+1) = cs;
        if (sqrtK != 0e0)
            M(ind, ind+1) = sn/sqrtK;
        else
            M(ind, ind+1) = L;
        if (sqrtK != 0e0)
            M(ind+1, ind) = -sqrtK*sn;
        else
            M(ind+1, ind) = 0e0;
    } else {
        // Defocusing.
        sqrtK = sqrt(-K);
        psi = sqrtK*L;
        cs = ::cosh(psi);
        sn = ::sinh(psi);

        M(ind, ind) = M(ind+1, ind+1) = cs;
        if (sqrtK != 0e0)
            M(ind, ind+1) = sn/sqrtK;
        else
            M(ind, ind+1) = L;
        if (sqrtK != 0e0)
            M(ind+1, ind) = sqrtK*sn;
        else
            M(ind+1, ind) = 0e0;
    }
}

template<typename Base>
struct ElementSource : public Base
{
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementSource(const Config& c)
        :base_t(c), istate(c)
    {}

    virtual void advance(StateBase& s)
    {
        state_t& ST = static_cast<state_t&>(s);
        // Replace state with our initial values
        ST.assign(istate);
    }

    virtual void show(std::ostream& strm, int level) const
    {
        ElementVoid::show(strm, level);
        strm<<"Initial: "<<istate.state<<"\n";
    }

    state_t istate;
    // note that 'transfer' is not used by this element type

    virtual ~ElementSource() {}

    virtual const char* type_name() const {return "source";}
};

template<typename Base>
struct ElementMark : public Base
{
    // Transport (identity) matrix for a Marker.
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementMark(const Config& c)
        :base_t(c)
    {
//        double L = c.get<double>("L", 0e0);

        // Identity matrix.
    }
    virtual ~ElementMark() {}

    virtual const char* type_name() const {return "marker";}
};

template<typename Base>
struct ElementDrift : public Base
{
    // Transport matrix for a Drift.
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementDrift(const Config& c)
        :base_t(c)
    {
        double L = this->length*MtoMM; // Convert from [m] to [mm].

        this->transfer(state_t::PS_X, state_t::PS_PX) = L;
        this->transfer(state_t::PS_Y, state_t::PS_PY) = L;
        // For total path length.
//        this->transfer(state_t::PS_S, state_t::PS_S)  = L;
    }
    virtual ~ElementDrift() {}

    virtual const char* type_name() const {return "drift";}
};

template<typename Base>
struct ElementSBend : public Base
{
    // Transport matrix for a Gradient Sector Bend (cylindrical coordinates).
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementSBend(const Config& c)
        :base_t(c)
    {
        double L   = this->length*MtoMM,
               phi = c.get<double>("phi"),               // [rad].
               rho = L/phi,
               K   = c.get<double>("K", 0e0)/sqr(MtoMM), // [1/m^2].
               Kx  = K + 1e0/sqr(rho),
               Ky  = -K;

        // Horizontal plane.
        Get2by2Matrix<Base>(L, Kx, (unsigned)state_t::PS_X, this->transfer);
        // Vertical plane.
        Get2by2Matrix<Base>(L, Ky, (unsigned)state_t::PS_Y, this->transfer);
        // Longitudinal plane.
//        this->transfer(state_t::PS_S,  state_t::PS_S) = L;
    }
    virtual ~ElementSBend() {}

    virtual const char* type_name() const {return "sbend";}
};

template<typename Base>
struct ElementQuad : public Base
{
    // Transport matrix for a Quadrupole; K = B2/Brho.
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementQuad(const Config& c)
        :base_t(c)
    {
        double L = this->length*MtoMM,
               //B2 = c.get<double>("B2"),
               K = c.get<double>("K", 0e0)/sqr(MtoMM);

        // Horizontal plane.
        Get2by2Matrix<Base>(L,  K, (unsigned)state_t::PS_X, this->transfer);
        // Vertical plane.
        Get2by2Matrix<Base>(L, -K, (unsigned)state_t::PS_Y, this->transfer);
        // Longitudinal plane.
        // For total path length.
//        this->transfer(state_t::PS_S, state_t::PS_S) = L;
    }
    virtual ~ElementQuad() {}

    virtual const char* type_name() const {return "quadrupole";}
};

template<typename Base>
struct ElementSolenoid : public Base
{
    // Transport (identity) matrix for a Solenoid; K = B0/(2 Brho).
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementSolenoid(const Config& c)
        :base_t(c)
    {
        double L = this->length*MtoMM,      // Convert from [m] to [mm].
//               B = c.get<double>("B"),
               K = c.get<double>("K", 0e0)/MtoMM, // Convert from [m] to [mm].
               C = ::cos(K*L),
               S = ::sin(K*L);

        this->transfer(state_t::PS_X, state_t::PS_X)
                = this->transfer(state_t::PS_PX, state_t::PS_PX)
                = this->transfer(state_t::PS_Y, state_t::PS_Y)
                = this->transfer(state_t::PS_PY, state_t::PS_PY)
                = sqr(C);

        if (K != 0e0)
            this->transfer(state_t::PS_X, state_t::PS_PX) = S*C/K;
        else
            this->transfer(state_t::PS_X, state_t::PS_PX) = L;
        this->transfer(state_t::PS_X, state_t::PS_Y) = S*C;
        if (K != 0e0)
            this->transfer(state_t::PS_X, state_t::PS_PY) = sqr(S)/K;
        else
            this->transfer(state_t::PS_X, state_t::PS_PY) = 0e0;

        this->transfer(state_t::PS_PX, state_t::PS_X) = -K*S*C;
        this->transfer(state_t::PS_PX, state_t::PS_Y) = -K*sqr(S);
        this->transfer(state_t::PS_PX, state_t::PS_PY) = S*C;

        this->transfer(state_t::PS_Y, state_t::PS_X) = -S*C;
        if (K != 0e0)
            this->transfer(state_t::PS_Y, state_t::PS_PX) = -sqr(S)/K;
        else
            this->transfer(state_t::PS_Y, state_t::PS_PX) = 0e0;
        if (K != 0e0)
            this->transfer(state_t::PS_Y, state_t::PS_PY) = S*C/K;
        else
            this->transfer(state_t::PS_Y, state_t::PS_PY) = L;

        this->transfer(state_t::PS_PY, state_t::PS_X) = K*sqr(S);
        this->transfer(state_t::PS_PY, state_t::PS_PX) = -S*C;
        this->transfer(state_t::PS_PY, state_t::PS_Y) = -K*S*C;

        // Longitudinal plane.
        // For total path length.
//        this->transfer(state_t::PS_S, state_t::PS_S) = L;
    }
    virtual ~ElementSolenoid() {}

    virtual const char* type_name() const {return "solenoid";}
};

template<typename Base>
struct ElementGeneric : public Base
{
    typedef Base base_t;
    typedef typename base_t::state_t state_t;
    ElementGeneric(const Config& c)
        :base_t(c)
    {
        std::vector<double> I = c.get<std::vector<double> >("transfer");
        if(I.size()>this->transfer.data().size())
            throw std::invalid_argument("Initial transfer size too big");
        std::copy(I.begin(), I.end(), this->transfer.data().begin());
    }
    virtual ~ElementGeneric() {}

    virtual const char* type_name() const {return "generic";}
};

} // namespace

void registerLinear()
{
    Machine::registerState<VectorState>("Vector");
    Machine::registerState<MatrixState>("TransferMatrix");

    Machine::registerElement<ElementSource<LinearElementBase<VectorState>   > >("Vector",         "source");
    Machine::registerElement<ElementSource<LinearElementBase<MatrixState>   > >("TransferMatrix", "source");

    Machine::registerElement<ElementMark<LinearElementBase<VectorState>     > >("Vector",         "marker");
    Machine::registerElement<ElementMark<LinearElementBase<MatrixState>     > >("TransferMatrix", "marker");

    Machine::registerElement<ElementDrift<LinearElementBase<VectorState>    > >("Vector",         "drift");
    Machine::registerElement<ElementDrift<LinearElementBase<MatrixState>    > >("TransferMatrix", "drift");

    Machine::registerElement<ElementSBend<LinearElementBase<VectorState>    > >("Vector",         "sbend");
    Machine::registerElement<ElementSBend<LinearElementBase<MatrixState>    > >("TransferMatrix", "sbend");

    Machine::registerElement<ElementQuad<LinearElementBase<VectorState>     > >("Vector",         "quadrupole");
    Machine::registerElement<ElementQuad<LinearElementBase<MatrixState>     > >("TransferMatrix", "quadrupole");

    Machine::registerElement<ElementSolenoid<LinearElementBase<VectorState> > >("Vector",         "solenoid");
    Machine::registerElement<ElementSolenoid<LinearElementBase<MatrixState> > >("TransferMatrix", "solenoid");

    Machine::registerElement<ElementGeneric<LinearElementBase<VectorState>  > >("Vector",         "generic");
    Machine::registerElement<ElementGeneric<LinearElementBase<MatrixState>  > >("TransferMatrix", "generic");
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2012 Ryan Prichard
//
// 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.

#include "Terminal.h"
#include "NamedPipe.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <string>

#define CSI "\x1b["

const int COLOR_ATTRIBUTE_MASK =
        FOREGROUND_BLUE |
        FOREGROUND_GREEN |
        FOREGROUND_RED |
        FOREGROUND_INTENSITY |
        BACKGROUND_BLUE |
        BACKGROUND_GREEN |
        BACKGROUND_RED |
        BACKGROUND_INTENSITY;

const int TERMINAL_BLACK = 0;
const int TERMINAL_RED   = 1;
const int TERMINAL_GREEN = 2;
const int TERMINAL_BLUE  = 4;
const int TERMINAL_WHITE = 7;

const int TERMINAL_FOREGROUND = 30;
const int TERMINAL_BACKGROUND = 40;

Terminal::Terminal(NamedPipe *output) :
    m_output(output),
    m_remoteLine(0),
    m_cursorHidden(false),
    m_remoteColor(-1),
    m_consoleMode(false)
{
}

void Terminal::setConsoleMode(int mode)
{
    if (mode == 1)
        m_consoleMode = true;
    else
        m_consoleMode = false;
}

void Terminal::reset(bool sendClearFirst, int newLine)
{
    if (sendClearFirst && !m_consoleMode)
        m_output->write(CSI"1;1H"CSI"2J");
    m_remoteLine = newLine;
    m_cursorHidden = false;
    m_cursorPos = std::pair<int, int>(0, newLine);
    m_remoteColor = -1;

	//use mouse
    if (!m_consoleMode) m_output->write(CSI"?1000h");
}

void Terminal::sendLine(int line, CHAR_INFO *lineData, int width)
{
    hideTerminalCursor();
    moveTerminalToLine(line);

    // Erase in Line -- erase entire line.
    if (!m_consoleMode)
        m_output->write(CSI"2K");

    std::string termLine;
    termLine.reserve(width + 32);

    int length = 0;
    for (int i = 0; i < width; ++i) {
        int color = lineData[i].Attributes & COLOR_ATTRIBUTE_MASK;
        if (color != m_remoteColor) {
            int fore = 0;
            int back = 0;
            if (color & FOREGROUND_RED)   fore |= TERMINAL_RED;
            if (color & FOREGROUND_GREEN) fore |= TERMINAL_GREEN;
            if (color & FOREGROUND_BLUE)  fore |= TERMINAL_BLUE;
            if (color & BACKGROUND_RED)   back |= TERMINAL_RED;
            if (color & BACKGROUND_GREEN) back |= TERMINAL_GREEN;
            if (color & BACKGROUND_BLUE)  back |= TERMINAL_BLUE;

            char buffer[128];
            if (back == TERMINAL_BLACK) {
                if (fore == TERMINAL_WHITE) {
                    // Use the terminal's default colors.
                    sprintf(buffer, CSI"0");
                } else if (fore == TERMINAL_BLACK) {
                    // Attempt to hide the character, but some terminals won't
                    // hide it.  Is this an important case?
                    sprintf(buffer, CSI"0;8");
                } else {
                    sprintf(buffer, CSI"0;%d", TERMINAL_FOREGROUND + fore);
                }
                if (color & FOREGROUND_INTENSITY)
                    strcat(buffer, ";1");
            } else if (back == TERMINAL_WHITE) {
                // Use the terminal's inverted colors.
                if (fore == TERMINAL_BLACK) {
                    sprintf(buffer, CSI"0;7");
                } else if (fore == TERMINAL_WHITE) {
                    // Attempt to hide the character, but some terminals won't
                    // hide it.  Is this an important case?
                    sprintf(buffer, CSI"0;7;8");
                } else {
                    sprintf(buffer, CSI"0;7;%d", TERMINAL_BACKGROUND + fore);
                }
                // Don't worry about FOREGROUND_INTENSITY because with at least
                // one terminal (gnome-terminal 2.32.0), setting the Intensity
                // flag affects both foreground and background when Reverse
                // flag is also set.
            } else {
                sprintf(buffer, CSI"0;%d;%d",
                        TERMINAL_FOREGROUND + fore,
                        TERMINAL_BACKGROUND + back);
                if (color & FOREGROUND_INTENSITY)
                    strcat(buffer, ";1");
            }
            strcat(buffer, "m");
            if (!m_consoleMode)
                termLine.append(buffer);
            length = termLine.size();
            m_remoteColor = color;
        }
        // TODO: Is it inefficient to call WideCharToMultiByte once per
        // character?
        char mbstr[16];
        int mblen = WideCharToMultiByte(CP_UTF8,
                                        0,
                                        &lineData[i].Char.UnicodeChar,
                                        1,
                                        mbstr,
                                        sizeof(mbstr),
                                        NULL,
                                        NULL);
        if (mblen <= 0) {
            mbstr[0] = '?';
            mblen = 1;
        }
        if (mblen == 1 && mbstr[0] == ' ') {
            termLine.push_back(' ');
        } else {
            termLine.append(mbstr, mblen);
            length = termLine.size();
        }
    }

    m_output->write(termLine.data(), length);
}

void Terminal::finishOutput(const std::pair<int, int> &newCursorPos)
{
    if (newCursorPos != m_cursorPos)
        hideTerminalCursor();
    if (m_cursorHidden) {
        moveTerminalToLine(newCursorPos.second);
        char buffer[32];
        sprintf(buffer, CSI"%dG"CSI"?25h", newCursorPos.first + 1);
        if (!m_consoleMode)
            m_output->write(buffer);
        m_cursorHidden = false;
    }
    m_cursorPos = newCursorPos;
}

void Terminal::hideTerminalCursor()
{
    if (m_cursorHidden)
        return;
    if (!m_consoleMode)
        m_output->write(CSI"?25l");
    m_cursorHidden = true;
}

void Terminal::moveTerminalToLine(int line)
{
    // Do not use CPL or CNL.  Konsole 2.5.4 does not support Cursor Previous
    // Line (CPL) -- there are "Undecodable sequence" errors.  gnome-terminal
    // 2.32.0 does handle it.  Cursor Next Line (CNL) does nothing if the
    // cursor is on the last line already.

    if (line < m_remoteLine) {
        // CUrsor Up (CUU)
        char buffer[32];
        sprintf(buffer, "\r"CSI"%dA", m_remoteLine - line);
        if (!m_consoleMode)
            m_output->write(buffer);
        m_remoteLine = line;
    } else if (line > m_remoteLine) {
        while (line > m_remoteLine) {
            m_output->write("\r\n");
            m_remoteLine++;
        }
    } else {
        m_output->write("\r");
    }
}
<commit_msg>Console mode: don't send \r when invoking moveTerminalToLine() with line == m_remoteLine<commit_after>// Copyright (c) 2011-2012 Ryan Prichard
//
// 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.

#include "Terminal.h"
#include "NamedPipe.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <string>

#define CSI "\x1b["

const int COLOR_ATTRIBUTE_MASK =
        FOREGROUND_BLUE |
        FOREGROUND_GREEN |
        FOREGROUND_RED |
        FOREGROUND_INTENSITY |
        BACKGROUND_BLUE |
        BACKGROUND_GREEN |
        BACKGROUND_RED |
        BACKGROUND_INTENSITY;

const int TERMINAL_BLACK = 0;
const int TERMINAL_RED   = 1;
const int TERMINAL_GREEN = 2;
const int TERMINAL_BLUE  = 4;
const int TERMINAL_WHITE = 7;

const int TERMINAL_FOREGROUND = 30;
const int TERMINAL_BACKGROUND = 40;

Terminal::Terminal(NamedPipe *output) :
    m_output(output),
    m_remoteLine(0),
    m_cursorHidden(false),
    m_remoteColor(-1),
    m_consoleMode(false)
{
}

void Terminal::setConsoleMode(int mode)
{
    if (mode == 1)
        m_consoleMode = true;
    else
        m_consoleMode = false;
}

void Terminal::reset(bool sendClearFirst, int newLine)
{
    if (sendClearFirst && !m_consoleMode)
        m_output->write(CSI"1;1H"CSI"2J");
    m_remoteLine = newLine;
    m_cursorHidden = false;
    m_cursorPos = std::pair<int, int>(0, newLine);
    m_remoteColor = -1;

	//use mouse
    if (!m_consoleMode) m_output->write(CSI"?1000h");
}

void Terminal::sendLine(int line, CHAR_INFO *lineData, int width)
{
    hideTerminalCursor();
    moveTerminalToLine(line);

    // Erase in Line -- erase entire line.
    if (!m_consoleMode)
        m_output->write(CSI"2K");

    std::string termLine;
    termLine.reserve(width + 32);

    int length = 0;
    for (int i = 0; i < width; ++i) {
        int color = lineData[i].Attributes & COLOR_ATTRIBUTE_MASK;
        if (color != m_remoteColor) {
            int fore = 0;
            int back = 0;
            if (color & FOREGROUND_RED)   fore |= TERMINAL_RED;
            if (color & FOREGROUND_GREEN) fore |= TERMINAL_GREEN;
            if (color & FOREGROUND_BLUE)  fore |= TERMINAL_BLUE;
            if (color & BACKGROUND_RED)   back |= TERMINAL_RED;
            if (color & BACKGROUND_GREEN) back |= TERMINAL_GREEN;
            if (color & BACKGROUND_BLUE)  back |= TERMINAL_BLUE;

            char buffer[128];
            if (back == TERMINAL_BLACK) {
                if (fore == TERMINAL_WHITE) {
                    // Use the terminal's default colors.
                    sprintf(buffer, CSI"0");
                } else if (fore == TERMINAL_BLACK) {
                    // Attempt to hide the character, but some terminals won't
                    // hide it.  Is this an important case?
                    sprintf(buffer, CSI"0;8");
                } else {
                    sprintf(buffer, CSI"0;%d", TERMINAL_FOREGROUND + fore);
                }
                if (color & FOREGROUND_INTENSITY)
                    strcat(buffer, ";1");
            } else if (back == TERMINAL_WHITE) {
                // Use the terminal's inverted colors.
                if (fore == TERMINAL_BLACK) {
                    sprintf(buffer, CSI"0;7");
                } else if (fore == TERMINAL_WHITE) {
                    // Attempt to hide the character, but some terminals won't
                    // hide it.  Is this an important case?
                    sprintf(buffer, CSI"0;7;8");
                } else {
                    sprintf(buffer, CSI"0;7;%d", TERMINAL_BACKGROUND + fore);
                }
                // Don't worry about FOREGROUND_INTENSITY because with at least
                // one terminal (gnome-terminal 2.32.0), setting the Intensity
                // flag affects both foreground and background when Reverse
                // flag is also set.
            } else {
                sprintf(buffer, CSI"0;%d;%d",
                        TERMINAL_FOREGROUND + fore,
                        TERMINAL_BACKGROUND + back);
                if (color & FOREGROUND_INTENSITY)
                    strcat(buffer, ";1");
            }
            strcat(buffer, "m");
            if (!m_consoleMode)
                termLine.append(buffer);
            length = termLine.size();
            m_remoteColor = color;
        }
        // TODO: Is it inefficient to call WideCharToMultiByte once per
        // character?
        char mbstr[16];
        int mblen = WideCharToMultiByte(CP_UTF8,
                                        0,
                                        &lineData[i].Char.UnicodeChar,
                                        1,
                                        mbstr,
                                        sizeof(mbstr),
                                        NULL,
                                        NULL);
        if (mblen <= 0) {
            mbstr[0] = '?';
            mblen = 1;
        }
        if (mblen == 1 && mbstr[0] == ' ') {
            termLine.push_back(' ');
        } else {
            termLine.append(mbstr, mblen);
            length = termLine.size();
        }
    }

    m_output->write(termLine.data(), length);
}

void Terminal::finishOutput(const std::pair<int, int> &newCursorPos)
{
    if (newCursorPos != m_cursorPos)
        hideTerminalCursor();
    if (m_cursorHidden) {
        moveTerminalToLine(newCursorPos.second);
        char buffer[32];
        sprintf(buffer, CSI"%dG"CSI"?25h", newCursorPos.first + 1);
        if (!m_consoleMode)
            m_output->write(buffer);
        m_cursorHidden = false;
    }
    m_cursorPos = newCursorPos;
}

void Terminal::hideTerminalCursor()
{
    if (m_cursorHidden)
        return;
    if (!m_consoleMode)
        m_output->write(CSI"?25l");
    m_cursorHidden = true;
}

void Terminal::moveTerminalToLine(int line)
{
    // Do not use CPL or CNL.  Konsole 2.5.4 does not support Cursor Previous
    // Line (CPL) -- there are "Undecodable sequence" errors.  gnome-terminal
    // 2.32.0 does handle it.  Cursor Next Line (CNL) does nothing if the
    // cursor is on the last line already.

    if (line < m_remoteLine) {
        if (!m_consoleMode) {
            // CUrsor Up (CUU)
            char buffer[32];
            sprintf(buffer, "\r"CSI"%dA", m_remoteLine - line);
            m_output->write(buffer);
        }
        m_remoteLine = line;
    } else if (line > m_remoteLine) {
        while (line > m_remoteLine) {
            m_output->write("\r\n");
            m_remoteLine++;
        }
    } else {
        if (!m_consoleMode)
            m_output->write("\r");
    }
}
<|endoftext|>


<commit_before>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the BSD License.
*/

#ifdef TRITON_PYTHON_BINDINGS

#include <exceptions.hpp>
#include <pythonObjects.hpp>
#include <pythonUtils.hpp>
#include <pythonXFunctions.hpp>
#include <register.hpp>

/*! \page py_Register_page Register
    \brief [**python api**] All information about the Register python object.

\tableofcontents

\section py_Register_description Description

This object is used to represent a register operand according to the CPU architecture.

\subsection py_Register_example Example

~~~~~~~~~~~~~{.py}
>>> processing(inst)
>>> print inst
40000: mov ah, byte ptr [rdx + rcx*2 + 0x100]

>>> op0 = inst.getOperands()[0]
>>> print op0
ah:8 bv[15..8]

>>> op0.getName()
'ah'

>>> op0.getSize()
1

>>> op0.getBitSize()
8

>>> op0.getParent().getName()
'rax'
~~~~~~~~~~~~~

\subsection py_Register_constructor Constructor

~~~~~~~~~~~~~{.py}
>>> ah = Register(REG.AH, 0x18)
>>> print ah
ah:8 bv[15..8]

>>> print ah.getBitSize()
8

>>> print hex(ah.getConcreteValue())
0x18L

>>> regId = 1
>>> Register(regId)
rax:64 bv[63..0]
~~~~~~~~~~~~~

\section Register_py_api Python API - Methods of the Register class

- **getBitSize(void)**

Returns the size (in bits) of the register as integer.

e.g: `64`

- **getBitvector(void)**

Returns the bitvector as \ref py_Bitvector_page.

- **getConcreteValue(void)**

Returns the concrete value assigned to this register operand.

- **getName(void)**

Returns the name of the register as string.

e.g: `rbx`

- **getParent(void)**

Returns the parent register as \ref py_Register_page.

- **getSize(void)**

Returns the size (in bytes) of the register as integer.

e.g: `8`

- **getType(void)**

Returns type of the register as \ref py_OPERAND_page. In this case this function returns `OPERAND.REG`.

- **isValid(void)**

Returns true if the register is valid.

- **isFlag(void)**

Returns true if the register is a flag.

- **isRegister(void)**

Returns true if the register is a register.

- **setConcreteValue(integer value)**

Sets a concrete value to this register.

*/

namespace triton {
  namespace bindings {
    namespace python {

      //! Register destructor.
      void Register_dealloc(PyObject* self) {
        std::cout << std::flush;
        delete PyRegister_AsRegister(self);
        Py_DECREF(self);
      }

      static PyObject* Register_getBitSize(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getBitSize());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getBitvector(PyObject* self, PyObject* noarg) {
        try {
          return PyBitvector(*PyRegister_AsRegister(self));
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getConcreteValue(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint512(PyRegister_AsRegister(self)->getConcreteValue());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getName(PyObject* self, PyObject* noarg) {
        try {
          return Py_BuildValue("s", PyRegister_AsRegister(self)->getName().c_str());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getParent(PyObject* self, PyObject* noarg) {
        try {
          triton::arch::Register parent = PyRegister_AsRegister(self)->getParent();
          return PyRegister(parent);
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getSize(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getSize());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getType(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getType());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_isValid(PyObject* self, PyObject* noarg) {
        try {
          if (PyRegister_AsRegister(self)->isValid())
            Py_RETURN_TRUE;
          Py_RETURN_FALSE;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_isRegister(PyObject* self, PyObject* noarg) {
        try {
          if (PyRegister_AsRegister(self)->isRegister())
            Py_RETURN_TRUE;
          Py_RETURN_FALSE;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_isFlag(PyObject* self, PyObject* noarg) {
        try {
          if (PyRegister_AsRegister(self)->isFlag())
            Py_RETURN_TRUE;
          Py_RETURN_FALSE;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_setConcreteValue(PyObject* self, PyObject* value) {
        try {
          triton::arch::Register* reg;

          if (!PyLong_Check(value) && !PyInt_Check(value))
            return PyErr_Format(PyExc_TypeError, "Register::setConcretevalue(): Expected an integer as argument.");

          reg = PyRegister_AsRegister(self);
          reg->setConcreteValue(PyLong_AsUint512(value));

          Py_INCREF(Py_None);
          return Py_None;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static int Register_print(PyObject* self) {
        std::cout << PyRegister_AsRegister(self);
        return 0;
      }

      static PyObject* Register_str(PyObject* self) {
        try {
          std::stringstream str;
          str << PyRegister_AsRegister(self);
          return PyString_FromFormat("%s", str.str().c_str());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      //! Register methods.
      PyMethodDef Register_callbacks[] = {
        {"getBitSize",        Register_getBitSize,       METH_NOARGS,    ""},
        {"getBitvector",      Register_getBitvector,     METH_NOARGS,    ""},
        {"getConcreteValue",  Register_getConcreteValue, METH_NOARGS,    ""},
        {"getName",           Register_getName,          METH_NOARGS,    ""},
        {"getParent",         Register_getParent,        METH_NOARGS,    ""},
        {"getSize",           Register_getSize,          METH_NOARGS,    ""},
        {"getType",           Register_getType,          METH_NOARGS,    ""},
        {"isFlag",            Register_isFlag,           METH_NOARGS,    ""},
        {"isRegister",        Register_isRegister,       METH_NOARGS,    ""},
        {"isValid",           Register_isValid,          METH_NOARGS,    ""},
        {"setConcreteValue",  Register_setConcreteValue, METH_O,         ""},
        {nullptr,             nullptr,                   0,              nullptr}
      };

      PyTypeObject Register_Type = {
        PyObject_HEAD_INIT(&PyType_Type)
        0,                                          /* ob_size */
        "Register",                                 /* tp_name */
        sizeof(Register_Object),                    /* tp_basicsize */
        0,                                          /* tp_itemsize */
        (destructor)Register_dealloc,               /* tp_dealloc */
        (printfunc)Register_print,                  /* tp_print */
        0,                                          /* tp_getattr */
        0,                                          /* tp_setattr */
        0,                                          /* tp_compare */
        0,                                          /* tp_repr */
        0,                                          /* tp_as_number */
        0,                                          /* tp_as_sequence */
        0,                                          /* tp_as_mapping */
        0,                                          /* tp_hash */
        0,                                          /* tp_call */
        (reprfunc)Register_str,                     /* tp_str */
        0,                                          /* tp_getattro */
        0,                                          /* tp_setattro */
        0,                                          /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT,                         /* tp_flags */
        "Register objects",                         /* tp_doc */
        0,                                          /* tp_traverse */
        0,                                          /* tp_clear */
        0,                                          /* tp_richcompare */
        0,                                          /* tp_weaklistoffset */
        0,                                          /* tp_iter */
        0,                                          /* tp_iternext */
        Register_callbacks,                         /* tp_methods */
        0,                                          /* tp_members */
        0,                                          /* tp_getset */
        0,                                          /* tp_base */
        0,                                          /* tp_dict */
        0,                                          /* tp_descr_get */
        0,                                          /* tp_descr_set */
        0,                                          /* tp_dictoffset */
        0,                                          /* tp_init */
        0,                                          /* tp_alloc */
        0,                                          /* tp_new */
        0,                                          /* tp_free */
        0,                                          /* tp_is_gc */
        0,                                          /* tp_bases */
        0,                                          /* tp_mro */
        0,                                          /* tp_cache */
        0,                                          /* tp_subclasses */
        0,                                          /* tp_weaklist */
        0,                                          /* tp_del */
        0                                           /* tp_version_tag */
      };

      PyObject* PyRegister(const triton::arch::Register& reg) {
        Register_Object* object;

        PyType_Ready(&Register_Type);
        object = PyObject_NEW(Register_Object, &Register_Type);
        if (object != NULL)
          object->reg = new triton::arch::Register(reg);

        return (PyObject*)object;
      }

    }; /* python namespace */
  }; /* bindings namespace */
}; /* triton namespace */

#endif /* TRITON_PYTHON_BINDINGS */
<commit_msg>#369 in progress: Remove the global API instance (test osx)<commit_after>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the BSD License.
*/

#ifdef TRITON_PYTHON_BINDINGS

#include <exceptions.hpp>
#include <pythonObjects.hpp>
#include <pythonUtils.hpp>
#include <pythonXFunctions.hpp>
#include <register.hpp>

/*! \page py_Register_page Register
    \brief [**python api**] All information about the Register python object.

\tableofcontents

\section py_Register_description Description

This object is used to represent a register operand according to the CPU architecture.

\subsection py_Register_example Example

~~~~~~~~~~~~~{.py}
>>> processing(inst)
>>> print inst
40000: mov ah, byte ptr [rdx + rcx*2 + 0x100]

>>> op0 = inst.getOperands()[0]
>>> print op0
ah:8 bv[15..8]

>>> op0.getName()
'ah'

>>> op0.getSize()
1

>>> op0.getBitSize()
8

>>> op0.getParent().getName()
'rax'
~~~~~~~~~~~~~

\subsection py_Register_constructor Constructor

~~~~~~~~~~~~~{.py}
>>> ah = Register(REG.AH, 0x18)
>>> print ah
ah:8 bv[15..8]

>>> print ah.getBitSize()
8

>>> print hex(ah.getConcreteValue())
0x18L

>>> regId = 1
>>> Register(regId)
rax:64 bv[63..0]
~~~~~~~~~~~~~

\section Register_py_api Python API - Methods of the Register class

- **getBitSize(void)**

Returns the size (in bits) of the register as integer.

e.g: `64`

- **getBitvector(void)**

Returns the bitvector as \ref py_Bitvector_page.

- **getConcreteValue(void)**

Returns the concrete value assigned to this register operand.

- **getName(void)**

Returns the name of the register as string.

e.g: `rbx`

- **getParent(void)**

Returns the parent register as \ref py_Register_page.

- **getSize(void)**

Returns the size (in bytes) of the register as integer.

e.g: `8`

- **getType(void)**

Returns type of the register as \ref py_OPERAND_page. In this case this function returns `OPERAND.REG`.

- **isValid(void)**

Returns true if the register is valid.

- **isFlag(void)**

Returns true if the register is a flag.

- **isRegister(void)**

Returns true if the register is a register.

- **setConcreteValue(integer value)**

Sets a concrete value to this register.

*/

namespace triton {
  namespace bindings {
    namespace python {

      //! Register destructor.
      void Register_dealloc(PyObject* self) {
        std::cout << std::flush;
        delete PyRegister_AsRegister(self);
        Py_DECREF(self);
      }

      static PyObject* Register_getBitSize(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getBitSize());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getBitvector(PyObject* self, PyObject* noarg) {
        try {
          return PyBitvector(*PyRegister_AsRegister(self));
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getConcreteValue(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint512(PyRegister_AsRegister(self)->getConcreteValue());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getName(PyObject* self, PyObject* noarg) {
        try {
          return Py_BuildValue("s", PyRegister_AsRegister(self)->getName().c_str());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getParent(PyObject* self, PyObject* noarg) {
        try {
          triton::arch::Register parent = PyRegister_AsRegister(self)->getParent();
          return PyRegister(parent);
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getSize(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getSize());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_getType(PyObject* self, PyObject* noarg) {
        try {
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getType());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_isValid(PyObject* self, PyObject* noarg) {
        try {
          if (PyRegister_AsRegister(self)->isValid())
            Py_RETURN_TRUE;
          Py_RETURN_FALSE;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_isRegister(PyObject* self, PyObject* noarg) {
        try {
          if (PyRegister_AsRegister(self)->isRegister())
            Py_RETURN_TRUE;
          Py_RETURN_FALSE;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_isFlag(PyObject* self, PyObject* noarg) {
        try {
          if (PyRegister_AsRegister(self)->isFlag())
            Py_RETURN_TRUE;
          Py_RETURN_FALSE;
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static PyObject* Register_setConcreteValue(PyObject* self, PyObject* value) {
        try {
          triton::arch::Register* reg;

          if (!PyLong_Check(value) && !PyInt_Check(value))
            return PyErr_Format(PyExc_TypeError, "Register::setConcretevalue(): Expected an integer as argument.");

          reg = PyRegister_AsRegister(self);
          reg->setConcreteValue(PyLong_AsUint512(value));

          Py_INCREF(Py_None);
          return Py_None;
        }
        catch (const triton::exceptions::Exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      static int Register_print(PyObject* self) {
        std::cout << PyRegister_AsRegister(self);
        return 0;
      }

      static PyObject* Register_str(PyObject* self) {
        try {
          std::stringstream str;
          str << PyRegister_AsRegister(self);
          return PyString_FromFormat("%s", str.str().c_str());
        }
        catch (const std::exception& e) {
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
        }
      }

      //! Register methods.
      PyMethodDef Register_callbacks[] = {
        {"getBitSize",        Register_getBitSize,       METH_NOARGS,    ""},
        {"getBitvector",      Register_getBitvector,     METH_NOARGS,    ""},
        {"getConcreteValue",  Register_getConcreteValue, METH_NOARGS,    ""},
        {"getName",           Register_getName,          METH_NOARGS,    ""},
        {"getParent",         Register_getParent,        METH_NOARGS,    ""},
        {"getSize",           Register_getSize,          METH_NOARGS,    ""},
        {"getType",           Register_getType,          METH_NOARGS,    ""},
        {"isFlag",            Register_isFlag,           METH_NOARGS,    ""},
        {"isRegister",        Register_isRegister,       METH_NOARGS,    ""},
        {"isValid",           Register_isValid,          METH_NOARGS,    ""},
        {"setConcreteValue",  Register_setConcreteValue, METH_O,         ""},
        {nullptr,             nullptr,                   0,              nullptr}
      };

      PyTypeObject Register_Type = {
        PyObject_HEAD_INIT(&PyType_Type)
        0,                                          /* ob_size */
        "Register",                                 /* tp_name */
        sizeof(Register_Object),                    /* tp_basicsize */
        0,                                          /* tp_itemsize */
        (destructor)Register_dealloc,               /* tp_dealloc */
        (printfunc)Register_print,                  /* tp_print */
        0,                                          /* tp_getattr */
        0,                                          /* tp_setattr */
        0,                                          /* tp_compare */
        0,                                          /* tp_repr */
        0,                                          /* tp_as_number */
        0,                                          /* tp_as_sequence */
        0,                                          /* tp_as_mapping */
        0,                                          /* tp_hash */
        0,                                          /* tp_call */
        (reprfunc)Register_str,                     /* tp_str */
        0,                                          /* tp_getattro */
        0,                                          /* tp_setattro */
        0,                                          /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT,                         /* tp_flags */
        "Register objects",                         /* tp_doc */
        0,                                          /* tp_traverse */
        0,                                          /* tp_clear */
        0,                                          /* tp_richcompare */
        0,                                          /* tp_weaklistoffset */
        0,                                          /* tp_iter */
        0,                                          /* tp_iternext */
        Register_callbacks,                         /* tp_methods */
        0,                                          /* tp_members */
        0,                                          /* tp_getset */
        0,                                          /* tp_base */
        0,                                          /* tp_dict */
        0,                                          /* tp_descr_get */
        0,                                          /* tp_descr_set */
        0,                                          /* tp_dictoffset */
        0,                                          /* tp_init */
        0,                                          /* tp_alloc */
        0,                                          /* tp_new */
        0,                                          /* tp_free */
        0,                                          /* tp_is_gc */
        0,                                          /* tp_bases */
        0,                                          /* tp_mro */
        0,                                          /* tp_cache */
        0,                                          /* tp_subclasses */
        0,                                          /* tp_weaklist */
        0,                                          /* tp_del */
        0                                           /* tp_version_tag */
      };

      PyObject* PyRegister(const triton::arch::Register& reg) {
        Register_Object* object;

        PyType_Ready(&Register_Type);
        object = PyObject_NEW(Register_Object, &Register_Type);
        if (object != NULL)
          object->reg = new triton::arch::Register(reg);

        return (PyObject*)object;
      }

    }; /* python namespace */
  }; /* bindings namespace */
}; /* triton namespace */

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


<commit_before>// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iceoryx_posh/popo/trigger_handle.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp"

namespace iox
{
namespace popo
{
TriggerHandle::TriggerHandle(ConditionVariableData* const conditionVariableDataPtr,
                             const cxx::MethodCallback<void, EventAccessor, uint64_t> resetCallback,
                             const uint64_t uniqueTriggerId) noexcept
    : m_conditionVariableDataPtr(conditionVariableDataPtr)
    , m_resetCallback(resetCallback)
    , m_uniqueTriggerId(uniqueTriggerId)
{
}

TriggerHandle::TriggerHandle(TriggerHandle&& rhs) noexcept
{
    *this = std::move(rhs);
}

TriggerHandle& TriggerHandle::operator=(TriggerHandle&& rhs) noexcept
{
    if (this != &rhs)
    {
        std::lock(m_mutex, rhs.m_mutex);
        std::lock_guard<std::recursive_mutex> lock(m_mutex, std::adopt_lock);
        std::lock_guard<std::recursive_mutex> lockRhs(rhs.m_mutex, std::adopt_lock);

        reset();

        m_conditionVariableDataPtr = std::move(rhs.m_conditionVariableDataPtr);
        m_resetCallback = std::move(rhs.m_resetCallback);
        m_uniqueTriggerId = rhs.m_uniqueTriggerId;

        rhs.invalidate();
    }

    return *this;
}

TriggerHandle::~TriggerHandle()
{
    reset();
}

TriggerHandle::operator bool() const noexcept
{
    return isValid();
}

bool TriggerHandle::isValid() const noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    return m_conditionVariableDataPtr != nullptr;
}

void TriggerHandle::trigger() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    if (isValid())
    {
        ConditionVariableSignaler(m_conditionVariableDataPtr).notifyOne();
    }
}

void TriggerHandle::reset() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    if (!isValid())
    {
        return;
    }

    m_resetCallback(EVENT_ACCESSOR, m_uniqueTriggerId);

    invalidate();
}

void TriggerHandle::invalidate() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    m_conditionVariableDataPtr = nullptr;
    m_resetCallback = cxx::MethodCallback<void, EventAccessor, uint64_t>();
    m_uniqueTriggerId = 0U;
}

ConditionVariableData* TriggerHandle::getConditionVariableData() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    return m_conditionVariableDataPtr;
}

uint64_t TriggerHandle::getUniqueId() const noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    return m_uniqueTriggerId;
}

} // namespace popo
} // namespace iox
<commit_msg>iox-#350 defined constexpr TriggerHandle::EVENT_ACCESSOR in cpp file to solve compiler bug<commit_after>// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iceoryx_posh/popo/trigger_handle.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp"

namespace iox
{
namespace popo
{
constexpr EventAccessor TriggerHandle::EVENT_ACCESSOR;

TriggerHandle::TriggerHandle(ConditionVariableData* const conditionVariableDataPtr,
                             const cxx::MethodCallback<void, EventAccessor, uint64_t> resetCallback,
                             const uint64_t uniqueTriggerId) noexcept
    : m_conditionVariableDataPtr(conditionVariableDataPtr)
    , m_resetCallback(resetCallback)
    , m_uniqueTriggerId(uniqueTriggerId)
{
}

TriggerHandle::TriggerHandle(TriggerHandle&& rhs) noexcept
{
    *this = std::move(rhs);
}

TriggerHandle& TriggerHandle::operator=(TriggerHandle&& rhs) noexcept
{
    if (this != &rhs)
    {
        std::lock(m_mutex, rhs.m_mutex);
        std::lock_guard<std::recursive_mutex> lock(m_mutex, std::adopt_lock);
        std::lock_guard<std::recursive_mutex> lockRhs(rhs.m_mutex, std::adopt_lock);

        reset();

        m_conditionVariableDataPtr = std::move(rhs.m_conditionVariableDataPtr);
        m_resetCallback = std::move(rhs.m_resetCallback);
        m_uniqueTriggerId = rhs.m_uniqueTriggerId;

        rhs.invalidate();
    }

    return *this;
}

TriggerHandle::~TriggerHandle()
{
    reset();
}

TriggerHandle::operator bool() const noexcept
{
    return isValid();
}

bool TriggerHandle::isValid() const noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    return m_conditionVariableDataPtr != nullptr;
}

void TriggerHandle::trigger() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    if (isValid())
    {
        ConditionVariableSignaler(m_conditionVariableDataPtr).notifyOne();
    }
}

void TriggerHandle::reset() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    if (!isValid())
    {
        return;
    }

    m_resetCallback(EVENT_ACCESSOR, m_uniqueTriggerId);

    invalidate();
}

void TriggerHandle::invalidate() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    m_conditionVariableDataPtr = nullptr;
    m_resetCallback = cxx::MethodCallback<void, EventAccessor, uint64_t>();
    m_uniqueTriggerId = 0U;
}

ConditionVariableData* TriggerHandle::getConditionVariableData() noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    return m_conditionVariableDataPtr;
}

uint64_t TriggerHandle::getUniqueId() const noexcept
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);

    return m_uniqueTriggerId;
}

} // namespace popo
} // namespace iox
<|endoftext|>


<commit_before>#ifndef ALEPH_TOPOLOGY_IO_LINES_AND_POINTS_HH__
#define ALEPH_TOPOLOGY_IO_LINES_AND_POINTS_HH__

#include <fstream>
#include <ostream>
#include <stdexcept>
#include <string>

namespace aleph
{

namespace topology
{

namespace io
{

/**
  @class LinesAndPoints
  @brief Writes files as lines and points

  This writer class uses coordinate information of a simplicial complex
  to represent its 1-skeleton, i.e. its vertices and edges. All data is
  stored in a simple format, representing 0-simplex by its coordinates,
  and a 1-simplex by a sequence of coordinates.

  An edge \f$(u,v)\f$ will be stored as:

  \[
    x_u y_u
    x_v y_v\n
  \]

  Vertices and edges will be separated by two newlines in order to show
  that a new block was started. This makes it possible to use `gnuplot`
  for the visualization:

  \code
  plot "output.txt" index 0 with points pt 7, # to represent vertices
       ""           index 1 with lines        # to represent edges
  \endcode
*/

class LinesAndPoints
{
public:

  /** Writes the simplicial complex to a new file. */
  template <class SimplicialComplex, class Container> void operator()( const std::string& filename,
                                                                       const SimplicialComplex& K,
                                                                       const Container& container )
  {
    std::ofstream out( filename );
    if( !out )
      throw std::runtime_error( "Unable to open output file" );

    this->operator()( out, K, container );
  }

  /** Writes the simplicial complex to a new output stream. */
  template <class SimplicialComplex, class Container> void operator()( std::ostream& out,
                                                                       const SimplicialComplex& K,
                                                                       const Container& container )
  {
    for( auto&& s : K )
    {
      if( s.dimension() != 0 )
        continue;

      auto u = s[0];         // vertex
      auto p = container[u]; // coordinate

      if( p.size() >= 2 )
        write( out, p );
      else
        throw std::runtime_error( "Insufficient number of dimensions for storing coordinates" );
    }

    out << "\n\n";

    for( auto&& s : K )
    {
      if( s.dimension() != 1 )
        continue;

      auto u = s[0];         // vertex
      auto v = s[1];         // vertex
      auto p = container[u]; // first coordinate
      auto q = container[v]; // second coordinate

      if( p.size() >= 2 && q.size() >= 2 )
      {
        write(out, p);
        write(out, q);

        out << "\n";
      }
      else
        throw std::runtime_error( "Insufficient number of dimensions for storing coordinates" );
    }
  }
private:
  template <class Container> void write( std::ostream& out, Container& p )
  {
    out << p[0] << "\t" << p[1] << " ";

    if( p.size() >= 3 )
      out << p[2];

    out << "\n";
  }
};

} // namespace io

} // namespace topology

} // namespace aleph

#endif
<commit_msg>Added vertex label output for simplicial complex I/O<commit_after>#ifndef ALEPH_TOPOLOGY_IO_LINES_AND_POINTS_HH__
#define ALEPH_TOPOLOGY_IO_LINES_AND_POINTS_HH__

#include <fstream>
#include <ostream>
#include <stdexcept>
#include <string>

namespace aleph
{

namespace topology
{

namespace io
{

/**
  @class LinesAndPoints
  @brief Writes files as lines and points

  This writer class uses coordinate information of a simplicial complex
  to represent its 1-skeleton, i.e. its vertices and edges. All data is
  stored in a simple format, representing 0-simplex by its coordinates,
  and a 1-simplex by a sequence of coordinates.

  An edge \f$(u,v)\f$ will be stored as:

  \[
    x_u y_u
    x_v y_v\n
  \]

  Vertices and edges will be separated by two newlines in order to show
  that a new block was started. This makes it possible to use `gnuplot`
  for the visualization:

  \code
  plot "output.txt" index 0 with points pt 7, # to represent vertices
       ""           index 1 with lines        # to represent edges
  \endcode
*/

class LinesAndPoints
{
public:

  /** Writes the simplicial complex to a new file. */
  template <class SimplicialComplex, class Container> void operator()( const std::string& filename,
                                                                       const SimplicialComplex& K,
                                                                       const Container& container )
  {
    std::ofstream out( filename );
    if( !out )
      throw std::runtime_error( "Unable to open output file" );

    this->operator()( out, K, container );
  }

  /** Writes the simplicial complex to a new output stream. */
  template <class SimplicialComplex, class Container> void operator()( std::ostream& out,
                                                                       const SimplicialComplex& K,
                                                                       const Container& container )
  {
    for( auto&& s : K )
    {
      if( s.dimension() != 0 )
        continue;

      auto u = s[0];         // vertex
      auto p = container[u]; // coordinate

      if( p.size() >= 2 )
        write( out, p, _addVertexLabels ? std::to_string( u ) : std::string() );
      else
        throw std::runtime_error( "Insufficient number of dimensions for storing coordinates" );
    }

    out << "\n\n";

    for( auto&& s : K )
    {
      if( s.dimension() != 1 )
        continue;

      auto u = s[0];         // vertex
      auto v = s[1];         // vertex
      auto p = container[u]; // first coordinate
      auto q = container[v]; // second coordinate

      if( p.size() >= 2 && q.size() >= 2 )
      {
        write(out, p);
        write(out, q);

        out << "\n";
      }
      else
        throw std::runtime_error( "Insufficient number of dimensions for storing coordinates" );
    }
  }

  bool addVertexLabels() const noexcept
  {
    return _addVertexLabels;
  }

  void addVertexLabels( bool value ) noexcept
  {
    _addVertexLabels = value;
  }

private:
  template <class Container> void write( std::ostream& out, Container& p, const std::string& label = std::string() )
  {
    out << p[0] << "\t" << p[1];

    if( p.size() >= 3 )
      out << " " << p[2];

    if( not label.empty() )
      out << " " << label;

    out << "\n";
  }

  bool _addVertexLabels = false;
};

} // namespace io

} // namespace topology

} // namespace aleph

#endif
<|endoftext|>