<commit_before>#include "../debug/anglib.hpp"

using anglib::Const::pi; // Угол в 180 градусов
using anglib::Deg; // Тип для хранения градусного представления
using anglib::Hour; // Тип для хранения часового предствления

//-------Для параметризации рекомендуется использовать
//---знаковые целые типы, например:
typedef Deg<short> degshort;
typedef Hour<short> hourshort;

typedef Deg<int> degint;
typedef Hour<int> hourint;

//-------Плохой выбор:
typedef Deg<uint> udegint;
typedef Hour<uint> uhourint;

int main()
{
	degshort zero; // -- по-умолчанию, нулевой угол
	hourshort hzero;

	std::cout << zero << "\n"; // -- можно выводить так
	std::cout << hzero << "\n";

	//--Конструктор от арифметического типа, приводящегося
	//--к double, порождает угол с радианной мерой, равной
	//--значению в double, к которому привелся тип.
	degshort radian(1); //  -- угол в один радиан
	hourshort hradian(1);

	std::cout << radian << "\n";
	std::cout << hradian << "\n";

	//--Конструктор от списка: два значения одинаковых целых
	//--арифметических типов, и double.
	degint a(0, 1, 2.08); // -- угол 1' 2.08"
	hourint ha(0, 1, 2.08); // -- угол 1m 2.08s

	std::cout << a << "\n";
	std::cout << ha << "\n";

	degint b(-15, 300, -61); // -- такой список будет коррект-
							 // -- но обработан согласно ариф-
							 // -- метике -15g + 300' - 61",
							 // -- что может быть использовано
							 // -- в вычислениях с сильно отли-
							 // -- чающимися по порядку значе-
							 // -- ниями
	hourint hb(-15, 300, -61);  // -- аналогично для Hour

	std::cout << b << "\n";
	std::cout << hb << "\n";

	//--Копирующий конструктор от любой допустимой параметриза-
	//--ции:
	degshort c(a); // -- degshort (c) != degint (a) в смысле ти-
				   // -- пов, но можно приводить один к другому:
	degint d = c;

	std::cout << c << "\n";
	std::cout << d << "\n";

	hourshort hc(ha);
	hourint hd = hc;

	d = hc, hd = c; // -- допустимы и такие приведения, разве не
					// -- здорово?!)

	std::cout << c << "\n";
	std::cout << d << "\n";
	std::cout << hc << "\n";
	std::cout << hd << "\n";

	//--Сравнение углов
	degshort da1(180, 1, 0), da2(180, 0, 0.899);
	hourint ha1(24, 1, 0), ha2(24, 0, 0.899);

	std::cout << "da1: " << da1 << "\n" << "da2: " << da2 << "\n"
			  << "ha1: " << ha1 << "\n" << "ha2: " << ha2 << "\n";
								// -- обратите внимание, что
								// -- для нормального приоритета
								// -- операции между << ставим
								// -- скобки:
	std::cout << "da1 < da2 ? " << (da1 < da2) << "\n";
	std::cout << "da1 > da2 ? " << (da1 > da2) << "\n";
	std::cout << "da1 == da2 ? " << (da1 == da2) << "\n";
	std::cout << "da1 != da2 ? " << (da1 != da2) << "\n";
								// -- аналогично для часовых мер
	std::cout << "ha1 < ha2 ? " << (ha1 < ha2) << "\n";
	std::cout << "ha1 > ha2 ? " << (ha1 > ha2) << "\n";
	std::cout << "ha1 == ha2 ? " << (ha1 == ha2) << "\n";
	std::cout << "ha1 != ha2 ? " << (ha1 != ha2) << "\n";
								// -- возможны сравнения в разных
								// -- мерах:
	std::cout << "da1 < ha1 ? " << (da1 < ha2) << "\n";
	std::cout << "da2 > ha2 ? " << (ha1 > da2) << "\n";
	std::cout << "ha1 == da1 ? " << (da1 == ha2) << "\n";
	std::cout << "ha1 != da1 ? " << (da1 != ha1) << "\n";

	//--Арифметика

	//--Допустимо складывать углы в различных мерах и вычитать их
	//--друг из друга:
	std::cout << "radian + radian = " << (radian + radian) << "\n";
	std::cout << "radian - radian = " << (radian - radian) << "\n";

	//----ВАЖНО!
	//--Если складываются два угла в различных мерах, то тип резу-
	//--льтата определяется ЛЕВЫМ операндом. Например, ниже вывод
	//--будет в часах:
	std::cout << "ha1 + da1 = " << (ha1 + da1) << "\n";
	std::cout << "ha1 - da1 = " << (ha1 - da1) << "\n";

	//--Углы можно умножать и делить на числовые типы, и обратно:
	std::cout << "radian * 3.14 = " << (radian * 3.14) << "\n";
	std::cout << "PI * radian = " << (M_PI * radian) << "\n";
	std::cout << "radian / 2 * PI = " << (M_PI * radian / 2) << "\n";
	//--При делении числа на угол происходит преобразование число-
	//--вого типа в угловой, т.е. подразумевается, что делят угол в
	//--радианной мере:
	std::cout << "1 / radian = " << (1 / radian) << "\n";

}
<commit_msg>0.9999 -- complete primary test set<commit_after>#include "../debug/anglib.hpp"

using anglib::Const::pi; // Угол в 180 градусов
using anglib::Deg; // Тип для хранения градусного представления
using anglib::Hour; // Тип для хранения часового предствления

//-------Для параметризации рекомендуется использовать
//---знаковые целые типы, например:
typedef Deg<short> degshort;
typedef Hour<short> hourshort;

typedef Deg<int> degint;
typedef Hour<int> hourint;

//-------Плохой выбор:
typedef Deg<uint> udegint;
typedef Hour<uint> uhourint;

int main()
{
	degshort zero; // -- по-умолчанию, нулевой угол
	hourshort hzero;

	std::cout << zero << "\n"; // -- можно выводить так
	std::cout << hzero << "\n";

	//--Конструктор от арифметического типа, приводящегося
	//--к double, порождает угол с радианной мерой, равной
	//--значению в double, к которому привелся тип.
	degshort radian(1); //  -- угол в один радиан
	hourshort hradian(1);

	std::cout << radian << "\n";
	std::cout << hradian << "\n";

	//--Конструктор от списка: два значения одинаковых целых
	//--арифметических типов, и double.
	degint a(0, 1, 2.08); // -- угол 1' 2.08"
	hourint ha(0, 1, 2.08); // -- угол 1m 2.08s

	std::cout << a << "\n";
	std::cout << ha << "\n";

	degint b(-15, 300, -61); // -- такой список будет коррект-
							 // -- но обработан согласно ариф-
							 // -- метике -15g + 300' - 61",
							 // -- что может быть использовано
							 // -- в вычислениях с сильно отли-
							 // -- чающимися по порядку значе-
							 // -- ниями
	hourint hb(-15, 300, -61);  // -- аналогично для Hour

	std::cout << b << "\n";
	std::cout << hb << "\n";

	//--Копирующий конструктор от любой допустимой параметриза-
	//--ции:
	degshort c(a); // -- degshort (c) != degint (a) в смысле ти-
				   // -- пов, но можно приводить один к другому:
	degint d = c;

	std::cout << c << "\n";
	std::cout << d << "\n";

	hourshort hc(ha);
	hourint hd = hc;

	d = hc, hd = c; // -- допустимы и такие приведения, разве не
					// -- здорово?!)

	std::cout << c << "\n";
	std::cout << d << "\n";
	std::cout << hc << "\n";
	std::cout << hd << "\n";

	//--Сравнение углов
	degshort da1(180, 1, 0), da2(180, 0, 0.899);
	hourint ha1(24, 1, 0), ha2(24, 0, 0.899);

	std::cout << "da1: " << da1 << "\n" << "da2: " << da2 << "\n"
			  << "ha1: " << ha1 << "\n" << "ha2: " << ha2 << "\n";
								// -- обратите внимание, что
								// -- для нормального приоритета
								// -- операции между << ставим
								// -- скобки:
	std::cout << "da1 < da2 ? " << (da1 < da2) << "\n";
	std::cout << "da1 > da2 ? " << (da1 > da2) << "\n";
	std::cout << "da1 == da2 ? " << (da1 == da2) << "\n";
	std::cout << "da1 != da2 ? " << (da1 != da2) << "\n";
								// -- аналогично для часовых мер
	std::cout << "ha1 < ha2 ? " << (ha1 < ha2) << "\n";
	std::cout << "ha1 > ha2 ? " << (ha1 > ha2) << "\n";
	std::cout << "ha1 == ha2 ? " << (ha1 == ha2) << "\n";
	std::cout << "ha1 != ha2 ? " << (ha1 != ha2) << "\n";
								// -- возможны сравнения в разных
								// -- мерах:
	std::cout << "da1 < ha1 ? " << (da1 < ha2) << "\n";
	std::cout << "da2 > ha2 ? " << (ha1 > da2) << "\n";
	std::cout << "ha1 == da1 ? " << (da1 == ha2) << "\n";
	std::cout << "ha1 != da1 ? " << (da1 != ha1) << "\n";

	//--Арифметика

	//--Допустимо складывать углы в различных мерах и вычитать их
	//--друг из друга:
	std::cout << "radian + radian = " << (radian + radian) << "\n";
	std::cout << "radian - radian = " << (radian - radian) << "\n";

	//----ВАЖНО!
	//--Если складываются два угла в различных мерах, то тип резу-
	//--льтата определяется ЛЕВЫМ операндом. Например, ниже вывод
	//--будет в часах:
	std::cout << "ha1 + da1 = " << (ha1 + da1) << "\n";
	std::cout << "ha1 - da1 = " << (ha1 - da1) << "\n";
	std::cout << "da2 + ha1 = " << (da2 + ha1) << "\n";
	std::cout << "da2 - ha1 = " << (da2 - ha1) << "\n";

	//--Углы можно умножать и делить на числовые типы, и обратно:
	std::cout << "radian * 3.14 = " << (radian * 3.14) << "\n";
	std::cout << "PI * radian = " << (M_PI * radian) << "\n";
	std::cout << "radian / 2 * PI = " << (M_PI * radian / 2) << "\n";
	//--При делении числа на угол происходит преобразование число-
	//--вого типа в угловой, т.е. подразумевается, что делят угол в
	//--радианной мере:
	std::cout << "1 / radian = " << (1 / radian) << "\n";
	std::cout << "PI / 360deg = " << (M_PI / degint(360, 0, 0)) << "\n";

	//--При операциях с числовыми типами происходят аналогичные
	//--преобразования числовых типов в углы:
	std::cout << "ha1 + 1 = " << (ha1 + 1) << "\n";
	std::cout << "1 + radian = " << (1 + radian) << "\n";
	std::cout << "PI + da1 = " << (M_PI + da1) << "\n";
	std::cout << "da2 - PI/2 = " << (da2 - M_PI/2) << "\n";

	//--Приведения углов

	//--Можно приводить углы к заданному диапазону значений
	//--Функция-член mod_2pi приводит значение угла к проме-
	//--жутку [-360, 360] (или [-24, 24]):
	//----ВНИМАНИЕ! функция изменяет состояние класса
	degshort ten_rad(100*radian);
	hourint hten_rad(100*radian);
	std::cout << "100 rad: " << ten_rad << "\n";
	std::cout << "100 rad: " << hten_rad << "\n";
	ten_rad.mod_2pi();
	hten_rad.mod_2pi();
	std::cout << "reduce 100 rad: " << ten_rad << "\n";
	std::cout << "reduce 100 rad: " << hten_rad << "\n";

	//--Можно узнать число оборотов с помощью константной
	//--параметризованной функцией:
	ten_rad = 100 * radian;
	hten_rad = 100 * radian;
	std::cout << "In 100 rad: " << ten_rad.mod_2pi<int>() << " circles\n";
	std::cout << "In 100 rad: " << hten_rad.mod_2pi<int>() << " circles\n";

	//--Нормализация к виду положительного, меньше 2pi ра-
	//--диан угла:
	degint denormalize_angle = degint(-275,0,0);
	hourint hdenormalize_angle = hourint(-15,-25,-34);
	std::cout << "Not normalize angle: " << denormalize_angle << "\n";
	std::cout << "Not normalize angle(h): " << hdenormalize_angle << "\n";

	denormalize_angle.normalize();
	hdenormalize_angle.normalize();
	std::cout << "Normalize angle: " << denormalize_angle << "\n";
	std::cout << "Normalize angle(h): " << hdenormalize_angle << "\n";

}
<|endoftext|>


