<commit_before>//
//  yas_db_object_event.cpp
//

#include "yas_db_object_event.h"

#include "yas_db_object.h"

using namespace yas;
using namespace yas::db;

namespace yas::db {
static db::object_ptr const _empty_object = nullptr;
static db::object_id const _empty_object_id = nullptr;
static std::string const _empty_string;
static std::vector<std::size_t> const _empty_indices;
static db::value const _empty_value = nullptr;

struct object_fetched_event {
    static object_event_type const type = object_event_type::fetched;
    db::object_ptr const &object;
};

struct object_loaded_event {
    static object_event_type const type = object_event_type::loaded;
    db::object_ptr const &object;
};

struct object_cleared_event {
    static object_event_type const type = object_event_type::cleared;
    db::object_ptr const &object;
};

struct object_attribute_updated_event {
    static object_event_type const type = object_event_type::attribute_updated;
    db::object_ptr const &object;
    std::string const name;
    db::value const &value;
};

struct object_relation_inserted_event {
    static object_event_type const type = object_event_type::relation_inserted;
    db::object_ptr const &object;
    std::string const name;
    std::vector<std::size_t> const indices;
};

struct object_relation_removed_event {
    static object_event_type const type = object_event_type::relation_removed;
    db::object_ptr const &object;
    std::string const name;
    std::vector<std::size_t> const indices;
};

struct object_relation_replaced_event {
    static object_event_type const type = object_event_type::relation_replaced;
    db::object_ptr const &object;
    std::string const name;
};

struct object_erased_event {
    static object_event_type const type = object_event_type::erased;
    std::string const &entity_name;
    db::object_id const &object_id;
};
}  // namespace yas::db

object_event db::object_event::make_fetched(db::object_ptr const &object) {
    return object_event{object_fetched_event{.object = object}};
}

object_event db::object_event::make_loaded(db::object_ptr const &object) {
    return object_event{object_loaded_event{.object = object}};
}

object_event db::object_event::make_cleared(db::object_ptr const &object) {
    return object_event{object_cleared_event{.object = object}};
}

object_event db::object_event::make_attribute_updated(db::object_ptr const &object, std::string const &name,
                                                      db::value const &value) {
    return object_event{object_attribute_updated_event{.object = object, .name = name, .value = value}};
}

object_event db::object_event::make_relation_inserted(db::object_ptr const &object, std::string const &name,
                                                      std::vector<std::size_t> &&indices) {
    return object_event{object_relation_inserted_event{.object = object, .name = name, .indices = std::move(indices)}};
}

object_event db::object_event::make_relation_removed(db::object_ptr const &object, std::string const &name,
                                                     std::vector<std::size_t> &&indices) {
    return object_event{object_relation_removed_event{.object = object, .name = name, .indices = std::move(indices)}};
}

object_event db::object_event::make_relation_replaced(db::object_ptr const &object, std::string const &name) {
    return object_event{object_relation_replaced_event{.object = object, .name = name}};
}

object_event db::object_event::make_erased(std::string const &entity_name, db::object_id const &object_id) {
    return object_event{object_erased_event{.entity_name = entity_name, .object_id = object_id}};
}

struct object_event::impl_base {
    virtual object_event_type type() {
        throw std::runtime_error("type() must be overridden");
    }
};

template <typename Event>
struct object_event::impl : object_event::impl_base {
    Event const event;

    impl(Event &&event) : event(std::move(event)) {
    }

    object_event_type type() override {
        return Event::type;
    }
};

object_event::object_event(std::shared_ptr<impl_base> &&impl)
    : _impl(std::move(impl)),
      _type(object_event_type::fetched),
      _object(_empty_object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_fetched_event &&event)
    : _type(object_event_type::fetched),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_loaded_event &&event)
    : _type(object_event_type::loaded),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_cleared_event &&event)
    : _type(object_event_type::cleared),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_attribute_updated_event &&event)
    : _type(object_event_type::attribute_updated),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(event.value) {
}

object_event::object_event(object_relation_inserted_event &&event)
    : _type(object_event_type::relation_inserted),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(event.indices),
      _value(_empty_value) {
}

object_event::object_event(object_relation_removed_event &&event)
    : _type(object_event_type::relation_removed),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(event.indices),
      _value(_empty_value) {
}

object_event::object_event(object_relation_replaced_event &&event)
    : object_event(std::make_shared<impl<object_relation_replaced_event>>(std::move(event))) {
}

object_event::object_event(object_erased_event &&event)
    : object_event(std::make_shared<impl<object_erased_event>>(std::move(event))) {
}

object_event_type object_event::type() const {
    return this->_impl->type();
}

template <typename Event>
Event const &object_event::get() const {
    if (auto ip = std::dynamic_pointer_cast<impl<Event>>(this->_impl)) {
        return ip->event;
    }

    throw std::runtime_error("get event failed.");
}

bool object_event::is_changed() const {
    switch (this->type()) {
        case object_event_type::attribute_updated:
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::relation_replaced:
            return true;
        default:
            return false;
    }
}

bool object_event::is_erased() const {
    return this->type() == object_event_type::erased;
}

db::object_ptr const &object_event::object() const {
    switch (this->type()) {
        case object_event_type::fetched:
            return this->get<db::object_fetched_event>().object;
        case object_event_type::loaded:
            return this->get<db::object_loaded_event>().object;
        case object_event_type::cleared:
            return this->get<db::object_cleared_event>().object;
        case object_event_type::attribute_updated:
            return this->get<db::object_attribute_updated_event>().object;
        case object_event_type::relation_inserted:
            return this->get<db::object_relation_inserted_event>().object;
        case object_event_type::relation_removed:
            return this->get<db::object_relation_removed_event>().object;
        case object_event_type::relation_replaced:
            return this->get<db::object_relation_replaced_event>().object;
        case object_event_type::erased:
            throw std::runtime_error("object not found.");
    }
}

db::object_id const &object_event::object_id() const {
    switch (this->type()) {
        case object_event_type::erased:
            return this->get<db::object_erased_event>().object_id;
        case object_event_type::attribute_updated:
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::relation_replaced:
            return this->object()->object_id();
    }
}

std::string const &object_event::name() const {
    switch (this->type()) {
        case object_event_type::attribute_updated:
            return this->get<db::object_attribute_updated_event>().name;
        case object_event_type::relation_inserted:
            return this->get<db::object_relation_inserted_event>().name;
        case object_event_type::relation_removed:
            return this->get<db::object_relation_removed_event>().name;
        case object_event_type::relation_replaced:
            return this->get<db::object_relation_replaced_event>().name;
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::erased:
            throw std::runtime_error("name not found.");
    }
}

std::string const &object_event::entity_name() const {
    switch (this->type()) {
        case object_event_type::erased:
            return this->get<db::object_erased_event>().entity_name;
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::attribute_updated:
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::relation_replaced:
            throw std::runtime_error("entity name not found.");
    }
}

std::vector<std::size_t> const &object_event::indices() const {
    switch (this->type()) {
        case object_event_type::relation_inserted:
            return this->get<db::object_relation_inserted_event>().indices;
        case object_event_type::relation_removed:
            return this->get<db::object_relation_removed_event>().indices;
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::attribute_updated:
        case object_event_type::relation_replaced:
        case object_event_type::erased:
            throw std::runtime_error("indices not found.");
    }
}

db::value const &object_event::value() const {
    switch (this->type()) {
        case object_event_type::attribute_updated:
            return this->get<db::object_attribute_updated_event>().value;
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::relation_replaced:
        case object_event_type::erased:
            throw std::runtime_error("indices not found.");
    }
}

template db::object_fetched_event const &object_event::get<db::object_fetched_event>() const;
template db::object_loaded_event const &object_event::get<db::object_loaded_event>() const;
template db::object_cleared_event const &object_event::get<db::object_cleared_event>() const;
template db::object_attribute_updated_event const &object_event::get<db::object_attribute_updated_event>() const;
template db::object_relation_inserted_event const &object_event::get<db::object_relation_inserted_event>() const;
template db::object_relation_removed_event const &object_event::get<db::object_relation_removed_event>() const;
template db::object_relation_replaced_event const &object_event::get<db::object_relation_replaced_event>() const;
template db::object_erased_event const &object_event::get<db::object_erased_event>() const;
<commit_msg>relation_replaced_event<commit_after>//
//  yas_db_object_event.cpp
//

#include "yas_db_object_event.h"

#include "yas_db_object.h"

using namespace yas;
using namespace yas::db;

namespace yas::db {
static db::object_ptr const _empty_object = nullptr;
static db::object_id const _empty_object_id = nullptr;
static std::string const _empty_string;
static std::vector<std::size_t> const _empty_indices;
static db::value const _empty_value = nullptr;

struct object_fetched_event {
    static object_event_type const type = object_event_type::fetched;
    db::object_ptr const &object;
};

struct object_loaded_event {
    static object_event_type const type = object_event_type::loaded;
    db::object_ptr const &object;
};

struct object_cleared_event {
    static object_event_type const type = object_event_type::cleared;
    db::object_ptr const &object;
};

struct object_attribute_updated_event {
    static object_event_type const type = object_event_type::attribute_updated;
    db::object_ptr const &object;
    std::string const name;
    db::value const &value;
};

struct object_relation_inserted_event {
    static object_event_type const type = object_event_type::relation_inserted;
    db::object_ptr const &object;
    std::string const name;
    std::vector<std::size_t> const indices;
};

struct object_relation_removed_event {
    static object_event_type const type = object_event_type::relation_removed;
    db::object_ptr const &object;
    std::string const name;
    std::vector<std::size_t> const indices;
};

struct object_relation_replaced_event {
    static object_event_type const type = object_event_type::relation_replaced;
    db::object_ptr const &object;
    std::string const name;
};

struct object_erased_event {
    static object_event_type const type = object_event_type::erased;
    std::string const &entity_name;
    db::object_id const &object_id;
};
}  // namespace yas::db

object_event db::object_event::make_fetched(db::object_ptr const &object) {
    return object_event{object_fetched_event{.object = object}};
}

object_event db::object_event::make_loaded(db::object_ptr const &object) {
    return object_event{object_loaded_event{.object = object}};
}

object_event db::object_event::make_cleared(db::object_ptr const &object) {
    return object_event{object_cleared_event{.object = object}};
}

object_event db::object_event::make_attribute_updated(db::object_ptr const &object, std::string const &name,
                                                      db::value const &value) {
    return object_event{object_attribute_updated_event{.object = object, .name = name, .value = value}};
}

object_event db::object_event::make_relation_inserted(db::object_ptr const &object, std::string const &name,
                                                      std::vector<std::size_t> &&indices) {
    return object_event{object_relation_inserted_event{.object = object, .name = name, .indices = std::move(indices)}};
}

object_event db::object_event::make_relation_removed(db::object_ptr const &object, std::string const &name,
                                                     std::vector<std::size_t> &&indices) {
    return object_event{object_relation_removed_event{.object = object, .name = name, .indices = std::move(indices)}};
}

