<commit_before>#pragma once
#include <array>
#include <string>

class GLFWwindow;

/**
 * This class defines GLFW based OpenGL Context.
 * There are two use cases of such a context :
 *   - headless rendering application.
 *   - simple window with limited interaction
 */
class OpenGLContext
{
  public:
    /** @defgroup context OpenGL context management
     *  These methods allow to create and manipulate an openGLContext.
     *  Using this function, the openGL context created is an offscreen context with no exposed
     *  window.
     *  @{
     */
    /**
     * Create an offscreen openGl context.
     * The created context has the following properties
     *  - OpenGL version requested : >= 4.1
     *  - OpenGL consstext profile : Core Profile
     * @param size
     */
    explicit OpenGLContext( const std::array<int, 2>& size = {1, 1} );
    /// destructor
    ~OpenGLContext();
    /// make the context active
    void makeCurrent() const;
    /// make the context inactive
    void doneCurrent() const;
    /// Check for validity of the context
    bool isValid() const;

    [[nodiscard]] std::string getInfo() const;
    /** @} */

    /** @defgroup window Window management from an openGL context
     *  These methods allow to display and control a simple window associated with the created
     *  OpenGL Context
     *  @{
     */
    /// Show the window
    void show();
    /// Hide the window
    void hide();
    /// Resize the window
    void resize( const std::array<int, 2>& size );
    /// Swap back/front buffers
    void swapbuffers();
    /// Wait for the user to close the window
    void waitForClose();
    /** @} */

  private:
    GLFWwindow* m_offscreenContext {nullptr};
};
<commit_msg>[testes] GLFWwindow forward decl as struct.<commit_after>#pragma once
#include <array>
#include <string>

struct GLFWwindow;

/**
 * This class defines GLFW based OpenGL Context.
 * There are two use cases of such a context :
 *   - headless rendering application.
 *   - simple window with limited interaction
 */
class OpenGLContext
{
  public:
    /** @defgroup context OpenGL context management
     *  These methods allow to create and manipulate an openGLContext.
     *  Using this function, the openGL context created is an offscreen context with no exposed
     *  window.
     *  @{
     */
    /**
     * Create an offscreen openGl context.
     * The created context has the following properties
     *  - OpenGL version requested : >= 4.1
     *  - OpenGL consstext profile : Core Profile
     * @param size
     */
    explicit OpenGLContext( const std::array<int, 2>& size = {1, 1} );
    /// destructor
    ~OpenGLContext();
    /// make the context active
    void makeCurrent() const;
    /// make the context inactive
    void doneCurrent() const;
    /// Check for validity of the context
    bool isValid() const;

    [[nodiscard]] std::string getInfo() const;
    /** @} */

    /** @defgroup window Window management from an openGL context
     *  These methods allow to display and control a simple window associated with the created
     *  OpenGL Context
     *  @{
     */
    /// Show the window
    void show();
    /// Hide the window
    void hide();
    /// Resize the window
    void resize( const std::array<int, 2>& size );
    /// Swap back/front buffers
    void swapbuffers();
    /// Wait for the user to close the window
    void waitForClose();
    /** @} */

  private:
    GLFWwindow* m_offscreenContext {nullptr};
};
<|endoftext|>


<commit_before>#ifndef TWISTEDCPP_MIXED_RECEIVER
#define TWISTEDCPP_MIXED_RECEIVER

#include "protocol_core.hpp"
#include "detail/line_receiver_parser.hpp"
#include "detail/byte_receiver_parser.hpp"

#include <boost/container/vector.hpp>

namespace twisted {

template <typename ChildProtocol>
class mixed_receiver
    : public twisted::protocol_core<
          ChildProtocol,
          boost::iterator_range<boost::container::vector<char>::iterator>> {
public:
    typedef boost::container::vector<char> internal_buffer_type;
    typedef internal_buffer_type::size_type size_type;
    typedef boost::iterator_range<internal_buffer_type::iterator> buffer_type;
    typedef boost::iterator_range<internal_buffer_type::const_iterator>
    const_buffer_type;

    mixed_receiver(std::string delimiter = std::string("\r\n"))
        : is_byte_mode(false), _current_begin(0), _current_count(0),
          _delimiter(std::move(delimiter)), _next_bytes_size(0),
          _read_buffer(32) {}

    template <typename Iter>
    void on_message(Iter begin, Iter end) {
        _current_count += std::distance(begin, end);

        bool process = false;

        Iter line_start;
        Iter search_iter;

        process = loop_condition(search_iter, end, line_start, _current_begin,
                                 _read_buffer, _delimiter);

        while (process) {
            if (is_byte_mode) {
                byte::core_loop(_current_count, _current_begin, _read_buffer,
                                _next_bytes_size, this->this_protocol());
            } else {
                line::core_loop(line_start, search_iter, _delimiter,
                                _current_count, _current_begin,
                                this->this_protocol());
            }

            process = loop_condition(search_iter, end, line_start,
                                     _current_begin, _read_buffer, _delimiter);
        }

        if (is_byte_mode) {
            byte::prepare_buffers(_current_count, _current_begin, _read_buffer);
        } else {
            line::prepare_buffers(_current_count, _current_begin, _read_buffer);
        }
    }

    template <typename Iter>
    void send_line(Iter begin, Iter end) {
        std::array<boost::asio::const_buffer, 2> buffers{
            { boost::asio::buffer(&*begin, std::distance(begin, end)),
              boost::asio::buffer(&*_delimiter.begin(), _delimiter.size()) }
        };

        this->send_buffers(buffers);
    }

    buffer_type read_buffer() {
        return boost::make_iterator_range(
            std::next(_read_buffer.begin(), _current_begin + _current_count),
            _read_buffer.end());
    }

    const const_buffer_type& read_buffer() const {
        return boost::make_iterator_range(
            std::next(_read_buffer.begin(), _current_begin + _current_count),
            _read_buffer.end());
    }

    void set_byte_mode() { is_byte_mode = true; }

    void set_line_mode() { is_byte_mode = false; }

    void set_package_size(size_type package_size) {
        byte::set_package_size(package_size, _next_bytes_size, _read_buffer);
    }

private:
    template <typename Iter>
    bool loop_condition(Iter& search_iter, Iter end, Iter& line_start,
                        std::size_t _current_begin,
                        boost::container::vector<char>& _read_buffer,
                        const std::string& _delimiter) const {
        if (is_byte_mode) {
            return byte::loop_condition(_current_count, _next_bytes_size);
        } else {
            return line::loop_condition(search_iter, end, line_start,
                                        _current_begin, _read_buffer,
                                        _delimiter);
        }
    }

    // TODO evaluate whether copying each time is faster than tracking
    // _current_begin
    bool is_byte_mode;
    size_type _current_begin; // start-position of not processed data in buffer
    size_type _current_count; // current amount of not processed data
    const std::string _delimiter;
    size_type _next_bytes_size;
    internal_buffer_type _read_buffer;
};
}

#endif
<commit_msg>added mixed receiver docs<commit_after>#ifndef TWISTEDCPP_MIXED_RECEIVER
#define TWISTEDCPP_MIXED_RECEIVER

#include "protocol_core.hpp"
#include "detail/line_receiver_parser.hpp"
#include "detail/byte_receiver_parser.hpp"

#include <boost/container/vector.hpp>