<commit_before>/***********************************************************************
 test/string.cpp - Tests the behavior of mysqlpp::String, particularly
	its data conversion methods.

 Copyright (c) 2007-2008 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ 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.

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>

// Does an equality comparison on the value, forcing the string to
// convert itself to T on the way.  Note that we do this test in terms
// of greater and less than to avoid pedantic GCC warnings for the
// floating point type tests.
template <typename T>
static bool
test_equality(const mysqlpp::String& s, T value)
{
	T converted = s.conv(value);
	if ((value < converted) || (value > converted)) {
		std::cerr << "Type conversion to " << typeid(T).name() <<
				" failed: \"" << s << "\" != \"" << value << "\"." <<
				std::endl;
		return false;
	}
	else {
		return true;
	}
}

// Check that we can convert strings with decimals in them to native
// floating-point values, regardless of locale.
static bool
test_float_conversion()
{
	// This stuff should just work
	if (!test_equality(mysqlpp::String("123.00"), 123)) return false;
	if (!test_equality(mysqlpp::String("123."), 123)) return false;

	// This is trickier: MySQL ignores the system locale when it comes
	// to decimal separators, always using '.', so ensure the conversion
	// stuff in MySQL++ does the right thing regardless.  Test against
	// this system's current locale, an arbitrary European one where ','
	// is the decimal separator, and the "C" locale where it's '.'.
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale old_locale = std::locale::global(std::locale::classic());
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(std::locale("de_DE"));
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(old_locale);

	// Check that we choke on silly float-like values
	try {
		if (test_equality(mysqlpp::String("621.20.0"), 621.2)) {
			std::cerr << "Quasi-FP with two decimal points "
					"converting without error!" << std::endl;
		}
		return false;
	}
	catch (const mysqlpp::BadConversion&) {
		return true;
	}
}

// Tries to convert the given string to an int.  Returns false if we got
// a BadConversion exception and didn't expect it, or didn't get one we
// expected.  Returns false on all other exceptions regardless.
static bool
test_int_conversion(const mysqlpp::String& s, bool throw_expected)
{
	// Try the conversion
	bool conv_threw = false;
	try {
		int converted = s;
		(void)converted;	// pedantic warning squisher
	}
	catch (const mysqlpp::BadConversion&) {
		conv_threw = true;
	}
	catch (const std::exception& e) {
		std::cerr << "Unexpected " << typeid(e).name() <<
				" exception in test_int_conv: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		std::cerr << "Like, totally bogus exception in test_int_conv, "
				"man!" << std::endl;
		return false;
	}

	// Did it do what we expected?
	if (throw_expected == conv_threw) {
		return true;
	}
	else {
		std::cerr << "Conversion of \"" << s << "\" to int " <<
				(conv_threw ? "did not " : "") << "throw; did " <<
				(throw_expected ? "not " : "") << "expect it to." <<
				std::endl;
		return false;
	}
}

// Ensures that the program's locale doesn't affect our floating-point
// conversions.  ('.' vs. ',' stuff.)
static bool
test_locale()
{

	return true;
}

// Ensures numeric conversions of many different types get handled
// correctly.
static bool
test_numeric(const mysqlpp::String& s, int value)
{
	return	test_equality(s, static_cast<signed char>(value)) &&
			test_equality(s, static_cast<unsigned char>(value)) &&
			test_equality(s, static_cast<signed short>(value)) &&
			test_equality(s, static_cast<unsigned short>(value)) &&
			test_equality(s, static_cast<signed int>(value)) &&
			test_equality(s, static_cast<unsigned int>(value)) &&
			test_equality(s, static_cast<signed long>(value)) &&
			test_equality(s, static_cast<unsigned long>(value)) &&
#if !defined(NO_LONG_LONGS)
			test_equality(s, static_cast<mysqlpp::longlong>(value)) &&
			test_equality(s, static_cast<mysqlpp::ulonglong>(value)) &&
#endif
			test_equality(s, static_cast<float>(value)) &&
			test_equality(s, static_cast<double>(value));
}

static bool
test_quote_q(const mysqlpp::String& s, bool expected)
{
	if (s.quote_q() == expected) {
		return true;
	}
	else {
		std::cerr << s.type().name() << " should" <<
				(expected ? "" : " NOT") << " be quoted." << std::endl;
		return false;
	}
}

int
main(int, char* argv[])
{
	try {
		int failures = 0;
		mysqlpp::String empty;
		mysqlpp::String zero("0");
		mysqlpp::String nonzero("42");

		failures += test_equality(empty, mysqlpp::Date()) == false;
		failures += test_equality(empty,
				mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false;
		failures += test_equality(empty, mysqlpp::Time()) == false;
		failures += test_equality(empty, false) == false;
		failures += test_equality(nonzero, true) == false;
		failures += test_numeric(empty, 0) == false;
		failures += test_numeric(zero, 0) == false;
		failures += test_numeric(nonzero, 42) == false;
		failures += test_quote_q(empty, true) == false;
		failures += test_quote_q(mysqlpp::String("1", typeid(int)),
				false) == false;
		failures += test_locale() == false;
		failures += test_float_conversion() == false;
		failures += test_float_conversion() == false;

		return failures;
	}
	catch (mysqlpp::Exception& e) {
		std::cerr << "Unexpected MySQL++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected C++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}

}

<commit_msg>Wrote a test case for test/string.cpp that wasn't getting called. (Ooopsie.)  Made up several ways to call it, so now we know string to int conversions are working.<commit_after>/***********************************************************************
 test/string.cpp - Tests the behavior of mysqlpp::String, particularly
	its data conversion methods.

 Copyright (c) 2007-2008 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the
 CREDITS file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ 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.

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>

#include <iostream>

// Does an equality comparison on the value, forcing the string to
// convert itself to T on the way.  Note that we do this test in terms
// of greater and less than to avoid pedantic GCC warnings for the
// floating point type tests.
template <typename T>
static bool
test_equality(const mysqlpp::String& s, T value)
{
	T converted = s.conv(value);
	if ((value < converted) || (value > converted)) {
		std::cerr << "Type conversion to " << typeid(T).name() <<
				" failed: \"" << s << "\" != \"" << value << "\"." <<
				std::endl;
		return false;
	}
	else {
		return true;
	}
}

// Check that we can convert strings with decimals in them to native
// floating-point values, regardless of locale.
static bool
test_float_conversion()
{
	// This stuff should just work
	if (!test_equality(mysqlpp::String("123.00"), 123)) return false;
	if (!test_equality(mysqlpp::String("123."), 123)) return false;

	// This is trickier: MySQL ignores the system locale when it comes
	// to decimal separators, always using '.', so ensure the conversion
	// stuff in MySQL++ does the right thing regardless.  Test against
	// this system's current locale, an arbitrary European one where ','
	// is the decimal separator, and the "C" locale where it's '.'.
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale old_locale = std::locale::global(std::locale::classic());
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(std::locale("de_DE"));
	if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false;
	std::locale::global(old_locale);

	// Check that we choke on silly float-like values
	try {
		if (test_equality(mysqlpp::String("621.20.0"), 621.2)) {
			std::cerr << "Quasi-FP with two decimal points "
					"converting without error!" << std::endl;
		}
		return false;
	}
	catch (const mysqlpp::BadConversion&) {
		return true;
	}
}

// Tries to convert the given string to an int.  Returns false if we got
// a BadConversion exception and didn't expect it, or didn't get one we
// expected.  Returns false on all other exceptions regardless.
static bool
test_int_conversion(const mysqlpp::String& s, bool throw_expected)
{
	// Try the conversion
	bool conv_threw = false;
	try {
		int converted = s;
		(void)converted;	// pedantic warning squisher
	}
	catch (const mysqlpp::BadConversion&) {
		conv_threw = true;
	}
	catch (const std::exception& e) {
		std::cerr << "Unexpected " << typeid(e).name() <<
				" exception in test_int_conv: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		std::cerr << "Like, totally bogus exception in test_int_conv, "
				"man!" << std::endl;
		return false;
	}

	// Did it do what we expected?
	if (throw_expected == conv_threw) {
		return true;
	}
	else {
		std::cerr << "Conversion of \"" << s << "\" to int " <<
				(conv_threw ? "did not throw" : "threw") << "; " <<
				(throw_expected ? "did not expect" : "expected") <<
				" it to." << std::endl;
		return false;
	}
}

// Ensures that the program's locale doesn't affect our floating-point
// conversions.  ('.' vs. ',' stuff.)
static bool
test_locale()
{

	return true;
}

// Ensures numeric conversions of many different types get handled
// correctly.
static bool
test_numeric(const mysqlpp::String& s, int value)
{
	return	test_equality(s, static_cast<signed char>(value)) &&
			test_equality(s, static_cast<unsigned char>(value)) &&
			test_equality(s, static_cast<signed short>(value)) &&
			test_equality(s, static_cast<unsigned short>(value)) &&
			test_equality(s, static_cast<signed int>(value)) &&
			test_equality(s, static_cast<unsigned int>(value)) &&
			test_equality(s, static_cast<signed long>(value)) &&
			test_equality(s, static_cast<unsigned long>(value)) &&
#if !defined(NO_LONG_LONGS)
			test_equality(s, static_cast<mysqlpp::longlong>(value)) &&
			test_equality(s, static_cast<mysqlpp::ulonglong>(value)) &&
#endif
			test_equality(s, static_cast<float>(value)) &&
			test_equality(s, static_cast<double>(value));
}

static bool
test_quote_q(const mysqlpp::String& s, bool expected)
{
	if (s.quote_q() == expected) {
		return true;
	}
	else {
		std::cerr << s.type().name() << " should" <<
				(expected ? "" : " NOT") << " be quoted." << std::endl;
		return false;
	}
}

int
main(int, char* argv[])
{
	try {
		int failures = 0;
		mysqlpp::String empty;
		mysqlpp::String zero("0");
		mysqlpp::String nonzero("42");
		mysqlpp::String intable1("42.");
		mysqlpp::String intable2("42.0");
		mysqlpp::String nonint("42.1");

		failures += test_equality(empty, mysqlpp::Date()) == false;
		failures += test_equality(empty,
				mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false;
		failures += test_equality(empty, mysqlpp::Time()) == false;
		failures += test_equality(empty, false) == false;
		failures += test_equality(nonzero, true) == false;
		failures += test_numeric(empty, 0) == false;
		failures += test_numeric(zero, 0) == false;
		failures += test_numeric(nonzero, 42) == false;
		failures += test_quote_q(empty, true) == false;
		failures += test_quote_q(mysqlpp::String("1", typeid(int)),
				false) == false;
		failures += test_locale() == false;
		failures += test_float_conversion() == false;
		failures += test_float_conversion() == false;
		failures += test_int_conversion(empty, false) == false;
		failures += test_int_conversion(zero, false) == false;
		failures += test_int_conversion(nonzero, false) == false;
		failures += test_int_conversion(intable1, false) == false;
		failures += test_int_conversion(intable2, false) == false;
		failures += test_int_conversion(nonint, true) == false;

		return failures;
	}
	catch (mysqlpp::Exception& e) {
		std::cerr << "Unexpected MySQL++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}
	catch (std::exception& e) {
		std::cerr << "Unexpected C++ exception caught in " <<
				argv[0] << ": " << e.what() << std::endl;
		return 1;
	}

}

<|endoftext|>


<commit_before>#include <functional>
#include <iostream>
#include <map>

#include "test_helpers.hxx"

using namespace pqxx;

// Example program for libpqxx.  Modify the database, retaining transactional
// integrity using the transactor framework.
namespace
{
// Convert year to 4-digit format.
int To4Digits(int Y)
{
  int Result = Y;

  PQXX_CHECK(Y >= 0, "Negative year: " + to_string(Y));

  if (Y  < 70)   Result += 2000;
  else if (Y  < 100)  Result += 1900;
  else PQXX_CHECK(Y >= 1970, "Unexpected year: " + to_string(Y));
  return Result;
}

// Transaction definition for year-field update.  Returns conversions done.
std::map<int, int> update_years(connection_base &C)
{
  std::map<int, int> conversions;
  work tx{C};

  // First select all different years occurring in the table.
  result R{ tx.exec("SELECT year FROM pqxxevents") };

  // Note all different years currently occurring in the table, writing them
  // and their correct mappings to m_conversions
  for (const auto &r: R)
  {
    int Y;

    // Read year, and if it is non-null, note its converted value
    if (r[0].to(Y)) conversions[Y] = To4Digits(Y);
  }

  // For each occurring year, write converted date back to whereever it may
  // occur in the table.  Since we're in a transaction, any changes made by
  // others at the same time will not affect us.
  for (const auto &c: conversions)
    tx.exec0(
	"UPDATE pqxxevents "
	"SET year=" + to_string(c.second) + " "
	"WHERE year=" + to_string(c.first));

  tx.commit();

  return conversions;
}

void test_026()
{
  connection conn;
  {
    nontransaction tx{conn};
    test::create_pqxxevents(tx);
    tx.commit();
  }

  // Perform (an instantiation of) the UpdateYears transactor we've defined
  // in the code above.  This is where the work gets done.
  const auto conversions = perform(std::bind(update_years, std::ref(conn)));

  // Just for fun, report the exact conversions performed.  Note that this
  // list will be accurate even if other people were modifying the database
  // at the same time; this property was established through use of the
  // transactor framework.
  for (const auto &i: conversions)
    std::cout << '\t' << i.first << "\t-> " << i.second << std::endl;
}

PQXX_REGISTER_TEST(test_026);
} // namespace
<commit_msg>Fix silly warning.<commit_after>#include <functional>
#include <iostream>
#include <map>

#include "test_helpers.hxx"

using namespace pqxx;

// Example program for libpqxx.  Modify the database, retaining transactional
// integrity using the transactor framework.
namespace
{
// Convert year to 4-digit format.
int To4Digits(int Y)
{
  int Result = Y;

  PQXX_CHECK(Y >= 0, "Negative year: " + to_string(Y));

  if (Y  < 70)   Result += 2000;
  else if (Y  < 100)  Result += 1900;
  else PQXX_CHECK(Y >= 1970, "Unexpected year: " + to_string(Y));
  return Result;
}

// Transaction definition for year-field update.  Returns conversions done.
std::map<int, int> update_years(connection_base &C)
{
  std::map<int, int> conversions;
  work tx{C};

  // First select all different years occurring in the table.
  result R{ tx.exec("SELECT year FROM pqxxevents") };

  // Note all different years currently occurring in the table, writing them
  // and their correct mappings to m_conversions
  for (const auto &r: R)
  {
    int Y{};

    // Read year, and if it is non-null, note its converted value
    if (r[0].to(Y)) conversions[Y] = To4Digits(Y);
  }

  // For each occurring year, write converted date back to whereever it may
  // occur in the table.  Since we're in a transaction, any changes made by
  // others at the same time will not affect us.
  for (const auto &c: conversions)
    tx.exec0(
	"UPDATE pqxxevents "
	"SET year=" + to_string(c.second) + " "
	"WHERE year=" + to_string(c.first));

  tx.commit();

  return conversions;
}

void test_026()
{
  connection conn;
  {
    nontransaction tx{conn};
    test::create_pqxxevents(tx);
    tx.commit();
  }

  // Perform (an instantiation of) the UpdateYears transactor we've defined
  // in the code above.  This is where the work gets done.
  const auto conversions = perform(std::bind(update_years, std::ref(conn)));

  // Just for fun, report the exact conversions performed.  Note that this
  // list will be accurate even if other people were modifying the database
  // at the same time; this property was established through use of the
  // transactor framework.
  for (const auto &i: conversions)
    std::cout << '\t' << i.first << "\t-> " << i.second << std::endl;
}

PQXX_REGISTER_TEST(test_026);
} // namespace
<|endoftext|>


<commit_before>#include <GL/freeglut.h>
#include <stdio.h>
#include "math.h"
#include "iostream"
#include <GL/gl.h>
#define PI 3.1415926535898

int w_width=600,w_height=600;
int p,r;

void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(1,w_width,1,w_height,-1,1);
}

//::::::::::::::::DISPLAY FUNCTION::::::::::::::::://
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);

GLint circle_points=100,i;
GLfloat angle;
glBegin(GL_POLYGON);
for(i=0;i<circle_points;i++) {
    angle=2*PI*i/circle_points;
    glVertex2f(300+w_width*cos(angle)/35,300+w_height*sin(angle)/35);
  }
glEnd();

//..........Separator...........//
glColor3f(0.0,0.0,0.0);
glBegin(GL_POLYGON);
{
  glVertex3i(0,70,0);
  glVertex3i(w_width,70,0);
  glVertex3i(w_width,73,0);
  glVertex3i(0,73,0);
}
glEnd();

//..........Target Blocks.........//
glColor3f(1.0,1.0,0.0);
glBegin(GL_QUADS);
{
  for(p=590;p>440;p-=50)
  {
    for(r=5;r<590;r+=50)
    {
      glVertex3f(r,p,0);
      glVertex3f(r+40,p,0);
      glVertex3f(r+40,p-40,0);
      glVertex3f(r,p-40,0);
    }
  }
}
glEnd();

//.........Block..........//

glColor3f(1.0,0.0,1.0);
glBegin(GL_QUADS);
{
  glVertex3i(300,30,0);
  glVertex3i(380,30,0);
  glVertex3i(380,60,0);
  glVertex3i(300,60,0);
}
glEnd();
glFinish();
glutSwapBuffers();
}

//::::::::::::::RESHAPE FUNCTION:::::::::::::::::://
void reshape(int w, int h)
{
	w_height=h;
	w_width=w;
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,(GLdouble)w,0.0,(GLdouble)h,0.0,1.0);
}

int main(int argc,char** argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
  glutInitWindowSize(w_width,w_height);
  glutInitWindowPosition(270,50);
  glutCreateWindow("Tikinoid by Jalaz");
  init();
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutMainLoop();
  return 0;
}
<commit_msg>Initiate Motion<commit_after>#include <GL/freeglut.h>
#include <stdio.h>
#include "math.h"
#include "iostream"
#include <GL/gl.h>
#define PI 3.1415926535898

int w_width=600,w_height=600;
int x=0,y=0;
int p,r;
float iball=300.0,jball=300.0,a=1.0,b=1.0;

void init(void)
  {
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(1,w_width,1,w_height,-1,1);
  }

//::::::::::::::::DISPLAY FUNCTION::::::::::://
void display(void)
  {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0,0.0,1.0);

    GLint circle_points=100,i;
    GLfloat angle;
    glBegin(GL_POLYGON);
      for(i=0;i<circle_points;i++)
      {
        angle=2*PI*i/circle_points;
        glVertex2f(iball+w_width*cos(angle)/35,jball+w_height*sin(angle)/35);
      }
    glEnd();

    //.......Separator.......//
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_POLYGON);
    {
      glVertex3i(0,70,0);
      glVertex3i(w_width,70,0);
      glVertex3i(w_width,73,0);
      glVertex3i(0,73,0);
    }
    glEnd();

    //.......Target Blocks.......//
    glColor3f(1.0,1.0,0.0);
    glBegin(GL_QUADS);
    {
      for(p=590;p>440;p-=50)
        {
          for(r=5;r<590;r+=50)
            {
              glVertex3f(r,p,0);
              glVertex3f(r+40,p,0);
              glVertex3f(r+40,p-40,0);
              glVertex3f(r,p-40,0);
            }
        }
    }
    glEnd();

    //.......Block............//
    glColor3f(1.0,0.0,1.0);
    glBegin(GL_QUADS);
      {
        glVertex3i(300+x,30+y,0);
        glVertex3i(380+x,30+y,0);
        glVertex3i(380+x,60+y,0);
        glVertex3i(300+x,60+y,0);
      }
      glEnd();
  glFinish();
  glutSwapBuffers();
}

//:::::::::Reshape Function::::::::::://
void reshape(int w, int h)
  {
	   w_height=h;
	   w_width=w;
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0,(GLdouble)w,0.0,(GLdouble)h,0.0,1.0);
  }

//:::::::::::Display Function::::::::::://
void againDisplay()
{
  iball=iball+(a*0.5);
  jball=jball+(b*0.5);
  if((jball>=600.0-150.0)||(jball<=50.0) )
    b=-b ;
  else if((iball>=600-10.0)||(iball<=10.0))
    a=-a;
  glutPostRedisplay();
}

//:::::::::::keyboard function:::::::::::://
void keyboard(unsigned char key, int xm, int ym)
{
  switch (key)
    {
      case 'i':y+=5;
      break;

      case 'j':x-=5;
      break;

      case 'k':y-=5;
      break;

      case 'l':x+=5;
      break;

      case 'p':glutIdleFunc(againDisplay);     //Start the game
      break;

      case 's':glutIdleFunc(NULL);            //Pause the game
      break;

      default:
      break;
    }
}

int main(int argc,char** argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
  glutInitWindowSize(w_width,w_height);
  glutInitWindowPosition(270,50);
  glutCreateWindow("Tikinoid by Jalaz");
  init();
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutKeyboardFunc(keyboard);
  glutMainLoop();
  return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>

#include "log.hpp"
#include "comm.hpp"
#include "commands.hpp"

#include "linenoise/linenoise.h"

#include <thread>
#include <chrono>
#include <vector>
#include <string>

namespace fcwt {

static void print_status(int sockfd)
{
    auto const msg = generate<status_request_message>();
    fuji_send(sockfd, &msg, sizeof(msg));
    uint8_t buf[1024];
    uint32_t receivedBytes = fuji_receive(sockfd, buf);
    print_hex(buf, receivedBytes);
    print_uint32(buf, receivedBytes);
    print_ascii(buf, receivedBytes);
    receivedBytes = fuji_receive(sockfd, buf);
    print_hex(buf, receivedBytes);
    print_uint32(buf, receivedBytes);
    print_ascii(buf, receivedBytes);
}

void image_stream_main(std::atomic<bool>& flag)
{
  LOG_INFO("image_stream_main");
  sock const sockfd2 = connect_to_camera(jpg_stream_server_port);

  std::vector<uint8_t> buffer(1024 * 1024);

  if (sockfd2 <= 0)
    return;

  unsigned int image = 0;
  while (flag)
  {
    uint32_t receivedBytes = fuji_receive(sockfd2, buffer.data(), buffer.size());
    LOG_INFO_FORMAT("image_stream_main received %d bytes", receivedBytes);

    char filename[1024];
    snprintf(filename, sizeof(filename), "out/img_%d.jpg", image++);
    FILE* file = fopen(filename, "wb");
    if (file)
    {
      int const header = 14; // not sure what's in the first 14 bytes
      fwrite(&buffer[header], receivedBytes, 1, file);
      fclose(file);
    }
    else
    {
      LOG_WARN_FORMAT("image_stream_main Failed to create file %s", filename);
    }
  }
}

char const* comamndStrings[] =
{
  "connect",
  "shutter",
  "stream",
};

enum class command
{
  connect,
  shutter,
  stream,
  unknown,
  count = unknown
};

static void completion(char const* buf, linenoiseCompletions* lc)
{
  for (int i = 0; i < static_cast<int>(command::count); ++i)
  {
    char const* const cmd = comamndStrings[i];
    if (strstr(cmd, buf) == cmd)
      linenoiseAddCompletion(lc, cmd);
  }
}

bool getline(std::string& line)
{
  char* const str = linenoise("fcwt> ");
  if (!str)
    return false;

  line.assign(str);
  free(str);
  return true;
}

command parse_command(std::string const& line)
{
  for (int i = 0; i < static_cast<int>(command::count); ++i)
  {
    if (line == comamndStrings[i])
      return static_cast<command>(i);
  }

  return command::unknown;
}

int main()
{

  /* Set the completion callback. This will be called every time the
   * user uses the <tab> key. */
  linenoiseSetCompletionCallback(completion);

  sock sockfd;
  std::atomic<bool> imageStreamFlag(true);
  std::thread imageStreamThread;

  std::string line;
  while(getline(line))
  {
      linenoiseHistoryAdd(line.c_str());
      command cmd = parse_command(line);
      /* Do something with the string. */
      switch(cmd)
      {
        case command::connect:
        {
          if (sockfd <= 0)
          {
            sockfd = connect_to_camera(control_server_port);
            if (!init_control_connection(sockfd, "HackedClient"))
              printf("failure\n");
            else
              print_status(sockfd);
          }
          else
          {
            printf("already connected\n");
          }
        }
        break;
      case command::shutter:
      {
        if (!shutter(sockfd))
          printf("failure\n");
        print_status(sockfd);

      }
      break;
      case command::stream:
      {
        imageStreamThread = std::thread(([&]() { image_stream_main(imageStreamFlag); }));
      }
      break;
      default:
      {
        printf("Unreconized command: %s\n", line.c_str());
      }
    }
  }

  if (imageStreamThread.joinable())
  {
    imageStreamFlag = false;
    imageStreamThread.join();
  }

  terminate_control_connection(sockfd);

  return 0;
}

} // namespace fcwt