object_event db::object_event::make_relation_replaced(db::object_ptr const &object, std::string const &name) {
    return object_event{object_relation_replaced_event{.object = object, .name = name}};
}

object_event db::object_event::make_erased(std::string const &entity_name, db::object_id const &object_id) {
    return object_event{object_erased_event{.entity_name = entity_name, .object_id = object_id}};
}

struct object_event::impl_base {
    virtual object_event_type type() {
        throw std::runtime_error("type() must be overridden");
    }
};

template <typename Event>
struct object_event::impl : object_event::impl_base {
    Event const event;

    impl(Event &&event) : event(std::move(event)) {
    }

    object_event_type type() override {
        return Event::type;
    }
};

object_event::object_event(std::shared_ptr<impl_base> &&impl)
    : _impl(std::move(impl)),
      _type(object_event_type::fetched),
      _object(_empty_object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_fetched_event &&event)
    : _type(object_event_type::fetched),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_loaded_event &&event)
    : _type(object_event_type::loaded),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_cleared_event &&event)
    : _type(object_event_type::cleared),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(_empty_string),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_attribute_updated_event &&event)
    : _type(object_event_type::attribute_updated),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(event.value) {
}

object_event::object_event(object_relation_inserted_event &&event)
    : _type(object_event_type::relation_inserted),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(event.indices),
      _value(_empty_value) {
}

object_event::object_event(object_relation_removed_event &&event)
    : _type(object_event_type::relation_removed),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(event.indices),
      _value(_empty_value) {
}

object_event::object_event(object_relation_replaced_event &&event)
    : _type(object_event_type::relation_replaced),
      _object(event.object),
      _object_id(_empty_object_id),
      _name(event.name),
      _entity_name(_empty_string),
      _indices(_empty_indices),
      _value(_empty_value) {
}

object_event::object_event(object_erased_event &&event)
    : object_event(std::make_shared<impl<object_erased_event>>(std::move(event))) {
}

object_event_type object_event::type() const {
    return this->_impl->type();
}

template <typename Event>
Event const &object_event::get() const {
    if (auto ip = std::dynamic_pointer_cast<impl<Event>>(this->_impl)) {
        return ip->event;
    }

    throw std::runtime_error("get event failed.");
}

bool object_event::is_changed() const {
    switch (this->type()) {
        case object_event_type::attribute_updated:
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::relation_replaced:
            return true;
        default:
            return false;
    }
}

bool object_event::is_erased() const {
    return this->type() == object_event_type::erased;
}

db::object_ptr const &object_event::object() const {
    switch (this->type()) {
        case object_event_type::fetched:
            return this->get<db::object_fetched_event>().object;
        case object_event_type::loaded:
            return this->get<db::object_loaded_event>().object;
        case object_event_type::cleared:
            return this->get<db::object_cleared_event>().object;
        case object_event_type::attribute_updated:
            return this->get<db::object_attribute_updated_event>().object;
        case object_event_type::relation_inserted:
            return this->get<db::object_relation_inserted_event>().object;
        case object_event_type::relation_removed:
            return this->get<db::object_relation_removed_event>().object;
        case object_event_type::relation_replaced:
            return this->get<db::object_relation_replaced_event>().object;
        case object_event_type::erased:
            throw std::runtime_error("object not found.");
    }
}

db::object_id const &object_event::object_id() const {
    switch (this->type()) {
        case object_event_type::erased:
            return this->get<db::object_erased_event>().object_id;
        case object_event_type::attribute_updated:
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::relation_replaced:
            return this->object()->object_id();
    }
}

std::string const &object_event::name() const {
    switch (this->type()) {
        case object_event_type::attribute_updated:
            return this->get<db::object_attribute_updated_event>().name;
        case object_event_type::relation_inserted:
            return this->get<db::object_relation_inserted_event>().name;
        case object_event_type::relation_removed:
            return this->get<db::object_relation_removed_event>().name;
        case object_event_type::relation_replaced:
            return this->get<db::object_relation_replaced_event>().name;
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::erased:
            throw std::runtime_error("name not found.");
    }
}

std::string const &object_event::entity_name() const {
    switch (this->type()) {
        case object_event_type::erased:
            return this->get<db::object_erased_event>().entity_name;
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::attribute_updated:
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::relation_replaced:
            throw std::runtime_error("entity name not found.");
    }
}

std::vector<std::size_t> const &object_event::indices() const {
    switch (this->type()) {
        case object_event_type::relation_inserted:
            return this->get<db::object_relation_inserted_event>().indices;
        case object_event_type::relation_removed:
            return this->get<db::object_relation_removed_event>().indices;
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::attribute_updated:
        case object_event_type::relation_replaced:
        case object_event_type::erased:
            throw std::runtime_error("indices not found.");
    }
}

db::value const &object_event::value() const {
    switch (this->type()) {
        case object_event_type::attribute_updated:
            return this->get<db::object_attribute_updated_event>().value;
        case object_event_type::relation_inserted:
        case object_event_type::relation_removed:
        case object_event_type::fetched:
        case object_event_type::loaded:
        case object_event_type::cleared:
        case object_event_type::relation_replaced:
        case object_event_type::erased:
            throw std::runtime_error("indices not found.");
    }
}

template db::object_fetched_event const &object_event::get<db::object_fetched_event>() const;
template db::object_loaded_event const &object_event::get<db::object_loaded_event>() const;
template db::object_cleared_event const &object_event::get<db::object_cleared_event>() const;
template db::object_attribute_updated_event const &object_event::get<db::object_attribute_updated_event>() const;
template db::object_relation_inserted_event const &object_event::get<db::object_relation_inserted_event>() const;
template db::object_relation_removed_event const &object_event::get<db::object_relation_removed_event>() const;
template db::object_relation_replaced_event const &object_event::get<db::object_relation_replaced_event>() const;
template db::object_erased_event const &object_event::get<db::object_erased_event>() const;
<|endoftext|>


<commit_before>/*
  Copyright 2008 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the software's owners nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  (This is the Modified BSD License)
*/

#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>

#include <OpenEXR/half.h>

#include <cmath>

#include "OpenImageIO/imagebuf.h"
#include "OpenImageIO/imagebufalgo.h"
#include "OpenImageIO/imagebufalgo_util.h"
#include "OpenImageIO/dassert.h"
#include "OpenImageIO/sysutil.h"
#include "OpenImageIO/filter.h"
#include "OpenImageIO/thread.h"
#include "OpenImageIO/filesystem.h"

#ifdef USE_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#endif

OIIO_NAMESPACE_ENTER {

#ifdef USE_FREETYPE
namespace { // anon
static mutex ft_mutex;
static FT_Library ft_library = NULL;
static bool ft_broken = false;
static const char * default_font_name[] = {
        "cour", "Courier New", "FreeMono", NULL
     };
} // anon namespace
#endif

bool
ImageBufAlgo::render_text (ImageBuf &R, int x, int y, string_view text,
                           int fontsize, string_view font_,
                           const float *textcolor)
{
    if (R.spec().depth > 1) {
        R.error ("ImageBufAlgo::render_text does not support volume images");
        return false;
    }

#ifdef USE_FREETYPE
    // If we know FT is broken, don't bother trying again
    if (ft_broken)
        return false;

    // Thread safety
    lock_guard ft_lock (ft_mutex);
    int error = 0;

    // If FT not yet initialized, do it now.
    if (! ft_library) {
        error = FT_Init_FreeType (&ft_library);
        if (error) {
            ft_broken = true;
            R.error ("Could not initialize FreeType for font rendering");
            return false;
        }
    }

    // A set of likely directories for fonts to live, across several systems.
    std::vector<std::string> search_dirs;
    const char *home = getenv ("HOME");
    if (home && *home) {
        std::string h (home);
        search_dirs.push_back (h + "/fonts");
        search_dirs.push_back (h + "/Fonts");
        search_dirs.push_back (h + "/Library/Fonts");
    }
    const char *systemRoot = getenv ("SystemRoot");
    if (systemRoot && *systemRoot) {
        std::string sysroot (systemRoot);
        search_dirs.push_back (sysroot + "/Fonts");
    }
    search_dirs.push_back ("/usr/share/fonts");
    search_dirs.push_back ("/Library/Fonts");
    search_dirs.push_back ("C:/Windows/Fonts");
    search_dirs.push_back ("/opt/local/share/fonts");

    // Try to find the font.  Experiment with several extensions
    std::string font = font_;
    if (font.empty()) {
        // nothing specified -- look for something to use as a default.
        for (int j = 0;  default_font_name[j] && font.empty(); ++j) {
            static const char *extensions[] = { "", ".ttf", ".pfa", ".pfb", NULL };
            for (int i = 0;  font.empty() && extensions[i];  ++i)
                font = Filesystem::searchpath_find (std::string(default_font_name[j])+extensions[i],
                                                 search_dirs, true, true);
        }
        if (font.empty()) {
            R.error ("Could not set default font face");
            return false;
        }
    } else if (Filesystem::is_regular (font)) {
        // directly specified a filename -- use it
    } else {
        // A font name was specified but it's not a full path, look for it
        std::string f;
        static const char *extensions[] = { "", ".ttf", ".pfa", ".pfb", NULL };
        for (int i = 0;  f.empty() && extensions[i];  ++i)
            f = Filesystem::searchpath_find (font+extensions[i],
                                             search_dirs, true, true);
        if (f.empty()) {
            R.error ("Could not set font face to \"%s\"", font);
            return false;
        }
        font = f;
    }

    ASSERT (! font.empty());
    if (! Filesystem::is_regular (font)) {
        R.error ("Could not find font \"%s\"", font);
        return false;
    }

    FT_Face face;      // handle to face object
    error = FT_New_Face (ft_library, font.c_str(), 0 /* face index */, &face);
    if (error) {
        R.error ("Could not set font face to \"%s\"", font);
        return false;  // couldn't open the face
    }

    error = FT_Set_Pixel_Sizes (face,        // handle to face object
                                0,           // pixel_width
                                fontsize);   // pixel_heigh
    if (error) {
        FT_Done_Face (face);
        R.error ("Could not set font size to %d", fontsize);
        return false;  // couldn't set the character size
    }

    FT_GlyphSlot slot = face->glyph;  // a small shortcut
    int nchannels = R.spec().nchannels;
    float *pixelcolor = ALLOCA (float, nchannels);
    if (! textcolor) {
        float *localtextcolor = ALLOCA (float, nchannels);
        for (int c = 0;  c < nchannels;  ++c)
            localtextcolor[c] = 1.0f;
        textcolor = localtextcolor;
    }

    for (size_t n = 0, e = text.size();  n < e;  ++n) {
        // load glyph image into the slot (erase previous one)
        error = FT_Load_Char (face, text[n], FT_LOAD_RENDER);
        if (error)
            continue;  // ignore errors
        // now, draw to our target surface
        for (int j = 0;  j < slot->bitmap.rows; ++j) {
            int ry = y + j - slot->bitmap_top;
            for (int i = 0;  i < slot->bitmap.width; ++i) {
                int rx = x + i + slot->bitmap_left;
                float b = slot->bitmap.buffer[slot->bitmap.pitch*j+i] / 255.0f;
                R.getpixel (rx, ry, pixelcolor);
                for (int c = 0;  c < nchannels;  ++c)
                    pixelcolor[c] = b*textcolor[c] + (1.0f-b) * pixelcolor[c];
                R.setpixel (rx, ry, pixelcolor);
            }
        }
        // increment pen position
        x += slot->advance.x >> 6;
    }

    FT_Done_Face (face);
    return true;

#else
    R.error ("OpenImageIO was not compiled with FreeType for font rendering");
    return false;   // Font rendering not supported
#endif
}

} OIIO_NAMESPACE_EXIT
<commit_msg>Fix build with freetype>=2.5.4<commit_after>/*
  Copyright 2008 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the software's owners nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  (This is the Modified BSD License)
*/

