<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa is distributed in the hope that it will be useful,                 *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       *
 * See the GNU Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef DO_MATCH_HPP
#define DO_MATCH_HPP

#include <algorithm>
#include <type_traits>

#include "cppa/pattern.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"

namespace cppa { namespace detail {

template<typename T>
inline auto ptr_type(T& ptr, util::enable_if<std::is_pointer<T>>* = 0) -> T
{
    return ptr;
}

template<typename T>
inline auto ptr_type(T& iter, util::disable_if<std::is_pointer<T>>* = 0) -> decltype(iter.operator->())
{
    return iter.operator->();
}

template<class MappingVector, typename Iterator>
class push_mapping_decorator
{

    size_t pos;
    Iterator iter;
    MappingVector& mapping;
    size_t commited_size;

 public:

    typedef MappingVector mapping_vector;

    push_mapping_decorator(Iterator const& i, MappingVector& mv)
        : pos(0), iter(i), mapping(mv), commited_size(0)
    {
    }

    push_mapping_decorator(push_mapping_decorator const&) = default;

    inline push_mapping_decorator& operator++()
    {
        ++pos;
        ++iter;
        return *this;
    }

    inline bool operator==(Iterator const& i)
    {
        return iter == i;
    }

    inline decltype(*iter) operator*()
    {
        return *iter;
    }

    inline decltype(ptr_type(iter)) operator->()
    {
        return ptr_type(iter);
    }

    inline void push_mapping()
    {
        mapping.push_back(pos);
    }

    inline void commit_mapping()
    {
        commited_size = mapping.size();
    }

    inline void rollback_mapping()
    {
        mapping.resize(commited_size);
    }

};

template<typename Iterator, class MappingVector>
push_mapping_decorator<MappingVector, Iterator> pm_decorated(Iterator i, MappingVector& mv)
{
    return {i, mv};
}

template<typename T>
class is_pm_decorated
{

    template<class C> static bool sfinae_fun(C* cptr,
                                             decltype(cptr->has_mapping())* = 0)
    {
        return true;
    }

    static void sfinae_fun(void*) { }

    typedef decltype(sfinae_fun(static_cast<T*>(nullptr))) result_type;

 public:

    static constexpr bool value = std::is_same<bool, result_type>::value;

};

template<typename T>
inline typename util::disable_if<is_pm_decorated<T>, void>::type
push_mapping(T&) { }

template<typename T>
inline typename util::enable_if<is_pm_decorated<T>, void>::type
push_mapping(T& iter)
{
    iter->push_mapping();
}

template<typename T>
inline typename util::disable_if<is_pm_decorated<T>, void>::type
commit_mapping(T&) { }

template<typename T>
inline typename util::enable_if<is_pm_decorated<T>, void>::type
commit_mapping(T& iter)
{
    iter->commit_mapping();
}

template<typename T>
inline typename util::disable_if<is_pm_decorated<T>, void>::type
rollback_mapping(T&) { }

template<typename T>
inline typename util::enable_if<is_pm_decorated<T>, void>::type
rollback_mapping(T& iter)
{
    iter->rollback_mapping();
}

template<class TupleBeginIterator, class TupleEndIterator, class PatternIterator>
bool matches(TupleBeginIterator tbegin, TupleEndIterator tend,
             PatternIterator pbegin, PatternIterator pend)
{
    for ( ; !(pbegin == pend && tbegin == tend); ++pbegin, ++tbegin)
    {
        if (pbegin == pend)
        {
            return false;
        }
        else if (pbegin->first == nullptr) // nullptr == wildcard (anything)
        {
            // perform submatching
            ++pbegin;
            if (pbegin == pend)
            {
                // always true at the end of the pattern
                return true;
            }
            // safe current mapping as fallback
            commit_mapping(tbegin);
            // iterate over tu_args until we found a match
            for (; tbegin != tend; ++tbegin)
            {
                if (matches(tbegin, tend, pbegin, pend)) return true;
                // restore mapping to fallback (delete invalid mappings)
                rollback_mapping(tbegin);
            }
            return false; // no submatch found
        }
        // compare types
        else if (tbegin != tend && pbegin->first == tbegin->first)
        {
            // compare values if needed
            if (   pbegin->second == nullptr
                || pbegin->first->equals(pbegin->second, tbegin->second))
            {
                push_mapping(tbegin);
            }
            else
            {
                return false; // values didn't match
            }
        }
        else
        {
            return false; // no match
        }
    }
    return true; // pbegin == pend && targ.at_end()
}

// pattern does not contain "anything"
template<class Tuple, class Pattern>
bool matches(std::integral_constant<int, 0>,
             Tuple const& tpl, Pattern const& pttrn,
             util::fixed_vector<size_t, Pattern::filtered_size>* mv)
{
    // assertion "tpl.size() == pttrn.size()" is guaranteed from caller
    typedef typename Pattern::types ptypes;
    typedef typename decorated_tuple_from_type_list<ptypes>::type dec_t;
    typedef typename tuple_vals_from_type_list<ptypes>::type tv_t;
    std::type_info const& tinfo = tpl.impl_type();
    if (tinfo == typeid(dec_t) || tinfo == typeid(tv_t))
    {
        if (pttrn.has_values())
        {
            // compare values only (types are guaranteed to be equal)
            auto eq = [](type_value_pair const& lhs, type_value_pair const& rhs)
            {
                // pattern (rhs) does not have to have a value
                return    rhs.second == nullptr
                       || lhs.first->equals(lhs.second, rhs.second);
            };
            if (std::equal(tpl.begin(), tpl.end(), pttrn.begin(), eq) == false)
            {
                // values differ
                return false;
            }
        }
    }
    else if (tinfo == typeid(object_array))
    {
        if (pttrn.has_values())
        {
            // compares type and value
            auto eq = [](type_value_pair const& lhs, type_value_pair const& rhs)
            {
                // pattern (rhs) does not have to have a value
                return    lhs.first == rhs.first
                       && (   rhs.second == nullptr
                           || lhs.first->equals(lhs.second, rhs.second));
            };
            if (std::equal(tpl.begin(), tpl.end(), pttrn.begin(), eq) == false)
            {
                // types or values differ
                return false;
            }
        }
        else
        {
            // compares the types only
            auto eq = [](type_value_pair const& lhs, type_value_pair const& rhs)
            {
                return lhs.first == rhs.first;
            };
            if (std::equal(tpl.begin(), tpl.end(), pttrn.begin(), eq) == false)
            {
                // types differ
                return false;
            }
        }
    }
    else
    {
        return false;
    }
    // ok => match
    if (mv) for (size_t i = 0; i < Pattern::size; ++i) mv->push_back(i);
    return true;
}

// "anything" at end of pattern
template<class Tuple, class Pattern>
bool matches(std::integral_constant<int, 1>,
             Tuple const& tpl, Pattern const& pttrn,
             util::fixed_vector<size_t, Pattern::filtered_size>* mv)
{
    static_assert(Pattern::size > 0, "empty pattern");
    auto end = pttrn.end();
    --end; // iterate until we reach "anything"
    size_t i = 0;
    if (pttrn.has_values())
    {
        for (auto iter = pttrn.begin(); iter != end; ++iter, ++i)
        {
            if (iter->first != tpl.type_at(i)) return false;
            if (iter->second)
            {
                if (iter->first->equals(iter->second, tpl.at(i)) == false)
                    return false;
            }
        }
    }
    else
    {
        for (auto iter = pttrn.begin(); iter != end; ++iter, ++i)
        {
            if (iter->first != tpl.type_at(i)) return false;
        }
    }
    // ok => match, fill vector if needed and pattern is != <anything>
    if (mv)
    {
        // fill vector up to the position of 'anything'
        size_t end = Pattern::size - 1;
        for (size_t i = 0; i < end; ++i) mv->push_back(i);
    }
    return true;
}

// "anything" somewhere in between (ugh!)
template<class Tuple, class Pattern>
bool matches(std::integral_constant<int, 2>,
             Tuple const& tpl, Pattern const& ptrn,
             util::fixed_vector<size_t, Pattern::filtered_size>* mv = 0)
{
    if (mv)
        return matches(pm_decorated(tpl.begin(), *mv), tpl.end(), ptrn.begin(), ptrn.end());
    return matches(tpl.begin(), tpl.end(), ptrn.begin(), ptrn.end());
}

template<class Tuple, class Pattern>
inline bool matches(Tuple const& tpl, Pattern const& pttrn,
                    util::fixed_vector<size_t, Pattern::filtered_size>* mv = 0)
{
    typedef typename Pattern::types ptypes;
    static constexpr int first_anything = util::tl_find<ptypes, anything>::value;
    // impl0 = no anything
    // impl1 = anything at end
    // impl2 = anything somewhere in between
    static constexpr int impl = (first_anything == -1)
            ? 0
            : ((first_anything == ((int) Pattern::size) - 1) ? 1 : 2);
    std::integral_constant<int, impl> token;
    return matches(token, tpl, pttrn, mv);
}

} } // namespace cppa::detail

#endif // DO_MATCH_HPP
<commit_msg>refactoring<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa is distributed in the hope that it will be useful,                 *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       *
 * See the GNU Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef DO_MATCH_HPP
#define DO_MATCH_HPP

#include <algorithm>
#include <type_traits>

#include "cppa/pattern.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"

namespace cppa { namespace detail {

template<typename T>
inline auto ptr_type(T& ptr, util::enable_if<std::is_pointer<T>>* = 0) -> T
{
    return ptr;
}

template<typename T>
inline auto ptr_type(T& iter, util::disable_if<std::is_pointer<T>>* = 0) -> decltype(iter.operator->())
{
    return iter.operator->();
}

template<class MappingVector, typename Iterator>
class push_mapping_decorator
{

    size_t pos;
    Iterator iter;
    MappingVector& mapping;
    size_t commited_size;

 public:

    typedef MappingVector mapping_vector;

    push_mapping_decorator(Iterator const& i, MappingVector& mv)
        : pos(0), iter(i), mapping(mv), commited_size(0)
    {
    }

    push_mapping_decorator(push_mapping_decorator const&) = default;

