<commit_before>#include "expr-to-xml.hh"
#include "xml-writer.hh"
#include "nixexpr-ast.hh"
#include "aterm.hh"
#include "util.hh"

namespace nix {

static XMLAttrs singletonAttrs(const string & name, const string & value)
{
    XMLAttrs attrs;
    attrs[name] = value;
    return attrs;
}

static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context)
{
    XMLAttrs attrs;
    string s;
    ATerm s2;
    int i;
    ATermList as, es, formals;
    ATerm body, pos;

    checkInterrupt();

    if (matchStr(e, s, context)) /* !!! show the context? */
        doc.writeEmptyElement("string", singletonAttrs("value", s));

    else if (matchPath(e, s2))
        doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s2)));

    else if (matchNull(e))
        doc.writeEmptyElement("null");

    else if (matchInt(e, i))
        doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % i).str()));

    else if (e == eTrue)
        doc.writeEmptyElement("bool", singletonAttrs("value", "true"));

    else if (e == eFalse)
        doc.writeEmptyElement("bool", singletonAttrs("value", "false"));

    else if (matchAttrs(e, as)) {
        XMLOpenElement _(doc, "attrs");
        ATermMap attrs;
        queryAllAttrs(e, attrs);
        StringSet names;
        for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
            names.insert(aterm2String(i->key));
        for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
            XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
            printTermAsXML(attrs.get(toATerm(*i)), doc, context);
        }
    }

    else if (matchList(e, es)) {
        XMLOpenElement _(doc, "list");
        for (ATermIterator i(es); i; ++i)
            printTermAsXML(*i, doc, context);
    }

    else if (matchFunction(e, formals, body, pos)) {
        XMLOpenElement _(doc, "function");

        for (ATermIterator i(formals); i; ++i) {
            Expr name; ValidValues valids; ATerm dummy;
            if (!matchFormal(*i, name, valids, dummy)) abort();
            XMLOpenElement _(doc, "arg", singletonAttrs("name", aterm2String(name)));

            ATermList valids2;
            if (matchValidValues(valids, valids2)) {
                for (ATermIterator j(valids2); j; ++j) {
                    XMLOpenElement _(doc, "value");
                    printTermAsXML(*j, doc, context);
                }
            }
        }
    }

    else
        doc.writeEmptyElement("unevaluated");
}

void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
{
    XMLWriter doc(true, out);
    XMLOpenElement root(doc, "expr");
    printTermAsXML(e, doc, context);
}

}
<commit_msg>* printTermAsXML: treat derivations specially; emit an element   <derivation outPath=... drvPath=...> attrs </derivation>.  Only emit   the attributes of any specific derivation only.  This prevents   exponententially large XML output due to the absense of sharing.<commit_after>#include "expr-to-xml.hh"
#include "xml-writer.hh"
#include "nixexpr-ast.hh"
#include "aterm.hh"
#include "util.hh"

namespace nix {

static XMLAttrs singletonAttrs(const string & name, const string & value)
{
    XMLAttrs attrs;
    attrs[name] = value;
    return attrs;
}

/* set<Expr> is safe because all the expressions are also reachable
   from the stack, therefore can't be garbage-collected. */
typedef set<Expr> ExprSet;

static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
    ExprSet & drvsSeen);

static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
    PathSet & context, ExprSet & drvsSeen)
{
    StringSet names;
    for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
        names.insert(aterm2String(i->key));
    for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
        XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
        printTermAsXML(attrs.get(toATerm(*i)), doc, context, drvsSeen);
    }
}

static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
    ExprSet & drvsSeen)
{
    XMLAttrs attrs;
    string s;
    ATerm s2;
    int i;
    ATermList as, es, formals;
    ATerm body, pos;

    checkInterrupt();

    if (matchStr(e, s, context)) /* !!! show the context? */
        doc.writeEmptyElement("string", singletonAttrs("value", s));

    else if (matchPath(e, s2))
        doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s2)));

    else if (matchNull(e))
        doc.writeEmptyElement("null");

    else if (matchInt(e, i))
        doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % i).str()));

    else if (e == eTrue)
        doc.writeEmptyElement("bool", singletonAttrs("value", "true"));

    else if (e == eFalse)
        doc.writeEmptyElement("bool", singletonAttrs("value", "false"));

    else if (matchAttrs(e, as)) {
        ATermMap attrs;
        queryAllAttrs(e, attrs);

        Expr a = attrs.get(toATerm("type"));
        if (a && matchStr(a, s, context) && s == "derivation") {

            XMLAttrs xmlAttrs;
            Path outPath, drvPath;

            a = attrs.get(toATerm("drvPath"));
            if (matchStr(a, drvPath, context))
                xmlAttrs["drvPath"] = drvPath;

            a = attrs.get(toATerm("outPath"));
            if (matchStr(a, outPath, context))
                xmlAttrs["outPath"] = outPath;

            XMLOpenElement _(doc, "derivation", xmlAttrs);

            if (drvsSeen.find(e) == drvsSeen.end()) {
                drvsSeen.insert(e);
                showAttrs(attrs, doc, context, drvsSeen);
            } else
                doc.writeEmptyElement("repeated");
        }

        else {
            XMLOpenElement _(doc, "attrs");
            showAttrs(attrs, doc, context, drvsSeen);
        }
    }

    else if (matchList(e, es)) {
        XMLOpenElement _(doc, "list");
        for (ATermIterator i(es); i; ++i)
            printTermAsXML(*i, doc, context, drvsSeen);
    }

    else if (matchFunction(e, formals, body, pos)) {
        XMLOpenElement _(doc, "function");

        for (ATermIterator i(formals); i; ++i) {
            Expr name; ValidValues valids; ATerm dummy;
            if (!matchFormal(*i, name, valids, dummy)) abort();
            XMLOpenElement _(doc, "arg", singletonAttrs("name", aterm2String(name)));

            ATermList valids2;
            if (matchValidValues(valids, valids2)) {
                for (ATermIterator j(valids2); j; ++j) {
                    XMLOpenElement _(doc, "value");
                    printTermAsXML(*j, doc, context, drvsSeen);
                }
            }
        }
    }

    else
        doc.writeEmptyElement("unevaluated");
}

void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
{
    XMLWriter doc(true, out);
    XMLOpenElement root(doc, "expr");
    ExprSet drvsSeen;
    printTermAsXML(e, doc, context, drvsSeen);
}

}
<|endoftext|>


<commit_before>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <vector>
#include <memory>
#include <string>
#include "util/sstream.h"
#include "library/scoped_ext.h"

namespace lean {
typedef std::tuple<push_scope_fn, pop_scope_fn> entry;
typedef std::vector<entry> scoped_exts;
static scoped_exts * g_exts = nullptr;
static scoped_exts & get_exts() { return *g_exts; }

void register_scoped_ext(push_scope_fn push, pop_scope_fn pop) {
    get_exts().emplace_back(push, pop);
}

struct scope_mng_ext : public environment_extension {
    name_set         m_namespace_set;     // all namespaces registered in the system
    name_set         m_opened_namespaces; // set of namespaces marked as "open"
    list<name>       m_namespaces;        // stack of namespaces/sections
    list<name>       m_headers;           // namespace/section header
    list<scope_kind> m_scope_kinds;
};

struct scope_mng_ext_reg {
    unsigned m_ext_id;
    scope_mng_ext_reg() { m_ext_id = environment::register_extension(std::make_shared<scope_mng_ext>()); }
};

static scope_mng_ext_reg * g_ext = nullptr;
static scope_mng_ext const & get_extension(environment const & env) {
    return static_cast<scope_mng_ext const &>(env.get_extension(g_ext->m_ext_id));
}
static environment update(environment const & env, scope_mng_ext const & ext) {
    return env.update(g_ext->m_ext_id, std::make_shared<scope_mng_ext>(ext));
}

name const & get_namespace(environment const & env) {
    scope_mng_ext const & ext = get_extension(env);
    return !is_nil(ext.m_namespaces) ? head(ext.m_namespaces) : name::anonymous();
}

list<name> const & get_namespaces(environment const & env) {
    return get_extension(env).m_namespaces;
}

bool in_section(environment const & env) {
    scope_mng_ext const & ext = get_extension(env);
    return !is_nil(ext.m_scope_kinds) && head(ext.m_scope_kinds) == scope_kind::Section;
}

environment mark_namespace_as_open(environment const & env, name const & n) {
    scope_mng_ext ext = get_extension(env);
    ext.m_opened_namespaces.insert(n);
    return update(env, ext);
}

name_set get_opened_namespaces(environment const & env) {
    return get_extension(env).m_opened_namespaces;
}

optional<name> to_valid_namespace_name(environment const & env, name const & n) {
    scope_mng_ext const & ext = get_extension(env);
    if (ext.m_namespace_set.contains(n))
        return optional<name>(n);
    for (auto const & ns : ext.m_namespaces) {
        name r = ns + n;
        if (ext.m_namespace_set.contains(r))
            return optional<name>(r);
    }
    return optional<name>();
}

std::vector<name> get_namespace_completion_candidates(environment const & env) {
    std::vector<name> ret;
    scope_mng_ext const & ext = get_extension(env);
    ext.m_namespace_set.for_each([&](name const & ns) {
        ret.push_back(ns);
        for (auto const & open_ns : ext.m_namespaces)
            if (open_ns != ns && is_prefix_of(open_ns, ns))
                ret.push_back(ns.replace_prefix(open_ns, {}));
    });
    return ret;
}

struct new_namespace_modification : public modification {
    LEAN_MODIFICATION("nspace")

    name m_ns;

    new_namespace_modification(name const & ns) : m_ns(ns) {}
    new_namespace_modification() {}

    void perform(environment & env) const override {
        scope_mng_ext ext = get_extension(env);
        ext.m_namespace_set.insert(m_ns);
        env = update(env, ext);
    }

    void serialize(serializer & s) const override {
        s << m_ns;
    }

    static std::shared_ptr<modification const> deserialize(deserializer & d) {
        name n;
        d >> n;
        return std::make_shared<new_namespace_modification>(n);
    }
};

environment add_namespace(environment const & env, name const & ns) {
    scope_mng_ext ext = get_extension(env);
    if (!ext.m_namespace_set.contains(ns)) {
        ext.m_namespace_set.insert(ns);
        environment r = update(env, ext);
        r = module::add(r, std::make_shared<new_namespace_modification>(ns));
        if (ns.is_atomic())
            return r;
        else
            return add_namespace(r, ns.get_prefix());
    } else {
        return env;
    }
}

environment push_scope(environment const & env, io_state const & ios, scope_kind k, name const & n) {
    if (k == scope_kind::Namespace && in_section(env))
        throw exception("invalid namespace declaration, a namespace cannot be declared inside a section");
    name new_n = get_namespace(env);
    if (k == scope_kind::Namespace)
        new_n = new_n + n;
    scope_mng_ext ext = get_extension(env);
    bool save_ns = false;
    if (!ext.m_namespace_set.contains(new_n)) {
        save_ns  = true;
        ext.m_namespace_set.insert(new_n);
    }
    ext.m_namespaces  = cons(new_n, ext.m_namespaces);
    ext.m_headers     = cons(n, ext.m_headers);
    ext.m_scope_kinds = cons(k, ext.m_scope_kinds);
    environment r = update(env, ext);
    for (auto const & t : get_exts()) {
        r = std::get<0>(t)(r, ios, k);
    }
    if (save_ns)
        r = module::add(r, std::make_shared<new_namespace_modification>(new_n));
    return r;
}

environment pop_scope_core(environment const & env, io_state const & ios) {
    scope_mng_ext ext = get_extension(env);
    if (is_nil(ext.m_namespaces))
        return env;
    scope_kind k      = head(ext.m_scope_kinds);
    ext.m_namespaces  = tail(ext.m_namespaces);
    ext.m_headers     = tail(ext.m_headers);
    ext.m_scope_kinds = tail(ext.m_scope_kinds);
    environment r = update(env, ext);
    for (auto const & t : get_exts()) {
        r = std::get<1>(t)(r, ios, k);
    }
    return r;
}

environment pop_scope(environment const & env, io_state const & ios, name const & n) {
    scope_mng_ext ext = get_extension(env);
    if (is_nil(ext.m_namespaces))
        throw exception("invalid end of scope, there are no open namespaces/sections");
    if (n != head(ext.m_headers))
        throw exception(sstream() << "invalid end of scope, begin/end mistmatch, scope starts with '"
                        << head(ext.m_headers) << "', and ends with '" << n << "'");
    return pop_scope_core(env, ios);
}

bool has_open_scopes(environment const & env) {
    scope_mng_ext ext = get_extension(env);
    return !is_nil(ext.m_namespaces);
}

void initialize_scoped_ext() {
    g_exts = new scoped_exts();
    g_ext  = new scope_mng_ext_reg();
    new_namespace_modification::init();
}

void finalize_scoped_ext() {
    new_namespace_modification::finalize();
    delete g_exts;
    delete g_ext;
}
}
<commit_msg>fix(library/scoped_ext): typo in error message<commit_after>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <vector>
#include <memory>
#include <string>
#include "util/sstream.h"
#include "library/scoped_ext.h"

