<commit_before>// --------------------------------------------------------------------------
#include <string>
#include <map>
#include <list>
#include <fstream>
#include <iomanip>
#include <getopt.h>
#include <math.h>
#include "Debug.h"
#include "modbus/ModbusRTUMaster.h"
#include "modbus/ModbusHelpers.h"
#include "extensions/MTR.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
	{ "help", no_argument, 0, 'h' },
	{ "read", required_argument, 0, 'r' },
	{ "save", required_argument, 0, 'w' },
	{ "timeout", required_argument, 0, 't' },
	{ "autodetect-slave", required_argument, 0, 'l' },
	{ "autodetect-speed", required_argument, 0, 'n' },
	{ "device", required_argument, 0, 'd' },
	{ "verbose", no_argument, 0, 'v' },
	{ "speed", required_argument, 0, 's' },
	{ "stop-bits", required_argument, 0, 'i' },
	{ "parity", required_argument, 0, 'p' },
	{ "use485F", no_argument, 0, 'y' },
	{ "min-addr", required_argument, 0, 'b' },
	{ "max-addr", required_argument, 0, 'e' },
	{ "model", required_argument, 0, 'x' },
	{ "serial", required_argument, 0, 'z' },
	{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
	printf("-h|--help                 - this message\n");
	printf("[--read] mtraddr          - read configuration from MTR\n");
	printf("[--save] mtraddr confile  - save configureation to MTR\n");
	printf("             mtraddr=0x00 - autodetect addr\n");
	printf("[-d|--device] dev         - use device dev. Default: /dev/ttyS0\n");
	printf("[-s|--speed] speed        - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
	printf("[--stop-bits] n           - stop bits [1,2]. Default: 1\n");
	printf("[--parity] par            - parity [odd,even,no]. Default: no\n");
	printf("[-t|--timeout] msec       - Timeout. Default: 2000.\n");
	printf("[-v|--verbose]            - Print all messages to stdout\n");
	printf("[-y|--use485F]            - use RS485 Fastwel.\n");
	printf("[--autodetect-speed] slaveaddr [reg fn]  - detect speed\n");
	printf("          reg - register of test. Default: 0\n");
	printf("          fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
	printf("[--autodetect-slave] [reg fn]  - find slave\n");
	printf("          reg - register of test. Default: 0\n");
	printf("          fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
	printf("[--min-addr] - start addres for autodetect. Default: 0\n");
	printf("[--max-addr] - end addres for autodetect. Default: 255\n");
	printf("\n");
}
// --------------------------------------------------------------------------
enum Command
{
	cmdNOP,
	cmdRead,
	cmdSave,
	cmdDetectSpeed,
	cmdDetectSlave,
	cmdGetModel,
	cmdGetSerial
};
// --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] );
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
	Command cmd = cmdNOP;
	int optindex = 0;
	int opt = 0;
	int verb = 0;
	string dev("/dev/ttyS0");
	string speed("38400");
	string mtrconfile("");
	string par("");
	ModbusRTU::ModbusData reg = 0;
	ModbusRTU::ModbusAddr slaveaddr = 0x00;
	ModbusRTU::SlaveFunctionCode fn = ModbusRTU::fnReadInputRegisters;
	ModbusRTU::ModbusAddr beg = 0;
	ModbusRTU::ModbusAddr end = 255;
	int tout = 20;
	DebugStream dlog;
	//string tofile("");
	int use485 = 0;
	ComPort::StopBits sbits = ComPort::OneBit;
	ComPort::Parity parity = ComPort::NoParity;

//	ModbusRTU::ModbusAddr b=255;
//
//	cout << "b=" << (int)b << " b++=" << (int)(b++) << endl;
//	return 0;

	try
	{
		while( (opt = getopt_long(argc, argv, "hvw:r:x:d:s:t:l:n:yb:e:x:z:",longopts,&optindex)) != -1 )
		{
			switch (opt)
			{
				case 'h':
					print_help();
				return 0;

				case 'r':
						cmd = cmdRead;
						slaveaddr = ModbusRTU::str2mbAddr(optarg);
				break;

				case 'w':
					cmd = cmdSave;
					slaveaddr = ModbusRTU::str2mbAddr( optarg );
					if( !checkArg(optind,argc,argv) )
					{
						cerr << "read command error: bad or no arguments..." << endl;
						return 1;
					}
					else
						mtrconfile = string(argv[optind]);
				break;

				case 'x':
						cmd = cmdGetModel;
						slaveaddr = ModbusRTU::str2mbAddr(optarg);
				break;

				case 'z':
						cmd = cmdGetSerial;
						slaveaddr = ModbusRTU::str2mbAddr(optarg);
				break;

				case 'y':
					use485 = 1;
				break;

				case 'd':
					dev = string(optarg);
				break;

				case 's':
					speed = string(optarg);
				break;

				case 'p':
					par = string(optarg);
					if( !par.compare("odd") )
						parity = ComPort::Odd;
					else if( !par.compare("even") )
						parity = ComPort::Even;
				break;

#undef atoi
				case 't':
					tout = atoi(optarg);
				break;

				case 'i':
					if( atoi(optarg) == 2 )
						sbits = ComPort::TwoBits;
				break;

				case 'b':
					beg = atoi(optarg);
				break;

				case 'e':
					end = atoi(optarg);
				break;

//				case 'a':
//					myaddr = ModbusRTU::str2mbAddr(optarg);
//				break;

				case 'v':
					verb = 1;
				break;

				case 'l':
				{
					if( cmd == cmdNOP )
						cmd = cmdDetectSlave;

					if( !checkArg(optind,argc,argv) )
						break;
					reg = ModbusRTU::str2mbData(argv[optind+2]);

					if( !checkArg(optind+1,argc,argv) )
						break;
					fn = (ModbusRTU::SlaveFunctionCode)UniSetTypes::uni_atoi(argv[optind+3]);
				}
				break;

				case 'n':
				{
					if( cmd == cmdNOP )
						cmd = cmdDetectSpeed;

					slaveaddr = ModbusRTU::str2mbAddr(optarg);

					if( !checkArg(optind,argc,argv) )
						break;

					reg = ModbusRTU::str2mbData(argv[optind]);

					if( !checkArg(optind+1,argc,argv) )
						break;

					fn = (ModbusRTU::SlaveFunctionCode)UniSetTypes::uni_atoi(argv[optind+1]);
				}
				break;

				case '?':
				default:
					printf("? argumnet\n");
					return 0;
			}
		}

		if( verb )
		{
			cout << "(init): dev=" << dev << " speed=" << speed
					<< " timeout=" << tout << " msec "
					<< endl;
		}

		ModbusRTUMaster mb(dev,use485);

		if( verb )
			dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );

		mb.setTimeout(tout);
		mb.setSpeed(speed);
		mb.setParity(parity);
		mb.setStopBits(sbits);
		mb.setLog(dlog);

		switch(cmd)
		{
			case cmdRead:
			{
				if( verb )
					cout << "(mtr-setup): read: slaveaddr=" << ModbusRTU::addr2str(slaveaddr) << endl;
			}
			break;

			case cmdSave:
			{
				if( slaveaddr == 0x00 )
				{
					if( verb )
						cout << "(mtr-setup): save: autodetect slave addr... (speed=" << speed <<  ")" << endl;

					mb.setTimeout(50);
					slaveaddr = ModbusHelpers::autodetectSlave(&mb,beg,end,MTR::regModelNumber,ModbusRTU::fnReadInputRegisters);
					mb.setTimeout(tout);
				}

				if( speed.empty() )
				{
					if( verb )
						cout << "(mtr-setup): save: autodetect speed... (addr=" << ModbusRTU::addr2str(slaveaddr) << ")" << endl;

					mb.setTimeout(50);
					ComPort::Speed s = ModbusHelpers::autodetectSpeed(&mb,slaveaddr,MTR::regModelNumber,ModbusRTU::fnReadInputRegisters);
					mb.setSpeed(s);
					mb.setTimeout(tout);
				}

				if( verb )
					cout << "(mtr-setup): save: "
						 << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << " confile=" << mtrconfile
						 << " speed=" << speed
						 << endl;

				return  MTR::update_configuration(&mb,slaveaddr,mtrconfile,verb) ? 0 : 1;
			}
			break;

			case cmdDetectSlave:
			{
				if( verb )
				{
					cout << "(mtr-setup): autodetect slave: "
						 << " beg=" << ModbusRTU::addr2str(beg)
						 << " end=" << ModbusRTU::addr2str(end)
						 << " reg=" << ModbusRTU::dat2str(reg)
						 << " fn=" << ModbusRTU::b2str(fn)
						 << endl;
				}

				try
				{
					ModbusRTU::ModbusAddr a = ModbusHelpers::autodetectSlave(&mb,beg,end,reg,fn);
					cout << "(mtr-setup): autodetect modbus slave: " << ModbusRTU::addr2str(a) << endl;
				}
				catch( UniSetTypes::TimeOut )
				{
					cout << "(mtr-setup): slave not autodetect..." << endl;
				}
			break;
			}

			case cmdDetectSpeed:
			{
				if( verb )
				{
					cout << "(mtr-setup): autodetect speed: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << " reg=" << ModbusRTU::dat2str(reg)
						 << " fn=" << ModbusRTU::b2str(fn)
						 << endl;
				}

				try
				{
					ComPort::Speed s = ModbusHelpers::autodetectSpeed(&mb,slaveaddr,reg,fn);
					cout << "(mtr-setup): autodetect: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						<< " speed=" << ComPort::getSpeed(s) << endl;
				}
				catch( UniSetTypes::TimeOut )
				{
					cout << "(mtr-setup): speed not autodetect for slaveaddr="
						<< ModbusRTU::addr2str(slaveaddr) << endl;
				}
			}
			break;

			case cmdGetModel:
			{
				if( verb )
				{
					cout << "(mtr-setup): model: "
						 << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << endl;
				}

				cout << "model: " << MTR::getModelNumber(&mb,slaveaddr) << endl;
			}
			break;

			case cmdGetSerial:
			{
				if( verb )
				{
					cout << "(mtr-setup): serial: "
						 << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << endl;
				}

				cout << "serial: " << MTR::getSerialNumber(&mb,slaveaddr) << endl;
			}
			break;

			case cmdNOP:
			default:
				cerr << "No command. Use -h for help." << endl;
				return 1;
		}

		return 0;
	}
	catch( ModbusRTU::mbException& ex )
	{
		cerr << "(mtr-setup): " << ex << endl;
	}
	catch(SystemError& err)
	{
		cerr << "(mtr-setup): " << err << endl;
	}
	catch(Exception& ex)
	{
		cerr << "(mtr-setup): " << ex << endl;
	}
	catch(...)
	{
		cerr << "(mtr-setup): catch(...)" << endl;
	}

	return 1;
}
// --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
{
	if( i<argc && (argv[i])[0]!='-' )
		return argv[i];

	return 0;
}
// --------------------------------------------------------------------------
<commit_msg>(MTR): исправил ошибку с максимальным адресов устройства (close #eterbug 10342)<commit_after>// --------------------------------------------------------------------------
#include <string>
#include <map>
#include <list>
#include <fstream>
#include <iomanip>
#include <getopt.h>
#include <math.h>
#include "Debug.h"
#include "modbus/ModbusRTUMaster.h"
#include "modbus/ModbusHelpers.h"
#include "extensions/MTR.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
	{ "help", no_argument, 0, 'h' },
	{ "read", required_argument, 0, 'r' },
	{ "save", required_argument, 0, 'w' },
	{ "timeout", required_argument, 0, 't' },
	{ "autodetect-slave", required_argument, 0, 'l' },
	{ "autodetect-speed", required_argument, 0, 'n' },
	{ "device", required_argument, 0, 'd' },
	{ "verbose", no_argument, 0, 'v' },
	{ "speed", required_argument, 0, 's' },
	{ "stop-bits", required_argument, 0, 'i' },
	{ "parity", required_argument, 0, 'p' },
	{ "use485F", no_argument, 0, 'y' },
	{ "min-addr", required_argument, 0, 'b' },
	{ "max-addr", required_argument, 0, 'e' },
	{ "model", required_argument, 0, 'x' },
	{ "serial", required_argument, 0, 'z' },
	{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
	printf("-h|--help                 - this message\n");
	printf("[--read] mtraddr          - read configuration from MTR\n");
	printf("[--save] mtraddr confile  - save configureation to MTR\n");
	printf("             mtraddr=0x00 - autodetect addr\n");
	printf("[-d|--device] dev         - use device dev. Default: /dev/ttyS0\n");
	printf("[-s|--speed] speed        - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
	printf("[--stop-bits] n           - stop bits [1,2]. Default: 1\n");
	printf("[--parity] par            - parity [odd,even,no]. Default: no\n");
	printf("[-t|--timeout] msec       - Timeout. Default: 2000.\n");
	printf("[-v|--verbose]            - Print all messages to stdout\n");
	printf("[-y|--use485F]            - use RS485 Fastwel.\n");
	printf("[--autodetect-speed] slaveaddr [reg fn]  - detect speed\n");
	printf("          reg - register of test. Default: 0\n");
	printf("          fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
	printf("[--autodetect-slave] [reg fn]  - find slave\n");
	printf("          reg - register of test. Default: 0\n");
	printf("          fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
	printf("[--min-addr] - start addres for autodetect. Default: 0\n");
	printf("[--max-addr] - end addres for autodetect. Default: 254\n");
	printf("\n");
}
// --------------------------------------------------------------------------
enum Command
{
	cmdNOP,
	cmdRead,
	cmdSave,
	cmdDetectSpeed,
	cmdDetectSlave,
	cmdGetModel,
	cmdGetSerial
};
// --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] );
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
	Command cmd = cmdNOP;
	int optindex = 0;
	int opt = 0;
	int verb = 0;
	string dev("/dev/ttyS0");
	string speed("38400");
	string mtrconfile("");
	string par("");
	ModbusRTU::ModbusData reg = 0;
	ModbusRTU::ModbusAddr slaveaddr = 0x00;
	ModbusRTU::SlaveFunctionCode fn = ModbusRTU::fnReadInputRegisters;
	ModbusRTU::ModbusAddr beg = 0;
	ModbusRTU::ModbusAddr end = 254;
	int tout = 20;
	DebugStream dlog;
	//string tofile("");
	int use485 = 0;
	ComPort::StopBits sbits = ComPort::OneBit;
	ComPort::Parity parity = ComPort::NoParity;

//	ModbusRTU::ModbusAddr b=255;
//
//	cout << "b=" << (int)b << " b++=" << (int)(b++) << endl;
//	return 0;

	try
	{
		while( (opt = getopt_long(argc, argv, "hvw:r:x:d:s:t:l:n:yb:e:x:z:",longopts,&optindex)) != -1 )
		{
			switch (opt)
			{
				case 'h':
					print_help();
				return 0;

				case 'r':
						cmd = cmdRead;
						slaveaddr = ModbusRTU::str2mbAddr(optarg);
				break;

				case 'w':
					cmd = cmdSave;
					slaveaddr = ModbusRTU::str2mbAddr( optarg );
					if( !checkArg(optind,argc,argv) )
					{
						cerr << "read command error: bad or no arguments..." << endl;
						return 1;
					}
					else
						mtrconfile = string(argv[optind]);
				break;

				case 'x':
						cmd = cmdGetModel;
						slaveaddr = ModbusRTU::str2mbAddr(optarg);
				break;

				case 'z':
						cmd = cmdGetSerial;
						slaveaddr = ModbusRTU::str2mbAddr(optarg);
				break;

				case 'y':
					use485 = 1;
				break;

				case 'd':
					dev = string(optarg);
				break;

				case 's':
					speed = string(optarg);
				break;

				case 'p':
					par = string(optarg);
					if( !par.compare("odd") )
						parity = ComPort::Odd;
					else if( !par.compare("even") )
						parity = ComPort::Even;
				break;

#undef atoi
				case 't':
					tout = atoi(optarg);
				break;

				case 'i':
					if( atoi(optarg) == 2 )
						sbits = ComPort::TwoBits;
				break;

				case 'b':
					beg = atoi(optarg);
				break;

				case 'e':
					end = atoi(optarg);
				break;

//				case 'a':
//					myaddr = ModbusRTU::str2mbAddr(optarg);
//				break;

				case 'v':
					verb = 1;
				break;

				case 'l':
				{
					if( cmd == cmdNOP )
						cmd = cmdDetectSlave;

					if( !checkArg(optind,argc,argv) )
						break;
					reg = ModbusRTU::str2mbData(argv[optind+2]);

					if( !checkArg(optind+1,argc,argv) )
						break;
					fn = (ModbusRTU::SlaveFunctionCode)UniSetTypes::uni_atoi(argv[optind+3]);
				}
				break;

				case 'n':
				{
					if( cmd == cmdNOP )
						cmd = cmdDetectSpeed;

					slaveaddr = ModbusRTU::str2mbAddr(optarg);

					if( !checkArg(optind,argc,argv) )
						break;

					reg = ModbusRTU::str2mbData(argv[optind]);

					if( !checkArg(optind+1,argc,argv) )
						break;

					fn = (ModbusRTU::SlaveFunctionCode)UniSetTypes::uni_atoi(argv[optind+1]);
				}
				break;

				case '?':
				default:
					printf("? argumnet\n");
					return 0;
			}
		}

		if( verb )
		{
			cout << "(init): dev=" << dev << " speed=" << speed
					<< " timeout=" << tout << " msec "
					<< endl;
		}

		ModbusRTUMaster mb(dev,use485);

		if( verb )
			dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );

		mb.setTimeout(tout);
		mb.setSpeed(speed);
		mb.setParity(parity);
		mb.setStopBits(sbits);
		mb.setLog(dlog);

		switch(cmd)
		{
			case cmdRead:
			{
				if( verb )
					cout << "(mtr-setup): read: slaveaddr=" << ModbusRTU::addr2str(slaveaddr) << endl;
			}
			break;

			case cmdSave:
			{
				if( slaveaddr == 0x00 )
				{
					if( verb )
						cout << "(mtr-setup): save: autodetect slave addr... (speed=" << speed <<  ")" << endl;

					mb.setTimeout(50);
					slaveaddr = ModbusHelpers::autodetectSlave(&mb,beg,end,MTR::regModelNumber,ModbusRTU::fnReadInputRegisters);
					mb.setTimeout(tout);
				}

				if( speed.empty() )
				{
					if( verb )
						cout << "(mtr-setup): save: autodetect speed... (addr=" << ModbusRTU::addr2str(slaveaddr) << ")" << endl;

					mb.setTimeout(50);
					ComPort::Speed s = ModbusHelpers::autodetectSpeed(&mb,slaveaddr,MTR::regModelNumber,ModbusRTU::fnReadInputRegisters);
					mb.setSpeed(s);
					mb.setTimeout(tout);
				}

				if( verb )
					cout << "(mtr-setup): save: "
						 << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << " confile=" << mtrconfile
						 << " speed=" << speed
						 << endl;

				return  MTR::update_configuration(&mb,slaveaddr,mtrconfile,verb) ? 0 : 1;
			}
			break;

			case cmdDetectSlave:
			{
				if( verb )
				{
					cout << "(mtr-setup): autodetect slave: "
						 << " beg=" << ModbusRTU::addr2str(beg)
						 << " end=" << ModbusRTU::addr2str(end)
						 << " reg=" << ModbusRTU::dat2str(reg)
						 << " fn=" << ModbusRTU::b2str(fn)
						 << endl;
				}

				try
				{
					ModbusRTU::ModbusAddr a = ModbusHelpers::autodetectSlave(&mb,beg,end,reg,fn);
					cout << "(mtr-setup): autodetect modbus slave: " << ModbusRTU::addr2str(a) << endl;
				}
				catch( UniSetTypes::TimeOut )
				{
					cout << "(mtr-setup): slave not autodetect..." << endl;
				}
			break;
			}

			case cmdDetectSpeed:
			{
				if( verb )
				{
					cout << "(mtr-setup): autodetect speed: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << " reg=" << ModbusRTU::dat2str(reg)
						 << " fn=" << ModbusRTU::b2str(fn)
						 << endl;
				}

				try
				{
					ComPort::Speed s = ModbusHelpers::autodetectSpeed(&mb,slaveaddr,reg,fn);
					cout << "(mtr-setup): autodetect: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						<< " speed=" << ComPort::getSpeed(s) << endl;
				}
				catch( UniSetTypes::TimeOut )
				{
					cout << "(mtr-setup): speed not autodetect for slaveaddr="
						<< ModbusRTU::addr2str(slaveaddr) << endl;
				}
			}
			break;

			case cmdGetModel:
			{
				if( verb )
				{
					cout << "(mtr-setup): model: "
						 << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << endl;
				}

				cout << "model: " << MTR::getModelNumber(&mb,slaveaddr) << endl;
			}
			break;

			case cmdGetSerial:
			{
				if( verb )
				{
					cout << "(mtr-setup): serial: "
						 << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
						 << endl;
				}

				cout << "serial: " << MTR::getSerialNumber(&mb,slaveaddr) << endl;
			}
			break;

			case cmdNOP:
			default:
				cerr << "No command. Use -h for help." << endl;
				return 1;
		}

		return 0;
	}
	catch( ModbusRTU::mbException& ex )
	{
		cerr << "(mtr-setup): " << ex << endl;
	}
	catch(SystemError& err)
	{
		cerr << "(mtr-setup): " << err << endl;
	}
	catch(Exception& ex)
	{
		cerr << "(mtr-setup): " << ex << endl;
	}
	catch(...)
	{
		cerr << "(mtr-setup): catch(...)" << endl;
	}

	return 1;
}
// --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
{
	if( i<argc && (argv[i])[0]!='-' )
		return argv[i];

	return 0;
}
// --------------------------------------------------------------------------
<|endoftext|>


<commit_before><commit_msg>Make output errors also a process error in CLI.<commit_after><|endoftext|>


<commit_before>#include "GuiEventManager.hpp"
#include "GuiEventObserver.hpp"
#include "DirectGuiEventObserver.hpp"

#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

// Christopher D. Canfield
// October 2013
// GuiEventManager.cpp

using cdc::GuiEventManager;
using cdc::DirectGuiEventObserver;
using cdc::GuiEventObserver;

// Passes the event to the GuiEventObservers in the referenced vector.
void notifyGuiEventObservers(const std::vector<GuiEventObserver*>& observers, const sf::Event& e);
// Passes the event to the observers in the referenced vector.
void notifyDirectGuiEventObservers(const std::vector<DirectGuiEventObserver*>& observers, const sf::Event& e);
// Removes the specified observer from the referenced vector if it is found in the container.
void removeIfMatchFound(std::vector<GuiEventObserver*>& observers, const GuiEventObserver& o);

void GuiEventManager::update(const sf::Event& e, const sf::RenderWindow& window)
{
	if (e.type == sf::Event::MouseButtonReleased)
	{
		sf::Event clonedEvent(e);
		sf::Vector2i location(e.mouseButton.x, e.mouseButton.y);
		clonedEvent.mouseButton.x = static_cast<int>(window.mapPixelToCoords(location).x);
		clonedEvent.mouseButton.y = static_cast<int>(window.mapPixelToCoords(location).y);

		notifyDirectGuiEventObservers(directClickObservers, clonedEvent);
		notifyGuiEventObservers(clickObservers, clonedEvent);
	}
	else if (e.type == sf::Event::MouseMoved)
	{
		sf::Event clonedEvent(e);
		sf::Vector2i location(e.mouseButton.x, e.mouseButton.y);
		clonedEvent.mouseMove.x = static_cast<int>(window.mapPixelToCoords(location).x);
		clonedEvent.mouseMove.y = static_cast<int>(window.mapPixelToCoords(location).y);

		notifyDirectGuiEventObservers(directMouseMoveObservers, clonedEvent);
		notifyGuiEventObservers(mouseMoveObservers, clonedEvent);
	}
	else if (e.type == sf::Event::KeyPressed)
	{
		notifyGuiEventObservers(keyPressObservers, e);
	}
	else if (e.type == sf::Event::MouseWheelMoved)
	{
		notifyGuiEventObservers(mouseWheelObservers, e);
	}
}

void GuiEventManager::addClickListener(GuiEventObserver& o)
{
	clickObservers.push_back(&o);
}

void GuiEventManager::removeClickListener(const GuiEventObserver& o)
{
	removeIfMatchFound(clickObservers, o);
}

void GuiEventManager::addMouseMoveListener(GuiEventObserver& o)
{
	mouseMoveObservers.push_back(&o);
}

void GuiEventManager::removeMouseMoveListener(const GuiEventObserver& o)
{
	removeIfMatchFound(mouseMoveObservers, o);
}

void GuiEventManager::addMouseWheelListener(GuiEventObserver& o)
{
	mouseWheelObservers.push_back(&o);
}

void GuiEventManager::removeMouseWheelListener(const GuiEventObserver& o)
{
	removeIfMatchFound(mouseWheelObservers, o);
}

void GuiEventManager::addKeyPressListener(GuiEventObserver& o)
{
	keyPressObservers.push_back(&o);
}

void GuiEventManager::removeKeyPressListener(const GuiEventObserver& o)
{
	removeIfMatchFound(keyPressObservers, o);
}

void GuiEventManager::addDirectClickListener(DirectGuiEventObserver& o)
{
	directClickObservers.push_back(&o);
}

void GuiEventManager::removeDirectClickListener(const DirectGuiEventObserver& o)
{
	for (auto observer = directClickObservers.begin(); observer != directClickObservers.end();)
	{
		if (*observer == &o)
		{
			observer = directClickObservers.erase(observer);
		}
		else
		{
			++observer;
		}
	}
}

void GuiEventManager::addDirectMouseMoveListener(DirectGuiEventObserver& o)
{
	directMouseMoveObservers.push_back(&o);
}

void GuiEventManager::removeDirectMouseMoveListener(const DirectGuiEventObserver& o)
{
	for (auto observer = directMouseMoveObservers.begin(); observer != directMouseMoveObservers.end();)
	{
		if (*observer == &o)
		{
			observer = directMouseMoveObservers.erase(observer);
		}
		else
		{
			++observer;
		}
	}
}

void notifyGuiEventObservers(const std::vector<GuiEventObserver*>& observers, const sf::Event& e)
{
	for (auto observer : observers)
	{
		observer->onGuiEvent(e);
	}
}

void notifyDirectGuiEventObservers(const std::vector<DirectGuiEventObserver*>& observers, const sf::Event& e)
{
	float mouseX = static_cast<float>((e.type == sf::Event::MouseMoved) ? e.mouseMove.x : e.mouseButton.x);
	float mouseY = static_cast<float>((e.type == sf::Event::MouseMoved) ? e.mouseMove.y : e.mouseButton.y);

	for (auto observer : observers)
	{
		auto boundingBox = observer->getBoundingBox();
		// Call the observer's onClick method if the click fell within the observer's
		// bounding box.
		if (boundingBox.contains(mouseX, mouseY))
		{
			observer->onDirectGuiEvent(e);
		}
	}
}

void removeIfMatchFound(std::vector<GuiEventObserver*>& observers, const GuiEventObserver& o)
{
	for (auto observer = observers.begin(); observer != observers.end();)
	{
		if (*observer == &o)
		{
			observer = observers.erase(observer);
		}
		else
		{
			++observer;
		}
	}
}
<commit_msg>Fixed addtl issues w/ GuiEventManager<commit_after>#include "GuiEventManager.hpp"
#include "GuiEventObserver.hpp"
#include "DirectGuiEventObserver.hpp"

#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

#include <iostream>

// Christopher D. Canfield
// October 2013
// GuiEventManager.cpp

using cdc::GuiEventManager;
using cdc::DirectGuiEventObserver;
using cdc::GuiEventObserver;

// Passes the event to the GuiEventObservers in the referenced vector.
void notifyGuiEventObservers(const std::vector<GuiEventObserver*>& observers, const sf::Event& e);
// Passes the event to the observers in the referenced vector.
void notifyDirectGuiEventObservers(const std::vector<DirectGuiEventObserver*>& observers, const sf::Event& e);
// Removes the specified observer from the referenced vector if it is found in the container.
void removeIfMatchFound(std::vector<GuiEventObserver*>& observers, const GuiEventObserver& o);

void GuiEventManager::update(const sf::Event& e, const sf::RenderWindow& window)
{
	if (e.type == sf::Event::MouseButtonReleased)
	{
		sf::Event clonedEvent(e);
		sf::Vector2i location(e.mouseButton.x, e.mouseButton.y);
		clonedEvent.mouseButton.x = static_cast<int>(window.mapPixelToCoords(location).x);
		clonedEvent.mouseButton.y = static_cast<int>(window.mapPixelToCoords(location).y);

		notifyDirectGuiEventObservers(directClickObservers, clonedEvent);
		notifyGuiEventObservers(clickObservers, clonedEvent);
	}
	else if (e.type == sf::Event::MouseMoved)
	{
		sf::Event clonedEvent(e);
		sf::Vector2i location(e.mouseMove.x, e.mouseMove.y);
		clonedEvent.mouseMove.x = static_cast<int>(window.mapPixelToCoords(location).x);
		clonedEvent.mouseMove.y = static_cast<int>(window.mapPixelToCoords(location).y);

		notifyDirectGuiEventObservers(directMouseMoveObservers, clonedEvent);
		notifyGuiEventObservers(mouseMoveObservers, clonedEvent);
	}
	else if (e.type == sf::Event::KeyPressed)
	{
		notifyGuiEventObservers(keyPressObservers, e);
	}
	else if (e.type == sf::Event::MouseWheelMoved)
	{
		notifyGuiEventObservers(mouseWheelObservers, e);
	}
}

void GuiEventManager::addClickListener(GuiEventObserver& o)
{
	clickObservers.push_back(&o);
}

void GuiEventManager::removeClickListener(const GuiEventObserver& o)
{
	removeIfMatchFound(clickObservers, o);
}

void GuiEventManager::addMouseMoveListener(GuiEventObserver& o)
{
	mouseMoveObservers.push_back(&o);
}

void GuiEventManager::removeMouseMoveListener(const GuiEventObserver& o)
{
	removeIfMatchFound(mouseMoveObservers, o);
}

void GuiEventManager::addMouseWheelListener(GuiEventObserver& o)
{
	mouseWheelObservers.push_back(&o);
}

void GuiEventManager::removeMouseWheelListener(const GuiEventObserver& o)
{
	removeIfMatchFound(mouseWheelObservers, o);
}

void GuiEventManager::addKeyPressListener(GuiEventObserver& o)
{
	keyPressObservers.push_back(&o);
}

void GuiEventManager::removeKeyPressListener(const GuiEventObserver& o)
{
	removeIfMatchFound(keyPressObservers, o);
}

void GuiEventManager::addDirectClickListener(DirectGuiEventObserver& o)
{
	directClickObservers.push_back(&o);
}

void GuiEventManager::removeDirectClickListener(const DirectGuiEventObserver& o)
{
	for (auto observer = directClickObservers.begin(); observer != directClickObservers.end();)
	{
		if (*observer == &o)
		{
			observer = directClickObservers.erase(observer);
		}
		else
		{
			++observer;
		}
	}
}

void GuiEventManager::addDirectMouseMoveListener(DirectGuiEventObserver& o)
{
	directMouseMoveObservers.push_back(&o);
}

void GuiEventManager::removeDirectMouseMoveListener(const DirectGuiEventObserver& o)
{
	for (auto observer = directMouseMoveObservers.begin(); observer != directMouseMoveObservers.end();)
	{
		if (*observer == &o)
		{
			observer = directMouseMoveObservers.erase(observer);
		}
		else
		{
			++observer;
		}
	}
}

void notifyGuiEventObservers(const std::vector<GuiEventObserver*>& observers, const sf::Event& e)
{
	for (auto observer : observers)
	{
		observer->onGuiEvent(e);
	}
}

void notifyDirectGuiEventObservers(const std::vector<DirectGuiEventObserver*>& observers, const sf::Event& e)
{
	float mouseX = static_cast<float>((e.type == sf::Event::MouseMoved) ? e.mouseMove.x : e.mouseButton.x);
	float mouseY = static_cast<float>((e.type == sf::Event::MouseMoved) ? e.mouseMove.y : e.mouseButton.y);

	for (auto observer : observers)
	{
		auto boundingBox = observer->getBoundingBox();
		// Call the observer's onClick method if the click fell within the observer's
		// bounding box.
		if (boundingBox.contains(mouseX, mouseY))
		{
			observer->onDirectGuiEvent(e);
		}
	}
}

void removeIfMatchFound(std::vector<GuiEventObserver*>& observers, const GuiEventObserver& o)
{
	for (auto observer = observers.begin(); observer != observers.end();)
	{
		if (*observer == &o)
		{
			observer = observers.erase(observer);
		}
		else
		{
			++observer;
		}
	}
}
<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "std_msgs/Float32.h"
#include "subSim/motor.h"
#include "Robosub/ModuleEnableMsg.h"
#include "Robosub/Point.h"
#include "Robosub/Line.h"

#define OFF 0
#define ON 1

const float MAX_THRESHOLD = 0.05; //5%
const float MIN_THRESHOLD = 0.01; //1%
//bool OMODE = OFF;
bool POINTMODE = OFF;
bool LINEMODE = OFF;
//bool Centered = false;
bool Begun = false;
bool OnLine = false;
bool Rotating = false;

float start_x = 0;
float start_y = 0;
float start_rot = 0;

void mEnabledCallback(const Robosub::ModuleEnableMsg::ConstPtr& msg) {
	if(msg->Module == "Center_on_Point"){
		POINTMODE = msg->State;
	} else if (msg->Module == "Center_on_Line"){
	    LINEMODE = msg->State;
	}
}

void mPointCallback(const Robosub::Point::ConstPtr& msg) {
	if(POINTMODE == OFF)
		return;
		// The speed is created based on the difference between
        // the target point and the center

    // If the it is the beginning of the process
    // save the target as the objective

    // Target points
    int target_x = msg->x;
    int target_y = msg->y;

    if (!target_x && !target_y ) {
//        Centered = true;
        Begun = false;
        start_x = 0;
        start_y = 0;

        setStraf(0);
        setDive(0);

        return;
    }

    if (!Begun){ // First assignment: create starting points
        start_x = msg->x;
        start_y = msg->y;
        Begun = true;
//        Centered = false;
    }

    // Calculate the directions what direction do we have to move?

    int dir_x = target_x>0 ? 1 : -1; //Left -1, Right +1
    int dir_y = target_y>0 ? -1 : 1; //Up -1, Down +1

    // Calculate the percentage (OR SIMPLY USE ERROR??)

    float per_x = (target_x/start_x);
    float per_y = (target_y/start_y);

    //  Control Process (calculate the right thrust)
    //  Use less than 100% based on how big the number is.

    //  Convert the distance percentage to thrust percentage

    // These are set assuming there is no bias on the voltage
    // sent to the thrusters
    int minT = 50; // to avoid sending values under the minimum.
    //maxT = 90; //To avoid moving too fast and sucking too much power
    int range = 40;

    int thrust_x = 0;
    int thrust_y = 0;

    if((per_x) <MAX_THRESHOLD){
        if((per_x)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_x = -60*dir_x;
        } else {
            thrust_x = 0;
        }
    } else {
        thrust_x = (range*per_x+minT)*dir_x;
    }

    if((per_y) <MAX_THRESHOLD){
        if((per_y)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_y = -60*dir_y;
        } else {
            thrust_y = 0; // We zeroed out in this direction
        }
    } else {
        if(dir_y>0) // && FORWARDCAMERA
            range = 30; //So we don't go up too fast
            thrust_y = (range*per_y+minT)*dir_y;
    }

    //Send the calculated speed to the motor
    setStraf(thrust_x);
    setDive(thrust_y);

}

bool moveToLine(int x, int y){
    //Returns 1 if on top of the line, 0 otherwise

    int target_x = x;
    int target_y = y;

    if (!target_x && !target_y ) {
//        Centered = true;
        Begun = false;

        start_x = 0;
        start_y = 0;

        setStraf(0);
        setDrive(0);

        return 1; //Centered
    }

    if (!Begun){ // First assignment: create starting points
        start_x = msg->x;
        start_y = msg->y;
        Begun = true;
//        Centered = false;
    }

    // Calculate the directions what direction do we have to move?

    int dir_x = target_x>0 ? 1 : -1; //Left -1, Right +1
    int dir_y = target_y>0 ? 1 : -1; //Reverse -1, Forward +1

    // Calculate the percentage (OR SIMPLY USE ERROR??)

    float per_x = (target_x/start_x);
    float per_y = (target_y/start_y);

    //  Control Process (calculate the right thrust)
    //  Use less than 100% based on how big the number is.

    //  Convert the distance percentage to thrust percentage

    // These are set assuming there is no bias on the voltage
    // sent to the thrusters
    int minT = 50; // to avoid sending values under the minimum.
    //maxT = 90; //To avoid moving too fast and sucking too much power
    int range = 40;

    int thrust_x = 0;
    int thrust_y = 0;

    if((per_x) <MAX_THRESHOLD ){
        if((per_x)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_x = -60*dir_x;
        } else {
            thrust_x = 0; // this line may be unnecessary
        }
    } else {
        thrust_x = (range*per_x+minT)*dir_x;
    }

    if((per_y) <MAX_THRESHOLD ){
        if((per_y)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_y = -60*dir_y;
        } else {
            thrust_y = 0; // We zeroed out in this direction
        }
    } else {
        if(dir_y>0) // && FORWARDCAMERA
            range = 30; //So we don't go up too fast
            thrust_y = (range*per_y+minT)*dir_y;
    }

    if (!thrust_x && !thrust_y)
        return 1; //No speed means we're <1% away

    //Send the calculated speed to the motor
    setStraf(thrust_x);
    setDrive(thrust_y);

    return 0;

}

void mLineCallback(const Robosub::Line::ConstPtr& msg) {
	if(LINEMODE == OFF)
		return;

    OnLine = moveToLine(msg->x, msg->y);
    //Once it's on top of the line, rotate
    if (!OnLine){
        return;
    }

    int target_rot = msg->rotation;
    if(!target_rot)
        return; //Stoppped by Higher Level

    if(!Rotating){
        start_rot = target_rot;
    }

    float per_rot = (target_rot/start_rot);

    //This needs to be implemented better (any ideas?)
    int direction = 1; //always rotate right?
    //int direction = target_rot>180? -1 : 1; //-1 Rotate left

    int rate = 0;
    int range=40;
    int minR = 50;

    if(abs(per_rot)<MAX_THRESHOLD ){
        if(abs(per_rot)>.01)
            rate = -60*direction;
        else
            rate = 0;
    } else {
        rate = (range*per_rot+minR)*direction;
    }

    setTurn(rate);

}

int main(int argc, char** argv) {
	ros::init(argc, argv, "NavCenterOnPoint");
	ros::NodeHandle nh;
	ros::Subscriber targetPoint = nh.subscribe("/Center_on_Point", 1, mPointCallback);
	ros::Subscriber targetLine = nh.subscribe("/Center_on_Line", 1, mLineCallback);
	ros::Subscriber enabled = nh.subscribe("/Module_Control", 1, mEnabledCallback);
	ros::spin();
}

<commit_msg>Fixed a little thing on NavigationControl<commit_after>#include "ros/ros.h"
#include "std_msgs/Float32.h"
#include "subSim/motor.h"
#include "Robosub/ModuleEnableMsg.h"
#include "Robosub/Point.h"
#include "Robosub/Line.h"

#define OFF 0
#define ON 1

const float MAX_THRESHOLD = 0.05; //5%
const float MIN_THRESHOLD = 0.01; //1%
//bool OMODE = OFF;
bool POINTMODE = OFF;
bool LINEMODE = OFF;
//bool Centered = false;
bool Begun = false;
bool OnLine = false;
bool Rotating = false;

float start_x = 0;
float start_y = 0;
float start_rot = 0;

void mEnabledCallback(const Robosub::ModuleEnableMsg::ConstPtr& msg) {
	if(msg->Module == "Center_on_Point"){
		POINTMODE = msg->State;
	} else if (msg->Module == "Center_on_Line"){
	    LINEMODE = msg->State;
	}
}

void mPointCallback(const Robosub::Point::ConstPtr& msg) {
	if(POINTMODE == OFF)
		return;
		// The speed is created based on the difference between
        // the target point and the center

    // If the it is the beginning of the process
    // save the target as the objective

    // Target points
    int target_x = msg->x;
    int target_y = msg->y;

    if (!target_x && !target_y ) {
//        Centered = true;
        Begun = false;
        start_x = 0;
        start_y = 0;

        setStraf(0);
        setDive(0);

        return;
    }

    if (!Begun){ // First assignment: create starting points
        start_x = msg->x;
        start_y = msg->y;
        Begun = true;
//        Centered = false;
    }

    // Calculate the directions what direction do we have to move?

    int dir_x = target_x>0 ? 1 : -1; //Left -1, Right +1
    int dir_y = target_y>0 ? -1 : 1; //Up -1, Down +1

    // Calculate the percentage (OR SIMPLY USE ERROR??)

    float per_x = (target_x/start_x);
    float per_y = (target_y/start_y);

    //  Control Process (calculate the right thrust)
    //  Use less than 100% based on how big the number is.

    //  Convert the distance percentage to thrust percentage

    // These are set assuming there is no bias on the voltage
    // sent to the thrusters
    int minT = 50; // to avoid sending values under the minimum.
    //maxT = 90; //To avoid moving too fast and sucking too much power
    int range = 40;

    int thrust_x = 0;
    int thrust_y = 0;

    if((per_x) <MAX_THRESHOLD){
        if((per_x)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_x = -60*dir_x;
        } else {
            thrust_x = 0;
        }
    } else {
        thrust_x = (range*per_x+minT)*dir_x;
    }

    if((per_y) <MAX_THRESHOLD){
        if((per_y)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_y = -60*dir_y;
        } else {
            thrust_y = 0; // We zeroed out in this direction
        }
    } else {
        if(dir_y>0) // && FORWARDCAMERA
            range = 30; //So we don't go up too fast
            thrust_y = (range*per_y+minT)*dir_y;
    }

    //Send the calculated speed to the motor
    setStraf(thrust_x);
    setDive(thrust_y);

}

bool moveToLine(int x, int y){
    //Returns 1 if on top of the line, 0 otherwise

    int target_x = x;
    int target_y = y;

    if (!target_x && !target_y ) {
//        Centered = true;
        Begun = false;

        start_x = 0;
        start_y = 0;

        setStraf(0);
        setDrive(0);

        return 1; //Centered
    }

    if (!Begun){ // First assignment: create starting points
        start_x = msg->x;
        start_y = msg->y;
        Begun = true;
//        Centered = false;
    }

    // Calculate the directions what direction do we have to move?

    int dir_x = target_x>0 ? 1 : -1; //Left -1, Right +1
    int dir_y = target_y>0 ? 1 : -1; //Reverse -1, Forward +1

    // Calculate the percentage (OR SIMPLY USE ERROR??)

    float per_x = (target_x/start_x);
    float per_y = (target_y/start_y);

    //  Control Process (calculate the right thrust)
    //  Use less than 100% based on how big the number is.

    //  Convert the distance percentage to thrust percentage

    // These are set assuming there is no bias on the voltage
    // sent to the thrusters
    int minT = 50; // to avoid sending values under the minimum.
    //maxT = 90; //To avoid moving too fast and sucking too much power
    int range = 40;

    int thrust_x = 0;
    int thrust_y = 0;

    if((per_x) <MAX_THRESHOLD ){
        if((per_x)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_x = -60*dir_x;
        } else {
            thrust_x = 0; // this line may be unnecessary
        }
    } else {
        thrust_x = (range*per_x+minT)*dir_x;
    }

    if((per_y) <MAX_THRESHOLD ){
        if((per_y)>MIN_THRESHOLD){ //Send a negative thrust to decrease the speed
            thrust_y = -60*dir_y;
        } else {
            thrust_y = 0; // We zeroed out in this direction
        }
    } else {
        if(dir_y>0) // && FORWARDCAMERA
            range = 30; //So we don't go up too fast
            thrust_y = (range*per_y+minT)*dir_y;
    }

    if (!thrust_x && !thrust_y)
        return 1; //No speed means we're <1% away

    //Send the calculated speed to the motor
    setStraf(thrust_x);
    setDrive(thrust_y);

    return 0;

}

void mLineCallback(const Robosub::Line::ConstPtr& msg) {
	if(LINEMODE == OFF)
		return;

    OnLine = moveToLine(msg->x, msg->y);
    //Once it's on top of the line, rotate
    if (!OnLine){
        return; //keep rotating
    }

    int target_rot = msg->rotation;
    if(!target_rot){
	 start_rot = 0;
         Rotating = 0;
	 setTurn(0);
	 return; //Stoppped by Higher Level
    }
    if(!Rotating){
        start_rot = target_rot;
    }

    float per_rot = (target_rot/start_rot);

    //This needs to be implemented better (any ideas?)
    int direction = 1; //always rotate right?
    //int direction = target_rot>180? -1 : 1; //-1 Rotate left

    int rate = 0;
    int range=40;
    int minR = 50;

    if(abs(per_rot)<MAX_THRESHOLD ){
        if(abs(per_rot)>.01)
            rate = -60*direction;
        else
            rate = 0;
    } else {
        rate = (range*per_rot+minR)*direction;
    }

    setTurn(rate);

}

int main(int argc, char** argv) {
	ros::init(argc, argv, "NavCenterOnPoint");
	ros::NodeHandle nh;
	ros::Subscriber targetPoint = nh.subscribe("/Center_on_Point", 1, mPointCallback);
	ros::Subscriber targetLine = nh.subscribe("/Center_on_Line", 1, mLineCallback);
	ros::Subscriber enabled = nh.subscribe("/Module_Control", 1, mEnabledCallback);
	ros::spin();
}

<|endoftext|>


<commit_before>/* * This file is part of Maliit framework *
 *
 * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * Contact: maliit-discuss@lists.maliit.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

// Based on minputmethodstate.cpp from libmeegotouch

#include "inputmethod.h"
#include "inputmethod_p.h"

#if QT_VERSION >= 0x050000
#include <QGuiApplication>
#include <QInputPanel>
#else
#include <QApplication>
#include <QInputContext>
#endif

namespace Maliit {

InputMethodPrivate::InputMethodPrivate() :
    area(),
    widget(0),
    orientationAngle(),
    rotationInProgress(false)
{
}

InputMethodPrivate::~InputMethodPrivate()
{
}

InputMethod::InputMethod() :
    QObject(),
    d_ptr(new InputMethodPrivate)
{
}

InputMethod::~InputMethod()
{
}

InputMethod *InputMethod::instance()
{
    static InputMethod singleton;

    return &singleton;
}

void InputMethod::setWidget(QWidget *widget)
{
    Q_D(InputMethod);
    d->widget = widget;
}

QWidget *InputMethod::widget() const
{
    Q_D(const InputMethod);
    return d->widget;
}

QRect InputMethod::area() const
{
    Q_D(const InputMethod);

    return d->area;
}

void InputMethod::setArea(const QRect &newArea)
{
    Q_D(InputMethod);

    if (d->area != newArea) {
        d->area = newArea;
        Q_EMIT areaChanged(d->area);
    }
}

void InputMethod::startOrientationAngleChange(OrientationAngle newOrientationAngle)
{
    Q_D(InputMethod);

    if (d->orientationAngle != newOrientationAngle) {
        d->orientationAngle = newOrientationAngle;
        d->rotationInProgress = true;
        Q_EMIT orientationAngleAboutToChange(d->orientationAngle);
    }
}

void InputMethod::setOrientationAngle(OrientationAngle newOrientationAngle)
{
    Q_D(InputMethod);

    if (d->orientationAngle != newOrientationAngle) {
        d->orientationAngle = newOrientationAngle;
        d->rotationInProgress = true;
    }

    if (d->rotationInProgress) {
        d->rotationInProgress = false;
        Q_EMIT orientationAngleChanged(d->orientationAngle);
    }
}

OrientationAngle InputMethod::orientationAngle() const
{
    Q_D(const InputMethod);

    return d->orientationAngle;
}

void InputMethod::emitKeyPress(const QKeyEvent &event)
{
    Q_EMIT keyPress(event);
}

void InputMethod::emitKeyRelease(const QKeyEvent &event)
{
    Q_EMIT keyRelease(event);
}

void InputMethod::setLanguage(const QString &language)
{
    Q_D(InputMethod);
    if (d->language != language) {
        d->language = language;
        Q_EMIT languageChanged(language);
    }
}

const QString &InputMethod::language() const
{
    Q_D(const InputMethod);
    return d->language;
}

void requestInputMethodPanel()
{
#if QT_VERSION >= 0x050000
    qApp->inputPanel()->show();
#else
    QInputContext *inputContext = qApp->inputContext();

    if (!inputContext) {
        return;
    }

    QEvent request(QEvent::RequestSoftwareInputPanel);
    inputContext->filterEvent(&request);
#endif
}

void closeInputMethodPanel()
{
#if QT_VERSION >= 0x050000
    qApp->inputPanel()->hide();
#else
    QInputContext *inputContext = qApp->inputContext();

    if (!inputContext) {
        return;
    }

    QEvent close(QEvent::CloseSoftwareInputPanel);
    inputContext->filterEvent(&close);
    inputContext->reset();
#endif
}

} // namespace Maliit
<commit_msg>Allow compiling with Qt5<commit_after>/* * This file is part of Maliit framework *
 *
 * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * Contact: maliit-discuss@lists.maliit.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

// Based on minputmethodstate.cpp from libmeegotouch

#include "inputmethod.h"
#include "inputmethod_p.h"

#if QT_VERSION >= 0x050000
#include <QGuiApplication>
#include <QInputMethod>
#else
#include <QApplication>
#include <QInputContext>
#endif

namespace Maliit {

InputMethodPrivate::InputMethodPrivate() :
    area(),
    widget(0),
    orientationAngle(),
    rotationInProgress(false)
{
}

InputMethodPrivate::~InputMethodPrivate()
{
}

InputMethod::InputMethod() :
    QObject(),
    d_ptr(new InputMethodPrivate)
{
}

InputMethod::~InputMethod()
{
}

InputMethod *InputMethod::instance()
{
    static InputMethod singleton;

    return &singleton;
}

void InputMethod::setWidget(QWidget *widget)
{
    Q_D(InputMethod);
    d->widget = widget;
}

QWidget *InputMethod::widget() const
{
    Q_D(const InputMethod);
    return d->widget;
}

QRect InputMethod::area() const
{
    Q_D(const InputMethod);

    return d->area;
}

void InputMethod::setArea(const QRect &newArea)
{
    Q_D(InputMethod);

    if (d->area != newArea) {
        d->area = newArea;
        Q_EMIT areaChanged(d->area);
    }
}

void InputMethod::startOrientationAngleChange(OrientationAngle newOrientationAngle)
{
    Q_D(InputMethod);

    if (d->orientationAngle != newOrientationAngle) {
        d->orientationAngle = newOrientationAngle;
        d->rotationInProgress = true;
        Q_EMIT orientationAngleAboutToChange(d->orientationAngle);
    }
}

void InputMethod::setOrientationAngle(OrientationAngle newOrientationAngle)
{
    Q_D(InputMethod);

    if (d->orientationAngle != newOrientationAngle) {
        d->orientationAngle = newOrientationAngle;
        d->rotationInProgress = true;
    }

    if (d->rotationInProgress) {
        d->rotationInProgress = false;
        Q_EMIT orientationAngleChanged(d->orientationAngle);
    }
}

OrientationAngle InputMethod::orientationAngle() const
{
    Q_D(const InputMethod);

    return d->orientationAngle;
}

void InputMethod::emitKeyPress(const QKeyEvent &event)
{
    Q_EMIT keyPress(event);
}

void InputMethod::emitKeyRelease(const QKeyEvent &event)
{
    Q_EMIT keyRelease(event);
}

void InputMethod::setLanguage(const QString &language)
{
    Q_D(InputMethod);
    if (d->language != language) {
        d->language = language;
        Q_EMIT languageChanged(language);
    }
}

const QString &InputMethod::language() const
{
    Q_D(const InputMethod);
    return d->language;
}

void requestInputMethodPanel()
{
#if QT_VERSION >= 0x050000
    qApp->inputMethod()->show();
#else
    QInputContext *inputContext = qApp->inputContext();

    if (!inputContext) {
        return;
    }

    QEvent request(QEvent::RequestSoftwareInputPanel);
    inputContext->filterEvent(&request);
#endif
}

void closeInputMethodPanel()
{
#if QT_VERSION >= 0x050000
    qApp->inputMethod()->hide();
#else
    QInputContext *inputContext = qApp->inputContext();

    if (!inputContext) {
        return;
    }

    QEvent close(QEvent::CloseSoftwareInputPanel);
    inputContext->filterEvent(&close);
    inputContext->reset();
#endif
}

} // namespace Maliit
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03

// <experimental/filesystem>

// uintmax_t hard_link_count(const path& p);
// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept;

#include <experimental/filesystem>
#include <type_traits>
#include <cassert>

#include "test_macros.h"
#include "rapid-cxx-test.hpp"
#include "filesystem_test_helper.hpp"

using namespace std::experimental::filesystem;

TEST_SUITE(hard_link_count_test_suite)

TEST_CASE(signature_test)
{
    const path p; ((void)p);
    std::error_code ec; ((void)ec);
    ASSERT_SAME_TYPE(decltype(hard_link_count(p)), uintmax_t);
    ASSERT_SAME_TYPE(decltype(hard_link_count(p, ec)), uintmax_t);
    ASSERT_NOT_NOEXCEPT(hard_link_count(p));
    ASSERT_NOEXCEPT(hard_link_count(p, ec));
}

TEST_CASE(hard_link_count_for_file)
{
    TEST_CHECK(hard_link_count(StaticEnv::File) == 1);
    std::error_code ec;
    TEST_CHECK(hard_link_count(StaticEnv::File, ec) == 1);
}

TEST_CASE(hard_link_count_for_directory)
{
    uintmax_t DirExpect = 3; // hard link from . .. and Dir2
    uintmax_t Dir3Expect = 2; // hard link from . ..
    uintmax_t DirExpectAlt = DirExpect;
    uintmax_t Dir3ExpectAlt = Dir3Expect;
#if defined(__APPLE__)
    // Filesystems formatted with case sensitive hfs+ behave unixish as
    // expected. Normal hfs+ filesystems report the number of directory
    // entries instead.
    DirExpectAlt = 5; // .  ..  Dir2  file1  file2
    Dir3Expect = 3; // .  ..  file5
#endif
    TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect ||
               hard_link_count(StaticEnv::Dir) == DirExpectAlt);
    TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect ||
               hard_link_count(StaticEnv::Dir3) == Dir3ExpectAlt);

    std::error_code ec;
    TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect ||
               hard_link_count(StaticEnv::Dir, ec) == DirExpectAlt);
    TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect ||
               hard_link_count(StaticEnv::Dir3, ec) == Dir3ExpectAlt);
}
TEST_CASE(hard_link_count_increments_test)
{
    scoped_test_env env;
    const path file = env.create_file("file", 42);
    TEST_CHECK(hard_link_count(file) == 1);

    env.create_hardlink(file, "file_hl");
    TEST_CHECK(hard_link_count(file) == 2);
}

TEST_CASE(hard_link_count_error_cases)
{
    const path testCases[] = {
        StaticEnv::BadSymlink,
        StaticEnv::DNE
    };
    const uintmax_t expect = static_cast<uintmax_t>(-1);
    for (auto& TC : testCases) {
        std::error_code ec;
        TEST_CHECK(hard_link_count(TC, ec) == expect);
        TEST_CHECK(ec);
    }
}

TEST_SUITE_END()
<commit_msg>[test] Fix hard_link_count test to account for fs with dir nlink==1<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03

// <experimental/filesystem>

// uintmax_t hard_link_count(const path& p);
// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept;

#include <experimental/filesystem>
#include <type_traits>
#include <cassert>

#include "test_macros.h"
#include "rapid-cxx-test.hpp"
#include "filesystem_test_helper.hpp"

using namespace std::experimental::filesystem;

TEST_SUITE(hard_link_count_test_suite)

TEST_CASE(signature_test)
{
    const path p; ((void)p);
    std::error_code ec; ((void)ec);
    ASSERT_SAME_TYPE(decltype(hard_link_count(p)), uintmax_t);
    ASSERT_SAME_TYPE(decltype(hard_link_count(p, ec)), uintmax_t);
    ASSERT_NOT_NOEXCEPT(hard_link_count(p));
    ASSERT_NOEXCEPT(hard_link_count(p, ec));
}

TEST_CASE(hard_link_count_for_file)
{
    TEST_CHECK(hard_link_count(StaticEnv::File) == 1);
    std::error_code ec;
    TEST_CHECK(hard_link_count(StaticEnv::File, ec) == 1);
}

TEST_CASE(hard_link_count_for_directory)
{
    uintmax_t DirExpect = 3; // hard link from . .. and Dir2
    uintmax_t Dir3Expect = 2; // hard link from . ..
    uintmax_t DirExpectAlt = DirExpect;
    uintmax_t Dir3ExpectAlt = Dir3Expect;
#if defined(__APPLE__)
    // Filesystems formatted with case sensitive hfs+ behave unixish as
    // expected. Normal hfs+ filesystems report the number of directory
    // entries instead.
    DirExpectAlt = 5; // .  ..  Dir2  file1  file2
    Dir3Expect = 3; // .  ..  file5
#endif
    TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect ||
               hard_link_count(StaticEnv::Dir) == DirExpectAlt ||
               hard_link_count(StaticEnv::Dir) == 1);
    TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect ||
               hard_link_count(StaticEnv::Dir3) == Dir3ExpectAlt ||
               hard_link_count(StaticEnv::Dir3) == 1);

    std::error_code ec;
    TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect ||
               hard_link_count(StaticEnv::Dir, ec) == DirExpectAlt ||
               hard_link_count(StaticEnv::Dir) == 1);
    TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect ||
               hard_link_count(StaticEnv::Dir3, ec) == Dir3ExpectAlt ||
               hard_link_count(StaticEnv::Dir3) == 1);
}
TEST_CASE(hard_link_count_increments_test)
{
    scoped_test_env env;
    const path file = env.create_file("file", 42);
    TEST_CHECK(hard_link_count(file) == 1);

    env.create_hardlink(file, "file_hl");
    TEST_CHECK(hard_link_count(file) == 2);
}

TEST_CASE(hard_link_count_error_cases)
{
    const path testCases[] = {
        StaticEnv::BadSymlink,
        StaticEnv::DNE
    };
    const uintmax_t expect = static_cast<uintmax_t>(-1);
    for (auto& TC : testCases) {
        std::error_code ec;
        TEST_CHECK(hard_link_count(TC, ec) == expect);
        TEST_CHECK(ec);
    }
}

TEST_SUITE_END()
<|endoftext|>


<commit_before>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/cdm/cenc_utils.h"

#include "base/stl_util.h"
#include "media/formats/mp4/box_definitions.h"
#include "media/formats/mp4/box_reader.h"

namespace media {

// The initialization data for encrypted media files using the ISO Common
// Encryption ('cenc') protection scheme may contain one or more protection
// system specific header ('pssh') boxes.
// ref: https://w3c.github.io/encrypted-media/cenc-format.html

// CENC SystemID for the Common System.
// https://w3c.github.io/encrypted-media/cenc-format.html#common-system
const uint8_t kCencCommonSystemId[] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2,
                                       0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
                                       0x52, 0xe2, 0xfb, 0x4b};

// Returns true if |input| contains only 1 or more valid 'pssh' boxes, false
// otherwise. |pssh_boxes| is updated as the set of parsed 'pssh' boxes.
// Note: All boxes in |input| must be 'pssh' boxes. However, if they can't be
//       properly parsed (e.g. unsupported version), then they will be skipped.
static bool ReadAllPsshBoxes(
    const std::vector<uint8_t>& input,
    std::vector<mp4::FullProtectionSystemSpecificHeader>* pssh_boxes) {
  DCHECK(!input.empty());

  // Verify that |input| contains only 'pssh' boxes.
  // ReadAllChildrenAndCheckFourCC() is templated, so it checks that each
  // box in |input| matches the box type of the parameter (in this case
  // mp4::ProtectionSystemSpecificHeader is a 'pssh' box).
  // mp4::ProtectionSystemSpecificHeader doesn't validate the 'pssh' contents,
  // so this simply verifies that |input| only contains 'pssh' boxes and
  // nothing else.
  scoped_ptr<mp4::BoxReader> input_reader(
      mp4::BoxReader::ReadConcatentatedBoxes(
          vector_as_array(&input), input.size()));
  std::vector<mp4::ProtectionSystemSpecificHeader> raw_pssh_boxes;
  if (!input_reader->ReadAllChildrenAndCheckFourCC(&raw_pssh_boxes))
    return false;

  // Now that we have |input| parsed into |raw_pssh_boxes|, reparse each one
  // into a mp4::FullProtectionSystemSpecificHeader, which extracts all the
  // relevant fields from the box. Since there may be unparseable 'pssh' boxes
  // (due to unsupported version, for example), this is done one by one,
  // ignoring any boxes that can't be parsed.
  for (const auto& raw_pssh_box : raw_pssh_boxes) {
    scoped_ptr<mp4::BoxReader> raw_pssh_reader(
        mp4::BoxReader::ReadConcatentatedBoxes(
            vector_as_array(&raw_pssh_box.raw_box),
            raw_pssh_box.raw_box.size()));
    // ReadAllChildren() appends any successfully parsed box onto it's
    // parameter, so |pssh_boxes| will contain the collection of successfully
    // parsed 'pssh' boxes. If an error occurs, try the next box.
    if (!raw_pssh_reader->ReadAllChildrenAndCheckFourCC(pssh_boxes))
      continue;
  }

  // Must have successfully parsed at least one 'pssh' box.
  return pssh_boxes->size() > 0;
}

bool ValidatePsshInput(const std::vector<uint8_t>& input) {
  // No 'pssh' boxes is considered valid.
  if (input.empty())
    return true;

  std::vector<mp4::FullProtectionSystemSpecificHeader> children;
  return ReadAllPsshBoxes(input, &children);
}

bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& pssh_boxes,
                                KeyIdList* key_ids) {
  // If there are no 'pssh' boxes then no key IDs found.
  if (pssh_boxes.empty())
    return false;

  std::vector<mp4::FullProtectionSystemSpecificHeader> children;
  if (!ReadAllPsshBoxes(pssh_boxes, &children))
    return false;

  // Check all children for an appropriate 'pssh' box, returning the
  // key IDs found.
  KeyIdList result;
  std::vector<uint8_t> common_system_id(
      kCencCommonSystemId,
      kCencCommonSystemId + arraysize(kCencCommonSystemId));
  for (const auto& child : children) {
    if (child.system_id == common_system_id) {
      key_ids->assign(child.key_ids.begin(), child.key_ids.end());
      return key_ids->size() > 0;
    }
  }

  // No matching 'pssh' box found.
  return false;
}

bool GetPsshData(const std::vector<uint8_t>& input,
                 const std::vector<uint8_t>& system_id,
                 std::vector<uint8_t>* pssh_data) {
  if (input.empty())
    return false;

  std::vector<mp4::FullProtectionSystemSpecificHeader> children;
  if (!ReadAllPsshBoxes(input, &children))
    return false;

  // Check all children for an appropriate 'pssh' box, returning |data| from
  // the first one found.
  for (const auto& child : children) {
    if (child.system_id == system_id) {
      pssh_data->assign(child.data.begin(), child.data.end());
      return true;
    }
  }

  // No matching 'pssh' box found.
  return false;
}

}  // namespace media
<commit_msg>[EME] Add support of legacy cenc system id for testing.<commit_after>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/cdm/cenc_utils.h"

#include "base/stl_util.h"
#include "media/formats/mp4/box_definitions.h"
#include "media/formats/mp4/box_reader.h"

namespace media {

// The initialization data for encrypted media files using the ISO Common
// Encryption ('cenc') protection scheme may contain one or more protection
// system specific header ('pssh') boxes.
// ref: https://w3c.github.io/encrypted-media/cenc-format.html

// CENC SystemID for the Common System.
// https://w3c.github.io/encrypted-media/cenc-format.html#common-system
const uint8_t kCencCommonSystemId[] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2,
                                       0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
                                       0x52, 0xe2, 0xfb, 0x4b};

#if defined(USE_GSTREAMER)
const uint8_t kLegacyCencCommonSystemId[] = {0x58, 0x14, 0x7e, 0xc8, 0x04, 0x23,
                                             0x46, 0x59, 0x92, 0xe6, 0xf5, 0x2c,
                                             0x5c, 0xe8, 0xc3, 0xcc};
#endif

// Returns true if |input| contains only 1 or more valid 'pssh' boxes, false
// otherwise. |pssh_boxes| is updated as the set of parsed 'pssh' boxes.
// Note: All boxes in |input| must be 'pssh' boxes. However, if they can't be
//       properly parsed (e.g. unsupported version), then they will be skipped.
static bool ReadAllPsshBoxes(
    const std::vector<uint8_t>& input,
    std::vector<mp4::FullProtectionSystemSpecificHeader>* pssh_boxes) {
  DCHECK(!input.empty());

  // Verify that |input| contains only 'pssh' boxes.
  // ReadAllChildrenAndCheckFourCC() is templated, so it checks that each
  // box in |input| matches the box type of the parameter (in this case
  // mp4::ProtectionSystemSpecificHeader is a 'pssh' box).
  // mp4::ProtectionSystemSpecificHeader doesn't validate the 'pssh' contents,
  // so this simply verifies that |input| only contains 'pssh' boxes and
  // nothing else.
  scoped_ptr<mp4::BoxReader> input_reader(
      mp4::BoxReader::ReadConcatentatedBoxes(
          vector_as_array(&input), input.size()));
  std::vector<mp4::ProtectionSystemSpecificHeader> raw_pssh_boxes;
  if (!input_reader->ReadAllChildrenAndCheckFourCC(&raw_pssh_boxes))
    return false;

  // Now that we have |input| parsed into |raw_pssh_boxes|, reparse each one
  // into a mp4::FullProtectionSystemSpecificHeader, which extracts all the
  // relevant fields from the box. Since there may be unparseable 'pssh' boxes
  // (due to unsupported version, for example), this is done one by one,
  // ignoring any boxes that can't be parsed.
  for (const auto& raw_pssh_box : raw_pssh_boxes) {
    scoped_ptr<mp4::BoxReader> raw_pssh_reader(
        mp4::BoxReader::ReadConcatentatedBoxes(
            vector_as_array(&raw_pssh_box.raw_box),
            raw_pssh_box.raw_box.size()));
    // ReadAllChildren() appends any successfully parsed box onto it's
    // parameter, so |pssh_boxes| will contain the collection of successfully
    // parsed 'pssh' boxes. If an error occurs, try the next box.
    if (!raw_pssh_reader->ReadAllChildrenAndCheckFourCC(pssh_boxes))
      continue;
  }

  // Must have successfully parsed at least one 'pssh' box.
  return pssh_boxes->size() > 0;
}

bool ValidatePsshInput(const std::vector<uint8_t>& input) {
  // No 'pssh' boxes is considered valid.
  if (input.empty())
    return true;

  std::vector<mp4::FullProtectionSystemSpecificHeader> children;
  return ReadAllPsshBoxes(input, &children);
}

bool GetKeyIdsForCommonSystemId(const std::vector<uint8_t>& pssh_boxes,
                                KeyIdList* key_ids) {
  // If there are no 'pssh' boxes then no key IDs found.
  if (pssh_boxes.empty())
    return false;

  std::vector<mp4::FullProtectionSystemSpecificHeader> children;
  if (!ReadAllPsshBoxes(pssh_boxes, &children))
    return false;

  // Check all children for an appropriate 'pssh' box, returning the
  // key IDs found.
  KeyIdList result;
  std::vector<uint8_t> common_system_id(
      kCencCommonSystemId,
      kCencCommonSystemId + arraysize(kCencCommonSystemId));
#if defined(USE_GSTREAMER)  // Some tests still use legacy cenc id.
  std::vector<uint8_t> legacy_common_system_id(
      kLegacyCencCommonSystemId,
      kLegacyCencCommonSystemId + arraysize(kLegacyCencCommonSystemId));
#endif
  for (const auto& child : children) {
#if defined(USE_GSTREAMER)
    if (child.system_id == common_system_id ||
        child.system_id == legacy_common_system_id) {
#else
    if (child.system_id == common_system_id) {
#endif
      key_ids->assign(child.key_ids.begin(), child.key_ids.end());
#if defined(USE_GSTREAMER)
      return true;  // pssh for common decryption might not have key ids at all.
#else
      return key_ids->size() > 0;
#endif
    }
  }

  // No matching 'pssh' box found.
  return false;
}

bool GetPsshData(const std::vector<uint8_t>& input,
                 const std::vector<uint8_t>& system_id,
                 std::vector<uint8_t>* pssh_data) {
  if (input.empty())
    return false;

  std::vector<mp4::FullProtectionSystemSpecificHeader> children;
  if (!ReadAllPsshBoxes(input, &children))
    return false;

  // Check all children for an appropriate 'pssh' box, returning |data| from
  // the first one found.
  for (const auto& child : children) {
    if (child.system_id == system_id) {
      pssh_data->assign(child.data.begin(), child.data.end());
      return true;
    }
  }

  // No matching 'pssh' box found.
  return false;
}

}  // namespace media
<|endoftext|>


<commit_before>/* Copyright (c) 2014 Quanta Research Cambridge, Inc
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include "P4TopIndication.h"
#include "P4TopRequest.h"
#include "GeneratedTypes.h"
#include "utils.h"

#ifndef le32
#define le32    int32_t
#endif

#ifndef u32
#define u32     u_int32_t
#endif

#ifndef u16
#define u16     u_int16_t
#endif

#ifndef s32
#define s32     int32_t
#endif

#define DATA_WIDTH 128

struct pcap_file_header {
    u32 magic;
    u16 version_major;
    u16 version_minor;
    s32 thiszone; /* gmt to local correction */
    u32 sigfigs;  /* accuracy of timL1 cache bytes userspaceestamps */
    u32 snaplen;  /* max length saved portion of each pkt */
    u32 linktype; /* data link type (LINKTYPE_*) */
} __attribute__((packed));

struct pcap_pkthdr_ts {
    le32 hts_sec;
    le32 hts_usec;
}  __attribute__((packed));

struct pcap_pkthdr {
    struct  pcap_pkthdr_ts ts;  /* time stamp */
    le32 caplen;              /* length of portion present */
    le32 length;                  /* length this packet (off wire) */
}  __attribute__((packed));

void mem_copy(const void *buff, int length);

static P4TopRequestProxy *device = 0;

class P4TopIndication : public P4TopIndicationWrapper
{
public:
    virtual void sonic_read_version_resp(uint32_t a) {
        fprintf(stderr, "version %08x\n", a);
    }
    virtual void matchTableResponse(uint32_t key, uint32_t value) {
        fprintf(stderr, "\nkey = %u  value = %u\n", key, value);
    }
    P4TopIndication(unsigned int id) : P4TopIndicationWrapper(id) {}
};

void mem_copy(const void *buff, int packet_size) {

    int i, sop, eop;
    uint64_t data[2];
    int numBeats;

    numBeats = packet_size / 8; // 16 bytes per beat for 128-bit datawidth;
    if (packet_size % 8) numBeats++;
    PRINT_INFO("nBeats=%d, packetSize=%d\n", numBeats, packet_size);
    for (i=0; i<numBeats; i++) {
        data[i%2] = *(static_cast<const uint64_t *>(buff) + i);
        sop = (i/2 == 0);
        eop = (i/2 == (numBeats-1)/2);
        if (i%2) {
            device->writePacketData(data, sop, eop);
            PRINT_INFO("%016lx %016lx %d %d\n", data[1], data[0], sop, eop);
        }

        // last beat, padding with zero
        if ((numBeats%2!=0) && (i==numBeats-1)) {
            sop = (i/2 == 0) ? 1 : 0;
            eop = 1;
            data[1] = 0;
            device->writePacketData(data, sop, eop);
            PRINT_INFO("%016lx %016lx %d %d\n", data[1], data[0], sop, eop);
        }
    }
}

/**
 * Send packet on quick_tx device
 * @param qtx       pointer to a quick_tx structure
 * @param buffer   full packet data starting at the ETH frame
 * @param length  length of packet (must be over 0)
 * @return           length of packet if it was successfully queued, QTX_E_EXIT if a critical error occurred
 *                  and close needs to be called
 */
static inline int quick_tx_send_packet(const void* buffer, int length) {
    assert(buffer);
    assert(length > 0);

#ifdef EXTRA_DEBUG
    printf("[quick_tx] Copying data from %p buffer, length = %d\n",
                (buffer, length);
#endif
    mem_copy(buffer, length);

    return length;
}

bool read_pcap_file(char* filename, void** buffer, long *length) {
    FILE *infile;
    long length_read;

    infile = fopen(filename, "r");
    if(infile == NULL) {
            printf("File does not exist!\n");
            return false;
        }

    fseek(infile, 0L, SEEK_END);
    *length = ftell(infile);
    fseek(infile, 0L, SEEK_SET);
    *buffer = (char*)calloc(*length, sizeof(char));

    /* memory error */
    if(*buffer == NULL) {
            printf("Could not allocate %ld bytes of memory!\n", *length);
            return false;
        }

    length_read = fread(*buffer, sizeof(char), *length, infile);
    *length = length_read;
    fclose(infile);

    return true;
}

int main(int argc, char **argv)
{
    void *buffer;
    long length;
    struct pcap_pkthdr* pcap_hdr;
    int i;
    int loops = 1;

    P4TopIndication echoIndication(IfcNames_P4TopIndicationH2S);
    device = new P4TopRequestProxy(IfcNames_P4TopRequestS2H);

    device->sonic_read_version();

    device->matchTableRequest(10, 15, 1);
    device->matchTableRequest(10, 0, 0);
    while(1);
    fprintf(stderr, "Attempts to read pcap file %s\n", argv[1]);
    if (!read_pcap_file(argv[1], &buffer, &length)) {
        perror("Failed to read file!");
        exit(-1);
    }

    for (i = 0; i < loops; i++) {
        void* offset = static_cast<char *>(buffer) + sizeof(struct pcap_file_header);

        while(offset < static_cast<char *>(buffer) + length) {
            pcap_hdr = (struct pcap_pkthdr*) offset;
            offset = static_cast<char *>(offset) + sizeof(struct pcap_pkthdr);

            if ((quick_tx_send_packet((const void*)offset, pcap_hdr->caplen)) < 0) {
                printf("An error occurred while trying to send a packet\n");
                exit(-1);
            }

            offset = static_cast<char *>(offset) + pcap_hdr->caplen;
        }
    }

    while(1) sleep(1);

    return 0;
}
<commit_msg>added more robust tests that tests all ops<commit_after>/* Copyright (c) 2014 Quanta Research Cambridge, Inc
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include "P4TopIndication.h"
#include "P4TopRequest.h"
#include "GeneratedTypes.h"
#include "utils.h"

#ifndef le32
#define le32    int32_t
#endif

#ifndef u32
#define u32     u_int32_t
#endif

#ifndef u16
#define u16     u_int16_t
#endif

#ifndef s32
#define s32     int32_t
#endif

#define DATA_WIDTH 128

struct pcap_file_header {
    u32 magic;
    u16 version_major;
    u16 version_minor;
    s32 thiszone; /* gmt to local correction */
    u32 sigfigs;  /* accuracy of timL1 cache bytes userspaceestamps */
    u32 snaplen;  /* max length saved portion of each pkt */
    u32 linktype; /* data link type (LINKTYPE_*) */
} __attribute__((packed));

struct pcap_pkthdr_ts {
    le32 hts_sec;
    le32 hts_usec;
}  __attribute__((packed));

struct pcap_pkthdr {
    struct  pcap_pkthdr_ts ts;  /* time stamp */
    le32 caplen;              /* length of portion present */
    le32 length;                  /* length this packet (off wire) */
}  __attribute__((packed));

void mem_copy(const void *buff, int length);

static P4TopRequestProxy *device = 0;

class P4TopIndication : public P4TopIndicationWrapper
{
public:
    virtual void sonic_read_version_resp(uint32_t a) {
        fprintf(stderr, "version %08x\n", a);
    }
    virtual void matchTableResponse(uint32_t key, uint32_t value) {
        fprintf(stderr, "GET : key = %u  value = %u\n", key, value);
    }
    P4TopIndication(unsigned int id) : P4TopIndicationWrapper(id) {}
};

void mem_copy(const void *buff, int packet_size) {

    int i, sop, eop;
    uint64_t data[2];
    int numBeats;

    numBeats = packet_size / 8; // 16 bytes per beat for 128-bit datawidth;
    if (packet_size % 8) numBeats++;
    PRINT_INFO("nBeats=%d, packetSize=%d\n", numBeats, packet_size);
    for (i=0; i<numBeats; i++) {
        data[i%2] = *(static_cast<const uint64_t *>(buff) + i);
        sop = (i/2 == 0);
        eop = (i/2 == (numBeats-1)/2);
        if (i%2) {
            device->writePacketData(data, sop, eop);
            PRINT_INFO("%016lx %016lx %d %d\n", data[1], data[0], sop, eop);
        }

        // last beat, padding with zero
        if ((numBeats%2!=0) && (i==numBeats-1)) {
            sop = (i/2 == 0) ? 1 : 0;
            eop = 1;
            data[1] = 0;
            device->writePacketData(data, sop, eop);
            PRINT_INFO("%016lx %016lx %d %d\n", data[1], data[0], sop, eop);
        }
    }
}

/**
 * Send packet on quick_tx device
 * @param qtx       pointer to a quick_tx structure
 * @param buffer   full packet data starting at the ETH frame
 * @param length  length of packet (must be over 0)
 * @return           length of packet if it was successfully queued, QTX_E_EXIT if a critical error occurred
 *                  and close needs to be called
 */
static inline int quick_tx_send_packet(const void* buffer, int length) {
    assert(buffer);
    assert(length > 0);

#ifdef EXTRA_DEBUG
    printf("[quick_tx] Copying data from %p buffer, length = %d\n",
                (buffer, length);
#endif
    mem_copy(buffer, length);

    return length;
}

bool read_pcap_file(char* filename, void** buffer, long *length) {
    FILE *infile;
    long length_read;

    infile = fopen(filename, "r");
    if(infile == NULL) {
            printf("File does not exist!\n");
            return false;
        }

    fseek(infile, 0L, SEEK_END);
    *length = ftell(infile);
    fseek(infile, 0L, SEEK_SET);
    *buffer = (char*)calloc(*length, sizeof(char));

    /* memory error */
    if(*buffer == NULL) {
            printf("Could not allocate %ld bytes of memory!\n", *length);
            return false;
        }

    length_read = fread(*buffer, sizeof(char), *length, infile);
    *length = length_read;
    fclose(infile);

    return true;
}

int main(int argc, char **argv)
{
    void *buffer;
    long length;
    struct pcap_pkthdr* pcap_hdr;
    int i;
    int loops = 1;

    P4TopIndication echoIndication(IfcNames_P4TopIndicationH2S);
    device = new P4TopRequestProxy(IfcNames_P4TopRequestS2H);

    device->sonic_read_version();

    device->matchTableRequest(10, 15, 1); //PUT(10,15)
    device->matchTableRequest(10, 0, 0);  //GET(10) should print k=10 v=15
    device->matchTableRequest(10, 20, 2); //UPDATE(10,20)
    device->matchTableRequest(10, 0, 0);  //GET(10) should print k=10 v=20
    device->matchTableRequest(10, 0, 3);  //REMOVE(10)
    device->matchTableRequest(10, 0, 0);  //GET(10) should not print anything
    device->matchTableRequest(10, 30, 2); //UPDATE(10,30) should not update
    device->matchTableRequest(10, 0, 0);  //GET(10) should not print anything
    device->matchTableRequest(10, 45, 1); //PUT(10,45)
    device->matchTableRequest(10, 0, 0);  //GET(10) should print k=10 v=45

    while(1);

    fprintf(stderr, "Attempts to read pcap file %s\n", argv[1]);
    if (!read_pcap_file(argv[1], &buffer, &length)) {
        perror("Failed to read file!");
        exit(-1);
    }

    for (i = 0; i < loops; i++) {
        void* offset = static_cast<char *>(buffer) + sizeof(struct pcap_file_header);

        while(offset < static_cast<char *>(buffer) + length) {
            pcap_hdr = (struct pcap_pkthdr*) offset;
            offset = static_cast<char *>(offset) + sizeof(struct pcap_pkthdr);

            if ((quick_tx_send_packet((const void*)offset, pcap_hdr->caplen)) < 0) {
                printf("An error occurred while trying to send a packet\n");
                exit(-1);
            }

            offset = static_cast<char *>(offset) + pcap_hdr->caplen;
        }
    }

    while(1) sleep(1);

    return 0;
}
<|endoftext|>


<commit_before>#include "../ris_lib/ris_resources_from_file.h"
#include "../ris_lib/ris_bundle_compression.h"
#include "../ris_lib/ris_writing_files.h"
#include "../ris_lib/template.h"
#include "../ris_lib/ris_resource_loader.h"
#include "../ris_lib/ris_default_or_from_file.h"
#include "../ris_lib/ris_resource_snapshot.h"
#include "../ris_lib/ris_late_context.h"
#include "../ris_lib/ris_late.h"
#include "../ris_lib/ris_resource_loader.h"

#include <iostream>
#include <string>
#include <stdexcept>
#include <unordered_map>

#include <boost/filesystem.hpp>

void print_usage() {
    std::cout
        << "---      ris v0.3.0            ---" << std::endl
        << "a simple resource compiler for c++" << std::endl
        << "https://github.com/d-led/ris" << std::endl
        << "USAGE:" << std::endl
        << "       ris <path_to>/<resources>.[json/yml/yaml] [<template_overrides>.[json/yml/yaml]]" << std::endl
        << "Available algorithms: " << ris::bundle_compression().available_algorithms() << std::endl
        << "Minimal YAML resource file:"
        <<
R"(
#------------------------
header: "res.h"
source: "res.cpp"

resources:
  -
    compression: "LZ4F"
    name: "some_text"
    source: "some text"
    source_type: "string"
#------------------------
)" << std::endl
        ;
}

template <typename TResource>
std::string member_name(TResource const& res) {
    if (!res.member_name.empty())
        return res.member_name;
    return res.name;
}

void process(std::string const& path, std::string const& source_template) {
    auto full_path = absolute(boost::filesystem::path(path));
    full_path.make_preferred();
    std::cout << "reading " << full_path.generic_string() << std::endl;

    auto user_resources = ris::load_resources_from_file(path);
    auto lookup = user_resources.to_lookup();
    std::cout << "read " << user_resources.resources().resources.size() << " resources" << std::endl;

    auto compression = ris::bundle_compression();
    auto ris_res = ris::default_or_from_file<ris::Resource>(source_template);
    auto template_snapshot = ris::resource_snapshot(ris_res);
    bool any_with_compression = std::any_of(std::begin(user_resources.resources().resources),
        std::end(user_resources.resources().resources),
        [&compression](ris::resource const& res) {
        return compression.is_legal(res.compression);
    });

    ris::write_to_temp_first_then_move header([&ris_res, &template_snapshot, &user_resources,&lookup](std::ostream& s) {
        template_snapshot["namespace_name"] = user_resources.namespace_();
        template_snapshot["class_name"] = user_resources.class_();
        auto lazy = ris::get_context(template_snapshot);
        lazy
            .lazy("header", [&lazy, &ris_res](std::ostream& s) {
                ris::render(ris_res.Get("header"), lazy, s);
            })
            .lazy("header_declarations", [&ris_res,&user_resources,&lazy](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy.lazy("resource_member_name", [&resource](std::ostream& s){
                        s << member_name(resource);
                    });
                    ris::render(ris_res.Get("header_single_declaration"), lazy, s);
                }
            })
            .lazy("header_resource_names", [&ris_res, &user_resources, &lazy](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy.lazy("resource_name", [&resource](std::ostream& s){
                        s << resource.name;
                    });
                    ris::render(ris_res.Get("header_single_resource_name"), lazy, s);
                }
            })
        ;
        ris::render("{{header}}", lazy, s);
    }, user_resources.header());
    header.start();

    ris::write_to_temp_first_then_move source([&](std::ostream& s) {
        template_snapshot["namespace_name"] = user_resources.namespace_();
        template_snapshot["class_name"] = user_resources.class_();
        auto lazy = ris::get_context(template_snapshot);
        lazy
            .lazy("source", [&lazy, &ris_res](std::ostream& s) {
                ris::render(ris_res.Get("source"), lazy, s);
            })
            .lazy("optional_compression_header", [&](std::ostream& s) {
                if (any_with_compression)
                    s << "#include <bundle.hpp>\n";
            })
            .lazy("source_default_include", [&](std::ostream& s) {
                s << "#include \"" << boost::filesystem::path(user_resources.header()).filename().generic_string() << "\"";
            })
            .lazy("source_definitions", [&](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy
                    .lazy("resource_member_name", [&](std::ostream& s){
                        s << member_name(resource);
                    })
                    .lazy("source_literal_bytes", [&](std::ostream& s){
                        static const unsigned MAX_IN_ONE_LINE = 100;
                        std::string data = ris::resource_loader(resource, user_resources.base_path()).get();

                        auto raw_size = data.size();

                        if (compression.is_legal(resource.compression)) {
                            data = compression.pack(resource.compression, data);
                            auto new_size = data.size();
                            std::cout << "[" << resource.compression << "] "
                                << resource.name << ": "
                                << new_size << "/" << raw_size
                                << " (" << ((double)new_size / raw_size*100.0) << "%)" << std::endl;
                        }

                        int count = 0;

                        for (char c : data) {
                            if (count > MAX_IN_ONE_LINE - 1) {
                                count = 0;
                            }

                            if (count == 0) {
                                s << "\n        ";
                            }

                            s << static_cast<short>(c) << ", ";

                            count++;
                        }
                    })
                    .lazy("source_return_literal", [&](std::ostream& s) {
                        if (compression.is_legal(resource.compression)) {
                            ris::render(ris_res.Get("source_return_compressed_literal"), lazy, s);
                        }
                        else {
                            ris::render(ris_res.Get("source_return_plain_literal"), lazy, s);
                        }
                    })
                    ;
                    ris::render(ris_res.Get("source_single_definition"), lazy, s);
                }
            })
            .lazy("source_getters", [&](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy
                    .lazy("resource_name", [&resource](std::ostream& s){
                        s << resource.name;
                    })
                    .lazy("resource_member_name", [&](std::ostream& s){
                        s << member_name(resource);
                    })
                    ;
                    ris::render(ris_res.Get("source_single_getter"), lazy, s);
                }
            })
        ;
        ris::render("{{source}}", lazy, s);
    }, user_resources.source());
    source.start();
}