namespace twisted {

/**
 * @brief Protocol that combines the line_receiver and the byte_receiver
 *
 * You can switch between the two modes by calling
 *
 * void set_byte_mode() and void set_line_mode();
 *
 * Provided callbacks:
 *
 * void bytes_received(const_buffer_iterator begin, const_buffer_iterator end);
 *
 * Will be called whenever N bytes have been received. [begin, end) is the data
 * range. (In byte mode)
 *
 * void line_received(const_buffer_iterator begin, const_buffer_iterator end);
 *
 * Will be called whenever a line delimited by the delimiter has been received.
 * [begin, end) is the data
 * range. The range does not include the delimiter. (In line mode)
 */
template <typename ChildProtocol>
class mixed_receiver
    : public twisted::protocol_core<
          ChildProtocol,
          boost::iterator_range<boost::container::vector<char>::iterator>> {
public:
    typedef boost::container::vector<char> internal_buffer_type;
    typedef internal_buffer_type::size_type size_type;
    typedef boost::iterator_range<internal_buffer_type::iterator> buffer_type;
    typedef boost::iterator_range<internal_buffer_type::const_iterator>
    const_buffer_type;

    /**
     * @brief constructor
     * @param delimiter delimiter for the string mode
     */
    mixed_receiver(std::string delimiter = std::string("\r\n"))
        : is_byte_mode(false), _current_begin(0), _current_count(0),
          _delimiter(std::move(delimiter)), _next_bytes_size(0),
          _read_buffer(32) {}

    template <typename Iter>
    void on_message(Iter begin, Iter end) {
        _current_count += std::distance(begin, end);

        bool process = false;

        Iter line_start;
        Iter search_iter;

        process = loop_condition(search_iter, end, line_start, _current_begin,
                                 _read_buffer, _delimiter);

        while (process) {
            if (is_byte_mode) {
                byte::core_loop(_current_count, _current_begin, _read_buffer,
                                _next_bytes_size, this->this_protocol());
            } else {
                line::core_loop(line_start, search_iter, _delimiter,
                                _current_count, _current_begin,
                                this->this_protocol());
            }

            process = loop_condition(search_iter, end, line_start,
                                     _current_begin, _read_buffer, _delimiter);
        }

        if (is_byte_mode) {
            byte::prepare_buffers(_current_count, _current_begin, _read_buffer);
        } else {
            line::prepare_buffers(_current_count, _current_begin, _read_buffer);
        }
    }

    /**
     * @brief Sends a line. Automatically adds the current delimiter
     * @param begin range begin
     * @param end range end
     */
    template <typename Iter>
    void send_line(Iter begin, Iter end) {
        std::array<boost::asio::const_buffer, 2> buffers{
            { boost::asio::buffer(&*begin, std::distance(begin, end)),
              boost::asio::buffer(&*_delimiter.begin(), _delimiter.size()) }
        };

        this->send_buffers(buffers);
    }

    buffer_type read_buffer() {
        return boost::make_iterator_range(
            std::next(_read_buffer.begin(), _current_begin + _current_count),
            _read_buffer.end());
    }

    const const_buffer_type& read_buffer() const {
        return boost::make_iterator_range(
            std::next(_read_buffer.begin(), _current_begin + _current_count),
            _read_buffer.end());
    }

    /**
     * @brief puts the mixed receiver into byte mode
     */
    void set_byte_mode() { is_byte_mode = true; }

    /**
     * @brief puts the mixed receiver into line mode
     */
    void set_line_mode() { is_byte_mode = false; }

    /**
     * @brief sets the size in bytes of the next packet to read (byte mode)
     */
    void set_package_size(size_type package_size) {
        byte::set_package_size(package_size, _next_bytes_size, _read_buffer);
    }

private:
    template <typename Iter>
    bool loop_condition(Iter& search_iter, Iter end, Iter& line_start,
                        std::size_t _current_begin,
                        boost::container::vector<char>& _read_buffer,
                        const std::string& _delimiter) const {
        if (is_byte_mode) {
            return byte::loop_condition(_current_count, _next_bytes_size);
        } else {
            return line::loop_condition(search_iter, end, line_start,
                                        _current_begin, _read_buffer,
                                        _delimiter);
        }
    }

    // TODO evaluate whether copying each time is faster than tracking
    // _current_begin
    bool is_byte_mode;
    size_type _current_begin; // start-position of not processed data in buffer
    size_type _current_count; // current amount of not processed data
    const std::string _delimiter;
    size_type _next_bytes_size;
    internal_buffer_type _read_buffer;
};
}

#endif
<|endoftext|>


<commit_before>#ifndef V_SMC_HELPER_SEQUENTIAL_HPP
#define V_SMC_HELPER_SEQUENTIAL_HPP

namespace vSMC {

/// \brief Type of weight returned by MoveSeq::move_state
///
/// \li No_ACTION The weight is discarded without further action
/// \li SET_WEIGHT The weight is set directly as the new weight
/// \li SET_LOG_WEIGHT The weight is set direclty as the new log weight
/// \li MUL_WEIGHT The weight is the incremental weight
/// \li ADD_LOG_WEIGHT The weight is the log of the incremental weight
enum WeightAction {
    NO_ACTION, SET_WEIGHT, SET_LOG_WEIGHT, MUL_WEIGHT, ADD_LOG_WEIGHT};

/// \brief Particle type for helping implementing SMC sequentially
///
/// StateSeq or its derived class can be used as the template argument of
/// Particle. It targets the particular problems where the parameters to be
/// sampled can be viewed as a vector of dimension Dim and type T.
template <int Dim, typename T = double>
class StateSeq
{
    public :

    /// The type of parameters
    typedef T value_type;

    /// \brief Construct a StateSeq object with given number of particles
    ///
    /// \param N The number of particles
    StateSeq (std::size_t N) : size_(N), state_(N * Dim) {}

    /// \brief The dimension of the problem
    ///
    /// \return The dimension of the parameter vector
    static int dim ()
    {
        return Dim;
    }

    /// \brief The number of particles
    ///
    /// \return The number of particles in the current particle set
    std::size_t size () const
    {
        return size_;
    }

    /// \brief Read and write access to the array of a single particle states
    ///
    /// \return A pointer to the states of a single particle
    T *state (std::size_t n)
    {
        return state_.get() + n * dim();
    }

    /// \brief Read only access to the array of a single particle states
    ///
    /// \return A const pointer to the states of a single array particle
    const T *state (std::size_t n) const
    {
        return state_.get() + n * dim();
    }

    /// \brief Read and write access to the array of all particle states
    ///
    /// \return A pointer to the states of all particles
    ///
    /// \note The array is of row major order. In other words, it is ordered
    /// as the first Dim elements are the states of first particle, the next
    /// Dim elements are the states of the second particle, and so on.
    T *state ()
    {
        return state_.get();
    }

    /// \brief Read only access to the array of all particle states
    ///
    /// \return A const pointer to the states of all particles
    const T *state () const
    {
        return state_.get();
    }

    /// \brief Read only access to the states of a particular paramter
    ///
    /// \param id The index, starting from 0, of the paramter
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void state (int id, OIter first) const
    {
        const T *src = state_.get() + id;
        for (std::size_t i = 0; i != size_; ++i, src += Dim)
            *first++ = *src;
    }

    /// \brief The copy method used by the Sampler
    ///
    /// \param from The index of particle whose state to be copied
    /// \param to The index of particle to which new state to be written
    void copy (std::size_t from, std::size_t to)
    {
        const T *state_from = state(from);
        T *state_to = state(to);
        for (int i = 0; i != Dim; ++i, ++state_from, ++state_to)
            *state_to = *state_from;
    }

    private :

    std::size_t size_;
    vDist::tool::Buffer<T> state_;
}; // class StateSeq

/// \brief Sampler::init_type class for helping implementing SMC sequentially
///
/// This is a abstract factory class. Object of its derived type can used as
/// the argument \b init of Sampler constructor. The derived class need to at
/// least define method initialize_state. Optionally, it can also overload the
/// method initialize_param, which will be called before initialization and
/// accept the last argument of Sampler::init_type functor as its parameter.
///
/// \note The template parameter has to be type StateSeq or its derived
/// class.
template <typename T>
class InitializeSeq
{
    public :

    InitializeSeq () {}

    InitializeSeq (const InitializeSeq<T> &init) {}

    InitializeSeq<T> & operator= (const InitializeSeq<T> &init) {return *this;}

    /// \brief Operator called by Sampler for initialize the particle set
    ///
    /// \param particle The Particle set passed by Sampler
    /// \param param Additional parameters
    ///
    /// \return Accept count
    virtual std::size_t operator() (Particle<T> &particle, void *param)
    {
        initialize_param(particle, param);

        weight_.resize(particle.size());
        std::size_t accept = 0;

        for (std::size_t i = 0; i != particle.size(); ++i) {
            accept += initialize_state(particle,
                    particle.value().state(i), weight_[i]);
        }

        particle.set_log_weight(weight_);

        return accept;
    }

    /// \brief Initialize a single particle
    ///
    /// \param particle The Particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    /// \param weight The log weight of the particle
    ///
    /// \return Accept count, normally should be zero or one
    virtual int initialize_state (const Particle<T> &particle,
            typename T::value_type *state, double &weight) = 0;

    /// \brief Initialize the Particle set
    ///
    /// \param particle The Particle set passed by Sampler
    /// \param param Additional parameter passed by Sampler
    virtual void initialize_param (Particle<T> &particle, void *param) {};

    private :

    vDist::tool::Buffer<double> weight_;
}; // class InitializeSeq

/// \brief Sampler::move_type class for helping implementing SMC sequentially
///
/// This is a abstract factory class. Object of its derived type can be used as
/// the argument \b move or \b mcmc of Sampler constructor. The derived class
/// need to at least define method move_state. Optionally, it can also overload
/// the weight_action method to change how the returned weighted should be
/// treated.
///
/// \note The template parameter has to be type StateSeq or its derived
/// class.
template <typename T>
class MoveSeq
{
    public :

    MoveSeq () {}

    MoveSeq (const MoveSeq<T> &move) {}

