<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DBN_UNIT_TYPE_HPP
#define DBN_UNIT_TYPE_HPP

namespace dll {

enum class unit_type {
    BINARY,    //Stochastic binary unity
    EXP,        //Exponential unit (for last layer)
    SOFTMAX,    //Softmax unit (for last layer)
    GAUSSIAN,   //Gaussian visible layers
    RELU        //Noisy Rectified Linear Unit (nRLU)
};

} //end of dbn namespace

#endif<commit_msg>Prepare support for new RELU unit<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DBN_UNIT_TYPE_HPP
#define DBN_UNIT_TYPE_HPP

namespace dll {

enum class unit_type {
    BINARY,     //Stochastic binary unity
    EXP,        //Exponential unit (for last layer)
    SOFTMAX,    //Softmax unit (for last layer)
    GAUSSIAN,   //Gaussian unit
    RELU,       //Rectified Linear Unit (ReLU) (Nair and Hinton, 2010)
    RELU1,      //Rectified Linear Unit (ReLU) capped at 1 (Krizhevsky, 2010)
    RELU6,      //Rectified Linear Unit (ReLU) capped at 6 (Krizhevsky,. 2010)
};

constexpr bool is_relu(unit_type t){
    return t == unit_type::RELU || t == unit_type::RELU1 || t == unit_type::RELU6;
}

} //end of dbn namespace

#endif<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef ETL_FAST_EXPR_HPP
#define ETL_FAST_EXPR_HPP

#include "fast_op.hpp"
#include "tmp.hpp"

namespace etl {

template<typename LE, typename RE, typename Enable = void>
struct get_etl_size ;

template<typename LE, typename RE>
struct get_etl_size<LE, RE, enable_if_t<is_etl_expr<LE>::value>>
    : std::integral_constant<std::size_t, std::remove_reference<LE>::type::etl_size> {} ;

template<typename LE, typename RE>
struct get_etl_size<LE, RE, enable_if_t<and_u<is_etl_expr<RE>::value, not_u<is_etl_expr<LE>::value>::value>::value>>
    : std::integral_constant<std::size_t, std::remove_reference<RE>::type::etl_size> {};

template <typename T, typename LeftExpr, typename BinaryOp, typename RightExpr>
class binary_expr {
private:
    LeftExpr _lhs;
    RightExpr _rhs;

    typedef binary_expr<T, LeftExpr, BinaryOp, RightExpr> this_type;

public:
    static constexpr const bool etl_marker = true;
    static constexpr const bool etl_fast = true;
    static constexpr const std::size_t etl_size = get_etl_size<LeftExpr, RightExpr>::value;

    using value_type = T;

    //Cannot be constructed with no args
    binary_expr() = delete;

    //Construct a new expression
    binary_expr(LeftExpr l, RightExpr r) :
            _lhs(std::forward<LeftExpr>(l)), _rhs(std::forward<RightExpr>(r)){
        //Nothing else to init
    }

    //No copying
    binary_expr(const binary_expr&) = delete;
    binary_expr& operator=(const binary_expr&) = delete;

    //Make sure move is supported
    binary_expr(binary_expr&&) = default;
    binary_expr& operator=(binary_expr&&) = default;

    //Accessors

    //TODO size() can be constexpr if Expr is fast_X

    template<typename LE = LeftExpr, enable_if_u<is_etl_expr<LE>::value> = detail::dummy>
    std::size_t size() const {
        return _lhs.size();
    }

    template<typename LE = LeftExpr, disable_if_u<is_etl_expr<LE>::value> = detail::dummy>
    std::size_t size() const {
        return _rhs.size();
    }

    typename std::add_lvalue_reference<LeftExpr>::type lhs(){
        return _lhs;
    }

    typename std::add_lvalue_reference<typename std::add_const<LeftExpr>::type>::type lhs() const {
        return _lhs;
    }

    typename std::add_lvalue_reference<RightExpr>::type rhs(){
        return _rhs;
    }

    typename std::add_lvalue_reference<typename std::add_const<RightExpr>::type>::type rhs() const {
        return _rhs;
    }

    //Apply the expression

    decltype(auto) operator[](std::size_t i) const {
        return BinaryOp::apply(lhs()[i], rhs()[i]);
    }
};

template <typename T, typename Expr, typename UnaryOp>
class unary_expr {
private:
    Expr _value;

    typedef unary_expr<T, Expr, UnaryOp> this_type;

public:
    static constexpr const bool etl_marker = true;
    static constexpr const bool etl_fast = true;
    static constexpr const std::size_t etl_size = std::remove_reference<Expr>::type::etl_size;

    using value_type = T;

    //Cannot be constructed with no args
    unary_expr() = delete;

    //Construct a new expression
    unary_expr(Expr l) : _value(std::forward<Expr>(l)){
        //Nothing else to init
    }

    //No copying
    unary_expr(const unary_expr&) = delete;
    unary_expr& operator=(const unary_expr&) = delete;

    //Make sure move is supported
    unary_expr(unary_expr&&) = default;
    unary_expr& operator=(unary_expr&&) = default;

    //Accessors

    //TODO size() can be constexpr if Expr is fast_X

    std::size_t size() const {
        return _value.size();
    }

    typename std::add_lvalue_reference<Expr>::type value(){
        return _value;
    }

    typename std::add_lvalue_reference<typename std::add_const<Expr>::type>::type value() const {
        return _value;
    }

    //Apply the expression