int main(int argc, char ** argv) {
    std::string source_template;

    switch (argc) {
        case 3:
            source_template = argv[2];
            // fall through
        case 2:
            try {
                process(argv[1], source_template);
            }
            catch (std::exception& e) {
                std::cerr << "Error: " << e.what() << std::endl;
                return 1;
            }
            break;
        default:
            print_usage();
    }
}
<commit_msg>prettier output [ci skip]<commit_after>#include "../ris_lib/ris_resources_from_file.h"
#include "../ris_lib/ris_bundle_compression.h"
#include "../ris_lib/ris_writing_files.h"
#include "../ris_lib/template.h"
#include "../ris_lib/ris_resource_loader.h"
#include "../ris_lib/ris_default_or_from_file.h"
#include "../ris_lib/ris_resource_snapshot.h"
#include "../ris_lib/ris_late_context.h"
#include "../ris_lib/ris_late.h"
#include "../ris_lib/ris_resource_loader.h"

#include <iostream>
#include <string>
#include <stdexcept>
#include <unordered_map>

#include <boost/filesystem.hpp>

void print_usage() {
    std::cout
        << "---      ris v0.3.0            ---" << std::endl
        << "a simple resource compiler for c++" << std::endl
        << "https://github.com/d-led/ris" << std::endl
        << "USAGE:" << std::endl
        << "       ris <path_to>/<resources>.[json/yml/yaml] [<template_overrides>.[json/yml/yaml]]" << std::endl << std::endl
        << "Available algorithms: " << ris::bundle_compression().available_algorithms() << std::endl << std::endl
        << "Minimal YAML resource file:"
        <<
R"(
#------------------------
header: "res.h"
source: "res.cpp"

resources:
  -
    compression: "LZ4F"
    name: "some_text"
    source: "some text"
    source_type: "string"
#------------------------
)" << std::endl
        ;
}