    MoveSeq<T> & operator= (const MoveSeq<T> &move) {return *this;}

    /// \brief Operator called by Sampler for move the particle set
    ///
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    ///
    /// \return Accept count
    virtual std::size_t operator () (std::size_t iter, Particle<T> &particle)
    {
        weight_.resize(particle.size());
        std::size_t accept = 0;

        for (std::size_t i = 0; i != particle.size(); ++i) {
            accept += move_state(iter, particle,
                    particle.value().state(i), weight_[i]);
        }

        set_weight(particle);

        return accept;
    }

    /// \brief Move a single particle
    ///
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    /// \param weight The weight of the particle. This may not be the actual
    /// weight. How the returned weight is treated depend on the return from
    /// another method, weight_action. The default behavior is that it is
    /// treated as the log of the incremental weight. It can also be treated
    /// as multiplier to the original weight, or the acutal value of the (log
    /// of) weight. It can even be meaningless, namely no action is taken with
    /// this weight. See WeightAction and weight_action.
    virtual int move_state (std::size_t iter, const Particle<T> &particle,
            typename T::value_type *state, double &weight) = 0;

    /// \brief Determine how weight returned by move_state shall be treated
    ///
    /// \return One of the enumerators of WeightAction
    virtual WeightAction weight_action ()
    {
        return ADD_LOG_WEIGHT;
    }

    private :

    vDist::tool::Buffer<double> weight_;

    void set_weight (Particle<T> &particle)
    {
        switch (weight_action()) {
            case NO_ACTION :
                break;
            case SET_WEIGHT :
                vdLn(particle.size(), weight_, weight_);
            case SET_LOG_WEIGHT :
                particle.set_log_weight(weight_);
                break;
            case MUL_WEIGHT :
                vdLn(particle.size(), weight_, weight_);
            case ADD_LOG_WEIGHT :
                particle.add_log_weight(weight_);
                break;
            default :
                particle.add_log_weight(weight_);
                break;
        }
    }
}; // class MoveSeq

/// \brief Monitor::integral_type class for helping implementing SMC
/// sequentially
///
/// This is a abstract factory class. Object of its derived type can be used
/// as the argument integral of Sampler::monitor(std::string,
/// Monitor<T>::integral_type integral). The derived class need to at least
/// define method monitor_state.
template <typename T>
class MonitorSeq
{
    public :

    /// \brief Operator called by Monitor to record Monte Carlo integration
    ///
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    /// \param [out] res The integrands. Sum(res * weight) is the Monte Carlo
    /// integration result.
    virtual void operator () (std::size_t iter, Particle<T> &particle,
            double *res)
    {
        for (std::size_t i = 0; i != particle.size(); ++i)
            res[i] = monitor_state(iter, particle, particle.value().state(i));
    }

    /// \brief Record the integrand from a single particle
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    ///
    /// \return The value to be estimated
    virtual double monitor_state (std::size_t iter,
            const Particle<T> &particle, typename T::value_type *state) = 0;
}; // class MonitorSeq

/// \brief Path::integral_type class for helping implementing SMC sequentially
///
/// This is a abstract factory class. Object of its derived type can be used
/// as the argument integral of Sampler::path_sampling(Path<T>::integral_type
/// integral). The derived class need to at least define method path_state and
/// width_state.
template <typename T>
class PathSeq
{
    public :

    /// \brief Operator called by Path to record path sampling integrands and
    /// widths
    ///
    /// \param iter The iteration number
    /// \param particle The particle set passed by Sampler
    /// \param [out] res The integrands. Sum(res * weight) is the path
    ///
    /// \return The width
    /// sampling integrand.
    virtual double operator () (std::size_t iter, Particle<T> &particle,
            double *res)
    {
        for (std::size_t i = 0; i != particle.size(); ++i)
            res[i] = path_state(iter, particle, particle.value().state(i));

        return width_state(iter, particle);
    }

    /// \brief Evaluate the path sampling integrand for a single particle
    ///
    ///
    /// \param iter The iteration number
    /// \param particle The particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    ///
    /// \return The value of the integrand
    virtual double path_state (std::size_t iter, const Particle<T> &particle,
            typename T::value_type *state) = 0;

    /// \brief Evaluate the path sampling width
    ///
    /// \param iter The iteration number
    /// \param particle The particle set passed by Sampler
    ///
    /// \return The value of the width
    virtual double width_state (std::size_t iter,
            const Particle<T> &particle) = 0;
};

} // namespace vSMC

#endif // V_SMC_HELPER_SEQUENTIAL_HPP
<commit_msg>set_weight no long use private data<commit_after>#ifndef V_SMC_HELPER_SEQUENTIAL_HPP
#define V_SMC_HELPER_SEQUENTIAL_HPP

namespace vSMC {

/// \brief Type of weight returned by MoveSeq::move_state
///
/// \li No_ACTION The weight is discarded without further action
/// \li SET_WEIGHT The weight is set directly as the new weight
/// \li SET_LOG_WEIGHT The weight is set direclty as the new log weight
/// \li MUL_WEIGHT The weight is the incremental weight
/// \li ADD_LOG_WEIGHT The weight is the log of the incremental weight
enum WeightAction {
    NO_ACTION, SET_WEIGHT, SET_LOG_WEIGHT, MUL_WEIGHT, ADD_LOG_WEIGHT};

/// \brief Particle type for helping implementing SMC sequentially
///
/// StateSeq or its derived class can be used as the template argument of
/// Particle. It targets the particular problems where the parameters to be
/// sampled can be viewed as a vector of dimension Dim and type T.
template <int Dim, typename T = double>
class StateSeq
{
    public :

    /// The type of parameters
    typedef T value_type;

    /// \brief Construct a StateSeq object with given number of particles
    ///
    /// \param N The number of particles
    StateSeq (std::size_t N) : size_(N), state_(N * Dim) {}

    /// \brief The dimension of the problem
    ///
    /// \return The dimension of the parameter vector
    static int dim ()
    {
        return Dim;
    }

    /// \brief The number of particles
    ///
    /// \return The number of particles in the current particle set
    std::size_t size () const
    {
        return size_;
    }

    /// \brief Read and write access to the array of a single particle states
    ///
    /// \return A pointer to the states of a single particle
    T *state (std::size_t n)
    {
        return state_.get() + n * dim();
    }

    /// \brief Read only access to the array of a single particle states
    ///
    /// \return A const pointer to the states of a single array particle
    const T *state (std::size_t n) const
    {
        return state_.get() + n * dim();
    }

    /// \brief Read and write access to the array of all particle states
    ///
    /// \return A pointer to the states of all particles
    ///
    /// \note The array is of row major order. In other words, it is ordered
    /// as the first Dim elements are the states of first particle, the next
    /// Dim elements are the states of the second particle, and so on.
    T *state ()
    {
        return state_.get();
    }

    /// \brief Read only access to the array of all particle states
    ///
    /// \return A const pointer to the states of all particles
    const T *state () const
    {
        return state_.get();
    }

    /// \brief Read only access to the states of a particular paramter
    ///
    /// \param id The index, starting from 0, of the paramter
    /// \param first An iterator point to where writing starts
    template<typename OIter>
    void state (int id, OIter first) const
    {
        const T *src = state_.get() + id;
        for (std::size_t i = 0; i != size_; ++i, src += Dim)
            *first++ = *src;
    }

    /// \brief The copy method used by the Sampler
    ///
    /// \param from The index of particle whose state to be copied
    /// \param to The index of particle to which new state to be written
    void copy (std::size_t from, std::size_t to)
    {
        const T *state_from = state(from);
        T *state_to = state(to);
        for (int i = 0; i != Dim; ++i, ++state_from, ++state_to)
            *state_to = *state_from;
    }

    private :

    std::size_t size_;
    vDist::tool::Buffer<T> state_;
}; // class StateSeq

/// \brief Sampler::init_type class for helping implementing SMC sequentially
///
/// This is a abstract factory class. Object of its derived type can used as
/// the argument \b init of Sampler constructor. The derived class need to at
/// least define method initialize_state. Optionally, it can also overload the
/// method initialize_param, which will be called before initialization and
/// accept the last argument of Sampler::init_type functor as its parameter.
///
/// \note The template parameter has to be type StateSeq or its derived
/// class.
template <typename T>
class InitializeSeq
{
    public :

    InitializeSeq () {}

    InitializeSeq (const InitializeSeq<T> &init) {}

    InitializeSeq<T> & operator= (const InitializeSeq<T> &init) {return *this;}