namespace lean {
typedef std::tuple<push_scope_fn, pop_scope_fn> entry;
typedef std::vector<entry> scoped_exts;
static scoped_exts * g_exts = nullptr;
static scoped_exts & get_exts() { return *g_exts; }

void register_scoped_ext(push_scope_fn push, pop_scope_fn pop) {
    get_exts().emplace_back(push, pop);
}

struct scope_mng_ext : public environment_extension {
    name_set         m_namespace_set;     // all namespaces registered in the system
    name_set         m_opened_namespaces; // set of namespaces marked as "open"
    list<name>       m_namespaces;        // stack of namespaces/sections
    list<name>       m_headers;           // namespace/section header
    list<scope_kind> m_scope_kinds;
};

struct scope_mng_ext_reg {
    unsigned m_ext_id;
    scope_mng_ext_reg() { m_ext_id = environment::register_extension(std::make_shared<scope_mng_ext>()); }
};

static scope_mng_ext_reg * g_ext = nullptr;
static scope_mng_ext const & get_extension(environment const & env) {
    return static_cast<scope_mng_ext const &>(env.get_extension(g_ext->m_ext_id));
}
static environment update(environment const & env, scope_mng_ext const & ext) {
    return env.update(g_ext->m_ext_id, std::make_shared<scope_mng_ext>(ext));
}

name const & get_namespace(environment const & env) {
    scope_mng_ext const & ext = get_extension(env);
    return !is_nil(ext.m_namespaces) ? head(ext.m_namespaces) : name::anonymous();
}

list<name> const & get_namespaces(environment const & env) {
    return get_extension(env).m_namespaces;
}

bool in_section(environment const & env) {
    scope_mng_ext const & ext = get_extension(env);
    return !is_nil(ext.m_scope_kinds) && head(ext.m_scope_kinds) == scope_kind::Section;
}

environment mark_namespace_as_open(environment const & env, name const & n) {
    scope_mng_ext ext = get_extension(env);
    ext.m_opened_namespaces.insert(n);
    return update(env, ext);
}

name_set get_opened_namespaces(environment const & env) {
    return get_extension(env).m_opened_namespaces;
}

optional<name> to_valid_namespace_name(environment const & env, name const & n) {
    scope_mng_ext const & ext = get_extension(env);
    if (ext.m_namespace_set.contains(n))
        return optional<name>(n);
    for (auto const & ns : ext.m_namespaces) {
        name r = ns + n;
        if (ext.m_namespace_set.contains(r))
            return optional<name>(r);
    }
    return optional<name>();
}

std::vector<name> get_namespace_completion_candidates(environment const & env) {
    std::vector<name> ret;
    scope_mng_ext const & ext = get_extension(env);
    ext.m_namespace_set.for_each([&](name const & ns) {
        ret.push_back(ns);
        for (auto const & open_ns : ext.m_namespaces)
            if (open_ns != ns && is_prefix_of(open_ns, ns))
                ret.push_back(ns.replace_prefix(open_ns, {}));
    });
    return ret;
}

struct new_namespace_modification : public modification {
    LEAN_MODIFICATION("nspace")

    name m_ns;

    new_namespace_modification(name const & ns) : m_ns(ns) {}
    new_namespace_modification() {}

    void perform(environment & env) const override {
        scope_mng_ext ext = get_extension(env);
        ext.m_namespace_set.insert(m_ns);
        env = update(env, ext);
    }

    void serialize(serializer & s) const override {
        s << m_ns;
    }

    static std::shared_ptr<modification const> deserialize(deserializer & d) {
        name n;
        d >> n;
        return std::make_shared<new_namespace_modification>(n);
    }
};

environment add_namespace(environment const & env, name const & ns) {
    scope_mng_ext ext = get_extension(env);
    if (!ext.m_namespace_set.contains(ns)) {
        ext.m_namespace_set.insert(ns);
        environment r = update(env, ext);
        r = module::add(r, std::make_shared<new_namespace_modification>(ns));
        if (ns.is_atomic())
            return r;
        else
            return add_namespace(r, ns.get_prefix());
    } else {
        return env;
    }
}

environment push_scope(environment const & env, io_state const & ios, scope_kind k, name const & n) {
    if (k == scope_kind::Namespace && in_section(env))
        throw exception("invalid namespace declaration, a namespace cannot be declared inside a section");
    name new_n = get_namespace(env);
    if (k == scope_kind::Namespace)
        new_n = new_n + n;
    scope_mng_ext ext = get_extension(env);
    bool save_ns = false;
    if (!ext.m_namespace_set.contains(new_n)) {
        save_ns  = true;
        ext.m_namespace_set.insert(new_n);
    }
    ext.m_namespaces  = cons(new_n, ext.m_namespaces);
    ext.m_headers     = cons(n, ext.m_headers);
    ext.m_scope_kinds = cons(k, ext.m_scope_kinds);
    environment r = update(env, ext);
    for (auto const & t : get_exts()) {
        r = std::get<0>(t)(r, ios, k);
    }
    if (save_ns)
        r = module::add(r, std::make_shared<new_namespace_modification>(new_n));
    return r;
}

environment pop_scope_core(environment const & env, io_state const & ios) {
    scope_mng_ext ext = get_extension(env);
    if (is_nil(ext.m_namespaces))
        return env;
    scope_kind k      = head(ext.m_scope_kinds);
    ext.m_namespaces  = tail(ext.m_namespaces);
    ext.m_headers     = tail(ext.m_headers);
    ext.m_scope_kinds = tail(ext.m_scope_kinds);
    environment r = update(env, ext);
    for (auto const & t : get_exts()) {
        r = std::get<1>(t)(r, ios, k);
    }
    return r;
}

environment pop_scope(environment const & env, io_state const & ios, name const & n) {
    scope_mng_ext ext = get_extension(env);
    if (is_nil(ext.m_namespaces))
        throw exception("invalid end of scope, there are no open namespaces/sections");
    if (n != head(ext.m_headers))
        throw exception(sstream() << "invalid end of scope, begin/end mismatch, scope starts with '"
                        << head(ext.m_headers) << "', and ends with '" << n << "'");
    return pop_scope_core(env, ios);
}

bool has_open_scopes(environment const & env) {
    scope_mng_ext ext = get_extension(env);
    return !is_nil(ext.m_namespaces);
}

void initialize_scoped_ext() {
    g_exts = new scoped_exts();
    g_ext  = new scope_mng_ext_reg();
    new_namespace_modification::init();
}

void finalize_scoped_ext() {
    new_namespace_modification::finalize();
    delete g_exts;
    delete g_ext;
}
}
<|endoftext|>


<commit_before>#include "robocup-py.hpp"
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <string>
#include <sstream>
#include <iostream>

using namespace boost::python;

#include <Geometry2d/Point.hpp>
#include <Geometry2d/Rect.hpp>
#include <Geometry2d/CompositeShape.hpp>
#include <Robot.hpp>
#include <SystemState.hpp>
#include <protobuf/LogFrame.pb.h>

//	this is here so boost can work with std::shared_ptr
template<class T> T * get_pointer( std::shared_ptr<T> const& p) {
	return p.get();
}

std::string Point_repr(Geometry2d::Point *self) {
	std::ostringstream ss;
	ss << "Point(";
	ss << self->x;
	ss << ", ";
	ss << self->y;
	ss << ")";

	std::string repr(ss.str());
	return repr;
}

std::string Robot_repr(Robot *self) {
	std::ostringstream ss;
	ss << "<Robot ";
	ss << (self->self() ? "us[" : "them[");
	ss << self->shell();
	ss << "], pos=";
	ss << Point_repr(&(self->pos));
	ss << ">";

	std::string repr(ss.str());
	return repr;
}

void OurRobot_move_to(OurRobot *self, Geometry2d::Point *to) {
	self->move(*to);
}

void OurRobot_set_avoid_ball_radius(OurRobot *self, float radius) {
	self->avoidBallRadius(radius);
}

void OurRobot_approach_opponent(OurRobot *self, unsigned shell_id, bool enable_approach) {
	self->approachOpponent(shell_id, enable_approach);
}

void OutRobot_add_text(OurRobot *self, const std::string &text, boost::python::tuple rgb, const std::string &layerPrefix) {
	float r = extract<float>(rgb[0]);
	float g = extract<float>(rgb[1]);
	float b = extract<float>(rgb[2]);

	self->addText(QString::fromStdString(text), QColor(r,g,b), QString::fromStdString(layerPrefix));
}

bool Rect_contains_rect(Geometry2d::Rect *self, Geometry2d::Rect *other) {
	return self->contains(*other);
}

bool Rect_contains_point(Geometry2d::Rect *self, Geometry2d::Point *pt) {
	return self->contains(*pt);
}

void Point_rotate(Geometry2d::Point *self, Geometry2d::Point *origin, float angle) {
	self->rotate(*origin, angle);
}

void CompositeShape_add_shape(Geometry2d::CompositeShape *self, Geometry2d::Shape *shape) {
	self->add(std::shared_ptr<Geometry2d::Shape>( shape->clone() ));
}

boost::python::tuple Line_wrap_pt(Geometry2d::Line *self) {
	boost::python::list a;
	for (int i = 0; i < 2; i++) {
		a.append(self->pt[i]);
	}
	return boost::python::tuple(a);
}

void State_draw_circle(SystemState *self, const Geometry2d::Point *center, float radius, boost::python::tuple rgb, const std::string &layer) {
	float r = extract<float>(rgb[0]);
	float g = extract<float>(rgb[1]);
	float b = extract<float>(rgb[2]);

	self->drawCircle(*center, radius, QColor(r,g,b), QString::fromStdString(layer));
}

//	returns None or a Geometry2d::Point
boost::python::object Line_line_intersection(Geometry2d::Line *self, Geometry2d::Line *other) {
	Geometry2d::Point pt;
	if (self->intersects(*other, &pt)) {
		boost::python::object obj(pt);
		return obj;
	} else {
		//	return None
		return boost::python::object();
	}
};

void State_draw_line(SystemState *self, const Geometry2d::Line *line, boost::python::tuple rgb, const std::string &layer) {
	float r = extract<float>(rgb[0]);
	float g = extract<float>(rgb[1]);
	float b = extract<float>(rgb[2]);

	self->drawLine(*line, QColor(r, g, b), QString::fromStdString(layer));
}

/**
 * The code in this block wraps up c++ classes and makes them
 * accessible to python in the 'robocup' module.
 */