    decltype(auto) operator[](std::size_t i) const {
        return UnaryOp::apply(value()[i]);
    }
};

//{{{ Build binary expressions from two ETL expressions (vector,matrix,binary,unary)

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator-(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, minus_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator+(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, plus_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator*(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, mul_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator/(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, div_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator%(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, mod_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

//}}}

//{{{ Mix scalars and ETL expressions (vector,matrix,binary,unary)

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator-(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, minus_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator-(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, minus_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator+(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, plus_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator+(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, plus_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator*(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, mul_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator*(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, mul_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator/(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, div_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator/(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, div_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator%(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, mod_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator%(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, mod_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

//}}}

//{{{ Apply an unary expression on an ETL expression (vector,matrix,binary,unary)

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
auto abs(const E& value) -> unary_expr<typename E::value_type, const E&, abs_unary_op<typename E::value_type>> {
    return {value};
}

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
auto log(const E& value) -> unary_expr<typename E::value_type, const E&, log_unary_op<typename E::value_type>> {
    return {value};
}

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
auto sign(const E& value) -> unary_expr<typename E::value_type, const E&, sign_unary_op<typename E::value_type>> {
    return {value};
}

//}}}

//{{{ Apply a reduction on an ETL expression (vector,matrix,binary,unary)

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
typename E::value_type sum(const E& values){
    auto acc = static_cast<typename E::value_type>(0);

    for(std::size_t i = 0; i < values.size(); ++i){
        acc += values[i];
    }

    return acc;
}

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
typename E::value_type mean(const E& values){
    return sum(values) / values.size();
}

//}}}

} //end of namespace etl

#endif
<commit_msg>Cleanup size stuff<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef ETL_FAST_EXPR_HPP
#define ETL_FAST_EXPR_HPP

#include "fast_op.hpp"
#include "tmp.hpp"

namespace etl {

template<typename LE, typename RE, typename Enable = void>
struct get_etl_size ;

template<typename LE, typename RE>
struct get_etl_size<LE, RE, enable_if_t<is_etl_expr<LE>::value>>
    : std::integral_constant<std::size_t, std::remove_reference<LE>::type::etl_size> {} ;

template<typename LE, typename RE>
struct get_etl_size<LE, RE, enable_if_t<and_u<is_etl_expr<RE>::value, not_u<is_etl_expr<LE>::value>::value>::value>>
    : std::integral_constant<std::size_t, std::remove_reference<RE>::type::etl_size> {};

template <typename T, typename LeftExpr, typename BinaryOp, typename RightExpr>
class binary_expr {
private:
    static_assert(or_u<is_etl_expr<LeftExpr>::value, is_etl_expr<RightExpr>::value>::value, "At least one of the binary expressions arguments must be an ETL expr");

    LeftExpr _lhs;
    RightExpr _rhs;

    typedef binary_expr<T, LeftExpr, BinaryOp, RightExpr> this_type;

public:
    static constexpr const bool etl_marker = true;
    static constexpr const bool etl_fast = true;
    static constexpr const std::size_t etl_size = get_etl_size<LeftExpr, RightExpr>::value;

    using value_type = T;

    //Cannot be constructed with no args
    binary_expr() = delete;

    //Construct a new expression
    binary_expr(LeftExpr l, RightExpr r) :
            _lhs(std::forward<LeftExpr>(l)), _rhs(std::forward<RightExpr>(r)){
        //Nothing else to init
    }

    //No copying
    binary_expr(const binary_expr&) = delete;
    binary_expr& operator=(const binary_expr&) = delete;

    //Make sure move is supported
    binary_expr(binary_expr&&) = default;
    binary_expr& operator=(binary_expr&&) = default;

    //Accessors

    //TODO size() can be constexpr if Expr is fast_X

    template<typename LE = LeftExpr, enable_if_u<is_etl_expr<LE>::value> = detail::dummy>
    std::size_t size() const {
        return _lhs.size();
    }

    template<typename LE = LeftExpr, disable_if_u<is_etl_expr<LE>::value> = detail::dummy>
    std::size_t size() const {
        return _rhs.size();
    }

    typename std::add_lvalue_reference<LeftExpr>::type lhs(){
        return _lhs;
    }

    typename std::add_lvalue_reference<typename std::add_const<LeftExpr>::type>::type lhs() const {
        return _lhs;
    }

    typename std::add_lvalue_reference<RightExpr>::type rhs(){
        return _rhs;
    }

    typename std::add_lvalue_reference<typename std::add_const<RightExpr>::type>::type rhs() const {
        return _rhs;
    }

    //Apply the expression

    decltype(auto) operator[](std::size_t i) const {
        return BinaryOp::apply(lhs()[i], rhs()[i]);
    }
};

template <typename T, typename Expr, typename UnaryOp>
class unary_expr {
private:
    static_assert(is_etl_expr<Expr>::value, "Only ETL expressions can be used in unary_expr");

    Expr _value;

    typedef unary_expr<T, Expr, UnaryOp> this_type;

public:
    static constexpr const bool etl_marker = true;
    static constexpr const bool etl_fast = true;
    static constexpr const std::size_t etl_size = std::remove_reference<Expr>::type::etl_size;

    using value_type = T;

    //Cannot be constructed with no args
    unary_expr() = delete;

    //Construct a new expression
    unary_expr(Expr l) : _value(std::forward<Expr>(l)){
        //Nothing else to init
    }

    //No copying
    unary_expr(const unary_expr&) = delete;
    unary_expr& operator=(const unary_expr&) = delete;

    //Make sure move is supported
    unary_expr(unary_expr&&) = default;
    unary_expr& operator=(unary_expr&&) = default;

    //Accessors

    template<typename E = Expr, enable_if_u<std::remove_reference<E>::type::etl_fast> = detail::dummy>
    constexpr std::size_t size() const {
        return _value.size();
    }

    template<typename E = Expr, disable_if_u<std::remove_reference<E>::type::etl_fast> = detail::dummy>
    std::size_t size() const {
        return _value.size();
    }

    typename std::add_lvalue_reference<Expr>::type value(){
        return _value;
    }

    typename std::add_lvalue_reference<typename std::add_const<Expr>::type>::type value() const {
        return _value;
    }

    //Apply the expression

    decltype(auto) operator[](std::size_t i) const {
        return UnaryOp::apply(value()[i]);
    }
};

//{{{ Build binary expressions from two ETL expressions (vector,matrix,binary,unary)

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator-(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, minus_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator+(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, plus_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator*(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, mul_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator/(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, div_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<is_etl_expr<LE>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator%(const LE& lhs, const RE& rhs) -> binary_expr<typename LE::value_type, const LE&, mod_binary_op<typename LE::value_type>, const RE&> {
    return {lhs, rhs};
}

//}}}

//{{{ Mix scalars and ETL expressions (vector,matrix,binary,unary)

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator-(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, minus_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator-(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, minus_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator+(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, plus_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator+(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, plus_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator*(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, mul_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator*(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, mul_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator/(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, div_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator/(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, div_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<RE, typename LE::value_type>::value, is_etl_expr<LE>::value>::value> = detail::dummy>
auto operator%(const LE& lhs, RE rhs) -> binary_expr<typename LE::value_type, const LE&, mod_binary_op<typename LE::value_type>, scalar<typename LE::value_type>> {
    return {lhs, rhs};
}

template<typename LE, typename RE, enable_if_u<and_u<std::is_convertible<LE, typename RE::value_type>::value, is_etl_expr<RE>::value>::value> = detail::dummy>
auto operator%(LE lhs, const RE& rhs) -> binary_expr<typename RE::value_type, scalar<typename RE::value_type>, mod_binary_op<typename RE::value_type>, const RE&> {
    return {lhs, rhs};
}

//}}}

//{{{ Apply an unary expression on an ETL expression (vector,matrix,binary,unary)

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
auto abs(const E& value) -> unary_expr<typename E::value_type, const E&, abs_unary_op<typename E::value_type>> {
    return {value};
}

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
auto log(const E& value) -> unary_expr<typename E::value_type, const E&, log_unary_op<typename E::value_type>> {
    return {value};
}

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
auto sign(const E& value) -> unary_expr<typename E::value_type, const E&, sign_unary_op<typename E::value_type>> {
    return {value};
}

//}}}

//{{{ Apply a reduction on an ETL expression (vector,matrix,binary,unary)

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
typename E::value_type sum(const E& values){
    auto acc = static_cast<typename E::value_type>(0);

    for(std::size_t i = 0; i < values.size(); ++i){
        acc += values[i];
    }

    return acc;
}

template<typename E, enable_if_u<is_etl_expr<E>::value> = detail::dummy>
typename E::value_type mean(const E& values){
    return sum(values) / values.size();
}

//}}}

} //end of namespace etl

#endif
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_IMAGE_HPP
#define GCN_IMAGE_HPP

#include <string>

#include "guichan/platform.hpp"

namespace gcn
{
    class Color;
    class ImageLoader;

    /**
     * Holds an image. To be able to use this class you must first set an
     * ImageLoader in Image by calling
     * @code Image::setImageLoader(myImageLoader) @endcode
     * The function is static. If this is not done, the constructor taking a
     * filename will throw an exception. The ImageLoader you use must be
     * compatible with the Graphics object you use.
     *
     * EXAMPLE: If you use SDLGraphics you should use SDLImageLoader.
     *          Otherwise your program will crash in a most bizarre way.
     */
    class GCN_CORE_DECLSPEC Image
    {
    public:

        /**
         * Constructor.
         */
        Image();

        /**
         * Destructor.
         */
        virtual ~Image();

        /**
         * Loads an image by calling the Image class' ImageLoader.
         *
         * NOTE: The functions getPixel and putPixel are only guaranteed to work
         *       before an image has been converted to display format.
         *
         * @param filename the file to load.
         * @param convertToDisplayFormat true if the image should be converted
         *                               to display, false otherwise.
         */
        static Image* load(const std::string& filename, bool convertToDisplayFormat = true);

        /**
         * Gets the ImageLoader used for loading Images.
         *
         * @return the ImageLoader used for loading Images.
         * @see SDLImageLoader, AllegroImageLoader
         */
        static ImageLoader* getImageLoader();

        /**
         * Sets the ImageLoader to be used for loading images.
         *
         * IMPORTANT: The ImageLoader is static and MUST be set before loading
         *            images!
         *
         * @param imageLoader the ImageLoader to be used for loading images.
         * @see SDLImageLoader, AllegroImageLoader
         */
        static void setImageLoader(ImageLoader* imageLoader);

        /**
         * Frees an image.
         */
        virtual void free() = 0;

        /**
         * Gets the width of the Image.
         *
         * @return the image width
         */
        virtual int getWidth() const = 0;

        /**
         * Gets the height of the Image.
         *
         * @return the image height
         */
        virtual int getHeight() const = 0;

        /**
         * Gets the color of a pixel at coordinate (x, y) in the image.
         *
         * IMPORTANT: Only guaranteed to work before the image has been
         *            converted to display format.
         *
         * @param x the x coordinate.
         * @param y the y coordinate.
         * @return the color of the pixel.
         */
        virtual Color getPixel(int x, int y) = 0;

        /**
         * Puts a pixel with a certain color at coordinate (x, y).
         *
         * @param x the x coordinate.
         * @param y the y coordinate.
         * @param color the color of the pixel to put.
         */
        virtual void putPixel(int x, int y, const Color& color) = 0;

        /**
         * Converts the image, if possible, to display format.
         *
         * IMPORTANT: Only guaranteed to work before the image has been
         *            converted to display format.
         */
        virtual void convertToDisplayFormat() = 0;

    protected:
        static ImageLoader* mImageLoader;
    };
}

#endif // end GCN_IMAGE_HPP
<commit_msg>Documentation has been improved.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_IMAGE_HPP
#define GCN_IMAGE_HPP

#include <string>

#include "guichan/platform.hpp"

namespace gcn
{
    class Color;
    class ImageLoader;

    /**
     * Holds an image. To be able to use this class you must first set an
     * ImageLoader in Image by calling
     * @code Image::setImageLoader(myImageLoader) @endcode
     * The function is static. If this is not done, the constructor taking a
     * filename will throw an exception. The ImageLoader you use must be
     * compatible with the Graphics object you use.
     *
     * EXAMPLE: If you use SDLGraphics you should use SDLImageLoader.
     *          Otherwise your program will crash in a most bizarre way.
     */
    class GCN_CORE_DECLSPEC Image
    {
    public:

        /**
         * Constructor.
         */
        Image();

        /**
         * Destructor.
         */
        virtual ~Image();

        /**
         * Loads an image by calling the Image class' ImageLoader. With most image loaders
         * you can assume a newly instantiated image is return which must be deleted in
         * order to avoid a memory leak.
         *
         * NOTE: The functions getPixel and putPixel are only guaranteed to work
         *       before an image has been converted to display format.
         *
         * @param filename the file to load.
         * @param convertToDisplayFormat true if the image should be converted
         *                               to display, false otherwise.
         */
        static Image* load(const std::string& filename, bool convertToDisplayFormat = true);

        /**
         * Gets the ImageLoader used for loading Images.
         *
         * @return the ImageLoader used for loading Images.
         * @see SDLImageLoader, AllegroImageLoader
         */
        static ImageLoader* getImageLoader();

        /**
         * Sets the ImageLoader to be used for loading images.
         *
         * IMPORTANT: The ImageLoader is static and MUST be set before loading
         *            images!
         *
         * @param imageLoader the ImageLoader to be used for loading images.
         * @see SDLImageLoader, AllegroImageLoader
         */
        static void setImageLoader(ImageLoader* imageLoader);

        /**
         * Frees an image.
         */
        virtual void free() = 0;

        /**
         * Gets the width of the Image.
         *
         * @return the image width
         */
        virtual int getWidth() const = 0;

        /**
         * Gets the height of the Image.
         *
         * @return the image height
         */
        virtual int getHeight() const = 0;

        /**
         * Gets the color of a pixel at coordinate (x, y) in the image.
         *
         * IMPORTANT: Only guaranteed to work before the image has been
         *            converted to display format.
         *
         * @param x the x coordinate.
         * @param y the y coordinate.
         * @return the color of the pixel.
         */
        virtual Color getPixel(int x, int y) = 0;

        /**
         * Puts a pixel with a certain color at coordinate (x, y).
         *
         * @param x the x coordinate.
         * @param y the y coordinate.
         * @param color the color of the pixel to put.
         */
        virtual void putPixel(int x, int y, const Color& color) = 0;

        /**
         * Converts the image, if possible, to display format.
         *
         * IMPORTANT: Only guaranteed to work before the image has been
         *            converted to display format.
         */
        virtual void convertToDisplayFormat() = 0;

    protected:
        static ImageLoader* mImageLoader;
    };
}

#endif // end GCN_IMAGE_HPP
<|endoftext|>


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

class Solution {
public:
    string findLongestWord(string s, vector<string>& d) {
        sort(d.begin(), d.end(),
             [](const string& a, const string&b) {
                return a.length() != b.length() ? a.length() > b.length() : a < b;
             });

        for (const auto& word : d) {
            int i = 0;
            for (const auto& c : s) {
                if (i < word.length() && word[i] == c) {
                    ++i;
                }
            }
            if (i == word.length()) {
                return word;
            }
        }
        return "";
    }
};
<commit_msg>Update longest-word-in-dictionary-through-deleting.cpp<commit_after>// Time:  O((d * l) * logd), l is the average length of words
// Space: O(1)

class Solution {
public:
    string findLongestWord(string s, vector<string>& d) {
        sort(d.begin(), d.end(),
             [](const string& a, const string&b) {
                return a.length() != b.length() ? a.length() > b.length() : a < b;
             });

        for (const auto& word : d) {
            int i = 0;
            for (const auto& c : s) {
                if (i < word.length() && word[i] == c) {
                    ++i;
                }
            }
            if (i == word.length()) {
                return word;
            }
        }
        return "";
    }
};
<|endoftext|>


<commit_before>/*****************************************************************************
 * Licensed to Qualys, Inc. (QUALYS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * QUALYS licenses this file to You 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.
 ****************************************************************************/

/**
 * @file
 * @brief IronBee++ — All IronBee++ Headers
 *
 * @author Christopher Alfeld <calfeld@qualys.com>
 */

#ifndef __IBPP__ALL__
#define __IBPP__ALL__

#include <include/ironbeepp/byte_string.hpp>
#include <include/ironbeepp/clock.hpp>
#include <include/ironbeepp/common_semantics.hpp>
#include <include/ironbeepp/configuration_directives.hpp>
#include <include/ironbeepp/configuration_map.hpp>
#include <include/ironbeepp/configuration_parser.hpp>
#include <include/ironbeepp/connection.hpp>
#include <include/ironbeepp/connection_data.hpp>
#include <include/ironbeepp/context.hpp>
#include <include/ironbeepp/engine.hpp>
#include <include/ironbeepp/exception.hpp>
#include <include/ironbeepp/field.hpp>
#include <include/ironbeepp/hooks.hpp>
#include <include/ironbeepp/internal>
#include <include/ironbeepp/internal/catch.hpp>
#include <include/ironbeepp/internal/data.hpp>
#include <include/ironbeepp/internal/throw.hpp>
#include <include/ironbeepp/ironbee.hpp>
#include <include/ironbeepp/list.hpp>
#include <include/ironbeepp/memory_pool.hpp>
#include <include/ironbeepp/module.hpp>
#include <include/ironbeepp/module_bootstrap.hpp>
#include <include/ironbeepp/module_delegate.hpp>
#include <include/ironbeepp/notifier.hpp>
#include <include/ironbeepp/parsed_name_value.hpp>
#include <include/ironbeepp/parsed_request_line.hpp>
#include <include/ironbeepp/parsed_response_line.hpp>
#include <include/ironbeepp/server.hpp>
#include <include/ironbeepp/site.hpp>
#include <include/ironbeepp/transaction.hpp>
#include <include/ironbeepp/transaction_data.hpp>

#endif
<commit_msg>IronBee++/all.hpp: Fixed issue with all.hpp<commit_after>/*****************************************************************************
 * Licensed to Qualys, Inc. (QUALYS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * QUALYS licenses this file to You 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.
 ****************************************************************************/

/**
 * @file
 * @brief IronBee++ — All IronBee++ Headers
 *
 * @author Christopher Alfeld <calfeld@qualys.com>
 */

#ifndef __IBPP__ALL__
#define __IBPP__ALL__

#include <include/ironbeepp/byte_string.hpp>
#include <include/ironbeepp/clock.hpp>
#include <include/ironbeepp/common_semantics.hpp>
#include <include/ironbeepp/configuration_directives.hpp>
#include <include/ironbeepp/configuration_map.hpp>
#include <include/ironbeepp/configuration_parser.hpp>
#include <include/ironbeepp/connection.hpp>
#include <include/ironbeepp/connection_data.hpp>
#include <include/ironbeepp/context.hpp>
#include <include/ironbeepp/engine.hpp>
#include <include/ironbeepp/exception.hpp>
#include <include/ironbeepp/field.hpp>
#include <include/ironbeepp/hooks.hpp>
#include <include/ironbeepp/internal/catch.hpp>
#include <include/ironbeepp/internal/data.hpp>
#include <include/ironbeepp/internal/throw.hpp>
#include <include/ironbeepp/ironbee.hpp>
#include <include/ironbeepp/list.hpp>
#include <include/ironbeepp/memory_pool.hpp>
#include <include/ironbeepp/module.hpp>
#include <include/ironbeepp/module_bootstrap.hpp>
#include <include/ironbeepp/module_delegate.hpp>
#include <include/ironbeepp/notifier.hpp>
#include <include/ironbeepp/parsed_name_value.hpp>
#include <include/ironbeepp/parsed_request_line.hpp>
#include <include/ironbeepp/parsed_response_line.hpp>
#include <include/ironbeepp/server.hpp>
#include <include/ironbeepp/site.hpp>
#include <include/ironbeepp/transaction.hpp>
#include <include/ironbeepp/transaction_data.hpp>

#endif
<|endoftext|>


<commit_before>/*
 *  shellprocess.cpp  -  execute a shell process
 *  Program:  kalarm
 *  Copyright © 2004,2005,2007,2008 by David Jarvie <djarvie@kde.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU 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 General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <stdlib.h>
#include <qglobal.h>
#include <kde_file.h>
#include <kapplication.h>
#include <klocale.h>
#include <kdebug.h>
#include <kauthorized.h>

#include "shellprocess.moc"

QByteArray ShellProcess::mShellName;
QByteArray ShellProcess::mShellPath;
bool       ShellProcess::mInitialised = false;
bool       ShellProcess::mAuthorised  = false;

ShellProcess::ShellProcess(const QString& command)
	: mCommand(command),
	  mStdinBytes(0),
	  mStatus(INACTIVE),
	  mStdinExit(false)
{
}

/******************************************************************************
* Execute a command.
*/
bool ShellProcess::start(OpenMode openMode)
{
	if (!authorised())
	{
		mStatus = UNAUTHORISED;
		return false;
	}
	connect(this, SIGNAL(bytesWritten(qint64)), SLOT(writtenStdin(qint64)));
	connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(slotExited(int, QProcess::ExitStatus)));
	connect(this, SIGNAL(readyReadStandardOutput()), SLOT(stdoutReady()));
	connect(this, SIGNAL(readyReadStandardError()), SLOT(stderrReady()));
	QStringList args;
	args << "-c" << mCommand;
	QProcess::start(shellName(), args, openMode);
	if (!waitForStarted())
	{
		mStatus = START_FAIL;
		return false;
	}
	mStatus = RUNNING;
	return true;
}

/******************************************************************************
* Called when a shell process execution completes.
* Interprets the exit status according to which shell was called, and emits
* a shellExited() signal.
*/
void ShellProcess::slotExited(int exitCode, QProcess::ExitStatus exitStatus)
{
	kDebug() << exitCode << "," << exitStatus;
	mStdinQueue.clear();
	mStatus = SUCCESS;
	mExitCode = exitCode;
	if (exitStatus != NormalExit)
	{
		kWarning(5950) << mCommand << ":" << mShellName << ": crashed/killed";
		mStatus = DIED;
	}
	else
	{
		// Some shells report if the command couldn't be found, or is not executable
		if ((mShellName == "bash"  &&  (exitCode == 126 || exitCode == 127))
		||  (mShellName == "ksh"  &&  exitCode == 127))
		{
			kWarning(5950) << mCommand << ":" << mShellName << ": not found or not executable";
			mStatus = NOT_FOUND;
		}
	}
	emit shellExited(this);
}

/******************************************************************************
* Write a string to STDIN.
*/
void ShellProcess::writeStdin(const char* buffer, int bufflen)
{
	QByteArray scopy(buffer, bufflen);    // construct a deep copy
	bool doWrite = mStdinQueue.isEmpty();
	mStdinQueue.enqueue(scopy);
	if (doWrite)
	{
		mStdinBytes = mStdinQueue.head().length();
		write(mStdinQueue.head());
	}
}

/******************************************************************************
* Called when output to STDIN completes.
* Send the next queued output, if any.
* Note that buffers written to STDIN must not be freed until the bytesWritten()
* signal has been processed.
*/
void ShellProcess::writtenStdin(qint64 bytes)
{
	mStdinBytes -= bytes;
	if (mStdinBytes > 0)
		return;   // buffer has only been partially written so far
	if (!mStdinQueue.isEmpty())
		mStdinQueue.dequeue();   // free the buffer which has now been written
	if (!mStdinQueue.isEmpty())
	{
		mStdinBytes = mStdinQueue.head().length();
		write(mStdinQueue.head());
	}
	else if (mStdinExit)
		kill();
}

/******************************************************************************
* Tell the process to exit once all STDIN strings have been written.
*/
void ShellProcess::stdinExit()
{
	if (mStdinQueue.isEmpty())
		kill();
	else
		mStdinExit = true;
}

/******************************************************************************
* Return the error message corresponding to the command exit status.
* Reply = null string if not yet exited, or if command successful.
*/
QString ShellProcess::errorMessage() const
{
	switch (mStatus)
	{
		case UNAUTHORISED:
			return i18nc("@info", "Failed to execute command (shell access not authorized)");
		case START_FAIL:
		case NOT_FOUND:
			return i18nc("@info", "Failed to execute command");
		case DIED:
			return i18nc("@info", "Command execution error");
		case SUCCESS:
			if (mExitCode)
				return i18nc("@info", "Command exit code: %1", mExitCode);
			// Fall through to INACTIVE
		case INACTIVE:
		case RUNNING:
		default:
			return QString();
	}
}

/******************************************************************************
* Determine which shell to use.
* Don't use the KProcess default shell, since we need to know which shell is
* used in order to decide what its exit code means.
*/
const QByteArray& ShellProcess::shellPath()
{
	if (mShellPath.isEmpty())
	{
		// Get the path to the shell
		mShellPath = "/bin/sh";
		QByteArray envshell = qgetenv("SHELL").trimmed();
		if (!envshell.isEmpty())
		{
			struct stat fileinfo;
			if (KDE_stat(envshell.data(), &fileinfo) != -1  // ensure file exists
			&&  !S_ISDIR(fileinfo.st_mode)              // and it's not a directory
			&&  !S_ISCHR(fileinfo.st_mode)              // and it's not a character device
			&&  !S_ISBLK(fileinfo.st_mode)              // and it's not a block device
#ifdef S_ISSOCK
			&&  !S_ISSOCK(fileinfo.st_mode)             // and it's not a socket
#endif
			&&  !S_ISFIFO(fileinfo.st_mode)             // and it's not a fifo
			&&  !access(envshell.data(), X_OK))         // and it's executable
				mShellPath = envshell;
		}

		// Get the shell filename with the path stripped off
		int i = mShellPath.lastIndexOf('/');
		if (i >= 0)
			mShellName = mShellPath.mid(i + 1);
		else
			mShellName = mShellPath;
	}
	return mShellPath;
}

/******************************************************************************
* Check whether shell commands are allowed at all.
*/
bool ShellProcess::authorised()
{
	if (!mInitialised)
	{
		mAuthorised = KAuthorized::authorizeKAction("shell_access");
		mInitialised = true;
	}
	return mAuthorised;
}
<commit_msg>Krazy<commit_after>/*
 *  shellprocess.cpp  -  execute a shell process
 *  Program:  kalarm
 *  Copyright © 2004,2005,2007,2008 by David Jarvie <djarvie@kde.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU 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 General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <stdlib.h>
#include <qglobal.h>
#include <kde_file.h>
#include <kapplication.h>
#include <klocale.h>
#include <kdebug.h>
#include <kauthorized.h>

#include "shellprocess.moc"

QByteArray ShellProcess::mShellName;
QByteArray ShellProcess::mShellPath;
bool       ShellProcess::mInitialised = false;
bool       ShellProcess::mAuthorised  = false;

ShellProcess::ShellProcess(const QString& command)
	: mCommand(command),
	  mStdinBytes(0),
	  mStatus(INACTIVE),
	  mStdinExit(false)
{
}

/******************************************************************************
* Execute a command.
*/
bool ShellProcess::start(OpenMode openMode)
{
	if (!authorised())
	{
		mStatus = UNAUTHORISED;
		return false;
	}
	connect(this, SIGNAL(bytesWritten(qint64)), SLOT(writtenStdin(qint64)));
	connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(slotExited(int, QProcess::ExitStatus)));
	connect(this, SIGNAL(readyReadStandardOutput()), SLOT(stdoutReady()));
	connect(this, SIGNAL(readyReadStandardError()), SLOT(stderrReady()));
	QStringList args;
	args << "-c" << mCommand;
	QProcess::start(shellName(), args, openMode);
	if (!waitForStarted())
	{
		mStatus = START_FAIL;
		return false;
	}
	mStatus = RUNNING;
	return true;
}

/******************************************************************************
* Called when a shell process execution completes.
* Interprets the exit status according to which shell was called, and emits
* a shellExited() signal.
*/
void ShellProcess::slotExited(int exitCode, QProcess::ExitStatus exitStatus)
{
	kDebug() << exitCode << "," << exitStatus;
	mStdinQueue.clear();
	mStatus = SUCCESS;
	mExitCode = exitCode;
	if (exitStatus != NormalExit)
	{
		kWarning(5950) << mCommand << ":" << mShellName << ": crashed/killed";
		mStatus = DIED;
	}
	else
	{
		// Some shells report if the command couldn't be found, or is not executable
		if ((mShellName == "bash"  &&  (exitCode == 126 || exitCode == 127))
		||  (mShellName == "ksh"  &&  exitCode == 127))
		{
			kWarning(5950) << mCommand << ":" << mShellName << ": not found or not executable";
			mStatus = NOT_FOUND;
		}
	}
	emit shellExited(this);
}

/******************************************************************************
* Write a string to STDIN.
*/
void ShellProcess::writeStdin(const char* buffer, int bufflen)
{
	QByteArray scopy(buffer, bufflen);    // construct a deep copy
	bool doWrite = mStdinQueue.isEmpty();
	mStdinQueue.enqueue(scopy);
	if (doWrite)
	{
		mStdinBytes = mStdinQueue.head().length();
		write(mStdinQueue.head());
	}
}

/******************************************************************************
* Called when output to STDIN completes.
* Send the next queued output, if any.
* Note that buffers written to STDIN must not be freed until the bytesWritten()
* signal has been processed.
*/
void ShellProcess::writtenStdin(qint64 bytes)
{
	mStdinBytes -= bytes;
	if (mStdinBytes > 0)
		return;   // buffer has only been partially written so far
	if (!mStdinQueue.isEmpty())
		mStdinQueue.dequeue();   // free the buffer which has now been written
	if (!mStdinQueue.isEmpty())
	{
		mStdinBytes = mStdinQueue.head().length();
		write(mStdinQueue.head());
	}
	else if (mStdinExit)
		kill();
}

/******************************************************************************
* Tell the process to exit once all STDIN strings have been written.
*/
void ShellProcess::stdinExit()
{
	if (mStdinQueue.isEmpty())
		kill();
	else
		mStdinExit = true;
}

/******************************************************************************
* Return the error message corresponding to the command exit status.
* Reply = null string if not yet exited, or if command successful.
*/
QString ShellProcess::errorMessage() const
{
	switch (mStatus)
	{
		case UNAUTHORISED:
			return i18nc("@info", "Failed to execute command (shell access not authorized)");
		case START_FAIL:
		case NOT_FOUND:
			return i18nc("@info", "Failed to execute command");
		case DIED:
			return i18nc("@info", "Command execution error");
		case SUCCESS:
			if (mExitCode)
				return i18nc("@info", "Command exit code: %1", mExitCode);
			// Fall through to INACTIVE
		case INACTIVE:
		case RUNNING:
		default:
			return QString();
	}
}

/******************************************************************************
* Determine which shell to use.
* Don't use the KProcess default shell, since we need to know which shell is
* used in order to decide what its exit code means.
*/
const QByteArray& ShellProcess::shellPath()
{
	if (mShellPath.isEmpty())
	{
		// Get the path to the shell
		mShellPath = "/bin/sh";
		QByteArray envshell = qgetenv("SHELL").trimmed();
		if (!envshell.isEmpty())
		{
			KDE_struct_stat fileinfo;
			if (KDE_stat(envshell.data(), &fileinfo) != -1  // ensure file exists
			&&  !S_ISDIR(fileinfo.st_mode)              // and it's not a directory
			&&  !S_ISCHR(fileinfo.st_mode)              // and it's not a character device
			&&  !S_ISBLK(fileinfo.st_mode)              // and it's not a block device
#ifdef S_ISSOCK
			&&  !S_ISSOCK(fileinfo.st_mode)             // and it's not a socket
#endif
			&&  !S_ISFIFO(fileinfo.st_mode)             // and it's not a fifo
			&&  !access(envshell.data(), X_OK))         // and it's executable
				mShellPath = envshell;
		}

		// Get the shell filename with the path stripped off
		int i = mShellPath.lastIndexOf('/');
		if (i >= 0)
			mShellName = mShellPath.mid(i + 1);
		else
			mShellName = mShellPath;
	}
	return mShellPath;
}

/******************************************************************************
* Check whether shell commands are allowed at all.
*/
bool ShellProcess::authorised()
{
	if (!mInitialised)
	{
		mAuthorised = KAuthorized::authorizeKAction("shell_access");
		mInitialised = true;
	}
	return mAuthorised;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_dmi_clear_firs.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_dmi_clear_firs.C
/// @brief Clears I/O Firs
///-----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 2
/// *HWP Consumed by      : FSP:HB
///-----------------------------------------------------------------------------
///
/// @verbatim
/// High-level procedure flow:
///
/// Clears I/O Xbus FIRs on the PHY Rx/Tx.
///
/// Clocks must be running.
///
/// @endverbatim
///----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//  Includes
//-----------------------------------------------------------------------------
#include <p9_io_dmi_clear_firs.H>
#include <p9_io_scom.H>
#include <p9_io_regs.H>

//-----------------------------------------------------------------------------
//  Definitions
//-----------------------------------------------------------------------------
fapi2::ReturnCode io_dmi_proc_rx_fir_reset(const DMI_PROC_TGT& i_tgt);
fapi2::ReturnCode io_dmi_proc_tx_fir_reset(const DMI_PROC_TGT& i_tgt);

fapi2::ReturnCode io_dmi_cn_rx_fir_reset(const DMI_CN_TGT& i_tgt);
fapi2::ReturnCode io_dmi_cn_tx_fir_reset(const DMI_CN_TGT& i_tgt);

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI(EDI+) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_tgt         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_proc_clear_firs(const DMI_PROC_TGT& i_tgt)
{
    FAPI_IMP("I/O Start DMI Proc Clear FIRs");

    FAPI_TRY(io_dmi_proc_tx_fir_reset(i_tgt), "Tx Reset Failed");

    FAPI_TRY(io_dmi_proc_rx_fir_reset(i_tgt), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Proc Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI+ DMI
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_proc_rx_fir_reset(const DMI_PROC_TGT& i_tgt)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI+ DMI
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_proc_tx_fir_reset(const DMI_PROC_TGT& i_tgt)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI Centaur(EDI) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_tgt         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_cn_clear_firs(const DMI_CN_TGT& i_tgt)
{
    FAPI_IMP("I/O Start DMI Proc Clear FIRs");

    FAPI_TRY(io_dmi_cn_tx_fir_reset(i_tgt), "Tx Reset Failed");

    FAPI_TRY(io_dmi_cn_rx_fir_reset(i_tgt), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Proc Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI DMI Centaur
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_cn_rx_fir_reset(const DMI_CN_TGT& i_tgt)
{
    const uint8_t GRP0 = 0;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI DMI Centaur
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_cn_tx_fir_reset(const DMI_CN_TGT& i_tgt)
{
    const uint8_t GRP0 = 0;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}
<commit_msg>I/O Metadata Cleanup<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_dmi_clear_firs.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_dmi_clear_firs.C
/// @brief Clears I/O Firs
///-----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 3
/// *HWP Consumed by      : FSP:HB
///-----------------------------------------------------------------------------
///
/// @verbatim
/// High-level procedure flow:
///
/// Clears I/O Xbus FIRs on the PHY Rx/Tx.
///
/// Clocks must be running.
///
/// @endverbatim
///----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//  Includes
//-----------------------------------------------------------------------------
#include <p9_io_dmi_clear_firs.H>
#include <p9_io_scom.H>
#include <p9_io_regs.H>

//-----------------------------------------------------------------------------
//  Definitions
//-----------------------------------------------------------------------------
fapi2::ReturnCode io_dmi_proc_rx_fir_reset(const DMI_PROC_TGT& i_tgt);
fapi2::ReturnCode io_dmi_proc_tx_fir_reset(const DMI_PROC_TGT& i_tgt);

fapi2::ReturnCode io_dmi_cn_rx_fir_reset(const DMI_CN_TGT& i_tgt);
fapi2::ReturnCode io_dmi_cn_tx_fir_reset(const DMI_CN_TGT& i_tgt);

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI(EDI+) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_tgt         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_proc_clear_firs(const DMI_PROC_TGT& i_tgt)
{
    FAPI_IMP("I/O Start DMI Proc Clear FIRs");

    FAPI_TRY(io_dmi_proc_tx_fir_reset(i_tgt), "Tx Reset Failed");

    FAPI_TRY(io_dmi_proc_rx_fir_reset(i_tgt), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Proc Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI+ DMI
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_proc_rx_fir_reset(const DMI_PROC_TGT& i_tgt)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI+ DMI
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_proc_tx_fir_reset(const DMI_PROC_TGT& i_tgt)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI Centaur(EDI) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_tgt         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_cn_clear_firs(const DMI_CN_TGT& i_tgt)
{
    FAPI_IMP("I/O Start DMI Proc Clear FIRs");

    FAPI_TRY(io_dmi_cn_tx_fir_reset(i_tgt), "Tx Reset Failed");

    FAPI_TRY(io_dmi_cn_rx_fir_reset(i_tgt), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Proc Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI DMI Centaur
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_cn_rx_fir_reset(const DMI_CN_TGT& i_tgt)
{
    const uint8_t GRP0 = 0;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI DMI Centaur
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_cn_tx_fir_reset(const DMI_CN_TGT& i_tgt)
{
    const uint8_t GRP0 = 0;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_web_request.h"

#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "base/files/file_path.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "v8/include/v8.h"

using content::BrowserThread;

namespace mate {

template<>
struct Converter<URLPattern> {
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
                     URLPattern* out) {
    std::string pattern;
    if (!ConvertFromV8(isolate, val, &pattern))
      return false;
    return out->Parse(pattern) == URLPattern::PARSE_SUCCESS;
  }
};

template<>
struct Converter<net::URLFetcher::RequestType> {
  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
                     net::URLFetcher::RequestType* out) {
    std::string type = base::ToLowerASCII(V8ToString(val));
    if (type == "get")
      *out = net::URLFetcher::RequestType::GET;
    else if (type == "post")
      *out = net::URLFetcher::RequestType::POST;
    else if (type == "head")
      *out = net::URLFetcher::RequestType::HEAD;
    else if (type == "delete_request")
      *out = net::URLFetcher::RequestType::DELETE_REQUEST;
    else if (type == "put")
      *out = net::URLFetcher::RequestType::PUT;
    else if (type == "patch")
      *out = net::URLFetcher::RequestType::PATCH;
    return true;
  }
};

}  // namespace mate

namespace atom {

namespace api {

WebRequest::WebRequest(v8::Isolate* isolate,
                       AtomBrowserContext* browser_context)
    : browser_context_(browser_context) {
  Init(isolate);
}

WebRequest::~WebRequest() {
  net::URLFetcher::CancelAll();
}

void WebRequest::OnURLFetchComplete(
    const net::URLFetcher* source) {
  mate::Dictionary response = mate::Dictionary::CreateEmpty(isolate());
  int response_code = source->GetResponseCode();
  response.Set("statusCode", response_code);

  std::string body;
  v8::Local<v8::Value> err = v8::Null(isolate());
  if (response_code == net::URLFetcher::ResponseCode::RESPONSE_CODE_INVALID) {
    base::DictionaryValue dict;
    dict.SetInteger("errorCode", source->GetStatus().error());
    err = mate::ConvertToV8(isolate(), dict);
  } else {
    response.Set("headers", source->GetResponseHeaders());
    source->GetResponseAsString(&body);
  }

  FetchCallback callback = fetchers_[source];
  // error, response, body
  const uint8_t* data = reinterpret_cast<const uint8_t*>(body.c_str());
  callback.Run(err, response, v8::String::NewFromOneByte(isolate(),
      data, v8::NewStringType::kNormal, body.length()).ToLocalChecked());
  fetchers_.erase(source);
}

void WebRequest::Fetch(mate::Arguments* args) {
  GURL url;
  if (!args->GetNext(&url)) {
    args->ThrowError("invalid url parameter");
    return;
  }

  net::URLFetcher::RequestType request_type = net::URLFetcher::RequestType::GET;
  net::HttpRequestHeaders headers;
  base::FilePath path;
  std::string payload;
  std::string payload_content_type;
  mate::Dictionary dict;
  if (args->GetNext(&dict)) {
    dict.Get("method", &request_type);
    dict.Get("headers", &headers);
    dict.Get("path", &path);
    if (dict.Get("payload", &payload)) {
      if (!dict.Get("payload_content_type", &payload_content_type)) {
        args->ThrowError("payload_content_type is required for payload");
      }
    }
  }

  FetchCallback callback;
  if (!args->GetNext(&callback)) {
    args->ThrowError("invalid callback parameter");
    return;
  }

  net::URLFetcher* fetcher = net::URLFetcher::Create(url, request_type, this)
      .release();
  fetcher->SetRequestContext(browser_context_->GetRequestContext());
  if (!payload.empty())
    fetcher->SetUploadData(payload_content_type, payload);
  if (!headers.IsEmpty())
    fetcher->SetExtraRequestHeaders(headers.ToString());
  if (!path.empty())
    fetcher->SaveResponseToFileAtPath(
        path,
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
  fetcher->Start();
  fetchers_[fetcher] = FetchCallback(callback);
}

template<AtomNetworkDelegate::SimpleEvent type>
void WebRequest::SetSimpleListener(mate::Arguments* args) {
  SetListener<AtomNetworkDelegate::SimpleListener>(
      &AtomNetworkDelegate::SetSimpleListenerInIO, type, args);
}

template<AtomNetworkDelegate::ResponseEvent type>
void WebRequest::SetResponseListener(mate::Arguments* args) {
  SetListener<AtomNetworkDelegate::ResponseListener>(
      &AtomNetworkDelegate::SetResponseListenerInIO, type, args);
}

template<typename Listener, typename Method, typename Event>
void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
  // { urls }.
  URLPatterns patterns;
  mate::Dictionary dict;
  args->GetNext(&dict) && dict.Get("urls", &patterns);

  // Function or null.
  v8::Local<v8::Value> value;
  Listener listener;
  if (!args->GetNext(&listener) &&
      !(args->GetNext(&value) && value->IsNull())) {
    args->ThrowError("Must pass null or a Function");
    return;
  }

  auto delegate = browser_context_->network_delegate();
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                          base::Bind(method, base::Unretained(delegate), type,
                                     patterns, listener));
}

// static
mate::Handle<WebRequest> WebRequest::Create(
    v8::Isolate* isolate,
    AtomBrowserContext* browser_context) {
  return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context));
}

// static
void WebRequest::BuildPrototype(v8::Isolate* isolate,
                                v8::Local<v8::FunctionTemplate> prototype) {
  prototype->SetClassName(mate::StringToV8(isolate, "WebRequest"));
  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
      .SetMethod("onBeforeRequest",
                 &WebRequest::SetResponseListener<
                    AtomNetworkDelegate::kOnBeforeRequest>)
      .SetMethod("onBeforeSendHeaders",
                 &WebRequest::SetResponseListener<
                    AtomNetworkDelegate::kOnBeforeSendHeaders>)
      .SetMethod("onHeadersReceived",
                 &WebRequest::SetResponseListener<
                    AtomNetworkDelegate::kOnHeadersReceived>)
      .SetMethod("onSendHeaders",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnSendHeaders>)
      .SetMethod("onBeforeRedirect",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnBeforeRedirect>)
      .SetMethod("onResponseStarted",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnResponseStarted>)
      .SetMethod("onCompleted",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnCompleted>)
      .SetMethod("onErrorOccurred",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnErrorOccurred>)
      .SetMethod("fetch",
                 &WebRequest::Fetch);
}

}  // namespace api

}  // namespace atom
<commit_msg>let `BrowserProcessSubThread` handle cancelling fetches auditors: @bbondy<commit_after>// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_web_request.h"

#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "base/files/file_path.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "v8/include/v8.h"

using content::BrowserThread;

namespace mate {

template<>
struct Converter<URLPattern> {
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
                     URLPattern* out) {
    std::string pattern;
    if (!ConvertFromV8(isolate, val, &pattern))
      return false;
    return out->Parse(pattern) == URLPattern::PARSE_SUCCESS;
  }
};

template<>
struct Converter<net::URLFetcher::RequestType> {
  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
                     net::URLFetcher::RequestType* out) {
    std::string type = base::ToLowerASCII(V8ToString(val));
    if (type == "get")
      *out = net::URLFetcher::RequestType::GET;
    else if (type == "post")
      *out = net::URLFetcher::RequestType::POST;
    else if (type == "head")
      *out = net::URLFetcher::RequestType::HEAD;
    else if (type == "delete_request")
      *out = net::URLFetcher::RequestType::DELETE_REQUEST;
    else if (type == "put")
      *out = net::URLFetcher::RequestType::PUT;
    else if (type == "patch")
      *out = net::URLFetcher::RequestType::PATCH;
    return true;
  }
};

}  // namespace mate

namespace atom {

namespace api {

WebRequest::WebRequest(v8::Isolate* isolate,
                       AtomBrowserContext* browser_context)
    : browser_context_(browser_context) {
  Init(isolate);
}

WebRequest::~WebRequest() {
  fetchers_.clear();
}

void WebRequest::OnURLFetchComplete(
    const net::URLFetcher* source) {
  FetchCallback callback = fetchers_[source];
  fetchers_.erase(source);

  mate::Dictionary response = mate::Dictionary::CreateEmpty(isolate());
  int response_code = source->GetResponseCode();
  response.Set("statusCode", response_code);

  std::string body;
  v8::Local<v8::Value> err = v8::Null(isolate());
  if (response_code == net::URLFetcher::ResponseCode::RESPONSE_CODE_INVALID ||
      !source->GetStatus().is_success()) {
    base::DictionaryValue dict;
    dict.SetInteger("errorCode", source->GetStatus().error());
    err = mate::ConvertToV8(isolate(), dict);
  } else {
    response.Set("headers", source->GetResponseHeaders());
    source->GetResponseAsString(&body);
  }

  // error, response, body
  const uint8_t* data = reinterpret_cast<const uint8_t*>(body.c_str());
  callback.Run(err, response, v8::String::NewFromOneByte(isolate(),
      data, v8::NewStringType::kNormal, body.length()).ToLocalChecked());
}

void WebRequest::Fetch(mate::Arguments* args) {
  GURL url;
  if (!args->GetNext(&url)) {
    args->ThrowError("invalid url parameter");
    return;
  }

  net::URLFetcher::RequestType request_type = net::URLFetcher::RequestType::GET;
  net::HttpRequestHeaders headers;
  base::FilePath path;
  std::string payload;
  std::string payload_content_type;
  mate::Dictionary dict;
  if (args->GetNext(&dict)) {
    dict.Get("method", &request_type);
    dict.Get("headers", &headers);
    dict.Get("path", &path);
    if (dict.Get("payload", &payload)) {
      if (!dict.Get("payload_content_type", &payload_content_type)) {
        args->ThrowError("payload_content_type is required for payload");
      }
    }
  }

  FetchCallback callback;
  if (!args->GetNext(&callback)) {
    args->ThrowError("invalid callback parameter");
    return;
  }

  net::URLFetcher* fetcher = net::URLFetcher::Create(url, request_type, this)
      .release();
  fetcher->SetRequestContext(browser_context_->GetRequestContext());
  if (!payload.empty())
    fetcher->SetUploadData(payload_content_type, payload);
  if (!headers.IsEmpty())
    fetcher->SetExtraRequestHeaders(headers.ToString());
  if (!path.empty())
    fetcher->SaveResponseToFileAtPath(
        path,
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
  fetcher->Start();
  fetchers_[fetcher] = FetchCallback(callback);
}

template<AtomNetworkDelegate::SimpleEvent type>
void WebRequest::SetSimpleListener(mate::Arguments* args) {
  SetListener<AtomNetworkDelegate::SimpleListener>(
      &AtomNetworkDelegate::SetSimpleListenerInIO, type, args);
}

template<AtomNetworkDelegate::ResponseEvent type>
void WebRequest::SetResponseListener(mate::Arguments* args) {
  SetListener<AtomNetworkDelegate::ResponseListener>(
      &AtomNetworkDelegate::SetResponseListenerInIO, type, args);
}

template<typename Listener, typename Method, typename Event>
void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
  // { urls }.
  URLPatterns patterns;
  mate::Dictionary dict;
  args->GetNext(&dict) && dict.Get("urls", &patterns);

  // Function or null.
  v8::Local<v8::Value> value;
  Listener listener;
  if (!args->GetNext(&listener) &&
      !(args->GetNext(&value) && value->IsNull())) {
    args->ThrowError("Must pass null or a Function");
    return;
  }

  auto delegate = browser_context_->network_delegate();
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                          base::Bind(method, base::Unretained(delegate), type,
                                     patterns, listener));
}

// static
mate::Handle<WebRequest> WebRequest::Create(
    v8::Isolate* isolate,
    AtomBrowserContext* browser_context) {
  return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context));
}

// static
void WebRequest::BuildPrototype(v8::Isolate* isolate,
                                v8::Local<v8::FunctionTemplate> prototype) {
  prototype->SetClassName(mate::StringToV8(isolate, "WebRequest"));
  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
      .SetMethod("onBeforeRequest",
                 &WebRequest::SetResponseListener<
                    AtomNetworkDelegate::kOnBeforeRequest>)
      .SetMethod("onBeforeSendHeaders",
                 &WebRequest::SetResponseListener<
                    AtomNetworkDelegate::kOnBeforeSendHeaders>)
      .SetMethod("onHeadersReceived",
                 &WebRequest::SetResponseListener<
                    AtomNetworkDelegate::kOnHeadersReceived>)
      .SetMethod("onSendHeaders",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnSendHeaders>)
      .SetMethod("onBeforeRedirect",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnBeforeRedirect>)
      .SetMethod("onResponseStarted",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnResponseStarted>)
      .SetMethod("onCompleted",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnCompleted>)
      .SetMethod("onErrorOccurred",
                 &WebRequest::SetSimpleListener<
                    AtomNetworkDelegate::kOnErrorOccurred>)
      .SetMethod("fetch",
                 &WebRequest::Fetch);
}

}  // namespace api

}  // namespace atom
<|endoftext|>