<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_CHAINED_BUFFER_HPP_INCLUDED
#define TORRENT_CHAINED_BUFFER_HPP_INCLUDED

#include <boost/function/function1.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION < 103500
#include <asio/buffer.hpp>
#else
#include <boost/asio/buffer.hpp>
#endif
#include <list>
#include	<string.h> // for memcpy

namespace libtorrent
{
#if BOOST_VERSION >= 103500
	namespace asio = boost::asio;
#endif
	struct chained_buffer
	{
		chained_buffer(): m_bytes(0), m_capacity(0) {}

		struct buffer_t
		{
			boost::function<void(char*)> free; // destructs the buffer
			char* buf; // the first byte of the buffer
			int size; // the total size of the buffer

			char* start; // the first byte to send/receive in the buffer
			int used_size; // this is the number of bytes to send/receive
		};

		bool empty() const { return m_bytes == 0; }
		int size() const { return m_bytes; }
		int capacity() const { return m_capacity; }

		void pop_front(int bytes_to_pop)
		{
			TORRENT_ASSERT(bytes_to_pop <= m_bytes);
			while (bytes_to_pop > 0 && !m_vec.empty())
			{
				buffer_t& b = m_vec.front();
				if (b.used_size > bytes_to_pop)
				{
					b.start += bytes_to_pop;
					b.used_size -= bytes_to_pop;
					m_bytes -= bytes_to_pop;
					TORRENT_ASSERT(m_bytes <= m_capacity);
					TORRENT_ASSERT(m_bytes >= 0);
					TORRENT_ASSERT(m_capacity >= 0);
					break;
				}

				b.free(b.buf);
				m_bytes -= b.used_size;
				m_capacity -= b.size;
				bytes_to_pop -= b.used_size;
				TORRENT_ASSERT(m_bytes >= 0);
				TORRENT_ASSERT(m_capacity >= 0);
				TORRENT_ASSERT(m_bytes <= m_capacity);
				m_vec.pop_front();
			}
		}

		template <class D>
		void append_buffer(char* buffer, int s, int used_size, D const& destructor)
		{
			TORRENT_ASSERT(s >= used_size);
			buffer_t b;
			b.buf = buffer;
			b.size = s;
			b.start = buffer;
			b.used_size = used_size;
			b.free = destructor;
			m_vec.push_back(b);

			m_bytes += used_size;
			m_capacity += s;
			TORRENT_ASSERT(m_bytes <= m_capacity);
		}

		// returns the number of bytes available at the
		// end of the last chained buffer.
		int space_in_last_buffer()
		{
			if (m_vec.empty()) return 0;
			buffer_t& b = m_vec.back();
			return b.size - b.used_size - (b.start - b.buf);
		}

		// tries to copy the given buffer to the end of the
		// last chained buffer. If there's not enough room
		// it returns false
		bool append(char const* buf, int s)
		{
			char* insert = allocate_appendix(s);
			if (insert == 0) return false;
			memcpy(insert, buf, s);
			return true;
		}

		// tries to allocate memory from the end
		// of the last buffer. If there isn't
		// enough room, returns 0
		char* allocate_appendix(int s)
		{
			if (m_vec.empty()) return 0;
			buffer_t& b = m_vec.back();
			char* insert = b.start + b.used_size;
			if (insert + s > b.buf + b.size) return 0;
			b.used_size += s;
			m_bytes += s;
			TORRENT_ASSERT(m_bytes <= m_capacity);
			return insert;
		}

		std::list<asio::const_buffer> const& build_iovec(int to_send)
		{
			m_tmp_vec.clear();

			for (std::list<buffer_t>::iterator i = m_vec.begin()
				, end(m_vec.end()); to_send > 0 && i != end; ++i)
			{
				if (i->used_size > to_send)
				{
					TORRENT_ASSERT(to_send > 0);
					m_tmp_vec.push_back(asio::const_buffer(i->start, to_send));
					break;
				}
				TORRENT_ASSERT(i->used_size > 0);
				m_tmp_vec.push_back(asio::const_buffer(i->start, i->used_size));
				to_send -= i->used_size;
			}
			return m_tmp_vec;
		}

		~chained_buffer()
		{
			for (std::list<buffer_t>::iterator i = m_vec.begin()
				, end(m_vec.end()); i != end; ++i)
			{
				i->free(i->buf);
			}
		}

	private:

		// this is the list of all the buffers we want to
		// send
		std::list<buffer_t> m_vec;

		// this is the number of bytes in the send buf.
		// this will always be equal to the sum of the
		// size of all buffers in vec
		int m_bytes;

		// the total size of all buffers in the chain
		// including unused space
		int m_capacity;

		// this is the vector of buffers used when
		// invoking the async write call
		std::list<asio::const_buffer> m_tmp_vec;
	};
}

#endif

<commit_msg>fix typo<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_CHAINED_BUFFER_HPP_INCLUDED
#define TORRENT_CHAINED_BUFFER_HPP_INCLUDED

#include <boost/function/function1.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION < 103500
#include <asio/buffer.hpp>
#else
#include <boost/asio/buffer.hpp>
#endif
#include <list>
#include <string.h> // for memcpy

namespace libtorrent
{
#if BOOST_VERSION >= 103500
	namespace asio = boost::asio;
#endif
	struct chained_buffer
	{
		chained_buffer(): m_bytes(0), m_capacity(0) {}

		struct buffer_t
		{
			boost::function<void(char*)> free; // destructs the buffer
			char* buf; // the first byte of the buffer
			int size; // the total size of the buffer

			char* start; // the first byte to send/receive in the buffer
			int used_size; // this is the number of bytes to send/receive
		};

		bool empty() const { return m_bytes == 0; }
		int size() const { return m_bytes; }
		int capacity() const { return m_capacity; }

		void pop_front(int bytes_to_pop)
		{
			TORRENT_ASSERT(bytes_to_pop <= m_bytes);
			while (bytes_to_pop > 0 && !m_vec.empty())
			{
				buffer_t& b = m_vec.front();
				if (b.used_size > bytes_to_pop)
				{
					b.start += bytes_to_pop;
					b.used_size -= bytes_to_pop;
					m_bytes -= bytes_to_pop;
					TORRENT_ASSERT(m_bytes <= m_capacity);
					TORRENT_ASSERT(m_bytes >= 0);
					TORRENT_ASSERT(m_capacity >= 0);
					break;
				}

				b.free(b.buf);
				m_bytes -= b.used_size;
				m_capacity -= b.size;
				bytes_to_pop -= b.used_size;
				TORRENT_ASSERT(m_bytes >= 0);
				TORRENT_ASSERT(m_capacity >= 0);
				TORRENT_ASSERT(m_bytes <= m_capacity);
				m_vec.pop_front();
			}
		}

		template <class D>
		void append_buffer(char* buffer, int s, int used_size, D const& destructor)
		{
			TORRENT_ASSERT(s >= used_size);
			buffer_t b;
			b.buf = buffer;
			b.size = s;
			b.start = buffer;
			b.used_size = used_size;
			b.free = destructor;
			m_vec.push_back(b);

			m_bytes += used_size;
			m_capacity += s;
			TORRENT_ASSERT(m_bytes <= m_capacity);
		}

		// returns the number of bytes available at the
		// end of the last chained buffer.
		int space_in_last_buffer()
		{
			if (m_vec.empty()) return 0;
			buffer_t& b = m_vec.back();
			return b.size - b.used_size - (b.start - b.buf);
		}

		// tries to copy the given buffer to the end of the
		// last chained buffer. If there's not enough room
		// it returns false
		bool append(char const* buf, int s)
		{
			char* insert = allocate_appendix(s);
			if (insert == 0) return false;
			memcpy(insert, buf, s);
			return true;
		}

		// tries to allocate memory from the end
		// of the last buffer. If there isn't
		// enough room, returns 0
		char* allocate_appendix(int s)
		{
			if (m_vec.empty()) return 0;
			buffer_t& b = m_vec.back();
			char* insert = b.start + b.used_size;
			if (insert + s > b.buf + b.size) return 0;
			b.used_size += s;
			m_bytes += s;
			TORRENT_ASSERT(m_bytes <= m_capacity);
			return insert;
		}

		std::list<asio::const_buffer> const& build_iovec(int to_send)
		{
			m_tmp_vec.clear();

			for (std::list<buffer_t>::iterator i = m_vec.begin()
				, end(m_vec.end()); to_send > 0 && i != end; ++i)
			{
				if (i->used_size > to_send)
				{
					TORRENT_ASSERT(to_send > 0);
					m_tmp_vec.push_back(asio::const_buffer(i->start, to_send));
					break;
				}
				TORRENT_ASSERT(i->used_size > 0);
				m_tmp_vec.push_back(asio::const_buffer(i->start, i->used_size));
				to_send -= i->used_size;
			}
			return m_tmp_vec;
		}

		~chained_buffer()
		{
			for (std::list<buffer_t>::iterator i = m_vec.begin()
				, end(m_vec.end()); i != end; ++i)
			{
				i->free(i->buf);
			}
		}

	private:

		// this is the list of all the buffers we want to
		// send
		std::list<buffer_t> m_vec;

		// this is the number of bytes in the send buf.
		// this will always be equal to the sum of the
		// size of all buffers in vec
		int m_bytes;

		// the total size of all buffers in the chain
		// including unused space
		int m_capacity;

		// this is the vector of buffers used when
		// invoking the async write call
		std::list<asio::const_buffer> m_tmp_vec;
	};
}

#endif

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2009 Artem Pavlenko
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_HPP
#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/expression_node.hpp>

// boost
#include <boost/version.hpp>
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>
//spirit2
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
//fusion
#include <boost/fusion/include/adapt_struct.hpp>
//phoenix
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>

namespace mapnik
{

namespace qi = boost::spirit::qi;
namespace standard_wide =  boost::spirit::standard_wide;
using standard_wide::space_type;

struct unicode_impl
{
    template <typename T>
    struct result
    {
        typedef UnicodeString type;
    };

    explicit unicode_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    UnicodeString operator()(std::string const& str) const
    {
        return tr_.transcode(str.c_str());
    }