BOOST_PYTHON_MODULE(robocup)
{
	class_<Geometry2d::Point>("Point", init<float, float>())
		.def(init<const Geometry2d::Point &>())
		.def_readwrite("x", &Geometry2d::Point::x)
		.def_readwrite("y", &Geometry2d::Point::y)
		.def(self - self)
		.def(self + self)
		.def("mag", &Geometry2d::Point::mag)
		.def("magsq", &Geometry2d::Point::magsq)
		.def("__repr__", &Point_repr)
		.def("normalized", &Geometry2d::Point::normalized)
		.def("rotate", &Point_rotate)
		.def(self * float())
		.def(self / float())
		.def("perp_ccw", &Geometry2d::Point::perpCCW)
		.def("perp_cw", &Geometry2d::Point::perpCW)
		.def("angle", &Geometry2d::Point::angle)
		.def("dot", &Geometry2d::Point::dot)
		.def("near_point", &Geometry2d::Point::nearPoint)
	;

	class_<Geometry2d::Line, Geometry2d::Line*>("Line", init<Geometry2d::Point, Geometry2d::Point>())
		.add_property("pt", Line_wrap_pt)
		.def("delta", &Geometry2d::Line::delta)
		.def("line_intersection", &Line_line_intersection)
		.def("dist_to", &Geometry2d::Line::distTo)
	;

	class_<Geometry2d::Segment, Geometry2d::Segment*, bases<Geometry2d::Line> >("Segment", init<Geometry2d::Point, Geometry2d::Point>())
		.def("center", &Geometry2d::Segment::center)
		.def("length", &Geometry2d::Segment::length)
		.def("dist_to", &Geometry2d::Segment::distTo)
		.def("nearest_point", &Geometry2d::Segment::nearestPoint)
	;

	class_<Geometry2d::Shape, boost::noncopyable>("Shape")
	;

	class_<Geometry2d::Rect, bases<Geometry2d::Shape> >("Rect", init<Geometry2d::Point, Geometry2d::Point>())
		.def("contains_rect", &Rect_contains_rect)
		.def("min_x", &Geometry2d::Rect::minx)
		.def("min_y", &Geometry2d::Rect::miny)
		.def("max_x", &Geometry2d::Rect::maxx)
		.def("max_y", &Geometry2d::Rect::maxy)
		.def("near_point", &Geometry2d::Rect::nearPoint)
		.def("intersects_rect", &Geometry2d::Rect::intersects)
		.def("contains_point", &Geometry2d::Rect::containsPoint)
	;

	class_<Geometry2d::Circle, bases<Geometry2d::Shape> >("Circle", init<Geometry2d::Point, float>());

	class_<Geometry2d::CompositeShape, bases<Geometry2d::Shape> >("CompositeShape", init<>())
		.def("clear", &Geometry2d::CompositeShape::clear)
		.def("is_empty", &Geometry2d::CompositeShape::empty)
		.def("size", &Geometry2d::CompositeShape::size)
		.def("add_shape", &CompositeShape_add_shape)
		.def("contains_point", &Geometry2d::CompositeShape::containsPoint)
	;

	class_<GameState>("GameState")
		.def_readonly("our_score", &GameState::ourScore)
		.def_readonly("their_score", &GameState::theirScore)
		.def("is_halted", &GameState::halt)
		.def("is_stopped", &GameState::stopped)
		.def("is_playing", &GameState::playing)
		.def("is_kickoff", &GameState::kickoff)
		.def("is_penalty", &GameState::penalty)
		.def("is_direct", &GameState::direct)
		.def("is_indirect", &GameState::indirect)
		.def("is_our_kickoff", &GameState::ourKickoff)
		.def("is_our_penalty", &GameState::ourPenalty)
		.def("is_our_direct", &GameState::ourDirect)
		.def("is_our_indirect", &GameState::ourIndirect)
		.def("is_our_free_kick", &GameState::ourFreeKick)
		.def("is_their_kickoff", &GameState::theirKickoff)
		.def("is_their_penalty", &GameState::theirPenalty)
		.def("is_their_direct", &GameState::theirDirect)
		.def("is_their_indirect", &GameState::theirIndirect)
		.def("is_their_free_kick", &GameState::theirFreeKick)
		.def("is_setup_state", &GameState::inSetupState)
		.def("is_ready_state", &GameState::inReadyState)
		.def("can_kick", &GameState::canKick)
		.def("stay_away_from_ball", &GameState::stayAwayFromBall)
		.def("stay_on_side", &GameState::stayOnSide)
		.def("stay_behind_penalty_line", &GameState::stayBehindPenaltyLine)
	;

	class_<Robot>("Robot", init<int, bool>())
		.def("shell_id", &Robot::shell)
		.def("is_ours", &Robot::self)
		.def_readwrite("pos", &Robot::pos)
		.def_readwrite("vel", &Robot::vel)
		.def_readwrite("angle", &Robot::angle)
		.def_readwrite("angle_vel", &Robot::angleVel)
		.def_readwrite("visible", &Robot::visible)
		.def("__repr__", &Robot_repr)
	;

	class_<OurRobot, OurRobot *, std::shared_ptr<OurRobot>, bases<Robot> >("OurRobot", init<int, SystemState*>())
		.def("move_to", &OurRobot_move_to)
		.def("set_world_vel", &OurRobot::worldVelocity)
		.def("face", &OurRobot::face)
		.def("set_avoid_ball_radius", &OurRobot_set_avoid_ball_radius)
		.def("disable_avoid_ball", &OurRobot::disableAvoidBall)
		.def("avoid_all_teammates", &OurRobot::avoidAllTeammates)
		.def("add_text", &OutRobot_add_text)
		.def("approach_opponent", &OurRobot_approach_opponent)
		.def("set_dribble_speed", &OurRobot::dribble)
		.def("has_ball", &OurRobot::hasBall)
	;

	class_<OpponentRobot, OpponentRobot *, std::shared_ptr<OpponentRobot>, bases<Robot> >("OpponentRobot", init<int>());

	class_<Ball, std::shared_ptr<Ball> >("Ball", init<>())
		.def_readonly("pos", &Ball::pos)
		.def_readonly("vel", &Ball::vel)
		.def_readonly("valid", &Ball::valid)
	;

	class_<std::vector<OurRobot *> >("vector_OurRobot")
		.def(vector_indexing_suite<std::vector<OurRobot *> >())
	;

	class_<std::vector<OpponentRobot *> >("vector_OpponentRobot")
		.def(vector_indexing_suite<std::vector<OpponentRobot *> >())
	;

	class_<SystemState, SystemState *>("SystemState")
		.def_readonly("our_robots", &SystemState::self)
		.def_readonly("their_robots", &SystemState::opp)
		.def_readonly("ball", &SystemState::ball)
		.def_readonly("game_state", &SystemState::gameState)
		.def_readonly("timestamp", &SystemState::timestamp)

		//	debug drawing methods
		.def("draw_circle", &State_draw_circle)
		.def("draw_path", &SystemState::drawPath)
		.def("draw_text", &SystemState::drawText)
		.def("draw_shape", &SystemState::drawShape)
		.def("draw_line", &State_draw_line)
	;
}
<commit_msg>added some wrapper stuff<commit_after>#include "robocup-py.hpp"
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <string>
#include <sstream>
#include <iostream>

using namespace boost::python;

#include <Geometry2d/Point.hpp>
#include <Geometry2d/Rect.hpp>
#include <Geometry2d/CompositeShape.hpp>
#include <Robot.hpp>
#include <SystemState.hpp>
#include <protobuf/LogFrame.pb.h>

/**
 * NOTES FOR WRAPPER FUNCTIONS/METHODS
 *
 * Keep in mind that pointer parameters will be be nullptr/NULL if the value
 * from python was None.  Check for this case so that we don't segfault.
 */

//	this is here so boost can work with std::shared_ptr
template<class T> T * get_pointer( std::shared_ptr<T> const& p) {
	return p.get();
}

std::string Point_repr(Geometry2d::Point *self) {
	std::ostringstream ss;
	ss << "Point(";
	ss << self->x;
	ss << ", ";
	ss << self->y;
	ss << ")";

	std::string repr(ss.str());
	return repr;
}

std::string Robot_repr(Robot *self) {
	std::ostringstream ss;
	ss << "<Robot ";
	ss << (self->self() ? "us[" : "them[");
	ss << self->shell();
	ss << "], pos=";
	ss << Point_repr(&(self->pos));
	ss << ">";

	std::string repr(ss.str());
	return repr;
}

void OurRobot_move_to(OurRobot *self, Geometry2d::Point *to) {
	self->move(*to);
}

void OurRobot_set_avoid_ball_radius(OurRobot *self, float radius) {
	self->avoidBallRadius(radius);
}

void OurRobot_approach_opponent(OurRobot *self, unsigned shell_id, bool enable_approach) {
	self->approachOpponent(shell_id, enable_approach);
}

void OutRobot_add_text(OurRobot *self, const std::string &text, boost::python::tuple rgb, const std::string &layerPrefix) {
	float r = extract<float>(rgb[0]);
	float g = extract<float>(rgb[1]);
	float b = extract<float>(rgb[2]);

	self->addText(QString::fromStdString(text), QColor(r,g,b), QString::fromStdString(layerPrefix));
}

bool Rect_contains_rect(Geometry2d::Rect *self, Geometry2d::Rect *other) {
	return self->contains(*other);
}

bool Rect_contains_point(Geometry2d::Rect *self, Geometry2d::Point *pt) {
	return self->contains(*pt);
}

void Point_rotate(Geometry2d::Point *self, Geometry2d::Point *origin, float angle) {
	self->rotate(*origin, angle);
}

void CompositeShape_add_shape(Geometry2d::CompositeShape *self, Geometry2d::Shape *shape) {
	self->add(std::shared_ptr<Geometry2d::Shape>( shape->clone() ));
}

boost::python::tuple Line_wrap_pt(Geometry2d::Line *self) {
	boost::python::list a;
	for (int i = 0; i < 2; i++) {
		a.append(self->pt[i]);
	}
	return boost::python::tuple(a);
}

//	returns None or a Geometry2d::Point
boost::python::object Line_line_intersection(Geometry2d::Line *self, Geometry2d::Line *other) {
	Geometry2d::Point pt;
	if (self->intersects(*other, &pt)) {
		boost::python::object obj(pt);
		return obj;
	} else {
		//	return None
		return boost::python::object();
	}
};

QColor Color_from_tuple(const boost::python::tuple &colorTuple) {
	float r = extract<float>(rgb[0]);
	float g = extract<float>(rgb[1]);
	float b = extract<float>(rgb[2]);

	return QColor(r, g, b);
}

void State_draw_circle(SystemState *self, const Geometry2d::Point *center, float radius, boost::python::tuple rgb, const std::string &layer) {
	self->drawCircle(*center, radius, Color_from_tuple(rgb), QString::fromStdString(layer));
}

void State_draw_line(SystemState *self, const Geometry2d::Line *line, boost::python::tuple rgb, const std::string &layer) {
	self->drawLine(*line, Color_from_tuple(rgb), QString::fromStdString(layer));
}

/**
 * The code in this block wraps up c++ classes and makes them
 * accessible to python in the 'robocup' module.
 */