#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>

#include <OpenEXR/half.h>

#include <cmath>

#include "OpenImageIO/imagebuf.h"
#include "OpenImageIO/imagebufalgo.h"
#include "OpenImageIO/imagebufalgo_util.h"
#include "OpenImageIO/dassert.h"
#include "OpenImageIO/sysutil.h"
#include "OpenImageIO/filter.h"
#include "OpenImageIO/thread.h"
#include "OpenImageIO/filesystem.h"

#ifdef USE_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#endif

OIIO_NAMESPACE_ENTER {

#ifdef USE_FREETYPE
namespace { // anon
static mutex ft_mutex;
static FT_Library ft_library = NULL;
static bool ft_broken = false;
static const char * default_font_name[] = {
        "cour", "Courier New", "FreeMono", NULL
     };
} // anon namespace
#endif

bool
ImageBufAlgo::render_text (ImageBuf &R, int x, int y, string_view text,
                           int fontsize, string_view font_,
                           const float *textcolor)
{
    if (R.spec().depth > 1) {
        R.error ("ImageBufAlgo::render_text does not support volume images");
        return false;
    }

#ifdef USE_FREETYPE
    // If we know FT is broken, don't bother trying again
    if (ft_broken)
        return false;

    // Thread safety
    lock_guard ft_lock (ft_mutex);
    int error = 0;

    // If FT not yet initialized, do it now.
    if (! ft_library) {
        error = FT_Init_FreeType (&ft_library);
        if (error) {
            ft_broken = true;
            R.error ("Could not initialize FreeType for font rendering");
            return false;
        }
    }

    // A set of likely directories for fonts to live, across several systems.
    std::vector<std::string> search_dirs;
    const char *home = getenv ("HOME");
    if (home && *home) {
        std::string h (home);
        search_dirs.push_back (h + "/fonts");
        search_dirs.push_back (h + "/Fonts");
        search_dirs.push_back (h + "/Library/Fonts");
    }
    const char *systemRoot = getenv ("SystemRoot");
    if (systemRoot && *systemRoot) {
        std::string sysroot (systemRoot);
        search_dirs.push_back (sysroot + "/Fonts");
    }
    search_dirs.push_back ("/usr/share/fonts");
    search_dirs.push_back ("/Library/Fonts");
    search_dirs.push_back ("C:/Windows/Fonts");
    search_dirs.push_back ("/opt/local/share/fonts");

    // Try to find the font.  Experiment with several extensions
    std::string font = font_;
    if (font.empty()) {
        // nothing specified -- look for something to use as a default.
        for (int j = 0;  default_font_name[j] && font.empty(); ++j) {
            static const char *extensions[] = { "", ".ttf", ".pfa", ".pfb", NULL };
            for (int i = 0;  font.empty() && extensions[i];  ++i)
                font = Filesystem::searchpath_find (std::string(default_font_name[j])+extensions[i],
                                                 search_dirs, true, true);
        }
        if (font.empty()) {
            R.error ("Could not set default font face");
            return false;
        }
    } else if (Filesystem::is_regular (font)) {
        // directly specified a filename -- use it
    } else {
        // A font name was specified but it's not a full path, look for it
        std::string f;
        static const char *extensions[] = { "", ".ttf", ".pfa", ".pfb", NULL };
        for (int i = 0;  f.empty() && extensions[i];  ++i)
            f = Filesystem::searchpath_find (font+extensions[i],
                                             search_dirs, true, true);
        if (f.empty()) {
            R.error ("Could not set font face to \"%s\"", font);
            return false;
        }
        font = f;
    }

    ASSERT (! font.empty());
    if (! Filesystem::is_regular (font)) {
        R.error ("Could not find font \"%s\"", font);
        return false;
    }

    FT_Face face;      // handle to face object
    error = FT_New_Face (ft_library, font.c_str(), 0 /* face index */, &face);
    if (error) {
        R.error ("Could not set font face to \"%s\"", font);
        return false;  // couldn't open the face
    }

    error = FT_Set_Pixel_Sizes (face,        // handle to face object
                                0,           // pixel_width
                                fontsize);   // pixel_heigh
    if (error) {
        FT_Done_Face (face);
        R.error ("Could not set font size to %d", fontsize);
        return false;  // couldn't set the character size
    }

    FT_GlyphSlot slot = face->glyph;  // a small shortcut
    int nchannels = R.spec().nchannels;
    float *pixelcolor = ALLOCA (float, nchannels);
    if (! textcolor) {
        float *localtextcolor = ALLOCA (float, nchannels);
        for (int c = 0;  c < nchannels;  ++c)
            localtextcolor[c] = 1.0f;
        textcolor = localtextcolor;
    }

    for (size_t n = 0, e = text.size();  n < e;  ++n) {
        // load glyph image into the slot (erase previous one)
        error = FT_Load_Char (face, text[n], FT_LOAD_RENDER);
        if (error)
            continue;  // ignore errors
        // now, draw to our target surface
        for (int j = 0;  j < static_cast<int>(slot->bitmap.rows); ++j) {
            int ry = y + j - slot->bitmap_top;
            for (int i = 0;  i < static_cast<int>(slot->bitmap.width); ++i) {
                int rx = x + i + slot->bitmap_left;
                float b = slot->bitmap.buffer[slot->bitmap.pitch*j+i] / 255.0f;
                R.getpixel (rx, ry, pixelcolor);
                for (int c = 0;  c < nchannels;  ++c)
                    pixelcolor[c] = b*textcolor[c] + (1.0f-b) * pixelcolor[c];
                R.setpixel (rx, ry, pixelcolor);
            }
        }
        // increment pen position
        x += slot->advance.x >> 6;
    }

    FT_Done_Face (face);
    return true;

#else
    R.error ("OpenImageIO was not compiled with FreeType for font rendering");
    return false;   // Font rendering not supported
#endif
}

} OIIO_NAMESPACE_EXIT
<|endoftext|>


<commit_before>/*
 *
 */

#include "IPyraNet2DLayer.h"
#include <assert.h>

#define UNIFORM_PLUS_MINUS_ONE ( static_cast<OutType>((2.0 * rand())/RAND_MAX - 1.0) )

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer()
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(0),
    overlap(0),
    inhibitorySize(0)
{

}

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer(int receptive, int inhibitory, int overlap, IPyraNetActivationFunction<OutType>* activationFunc)
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(receptive),
    overlap(overlap),
    inhibitorySize(inhibitory)
{
    setActivationFunction(activationFunc);
}

template<class OutType>
IPyraNet2DLayer<OutType>::~IPyraNet2DLayer() {

}

template<class OutType>
void IPyraNet2DLayer<OutType>::initWeights() {

    assert(getParentLayer() != NULL);

    IPyraNetLayer<OutType>* parent = getParentLayer();

    // get parent size
    int parentSize[2];
    parent->getSize(parentSize);

    // we need to have as many weights as the number of neurons in last
    // layer.
    weights.resize(parentSize[0]);

    for (int u = 0; u < parentSize[0]; ++u) {

        weights[u].resize(parentSize[1]);

        for (int v = 0; v < parentSize[1]; ++v) {
            weights[u][v] = UNIFORM_PLUS_MINUS_ONE;
        }
    }
}

template<class OutType>
void IPyraNet2DLayer<OutType>::initBiases() {

    biases.resize(width);

    for (int u = 0; u < width; ++u) {

        biases[u].resize(height);

        for (int v = 0; v < height; ++v) {
            biases[u][v] = UNIFORM_PLUS_MINUS_ONE;
        }
    }
}

template<class OutType>
OutType IPyraNet2DLayer<OutType>::getNeuronOutput(int dimensions, int* neuronLocation) {

    // sanity checks
    assert (dimensions == 2);
    assert (neuronLocation != NULL);
    assert (neuronLocation[0] > 0 && neuronLocation[1] > 0);
    assert (getParentLayer() != NULL);
    assert (getActivationFunction() != NULL);

    // parent layer pointer
    IPyraNetLayer<OutType>* parent = getParentLayer();

    // compute the gap
    const int gap = receptiveSize - overlap;

    // just for compliance with the article
    const int u = neuronLocation[0];
    const int v = neuronLocation[1];

    OutType fieldAccumulator = 0;

    int parentLoc[2];

    // iterate through the neurons inside the receptive field of the previous layer
    // TODO: optimize (bring the condition outside the loop)
    for (int i = (u - 1) * gap + 1; i <= ((u - 1) * gap + receptiveSize); ++i) {

        parentLoc[0] = i;

        for (int j = (v - 1) * gap + 1; j <= ((v - 1) * gap + receptiveSize); ++j) {

            parentLoc[1] = j;

            OutType parentOutput = parent->getNeuronOutput(2, parentLoc);
            OutType weight = weights[i][j];
            OutType bias = biases[u][v];

            fieldAccumulator += parentOutput * weight + bias;
        }
    }

    OutType result = getActivationFunction()->compute(fieldAccumulator);

    return result;
}

template<class OutType>
int IPyraNet2DLayer<OutType>::getDimensions() const {
    return 2;
}

template<class OutType>
void IPyraNet2DLayer<OutType>::getSize(int* size) {
    assert(size != NULL);

    size[0] = width;
    size[1] = height;
}

template<class OutType>
void IPyraNet2DLayer<OutType>::setParentLayer(IPyraNetLayer<OutType>* parent) {

    assert(parent != NULL);
    assert(receptiveSize != 0);
    assert(overlap != 0);

    // calls base class
    IPyraNetLayer<OutType>::setParentLayer(parent);

    const int dims = parent->getDimensions();

    // we can just connect 2d layers to 2d layers
    assert(dims == 2);

    // get parent size
    int parentSize[2];
    parent->getSize(parentSize);

    // compute the gap
    const float gap = static_cast<float>(receptiveSize - overlap);

    width = static_cast<int>(floor(static_cast<float>(parentSize[0] - overlap) / gap));
    height = static_cast<int>(floor(static_cast<float>(parentSize[1] - overlap) / gap));

    // init weights and biases
    initWeights();
    initBiases();
}