int main(const int argc, char const* argv[])
{
  return fcwt::main();
}
<commit_msg>Parsing camera settings status, so far white balance, iso, autofocus point and film simulation<commit_after>#include <stdio.h>

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>

#include "log.hpp"
#include "comm.hpp"
#include "commands.hpp"

#include "linenoise/linenoise.h"

#include <thread>
#include <chrono>
#include <vector>
#include <string>

namespace fcwt {

static void print_status(int sockfd)
{
    auto const msg = generate<status_request_message>();
    printf("Status request %d\n", msg.id);
    fuji_send(sockfd, &msg, sizeof(msg));
    uint8_t buf[1024];
    uint32_t receivedBytes = fuji_receive(sockfd, buf);
    printf("Status: %d bytes\n", receivedBytes);
    print_hex(buf, receivedBytes);
    print_uint32(buf, receivedBytes);
    print_ascii(buf, receivedBytes);

    if (receivedBytes >= 124)
    {
      uint32_t iso, white_balance, film_simulation, autofocus_point, flash;
      memcpy(&flash, &buf[8 + 8], 4);
      memcpy(&iso, &buf[8 + 58], 4);
      memcpy(&white_balance, &buf[8 + 88], 4);
      memcpy(&film_simulation, &buf[8 + 92], 4);
      memcpy(&autofocus_point, &buf[8 + 104], 4); // only seems to work for single point, have not found data for 'zone' yet

      printf("iso=%u (%u) raw=%u\n", iso & 0xffff, iso >> 16, iso);
      printf("white_balance=%d\n", white_balance);
      printf("film_simulation=%u raw=%08X\n", film_simulation >> 16, film_simulation);
      printf("autofocus_point(x/y)=(%u,%u) raw=%08X\n", autofocus_point >> 24, (autofocus_point >> 16) & 0xff, autofocus_point);
      printf("flash raw=%08X\n", flash);
    }

    receivedBytes = fuji_receive(sockfd, buf);
}

void image_stream_main(std::atomic<bool>& flag)
{
  LOG_INFO("image_stream_main");
  sock const sockfd2 = connect_to_camera(jpg_stream_server_port);

  std::vector<uint8_t> buffer(1024 * 1024);

  if (sockfd2 <= 0)
    return;

  unsigned int image = 0;
  while (flag)
  {
    uint32_t receivedBytes = fuji_receive(sockfd2, buffer.data(), buffer.size());
    LOG_INFO_FORMAT("image_stream_main received %d bytes", receivedBytes);

    char filename[1024];
    snprintf(filename, sizeof(filename), "out/img_%d.jpg", image++);
    FILE* file = fopen(filename, "wb");
    if (file)
    {
      int const header = 14; // not sure what's in the first 14 bytes
      fwrite(&buffer[header], receivedBytes, 1, file);
      fclose(file);
    }
    else
    {
      LOG_WARN_FORMAT("image_stream_main Failed to create file %s", filename);
    }
  }
}

char const* comamndStrings[] =
{
  "connect",
  "shutter",
  "stream",
  "info"
};

enum class command
{
  connect,
  shutter,
  stream,
  info,
  unknown,
  count = unknown
};

static void completion(char const* buf, linenoiseCompletions* lc)
{
  for (int i = 0; i < static_cast<int>(command::count); ++i)
  {
    char const* const cmd = comamndStrings[i];
    if (strstr(cmd, buf) == cmd)
      linenoiseAddCompletion(lc, cmd);
  }
}

bool getline(std::string& line)
{
  char* const str = linenoise("fcwt> ");
  if (!str)
    return false;

  line.assign(str);
  free(str);
  return true;
}

command parse_command(std::string const& line)
{
  for (int i = 0; i < static_cast<int>(command::count); ++i)
  {
    if (line == comamndStrings[i])
      return static_cast<command>(i);
  }

  return command::unknown;
}

int main()
{

  /* Set the completion callback. This will be called every time the
   * user uses the <tab> key. */
  linenoiseSetCompletionCallback(completion);

  sock sockfd;
  std::atomic<bool> imageStreamFlag(true);
  std::thread imageStreamThread;

  std::string line;
  while(getline(line))
  {
      linenoiseHistoryAdd(line.c_str());
      command cmd = parse_command(line);
      /* Do something with the string. */
      switch(cmd)
      {
        case command::connect:
        {
          if (sockfd <= 0)
          {
            sockfd = connect_to_camera(control_server_port);
            if (!init_control_connection(sockfd, "HackedClient"))
              printf("failure\n");
            else
              print_status(sockfd);
          }
          else
          {
            printf("already connected\n");
          }
        }
        break;
      case command::shutter:
      {
        if (!shutter(sockfd))
          printf("failure\n");
        print_status(sockfd);

      }
      break;

      case command::stream:
      {
        imageStreamThread = std::thread(([&]() { image_stream_main(imageStreamFlag); }));
      }
      break;

      case command::info:
      {
        print_status(sockfd);
      }
      break;

      default:
      {
        printf("Unreconized command: %s\n", line.c_str());
      }
    }
  }

  if (imageStreamThread.joinable())
  {
    imageStreamFlag = false;
    imageStreamThread.join();
  }

  terminate_control_connection(sockfd);

  return 0;
}

} // namespace fcwt