    inline push_mapping_decorator& operator++()
    {
        ++pos;
        ++iter;
        return *this;
    }

    inline bool operator==(Iterator const& i)
    {
        return iter == i;
    }

    inline decltype(*iter) operator*()
    {
        return *iter;
    }

    inline decltype(ptr_type(iter)) operator->()
    {
        return ptr_type(iter);
    }

    inline void push_mapping()
    {
        mapping.push_back(pos);
    }

    inline void commit_mapping()
    {
        commited_size = mapping.size();
    }

    inline void rollback_mapping()
    {
        mapping.resize(commited_size);
    }

};

template<typename Iterator, class MappingVector>
push_mapping_decorator<MappingVector, Iterator> pm_decorated(Iterator i, MappingVector& mv)
{
    return {i, mv};
}

template<typename T>
class is_pm_decorated
{

    template<class C> static bool sfinae_fun(C* cptr,
                                             decltype(cptr->has_mapping())* = 0)
    {
        return true;
    }

    static void sfinae_fun(void*) { }

    typedef decltype(sfinae_fun(static_cast<T*>(nullptr))) result_type;

 public:

    static constexpr bool value = std::is_same<bool, result_type>::value;

};

template<typename T>
inline typename util::disable_if<is_pm_decorated<T>, void>::type
push_mapping(T&) { }

template<typename T>
inline typename util::enable_if<is_pm_decorated<T>, void>::type
push_mapping(T& iter)
{
    iter->push_mapping();
}

template<typename T>
inline typename util::disable_if<is_pm_decorated<T>, void>::type
commit_mapping(T&) { }

template<typename T>
inline typename util::enable_if<is_pm_decorated<T>, void>::type
commit_mapping(T& iter)
{
    iter->commit_mapping();
}

template<typename T>
inline typename util::disable_if<is_pm_decorated<T>, void>::type
rollback_mapping(T&) { }

template<typename T>
inline typename util::enable_if<is_pm_decorated<T>, void>::type
rollback_mapping(T& iter)
{
    iter->rollback_mapping();
}

template<class TupleBeginIterator, class TupleEndIterator, class PatternIterator>
bool matches(TupleBeginIterator tbegin, TupleEndIterator tend,
             PatternIterator pbegin, PatternIterator pend)
{
    for ( ; !(pbegin == pend && tbegin == tend); ++pbegin, ++tbegin)
    {
        if (pbegin == pend)
        {
            return false;
        }
        else if (pbegin->first == nullptr) // nullptr == wildcard (anything)
        {
            // perform submatching
            ++pbegin;
            if (pbegin == pend)
            {
                // always true at the end of the pattern
                return true;
            }
            // safe current mapping as fallback
            commit_mapping(tbegin);
            // iterate over tu_args until we found a match
            for (; tbegin != tend; ++tbegin)
            {
                if (matches(tbegin, tend, pbegin, pend)) return true;
                // restore mapping to fallback (delete invalid mappings)
                rollback_mapping(tbegin);
            }
            return false; // no submatch found
        }
        // compare types
        else if (tbegin != tend && pbegin->first == tbegin->first)
        {
            // compare values if needed
            if (   pbegin->second == nullptr
                || pbegin->first->equals(pbegin->second, tbegin->second))
            {
                push_mapping(tbegin);
            }
            else
            {
                return false; // values didn't match
            }
        }
        else
        {
            return false; // no match
        }
    }
    return true; // pbegin == pend && targ.at_end()
}

// pattern does not contain "anything"
template<class Tuple, class Pattern>
bool matches(std::integral_constant<int, 0>,
             Tuple const& tpl, Pattern const& pttrn,
             util::fixed_vector<size_t, Pattern::filtered_size>* mv)
{
    // assertion "tpl.size() == pttrn.size()" is guaranteed from caller
    typedef typename Pattern::types ptypes;
    typedef typename decorated_tuple_from_type_list<ptypes>::type dec_t;
    typedef typename tuple_vals_from_type_list<ptypes>::type tv_t;
    std::type_info const& tinfo = tpl.impl_type();
    auto j = pttrn.begin();
    auto end = tpl.end();
    if (tinfo == typeid(dec_t) || tinfo == typeid(tv_t))
    {
        if (pttrn.has_values())
        {
            // compare values only (types are guaranteed to be equal)
            for (auto i = tpl.begin(); i != end; ++i, ++j)
            {
                if (   j->second != nullptr
                    && i->first->equals(i->second, j->second) == false) return false;
            }
        }
    }
    else if (tinfo == typeid(object_array))
    {
        if (pttrn.has_values())
        {
            // compares type and value
            for (auto i = tpl.begin(); i != end; ++i, ++j)
            {
                if (   i->first != j->first
                    || (   j->second != nullptr
                        && i->first->equals(i->second, j->second) == false)) return false;
            }
        }
        else
        {
            // compares the types only
            for (auto i = tpl.begin(); i != end; ++i, ++j)
            {
                if (i->first != j->first) return false;
            }
        }
    }
    else
    {
        return false;
    }
    // ok => match
    if (mv) for (size_t i = 0; i < Pattern::size; ++i) mv->push_back(i);
    return true;
}

// "anything" at end of pattern
template<class Tuple, class Pattern>
bool matches(std::integral_constant<int, 1>,
             Tuple const& tpl, Pattern const& pttrn,
             util::fixed_vector<size_t, Pattern::filtered_size>* mv)
{
    static_assert(Pattern::size > 0, "empty pattern");
    auto end = pttrn.end();
    --end; // iterate until we reach "anything"
    size_t i = 0;
    if (pttrn.has_values())
    {
        for (auto iter = pttrn.begin(); iter != end; ++iter, ++i)
        {
            if (iter->first != tpl.type_at(i)) return false;
            if (iter->second)
            {
                if (iter->first->equals(iter->second, tpl.at(i)) == false)
                    return false;
            }
        }
    }
    else
    {
        for (auto iter = pttrn.begin(); iter != end; ++iter, ++i)
        {
            if (iter->first != tpl.type_at(i)) return false;
        }
    }
    // ok => match, fill vector if needed and pattern is != <anything>
    if (mv)
    {
        // fill vector up to the position of 'anything'
        size_t end = Pattern::size - 1;
        for (size_t i = 0; i < end; ++i) mv->push_back(i);
    }
    return true;
}

// "anything" somewhere in between (ugh!)
template<class Tuple, class Pattern>
bool matches(std::integral_constant<int, 2>,
             Tuple const& tpl, Pattern const& ptrn,
             util::fixed_vector<size_t, Pattern::filtered_size>* mv = 0)
{
    if (mv)
        return matches(pm_decorated(tpl.begin(), *mv), tpl.end(), ptrn.begin(), ptrn.end());
    return matches(tpl.begin(), tpl.end(), ptrn.begin(), ptrn.end());
}

template<class Tuple, class Pattern>
inline bool matches(Tuple const& tpl, Pattern const& pttrn,
                    util::fixed_vector<size_t, Pattern::filtered_size>* mv = 0)
{
    typedef typename Pattern::types ptypes;
    static constexpr int first_anything = util::tl_find<ptypes, anything>::value;
    // impl0 = no anything
    // impl1 = anything at end
    // impl2 = anything somewhere in between
    static constexpr int impl = (first_anything == -1)
            ? 0
            : ((first_anything == ((int) Pattern::size) - 1) ? 1 : 2);
    std::integral_constant<int, impl> token;
    return matches(token, tpl, pttrn, mv);
}

} } // namespace cppa::detail

#endif // DO_MATCH_HPP
<|endoftext|>


<commit_before>/* Esvg - SVG
 * Copyright (C) 2011 Jorge Luis Zapata, Vincent Torri
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 * If not, see <http://www.gnu.org/licenses/>.
 */
#include "esvg_private_main.h"
#include "esvg_private_scriptor.h"
#include "esvg_private_svg.h"

#include <v8.h>
#include <map>

using namespace v8;
/*
 * We need to implement functions on ender, that way we can introspect
 * correctly an object, based on its atttributes (properties for ender)
 * and functions. I suppose that whenever a function return an ender
 * element, we need to wrap that function so we can assign the prototype
 * of the returned element based on some lookup of its ender descriptor
 *
 * For getters/setters it is very simple, we just call the
 * ender_element_property_set. But with a value? or without?
 *
 * We need to add the ender element passed on the context new
 * as the global object
 */
/*============================================================================*
 *                                  Local                                     *
 *============================================================================*/
typedef struct _Esvg_Scriptor_Js_V8
{
	Ender_Element *svg;
	Persistent<Context> context;
} Esvg_Scriptor_Js_V8;

/* FIXME or we either use the stl or an eina hash, but looks like
 * we cannot access the pointer of the persistent handle to pass
 * it to eina_hash?
 */
static std::map<const char *, Persistent<FunctionTemplate> > _prototypes;

#if 0
static Handle<Value> GetPointX(Local<String> property, const AccessorInfo &info)
{
	Local<Object> self = info.Holder();
	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
	void* ptr = wrap->Value();
	int value = static_cast<Point*>(ptr)->x_;
	return Integer::New(value);
}

static void SetPointX(Local<String> property, Local<Value> value,
		const AccessorInfo& info)
{
	Local<Object> self = info.Holder();
	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
	void* ptr = wrap->Value();
	static_cast<Point*>(ptr)->x_ = value->Int32Value();
}
#endif

static void _v8_element_property_to_js(Ender_Property *prop,
		void *data)
{
	Ender_Container *c;
	const char *name = (const char *)data;

	/* FIXME we need to figure out how to pass the
	 * handle as a void *
	 */
	Persistent<FunctionTemplate> tmpl = _prototypes[name];
	/* get the container of the property */
	c = ender_property_container_get(prop);
	/* for simple containers it is simple, for
	 * compound containers, we need to use the specification
	 * as found on the svg spec
	 */
	printf("property of name = %s\n", ender_property_name_get(prop));
	/* add an accessor to the template */
}