// explicit instantiations
template class IPyraNet2DLayer<float>;
template class IPyraNet2DLayer<double>;<commit_msg>Slightly refactored 2D Layer<commit_after>/*
 *
 */

#include "IPyraNet2DLayer.h"
#include <assert.h>

#define UNIFORM_PLUS_MINUS_ONE ( static_cast<OutType>((2.0 * rand())/RAND_MAX - 1.0) )

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer()
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(0),
    overlap(0),
    inhibitorySize(0)
{

}

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer(int receptive, int inhibitory, int overlap, IPyraNetActivationFunction<OutType>* activationFunc)
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(receptive),
    overlap(overlap),
    inhibitorySize(inhibitory)
{
    setActivationFunction(activationFunc);
}

template<class OutType>
IPyraNet2DLayer<OutType>::~IPyraNet2DLayer() {

}

template<class OutType>
void IPyraNet2DLayer<OutType>::initWeights() {

    assert(getParentLayer() != NULL);

    IPyraNetLayer<OutType>* parent = getParentLayer();

    // get parent size
    int parentSize[2];
    parent->getSize(parentSize);

    // we need to have as many weights as the number of neurons in last
    // layer.
    weights.resize(parentSize[0]);

    for (int u = 0; u < parentSize[0]; ++u) {

        weights[u].resize(parentSize[1]);

        for (int v = 0; v < parentSize[1]; ++v) {
            weights[u][v] = UNIFORM_PLUS_MINUS_ONE;
        }
    }
}

template<class OutType>
void IPyraNet2DLayer<OutType>::initBiases() {

    biases.resize(width);

    for (int u = 0; u < width; ++u) {

        biases[u].resize(height);

        for (int v = 0; v < height; ++v) {
            biases[u][v] = UNIFORM_PLUS_MINUS_ONE;
        }
    }
}

template<class OutType>
OutType IPyraNet2DLayer<OutType>::getNeuronOutput(int dimensions, int* neuronLocation) {

    // sanity checks
    assert (dimensions == 2);
    assert (neuronLocation != NULL);
    assert (neuronLocation[0] > 0 && neuronLocation[1] > 0);
    assert (getParentLayer() != NULL);
    assert (getActivationFunction() != NULL);

    // parent layer pointer
    IPyraNetLayer<OutType>* parent = getParentLayer();

    // compute the gap
    const int gap = receptiveSize - overlap;

    // just for compliance with the article
    const int u = neuronLocation[0];
    const int v = neuronLocation[1];

    OutType receptiveAccumulator = 0;
    OutType inhibitoryAccumulator = 0;
    OutType bias = biases[u][v];

    int parentLoc[2];

    // iterate through the neurons inside the receptive field of the previous layer
    const int max_u = (u - 1) * gap + receptiveSize;
    const int max_v = (v - 1) * gap + receptiveSize;

    for (int i = (u - 1) * gap + 1; i <= max_u; ++i) {

        parentLoc[0] = i;

        for (int j = (v - 1) * gap + 1; j <= max_v; ++j) {

            parentLoc[1] = j;

            OutType parentOutput = parent->getNeuronOutput(2, parentLoc);
            OutType weight = weights[i][j];

            receptiveAccumulator += parentOutput * weight;
        }
    }

    // iterate through the neurons inside the inhibitory field
    // TODO

    OutType result = getActivationFunction()->compute(receptiveAccumulator - inhibitoryAccumulator + bias);

    return result;
}

template<class OutType>
int IPyraNet2DLayer<OutType>::getDimensions() const {
    return 2;
}

template<class OutType>
void IPyraNet2DLayer<OutType>::getSize(int* size) {
    assert(size != NULL);

    size[0] = width;
    size[1] = height;
}

template<class OutType>
void IPyraNet2DLayer<OutType>::setParentLayer(IPyraNetLayer<OutType>* parent) {

    assert(parent != NULL);
    assert(receptiveSize != 0);
    assert(overlap != 0);

    // calls base class
    IPyraNetLayer<OutType>::setParentLayer(parent);

    const int dims = parent->getDimensions();

    // we can just connect 2d layers to 2d layers
    assert(dims == 2);

    // get parent size
    int parentSize[2];
    parent->getSize(parentSize);

    // compute the gap
    const float gap = static_cast<float>(receptiveSize - overlap);

    width = static_cast<int>(floor(static_cast<float>(parentSize[0] - overlap) / gap));
    height = static_cast<int>(floor(static_cast<float>(parentSize[1] - overlap) / gap));

    // init weights and biases
    initWeights();
    initBiases();
}

// explicit instantiations
template class IPyraNet2DLayer<float>;
template class IPyraNet2DLayer<double>;<|endoftext|>


<commit_before>#include "btc_ma.h"
#include "../../log/logger.h"
#include "../../network/networkmanager.h"

#include <QDataStream>
#include <numeric>
#include <QtCore/QtMath>

LOGGER(BulkTransportCapacityMA);

BulkTransportCapacityMA::BulkTransportCapacityMA(QObject *parent)
: Measurement(parent)
, m_preTest(true)
, m_tcpSocket(NULL)
, m_lasttime(-1)
, m_status(Unknown)
{
}

bool BulkTransportCapacityMA::start()
{
    m_status = BulkTransportCapacityMA::Running;
    sendInitialRequest();
    return true;
}

void BulkTransportCapacityMA::sendRequest(quint64 bytes)
{
    // invalidate timer
    m_time.invalidate();

    m_bytesExpected = bytes;
    QDataStream out(m_tcpSocket);
    out<<bytes;
}

void BulkTransportCapacityMA::sendInitialRequest()
{
    LOG_INFO("Sending initial data size to server");
    sendRequest(definition->initialDataSize);
}

void BulkTransportCapacityMA::receiveResponse()
{
    qint64 time = m_time.nsecsElapsed();

    // if the timer is not valid this is the first response packet
    if (!m_time.isValid())
    {
        // reset variables
        m_bytesReceived = 0;
        m_lasttime = 0;

        // this packet counts to the total bytes, but not to the measurement bytes in m_bytesReceived
        m_totalBytesReceived = m_tcpSocket->bytesAvailable();

        // ignor the first data received
        m_tcpSocket->readAll();

        m_time.restart();
    }
    else // this is a response within an active measurement
    {
        qint64 bytes = m_tcpSocket->bytesAvailable();
        m_bytesReceivedList<<bytes;
        m_times<<time - m_lasttime;
        m_bytesReceived += bytes;
        m_totalBytesReceived += bytes;
        m_tcpSocket->readAll(); // we don't care for the data-content
        m_lasttime = time;
    }

    // check if all measurement data was received
    if (m_totalBytesReceived >= m_bytesExpected)
    {
        // if this was the pretest we need to calculate the bytes for the real test
        if (m_preTest)
        {
            // get the download speed in kbyte
            qreal downloadSpeed = (m_bytesReceived / 1024.0) / (((m_lasttime / 1000.0) / 1000) / 1000);

            LOG_INFO(QString("Speed (pretest): %1 KByte/s").arg(downloadSpeed, 0, 'f', 0));

            // Calculate new test size
            m_bytesExpected = downloadSpeed * 1024 * 3; // should be <3 seconds if the calculated speed was correct

            m_preTest = false;

            LOG_INFO("Sending test data size to server");

            // set next state
            sendRequest(m_bytesExpected);
        }
        else
        {
            // calculate download speed for n slices
            int slices = 10; // TODO 10 slices, as parameter?
            int slice_size = m_times.size() / slices;

            // counters
            qint64 bytes = 0;
            qint64 time = 0;

            // calculate slices
            for (int i=0; i<m_times.size(); i++)
            {
                bytes += m_bytesReceivedList.at(i);
                time += m_times.at(i);

                if (((i+1) % slice_size) == 0) // calculate a slice
                {
                    qreal speed = (bytes / 1024.0) / (((time / 1000.0) / 1000) / 1000);
                    m_downloadSpeeds<<speed;

                    // reset counters
                    bytes = 0;
                    time = 0;
                }
            }

            // calculate mean speed
            qreal sum = std::accumulate(m_downloadSpeeds.begin(), m_downloadSpeeds.end(), 0.0);
            qreal mean = sum / m_downloadSpeeds.size();
            LOG_INFO(QString("Speed (mean): %1 KByte/s").arg(mean, 0, 'f', 0));

            /* At the moment deactivated
            // calculate standard deviation
            qreal sq_sum = std::inner_product(speeds.begin(), speeds.end(), speeds.begin(), 0.0);
            qreal stdev = qSqrt(sq_sum / speeds.size() - mean * mean);
            LOG_INFO(QString("Standard deviation: %1").arg(stdev, 0, 'f', 0));
            */

            /* At the moment deactivated to get all results
            // get ride of the lower and upper 20%
            qSort(speeds);
            int percentil = slices * 0.2;
            sum = std::accumulate(speeds.begin()+percentil, speeds.end()-percentil, 0.0);
            mean = sum / (speeds.size() - 2 * percentil);
            LOG_INFO(QString("Speed (60 percentil mean): %1 KByte/s").arg(mean, 0, 'f', 0));
            */

            m_status = BulkTransportCapacityMA::Finished;

            emit finished();
        }
    }
}

void BulkTransportCapacityMA::serverDisconnected()
{
    if (m_status != BulkTransportCapacityMA::Finished)
    {
        LOG_WARNING("Server closed connection, this should not happen");
    }
}

void BulkTransportCapacityMA::handleError(QAbstractSocket::SocketError socketError)
{
    if (socketError == QAbstractSocket::RemoteHostClosedError)
    {
        return;
    }

    QAbstractSocket* socket = qobject_cast<QAbstractSocket*>(sender());
    LOG_ERROR(QString("Socket Error: %1").arg(socket->errorString()));
}

Measurement::Status BulkTransportCapacityMA::status() const
{
    return m_status;
}

bool BulkTransportCapacityMA::prepare(NetworkManager *networkManager, const MeasurementDefinitionPtr &measurementDefinition)
{
    definition = measurementDefinition.dynamicCast<BulkTransportCapacityDefinition>();
    if ( definition.isNull() )
    {
        LOG_WARNING("Definition is empty");
    }

    QString hostname = QString("%1:%2").arg(definition->host).arg(definition->port);

    m_tcpSocket = qobject_cast<QTcpSocket*>(networkManager->establishConnection(hostname, "btc_mp", definition->toVariant(), NetworkManager::TcpSocket));
    if (!m_tcpSocket)
    {
        LOG_ERROR("Preparation failed");
        return false;
    }

    m_tcpSocket->setParent(this);
    m_bytesExpected = 0;
    m_preTest = true;

    // Signal for new data
    connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveResponse()));

    // Signal for errors
    connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleError(QAbstractSocket::SocketError)));

    // Signal for end of data transmission
    connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(serverDisconnected()));

    return true;
}