    /// \brief Operator called by Sampler for initialize the particle set
    ///
    /// \param particle The Particle set passed by Sampler
    /// \param param Additional parameters
    ///
    /// \return Accept count
    virtual std::size_t operator() (Particle<T> &particle, void *param)
    {
        initialize_param(particle, param);

        weight_.resize(particle.size());
        std::size_t accept = 0;

        for (std::size_t i = 0; i != particle.size(); ++i) {
            accept += initialize_state(particle,
                    particle.value().state(i), weight_[i]);
        }

        particle.set_log_weight(weight_);

        return accept;
    }

    /// \brief Initialize a single particle
    ///
    /// \param particle The Particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    /// \param weight The log weight of the particle
    ///
    /// \return Accept count, normally should be zero or one
    virtual int initialize_state (const Particle<T> &particle,
            typename T::value_type *state, double &weight) = 0;

    /// \brief Initialize the Particle set
    ///
    /// \param particle The Particle set passed by Sampler
    /// \param param Additional parameter passed by Sampler
    virtual void initialize_param (Particle<T> &particle, void *param) {};

    private :

    vDist::tool::Buffer<double> weight_;
}; // class InitializeSeq

/// \brief Sampler::move_type class for helping implementing SMC sequentially
///
/// This is a abstract factory class. Object of its derived type can be used as
/// the argument \b move or \b mcmc of Sampler constructor. The derived class
/// need to at least define method move_state. Optionally, it can also overload
/// the weight_action method to change how the returned weighted should be
/// treated.
///
/// \note The template parameter has to be type StateSeq or its derived
/// class.
template <typename T>
class MoveSeq
{
    public :

    MoveSeq () {}

    MoveSeq (const MoveSeq<T> &move) {}

    MoveSeq<T> & operator= (const MoveSeq<T> &move) {return *this;}

    /// \brief Operator called by Sampler for move the particle set
    ///
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    ///
    /// \return Accept count
    virtual std::size_t operator () (std::size_t iter, Particle<T> &particle)
    {
        weight_.resize(particle.size());
        std::size_t accept = 0;

        for (std::size_t i = 0; i != particle.size(); ++i) {
            accept += move_state(iter, particle,
                    particle.value().state(i), weight_[i]);
        }

        set_weight(weight_action(), particle, weight_.get());

        return accept;
    }

    /// \brief Move a single particle
    ///
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    /// \param weight The weight of the particle. This may not be the actual
    /// weight. How the returned weight is treated depend on the return from
    /// another method, weight_action. The default behavior is that it is
    /// treated as the log of the incremental weight. It can also be treated
    /// as multiplier to the original weight, or the acutal value of the (log
    /// of) weight. It can even be meaningless, namely no action is taken with
    /// this weight. See WeightAction and weight_action.
    virtual int move_state (std::size_t iter, const Particle<T> &particle,
            typename T::value_type *state, double &weight) = 0;

    /// \brief Determine how weight returned by move_state shall be treated
    ///
    /// \return One of the enumerators of WeightAction
    virtual WeightAction weight_action ()
    {
        return ADD_LOG_WEIGHT;
    }

    void set_weight (WeightAction action,
            Particle<T> &particle, double *weight)
    {
        switch (action) {
            case NO_ACTION :
                break;
            case SET_WEIGHT :
                vdLn(particle.size(), weight, weight);
            case SET_LOG_WEIGHT :
                particle.set_log_weight(weight);
                break;
            case MUL_WEIGHT :
                vdLn(particle.size(), weight, weight);
            case ADD_LOG_WEIGHT :
                particle.add_log_weight(weight);
                break;
            default :
                particle.add_log_weight(weight);
                break;
        }
    }

    private :

    vDist::tool::Buffer<double> weight_;
}; // class MoveSeq

/// \brief Monitor::integral_type class for helping implementing SMC
/// sequentially
///
/// This is a abstract factory class. Object of its derived type can be used
/// as the argument integral of Sampler::monitor(std::string,
/// Monitor<T>::integral_type integral). The derived class need to at least
/// define method monitor_state.
template <typename T>
class MonitorSeq
{
    public :

    /// \brief Operator called by Monitor to record Monte Carlo integration
    ///
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    /// \param [out] res The integrands. Sum(res * weight) is the Monte Carlo
    /// integration result.
    virtual void operator () (std::size_t iter, Particle<T> &particle,
            double *res)
    {
        for (std::size_t i = 0; i != particle.size(); ++i)
            res[i] = monitor_state(iter, particle, particle.value().state(i));
    }

    /// \brief Record the integrand from a single particle
    /// \param iter The iteration number
    /// \param particle The Particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    ///
    /// \return The value to be estimated
    virtual double monitor_state (std::size_t iter,
            const Particle<T> &particle, typename T::value_type *state) = 0;
}; // class MonitorSeq

/// \brief Path::integral_type class for helping implementing SMC sequentially
///
/// This is a abstract factory class. Object of its derived type can be used
/// as the argument integral of Sampler::path_sampling(Path<T>::integral_type
/// integral). The derived class need to at least define method path_state and
/// width_state.
template <typename T>
class PathSeq
{
    public :

    /// \brief Operator called by Path to record path sampling integrands and
    /// widths
    ///
    /// \param iter The iteration number
    /// \param particle The particle set passed by Sampler
    /// \param [out] res The integrands. Sum(res * weight) is the path
    ///
    /// \return The width
    /// sampling integrand.
    virtual double operator () (std::size_t iter, Particle<T> &particle,
            double *res)
    {
        for (std::size_t i = 0; i != particle.size(); ++i)
            res[i] = path_state(iter, particle, particle.value().state(i));

        return width_state(iter, particle);
    }

    /// \brief Evaluate the path sampling integrand for a single particle
    ///
    ///
    /// \param iter The iteration number
    /// \param particle The particle set passed by Sampler
    /// \param state The array contains the states of a single particle
    ///
    /// \return The value of the integrand
    virtual double path_state (std::size_t iter, const Particle<T> &particle,
            typename T::value_type *state) = 0;

    /// \brief Evaluate the path sampling width
    ///
    /// \param iter The iteration number
    /// \param particle The particle set passed by Sampler
    ///
    /// \return The value of the width
    virtual double width_state (std::size_t iter,
            const Particle<T> &particle) = 0;
};

} // namespace vSMC

#endif // V_SMC_HELPER_SEQUENTIAL_HPP
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Ingo Kloecker <kloecker@kde.org>                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/
#include <QDebug>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "storage/datastore.h"
#include "storage/entity.h"

#include "status.h"
#include "response.h"

using namespace Akonadi;

Status::Status(): Handler()
{
}

Status::~Status()
{
}