static Persistent<FunctionTemplate> _v8_element_descriptor_to_js(
		Esvg_Scriptor_Js_V8 *thiz,
		Ender_Descriptor *descriptor)
{
	const char *name;
	const void *ot;

	/* find the descriptor name in the hash of templates */
	name = ender_descriptor_name_get(descriptor);
	Persistent<FunctionTemplate> tmpl = _prototypes[name];

	if (tmpl.IsEmpty())
	{
		Ender_Namespace *ns;
		const char *ns_name = "SVG";
		char real_name[PATH_MAX];

#if 0
		ns = ender_descriptor_namespace_get(descriptor);
		ns_name = ender_namespace_name_get(ns);
#endif
		strcpy(real_name, ns_name);
		strcat(real_name, name);

		/* create a new prototype and store it */
		HandleScope handle_scope;
		Handle<FunctionTemplate> l_tmpl = FunctionTemplate::New();
		l_tmpl->SetClassName(String::New(real_name));
		Handle<ObjectTemplate> o_tmpl = l_tmpl->InstanceTemplate();

		o_tmpl->SetInternalFieldCount(1);
		tmpl = Persistent<FunctionTemplate>::New(l_tmpl);
		_prototypes[name] = tmpl;
	}
	/* start adding the properties for such descriptor */
	ender_descriptor_property_list(descriptor, _v8_element_property_to_js,
			&tmpl);
	/* TODO add the functions */

	/* get the parent descriptor and do the same */
	descriptor = ender_descriptor_parent(descriptor);
	if (descriptor)
	{
		Persistent<FunctionTemplate> ptmpl =
				_v8_element_descriptor_to_js(thiz, descriptor);
		/* inherit from its parent */
		tmpl->Inherit(ptmpl);
	}
	return tmpl;
}

static Handle<Object> _v8_element_to_js(Esvg_Scriptor_Js_V8 *thiz, Ender_Element *e)
{
	Ender_Descriptor *descriptor;
	HandleScope handle_scope;

	descriptor = ender_element_descriptor_get(e);
	Persistent<FunctionTemplate> tmpl = _v8_element_descriptor_to_js(thiz,
			descriptor);

	Handle<Function> f = tmpl->GetFunction();
	Handle<Object> obj = f->NewInstance();
	obj->SetInternalField(0, External::New(e));
	return handle_scope.Close(obj);
}

v8::Handle<v8::Value> Alert(const v8::Arguments& args)
{
	Esvg_Scriptor_Js_V8 *thiz;

	String::Utf8Value str(args[0]); // Convert first argument to V8 String
	Local<External> wrap = Local<External>::Cast(args.Data());
	thiz = static_cast<Esvg_Scriptor_Js_V8*>(wrap->Value());

	/* call the svg with the string */
	esvg_svg_script_alert(thiz->svg, *str);
	return Undefined();
}
/*----------------------------------------------------------------------------*
 *                          The script  interface                             *
 *----------------------------------------------------------------------------*/
static void * _v8_context_new(Ender_Element *e)
{
	Esvg_Scriptor_Js_V8 *thiz;
	HandleScope handle_scope;
	Persistent<Context> context;

	thiz = (Esvg_Scriptor_Js_V8 *)calloc(1, sizeof(Esvg_Scriptor_Js_V8));
	thiz->svg = e;

	/* create the global object */
	Handle<ObjectTemplate> global = ObjectTemplate::New();
	/* add default implementation of the alert message */
	global->Set(String::New("alert"), FunctionTemplate::New(Alert, External::New(thiz)));
	context = Context::New(NULL, global);
	/* enter the context so all the following operation are done there */
	context->Enter();

	/* store the context */
	thiz->context = context;

	/* add the svg document */
	context->Global()->Set(String::New("document"), _v8_element_to_js(thiz, e));

	return thiz;
}

static void _v8_context_free(void *ctx)
{
	Esvg_Scriptor_Js_V8 *thiz = (Esvg_Scriptor_Js_V8 *)ctx;

	thiz->context.Dispose();
	free(thiz);
}

static void _v8_run(void *ctx, const char *s)
{
	Esvg_Scriptor_Js_V8 *thiz = (Esvg_Scriptor_Js_V8 *)ctx;
	HandleScope handle_scope;

	/* create the source string */
	Handle<String> source = String::New(s);
	/* compile it */
	Handle<Script> script = Script::Compile(source);
	/* run it */
 	script->Run();
}

static Esvg_Scriptor_Descriptor _descriptor = {
	/* .context_new 	= */ _v8_context_new,
	/* .context_free	= */ _v8_context_free,
	/* .run 		= */ _v8_run,
};
/*============================================================================*
 *                                 Global                                     *
 *============================================================================*/
void esvg_scriptor_js_v8_init(void)
{
	esvg_scriptor_register(&_descriptor, "application/ecmascript");
}

void esvg_scriptor_js_v8_shutdown(void)
{
	esvg_scriptor_unregister(&_descriptor, "application/ecmascript");
}
/*============================================================================*
 *                                   API                                      *
 *============================================================================*/

<commit_msg>More ideas<commit_after>/* Esvg - SVG
 * Copyright (C) 2011 Jorge Luis Zapata, Vincent Torri
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 * If not, see <http://www.gnu.org/licenses/>.
 */
#include "esvg_private_main.h"
#include "esvg_private_scriptor.h"
#include "esvg_private_svg.h"

#include <v8.h>
#include <map>

using namespace v8;
/*
 * We need to implement functions on ender, that way we can introspect
 * correctly an object, based on its atttributes (properties for ender)
 * and functions. I suppose that whenever a function return an ender
 * element, we need to wrap that function so we can assign the prototype
 * of the returned element based on some lookup of its ender descriptor
 *
 * For getters/setters it is very simple, we just call the
 * ender_element_property_set. But with a value? or without?
 *
 * We need to add the ender element passed on the context new
 * as the global object
 */
/*============================================================================*
 *                                  Local                                     *
 *============================================================================*/
typedef struct _Esvg_Scriptor_Js_V8
{
	Ender_Element *svg;
	Persistent<Context> context;
} Esvg_Scriptor_Js_V8;

/* FIXME or we either use the stl or an eina hash, but looks like
 * we cannot access the pointer of the persistent handle to pass
 * it to eina_hash?
 */
static std::map<const char *, Persistent<FunctionTemplate> > _prototypes;

#if 0
static Handle<Value> GetPointX(Local<String> property, const AccessorInfo &info)
{
	Local<Object> self = info.Holder();
	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
	void* ptr = wrap->Value();
	int value = static_cast<Point*>(ptr)->x_;
	return Integer::New(value);
}

static void SetPointX(Local<String> property, Local<Value> value,
		const AccessorInfo& info)
{
	Local<Object> self = info.Holder();
	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
	void* ptr = wrap->Value();
	static_cast<Point*>(ptr)->x_ = value->Int32Value();
}
#endif

static void _v8_element_property_to_js(Ender_Property *prop,
		void *data)
{
	Ender_Container *c;
	const char *name = (const char *)data;

#if 0
	Persistent<FunctionTemplate> tmpl = Persistent<FunctionTemplate>::New(External::Wrap(data));
#endif
	/* FIXME we need to figure out how to pass the
	 * handle as a void *
	 */
	Persistent<FunctionTemplate> tmpl = _prototypes[name];
	/* get the container of the property */
	c = ender_property_container_get(prop);
	/* for simple containers it is simple, for
	 * compound containers, we need to use the specification
	 * as found on the svg spec
	 */
	printf("property of name = %s\n", ender_property_name_get(prop));
	/* add an accessor to the template */
}

static Persistent<FunctionTemplate> _v8_element_descriptor_to_js(
		Esvg_Scriptor_Js_V8 *thiz,
		Ender_Descriptor *descriptor)
{
	const char *name;
	void *cb_data;

	/* find the descriptor name in the hash of templates */
	name = ender_descriptor_name_get(descriptor);
	Persistent<FunctionTemplate> tmpl = _prototypes[name];

	if (tmpl.IsEmpty())
	{
		Ender_Namespace *ns;
		const char *ns_name = "SVG";
		char real_name[PATH_MAX];

#if 0
		ns = ender_descriptor_namespace_get(descriptor);
		ns_name = ender_namespace_name_get(ns);
#endif
		strcpy(real_name, ns_name);
		strcat(real_name, name);

		/* create a new prototype and store it */
		HandleScope handle_scope;
		Handle<FunctionTemplate> l_tmpl = FunctionTemplate::New();
		l_tmpl->SetClassName(String::New(real_name));
		Handle<ObjectTemplate> o_tmpl = l_tmpl->InstanceTemplate();

		o_tmpl->SetInternalFieldCount(1);
		tmpl = Persistent<FunctionTemplate>::New(l_tmpl);
		_prototypes[name] = tmpl;
	}
	/* start adding the properties for such descriptor */
#if 0
	cb_data = static_cast<void *>(External::Unwrap(tmpl));
#endif
	ender_descriptor_property_list(descriptor, _v8_element_property_to_js,
			(void *)name);
	/* TODO add the functions */

	/* get the parent descriptor and do the same */
	descriptor = ender_descriptor_parent(descriptor);
	if (descriptor)
	{
		Persistent<FunctionTemplate> ptmpl =
				_v8_element_descriptor_to_js(thiz, descriptor);
		/* inherit from its parent */
		tmpl->Inherit(ptmpl);
	}
	return tmpl;
}

static Handle<Object> _v8_element_to_js(Esvg_Scriptor_Js_V8 *thiz, Ender_Element *e)
{
	Ender_Descriptor *descriptor;
	HandleScope handle_scope;

	descriptor = ender_element_descriptor_get(e);
	Persistent<FunctionTemplate> tmpl = _v8_element_descriptor_to_js(thiz,
			descriptor);

	Handle<Function> f = tmpl->GetFunction();
	Handle<Object> obj = f->NewInstance();
	obj->SetInternalField(0, External::New(e));
	return handle_scope.Close(obj);
}