BOOST_PYTHON_MODULE(robocup)
{
	class_<Geometry2d::Point>("Point", init<float, float>())
		.def(init<const Geometry2d::Point &>())
		.def_readwrite("x", &Geometry2d::Point::x)
		.def_readwrite("y", &Geometry2d::Point::y)
		.def(self - self)
		.def(self + self)
		.def("mag", &Geometry2d::Point::mag)
		.def("magsq", &Geometry2d::Point::magsq)
		.def("__repr__", &Point_repr)
		.def("normalized", &Geometry2d::Point::normalized)
		.def("rotate", &Point_rotate)
		.def(self * float())
		.def(self / float())
		.def("perp_ccw", &Geometry2d::Point::perpCCW)
		.def("perp_cw", &Geometry2d::Point::perpCW)
		.def("angle", &Geometry2d::Point::angle)
		.def("dot", &Geometry2d::Point::dot)
		.def("near_point", &Geometry2d::Point::nearPoint)
	;

	class_<Geometry2d::Line, Geometry2d::Line*>("Line", init<Geometry2d::Point, Geometry2d::Point>())
		.add_property("pt", Line_wrap_pt)
		.def("delta", &Geometry2d::Line::delta)
		.def("line_intersection", &Line_line_intersection)
		.def("dist_to", &Geometry2d::Line::distTo)
	;

	class_<Geometry2d::Segment, Geometry2d::Segment*, bases<Geometry2d::Line> >("Segment", init<Geometry2d::Point, Geometry2d::Point>())
		.def("center", &Geometry2d::Segment::center)
		.def("length", &Geometry2d::Segment::length)
		.def("dist_to", &Geometry2d::Segment::distTo)
		.def("nearest_point", &Geometry2d::Segment::nearestPoint)
	;

	class_<Geometry2d::Shape, boost::noncopyable>("Shape")
	;

	class_<Geometry2d::Rect, bases<Geometry2d::Shape> >("Rect", init<Geometry2d::Point, Geometry2d::Point>())
		.def("contains_rect", &Rect_contains_rect)
		.def("min_x", &Geometry2d::Rect::minx)
		.def("min_y", &Geometry2d::Rect::miny)
		.def("max_x", &Geometry2d::Rect::maxx)
		.def("max_y", &Geometry2d::Rect::maxy)
		.def("near_point", &Geometry2d::Rect::nearPoint)
		.def("intersects_rect", &Geometry2d::Rect::intersects)
		.def("contains_point", &Geometry2d::Rect::containsPoint)
	;

	class_<Geometry2d::Circle, bases<Geometry2d::Shape> >("Circle", init<Geometry2d::Point, float>());

	class_<Geometry2d::CompositeShape, bases<Geometry2d::Shape> >("CompositeShape", init<>())
		.def("clear", &Geometry2d::CompositeShape::clear)
		.def("is_empty", &Geometry2d::CompositeShape::empty)
		.def("size", &Geometry2d::CompositeShape::size)
		.def("add_shape", &CompositeShape_add_shape)
		.def("contains_point", &Geometry2d::CompositeShape::containsPoint)
	;

	class_<GameState>("GameState")
		.def_readonly("our_score", &GameState::ourScore)
		.def_readonly("their_score", &GameState::theirScore)
		.def("is_halted", &GameState::halt)
		.def("is_stopped", &GameState::stopped)
		.def("is_playing", &GameState::playing)
		.def("is_kickoff", &GameState::kickoff)
		.def("is_penalty", &GameState::penalty)
		.def("is_direct", &GameState::direct)
		.def("is_indirect", &GameState::indirect)
		.def("is_our_kickoff", &GameState::ourKickoff)
		.def("is_our_penalty", &GameState::ourPenalty)
		.def("is_our_direct", &GameState::ourDirect)
		.def("is_our_indirect", &GameState::ourIndirect)
		.def("is_our_free_kick", &GameState::ourFreeKick)
		.def("is_their_kickoff", &GameState::theirKickoff)
		.def("is_their_penalty", &GameState::theirPenalty)
		.def("is_their_direct", &GameState::theirDirect)
		.def("is_their_indirect", &GameState::theirIndirect)
		.def("is_their_free_kick", &GameState::theirFreeKick)
		.def("is_setup_state", &GameState::inSetupState)
		.def("is_ready_state", &GameState::inReadyState)
		.def("can_kick", &GameState::canKick)
		.def("stay_away_from_ball", &GameState::stayAwayFromBall)
		.def("stay_on_side", &GameState::stayOnSide)
		.def("stay_behind_penalty_line", &GameState::stayBehindPenaltyLine)
	;

	class_<Robot>("Robot", init<int, bool>())
		.def("shell_id", &Robot::shell)
		.def("is_ours", &Robot::self)
		.def_readwrite("pos", &Robot::pos)
		.def_readwrite("vel", &Robot::vel)
		.def_readwrite("angle", &Robot::angle)
		.def_readwrite("angle_vel", &Robot::angleVel)
		.def_readwrite("visible", &Robot::visible)
		.def("__repr__", &Robot_repr)
	;

	class_<OurRobot, OurRobot *, std::shared_ptr<OurRobot>, bases<Robot> >("OurRobot", init<int, SystemState*>())
		.def("move_to", &OurRobot_move_to)
		.def("set_world_vel", &OurRobot::worldVelocity)
		.def("face", &OurRobot::face)
		.def("set_avoid_ball_radius", &OurRobot_set_avoid_ball_radius)
		.def("disable_avoid_ball", &OurRobot::disableAvoidBall)
		.def("avoid_all_teammates", &OurRobot::avoidAllTeammates)
		.def("add_text", &OutRobot_add_text)
		.def("approach_opponent", &OurRobot_approach_opponent)
		.def("set_dribble_speed", &OurRobot::dribble)
		.def("has_ball", &OurRobot::hasBall)
	;

	class_<OpponentRobot, OpponentRobot *, std::shared_ptr<OpponentRobot>, bases<Robot> >("OpponentRobot", init<int>());

	class_<Ball, std::shared_ptr<Ball> >("Ball", init<>())
		.def_readonly("pos", &Ball::pos)
		.def_readonly("vel", &Ball::vel)
		.def_readonly("valid", &Ball::valid)
	;

	class_<std::vector<OurRobot *> >("vector_OurRobot")
		.def(vector_indexing_suite<std::vector<OurRobot *> >())
	;

	class_<std::vector<OpponentRobot *> >("vector_OpponentRobot")
		.def(vector_indexing_suite<std::vector<OpponentRobot *> >())
	;

	class_<SystemState, SystemState *>("SystemState")
		.def_readonly("our_robots", &SystemState::self)
		.def_readonly("their_robots", &SystemState::opp)
		.def_readonly("ball", &SystemState::ball)
		.def_readonly("game_state", &SystemState::gameState)
		.def_readonly("timestamp", &SystemState::timestamp)

		//	debug drawing methods
		.def("draw_circle", &State_draw_circle)
		.def("draw_path", &SystemState::drawPath)
		.def("draw_text", &SystemState::drawText)
		.def("draw_shape", &SystemState::drawShape)
		.def("draw_line", &State_draw_line)
	;
}
<|endoftext|>


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

#include "Barrier.h"
#include "Matrix2x2.h"

typedef int veci16 __attribute__((ext_vector_type(16)));
typedef float vecf16 __attribute__((ext_vector_type(16)));

veci16* const kFrameBufferAddress = (veci16*) 0x200000;
const vecf16 kXOffsets = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f,
	8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f };
extern unsigned int kImage[];
const int kImageWidth = 16;
const int kImageHeight = 16;
const int kBytesPerPixel = 4;
const int kScreenWidth = 640;
const int kScreenHeight = 480;

void dflush(void *ptr)
{
	__asm("dflush %0" : : "r" (ptr));
}

Barrier<4> gFrameBarrier;	// We don't execute global ctors yet, but I know this is fine.
Matrix2x2 displayMatrix;

int main()
{
	// Start other threads
	__builtin_nyuzi_write_control_reg(30, 0xffffffff);

	int myStrandId = __builtin_nyuzi_read_control_reg(0);
	if (myStrandId == 0)
		displayMatrix = Matrix2x2();

	// 1/64 step rotation
	Matrix2x2 stepMatrix(
		0.9987954562, -0.04906767432,
		0.04906767432, 0.9987954562);
	stepMatrix = stepMatrix * Matrix2x2(0.99, 0.0, 0.0, 0.99);	// Scale slightly

	// Strands work on interleaved chunks of pixels.  The strand ID determines
	// the starting point.
	while (true)
	{
		unsigned int imageBase = (unsigned int) kImage;
		veci16 *outputPtr = kFrameBufferAddress + myStrandId;
		for (int y = 0; y < kScreenHeight; y++)
		{
			for (int x = myStrandId * 16; x < kScreenWidth; x += 64)
			{
				vecf16 xv = kXOffsets + __builtin_nyuzi_makevectorf((float) x)
					- __builtin_nyuzi_makevectorf(kScreenWidth / 2);
				vecf16 yv = __builtin_nyuzi_makevectorf((float) y)
					- __builtin_nyuzi_makevectorf(kScreenHeight / 2);;
				vecf16 u = xv * __builtin_nyuzi_makevectorf(displayMatrix.a)
					 + yv * __builtin_nyuzi_makevectorf(displayMatrix.b);
				vecf16 v = xv * __builtin_nyuzi_makevectorf(displayMatrix.c)
					+ yv * __builtin_nyuzi_makevectorf(displayMatrix.d);

				veci16 tx = (__builtin_convertvector(u, veci16) & __builtin_nyuzi_makevectori(kImageWidth - 1));
				veci16 ty = (__builtin_convertvector(v, veci16) & __builtin_nyuzi_makevectori(kImageHeight - 1));
				veci16 pixelPtrs = (ty * __builtin_nyuzi_makevectori(kImageWidth * kBytesPerPixel))
					+ (tx * __builtin_nyuzi_makevectori(kBytesPerPixel))
					+ __builtin_nyuzi_makevectori(imageBase);
				*outputPtr = __builtin_nyuzi_gather_loadi(pixelPtrs);
				dflush(outputPtr);
				outputPtr += 4;	// Skip over four chunks because there are four threads.
			}
		}

		if (myStrandId == 0)
			displayMatrix = displayMatrix * stepMatrix;

		gFrameBarrier.wait();
	}

	return 0;
}

unsigned int kImage[] = {
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xfffff8,
	0xc8ffeb,
	0x68ffe3,
	0x28ffdf,
	0x7ffdf,
	0x7ffe3,
	0x28ffeb,
	0x68fff8,
	0xc8ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffe7,
	0x48ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffe7,
	0x48ffff,
	0xffffff,
	0xffffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xfffff8,
	0xc8ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xfff8,
	0xc8ffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffe3,
	0x28ffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffe3,
	0x28ffdf,
	0x7ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffdf,
	0x7ffdf,
	0x7ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffdf,
	0x7ffe3,
	0x28ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffe3,
	0x28ffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68fff8,
	0xc8ffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xfff8,
	0xc8ffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0x0,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xffffff,
	0xffffff,
	0xffffe7,
	0x48ffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffe7,
	0x48ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xfffff8,
	0xc8ffeb,
	0x68ffe3,
	0x28ffdf,
	0x7ffdf,
	0x7ffe3,
	0x28ffeb,
	0x68fff8,
	0xc8ffff,
	0xffffff,
	0xffffff,
	0xffffff
};
<commit_msg>remove obsolete comment<commit_after>//
// Copyright 2011-2015 Jeff Bush
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "Barrier.h"
#include "Matrix2x2.h"

typedef int veci16 __attribute__((ext_vector_type(16)));
typedef float vecf16 __attribute__((ext_vector_type(16)));

veci16* const kFrameBufferAddress = (veci16*) 0x200000;
const vecf16 kXOffsets = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f,
	8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f };
extern unsigned int kImage[];
const int kImageWidth = 16;
const int kImageHeight = 16;
const int kBytesPerPixel = 4;
const int kScreenWidth = 640;
const int kScreenHeight = 480;

void dflush(void *ptr)
{
	__asm("dflush %0" : : "r" (ptr));
}

Barrier<4> gFrameBarrier;
Matrix2x2 displayMatrix;

int main()
{
	// Start other threads
	__builtin_nyuzi_write_control_reg(30, 0xffffffff);

	int myStrandId = __builtin_nyuzi_read_control_reg(0);
	if (myStrandId == 0)
		displayMatrix = Matrix2x2();

	// 1/64 step rotation
	Matrix2x2 stepMatrix(
		0.9987954562, -0.04906767432,
		0.04906767432, 0.9987954562);
	stepMatrix = stepMatrix * Matrix2x2(0.99, 0.0, 0.0, 0.99);	// Scale slightly

	// Strands work on interleaved chunks of pixels.  The strand ID determines
	// the starting point.
	while (true)
	{
		unsigned int imageBase = (unsigned int) kImage;
		veci16 *outputPtr = kFrameBufferAddress + myStrandId;
		for (int y = 0; y < kScreenHeight; y++)
		{
			for (int x = myStrandId * 16; x < kScreenWidth; x += 64)
			{
				vecf16 xv = kXOffsets + __builtin_nyuzi_makevectorf((float) x)
					- __builtin_nyuzi_makevectorf(kScreenWidth / 2);
				vecf16 yv = __builtin_nyuzi_makevectorf((float) y)
					- __builtin_nyuzi_makevectorf(kScreenHeight / 2);;
				vecf16 u = xv * __builtin_nyuzi_makevectorf(displayMatrix.a)
					 + yv * __builtin_nyuzi_makevectorf(displayMatrix.b);
				vecf16 v = xv * __builtin_nyuzi_makevectorf(displayMatrix.c)
					+ yv * __builtin_nyuzi_makevectorf(displayMatrix.d);

				veci16 tx = (__builtin_convertvector(u, veci16) & __builtin_nyuzi_makevectori(kImageWidth - 1));
				veci16 ty = (__builtin_convertvector(v, veci16) & __builtin_nyuzi_makevectori(kImageHeight - 1));
				veci16 pixelPtrs = (ty * __builtin_nyuzi_makevectori(kImageWidth * kBytesPerPixel))
					+ (tx * __builtin_nyuzi_makevectori(kBytesPerPixel))
					+ __builtin_nyuzi_makevectori(imageBase);
				*outputPtr = __builtin_nyuzi_gather_loadi(pixelPtrs);
				dflush(outputPtr);
				outputPtr += 4;	// Skip over four chunks because there are four threads.
			}
		}

		if (myStrandId == 0)
			displayMatrix = displayMatrix * stepMatrix;

		gFrameBarrier.wait();
	}

	return 0;
}