bool Status::handleLine( const QByteArray& line )
{
    // Arguments: mailbox name
    //            status data item names

    // Syntax:
    // status     = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
    // status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" / "UNSEEN"
    const int startOfCommand = line.indexOf( ' ' ) + 1;
    const int startOfMailbox = line.indexOf( ' ', startOfCommand ) + 1;
    const int endOfMailbox = line.indexOf( ' ', startOfMailbox );
    const QByteArray mailbox = stripQuotes( line.mid( startOfMailbox, endOfMailbox - startOfMailbox ) );
    const QByteArray statusAttributes = line.mid( endOfMailbox + 2, line.size() - ( endOfMailbox + 2 ) - 1 );
    const QList<QByteArray> attributeList = statusAttributes.split( ' ' );

    Response response;

    DataStore *db = connection()->storageBackend();
    Location l = db->locationByRawMailbox( mailbox );

    if ( !l.isValid() )
        return failureResponse( "No status for this folder" );

    // Responses:
    // REQUIRED untagged responses: STATUS

    // build STATUS response
    QString statusResponse;
    // MESSAGES - The number of messages in the mailbox
    if ( attributeList.contains( "MESSAGES" ) ) {
        statusResponse += "MESSAGES ";
        statusResponse += QString::number( l.exists() );
    }
    // RECENT - The number of messages with the \Recent flag set
    if ( attributeList.contains( "RECENT" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " RECENT ";
        else
            statusResponse += "RECENT ";
        statusResponse += QString::number( l.recent() );
    }
    // UIDNEXT - The next unique identifier value of the mailbox
    if ( attributeList.contains( "UIDNEXT" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " UIDNEXT ";
        else
            statusResponse += "UIDNEXT ";
        statusResponse += QString::number( db->uidNext() );
    }
    // UIDVALIDITY - The unique identifier validity value of the mailbox
    if ( attributeList.contains( "UIDVALIDITY" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " UIDVALIDITY ";
        else
            statusResponse += "UIDVALIDITY ";
        statusResponse += QString::number( l.uidValidity() );
    }
    if ( attributeList.contains( "UNSEEN" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " UNSEEN ";
        else
            statusResponse += "UNSEEN ";
        statusResponse += QString::number( l.unseen() );
    }

    response.setUntagged();
    response.setString( "STATUS " + mailbox + " (" + statusResponse + ')' );
    emit responseAvailable( response );

    response.setSuccess();
    response.setTag( tag() );
    response.setString( "STATUS completed" );
    emit responseAvailable( response );

    deleteLater();
    return true;
}
<commit_msg>Handle collection names with spaces.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Ingo Kloecker <kloecker@kde.org>                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/
#include <QDebug>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "storage/datastore.h"
#include "storage/entity.h"

#include "status.h"
#include "response.h"
#include "handlerhelper.h"

using namespace Akonadi;

Status::Status(): Handler()
{
}

Status::~Status()
{
}

bool Status::handleLine( const QByteArray& line )
{
    // Arguments: mailbox name
    //            status data item names

    // Syntax:
    // status     = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
    // status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" / "UNSEEN"
    const int startOfCommand = line.indexOf( ' ' ) + 1;
    const int startOfMailbox = line.indexOf( ' ', startOfCommand ) + 1;
    QByteArray mailbox;
    const int endOfMailbox = HandlerHelper::parseQuotedString( line, mailbox, startOfMailbox );
    const QByteArray statusAttributes = line.mid( endOfMailbox + 2, line.size() - ( endOfMailbox + 2 ) - 1 );
    const QList<QByteArray> attributeList = statusAttributes.split( ' ' );

    Response response;

    DataStore *db = connection()->storageBackend();
    Location l = db->locationByRawMailbox( mailbox );

    if ( !l.isValid() )
        return failureResponse( "No status for this folder" );

    // Responses:
    // REQUIRED untagged responses: STATUS

    // build STATUS response
    QString statusResponse;
    // MESSAGES - The number of messages in the mailbox
    if ( attributeList.contains( "MESSAGES" ) ) {
        statusResponse += "MESSAGES ";
        statusResponse += QString::number( l.exists() );
    }
    // RECENT - The number of messages with the \Recent flag set
    if ( attributeList.contains( "RECENT" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " RECENT ";
        else
            statusResponse += "RECENT ";
        statusResponse += QString::number( l.recent() );
    }
    // UIDNEXT - The next unique identifier value of the mailbox
    if ( attributeList.contains( "UIDNEXT" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " UIDNEXT ";
        else
            statusResponse += "UIDNEXT ";
        statusResponse += QString::number( db->uidNext() );
    }
    // UIDVALIDITY - The unique identifier validity value of the mailbox
    if ( attributeList.contains( "UIDVALIDITY" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " UIDVALIDITY ";
        else
            statusResponse += "UIDVALIDITY ";
        statusResponse += QString::number( l.uidValidity() );
    }
    if ( attributeList.contains( "UNSEEN" ) ) {
        if ( !statusResponse.isEmpty() )
            statusResponse += " UNSEEN ";
        else
            statusResponse += "UNSEEN ";
        statusResponse += QString::number( l.unseen() );
    }

    response.setUntagged();
    response.setString( "STATUS " + mailbox + " (" + statusResponse + ')' );
    emit responseAvailable( response );

    response.setSuccess();
    response.setTag( tag() );
    response.setString( "STATUS completed" );
    emit responseAvailable( response );

    deleteLater();
    return true;
}
<|endoftext|>


<commit_before>#include <float.h>

#include <functional>
#include <iostream>  // NOLINT(readability/streams)

#include "geometry/grassmann.hpp"
#include "geometry/r3_element.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/astronomy.hpp"
#include "quantities/BIPM.hpp"
#include "quantities/constants.hpp"
#include "quantities/dimensionless.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "quantities/uk.hpp"
#include "testing_utilities/algebra.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/explicit_operators.hpp"

using principia::astronomy::JulianYear;
using principia::astronomy::Parsec;
using principia::constants::SpeedOfLight;
using principia::quantities::Dimensionless;
using principia::quantities::Length;
using principia::quantities::Product;
using principia::quantities::Speed;
using principia::quantities::Sqrt;
using principia::quantities::Time;
using principia::si::Day;
using principia::si::Metre;
using principia::si::Second;
using principia::testing_utilities::AlmostEquals;
using principia::testing_utilities::Times;
using principia::uk::admiralty::Fathom;
using principia::uk::Foot;
using principia::uk::Furlong;
using principia::uk::Inch;
using principia::uk::Rod;
using testing::Eq;

namespace principia {
namespace geometry {

class GrassmannTest : public testing::Test {
 protected:
  struct World;

  template<typename LScalar, typename RScalar, typename Frame, int Rank>
  static Product<LScalar, RScalar> MultivectorInnerProduct(
      Multivector<LScalar, Frame, Rank> const& left,
      Multivector<RScalar, Frame, Rank> const& right) {
    return InnerProduct(left, right);
  }

  template<typename LScalar, typename RScalar, typename Frame, int LRank,
          int RRank>
  static Multivector<Product<LScalar, RScalar>, Frame, LRank + RRank>
  Multivectorwedge(Multivector<LScalar, Frame, LRank> const& left,
                   Multivector<RScalar, Frame, RRank> const& right) {
    return Wedge(left, right);
  }

  R3Element<Length> const null_displacement_ = {0 * Metre,
                                                0 * Metre,
                                                0 * Metre};
  R3Element<Length> const u_ = {3 * Metre, -42 * Metre, 0 * Metre};
  R3Element<Length> const v_ = {-π * Metre, -e * Metre, -1 * Metre};
  R3Element<Length> const w_ = {2 * Metre, 2 * Metre, 2 * Metre};
  R3Element<Length> const a_ = {1 * Inch, 2 * Foot, 3 * Fathom};
};

TEST_F(GrassmannTest, Operators) {
  testing_utilities::TestEquality(Bivector<Length, World>(u_),
                                  Bivector<Length, World>(v_));
  testing_utilities::TestEquality(Vector<Length, World>(u_),
                                  Vector<Length, World>(v_));
  testing_utilities::TestEquality(Trivector<Length, World>(u_.x),
                                  Trivector<Length, World>(v_.x));
  std::cout << "vector: " << Vector<Length, World>(u_) << "\n";
  std::cout << "bivector: " << Bivector<Length, World>(u_) << "\n";
  std::cout << "trivector: " << Trivector<Length, World>(u_.x) << "\n";
}

TEST_F(GrassmannTest, SpecialOrthogonalLieAlgebra) {
  testing_utilities::TestLieBracket(
      Commutator<Dimensionless, Dimensionless, World>,
      Bivector<Dimensionless, World>(u_ / Foot),
      Bivector<Dimensionless, World>(v_ / Metre),
      Bivector<Dimensionless, World>(w_ / Rod),
      Bivector<Dimensionless, World>(a_ / Furlong),
      Dimensionless(0.42), 1000 / DBL_EPSILON);
}

TEST_F(GrassmannTest, MixedScalarMultiplication) {
  testing_utilities::TestBilinearMap(
    Times<Vector<Speed, World>, Time::Inverse, Vector<Length, World>>,
    1 / Second,
    1 / JulianYear,
    Vector<Length, World>(u_),
    Vector<Length, World>(v_),
    Dimensionless(42),
    2);
  testing_utilities::TestBilinearMap(
    Times<Vector<Speed, World>, Vector<Length, World>, Time::Inverse>,
    Vector<Length, World>(w_),
    Vector<Length, World>(a_),
    -1 / Day,
    SpeedOfLight / Parsec,
    Dimensionless(-π),
    1);
  Time::Inverse t = -3 / Second;
  EXPECT_EQ((t * Vector<Length, World>(u_)), (Vector<Length, World>(u_) * t));
  EXPECT_EQ((Vector<Length, World>(v_) * t) / t, (Vector<Length, World>(v_)));
}

TEST_F(GrassmannTest, VectorSpaces) {
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Length, Length, World, 1>,
      Vector<Length, World>(null_displacement_),
      Vector<Length, World>(u_),
      Vector<Length, World>(v_),
      Vector<Length, World>(w_),
      Vector<Length, World>(a_),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Length, Length, World, 2>,
      Bivector<Length, World>(null_displacement_),
      Bivector<Length, World>(u_),
      Bivector<Length, World>(v_),
      Bivector<Length, World>(w_),
      Bivector<Length, World>(a_),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Length, Length, World, 3>,
      Trivector<Length, World>(null_displacement_.x),
      Trivector<Length, World>(u_.y),
      Trivector<Length, World>(v_.z),
      Trivector<Length, World>(w_.x),
      Trivector<Length, World>(a_.y),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2));
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Dimensionless, Dimensionless, World, 1>,
      Vector<Dimensionless, World>(null_displacement_ / Metre),
      Vector<Dimensionless, World>(u_ / Metre),
      Vector<Dimensionless, World>(v_ / Metre),
      Vector<Dimensionless, World>(w_ / Metre),
      Vector<Dimensionless, World>(a_ / Metre),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Dimensionless, Dimensionless, World, 2>,
      Bivector<Dimensionless, World>(null_displacement_ / Metre),
      Bivector<Dimensionless, World>(u_ / Metre),
      Bivector<Dimensionless, World>(v_ / Metre),
      Bivector<Dimensionless, World>(w_ / Metre),
      Bivector<Dimensionless, World>(a_ / Metre),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Dimensionless, Dimensionless, World, 3>,
      Trivector<Dimensionless, World>(null_displacement_.x / Metre),
      Trivector<Dimensionless, World>(u_.y / Metre),
      Trivector<Dimensionless, World>(v_.z / Metre),
      Trivector<Dimensionless, World>(w_.x / Metre),
      Trivector<Dimensionless, World>(a_.y / Metre),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2));
}

TEST_F(GrassmannTest, GrassmannAlgebra) {
  testing_utilities::TestAlternatingBilinearMap(
      Multivectorwedge<Dimensionless, Dimensionless, World, 1, 1>,
      Vector<Dimensionless, World>(u_ / Metre),
      Vector<Dimensionless, World>(v_ / Metre),
      Vector<Dimensionless, World>(w_ / Metre),
      Vector<Dimensionless, World>(a_ / Metre),
      Dimensionless(6 * 9),
      2);
  testing_utilities::TestBilinearMap(
      Multivectorwedge<Length, Speed, World, 1, 2>,
      Vector<Length, World>(u_),
      Vector<Length, World>(v_),
      Bivector<Speed, World>(w_ / Second),
      Bivector<Speed, World>(a_ / Second),
      Dimensionless(6 * 9),
      2);
  testing_utilities::TestBilinearMap(
      Multivectorwedge<Length, Speed, World, 2, 1>,
      Bivector<Length, World>(u_),
      Bivector<Length, World>(v_),
      Vector<Speed, World>(w_ / Second),
      Vector<Speed, World>(a_ / Second),
      Dimensionless(6 * 9),
      2);
  EXPECT_EQ(
      Wedge(Vector<Speed, World>(v_ / Second), Bivector<Length, World>(u_)),
      Wedge(Bivector<Length, World>(u_), Vector<Speed, World>(v_ / Second)));
}

TEST_F(GrassmannTest, Actions) {
  Vector<Length, World> const a(u_);
  Vector<Length, World> const b(v_);
  Bivector<Length, World> const β(v_);
  Bivector<Length, World> const γ(w_);
  // A strongly typed version of the Lagrange formula
  // a × (b × c) = b (a · c) - c (a · b).
  EXPECT_THAT(a * Commutator(β, γ),
              AlmostEquals(β * Wedge(a, γ) - γ * Wedge(a, β), 26));
  EXPECT_THAT(Commutator(β, γ) * a,
              AlmostEquals(Wedge(a, β) * γ - β * Wedge(a, γ), 26));

  EXPECT_THAT(a * Wedge(b, γ), AlmostEquals(Wedge(γ, b) * a, 21));
}

}  // namespace geometry
}  // namespace principia
<commit_msg>Readying<commit_after>#include <float.h>

#include <functional>
#include <iostream>  // NOLINT(readability/streams)

#include "geometry/grassmann.hpp"
#include "geometry/r3_element.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/astronomy.hpp"
#include "quantities/BIPM.hpp"
#include "quantities/constants.hpp"
#include "quantities/dimensionless.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "quantities/uk.hpp"
#include "testing_utilities/algebra.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/explicit_operators.hpp"

using principia::astronomy::JulianYear;
using principia::astronomy::Parsec;
using principia::constants::SpeedOfLight;
using principia::quantities::Dimensionless;
using principia::quantities::Length;
using principia::quantities::Product;
using principia::quantities::Speed;
using principia::quantities::Sqrt;
using principia::quantities::Time;
using principia::si::Day;
using principia::si::Metre;
using principia::si::Second;
using principia::testing_utilities::AlmostEquals;
using principia::testing_utilities::Times;
using principia::uk::admiralty::Fathom;
using principia::uk::Foot;
using principia::uk::Furlong;
using principia::uk::Inch;
using principia::uk::Rod;
using testing::Eq;

namespace principia {
namespace geometry {

class GrassmannTest : public testing::Test {
 protected:
  struct World;

  template<typename LScalar, typename RScalar, typename Frame, int Rank>
  static Product<LScalar, RScalar> MultivectorInnerProduct(
      Multivector<LScalar, Frame, Rank> const& left,
      Multivector<RScalar, Frame, Rank> const& right) {
    return InnerProduct(left, right);
  }

  template<typename LScalar, typename RScalar, typename Frame, int LRank,
          int RRank>
  static Multivector<Product<LScalar, RScalar>, Frame, LRank + RRank>
  Multivectorwedge(Multivector<LScalar, Frame, LRank> const& left,
                   Multivector<RScalar, Frame, RRank> const& right) {
    return Wedge(left, right);
  }

  R3Element<Length> const null_displacement_ = {0 * Metre,
                                                0 * Metre,
                                                0 * Metre};
  R3Element<Length> const u_ = {3 * Metre, -42 * Metre, 0 * Metre};
  R3Element<Length> const v_ = {-π * Metre, -e * Metre, -1 * Metre};
  R3Element<Length> const w_ = {2 * Metre, 2 * Metre, 2 * Metre};
  R3Element<Length> const a_ = {1 * Inch, 2 * Foot, 3 * Fathom};
};

TEST_F(GrassmannTest, Operators) {
  testing_utilities::TestEquality(Bivector<Length, World>(u_),
                                  Bivector<Length, World>(v_));
  testing_utilities::TestEquality(Vector<Length, World>(u_),
                                  Vector<Length, World>(v_));
  testing_utilities::TestEquality(Trivector<Length, World>(u_.x),
                                  Trivector<Length, World>(v_.x));
  std::cout << "vector: " << Vector<Length, World>(u_) << "\n";
  std::cout << "bivector: " << Bivector<Length, World>(u_) << "\n";
  std::cout << "trivector: " << Trivector<Length, World>(u_.x) << "\n";
}

TEST_F(GrassmannTest, SpecialOrthogonalLieAlgebra) {
  testing_utilities::TestLieBracket(
      Commutator<Dimensionless, Dimensionless, World>,
      Bivector<Dimensionless, World>(u_ / Foot),
      Bivector<Dimensionless, World>(v_ / Metre),
      Bivector<Dimensionless, World>(w_ / Rod),
      Bivector<Dimensionless, World>(a_ / Furlong),
      Dimensionless(0.42), static_cast<int64_t>(1000 / DBL_EPSILON));
}

TEST_F(GrassmannTest, MixedScalarMultiplication) {
  testing_utilities::TestBilinearMap(
      Times<Vector<Speed, World>, Time::Inverse, Vector<Length, World>>,
      1 / Second,
      1 / JulianYear,
      Vector<Length, World>(u_),
      Vector<Length, World>(v_),
      Dimensionless(42),
      2);
  testing_utilities::TestBilinearMap(
      Times<Vector<Speed, World>, Vector<Length, World>, Time::Inverse>,
      Vector<Length, World>(w_),
      Vector<Length, World>(a_),
      -1 / Day,
      SpeedOfLight / Parsec,
      Dimensionless(-π),
      1);
  Time::Inverse t = -3 / Second;
  EXPECT_EQ((t * Vector<Length, World>(u_)), (Vector<Length, World>(u_) * t));
  EXPECT_EQ((Vector<Length, World>(v_) * t) / t, (Vector<Length, World>(v_)));
}

TEST_F(GrassmannTest, VectorSpaces) {
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Length, Length, World, 1>,
      Vector<Length, World>(null_displacement_),
      Vector<Length, World>(u_),
      Vector<Length, World>(v_),
      Vector<Length, World>(w_),
      Vector<Length, World>(a_),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Length, Length, World, 2>,
      Bivector<Length, World>(null_displacement_),
      Bivector<Length, World>(u_),
      Bivector<Length, World>(v_),
      Bivector<Length, World>(w_),
      Bivector<Length, World>(a_),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Length, Length, World, 3>,
      Trivector<Length, World>(null_displacement_.x),
      Trivector<Length, World>(u_.y),
      Trivector<Length, World>(v_.z),
      Trivector<Length, World>(w_.x),
      Trivector<Length, World>(a_.y),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2));
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Dimensionless, Dimensionless, World, 1>,
      Vector<Dimensionless, World>(null_displacement_ / Metre),
      Vector<Dimensionless, World>(u_ / Metre),
      Vector<Dimensionless, World>(v_ / Metre),
      Vector<Dimensionless, World>(w_ / Metre),
      Vector<Dimensionless, World>(a_ / Metre),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Dimensionless, Dimensionless, World, 2>,
      Bivector<Dimensionless, World>(null_displacement_ / Metre),
      Bivector<Dimensionless, World>(u_ / Metre),
      Bivector<Dimensionless, World>(v_ / Metre),
      Bivector<Dimensionless, World>(w_ / Metre),
      Bivector<Dimensionless, World>(a_ / Metre),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2), 18);
  testing_utilities::TestInnerProductSpace(
      MultivectorInnerProduct<Dimensionless, Dimensionless, World, 3>,
      Trivector<Dimensionless, World>(null_displacement_.x / Metre),
      Trivector<Dimensionless, World>(u_.y / Metre),
      Trivector<Dimensionless, World>(v_.z / Metre),
      Trivector<Dimensionless, World>(w_.x / Metre),
      Trivector<Dimensionless, World>(a_.y / Metre),
      Dimensionless(0), Dimensionless(1), Sqrt(163),
      -Sqrt(2));
}

TEST_F(GrassmannTest, GrassmannAlgebra) {
  testing_utilities::TestAlternatingBilinearMap(
      Multivectorwedge<Dimensionless, Dimensionless, World, 1, 1>,
      Vector<Dimensionless, World>(u_ / Metre),
      Vector<Dimensionless, World>(v_ / Metre),
      Vector<Dimensionless, World>(w_ / Metre),
      Vector<Dimensionless, World>(a_ / Metre),
      Dimensionless(6 * 9),
      2);
  testing_utilities::TestBilinearMap(
      Multivectorwedge<Length, Speed, World, 1, 2>,
      Vector<Length, World>(u_),
      Vector<Length, World>(v_),
      Bivector<Speed, World>(w_ / Second),
      Bivector<Speed, World>(a_ / Second),
      Dimensionless(6 * 9),
      2);
  testing_utilities::TestBilinearMap(
      Multivectorwedge<Length, Speed, World, 2, 1>,
      Bivector<Length, World>(u_),
      Bivector<Length, World>(v_),
      Vector<Speed, World>(w_ / Second),
      Vector<Speed, World>(a_ / Second),
      Dimensionless(6 * 9),
      2);
  EXPECT_EQ(
      Wedge(Vector<Speed, World>(v_ / Second), Bivector<Length, World>(u_)),
      Wedge(Bivector<Length, World>(u_), Vector<Speed, World>(v_ / Second)));
}

// The Greek letters cause a warning when stringified by the macros, because
// apparently Visual Studio doesn't encode strings in UTF-8 by default.
#pragma warning(disable: 4566)

TEST_F(GrassmannTest, Actions) {
  Vector<Length, World> const a(u_);
  Vector<Length, World> const b(v_);
  Bivector<Length, World> const β(v_);
  Bivector<Length, World> const γ(w_);
  // A strongly typed version of the Lagrange formula
  // a × (b × c) = b (a · c) - c (a · b).
  EXPECT_THAT(a * Commutator(β, γ),
              AlmostEquals(β * Wedge(a, γ) - γ * Wedge(a, β), 26));
  EXPECT_THAT(Commutator(β, γ) * a,
              AlmostEquals(Wedge(a, β) * γ - β * Wedge(a, γ), 26));

  EXPECT_THAT(a * Wedge(b, γ), AlmostEquals(Wedge(γ, b) * a, 21));
}

#pragma warning(default: 4566)

}  // namespace geometry
}  // namespace principia
<|endoftext|>