v8::Handle<v8::Value> Alert(const v8::Arguments& args)
{
	Esvg_Scriptor_Js_V8 *thiz;

	String::Utf8Value str(args[0]); // Convert first argument to V8 String
	Local<External> wrap = Local<External>::Cast(args.Data());
	thiz = static_cast<Esvg_Scriptor_Js_V8*>(wrap->Value());

	/* call the svg with the string */
	esvg_svg_script_alert(thiz->svg, *str);
	return Undefined();
}
/*----------------------------------------------------------------------------*
 *                          The script  interface                             *
 *----------------------------------------------------------------------------*/
static void * _v8_context_new(Ender_Element *e)
{
	Esvg_Scriptor_Js_V8 *thiz;
	HandleScope handle_scope;
	Persistent<Context> context;

	thiz = (Esvg_Scriptor_Js_V8 *)calloc(1, sizeof(Esvg_Scriptor_Js_V8));
	thiz->svg = e;

	/* create the global object */
	Handle<ObjectTemplate> global = ObjectTemplate::New();
	/* add default implementation of the alert message */
	global->Set(String::New("alert"), FunctionTemplate::New(Alert, External::New(thiz)));
	context = Context::New(NULL, global);
	/* enter the context so all the following operation are done there */
	context->Enter();

	/* store the context */
	thiz->context = context;

	/* add the svg document */
	context->Global()->Set(String::New("document"), _v8_element_to_js(thiz, e));

	return thiz;
}

static void _v8_context_free(void *ctx)
{
	Esvg_Scriptor_Js_V8 *thiz = (Esvg_Scriptor_Js_V8 *)ctx;

	thiz->context.Dispose();
	free(thiz);
}

static void _v8_run(void *ctx, const char *s)
{
	Esvg_Scriptor_Js_V8 *thiz = (Esvg_Scriptor_Js_V8 *)ctx;
	HandleScope handle_scope;

	/* create the source string */
	Handle<String> source = String::New(s);
	/* compile it */
	Handle<Script> script = Script::Compile(source);
	/* run it */
 	script->Run();
}

static Esvg_Scriptor_Descriptor _descriptor = {
	/* .context_new 	= */ _v8_context_new,
	/* .context_free	= */ _v8_context_free,
	/* .run 		= */ _v8_run,
};
/*============================================================================*
 *                                 Global                                     *
 *============================================================================*/
void esvg_scriptor_js_v8_init(void)
{
	esvg_scriptor_register(&_descriptor, "application/ecmascript");
}

void esvg_scriptor_js_v8_shutdown(void)
{
	esvg_scriptor_unregister(&_descriptor, "application/ecmascript");
}
/*============================================================================*
 *                                   API                                      *
 *============================================================================*/

<|endoftext|>


<commit_before>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * 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.
 */

#pragma once

#include "Common.hpp"
#include "UTF8Util.hpp"
#include "Segments.hpp"

namespace opencc {
/**
* Key-values pair entry
* @ingroup opencc_cpp_api
*/
class OPENCC_EXPORT DictEntry {
public:
  virtual ~DictEntry() {
  }

  virtual const char* Key() const = 0;

  virtual const char* GetDefault() const = 0;

  virtual size_t NumValues() const = 0;

  virtual string ToString() const = 0;

  size_t KeyLength() const {
    return strlen(Key());
  }

  bool operator<(const DictEntry& that) const {
    return strcmp(Key(), that.Key()) < 0;
  }

  bool operator==(const DictEntry& that) const {
    return strcmp(Key(), that.Key()) == 0;
  }

  static bool PtrLessThan(const DictEntry* a, const DictEntry* b) {
    return *a < *b;
  }
};

class OPENCC_EXPORT NoValueDictEntry : public DictEntry {
public:
  NoValueDictEntry(const string& _key) : key(_key) {
  }

  virtual ~NoValueDictEntry() {
  }

  virtual const char* Key() const {
    return key.c_str();
  }

  virtual const char* GetDefault() const {
    return Key();
  }

  virtual size_t NumValues() const {
    return 0;
  }

  virtual string ToString() const {
    return key;
  }

private:
  string key;
};

class OPENCC_EXPORT SingleValueDictEntry : public DictEntry {
public:
  virtual const char* Value() const = 0;

  virtual const char* GetDefault() const {
    return Value();
  }

  virtual size_t NumValues() const {
    return 1;
  }

  virtual string ToString() const {
    return string(Key()) + "\t" + Value();
  }
};

class OPENCC_EXPORT StrSingleValueDictEntry : public SingleValueDictEntry {
public:
  StrSingleValueDictEntry(const string& _key, const string& _value)
      : key(_key), value(_value) {
  }

  virtual ~StrSingleValueDictEntry() {
  }

  virtual const char* Key() const {
    return key.c_str();
  }

  virtual const char* Value() const {
    return value.c_str();
  }

private:
  string key;
  string value;
};

class OPENCC_EXPORT MultiValueDictEntry : public DictEntry {
public:
  virtual vector<const char*> Values() const = 0;

  virtual const char* GetDefault() const {
    if (NumValues() > 0) {
      return Values().at(0);
    } else {
      return Key();
    }
  }

  virtual string ToString() const;
};

class OPENCC_EXPORT StrMultiValueDictEntry : public MultiValueDictEntry {
public:
  StrMultiValueDictEntry(const string& _key, const vector<string>& _values)
      : key(_key), values(_values) {
  }

  StrMultiValueDictEntry(const string& _key, const vector<const char*>& _values)
      : key(_key) {
    values.reserve(_values.size());
    for (const char* str : _values) {
      values.push_back(str);
    }
  }

  virtual ~StrMultiValueDictEntry() {
  }

  virtual const char* Key() const {
    return key.c_str();
  }

  size_t NumValues() const {
    return values.size();
  }

  vector<const char*> Values() const {
    vector<const char*> values;
    for (const string& value : this->values) {
      values.push_back(value.c_str());
    }
    return values;
  }

private:
  string key;
  vector<string> values;
};

class OPENCC_EXPORT PtrDictEntry : public MultiValueDictEntry {
public:
  PtrDictEntry(const char* _key, const vector<const char*>& _values)
      : key(_key), values(_values) {
  }

  virtual ~PtrDictEntry() {
  }

  virtual const char* Key() const {
    return key;
  }

  size_t NumValues() const {
    return values.size();
  }

  vector<const char*> Values() const {
    return values;
  }

private:
  const char* key;
  vector<const char*> values;
};

class OPENCC_EXPORT DictEntryFactory {
public:
  static DictEntry* New(const string& key) {
    return new NoValueDictEntry(key);
  }

  static DictEntry* New(const string& key, const string& value) {
    return new StrSingleValueDictEntry(key, value);
  }

  static DictEntry* New(const string& key, const vector<string>& values) {
    return new StrMultiValueDictEntry(key, values);
  }

  static DictEntry* New(const DictEntry* entry) {
    if (entry->NumValues() == 0) {
      return new NoValueDictEntry(entry->Key());
    } else if (entry->NumValues() == 1) {
      const auto svEntry = static_cast<const SingleValueDictEntry*>(entry);
      return new StrSingleValueDictEntry(svEntry->Key(), svEntry->Value());
    } else {
      const auto mvEntry = static_cast<const MultiValueDictEntry*>(entry);
      return new StrMultiValueDictEntry(mvEntry->Key(), mvEntry->Values());
    }
  }
};

}
<commit_msg>Squashed 'thirdparty/src/opencc/' changes from 223c1df..2cdf489<commit_after>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * 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.
 */

#pragma once

#include "Common.hpp"
#include "UTF8Util.hpp"
#include "Segments.hpp"

namespace opencc {
/**
* Key-values pair entry
* @ingroup opencc_cpp_api
*/
class OPENCC_EXPORT DictEntry {
public:
  virtual ~DictEntry() {
  }

  virtual const char* Key() const = 0;

  virtual vector<const char*> Values() const = 0;

  virtual const char* GetDefault() const = 0;

  virtual size_t NumValues() const = 0;

  virtual string ToString() const = 0;

  size_t KeyLength() const {
    return strlen(Key());
  }

  bool operator<(const DictEntry& that) const {
    return strcmp(Key(), that.Key()) < 0;
  }

  bool operator==(const DictEntry& that) const {
    return strcmp(Key(), that.Key()) == 0;
  }

  static bool PtrLessThan(const DictEntry* a, const DictEntry* b) {
    return *a < *b;
  }
};

class OPENCC_EXPORT NoValueDictEntry : public DictEntry {
public:
  NoValueDictEntry(const string& _key) : key(_key) {
  }

  virtual ~NoValueDictEntry() {
  }

  virtual const char* Key() const {
    return key.c_str();
  }

  virtual vector<const char*> Values() const {
    return vector<const char*>();
  }

  virtual const char* GetDefault() const {
    return Key();
  }

  virtual size_t NumValues() const {
    return 0;
  }

  virtual string ToString() const {
    return key;
  }

private:
  string key;
};

class OPENCC_EXPORT SingleValueDictEntry : public DictEntry {
public:
  virtual const char* Value() const = 0;

  virtual vector<const char*> Values() const {
    return vector<const char*>{Value()};
  }

  virtual const char* GetDefault() const {
    return Value();
  }

  virtual size_t NumValues() const {
    return 1;
  }

  virtual string ToString() const {
    return string(Key()) + "\t" + Value();
  }
};

class OPENCC_EXPORT StrSingleValueDictEntry : public SingleValueDictEntry {
public:
  StrSingleValueDictEntry(const string& _key, const string& _value)
      : key(_key), value(_value) {
  }

  virtual ~StrSingleValueDictEntry() {
  }

  virtual const char* Key() const {
    return key.c_str();
  }

  virtual const char* Value() const {
    return value.c_str();
  }

private:
  string key;
  string value;
};

class OPENCC_EXPORT MultiValueDictEntry : public DictEntry {
public:
  virtual const char* GetDefault() const {
    if (NumValues() > 0) {
      return Values().at(0);
    } else {
      return Key();
    }
  }

  virtual string ToString() const;
};

class OPENCC_EXPORT StrMultiValueDictEntry : public MultiValueDictEntry {
public:
  StrMultiValueDictEntry(const string& _key, const vector<string>& _values)
      : key(_key), values(_values) {
  }