bool BulkTransportCapacityMA::stop()
{
    if (m_tcpSocket)
    {
        m_tcpSocket->disconnectFromHost();
        if (m_tcpSocket->state() != QTcpSocket::UnconnectedState &&
                !m_tcpSocket->waitForDisconnected(1000))
        {
            return false;
        }
    }

    return true;
}

ResultPtr BulkTransportCapacityMA::result() const
{
    QVariantList res;
    foreach(qreal val, m_downloadSpeeds)
    {
        res<<QString::number(val, 'f');
    }

    return ResultPtr(new Result(QDateTime::currentDateTime(), res, QVariant()));
}
<commit_msg>Fixed a bug in the BTC slices<commit_after>#include "btc_ma.h"
#include "../../log/logger.h"
#include "../../network/networkmanager.h"

#include <QDataStream>
#include <numeric>
#include <QtCore/QtMath>

LOGGER(BulkTransportCapacityMA);

BulkTransportCapacityMA::BulkTransportCapacityMA(QObject *parent)
: Measurement(parent)
, m_preTest(true)
, m_tcpSocket(NULL)
, m_lasttime(-1)
, m_status(Unknown)
{
}

bool BulkTransportCapacityMA::start()
{
    m_status = BulkTransportCapacityMA::Running;
    sendInitialRequest();
    return true;
}

void BulkTransportCapacityMA::sendRequest(quint64 bytes)
{
    // invalidate timer
    m_time.invalidate();

    m_bytesExpected = bytes;
    QDataStream out(m_tcpSocket);
    out<<bytes;
}

void BulkTransportCapacityMA::sendInitialRequest()
{
    LOG_INFO("Sending initial data size to server");
    sendRequest(definition->initialDataSize);
}

void BulkTransportCapacityMA::receiveResponse()
{
    qint64 time = m_time.nsecsElapsed();

    // if the timer is not valid this is the first response packet
    if (!m_time.isValid())
    {
        // reset variables
        m_bytesReceived = 0;
        m_lasttime = 0;

        // this packet counts to the total bytes, but not to the measurement bytes in m_bytesReceived
        m_totalBytesReceived = m_tcpSocket->bytesAvailable();

        // ignor the first data received
        m_tcpSocket->readAll();

        m_time.restart();
    }
    else // this is a response within an active measurement
    {
        qint64 bytes = m_tcpSocket->bytesAvailable();
        m_bytesReceivedList<<bytes;
        m_times<<time - m_lasttime;
        m_bytesReceived += bytes;
        m_totalBytesReceived += bytes;
        m_tcpSocket->readAll(); // we don't care for the data-content
        m_lasttime = time;
    }

    // check if all measurement data was received
    if (m_totalBytesReceived >= m_bytesExpected)
    {
        // if this was the pretest we need to calculate the bytes for the real test
        if (m_preTest)
        {
            // get the download speed in kbyte
            qreal downloadSpeed = (m_bytesReceived / 1024.0) / (((m_lasttime / 1000.0) / 1000) / 1000);

            LOG_INFO(QString("Speed (pretest): %1 KByte/s").arg(downloadSpeed, 0, 'f', 0));

            // Calculate new test size
            m_bytesExpected = downloadSpeed * 1024 * 3; // should be <3 seconds if the calculated speed was correct

            m_preTest = false;

            LOG_INFO("Sending test data size to server");

            // set next state
            sendRequest(m_bytesExpected);
        }
        else
        {
            // calculate download speed for n slices
            int slices = 10; // TODO 10 slices, as parameter?
            int slice_size = ceil((double)m_times.size() / slices); // round up to get the correct number of slices

            // counters
            qint64 bytes = 0;
            qint64 time = 0;

            // calculate slices
            for (int i=0; i<m_times.size(); i++)
            {
                bytes += m_bytesReceivedList.at(i);
                time += m_times.at(i);

                // calculate a slice if enough samples are added up or if this is the last iteration
                if (((i+1) % slice_size) == 0 || i == m_times.size() - 1) // calculate a slice
                {
                    qreal speed = (bytes / 1024.0) / (((time / 1000.0) / 1000) / 1000);
                    m_downloadSpeeds<<speed;

                    // reset counters
                    bytes = 0;
                    time = 0;
                }
            }

            // calculate mean speed
            qreal sum = std::accumulate(m_downloadSpeeds.begin(), m_downloadSpeeds.end(), 0.0);
            qreal mean = sum / m_downloadSpeeds.size();
            LOG_INFO(QString("Speed (mean): %1 KByte/s").arg(mean, 0, 'f', 0));

            /* At the moment deactivated
            // calculate standard deviation
            qreal sq_sum = std::inner_product(speeds.begin(), speeds.end(), speeds.begin(), 0.0);
            qreal stdev = qSqrt(sq_sum / speeds.size() - mean * mean);
            LOG_INFO(QString("Standard deviation: %1").arg(stdev, 0, 'f', 0));
            */

            /* At the moment deactivated to get all results
            // get ride of the lower and upper 20%
            qSort(speeds);
            int percentil = slices * 0.2;
            sum = std::accumulate(speeds.begin()+percentil, speeds.end()-percentil, 0.0);
            mean = sum / (speeds.size() - 2 * percentil);
            LOG_INFO(QString("Speed (60 percentil mean): %1 KByte/s").arg(mean, 0, 'f', 0));
            */

            m_status = BulkTransportCapacityMA::Finished;

            emit finished();
        }
    }
}

void BulkTransportCapacityMA::serverDisconnected()
{
    if (m_status != BulkTransportCapacityMA::Finished)
    {
        LOG_WARNING("Server closed connection, this should not happen");
    }
}

void BulkTransportCapacityMA::handleError(QAbstractSocket::SocketError socketError)
{
    if (socketError == QAbstractSocket::RemoteHostClosedError)
    {
        return;
    }

    QAbstractSocket* socket = qobject_cast<QAbstractSocket*>(sender());
    LOG_ERROR(QString("Socket Error: %1").arg(socket->errorString()));
}

Measurement::Status BulkTransportCapacityMA::status() const
{
    return m_status;
}

bool BulkTransportCapacityMA::prepare(NetworkManager *networkManager, const MeasurementDefinitionPtr &measurementDefinition)
{
    definition = measurementDefinition.dynamicCast<BulkTransportCapacityDefinition>();
    if ( definition.isNull() )
    {
        LOG_WARNING("Definition is empty");
    }

    QString hostname = QString("%1:%2").arg(definition->host).arg(definition->port);

    m_tcpSocket = qobject_cast<QTcpSocket*>(networkManager->establishConnection(hostname, "btc_mp", definition->toVariant(), NetworkManager::TcpSocket));
    if (!m_tcpSocket)
    {
        LOG_ERROR("Preparation failed");
        return false;
    }

    m_tcpSocket->setParent(this);
    m_bytesExpected = 0;
    m_preTest = true;

    // Signal for new data
    connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveResponse()));

    // Signal for errors
    connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleError(QAbstractSocket::SocketError)));

    // Signal for end of data transmission
    connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(serverDisconnected()));

    return true;
}

bool BulkTransportCapacityMA::stop()
{
    if (m_tcpSocket)
    {
        m_tcpSocket->disconnectFromHost();
        if (m_tcpSocket->state() != QTcpSocket::UnconnectedState &&
                !m_tcpSocket->waitForDisconnected(1000))
        {
            return false;
        }
    }

    return true;
}