<commit_before>/**
 * @file llpacketbuffer.cpp
 * @brief implementation of LLPacketBuffer class for a packet.
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 *
 * Copyright (c) 2001-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "linden_common.h"

#include "llpacketbuffer.h"

#include "net.h"
#include "timing.h"
#include "llhost.h"

///////////////////////////////////////////////////////////

LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host)
{
	if (size > NET_BUFFER_SIZE)
	{
		llerrs << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << llendl;
	}
	else // we previously relied on llerrs being fatal to not get here...
	{
		if (datap != NULL)
		{
			memcpy(mData, datap, size);
			mSize = size;
		}
	}

}

LLPacketBuffer::LLPacketBuffer (S32 hSocket)
{
	init(hSocket);
}

///////////////////////////////////////////////////////////

LLPacketBuffer::~LLPacketBuffer ()
{
}

///////////////////////////////////////////////////////////

void LLPacketBuffer::init (S32 hSocket)
{
	mSize = receive_packet(hSocket, mData);
	mHost = ::get_sender();
	mReceivingIF = ::get_receiving_interface();
}

<commit_msg>CID-277<commit_after>/**
 * @file llpacketbuffer.cpp
 * @brief implementation of LLPacketBuffer class for a packet.
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 *
 * Copyright (c) 2001-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "linden_common.h"

#include "llpacketbuffer.h"

#include "net.h"
#include "timing.h"
#include "llhost.h"

///////////////////////////////////////////////////////////

LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host)
{
	if (size > NET_BUFFER_SIZE)
	{
		mSize = 0;
		mData[0] = 0;
		llerrs << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << llendl;
	}
	else // we previously relied on llerrs being fatal to not get here...
	{
		if (datap != NULL)
		{
			memcpy(mData, datap, size);
			mSize = size;
		}
	}

}

LLPacketBuffer::LLPacketBuffer (S32 hSocket)
{
	init(hSocket);
}

///////////////////////////////////////////////////////////

LLPacketBuffer::~LLPacketBuffer ()
{
}

///////////////////////////////////////////////////////////

void LLPacketBuffer::init (S32 hSocket)
{
	mSize = receive_packet(hSocket, mData);
	mHost = ::get_sender();
	mReceivingIF = ::get_receiving_interface();
}

<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/url_request_slow_download_job.h"

#include "base/message_loop.h"
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"

const int kFirstDownloadSize = 1024 * 35;
const int kSecondDownloadSize = 1024 * 10;

const char URLRequestSlowDownloadJob::kUnknownSizeUrl[] =
  "http://url.handled.by.slow.download/download-unknown-size";
const char URLRequestSlowDownloadJob::kKnownSizeUrl[] =
  "http://url.handled.by.slow.download/download-known-size";
const char URLRequestSlowDownloadJob::kFinishDownloadUrl[] =
  "http://url.handled.by.slow.download/download-finish";

std::vector<URLRequestSlowDownloadJob*>
    URLRequestSlowDownloadJob::kPendingRequests;

void URLRequestSlowDownloadJob::Start() {
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
      &URLRequestSlowDownloadJob::StartAsync));
}

/* static */
void URLRequestSlowDownloadJob::AddUrlHandler() {
  URLRequestFilter* filter = URLRequestFilter::GetInstance();
  filter->AddUrlHandler(GURL(kUnknownSizeUrl),
                        &URLRequestSlowDownloadJob::Factory);
  filter->AddUrlHandler(GURL(kKnownSizeUrl),
                        &URLRequestSlowDownloadJob::Factory);
  filter->AddUrlHandler(GURL(kFinishDownloadUrl),
                        &URLRequestSlowDownloadJob::Factory);
}