int main(const int argc, char const* argv[])
{
  return fcwt::main();
}
<|endoftext|>


<commit_before>#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "Getopt.hpp"
#include "snarkfront.hpp"

using namespace snarkfront;
using namespace std;

void printUsage(const char* exeName) {
    const string
        PAIR = " -p BN128|Edwards",
        BITS = " -b 256|512",
        D = " -d tree_depth",
        T = " -t merkle_tree_file",
        LEAF = " -c hex_digest",
        KEEP = " [-k]",
        SYS = " -s constraint_system_file",
        N = " -n constraints_per_file",
        IN = " -i proof_input_file",
        WIT = " -w proof_witness_file";

    cout << "new tree:      " << exeName << PAIR << BITS << T << D << endl
         << "add leaf:      " << exeName << PAIR << BITS << T << LEAF << KEEP << endl
         << "constraints:   " << exeName << PAIR << BITS << T << SYS << N << endl
         << "proof input:   " << exeName << PAIR << BITS << T << IN << endl
         << "proof witness: " << exeName << PAIR << BITS << T << WIT << endl;

    exit(EXIT_FAILURE);
}

template <typename PAIRING, typename BUNDLE>
bool newTree(const string& treefile,
             const size_t depth)
{
    if (0 == depth) return false;

    BUNDLE bund(depth);

    ofstream ofs(treefile);
    if (!ofs)
        return false;
    else
        bund.marshal_out(ofs);

    return true;
}