ResultPtr BulkTransportCapacityMA::result() const
{
    QVariantList res;
    foreach(qreal val, m_downloadSpeeds)
    {
        res<<QString::number(val, 'f');
    }

    return ResultPtr(new Result(QDateTime::currentDateTime(), res, QVariant()));
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <v8.h>
#include <node.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <nan.h>

#include "dbus.h"
#include "decoder.h"
#include "connection.h"
#include "signal.h"

namespace Connection {

	using namespace node;
	using namespace v8;
	using namespace std;

	static void connection_loop_free(uv_handle_t* handle) {
		uv_async_t *connection_loop = reinterpret_cast<uv_async_t *>(handle);
		delete connection_loop;
	}

	static void watcher_free(uv_handle_t* handle) {
		uv_poll_t *watcher = reinterpret_cast<uv_poll_t *>(handle);
		delete watcher;
	}

	static void timer_free(uv_handle_t* handle) {
		uv_timer_t *timer = reinterpret_cast<uv_timer_t *>(handle);
		delete timer;
	}

	static void watcher_handle(uv_poll_t *watcher, int status, int events)
	{
		DBusWatch *watch = static_cast<DBusWatch *>(watcher->data);
		unsigned int flags = 0;

		if (events & UV_READABLE)
			flags |= DBUS_WATCH_READABLE;

		if (events & UV_WRITABLE)
			flags |= DBUS_WATCH_WRITABLE;

		dbus_watch_handle(watch, flags);
	}

	static void watcher_close(void *data)
	{
		uv_poll_t *watcher = static_cast<uv_poll_t *>(data);

		if (watcher == NULL)
			return;

		watcher->data = NULL;

		// Stop watching
		uv_ref((uv_handle_t *)watcher);
		uv_poll_stop(watcher);
		uv_close((uv_handle_t *)watcher, (uv_close_cb)watcher_free);
	}

	static dbus_bool_t watch_add(DBusWatch *watch, void *data)
	{
		if (!dbus_watch_get_enabled(watch) || dbus_watch_get_data(watch) != NULL)
			return true;

		int events = 0;
		int fd = dbus_watch_get_unix_fd(watch);
		unsigned int flags = dbus_watch_get_flags(watch);

		if (flags & DBUS_WATCH_READABLE)
			events |= UV_READABLE;

		if (flags & DBUS_WATCH_WRITABLE)
			events |= UV_WRITABLE;

		// Initializing watcher
		uv_poll_t *watcher = new uv_poll_t;
		watcher->data = (void *)watch;

		// Start watching
		uv_poll_init(uv_default_loop(), watcher, fd);
		uv_poll_start(watcher, events, watcher_handle);
		uv_unref((uv_handle_t *)watcher);

		dbus_watch_set_data(watch, (void *)watcher, watcher_close);

		return true;
	}

	static void watch_remove(DBusWatch *watch, void *data)
	{
		uv_poll_t *watcher = static_cast<uv_poll_t *>(dbus_watch_get_data(watch));

		if (watcher == NULL)
			return;

		dbus_watch_set_data(watch, NULL, NULL);
	}

	static void watch_handle(DBusWatch *watch, void *data)
	{
		if (dbus_watch_get_enabled(watch))
			watch_add(watch, data);
		else
			watch_remove(watch, data);
	}

#if UV_VERSION_MAJOR == 0
	static void timer_handle(uv_timer_t *timer, int status)
#else
	static void timer_handle(uv_timer_t *timer)
#endif
	{
		DBusTimeout *timeout = static_cast<DBusTimeout *>(timer->data);
		dbus_timeout_handle(timeout);
	}

	static void timer_close(void *data)
	{
		uv_timer_t *timer = static_cast<uv_timer_t *>(data);

		if (timer == NULL)
			return;

		timer->data =  NULL;

		// Stop timer
		uv_timer_stop(timer);
		uv_unref((uv_handle_t *)timer);
		uv_close((uv_handle_t *)timer, (uv_close_cb)timer_free);
	}

	static dbus_bool_t timeout_add(DBusTimeout *timeout, void *data)
	{
		if (!dbus_timeout_get_enabled(timeout) || dbus_timeout_get_data(timeout) != NULL)
			return true;

		uv_timer_t *timer = new uv_timer_t;
		timer->data = timeout;

		// Initializing timer
		uv_timer_init(uv_default_loop(), timer);
		uv_timer_start(timer, timer_handle, dbus_timeout_get_interval(timeout), 0);

		dbus_timeout_set_data(timeout, (void *)timer, timer_close);

		return true;
	}

	static void timeout_remove(DBusTimeout *timeout, void *data)
	{
		dbus_timeout_set_data(timeout, NULL, NULL);
	}

	static void timeout_toggled(DBusTimeout *timeout, void *data)
	{
		if (dbus_timeout_get_enabled(timeout))
			timeout_add(timeout, data);
		else
			timeout_remove(timeout, data);
	}

#if UV_VERSION_MAJOR == 0
	static void connection_loop_handle(uv_async_t *connection_loop, int status)
#else
	static void connection_loop_handle(uv_async_t *connection_loop)
#endif
	{
		DBusConnection *connection = static_cast<DBusConnection *>(connection_loop->data);
		dbus_connection_read_write(connection, 0);

		while(dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);
	}

	static void connection_loop_close(void *data) {
		uv_async_t *connection_loop = static_cast<uv_async_t *>(data);

		if (connection_loop == NULL)
			return;

		connection_loop->data = NULL;

		uv_close((uv_handle_t *)connection_loop, (uv_close_cb)connection_loop_free);
	}

	static void connection_wakeup(void *data)
	{
		uv_async_t *connection_loop = static_cast<uv_async_t *>(data);
		uv_async_send(connection_loop);
	}

	static DBusHandlerResult signal_filter(DBusConnection *connection, DBusMessage *message, void *user_data)
	{
		// Ignore message if it's not a valid signal
		if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) {
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}

		// Getting the interface name and signal name
		const char *sender = dbus_message_get_sender(message);
		const char *object_path = dbus_message_get_path(message);
		const char *interface = dbus_message_get_interface(message);
		const char *signal_name = dbus_message_get_member(message);
		if (interface == NULL || signal_name == NULL) {
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}

		// Getting V8 context
/*
		Local<Context> context = Context::GetCurrent();
		Context::Scope ctxScope(context);
		HandleScope scope;
*/
		NanScope();

		// Getting arguments of signal
		Handle<Value> arguments = Decoder::DecodeArguments(message);
		Local<Value> senderValue = NanNull();
		if (sender)
			senderValue = NanNew<String>(sender);

		Handle<Value> args[] = {
			NanNew<String>(dbus_bus_get_unique_name(connection)),
			senderValue,
			NanNew<String>(object_path),
			NanNew<String>(interface),
			NanNew<String>(signal_name),
			arguments
		};

		Signal::DispatchSignal(args);

		return DBUS_HANDLER_RESULT_HANDLED;
	}

	void Init(NodeDBus::BusObject *bus)
	{
		DBusConnection *connection = bus->connection;

		dbus_connection_set_exit_on_disconnect(connection, false);

		// Initializing watcher
		dbus_connection_set_watch_functions(connection, watch_add, watch_remove, watch_handle, NULL, NULL);

		// Initializing timeout handlers
		dbus_connection_set_timeout_functions(connection, timeout_add, timeout_remove, timeout_toggled, NULL, NULL);

		// Initializing loop
		uv_async_t *connection_loop = new uv_async_t;
		connection_loop->data = (void *)connection;
		uv_async_init(uv_default_loop(), connection_loop, connection_loop_handle);
		bus->loop = connection_loop;

		dbus_connection_set_wakeup_main_function(connection, connection_wakeup, connection_loop, connection_loop_close);

		// Initializing signal handler
		dbus_connection_add_filter(connection, signal_filter, NULL, NULL);
	}

	void UnInit(NodeDBus::BusObject *bus)
	{
		DBusConnection *connection = bus->connection;

		uv_unref((uv_handle_t *)bus->loop);

		if (dbus_connection_get_is_connected(connection))
			dbus_connection_close(connection);

		dbus_connection_unref(connection);
	}

}

<commit_msg>connection.cc: don't add two watchers for one fd<commit_after>#include <stdlib.h>
#include <v8.h>
#include <node.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <nan.h>

#include "dbus.h"
#include "decoder.h"
#include "connection.h"
#include "signal.h"

namespace Connection {

	using namespace node;
	using namespace v8;
	using namespace std;

	static void connection_loop_free(uv_handle_t* handle) {
		uv_async_t *connection_loop = reinterpret_cast<uv_async_t *>(handle);
		delete connection_loop;
	}

	static void watcher_free(uv_handle_t* handle) {
		uv_poll_t *watcher = reinterpret_cast<uv_poll_t *>(handle);
		delete watcher;
	}

	static void timer_free(uv_handle_t* handle) {
		uv_timer_t *timer = reinterpret_cast<uv_timer_t *>(handle);
		delete timer;
	}

	static void watcher_handle(uv_poll_t *watcher, int status, int events)
	{
		DBusWatch *watch = static_cast<DBusWatch *>(watcher->data);
		unsigned int flags = 0;

		if (events & UV_READABLE)
			flags |= DBUS_WATCH_READABLE;

		if (events & UV_WRITABLE)
			flags |= DBUS_WATCH_WRITABLE;

		dbus_watch_handle(watch, flags);
	}

	static void watcher_close(void *data)
	{
		uv_poll_t *watcher = static_cast<uv_poll_t *>(data);

		if (watcher == NULL)
			return;

		watcher->data = NULL;

		// Stop watching
		uv_ref((uv_handle_t *)watcher);
		uv_poll_stop(watcher);
		uv_close((uv_handle_t *)watcher, (uv_close_cb)watcher_free);
	}

	static dbus_bool_t watch_add(DBusWatch *watch, void *data)
	{
		if (!dbus_watch_get_enabled(watch) || dbus_watch_get_data(watch) != NULL)
			return true;

		int events = 0;
		int fd = dbus_watch_get_unix_fd(watch);
		unsigned int flags = dbus_watch_get_flags(watch);

		if (flags & DBUS_WATCH_READABLE)
			events |= UV_READABLE;

		if (flags & DBUS_WATCH_WRITABLE)
			events |= UV_WRITABLE;

		// Initializing watcher
		uv_poll_t *watcher = new uv_poll_t;
		watcher->data = (void *)watch;

		// Start watching
		uv_poll_init(uv_default_loop(), watcher, fd);
		uv_poll_start(watcher, events, watcher_handle);
		uv_unref((uv_handle_t *)watcher);

		dbus_watch_set_data(watch, (void *)watcher, watcher_close);

		return true;
	}

	static void watch_remove(DBusWatch *watch, void *data)
	{
		uv_poll_t *watcher = static_cast<uv_poll_t *>(dbus_watch_get_data(watch));

		if (watcher == NULL)
			return;

		dbus_watch_set_data(watch, NULL, NULL);
	}

	static void watch_handle(DBusWatch *watch, void *data)
	{
		// This watch was never added, so don't do anything!
		// If we would react in this case, it can happen that we add
		// two watches for one filehandler, this crashes libuv!
		if (dbus_watch_get_data(watch) == NULL) {
			return;
		}

		if (dbus_watch_get_enabled(watch))
			watch_add(watch, data);
		else
			watch_remove(watch, data);
	}

#if UV_VERSION_MAJOR == 0
	static void timer_handle(uv_timer_t *timer, int status)
#else
	static void timer_handle(uv_timer_t *timer)
#endif
	{
		DBusTimeout *timeout = static_cast<DBusTimeout *>(timer->data);
		dbus_timeout_handle(timeout);
	}

	static void timer_close(void *data)
	{
		uv_timer_t *timer = static_cast<uv_timer_t *>(data);

		if (timer == NULL)
			return;

		timer->data =  NULL;

		// Stop timer
		uv_timer_stop(timer);
		uv_unref((uv_handle_t *)timer);
		uv_close((uv_handle_t *)timer, (uv_close_cb)timer_free);
	}

	static dbus_bool_t timeout_add(DBusTimeout *timeout, void *data)
	{
		if (!dbus_timeout_get_enabled(timeout) || dbus_timeout_get_data(timeout) != NULL)
			return true;

		uv_timer_t *timer = new uv_timer_t;
		timer->data = timeout;

		// Initializing timer
		uv_timer_init(uv_default_loop(), timer);
		uv_timer_start(timer, timer_handle, dbus_timeout_get_interval(timeout), 0);

		dbus_timeout_set_data(timeout, (void *)timer, timer_close);

		return true;
	}

	static void timeout_remove(DBusTimeout *timeout, void *data)
	{
		dbus_timeout_set_data(timeout, NULL, NULL);
	}

	static void timeout_toggled(DBusTimeout *timeout, void *data)
	{
		if (dbus_timeout_get_enabled(timeout))
			timeout_add(timeout, data);
		else
			timeout_remove(timeout, data);
	}

#if UV_VERSION_MAJOR == 0
	static void connection_loop_handle(uv_async_t *connection_loop, int status)
#else
	static void connection_loop_handle(uv_async_t *connection_loop)
#endif
	{
		DBusConnection *connection = static_cast<DBusConnection *>(connection_loop->data);
		dbus_connection_read_write(connection, 0);

		while(dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);
	}

	static void connection_loop_close(void *data) {
		uv_async_t *connection_loop = static_cast<uv_async_t *>(data);

		if (connection_loop == NULL)
			return;

		connection_loop->data = NULL;

		uv_close((uv_handle_t *)connection_loop, (uv_close_cb)connection_loop_free);
	}

	static void connection_wakeup(void *data)
	{
		uv_async_t *connection_loop = static_cast<uv_async_t *>(data);
		uv_async_send(connection_loop);
	}

	static DBusHandlerResult signal_filter(DBusConnection *connection, DBusMessage *message, void *user_data)
	{
		// Ignore message if it's not a valid signal
		if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) {
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}

		// Getting the interface name and signal name
		const char *sender = dbus_message_get_sender(message);
		const char *object_path = dbus_message_get_path(message);
		const char *interface = dbus_message_get_interface(message);
		const char *signal_name = dbus_message_get_member(message);
		if (interface == NULL || signal_name == NULL) {
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}