/*static */
URLRequestJob* URLRequestSlowDownloadJob::Factory(URLRequest* request,
    const std::string& scheme) {
  URLRequestSlowDownloadJob* job = new URLRequestSlowDownloadJob(request);
  if (request->url().spec() != kFinishDownloadUrl)
    URLRequestSlowDownloadJob::kPendingRequests.push_back(job);
  return job;
}

/* static */
void URLRequestSlowDownloadJob::FinishPendingRequests() {
  typedef std::vector<URLRequestSlowDownloadJob*> JobList;
  for (JobList::iterator it = kPendingRequests.begin(); it !=
       kPendingRequests.end(); ++it) {
    (*it)->set_should_finish_download();
  }
  kPendingRequests.clear();
}

URLRequestSlowDownloadJob::URLRequestSlowDownloadJob(URLRequest* request)
  : URLRequestJob(request),
    first_download_size_remaining_(kFirstDownloadSize),
    should_finish_download_(false),
    should_send_second_chunk_(false) {
}

void URLRequestSlowDownloadJob::StartAsync() {
  if (LowerCaseEqualsASCII(kFinishDownloadUrl, request_->url().spec().c_str()))
    URLRequestSlowDownloadJob::FinishPendingRequests();

  NotifyHeadersComplete();
}

bool URLRequestSlowDownloadJob::ReadRawData(net::IOBuffer* buf, int buf_size,
                                            int *bytes_read) {
  if (LowerCaseEqualsASCII(kFinishDownloadUrl,
                           request_->url().spec().c_str())) {
    *bytes_read = 0;
    return true;
  }

  if (should_send_second_chunk_) {
    DCHECK(buf_size > kSecondDownloadSize);
    for (int i = 0; i < kSecondDownloadSize; ++i) {
      buf->data()[i] = '*';
    }
    *bytes_read = kSecondDownloadSize;
    should_send_second_chunk_ = false;
    return true;
  }

  if (first_download_size_remaining_ > 0) {
    int send_size = std::min(first_download_size_remaining_, buf_size);
    for (int i = 0; i < send_size; ++i) {
      buf->data()[i] = '*';
    }
    *bytes_read = send_size;
    first_download_size_remaining_ -= send_size;

    SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
    DCHECK(!is_done());
    return true;
  }

  if (should_finish_download_) {
    *bytes_read = 0;
    return true;
  }

  // If we make it here, the first chunk has been sent and we need to wait
  // until a request is made for kFinishDownloadUrl.
  MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
      this, &URLRequestSlowDownloadJob::CheckDoneStatus), 100);
  AddRef();

  // Return false to signal there is pending data.
  return false;
}