unsigned int kImage[] = {
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xfffff8,
	0xc8ffeb,
	0x68ffe3,
	0x28ffdf,
	0x7ffdf,
	0x7ffe3,
	0x28ffeb,
	0x68fff8,
	0xc8ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffe7,
	0x48ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffe7,
	0x48ffff,
	0xffffff,
	0xffffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xfffff8,
	0xc8ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xfff8,
	0xc8ffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffe3,
	0x28ffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffe3,
	0x28ffdf,
	0x7ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffdf,
	0x7ffdf,
	0x7ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffdf,
	0x7ffe3,
	0x28ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffe3,
	0x28ffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68fff8,
	0xc8ffde,
	0xffde,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xfff8,
	0xc8ffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0x0,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xffffff,
	0xffffff,
	0xffffe7,
	0x48ffde,
	0xffde,
	0xffde,
	0x0,
	0x0,
	0x0,
	0x0,
	0xffde,
	0xffde,
	0xffde,
	0xffe7,
	0x48ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffeb,
	0x68ffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffde,
	0xffeb,
	0x68ffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xffffff,
	0xfffff8,
	0xc8ffeb,
	0x68ffe3,
	0x28ffdf,
	0x7ffdf,
	0x7ffe3,
	0x28ffeb,
	0x68fff8,
	0xc8ffff,
	0xffffff,
	0xffffff,
	0xffffff
};
<|endoftext|>


