<commit_before>/*

Copyright (c) 2008, 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.

*/

#include "libtorrent/lazy_entry.hpp"
#include <iostream>
#include <iomanip>
#include <cstring>

namespace libtorrent
{
	int fail_bdecode() { return -1; }

	// fills in 'val' with what the string between start and the
	// first occurance of the delimiter is interpreted as an int.
	// return the pointer to the delimiter, or 0 if there is a
	// parse error. val should be initialized to zero
	char const* parse_int(char const* start, char const* end, char delimiter, boost::int64_t& val)
	{
		while (start < end && *start != delimiter)
		{
			using namespace std;
			if (!isdigit(*start)) { fail_bdecode(); return 0; }
			val *= 10;
			val += *start - '0';
			++start;
		}
		return start;
	}

	char const* find_char(char const* start, char const* end, char delimiter)
	{
		while (start < end && *start != delimiter) ++start;
		return start;
	}

	// return 0 = success
	int lazy_bdecode(char const* start, char const* end, lazy_entry& ret, int depth_limit)
	{
		ret.clear();
		if (start == end) return 0;

		std::vector<lazy_entry*> stack;

		stack.push_back(&ret);
		while (start < end)
		{
			if (stack.empty()) break; // done!

			lazy_entry* top = stack.back();

			if (int(stack.size()) > depth_limit) return fail_bdecode();
			if (start == end) return fail_bdecode();
			char t = *start;
			++start;
			if (start == end && t != 'e') return fail_bdecode();

			switch (top->type())
			{
				case lazy_entry::dict_t:
				{
					if (t == 'e')
					{
						top->set_end(start);
						stack.pop_back();
						continue;
					}
					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 3 > end || *start != ':') return fail_bdecode();
					++start;
					lazy_entry* ent = top->dict_append(start);
					start += len;
					stack.push_back(ent);
					t = *start;
					++start;
					break;
				}
				case lazy_entry::list_t:
				{
					if (t == 'e')
					{
						top->set_end(start);
						stack.pop_back();
						continue;
					}
					lazy_entry* ent = top->list_append();
					stack.push_back(ent);
					break;
				}
				default: break;
			}

			top = stack.back();
			switch (t)
			{
				case 'd':
					top->construct_dict(start - 1);
					continue;
				case 'l':
					top->construct_list(start - 1);
					continue;
				case 'i':
				{
					char const* int_start = start;
					start = find_char(start, end, 'e');
					top->construct_int(int_start, start - int_start);
					if (start == end) return fail_bdecode();
					TORRENT_ASSERT(*start == 'e');
					++start;
					stack.pop_back();
					continue;
				}
				default:
				{
					using namespace std;
					if (!isdigit(t)) return fail_bdecode();

					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 1 > end || *start != ':') return fail_bdecode();
					++start;
					top->construct_string(start, int(len));
					stack.pop_back();
					start += len;
					continue;
				}
			}
			return 0;
		}
		return 0;
	}

	size_type lazy_entry::int_value() const
	{
		TORRENT_ASSERT(m_type == int_t);
		boost::int64_t val = 0;
		bool negative = false;
		if (*m_data.start == '-') negative = true;
		parse_int(negative?m_data.start+1:m_data.start, m_data.start + m_size, 'e', val);
		if (negative) val = -val;
		return val;
	}

	lazy_entry* lazy_entry::dict_append(char const* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.dict = new (std::nothrow) std::pair<char const*, lazy_entry>[capacity];
			if (m_data.dict == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			std::pair<char const*, lazy_entry>* tmp = new (std::nothrow) std::pair<char const*, lazy_entry>[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.dict, sizeof(std::pair<char const*, lazy_entry>) * m_size);
			delete[] m_data.dict;
			m_data.dict = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		std::pair<char const*, lazy_entry>& ret = m_data.dict[m_size++];
		ret.first = name;
		return &ret.second;
	}

	namespace
	{
		// the number of decimal digits needed
		// to represent the given value
		int num_digits(int val)
		{
			int ret = 1;
			while (val > 10)
			{
				++ret;
				val /= 10;
			}
			return ret;
		}
	}

	void lazy_entry::construct_string(char const* start, int length)
	{
		TORRENT_ASSERT(m_type == none_t);
		m_type = string_t;
		m_data.start = start;
		m_size = length;
		m_begin = start - 1 - num_digits(length);
		m_end = start + length;
	}

	namespace
	{
		// str1 is null-terminated
		// str2 is not, str2 is len2 chars
		bool string_equal(char const* str1, char const* str2, int len2)
		{
			while (len2 > 0)
			{
				if (*str1 != *str2) return false;
				if (*str1 == 0) return false;
				++str1;
				++str2;
				--len2;
			}
			return *str1 == 0;
		}
	}

	std::string lazy_entry::dict_find_string_value(char const* name) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::string_t) return std::string();
		return e->string_value();
	}

	size_type lazy_entry::dict_find_int_value(char const* name, size_type default_val) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::int_t) return default_val;
		return e->int_value();
	}

	lazy_entry const* lazy_entry::dict_find_dict(char const* name) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::dict_t) return 0;
		return e;
	}

	lazy_entry const* lazy_entry::dict_find_list(char const* name) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::list_t) return 0;
		return e;
	}

	lazy_entry* lazy_entry::dict_find(char const* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		for (int i = 0; i < m_size; ++i)
		{
			std::pair<char const*, lazy_entry> const& e = m_data.dict[i];
			if (string_equal(name, e.first, e.second.m_begin - e.first))
				return &m_data.dict[i].second;
		}
		return 0;
	}

	lazy_entry* lazy_entry::list_append()
	{
		TORRENT_ASSERT(m_type == list_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.list = new (std::nothrow) lazy_entry[capacity];
			if (m_data.list == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			lazy_entry* tmp = new (std::nothrow) lazy_entry[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.list, sizeof(lazy_entry) * m_size);
			delete[] m_data.list;
			m_data.list = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		return m_data.list + (m_size++);
	}

	std::string lazy_entry::list_string_value_at(int i) const
	{
		lazy_entry const* e = list_at(i);
		if (e == 0 || e->type() != lazy_entry::string_t) return std::string();
		return e->string_value();
	}

	size_type lazy_entry::list_int_value_at(int i, size_type default_val) const
	{
		lazy_entry const* e = list_at(i);
		if (e == 0 || e->type() != lazy_entry::int_t) return default_val;
		return e->int_value();
	}

	void lazy_entry::clear()
	{
		switch (m_type)
		{
			case list_t: delete[] m_data.list; break;
			case dict_t: delete[] m_data.dict; break;
			default: break;
		}
		m_size = 0;
		m_capacity = 0;
		m_type = none_t;
	}

	std::pair<char const*, int> lazy_entry::data_section() const
	{
		typedef std::pair<char const*, int> return_t;
		return return_t(m_begin, m_end - m_begin);
	}

	std::ostream& operator<<(std::ostream& os, lazy_entry const& e)
	{
		switch (e.type())
		{
			case lazy_entry::none_t: return os << "none";
			case lazy_entry::int_t: return os << e.int_value();
			case lazy_entry::string_t:
			{
				bool printable = true;
				char const* str = e.string_ptr();
				for (int i = 0; i < e.string_length(); ++i)
				{
					using namespace std;
					if (isprint(str[i])) continue;
					printable = false;
					break;
				}
				os << "'";
				if (printable) return os << e.string_value() << "'";
				for (int i = 0; i < e.string_length(); ++i)
					os << std::hex << int((unsigned char)(str[i]));
				return os << "'";
			}
			case lazy_entry::list_t:
			{
				os << "[";
				bool one_liner = (e.list_size() == 0
					|| e.list_at(0)->type() == lazy_entry::int_t
					|| (e.list_at(0)->type() == lazy_entry::string_t
						&& e.list_at(0)->string_length() < 10))
					&& e.list_size() < 5;
				if (!one_liner) os << "\n";
				for (int i = 0; i < e.list_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					os << *e.list_at(i);
					if (i < e.list_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "]";
			}
			case lazy_entry::dict_t:
			{
				os << "{";
				bool one_liner = (e.dict_size() == 0
					|| e.dict_at(0).second->type() == lazy_entry::int_t
					|| (e.dict_at(0).second->type() == lazy_entry::string_t
						&& e.dict_at(0).second->string_length() < 10)
					|| e.dict_at(0).first.size() < 10)
					&& e.dict_size() < 5;

				if (!one_liner) os << "\n";
				for (int i = 0; i < e.dict_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					std::pair<std::string, lazy_entry const*> ent = e.dict_at(i);
					os << "'" << ent.first << "': " << *ent.second;
					if (i < e.dict_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "}";
			}
		}
		return os;
	}

};

<commit_msg>bdecode print formatting fix<commit_after>/*

Copyright (c) 2008, 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.

*/

#include "libtorrent/lazy_entry.hpp"
#include <iostream>
#include <iomanip>
#include <cstring>

namespace libtorrent
{
	int fail_bdecode() { return -1; }

	// fills in 'val' with what the string between start and the
	// first occurance of the delimiter is interpreted as an int.
	// return the pointer to the delimiter, or 0 if there is a
	// parse error. val should be initialized to zero
	char const* parse_int(char const* start, char const* end, char delimiter, boost::int64_t& val)
	{
		while (start < end && *start != delimiter)
		{
			using namespace std;
			if (!isdigit(*start)) { fail_bdecode(); return 0; }
			val *= 10;
			val += *start - '0';
			++start;
		}
		return start;
	}

	char const* find_char(char const* start, char const* end, char delimiter)
	{
		while (start < end && *start != delimiter) ++start;
		return start;
	}

	// return 0 = success
	int lazy_bdecode(char const* start, char const* end, lazy_entry& ret, int depth_limit)
	{
		ret.clear();
		if (start == end) return 0;

		std::vector<lazy_entry*> stack;

		stack.push_back(&ret);
		while (start < end)
		{
			if (stack.empty()) break; // done!

			lazy_entry* top = stack.back();

			if (int(stack.size()) > depth_limit) return fail_bdecode();
			if (start == end) return fail_bdecode();
			char t = *start;
			++start;
			if (start == end && t != 'e') return fail_bdecode();

			switch (top->type())
			{
				case lazy_entry::dict_t:
				{
					if (t == 'e')
					{
						top->set_end(start);
						stack.pop_back();
						continue;
					}
					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 3 > end || *start != ':') return fail_bdecode();
					++start;
					lazy_entry* ent = top->dict_append(start);
					start += len;
					stack.push_back(ent);
					t = *start;
					++start;
					break;
				}
				case lazy_entry::list_t:
				{
					if (t == 'e')
					{
						top->set_end(start);
						stack.pop_back();
						continue;
					}
					lazy_entry* ent = top->list_append();
					stack.push_back(ent);
					break;
				}
				default: break;
			}

			top = stack.back();
			switch (t)
			{
				case 'd':
					top->construct_dict(start - 1);
					continue;
				case 'l':
					top->construct_list(start - 1);
					continue;
				case 'i':
				{
					char const* int_start = start;
					start = find_char(start, end, 'e');
					top->construct_int(int_start, start - int_start);
					if (start == end) return fail_bdecode();
					TORRENT_ASSERT(*start == 'e');
					++start;
					stack.pop_back();
					continue;
				}
				default:
				{
					using namespace std;
					if (!isdigit(t)) return fail_bdecode();

					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 1 > end || *start != ':') return fail_bdecode();
					++start;
					top->construct_string(start, int(len));
					stack.pop_back();
					start += len;
					continue;
				}
			}
			return 0;
		}
		return 0;
	}

	size_type lazy_entry::int_value() const
	{
		TORRENT_ASSERT(m_type == int_t);
		boost::int64_t val = 0;
		bool negative = false;
		if (*m_data.start == '-') negative = true;
		parse_int(negative?m_data.start+1:m_data.start, m_data.start + m_size, 'e', val);
		if (negative) val = -val;
		return val;
	}

	lazy_entry* lazy_entry::dict_append(char const* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.dict = new (std::nothrow) std::pair<char const*, lazy_entry>[capacity];
			if (m_data.dict == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			std::pair<char const*, lazy_entry>* tmp = new (std::nothrow) std::pair<char const*, lazy_entry>[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.dict, sizeof(std::pair<char const*, lazy_entry>) * m_size);
			delete[] m_data.dict;
			m_data.dict = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		std::pair<char const*, lazy_entry>& ret = m_data.dict[m_size++];
		ret.first = name;
		return &ret.second;
	}

	namespace
	{
		// the number of decimal digits needed
		// to represent the given value
		int num_digits(int val)
		{
			int ret = 1;
			while (val > 10)
			{
				++ret;
				val /= 10;
			}
			return ret;
		}
	}

	void lazy_entry::construct_string(char const* start, int length)
	{
		TORRENT_ASSERT(m_type == none_t);
		m_type = string_t;
		m_data.start = start;
		m_size = length;
		m_begin = start - 1 - num_digits(length);
		m_end = start + length;
	}

	namespace
	{
		// str1 is null-terminated
		// str2 is not, str2 is len2 chars
		bool string_equal(char const* str1, char const* str2, int len2)
		{
			while (len2 > 0)
			{
				if (*str1 != *str2) return false;
				if (*str1 == 0) return false;
				++str1;
				++str2;
				--len2;
			}
			return *str1 == 0;
		}
	}

	std::string lazy_entry::dict_find_string_value(char const* name) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::string_t) return std::string();
		return e->string_value();
	}

	size_type lazy_entry::dict_find_int_value(char const* name, size_type default_val) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::int_t) return default_val;
		return e->int_value();
	}

	lazy_entry const* lazy_entry::dict_find_dict(char const* name) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::dict_t) return 0;
		return e;
	}

	lazy_entry const* lazy_entry::dict_find_list(char const* name) const
	{
		lazy_entry const* e = dict_find(name);
		if (e == 0 || e->type() != lazy_entry::list_t) return 0;
		return e;
	}

	lazy_entry* lazy_entry::dict_find(char const* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		for (int i = 0; i < m_size; ++i)
		{
			std::pair<char const*, lazy_entry> const& e = m_data.dict[i];
			if (string_equal(name, e.first, e.second.m_begin - e.first))
				return &m_data.dict[i].second;
		}
		return 0;
	}

	lazy_entry* lazy_entry::list_append()
	{
		TORRENT_ASSERT(m_type == list_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.list = new (std::nothrow) lazy_entry[capacity];
			if (m_data.list == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			lazy_entry* tmp = new (std::nothrow) lazy_entry[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.list, sizeof(lazy_entry) * m_size);
			delete[] m_data.list;
			m_data.list = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		return m_data.list + (m_size++);
	}

	std::string lazy_entry::list_string_value_at(int i) const
	{
		lazy_entry const* e = list_at(i);
		if (e == 0 || e->type() != lazy_entry::string_t) return std::string();
		return e->string_value();
	}

	size_type lazy_entry::list_int_value_at(int i, size_type default_val) const
	{
		lazy_entry const* e = list_at(i);
		if (e == 0 || e->type() != lazy_entry::int_t) return default_val;
		return e->int_value();
	}

	void lazy_entry::clear()
	{
		switch (m_type)
		{
			case list_t: delete[] m_data.list; break;
			case dict_t: delete[] m_data.dict; break;
			default: break;
		}
		m_size = 0;
		m_capacity = 0;
		m_type = none_t;
	}

	std::pair<char const*, int> lazy_entry::data_section() const
	{
		typedef std::pair<char const*, int> return_t;
		return return_t(m_begin, m_end - m_begin);
	}

	std::ostream& operator<<(std::ostream& os, lazy_entry const& e)
	{
		switch (e.type())
		{
			case lazy_entry::none_t: return os << "none";
			case lazy_entry::int_t: return os << e.int_value();
			case lazy_entry::string_t:
			{
				bool printable = true;
				char const* str = e.string_ptr();
				for (int i = 0; i < e.string_length(); ++i)
				{
					using namespace std;
					if (isprint(str[i])) continue;
					printable = false;
					break;
				}
				os << "'";
				if (printable) return os << e.string_value() << "'";
				for (int i = 0; i < e.string_length(); ++i)
					os << std::hex << int((unsigned char)(str[i]));
				return os << "'";
			}
			case lazy_entry::list_t:
			{
				os << "[";
				bool one_liner = (e.list_size() == 0
					|| e.list_at(0)->type() == lazy_entry::int_t
					|| (e.list_at(0)->type() == lazy_entry::string_t
						&& (e.list_at(0)->string_length() < 10
							|| e.list_size() < 2)))
					&& e.list_size() < 5;
				if (!one_liner) os << "\n";
				for (int i = 0; i < e.list_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					os << *e.list_at(i);
					if (i < e.list_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "]";
			}
			case lazy_entry::dict_t:
			{
				os << "{";
				bool one_liner = (e.dict_size() == 0
					|| e.dict_at(0).second->type() == lazy_entry::int_t
					|| (e.dict_at(0).second->type() == lazy_entry::string_t
						&& e.dict_at(0).second->string_length() < 30)
					|| e.dict_at(0).first.size() < 10)
					&& e.dict_size() < 5;

				if (!one_liner) os << "\n";
				for (int i = 0; i < e.dict_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					std::pair<std::string, lazy_entry const*> ent = e.dict_at(i);
					os << "'" << ent.first << "': " << *ent.second;
					if (i < e.dict_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "}";
			}
		}
		return os;
	}

};

<|endoftext|>


<commit_before>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file	    g_thread.cpp
* @version
* @brief
* @author   duye
* @date	    2013-11-26
* @note
*
*  1. 2013-11-26 duye Created this file
*
*/
#include <g_thread.h>

using namespace gsys;

Thread::Thread(Runnable* runnable, const bool autoRel)
    : m_threadId(-1)
    , m_autoRel(autoRel)
    , m_runnable(runnable)
{
}

Thread::~Thread()
{
}

GResult Thread::start()
{
    pthread_attr_t* attributes = NULL;
    GResult ret = pthread_create(&m_threadId, attributes, enterPoint, m_runnable);
    if (ret != 0)
    {
    	return G_NO;
    }

    if (m_autoRel)
    {
    	pthread_detach(m_threadId);
    }

    return G_YES;
}

GUint32 Thread::getGThreadId() const
{
    return (GUint32)m_threadId;
}

void* Thread::enterPoint(void* argument)
{
    Runnable* runnable = static_cast<Runnable*>(argument);
    runnable->run();
    return NULL;
}

ThreadTask::ThreadTask(const bool autoRel) : m_threadId(-1), m_autoRel(autoRel) {}

ThreadTask::~ThreadTask() {}

GResult ThreadTask::startTask()
{
    pthread_attr_t* attributes = NULL;
    GInt32 ret = pthread_create(&m_threadId, attributes, enterPoint, this);
    if (ret != 0)
    {
    	return G_NO;
    }

    if (m_autoRel)
    {
    	pthread_detach(m_threadId);
    }

    return G_YES;
}

void* ThreadTask::enterPoint(void* argument)
{
    ThreadTask* threadTask = static_cast<ThreadTask*>(argument);
    threadTask->run();
    return NULL;
}

GInt32 ThreadUtil::createThread(void* entry, void* argument, const bool autoRel)
{
    pthread_attr_t* attributes = NULL;
    pthread_t threadId = -1;

    GInt32 ret = pthread_create(&threadId, attributes, (GThreadFunPoint_t)entry, argument);
    if (ret != 0)
    {
    	return (GInt32)threadId;
    }

    if (autoRel)
    {
    	pthread_detach(threadId);
    }

    return (GInt32)threadId;
}
}
<commit_msg>Update g_thread.cpp<commit_after>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file	    g_thread.cpp
* @version
* @brief
* @author   duye
* @date	    2013-11-26
* @note
*
*  1. 2013-11-26 duye Created this file
*
*/
#include <g_thread.h>

namespace gsys {

Thread::Thread(Runnable* runnable, const bool autoRel)
    : m_threadId(-1)
    , m_autoRel(autoRel)
    , m_runnable(runnable) {}

Thread::~Thread() {}

GResult Thread::start()
{
    pthread_attr_t* attributes = NULL;
    GResult ret = pthread_create(&m_threadId, attributes, enterPoint, m_runnable);
    if (ret != 0)
    {
    	return G_NO;
    }

    if (m_autoRel)
    {
    	pthread_detach(m_threadId);
    }

    return G_YES;
}

GUint32 Thread::getGThreadId() const
{
    return (GUint32)m_threadId;
}

void* Thread::enterPoint(void* argument)
{
    Runnable* runnable = static_cast<Runnable*>(argument);
    runnable->run();
    return NULL;
}

ThreadTask::ThreadTask(const bool autoRel) : m_threadId(-1), m_autoRel(autoRel) {}

ThreadTask::~ThreadTask() {}

GResult ThreadTask::startTask()
{
    pthread_attr_t* attributes = NULL;
    GInt32 ret = pthread_create(&m_threadId, attributes, enterPoint, this);
    if (ret != 0)
    {
    	return G_NO;
    }

    if (m_autoRel)
    {
    	pthread_detach(m_threadId);
    }

    return G_YES;
}

void* ThreadTask::enterPoint(void* argument)
{
    ThreadTask* threadTask = static_cast<ThreadTask*>(argument);
    threadTask->run();
    return NULL;
}

GInt32 ThreadUtil::createThread(void* entry, void* argument, const bool autoRel)
{
    pthread_attr_t* attributes = NULL;
    pthread_t threadId = -1;

    GInt32 ret = pthread_create(&threadId, attributes, (GThreadFunPoint_t)entry, argument);
    if (ret != 0)
    {
    	return (GInt32)threadId;
    }

    if (autoRel)
    {
    	pthread_detach(threadId);
    }

    return (GInt32)threadId;
}
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * tests/data/channel_multiplexer_test.cpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 * Copyright (C) 2015 Tobias Sturm  <tobias.sturm@student.kit.edu>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <c7a/data/channel_multiplexer.hpp>
#include <c7a/data/channel.hpp>
#include <c7a/data/manager.hpp>
#include <c7a/net/group.hpp>
#include <c7a/net/dispatcher_thread.hpp>
#include <c7a/common/cyclic_barrier.hpp>

#include <gtest/gtest.h>
#include <string>

using namespace c7a;
using namespace c7a::common;
using namespace c7a::net;
using Manager = c7a::data::Manager;
using Group = c7a::net::Group;

static const bool debug = true;

struct ChannelMultiplexerTest : public::testing::Test {
    ChannelMultiplexerTest()
        : dispatcher("dispatcher"), manager(dispatcher), single_group(0, 1), barrier(3) {
        manager.Connect(&single_group);
    }

    using WorkerThread = std::function<void(Manager&)>;
    void FunctionSelect(Group* group, WorkerThread f1, WorkerThread f2, WorkerThread f3 = [](Manager&) { }) {
        Manager manager(dispatcher);
        manager.Connect(group);
        switch (group->MyRank()) {
        case 0:
            GetThreadDirectory().NameThisThread("t0");
            f1(manager);
            break;
        case 1:
            GetThreadDirectory().NameThisThread("t1");
            f2(manager);
            break;
        case 2:
            GetThreadDirectory().NameThisThread("t2");
            f3(manager);
            break;
        }
        barrier.Await();
    }
    void Execute(WorkerThread f1, WorkerThread f2, WorkerThread f3) {
        Group::ExecuteLocalMock(3,
                                [=](Group* g) {
                                    FunctionSelect(g, f1, f2, f3);
                                });
    }
    DispatcherThread dispatcher;
    Manager          manager;
    Group            single_group;
    Barrier          barrier;
};

// open a Channel via data::Manager, and send a short message to all workers,
// receive and check the message.
void TalkAllToAllViaChannel(net::Group* net) {
    common::GetThreadDirectory().NameThisThread(
        "chmp" + std::to_string(net->MyRank()));

    net::DispatcherThread dispatcher(
        "chmp" + std::to_string(net->MyRank()) + "-dp");

    unsigned char send_buffer[123];
    for (size_t i = 0; i != sizeof(send_buffer); ++i)
        send_buffer[i] = i;

    static const size_t iterations = 1000;

    data::ChannelMultiplexer<1024> cmp(dispatcher);
    cmp.Connect(net);
    {
        data::ChannelId id = cmp.AllocateNext();

        // open Writers and send a message to all workers

        auto writer = cmp.GetOrCreateChannel(id)->OpenWriters();

        for (size_t tgt = 0; tgt != net->Size(); ++tgt) {
            writer[tgt]("hello I am " + std::to_string(net->MyRank())
                        + " calling " + std::to_string(tgt));

            writer[tgt].Flush();

            // write a few MiBs of oddly sized data
            for (size_t r = 0; r != iterations; ++r) {
                writer[tgt].Append(send_buffer, sizeof(send_buffer));
            }

            writer[tgt].Flush();
        }

        // open Readers and receive message from all workers

        auto reader = cmp.GetOrCreateChannel(id)->OpenReaders();

        for (size_t src = 0; src != net->Size(); ++src) {
            std::string msg = reader[src].Next<std::string>();

            ASSERT_EQ(msg, "hello I am " + std::to_string(src)
                      + " calling " + std::to_string(net->MyRank()));

            sLOG << net->MyRank() << "got msg from" << src;

            // read a few MiBs of oddly sized data
            unsigned char recv_buffer[sizeof(send_buffer)];

            for (size_t r = 0; r != iterations; ++r) {
                reader[src].Read(recv_buffer, sizeof(recv_buffer));

                ASSERT_TRUE(std::equal(send_buffer,
                                       send_buffer + sizeof(send_buffer),
                                       recv_buffer));
            }
        }
    }
}

TEST(ChannelMultiplexer, TalkAllToAllViaChannelForManyNetSizes) {
    // test for all network mesh sizes 1, 2, 5, 16:
    net::Group::ExecuteLocalMock(1, TalkAllToAllViaChannel);
    net::Group::ExecuteLocalMock(2, TalkAllToAllViaChannel);
    net::Group::ExecuteLocalMock(5, TalkAllToAllViaChannel);
    net::Group::ExecuteLocalMock(16, TalkAllToAllViaChannel);
}

TEST_F(ChannelMultiplexerTest, ReadCompleteChannel) {
    Barrier sync(3);
    auto w0 = [&sync](Manager& manager) {
                  auto c = manager.GetNewChannel();
                  auto writers = c->OpenWriters();
                  std::string msg1 = "I came from worker 0";
                  std::string msg2 = "I am another message from worker 0";
                  writers[2](msg1);
                  //writers[2].Flush();
                  writers[2](msg2);
                  for (auto& w : writers) {
                      sLOG << "close worker";
                      w.Close();
                  }
              };
    auto w1 = [&sync](Manager& manager) {
                  auto c = manager.GetNewChannel();
                  auto writers = c->OpenWriters();
                  std::string msg1 = "I came from worker 1";
                  writers[2](msg1);
                  for (auto& w : writers) {
                      sLOG << "close worker";
                      w.Close();
                  }
              };
    auto w2 = [&sync](Manager& manager) {
                  auto c = manager.GetNewChannel();
                  auto writers = c->OpenWriters();
                  for (auto& w : writers) {
                      sLOG << "close worker";
                      w.Close();
                  }
                  auto file = c->ReadCompleteChannel();
                  for (size_t i = 0; i < file.NumBlocks(); i++)
                      sLOG << "block" << i << file.BlockAsString(i);

                  auto reader = file.GetReader();
                  ASSERT_EQ("I came from worker 0", reader.Next<std::string>());
                  ASSERT_EQ("I am another message from worker 0", reader.Next<std::string>());
                  ASSERT_EQ("I came from worker 1", reader.Next<std::string>());
              };
    Execute(w0, w1, w2);
}

/******************************************************************************/
<commit_msg>Fixing chaos in data/channel_multiplexer_test initialization: each thread creates data::Manager and DispatcherThread. No sharing.<commit_after>/*******************************************************************************
 * tests/data/channel_multiplexer_test.cpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 * Copyright (C) 2015 Tobias Sturm  <tobias.sturm@student.kit.edu>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <c7a/data/channel_multiplexer.hpp>
#include <c7a/data/channel.hpp>
#include <c7a/data/manager.hpp>
#include <c7a/net/group.hpp>
#include <c7a/net/dispatcher_thread.hpp>
#include <c7a/common/cyclic_barrier.hpp>

#include <gtest/gtest.h>
#include <string>

using namespace c7a;
using namespace c7a::common;
using namespace c7a::net;
using c7a::net::Group;

static const bool debug = false;

struct ChannelMultiplexerTest : public::testing::Test {

    using WorkerThread = std::function<void(data::Manager&)>;

    void FunctionSelect(
        Group* group, WorkerThread f1, WorkerThread f2, WorkerThread f3) {
        net::DispatcherThread dispatcher("dp");
        data::Manager manager(dispatcher);
        manager.Connect(group);
        switch (group->MyRank()) {
        case 0:
            GetThreadDirectory().NameThisThread("t0");
            f1(manager);
            break;
        case 1:
            GetThreadDirectory().NameThisThread("t1");
            f2(manager);
            break;
        case 2:
            GetThreadDirectory().NameThisThread("t2");
            f3(manager);
            break;
        }
    }

    void Execute(WorkerThread f1, WorkerThread f2, WorkerThread f3) {
        Group::ExecuteLocalMock(3,
                                [=](Group* g) {
                                    FunctionSelect(g, f1, f2, f3);
                                });
    }
};

// open a Channel via data::Manager, and send a short message to all workers,
// receive and check the message.
void TalkAllToAllViaChannel(net::Group* net) {
    common::GetThreadDirectory().NameThisThread(
        "chmp" + std::to_string(net->MyRank()));

    net::DispatcherThread dispatcher(
        "chmp" + std::to_string(net->MyRank()) + "-dp");

    unsigned char send_buffer[123];
    for (size_t i = 0; i != sizeof(send_buffer); ++i)
        send_buffer[i] = i;

    static const size_t iterations = 1000;

    data::ChannelMultiplexer<1024> cmp(dispatcher);
    cmp.Connect(net);
    {
        data::ChannelId id = cmp.AllocateNext();

        // open Writers and send a message to all workers

        auto writer = cmp.GetOrCreateChannel(id)->OpenWriters();

        for (size_t tgt = 0; tgt != net->Size(); ++tgt) {
            writer[tgt]("hello I am " + std::to_string(net->MyRank())
                        + " calling " + std::to_string(tgt));

            writer[tgt].Flush();

            // write a few MiBs of oddly sized data
            for (size_t r = 0; r != iterations; ++r) {
                writer[tgt].Append(send_buffer, sizeof(send_buffer));
            }

            writer[tgt].Flush();
        }

        // open Readers and receive message from all workers

        auto reader = cmp.GetOrCreateChannel(id)->OpenReaders();

        for (size_t src = 0; src != net->Size(); ++src) {
            std::string msg = reader[src].Next<std::string>();

            ASSERT_EQ(msg, "hello I am " + std::to_string(src)
                      + " calling " + std::to_string(net->MyRank()));

            sLOG << net->MyRank() << "got msg from" << src;

            // read a few MiBs of oddly sized data
            unsigned char recv_buffer[sizeof(send_buffer)];

            for (size_t r = 0; r != iterations; ++r) {
                reader[src].Read(recv_buffer, sizeof(recv_buffer));

                ASSERT_TRUE(std::equal(send_buffer,
                                       send_buffer + sizeof(send_buffer),
                                       recv_buffer));
            }
        }
    }
}

TEST(ChannelMultiplexer, TalkAllToAllViaChannelForManyNetSizes) {
    // test for all network mesh sizes 1, 2, 5, 16:
    net::Group::ExecuteLocalMock(1, TalkAllToAllViaChannel);
    net::Group::ExecuteLocalMock(2, TalkAllToAllViaChannel);
    net::Group::ExecuteLocalMock(5, TalkAllToAllViaChannel);
    net::Group::ExecuteLocalMock(16, TalkAllToAllViaChannel);
}

TEST_F(ChannelMultiplexerTest, ReadCompleteChannel) {
    Barrier sync(3);
    auto w0 = [&sync](data::Manager& manager) {
                  auto c = manager.GetNewChannel();
                  auto writers = c->OpenWriters();
                  std::string msg1 = "I came from worker 0";
                  std::string msg2 = "I am another message from worker 0";
                  writers[2](msg1);
                  //writers[2].Flush();
                  writers[2](msg2);
                  for (auto& w : writers) {
                      sLOG << "close worker";
                      w.Close();
                  }
              };
    auto w1 = [&sync](data::Manager& manager) {
                  auto c = manager.GetNewChannel();
                  auto writers = c->OpenWriters();
                  std::string msg1 = "I came from worker 1";
                  writers[2](msg1);
                  for (auto& w : writers) {
                      sLOG << "close worker";
                      w.Close();
                  }
              };
    auto w2 = [&sync](data::Manager& manager) {
                  auto c = manager.GetNewChannel();
                  auto writers = c->OpenWriters();
                  for (auto& w : writers) {
                      sLOG << "close worker";
                      w.Close();
                  }
                  auto file = c->ReadCompleteChannel();
                  for (size_t i = 0; i < file.NumBlocks(); i++)
                      sLOG << "block" << i << file.BlockAsString(i);

                  auto reader = file.GetReader();
                  ASSERT_EQ("I came from worker 0", reader.Next<std::string>());
                  ASSERT_EQ("I am another message from worker 0", reader.Next<std::string>());
                  ASSERT_EQ("I came from worker 1", reader.Next<std::string>());
              };
    Execute(w0, w1, w2);
}

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


<commit_before>/*
 * Launch "Local HTTP" child processes.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "lhttp_launch.hxx"
#include "lhttp_address.hxx"
#include "exec.hxx"

#include <daemon/log.h>
#include <inline/compiler.h>

#include <unistd.h>
#include <stdlib.h>

gcc_noreturn
void
lhttp_run(const struct lhttp_address *address, int fd)
{
    if (fd != 0) {
        dup2(fd, 0);
        close(fd);
    }

    clearenv();

    for (unsigned j = 0; j < address->env.n; ++j) {
        union {
            const char *in;
            char *out;
        } u = {
            .in = address->env.values[j],
        };

        putenv(u.out);
    }

    Exec e;
    jail_wrapper_insert(e, &address->options.jail, nullptr);
    e.Append(address->path);

    for (unsigned i = 0; i < address->args.n; ++i)
        e.Append(address->args.values[i]);

    e.DoExec();
}
<commit_msg>lhttp_launch: use range-based for<commit_after>/*
 * Launch "Local HTTP" child processes.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "lhttp_launch.hxx"
#include "lhttp_address.hxx"
#include "exec.hxx"

#include <daemon/log.h>
#include <inline/compiler.h>

#include <unistd.h>
#include <stdlib.h>

gcc_noreturn
void
lhttp_run(const struct lhttp_address *address, int fd)
{
    if (fd != 0) {
        dup2(fd, 0);
        close(fd);
    }

    clearenv();

    for (auto i : address->env)
        putenv(const_cast<char *>(i));

    Exec e;
    jail_wrapper_insert(e, &address->options.jail, nullptr);
    e.Append(address->path);

    for (unsigned i = 0; i < address->args.n; ++i)
        e.Append(address->args.values[i]);

    e.DoExec();
}
<|endoftext|>


<commit_before>/*
 * Sponge: hash sha-3 (keccak)
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "keccak.H"
#include "action_sponge.H"

#define HASH_SIZE 64
#define RESULT_SIZE 8

#undef TEST /* get faster turn-around time */
#ifdef NO_SYNTH /* TEST */
#  define NB_SLICES 4
#  define NB_ROUND 1<<10
#else
#  ifndef NB_SLICES
#    define NB_SLICES 65536 	/* for real benchmark */
#  endif
#  ifndef NB_ROUND
#    define NB_ROUND 1<<24 	/* for real benchmark */
#  endif
#endif

uint64_t sponge (const uint64_t rank)
{
  uint64_t magic[8] = {0x0123456789abcdeful,0x13579bdf02468aceul,
		       0xfdecba9876543210ul,0xeca86420fdb97531ul,
                       0x571e30cf4b29a86dul,0xd48f0c376e1b29a5ul,
		       0xc5301e9f6b2ad748ul,0x3894d02e5ba71c6ful};
  uint64_t odd[8],even[8],result;
  int i,j;
  int rnd_nb;

   for(i=0;i<RESULT_SIZE;i++) {
#pragma HLS UNROLL
    even[i] = magic[i] + rank;
  }

  //keccak((uint8_t*)even,HASH_SIZE,(uint8_t*)odd,HASH_SIZE);
  keccak((uint64_t*)even,HASH_SIZE,(uint64_t*)odd,HASH_SIZE);

   for(rnd_nb=0;rnd_nb<NB_ROUND;rnd_nb++) {
//#pragma HLS UNROLL factor=2

    for(j=0;j<4;j++) {
#pragma HLS UNROLL
      odd[2*j] ^= ROTL64( even[2*j] , 4*j+1);
      odd[2*j+1] = ROTL64( even[2*j+1] + odd[2*j+1], 4*j+3);
    }

    //keccak((uint8_t*)odd,HASH_SIZE,(uint8_t*)even,HASH_SIZE);
    keccak((uint64_t*)odd,HASH_SIZE,(uint64_t*)even,HASH_SIZE);

     for(j=0;j<4;j++) {
#pragma HLS UNROLL
      even[2*j] += ROTL64( odd[2*j] , 4*j+5);
      even[2*j+1] = ROTL64( even[2*j+1] ^ odd[2*j+1], 4*j+7);
    }

    //keccak((uint8_t*)even,HASH_SIZE,(uint8_t*)odd,HASH_SIZE);
    keccak((uint64_t*)even,HASH_SIZE,(uint64_t*)odd,HASH_SIZE);
  }
  result=0;

   for(i=0;i<RESULT_SIZE;i++) {
#pragma HLS UNROLL
    result += (even[i] ^ odd[i]);
  }
  return result;
}

/*
 * WRITE RESULTS IN MMIO REGS
 *
 * Always check that ALL Outputs are tied to a value or HLS will generate a
 * Action_Output_i and a Action_Output_o registers and address to read results
 * will be shifted ...and wrong
 * => easy checking in generated files:
 *   grep 0x184 action_wrapper_ctrl_reg_s_axi.vhd
 * this grep should return nothing if no duplication of registers
 * (which is expected)
 */
static void write_results(action_output_reg *Action_Output,
			  action_input_reg *Action_Input,
			  snapu32_t ReturnCode,
			  snapu64_t field1,
			  snapu64_t field2)
{
	Action_Output->Retc = (snapu32_t)ReturnCode;
	Action_Output->Data.chk_out = field1;
	Action_Output->Data.timer_ticks = field2;
	Action_Output->Data.action_version =  RELEASE_VERSION;
	Action_Output->Reserved = 0;
	Action_Output->Data.in = Action_Input->Data.in;
	Action_Output->Data.chk_type = Action_Input->Data.chk_type;
	Action_Output->Data.chk_in = Action_Input->Data.chk_in;
	Action_Output->Data.pe = Action_Input->Data.pe;
	Action_Output->Data.nb_pe = Action_Input->Data.nb_pe;
	Action_Output->Data.nb_slices = NB_SLICES;
	Action_Output->Data.nb_round = NB_ROUND;
}

//-----------------------------------------------------------------------------
//--- MAIN PROGRAM ------------------------------------------------------------
//-----------------------------------------------------------------------------

/**
 * Remarks: Using pointers for the din_gmem, ... parameters is requiring to
 * to set the depth=... parameter via the pragma below. If missing to do this
 * the cosimulation will not work, since the width of the interface cannot
 * be determined. Using an array din_gmem[...] works too to fix that.
 */
void action_wrapper(snap_membus_t *din_gmem,
		    snap_membus_t *dout_gmem,
		    snap_membus_t *d_ddrmem,
		    action_input_reg *Action_Input,
		    action_output_reg *Action_Output)
{
	// Host Memory AXI Interface
#pragma HLS INTERFACE m_axi depth=256 port=din_gmem bundle=host_mem
#pragma HLS INTERFACE m_axi depth=256 port=dout_gmem bundle=host_mem

#pragma HLS INTERFACE s_axilite depth=256 port=din_gmem bundle=ctrl_reg
#pragma HLS INTERFACE s_axilite depth=256 port=dout_gmem bundle=ctrl_reg

	//DDR memory Interface
#pragma HLS INTERFACE m_axi depth=256 port=d_ddrmem offset=slave bundle=card_mem0
#pragma HLS INTERFACE s_axilite depth=256 port=d_ddrmem bundle=ctrl_reg

	// Host Memory AXI Lite Master Interface
#pragma HLS DATA_PACK variable=Action_Input
#pragma HLS INTERFACE s_axilite port=Action_Input offset=0x080 bundle=ctrl_reg
#pragma HLS DATA_PACK variable=Action_Output
#pragma HLS INTERFACE s_axilite port=Action_Output offset=0x104 bundle=ctrl_reg
#pragma HLS INTERFACE s_axilite port=return bundle=ctrl_reg

	snapu32_t ReturnCode = RET_CODE_OK;
	uint64_t checksum = 0;
	uint32_t slice = 0;
	uint32_t pe, nb_pe;
	uint64_t timer_ticks = 42;

	pe = Action_Input->Data.pe;
	nb_pe = Action_Input->Data.nb_pe;

	/* Intermediate result display */
	write_results(Action_Output, Action_Input, ReturnCode, checksum,
		      timer_ticks);

	do {
		/* Check if the data alignment matches the expectations */
		if (Action_Input->Control.action != SPONGE_ACTION_TYPE) {
			ReturnCode = RET_CODE_FAILURE;
			break;
		}

		for (slice = 0; slice < NB_SLICES; slice++) {
			if (pe == (slice % nb_pe))
				checksum ^= sponge(slice);

			/* Intermediate result display */
			write_results(Action_Output, Action_Input, ReturnCode,
				      checksum, timer_ticks);

		}
		timer_ticks += 42;

	} while (0);

	/* Final output register writes */
	write_results(Action_Output, Action_Input, ReturnCode, checksum,
		      timer_ticks);
}

#ifdef NO_SYNTH

/**
 * FIXME We need to use action_wrapper from here to get the real thing
 * simulated. For now let's take the short path and try without it.
 */
int main(void)
{
	uint64_t slice;
	uint64_t checksum=0;
	short i, rc=0;

	typedef struct {
		uint32_t  pe;
		uint32_t  nb_pe;
		uint64_t checksum;
	} arguments_t;

	static arguments_t sequence[] = {
		{ 0, /*nb_pe =*/  1, /*expected checksum =*/ 0x948dd5b0109342d4 },
		{ 0, /*nb_pe =*/  2, /*expected checksum =*/ 0x0bca19b17df64085 },
		{ 1, /*nb_pe =*/  2, /*expected checksum =*/ 0x9f47cc016d650251 },
		{ 0, /*nb_pe =*/  4, /*expected checksum =*/ 0x7f13a4a377a2c4fe },
		{ 1, /*nb_pe =*/  4, /*expected checksum =*/ 0xee0710b96b0748fb },
		{ 2, /*nb_pe =*/  4, /*expected checksum =*/ 0x74d9bd120a54847b },
		{ 3, /*nb_pe =*/  4, /*expected checksum =*/ 0x7140dcb806624aaa }
	};

	for(i=0; i < 7; i++) {
		checksum = 0;
		for(slice=0;slice<NB_SLICES;slice++) {
			if(sequence[i].pe == (slice % sequence[i].nb_pe))
				checksum ^= sponge(slice);
		}
		printf("pe=%d - nb_pe=%d - processed checksum=%016llx ",
		       sequence[i].pe,
		       sequence[i].nb_pe,
		       (unsigned long long) checksum);
		if (sequence[i].checksum == checksum) {
			printf(" ==> CORRECT \n");
			rc |= 0;
		}
		else {
			printf(" ==> ERROR : expected checksum=%016llx \n",
			       (unsigned long long) sequence[i].checksum);
			rc |= 1;
		}
	}
	if (rc != 0)
		printf("\n\t Checksums are given with use of -DTEST "
		       "flag. Please check you have set it!\n\n");

	return rc;
}

#endif // end of NO_SYNTH flag

<commit_msg>HLS Sponge: Try remviing depencencies on calculation<commit_after>/*
 * Sponge: hash sha-3 (keccak)
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "keccak.H"
#include "action_sponge.H"

#define HASH_SIZE 64
#define RESULT_SIZE 8

#undef TEST /* get faster turn-around time */
#ifdef NO_SYNTH /* TEST */
#  define NB_SLICES 4
#  define NB_ROUND 1<<10
#else
#  ifndef NB_SLICES
#    define NB_SLICES 65536 	/* for real benchmark */
#  endif
#  ifndef NB_ROUND
#    define NB_ROUND 1<<24 	/* for real benchmark */
#  endif
#endif

uint64_t sponge (const uint64_t rank)
{
  uint64_t magic[8] = {0x0123456789abcdeful,0x13579bdf02468aceul,
		       0xfdecba9876543210ul,0xeca86420fdb97531ul,
                       0x571e30cf4b29a86dul,0xd48f0c376e1b29a5ul,
		       0xc5301e9f6b2ad748ul,0x3894d02e5ba71c6ful};
  uint64_t odd[8],even[8],result;
  int i,j;
  int rnd_nb;

   for(i=0;i<RESULT_SIZE;i++) {
#pragma HLS UNROLL
    even[i] = magic[i] + rank;
  }

  //keccak((uint8_t*)even,HASH_SIZE,(uint8_t*)odd,HASH_SIZE);
  keccak((uint64_t*)even,HASH_SIZE,(uint64_t*)odd,HASH_SIZE);

   for(rnd_nb=0;rnd_nb<NB_ROUND;rnd_nb++) {
//#pragma HLS UNROLL factor=2

    for(j=0;j<4;j++) {
#pragma HLS UNROLL
      odd[2*j] ^= ROTL64( even[2*j] , 4*j+1);
      odd[2*j+1] = ROTL64( even[2*j+1] + odd[2*j+1], 4*j+3);
    }

    //keccak((uint8_t*)odd,HASH_SIZE,(uint8_t*)even,HASH_SIZE);
    keccak((uint64_t*)odd,HASH_SIZE,(uint64_t*)even,HASH_SIZE);

     for(j=0;j<4;j++) {
#pragma HLS UNROLL
      even[2*j] += ROTL64( odd[2*j] , 4*j+5);
      even[2*j+1] = ROTL64( even[2*j+1] ^ odd[2*j+1], 4*j+7);
    }

    //keccak((uint8_t*)even,HASH_SIZE,(uint8_t*)odd,HASH_SIZE);
    keccak((uint64_t*)even,HASH_SIZE,(uint64_t*)odd,HASH_SIZE);
  }
  result=0;

   for(i=0;i<RESULT_SIZE;i++) {
#pragma HLS UNROLL
    result += (even[i] ^ odd[i]);
  }
  return result;
}

/*
 * WRITE RESULTS IN MMIO REGS
 *
 * Always check that ALL Outputs are tied to a value or HLS will generate a
 * Action_Output_i and a Action_Output_o registers and address to read results
 * will be shifted ...and wrong
 * => easy checking in generated files:
 *   grep 0x184 action_wrapper_ctrl_reg_s_axi.vhd
 * this grep should return nothing if no duplication of registers
 * (which is expected)
 */
static void write_results(action_output_reg *Action_Output,
			  action_input_reg *Action_Input,
			  snapu32_t ReturnCode,
			  snapu64_t field1,
			  snapu64_t field2)
{
	Action_Output->Retc = (snapu32_t)ReturnCode;
	Action_Output->Data.chk_out = field1;
	Action_Output->Data.timer_ticks = field2;
	Action_Output->Data.action_version =  RELEASE_VERSION;
	Action_Output->Reserved = 0;
	Action_Output->Data.in = Action_Input->Data.in;
	Action_Output->Data.chk_type = Action_Input->Data.chk_type;
	Action_Output->Data.chk_in = Action_Input->Data.chk_in;
	Action_Output->Data.pe = Action_Input->Data.pe;
	Action_Output->Data.nb_pe = Action_Input->Data.nb_pe;
	Action_Output->Data.nb_slices = NB_SLICES;
	Action_Output->Data.nb_round = NB_ROUND;
}

//-----------------------------------------------------------------------------
//--- MAIN PROGRAM ------------------------------------------------------------
//-----------------------------------------------------------------------------

/**
 * Remarks: Using pointers for the din_gmem, ... parameters is requiring to
 * to set the depth=... parameter via the pragma below. If missing to do this
 * the cosimulation will not work, since the width of the interface cannot
 * be determined. Using an array din_gmem[...] works too to fix that.
 */
void action_wrapper(snap_membus_t *din_gmem,
		    snap_membus_t *dout_gmem,
		    snap_membus_t *d_ddrmem,
		    action_input_reg *Action_Input,
		    action_output_reg *Action_Output)
{
	// Host Memory AXI Interface
#pragma HLS INTERFACE m_axi depth=256 port=din_gmem bundle=host_mem
#pragma HLS INTERFACE m_axi depth=256 port=dout_gmem bundle=host_mem

#pragma HLS INTERFACE s_axilite depth=256 port=din_gmem bundle=ctrl_reg
#pragma HLS INTERFACE s_axilite depth=256 port=dout_gmem bundle=ctrl_reg

	//DDR memory Interface
#pragma HLS INTERFACE m_axi depth=256 port=d_ddrmem offset=slave bundle=card_mem0
#pragma HLS INTERFACE s_axilite depth=256 port=d_ddrmem bundle=ctrl_reg

	// Host Memory AXI Lite Master Interface
#pragma HLS DATA_PACK variable=Action_Input
#pragma HLS INTERFACE s_axilite port=Action_Input offset=0x080 bundle=ctrl_reg
#pragma HLS DATA_PACK variable=Action_Output
#pragma HLS INTERFACE s_axilite port=Action_Output offset=0x104 bundle=ctrl_reg
#pragma HLS INTERFACE s_axilite port=return bundle=ctrl_reg

	snapu32_t ReturnCode = RET_CODE_OK;
	uint64_t checksum = 0;
	uint32_t slice = 0;
	uint32_t pe, nb_pe;
	uint64_t timer_ticks = 42;

	pe = Action_Input->Data.pe;
	nb_pe = Action_Input->Data.nb_pe;

	/* Intermediate result display */
	write_results(Action_Output, Action_Input, ReturnCode, checksum,
		      timer_ticks);

	do {
		/* Check if the data alignment matches the expectations */
		if (Action_Input->Control.action != SPONGE_ACTION_TYPE) {
			ReturnCode = RET_CODE_FAILURE;
			break;
		}

		for (slice = 0; slice < NB_SLICES; slice++) {
			if (pe == (slice % nb_pe))
				checksum ^= sponge(slice);

			/* Intermediate result display */
			write_results(Action_Output, Action_Input, ReturnCode,
				      0xfffffffffffffffful, timer_ticks);

		}
		timer_ticks += 42;

	} while (0);

	/* Final output register writes */
	write_results(Action_Output, Action_Input, ReturnCode, checksum,
		      timer_ticks);
}

#ifdef NO_SYNTH

/**
 * FIXME We need to use action_wrapper from here to get the real thing
 * simulated. For now let's take the short path and try without it.
 */
int main(void)
{
	uint64_t slice;
	uint64_t checksum=0;
	short i, rc=0;

	typedef struct {
		uint32_t  pe;
		uint32_t  nb_pe;
		uint64_t checksum;
	} arguments_t;

	static arguments_t sequence[] = {
		{ 0, /*nb_pe =*/  1, /*expected checksum =*/ 0x948dd5b0109342d4 },
		{ 0, /*nb_pe =*/  2, /*expected checksum =*/ 0x0bca19b17df64085 },
		{ 1, /*nb_pe =*/  2, /*expected checksum =*/ 0x9f47cc016d650251 },
		{ 0, /*nb_pe =*/  4, /*expected checksum =*/ 0x7f13a4a377a2c4fe },
		{ 1, /*nb_pe =*/  4, /*expected checksum =*/ 0xee0710b96b0748fb },
		{ 2, /*nb_pe =*/  4, /*expected checksum =*/ 0x74d9bd120a54847b },
		{ 3, /*nb_pe =*/  4, /*expected checksum =*/ 0x7140dcb806624aaa }
	};

	for(i=0; i < 7; i++) {
		checksum = 0;
		for(slice=0;slice<NB_SLICES;slice++) {
			if(sequence[i].pe == (slice % sequence[i].nb_pe))
				checksum ^= sponge(slice);
		}
		printf("pe=%d - nb_pe=%d - processed checksum=%016llx ",
		       sequence[i].pe,
		       sequence[i].nb_pe,
		       (unsigned long long) checksum);
		if (sequence[i].checksum == checksum) {
			printf(" ==> CORRECT \n");
			rc |= 0;
		}
		else {
			printf(" ==> ERROR : expected checksum=%016llx \n",
			       (unsigned long long) sequence[i].checksum);
			rc |= 1;
		}
	}
	if (rc != 0)
		printf("\n\t Checksums are given with use of -DTEST "
		       "flag. Please check you have set it!\n\n");

	return rc;
}

#endif // end of NO_SYNTH flag

<|endoftext|>


<commit_before>// Copyright (c) 2012-2013, the scalloc Project Authors.  All rights reserved.
// Please see the AUTHORS file for details.  Use of this source code is governed
// by a BSD license that can be found in the LICENSE file.

#include "scalloc.h"

#include <errno.h>
#include <string.h>

#include "allocators/large_object_allocator.h"
#include "allocators/dq_sc_allocator.h"
#include "allocators/slab_sc_allocator.h"
#include "common.h"
#include "runtime_vars.h"
#include "scalloc_guard.h"
#include "size_map.h"
#include "thread_cache.h"

static int scallocguard_refcount = 0;
ScallocGuard::ScallocGuard() {
  if (scallocguard_refcount++ == 0) {
    RuntimeVars::InitModule();
    scalloc::SizeMap::InitModule();

    scalloc::DQScAllocator::InitModule();
    scalloc::SlabScAllocator::InitModule();

    free(malloc(1));
  }
}

ScallocGuard::~ScallocGuard() {
  if (--scallocguard_refcount == 0) {
  }
}

static ScallocGuard StartupExitHook;

namespace scalloc {

always_inline void* malloc(const size_t size) {
  void* p;
  if (LIKELY(size <= kMaxSmallSize)) {
    p = ThreadCache::GetCache().Allocate(size);
  } else {
    p = LargeObjectAllocator::Alloc(size);
  }
  if (UNLIKELY(p == NULL)) {
    errno = ENOMEM;
  }
  return p;
}

always_inline void free(void* p) {
  if (UNLIKELY(p == NULL)) {
    return;
  }
  BlockHeader* hdr = BlockHeader::GetFromObject(p);
  if (hdr->type == kSlab) {
    ThreadCache::GetCache().Free(p, reinterpret_cast<SlabHeader*>(hdr));
  } else if (hdr->type == kLargeObject) {
    LargeObjectAllocator::Free(reinterpret_cast<LargeObjectHeader*>(hdr));
  }
  return;
}

}  // namespace scalloc

//
// Forward C calls to scalloc_fn to their corresponding scalloc::fn
//

extern "C" void* scalloc_malloc(size_t size) __THROW {
  return scalloc::malloc(size);
}

extern "C" void scalloc_free(void* p) __THROW {
  scalloc::free(p);
}

extern "C" void* scalloc_calloc(size_t nmemb, size_t size) __THROW {
  const size_t malloc_size = nmemb * size;
  if (size != 0 && (malloc_size / size) != nmemb) {
    return NULL;
  }
  void* result = scalloc::malloc(malloc_size);  // also sets errno
  if (result != NULL) {
    memset(result, 0, malloc_size);
  }
  return result;
}

extern "C" void* scalloc_realloc(void* ptr, size_t size) __THROW {
  ErrorOut("realloc() not yet implemented.");
}

extern "C" void* scalloc_memalign(size_t __alignment, size_t __size) __THROW {
  ErrorOut("memalign() not yet implemented.");
}

extern "C" int scalloc_posix_memalign(void** ptr, size_t align, size_t size) __THROW {
  ErrorOut("posix_memalign() not yet implemented.");
}

extern "C" void* scalloc_valloc(size_t __size) __THROW {
  ErrorOut("valloc() not yet implemented.");
}

extern "C" void* scalloc_pvalloc(size_t __size) __THROW {
  ErrorOut("pvalloc() not yet implemented.");
}

extern "C" void scalloc_malloc_stats(void) __THROW {
  ErrorOut("malloc_stats() not yet implemented.");
}

extern "C" int scalloc_mallopt(int cmd, int value) __THROW {
  ErrorOut("mallopt() not yet implemented.");
}
<commit_msg>Provide naive implementation for realloc()<commit_after>// Copyright (c) 2012-2013, the scalloc Project Authors.  All rights reserved.
// Please see the AUTHORS file for details.  Use of this source code is governed
// by a BSD license that can be found in the LICENSE file.

#include "scalloc.h"

#include <errno.h>
#include <string.h>

#include "allocators/large_object_allocator.h"
#include "allocators/dq_sc_allocator.h"
#include "allocators/slab_sc_allocator.h"
#include "common.h"
#include "runtime_vars.h"
#include "scalloc_guard.h"
#include "size_map.h"
#include "thread_cache.h"

static int scallocguard_refcount = 0;
ScallocGuard::ScallocGuard() {
  if (scallocguard_refcount++ == 0) {
    RuntimeVars::InitModule();
    scalloc::SizeMap::InitModule();

    scalloc::DQScAllocator::InitModule();
    scalloc::SlabScAllocator::InitModule();

    free(malloc(1));
  }
}

ScallocGuard::~ScallocGuard() {
  if (--scallocguard_refcount == 0) {
  }
}

static ScallocGuard StartupExitHook;

namespace scalloc {

always_inline void* malloc(const size_t size) {
  void* p;
  if (LIKELY(size <= kMaxSmallSize)) {
    p = ThreadCache::GetCache().Allocate(size);
  } else {
    p = LargeObjectAllocator::Alloc(size);
  }
  if (UNLIKELY(p == NULL)) {
    errno = ENOMEM;
  }
  return p;
}

always_inline void free(void* p) {
  if (UNLIKELY(p == NULL)) {
    return;
  }
  BlockHeader* hdr = BlockHeader::GetFromObject(p);
  if (hdr->type == kSlab) {
    ThreadCache::GetCache().Free(p, reinterpret_cast<SlabHeader*>(hdr));
  } else if (hdr->type == kLargeObject) {
    LargeObjectAllocator::Free(reinterpret_cast<LargeObjectHeader*>(hdr));
  }
  return;
}

}  // namespace scalloc

//
// Forward C calls to scalloc_fn to their corresponding scalloc::fn
//

extern "C" void* scalloc_malloc(size_t size) __THROW {
  return scalloc::malloc(size);
}

extern "C" void scalloc_free(void* p) __THROW {
  scalloc::free(p);
}

extern "C" void* scalloc_calloc(size_t nmemb, size_t size) __THROW {
  const size_t malloc_size = nmemb * size;
  if (size != 0 && (malloc_size / size) != nmemb) {
    return NULL;
  }
  void* result = scalloc::malloc(malloc_size);  // also sets errno
  if (result != NULL) {
    memset(result, 0, malloc_size);
  }
  return result;
}

extern "C" void* scalloc_realloc(void* ptr, size_t size) __THROW {
  if (ptr == NULL) {
    return scalloc::malloc(size);
  }
  void* new_ptr;
  size_t old_size;
  BlockHeader* hdr = BlockHeader::GetFromObject(ptr);
  if (LIKELY(hdr->type == kSlab)) {
    old_size = scalloc::SizeMap::Instance().ClassToSize(
        reinterpret_cast<SlabHeader*>(hdr)->size_class);
  } else {
    old_size = reinterpret_cast<LargeObjectHeader*>(hdr)->size -
               sizeof(LargeObjectHeader);
  }
  if (size <= old_size) {
    return ptr;
  } else {
    new_ptr = scalloc::malloc(size);
    if (LIKELY(new_ptr != NULL)) {
      memcpy(new_ptr, ptr, old_size);
      scalloc::free(ptr);
    }
  }
  return new_ptr;
}

extern "C" void* scalloc_memalign(size_t __alignment, size_t __size) __THROW {
  ErrorOut("memalign() not yet implemented.");
}

extern "C" int scalloc_posix_memalign(void** ptr, size_t align, size_t size) __THROW {
  ErrorOut("posix_memalign() not yet implemented.");
}

extern "C" void* scalloc_valloc(size_t __size) __THROW {
  ErrorOut("valloc() not yet implemented.");
}

extern "C" void* scalloc_pvalloc(size_t __size) __THROW {
  ErrorOut("pvalloc() not yet implemented.");
}

extern "C" void scalloc_malloc_stats(void) __THROW {
  ErrorOut("malloc_stats() not yet implemented.");
}

extern "C" int scalloc_mallopt(int cmd, int value) __THROW {
  ErrorOut("mallopt() not yet implemented.");
}
<|endoftext|>


<commit_before>#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
    sampleRate = 48000;
    channels = 1;
    ofSetFrameRate(30);

    ofSetLogLevel(OF_LOG_VERBOSE);
    vidGrabber.setDesiredFrameRate(30);
    vidGrabber.initGrabber(640, 360);
//    vidRecorder.setFfmpegLocation(ofFilePath::getAbsolutePath("ffmpeg")); // use this is you have ffmpeg installed in your data folder

    vidRecorder.setVideoCodec("h264");
    vidRecorder.setVideoBitrate("800k");

    soundStream.listDevices();
    soundStream.setup(this, 0, 1, sampleRate, 256, 4);

    ofSetWindowShape(vidGrabber.getWidth(), vidGrabber.getHeight()	);
    bRecording = false;
    ofEnableAlphaBlending();
}

void testApp::exit() {
    vidRecorder.close();
}

//--------------------------------------------------------------
void testApp::update(){
    vidGrabber.update();
    if(vidGrabber.isFrameNew() && bRecording){
        vidRecorder.addFrame(vidGrabber.getPixelsRef());
    }
}

//--------------------------------------------------------------
void testApp::draw(){
    ofSetColor(255, 255, 255);
    vidGrabber.draw(0,0);

    stringstream ss;
    ss << "video queue size: " << vidRecorder.getVideoQueueSize() << endl
    << "audio queue size: " << vidRecorder.getAudioQueueSize() << endl
    << "FPS: " << ofGetFrameRate() << endl
    << (bRecording?"pause":"start") << " recording: r" << endl
    << (bRecording?"close current video file: c":"") << endl;

    ofSetColor(0,0,0,100);
    ofRect(0, 0, 260, 65);
    ofSetColor(255, 255, 255);
    ofDrawBitmapString(ss.str(),15,15);

    if(bRecording){
    ofSetColor(255, 0, 0);
    ofCircle(ofGetWidth() - 20, 20, 5);
    }
}

void testApp::audioIn(float *input, int bufferSize, int nChannels){
    if(bRecording)
        vidRecorder.addAudioSamples(input, bufferSize, nChannels);
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

    if(key=='r'){
        bRecording = !bRecording;
        if(bRecording && !vidRecorder.isInitialized()) {
            vidRecorder.setup("testMovie"+ofGetTimestampString()+".mov", vidGrabber.getWidth(), vidGrabber.getHeight(), 30, sampleRate, channels);
            //    vidRecorder.setup("testMovie"+ofGetTimestampString()+".mov", vidGrabber.getWidth(), vidGrabber.getHeight(), 30);
            //    vidRecorder.setupCustomOutput(vidGrabber.getWidth(), vidGrabber.getHeight(), 15, "-vcodec h264 -sameq -f mpegts udp://localhost:1234"); // for custom ffmpeg output string (streaming, etc)
        }
    }
    if(key=='c'){
        bRecording = false;
        vidRecorder.close();
    }
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>resized the info overlay to accomodate new audio queue line<commit_after>#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
    sampleRate = 48000;
    channels = 1;
    ofSetFrameRate(30);

    ofSetLogLevel(OF_LOG_VERBOSE);
    vidGrabber.setDesiredFrameRate(30);
    vidGrabber.initGrabber(640, 360);
//    vidRecorder.setFfmpegLocation(ofFilePath::getAbsolutePath("ffmpeg")); // use this is you have ffmpeg installed in your data folder

    vidRecorder.setVideoCodec("h264");
    vidRecorder.setVideoBitrate("800k");

    soundStream.listDevices();
    soundStream.setup(this, 0, 1, sampleRate, 256, 4);

    ofSetWindowShape(vidGrabber.getWidth(), vidGrabber.getHeight()	);
    bRecording = false;
    ofEnableAlphaBlending();
}

void testApp::exit() {
    vidRecorder.close();
}

//--------------------------------------------------------------
void testApp::update(){
    vidGrabber.update();
    if(vidGrabber.isFrameNew() && bRecording){
        vidRecorder.addFrame(vidGrabber.getPixelsRef());
    }
}

//--------------------------------------------------------------
void testApp::draw(){
    ofSetColor(255, 255, 255);
    vidGrabber.draw(0,0);

    stringstream ss;
    ss << "video queue size: " << vidRecorder.getVideoQueueSize() << endl
    << "audio queue size: " << vidRecorder.getAudioQueueSize() << endl
    << "FPS: " << ofGetFrameRate() << endl
    << (bRecording?"pause":"start") << " recording: r" << endl
    << (bRecording?"close current video file: c":"") << endl;

    ofSetColor(0,0,0,100);
    ofRect(0, 0, 260, 75);
    ofSetColor(255, 255, 255);
    ofDrawBitmapString(ss.str(),15,15);

    if(bRecording){
    ofSetColor(255, 0, 0);
    ofCircle(ofGetWidth() - 20, 20, 5);
    }
}

void testApp::audioIn(float *input, int bufferSize, int nChannels){
    if(bRecording)
        vidRecorder.addAudioSamples(input, bufferSize, nChannels);
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

    if(key=='r'){
        bRecording = !bRecording;
        if(bRecording && !vidRecorder.isInitialized()) {
            vidRecorder.setup("testMovie"+ofGetTimestampString()+".mov", vidGrabber.getWidth(), vidGrabber.getHeight(), 30, sampleRate, channels);
            //    vidRecorder.setup("testMovie"+ofGetTimestampString()+".mov", vidGrabber.getWidth(), vidGrabber.getHeight(), 30);
            //    vidRecorder.setupCustomOutput(vidGrabber.getWidth(), vidGrabber.getHeight(), 15, "-vcodec h264 -sameq -f mpegts udp://localhost:1234"); // for custom ffmpeg output string (streaming, etc)
        }
    }
    if(key=='c'){
        bRecording = false;
        vidRecorder.close();
    }
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>//===--- swift-reflection-dump.cpp - Reflection testing application -------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
// This is a host-side tool to dump remote reflection sections in swift
// binaries.
//===----------------------------------------------------------------------===//

#include "swift/ABI/MetadataValues.h"
#include "swift/Demangling/Demangle.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Reflection/ReflectionContext.h"
#include "swift/Reflection/TypeRef.h"
#include "swift/Reflection/TypeRefBuilder.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/CommandLine.h"

#if defined(_WIN32)
#include <io.h>
#else
#include <unistd.h>
#endif

#include <algorithm>
#include <iostream>
#include <csignal>

using llvm::dyn_cast;
using llvm::StringRef;
using llvm::ArrayRef;
using namespace llvm::object;

using namespace swift;
using namespace swift::reflection;
using namespace swift::remote;
using namespace Demangle;

enum class ActionType {
  DumpReflectionSections,
  DumpTypeLowering
};

namespace options {
static llvm::cl::opt<ActionType>
Action(llvm::cl::desc("Mode:"),
       llvm::cl::values(
         clEnumValN(ActionType::DumpReflectionSections,
                    "dump-reflection-sections",
                    "Dump the field reflection section"),
         clEnumValN(ActionType::DumpTypeLowering,
                    "dump-type-lowering",
                    "Dump the field layout for typeref strings read from stdin")),
       llvm::cl::init(ActionType::DumpReflectionSections));

static llvm::cl::list<std::string>
BinaryFilename("binary-filename", llvm::cl::desc("Filenames of the binary files"),
               llvm::cl::OneOrMore);

static llvm::cl::opt<std::string>
Architecture("arch", llvm::cl::desc("Architecture to inspect in the binary"),
             llvm::cl::Required);
} // end namespace options

template<typename T>
static T unwrap(llvm::Expected<T> value) {
  if (value)
    return std::move(value.get());
  std::cerr << "swift-reflection-test error: " << toString(value.takeError()) << "\n";
  exit(EXIT_FAILURE);
}

using NativeReflectionContext
  = ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>;

class ObjectMemoryReader : public MemoryReader {
  const std::vector<const ObjectFile *> &ObjectFiles;
public:
  ObjectMemoryReader(const std::vector<const ObjectFile *> &ObjectFiles)
    : ObjectFiles(ObjectFiles)
  {
  }

  bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
                       void *outBuffer) override {
    switch (type) {
      case DLQ_GetPointerSize: {
        auto result = static_cast<uint8_t *>(outBuffer);
        *result = sizeof(void *);
        return true;
      }
      case DLQ_GetSizeSize: {
        auto result = static_cast<uint8_t *>(outBuffer);
        *result = sizeof(size_t);
        return true;
      }
    }

    return false;
  }

  RemoteAddress getSymbolAddress(const std::string &name) override {
    for (auto &object : ObjectFiles) {
      for (auto &symbol : object->symbols()) {
        if (unwrap(symbol.getName()).equals(name)) {
          // TODO: Account for offset in ELF binaries
          return RemoteAddress(unwrap(symbol.getAddress()));
        }
      }
    }
    return RemoteAddress(nullptr);
  }

  bool isAddressValid(RemoteAddress addr, uint64_t size) const {
    // TODO: Account for offset in ELF binaries

    auto src = addr.getAddressData();

    // Check that the source is in bounds of one of the object files.
    for (auto &object : ObjectFiles) {
      if ((uint64_t)object->getData().bytes_begin() <= src
          && src + size <= (uint64_t)object->getData().bytes_end()) {
        return true;
      }
    }
    return false;
  }

  ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
    if (!isAddressValid(address, size))
      return ReadBytesResult(nullptr, [](const void *){});

    // TODO: Account for offset in ELF binaries
    return ReadBytesResult((const void *)address.getAddressData(), [](const void *) {});
  }

  bool readString(RemoteAddress address, std::string &dest) override {
    if (!isAddressValid(address, 1))
      return false;
    // TODO: Account for running off the edge of an object, offset in ELF
    // binaries
    auto cString = StringRef((const char*)address.getAddressData());
    dest.append(cString.begin(), cString.end());
    return true;
  }
};

static int doDumpReflectionSections(ArrayRef<std::string> binaryFilenames,
                                    StringRef arch,
                                    ActionType action,
                                    std::ostream &OS) {
  // Note: binaryOrError and objectOrError own the memory for our ObjectFile;
  // once they go out of scope, we can no longer do anything.
  std::vector<OwningBinary<Binary>> binaryOwners;
  std::vector<std::unique_ptr<ObjectFile>> objectOwners;
  std::vector<const ObjectFile *> objectFiles;

  // Construct the ReflectionContext.
  // FIXME: Should pick a Runtime template based on the bitwidth of the target
  // architecture.
  auto reader = std::make_shared<ObjectMemoryReader>(objectFiles);
  NativeReflectionContext context(std::move(reader));

  for (auto binaryFilename : binaryFilenames) {
    auto binaryOwner = unwrap(createBinary(binaryFilename));
    Binary *binaryFile = binaryOwner.getBinary();

    // The object file we are doing lookups in -- either the binary itself, or
    // a particular slice of a universal binary.
    std::unique_ptr<ObjectFile> objectOwner;
    const ObjectFile *objectFile;

    if (auto o = dyn_cast<ObjectFile>(binaryFile)) {
      objectFile = o;
    } else {
      auto universal = cast<MachOUniversalBinary>(binaryFile);
      objectOwner = unwrap(universal->getObjectForArch(arch));
      objectFile = objectOwner.get();
    }

    // Retain the objects that own section memory
    binaryOwners.push_back(std::move(binaryOwner));
    objectOwners.push_back(std::move(objectOwner));
    objectFiles.push_back(objectFile);

    auto startAddress = (uintptr_t)objectFile->getData().begin();
    context.addImage(RemoteAddress(startAddress));
  }

  switch (action) {
  case ActionType::DumpReflectionSections:
    // Dump everything
    context.getBuilder().dumpAllSections(OS);
    break;
  case ActionType::DumpTypeLowering: {
    for (std::string line; std::getline(std::cin, line); ) {
      if (line.empty())
        continue;

      if (StringRef(line).startswith("//"))
        continue;

      Demangle::Demangler Dem;
      auto demangled = Dem.demangleType(line);
      auto *typeRef = swift::Demangle::decodeMangledType(context.getBuilder(),
                                                         demangled);
      if (typeRef == nullptr) {
        OS << "Invalid typeref: " << line << "\n";
        continue;
      }

      typeRef->dump(OS);
      auto *typeInfo =
        context.getBuilder().getTypeConverter().getTypeInfo(typeRef);
      if (typeInfo == nullptr) {
        OS << "Invalid lowering\n";
        continue;
      }
      typeInfo->dump(OS);
    }
    break;
  }
  }

  return EXIT_SUCCESS;
}

int main(int argc, char *argv[]) {
  PROGRAM_START(argc, argv);
  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift Reflection Dump\n");
  return doDumpReflectionSections(options::BinaryFilename,
                                  options::Architecture,
                                  options::Action,
                                  std::cout);
}

<commit_msg>swift-reflection-dump: use elaborated type name<commit_after>//===--- swift-reflection-dump.cpp - Reflection testing application -------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
// This is a host-side tool to dump remote reflection sections in swift
// binaries.
//===----------------------------------------------------------------------===//

#include "swift/ABI/MetadataValues.h"
#include "swift/Demangling/Demangle.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Reflection/ReflectionContext.h"
#include "swift/Reflection/TypeRef.h"
#include "swift/Reflection/TypeRefBuilder.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/CommandLine.h"

#if defined(_WIN32)
#include <io.h>
#else
#include <unistd.h>
#endif

#include <algorithm>
#include <iostream>
#include <csignal>

using llvm::dyn_cast;
using llvm::StringRef;
using llvm::ArrayRef;
using namespace llvm::object;

using namespace swift;
using namespace swift::reflection;
using namespace swift::remote;
using namespace Demangle;

enum class ActionType {
  DumpReflectionSections,
  DumpTypeLowering
};

namespace options {
static llvm::cl::opt<ActionType>
Action(llvm::cl::desc("Mode:"),
       llvm::cl::values(
         clEnumValN(ActionType::DumpReflectionSections,
                    "dump-reflection-sections",
                    "Dump the field reflection section"),
         clEnumValN(ActionType::DumpTypeLowering,
                    "dump-type-lowering",
                    "Dump the field layout for typeref strings read from stdin")),
       llvm::cl::init(ActionType::DumpReflectionSections));

static llvm::cl::list<std::string>
BinaryFilename("binary-filename", llvm::cl::desc("Filenames of the binary files"),
               llvm::cl::OneOrMore);

static llvm::cl::opt<std::string>
Architecture("arch", llvm::cl::desc("Architecture to inspect in the binary"),
             llvm::cl::Required);
} // end namespace options

template<typename T>
static T unwrap(llvm::Expected<T> value) {
  if (value)
    return std::move(value.get());
  std::cerr << "swift-reflection-test error: " << toString(value.takeError()) << "\n";
  exit(EXIT_FAILURE);
}

using NativeReflectionContext
    = swift::reflection::ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>;

class ObjectMemoryReader : public MemoryReader {
  const std::vector<const ObjectFile *> &ObjectFiles;
public:
  ObjectMemoryReader(const std::vector<const ObjectFile *> &ObjectFiles)
    : ObjectFiles(ObjectFiles)
  {
  }

  bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
                       void *outBuffer) override {
    switch (type) {
      case DLQ_GetPointerSize: {
        auto result = static_cast<uint8_t *>(outBuffer);
        *result = sizeof(void *);
        return true;
      }
      case DLQ_GetSizeSize: {
        auto result = static_cast<uint8_t *>(outBuffer);
        *result = sizeof(size_t);
        return true;
      }
    }

    return false;
  }

  RemoteAddress getSymbolAddress(const std::string &name) override {
    for (auto &object : ObjectFiles) {
      for (auto &symbol : object->symbols()) {
        if (unwrap(symbol.getName()).equals(name)) {
          // TODO: Account for offset in ELF binaries
          return RemoteAddress(unwrap(symbol.getAddress()));
        }
      }
    }
    return RemoteAddress(nullptr);
  }

  bool isAddressValid(RemoteAddress addr, uint64_t size) const {
    // TODO: Account for offset in ELF binaries

    auto src = addr.getAddressData();

    // Check that the source is in bounds of one of the object files.
    for (auto &object : ObjectFiles) {
      if ((uint64_t)object->getData().bytes_begin() <= src
          && src + size <= (uint64_t)object->getData().bytes_end()) {
        return true;
      }
    }
    return false;
  }

  ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
    if (!isAddressValid(address, size))
      return ReadBytesResult(nullptr, [](const void *){});

    // TODO: Account for offset in ELF binaries
    return ReadBytesResult((const void *)address.getAddressData(), [](const void *) {});
  }

  bool readString(RemoteAddress address, std::string &dest) override {
    if (!isAddressValid(address, 1))
      return false;
    // TODO: Account for running off the edge of an object, offset in ELF
    // binaries
    auto cString = StringRef((const char*)address.getAddressData());
    dest.append(cString.begin(), cString.end());
    return true;
  }
};

static int doDumpReflectionSections(ArrayRef<std::string> binaryFilenames,
                                    StringRef arch,
                                    ActionType action,
                                    std::ostream &OS) {
  // Note: binaryOrError and objectOrError own the memory for our ObjectFile;
  // once they go out of scope, we can no longer do anything.
  std::vector<OwningBinary<Binary>> binaryOwners;
  std::vector<std::unique_ptr<ObjectFile>> objectOwners;
  std::vector<const ObjectFile *> objectFiles;

  // Construct the ReflectionContext.
  // FIXME: Should pick a Runtime template based on the bitwidth of the target
  // architecture.
  auto reader = std::make_shared<ObjectMemoryReader>(objectFiles);
  NativeReflectionContext context(std::move(reader));

  for (auto binaryFilename : binaryFilenames) {
    auto binaryOwner = unwrap(createBinary(binaryFilename));
    Binary *binaryFile = binaryOwner.getBinary();

    // The object file we are doing lookups in -- either the binary itself, or
    // a particular slice of a universal binary.
    std::unique_ptr<ObjectFile> objectOwner;
    const ObjectFile *objectFile;

    if (auto o = dyn_cast<ObjectFile>(binaryFile)) {
      objectFile = o;
    } else {
      auto universal = cast<MachOUniversalBinary>(binaryFile);
      objectOwner = unwrap(universal->getObjectForArch(arch));
      objectFile = objectOwner.get();
    }

    // Retain the objects that own section memory
    binaryOwners.push_back(std::move(binaryOwner));
    objectOwners.push_back(std::move(objectOwner));
    objectFiles.push_back(objectFile);

    auto startAddress = (uintptr_t)objectFile->getData().begin();
    context.addImage(RemoteAddress(startAddress));
  }

  switch (action) {
  case ActionType::DumpReflectionSections:
    // Dump everything
    context.getBuilder().dumpAllSections(OS);
    break;
  case ActionType::DumpTypeLowering: {
    for (std::string line; std::getline(std::cin, line); ) {
      if (line.empty())
        continue;

      if (StringRef(line).startswith("//"))
        continue;

      Demangle::Demangler Dem;
      auto demangled = Dem.demangleType(line);
      auto *typeRef = swift::Demangle::decodeMangledType(context.getBuilder(),
                                                         demangled);
      if (typeRef == nullptr) {
        OS << "Invalid typeref: " << line << "\n";
        continue;
      }

      typeRef->dump(OS);
      auto *typeInfo =
        context.getBuilder().getTypeConverter().getTypeInfo(typeRef);
      if (typeInfo == nullptr) {
        OS << "Invalid lowering\n";
        continue;
      }
      typeInfo->dump(OS);
    }
    break;
  }
  }

  return EXIT_SUCCESS;
}

int main(int argc, char *argv[]) {
  PROGRAM_START(argc, argv);
  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift Reflection Dump\n");
  return doDumpReflectionSections(options::BinaryFilename,
                                  options::Architecture,
                                  options::Action,
                                  std::cout);
}

<|endoftext|>


<commit_before>#include "slre.h"
#include <string.h>
#include <stdbool.h>
#include "rest.hpp"

namespace ouroboros

{
	static const char * full_regex = "^/group/([^/]+)/name/([^/]+)$";
	static const char * group_regex = "^/group/([^/]+)$";

	bool is_REST_URI(const char* aURI)
	{
		int result = slre_match(full_regex, aURI, strlen(aURI), NULL, 0, 0);
		result |= slre_match(group_regex, aURI, strlen(aURI), NULL, 0, 0);
		return (result >= 0);
	}

	void extract_group_name(const char* aURI, char *aGroupName, size_t groupLength, char *aName, size_t aNameLength)
	{
		struct slre_cap match[2];
		//FIXME should we limit the size?
		int result = slre_match(full_regex, aURI, strlen(aURI), match, 2, 0);
		memcpy(aGroupName, match[0].ptr, match[0].len); //FIXME actually limit the size
		memcpy(aName, match[1].ptr, match[1].len); //FIXME actually limit the size
	}

	void extract_group(const char* aURI, char *aGroupName, size_t groupLength)
	{
		struct slre_cap match[1];
	    //FIXME should we limit the size?
	    int result = slre_match(group_regex, aURI, strlen(aURI), match, 1, 0);
	    memcpy(aGroupName, match[0].ptr, match[0].len); //FIXME actually limit the size
	}
}
<commit_msg>Fixed a bug where is_REST_API was plain wrong. Original implementation assumed zero would be returned on error, and this is not the case.<commit_after>#include "slre.h"
#include <string.h>
#include <stdbool.h>
#include "rest.hpp"

namespace ouroboros
{
	static const char * full_regex = "^/group/([^/]+)/name/([^/]+)$";
	static const char * group_regex = "^/group/([^/]+)$";

	bool is_REST_URI(const char* aURI)
	{
		int result = slre_match(full_regex, aURI, strlen(aURI), NULL, 0, 0);
		int group_result = slre_match(group_regex, aURI, strlen(aURI), NULL, 0, 0);
		return (result >= 0 || group_result >= 0);
	}

	void extract_group_name(const char* aURI, char *aGroupName, size_t groupLength, char *aName, size_t aNameLength)
	{
		struct slre_cap match[2];
		//FIXME should we limit the size?
		int result = slre_match(full_regex, aURI, strlen(aURI), match, 2, 0);
		memcpy(aGroupName, match[0].ptr, match[0].len); //FIXME actually limit the size
		memcpy(aName, match[1].ptr, match[1].len); //FIXME actually limit the size
	}

	void extract_group(const char* aURI, char *aGroupName, size_t groupLength)
	{
		struct slre_cap match[1];
	    //FIXME should we limit the size?
	    int result = slre_match(group_regex, aURI, strlen(aURI), match, 1, 0);
	    memcpy(aGroupName, match[0].ptr, match[0].len); //FIXME actually limit the size
	}
}
<|endoftext|>