    mapnik::transcoder const& tr_;
};

struct regex_match_impl
{
    template <typename T0, typename T1>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_match_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1>
    expr_node operator() (T0 & node, T1 const& pattern) const
    {
        return regex_match_node(node,tr_.transcode(pattern.c_str()));
    }

    mapnik::transcoder const& tr_;
};

struct regex_replace_impl
{
    template <typename T0, typename T1, typename T2>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_replace_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1,typename T2>
    expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
    {
        return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
    }

    mapnik::transcoder const& tr_;
};

template <typename Iterator>
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{
    typedef qi::rule<Iterator, expr_node(), space_type> rule_type;

    explicit expression_grammar(mapnik::transcoder const& tr)
        : expression_grammar::base_type(expr),
          unicode_(unicode_impl(tr)),
          regex_match_(regex_match_impl(tr)),
          regex_replace_(regex_replace_impl(tr))
    {
        using boost::phoenix::construct;
        using qi::_1;
        using qi::_a;
        using qi::_b;
        using qi::_r1;
#if BOOST_VERSION > 104200
        using qi::no_skip;
#else
        using qi::lexeme;
#endif
        using qi::_val;
        using qi::lit;
        using qi::int_;
        using qi::double_;
        using standard_wide::char_;

        expr = logical_expr.alias();

        logical_expr = not_expr [_val = _1]
            >>
            *(  (  ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
                | (( lit("or") | lit("||")) >> not_expr [_val || _1])
                )
            ;

        not_expr =
            cond_expr [_val = _1 ]
            | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
            ;

        cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
            ;

        equality_expr =
            relational_expr [_val = _1]
            >> *(  ( (lit("=") | lit("eq")) >> relational_expr [_val == _1])
                   | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
                )
            ;

        regex_match_expr = lit(".match")
            >> lit('(')
            >> ustring [_val = _1]
            >> lit(')')
            ;

        regex_replace_expr =
            lit(".replace")
            >> lit('(')
            >> ustring           [_a = _1]
            >> lit(',')
            >> ustring           [_b = _1]
            >> lit(')')          [_val = regex_replace_(_r1,_a,_b)]
            ;

        relational_expr = additive_expr[_val = _1]
            >>
            *(  (   (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
                | ( (lit('<')  | lit("lt") ) >> additive_expr [ _val <  _1 ])
                | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
                | ( (lit('>')  | lit("gt") ) >> additive_expr [ _val >  _1 ])
                )
            ;
        additive_expr = multiplicative_expr [_val = _1]
            >> * (   '+' >> multiplicative_expr[_val += _1]
                     | '-' >> multiplicative_expr[_val -= _1]
                )
            ;

        multiplicative_expr = primary_expr [_val = _1]
            >> *(     '*' >> primary_expr [_val *= _1]
                      | '/' >> primary_expr [_val /= _1]
                      | '%' >> primary_expr [_val %= _1]
                      |  regex_match_expr[_val = regex_match_(_val, _1)]
                      |  regex_replace_expr(_val) [_val = _1]
                )
            ;

        primary_expr = strict_double [_val = _1]
            | int_ [_val = _1]
            | lit("true") [_val = true]
            | lit("false") [_val = false]
            | ustring [_val = unicode_(_1) ]
            | attr [_val = construct<attribute>( _1 ) ]
            | '(' >> expr [_val = _1 ] >> ')'
            ;

        attr %= '[' >> +(char_ - ']') >> ']';
#if BOOST_VERSION > 104200
        ustring %= '\'' >> no_skip[*~char_('\'')] >> '\'';
#else
        ustring %= '\'' >> lexeme[*(char_-'\'')] >> '\'';
#endif
    }

    qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
    boost::phoenix::function<unicode_impl> unicode_;
    boost::phoenix::function<regex_match_impl> regex_match_;
    boost::phoenix::function<regex_replace_impl> regex_replace_;
    //
    rule_type expr;
    rule_type equality_expr;
    rule_type cond_expr;
    rule_type relational_expr;
    rule_type logical_expr;
    rule_type additive_expr;
    rule_type multiplicative_expr;
    rule_type not_expr;
    rule_type primary_expr;
    qi::rule<Iterator, std::string() > regex_match_expr;
    qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
    qi::rule<Iterator, std::string() , space_type> attr;
    qi::rule<Iterator, std::string() > ustring;
};

} // namespace

#endif  // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
<commit_msg>+ add 'is' keyword (same as 'eq', '=') + parse 'null' as  value_null()<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2009 Artem Pavlenko
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_HPP
#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/expression_node.hpp>

// boost
#include <boost/version.hpp>
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>
//spirit2
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
//fusion
#include <boost/fusion/include/adapt_struct.hpp>
//phoenix
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>

namespace mapnik
{

namespace qi = boost::spirit::qi;
namespace standard_wide =  boost::spirit::standard_wide;
using standard_wide::space_type;

struct unicode_impl
{
    template <typename T>
    struct result
    {
        typedef UnicodeString type;
    };

    explicit unicode_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    UnicodeString operator()(std::string const& str) const
    {
        return tr_.transcode(str.c_str());
    }

    mapnik::transcoder const& tr_;
};

struct regex_match_impl
{
    template <typename T0, typename T1>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_match_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1>
    expr_node operator() (T0 & node, T1 const& pattern) const
    {
        return regex_match_node(node,tr_.transcode(pattern.c_str()));
    }

    mapnik::transcoder const& tr_;
};

struct regex_replace_impl
{
    template <typename T0, typename T1, typename T2>
    struct result
    {
        typedef expr_node type;
    };

    explicit regex_replace_impl(mapnik::transcoder const& tr)
        : tr_(tr) {}

    template <typename T0,typename T1,typename T2>
    expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const
    {
        return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
    }

    mapnik::transcoder const& tr_;
};

template <typename Iterator>
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{
    typedef qi::rule<Iterator, expr_node(), space_type> rule_type;

    explicit expression_grammar(mapnik::transcoder const& tr)
        : expression_grammar::base_type(expr),
          unicode_(unicode_impl(tr)),
          regex_match_(regex_match_impl(tr)),
          regex_replace_(regex_replace_impl(tr))
    {
        using boost::phoenix::construct;
        using qi::_1;
        using qi::_a;
        using qi::_b;
        using qi::_r1;
#if BOOST_VERSION > 104200
        using qi::no_skip;
#else
        using qi::lexeme;
#endif
        using qi::_val;
        using qi::lit;
        using qi::int_;
        using qi::double_;
        using standard_wide::char_;

        expr = logical_expr.alias();

        logical_expr = not_expr [_val = _1]
            >>
            *(  (  ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
                | (( lit("or") | lit("||")) >> not_expr [_val || _1])
                )
            ;

        not_expr =
            cond_expr [_val = _1 ]
            | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
            ;

        cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
            ;

        equality_expr =
            relational_expr [_val = _1]
            >> *(  ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1])
                   | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
                )
            ;

        regex_match_expr = lit(".match")
            >> lit('(')
            >> ustring [_val = _1]
            >> lit(')')
            ;

        regex_replace_expr =
            lit(".replace")
            >> lit('(')
            >> ustring           [_a = _1]
            >> lit(',')
            >> ustring           [_b = _1]
            >> lit(')')          [_val = regex_replace_(_r1,_a,_b)]
            ;

        relational_expr = additive_expr[_val = _1]
            >>
            *(  (   (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
                | ( (lit('<')  | lit("lt") ) >> additive_expr [ _val <  _1 ])
                | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
                | ( (lit('>')  | lit("gt") ) >> additive_expr [ _val >  _1 ])
                )
            ;
        additive_expr = multiplicative_expr [_val = _1]
            >> * (   '+' >> multiplicative_expr[_val += _1]
                     | '-' >> multiplicative_expr[_val -= _1]
                )
            ;

        multiplicative_expr = primary_expr [_val = _1]
            >> *(     '*' >> primary_expr [_val *= _1]
                      | '/' >> primary_expr [_val /= _1]
                      | '%' >> primary_expr [_val %= _1]
                      |  regex_match_expr[_val = regex_match_(_val, _1)]
                      |  regex_replace_expr(_val) [_val = _1]
                )
            ;

        primary_expr = strict_double [_val = _1]
            | int_ [_val = _1]
            | lit("true") [_val = true]
            | lit("false") [_val = false]
            | lit("null") [_val = value_null() ]
            | ustring [_val = unicode_(_1) ]
            | attr [_val = construct<attribute>( _1 ) ]
            | '(' >> expr [_val = _1 ] >> ')'
            ;

        attr %= '[' >> +(char_ - ']') >> ']';
#if BOOST_VERSION > 104200
        ustring %= '\'' >> no_skip[*~char_('\'')] >> '\'';
#else
        ustring %= '\'' >> lexeme[*(char_-'\'')] >> '\'';
#endif
    }

    qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
    boost::phoenix::function<unicode_impl> unicode_;
    boost::phoenix::function<regex_match_impl> regex_match_;
    boost::phoenix::function<regex_replace_impl> regex_replace_;
    //
    rule_type expr;
    rule_type equality_expr;
    rule_type cond_expr;
    rule_type relational_expr;
    rule_type logical_expr;
    rule_type additive_expr;
    rule_type multiplicative_expr;
    rule_type not_expr;
    rule_type primary_expr;
    qi::rule<Iterator, std::string() > regex_match_expr;
    qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
    qi::rule<Iterator, std::string() , space_type> attr;
    qi::rule<Iterator, std::string() > ustring;
};

} // namespace

#endif  // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
<|endoftext|>


<commit_before>#include <QCoreApplication>

#include <iostream>
#include <fstream>
//#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265359
#endif

#define SHOW_PROGRESS
#define BASE_DT 0.0001

double drand48()
{
    return((double)(rand())/((double)RAND_MAX));
}

void normalDistRand(double stdDev,double* randomNumbers)
    {
        /* Generate a random number in polar coordinates */
        double radius = sqrt(-2.0*log(drand48()));
        double angle = 2.0*M_PI*drand48();
        /* transform the number back into cartesian coordinates */
        randomNumbers[0] = stdDev*radius*sin(angle);
        randomNumbers[1] = stdDev*radius*cos(angle);
    }

double linear(long steps,
              double a,double gamma,double r,double d,double g,
              double *x,double *y,double *z, double dt,
              int n,
              double beta,double tau,
              std::ofstream *fp,
              int q,
              double h,double s,double *v,double *w)
    {
        long m=n-1;
        long p=0;
        double B[2];
        int calcRandom=0;
        for (long k=0;k<steps;k++)
        {
            if(calcRandom==0)
                normalDistRand(sqrt(dt),B); //noise in most recent time step

            //x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt
            //x[0]=x[0]+beta*y[m]*(1-y[m])+0.5*beta*y[m]*(1-y[m])*beta*(1-2*y[m])*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Macroalgae
            x[0] = y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt;

            //Adds in the noise
            //x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*y[m]*beta*(B[calcRandom]*B[calcRandom]-dt);
            x[0] += beta*y[m]*B[calcRandom]+0.5*beta*beta*y[m]*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Coral
            x[1] = z[m]+(z[m]*(r-d-(a+r)*y[m]-r*z[m]))*dt;

            x[2] =  v[m]+(v[m]*(gamma-gamma*v[m]+(a-gamma)*w[m])-(g*v[p]/(1-w[p])))*dt;
            x[2] += beta*v[m]*(1-v[m])*B[calcRandom]+0.5*beta*(1-2*v[m])*beta*v[m]*(1-v[m])*(B[calcRandom]*B[calcRandom]-dt);
            x[3] =  w[m]+(w[m]*(r-d-(a+r)*v[m]-r*w[m]))*dt;

            /****************************************************************
                Account for extinction and overgrowing!!
            ****************************************************************/
            for(int i=0;i<4;++i)
                {
                    if(x[i]<0.0)
                        x[i] = 0.0;
                    else if (x[i]>1.0)
                        x[i] = 1.0;
                }

            //Updates delay and cell index
            m=(m+1)%n;
            p=(p+1)%n;
            y[m]=x[0];
            z[m]=x[1];
            v[m]=x[2];
            w[m]=x[3];
            calcRandom = (calcRandom+1)%2; // update which random number to use.
            //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",x[0],x[1],1-x[0]-x[1],x[2],x[3],1-x[2]-x[3]);
        }

        //printf("%f\t%f\t%f\t%f\t%f\n",dt,beta,tau,x[0],x[1]);
        *fp << dt << ","
            << beta << ","
            << g << ","
            << tau << ","
            << q+1 << ","
            << h << ","
            << s << ","
            << 1-h-s << ","
            << x[0] << ","
            << x[1] << ","
            << 1-x[0]-x[1] << ","
            << x[2] << ","
            << x[3] << ","
            << 1-x[2]-x[3]
            << std::endl;
        return 0;
    }

/* ****************************************************************
     main

     The main function. Called at the start of the program.
**************************************************************** */
int main(int argc, char *argv[])
{
    QCoreApplication b(argc, argv);

        long steps;    // The number of steps to take in a single simulation.
        double *v,*w,*x,*y,*z;  // The variables used for the state of the system.

        /*
            Define the constants.

            These are the parameters that are used in the operator for the
            differential equations.
         */
        double a    	 = 0.1;
        double g    	 = 0.3;
        double gamma	 = 0.8;
        double r    	 = 1.0;
        double d    	 = 0.44;
    //	double tau		 = 0.5;
        double beta 	 = .5;
        double chi		 = r*gamma/(r+a)-gamma+a;					//Intermediate Step
        double xi		 = -(d*gamma/(r+a)+a);						//Intermediate Step
        double cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);		//Intermediate Step
        double coralSaddle		 = 1-cbar;									//Saddle point value for coral
        double macroSaddle		 = (r-r*coralSaddle-d)/(r+a);						//Saddle point value for macroalgae
        double gZero	 = ((d*a*r+d*d)*(gamma-a))/(r*r);
        double gOne		 = (gamma*(a+d))/(a+r);
        double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
        double tauZero	 = (1/omega)*acos(gZero/g);

        double dt;          // Set the initial time step
        long   numberDT;    // The current iteration for the number assocated with the value of dt.
        double final;       // The final time for each simulation.
        long   trials;      // The number of simulations to make.

        final=100;  // Set the final time.
        trials=400; // Set the number of trials to perform.

        // Set tau
        double tau = 0.5;

        // Sets the seed for the random numbers
        srand(time(NULL));

        // Create a CSV File
        std::ofstream fp;
                //String fileName = "trials-g" + std::toString(g) + "-tau" + std::toString(tau);
        fp.open("trials.csv",std::ios::out | std::ios::trunc);

        fp << "dt,beta,g,tau,trial,initMacro,initCoral,initTurf,macroalgae,coral,turf,lgMacro,lgCoral,lgTurf" << std::endl;

/*		for (g=0.1;g<=0.8;g=g+0.02)
            {
                //Redefine initial conditions and critical points for varying g
                cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);
                coralSaddle		 = 1-cbar;
                macroSaddle		 = (r-r*coralSaddle-d)/(r+a);
                omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
                tauZero	 = (1/omega)*acos(gZero/g);
                if (coralSaddle>0 && coralSaddle<1 && macroSaddle>0 && macroSaddle<1 && tauZero>0)
            for (double aleph=0;aleph<=5;aleph=aleph+1)
            {

                tau=.3*(1+aleph)*tauZero;
                dt=0.0001;
*/
            // The number of cells needed for the delay (changes with dt)
            int n;
            n=(int)(tau/BASE_DT+0.5);

            // Allocate the space for the state of the system
            x=(double *) calloc(4,sizeof(double));
            y=(double *) calloc(n,sizeof(double));		//macroalgae for multiplicative noise
            z=(double *) calloc(n,sizeof(double));		//coral for multiplicative noise
            v=(double *) calloc(n,sizeof(double));		//macroalgae for logistic noise
            w=(double *) calloc(n,sizeof(double));		//coral for logistic noise
            for(numberDT=1;numberDT<5;++numberDT)
                {
                    dt = BASE_DT*(double)numberDT;
                    //printf("%f\t%f\n",dt,fmod(tau,dt));
#ifdef SHOW_PROGRESS
                    std::cout << "dt = " << dt << std::endl;
#endif
                    if ((int)(10000.0*tau+.5)%(int)(dt*10000.0+.5)==0)
                    {
                        //index = tau/dt;
                        n=(int)(tau/dt+.5);
                        //printf("%i\n",n);
                        steps=(long)(final/dt);
                        for (double theta=0;theta<=M_PI/2;theta+=(M_PI*0.5)*0.05)
                        {
                            for (int k=0;k<trials;k++)
                            {
                                y[0]=0.06*cos(theta); //initial Macroalgae level
                                z[0]=0.06*sin(theta); //initial Coral level
                                v[0]=0.06*cos(theta);
                                w[0]=0.06*sin(theta);
                                for (int l=1;l<n;l++) //fills in "negative" times for both y and z
                                {
                                    y[l]=y[0];
                                    z[l]=z[0];
                                    v[l]=v[0];
                                    w[l]=w[0];
                                }
                                //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",y[0],z[0],1-y[0]-z[0],v[0],w[0],1-v[0]-w[0]);
                                linear(steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,&fp,k,macroSaddle,coralSaddle,v,w);
#ifdef SHOW_PROGRESS
                                if(k%20 == 0)
                                    std::cout << "  Simulation number " << k << std::endl;
#endif
                            }
                        }
                    }
            }

            free(x);
            free(y);
            free(z);
            free(v);
            free(w);
            //}
            //}

        fp.close();

#ifdef SHOW_PROGRESS
            std::cout << "all done" << std::endl;
#endif

        return b.exec();
}
<commit_msg>Added a debug message for the coral simulation<commit_after>#include <QCoreApplication>
#include <QtDebug>

#include <iostream>
#include <fstream>
//#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265359
#endif

#define SHOW_PROGRESS
#define BASE_DT 0.0001

double drand48()
{
    return((double)(rand())/((double)RAND_MAX));
}

void normalDistRand(double stdDev,double* randomNumbers)
    {
        /* Generate a random number in polar coordinates */
        double radius = sqrt(-2.0*log(drand48()));
        double angle = 2.0*M_PI*drand48();
        /* transform the number back into cartesian coordinates */
        randomNumbers[0] = stdDev*radius*sin(angle);
        randomNumbers[1] = stdDev*radius*cos(angle);
    }

double linear(long steps,
              double a,double gamma,double r,double d,double g,
              double *x,double *y,double *z, double dt,
              int n,
              double beta,double tau,
              std::ofstream *fp,
              int q,
              double h,double s,double *v,double *w)
    {
        long m=n-1;
        long p=0;
        double B[2];
        int calcRandom=0;
        for (long k=0;k<steps;k++)
        {
            if(calcRandom==0)
                normalDistRand(sqrt(dt),B); //noise in most recent time step

            //x[0]=y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt
            //x[0]=x[0]+beta*y[m]*(1-y[m])+0.5*beta*y[m]*(1-y[m])*beta*(1-2*y[m])*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Macroalgae
            x[0] = y[m]+(y[m]*(gamma-gamma*y[m]+(a-gamma)*z[m])-(g*y[p]/(1-z[p])))*dt;

            //Adds in the noise
            //x[0]=x[0]+beta*y[m]*B[calcRandom]+0.5*beta*y[m]*beta*(B[calcRandom]*B[calcRandom]-dt);
            x[0] += beta*y[m]*B[calcRandom]+0.5*beta*beta*y[m]*(B[calcRandom]*B[calcRandom]-dt);

            //Computes the deterministic component for Coral
            x[1] = z[m]+(z[m]*(r-d-(a+r)*y[m]-r*z[m]))*dt;

            x[2] =  v[m]+(v[m]*(gamma-gamma*v[m]+(a-gamma)*w[m])-(g*v[p]/(1-w[p])))*dt;
            x[2] += beta*v[m]*(1-v[m])*B[calcRandom]+0.5*beta*(1-2*v[m])*beta*v[m]*(1-v[m])*(B[calcRandom]*B[calcRandom]-dt);
            x[3] =  w[m]+(w[m]*(r-d-(a+r)*v[m]-r*w[m]))*dt;

            /****************************************************************
                Account for extinction and overgrowing!!
            ****************************************************************/
            for(int i=0;i<4;++i)
                {
                    if(x[i]<0.0)
                        x[i] = 0.0;
                    else if (x[i]>1.0)
                        x[i] = 1.0;
                }

            //Updates delay and cell index
            m=(m+1)%n;
            p=(p+1)%n;
            y[m]=x[0];
            z[m]=x[1];
            v[m]=x[2];
            w[m]=x[3];
            calcRandom = (calcRandom+1)%2; // update which random number to use.
            //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",x[0],x[1],1-x[0]-x[1],x[2],x[3],1-x[2]-x[3]);
        }

        //printf("%f\t%f\t%f\t%f\t%f\n",dt,beta,tau,x[0],x[1]);
        *fp << dt << ","
            << beta << ","
            << g << ","
            << tau << ","
            << q+1 << ","
            << h << ","
            << s << ","
            << 1-h-s << ","
            << x[0] << ","
            << x[1] << ","
            << 1-x[0]-x[1] << ","
            << x[2] << ","
            << x[3] << ","
            << 1-x[2]-x[3]
            << std::endl;

        qDebug() << dt << ","
            << beta << ","
            << g << ","
            << tau << ","
            << q+1 << ","
            << h << ","
            << s << ","
            << 1-h-s << ","
            << x[0] << ","
            << x[1] << ","
            << 1-x[0]-x[1] << ","
            << x[2] << ","
            << x[3] << ","
            << 1-x[2]-x[3];
        return 0;
    }

/* ****************************************************************
     main

     The main function. Called at the start of the program.
**************************************************************** */
int main(int argc, char *argv[])
{
    QCoreApplication b(argc, argv);

        long steps;    // The number of steps to take in a single simulation.
        double *v,*w,*x,*y,*z;  // The variables used for the state of the system.

        /*
            Define the constants.

            These are the parameters that are used in the operator for the
            differential equations.
         */
        double a    	 = 0.1;
        double g    	 = 0.3;
        double gamma	 = 0.8;
        double r    	 = 1.0;
        double d    	 = 0.44;
    //	double tau		 = 0.5;
        double beta 	 = .5;
        double chi		 = r*gamma/(r+a)-gamma+a;					//Intermediate Step
        double xi		 = -(d*gamma/(r+a)+a);						//Intermediate Step
        double cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);		//Intermediate Step
        double coralSaddle		 = 1-cbar;									//Saddle point value for coral
        double macroSaddle		 = (r-r*coralSaddle-d)/(r+a);						//Saddle point value for macroalgae
        double gZero	 = ((d*a*r+d*d)*(gamma-a))/(r*r);
        double gOne		 = (gamma*(a+d))/(a+r);
        double omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
        double tauZero	 = (1/omega)*acos(gZero/g);

        double dt;          // Set the initial time step
        long   numberDT;    // The current iteration for the number assocated with the value of dt.
        double final;       // The final time for each simulation.
        long   trials;      // The number of simulations to make.

        final=100;  // Set the final time.
        trials=400; // Set the number of trials to perform.

        // Set tau
        double tau = 0.5;

        // Sets the seed for the random numbers
        srand(time(NULL));

        // Create a CSV File
        std::ofstream fp;
                //String fileName = "trials-g" + std::toString(g) + "-tau" + std::toString(tau);
        fp.open("trials.csv",std::ios::out | std::ios::trunc);

        fp << "dt,beta,g,tau,trial,initMacro,initCoral,initTurf,macroalgae,coral,turf,lgMacro,lgCoral,lgTurf" << std::endl;

/*		for (g=0.1;g<=0.8;g=g+0.02)
            {
                //Redefine initial conditions and critical points for varying g
                cbar		 = (-xi-sqrt(xi*xi-4*chi*g))/(2*chi);
                coralSaddle		 = 1-cbar;
                macroSaddle		 = (r-r*coralSaddle-d)/(r+a);
                omega	 = sqrt((r*r*(g*g-gZero*gZero))/(d*d));
                tauZero	 = (1/omega)*acos(gZero/g);
                if (coralSaddle>0 && coralSaddle<1 && macroSaddle>0 && macroSaddle<1 && tauZero>0)
            for (double aleph=0;aleph<=5;aleph=aleph+1)
            {

                tau=.3*(1+aleph)*tauZero;
                dt=0.0001;
*/
            // The number of cells needed for the delay (changes with dt)
            int n;
            n=(int)(tau/BASE_DT+0.5);

            // Allocate the space for the state of the system
            x=(double *) calloc(4,sizeof(double));
            y=(double *) calloc(n,sizeof(double));		//macroalgae for multiplicative noise
            z=(double *) calloc(n,sizeof(double));		//coral for multiplicative noise
            v=(double *) calloc(n,sizeof(double));		//macroalgae for logistic noise
            w=(double *) calloc(n,sizeof(double));		//coral for logistic noise
            for(numberDT=1;numberDT<5;++numberDT)
                {
                    dt = BASE_DT*(double)numberDT;
                    //printf("%f\t%f\n",dt,fmod(tau,dt));
#ifdef SHOW_PROGRESS
                    std::cout << "dt = " << dt << std::endl;
#endif
                    if ((int)(10000.0*tau+.5)%(int)(dt*10000.0+.5)==0)
                    {
                        //index = tau/dt;
                        n=(int)(tau/dt+.5);
                        //printf("%i\n",n);
                        steps=(long)(final/dt);
                        for (double theta=0;theta<=M_PI/2;theta+=(M_PI*0.5)*0.05)
                        {
                            for (int k=0;k<trials;k++)
                            {
                                y[0]=0.06*cos(theta); //initial Macroalgae level
                                z[0]=0.06*sin(theta); //initial Coral level
                                v[0]=0.06*cos(theta);
                                w[0]=0.06*sin(theta);
                                for (int l=1;l<n;l++) //fills in "negative" times for both y and z
                                {
                                    y[l]=y[0];
                                    z[l]=z[0];
                                    v[l]=v[0];
                                    w[l]=w[0];
                                }
                                //fprintf(fp,"%f,%f,%f,%f,%f,%f\n",y[0],z[0],1-y[0]-z[0],v[0],w[0],1-v[0]-w[0]);
                                linear(steps,a,gamma,r,d,g,x,y,z,dt,n,beta,tau,&fp,k,macroSaddle,coralSaddle,v,w);
#ifdef SHOW_PROGRESS
                                if(k%20 == 0)
                                    std::cout << "  Simulation number " << k << std::endl;
#endif
                            }
                        }
                    }
            }

            free(x);
            free(y);
            free(z);
            free(v);
            free(w);
            //}
            //}

        fp.close();

#ifdef SHOW_PROGRESS
            std::cout << "all done" << std::endl;
#endif

        return b.exec();
}
<|endoftext|>


<commit_before>/* -*-c++-*- Copyright (C) 2008 Miguel Escriva Gregori
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <iostream>
#include <sstream>
#include <osg/Image>
#include <osg/Notify>

#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ImageOptions>

extern "C" {
        #include <librsvg/rsvg.h>
        #include <librsvg/rsvg-cairo.h>
}

class ReaderWriterSVG : public osgDB::ReaderWriter
{
    public:

        ReaderWriterSVG()
        {
                supportsExtension("svg","Scalar Vector Graphics format");
                rsvg_init();
        }

        virtual const char* className() const { return "SVG Image Reader"; }

        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
                return readImage(file, options);
        }

        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
                std::string ext = osgDB::getLowerCaseFileExtension(file);
                if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

                std::string fileName = osgDB::findDataFile( file, options );
                if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

                RsvgDimensionData dimensionData;
                RsvgHandle* handle = rsvg_handle_new_from_file (fileName.c_str(), NULL);
                rsvg_handle_get_dimensions( handle, &dimensionData);

                osg::Image *image;
                if (options)
                {
                        unsigned int w=0, h=0;
                        std::string op = options->getOptionString();
                        size_t i = op.find("x");

                        std::stringstream ss1(op.substr(0, i));
                        std::stringstream ss2(op.substr(i+1, op.size()));
                        ss1 >> w;
                        ss2 >> h;
                        if (w==0 || h==0){
                                image = createImage(handle, dimensionData.width, dimensionData.height);
                        }
                        else{
                                image = createImage(handle, w, h);
                        }
                }
                else{
                        image = createImage(handle, dimensionData.width, dimensionData.height);
                }
                rsvg_handle_free(handle);
                image->setFileName(file);
                return image;
        }

        osg::Image* createImage(RsvgHandle *handle, unsigned int width, unsigned int height) const
        {
                RsvgDimensionData dimensionData;
                rsvg_handle_get_dimensions( handle, &dimensionData);
                // If image resollution < 128, cairo produces some artifacts.
                // I don't know why, but we check the size...
                if (width < 128) width = 128;
                if (height < 128) height = 128;
                width = osg::Image::computeNearestPowerOfTwo(width);
                height = osg::Image::computeNearestPowerOfTwo(height);
                osg::Image *image = new osg::Image();
                image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
                image->setPixelFormat(GL_BGRA);

                cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(image->data(),
                                        CAIRO_FORMAT_ARGB32, width, height, image->getRowSizeInBytes());
                cairo_t *cr = cairo_create(cairo_surface);
                cairo_scale(cr,((float)width)/dimensionData.width, ((float)height)/dimensionData.height);
                rsvg_handle_render_cairo(handle, cr);

                cairo_destroy(cr);
                cairo_surface_destroy(cairo_surface);

                image->flipVertical();
                return image;
        }
    protected:
        virtual ~ReaderWriterSVG()
        {
                rsvg_term();
        }
};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(SVG, ReaderWriterSVG)
<commit_msg>Fixed warnings<commit_after>/* -*-c++-*- Copyright (C) 2008 Miguel Escriva Gregori
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <iostream>
#include <sstream>
#include <osg/Image>
#include <osg/Notify>

#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ImageOptions>

extern "C" {
        #include <librsvg/rsvg.h>
}

class ReaderWriterSVG : public osgDB::ReaderWriter
{
    public:

        ReaderWriterSVG()
        {
                supportsExtension("svg","Scalar Vector Graphics format");
        }

        virtual const char* className() const { return "SVG Image Reader"; }

        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
                return readImage(file, options);
        }

        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
                std::string ext = osgDB::getLowerCaseFileExtension(file);
                if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

                std::string fileName = osgDB::findDataFile( file, options );
                if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

                RsvgDimensionData dimensionData;
                RsvgHandle* handle = rsvg_handle_new_from_file (fileName.c_str(), NULL);
                rsvg_handle_get_dimensions( handle, &dimensionData);

                osg::Image *image;
                if (options)
                {
                        unsigned int w=0, h=0;
                        std::string op = options->getOptionString();
                        size_t i = op.find("x");

                        std::stringstream ss1(op.substr(0, i));
                        std::stringstream ss2(op.substr(i+1, op.size()));
                        ss1 >> w;
                        ss2 >> h;
                        if (w==0 || h==0){
                                image = createImage(handle, dimensionData.width, dimensionData.height);
                        }
                        else{
                                image = createImage(handle, w, h);
                        }
                }
                else{
                        image = createImage(handle, dimensionData.width, dimensionData.height);
                }
                g_object_unref(handle);
                image->setFileName(file);
                return image;
        }

        osg::Image* createImage(RsvgHandle *handle, unsigned int width, unsigned int height) const
        {
                RsvgDimensionData dimensionData;
                rsvg_handle_get_dimensions( handle, &dimensionData);
                // If image resollution < 128, cairo produces some artifacts.
                // I don't know why, but we check the size...
                if (width < 128) width = 128;
                if (height < 128) height = 128;
                width = osg::Image::computeNearestPowerOfTwo(width);
                height = osg::Image::computeNearestPowerOfTwo(height);
                osg::Image *image = new osg::Image();
                image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
                image->setPixelFormat(GL_BGRA);

                cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(image->data(),
                                        CAIRO_FORMAT_ARGB32, width, height, image->getRowSizeInBytes());
                cairo_t *cr = cairo_create(cairo_surface);
                cairo_scale(cr,((float)width)/dimensionData.width, ((float)height)/dimensionData.height);
                rsvg_handle_render_cairo(handle, cr);

                cairo_destroy(cr);
                cairo_surface_destroy(cairo_surface);

                image->flipVertical();
                return image;
        }
    protected:
        virtual ~ReaderWriterSVG()
        {
                rsvg_cleanup();
        }
};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(SVG, ReaderWriterSVG)
<|endoftext|>


<commit_before>// Released under the OSGPL license, as part of the OpenSceneGraph distribution.
//
// specification : http://www.trackvis.org/docs/?subsect=fileformat
//
#include <osg/Geode>
#include <osg/io_utils>

#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>

struct TrkHeader
{
    char                id_string[6];
    short               dim[3];
    float               voxel_size[3];
    float               origin[3];
    short               n_scalars;
    char                scalar_name[10][20];
    short               n_properties;
    char                property_name[10][20];
    float               vox_to_ras[4][4];
    char                reserved[444];
    char                voxel_order[4];
    char                pad2[4];
    float               image_orientation_patient[6];
    char                pad1[2];
    unsigned char       invert_x;
    unsigned char       invert_y;
    unsigned char       invert_z;
    unsigned char       swap_xy;
    unsigned char       swap_yz;
    unsigned char       swap_zx;
    int                 n_count;
    int                 version;
    int                 hdr_size;
};

class ReaderWriterTRK : public osgDB::ReaderWriter
{
    public:

        ReaderWriterTRK()
        {
            supportsExtension("trk","Track file format");

            OSG_NOTICE<<"sizeof(TrkHeader)="<<sizeof(TrkHeader)<<std::endl;
        }

        virtual const char* className() const { return "Track Reader/Writer"; }

        virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const
        {
            return readNode(fin, options);
        }

        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
        {
            return readNode(file, options);
        }

        virtual ReadResult readNode(std::istream& fin,const osgDB::ReaderWriter::Options* =NULL) const
        {
            TrkHeader header;
            fin.read(reinterpret_cast<char*>(&header), sizeof(TrkHeader));

            if (fin.fail()) return ReadResult::ERROR_IN_READING_FILE;

            OSG_NOTICE<<"Read header successfuly ["<<header.id_string<<"]"<<std::endl;
            bool requiresByteSwap = header.hdr_size!=1000;
            if (requiresByteSwap)
            {
                OSG_NOTICE<<"Requires byteswap, but not implemented yet."<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }
            else
            {
                OSG_NOTICE<<"No byteswap required"<<std::endl;
            }

            OSG_NOTICE<<"version = "<<header.version<<std::endl;
            OSG_NOTICE<<"dim = "<<header.dim[0]<<", "<<header.dim[1]<<", "<<header.dim[2]<<std::endl;
            OSG_NOTICE<<"voxel_size = "<<header.voxel_size[0]<<", "<<header.voxel_size[1]<<", "<<header.voxel_size[2]<<std::endl;
            OSG_NOTICE<<"origin = "<<header.origin[0]<<", "<<header.origin[1]<<", "<<header.origin[2]<<std::endl;
            OSG_NOTICE<<"n_scalars = "<<header.n_scalars<<std::endl;
            OSG_NOTICE<<"n_properties = "<<header.n_properties<<std::endl;

            osg::Matrixf matrix(reinterpret_cast<const float*>(header.vox_to_ras));
            OSG_NOTICE<<"vox_to_ras="<<matrix<<std::endl;

            OSG_NOTICE<<"invert_x="<<static_cast<int>(header.invert_x)<<std::endl;
            OSG_NOTICE<<"invert_y="<<static_cast<int>(header.invert_y)<<std::endl;
            OSG_NOTICE<<"invert_z="<<static_cast<int>(header.invert_z)<<std::endl;
            OSG_NOTICE<<"swap_xy="<<static_cast<int>(header.swap_xy)<<std::endl;
            OSG_NOTICE<<"swap_yz="<<static_cast<int>(header.swap_yz)<<std::endl;
            OSG_NOTICE<<"swap_zx="<<static_cast<int>(header.swap_zx)<<std::endl;
            OSG_NOTICE<<"n_count="<<header.n_count<<std::endl;
            OSG_NOTICE<<"hdr_size="<<header.hdr_size<<std::endl;

            if (header.n_count==0)
            {
                OSG_NOTICE<<"No tracks stored."<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }

            int n_s = header.n_scalars;
            int n_p = header.n_properties;

            osg::ref_ptr<osg::Geode> geode = new osg::Geode;

            osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
            geode->addDrawable(geometry.get());

            osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
            stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
            geometry->setStateSet(stateset.get());

            osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
            geometry->setColorArray(colours.get());
            geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
            colours->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

            osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
            geometry->setVertexArray(vertices.get());

            osg::ref_ptr<osg::DrawElementsUInt> lines = new osg::DrawElementsUInt(GL_LINES);
            geometry->addPrimitiveSet(lines.get());

            for(int i=0; i<header.n_count; ++i)
            {
                // read track
                // OSG_NOTICE<<"reading track #"<<i<<std::endl;

                int n_points=0;
                fin.read(reinterpret_cast<char*>(&n_points),4);
                if (fin.fail()) break;

                // OSG_NOTICE<<"  n_points="<<n_points<<std::endl;

                int n_floats_per_vertex = (3+n_s);
                int n_point_floats = n_floats_per_vertex*n_points;
                float* point_data = new float[n_point_floats];
                fin.read(reinterpret_cast<char*>(point_data), n_point_floats*4);
                if (fin.fail()) break;

                if (n_p!=0)
                {
                    float* property_data = new float[n_p];
                    fin.read(reinterpret_cast<char*>(&property_data), n_p*4);
                    if (fin.fail()) break;

                    delete [] property_data;

                }

                if (n_points>0)
                {
                    // record the index of the first vertex of the new track
                    int vi = vertices->size();

                    // add the vertices of the track
                    for(int pi=0; pi<n_points; ++pi)
                    {
                        float* vptr = &point_data[pi*n_floats_per_vertex];
                        vertices->push_back(osg::Vec3(vptr[0],vptr[1],vptr[2]));
                    }

                    // add the line segmenets for track
                    for(int pi=0; pi<n_points-1; ++pi, ++vi)
                    {
                        lines->push_back(vi);
                        lines->push_back(vi+1);
                    }
                }

                delete [] point_data;
            }

            if (fin.fail())
            {
                OSG_NOTICE<<"Error on reading track file."<<std::endl;
                return ReadResult::ERROR_IN_READING_FILE;
            }

            return geode.release();
        }

        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            osgDB::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
            if(!fin) return ReadResult::FILE_NOT_HANDLED;

            return readNode(fin, options);
        }
};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(trk, ReaderWriterTRK)
<commit_msg>Added colouring and lighting of track using shader<commit_after>// Released under the OSGPL license, as part of the OpenSceneGraph distribution.
//
// specification : http://www.trackvis.org/docs/?subsect=fileformat
//
#include <osg/Geode>
#include <osg/io_utils>

#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/Registry>

struct TrkHeader
{
    char                id_string[6];
    short               dim[3];
    float               voxel_size[3];
    float               origin[3];
    short               n_scalars;
    char                scalar_name[10][20];
    short               n_properties;
    char                property_name[10][20];
    float               vox_to_ras[4][4];
    char                reserved[444];
    char                voxel_order[4];
    char                pad2[4];
    float               image_orientation_patient[6];
    char                pad1[2];
    unsigned char       invert_x;
    unsigned char       invert_y;
    unsigned char       invert_z;
    unsigned char       swap_xy;
    unsigned char       swap_yz;
    unsigned char       swap_zx;
    int                 n_count;
    int                 version;
    int                 hdr_size;
};

const char vert_shader_str[] =
"void main(void)\n"
"{\n"
"    vec4 eye = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);\n"
"    vec3 rayVector = normalize(gl_Vertex.xyz-eye.xyz);\n"
"\n"
"    vec3 dv = gl_Normal;\n"
"    float d = dot(rayVector, dv);\n"
"    float d2 = abs(d);//*d;\n"
"    const float base=1.5;\n"
"    float l = (base-d2)/base;\n"
"    float half_l = l*0.5;\n"
"\n"
"    gl_FrontColor = vec4( (dv.x+1.0)*half_l, (dv.y+1.0)*half_l, (dv.z+1.0)*half_l, 1.0);\n"
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
"}\n";

struct AssignDirectionColour
{
    AssignDirectionColour() {}

    void assign(osg::Geometry* geometry)
    {
        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
        if (!vertices) return;

        // allocate colours
        osg::ref_ptr<osg::Vec4Array> colours = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());
        if (!colours)
        {
            colours = new osg::Vec4Array;
            geometry->setColorArray(colours);
        }
        geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
        colours->resize(vertices->size(), osg::Vec4(0.0,0.0,0.0,0.0));
#if 1
        // allocate normals
        osg::ref_ptr<osg::Vec3Array> normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
        if (!normals)
        {
            normals = new osg::Vec3Array;
            geometry->setNormalArray(normals);
        }
        geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
        normals->resize(vertices->size(), osg::Vec3(0.0,0.0,0.0));
#endif

        typedef std::vector<float> Divisors;
        Divisors divisors;
        divisors.resize(vertices->size(), 0.0f);

        for(unsigned int i=0; i<geometry->getNumPrimitiveSets(); ++i)
        {
            osg::PrimitiveSet* pset = geometry->getPrimitiveSet(i);
            if (pset->getMode()==GL_LINES)
            {
                for(unsigned int pi=0; pi<pset->getNumIndices()-1; pi+=2)
                {
                    unsigned int vi_0 = pset->index(pi);
                    unsigned int vi_1 = pset->index(pi+1);
                    osg::Vec3& v0 = (*vertices)[vi_0];
                    osg::Vec3& v1 = (*vertices)[vi_1];

                    osg::Vec3 dv(v1-v0);
                    dv.normalize();

                    // assign colours
                    osg::Vec4& c0 = (*colours)[vi_0];
                    osg::Vec4& c1 = (*colours)[vi_1];

                    osg::Vec4 colour( (dv.x()+1.0f/2.0f), (dv.y()+1.0f/2.0f), (dv.z()+1.0f/2.0f), 1.0f );

                    if (divisors[vi_0]==0.0f) c0 = colour;
                    else c0 += colour;

                    if (divisors[vi_1]==0.0f) c1 = colour;
                    else c1 += colour;

                    // assign normals
                    osg::Vec3& n0 = (*normals)[vi_0];
                    osg::Vec3& n1 = (*normals)[vi_1];

#if 1
                    if (divisors[vi_0]==0.0f) n0 = dv;
                    else n0 += dv;

                    if (divisors[vi_1]==0.0f) n1 = dv;
                    else n1 += dv;
#else
                    float len_xy = sqrtf(dv.x()*dv.x() + dv.y()*dv.y());
                    osg::Vec3 normal(0.0f, 0.0f, 0.0f);
                    if (len_xy!=0.0)
                    {
                        normal.set((-dv.x()/len_xy)*dv.z(), (-dv.y()/len_xy)*dv.z(), len_xy);
                    }
                    else
                    {
                        normal.set(1.0f, 0.0f, 0.0f);
                    }

                    if (divisors[vi_0]==0.0f) n0 = normal;
                    else n0 += normal;

                    if (divisors[vi_1]==0.0f) n1 = normal;
                    else n1 += normal;
#endif

                    divisors[vi_0] += 1.0f;
                    divisors[vi_1] += 1.0f;
                }
            }
        }

        for(unsigned int vi=0; vi<vertices->size(); ++vi)
        {
            if (divisors[vi]>0.0f)
            {
                (*colours)[vi] /= divisors[vi];
                (*normals)[vi].normalize();

            }
        }

        std::string vertexShaderFile("track.vert");

        osg::ref_ptr<osg::StateSet> stateset = geometry->getOrCreateStateSet();
        osg::ref_ptr<osg::Program> program = new osg::Program;

        osg::ref_ptr<osg::Shader> vertexShader = osgDB::readShaderFile(osg::Shader::VERTEX, vertexShaderFile);
        if (!vertexShader)
        {
            vertexShader = new osg::Shader(osg::Shader::VERTEX, vert_shader_str);
        }

        program->addShader(vertexShader);

        stateset->setAttribute(program.get());
    }
};

class ReaderWriterTRK : public osgDB::ReaderWriter
{
    public:

        ReaderWriterTRK()
        {
            supportsExtension("trk","Track file format");

            OSG_NOTICE<<"sizeof(TrkHeader)="<<sizeof(TrkHeader)<<std::endl;
        }

        virtual const char* className() const { return "Track Reader/Writer"; }

        virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const
        {
            return readNode(fin, options);
        }

        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
        {
            return readNode(file, options);
        }

        virtual ReadResult readNode(std::istream& fin,const osgDB::ReaderWriter::Options* =NULL) const
        {
            TrkHeader header;
            fin.read(reinterpret_cast<char*>(&header), sizeof(TrkHeader));

            if (fin.fail()) return ReadResult::ERROR_IN_READING_FILE;

            OSG_NOTICE<<"Read header successfuly ["<<header.id_string<<"]"<<std::endl;
            bool requiresByteSwap = header.hdr_size!=1000;
            if (requiresByteSwap)
            {
                OSG_NOTICE<<"Requires byteswap, but not implemented yet."<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }
            else
            {
                OSG_NOTICE<<"No byteswap required"<<std::endl;
            }

            OSG_NOTICE<<"version = "<<header.version<<std::endl;
            OSG_NOTICE<<"dim = "<<header.dim[0]<<", "<<header.dim[1]<<", "<<header.dim[2]<<std::endl;
            OSG_NOTICE<<"voxel_size = "<<header.voxel_size[0]<<", "<<header.voxel_size[1]<<", "<<header.voxel_size[2]<<std::endl;
            OSG_NOTICE<<"origin = "<<header.origin[0]<<", "<<header.origin[1]<<", "<<header.origin[2]<<std::endl;
            OSG_NOTICE<<"n_scalars = "<<header.n_scalars<<std::endl;
            OSG_NOTICE<<"n_properties = "<<header.n_properties<<std::endl;

            osg::Matrixf matrix(reinterpret_cast<const float*>(header.vox_to_ras));
            OSG_NOTICE<<"vox_to_ras="<<matrix<<std::endl;

            OSG_NOTICE<<"invert_x="<<static_cast<int>(header.invert_x)<<std::endl;
            OSG_NOTICE<<"invert_y="<<static_cast<int>(header.invert_y)<<std::endl;
            OSG_NOTICE<<"invert_z="<<static_cast<int>(header.invert_z)<<std::endl;
            OSG_NOTICE<<"swap_xy="<<static_cast<int>(header.swap_xy)<<std::endl;
            OSG_NOTICE<<"swap_yz="<<static_cast<int>(header.swap_yz)<<std::endl;
            OSG_NOTICE<<"swap_zx="<<static_cast<int>(header.swap_zx)<<std::endl;
            OSG_NOTICE<<"n_count="<<header.n_count<<std::endl;
            OSG_NOTICE<<"hdr_size="<<header.hdr_size<<std::endl;

            if (header.n_count==0)
            {
                OSG_NOTICE<<"No tracks stored."<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }

            int n_s = header.n_scalars;
            int n_p = header.n_properties;

            osg::ref_ptr<osg::Geode> geode = new osg::Geode;

            osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
            geode->addDrawable(geometry.get());
#if 0
            osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
            stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
            geometry->setStateSet(stateset.get());
#endif
            osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
            geometry->setColorArray(colours.get());
            geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
            colours->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

            osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
            geometry->setVertexArray(vertices.get());

            osg::ref_ptr<osg::DrawElementsUInt> lines = new osg::DrawElementsUInt(GL_LINES);
            geometry->addPrimitiveSet(lines.get());

            for(int i=0; i<header.n_count; ++i)
            {
                // read track
                // OSG_NOTICE<<"reading track #"<<i<<std::endl;

                int n_points=0;
                fin.read(reinterpret_cast<char*>(&n_points),4);
                if (fin.fail()) break;

                // OSG_NOTICE<<"  n_points="<<n_points<<std::endl;

                int n_floats_per_vertex = (3+n_s);
                int n_point_floats = n_floats_per_vertex*n_points;
                float* point_data = new float[n_point_floats];
                fin.read(reinterpret_cast<char*>(point_data), n_point_floats*4);
                if (fin.fail()) break;

                if (n_p!=0)
                {
                    float* property_data = new float[n_p];
                    fin.read(reinterpret_cast<char*>(&property_data), n_p*4);
                    if (fin.fail()) break;

                    delete [] property_data;

                }

                if (n_points>0)
                {
                    // record the index of the first vertex of the new track
                    int vi = vertices->size();

                    // add the vertices of the track
                    for(int pi=0; pi<n_points; ++pi)
                    {
                        float* vptr = &point_data[pi*n_floats_per_vertex];
                        vertices->push_back(osg::Vec3(vptr[0],vptr[1],vptr[2]));
                    }

                    // add the line segmenets for track
                    for(int pi=0; pi<n_points-1; ++pi, ++vi)
                    {
                        lines->push_back(vi);
                        lines->push_back(vi+1);
                    }
                }

                delete [] point_data;
            }

            if (fin.fail())
            {
                OSG_NOTICE<<"Error on reading track file."<<std::endl;
                return ReadResult::ERROR_IN_READING_FILE;
            }

            AssignDirectionColour colourer;
            colourer.assign(geometry.get());

            return geode.release();
        }

        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            osgDB::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
            if(!fin) return ReadResult::FILE_NOT_HANDLED;

            return readNode(fin, options);
        }
};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(trk, ReaderWriterTRK)
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "welcomemode.h"
#include "coreconstants.h"
#include "uniqueidmanager.h"
#include "modemanager.h"

#if !defined(QT_NO_WEBKIT)
#include <QtWebKit/QWebView>
#include <QtGui/QApplication>
#include <QtCore/QFileInfo>
#else
#include <QtGui/QLabel>
#endif
#include <QtGui/QToolBar>
#include <QtGui/QDesktopServices>

#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QtCore/QDebug>
#include <QtCore/QUrl>

namespace Core {
namespace Internal {

static QString readFile(const QString &name)
{
    QFile f(name);
    if (!f.open(QIODevice::ReadOnly)) {
        qWarning("Unable to open %s: %s", name.toUtf8().constData(), f.errorString().toUtf8().constData());
        return QString();
    }
    QTextStream ts(&f);
    return ts.readAll();
}

struct WelcomeModePrivate
{
    WelcomeModePrivate();

    QWidget *m_widget;
#if !defined(QT_NO_WEBKIT)
    QWebView *m_webview;
#else
    QLabel *m_label;
#endif

    WelcomeMode::WelcomePageData lastData;

    const QString m_htmlTemplate;
    const QString m_sessionHtmlTemplate;
    const QString m_projectHtmlTemplate;
    const QUrl m_baseUrl;
};

WelcomeModePrivate::WelcomeModePrivate() :
    m_widget(new QWidget),
#if !defined(QT_NO_WEBKIT)
    m_webview(new QWebView),
#else
    m_label(new QLabel),
#endif
    m_htmlTemplate(readFile(QLatin1String(":/core/html/welcome.html"))),
    m_sessionHtmlTemplate(readFile(QLatin1String(":/core/html/recent_sessions.html"))),
    m_projectHtmlTemplate(readFile(QLatin1String(":/core/html/recent_projects.html"))),
    m_baseUrl(QUrl(QLatin1String("qrc:/core/html/welcome.html")))
{
#if !defined(QT_NO_WEBKIT)
    m_webview->setContextMenuPolicy(Qt::NoContextMenu);
#endif
}

#if defined(QT_NO_WEBKIT)

const char *LABEL = "

	"
                    "

Welcome

 Qt Creator is an intuitive, modern cross platform IDE that enables "
                    "developers to create graphically appealing applications for desktop, "
                    "embedded, and mobile devices. "
                    "
(This startup page lacks features due to disabled webkit support)"
                    "

";

#endif
// ---  WelcomePageData

bool WelcomeMode::WelcomePageData::operator==(const WelcomePageData &rhs) const
{
    return previousSession == rhs.previousSession
        && activeSession   == rhs.activeSession
        && sessionList     == rhs.sessionList
        && projectList     == rhs.projectList;
}

bool WelcomeMode::WelcomePageData::operator!=(const WelcomePageData &rhs) const
{
    return previousSession != rhs.previousSession
        || activeSession   != rhs.activeSession
        || sessionList     != rhs.sessionList
        || projectList     != rhs.projectList;
}

QDebug operator<<(QDebug dgb, const WelcomeMode::WelcomePageData &d)
{
    dgb.nospace() << "PreviousSession=" << d.previousSession
        << " activeSession=" << d.activeSession
        << " sessionList=" << d.sessionList
        << " projectList=" << d.projectList;
    return dgb;
}

// ---  WelcomeMode
WelcomeMode::WelcomeMode() :
    m_d(new WelcomeModePrivate)
{
    QVBoxLayout *l = new QVBoxLayout(m_d->m_widget);
    l->setMargin(0);
    l->setSpacing(0);
    l->addWidget(new QToolBar(m_d->m_widget));
#if !defined(QT_NO_WEBKIT)
    connect(m_d->m_webview, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl)));

    WelcomePageData welcomePageData;
    updateWelcomePage(welcomePageData);

    l->addWidget(m_d->m_webview);
    m_d->m_webview->setAcceptDrops(false);
    m_d->m_webview->settings()->setAttribute(QWebSettings::PluginsEnabled, false);
    m_d->m_webview->settings()->setAttribute(QWebSettings::JavaEnabled, false);

#else
    m_d->m_label->setWordWrap(true);
    m_d->m_label->setAlignment(Qt::AlignCenter);
    m_d->m_label->setText(LABEL);
    l->addWidget(m_d->m_label);
#endif
}

WelcomeMode::~WelcomeMode()
{
    delete m_d;
}

QString WelcomeMode::name() const
{
    return QLatin1String("Welcome");
}

QIcon WelcomeMode::icon() const
{
    return QIcon(QLatin1String(":/core/images/qtcreator_logo_32.png"));
}

int WelcomeMode::priority() const
{
    return Constants::P_MODE_WELCOME;
}

QWidget* WelcomeMode::widget()
{
    return m_d->m_widget;
}

const char* WelcomeMode::uniqueModeName() const
{
    return Constants::MODE_WELCOME;
}

QList<int> WelcomeMode::context() const
{
    static QList<int> contexts = QList<int>()
                                 << UniqueIDManager::instance()->uniqueIdentifier(Constants::C_WELCOME_MODE);
    return contexts;
}

void WelcomeMode::updateWelcomePage(const WelcomePageData &welcomePageData)
{
// should really only modify the DOM tree

#if defined(QT_NO_WEBKIT)
    Q_UNUSED(welcomePageData);
#else

    // Update only if data are modified
    if (welcomePageData == m_d->lastData)
        return;
    m_d->lastData = welcomePageData;

    QString html = m_d->m_htmlTemplate;

    if (!welcomePageData.previousSession.isEmpty() || !welcomePageData.projectList.isEmpty()) {
        QString sessionHtml = m_d->m_sessionHtmlTemplate;
        sessionHtml.replace(QLatin1String("LAST_SESSION"), welcomePageData.previousSession);

        if (welcomePageData.sessionList.count() > 1) {
            QString sessions;
            foreach (QString s, welcomePageData.sessionList) {
                QString last;
                if (s == welcomePageData.previousSession)
                    last = tr(" (last session)");
                sessions += QString::fromLatin1("

%2%3

").arg(s, s, last);
            }
            sessionHtml.replace(QLatin1String(""), sessions);
        }
        html.replace(QLatin1String(""), sessionHtml);

        QString projectHtml = m_d->m_projectHtmlTemplate;
        {
            QString projects;
            QTextStream str(&projects);

            QList<QPair<QString, QString> >::const_iterator it, end;
            end = welcomePageData.projectList.constEnd();
            for( it = welcomePageData.projectList.constBegin(); it != end; ++it) {
                const QFileInfo fi((*it).first);
                str << "

<a href=\"gh-project:" << (*it).first << "\" title=\""
                    << fi.absolutePath() << "\">" << (*it).second << "

\n";
            }
            projectHtml.replace(QLatin1String(""), projects);
        }
        html.replace(QLatin1String(""), projectHtml);
    }

    m_d->m_webview->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
    m_d->m_webview->setHtml(html, m_d->m_baseUrl);
#endif
}

void WelcomeMode::linkClicked(const QUrl &url)
{
    QString scheme = url.scheme();
    Core::ModeManager *modeManager = ModeManager::instance();
    if (scheme.startsWith(QLatin1String("gh"))) {
        QString s = url.toString(QUrl::RemoveScheme);
        if (scheme == QLatin1String("gh")) {
            emit requestHelp(s);
        } else if (scheme == QLatin1String("gh-project")) {
            emit requestProject(s);
            if (modeManager->currentMode() == this)
                modeManager->activateMode(Core::Constants::MODE_EDIT);
        } else if (scheme == QLatin1String("gh-session")) {
            emit requestSession(s);
            if (modeManager->currentMode() == this)
                modeManager->activateMode(Core::Constants::MODE_EDIT);
        }
    } else {
        QDesktopServices::openUrl(url);
    }
}

} // namespace Internal
} // namespace Core
<commit_msg>Don't annoy Windows users with alien dir separators<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "welcomemode.h"
#include "coreconstants.h"
#include "uniqueidmanager.h"
#include "modemanager.h"

#if !defined(QT_NO_WEBKIT)
#include <QtWebKit/QWebView>
#include <QtGui/QApplication>
#include <QtCore/QFileInfo>
#else
#include <QtGui/QLabel>
#endif
#include <QtGui/QToolBar>
#include <QtGui/QDesktopServices>

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QtCore/QDebug>
#include <QtCore/QUrl>

namespace Core {
namespace Internal {

static QString readFile(const QString &name)
{
    QFile f(name);
    if (!f.open(QIODevice::ReadOnly)) {
        qWarning("Unable to open %s: %s", name.toUtf8().constData(), f.errorString().toUtf8().constData());
        return QString();
    }
    QTextStream ts(&f);
    return ts.readAll();
}

struct WelcomeModePrivate
{
    WelcomeModePrivate();

    QWidget *m_widget;
#if !defined(QT_NO_WEBKIT)
    QWebView *m_webview;
#else
    QLabel *m_label;
#endif

    WelcomeMode::WelcomePageData lastData;

    const QString m_htmlTemplate;
    const QString m_sessionHtmlTemplate;
    const QString m_projectHtmlTemplate;
    const QUrl m_baseUrl;
};

WelcomeModePrivate::WelcomeModePrivate() :
    m_widget(new QWidget),
#if !defined(QT_NO_WEBKIT)
    m_webview(new QWebView),
#else
    m_label(new QLabel),
#endif
    m_htmlTemplate(readFile(QLatin1String(":/core/html/welcome.html"))),
    m_sessionHtmlTemplate(readFile(QLatin1String(":/core/html/recent_sessions.html"))),
    m_projectHtmlTemplate(readFile(QLatin1String(":/core/html/recent_projects.html"))),
    m_baseUrl(QUrl(QLatin1String("qrc:/core/html/welcome.html")))
{
#if !defined(QT_NO_WEBKIT)
    m_webview->setContextMenuPolicy(Qt::NoContextMenu);
#endif
}

#if defined(QT_NO_WEBKIT)

const char *LABEL = "

	"
                    "

Welcome

 Qt Creator is an intuitive, modern cross platform IDE that enables "
                    "developers to create graphically appealing applications for desktop, "
                    "embedded, and mobile devices. "
                    "
(This startup page lacks features due to disabled webkit support)"
                    "

";

#endif
// ---  WelcomePageData

bool WelcomeMode::WelcomePageData::operator==(const WelcomePageData &rhs) const
{
    return previousSession == rhs.previousSession
        && activeSession   == rhs.activeSession
        && sessionList     == rhs.sessionList
        && projectList     == rhs.projectList;
}

bool WelcomeMode::WelcomePageData::operator!=(const WelcomePageData &rhs) const
{
    return previousSession != rhs.previousSession
        || activeSession   != rhs.activeSession
        || sessionList     != rhs.sessionList
        || projectList     != rhs.projectList;
}

QDebug operator<<(QDebug dgb, const WelcomeMode::WelcomePageData &d)
{
    dgb.nospace() << "PreviousSession=" << d.previousSession
        << " activeSession=" << d.activeSession
        << " sessionList=" << d.sessionList
        << " projectList=" << d.projectList;
    return dgb;
}

// ---  WelcomeMode
WelcomeMode::WelcomeMode() :
    m_d(new WelcomeModePrivate)
{
    QVBoxLayout *l = new QVBoxLayout(m_d->m_widget);
    l->setMargin(0);
    l->setSpacing(0);
    l->addWidget(new QToolBar(m_d->m_widget));
#if !defined(QT_NO_WEBKIT)
    connect(m_d->m_webview, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl)));

    WelcomePageData welcomePageData;
    updateWelcomePage(welcomePageData);

    l->addWidget(m_d->m_webview);
    m_d->m_webview->setAcceptDrops(false);
    m_d->m_webview->settings()->setAttribute(QWebSettings::PluginsEnabled, false);
    m_d->m_webview->settings()->setAttribute(QWebSettings::JavaEnabled, false);

#else
    m_d->m_label->setWordWrap(true);
    m_d->m_label->setAlignment(Qt::AlignCenter);
    m_d->m_label->setText(LABEL);
    l->addWidget(m_d->m_label);
#endif
}

WelcomeMode::~WelcomeMode()
{
    delete m_d;
}

QString WelcomeMode::name() const
{
    return QLatin1String("Welcome");
}

QIcon WelcomeMode::icon() const
{
    return QIcon(QLatin1String(":/core/images/qtcreator_logo_32.png"));
}

int WelcomeMode::priority() const
{
    return Constants::P_MODE_WELCOME;
}

QWidget* WelcomeMode::widget()
{
    return m_d->m_widget;
}

const char* WelcomeMode::uniqueModeName() const
{
    return Constants::MODE_WELCOME;
}

QList<int> WelcomeMode::context() const
{
    static QList<int> contexts = QList<int>()
                                 << UniqueIDManager::instance()->uniqueIdentifier(Constants::C_WELCOME_MODE);
    return contexts;
}

void WelcomeMode::updateWelcomePage(const WelcomePageData &welcomePageData)
{
// should really only modify the DOM tree

#if defined(QT_NO_WEBKIT)
    Q_UNUSED(welcomePageData);
#else

    // Update only if data are modified
    if (welcomePageData == m_d->lastData)
        return;
    m_d->lastData = welcomePageData;

    QString html = m_d->m_htmlTemplate;

    if (!welcomePageData.previousSession.isEmpty() || !welcomePageData.projectList.isEmpty()) {
        QString sessionHtml = m_d->m_sessionHtmlTemplate;
        sessionHtml.replace(QLatin1String("LAST_SESSION"), welcomePageData.previousSession);

        if (welcomePageData.sessionList.count() > 1) {
            QString sessions;
            foreach (QString s, welcomePageData.sessionList) {
                QString last;
                if (s == welcomePageData.previousSession)
                    last = tr(" (last session)");
                sessions += QString::fromLatin1("

%2%3

").arg(s, s, last);
            }
            sessionHtml.replace(QLatin1String(""), sessions);
        }
        html.replace(QLatin1String(""), sessionHtml);

        QString projectHtml = m_d->m_projectHtmlTemplate;
        {
            QString projects;
            QTextStream str(&projects);

            QList<QPair<QString, QString> >::const_iterator it, end;
            end = welcomePageData.projectList.constEnd();
            for( it = welcomePageData.projectList.constBegin(); it != end; ++it) {
                const QFileInfo fi((*it).first);
                str << "

<a href=\"gh-project:" << (*it).first << "\" title=\""
                    << QDir::toNativeSeparators(fi.absolutePath()) << "\">" << (*it).second << "

\n";
            }
            projectHtml.replace(QLatin1String(""), projects);
        }
        html.replace(QLatin1String(""), projectHtml);
    }

    m_d->m_webview->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
    m_d->m_webview->setHtml(html, m_d->m_baseUrl);
#endif
}

void WelcomeMode::linkClicked(const QUrl &url)
{
    QString scheme = url.scheme();
    Core::ModeManager *modeManager = ModeManager::instance();
    if (scheme.startsWith(QLatin1String("gh"))) {
        QString s = url.toString(QUrl::RemoveScheme);
        if (scheme == QLatin1String("gh")) {
            emit requestHelp(s);
        } else if (scheme == QLatin1String("gh-project")) {
            emit requestProject(s);
            if (modeManager->currentMode() == this)
                modeManager->activateMode(Core::Constants::MODE_EDIT);
        } else if (scheme == QLatin1String("gh-session")) {
            emit requestSession(s);
            if (modeManager->currentMode() == this)
                modeManager->activateMode(Core::Constants::MODE_EDIT);
        }
    } else {
        QDesktopServices::openUrl(url);
    }
}

} // namespace Internal
} // namespace Core
<|endoftext|>


<commit_before>#include <vector>
#include <algorithm>
#include <iostream>
#include <Grappa.hpp>

#ifndef GRAPPARDD_RDD_H
#define GRAPPARDD_RDD_H

using namespace std;
using namespace Grappa;

template<typename T>
void print_vector(vector<T> v) {
    cout << "Length: " << v.size() << endl;
    for (auto i = v.begin(); i != v.end(); ++i) {
        cout << *i << ' ' << endl;
    }
}

template<typename A, typename B, typename Func>
class MappedRDD;

template <typename A>
class RDD {
public:

	template<typename Func>
	auto map(Func f) -> RDD<decltype(f(A()))>* {
		return new MappedRDD<A, decltype(f(A())), Func>(this, f);
	}

	//template<typename Func>
	//auto fold(A init, Func f) -> decltype(f(A(), A())) {
		//auto sequence = compute();
		//return std::accumulate(std::begin(sequence), std::end(sequence), init, f);
	//}

	auto collect() -> vector<A> {
		auto rdd = compute();
		vector<A> output;
		forall(rdd, size, [&output](A& e) {
			delegate::call<async>(0, [&output, e] {
				output.push_back(e);
			});
		});
		return output;
	}

	void print() {
		auto rdd = compute();
		forall(rdd, size, [](A& e) {
			cout << "Core: "<< rdd.core() << " ";
			cout << e << endl;
		});
	}

    virtual GlobalAddress<A> compute() = 0;
	int size;
};

template <typename A, typename B, typename Func>
class MappedRDD: public RDD<B> {
public:
	RDD<A> *prev;
	Func f;
	MappedRDD(RDD<A> *prev, Func f): prev(prev), f(f) {}

	GlobalAddress<B> compute() {
		// Assumes sizeof(A)=sizeof(B)
		GlobalAddress<A> prev_rdd = prev->compute();
		typedef GlobalAddress<decltype(f(A()))> result_type;
		result_type rdd = static_cast<result_type>(prev_rdd);
		forall(rdd, this->size, [this, prev_rdd](int64_t i, A& e) {
			e = this->f(*(prev_rdd + i).pointer());
		});
		return rdd;
	}
};

//template <typename A>
//class ParallelCollectionRDD: public RDD<A> {
	//vector<A> sequence;

//public:
	//ParallelCollectionRDD(vector<A> sequence): sequence(sequence) {}

//protected:
	//GlobalAddress<A> compute() {
		//return sequence;
	//}
//};

class RangedRDD: public RDD<double> {
	int start;
	int end;
public:
	RangedRDD(int start, int end): start(start), end(end) {
		size = end - start;
	}

	GlobalAddress<double> compute() {
		auto sequence = global_alloc<double>(end - start);
		forall(sequence, end - start, [](int64_t i, double& e) {
			e = i;
		});

		return sequence;
	}
};

#endif //GRAPPARDD_RDD_H

<commit_msg>Print core<commit_after>#include <vector>
#include <algorithm>
#include <iostream>
#include <Grappa.hpp>

#ifndef GRAPPARDD_RDD_H
#define GRAPPARDD_RDD_H

using namespace std;
using namespace Grappa;

template<typename T>
void print_vector(vector<T> v) {
    cout << "Length: " << v.size() << endl;
    for (auto i = v.begin(); i != v.end(); ++i) {
        cout << *i << ' ' << endl;
    }
}

template<typename A, typename B, typename Func>
class MappedRDD;

template <typename A>
class RDD {
public:

	template<typename Func>
	auto map(Func f) -> RDD<decltype(f(A()))>* {
		return new MappedRDD<A, decltype(f(A())), Func>(this, f);
	}

	//template<typename Func>
	//auto fold(A init, Func f) -> decltype(f(A(), A())) {
		//auto sequence = compute();
		//return std::accumulate(std::begin(sequence), std::end(sequence), init, f);
	//}

	auto collect() -> vector<A> {
		auto rdd = compute();
		vector<A> output;
		forall(rdd, size, [&output](A& e) {
			delegate::call<async>(0, [&output, e] {
				output.push_back(e);
			});
		});
		return output;
	}

	void print() {
		auto rdd = compute();
		cout << "Core: "<< mycore() << endl;
		forall(rdd, size, [](A& e) {
			cout << e << endl;
		});
	}

    virtual GlobalAddress<A> compute() = 0;
	int size;
};

template <typename A, typename B, typename Func>
class MappedRDD: public RDD<B> {
public:
	RDD<A> *prev;
	Func f;
	MappedRDD(RDD<A> *prev, Func f): prev(prev), f(f) {}

	GlobalAddress<B> compute() {
		// Assumes sizeof(A)=sizeof(B)
		GlobalAddress<A> prev_rdd = prev->compute();
		typedef GlobalAddress<decltype(f(A()))> result_type;
		result_type rdd = static_cast<result_type>(prev_rdd);
		forall(rdd, this->size, [this, prev_rdd](int64_t i, A& e) {
			e = this->f(*(prev_rdd + i).pointer());
		});
		return rdd;
	}
};

//template <typename A>
//class ParallelCollectionRDD: public RDD<A> {
	//vector<A> sequence;

//public:
	//ParallelCollectionRDD(vector<A> sequence): sequence(sequence) {}

//protected:
	//GlobalAddress<A> compute() {
		//return sequence;
	//}
//};

class RangedRDD: public RDD<double> {
	int start;
	int end;
public:
	RangedRDD(int start, int end): start(start), end(end) {
		size = end - start;
	}

	GlobalAddress<double> compute() {
		auto sequence = global_alloc<double>(end - start);
		forall(sequence, end - start, [](int64_t i, double& e) {
			e = i;
		});

		return sequence;
	}
};

#endif //GRAPPARDD_RDD_H

<|endoftext|>