<commit_before>/* Copyright © 2001-2022, Hove and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Hove (www.hove.com).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

LICENCE: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

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

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

Stay tuned using
twitter @navitia
channel `#navitia` on riot https://riot.im/app/#/room/#navitia:matrix.org
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "configuration.h"

#include "utils/exception.h"

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/optional.hpp>

#include <fstream>
#include <iostream>

namespace po = boost::program_options;

namespace navitia {
namespace kraken {

po::options_description get_options_description(const boost::optional<std::string>& name,
                                                const boost::optional<std::string>& zmq,
                                                const boost::optional<bool>& display_contributors) {
    po::options_description desc("Allowed options");
    // clang-format off
    desc.add_options()
        ("GENERAL.database", po::value<std::string>()->default_value("data.nav.lz4"), "path to the data file")

            //name and zmq socket can have default values (for tests)
        ("GENERAL.zmq_socket",
         zmq ? po::value<std::string>()->default_value(*zmq) : po::value<std::string>()->required(),
         "path to the zmq socket used for receiving resquest")
        ("GENERAL.instance_name",
         name ? po::value<std::string>()->default_value(*name) : po::value<std::string>()->required(),
         "name of the instance")

        ("GENERAL.nb_threads", po::value<int>()->default_value(1), "number of workers threads")
        ("GENERAL.is_realtime_enabled", po::value<bool>()->default_value(false),
                                        "enable loading of realtime data")
        ("GENERAL.is_realtime_add_enabled", po::value<bool>()->default_value(false),
                                        "enable loading of realtime data that add stop_times")
        ("GENERAL.is_realtime_add_trip_enabled", po::value<bool>()->default_value(false),
                                        "enable loading of realtime data that add trips (only if is_realtime_add_enabled is activated)")
        ("GENERAL.kirin_timeout", po::value<int>()->default_value(60000),
                                  "timeout in ms for loading realtime data from kirin")
        ("GENERAL.kirin_retry_timeout", po::value<int>()->default_value(5*60*1000),
                                  "timeout in ms before retrying to load realtime data")
        ("GENERAL.slow_request_duration", po::value<int>()->default_value(1000),
                                  "request running a least this number of milliseconds are logged")

        ("GENERAL.display_contributors", display_contributors ?
             po::value<bool>()->default_value(*display_contributors) : po::value<bool>()->default_value(false),
         "display all contributors in feed publishers")
        ("GENERAL.raptor_cache_size", po::value<int>()->default_value(10), "maximum number of stored raptor caches")
        ("GENERAL.log_level", po::value<std::string>(), "log level of kraken")
        ("GENERAL.log_format", po::value<std::string>()->default_value("[%D{%y-%m-%d %H:%M:%S,%q}] [%p] [%x] - %m %b:%L  %n"), "log format")

        ("GENERAL.enable_request_deadline", po::value<bool>()->default_value(true), "enable deadline of request")
        ("GENERAL.metrics_binding", po::value<std::string>(), "IP:PORT to serving metrics in http")
        ("GENERAL.core_file_size_limit", po::value<int>()->default_value(0), "ulimit that define the maximum size of a core file")

        ("BROKER.uri", po::value<std::string>(), "rabbitmq connection uri")
        ("BROKER.protocol", po::value<std::string>()->default_value("amqp"), "rabbitmq connection protocol")
        ("BROKER.host", po::value<std::string>()->default_value("localhost"), "host of rabbitmq")
        ("BROKER.port", po::value<int>()->default_value(5672), "port of rabbitmq")
        ("BROKER.username", po::value<std::string>()->default_value("guest"), "username for rabbitmq")
        ("BROKER.password", po::value<std::string>()->default_value("guest"), "password for rabbitmq")
        ("BROKER.vhost", po::value<std::string>()->default_value("/"), "vhost for rabbitmq")
        ("BROKER.exchange", po::value<std::string>()->default_value("navitia"), "exchange used in rabbitmq")
        ("BROKER.rt_topics", po::value<std::vector<std::string>>(), "list of realtime topic for this instance")
        ("BROKER.timeout", po::value<int>()->default_value(100), "timeout for maintenance worker in millisecond")
        ("BROKER.sleeptime", po::value<int>()->default_value(1), "sleeptime for maintenance worker in second")
        ("BROKER.queue", po::value<std::string>(), "rabbitmq's queue name to be bound")
        ("BROKER.queue_auto_delete", po::value<bool>()->default_value(false), "auto delete rabbitmq's queue when unbind")

        ("CHAOS.database", po::value<std::string>(), "Chaos database connection string")
        ("CHAOS.batch_size", po::value<int>()->default_value(1000000), "Chaos database row batch size");

    // clang-format on
    return desc;
}

static std::string env_parser(std::string env) {
    if (!boost::algorithm::starts_with(env, "KRAKEN_")) {
        return "";
    }
    boost::algorithm::replace_first(env, "KRAKEN_", "");
    boost::algorithm::replace_first(env, "GENERAL_", "GENERAL.");
    boost::algorithm::replace_first(env, "BROKER_", "BROKER.");
    boost::algorithm::replace_first(env, "CHAOS_", "CHAOS.");
    if (!boost::algorithm::starts_with(env, "GENERAL") && !boost::algorithm::starts_with(env, "BROKER")
        && !boost::algorithm::starts_with(env, "CHAOS")) {
        // it doesn't look like one of our var, we ignore it
        // docker and kubernetes define a lot of env var starting by kraken when deploying kraken
        // and boost po will abort startup if unknown var are present
        return "";
    }
    return env;
}

void Configuration::load(const std::string& filename) {
    po::options_description desc = get_options_description();

    po::store(po::parse_environment(desc, env_parser), this->vm);

    std::ifstream stream(filename);
    if (!stream.is_open() || !stream.good()) {
        std::cerr << "no configuration file found, using only environment variables" << std::endl;
    } else {
        // we allow unknown option for log4cplus
        po::store(po::parse_config_file(stream, desc, true), this->vm);
    }
    po::notify(this->vm);
}

std::vector<std::string> Configuration::load_from_command_line(const po::options_description& desc,
                                                               int argc,
                                                               const char* const argv[]) {
    auto tmp = po::basic_command_line_parser<char>(argc, argv).options(desc).allow_unregistered().run();
    po::store(tmp, vm);
    po::notify(vm);

    // return unparsed options
    return po::collect_unrecognized(tmp.options, po::include_positional);
}

std::string Configuration::databases_path() const {
    return this->vm["GENERAL.database"].as<std::string>();
}
std::string Configuration::zmq_socket_path() const {
    return this->vm["GENERAL.zmq_socket"].as<std::string>();
}
std::string Configuration::instance_name() const {
    return this->vm["GENERAL.instance_name"].as<std::string>();
}
boost::optional<std::string> Configuration::chaos_database() const {
    boost::optional<std::string> result;
    if (this->vm.count("CHAOS.database") > 0) {
        result = this->vm["CHAOS.database"].as<std::string>();
    }
    return result;
}
int Configuration::chaos_batch_size() const {
    int batch_size = vm["CHAOS.batch_size"].as<int>();
    if (batch_size < 0) {
        throw std::invalid_argument("chaos.batch_size cannot be negative");
    }
    return batch_size;
}

int Configuration::nb_threads() const {
    int nb_threads = vm["GENERAL.nb_threads"].as<int>();
    if (nb_threads < 0) {
        throw std::invalid_argument("nb_threads cannot be negative");
    }
    return size_t(nb_threads);
}

bool Configuration::is_realtime_enabled() const {
    return this->vm["GENERAL.is_realtime_enabled"].as<bool>();
}

bool Configuration::is_realtime_add_enabled() const {
    return this->vm["GENERAL.is_realtime_add_enabled"].as<bool>();
}

bool Configuration::is_realtime_add_trip_enabled() const {
    return this->vm["GENERAL.is_realtime_add_trip_enabled"].as<bool>();
}

int Configuration::kirin_timeout() const {
    return this->vm["GENERAL.kirin_timeout"].as<int>();
}

int Configuration::core_file_size_limit() const {
    return this->vm["GENERAL.core_file_size_limit"].as<int>();
}

boost::optional<std::string> Configuration::broker_uri() const {
    if (this->vm.count("BROKER.uri") > 0) {
        return this->vm["BROKER.uri"].as<std::string>();
    }
    return {};
}
std::string Configuration::broker_protocol() const {
    return this->vm["BROKER.protocol"].as<std::string>();
}
std::string Configuration::broker_host() const {
    return this->vm["BROKER.host"].as<std::string>();
}
int Configuration::broker_port() const {
    return this->vm["BROKER.port"].as<int>();
}
std::string Configuration::broker_username() const {
    return this->vm["BROKER.username"].as<std::string>();
}
std::string Configuration::broker_password() const {
    return this->vm["BROKER.password"].as<std::string>();
}
std::string Configuration::broker_vhost() const {
    return this->vm["BROKER.vhost"].as<std::string>();
}
std::string Configuration::broker_exchange() const {
    return this->vm["BROKER.exchange"].as<std::string>();
}

int Configuration::broker_timeout() const {
    return vm["BROKER.timeout"].as<int>();
}

int Configuration::broker_sleeptime() const {
    return vm["BROKER.sleeptime"].as<int>();
}

std::string Configuration::broker_queue(const std::string& default_queue) const {
    if (vm.count("BROKER.queue")) {
        return this->vm["BROKER.queue"].as<std::string>();
    }
    return default_queue;
}

bool Configuration::broker_queue_auto_delete() const {
    return vm["BROKER.queue_auto_delete"].as<bool>();
}

std::vector<std::string> Configuration::rt_topics() const {
    if (!this->vm.count("BROKER.rt_topics")) {
        return std::vector<std::string>();
    }
    return this->vm["BROKER.rt_topics"].as<std::vector<std::string>>();
}

int Configuration::kirin_retry_timeout() const {
    return vm["GENERAL.kirin_retry_timeout"].as<int>();
}

bool Configuration::display_contributors() const {
    if (!this->vm.count("GENERAL.display_contributors")) {
        return false;
    }
    return vm["GENERAL.display_contributors"].as<bool>();
}

int Configuration::slow_request_duration() const {
    return vm["GENERAL.slow_request_duration"].as<int>();
}

bool Configuration::enable_request_deadline() const {
    return vm["GENERAL.enable_request_deadline"].as<bool>();
}

size_t Configuration::raptor_cache_size() const {
    if (!vm.count("GENERAL.raptor_cache_size")) {
        return 10;
    }
    int raptor_cache_size = vm["GENERAL.raptor_cache_size"].as<int>();
    if (raptor_cache_size < 1) {
        throw std::invalid_argument("raptor_cache_size must be strictly positive");
    }
    return size_t(raptor_cache_size);
}

boost::optional<std::string> Configuration::log_level() const {
    boost::optional<std::string> result;
    if (this->vm.count("GENERAL.log_level") > 0) {
        result = this->vm["GENERAL.log_level"].as<std::string>();
    }
    return result;
}
boost::optional<std::string> Configuration::log_format() const {
    boost::optional<std::string> result;
    if (this->vm.count("GENERAL.log_format") > 0) {
        result = this->vm["GENERAL.log_format"].as<std::string>();
    }
    return result;
}

boost::optional<std::string> Configuration::metrics_binding() const {
    boost::optional<std::string> result;
    if (this->vm.count("GENERAL.metrics_binding") > 0) {
        result = this->vm["GENERAL.metrics_binding"].as<std::string>();
    }
    return result;
}
}  // namespace kraken
}  // namespace navitia
<commit_msg>Remove unused include<commit_after>/* Copyright © 2001-2022, Hove and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Hove (www.hove.com).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

LICENCE: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

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

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

Stay tuned using
twitter @navitia
channel `#navitia` on riot https://riot.im/app/#/room/#navitia:matrix.org
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "configuration.h"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/optional.hpp>

#include <fstream>
#include <iostream>

namespace po = boost::program_options;

namespace navitia {
namespace kraken {

po::options_description get_options_description(const boost::optional<std::string>& name,
                                                const boost::optional<std::string>& zmq,
                                                const boost::optional<bool>& display_contributors) {
    po::options_description desc("Allowed options");
    // clang-format off
    desc.add_options()
        ("GENERAL.database", po::value<std::string>()->default_value("data.nav.lz4"), "path to the data file")

            //name and zmq socket can have default values (for tests)
        ("GENERAL.zmq_socket",
         zmq ? po::value<std::string>()->default_value(*zmq) : po::value<std::string>()->required(),
         "path to the zmq socket used for receiving resquest")
        ("GENERAL.instance_name",
         name ? po::value<std::string>()->default_value(*name) : po::value<std::string>()->required(),
         "name of the instance")

        ("GENERAL.nb_threads", po::value<int>()->default_value(1), "number of workers threads")
        ("GENERAL.is_realtime_enabled", po::value<bool>()->default_value(false),
                                        "enable loading of realtime data")
        ("GENERAL.is_realtime_add_enabled", po::value<bool>()->default_value(false),
                                        "enable loading of realtime data that add stop_times")
        ("GENERAL.is_realtime_add_trip_enabled", po::value<bool>()->default_value(false),
                                        "enable loading of realtime data that add trips (only if is_realtime_add_enabled is activated)")
        ("GENERAL.kirin_timeout", po::value<int>()->default_value(60000),
                                  "timeout in ms for loading realtime data from kirin")
        ("GENERAL.kirin_retry_timeout", po::value<int>()->default_value(5*60*1000),
                                  "timeout in ms before retrying to load realtime data")
        ("GENERAL.slow_request_duration", po::value<int>()->default_value(1000),
                                  "request running a least this number of milliseconds are logged")

        ("GENERAL.display_contributors", display_contributors ?
             po::value<bool>()->default_value(*display_contributors) : po::value<bool>()->default_value(false),
         "display all contributors in feed publishers")
        ("GENERAL.raptor_cache_size", po::value<int>()->default_value(10), "maximum number of stored raptor caches")
        ("GENERAL.log_level", po::value<std::string>(), "log level of kraken")
        ("GENERAL.log_format", po::value<std::string>()->default_value("[%D{%y-%m-%d %H:%M:%S,%q}] [%p] [%x] - %m %b:%L  %n"), "log format")

        ("GENERAL.enable_request_deadline", po::value<bool>()->default_value(true), "enable deadline of request")
        ("GENERAL.metrics_binding", po::value<std::string>(), "IP:PORT to serving metrics in http")
        ("GENERAL.core_file_size_limit", po::value<int>()->default_value(0), "ulimit that define the maximum size of a core file")

        ("BROKER.uri", po::value<std::string>(), "rabbitmq connection uri")
        ("BROKER.protocol", po::value<std::string>()->default_value("amqp"), "rabbitmq connection protocol")
        ("BROKER.host", po::value<std::string>()->default_value("localhost"), "host of rabbitmq")
        ("BROKER.port", po::value<int>()->default_value(5672), "port of rabbitmq")
        ("BROKER.username", po::value<std::string>()->default_value("guest"), "username for rabbitmq")
        ("BROKER.password", po::value<std::string>()->default_value("guest"), "password for rabbitmq")
        ("BROKER.vhost", po::value<std::string>()->default_value("/"), "vhost for rabbitmq")
        ("BROKER.exchange", po::value<std::string>()->default_value("navitia"), "exchange used in rabbitmq")
        ("BROKER.rt_topics", po::value<std::vector<std::string>>(), "list of realtime topic for this instance")
        ("BROKER.timeout", po::value<int>()->default_value(100), "timeout for maintenance worker in millisecond")
        ("BROKER.sleeptime", po::value<int>()->default_value(1), "sleeptime for maintenance worker in second")
        ("BROKER.queue", po::value<std::string>(), "rabbitmq's queue name to be bound")
        ("BROKER.queue_auto_delete", po::value<bool>()->default_value(false), "auto delete rabbitmq's queue when unbind")

        ("CHAOS.database", po::value<std::string>(), "Chaos database connection string")
        ("CHAOS.batch_size", po::value<int>()->default_value(1000000), "Chaos database row batch size");

    // clang-format on
    return desc;
}

static std::string env_parser(std::string env) {
    if (!boost::algorithm::starts_with(env, "KRAKEN_")) {
        return "";
    }
    boost::algorithm::replace_first(env, "KRAKEN_", "");
    boost::algorithm::replace_first(env, "GENERAL_", "GENERAL.");
    boost::algorithm::replace_first(env, "BROKER_", "BROKER.");
    boost::algorithm::replace_first(env, "CHAOS_", "CHAOS.");
    if (!boost::algorithm::starts_with(env, "GENERAL") && !boost::algorithm::starts_with(env, "BROKER")
        && !boost::algorithm::starts_with(env, "CHAOS")) {
        // it doesn't look like one of our var, we ignore it
        // docker and kubernetes define a lot of env var starting by kraken when deploying kraken
        // and boost po will abort startup if unknown var are present
        return "";
    }
    return env;
}

void Configuration::load(const std::string& filename) {
    po::options_description desc = get_options_description();

    po::store(po::parse_environment(desc, env_parser), this->vm);

    std::ifstream stream(filename);
    if (!stream.is_open() || !stream.good()) {
        std::cerr << "no configuration file found, using only environment variables" << std::endl;
    } else {
        // we allow unknown option for log4cplus
        po::store(po::parse_config_file(stream, desc, true), this->vm);
    }
    po::notify(this->vm);
}

std::vector<std::string> Configuration::load_from_command_line(const po::options_description& desc,
                                                               int argc,
                                                               const char* const argv[]) {
    auto tmp = po::basic_command_line_parser<char>(argc, argv).options(desc).allow_unregistered().run();
    po::store(tmp, vm);
    po::notify(vm);

    // return unparsed options
    return po::collect_unrecognized(tmp.options, po::include_positional);
}

std::string Configuration::databases_path() const {
    return this->vm["GENERAL.database"].as<std::string>();
}
std::string Configuration::zmq_socket_path() const {
    return this->vm["GENERAL.zmq_socket"].as<std::string>();
}
std::string Configuration::instance_name() const {
    return this->vm["GENERAL.instance_name"].as<std::string>();
}
boost::optional<std::string> Configuration::chaos_database() const {
    boost::optional<std::string> result;
    if (this->vm.count("CHAOS.database") > 0) {
        result = this->vm["CHAOS.database"].as<std::string>();
    }
    return result;
}
int Configuration::chaos_batch_size() const {
    int batch_size = vm["CHAOS.batch_size"].as<int>();
    if (batch_size < 0) {
        throw std::invalid_argument("chaos.batch_size cannot be negative");
    }
    return batch_size;
}

int Configuration::nb_threads() const {
    int nb_threads = vm["GENERAL.nb_threads"].as<int>();
    if (nb_threads < 0) {
        throw std::invalid_argument("nb_threads cannot be negative");
    }
    return size_t(nb_threads);
}

bool Configuration::is_realtime_enabled() const {
    return this->vm["GENERAL.is_realtime_enabled"].as<bool>();
}

bool Configuration::is_realtime_add_enabled() const {
    return this->vm["GENERAL.is_realtime_add_enabled"].as<bool>();
}

bool Configuration::is_realtime_add_trip_enabled() const {
    return this->vm["GENERAL.is_realtime_add_trip_enabled"].as<bool>();
}

int Configuration::kirin_timeout() const {
    return this->vm["GENERAL.kirin_timeout"].as<int>();
}

int Configuration::core_file_size_limit() const {
    return this->vm["GENERAL.core_file_size_limit"].as<int>();
}

boost::optional<std::string> Configuration::broker_uri() const {
    if (this->vm.count("BROKER.uri") > 0) {
        return this->vm["BROKER.uri"].as<std::string>();
    }
    return {};
}
std::string Configuration::broker_protocol() const {
    return this->vm["BROKER.protocol"].as<std::string>();
}
std::string Configuration::broker_host() const {
    return this->vm["BROKER.host"].as<std::string>();
}
int Configuration::broker_port() const {
    return this->vm["BROKER.port"].as<int>();
}
std::string Configuration::broker_username() const {
    return this->vm["BROKER.username"].as<std::string>();
}
std::string Configuration::broker_password() const {
    return this->vm["BROKER.password"].as<std::string>();
}
std::string Configuration::broker_vhost() const {
    return this->vm["BROKER.vhost"].as<std::string>();
}
std::string Configuration::broker_exchange() const {
    return this->vm["BROKER.exchange"].as<std::string>();
}

int Configuration::broker_timeout() const {
    return vm["BROKER.timeout"].as<int>();
}

int Configuration::broker_sleeptime() const {
    return vm["BROKER.sleeptime"].as<int>();
}

std::string Configuration::broker_queue(const std::string& default_queue) const {
    if (vm.count("BROKER.queue")) {
        return this->vm["BROKER.queue"].as<std::string>();
    }
    return default_queue;
}

bool Configuration::broker_queue_auto_delete() const {
    return vm["BROKER.queue_auto_delete"].as<bool>();
}

std::vector<std::string> Configuration::rt_topics() const {
    if (!this->vm.count("BROKER.rt_topics")) {
        return std::vector<std::string>();
    }
    return this->vm["BROKER.rt_topics"].as<std::vector<std::string>>();
}

int Configuration::kirin_retry_timeout() const {
    return vm["GENERAL.kirin_retry_timeout"].as<int>();
}

bool Configuration::display_contributors() const {
    if (!this->vm.count("GENERAL.display_contributors")) {
        return false;
    }
    return vm["GENERAL.display_contributors"].as<bool>();
}

int Configuration::slow_request_duration() const {
    return vm["GENERAL.slow_request_duration"].as<int>();
}

bool Configuration::enable_request_deadline() const {
    return vm["GENERAL.enable_request_deadline"].as<bool>();
}

size_t Configuration::raptor_cache_size() const {
    if (!vm.count("GENERAL.raptor_cache_size")) {
        return 10;
    }
    int raptor_cache_size = vm["GENERAL.raptor_cache_size"].as<int>();
    if (raptor_cache_size < 1) {
        throw std::invalid_argument("raptor_cache_size must be strictly positive");
    }
    return size_t(raptor_cache_size);
}

boost::optional<std::string> Configuration::log_level() const {
    boost::optional<std::string> result;
    if (this->vm.count("GENERAL.log_level") > 0) {
        result = this->vm["GENERAL.log_level"].as<std::string>();
    }
    return result;
}
boost::optional<std::string> Configuration::log_format() const {
    boost::optional<std::string> result;
    if (this->vm.count("GENERAL.log_format") > 0) {
        result = this->vm["GENERAL.log_format"].as<std::string>();
    }
    return result;
}

boost::optional<std::string> Configuration::metrics_binding() const {
    boost::optional<std::string> result;
    if (this->vm.count("GENERAL.metrics_binding") > 0) {
        result = this->vm["GENERAL.metrics_binding"].as<std::string>();
    }
    return result;
}
}  // namespace kraken
}  // namespace navitia
<|endoftext|>


<commit_before>#include <fstream>

#include "data/EventsHeader.h"
#include "data/Event.h"
#include "exception/Base.h"

namespace blitzortung {
  namespace data {

    const char* EventsHeader::ID = "BOSF";

    const gr::date EventsHeader::STARTOFEPOCH = gr::date(1970, 1, 1);

    bool file_exists(std::string filename) {
      std::ifstream file;

      file.open(filename.c_str(), std::ios::in);
      file.close();

      return ! file.fail();
    }

    EventsHeader::EventsHeader(const gr::date& date) :
      date_(date),
      logger_("data.EventsHeader")
    {
      if (logger_.isDebugEnabled())
	logger_.debugStream() << "construct() date " << date;
    }

    EventsHeader::~EventsHeader() {
    }

    const gr::date& EventsHeader::getDate() const {
      return date_;
    }

    void EventsHeader::setDate(const gr::date& date) {
      date_ = date;
    }

    unsigned int EventsHeader::getNumberOfEvents() const {
      return numberOfEvents_;
    }

    unsigned int EventsHeader::getEventSize() const {
      return dataFormat_.getDataSize();
    }

    void EventsHeader::read(const std::string& filename) {

      if (! file_exists(filename)) {
	std::ostringstream oss;
	oss << "data::EventHeader::read() file '" << filename << "' does not exist";
	throw exception::Base(oss.str());
      }
      std::fstream fstream;

      fstream.open(formatFilename(filename).c_str(), std::ios::in | std::ios::binary);

      fstream.seekg(0, std::ios::beg);

      {
	char tempId[5];

	// check for correct file ID
	fstream.read(tempId, 4);

	std::string fileId(tempId);
	tempId[sizeof(tempId)-1] = 0;

	if (std::string(tempId) != ID) {
	  std::ostringstream oss;
	  oss << "data::EventsHeader bad file header '" << tempId << "' vs '" << ID << "'";
	  throw exception::Base(oss.str());
	}
      }

      {
	unsigned int fileEpochDays;

	// read file version from file
	fstream.read((char*)&fileEpochDays, sizeof(unsigned int));
	date_ = STARTOFEPOCH + gr::days(fileEpochDays);
      }

      dataFormat_.fromStream(fstream);

      // check if read position corresponds to header size
      assert(fstream.tellg() == getSize());

      fstream.seekg(0, std::ios::end);
      unsigned int filesize = fstream.tellg();

      fstream.close();

      filesize -= getSize();

      numberOfEvents_ = filesize / getEventSize();

      if (logger_.isDebugEnabled())
	logger_.debugStream() << "read() date " << date_ << " #events " << numberOfEvents_ << " eventsize " << getEventSize() << " filesize " << filesize;

      if (numberOfEvents_ * getEventSize() != filesize)
	throw exception::Base("data::EventsHeader file size mismatch");
    }

    Event::AP EventsHeader::createEvent(std::iostream& stream) const {
      return Event::AP(new Event(dataFormat_, date_, stream));
    }

    std::string EventsHeader::formatFilename(const std::string& fileformat) const {

      if (! date_.is_not_a_date()) {

        gr::date_facet *datefacet = new gr::date_facet();
        datefacet->format(fileformat.c_str());

        std::ostringstream filenamestream;
        filenamestream.imbue(std::locale(std::locale::classic(), datefacet));
        filenamestream << date_;

        return filenamestream.str();
      } else {
	return fileformat;
	throw exception::Base("data::EventsHeader formatFilename() ERROR: no file date");
      }
    }

    void EventsHeader::write(const std::string& filename) const {

      if (date_ == gr::date(pt::not_a_date_time))
	throw exception::Base("data::EventsHeader writeHeader() invalid file date");

      std::fstream fstream;

      fstream.open(formatFilename(filename).c_str(), std::ios::out | std::ios::trunc | std::ios::binary);

      fstream.seekg(0, std::ios::beg);

      fstream.write(ID, 4);

      {
	unsigned int fileEpochDays = (date_ - STARTOFEPOCH).days();
	fstream.write((char*) &fileEpochDays, sizeof(unsigned int));
      }

      dataFormat_.toStream(fstream);

      assert(fstream.tellg() == getSize());

      fstream.close();
    }

    bool EventsHeader::fileExists(const std::string& filename) const {
      return file_exists(formatFilename(filename));
    }

    bool EventsHeader::operator==(const EventsHeader& other) {
      return date_ == other.date_ && dataFormat_ == other.dataFormat_;
    }

    bool EventsHeader::operator!=(const EventsHeader& other) {
      return !(*this == other);
    }

    unsigned int EventsHeader::getSize() const {
      return 10;
    }

  }
}

<commit_msg>adapt header size<commit_after>#include <fstream>

#include "data/EventsHeader.h"
#include "data/Event.h"
#include "exception/Base.h"

namespace blitzortung {
  namespace data {

    const char* EventsHeader::ID = "BOSF";

    const gr::date EventsHeader::STARTOFEPOCH = gr::date(1970, 1, 1);

    bool file_exists(std::string filename) {
      std::ifstream file;

      file.open(filename.c_str(), std::ios::in);
      file.close();

      return ! file.fail();
    }

    EventsHeader::EventsHeader(const gr::date& date) :
      date_(date),
      logger_("data.EventsHeader")
    {
      if (logger_.isDebugEnabled())
	logger_.debugStream() << "construct() date " << date;
    }

    EventsHeader::~EventsHeader() {
    }

    const gr::date& EventsHeader::getDate() const {
      return date_;
    }

    void EventsHeader::setDate(const gr::date& date) {
      date_ = date;
    }

    unsigned int EventsHeader::getNumberOfEvents() const {
      return numberOfEvents_;
    }

    unsigned int EventsHeader::getEventSize() const {
      return dataFormat_.getDataSize();
    }

    void EventsHeader::read(const std::string& filename) {

      if (! file_exists(filename)) {
	std::ostringstream oss;
	oss << "data::EventHeader::read() file '" << filename << "' does not exist";
	throw exception::Base(oss.str());
      }
      std::fstream fstream;

      fstream.open(formatFilename(filename).c_str(), std::ios::in | std::ios::binary);

      fstream.seekg(0, std::ios::beg);

      {
	char tempId[5];

	// check for correct file ID
	fstream.read(tempId, 4);

	std::string fileId(tempId);
	tempId[sizeof(tempId)-1] = 0;

	if (std::string(tempId) != ID) {
	  std::ostringstream oss;
	  oss << "data::EventsHeader bad file header '" << tempId << "' vs '" << ID << "'";
	  throw exception::Base(oss.str());
	}
      }

      {
	unsigned int fileEpochDays;

	// read file version from file
	fstream.read((char*)&fileEpochDays, sizeof(unsigned int));
	date_ = STARTOFEPOCH + gr::days(fileEpochDays);
      }

      dataFormat_.fromStream(fstream);

      // check if read position corresponds to header size
      assert(fstream.tellg() == getSize());

      fstream.seekg(0, std::ios::end);
      unsigned int filesize = fstream.tellg();

      fstream.close();

      filesize -= getSize();

      numberOfEvents_ = filesize / getEventSize();

      if (logger_.isDebugEnabled())
	logger_.debugStream() << "read() date " << date_ << " #events " << numberOfEvents_ << " eventsize " << getEventSize() << " filesize " << filesize;

      if (numberOfEvents_ * getEventSize() != filesize)
	throw exception::Base("data::EventsHeader file size mismatch");
    }

    Event::AP EventsHeader::createEvent(std::iostream& stream) const {
      return Event::AP(new Event(dataFormat_, date_, stream));
    }

    std::string EventsHeader::formatFilename(const std::string& fileformat) const {

      if (! date_.is_not_a_date()) {

        gr::date_facet *datefacet = new gr::date_facet();
        datefacet->format(fileformat.c_str());

        std::ostringstream filenamestream;
        filenamestream.imbue(std::locale(std::locale::classic(), datefacet));
        filenamestream << date_;

        return filenamestream.str();
      } else {
	return fileformat;
	throw exception::Base("data::EventsHeader formatFilename() ERROR: no file date");
      }
    }

    void EventsHeader::write(const std::string& filename) const {

      if (date_ == gr::date(pt::not_a_date_time))
	throw exception::Base("data::EventsHeader writeHeader() invalid file date");

      std::fstream fstream;

      fstream.open(formatFilename(filename).c_str(), std::ios::out | std::ios::trunc | std::ios::binary);

      fstream.seekg(0, std::ios::beg);

      fstream.write(ID, 4);

      {
	unsigned int fileEpochDays = (date_ - STARTOFEPOCH).days();
	fstream.write((char*) &fileEpochDays, sizeof(unsigned int));
      }

      dataFormat_.toStream(fstream);

      //std::cout << " header size: " << fstream.tellg() << " should be " << getSize();

      assert(fstream.tellg() == getSize());

      fstream.close();
    }

    bool EventsHeader::fileExists(const std::string& filename) const {
      return file_exists(formatFilename(filename));
    }

    bool EventsHeader::operator==(const EventsHeader& other) {
      return date_ == other.date_ && dataFormat_ == other.dataFormat_;
    }

    bool EventsHeader::operator!=(const EventsHeader& other) {
      return !(*this == other);
    }

    unsigned int EventsHeader::getSize() const {
      return 12;
    }

  }
}

<|endoftext|>


<commit_before>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2009      Sandro Santilli <strk@keybit.net>
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 * Copyright (C) 2005 Refractions Research Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: operation/IsSimpleOp.java rev. 1.22 (JTS-1.10)
 *
 **********************************************************************/