		// Getting V8 context
/*
		Local<Context> context = Context::GetCurrent();
		Context::Scope ctxScope(context);
		HandleScope scope;
*/
		NanScope();

		// Getting arguments of signal
		Handle<Value> arguments = Decoder::DecodeArguments(message);
		Local<Value> senderValue = NanNull();
		if (sender)
			senderValue = NanNew<String>(sender);

		Handle<Value> args[] = {
			NanNew<String>(dbus_bus_get_unique_name(connection)),
			senderValue,
			NanNew<String>(object_path),
			NanNew<String>(interface),
			NanNew<String>(signal_name),
			arguments
		};

		Signal::DispatchSignal(args);

		return DBUS_HANDLER_RESULT_HANDLED;
	}

	void Init(NodeDBus::BusObject *bus)
	{
		DBusConnection *connection = bus->connection;

		dbus_connection_set_exit_on_disconnect(connection, false);

		// Initializing watcher
		dbus_connection_set_watch_functions(connection, watch_add, watch_remove, watch_handle, NULL, NULL);

		// Initializing timeout handlers
		dbus_connection_set_timeout_functions(connection, timeout_add, timeout_remove, timeout_toggled, NULL, NULL);

		// Initializing loop
		uv_async_t *connection_loop = new uv_async_t;
		connection_loop->data = (void *)connection;
		uv_async_init(uv_default_loop(), connection_loop, connection_loop_handle);
		bus->loop = connection_loop;

		dbus_connection_set_wakeup_main_function(connection, connection_wakeup, connection_loop, connection_loop_close);

		// Initializing signal handler
		dbus_connection_add_filter(connection, signal_filter, NULL, NULL);
	}

	void UnInit(NodeDBus::BusObject *bus)
	{
		DBusConnection *connection = bus->connection;

		uv_unref((uv_handle_t *)bus->loop);

		if (dbus_connection_get_is_connected(connection))
			dbus_connection_close(connection);

		dbus_connection_unref(connection);
	}

}

<|endoftext|>


<commit_before>#ifndef BEEEON_AUTH_SERVICE_TEST_H
#define BEEEON_AUTH_SERVICE_TEST_H

#include <Poco/Exception.h>

#include <cppunit/extensions/HelperMacros.h>

#include "provider/MockRandomProvider.h"
#include "provider/RandomProvider.h"
#include "service/AuthService.h"
#include "provider/PermitAuthProvider.h"
#include "dao/UserDao.h"
#include "dao/IdentityDao.h"
#include "dao/VerifiedIdentityDao.h"
#include "util/Base64.h"

using namespace std;
using namespace Poco;

namespace BeeeOn {

class AuthServiceTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(AuthServiceTest);
	CPPUNIT_TEST(testPermitAuth);
	CPPUNIT_TEST_SUITE_END();

public:
	void setUp();
	void tearDown();
	void testPermitAuth();

private:
	MockUserDao m_userDao;
	MockIdentityDao m_identityDao;
	MockVerifiedIdentityDao m_verifiedIdentityDao;
	SessionManager m_manager;
	MockRandomProvider m_mockRandomProvider;
	InsecureRandomProvider m_insecureRandomProvider;
	AuthService *m_service;
};

CPPUNIT_TEST_SUITE_REGISTRATION(AuthServiceTest);

#define SESSION_ID64 string( \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789")

void AuthServiceTest::setUp()
{
	m_userDao.storage().clear();
	m_identityDao.storage().clear();
	m_verifiedIdentityDao.storage().clear();

	m_mockRandomProvider.setNextRandom(SESSION_ID64);
	m_insecureRandomProvider.setProviderImpl(&m_mockRandomProvider);
	m_manager.setSecureRandomProvider(&m_insecureRandomProvider);
	m_manager.setMaxUserSessions(10);
	m_manager.setSessionExpireTime(1);

	m_service = new AuthService();
	m_service->setUserDao(&m_userDao);
	m_service->setIdentityDao(&m_identityDao);
	m_service->setVerifiedIdentityDao(&m_verifiedIdentityDao);
	m_service->setSessionManager(&m_manager);
}

void AuthServiceTest::tearDown()
{
	delete m_service;
}

void AuthServiceTest::testPermitAuth()
{
	UserID newID(UUIDGenerator::defaultGenerator().createRandom());
	User::Ptr user(new User(newID));
	m_userDao.storage().insert(make_pair(user->id(), user));

	Identity identity;
	identity.setEmail("permit@example.org");
	identity.setUser(*user);
	m_identityDao.create(identity);

	VerifiedIdentity verifiedIdentity;
	verifiedIdentity.setIdentity(identity);
	verifiedIdentity.setProvider("3rd-party");
	m_verifiedIdentityDao.create(verifiedIdentity);

	PermitAuthProvider provider;
	provider.setResultProvider("3rd-party");

	m_service->registerProvider(&provider);

	AuthCodeCredentials cred("permit", "permit@example.org");

	try {
		const ExpirableSession::Ptr session = m_service->login(cred);
		const SessionID id = session->sessionID();
		CPPUNIT_ASSERT(Base64::decode(id).compare(SESSION_ID64) == 0);
		m_service->logout(id);
	} catch(Exception &e) {
		CPPUNIT_FAIL("unexpected exception: " + e.displayText());
	}
}

}

#endif
<commit_msg>AuthServiceTest: introduce TestableAuthService<commit_after>#ifndef BEEEON_AUTH_SERVICE_TEST_H
#define BEEEON_AUTH_SERVICE_TEST_H

#include <Poco/Exception.h>

#include <cppunit/extensions/HelperMacros.h>

#include "provider/MockRandomProvider.h"
#include "provider/RandomProvider.h"
#include "service/AuthService.h"
#include "provider/PermitAuthProvider.h"
#include "dao/UserDao.h"
#include "dao/IdentityDao.h"
#include "dao/VerifiedIdentityDao.h"
#include "util/Base64.h"

using namespace std;
using namespace Poco;

namespace BeeeOn {

class TestableAuthService;

class AuthServiceTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(AuthServiceTest);
	CPPUNIT_TEST(testPermitAuth);
	CPPUNIT_TEST_SUITE_END();

public:
	void setUp();
	void tearDown();
	void testPermitAuth();

private:
	MockUserDao m_userDao;
	MockIdentityDao m_identityDao;
	MockVerifiedIdentityDao m_verifiedIdentityDao;
	SessionManager m_manager;
	MockRandomProvider m_mockRandomProvider;
	InsecureRandomProvider m_insecureRandomProvider;
	TestableAuthService *m_service;
};

CPPUNIT_TEST_SUITE_REGISTRATION(AuthServiceTest);

class TestableAuthService : public AuthService {
public:
};

#define SESSION_ID64 string( \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789"   \
	"abcdef0123456789")

void AuthServiceTest::setUp()
{
	m_userDao.storage().clear();
	m_identityDao.storage().clear();
	m_verifiedIdentityDao.storage().clear();

	m_mockRandomProvider.setNextRandom(SESSION_ID64);
	m_insecureRandomProvider.setProviderImpl(&m_mockRandomProvider);
	m_manager.setSecureRandomProvider(&m_insecureRandomProvider);
	m_manager.setMaxUserSessions(10);
	m_manager.setSessionExpireTime(1);

	m_service = new TestableAuthService();
	m_service->setUserDao(&m_userDao);
	m_service->setIdentityDao(&m_identityDao);
	m_service->setVerifiedIdentityDao(&m_verifiedIdentityDao);
	m_service->setSessionManager(&m_manager);
}

void AuthServiceTest::tearDown()
{
	delete m_service;
}

void AuthServiceTest::testPermitAuth()
{
	UserID newID(UUIDGenerator::defaultGenerator().createRandom());
	User::Ptr user(new User(newID));
	m_userDao.storage().insert(make_pair(user->id(), user));

	Identity identity;
	identity.setEmail("permit@example.org");
	identity.setUser(*user);
	m_identityDao.create(identity);

	VerifiedIdentity verifiedIdentity;
	verifiedIdentity.setIdentity(identity);
	verifiedIdentity.setProvider("3rd-party");
	m_verifiedIdentityDao.create(verifiedIdentity);

	PermitAuthProvider provider;
	provider.setResultProvider("3rd-party");

	m_service->registerProvider(&provider);

	AuthCodeCredentials cred("permit", "permit@example.org");

	try {
		const ExpirableSession::Ptr session = m_service->login(cred);
		const SessionID id = session->sessionID();
		CPPUNIT_ASSERT(Base64::decode(id).compare(SESSION_ID64) == 0);
		m_service->logout(id);
	} catch(Exception &e) {
		CPPUNIT_FAIL("unexpected exception: " + e.displayText());
	}
}

}

#endif
<|endoftext|>


<commit_before>
#include <gloperate-text/FontImporter.h>

#include <fstream>
#include <sstream>
#include <string>
#include <functional>
#include <set>
#include <algorithm>

#include <loggingzeug/logging.h>

#include <stringzeug/conversion.h>

#include <iozeug/FilePath.h>

#include <gloperate/resources/ResourceManager.h>

#include <gloperate-text/FontFace.h>

namespace
{

void extractKeyValuePairs(std::stringstream & stream, std::function<void(const std::string &, const std::string)> callback)
{
    std::string key;
    std::string value;

    while (stream)
    {
        if (std::getline(stream, key, '='))
        {
            if (std::getline(stream, value, ' '))
            {
                callback(key, value);
            }
        }
    }
}

std::string stripped(const std::string & string, const std::set<char> & blacklist)
{
    std::string result = string;

    result.erase(std::remove_if(result.begin(), result.end(), [&blacklist] (char x) { return blacklist.count(x) > 0; } ), result.end());

    return result;
}

} // namespace