template <typename PAIRING, typename BUNDLE>
bool addLeaf(const string& treefile,
             const string& cmtext,
             const bool keep)
{
    BUNDLE bund;
    {
        ifstream ifs(treefile);
        if (!ifs || !bund.marshal_in(ifs))
            return false;
    }

    typename BUNDLE::DigType cm;
    if (!asciiHexToArray(cmtext, cm))
        return false;

    bund.addLeaf(cm, keep);
    {
        ofstream ofs(treefile);
        if (!ofs)
            return false;
        else
            bund.marshal_out(ofs);
    }

    return true;
}

template <typename PAIRING, typename BUNDLE, typename ZK_PATH>
bool proofFiles(const string& treefile,
                const string& sysfile,
                const size_t sysnum,
                const string& pinfile,
                const string& witfile)
{
    BUNDLE bund;
    {
        ifstream ifs(treefile);
        if (!ifs || !bund.marshal_in(ifs))
            return false;
    }

    if (1 != bund.authLeaf().size() || 1 != bund.authPath().size())
        return false;

    const auto& authLeaf = bund.authLeaf().front();
    const auto& authPath = bund.authPath().front();

    if (!sysfile.empty()) write_files<PAIRING>(sysfile, sysnum);

    typename ZK_PATH::DigType zkRT;
    bless(zkRT, authPath.rootHash());

    end_input<PAIRING>();

    if (!pinfile.empty()) {
        ofstream ofs(pinfile);
        if (!ofs) return false;
        ofs << input<PAIRING>();
        return true;
    }

    typename ZK_PATH::DigType zkLeaf;
    bless(zkLeaf, authLeaf);

    ZK_PATH zkAuthPath(authPath);
    zkAuthPath.updatePath(zkLeaf);

    assert_true(zkRT == zkAuthPath.rootHash());

    if (!sysfile.empty()) finalize_files<PAIRING>();

    if (!witfile.empty()) {
        ofstream ofs(witfile);
        if (!ofs) return false;
        ofs << witness<PAIRING>();
        return true;
    }

    return true;
}