#include <geos/operation/IsSimpleOp.h>
//#include <geos/operation/EndpointInfo.h>
#include <geos/algorithm/BoundaryNodeRule.h>
#include <geos/algorithm/LineIntersector.h>
#include <geos/geomgraph/GeometryGraph.h>
#include <geos/geomgraph/Edge.h>
#include <geos/geomgraph/EdgeIntersection.h>
#include <geos/geomgraph/index/SegmentIntersector.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/MultiPoint.h>
#include <geos/geom/MultiLineString.h>
#include <geos/geom/Point.h>
#include <geos/geom/Coordinate.h>

#include <set>
#include <cassert>

using namespace std;
using namespace geos::algorithm;
using namespace geos::geomgraph;
using namespace geos::geomgraph::index;
using namespace geos::geom;

namespace geos {
namespace operation { // geos.operation

// This is supposedly a private of IsSimpleOp...
class EndpointInfo
{
public:

	Coordinate pt;

	bool isClosed;

	int degree;

    	EndpointInfo(const geom::Coordinate& newPt);

	const Coordinate& getCoordinate() const { return pt; }

	void addEndpoint(bool newIsClosed)
	{
		degree++;
		isClosed |= newIsClosed;
	}
};

EndpointInfo::EndpointInfo(const Coordinate& newPt)
{
	pt=newPt;
	isClosed=false;
	degree=0;
}

// -----------------------------------------------------

/*public*/
IsSimpleOp::IsSimpleOp()
	:
	isClosedEndpointsInInterior(true),
	geom(0),
	nonSimpleLocation()
{}

/*public*/
IsSimpleOp::IsSimpleOp(const Geometry& g)
	:
	isClosedEndpointsInInterior(true),
	geom(&g),
	nonSimpleLocation()
{}

/*public*/
IsSimpleOp::IsSimpleOp(const Geometry& g,
	               const BoundaryNodeRule& boundaryNodeRule)
	:
	isClosedEndpointsInInterior( ! boundaryNodeRule.isInBoundary(2) ),
	geom(&g),
	nonSimpleLocation()
{}

/*public*/
bool
IsSimpleOp::isSimple()
{
	nonSimpleLocation.reset();

	if ( dynamic_cast<const LineString*>(geom) )
		return isSimpleLinearGeometry(geom);

	if ( dynamic_cast<const MultiLineString*>(geom) )
		return isSimpleLinearGeometry(geom);

	const MultiPoint* mp = dynamic_cast<const MultiPoint*>(geom);
	if ( mp ) return isSimpleMultiPoint(*mp);

	// all other geometry types are simple by definition
	return true;
}

/*public*/
bool
IsSimpleOp::isSimple(const LineString *geom)
{
	return isSimpleLinearGeometry(geom);
}

/*public*/
bool
IsSimpleOp::isSimple(const MultiLineString *geom)
{
	return isSimpleLinearGeometry(geom);
}

/*public*/
bool
IsSimpleOp::isSimple(const MultiPoint *mp)
{
	return isSimpleMultiPoint(*mp);
}

/*private*/
bool
IsSimpleOp::isSimpleMultiPoint(const MultiPoint& mp)
{
	if (mp.isEmpty()) return true;
	set<const Coordinate*, CoordinateLessThen> points;

	for (std::size_t i=0, n=mp.getNumGeometries(); i<n; ++i)
	{
		assert(dynamic_cast<const Point*>(mp.getGeometryN(i)));
		const Point *pt=static_cast<const Point*>(mp.getGeometryN(i));
		const Coordinate *p=pt->getCoordinate();
		if (points.find(p) != points.end())
		{
			nonSimpleLocation.reset(new Coordinate(*p));
			return false;
		}
		points.insert(p);
	}
	return true;
}

bool
IsSimpleOp::isSimpleLinearGeometry(const Geometry *geom)
{
	if (geom->isEmpty()) return true;
	GeometryGraph graph(0,geom);
	LineIntersector li;
	std::auto_ptr<SegmentIntersector> si (graph.computeSelfNodes(&li,true));

	// if no self-intersection, must be simple
	if (!si->hasIntersection()) return true;

	if (si->hasProperIntersection())
	{
		nonSimpleLocation.reset(
			new Coordinate(si->getProperIntersectionPoint())
		);
		return false;
	}

	if (hasNonEndpointIntersection(graph)) return false;

	if ( isClosedEndpointsInInterior ) {
		if (hasClosedEndpointIntersection(graph)) return false;
	}

	return true;
}

/*private*/
bool
IsSimpleOp::hasNonEndpointIntersection(GeometryGraph &graph)
{
	vector<Edge*> *edges=graph.getEdges();
	for (vector<Edge*>::iterator i=edges->begin();i<edges->end();i++) {
		Edge *e=*i;
		int maxSegmentIndex=e->getMaximumSegmentIndex();
		EdgeIntersectionList &eiL=e->getEdgeIntersectionList();
		for ( EdgeIntersectionList::iterator eiIt=eiL.begin(),
			eiEnd=eiL.end(); eiIt!=eiEnd; ++eiIt )
		{
			EdgeIntersection *ei=*eiIt;
			if (!ei->isEndPoint(maxSegmentIndex))
			{
				nonSimpleLocation.reset(
					new Coordinate(ei->getCoordinate())
				);
				return true;
			}
		}
	}
	return false;
}

/*private*/
bool
IsSimpleOp::hasClosedEndpointIntersection(GeometryGraph &graph)
{
	map<const Coordinate*,EndpointInfo*,CoordinateLessThen> endPoints;
	vector<Edge*> *edges=graph.getEdges();
	for (vector<Edge*>::iterator i=edges->begin();i<edges->end();i++) {
		Edge *e=*i;
		//int maxSegmentIndex=e->getMaximumSegmentIndex();
		bool isClosed=e->isClosed();
		const Coordinate *p0=&e->getCoordinate(0);
		addEndpoint(endPoints,p0,isClosed);
		const Coordinate *p1=&e->getCoordinate(e->getNumPoints()-1);
		addEndpoint(endPoints,p1,isClosed);
	}

	map<const Coordinate*,EndpointInfo*,CoordinateLessThen>::iterator it=endPoints.begin();
	for (; it!=endPoints.end(); ++it) {
		EndpointInfo *eiInfo=it->second;
		if (eiInfo->isClosed && eiInfo->degree!=2) {
			it=endPoints.begin();
			for (; it!=endPoints.end(); ++it) {
				EndpointInfo *ep=it->second;
				delete ep;
			}
			nonSimpleLocation.reset(
				new Coordinate( eiInfo->getCoordinate() )
			);
            		return true;
		}
	}

	it=endPoints.begin();
	for (; it!=endPoints.end(); ++it) {
		EndpointInfo *ep=it->second;
		delete ep;
	}
	return false;
}

/*private*/
void
IsSimpleOp::addEndpoint(
	map<const Coordinate*,EndpointInfo*,CoordinateLessThen>&endPoints,
	const Coordinate *p,bool isClosed)
{
	map<const Coordinate*,EndpointInfo*,CoordinateLessThen>::iterator it=endPoints.find(p);
	EndpointInfo *eiInfo;
	if (it==endPoints.end()) {
		eiInfo=NULL;
	} else {
		eiInfo=it->second;
	}
	if (eiInfo==NULL) {
		eiInfo=new EndpointInfo(*p);
		endPoints[p]=eiInfo;
	}
	eiInfo->addEndpoint(isClosed);
}

} // namespace geos::operation
} // namespace geos