  StrMultiValueDictEntry(const string& _key, const vector<const char*>& _values)
      : key(_key) {
    values.reserve(_values.size());
    for (const char* str : _values) {
      values.push_back(str);
    }
  }

  virtual ~StrMultiValueDictEntry() {
  }

  virtual const char* Key() const {
    return key.c_str();
  }

  size_t NumValues() const {
    return values.size();
  }

  vector<const char*> Values() const {
    vector<const char*> values;
    for (const string& value : this->values) {
      values.push_back(value.c_str());
    }
    return values;
  }

private:
  string key;
  vector<string> values;
};

class OPENCC_EXPORT PtrDictEntry : public MultiValueDictEntry {
public:
  PtrDictEntry(const char* _key, const vector<const char*>& _values)
      : key(_key), values(_values) {
  }

  virtual ~PtrDictEntry() {
  }

  virtual const char* Key() const {
    return key;
  }

  size_t NumValues() const {
    return values.size();
  }

  vector<const char*> Values() const {
    return values;
  }

private:
  const char* key;
  vector<const char*> values;
};

class OPENCC_EXPORT DictEntryFactory {
public:
  static DictEntry* New(const string& key) {
    return new NoValueDictEntry(key);
  }

  static DictEntry* New(const string& key, const string& value) {
    return new StrSingleValueDictEntry(key, value);
  }

  static DictEntry* New(const string& key, const vector<string>& values) {
    return new StrMultiValueDictEntry(key, values);
  }

  static DictEntry* New(const DictEntry* entry) {
    if (entry->NumValues() == 0) {
      return new NoValueDictEntry(entry->Key());
    } else if (entry->NumValues() == 1) {
      const auto svEntry = static_cast<const SingleValueDictEntry*>(entry);
      return new StrSingleValueDictEntry(svEntry->Key(), svEntry->Value());
    } else {
      const auto mvEntry = static_cast<const MultiValueDictEntry*>(entry);
      return new StrMultiValueDictEntry(mvEntry->Key(), mvEntry->Values());
    }
  }
};

}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "GeoPolygon.h"

#include <stdlib.h>
#include <fcntl.h>
#include <cmath>
using std::fabs;

#include <QtCore/QFile>
#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QTime>
#ifdef Q_OS_UNIX
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/mman.h> /* mmap() is defined in this header */
#endif

using namespace Marble;

const qreal ARCMINUTE = 10800; // distance of 180deg in arcminutes
const qreal INT2RAD = M_PI / 10800.0;

GeoPolygon::GeoPolygon()
    : m_dateLineCrossing( false ),
      m_closed( false ),
      m_lonLeft( 0.0 ),
      m_latTop( 0.0 ),
      m_lonRight( 0.0 ),
      m_latBottom( 0.0 ),
      m_index( 0 )
{
}

GeoPolygon::~GeoPolygon()
{
//    qDeleteAll( begin(), end() );
    qDeleteAll( m_boundary );
}

void GeoPolygon::setBoundary( qreal lonLeft, qreal latTop, qreal lonRight, qreal latBottom)
{
    m_lonLeft   = lonLeft;
    m_latTop    = latTop;
    m_lonRight  = lonRight;
    m_latBottom = latBottom;

    m_boundary.clear();
    if ( getDateLine() == GeoPolygon::Even ) {
        qreal xcenter = ( lonLeft + ( 2.0 * M_PI + lonRight) ) / 2.0;

        if ( xcenter > M_PI )
            xcenter -=  2.0 * M_PI;
        if ( xcenter < -M_PI )
            xcenter +=  2.0 * M_PI;

        m_boundary.append( new GeoDataCoordinates( xcenter, 0.5 * (latTop + latBottom), 0.0, GeoDataCoordinates::Radian, 1 ) );
    }
    else
        m_boundary.append( new GeoDataCoordinates( 0.5 * (lonLeft + lonRight), 0.5 * (latTop + latBottom), 0.0, GeoDataCoordinates::Radian, 1 ) );

    m_boundary.append( new GeoDataCoordinates( lonLeft,  latTop,    0.0, GeoDataCoordinates::Radian, 1 ));
    m_boundary.append( new GeoDataCoordinates( lonRight, latBottom, 0.0, GeoDataCoordinates::Radian, 1 ));
    m_boundary.append( new GeoDataCoordinates( lonRight, latTop,    0.0, GeoDataCoordinates::Radian, 1 ));
    m_boundary.append( new GeoDataCoordinates( lonLeft,  latBottom, 0.0, GeoDataCoordinates::Radian, 1 ));

}

void GeoPolygon::displayBoundary()
{
    Quaternion  q;
    qreal      lon;
    qreal      lat;
    m_boundary.at(0)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(1)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(2)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(3)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(4)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;

//    qDebug() << "Points#: " << size() << " File: " << m_sourceFileName << " dateline " << getDateLine() << " Index: " << getIndex();
}

// ================================================================
//                               class PntMap

PntMap::PntMap()
    : m_isInitialized( false )
{
}

bool PntMap::isInitialized() const
{
    return m_isInitialized;
}

PntMap::~PntMap()
{
    if ( m_loader ) {
        m_loader->wait();
    }
    qDeleteAll( begin(), end() );
}

void PntMap::load(const QString &filename)
{
    m_loader = new PntMapLoader( this, filename );

    connect ( m_loader, SIGNAL( pntMapLoaded( bool ) ), SLOT( setInitialized( bool ) ) );
    m_loader->start();
}

void PntMap::setInitialized( bool isInitialized )
{
    if ( m_loader->isFinished() ) {
        delete m_loader;
        m_loader = 0;
    }

    m_isInitialized = isInitialized;
    emit initialized();
}

PntMapLoader::PntMapLoader( PntMap* parent, const QString& filename )
    : m_parent( parent ),
      m_filename( filename )
{
}

void PntMapLoader::run()
{
//    qDebug("PntMap::load trying to load: " + m_filename.toLocal8Bit());
    QTime *timer = new QTime();
    timer->restart();

#ifdef Q_OS_UNIX
    // MMAP Start
    int          fd;
    unsigned char* src;
    struct stat  statbuf;

    if ( (fd = open (m_filename.toLatin1(), O_RDONLY) ) < 0)  // krazy:exclude=syscalls
        qDebug() << "cannot open" << m_filename << " for reading";

    if ( fstat (fd,&statbuf) < 0 ) // krazy:exclude=syscalls
        qDebug() << "fstat error";

    int  filelength = statbuf.st_size;

    if ((src = (unsigned char*) mmap (0, filelength, PROT_READ, MAP_SHARED, fd, 0)) == (unsigned char*) (caddr_t) -1)
        qDebug() << "mmap error for input";

    short  header;
    short  iLat;
    short  iLon;
    int    count = 0;

    //const int halfFileLength = filelength / 2;

    for (int i=0; i < filelength; i+=6){
        header = src[i] | (src[i+1] << 8);
        iLat = src[i+2] | (src[i+3] << 8);
        iLon = src[i+4] | (src[i+5] << 8);

        // Transforming Range of Coordinates to iLat [0,ARCMINUTE] ,
        // iLon [0,2 * ARCMINUTE]

        //
        // 90 00N =   -ARCMINUTE / 2
        // 90 00S =   ARCMINUTE / 2
        // 180 00W =  -ARCMINUTE
        // 180 00E =   ARCMINUTE
        //
        if ( header > 5 ) {

            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());

            GeoPolygon  *polyline = new GeoPolygon();
            m_parent->append( polyline );

//            polyline->m_sourceFileName=filename;
            polyline->setIndex( header );

            // Find out whether the Polyline is a river or a closed polygon
            if ( ( header >= 7000 && header < 8000 )
                 || ( header >= 9000 && header < 20000 ) )
                polyline->setClosed( false );
            else
                polyline->setClosed( true );

            polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD, 0.0, GeoDataCoordinates::Radian, 5 ) );
        }
        else {
            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());
            m_parent->last()->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD, 0.0, GeoDataCoordinates::Radian, (int)(header) ) );
        }
        ++count;
    }
    munmap(src,filelength);
    close(fd);

    // qDebug(QString("Opened %1 with %2 Polylines and %3 Points").arg(filename).arg(this->count()).arg(count).toLatin1());
    // MMAP End
#else
#  ifdef Q_OS_WIN

    // qDebug("Loading PntMap ...");
    int    count = 0;
    QFile  file( m_filename );

    file.open( QIODevice::ReadOnly );
    QDataStream stream( &file );  // read the data serialized from the file
    stream.setByteOrder( QDataStream::LittleEndian );

    short  header;
    short  iLat;
    short  iLon;

    // Iterator that points to current PolyLine in PntMap
    //	QList<GeoPolygon*>::iterator it = begin();
    //	int count = 0;

    while( !stream.atEnd() ){
        stream >> header >> iLat >> iLon;
        // Transforming Range of Coordinates to iLat [0,ARCMINUTE] , iLon [0,2 * ARCMINUTE]

        if ( header > 5 ) {

            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());
            GeoPolygon  *polyline = new GeoPolygon();
            m_parent->append( polyline );

            polyline->setIndex(header);

            // Find out whether the Polyline is a river or a closed polygon
            if ( ( header >= 7000 && header < 8000 )
                 || ( header >= 9000 && header < 20000 ) )
                polyline->setClosed( false );
            else
                polyline->setClosed( true );

            polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD, 0.0, GeoDataCoordinates::Radian, 5 ) );
        }
        else {
            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());
            m_parent->last()->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD, 0.0, GeoDataCoordinates::Radian, (int)(header) ) );
        }
        ++count;
    }

    file.close();
    // qDebug(QString("Opened %1 with %2 Polylines and %3 Points").arg(filename).arg(this->count()).arg(count).toLatin1());