int main(int argc, char *argv[])
{
    Getopt cmdLine(argc, argv, "ptcsiw", "bdn", "k");
    if (!cmdLine || cmdLine.empty()) printUsage(argv[0]);

    const auto
        pairing = cmdLine.getString('p'),
        treefile = cmdLine.getString('t'),
        cmtext = cmdLine.getString('c'),
        sysfile = cmdLine.getString('s'),
        pinfile = cmdLine.getString('i'),
        witfile = cmdLine.getString('w');

    const auto
        numbits = cmdLine.getNumber('b'),
        depth = cmdLine.getNumber('d'),
        sysnum = cmdLine.getNumber('n');

    const auto keep = cmdLine.getFlag('k');

    if (!validPairingName(pairing)) {
        cerr << "error: elliptic curve pairing " << pairing << endl;
        exit(EXIT_FAILURE);
    }

    if (256 != numbits && 512 != numbits) {
        cerr << "error: number SHA-2 bits " << numbits << endl;
        exit(EXIT_FAILURE);
    }

    bool ok = false;

    if (pairingBN128(pairing)) {
        // Barreto-Naehrig 128 bits
        init_BN128();
        typedef BN128_PAIRING PAIR;
        typedef PAIR::Fr FR;

        if (256 == numbits) {
            typedef MerkleBundle_SHA256<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA256<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);

        } else if (512 == numbits) {
            typedef MerkleBundle_SHA512<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA512<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);
        }

    } else if (pairingEdwards(pairing)) {
        // Edwards 80 bits
        init_Edwards();
        typedef EDWARDS_PAIRING PAIR;
        typedef PAIR::Fr FR;

        if (256 == numbits) {
            typedef MerkleBundle_SHA256<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA256<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);

        } else if (512 == numbits) {
            typedef MerkleBundle_SHA512<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA512<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);
        }
    }

    if (!ok) {
        cerr << "ERROR" << endl;
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}
<commit_msg>CLI header files<commit_after>#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "snarkfront.hpp"

using namespace snarkfront;
using namespace std;

void printUsage(const char* exeName) {
    const string
        PAIR = " -p BN128|Edwards",
        BITS = " -b 256|512",
        D = " -d tree_depth",
        T = " -t merkle_tree_file",
        LEAF = " -c hex_digest",
        KEEP = " [-k]",
        SYS = " -s constraint_system_file",
        N = " -n constraints_per_file",
        IN = " -i proof_input_file",
        WIT = " -w proof_witness_file";

    cout << "new tree:      " << exeName << PAIR << BITS << T << D << endl
         << "add leaf:      " << exeName << PAIR << BITS << T << LEAF << KEEP << endl
         << "constraints:   " << exeName << PAIR << BITS << T << SYS << N << endl
         << "proof input:   " << exeName << PAIR << BITS << T << IN << endl
         << "proof witness: " << exeName << PAIR << BITS << T << WIT << endl;

    exit(EXIT_FAILURE);
}

template <typename PAIRING, typename BUNDLE>
bool newTree(const string& treefile,
             const size_t depth)
{
    if (0 == depth) return false;

    BUNDLE bund(depth);

    ofstream ofs(treefile);
    if (!ofs)
        return false;
    else
        bund.marshal_out(ofs);

    return true;
}

template <typename PAIRING, typename BUNDLE>
bool addLeaf(const string& treefile,
             const string& cmtext,
             const bool keep)
{
    BUNDLE bund;
    {
        ifstream ifs(treefile);
        if (!ifs || !bund.marshal_in(ifs))
            return false;
    }

    typename BUNDLE::DigType cm;
    if (!asciiHexToArray(cmtext, cm))
        return false;

    bund.addLeaf(cm, keep);
    {
        ofstream ofs(treefile);
        if (!ofs)
            return false;
        else
            bund.marshal_out(ofs);
    }

    return true;
}

template <typename PAIRING, typename BUNDLE, typename ZK_PATH>
bool proofFiles(const string& treefile,
                const string& sysfile,
                const size_t sysnum,
                const string& pinfile,
                const string& witfile)
{
    BUNDLE bund;
    {
        ifstream ifs(treefile);
        if (!ifs || !bund.marshal_in(ifs))
            return false;
    }

    if (1 != bund.authLeaf().size() || 1 != bund.authPath().size())
        return false;

    const auto& authLeaf = bund.authLeaf().front();
    const auto& authPath = bund.authPath().front();

    if (!sysfile.empty()) write_files<PAIRING>(sysfile, sysnum);

    typename ZK_PATH::DigType zkRT;
    bless(zkRT, authPath.rootHash());

    end_input<PAIRING>();

    if (!pinfile.empty()) {
        ofstream ofs(pinfile);
        if (!ofs) return false;
        ofs << input<PAIRING>();
        return true;
    }

    typename ZK_PATH::DigType zkLeaf;
    bless(zkLeaf, authLeaf);

    ZK_PATH zkAuthPath(authPath);
    zkAuthPath.updatePath(zkLeaf);

    assert_true(zkRT == zkAuthPath.rootHash());

    if (!sysfile.empty()) finalize_files<PAIRING>();

    if (!witfile.empty()) {
        ofstream ofs(witfile);
        if (!ofs) return false;
        ofs << witness<PAIRING>();
        return true;
    }

    return true;
}

int main(int argc, char *argv[])
{
    Getopt cmdLine(argc, argv, "ptcsiw", "bdn", "k");
    if (!cmdLine || cmdLine.empty()) printUsage(argv[0]);

    const auto
        pairing = cmdLine.getString('p'),
        treefile = cmdLine.getString('t'),
        cmtext = cmdLine.getString('c'),
        sysfile = cmdLine.getString('s'),
        pinfile = cmdLine.getString('i'),
        witfile = cmdLine.getString('w');

    const auto
        numbits = cmdLine.getNumber('b'),
        depth = cmdLine.getNumber('d'),
        sysnum = cmdLine.getNumber('n');

    const auto keep = cmdLine.getFlag('k');

    if (!validPairingName(pairing)) {
        cerr << "error: elliptic curve pairing " << pairing << endl;
        exit(EXIT_FAILURE);
    }

    if (256 != numbits && 512 != numbits) {
        cerr << "error: number SHA-2 bits " << numbits << endl;
        exit(EXIT_FAILURE);
    }

    bool ok = false;

    if (pairingBN128(pairing)) {
        // Barreto-Naehrig 128 bits
        init_BN128();
        typedef BN128_PAIRING PAIR;
        typedef PAIR::Fr FR;

        if (256 == numbits) {
            typedef MerkleBundle_SHA256<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA256<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);

        } else if (512 == numbits) {
            typedef MerkleBundle_SHA512<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA512<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);
        }

    } else if (pairingEdwards(pairing)) {
        // Edwards 80 bits
        init_Edwards();
        typedef EDWARDS_PAIRING PAIR;
        typedef PAIR::Fr FR;

        if (256 == numbits) {
            typedef MerkleBundle_SHA256<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA256<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);

        } else if (512 == numbits) {
            typedef MerkleBundle_SHA512<size_t> BUNDLE;
            typedef zk::MerkleAuthPath_SHA512<FR> ZK_PATH;

            if (-1 != depth)
                ok = newTree<PAIR, BUNDLE>(treefile, depth);
            else if (! cmtext.empty())
                ok = addLeaf<PAIR, BUNDLE>(treefile, cmtext, keep);
            else
                ok = proofFiles<PAIR, BUNDLE, ZK_PATH>(treefile,
                                                       sysfile,
                                                       sysnum,
                                                       pinfile,
                                                       witfile);
        }
    }

    if (!ok) {
        cerr << "ERROR" << endl;
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}
<|endoftext|>


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

#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>

#include <configuration.hpp>