void URLRequestSlowDownloadJob::CheckDoneStatus() {
  if (should_finish_download_) {
    should_send_second_chunk_ = true;
    SetStatus(URLRequestStatus());
    NotifyReadComplete(kSecondDownloadSize);
    Release();
  } else {
    MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
        this, &URLRequestSlowDownloadJob::CheckDoneStatus), 100);
  }
}

// Public virtual version.
void URLRequestSlowDownloadJob::GetResponseInfo(net::HttpResponseInfo* info) {
  // Forward to private const version.
  GetResponseInfoConst(info);
}

// Private const version.
void URLRequestSlowDownloadJob::GetResponseInfoConst(
    net::HttpResponseInfo* info) const {
  // Send back mock headers.
  std::string raw_headers;
  if (LowerCaseEqualsASCII(kFinishDownloadUrl,
                           request_->url().spec().c_str())) {
    raw_headers.append(
      "HTTP/1.1 200 OK\n"
      "Content-type: text/plain\n");
  } else {
    raw_headers.append(
      "HTTP/1.1 200 OK\n"
      "Content-type: application/octet-stream\n"
      "Cache-Control: max-age=0\n");

    if (LowerCaseEqualsASCII(kKnownSizeUrl, request_->url().spec().c_str())) {
      raw_headers.append(StringPrintf("Content-Length: %d\n",
          kFirstDownloadSize + kSecondDownloadSize));
    }
  }

  // ParseRawHeaders expects \0 to end each header line.
  ReplaceSubstringsAfterOffset(&raw_headers, 0, "\n", std::string("\0", 1));
  info->headers = new net::HttpResponseHeaders(raw_headers);
}

bool URLRequestSlowDownloadJob::GetMimeType(std::string* mime_type) const {
  net::HttpResponseInfo info;
  GetResponseInfoConst(&info);
  return info.headers && info.headers->GetMimeType(mime_type);
}
<commit_msg>Fix ReadRawData to make the job state match the return value.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/url_request_slow_download_job.h"

#include "base/message_loop.h"
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"

const int kFirstDownloadSize = 1024 * 35;
const int kSecondDownloadSize = 1024 * 10;

const char URLRequestSlowDownloadJob::kUnknownSizeUrl[] =
  "http://url.handled.by.slow.download/download-unknown-size";
const char URLRequestSlowDownloadJob::kKnownSizeUrl[] =
  "http://url.handled.by.slow.download/download-known-size";
const char URLRequestSlowDownloadJob::kFinishDownloadUrl[] =
  "http://url.handled.by.slow.download/download-finish";

std::vector<URLRequestSlowDownloadJob*>
    URLRequestSlowDownloadJob::kPendingRequests;

void URLRequestSlowDownloadJob::Start() {
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
      &URLRequestSlowDownloadJob::StartAsync));
}

/* static */
void URLRequestSlowDownloadJob::AddUrlHandler() {
  URLRequestFilter* filter = URLRequestFilter::GetInstance();
  filter->AddUrlHandler(GURL(kUnknownSizeUrl),
                        &URLRequestSlowDownloadJob::Factory);
  filter->AddUrlHandler(GURL(kKnownSizeUrl),
                        &URLRequestSlowDownloadJob::Factory);
  filter->AddUrlHandler(GURL(kFinishDownloadUrl),
                        &URLRequestSlowDownloadJob::Factory);
}

/*static */
URLRequestJob* URLRequestSlowDownloadJob::Factory(URLRequest* request,
    const std::string& scheme) {
  URLRequestSlowDownloadJob* job = new URLRequestSlowDownloadJob(request);
  if (request->url().spec() != kFinishDownloadUrl)
    URLRequestSlowDownloadJob::kPendingRequests.push_back(job);
  return job;
}

/* static */
void URLRequestSlowDownloadJob::FinishPendingRequests() {
  typedef std::vector<URLRequestSlowDownloadJob*> JobList;
  for (JobList::iterator it = kPendingRequests.begin(); it !=
       kPendingRequests.end(); ++it) {
    (*it)->set_should_finish_download();
  }
  kPendingRequests.clear();
}

URLRequestSlowDownloadJob::URLRequestSlowDownloadJob(URLRequest* request)
  : URLRequestJob(request),
    first_download_size_remaining_(kFirstDownloadSize),
    should_finish_download_(false),
    should_send_second_chunk_(false) {
}

void URLRequestSlowDownloadJob::StartAsync() {
  if (LowerCaseEqualsASCII(kFinishDownloadUrl, request_->url().spec().c_str()))
    URLRequestSlowDownloadJob::FinishPendingRequests();

  NotifyHeadersComplete();
}

bool URLRequestSlowDownloadJob::ReadRawData(net::IOBuffer* buf, int buf_size,
                                            int *bytes_read) {
  if (LowerCaseEqualsASCII(kFinishDownloadUrl,
                           request_->url().spec().c_str())) {
    *bytes_read = 0;
    return true;
  }

  if (should_send_second_chunk_) {
    DCHECK(buf_size > kSecondDownloadSize);
    for (int i = 0; i < kSecondDownloadSize; ++i) {
      buf->data()[i] = '*';
    }
    *bytes_read = kSecondDownloadSize;
    should_send_second_chunk_ = false;
    return true;
  }

  if (first_download_size_remaining_ > 0) {
    int send_size = std::min(first_download_size_remaining_, buf_size);
    for (int i = 0; i < send_size; ++i) {
      buf->data()[i] = '*';
    }
    *bytes_read = send_size;
    first_download_size_remaining_ -= send_size;

    DCHECK(!is_done());
    return true;
  }

  if (should_finish_download_) {
    *bytes_read = 0;
    return true;
  }

  // If we make it here, the first chunk has been sent and we need to wait
  // until a request is made for kFinishDownloadUrl.
  SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
  MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
      this, &URLRequestSlowDownloadJob::CheckDoneStatus), 100);
  AddRef();

  // Return false to signal there is pending data.
  return false;
}

void URLRequestSlowDownloadJob::CheckDoneStatus() {
  if (should_finish_download_) {
    should_send_second_chunk_ = true;
    SetStatus(URLRequestStatus());
    NotifyReadComplete(kSecondDownloadSize);
    Release();
  } else {
    MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
        this, &URLRequestSlowDownloadJob::CheckDoneStatus), 100);
  }
}

// Public virtual version.
void URLRequestSlowDownloadJob::GetResponseInfo(net::HttpResponseInfo* info) {
  // Forward to private const version.
  GetResponseInfoConst(info);
}

// Private const version.
void URLRequestSlowDownloadJob::GetResponseInfoConst(
    net::HttpResponseInfo* info) const {
  // Send back mock headers.
  std::string raw_headers;
  if (LowerCaseEqualsASCII(kFinishDownloadUrl,
                           request_->url().spec().c_str())) {
    raw_headers.append(
      "HTTP/1.1 200 OK\n"
      "Content-type: text/plain\n");
  } else {
    raw_headers.append(
      "HTTP/1.1 200 OK\n"
      "Content-type: application/octet-stream\n"
      "Cache-Control: max-age=0\n");

    if (LowerCaseEqualsASCII(kKnownSizeUrl, request_->url().spec().c_str())) {
      raw_headers.append(StringPrintf("Content-Length: %d\n",
          kFirstDownloadSize + kSecondDownloadSize));
    }
  }

  // ParseRawHeaders expects \0 to end each header line.
  ReplaceSubstringsAfterOffset(&raw_headers, 0, "\n", std::string("\0", 1));
  info->headers = new net::HttpResponseHeaders(raw_headers);
}

bool URLRequestSlowDownloadJob::GetMimeType(std::string* mime_type) const {
  net::HttpResponseInfo info;
  GetResponseInfoConst(&info);
  return info.headers && info.headers->GetMimeType(mime_type);
}
<|endoftext|>