#  else
#  warning Your OS is not supported!
#  endif
#endif

    // To optimize performance we compute the boundaries of the
    // polygons.  To detect inside/outside we need to detect the
    // dateline first We probably won't need this for spherical
    // projection but for flat projection
    //
    // FIXME: Break this out into its own function.

    qreal  lon     = 0.0;
    qreal  lastLon = 0.0;
    qreal  lat     = 0.0;

    GeoPolygon::PtrVector::ConstIterator       itPolyLine;
    GeoPolygon::PtrVector::ConstIterator  itEndPolyLine = m_parent->constEnd();
    GeoDataCoordinates::Vector::ConstIterator   itPoint;

    // Now we calculate the boundaries

    for ( itPolyLine = m_parent->constBegin(); itPolyLine != itEndPolyLine; ++itPolyLine ) {

        qreal  lonLeft       =  +M_PI;
        qreal  lonRight      =  -M_PI;
        qreal  otherLonLeft  =  +M_PI;
        qreal  otherLonRight =  -M_PI;
        qreal  latTop        =  -M_PI / 2.0;
        qreal  latBottom     =  +M_PI / 2.0;

        bool isCrossingDateLine = false;
        bool isOriginalSide = true;
        int  lastSign     = 0;

        GeoDataCoordinates::Vector::ConstIterator  itEndPoint = (*itPolyLine)->constEnd();

        for ( itPoint = (*itPolyLine)->constBegin();
                itPoint != itEndPoint;
                ++itPoint )
        {
            itPoint->geoCoordinates( lon, lat );

            int currentSign = ( lon > 0.0 ) ? 1 : -1 ;

            if( itPoint == (*itPolyLine)->constBegin() ) {
                lastSign = currentSign;
                lastLon  = lon;
            }

            if ( lastSign != currentSign && fabs(lastLon) + fabs(lon) > M_PI ) {
                isOriginalSide = !isOriginalSide;
                isCrossingDateLine = true;
            }

            if ( isOriginalSide == true ) {
                if ( lon < lonLeft  ) lonLeft = lon;
                if ( lon > lonRight ) lonRight = lon;
            } else {
                if ( lon < otherLonLeft  ) otherLonLeft = lon;
                if ( lon > otherLonRight ) otherLonRight = lon;
            }

            if ( lat > latTop )    latTop = lat;
            if ( lat < latBottom ) latBottom = lat;

            lastSign = currentSign;
            lastLon  = lon;
        }

        if ( isOriginalSide == false ) {
            (*itPolyLine)->setDateLine( GeoPolygon::Odd );
//            qDebug() << "Odd  >> File: " << (*itPolyLine)->m_sourceFileName;
            (*itPolyLine)->setBoundary( -M_PI, latTop, M_PI, -M_PI / 2.0 );
//            qDebug() << " lonLeft: " << lonLeft << " lonRight: " << lonRight << " otherLonLeft: " << otherLonLeft << " otherlonRight: " << otherLonRight;
        }

        if ( isOriginalSide == true && isCrossingDateLine == true ) {
            (*itPolyLine)->setDateLine( GeoPolygon::Even );
//            qDebug() << "Even >> File: " << (*itPolyLine)->m_sourceFileName << " Size: " << (*itPolyLine)->size();

//            qDebug() << " lonLeft: " << lonLeft << " lonRight: " << lonRight << " otherLonLeft: " << otherLonLeft << " otherlonRight: " << otherLonRight;

            qreal leftLonRight, rightLonLeft;

            if ( fabs( M_PI * lonRight/fabs(lonRight) - lonRight ) >
                 fabs( M_PI * otherLonRight/fabs(otherLonRight) - otherLonRight ) ) {
                rightLonLeft = otherLonLeft;
                leftLonRight = lonRight;
            } else {
                rightLonLeft = lonLeft;
                leftLonRight = otherLonRight;
            }

            (*itPolyLine)->setBoundary( rightLonLeft, latTop, leftLonRight, latBottom );

//            qDebug() << "Crosses: lonLeft: " << rightLonLeft << " is right from: lonRight: " << leftLonRight;

        }
        if ( isCrossingDateLine == false ) {
            (*itPolyLine)->setDateLine( GeoPolygon::None );
            (*itPolyLine)->setBoundary( lonLeft, latTop, lonRight, latBottom );
        }
    }
//    qDebug() << "Elapsed: " << timer->elapsed();
    delete timer;

    emit pntMapLoaded( true );
}

#include "GeoPolygon.moc"
<commit_msg>Break long lines.<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "GeoPolygon.h"

#include <stdlib.h>
#include <fcntl.h>
#include <cmath>
using std::fabs;

#include <QtCore/QFile>
#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QTime>
#ifdef Q_OS_UNIX
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/mman.h> /* mmap() is defined in this header */
#endif

using namespace Marble;

const qreal ARCMINUTE = 10800; // distance of 180deg in arcminutes
const qreal INT2RAD = M_PI / 10800.0;

GeoPolygon::GeoPolygon()
    : m_dateLineCrossing( false ),
      m_closed( false ),
      m_lonLeft( 0.0 ),
      m_latTop( 0.0 ),
      m_lonRight( 0.0 ),
      m_latBottom( 0.0 ),
      m_index( 0 )
{
}

GeoPolygon::~GeoPolygon()
{
//    qDeleteAll( begin(), end() );
    qDeleteAll( m_boundary );
}

void GeoPolygon::setBoundary( qreal lonLeft, qreal latTop, qreal lonRight, qreal latBottom)
{
    m_lonLeft   = lonLeft;
    m_latTop    = latTop;
    m_lonRight  = lonRight;
    m_latBottom = latBottom;

    m_boundary.clear();
    if ( getDateLine() == GeoPolygon::Even ) {
        qreal xcenter = ( lonLeft + ( 2.0 * M_PI + lonRight) ) / 2.0;

        if ( xcenter > M_PI )
            xcenter -=  2.0 * M_PI;
        if ( xcenter < -M_PI )
            xcenter +=  2.0 * M_PI;

        m_boundary.append( new GeoDataCoordinates( xcenter, 0.5 * (latTop + latBottom), 0.0,
                                                   GeoDataCoordinates::Radian, 1 ) );
    }
    else
        m_boundary.append( new GeoDataCoordinates( 0.5 * (lonLeft + lonRight),
                                                   0.5 * (latTop + latBottom), 0.0,
                                                   GeoDataCoordinates::Radian, 1 ) );

    m_boundary.append( new GeoDataCoordinates( lonLeft,  latTop,    0.0, GeoDataCoordinates::Radian, 1 ));
    m_boundary.append( new GeoDataCoordinates( lonRight, latBottom, 0.0, GeoDataCoordinates::Radian, 1 ));
    m_boundary.append( new GeoDataCoordinates( lonRight, latTop,    0.0, GeoDataCoordinates::Radian, 1 ));
    m_boundary.append( new GeoDataCoordinates( lonLeft,  latBottom, 0.0, GeoDataCoordinates::Radian, 1 ));

}

void GeoPolygon::displayBoundary()
{
    Quaternion  q;
    qreal      lon;
    qreal      lat;
    m_boundary.at(0)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(1)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(2)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(3)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;
    m_boundary.at(4)->geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
    qDebug() << "Boundary:" << lon << ", " << lat;

//     qDebug() << "Points#: " << size() << " File: " << m_sourceFileName
//              << " dateline " << getDateLine() << " Index: " << getIndex();
}

// ================================================================
//                               class PntMap

PntMap::PntMap()
    : m_isInitialized( false )
{
}

bool PntMap::isInitialized() const
{
    return m_isInitialized;
}

PntMap::~PntMap()
{
    if ( m_loader ) {
        m_loader->wait();
    }
    qDeleteAll( begin(), end() );
}

void PntMap::load(const QString &filename)
{
    m_loader = new PntMapLoader( this, filename );

    connect ( m_loader, SIGNAL( pntMapLoaded( bool ) ), SLOT( setInitialized( bool ) ) );
    m_loader->start();
}

void PntMap::setInitialized( bool isInitialized )
{
    if ( m_loader->isFinished() ) {
        delete m_loader;
        m_loader = 0;
    }

    m_isInitialized = isInitialized;
    emit initialized();
}

PntMapLoader::PntMapLoader( PntMap* parent, const QString& filename )
    : m_parent( parent ),
      m_filename( filename )
{
}

void PntMapLoader::run()
{
//    qDebug("PntMap::load trying to load: " + m_filename.toLocal8Bit());
    QTime *timer = new QTime();
    timer->restart();

#ifdef Q_OS_UNIX
    // MMAP Start
    int          fd;
    unsigned char* src;
    struct stat  statbuf;

    if ( (fd = open (m_filename.toLatin1(), O_RDONLY) ) < 0)  // krazy:exclude=syscalls
        qDebug() << "cannot open" << m_filename << " for reading";

    if ( fstat (fd,&statbuf) < 0 ) // krazy:exclude=syscalls
        qDebug() << "fstat error";

    int  filelength = statbuf.st_size;

    if ((src = (unsigned char*) mmap (0, filelength, PROT_READ, MAP_SHARED, fd, 0))
        == (unsigned char*) (caddr_t) -1)
        qDebug() << "mmap error for input";

    short  header;
    short  iLat;
    short  iLon;
    int    count = 0;

    //const int halfFileLength = filelength / 2;

    for (int i=0; i < filelength; i+=6){
        header = src[i] | (src[i+1] << 8);
        iLat = src[i+2] | (src[i+3] << 8);
        iLon = src[i+4] | (src[i+5] << 8);

        // Transforming Range of Coordinates to iLat [0,ARCMINUTE] ,
        // iLon [0,2 * ARCMINUTE]

        //
        // 90 00N =   -ARCMINUTE / 2
        // 90 00S =   ARCMINUTE / 2
        // 180 00W =  -ARCMINUTE
        // 180 00E =   ARCMINUTE
        //
        if ( header > 5 ) {

            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());

            GeoPolygon  *polyline = new GeoPolygon();
            m_parent->append( polyline );

//            polyline->m_sourceFileName=filename;
            polyline->setIndex( header );

            // Find out whether the Polyline is a river or a closed polygon
            if ( ( header >= 7000 && header < 8000 )
                 || ( header >= 9000 && header < 20000 ) )
                polyline->setClosed( false );
            else
                polyline->setClosed( true );

            polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD,
                                                  0.0, GeoDataCoordinates::Radian, 5 ) );
        }
        else {
            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());
            m_parent->last()->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD,
                                                          (qreal)(iLat) * INT2RAD, 0.0,
                                                          GeoDataCoordinates::Radian,
                                                          (int)(header) ) );
        }
        ++count;
    }
    munmap(src,filelength);
    close(fd);

    // qDebug(QString("Opened %1 with %2 Polylines and %3 Points").arg(filename).arg(this->count()).arg(count).toLatin1());
    // MMAP End