template <typename TResource>
std::string member_name(TResource const& res) {
    if (!res.member_name.empty())
        return res.member_name;
    return res.name;
}

void process(std::string const& path, std::string const& source_template) {
    auto full_path = absolute(boost::filesystem::path(path));
    full_path.make_preferred();
    std::cout << "reading " << full_path.generic_string() << std::endl;

    auto user_resources = ris::load_resources_from_file(path);
    auto lookup = user_resources.to_lookup();
    std::cout << "read " << user_resources.resources().resources.size() << " resources" << std::endl;

    auto compression = ris::bundle_compression();
    auto ris_res = ris::default_or_from_file<ris::Resource>(source_template);
    auto template_snapshot = ris::resource_snapshot(ris_res);
    bool any_with_compression = std::any_of(std::begin(user_resources.resources().resources),
        std::end(user_resources.resources().resources),
        [&compression](ris::resource const& res) {
        return compression.is_legal(res.compression);
    });

    ris::write_to_temp_first_then_move header([&ris_res, &template_snapshot, &user_resources,&lookup](std::ostream& s) {
        template_snapshot["namespace_name"] = user_resources.namespace_();
        template_snapshot["class_name"] = user_resources.class_();
        auto lazy = ris::get_context(template_snapshot);
        lazy
            .lazy("header", [&lazy, &ris_res](std::ostream& s) {
                ris::render(ris_res.Get("header"), lazy, s);
            })
            .lazy("header_declarations", [&ris_res,&user_resources,&lazy](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy.lazy("resource_member_name", [&resource](std::ostream& s){
                        s << member_name(resource);
                    });
                    ris::render(ris_res.Get("header_single_declaration"), lazy, s);
                }
            })
            .lazy("header_resource_names", [&ris_res, &user_resources, &lazy](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy.lazy("resource_name", [&resource](std::ostream& s){
                        s << resource.name;
                    });
                    ris::render(ris_res.Get("header_single_resource_name"), lazy, s);
                }
            })
        ;
        ris::render("{{header}}", lazy, s);
    }, user_resources.header());
    header.start();

    ris::write_to_temp_first_then_move source([&](std::ostream& s) {
        template_snapshot["namespace_name"] = user_resources.namespace_();
        template_snapshot["class_name"] = user_resources.class_();
        auto lazy = ris::get_context(template_snapshot);
        lazy
            .lazy("source", [&lazy, &ris_res](std::ostream& s) {
                ris::render(ris_res.Get("source"), lazy, s);
            })
            .lazy("optional_compression_header", [&](std::ostream& s) {
                if (any_with_compression)
                    s << "#include <bundle.hpp>\n";
            })
            .lazy("source_default_include", [&](std::ostream& s) {
                s << "#include \"" << boost::filesystem::path(user_resources.header()).filename().generic_string() << "\"";
            })
            .lazy("source_definitions", [&](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy
                    .lazy("resource_member_name", [&](std::ostream& s){
                        s << member_name(resource);
                    })
                    .lazy("source_literal_bytes", [&](std::ostream& s){
                        static const unsigned MAX_IN_ONE_LINE = 100;
                        std::string data = ris::resource_loader(resource, user_resources.base_path()).get();

                        auto raw_size = data.size();

                        if (compression.is_legal(resource.compression)) {
                            data = compression.pack(resource.compression, data);
                            auto new_size = data.size();
                            std::cout << "[" << resource.compression << "] "
                                << resource.name << ": "
                                << new_size << "/" << raw_size
                                << " (" << ((double)new_size / raw_size*100.0) << "%)" << std::endl;
                        }

                        int count = 0;

                        for (char c : data) {
                            if (count > MAX_IN_ONE_LINE - 1) {
                                count = 0;
                            }

                            if (count == 0) {
                                s << "\n        ";
                            }

                            s << static_cast<short>(c) << ", ";

                            count++;
                        }
                    })
                    .lazy("source_return_literal", [&](std::ostream& s) {
                        if (compression.is_legal(resource.compression)) {
                            ris::render(ris_res.Get("source_return_compressed_literal"), lazy, s);
                        }
                        else {
                            ris::render(ris_res.Get("source_return_plain_literal"), lazy, s);
                        }
                    })
                    ;
                    ris::render(ris_res.Get("source_single_definition"), lazy, s);
                }
            })
            .lazy("source_getters", [&](std::ostream& s) {
                for (auto& resource : user_resources.resources().resources) {
                    lazy
                    .lazy("resource_name", [&resource](std::ostream& s){
                        s << resource.name;
                    })
                    .lazy("resource_member_name", [&](std::ostream& s){
                        s << member_name(resource);
                    })
                    ;
                    ris::render(ris_res.Get("source_single_getter"), lazy, s);
                }
            })
        ;
        ris::render("{{source}}", lazy, s);
    }, user_resources.source());
    source.start();
}

int main(int argc, char ** argv) {
    std::string source_template;

    switch (argc) {
        case 3:
            source_template = argv[2];
            // fall through
        case 2:
            try {
                process(argv[1], source_template);
            }
            catch (std::exception& e) {
                std::cerr << "Error: " << e.what() << std::endl;
                return 1;
            }
            break;
        default:
            print_usage();
    }
}
<|endoftext|>