#include <Dedispersion.hpp>
#include <ArgumentList.hpp>
#include <Observation.hpp>
#include <utils.hpp>
#include <Shifts.hpp>
#include <ReadData.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  unsigned int padding = 0;
  uint8_t inputBits = 0;
  bool printResults = false;
  uint64_t wrongSamples = 0;
  std::string channelsFile;
  AstroData::Observation observation_c;
  AstroData::Observation observation;

  try {
    isa::utils::ArgumentList args(argc, argv);
    printResults = args.getSwitch("-print_results");
    inputBits = args.getSwitchArgument< unsigned int >("-input_bits");
    padding = args.getSwitchArgument< unsigned int >("-padding");
    channelsFile = args.getSwitchArgument< std::string >("-zapped_channels");
    observation.setNrBeams(args.getSwitchArgument< unsigned int >("-beams"));
    observation.setNrSyntheticBeams(args.getSwitchArgument< unsigned int >("-synthetic_beams"));
    observation.setFrequencyRange(args.getSwitchArgument< unsigned int >("-subbands"), args.getSwitchArgument< unsigned int >("-channels"), args.getSwitchArgument< float >("-min_freq"), args.getSwitchArgument< float >("-channel_bandwidth"));
    observation.setNrSamplesPerBatch(args.getSwitchArgument< unsigned int >("-samples"));
    observation.setDMSubbandingRange(args.getSwitchArgument< unsigned int >("-subbanding_dms"), args.getSwitchArgument< float >("-subbanding_dm_first"), args.getSwitchArgument< float >("-subbanding_dm_step"));
    observation.setDMRange(args.getSwitchArgument< unsigned int >("-dms"), 0.0, args.getSwitchArgument< float >("-dm_step"));
    observation_c = observation;
    observation_c.setDMRange(observation.getNrDMsSubbanding() * observation.getNrDMs(), args.getSwitchArgument< float >("-dm_first"), observation.getDMStep());
  } catch  ( isa::utils::SwitchNotFound & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << "Usage: " << argv[0] << " [-print_results] -input_bits ... -padding ... -zapped_channels ... -beams ... -synthetic_beams ... -min_freq ... -channel_bandwidth ... -samples ... -subbands ... -channels ... -subbanding_dms ... -dms ... -subbanding_dm_first ... -dm_first ... -subbanding_dm_step ... -dm_step ..." << std::endl;
    return 1;
  }

  // Allocate memory
  std::vector< inputDataType > dispersedData;
  std::vector< outputDataType > subbandedData;
  std::vector< outputDataType > dedispersedData;
  std::vector< outputDataType > dedispersedData_c;
  std::vector< uint8_t > zappedChannels(observation_c.getNrPaddedChannels(padding / sizeof(uint8_t)));
  std::vector< uint8_t > beamDriver(observation_c.getNrSyntheticBeams() * observation_c.getNrPaddedChannels(padding / sizeof(uint8_t)));
  std::vector< float > * shifts = PulsarSearch::getShifts(observation_c, padding);

  AstroData::readZappedChannels(observation_c, channelsFile, zappedChannels);
  observation_c.setNrSamplesPerDispersedChannel(observation.getNrSamplesPerBatch() + static_cast< unsigned int >(shifts->at(0) * (observation_c.getFirstDM() + ((observation_c.getNrDMs() - 1) * observation_c.getDMStep()))));
  observation.setNrSamplesPerBatchSubbanding(observation.getNrSamplesPerBatch() + static_cast< unsigned int >(shifts->at(0) * (observation.getFirstDM() + ((observation.getNrDMs() - 1) * observation.getDMStep()))));
  observation.setNrSamplesPerSubbandingDispersedChannel(observation.getNrSamplesPerBatchSubbanding() + static_cast< unsigned int >(shifts->at(0) * (observation.getFirstDMSubbanding() + ((observation.getNrDMsSubbanding() - 1) * observation.getDMSubbandingStep()))));
  if ( inputBits >= 8 ) {
    dispersedData.resize(observation_c.getNrBeams() * observation_c.getNrChannels() * observation_c.getNrSamplesPerPaddedSubbandingDispersedChannel(padding / sizeof(inputDataType)));
    subbandedData.resize(observation.getNrBeams() * observation.getNrSubbands() * observation.getNrDMsSubbanding()  * observation.getNrSamplesPerPaddedSubbandingDispersedChannel(padding / sizeof(inputDataType)));
    dedispersedData.resize(observation.getNrSyntheticBeams() * (observation.getNrDMsSubbanding() * observation.getNrDMs()) * observation.getNrSamplesPerPaddedBatch(padding / sizeof(inputDataType)));
    dedispersedData_c.resize(observation_c.getNrSyntheticBeams() * observation_c.getNrDMs() * observation_c.getNrSamplesPerPaddedBatch(padding / sizeof(inputDataType)));
  } else {
    dispersedData.resize(observation_c.getNrBeams() * observation_c.getNrChannels() * isa::utils::pad(observation_c.getNrSamplesPerPaddedDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType)));
    subbandedData.resize(observation.getNrBeams() * observation.getNrSubbands() * isa::utils::pad(observation.getNrSamplesPerSubbandingDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType)));
    dedispersedData.resize(observation.getNrSyntheticBeams() * (observation.getNrDMsSubbanding() * observation.getNrDMs()) * isa::utils::pad(observation.getNrSamplesPerBatch() / (8 / inputBits), padding / sizeof(inputDataType)));
    dedispersedData_c.resize(observation_c.getNrSyntheticBeams() * observation_c.getNrDMs() * isa::utils::pad(observation_c.getNrSamplesPerBatch() / (8 / inputBits), padding / sizeof(inputDataType)));
  }

  // Generate data
  srand(time(0));
  for ( unsigned int beam = 0; beam < observation_c.getNrBeams(); beam++ ) {
    for ( unsigned int channel = 0; channel < observation_c.getNrChannels(); channel++ ) {
      for ( unsigned int sample = 0; sample < observation_c.getNrSamplesPerDispersedChannel(); sample++ ) {
        if ( inputBits >= 8 ) {
          dispersedData[(beam * observation_c.getNrChannels() * observation_c.getNrSamplesPerPaddedDispersedChannel(padding / sizeof(inputDataType))) + (channel * observation_c.getNrSamplesPerPaddedDispersedChannel(padding / sizeof(inputDataType))) + sample] = rand() % observation_c.getNrChannels();
        } else {
          unsigned int byte = 0;
          uint8_t firstBit = 0;
          uint8_t value = rand() % inputBits;
          uint8_t buffer = 0;

          byte = sample / (8 / inputBits);
          firstBit = (sample % (8 / inputBits)) * inputBits;
          buffer = dispersedData[(beam * observation_c.getNrChannels() * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + (channel * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + byte];
          for ( unsigned int bit = 0; bit < inputBits; bit++ ) {
            isa::utils::setBit(buffer, isa::utils::getBit(value, bit), firstBit + bit);
          }
          dispersedData[(beam * observation_c.getNrChannels() * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + (channel * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + byte] = buffer;
        }
      }
    }
  }
  for ( unsigned int beam = 0; beam < observation_c.getNrSyntheticBeams(); beam++ ) {
    for ( unsigned int channel = 0; channel < observation_c.getNrChannels(); channel++ ) {
      beamDriver[(beam * observation_c.getNrPaddedChannels(padding / sizeof(uint8_t))) + channel] = rand() % observation_c.getNrBeams();
    }
  }
  std::fill(subbandedData.begin(), subbandedData.end(), 0);
  std::fill(dedispersedData.begin(), dedispersedData.end(), 0);
  std::fill(dedispersedData_c.begin(), dedispersedData_c.end(), 0);

  // Execute dedispersion
  PulsarSearch::dedispersion< inputDataType, intermediateDataType, outputDataType >(observation_c, zappedChannels, beamDriver, dispersedData, dedispersedData_c, *shifts, padding, inputBits);
  PulsarSearch::subbandDedispersionStepOne< inputDataType, intermediateDataType, outputDataType >(observation, zappedChannels, dispersedData, subbandedData, *shifts, padding, inputBits);
  PulsarSearch::subbandDedispersionStepTwo< outputDataType, intermediateDataType, outputDataType >(observation, beamDriver, subbandedData, dedispersedData, *shifts, padding);

  for ( unsigned int sBeam = 0; sBeam < observation.getNrSyntheticBeams(); sBeam++ ) {
    for ( unsigned int firstStepDM = 0; firstStepDM < observation.getNrDMsSubbanding(); firstStepDM++ ) {
      for ( unsigned int dm = 0; dm < observation.getNrDMs(); dm++ ) {
        if ( printResults ) {
          std::cout << "sBeam: " << sBeam << " DM: " << (firstStepDM * observation.getNrDMs()) + dm << std::endl;
        }
        for ( unsigned int sample = 0; sample < observation.getNrSamplesPerBatch(); sample++ ) {
          if ( !isa::utils::same(dedispersedData[(sBeam * observation.getNrDMsSubbanding() * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (firstStepDM * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (dm * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample], dedispersedData_c[(sBeam * observation_c.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (((firstStepDM * observation.getNrDMs()) + dm) * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample]) ) {
            wrongSamples++;
          }
          if ( printResults ) {
            std::cout << dedispersedData[(sBeam * observation.getNrDMsSubbanding() * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (firstStepDM * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (dm * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample] << "," << dedispersedData_c[(sBeam * observation_c.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (((firstStepDM * observation.getNrDMs()) + dm) * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample] << " ";
          }
        }
        if ( printResults ) {
          std::cout << std::endl;
        }
      }
    }
  }

  if ( wrongSamples > 0 ) {
    std::cout << "Wrong samples: " << wrongSamples << " (" << (wrongSamples * 100.0) / (static_cast< uint64_t >(observation_c.getNrSyntheticBeams()) * observation_c.getNrDMs() * observation_c.getNrSamplesPerBatch()) << "%)." << std::endl;
  } else {
    std::cout << "TEST PASSED." << std::endl;
  }

  return 0;
}

<commit_msg>Fixed a bug, using the wrong Observation object.<commit_after>// Copyright 2016 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>

#include <configuration.hpp>

#include <Dedispersion.hpp>
#include <ArgumentList.hpp>
#include <Observation.hpp>
#include <utils.hpp>
#include <Shifts.hpp>
#include <ReadData.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  unsigned int padding = 0;
  uint8_t inputBits = 0;
  bool printResults = false;
  uint64_t wrongSamples = 0;
  std::string channelsFile;
  AstroData::Observation observation_c;
  AstroData::Observation observation;

  try {
    isa::utils::ArgumentList args(argc, argv);
    printResults = args.getSwitch("-print_results");
    inputBits = args.getSwitchArgument< unsigned int >("-input_bits");
    padding = args.getSwitchArgument< unsigned int >("-padding");
    channelsFile = args.getSwitchArgument< std::string >("-zapped_channels");
    observation.setNrBeams(args.getSwitchArgument< unsigned int >("-beams"));
    observation.setNrSyntheticBeams(args.getSwitchArgument< unsigned int >("-synthetic_beams"));
    observation.setFrequencyRange(args.getSwitchArgument< unsigned int >("-subbands"), args.getSwitchArgument< unsigned int >("-channels"), args.getSwitchArgument< float >("-min_freq"), args.getSwitchArgument< float >("-channel_bandwidth"));
    observation.setNrSamplesPerBatch(args.getSwitchArgument< unsigned int >("-samples"));
    observation.setDMSubbandingRange(args.getSwitchArgument< unsigned int >("-subbanding_dms"), args.getSwitchArgument< float >("-subbanding_dm_first"), args.getSwitchArgument< float >("-subbanding_dm_step"));
    observation.setDMRange(args.getSwitchArgument< unsigned int >("-dms"), 0.0, args.getSwitchArgument< float >("-dm_step"));
    observation_c = observation;
    observation_c.setDMRange(observation.getNrDMsSubbanding() * observation.getNrDMs(), args.getSwitchArgument< float >("-dm_first"), observation.getDMStep());
  } catch  ( isa::utils::SwitchNotFound & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << "Usage: " << argv[0] << " [-print_results] -input_bits ... -padding ... -zapped_channels ... -beams ... -synthetic_beams ... -min_freq ... -channel_bandwidth ... -samples ... -subbands ... -channels ... -subbanding_dms ... -dms ... -subbanding_dm_first ... -dm_first ... -subbanding_dm_step ... -dm_step ..." << std::endl;
    return 1;
  }

  // Allocate memory
  std::vector< inputDataType > dispersedData;
  std::vector< outputDataType > subbandedData;
  std::vector< outputDataType > dedispersedData;
  std::vector< outputDataType > dedispersedData_c;
  std::vector< uint8_t > zappedChannels(observation_c.getNrPaddedChannels(padding / sizeof(uint8_t)));
  std::vector< uint8_t > beamDriver(observation_c.getNrSyntheticBeams() * observation_c.getNrPaddedChannels(padding / sizeof(uint8_t)));
  std::vector< float > * shifts = PulsarSearch::getShifts(observation_c, padding);

  AstroData::readZappedChannels(observation_c, channelsFile, zappedChannels);
  observation_c.setNrSamplesPerDispersedChannel(observation.getNrSamplesPerBatch() + static_cast< unsigned int >(shifts->at(0) * (observation_c.getFirstDM() + ((observation_c.getNrDMs() - 1) * observation_c.getDMStep()))));
  observation.setNrSamplesPerBatchSubbanding(observation.getNrSamplesPerBatch() + static_cast< unsigned int >(shifts->at(0) * (observation.getFirstDM() + ((observation.getNrDMs() - 1) * observation.getDMStep()))));
  observation.setNrSamplesPerSubbandingDispersedChannel(observation.getNrSamplesPerBatchSubbanding() + static_cast< unsigned int >(shifts->at(0) * (observation.getFirstDMSubbanding() + ((observation.getNrDMsSubbanding() - 1) * observation.getDMSubbandingStep()))));
  if ( inputBits >= 8 ) {
    dispersedData.resize(observation_c.getNrBeams() * observation_c.getNrChannels() * observation.getNrSamplesPerPaddedSubbandingDispersedChannel(padding / sizeof(inputDataType)));
    subbandedData.resize(observation.getNrBeams() * observation.getNrSubbands() * observation.getNrDMsSubbanding()  * observation.getNrSamplesPerPaddedSubbandingDispersedChannel(padding / sizeof(inputDataType)));
    dedispersedData.resize(observation.getNrSyntheticBeams() * (observation.getNrDMsSubbanding() * observation.getNrDMs()) * observation.getNrSamplesPerPaddedBatch(padding / sizeof(inputDataType)));
    dedispersedData_c.resize(observation_c.getNrSyntheticBeams() * observation_c.getNrDMs() * observation_c.getNrSamplesPerPaddedBatch(padding / sizeof(inputDataType)));
  } else {
    dispersedData.resize(observation_c.getNrBeams() * observation_c.getNrChannels() * isa::utils::pad(observation.getNrSamplesPerPaddedDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType)));
    subbandedData.resize(observation.getNrBeams() * observation.getNrSubbands() * isa::utils::pad(observation.getNrSamplesPerSubbandingDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType)));
    dedispersedData.resize(observation.getNrSyntheticBeams() * (observation.getNrDMsSubbanding() * observation.getNrDMs()) * isa::utils::pad(observation.getNrSamplesPerBatch() / (8 / inputBits), padding / sizeof(inputDataType)));
    dedispersedData_c.resize(observation_c.getNrSyntheticBeams() * observation_c.getNrDMs() * isa::utils::pad(observation_c.getNrSamplesPerBatch() / (8 / inputBits), padding / sizeof(inputDataType)));
  }

  // Generate data
  srand(time(0));
  for ( unsigned int beam = 0; beam < observation_c.getNrBeams(); beam++ ) {
    for ( unsigned int channel = 0; channel < observation_c.getNrChannels(); channel++ ) {
      for ( unsigned int sample = 0; sample < observation_c.getNrSamplesPerDispersedChannel(); sample++ ) {
        if ( inputBits >= 8 ) {
          dispersedData[(beam * observation_c.getNrChannels() * observation_c.getNrSamplesPerPaddedDispersedChannel(padding / sizeof(inputDataType))) + (channel * observation_c.getNrSamplesPerPaddedDispersedChannel(padding / sizeof(inputDataType))) + sample] = rand() % observation_c.getNrChannels();
        } else {
          unsigned int byte = 0;
          uint8_t firstBit = 0;
          uint8_t value = rand() % inputBits;
          uint8_t buffer = 0;

          byte = sample / (8 / inputBits);
          firstBit = (sample % (8 / inputBits)) * inputBits;
          buffer = dispersedData[(beam * observation_c.getNrChannels() * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + (channel * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + byte];
          for ( unsigned int bit = 0; bit < inputBits; bit++ ) {
            isa::utils::setBit(buffer, isa::utils::getBit(value, bit), firstBit + bit);
          }
          dispersedData[(beam * observation_c.getNrChannels() * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + (channel * isa::utils::pad(observation_c.getNrSamplesPerDispersedChannel() / (8 / inputBits), padding / sizeof(inputDataType))) + byte] = buffer;
        }
      }
    }
  }
  for ( unsigned int beam = 0; beam < observation_c.getNrSyntheticBeams(); beam++ ) {
    for ( unsigned int channel = 0; channel < observation_c.getNrChannels(); channel++ ) {
      beamDriver[(beam * observation_c.getNrPaddedChannels(padding / sizeof(uint8_t))) + channel] = rand() % observation_c.getNrBeams();
    }
  }
  std::fill(subbandedData.begin(), subbandedData.end(), 0);
  std::fill(dedispersedData.begin(), dedispersedData.end(), 0);
  std::fill(dedispersedData_c.begin(), dedispersedData_c.end(), 0);

  // Execute dedispersion
  PulsarSearch::dedispersion< inputDataType, intermediateDataType, outputDataType >(observation_c, zappedChannels, beamDriver, dispersedData, dedispersedData_c, *shifts, padding, inputBits);
  PulsarSearch::subbandDedispersionStepOne< inputDataType, intermediateDataType, outputDataType >(observation, zappedChannels, dispersedData, subbandedData, *shifts, padding, inputBits);
  PulsarSearch::subbandDedispersionStepTwo< outputDataType, intermediateDataType, outputDataType >(observation, beamDriver, subbandedData, dedispersedData, *shifts, padding);

  for ( unsigned int sBeam = 0; sBeam < observation.getNrSyntheticBeams(); sBeam++ ) {
    for ( unsigned int firstStepDM = 0; firstStepDM < observation.getNrDMsSubbanding(); firstStepDM++ ) {
      for ( unsigned int dm = 0; dm < observation.getNrDMs(); dm++ ) {
        if ( printResults ) {
          std::cout << "sBeam: " << sBeam << " DM: " << (firstStepDM * observation.getNrDMs()) + dm << std::endl;
        }
        for ( unsigned int sample = 0; sample < observation.getNrSamplesPerBatch(); sample++ ) {
          if ( !isa::utils::same(dedispersedData[(sBeam * observation.getNrDMsSubbanding() * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (firstStepDM * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (dm * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample], dedispersedData_c[(sBeam * observation_c.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (((firstStepDM * observation.getNrDMs()) + dm) * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample]) ) {
            wrongSamples++;
          }
          if ( printResults ) {
            std::cout << dedispersedData[(sBeam * observation.getNrDMsSubbanding() * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (firstStepDM * observation.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (dm * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample] << "," << dedispersedData_c[(sBeam * observation_c.getNrDMs() * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + (((firstStepDM * observation.getNrDMs()) + dm) * observation.getNrSamplesPerPaddedBatch(padding / sizeof(outputDataType))) + sample] << " ";
          }
        }
        if ( printResults ) {
          std::cout << std::endl;
        }
      }
    }
  }

  if ( wrongSamples > 0 ) {
    std::cout << "Wrong samples: " << wrongSamples << " (" << (wrongSamples * 100.0) / (static_cast< uint64_t >(observation_c.getNrSyntheticBeams()) * observation_c.getNrDMs() * observation_c.getNrSamplesPerBatch()) << "%)." << std::endl;
  } else {
    std::cout << "TEST PASSED." << std::endl;
  }

  return 0;
}

<|endoftext|>