#else
#  ifdef Q_OS_WIN

    // qDebug("Loading PntMap ...");
    int    count = 0;
    QFile  file( m_filename );

    file.open( QIODevice::ReadOnly );
    QDataStream stream( &file );  // read the data serialized from the file
    stream.setByteOrder( QDataStream::LittleEndian );

    short  header;
    short  iLat;
    short  iLon;

    // Iterator that points to current PolyLine in PntMap
    //	QList<GeoPolygon*>::iterator it = begin();
    //	int count = 0;

    while( !stream.atEnd() ){
        stream >> header >> iLat >> iLon;
        // Transforming Range of Coordinates to iLat [0,ARCMINUTE] , iLon [0,2 * ARCMINUTE]

        if ( header > 5 ) {

            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());
            GeoPolygon  *polyline = new GeoPolygon();
            m_parent->append( polyline );

            polyline->setIndex(header);

            // Find out whether the Polyline is a river or a closed polygon
            if ( ( header >= 7000 && header < 8000 )
                 || ( header >= 9000 && header < 20000 ) )
                polyline->setClosed( false );
            else
                polyline->setClosed( true );

            polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD,
                                                  0.0, GeoDataCoordinates::Radian, 5 ) );
        }
        else {
            // qDebug(QString("header: %1 iLat: %2 iLon: %3").arg(header).arg(iLat).arg(iLon).toLatin1());
            m_parent->last()->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD,
                                                          (qreal)(iLat) * INT2RAD, 0.0,
                                                          GeoDataCoordinates::Radian,
                                                          (int)(header) ) );
        }
        ++count;
    }

    file.close();
    // qDebug(QString("Opened %1 with %2 Polylines and %3 Points").arg(filename).arg(this->count()).arg(count).toLatin1());

#  else
#  warning Your OS is not supported!
#  endif
#endif

    // To optimize performance we compute the boundaries of the
    // polygons.  To detect inside/outside we need to detect the
    // dateline first We probably won't need this for spherical
    // projection but for flat projection
    //
    // FIXME: Break this out into its own function.

    qreal  lon     = 0.0;
    qreal  lastLon = 0.0;
    qreal  lat     = 0.0;

    GeoPolygon::PtrVector::ConstIterator       itPolyLine;
    GeoPolygon::PtrVector::ConstIterator  itEndPolyLine = m_parent->constEnd();
    GeoDataCoordinates::Vector::ConstIterator   itPoint;

    // Now we calculate the boundaries

    for ( itPolyLine = m_parent->constBegin(); itPolyLine != itEndPolyLine; ++itPolyLine ) {

        qreal  lonLeft       =  +M_PI;
        qreal  lonRight      =  -M_PI;
        qreal  otherLonLeft  =  +M_PI;
        qreal  otherLonRight =  -M_PI;
        qreal  latTop        =  -M_PI / 2.0;
        qreal  latBottom     =  +M_PI / 2.0;

        bool isCrossingDateLine = false;
        bool isOriginalSide = true;
        int  lastSign     = 0;

        GeoDataCoordinates::Vector::ConstIterator  itEndPoint = (*itPolyLine)->constEnd();

        for ( itPoint = (*itPolyLine)->constBegin();
                itPoint != itEndPoint;
                ++itPoint )
        {
            itPoint->geoCoordinates( lon, lat );

            int currentSign = ( lon > 0.0 ) ? 1 : -1 ;

            if( itPoint == (*itPolyLine)->constBegin() ) {
                lastSign = currentSign;
                lastLon  = lon;
            }

            if ( lastSign != currentSign && fabs(lastLon) + fabs(lon) > M_PI ) {
                isOriginalSide = !isOriginalSide;
                isCrossingDateLine = true;
            }

            if ( isOriginalSide == true ) {
                if ( lon < lonLeft  ) lonLeft = lon;
                if ( lon > lonRight ) lonRight = lon;
            } else {
                if ( lon < otherLonLeft  ) otherLonLeft = lon;
                if ( lon > otherLonRight ) otherLonRight = lon;
            }

            if ( lat > latTop )    latTop = lat;
            if ( lat < latBottom ) latBottom = lat;

            lastSign = currentSign;
            lastLon  = lon;
        }

        if ( isOriginalSide == false ) {
            (*itPolyLine)->setDateLine( GeoPolygon::Odd );
//            qDebug() << "Odd  >> File: " << (*itPolyLine)->m_sourceFileName;
            (*itPolyLine)->setBoundary( -M_PI, latTop, M_PI, -M_PI / 2.0 );
//            qDebug() << " lonLeft: " << lonLeft << " lonRight: " << lonRight << " otherLonLeft: " << otherLonLeft << " otherlonRight: " << otherLonRight;
        }

        if ( isOriginalSide == true && isCrossingDateLine == true ) {
            (*itPolyLine)->setDateLine( GeoPolygon::Even );
//            qDebug() << "Even >> File: " << (*itPolyLine)->m_sourceFileName << " Size: " << (*itPolyLine)->size();

//            qDebug() << " lonLeft: " << lonLeft << " lonRight: " << lonRight << " otherLonLeft: " << otherLonLeft << " otherlonRight: " << otherLonRight;

            qreal leftLonRight, rightLonLeft;

            if ( fabs( M_PI * lonRight/fabs(lonRight) - lonRight ) >
                 fabs( M_PI * otherLonRight/fabs(otherLonRight) - otherLonRight ) ) {
                rightLonLeft = otherLonLeft;
                leftLonRight = lonRight;
            } else {
                rightLonLeft = lonLeft;
                leftLonRight = otherLonRight;
            }

            (*itPolyLine)->setBoundary( rightLonLeft, latTop, leftLonRight, latBottom );

//            qDebug() << "Crosses: lonLeft: " << rightLonLeft << " is right from: lonRight: " << leftLonRight;

        }
        if ( isCrossingDateLine == false ) {
            (*itPolyLine)->setDateLine( GeoPolygon::None );
            (*itPolyLine)->setBoundary( lonLeft, latTop, lonRight, latBottom );
        }
    }
//    qDebug() << "Elapsed: " << timer->elapsed();
    delete timer;

    emit pntMapLoaded( true );
}

#include "GeoPolygon.moc"
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "NUM1Parser.h"

#include "libetonyek_xml.h"
#include "IWORKChainedTokenizer.h"
#include "IWORKDiscardContext.h"
#include "IWORKMetadataElement.h"
#include "IWORKTabularInfoElement.h"
#include "IWORKToken.h"
#include "NUMCollector.h"
#include "NUM1Token.h"
#include "NUM1XMLContextBase.h"

