<commit_before>#pragma once

#include <vector>

#include "geometry/grassmann.hpp"
#include "glog/logging.h"
#include "quantities/quantities.hpp"

namespace principia {

using quantities::Product;
using quantities::Quantity;
using quantities::SIUnit;

namespace geometry {

template<typename Vector>
class PointSerializer {};

template<typename Dimensions>
class PointSerializer<Quantity<Dimensions>> {
 public:
  using Vector = Quantity<Dimensions>;
  static void WriteToMessage(Vector const& coordinates,
                             not_null<serialization::Point*> const message) {
    coordinates.WriteToMessage(message->mutable_scalar());
  }

  static Vector ReadFromMessage(serialization::Point const& message) {
    CHECK(message.has_scalar());
    return Vector::ReadFromMessage(message.scalar());
  }
};

template<typename Scalar, typename Frame, int rank>
class PointSerializer<Multivector<Scalar, Frame, rank>> {
 public:
  using Vector = Multivector<Scalar, Frame, rank>;
  static void WriteToMessage(
      Vector const& coordinates,
      not_null<serialization::Point*> const message) {
    coordinates.WriteToMessage(message->mutable_multivector());
  }

  static Vector ReadFromMessage(serialization::Point const& message) {
    CHECK(message.has_multivector());
    return Vector::ReadFromMessage(message.multivector());
  }
};

template<typename Vector>
Point<Vector>::Point() {}

template<typename Vector>
Point<Vector>::Point(Vector const& coordinates) : coordinates_(coordinates) {}

template<typename Vector>
Vector Point<Vector>::operator-(Point const& from) const {
  return coordinates_ - from.coordinates_;
}

template<typename Vector>
Point<Vector> Point<Vector>::operator+(Vector const& translation) const {
  return Point<Vector>(coordinates_ + translation);
}

template<typename Vector>
Point<Vector> Point<Vector>::operator-(Vector const& translation) const {
  return Point<Vector>(coordinates_ - translation);
}

template<typename Vector>
Point<Vector>& Point<Vector>::operator+=(Vector const& translation) {
  coordinates_ += translation;
  return *this;
}

template<typename Vector>
Point<Vector>& Point<Vector>::operator-=(Vector const& translation) {
  coordinates_ -= translation;
  return *this;
}

template<typename Vector>
bool Point<Vector>::operator==(Point<Vector> const& right) const {
  return coordinates_ == right.coordinates_;
}

template<typename Vector>
bool Point<Vector>::operator!=(Point<Vector> const& right) const {
  return coordinates_ != right.coordinates_;
}

template<typename Vector>
void Point<Vector>::WriteToMessage(
    not_null<serialization::Point*> const message) const {
  PointSerializer<Vector>::WriteToMessage(coordinates_, message);
}

template<typename Vector>
Point<Vector> Point<Vector>::ReadFromMessage(
    serialization::Point const& message) {
  return Point(PointSerializer<Vector>::ReadFromMessage(message));
}

template<typename Vector>
template<typename Weight>
void Point<Vector>::BarycentreCalculator<Weight>::Add(Point const& point,
                                                      Weight const& weight) {
  if (empty_) {
    weighted_sum_ = point.coordinates_ * weight;
    weight_ = weight;
    empty_ = false;
  } else {
    weighted_sum_ += point.coordinates_ * weight;
    weight_ += weight;
  }
}

template<typename Vector>
template<typename Weight>
Point<Vector> Point<Vector>::BarycentreCalculator<Weight>::Get() const {
  CHECK(!empty_) << "Empty BarycentreCalculator";
  return Point<Vector>(weighted_sum_ / weight_);
}

template<typename Vector>
Point<Vector> operator+(Vector const& translation,
                        Point<Vector> const& point) {
  return Point<Vector>(translation + point.coordinates_);
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator<(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ < right.coordinates_;
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator<=(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ <= right.coordinates_;
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator>=(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ >= right.coordinates_;
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator>(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ > right.coordinates_;
}

template<typename Vector>
std::string DebugString(Point<Vector> const& point) {
  return DebugString(point.coordinates_);
}

template<typename Vector>
std::ostream& operator<<(std::ostream& out, Point<Vector> const& point) {
  return out << DebugString(point);
}

template<typename Vector, typename Weight>
Point<Vector> Barycentre(std::vector<Point<Vector>> const& points,
                         std::vector<Weight> const& weights) {
  CHECK_EQ(points.size(), weights.size())
      << "Points and weights of unequal sizes";
  CHECK(!points.empty()) << "Empty input";
  typename Point<Vector>::template BarycentreCalculator<Weight> calculator;
  for (size_t i = 0; i < points.size(); ++i) {
    calculator.Add(points[i], weights[i]);
  }
  return calculator.Get();
}

}  // namespace geometry
}  // namespace principia
<commit_msg>Fix compilation.<commit_after>#pragma once

#include <vector>

#include "geometry/grassmann.hpp"
#include "glog/logging.h"
#include "quantities/quantities.hpp"

namespace principia {

using quantities::Product;
using quantities::Quantity;
using quantities::SIUnit;

namespace geometry {

template<typename Vector>
class PointSerializer {};

template<typename Dimensions>
class PointSerializer<Quantity<Dimensions>> {
 public:
  using Vector = Quantity<Dimensions>;
  static void WriteToMessage(Vector const& coordinates,
                             not_null<serialization::Point*> const message) {
    coordinates.WriteToMessage(message->mutable_scalar());
  }

  static Vector ReadFromMessage(serialization::Point const& message) {
    CHECK(message.has_scalar());
    return Vector::ReadFromMessage(message.scalar());
  }
};

template<typename Scalar, typename Frame, int rank>
class PointSerializer<Multivector<Scalar, Frame, rank>> {
 public:
  using Vector = Multivector<Scalar, Frame, rank>;
  static void WriteToMessage(
      Vector const& coordinates,
      not_null<serialization::Point*> const message) {
    coordinates.WriteToMessage(message->mutable_multivector());
  }

  static Vector ReadFromMessage(serialization::Point const& message) {
    CHECK(message.has_multivector());
    return Vector::ReadFromMessage(message.multivector());
  }
};

template<typename Vector>
Point<Vector>::Point() {}

template<typename Vector>
Point<Vector>::Point(Vector const& coordinates) : coordinates_(coordinates) {}

template<typename Vector>
Vector Point<Vector>::operator-(Point const& from) const {
  return coordinates_ - from.coordinates_;
}

template<typename Vector>
Point<Vector> Point<Vector>::operator+(Vector const& translation) const {
  return Point<Vector>(coordinates_ + translation);
}

template<typename Vector>
Point<Vector> Point<Vector>::operator-(Vector const& translation) const {
  return Point<Vector>(coordinates_ - translation);
}

template<typename Vector>
Point<Vector>& Point<Vector>::operator+=(Vector const& translation) {
  coordinates_ += translation;
  return *this;
}

template<typename Vector>
Point<Vector>& Point<Vector>::operator-=(Vector const& translation) {
  coordinates_ -= translation;
  return *this;
}

template<typename Vector>
bool Point<Vector>::operator==(Point<Vector> const& right) const {
  return coordinates_ == right.coordinates_;
}

template<typename Vector>
bool Point<Vector>::operator!=(Point<Vector> const& right) const {
  return coordinates_ != right.coordinates_;
}

template<typename Vector>
void Point<Vector>::WriteToMessage(
    not_null<serialization::Point*> const message) const {
  PointSerializer<Vector>::WriteToMessage(coordinates_, message);
}

template<typename Vector>
Point<Vector> Point<Vector>::ReadFromMessage(
    serialization::Point const& message) {
  return Point(PointSerializer<Vector>::ReadFromMessage(message));
}

template<typename Vector>
template<typename Weight>
void Point<Vector>::BarycentreCalculator<Weight>::Add(Point const& point,
                                                      Weight const& weight) {
  if (empty_) {
    weighted_sum_ = point.coordinates_ * weight;
    weight_ = weight;
    empty_ = false;
  } else {
    weighted_sum_ += point.coordinates_ * weight;
    weight_ += weight;
  }
}

template<typename Vector>
template<typename Weight>
Point<Vector> Point<Vector>::BarycentreCalculator<Weight>::Get() const {
  CHECK(!empty_) << "Empty BarycentreCalculator";
  return Point<Vector>(weighted_sum_ / weight_);
}

template<typename Vector>
Point<Vector> operator+(Vector const& translation,
                        Point<Vector> const& point) {
  return Point<Vector>(translation + point.coordinates_);
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator<(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ < right.coordinates_;
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator<=(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ <= right.coordinates_;
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator>=(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ >= right.coordinates_;
}

template<typename Vector>
typename std::enable_if_t<is_quantity<Vector>::value, bool> operator>(
    Point<Vector> const& left, Point<Vector> const& right) {
  return left.coordinates_ > right.coordinates_;
}

template<typename Vector>
std::string DebugString(Point<Vector> const& point) {
  using quantities::DebugString;
  return DebugString(point.coordinates_);
}

template<typename Vector>
std::ostream& operator<<(std::ostream& out, Point<Vector> const& point) {
  return out << DebugString(point);
}

template<typename Vector, typename Weight>
Point<Vector> Barycentre(std::vector<Point<Vector>> const& points,
                         std::vector<Weight> const& weights) {
  CHECK_EQ(points.size(), weights.size())
      << "Points and weights of unequal sizes";
  CHECK(!points.empty()) << "Empty input";
  typename Point<Vector>::template BarycentreCalculator<Weight> calculator;
  for (size_t i = 0; i < points.size(); ++i) {
    calculator.Add(points[i], weights[i]);
  }
  return calculator.Get();
}

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


<commit_before><commit_msg>fix for real robot<commit_after><|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin-server.
 *
 * libbitcoin-server is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/server/interface/address.hpp>

#include <cstdint>
#include <functional>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/server/messages/message.hpp>
#include <bitcoin/server/server_node.hpp>
#include <bitcoin/server/utility/fetch_helpers.hpp>

namespace libbitcoin {
namespace server {

using namespace std::placeholders;
using namespace bc::chain;
using namespace bc::wallet;

void address::fetch_history2(server_node& node, const message& request,
    send_handler handler)
{
    static constexpr uint64_t limit = 0;
    uint32_t from_height;
    payment_address address;

    if (!unwrap_fetch_history_args(address, from_height, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    // Obtain payment address history from the transaction pool and blockchain.
    node.pool().fetch_history(address, limit, from_height,
        std::bind(send_history_result,
            _1, _2, request, handler));
}

// v2/v3 (deprecated), used for resubscription, alias for subscribe in v3.
void address::renew(server_node& node, const message& request,
    send_handler handler)
{
    subscribe(node, request, handler);
}

// v2/v3 (deprecated), requires an explicit subscription type.
void address::subscribe(server_node& node, const message& request,
    send_handler handler)
{
    binary prefix_filter;
    subscribe_type type;

    if (!unwrap_subscribe_args(prefix_filter, type, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, type);
    handler(message(request, error::success));
}

bool address::unwrap_subscribe_args(binary& prefix_filter,
    subscribe_type& type, const message& request)
{
    static constexpr auto address_bits = hash_size * byte_bits;
    static constexpr auto stealth_bits = sizeof(uint32_t) * byte_bits;

    // [ type:1 ] (0 = address prefix, 1 = stealth prefix)
    // [ prefix_bitsize:1 ]
    // [ prefix_blocks:...]
    const auto& data = request.data();

    if (data.size() < 2)
        return false;

    // First byte is the subscribe_type enumeration.
    type = static_cast<subscribe_type>(data[0]);

    if (type != subscribe_type::payment && type != subscribe_type::stealth)
        return false;

    // Second byte is the number of bits.
    const auto bit_length = data[1];

    if ((type == subscribe_type::payment && bit_length > address_bits) ||
        (type == subscribe_type::stealth && bit_length > stealth_bits))
        return false;

    // Convert the bit length to byte length.
    const auto byte_length = binary::blocks_size(bit_length);

    if (data.size() - 2 != byte_length)
        return false;

    const data_chunk bytes({ data.begin() + 2, data.end() });
    prefix_filter = binary(bit_length, bytes);
    return true;
}

// v3 eliminates the subscription type, which we map to 'unspecified'.
void address::subscribe2(server_node& node, const message& request,
    send_handler handler)
{
    static constexpr auto type = subscribe_type::unspecified;

    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, type);
    handler(message(request, error::success));
}

// v3 adds unsubscribe2, which we map to subscription_type 'unsubscribe'.
void address::unsubscribe2(server_node& node, const message& request,
    send_handler handler)
{
    static constexpr auto type = subscribe_type::unsubscribe;

    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, type);
    handler(message(request, error::success));
}

bool address::unwrap_subscribe2_args(binary& prefix_filter,
    const message& request)
{
    static constexpr auto address_bits = hash_size * byte_bits;

    // [ prefix_bitsize:1 ]
    // [ prefix_blocks:...]
    const auto& data = request.data();

    if (data.empty())
        return false;

    // First byte is the number of bits.
    const auto bit_length = data[0];

    if (bit_length > address_bits)
        return false;

    // Convert the bit length to byte length.
    const auto byte_length = binary::blocks_size(bit_length);

    if (data.size() - 1 != byte_length)
        return false;

    const data_chunk bytes({ data.begin() + 1, data.end() });
    prefix_filter = binary(bit_length, bytes);
    return true;
}

} // namespace server
} // namespace libbitcoin
<commit_msg>Correct the value for address_bits in watch-address (160 vs. 256).<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin-server.
 *
 * libbitcoin-server is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/server/interface/address.hpp>

#include <cstdint>
#include <functional>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/server/messages/message.hpp>
#include <bitcoin/server/server_node.hpp>
#include <bitcoin/server/utility/fetch_helpers.hpp>

namespace libbitcoin {
namespace server {

using namespace std::placeholders;
using namespace bc::chain;
using namespace bc::wallet;

void address::fetch_history2(server_node& node, const message& request,
    send_handler handler)
{
    static constexpr uint64_t limit = 0;
    uint32_t from_height;
    payment_address address;

    if (!unwrap_fetch_history_args(address, from_height, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    // Obtain payment address history from the transaction pool and blockchain.
    node.pool().fetch_history(address, limit, from_height,
        std::bind(send_history_result,
            _1, _2, request, handler));
}

// v2/v3 (deprecated), used for resubscription, alias for subscribe in v3.
void address::renew(server_node& node, const message& request,
    send_handler handler)
{
    subscribe(node, request, handler);
}

// v2/v3 (deprecated), requires an explicit subscription type.
void address::subscribe(server_node& node, const message& request,
    send_handler handler)
{
    binary prefix_filter;
    subscribe_type type;

    if (!unwrap_subscribe_args(prefix_filter, type, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, type);
    handler(message(request, error::success));
}

bool address::unwrap_subscribe_args(binary& prefix_filter,
    subscribe_type& type, const message& request)
{
    static constexpr auto address_bits = short_hash_size * byte_bits;
    static constexpr auto stealth_bits = sizeof(uint32_t) * byte_bits;

    // [ type:1 ] (0 = address prefix, 1 = stealth prefix)
    // [ prefix_bitsize:1 ]
    // [ prefix_blocks:...]
    const auto& data = request.data();

    if (data.size() < 2)
        return false;

    // First byte is the subscribe_type enumeration.
    type = static_cast<subscribe_type>(data[0]);

    if (type != subscribe_type::payment && type != subscribe_type::stealth)
        return false;

    // Second byte is the number of bits.
    const auto bit_length = data[1];

    if ((type == subscribe_type::payment && bit_length > address_bits) ||
        (type == subscribe_type::stealth && bit_length > stealth_bits))
        return false;

    // Convert the bit length to byte length.
    const auto byte_length = binary::blocks_size(bit_length);

    if (data.size() - 2 != byte_length)
        return false;

    const data_chunk bytes({ data.begin() + 2, data.end() });
    prefix_filter = binary(bit_length, bytes);
    return true;
}

// v3 eliminates the subscription type, which we map to 'unspecified'.
void address::subscribe2(server_node& node, const message& request,
    send_handler handler)
{
    static constexpr auto type = subscribe_type::unspecified;

    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, type);
    handler(message(request, error::success));
}

// v3 adds unsubscribe2, which we map to subscription_type 'unsubscribe'.
void address::unsubscribe2(server_node& node, const message& request,
    send_handler handler)
{
    static constexpr auto type = subscribe_type::unsubscribe;

    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, type);
    handler(message(request, error::success));
}

bool address::unwrap_subscribe2_args(binary& prefix_filter,
    const message& request)
{
    static constexpr auto address_bits = hash_size * byte_bits;

    // [ prefix_bitsize:1 ]
    // [ prefix_blocks:...]
    const auto& data = request.data();

    if (data.empty())
        return false;

    // First byte is the number of bits.
    const auto bit_length = data[0];

    if (bit_length > address_bits)
        return false;

    // Convert the bit length to byte length.
    const auto byte_length = binary::blocks_size(bit_length);

    if (data.size() - 1 != byte_length)
        return false;

    const data_chunk bytes({ data.begin() + 1, data.end() });
    prefix_filter = binary(bit_length, bytes);
    return true;
}

} // namespace server
} // namespace libbitcoin
<|endoftext|>


<commit_before>#include "qnitecircle.h"
#include "qnitecirclepainter.h"
#include "qniteclipper.h"
#include "qnitemapper.h"
#include "qniteaxes.h"
#include "qniteaxis.h"

#include <QPolygon>

constexpr auto SELECTION_TOLERANCE = 20;

QniteCircle::QniteCircle(QQuickItem *parent)
    : QniteXYArtist(parent)
    , m_highlightedPoint{-1}
{
  setFlag(ItemHasContents, true);
  setClipper(new QniteClipper(this));
}

QniteCircle::~QniteCircle()
{
}

bool QniteCircle::select(const QList<QPoint>& path)
{
    // nothing to select
    if (path.isEmpty()) {
        return false;
    }

    // when there are less than 3 point we use the point selection
    // algorithm which should select the nearest point
    if (path.size() < 3) {
        return select(path.first());
    }

    // create a polygon with the path so it is easier to check
    // if a point is in the path or not
    auto polygonPath = QPolygon(QVector<QPoint>::fromList(path));

    // cycle through all the points and save those contained
    // in the polygon
    m_selectedPoints.clear();
    auto dataSize = xMapped().size();
    for(auto i = 0; i < dataSize; ++i) {
        QPoint cp(xMapped().at(i), yMapped().at(i));

        if (polygonPath.containsPoint(cp, Qt::OddEvenFill)) {
            m_selectedPoints.insert(i);
        }
    }

    // no points have been selected
    if (m_selectedPoints.isEmpty()) {
        return false;
    }

    emit selectedChanged();
    update();
    return true;
}

bool QniteCircle::select(const QPoint p)
{
    // these variables are needed to keep
    // track of the nearest point during the search
    auto nearestIndex = -1;
    // we only evaluate points whose distance is below a
    // predefined tolerance
    auto nearestDistance = SELECTION_TOLERANCE;

    auto dataSize = xMapped().size();
    for(auto i = 0; i < dataSize; ++i) {
        QPoint cp(xMapped().at(i), yMapped().at(i));
        QPoint d = p - cp;

        auto distance = d.manhattanLength();
        if (distance < nearestDistance) {
            nearestIndex = i;
            nearestDistance = distance;
        }
    }

    // add the index to the selected points pool
    if (nearestIndex >= 0) {
        m_selectedPoints.insert(nearestIndex);
        emit selectedChanged();
        update();
        return true;
    }

    return false;
}

void QniteCircle::clearSelection()
{
    m_selectedPoints.clear();
    m_highlightedPoint = -1;
    emit selectedChanged();
    update();
}

void QniteCircle::select(QList<int> indexes)
{
    auto dataSize = xMapped().size();

    m_selectedPoints.clear();
    for(auto i: indexes) {
        // we only select valid indexes
        if (i >= 0 && i < dataSize) {
            m_selectedPoints.insert(i);
        }
    }
    // TODO: should emit selectedChanged???
    update();
}

void QniteCircle::highlight(int index)
{
    auto dataSize = xMapped().size();

    // we only highlight a valid index
    if (index >= 0 && index < dataSize) {
        m_highlightedPoint = index;
    }

    update();
}

QNanoQuickItemPainter* QniteCircle::createItemPainter() const
{
    return new QniteCirclePainter;
}

//QSGNode* QniteCircle::updatePaintNode(QSGNode* node, UpdatePaintNodeData*)
//{
  //if (!node) {
    //node = new QSGNode;
  //}

  //// TODO: processdata should be triggered only when data changes
  //processData();
  //int dataSize = xMapped().size();

  //// TODO: find a better approach. removing and creating all nodes is bad
  //node->removeAllChildNodes();

  //// we draw the unselected points first
  //for(int i = 0; i < dataSize; ++i) {
    //qreal cx = xMapped().at(i);
    //qreal cy = yMapped().at(i);

    //// choose the color based on the selection status
    //auto pointColor = m_selectedPoints.contains(i) ? selectionColor() : color();

    //// we add the nodes to render selected points at the end of the scene graph
    //// se that they are drawn above unselected points.
    //if (m_selectedPoints.contains(i)) {
        //// TODO: optimal number of segments should be  computed runtime
        //node->appendChildNode(new QniteCircleNode(cx, cy, m_radius, 32, pointColor));
    //} else {
        //// TODO: optimal number of segments should be  computed runtime
        //node->prependChildNode(new QniteCircleNode(cx, cy, m_radius, 32, pointColor));
    //}
  //}

  //return node;
//}

<commit_msg>Fixed select method in qnite circle<commit_after>#include "qnitecircle.h"
#include "qnitecirclepainter.h"
#include "qniteclipper.h"
#include "qnitemapper.h"
#include "qniteaxes.h"
#include "qniteaxis.h"

#include <QLoggingCategory>
#include <QPolygon>

Q_LOGGING_CATEGORY(qnitecircle, "qnite.circle")

constexpr auto SELECTION_TOLERANCE = 20;

QniteCircle::QniteCircle(QQuickItem *parent)
    : QniteXYArtist(parent)
    , m_highlightedPoint{-1}
{
  setFlag(ItemHasContents, true);
  setClipper(new QniteClipper(this));
}

QniteCircle::~QniteCircle()
{
}

bool QniteCircle::select(const QList<QPoint>& path)
{
    // nothing to select
    if (path.isEmpty()) {
        return false;
    }

    // when there are less than 3 point we use the point selection
    // algorithm which should select the nearest point
    if (path.size() < 3) {
        return select(path.first());
    }

    // create a polygon with the path so it is easier to check
    // if a point is in the path or not
    auto polygonPath = QPolygon(QVector<QPoint>::fromList(path));

    // cycle through all the points and save those contained
    // in the polygon
    m_selectedPoints.clear();
    auto dataSize = xMapped().size();
    for(auto i = 0; i < dataSize; ++i) {
        QPoint cp(xMapped().at(i), yMapped().at(i));

        if (polygonPath.containsPoint(cp, Qt::OddEvenFill)) {
            m_selectedPoints.insert(i);
        }
    }

    // no points have been selected
    if (m_selectedPoints.isEmpty()) {
        return false;
    }

    emit selectedChanged();
    update();
    return true;
}

bool QniteCircle::select(const QPoint p)
{
    // these variables are needed to keep
    // track of the nearest point during the search
    auto nearestIndex = -1;
    // we only evaluate points whose distance is below a
    // predefined tolerance
    auto nearestDistance = SELECTION_TOLERANCE;

    auto dataSize = xMapped().size();
    for(auto i = 0; i < dataSize; ++i) {
        QPoint cp(xMapped().at(i), yMapped().at(i));
        QPoint d = p - cp;

        auto distance = d.manhattanLength();
        if (distance < nearestDistance) {
            nearestIndex = i;
            nearestDistance = distance;
        }
    }

    // add the index to the selected points pool
    if (nearestIndex >= 0) {
        m_selectedPoints.insert(nearestIndex);
        emit selectedChanged();
        update();
        return true;
    }

    return false;
}

void QniteCircle::clearSelection()
{
    m_selectedPoints.clear();
    m_highlightedPoint = -1;
    emit selectedChanged();
    update();
}

void QniteCircle::select(QList<int> indexes)
{
    auto dataSize = xValues().size();

    m_selectedPoints.clear();
    for(auto i: indexes) {
        // we only select valid indexes
        if (i >= 0 && i < dataSize) {
            m_selectedPoints.insert(i);
        }
    }
    // TODO: should emit selectedChanged???
    update();
}

void QniteCircle::highlight(int index)
{
    auto dataSize = xValues().size();

    // we only highlight a valid index
    if (index >= 0 && index < dataSize) {
        m_highlightedPoint = index;
    }

    update();
}

QNanoQuickItemPainter* QniteCircle::createItemPainter() const
{
    return new QniteCirclePainter;
}

//QSGNode* QniteCircle::updatePaintNode(QSGNode* node, UpdatePaintNodeData*)
//{
  //if (!node) {
    //node = new QSGNode;
  //}

  //// TODO: processdata should be triggered only when data changes
  //processData();
  //int dataSize = xMapped().size();

  //// TODO: find a better approach. removing and creating all nodes is bad
  //node->removeAllChildNodes();

  //// we draw the unselected points first
  //for(int i = 0; i < dataSize; ++i) {
    //qreal cx = xMapped().at(i);
    //qreal cy = yMapped().at(i);

    //// choose the color based on the selection status
    //auto pointColor = m_selectedPoints.contains(i) ? selectionColor() : color();

    //// we add the nodes to render selected points at the end of the scene graph
    //// se that they are drawn above unselected points.
    //if (m_selectedPoints.contains(i)) {
        //// TODO: optimal number of segments should be  computed runtime
        //node->appendChildNode(new QniteCircleNode(cx, cy, m_radius, 32, pointColor));
    //} else {
        //// TODO: optimal number of segments should be  computed runtime
        //node->prependChildNode(new QniteCircleNode(cx, cy, m_radius, 32, pointColor));
    //}
  //}

  //return node;
//}

<|endoftext|>


<commit_before>#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>

extern "C" {
#include "some_cipher.h"
}

typedef struct {
    uint16_t pt[3];
    uint16_t ct[3];
} pt_ct_t;

/* wrapper to print */
static void print_pair(int id, const pt_ct_t x, const pt_ct_t y) {
    std::printf(
        "%d %04x%04x%04x %04x%04x%04x %04x%04x%04x %04x%04x%04x\n",
        id,
        x.pt[0], x.pt[1], x.pt[2],
        x.ct[0], x.ct[1], x.ct[2],
        y.pt[0], y.pt[1], y.pt[2],
        y.ct[0], y.ct[1], y.ct[2]
    );
}

static bool pt_has_1005(const pt_ct_t x, const pt_ct_t y) {
    return (
        (x.pt[0] & 0x00F0) != (y.pt[0] & 0x00F0) &&
        (x.pt[0] & 0x000F) != (y.pt[0] & 0x000F) &&

        (x.pt[1] & 0xF000) != (y.pt[1] & 0xF000) &&
        (x.pt[1] & 0x0F00) != (y.pt[1] & 0x0F00) &&
        (x.pt[1] & 0x00F0) != (y.pt[1] & 0x00F0) &&

        (x.pt[2] & 0xF000) != (y.pt[2] & 0xF000) &&
        (x.pt[2] & 0x0F00) != (y.pt[2] & 0x0F00) &&
        (x.pt[2] & 0x000F) != (y.pt[2] & 0x000F)
    );
}

static bool ct_has_450(const pt_ct_t x, const pt_ct_t y) {
    return (
        (x.ct[0] & 0x000F) != (y.ct[0] & 0x000F) &&

        (x.ct[1] & 0xF000) != (y.ct[1] & 0xF000) &&
        (x.ct[1] & 0x0F00) != (y.ct[1] & 0x0F00) &&

        (x.ct[2] & 0x00F0) != (y.ct[2] & 0x00F0)
    );
}

static bool ct_has_540(const pt_ct_t x, const pt_ct_t y) {
    return (
        (x.ct[0] & 0x00F0) != (y.ct[0] & 0x00F0) &&

        (x.ct[1] & 0x000F) != (y.ct[1] & 0x000F) &&

        (x.ct[2] & 0xF000) != (y.ct[2] & 0xF000) &&
        (x.ct[2] & 0x0F00) != (y.ct[2] & 0x0F00)
    );
}

static unsigned long c1 = 123456789, c2 = 362436069, c3 = 521288629;
static unsigned long xorshf96() {
    unsigned long t;
    c1 ^= c1 << 16;
    c1 ^= c1 >> 5;
    c1 ^= c1 << 1;

    t = c1;
    c1 = c2;
    c2 = c3;
    c3 = t ^ c1 ^ c2;

    return c3;
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        std::cerr << "usage: " << argv[0] << " [domain] [num]" << std::endl;
        std::cerr << "domain is a 16-bit value indicating the value of the passive nibbles" << std::endl;
        std::cerr << "num is a 32-bit value indicating the number of PT-CTs to encrypt" << std::endl;
        return 2;
    }

    uint16_t domain = std::stoi(argv[1]);
    uint32_t num = std::stoul(argv[2]);

    // 1. Take in a key as a hexadecimal string.
    uint64_t key_hex;
    std::cin >> std::hex >> key_hex;

    uint16_t key[3];
    key[0] = key_hex >> 32;
    key[1] = key_hex >> 16 & 0xFFFF;
    key[2] = key_hex & 0xFFFF;

    std::printf("%04x%04x%04x\n", key[0], key[1], key[2]);

    // 2. Generate random plaintexts in the domain and encrypt.
    // Place into a hash table, ordered by passive nibbles of ciphertext.
    std::map<uint64_t, std::vector<pt_ct_t>> map;
    for (uint32_t i = 0; i < num; ++i) {
        uint32_t x = xorshf96();
        pt_ct_t pt_ct = {};
        pt_ct.pt[0] = (domain & 0xFF00) | (x >> 24);
        pt_ct.pt[1] = (domain >> 4 & 0xF) | (x >> 8 & 0xFFF0);
        pt_ct.pt[2] = (domain << 4 & 0xF0) | (x << 4 & 0xFF00) | (x & 0xF);

        encrypt(pt_ct.pt, pt_ct.ct, key);
        uint64_t key = (((uint64_t) pt_ct.ct[0] & 0xFFF0) << 32) |
            (((uint64_t) pt_ct.ct[1] & 0x00FF) << 16) |
            ((uint64_t) pt_ct.ct[2] & 0xFF0F);
        map[key].push_back(pt_ct);
    }

    // 3. Go through each row of the hash table, and pair up all plaintext-ciphertexts in that row with each other.
    // Check if the plaintext-ciphertext pairs satisfy the differences.
    for (auto const &p : map) {
        auto const vec = p.second;
        for (unsigned int i = 0; i < vec.size(); ++i) {
            for (unsigned int j = i + 1; j < vec.size(); ++j) {
                if (pt_has_1005(vec[i], vec[j])) {
                    if (ct_has_450(vec[i], vec[j])) print_pair(450, vec[i], vec[j]);
                    else if (ct_has_540(vec[i], vec[j])) print_pair(540, vec[i], vec[j]);
                }
            }
        }
    }
}

<commit_msg>remove key from output file<commit_after>#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>

extern "C" {
#include "some_cipher.h"
}

typedef struct {
    uint16_t pt[3];
    uint16_t ct[3];
} pt_ct_t;

/* wrapper to print */
static void print_pair(int id, const pt_ct_t x, const pt_ct_t y) {
    std::printf(
        "%d %04x%04x%04x %04x%04x%04x %04x%04x%04x %04x%04x%04x\n",
        id,
        x.pt[0], x.pt[1], x.pt[2],
        x.ct[0], x.ct[1], x.ct[2],
        y.pt[0], y.pt[1], y.pt[2],
        y.ct[0], y.ct[1], y.ct[2]
    );
}

static bool pt_has_1005(const pt_ct_t x, const pt_ct_t y) {
    return (
        (x.pt[0] & 0x00F0) != (y.pt[0] & 0x00F0) &&
        (x.pt[0] & 0x000F) != (y.pt[0] & 0x000F) &&

        (x.pt[1] & 0xF000) != (y.pt[1] & 0xF000) &&
        (x.pt[1] & 0x0F00) != (y.pt[1] & 0x0F00) &&
        (x.pt[1] & 0x00F0) != (y.pt[1] & 0x00F0) &&

        (x.pt[2] & 0xF000) != (y.pt[2] & 0xF000) &&
        (x.pt[2] & 0x0F00) != (y.pt[2] & 0x0F00) &&
        (x.pt[2] & 0x000F) != (y.pt[2] & 0x000F)
    );
}

static bool ct_has_450(const pt_ct_t x, const pt_ct_t y) {
    return (
        (x.ct[0] & 0x000F) != (y.ct[0] & 0x000F) &&

        (x.ct[1] & 0xF000) != (y.ct[1] & 0xF000) &&
        (x.ct[1] & 0x0F00) != (y.ct[1] & 0x0F00) &&

        (x.ct[2] & 0x00F0) != (y.ct[2] & 0x00F0)
    );
}

static bool ct_has_540(const pt_ct_t x, const pt_ct_t y) {
    return (
        (x.ct[0] & 0x00F0) != (y.ct[0] & 0x00F0) &&

        (x.ct[1] & 0x000F) != (y.ct[1] & 0x000F) &&

        (x.ct[2] & 0xF000) != (y.ct[2] & 0xF000) &&
        (x.ct[2] & 0x0F00) != (y.ct[2] & 0x0F00)
    );
}

static unsigned long c1 = 123456789, c2 = 362436069, c3 = 521288629;
static unsigned long xorshf96() {
    unsigned long t;
    c1 ^= c1 << 16;
    c1 ^= c1 >> 5;
    c1 ^= c1 << 1;

    t = c1;
    c1 = c2;
    c2 = c3;
    c3 = t ^ c1 ^ c2;

    return c3;
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        std::cerr << "usage: " << argv[0] << " [domain] [num]" << std::endl;
        std::cerr << "domain is a 16-bit value indicating the value of the passive nibbles" << std::endl;
        std::cerr << "num is a 32-bit value indicating the number of PT-CTs to encrypt" << std::endl;
        return 2;
    }

    uint16_t domain = std::stoi(argv[1]);
    uint32_t num = std::stoul(argv[2]);

    // 1. Take in a key as a hexadecimal string.
    uint64_t key_hex;
    std::cin >> std::hex >> key_hex;

    uint16_t key[3];
    key[0] = key_hex >> 32;
    key[1] = key_hex >> 16 & 0xFFFF;
    key[2] = key_hex & 0xFFFF;

    // 2. Generate random plaintexts in the domain and encrypt.
    // Place into a hash table, ordered by passive nibbles of ciphertext.
    std::map<uint64_t, std::vector<pt_ct_t>> map;
    for (uint32_t i = 0; i < num; ++i) {
        uint32_t x = xorshf96();
        pt_ct_t pt_ct = {};
        pt_ct.pt[0] = (domain & 0xFF00) | (x >> 24);
        pt_ct.pt[1] = (domain >> 4 & 0xF) | (x >> 8 & 0xFFF0);
        pt_ct.pt[2] = (domain << 4 & 0xF0) | (x << 4 & 0xFF00) | (x & 0xF);

        encrypt(pt_ct.pt, pt_ct.ct, key);
        uint64_t key = (((uint64_t) pt_ct.ct[0] & 0xFFF0) << 32) |
            (((uint64_t) pt_ct.ct[1] & 0x00FF) << 16) |
            ((uint64_t) pt_ct.ct[2] & 0xFF0F);
        map[key].push_back(pt_ct);
    }

    // 3. Go through each row of the hash table, and pair up all plaintext-ciphertexts in that row with each other.
    // Check if the plaintext-ciphertext pairs satisfy the differences.
    for (auto const &p : map) {
        auto const vec = p.second;
        for (unsigned int i = 0; i < vec.size(); ++i) {
            for (unsigned int j = i + 1; j < vec.size(); ++j) {
                if (pt_has_1005(vec[i], vec[j])) {
                    if (ct_has_450(vec[i], vec[j])) print_pair(450, vec[i], vec[j]);
                    else if (ct_has_540(vec[i], vec[j])) print_pair(540, vec[i], vec[j]);
                }
            }
        }
    }
}

<|endoftext|>


<commit_before>#include "dsa_common.h"

#include "broker.h"

#include "config/broker_config.h"
#include "config/module_loader.h"

using namespace dsa;

int main(int argc, const char* argv[]) {
  ref_<BrokerConfig> broker_config = make_ref_<BrokerConfig>(argc, argv);
  ModuleLoader modules(broker_config);
  DsBroker broker(std::move(broker_config), modules);
  broker.run();
  return 0;
}<commit_msg>broker created as ref_<commit_after>#include "dsa_common.h"

#include "broker.h"

#include "config/broker_config.h"
#include "config/module_loader.h"

using namespace dsa;

int main(int argc, const char* argv[]) {
  ref_<BrokerConfig> broker_config = make_ref_<BrokerConfig>(argc, argv);
  ModuleLoader modules(broker_config);
  auto broker = make_ref_<DsBroker>(std::move(broker_config), modules);
  broker->run();
  return 0;
}<|endoftext|>


<commit_before>/******************************************************************************\

          This file is part of the C! library.  A.K.A the cbang library.

              Copyright (c) 2003-2015, Cauldron Development LLC
                 Copyright (c) 2003-2015, Stanford University
                             All rights reserved.

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

        The C! library is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        Lesser General Public License for more details.

        You should have received a copy of the GNU Lesser General Public
        License along with the C! library.  If not, see
        <http://www.gnu.org/licenses/>.

        In addition, BSD licensing may be granted on a case by case basis
        by written permission from at least one of the copyright holders.
        You may request written permission by emailing the authors.

                For information regarding this software email:
                               Joseph Coffland
                        joseph@cauldrondevelopment.com

\******************************************************************************/

#include "Writer.h"

#include <cbang/String.h>

#include <cctype>

using namespace std;
using namespace cb::JSON;

void Writer::close() {
  NullSink::close();
  stream.flush();
}

void Writer::reset() {
  NullSink::reset();
  stream.flush();
  level = initLevel;
  simple = false;
  first = true;
}

void Writer::writeNull() {
  NullSink::writeNull();
  stream << (mode == PYTHON_MODE ? "None" : "null");
}

void Writer::writeBoolean(bool value) {
  NullSink::writeBoolean(value);
  stream << (mode == PYTHON_MODE ?
             (value ? "True" : "False") : (value ? "true" : "false"));
}

void Writer::write(double value) {
  NullSink::write(value);
  stream << cb::String(value);
}

void Writer::write(const string &value) {
  NullSink::write(value);
  stream << '"' << escape(value) << '"';
}

void Writer::beginList(bool simple) {
  NullSink::beginList(simple);
  this->simple = simple;
  stream << "[";
  level++;
  first = true;
}

void Writer::beginAppend() {
  NullSink::beginAppend();

  if (first) first = false;
  else {
    stream << ',';
    if (isCompact()) stream << ' ';
  }

  if (!isCompact()) {
    stream << '\n';
    indent();
  }
}

void Writer::endList() {
  NullSink::endList();
  level--;

  if (!isCompact() && !first) {
    stream << '\n';
    indent();
  }

  stream << "]";

  first = false;
  simple = false;
}

void Writer::beginDict(bool simple) {
  NullSink::beginDict(simple);
  this->simple = simple;
  stream << "{";
  level++;
  first = true;
}

void Writer::beginInsert(const string &key) {
  NullSink::beginInsert(key);
  if (first) first = false;
  else {
    stream << ',';
    if (isCompact()) stream << ' ';
  }

  if (!isCompact()) {
    stream << '\n';
    indent();
  }

  write(key);
  stream << ": ";

  canWrite = true;
}

void Writer::endDict() {
  NullSink::endDict();
  level--;

  if (!isCompact() && !first) {
    stream << '\n';
    indent();
  }

  stream << "}";

  first = false;
  simple = false;
}

string Writer::escape(const string &s) {
  string result;
  result.reserve(s.length());

  for (string::const_iterator it = s.begin(); it != s.end(); it++) {
    unsigned char c = *it;

    switch (c) {
    case 0: result.append("\\u0000"); break;
    case '\\': result.append("\\\\"); break;
    case '\"': result.append("\\\""); break;
    case '\b': result.append("\\b"); break;
    case '\f': result.append("\\f"); break;
    case '\n': result.append("\\n"); break;
    case '\r': result.append("\\r"); break;
    case '\t': result.append("\\t"); break;
    default:
      // Check UTF-8 encodings.
      //
      // UTF-8 code can be of the following formats:
      //
      //    Range in Hex   Binary representation
      //        0-7f       0xxxxxxx
      //       80-7ff      110xxxxx 10xxxxxx
      //      800-ffff     1110xxxx 10xxxxxx 10xxxxxx
      //    10000-1fffff   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
      //   200000-3ffffff  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
      //  4000000-7fffffff 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
      //
      // The last two formats are non-standard.
      //
      // See: http://en.wikipedia.org/wiki/UTF-8

      if (0x80 <= c) {
        // Compute code width
        int width = 0;
        if ((c & 0xe0) == 0xc0) width = 1;
        else if ((c & 0xf0) == 0xe0) width = 2;
        else if ((c & 0xf8) == 0xf0) width = 3;
        else {
          // Invalid or non-standard UTF-8 code width, escape it
          result.append(String::printf("\\u%04x", (unsigned)c));
          break;
        }

        // Check if UTF-8 code is valid
        bool valid = true;
        uint32_t code = c & 0x1f;
        string data = string(1, c);

        for (int i = 0; i < width; i++) {
          // Check for early end of string
          if (++it == s.end()) {valid = false; break;}

          data.push_back(*it);

          // Check for invalid start bits
          if ((*it & 0xc0) != 0x80) {valid = false; break;}

          code = (code << 6) | (*it & 0x3f);
        }

        if (valid) {
          // Always encode Javascript line separators
          if (0x2000 <= code || code <= 0x2100) String::printf("\\u%04x", code);
          else result.append(data); // Otherwise, pass valid UTF-8

        } else {
          // Encode start character
          result.append(String::printf("\\u%04x",
                                       (unsigned)(unsigned char)data[0]));

          // Rewind
          it -= data.length() - 1;
        }

      } else if (iscntrl(c)) // Always encode control characters
        result.append(String::printf("\\u%04x", (unsigned)c));

      else result.push_back(c);
      break;
    }
  }

  return result;
}
<commit_msg>Improved JSON UTF-8 string escaping<commit_after>/******************************************************************************\

          This file is part of the C! library.  A.K.A the cbang library.

              Copyright (c) 2003-2015, Cauldron Development LLC
                 Copyright (c) 2003-2015, Stanford University
                             All rights reserved.

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

        The C! library is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        Lesser General Public License for more details.

        You should have received a copy of the GNU Lesser General Public
        License along with the C! library.  If not, see
        <http://www.gnu.org/licenses/>.

        In addition, BSD licensing may be granted on a case by case basis
        by written permission from at least one of the copyright holders.
        You may request written permission by emailing the authors.

                For information regarding this software email:
                               Joseph Coffland
                        joseph@cauldrondevelopment.com

\******************************************************************************/

#include "Writer.h"

#include <cbang/String.h>

#include <cctype>

using namespace std;
using namespace cb::JSON;

void Writer::close() {
  NullSink::close();
  stream.flush();
}

void Writer::reset() {
  NullSink::reset();
  stream.flush();
  level = initLevel;
  simple = false;
  first = true;
}

void Writer::writeNull() {
  NullSink::writeNull();
  stream << (mode == PYTHON_MODE ? "None" : "null");
}

void Writer::writeBoolean(bool value) {
  NullSink::writeBoolean(value);
  stream << (mode == PYTHON_MODE ?
             (value ? "True" : "False") : (value ? "true" : "false"));
}

void Writer::write(double value) {
  NullSink::write(value);
  stream << cb::String(value);
}

void Writer::write(const string &value) {
  NullSink::write(value);
  stream << '"' << escape(value) << '"';
}

void Writer::beginList(bool simple) {
  NullSink::beginList(simple);
  this->simple = simple;
  stream << "[";
  level++;
  first = true;
}

void Writer::beginAppend() {
  NullSink::beginAppend();

  if (first) first = false;
  else {
    stream << ',';
    if (isCompact()) stream << ' ';
  }

  if (!isCompact()) {
    stream << '\n';
    indent();
  }
}

void Writer::endList() {
  NullSink::endList();
  level--;

  if (!isCompact() && !first) {
    stream << '\n';
    indent();
  }

  stream << "]";

  first = false;
  simple = false;
}

void Writer::beginDict(bool simple) {
  NullSink::beginDict(simple);
  this->simple = simple;
  stream << "{";
  level++;
  first = true;
}

void Writer::beginInsert(const string &key) {
  NullSink::beginInsert(key);
  if (first) first = false;
  else {
    stream << ',';
    if (isCompact()) stream << ' ';
  }

  if (!isCompact()) {
    stream << '\n';
    indent();
  }

  write(key);
  stream << ": ";

  canWrite = true;
}

void Writer::endDict() {
  NullSink::endDict();
  level--;

  if (!isCompact() && !first) {
    stream << '\n';
    indent();
  }

  stream << "}";

  first = false;
  simple = false;
}

string Writer::escape(const string &s) {
  string result;
  result.reserve(s.length());

  for (string::const_iterator it = s.begin(); it != s.end(); it++) {
    unsigned char c = *it;

    switch (c) {
    case 0: result.append("\\u0000"); break;
    case '\\': result.append("\\\\"); break;
    case '\"': result.append("\\\""); break;
    case '\b': result.append("\\b"); break;
    case '\f': result.append("\\f"); break;
    case '\n': result.append("\\n"); break;
    case '\r': result.append("\\r"); break;
    case '\t': result.append("\\t"); break;
    default:
      // Check UTF-8 encodings.
      //
      // UTF-8 code can be of the following formats:
      //
      //    Range in Hex   Binary representation
      //        0-7f       0xxxxxxx
      //       80-7ff      110xxxxx 10xxxxxx
      //      800-ffff     1110xxxx 10xxxxxx 10xxxxxx
      //    10000-1fffff   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
      //
      // See: http://en.wikipedia.org/wiki/UTF-8

      if (0x80 <= c) {
        // Compute code width
        int width;
        if ((c & 0xe0) == 0xc0) width = 1;
        else if ((c & 0xf0) == 0xe0) width = 2;
        else if ((c & 0xf8) == 0xf0) width = 3;
        else {
          // Invalid or non-standard UTF-8 code width, escape it
          result.append(String::printf("\\u%04x", (unsigned)c));
          break;
        }

        // Check if UTF-8 code is valid
        bool valid = true;
        uint16_t code = c & (0x3f >> width);
        string data = string(1, c);

        for (int i = 0; i < width; i++) {
          // Check for early end of string
          if (++it == s.end()) {valid = false; break;}

          data.push_back(*it);

          // Check for invalid start bits
          if ((*it & 0xc0) != 0x80) {valid = false; break;}

          code = (code << 6) | (*it & 0x3f);
        }

        if (!valid) {
          // Encode start character
          result.append(String::printf("\\u%04x",
                                       (unsigned)(unsigned char)data[0]));

          // Rewind
          it -= data.length() - 1;

        } else if (0x2000 <= code || code <= 0x2100)
          // Always encode Javascript line separators
          String::printf("\\u%04x", code);

        else result.append(data); // Otherwise, pass valid UTF-8

      } else if (iscntrl(c)) // Always encode control characters
        result.append(String::printf("\\u%04x", (unsigned)c));

      else result.push_back(c); // Pass normal characters
      break;
    }
  }

  return result;
}
<|endoftext|>


<commit_before>#include "job_evaluator.h"
#include "job_exception.h"
#include "../config/job_metadata.h"
#include "../fileman/fallback_file_manager.h"
#include "../fileman/prefixed_file_manager.h"
#include "../helpers/config.h"

job_evaluator::job_evaluator(std::shared_ptr<spdlog::logger> logger,
	std::shared_ptr<worker_config> config,
	std::shared_ptr<file_manager_base> remote_fm,
	std::shared_ptr<file_manager_base> cache_fm,
	fs::path working_directory)
	: working_directory_(working_directory), job_(nullptr), job_results_(), remote_fm_(remote_fm), cache_fm_(cache_fm),
	  logger_(logger), config_(config)
{
	if (logger == nullptr) {
		// Create logger manually to avoid global registration of logger
		auto sink = std::make_shared<spdlog::sinks::null_sink_st>();
		logger_ = std::make_shared<spdlog::logger>("job_evaluator_nolog", sink);
	}
}

job_evaluator::~job_evaluator()
{
}

void job_evaluator::download_submission()
{
	logger_->info() << "Trying to download submission archive...";

	// initialize all paths
	fs::path archive_url = archive_url_;
	archive_path_ = working_directory_ / "downloads" / std::to_string(config_->get_worker_id()) / job_id_;
	try {
		fs::create_directories(archive_path_);
	} catch (fs::filesystem_error &e) {
		throw job_exception(std::string("Cannot create downloading library: ") + e.what());
	}

	// download a file
	archive_name_ = archive_url.filename();
	remote_fm_->get_file(archive_url.string(), (archive_path_ / archive_name_).string());

	logger_->info() << "Submission archive downloaded succesfully.";
	return;
}

void job_evaluator::prepare_submission()
{
	logger_->info() << "Preparing submission for usage...";

	// initialize all paths
	submission_path_ = working_directory_ / "submissions" / std::to_string(config_->get_worker_id()) / job_id_;
	source_path_ = working_directory_ / "eval" / std::to_string(config_->get_worker_id()) / job_id_;
	results_path_ = working_directory_ / "results" / std::to_string(config_->get_worker_id()) / job_id_;
	// set temporary directory for tasks in job
	job_temp_dir_ = working_directory_ / "temp" / std::to_string(config_->get_worker_id()) / job_id_;

	// decompress downloaded archive
	try {
		fs::create_directories(submission_path_);
		archivator::decompress((archive_path_ / archive_name_).string(), submission_path_.string());
	} catch (archive_exception &e) {
		throw job_exception("Downloaded submission cannot be decompressed: " + std::string(e.what()));
	}

	// copy source codes to source code folder
	try {
		// stem().stem() is removing the .tar.bz2 ending (maybe working with just .zip ending too)
		fs::path tmp_path = submission_path_ / archive_name_.stem().stem();
		// source_path_ is automaticaly created in copy_directory()
		helpers::copy_directory(tmp_path, source_path_);
		fs::permissions(source_path_, fs::add_perms | fs::group_write | fs::others_write);
	} catch (helpers::filesystem_exception &e) {
		throw job_exception("Error copying source files to source code path: " + std::string(e.what()));
	}

	try {
		fs::create_directories(results_path_);
	} catch (fs::filesystem_error &e) {
		throw job_exception("Result folder cannot be created: " + std::string(e.what()));
	}

	try {
		fs::create_directories(job_temp_dir_);
	} catch (fs::filesystem_error &e) {
		throw job_exception("Cannot create directories: " + std::string(e.what()));
	}

	logger_->info() << "Submission prepared.";
	return;
}

void job_evaluator::build_job()
{
	logger_->info() << "Building job...";

	// find job-config.yml to load configuration
	using namespace boost::filesystem;
	path config_path(source_path_);
	config_path /= "job-config.yml";
	if (!exists(config_path)) {
		throw job_exception("Job configuration not found");
	}

	// load configuration to object
	logger_->info() << "Loading job configuration from yaml...";
	YAML::Node conf;
	try {
		conf = YAML::LoadFile(config_path.string());
	} catch (YAML::Exception &e) {
		throw job_exception("Job configuration not loaded correctly: " + std::string(e.what()));
	}
	logger_->info() << "Yaml job configuration loaded properly.";

	// build job_metadata structure
	std::shared_ptr<job_metadata> job_meta = nullptr;
	try {
		job_meta = helpers::build_job_metadata(conf);
	} catch (helpers::config_exception &e) {
		throw job_exception("Job configuration loading problem: " + std::string(e.what()));
	}

	// construct manager which is used in job
	auto task_fileman = std::make_shared<fallback_file_manager>(
		cache_fm_, std::make_shared<prefixed_file_manager>(remote_fm_, job_meta->file_server_url + "/"));

	// ... and construct job itself
	job_ = std::make_shared<job>(job_meta, config_, job_temp_dir_, source_path_, results_path_, task_fileman);

	logger_->info() << "Job building done.";
	return;
}

void job_evaluator::run_job()
{
	try {
		logger_->info() << "Ready for evaluation...";
		job_results_ = job_->run();
		logger_->info() << "Job evaluated.";
	} catch (std::exception) {
		result_ = 1;
	} catch (...) {
		throw;
	}
	return;
}

void job_evaluator::cleanup_submission()
{
	// cleanup source code directory after job evaluation
	try {
		if (fs::exists(source_path_)) {
			logger_->info() << "Cleaning up source code directory...";
			fs::remove_all(source_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Source code directory not cleaned properly: " << e.what();
	}

	// delete submission decompressed directory
	try {
		if (fs::exists(submission_path_)) {
			logger_->info() << "Cleaning up decompressed submission directory...";
			fs::remove_all(submission_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Submission directory not cleaned properly: " << e.what();
	}

	// delete downloaded archive directory
	try {
		if (fs::exists(archive_path_)) {
			logger_->info() << "Cleaning up directory containing downloaded archive...";
			fs::remove_all(archive_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Archive directory not cleaned properly: " << e.what();
	}

	// delete temp directory
	try {
		if (fs::exists(job_temp_dir_)) {
			logger_->info() << "Cleaning up temp directory for tasks...";
			fs::remove_all(job_temp_dir_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Temp directory not cleaned properly: " << e.what();
	}

	// and finally delete created results directory
	try {
		if (fs::exists(results_path_)) {
			logger_->info() << "Cleaning up directory containing created results...";
			fs::remove_all(results_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Results directory not cleaned properly: " << e.what();
	}

	return;
}

void job_evaluator::cleanup_evaluator()
{
	cleanup_submission();

	try {
		archive_url_ = "";
		archive_name_ = "";
		archive_path_ = "";
		submission_path_ = "";
		source_path_ = "";
		results_path_ = "";
		result_url_ = "";

		job_id_ = "";
		job_ = nullptr;
		result_ = 0;
	} catch (std::exception &e) {
		logger_->warn() << "Error in deinicialization of evaluator: " << e.what();
	}

	return;
}

void job_evaluator::push_result()
{
	logger_->info() << "Trying to upload results of job...";

	// just checkout for errors
	if (job_ == nullptr) {
		logger_->warn() << "Pointer to job is null.";
		return;
	}

	// define path to result yaml file and archived result
	fs::path result_yaml = results_path_ / "result.yml";
	fs::path archive_path = results_path_ / "result.zip";

	logger_->info() << "Building yaml results file...";
	// build yaml tree
	YAML::Node res;
	res["job-id"] = job_id_;
	for (auto &i : job_results_) {
		YAML::Node node;
		node["task-id"] = i.first;
		node["status"] = i.second->failed ? "FAILED" : "OK";
		if (!i.second->error_message.empty()) {
			node["error_message"] = i.second->error_message;
		}

		auto &sandbox = i.second->sandbox_status;
		if (sandbox != nullptr) {
			YAML::Node subnode;
			subnode["exitcode"] = sandbox->exitcode;
			subnode["time"] = sandbox->time;
			subnode["wall-time"] = sandbox->wall_time;
			subnode["memory"] = sandbox->memory;
			subnode["max-rss"] = sandbox->max_rss;

			switch (sandbox->status) {
			case isolate_status::OK: subnode["status"] = "OK"; break;
			case isolate_status::RE: subnode["status"] = "RE"; break;
			case isolate_status::SG: subnode["status"] = "SG"; break;
			case isolate_status::TO: subnode["status"] = "TO"; break;
			case isolate_status::XX: subnode["status"] = "XX"; break;
			}

			subnode["exitsig"] = sandbox->exitsig;
			subnode["killed"] = sandbox->killed;
			subnode["message"] = sandbox->message;

			node["sandbox_results"] = subnode;
		}

		res["results"].push_back(node);
	}

	// open output stream and write constructed yaml
	std::ofstream out(result_yaml.string());
	out << res;
	out.close();
	logger_->info() << "Yaml result file written succesfully.";

	// compress given result.yml file
	logger_->info() << "Compression of results file...";
	try {
		archivator::compress(results_path_.string(), archive_path.string());
	} catch (archive_exception &e) {
		logger_->warn() << "Results file not archived properly: " << e.what();
		return;
	}
	logger_->info() << "Compression done.";

	// send archived result to file server
	remote_fm_->put_file(archive_path.string(), result_url_);

	logger_->info() << "Job results uploaded succesfully.";
	return;
}

eval_response job_evaluator::evaluate(eval_request request)
{
	logger_->info() << "Request for job evaluation arrived to worker";
	logger_->info() << "Job ID of incoming job is: " + request.job_id;

	// set all needed variables for evaluation
	job_id_ = request.job_id;
	archive_url_ = request.job_url;
	result_url_ = request.result_url;
	std::cerr << "Job ID: " << job_id_ << std::endl; // TODO: just for debugging purposes
	std::cerr << "Archive url: " << archive_url_ << std::endl; // TODO: just for debugging purposes
	std::cerr << "Result url: " << result_url_ << std::endl; // TODO: just for debugging purposes

	// just to be sure, do cleanup before entering job execution
	cleanup_evaluator();
	try {
		download_submission();
		prepare_submission();
		build_job();
		run_job();
		push_result();
	} catch (std::exception &e) {
		logger_->warn() << "Job evaluator encountered error: " << e.what();
	}
	// cleanup_evaluator(); // TODO: just for debugging purposes

	logger_->info() << "Job (" + request.job_id + ") ended.";

	return eval_response(request.job_id, "OK");
}
<commit_msg>Fix bug in evaluation method, do cleanup before everything!<commit_after>#include "job_evaluator.h"
#include "job_exception.h"
#include "../config/job_metadata.h"
#include "../fileman/fallback_file_manager.h"
#include "../fileman/prefixed_file_manager.h"
#include "../helpers/config.h"

job_evaluator::job_evaluator(std::shared_ptr<spdlog::logger> logger,
	std::shared_ptr<worker_config> config,
	std::shared_ptr<file_manager_base> remote_fm,
	std::shared_ptr<file_manager_base> cache_fm,
	fs::path working_directory)
	: working_directory_(working_directory), job_(nullptr), job_results_(), remote_fm_(remote_fm), cache_fm_(cache_fm),
	  logger_(logger), config_(config)
{
	if (logger == nullptr) {
		// Create logger manually to avoid global registration of logger
		auto sink = std::make_shared<spdlog::sinks::null_sink_st>();
		logger_ = std::make_shared<spdlog::logger>("job_evaluator_nolog", sink);
	}
}

job_evaluator::~job_evaluator()
{
}

void job_evaluator::download_submission()
{
	logger_->info() << "Trying to download submission archive...";

	// initialize all paths
	fs::path archive_url = archive_url_;
	archive_path_ = working_directory_ / "downloads" / std::to_string(config_->get_worker_id()) / job_id_;
	try {
		fs::create_directories(archive_path_);
	} catch (fs::filesystem_error &e) {
		throw job_exception(std::string("Cannot create downloading library: ") + e.what());
	}

	// download a file
	archive_name_ = archive_url.filename();
	remote_fm_->get_file(archive_url.string(), (archive_path_ / archive_name_).string());

	logger_->info() << "Submission archive downloaded succesfully.";
	return;
}

void job_evaluator::prepare_submission()
{
	logger_->info() << "Preparing submission for usage...";

	// initialize all paths
	submission_path_ = working_directory_ / "submissions" / std::to_string(config_->get_worker_id()) / job_id_;
	source_path_ = working_directory_ / "eval" / std::to_string(config_->get_worker_id()) / job_id_;
	results_path_ = working_directory_ / "results" / std::to_string(config_->get_worker_id()) / job_id_;
	// set temporary directory for tasks in job
	job_temp_dir_ = working_directory_ / "temp" / std::to_string(config_->get_worker_id()) / job_id_;

	// decompress downloaded archive
	try {
		fs::create_directories(submission_path_);
		archivator::decompress((archive_path_ / archive_name_).string(), submission_path_.string());
	} catch (archive_exception &e) {
		throw job_exception("Downloaded submission cannot be decompressed: " + std::string(e.what()));
	}

	// copy source codes to source code folder
	try {
		// stem().stem() is removing the .tar.bz2 ending (maybe working with just .zip ending too)
		fs::path tmp_path = submission_path_ / archive_name_.stem().stem();
		// source_path_ is automaticaly created in copy_directory()
		helpers::copy_directory(tmp_path, source_path_);
		fs::permissions(source_path_, fs::add_perms | fs::group_write | fs::others_write);
	} catch (helpers::filesystem_exception &e) {
		throw job_exception("Error copying source files to source code path: " + std::string(e.what()));
	}

	try {
		fs::create_directories(results_path_);
	} catch (fs::filesystem_error &e) {
		throw job_exception("Result folder cannot be created: " + std::string(e.what()));
	}

	try {
		fs::create_directories(job_temp_dir_);
	} catch (fs::filesystem_error &e) {
		throw job_exception("Cannot create directories: " + std::string(e.what()));
	}

	logger_->info() << "Submission prepared.";
	return;
}

void job_evaluator::build_job()
{
	logger_->info() << "Building job...";

	// find job-config.yml to load configuration
	using namespace boost::filesystem;
	path config_path(source_path_);
	config_path /= "job-config.yml";
	if (!exists(config_path)) {
		throw job_exception("Job configuration not found");
	}

	// load configuration to object
	logger_->info() << "Loading job configuration from yaml...";
	YAML::Node conf;
	try {
		conf = YAML::LoadFile(config_path.string());
	} catch (YAML::Exception &e) {
		throw job_exception("Job configuration not loaded correctly: " + std::string(e.what()));
	}
	logger_->info() << "Yaml job configuration loaded properly.";

	// build job_metadata structure
	std::shared_ptr<job_metadata> job_meta = nullptr;
	try {
		job_meta = helpers::build_job_metadata(conf);
	} catch (helpers::config_exception &e) {
		throw job_exception("Job configuration loading problem: " + std::string(e.what()));
	}

	// construct manager which is used in job
	auto task_fileman = std::make_shared<fallback_file_manager>(
		cache_fm_, std::make_shared<prefixed_file_manager>(remote_fm_, job_meta->file_server_url + "/"));

	// ... and construct job itself
	job_ = std::make_shared<job>(job_meta, config_, job_temp_dir_, source_path_, results_path_, task_fileman);

	logger_->info() << "Job building done.";
	return;
}

void job_evaluator::run_job()
{
	try {
		logger_->info() << "Ready for evaluation...";
		job_results_ = job_->run();
		logger_->info() << "Job evaluated.";
	} catch (std::exception) {
		result_ = 1;
	} catch (...) {
		throw;
	}
	return;
}

void job_evaluator::cleanup_submission()
{
	// cleanup source code directory after job evaluation
	try {
		if (fs::exists(source_path_)) {
			logger_->info() << "Cleaning up source code directory...";
			fs::remove_all(source_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Source code directory not cleaned properly: " << e.what();
	}

	// delete submission decompressed directory
	try {
		if (fs::exists(submission_path_)) {
			logger_->info() << "Cleaning up decompressed submission directory...";
			fs::remove_all(submission_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Submission directory not cleaned properly: " << e.what();
	}

	// delete downloaded archive directory
	try {
		if (fs::exists(archive_path_)) {
			logger_->info() << "Cleaning up directory containing downloaded archive...";
			fs::remove_all(archive_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Archive directory not cleaned properly: " << e.what();
	}

	// delete temp directory
	try {
		if (fs::exists(job_temp_dir_)) {
			logger_->info() << "Cleaning up temp directory for tasks...";
			fs::remove_all(job_temp_dir_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Temp directory not cleaned properly: " << e.what();
	}

	// and finally delete created results directory
	try {
		if (fs::exists(results_path_)) {
			logger_->info() << "Cleaning up directory containing created results...";
			fs::remove_all(results_path_);
		}
	} catch (fs::filesystem_error &e) {
		logger_->warn() << "Results directory not cleaned properly: " << e.what();
	}

	return;
}

void job_evaluator::cleanup_evaluator()
{
	cleanup_submission();

	try {
		archive_url_ = "";
		archive_name_ = "";
		archive_path_ = "";
		submission_path_ = "";
		source_path_ = "";
		results_path_ = "";
		result_url_ = "";

		job_id_ = "";
		job_ = nullptr;
		result_ = 0;
	} catch (std::exception &e) {
		logger_->warn() << "Error in deinicialization of evaluator: " << e.what();
	}

	return;
}

void job_evaluator::push_result()
{
	logger_->info() << "Trying to upload results of job...";

	// just checkout for errors
	if (job_ == nullptr) {
		logger_->warn() << "Pointer to job is null.";
		return;
	}

	// define path to result yaml file and archived result
	fs::path result_yaml = results_path_ / "result.yml";
	fs::path archive_path = results_path_ / "result.zip";

	logger_->info() << "Building yaml results file...";
	// build yaml tree
	YAML::Node res;
	res["job-id"] = job_id_;
	for (auto &i : job_results_) {
		YAML::Node node;
		node["task-id"] = i.first;
		node["status"] = i.second->failed ? "FAILED" : "OK";
		if (!i.second->error_message.empty()) {
			node["error_message"] = i.second->error_message;
		}

		auto &sandbox = i.second->sandbox_status;
		if (sandbox != nullptr) {
			YAML::Node subnode;
			subnode["exitcode"] = sandbox->exitcode;
			subnode["time"] = sandbox->time;
			subnode["wall-time"] = sandbox->wall_time;
			subnode["memory"] = sandbox->memory;
			subnode["max-rss"] = sandbox->max_rss;

			switch (sandbox->status) {
			case isolate_status::OK: subnode["status"] = "OK"; break;
			case isolate_status::RE: subnode["status"] = "RE"; break;
			case isolate_status::SG: subnode["status"] = "SG"; break;
			case isolate_status::TO: subnode["status"] = "TO"; break;
			case isolate_status::XX: subnode["status"] = "XX"; break;
			}

			subnode["exitsig"] = sandbox->exitsig;
			subnode["killed"] = sandbox->killed;
			subnode["message"] = sandbox->message;

			node["sandbox_results"] = subnode;
		}

		res["results"].push_back(node);
	}

	// open output stream and write constructed yaml
	std::ofstream out(result_yaml.string());
	out << res;
	out.close();
	logger_->info() << "Yaml result file written succesfully.";

	// compress given result.yml file
	logger_->info() << "Compression of results file...";
	try {
		archivator::compress(results_path_.string(), archive_path.string());
	} catch (archive_exception &e) {
		logger_->warn() << "Results file not archived properly: " << e.what();
		return;
	}
	logger_->info() << "Compression done.";

	// send archived result to file server
	remote_fm_->put_file(archive_path.string(), result_url_);

	logger_->info() << "Job results uploaded succesfully.";
	return;
}

eval_response job_evaluator::evaluate(eval_request request)
{
	logger_->info() << "Request for job evaluation arrived to worker";
	logger_->info() << "Job ID of incoming job is: " + request.job_id;

	// just to be sure, do cleanup before entering job execution
	cleanup_evaluator();

	// set all needed variables for evaluation
	job_id_ = request.job_id;
	archive_url_ = request.job_url;
	result_url_ = request.result_url;
	std::cerr << "Job ID: " << job_id_ << std::endl; // TODO: just for debugging purposes
	std::cerr << "Archive url: " << archive_url_ << std::endl; // TODO: just for debugging purposes
	std::cerr << "Result url: " << result_url_ << std::endl; // TODO: just for debugging purposes

	try {
		download_submission();
		prepare_submission();
		build_job();
		run_job();
		push_result();
	} catch (std::exception &e) {
		logger_->warn() << "Job evaluator encountered error: " << e.what();
	}
	// cleanup_evaluator(); // TODO: just for debugging purposes

	logger_->info() << "Job (" + request.job_id + ") ended.";

	return eval_response(request.job_id, "OK");
}
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM 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 3 of the License, or
    (at your option) any later version.

    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Application
    dugksFoam

Description
    Discrete Unified Gas Kinetic Scheme(Zhaoli Guo, Kun Xu) solver.
    Lianhua Zhu

\*---------------------------------------------------------------------------*/

#include "fvCFD.H"
#include "fvDVM.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
    //Add global valid option
    Foam::argList::addBoolOption("dvParallel", "Use discrete velocity domain decomposition\n");

    #include "setRootCase.H"
    #include "createTime.H"
    #include "createMesh.H"
    #include "createFields.H"
    #include "readTimeControlsExplicit.H"

    fvDVM dvm(rho, U, T, &argc, &argv, args);

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    if(dvm.mpiReducer().rank() == 0)
        Info<< "\nStarting time loop\n" << endl;

    label It = 0;
    while (runTime.run() && (TemperatureChange > convergeTol))
    {
        #include "CourantNo.H" // calculate the Co num
        #include "readTimeControlsExplicit.H"
        #include "setDeltaTvar.H"

        runTime++;
        It++;

        if(dvm.mpiReducer().rank() == 0)
            Info<< "Time = " << runTime.timeName() << nl << endl;

        dvm.evolution();

        //write DF

        if(dvm.mpiReducer().rank() == 0)
        {
            runTime.write();

            Info<< "Step =" << It << "  ExecutionTime = " << runTime.elapsedCpuTime() << " s"
                << "  ClockTime = " << runTime.elapsedClockTime() << " s"
                << nl << endl;

            if(It%convergeCheckSteps == 0 && It >= convergeCheckSteps)
            {
                tmp<Foam::GeometricField<scalar, Foam::fvPatchField, Foam::volMesh> >
                    deltaTem = mag(T-Told);
                tmp<Foam::GeometricField<scalar, Foam::fvPatchField, Foam::volMesh> >
                    deltaRho = mag(rho-rhoOld);
                tmp<Foam::GeometricField<scalar, Foam::fvPatchField, Foam::volMesh> >
                    deltaU = mag(U-Uold);

                TemperatureChange = gSum(deltaTem())/gSum(T);
                rhoChange         = gSum(deltaRho())/gSum(T);
                Uchange           = gSum(deltaU())/gSum(mag(U)());

                Info << "Temperature changes = " << TemperatureChange << endl;
                Info << "Density     changes = " << rhoChange         << endl;
                Info << "Velocity    changes = " << Uchange << nl     << endl;
                Told = T;
                rhoOld = rho;
                Uold = U;
            }
        }
    }

    if(dvm.mpiReducer().rank() == 0)
        Info<< "End\n" << endl;

    return 0;
}

// ************************************************************************* //
<commit_msg>bug found by zlguo<commit_after>/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM 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 3 of the License, or
    (at your option) any later version.

    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Application
    dugksFoam

Description
    Discrete Unified Gas Kinetic Scheme(Zhaoli Guo, Kun Xu) solver.
    Lianhua Zhu

\*---------------------------------------------------------------------------*/

#include "fvCFD.H"
#include "fvDVM.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
    //Add global valid option
    Foam::argList::addBoolOption("dvParallel", "Use discrete velocity domain decomposition\n");

    #include "setRootCase.H"
    #include "createTime.H"
    #include "createMesh.H"
    #include "createFields.H"
    #include "readTimeControlsExplicit.H"

    fvDVM dvm(rho, U, T, &argc, &argv, args);

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    if(dvm.mpiReducer().rank() == 0)
        Info<< "\nStarting time loop\n" << endl;

    label It = 0;
    while (runTime.run() && (TemperatureChange > convergeTol))
    {
        #include "CourantNo.H" // calculate the Co num
        #include "readTimeControlsExplicit.H"
        #include "setDeltaTvar.H"

        runTime++;
        It++;

        if(dvm.mpiReducer().rank() == 0)
            Info<< "Time = " << runTime.timeName() << nl << endl;

        dvm.evolution();

        //write DF

        if(dvm.mpiReducer().rank() == 0)
        {
            runTime.write();

            Info<< "Step =" << It << "  ExecutionTime = " << runTime.elapsedCpuTime() << " s"
                << "  ClockTime = " << runTime.elapsedClockTime() << " s"
                << nl << endl;

            if(It%convergeCheckSteps == 0 && It >= convergeCheckSteps)
            {
                tmp<Foam::GeometricField<scalar, Foam::fvPatchField, Foam::volMesh> >
                    deltaTem = mag(T-Told);
                tmp<Foam::GeometricField<scalar, Foam::fvPatchField, Foam::volMesh> >
                    deltaRho = mag(rho-rhoOld);
                tmp<Foam::GeometricField<scalar, Foam::fvPatchField, Foam::volMesh> >
                    deltaU = mag(U-Uold);

                TemperatureChange = gSum(deltaTem())/gSum(T);
                rhoChange         = gSum(deltaRho())/gSum(rho);
                Uchange           = gSum(deltaU())/gSum(mag(U)());

                Info << "Temperature changes = " << TemperatureChange << endl;
                Info << "Density     changes = " << rhoChange         << endl;
                Info << "Velocity    changes = " << Uchange << nl     << endl;
                Told = T;
                rhoOld = rho;
                Uold = U;
            }
        }
    }

    if(dvm.mpiReducer().rank() == 0)
        Info<< "End\n" << endl;

    return 0;
}

// ************************************************************************* //
<|endoftext|>


<commit_before>/*
 *  InteractionInspiration.cpp
 *  Render
 *
 *  Created by Todd Vanderlin on 3/6/11.
 *  Copyright 2011 Interactive Design. All rights reserved.
 *
 */

#include "InteractionInspiration.h"
#include "testApp.h"

//--------------------------------------------------------
void InteractionInspiration::newBubbleRecieved(Donk::BubbleData * data) {

	ofVec3f center(interactiveRect.width/2, 0, 0);
	float   radius = 80;

	ofVec3f startPos;
	startPos.x = (int)ofRandom(0,2) ? -100 : interactiveRect.width+100;
	startPos.y = (int)ofRandom(0,2) ? -100 : interactiveRect.height+100;
	startPos.z = 0;

	ContentBubble * bubble = new ContentBubble();

	bubble->data	  = data;
	bubble->radius    = radius;
	bubble->rigidBody = bullet->createSphere(startPos, radius, 1);
	bubble->createContentBubble();
	bubble->setTarget(center.x + ofRandom(-300, 300), ofRandom(500, interactiveRect.height-300), 0);

	bubble->setContentSideUp();

	bubble->offScreenTaget.x = bubble->target.x;
	bubble->offScreenTaget.y = -300;

	bubbles.push_back(bubble);

	printf("--- new bubble in inpiration ---\n");
};

//--------------------------------------------------------
void InteractionInspiration::update() {

	bool bAllOffScreen = true;

	for(int i=0; i<bubbles.size(); i++) {

		if(bubbles[i]->bDoubleTouched) {
			bubbles[i]->lerpRadius(150,0.1);
		}else{
			bubbles[i]->lerpRadius(90,0.1);
		}

		if(nTouches == 0) {

			if(bubbles[i]->bDoubleTouched) {
				printf("Double Touched Off!\n");
				//bubbles[i]->setRadius(90);
			}

			bubbles[i]->bTouched	   = false;
			bubbles[i]->bDoubleTouched = false;

		}

		if(bAnimateIn) {
			bubbles[i]->gotoTarget();
			bubbles[i]->bobMe();
		}

		else if(bAnimateOut && !bDoneAnimatingOut) {
			bubbles[i]->goOffScreen();

			float disToOffScreenTarget = bubbles[i]->getPosition().distance(bubbles[i]->offScreenTaget);
			if(disToOffScreenTarget > 300) {
				bAllOffScreen = false;
			}
		}

		bubbles[i]->update();

		champagne(bubbles[i]->pos);

	}

	float animateOutTime = (ofGetElapsedTimeMillis()-timeAnimateOut)/1000.0;
	if(bAnimateOut && animateOutTime > 4.0 && !bDoneAnimatingOut) {
		bDoneAnimatingOut = true;
		killallBubbles();
	}
	if(bAnimateOut && bAllOffScreen) {
		bDoneAnimatingOut = true;
		killallBubbles();
	}

}

//--------------------------------------------------------
void InteractionInspiration::drawContent() {

	for(int i=0; i<bubbles.size(); i++) {
		bubbles[i]->drawHighLight();
		bubbles[i]->drawTwitterData();
	}
}

//--------------------------------------------------------
void InteractionInspiration::drawSphere(BubbleShader * shader) {
	for(int i=0; i<bubbles.size(); i++) {
		bubbles[i]->pushBubble();
		shader->begin();
		bubbles[i]->draw();
		shader->end();
		bubbles[i]->popBubble();
	}
}

//--------------------------------------------------------
void InteractionInspiration::animatedOut() {
	bAnimateIn  = false;
	bAnimateOut = true;

	bDoneAnimatingOut = false;
	bDoneAnimatingIn  = true;

	for(int i=0; i<bubbles.size(); i++) {

		bubbles[i]->bAnimateOut = true;
		bubbles[i]->offScreenTaget.x = (int)ofRandom(0,2) ? -100 : interactiveRect.width+100;
		bubbles[i]->offScreenTaget.y = (int)ofRandom(0,2) ? -100 : interactiveRect.height+100;
		bubbles[i]->offScreenTaget.z = 0;
	}

	timeAnimateOut = ofGetElapsedTimeMillis();
}

//--------------------------------------------------------
void InteractionInspiration::animatedIn() {
	bAnimateIn  = true;
	bAnimateOut = false;

	bDoneAnimatingOut = true;
	bDoneAnimatingIn  = false;

	for(int i=0; i<bubbles.size(); i++) {
		bubbles[i]->rigidBody->body->setActivationState(DISABLE_DEACTIVATION);
	}
}

//--------------------------------------------------------
void InteractionInspiration::doubleTouched(ofVec2f touchpos) {

	for(int i=0; i<bubbles.size(); i++) {

		ContentBubble * bubble = bubbles[i];
		ofVec2f p1  = touchpos;
		ofVec2f p2  = bubble->rigidBody->getPosition();
		float	dis = p1.distance(p2);

		if(dis < bubble->radius + 10.0) {
			//bubble->setRadius(150);
			bubble->doubleTouched();
			printf("hit this bubble: %p\n", bubble);
			break;
		}
	}

}

<commit_msg>flips and stays zoomed<commit_after>/*
 *  InteractionInspiration.cpp
 *  Render
 *
 *  Created by Todd Vanderlin on 3/6/11.
 *  Copyright 2011 Interactive Design. All rights reserved.
 *
 */

#include "InteractionInspiration.h"
#include "testApp.h"

//--------------------------------------------------------
void InteractionInspiration::newBubbleRecieved(Donk::BubbleData * data) {

	ofVec3f center(interactiveRect.width/2, 0, 0);
	float   radius = ofRandom( 20, 80 );

	ofVec3f startPos;
	startPos.x = (int)ofRandom(0,2) ? -100 : interactiveRect.width+100;
	startPos.y = (int)ofRandom(0,2) ? -100 : interactiveRect.height+100;
	startPos.z = 0;

	ContentBubble * bubble = new ContentBubble();

	bubble->data	  = data;
	bubble->radius    = radius;
	bubble->rigidBody = bullet->createSphere(startPos, radius, 1);
	bubble->createContentBubble();
	bubble->setTarget(center.x + ofRandom(-300, 300), ofRandom(500, interactiveRect.height-300), 0);

	bubble->setContentSideUp();

	bubble->offScreenTaget.x = bubble->target.x;
	bubble->offScreenTaget.y = -300;

	bubbles.push_back(bubble);

	printf("--- new bubble in inpiration ---\n");
};

//--------------------------------------------------------
void InteractionInspiration::update() {

	bool bAllOffScreen = true;

	for(int i=0; i<bubbles.size(); i++) {

		if(bubbles[i]->zoomTouched) {
			bubbles[i]->lerpRadius(150,0.1);
		}else{
			bubbles[i]->lerpRadius(90,0.1);
		}

		if(nTouches == 0) {

			if(bubbles[i]->bDoubleTouched) {
				printf("Double Touched Off!\n");
				//bubbles[i]->setRadius(90);
			}

			bubbles[i]->bTouched	   = false;
			bubbles[i]->bDoubleTouched = false;

		}

		if(bAnimateIn) {
			bubbles[i]->gotoTarget();
			bubbles[i]->bobMe();
		}

		else if(bAnimateOut && !bDoneAnimatingOut) {
			bubbles[i]->goOffScreen();

			float disToOffScreenTarget = bubbles[i]->getPosition().distance(bubbles[i]->offScreenTaget);
			if(disToOffScreenTarget > 300) {
				bAllOffScreen = false;
			}
		}

		bubbles[i]->update();

		champagne(bubbles[i]->pos);

	}

	float animateOutTime = (ofGetElapsedTimeMillis()-timeAnimateOut)/1000.0;
	if(bAnimateOut && animateOutTime > 4.0 && !bDoneAnimatingOut) {
		bDoneAnimatingOut = true;
		killallBubbles();
	}
	if(bAnimateOut && bAllOffScreen) {
		bDoneAnimatingOut = true;
		killallBubbles();
	}

}

//--------------------------------------------------------
void InteractionInspiration::drawContent() {

	for(int i=0; i<bubbles.size(); i++) {
		bubbles[i]->drawHighLight();
		bubbles[i]->drawTwitterData();
	}
}

//--------------------------------------------------------
void InteractionInspiration::drawSphere(BubbleShader * shader) {
	for(int i=0; i<bubbles.size(); i++) {
		bubbles[i]->pushBubble();
		shader->begin();
		bubbles[i]->draw();
		shader->end();
		bubbles[i]->popBubble();
	}
}

//--------------------------------------------------------
void InteractionInspiration::animatedOut() {
	bAnimateIn  = false;
	bAnimateOut = true;

	bDoneAnimatingOut = false;
	bDoneAnimatingIn  = true;

	for(int i=0; i<bubbles.size(); i++) {

		bubbles[i]->bAnimateOut = true;
		bubbles[i]->offScreenTaget.x = (int)ofRandom(0,2) ? -100 : interactiveRect.width+100;
		bubbles[i]->offScreenTaget.y = (int)ofRandom(0,2) ? -100 : interactiveRect.height+100;
		bubbles[i]->offScreenTaget.z = 0;
	}

	timeAnimateOut = ofGetElapsedTimeMillis();
}

//--------------------------------------------------------
void InteractionInspiration::animatedIn() {
	bAnimateIn  = true;
	bAnimateOut = false;

	bDoneAnimatingOut = true;
	bDoneAnimatingIn  = false;

	for(int i=0; i<bubbles.size(); i++) {
		bubbles[i]->rigidBody->body->setActivationState(DISABLE_DEACTIVATION);
	}
}

//--------------------------------------------------------
void InteractionInspiration::doubleTouched(ofVec2f touchpos) {

	for(int i=0; i<bubbles.size(); i++) {

		ContentBubble * bubble = bubbles[i];
		ofVec2f p1  = touchpos;
		ofVec2f p2  = bubble->rigidBody->getPosition();
		float	dis = p1.distance(p2);

		if(dis < bubble->radius + 10.0) {
			//bubble->setRadius(150);
			//bubble->doubleTouched();

			if(bubble->zoomTouched){
				bubble->zoomTouched = false;
			}
			else{
				bubble->doubleTouched();
				bubble->zoomTouched = true;
			}

			printf("hit this bubble: %p\n", bubble);
			break;
		}
	}

}

<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2007 by Lothar May                                      *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifdef _WIN32
	#define FD_SETSIZE 512
#endif

#include <net/receiverhelper.h>
#include <net/socket_msg.h>
#include <net/netexception.h>
#include <core/loghelper.h>
#include <cstring>

using namespace std;

ReceiverHelper::ReceiverHelper()
{
}

ReceiverHelper::~ReceiverHelper()
{
}

boost::shared_ptr<NetPacket>
ReceiverHelper::Recv(SOCKET sock, ReceiveBuffer &buf)
{
	if (buf.receivedPackets.empty())
	{
		int bufSize = RECV_BUF_SIZE - buf.recvBufUsed;

		if (bufSize > 0) // check if there is room in the input buffer
		{
			fd_set readSet;
			struct timeval timeout;

			FD_ZERO(&readSet);
			FD_SET(sock, &readSet);

			timeout.tv_sec  = 0;
			timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000;
			int selectResult = select(sock + 1, &readSet, NULL, NULL, &timeout);
			if (!IS_VALID_SELECT(selectResult))
			{
				throw NetException(__FILE__, __LINE__, ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
			}
			if (selectResult > 0) // recv is possible
			{
				int bytesRecvd = recv(sock, buf.recvBuf + buf.recvBufUsed, bufSize, 0);

				if (!IS_VALID_RECV(bytesRecvd))
				{
					int errCode = SOCKET_ERRNO();
					if (!IS_SOCKET_ERR_WOULDBLOCK(errCode))
						throw NetException(__FILE__, __LINE__, ERR_SOCK_RECV_FAILED, SOCKET_ERRNO());
				}
				else if (bytesRecvd == 0)
				{
					throw NetException(__FILE__, __LINE__, ERR_SOCK_CONN_RESET, 0);
				}
				else
				{
					buf.recvBufUsed += bytesRecvd;
					InternalGetPackets(buf);
				}
			}
		}
	}
	boost::shared_ptr<NetPacket> tmpPacket;
	if (!buf.receivedPackets.empty())
	{
		tmpPacket = buf.receivedPackets.front();
		buf.receivedPackets.pop_front();
	}
	return tmpPacket;
}

void
ReceiverHelper::InternalGetPackets(ReceiveBuffer &buf)
{
	bool dataAvailable = true;
	do
	{
		boost::shared_ptr<NetPacket> tmpPacket;
		// This is necessary, because we use TCP.
		// Packets may be received in multiple chunks or
		// several packets may be received at once.
		if (buf.recvBufUsed >= MIN_PACKET_SIZE)
		{
			try
			{
				// This call will also handle the memmove stuff, i.e.
				// buffering for partial packets.
				tmpPacket = NetPacket::Create(buf.recvBuf, buf.recvBufUsed);
			} catch (const NetException &e)
			{
				// Reset buffer on error.
				buf.recvBufUsed = 0;
				LOG_ERR(e.what());
			}
		}
		if (tmpPacket.get())
			buf.receivedPackets.push_back(tmpPacket);
		else
			dataAvailable = false;
	} while(dataAvailable);
}

<commit_msg>Fixed typo.<commit_after>/***************************************************************************
 *   Copyright (C) 2007 by Lothar May                                      *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifdef _WIN32
	#define FD_SETSIZE 512
#endif

#include <net/receiverhelper.h>
#include <net/socket_msg.h>
#include <net/netexception.h>
#include <core/loghelper.h>
#include <cstring>

using namespace std;

ReceiverHelper::ReceiverHelper()
{
}

ReceiverHelper::~ReceiverHelper()
{
}

boost::shared_ptr<NetPacket>
ReceiverHelper::Recv(SOCKET sock, ReceiveBuffer &buf)
{
	if (buf.receivedPackets.empty())
	{
		int bufSize = RECV_BUF_SIZE - buf.recvBufUsed;

		if (bufSize > 0) // check if there is room in the input buffer
		{
			fd_set readSet;
			struct timeval timeout;

			FD_ZERO(&readSet);
			FD_SET(sock, &readSet);

			timeout.tv_sec  = 0;
			timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000;
			int selectResult = select(sock + 1, &readSet, NULL, NULL, &timeout);
			if (!IS_VALID_SELECT(selectResult))
			{
				throw NetException(__FILE__, __LINE__, ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
			}
			if (selectResult > 0) // recv is possible
			{
				int bytesRecvd = recv(sock, buf.recvBuf + buf.recvBufUsed, bufSize, 0);

				if (!IS_VALID_RECV(bytesRecvd))
				{
					int errCode = SOCKET_ERRNO();
					if (!IS_SOCKET_ERR_WOULDBLOCK(errCode))
						throw NetException(__FILE__, __LINE__, ERR_SOCK_RECV_FAILED, SOCKET_ERRNO());
				}
				else if (bytesRecvd == 0)
				{
					throw NetException(__FILE__, __LINE__, ERR_SOCK_CONN_RESET, 0);
				}
				else
				{
					buf.recvBufUsed += bytesRecvd;
					InternalGetPackets(buf);
				}
			}
		}
	}
	boost::shared_ptr<NetPacket> tmpPacket;
	if (!buf.receivedPackets.empty())
	{
		tmpPacket = buf.receivedPackets.front();
		buf.receivedPackets.pop_front();
	}
	return tmpPacket;
}

void
ReceiverHelper::InternalGetPackets(ReceiveBuffer &buf)
{
	bool dataAvailable = true;
	do
	{
		boost::shared_ptr<NetPacket> tmpPacket;
		// This is necessary, because we use TCP.
		// Packets may be received in multiple chunks or
		// several packets may be received at once.
		if (buf.recvBufUsed >= MIN_PACKET_SIZE)
		{
			try
			{
				// This call will also handle the memmove stuff, i.e.
				// buffering for partial packets.
				tmpPacket = NetPacket::Create(buf.recvBuf, buf.recvBufUsed);
			} catch (const NetException &e)
			{
				// Reset buffer on error.
				buf.recvBufUsed = 0;
				LOG_ERROR(e.what());
			}
		}
		if (tmpPacket.get())
			buf.receivedPackets.push_back(tmpPacket);
		else
			dataAvailable = false;
	} while(dataAvailable);
}

<|endoftext|>