<commit_msg>Fix memory bug <commit_after>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2009      Sandro Santilli <strk@keybit.net>
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 * Copyright (C) 2005 Refractions Research Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: operation/IsSimpleOp.java rev. 1.22 (JTS-1.10)
 *
 **********************************************************************/

#include <geos/operation/IsSimpleOp.h>
//#include <geos/operation/EndpointInfo.h>
#include <geos/algorithm/BoundaryNodeRule.h>
#include <geos/algorithm/LineIntersector.h>
#include <geos/geomgraph/GeometryGraph.h>
#include <geos/geomgraph/Edge.h>
#include <geos/geomgraph/EdgeIntersection.h>
#include <geos/geomgraph/index/SegmentIntersector.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/MultiPoint.h>
#include <geos/geom/MultiLineString.h>
#include <geos/geom/Point.h>
#include <geos/geom/Coordinate.h>

#include <set>
#include <cassert>

using namespace std;
using namespace geos::algorithm;
using namespace geos::geomgraph;
using namespace geos::geomgraph::index;
using namespace geos::geom;

namespace geos {
namespace operation { // geos.operation

// This is supposedly a private of IsSimpleOp...
class EndpointInfo
{
public:

	Coordinate pt;

	bool isClosed;

	int degree;

    	EndpointInfo(const geom::Coordinate& newPt);

	const Coordinate& getCoordinate() const { return pt; }

	void addEndpoint(bool newIsClosed)
	{
		degree++;
		isClosed |= newIsClosed;
	}
};

EndpointInfo::EndpointInfo(const Coordinate& newPt)
{
	pt=newPt;
	isClosed=false;
	degree=0;
}

// -----------------------------------------------------

/*public*/
IsSimpleOp::IsSimpleOp()
	:
	isClosedEndpointsInInterior(true),
	geom(0),
	nonSimpleLocation()
{}

/*public*/
IsSimpleOp::IsSimpleOp(const Geometry& g)
	:
	isClosedEndpointsInInterior(true),
	geom(&g),
	nonSimpleLocation()
{}

/*public*/
IsSimpleOp::IsSimpleOp(const Geometry& g,
	               const BoundaryNodeRule& boundaryNodeRule)
	:
	isClosedEndpointsInInterior( ! boundaryNodeRule.isInBoundary(2) ),
	geom(&g),
	nonSimpleLocation()
{}

/*public*/
bool
IsSimpleOp::isSimple()
{
	nonSimpleLocation.reset();

	if ( dynamic_cast<const LineString*>(geom) )
		return isSimpleLinearGeometry(geom);

	if ( dynamic_cast<const MultiLineString*>(geom) )
		return isSimpleLinearGeometry(geom);

	const MultiPoint* mp = dynamic_cast<const MultiPoint*>(geom);
	if ( mp ) return isSimpleMultiPoint(*mp);

	// all other geometry types are simple by definition
	return true;
}

/*public*/
bool
IsSimpleOp::isSimple(const LineString *geom)
{
	return isSimpleLinearGeometry(geom);
}

/*public*/
bool
IsSimpleOp::isSimple(const MultiLineString *geom)
{
	return isSimpleLinearGeometry(geom);
}

/*public*/
bool
IsSimpleOp::isSimple(const MultiPoint *mp)
{
	return isSimpleMultiPoint(*mp);
}

/*private*/
bool
IsSimpleOp::isSimpleMultiPoint(const MultiPoint& mp)
{
	if (mp.isEmpty()) return true;
	set<const Coordinate*, CoordinateLessThen> points;

	for (std::size_t i=0, n=mp.getNumGeometries(); i<n; ++i)
	{
		assert(dynamic_cast<const Point*>(mp.getGeometryN(i)));
		const Point *pt=static_cast<const Point*>(mp.getGeometryN(i));
		const Coordinate *p=pt->getCoordinate();
		if (points.find(p) != points.end())
		{
			nonSimpleLocation.reset(new Coordinate(*p));
			return false;
		}
		points.insert(p);
	}
	return true;
}

bool
IsSimpleOp::isSimpleLinearGeometry(const Geometry *geom)
{
	if (geom->isEmpty()) return true;
	GeometryGraph graph(0,geom);
	LineIntersector li;
	std::auto_ptr<SegmentIntersector> si (graph.computeSelfNodes(&li,true));

	// if no self-intersection, must be simple
	if (!si->hasIntersection()) return true;

	if (si->hasProperIntersection())
	{
		nonSimpleLocation.reset(
			new Coordinate(si->getProperIntersectionPoint())
		);
		return false;
	}

	if (hasNonEndpointIntersection(graph)) return false;

	if ( isClosedEndpointsInInterior ) {
		if (hasClosedEndpointIntersection(graph)) return false;
	}

	return true;
}

/*private*/
bool
IsSimpleOp::hasNonEndpointIntersection(GeometryGraph &graph)
{
	vector<Edge*> *edges=graph.getEdges();
	for (vector<Edge*>::iterator i=edges->begin();i<edges->end();i++) {
		Edge *e=*i;
		int maxSegmentIndex=e->getMaximumSegmentIndex();
		EdgeIntersectionList &eiL=e->getEdgeIntersectionList();
		for ( EdgeIntersectionList::iterator eiIt=eiL.begin(),
			eiEnd=eiL.end(); eiIt!=eiEnd; ++eiIt )
		{
			EdgeIntersection *ei=*eiIt;
			if (!ei->isEndPoint(maxSegmentIndex))
			{
				nonSimpleLocation.reset(
					new Coordinate(ei->getCoordinate())
				);
				return true;
			}
		}
	}
	return false;
}

/*private*/
bool
IsSimpleOp::hasClosedEndpointIntersection(GeometryGraph &graph)
{
	map<const Coordinate*,EndpointInfo*,CoordinateLessThen> endPoints;
	vector<Edge*> *edges=graph.getEdges();
	for (vector<Edge*>::iterator i=edges->begin();i<edges->end();i++) {
		Edge *e=*i;
		//int maxSegmentIndex=e->getMaximumSegmentIndex();
		bool isClosed=e->isClosed();
		const Coordinate *p0=&e->getCoordinate(0);
		addEndpoint(endPoints,p0,isClosed);
		const Coordinate *p1=&e->getCoordinate(e->getNumPoints()-1);
		addEndpoint(endPoints,p1,isClosed);
	}

	map<const Coordinate*,EndpointInfo*,CoordinateLessThen>::iterator it=endPoints.begin();
	for (; it!=endPoints.end(); ++it) {
		EndpointInfo *eiInfo=it->second;
		if (eiInfo->isClosed && eiInfo->degree!=2) {

			nonSimpleLocation.reset(
				new Coordinate( eiInfo->getCoordinate() )
			);

			it=endPoints.begin();
			for (; it!=endPoints.end(); ++it) {
				EndpointInfo *ep=it->second;
				delete ep;
			}
            		return true;
		}
	}

	it=endPoints.begin();
	for (; it!=endPoints.end(); ++it) {
		EndpointInfo *ep=it->second;
		delete ep;
	}
	return false;
}

/*private*/
void
IsSimpleOp::addEndpoint(
	map<const Coordinate*,EndpointInfo*,CoordinateLessThen>&endPoints,
	const Coordinate *p,bool isClosed)
{
	map<const Coordinate*,EndpointInfo*,CoordinateLessThen>::iterator it=endPoints.find(p);
	EndpointInfo *eiInfo;
	if (it==endPoints.end()) {
		eiInfo=NULL;
	} else {
		eiInfo=it->second;
	}
	if (eiInfo==NULL) {
		eiInfo=new EndpointInfo(*p);
		endPoints[p]=eiInfo;
	}
	eiInfo->addEndpoint(isClosed);
}

} // namespace geos::operation
} // namespace geos

<|endoftext|>