namespace libetonyek
{

namespace
{

unsigned getVersion(const int token)
{
  switch (token)
  {
  case NUM1Token::VERSION_STR_2 :
    return 2;
  }

  return 0;
}

}

namespace
{

class DrawablesElement : public NUM1XMLElementContextBase
{
public:
  explicit DrawablesElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual void attribute(int name, const char *value);
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

DrawablesElement::DrawablesElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void DrawablesElement::startOfElement()
{
  if (isCollector())
    getCollector().startLevel();
}

void DrawablesElement::attribute(int, const char *)
{
}

IWORKXMLContextPtr_t DrawablesElement::element(const int name)
{
  switch (name)
  {
  // case IWORKToken::NS_URI_SF | IWORKToken::body_placeholder_ref :
  //   return makeContext<PlaceholderRefContext>(getState(), false);
  // case IWORKToken::NS_URI_SF | IWORKToken::connection_line :
  //   return makeContext<ConnectionLineElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::group :
  //   return makeContext<GroupElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::image :
  //   return makeContext<ImageElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::line :
  //   return makeContext<LineElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::media :
  //   return makeContext<IWORKMediaElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::shape :
  //   return makeContext<ShapeElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::sticky_note :
  //   return makeContext<StickyNoteElement>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::tabular_info :
    return makeContext<IWORKTabularInfoElement>(getState());
    // case IWORKToken::NS_URI_SF | IWORKToken::title_placeholder_ref :
    //   return makeContext<PlaceholderRefContext>(getState(), true);

  }

  return IWORKXMLContextPtr_t();
}

void DrawablesElement::endOfElement()
{
  if (isCollector())
    getCollector().endLevel();
}

}

namespace
{

class LayerElement : public NUM1XMLElementContextBase
{
public:
  explicit LayerElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

LayerElement::LayerElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void LayerElement::startOfElement()
{
}

IWORKXMLContextPtr_t LayerElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::drawables :
    return makeContext<DrawablesElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void LayerElement::endOfElement()
{
}

}

namespace
{

class LayersElement : public NUM1XMLElementContextBase
{
public:
  explicit LayersElement(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

LayersElement::LayersElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

IWORKXMLContextPtr_t LayersElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::layer :
    return makeContext<LayerElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

}

namespace
{

class PageInfoElement : public NUM1XMLElementContextBase
{
public:
  explicit PageInfoElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

PageInfoElement::PageInfoElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void PageInfoElement::startOfElement()
{
}

IWORKXMLContextPtr_t PageInfoElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::layers :
    return makeContext<LayersElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void PageInfoElement::endOfElement()
{
}

}

namespace
{

class WorkSpaceElement : public NUM1XMLElementContextBase
{
public:
  explicit WorkSpaceElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

WorkSpaceElement::WorkSpaceElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void WorkSpaceElement::startOfElement()
{
}

IWORKXMLContextPtr_t WorkSpaceElement::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::page_info:
    return makeContext<PageInfoElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void WorkSpaceElement::endOfElement()
{
}

}

namespace
{

class WorkSpaceArrayElement : public NUM1XMLElementContextBase
{
public:
  explicit WorkSpaceArrayElement(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

WorkSpaceArrayElement::WorkSpaceArrayElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

IWORKXMLContextPtr_t WorkSpaceArrayElement::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::workspace:
    return makeContext<WorkSpaceElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

}

namespace
{

class DocumentElement : public NUM1XMLElementContextBase
{
public:
  explicit DocumentElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual void attribute(int name, const char *value);
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();

};

DocumentElement::DocumentElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void DocumentElement::startOfElement()
{
  if (isCollector())
    getCollector().startDocument();
}

void DocumentElement::attribute(const int name, const char *const value)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::version :
  {
    const unsigned version = getVersion(getToken(value));
    if (0 == version)
    {
      ETONYEK_DEBUG_MSG(("unknown version %s\n", value));
    }
  }
  break;
  }
}

IWORKXMLContextPtr_t DocumentElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::metadata :
    return makeContext<IWORKMetadataElement>(getState());
  case NUM1Token::NS_URI_LS | NUM1Token::workspace_array :
    return makeContext<WorkSpaceArrayElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void DocumentElement::endOfElement()
{
  if (isCollector())
    getCollector().endDocument();
}

}

namespace
{

class XMLDocument : public NUM1XMLElementContextBase
{
public:
  explicit XMLDocument(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

XMLDocument::XMLDocument(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

IWORKXMLContextPtr_t XMLDocument::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::document :
    return makeContext<DocumentElement>(m_state);
  }

  return IWORKXMLContextPtr_t();
}

}

namespace
{

class DiscardContext : public NUM1XMLContextBase<IWORKDiscardContext>
{
public:
  explicit DiscardContext(NUM1ParserState &state);
};

DiscardContext::DiscardContext(NUM1ParserState &state)
  : NUM1XMLContextBase<IWORKDiscardContext>(state)
{
}

}

NUM1Parser::NUM1Parser(const RVNGInputStreamPtr_t &input, const RVNGInputStreamPtr_t &package, NUMCollector &collector, NUMDictionary *const dict)
  : IWORKParser(input, package)
  , m_state(*this, collector, *dict)
{
}

NUM1Parser::~NUM1Parser()
{
}

IWORKXMLContextPtr_t NUM1Parser::createDocumentContext()
{
  return makeContext<XMLDocument>(m_state);
}

IWORKXMLContextPtr_t NUM1Parser::createDiscardContext()
{
  return makeContext<DiscardContext>(m_state);
}

const IWORKTokenizer &NUM1Parser::getTokenizer() const
{
  static IWORKChainedTokenizer tokenizer(NUM1Token::getTokenizer(), IWORKToken::getTokenizer());
  return tokenizer;
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>numbers: parse stylesheet<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "NUM1Parser.h"

#include "libetonyek_xml.h"
#include "IWORKChainedTokenizer.h"
#include "IWORKDiscardContext.h"
#include "IWORKMetadataElement.h"
#include "IWORKStylesheetBase.h"
#include "IWORKTabularInfoElement.h"
#include "IWORKToken.h"
#include "NUMCollector.h"
#include "NUM1Token.h"
#include "NUM1XMLContextBase.h"

namespace libetonyek
{

namespace
{

unsigned getVersion(const int token)
{
  switch (token)
  {
  case NUM1Token::VERSION_STR_2 :
    return 2;
  }

  return 0;
}

}

namespace
{

class DrawablesElement : public NUM1XMLElementContextBase
{
public:
  explicit DrawablesElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual void attribute(int name, const char *value);
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

DrawablesElement::DrawablesElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void DrawablesElement::startOfElement()
{
  if (isCollector())
    getCollector().startLevel();
}

void DrawablesElement::attribute(int, const char *)
{
}

IWORKXMLContextPtr_t DrawablesElement::element(const int name)
{
  switch (name)
  {
  // case IWORKToken::NS_URI_SF | IWORKToken::body_placeholder_ref :
  //   return makeContext<PlaceholderRefContext>(getState(), false);
  // case IWORKToken::NS_URI_SF | IWORKToken::connection_line :
  //   return makeContext<ConnectionLineElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::group :
  //   return makeContext<GroupElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::image :
  //   return makeContext<ImageElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::line :
  //   return makeContext<LineElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::media :
  //   return makeContext<IWORKMediaElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::shape :
  //   return makeContext<ShapeElement>(getState());
  // case IWORKToken::NS_URI_SF | IWORKToken::sticky_note :
  //   return makeContext<StickyNoteElement>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::tabular_info :
    return makeContext<IWORKTabularInfoElement>(getState());
    // case IWORKToken::NS_URI_SF | IWORKToken::title_placeholder_ref :
    //   return makeContext<PlaceholderRefContext>(getState(), true);

  }

  return IWORKXMLContextPtr_t();
}

void DrawablesElement::endOfElement()
{
  if (isCollector())
    getCollector().endLevel();
}

}

namespace
{

class LayerElement : public NUM1XMLElementContextBase
{
public:
  explicit LayerElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

LayerElement::LayerElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void LayerElement::startOfElement()
{
}

IWORKXMLContextPtr_t LayerElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::drawables :
    return makeContext<DrawablesElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void LayerElement::endOfElement()
{
}

}

namespace
{

class LayersElement : public NUM1XMLElementContextBase
{
public:
  explicit LayersElement(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

LayersElement::LayersElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

IWORKXMLContextPtr_t LayersElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::layer :
    return makeContext<LayerElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

}

namespace
{

class PageInfoElement : public NUM1XMLElementContextBase
{
public:
  explicit PageInfoElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

PageInfoElement::PageInfoElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void PageInfoElement::startOfElement()
{
}

IWORKXMLContextPtr_t PageInfoElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::layers :
    return makeContext<LayersElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void PageInfoElement::endOfElement()
{
}

}

namespace
{

class StylesheetElement : public NUM1XMLContextBase<IWORKStylesheetBase>
{
public:
  explicit StylesheetElement(NUM1ParserState &state);
};

StylesheetElement::StylesheetElement(NUM1ParserState &state)
  : NUM1XMLContextBase<IWORKStylesheetBase>(state)
{
}

}

namespace
{

class WorkSpaceElement : public NUM1XMLElementContextBase
{
public:
  explicit WorkSpaceElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();
};

WorkSpaceElement::WorkSpaceElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void WorkSpaceElement::startOfElement()
{
}

IWORKXMLContextPtr_t WorkSpaceElement::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::page_info:
    return makeContext<PageInfoElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void WorkSpaceElement::endOfElement()
{
}

}

namespace
{

class WorkSpaceArrayElement : public NUM1XMLElementContextBase
{
public:
  explicit WorkSpaceArrayElement(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

WorkSpaceArrayElement::WorkSpaceArrayElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

IWORKXMLContextPtr_t WorkSpaceArrayElement::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::workspace:
    return makeContext<WorkSpaceElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

}

namespace
{

class DocumentElement : public NUM1XMLElementContextBase
{
public:
  explicit DocumentElement(NUM1ParserState &state);

private:
  virtual void startOfElement();
  virtual void attribute(int name, const char *value);
  virtual IWORKXMLContextPtr_t element(int name);
  virtual void endOfElement();

};

DocumentElement::DocumentElement(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

void DocumentElement::startOfElement()
{
  if (isCollector())
    getCollector().startDocument();
}

void DocumentElement::attribute(const int name, const char *const value)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::version :
  {
    const unsigned version = getVersion(getToken(value));
    if (0 == version)
    {
      ETONYEK_DEBUG_MSG(("unknown version %s\n", value));
    }
  }
  break;
  }
}

IWORKXMLContextPtr_t DocumentElement::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::metadata :
    return makeContext<IWORKMetadataElement>(getState());
  case NUM1Token::NS_URI_LS | NUM1Token::stylesheet :
    return makeContext<StylesheetElement>(getState());
  case NUM1Token::NS_URI_LS | NUM1Token::workspace_array :
    return makeContext<WorkSpaceArrayElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void DocumentElement::endOfElement()
{
  if (isCollector())
    getCollector().endDocument();
}

}

namespace
{

class XMLDocument : public NUM1XMLElementContextBase
{
public:
  explicit XMLDocument(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

XMLDocument::XMLDocument(NUM1ParserState &state)
  : NUM1XMLElementContextBase(state)
{
}

IWORKXMLContextPtr_t XMLDocument::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::document :
    return makeContext<DocumentElement>(m_state);
  }

  return IWORKXMLContextPtr_t();
}

}

namespace
{

class DiscardContext : public NUM1XMLContextBase<IWORKDiscardContext>
{
public:
  explicit DiscardContext(NUM1ParserState &state);

private:
  virtual IWORKXMLContextPtr_t element(int name);
};

DiscardContext::DiscardContext(NUM1ParserState &state)
  : NUM1XMLContextBase<IWORKDiscardContext>(state)
{
}

IWORKXMLContextPtr_t DiscardContext::element(const int name)
{
  switch (name)
  {
  case NUM1Token::NS_URI_LS | NUM1Token::stylesheet :
    return makeContext<StylesheetElement>(getState());
  }

  return shared_from_this();
}

}

NUM1Parser::NUM1Parser(const RVNGInputStreamPtr_t &input, const RVNGInputStreamPtr_t &package, NUMCollector &collector, NUMDictionary *const dict)
  : IWORKParser(input, package)
  , m_state(*this, collector, *dict)
{
}

NUM1Parser::~NUM1Parser()
{
}

IWORKXMLContextPtr_t NUM1Parser::createDocumentContext()
{
  return makeContext<XMLDocument>(m_state);
}

IWORKXMLContextPtr_t NUM1Parser::createDiscardContext()
{
  return makeContext<DiscardContext>(m_state);
}

const IWORKTokenizer &NUM1Parser::getTokenizer() const
{
  static IWORKChainedTokenizer tokenizer(NUM1Token::getTokenizer(), IWORKToken::getTokenizer());
  return tokenizer;
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>