namespace gloperate_text
{

FontImporter::FontImporter(gloperate::ResourceManager & resourceManager)
: m_resourceManager(resourceManager)
{
}

FontFace * FontImporter::loadFont(const std::string & filename)
{
    std::ifstream in(filename, std::ios::in | std::ios::binary);

    if (!in)
    {
        return nullptr;
    }

    FontFace * font = new FontFace();

    std::string line;
    std::string identifier;
    while (std::getline(in, line))
    {
        auto ss = std::stringstream();
        ss << line;

        if (std::getline(ss, identifier, ' '))
        {
            if (identifier == "info")
            {
                handleInfo(ss, font);
            }
            else if (identifier == "common")
            {
                handleCommon(ss, font);
            }
            else if (identifier == "page")
            {
                handlePage(ss, font, filename);
            }
            else if (identifier == "chars")
            {
                handleChars(ss, font);
            }
            else if (identifier == "char")
            {
                handleChar(ss, font);
            }
            else if (identifier == "kernings")
            {
                handleKernings(ss, font);
            }
            else if (identifier == "kerning")
            {
                handleKerning(ss, font);
            }
            else
            {
                assert(false);
            }
        }
        else
        {
            assert(false);
        }
    }

    if (!font->glyphTexture())
    {
        delete font;

        return nullptr;
    }

    return font;
}

void FontImporter::handleInfo(std::stringstream & stream, FontFace * font)
{
    extractKeyValuePairs(stream, [font](const std::string & key, const std::string & value) {
        font->setConfiguration(key, value);
    });
}

void FontImporter::handleCommon(std::stringstream & stream, FontFace * font)
{
    extractKeyValuePairs(stream, [font](const std::string & key, const std::string & value) {
        font->setConfiguration(key, value);
    });
}

void FontImporter::handlePage(std::stringstream & stream, FontFace * font, const std::string & filename)
{
    const std::string path = iozeug::FilePath(filename).directoryPath();
    extractKeyValuePairs(stream, [this, font, &path](const std::string & key, const std::string & value) {
        if (key == "file")
        {
            std::string filename = stripped(value, { '"', '\r' });

            font->setGlyphTexture(m_resourceManager.load<globjects::Texture>(path + "/" + filename));
        }
        else if (key == "id")
        {
            // nothing for now
        }
    });
}

void FontImporter::handleChars(std::stringstream & stream, FontFace * font)
{
    // nothing
}

void FontImporter::handleChar(std::stringstream & stream, FontFace * font)
{
    Glyph glyph;

    extractKeyValuePairs(stream, [&glyph](const std::string & key, const std::string & value) {
        std::uint32_t number = stringzeug::fromString<std::uint32_t>(value);

        if (key == "id")
        {
            glyph.setIndex(number);
        }
        else if (key == "x")
        {
            glyph.setX(number);
        }
        else if (key == "y")
        {
            glyph.setY(number);
        }
        else if (key == "width")
        {
            glyph.setWidth(number);
        }
        else if (key == "height")
        {
            glyph.setHeight(number);
        }
        else if (key == "xoffset")
        {
            glyph.setXOffset(number);
        }
        else if (key == "yoffset")
        {
            glyph.setYOffset(number);
        }
        else if (key == "xadvance")
        {
            glyph.setXAdvance(number);
        }
        else if (key == "page")
        {
            glyph.setPage(number);
        }
        else if (key == "chnl")
        {
            glyph.setChannel(number);
        }
    });

    if (glyph.index() > 0)
    {
        font->addGlyph(glyph);
    }
}

void FontImporter::handleKernings(std::stringstream & stream, FontFace * font)
{
    // nothing
}

void FontImporter::handleKerning(std::stringstream & stream, FontFace * font)
{
    std::uint32_t first = 0;
    std::uint32_t second = 0;
    int amount = 0;

    extractKeyValuePairs(stream, [this, font, &first, &second, &amount](const std::string & key, const std::string & value) {
        if (key == "first")
        {
            first = stringzeug::fromString<std::uint32_t>(value);
        }
        else if (key == "second")
        {
            second = stringzeug::fromString<std::uint32_t>(value);
        }
        else if (key == "amount")
        {
            // nothing for now
            amount = stringzeug::fromString<int>(value);
        }
    });
}

} // namespace gloperate_text
<commit_msg>Fix compilation for GCC 4.8<commit_after>
#include <gloperate-text/FontImporter.h>

#include <fstream>
#include <sstream>
#include <string>
#include <functional>
#include <set>
#include <algorithm>

#include <loggingzeug/logging.h>

#include <stringzeug/conversion.h>

#include <iozeug/FilePath.h>

#include <gloperate/resources/ResourceManager.h>

#include <gloperate-text/FontFace.h>

namespace
{

void extractKeyValuePairs(std::stringstream & stream, std::function<void(const std::string &, const std::string)> callback)
{
    std::string key;
    std::string value;

    while (stream)
    {
        if (std::getline(stream, key, '='))
        {
            if (std::getline(stream, value, ' '))
            {
                callback(key, value);
            }
        }
    }
}

std::string stripped(const std::string & string, const std::set<char> & blacklist)
{
    std::string result = string;

    result.erase(std::remove_if(result.begin(), result.end(), [&blacklist] (char x) { return blacklist.count(x) > 0; } ), result.end());

    return result;
}

} // namespace

namespace gloperate_text
{

FontImporter::FontImporter(gloperate::ResourceManager & resourceManager)
: m_resourceManager(resourceManager)
{
}

FontFace * FontImporter::loadFont(const std::string & filename)
{
    std::ifstream in(filename, std::ios::in | std::ios::binary);

    if (!in)
    {
        return nullptr;
    }

    FontFace * font = new FontFace();

    std::string line;
    std::string identifier;
    while (std::getline(in, line))
    {
        std::stringstream ss(line);

        if (std::getline(ss, identifier, ' '))
        {
            if (identifier == "info")
            {
                handleInfo(ss, font);
            }
            else if (identifier == "common")
            {
                handleCommon(ss, font);
            }
            else if (identifier == "page")
            {
                handlePage(ss, font, filename);
            }
            else if (identifier == "chars")
            {
                handleChars(ss, font);
            }
            else if (identifier == "char")
            {
                handleChar(ss, font);
            }
            else if (identifier == "kernings")
            {
                handleKernings(ss, font);
            }
            else if (identifier == "kerning")
            {
                handleKerning(ss, font);
            }
            else
            {
                assert(false);
            }
        }
        else
        {
            assert(false);
        }
    }

    if (!font->glyphTexture())
    {
        delete font;

        return nullptr;
    }

    return font;
}

void FontImporter::handleInfo(std::stringstream & stream, FontFace * font)
{
    extractKeyValuePairs(stream, [font](const std::string & key, const std::string & value) {
        font->setConfiguration(key, value);
    });
}

void FontImporter::handleCommon(std::stringstream & stream, FontFace * font)
{
    extractKeyValuePairs(stream, [font](const std::string & key, const std::string & value) {
        font->setConfiguration(key, value);
    });
}

void FontImporter::handlePage(std::stringstream & stream, FontFace * font, const std::string & filename)
{
    const std::string path = iozeug::FilePath(filename).directoryPath();
    extractKeyValuePairs(stream, [this, font, &path](const std::string & key, const std::string & value) {
        if (key == "file")
        {
            std::string filename = stripped(value, { '"', '\r' });

            font->setGlyphTexture(m_resourceManager.load<globjects::Texture>(path + "/" + filename));
        }
        else if (key == "id")
        {
            // nothing for now
        }
    });
}

void FontImporter::handleChars(std::stringstream & stream, FontFace * font)
{
    // nothing
}

void FontImporter::handleChar(std::stringstream & stream, FontFace * font)
{
    Glyph glyph;

    extractKeyValuePairs(stream, [&glyph](const std::string & key, const std::string & value) {
        std::uint32_t number = stringzeug::fromString<std::uint32_t>(value);

        if (key == "id")
        {
            glyph.setIndex(number);
        }
        else if (key == "x")
        {
            glyph.setX(number);
        }
        else if (key == "y")
        {
            glyph.setY(number);
        }
        else if (key == "width")
        {
            glyph.setWidth(number);
        }
        else if (key == "height")
        {
            glyph.setHeight(number);
        }
        else if (key == "xoffset")
        {
            glyph.setXOffset(number);
        }
        else if (key == "yoffset")
        {
            glyph.setYOffset(number);
        }
        else if (key == "xadvance")
        {
            glyph.setXAdvance(number);
        }
        else if (key == "page")
        {
            glyph.setPage(number);
        }
        else if (key == "chnl")
        {
            glyph.setChannel(number);
        }
    });

    if (glyph.index() > 0)
    {
        font->addGlyph(glyph);
    }
}

void FontImporter::handleKernings(std::stringstream & stream, FontFace * font)
{
    // nothing
}

void FontImporter::handleKerning(std::stringstream & stream, FontFace * font)
{
    std::uint32_t first = 0;
    std::uint32_t second = 0;
    int amount = 0;

    extractKeyValuePairs(stream, [this, font, &first, &second, &amount](const std::string & key, const std::string & value) {
        if (key == "first")
        {
            first = stringzeug::fromString<std::uint32_t>(value);
        }
        else if (key == "second")
        {
            second = stringzeug::fromString<std::uint32_t>(value);
        }
        else if (key == "amount")
        {
            // nothing for now
            amount = stringzeug::fromString<int>(value);
        }
    });
}

} // namespace gloperate_text
<|endoftext|>


<commit_before>// $Id: HINFile_test.C,v 1.2 2000/07/12 19:36:46 oliver Exp $
#include <BALL/CONCEPT/classTest.h>

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

#include <BALL/FORMAT/HINFile.h>
#include <BALL/KERNEL/system.h>

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

START_TEST(HINFile, "$Id: HINFile_test.C,v 1.2 2000/07/12 19:36:46 oliver Exp $")

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

using namespace BALL;

CHECK(HINFile::HINFile())
  //BAUSTELLE
RESULT

CHECK(HINFile::HINFile(const String& filename, File::OpenMode open_mode = File::IN))
  //BAUSTELLE
RESULT

CHECK(HINFile::~HINFile())
  //BAUSTELLE
RESULT

CHECK(HINFile::write(const System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::read(System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::HINFile& operator >> (System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::HINFile& operator << (const System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::hasPeriodicBoundary() const )
  //BAUSTELLE
RESULT

CHECK(HINFile::getPeriodicBoundary() const )
  //BAUSTELLE
RESULT

CHECK(HINFile::getTemperature() const )
  //BAUSTELLE
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>added some trivial tests<commit_after>// $Id: HINFile_test.C,v 1.3 2001/03/11 21:03:07 anker Exp $
#include <BALL/CONCEPT/classTest.h>

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

#include <BALL/FORMAT/HINFile.h>
#include <BALL/KERNEL/system.h>

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

START_TEST(HINFile, "$Id: HINFile_test.C,v 1.3 2001/03/11 21:03:07 anker Exp $")

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

using namespace BALL;

HINFile* ptr;

CHECK(HINFile::HINFile())
	ptr = new HINFile;
	CHECK_NOT_EQUAL(ptr, 0)
RESULT

CHECK(HINFile::~HINFile())
  delete ptr;
RESULT

CHECK(HINFile::HINFile(const String& filename, File::OpenMode open_mode = File::IN))
  //BAUSTELLE
RESULT

CHECK(HINFile::write(const System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::read(System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::HINFile& operator >> (System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::HINFile& operator << (const System& system))
  //BAUSTELLE
RESULT

CHECK(HINFile::hasPeriodicBoundary() const )
  HINFile box("data/water.hin");
	TEST_EQUAL(box.hasPeriodicBoundary(), true)
RESULT

CHECK(HINFile::getPeriodicBoundary() const )
  HINFile box("data/water.hin");
RESULT

CHECK(HINFile::getTemperature() const )
  //BAUSTELLE
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>