text:
// This file is part of the ROS PLUGIN for V-REP
//
// Copyright 2006-2014 Coppelia Robotics GmbH. All rights reserved.
// marc@coppeliarobotics.com
// www.coppeliarobotics.com
//
// A big thanks to Svetlin Penkov for his precious help!
//
// The ROS PLUGIN is licensed under the terms of GNU GPL:
//
// -------------------------------------------------------------------
// The ROS PLUGIN is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// THE ROS PLUGIN IS DISTRIBUTED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTY. THE USER WILL USE IT AT HIS/HER OWN RISK. THE ORIGINAL
// AUTHORS AND COPPELIA ROBOTICS GMBH WILL NOT BE LIABLE FOR DATA LOSS,
// DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR
// MISUSING THIS SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the ROS PLUGIN.  If not, see <http://www.gnu.org/licenses/>.
// -------------------------------------------------------------------
//
// This file was automatically created for V-REP release V3.1.2 on June 16th 2014

#include "../include/v_repLib.h"
#include <boost/lexical_cast.hpp>
#include "../include/vrep_plugin/vrep_plugin.h"
#include "../include/vrep_plugin/ROS_server.h"

#include "ros/ros.h"
#include "std_msgs/Float32.h"

#include <iostream>
#include <opencv2/opencv.hpp>

#define PLUGIN_VERSION 2

#define LUA_ENABLE_PUBLISHER			"simExtROS_enablePublisher"
#define LUA_ENABLE_PUBLISHER_TIPS 	"string topicName=" LUA_ENABLE_PUBLISHER "(string topicName,number queueSize,number rosStreamCmd,number auxInt1,number auxInt2,string auxString,number publishCnt=0)"

#define LUA_DISABLE_PUBLISHER			"simExtROS_disablePublisher"
#define LUA_DISABLE_PUBLISHER_TIPS 	"number referenceCounter=" LUA_DISABLE_PUBLISHER "(string topicName)"

#define LUA_WAKE_PUBLISHER			"simExtROS_wakePublisher"
#define LUA_WAKE_PUBLISHER_TIPS 	"number result=" LUA_WAKE_PUBLISHER "(string topicName,number publishCnt)"

#define LUA_ENABLE_SUBSCRIBER			"simExtROS_enableSubscriber"
#define LUA_ENABLE_SUBSCRIBER_TIPS 	"number subscriberID=" LUA_ENABLE_SUBSCRIBER "(string topicName,number queueSize,number rosStreamCmd,number auxInt1,number auxInt2,string auxString)"

#define LUA_DISABLE_SUBSCRIBER			"simExtROS_disableSubscriber"
#define LUA_DISABLE_SUBSCRIBER_TIPS 	"boolean result=" LUA_DISABLE_SUBSCRIBER "(number subscriberID)"

LIBRARY vrepLib; // the V-REP library that we will dynamically load and bind

void LUA_ENABLE_PUBLISHER_CALLBACK(SLuaCallBack* p)
{
	std::string effectiveTopicName;
	if (p->inputArgCount>=6)
	{
		// Ok, we have at least 6 input argument
		if (	(p->inputArgTypeAndSize[0*2+0]==sim_lua_arg_string) &&
				(p->inputArgTypeAndSize[1*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[2*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[3*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[4*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[5*2+0]==sim_lua_arg_string) )
		{ // the input arguments seem ok
			std::string topicName(p->inputChar);
			std::string auxString(p->inputChar+strlen(p->inputChar)+1);
			int queueSize=p->inputInt[0];
			int streamCmd=p->inputInt[1];
			int auxInt1=p->inputInt[2];
			int auxInt2=p->inputInt[3];
			int publishCnt=0; // 0 is the default value for this optional argument
			bool allIsFine=true;
			if (p->inputArgCount>=7)
			{ // Check the optional argument 'publishCnt':
				if (p->inputArgTypeAndSize[6*2+0]==sim_lua_arg_int)
					publishCnt=p->inputInt[4];
				else
					allIsFine=false;
			}

			if (allIsFine)
			{
				int errorModeSaved;
				simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
				simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);

				effectiveTopicName=ROS_server::addPublisher(topicName.c_str(),queueSize,streamCmd,auxInt1,auxInt2,auxString.c_str(),publishCnt);

				simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings

				if (effectiveTopicName.length()==0)
					simSetLastError(LUA_ENABLE_PUBLISHER, "Topic could not be published."); // output an error
			}
			else
				simSetLastError(LUA_ENABLE_PUBLISHER, "Wrong argument type/size."); // output an error
		}
		else
			simSetLastError(LUA_ENABLE_PUBLISHER, "Wrong argument type/size."); // output an error
	}
	else
		simSetLastError(LUA_ENABLE_PUBLISHER, "Wrong number of arguments."); // output an error

	// Now we prepare the return value:
	if (effectiveTopicName.length()==0)
		p->outputArgCount=0;
	else
	{
		p->outputArgCount=1;
		p->outputArgTypeAndSize=(int*)simCreateBuffer(p->outputArgCount*2*sizeof(int));
		p->outputArgTypeAndSize[2*0+0]=sim_lua_arg_string;
		p->outputArgTypeAndSize[2*0+1]=1;
		p->outputChar=(simChar*)simCreateBuffer(effectiveTopicName.length()+1);
		for (unsigned int i=0;i<effectiveTopicName.length();i++)
			p->outputChar[i]=effectiveTopicName[i];
		p->outputChar[effectiveTopicName.length()]=0;
	}
}

void LUA_DISABLE_PUBLISHER_CALLBACK(SLuaCallBack* p)
{
	int result=-1;
	if (p->inputArgCount>=1)
	{
		// Ok, we have at least 1 input argument
		if (p->inputArgTypeAndSize[0*2+0]==sim_lua_arg_string)
		{ // the input argument seem ok
			std::string topicName(p->inputChar);

			int errorModeSaved;
			simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
			simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);

			result=ROS_server::removePublisher(topicName.c_str(),false);

			simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings

			if (result==-1)
				simSetLastError(LUA_DISABLE_PUBLISHER, "Topic could not be unpublished."); // output an error
		}
		else
			simSetLastError(LUA_DISABLE_PUBLISHER, "Wrong argument type/size."); // output an error
	}
	else
		simSetLastError(LUA_DISABLE_PUBLISHER, "Wrong number of arguments."); // output an error

	// Now we prepare the return value:
	p->outputArgCount=1;
	p->outputArgTypeAndSize=(int*)simCreateBuffer(p->outputArgCount*2*sizeof(int));
	p->outputArgTypeAndSize[2*0+0]=sim_lua_arg_int;
	p->outputArgTypeAndSize[2*0+1]=1;
	p->outputInt=(simInt*)simCreateBuffer(sizeof(simInt));
	p->outputInt[0]=result;
}

void LUA_WAKE_PUBLISHER_CALLBACK(SLuaCallBack* p)
{
	int result=-1;
	if (p->inputArgCount>=2)
	{
		// Ok, we have at least 2 input arguments
		if ( (p->inputArgTypeAndSize[0*2+0]==sim_lua_arg_string) &&
			(p->inputArgTypeAndSize[1*2+0]==sim_lua_arg_int) )
		{ // the input argument seem ok
			std::string topicName(p->inputChar);

			int errorModeSaved;
			simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
			simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);

			result=ROS_server::wakePublisher(topicName.c_str(),p->inputInt[0]);

			simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings

			if (result==-2)
				simSetLastError(LUA_WAKE_PUBLISHER, "Topic could not be found."); // output an error
		}
		else
			simSetLastError(LUA_WAKE_PUBLISHER, "Wrong argument type/size."); // output an error
	}
	else
		simSetLastError(LUA_WAKE_PUBLISHER, "Wrong number of arguments."); // output an error

	// Now we prepare the return value:
	p->outputArgCount=1;
	p->outputArgTypeAndSize=(int*)simCreateBuffer(p->outputArgCount*2*sizeof(int));
	p->outputArgTypeAndSize[2*0+0]=sim_lua_arg_int;
	p->outputArgTypeAndSize[2*0+1]=1;
	p->outputInt=(simInt*)simCreateBuffer(sizeof(simInt));
	p->outputInt[0]=result;
}

void LUA_ENABLE_SUBSCRIBER_CALLBACK(SLuaCallBack* p)
{
	int result=-1;
	if (p->inputArgCount>=6)
	{
		// Ok, we have at least 5 input argument
		if (	(p->inputArgTypeAndSize[0*2+0]==sim_lua_arg_string) &&
				(p->inputArgTypeAndSize[1*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[2*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[3*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[4*2+0]==sim_lua_arg_int) &&
				(p->inputArgTypeAndSize[5*2+0]==sim_lua_arg_string) )
		{ // the input arguments seem ok
			std::string topicName(p->inputChar);
			std::string auxString(p->inputChar+strlen(p->inputChar)+1);
			int queueSize=p->inputInt[0];
			int streamCmd=p->inputInt[1];
			int auxInt1=p->inputInt[2];
			int auxInt2=p->inputInt[3];

			int errorModeSaved;
			simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
			simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);

			result=ROS_server::addSubscriber(topicName.c_str(),queueSize,streamCmd,auxInt1,auxInt2,auxString.c_str());

			simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings

			if (result==-1)
				simSetLastError(LUA_ENABLE_SUBSCRIBER, "Topic could not be subscribed."); // output an error
		}
		else
			simSetLastError(LUA_ENABLE_SUBSCRIBER, "Wrong argument type/size."); // output an error
	}
	else
		simSetLastError(LUA_ENABLE_SUBSCRIBER, "Wrong number of arguments."); // output an error

	// Now we prepare the return value:
	p->outputArgCount=1;
	p->outputArgTypeAndSize=(int*)simCreateBuffer(p->outputArgCount*2*sizeof(int));
	p->outputArgTypeAndSize[2*0+0]=sim_lua_arg_int;
	p->outputArgTypeAndSize[2*0+1]=1;
	p->outputInt=(simInt*)simCreateBuffer(sizeof(simInt));
	p->outputInt[0]=result;
}

void LUA_DISABLE_SUBSCRIBER_CALLBACK(SLuaCallBack* p)
{
	bool result=false;
	if (p->inputArgCount>=1)
	{
		// Ok, we have at least 1 input argument
		if (p->inputArgTypeAndSize[0*2+0]==sim_lua_arg_int)
		{ // the input argument seem ok

			int errorModeSaved;
			simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
			simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);

			result=ROS_server::removeSubscriber(p->inputInt[0]);

			simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings

			if (!result)
				simSetLastError(LUA_DISABLE_SUBSCRIBER, "Topic could not be unsubscribed."); // output an error
		}
		else
			simSetLastError(LUA_DISABLE_SUBSCRIBER, "Wrong argument type/size."); // output an error
	}
	else
		simSetLastError(LUA_DISABLE_SUBSCRIBER, "Wrong number of arguments."); // output an error

	// Now we prepare the return value:
	p->outputArgCount=1;
	p->outputArgTypeAndSize=(int*)simCreateBuffer(p->outputArgCount*2*sizeof(int));
	p->outputArgTypeAndSize[2*0+0]=sim_lua_arg_bool;
	p->outputArgTypeAndSize[2*0+1]=1;
	p->outputBool=(simBool*)simCreateBuffer(sizeof(simBool));
	p->outputBool[0]=result;
}

// This is the plugin start routine (called just once, just after the plugin was loaded):
VREP_DLLEXPORT unsigned char v_repStart(void* reservedPointer,int reservedInt)
{
	// Dynamically load and bind V-REP functions:
	// ******************************************
	// 1. Figure out this plugin's directory:
	char curDirAndFile[1024];
	getcwd(curDirAndFile, sizeof(curDirAndFile));

	std::string currentDirAndPath(curDirAndFile);
	// 2. Append the V-REP library's name:
	std::string temp(currentDirAndPath);
	temp+="/libv_rep.so";

	// 3. Load the V-REP library:
	vrepLib=loadVrepLibrary(temp.c_str());
	if (vrepLib==NULL)
	{
		std::cout << "Error, could not find or correctly load the V-REP library. Cannot start 'ROS' plugin.\n";
		return(0); // Means error, V-REP will unload this plugin
	}
	if (getVrepProcAddresses(vrepLib)==0)
	{
		std::cout << "Error, could not find all required functions in the V-REP library. Cannot start 'ROS' plugin.\n";
		unloadVrepLibrary(vrepLib);
		return(0); // Means error, V-REP will unload this plugin
	}
	// ******************************************

	// Check the version of V-REP:
	// ******************************************
	int vrepVer;
	simGetIntegerParameter(sim_intparam_program_version,&vrepVer);
	if (vrepVer<20605) // if V-REP version is smaller than 2.06.04
	{
		std::cout << "Sorry, your V-REP copy is somewhat old. Cannot start 'ROS' plugin.\n";
		unloadVrepLibrary(vrepLib);
		return(0); // Means error, V-REP will unload this plugin
	}
	// ******************************************

	// Initialize the ROS part:
	if(!ROS_server::initialize())
	{
		std::cout << "ROS master is not running. Cannot start 'ROS' plugin.\n";
		return (0); //If the master is not running then the plugin is not loaded.
	}

	int enablePublisherArgs[]={7,sim_lua_arg_string,sim_lua_arg_int,sim_lua_arg_int,sim_lua_arg_int,sim_lua_arg_int,sim_lua_arg_string,sim_lua_arg_int};
	simRegisterCustomLuaFunction(LUA_ENABLE_PUBLISHER,LUA_ENABLE_PUBLISHER_TIPS,enablePublisherArgs,LUA_ENABLE_PUBLISHER_CALLBACK);

	int disablePublisherArgs[]={1,sim_lua_arg_string};
	simRegisterCustomLuaFunction(LUA_DISABLE_PUBLISHER,LUA_DISABLE_PUBLISHER_TIPS,disablePublisherArgs,LUA_DISABLE_PUBLISHER_CALLBACK);

	int wakePublisherArgs[]={2,sim_lua_arg_string,sim_lua_arg_int};
	simRegisterCustomLuaFunction(LUA_WAKE_PUBLISHER,LUA_WAKE_PUBLISHER_TIPS,wakePublisherArgs,LUA_WAKE_PUBLISHER_CALLBACK);

	int enableSubscriberArgs[]={6,sim_lua_arg_string,sim_lua_arg_int,sim_lua_arg_int,sim_lua_arg_int,sim_lua_arg_int,sim_lua_arg_string};
	simRegisterCustomLuaFunction(LUA_ENABLE_SUBSCRIBER,LUA_ENABLE_SUBSCRIBER_TIPS,enableSubscriberArgs,LUA_ENABLE_SUBSCRIBER_CALLBACK);

	int disableSubscriberArgs[]={1,sim_lua_arg_int};
	simRegisterCustomLuaFunction(LUA_DISABLE_SUBSCRIBER,LUA_DISABLE_SUBSCRIBER_TIPS,disableSubscriberArgs,LUA_DISABLE_SUBSCRIBER_CALLBACK);

	// Publisher constants:
	simRegisterCustomLuaVariable("simros_strmcmd_get_laser_scanner_data",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_laser_scanner_data))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_odom_data",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_odom_data))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_object_selection",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_selection))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_array_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_array_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_boolean_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_boolean_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_dialog_result",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_dialog_result))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_floating_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_floating_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_integer_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_integer_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_joint_state",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_joint_state))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_object_pose",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_pose))).c_str());
//	simRegisterCustomLuaVariable("simros_strmcmd_get_object_quaternion",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_quaternion))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_object_parent",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_parent))).c_str());
//	simRegisterCustomLuaVariable("simros_strmcmd_get_object_position",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_position))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_objects",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_objects))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_string_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_string_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_ui_event_button",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_ui_event_button))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_vision_sensor_depth_buffer",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_vision_sensor_depth_buffer))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_vision_sensor_image",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_vision_sensor_image))).c_str());
//	simRegisterCustomLuaVariable("simros_strmcmd_get_joint_force",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_joint_force))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_read_collision",(boost::lexical_cast<std::string>(int(simros_strmcmd_read_collision))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_read_distance",(boost::lexical_cast<std::string>(int(simros_strmcmd_read_distance))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_read_force_sensor",(boost::lexical_cast<std::string>(int(simros_strmcmd_read_force_sensor))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_read_proximity_sensor",(boost::lexical_cast<std::string>(int(simros_strmcmd_read_proximity_sensor))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_read_vision_sensor",(boost::lexical_cast<std::string>(int(simros_strmcmd_read_vision_sensor))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_object_float_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_float_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_object_int_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_int_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_ui_button_property",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_ui_button_property))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_ui_slider",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_ui_slider))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_float_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_float_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_integer_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_integer_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_string_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_string_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_and_clear_string_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_and_clear_string_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_transform",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_transform))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_range_finder_data",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_range_finder_data))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_depth_sensor_data",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_depth_sensor_data))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_vision_sensor_info",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_vision_sensor_info))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_twist_status",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_twist_status))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_get_object_group_data",(boost::lexical_cast<std::string>(int(simros_strmcmd_get_object_group_data))).c_str());

	// Subscriber constants:
	simRegisterCustomLuaVariable("simros_strmcmd_add_status_bar_message",(boost::lexical_cast<std::string>(int(simros_strmcmd_add_status_bar_message))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_object_selection",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_selection))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_auxiliary_console_print",(boost::lexical_cast<std::string>(int(simros_strmcmd_auxiliary_console_print))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_array_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_array_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_boolean_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_boolean_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_floating_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_floating_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_integer_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_integer_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_joint_force",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joint_force))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_joint_position",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joint_position))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_joint_target_position",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joint_target_position))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_joint_target_velocity",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joint_target_velocity))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_vision_sensor_image",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_vision_sensor_image))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_object_float_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_float_parameter))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_object_int_parameter",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_int_parameter))).c_str());
//	simRegisterCustomLuaVariable("simros_strmcmd_set_object_orientation",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_orientation))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_object_position",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_position))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_object_pose",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_pose))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_joint_state",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joint_state))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_object_quaternion",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_object_quaternion))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_ui_button_label",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_ui_button_label))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_ui_button_property",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_ui_button_property))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_ui_slider",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_ui_slider))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_clear_float_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_clear_float_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_clear_integer_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_clear_integer_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_clear_string_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_clear_string_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_float_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_float_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_integer_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_integer_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_string_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_string_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_append_string_signal",(boost::lexical_cast<std::string>(int(simros_strmcmd_append_string_signal))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_twist_command",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_twist_command))).c_str());
	simRegisterCustomLuaVariable("simros_strmcmd_set_joy_sensor",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joy_sensor))).c_str());
//	simRegisterCustomLuaVariable("simros_strmcmd_set_joint_trajectory",(boost::lexical_cast<std::string>(int(simros_strmcmd_set_joint_trajectory))).c_str());

	return(PLUGIN_VERSION); // initialization went fine, we return the version number of this plugin (can be queried with simGetModuleName)
}

// This is the plugin end routine (called just once, when V-REP is ending, i.e. releasing this plugin):
VREP_DLLEXPORT void v_repEnd()
{
	ROS_server::shutDown();	// shutdown the ROS_server
	unloadVrepLibrary(vrepLib); // release the library
}

// This is the plugin messaging routine (i.e. V-REP calls this function very often, with various messages):
VREP_DLLEXPORT void* v_repMessage(int message,int* auxiliaryData,void* customData,int* replyData)
{
	// This is called quite often. Just watch out for messages/events you want to handle
	// Keep following 4 lines at the beginning and unchanged:
	int errorModeSaved;
	simGetIntegerParameter(sim_intparam_error_report_mode,&errorModeSaved);
	simSetIntegerParameter(sim_intparam_error_report_mode,sim_api_errormessage_ignore);
	void* retVal=NULL;

	// Here we can intercept many messages from V-REP (actually callbacks). Only the most important messages are listed here:

	if (message==sim_message_eventcallback_instancepass)
	{
		// This message is sent each time the scene was rendered (well, shortly after) (very often)
		// When a simulation is not running, but you still need to execute some commands, then put some code here
		ROS_server::instancePass();
	}

	if (message==sim_message_eventcallback_mainscriptabouttobecalled)
	{
		// Main script is about to be run (only called while a simulation is running (and not paused!))
		//
		// This is a good location to execute simulation commands

		if (ROS_server::mainScriptAboutToBeCalled())
			replyData[0]=0; // this tells V-REP that we don't wanna execute the main script
	}

	if (message==sim_message_eventcallback_simulationabouttostart)
	{
	    // Simulation is about to start

		ROS_server::simulationAboutToStart();
	}

	if (message==sim_message_eventcallback_simulationended)
	{
		// Simulation just ended

		ROS_server::simulationEnded();
	}

	// Keep following unchanged:
	simSetIntegerParameter(sim_intparam_error_report_mode,errorModeSaved); // restore previous settings
	return(retVal);
}


text:
// auto-generated header by CodeFromTemplate - Connected Vision - https://github.com/ConnectedVision
// CodeFromTemplate Version: 0.3 alpha
// stubs/Store_SQLite_Stub_Skeleton_output_Average.cpp
// NEVER TOUCH this file!

#include <exception>
#include <boost/assign/list_of.hpp>

#include "../Store_SQLite_Skeleton_output_Average.h"

#include "Store_SQLite_Stub_Skeleton_output_Average.h"

// --> Do NOT EDIT <--
namespace ConnectedVision {
namespace test {
namespace DataHandling {

//////////////////////////////////////////////////////////////////////////////
//
// Store_SQLite_Stub_Skeleton_output_Average
//
//////////////////////////////////////////////////////////////////////////////

// --> Do NOT EDIT <--
static const std::string _tableName = "Skeleton_output_Average";

// --> Do NOT EDIT <--
static const std::vector<std::string> _columnDesc = boost::assign::list_of
	("'_sortID' BIGINT NOT NULL DEFAULT '0' /* object sortable id () */")
	("'id' VARCHAR(32) NOT NULL DEFAULT '' /*  (string) */")
	("'configID' VARCHAR(32) NOT NULL DEFAULT '' /*  (string) */")
	("'timestamp' BIGINT NOT NULL DEFAULT '0' /* first detection (integer) */")
	("'color.R' BIGINT /* red (integer) */")
	("'color.G' BIGINT /* green (integer) */")
	("'color.B' BIGINT /* blue (integer) */")
;

// --> Do NOT EDIT <--
Store_SQLite_Stub_Skeleton_output_Average::Store_SQLite_Stub_Skeleton_output_Average(const id_t& configID, DBConnection& db) :
	Store_SQLite_BaseClass<Class_Skeleton_output_Average>(configID, db, _tableName, _columnDesc)
{
}

// --> Do NOT EDIT <--
Store_SQLite_Stub_Skeleton_output_Average::~Store_SQLite_Stub_Skeleton_output_Average()
{
}

#ifdef ENABLE_SQLITE_SEARCH
// --> Do NOT EDIT <--
/**
 *  Get objects filtered by id
 */
std::vector<shared_ptr<const Class_Skeleton_output_Average> > Store_SQLite_Stub_Skeleton_output_Average::getBy_id(const ConnectedVision::id_t& val)
{
	std::vector< Store::FilterEntry > filterList;
	std::vector< Store::SortEntry > sortList;
	filterList.push_back( Store::FilterEntry("id", Store::Op::EQUAL, IDToStr(val) ) );
	return getByFilter(filterList, sortList);
}

// --> Do NOT EDIT <--
/**
 *  Get objects filtered by configID
 */
std::vector<shared_ptr<const Class_Skeleton_output_Average> > Store_SQLite_Stub_Skeleton_output_Average::getBy_configID(const ConnectedVision::id_t& val)
{
	std::vector< Store::FilterEntry > filterList;
	std::vector< Store::SortEntry > sortList;
	filterList.push_back( Store::FilterEntry("configID", Store::Op::EQUAL, IDToStr(val) ) );
	return getByFilter(filterList, sortList);
}

// --> Do NOT EDIT <--
/**
 *  Get objects filtered by timestamp
 */
std::vector<shared_ptr<const Class_Skeleton_output_Average> > Store_SQLite_Stub_Skeleton_output_Average::getBy_timestamp(const ConnectedVision::timestamp_t& val)
{
	std::vector< Store::FilterEntry > filterList;
	std::vector< Store::SortEntry > sortList;
	filterList.push_back( Store::FilterEntry("timestamp", Store::Op::EQUAL, val) );
	return getByFilter(filterList, sortList);
}

#endif

// --> Do NOT EDIT <--
int Store_SQLite_Stub_Skeleton_output_Average::readObject(sqlite3_stmt *stmt, shared_ptr<const Class_Skeleton_output_Average>& outObj, sqlite3 *db)
{
	int error = SQLITE_ROW;

	int64_t objSortID = sqlite3_column_int64(stmt, 0);
	int64_t sortID = objSortID;
	outObj.reset( new Class_Skeleton_output_Average() );
	auto obj = this->create();

	while ( (error == SQLITE_ROW) && (sortID == objSortID) )
	{
		// process row
			// Skeleton_output_Average_id -> ConnectedVision::id_t
  			if ( sqlite3_column_type(stmt, 1) != SQLITE_NULL )
  				obj->set_id( strToID( reinterpret_cast<const char *>(sqlite3_column_text(stmt,1) ) ) );
			// Skeleton_output_Average_configID -> ConnectedVision::id_t
  			if ( sqlite3_column_type(stmt, 2) != SQLITE_NULL )
  				obj->set_configID( strToID( reinterpret_cast<const char *>(sqlite3_column_text(stmt,2) ) ) );
			// Skeleton_output_Average_timestamp -> ConnectedVision::timestamp_t
  			if ( sqlite3_column_type(stmt, 3) != SQLITE_NULL )
  				obj->set_timestamp( sqlite3_column_int64(stmt,3) );
			// Skeleton_output_Average_color -> Class_Skeleton_output_Average_color
  			{
  				boost::shared_ptr<Class_Skeleton_output_Average_color>&& o1 = obj->get_color(); // rvalue reference for const functions
  				if ( !o1 ) o1.reset( new Class_Skeleton_output_Average_color );
				// Skeleton_output_Average_color_R -> int64_t
  				if ( sqlite3_column_type(stmt, 4) != SQLITE_NULL )
  					o1->set_R( sqlite3_column_int64(stmt,4) );
				// Skeleton_output_Average_color_G -> int64_t
  				if ( sqlite3_column_type(stmt, 5) != SQLITE_NULL )
  					o1->set_G( sqlite3_column_int64(stmt,5) );
				// Skeleton_output_Average_color_B -> int64_t
  				if ( sqlite3_column_type(stmt, 6) != SQLITE_NULL )
  					o1->set_B( sqlite3_column_int64(stmt,6) );
  			}

		error = sqlite3_step(stmt);
		if ( error == SQLITE_ROW )
			sortID = sqlite3_column_int64(stmt, 0);
	}

	outObj = this->make_const(obj);
	return error;
}

// --> Do NOT EDIT <--
int Store_SQLite_Stub_Skeleton_output_Average::writeObject(sqlite3_stmt *stmt, const shared_ptr<const Class_Skeleton_output_Average>& obj, sqlite3 *db, const int64_t sortID)
{
	int error = 0;

		sqlite3_reset(stmt);
		sqlite3_clear_bindings(stmt);

		bind_Skeleton_output_Average( stmt, obj, sortID );

		bind_color( stmt, obj->getconst_color(), sortID );
		// write object base data and sub objects
		error = sqlite3_step(stmt);
		if ( error != SQLITE_DONE )
			return error;
	return error;
}

// --> Do NOT EDIT <--
void Store_SQLite_Stub_Skeleton_output_Average::bind_Skeleton_output_Average(sqlite3_stmt *stmt, const boost::shared_ptr<const Class_Skeleton_output_Average>& obj, const int64_t sortID) const
{
	sqlite3_bind_int64(stmt, 1, sortID );
	sqlite3_bind_text(stmt, 2, IDToChar(obj->getconst_id()), -1, SQLITE_TRANSIENT);
	sqlite3_bind_text(stmt, 3, IDToChar(obj->getconst_configID()), -1, SQLITE_TRANSIENT);
	sqlite3_bind_int64(stmt, 4, obj->getconst_timestamp() );
	// object: color handled separately
}

// --> Do NOT EDIT <--
void Store_SQLite_Stub_Skeleton_output_Average::bind_color(sqlite3_stmt *stmt, const boost::shared_ptr<const Class_Skeleton_output_Average_color>& obj, const int64_t sortID) const
{
	sqlite3_bind_int64(stmt, 1, sortID );
  	sqlite3_bind_int64(stmt, 5, obj->getconst_R() );
  	sqlite3_bind_int64(stmt, 6, obj->getconst_G() );
  	sqlite3_bind_int64(stmt, 7, obj->getconst_B() );
}

// --> Do NOT EDIT <--
void Store_SQLite_Stub_Skeleton_output_Average::appendObjectGrouping(std::vector< Store::SortEntry >& sortList) const
{
	sortList.push_back( Store::SortEntry ("_sortID", Store::Order::ASC) );
}

// --> Do NOT EDIT <--
/**
 *  append object internal sort criteria to list
 */
const std::string Store_SQLite_Stub_Skeleton_output_Average::objectKey() const
{
	return std::string("_sortID");
}

//////////////////////////////////////////////////////////////////////////////
//
// Store_SQLite_Factory_Stub_Skeleton_output_Average
//
//////////////////////////////////////////////////////////////////////////////

// --> Do NOT EDIT <--
Store_SQLite_Factory_Stub_Skeleton_output_Average::Store_SQLite_Factory_Stub_Skeleton_output_Average(DBConnection& db) :
	db(db)
{}

// --> Do NOT EDIT <--
Store_SQLite_Factory_Stub_Skeleton_output_Average::~Store_SQLite_Factory_Stub_Skeleton_output_Average()
{}

shared_ptr< ConnectedVision::DataHandling::IStore_ReadWrite<Class_Skeleton_output_Average> > Store_SQLite_Factory_Stub_Skeleton_output_Average::create(const id_t configID = ID_NULL)
{
#ifdef Store_SQLite_Factory_Skeleton_output_Average_enabled
	return boost::dynamic_pointer_cast< ConnectedVision::DataHandling::IStore_ReadWrite<Class_Skeleton_output_Average> > (make_shared< DataHandling::Store_SQLite_Skeleton_output_Average >(configID, this->db));
#else
	return shared_ptr< ConnectedVision::DataHandling::IStore_ReadWrite<Class_Skeleton_output_Average> >();
#endif
}

} // namespace DataHandling
} // namespace test
} // namespace ConnectedVision

ext: cpp

max_stars_repo_name: ConnectedVision/ConnectedVision

max_issues_repo_name: ConnectedVision/ConnectedVision

max_forks_repo_name: ConnectedVision/ConnectedVision


text:
#include "lm/builder/output.hh"
#include "util/stream/multi_stream.hh"

#include <boost/ref.hpp>

namespace lm { namespace builder {

OutputHook::~OutputHook() {}

void OutputHook::Apply(util::stream::Chains &chains) {
  chains >> boost::ref(*this);
}

}} // namespaces

ext: cc

max_stars_repo_name: janlelis/wisdom-query

max_issues_repo_name: janlelis/wisdom-query

max_forks_repo_name: janlelis/wisdom-query


text:
/*
 * The MIT License (MIT)
 *
 * Copyright (c) <2015> <Stephan Gatzka>
 *
 * 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.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE state

#include <boost/test/unit_test.hpp>
#include <list>

#include "compiler.h"
#include "element.h"
#include "json/cJSON.h"
#include "parse.h"
#include "peer.h"
#include "router.h"
#include "table.h"

static char send_buffer[100000];

static std::list<struct io_event *> timer_evs;

extern "C" {
	cjet_ssize_t socket_read(socket_type sock, void *buf, size_t count)
	{
		(void)sock;
		(void)count;
		uint64_t number_of_timeouts = 1;
		::memcpy(buf, &number_of_timeouts, sizeof(number_of_timeouts));
		return 8;
	}

	int socket_close(socket_type sock)
	{
		(void)sock;
		return 0;
	}
}

int send_message(const struct peer *p, char *rendered, size_t len)
{
	(void)p;
	memcpy(send_buffer, rendered, len);
	return 0;
}

static struct element *get_state(const char *path)
{
	return (struct element *)element_table_get(path);
}

static cJSON *parse_send_buffer(void)
{
	char *read_ptr = send_buffer;
	const char *end_parse;
	cJSON *root = cJSON_ParseWithOpts(read_ptr, &end_parse, 0);
	return root;
}

static cJSON *create_response_from_message(const cJSON *routed_message)
{
	const cJSON *id = cJSON_GetObjectItem(routed_message, "id");
	cJSON *duplicated_id = cJSON_Duplicate(id, 1);

	cJSON *response = cJSON_CreateObject();
	cJSON_AddItemToObject(response, "id", duplicated_id);
	cJSON *result = cJSON_CreateString("");
	cJSON_AddItemToObject(response, "result", result);
	return response;
}

static cJSON *create_set_request(const char *request_id, const char *path)
{
	cJSON *set_request = cJSON_CreateObject();
	cJSON_AddStringToObject(set_request, "method", "set");
	if (request_id != NULL) {
		cJSON_AddStringToObject(set_request, "id", request_id);
	}

	cJSON *params = cJSON_CreateObject();
	cJSON_AddStringToObject(params, "path", path);
	cJSON *new_value = cJSON_CreateNumber(4321);
	cJSON_AddItemToObject(params, "value", new_value);
	cJSON_AddItemToObject(set_request, "params", params);
	return set_request;
}

static cJSON *create_set_request_with_timeout(const char *request_id, const char *path, double timeout_s)
{
	cJSON *set_request = create_set_request(request_id, path);
	cJSON *params = cJSON_GetObjectItem(set_request, "params");
	cJSON_AddNumberToObject(params, "timeout", timeout_s);
	return set_request;
}

static cJSON *get_result_from_response(const cJSON *response)
{
	cJSON *result = cJSON_GetObjectItem(response, "result");
	if (result != NULL) {
		return result;
	}
	const cJSON *error = cJSON_GetObjectItem(response, "error");
	if (error != NULL) {
		return result;
	}
	return NULL;
}

static enum eventloop_return fake_add(const void *this_ptr, const struct io_event *ev)
{
	(void)this_ptr;
	timer_evs.push_back((struct io_event *)ev);
	return EL_CONTINUE_LOOP;
}

static void fake_remove(void *this_ptr, const struct io_event *ev)
{
	(void)this_ptr;
	(void)ev;
	timer_evs.remove((struct io_event *)ev);
	return;
}

static struct eventloop loop;

struct F {
	F()
	{
		timer_evs.clear();
		loop.this_ptr = NULL;
		loop.init = NULL;
		loop.destroy = NULL;
		loop.run = NULL;
		loop.add = fake_add;
		loop.remove = fake_remove;

		init_parser();
		element_hashtable_create();
		init_peer(&p, false, &loop);
		p.send_message = send_message;
		init_peer(&owner_peer, false, &loop);
		owner_peer.send_message = send_message;
		init_peer(&set_peer, false, &loop);
		set_peer.send_message = send_message;
	}

	~F()
	{
		free_peer_resources(&set_peer);
		free_peer_resources(&owner_peer);
		free_peer_resources(&p);
		element_hashtable_delete();
	}

	struct peer p;
	struct peer owner_peer;
	struct peer set_peer;
};

static void check_response(cJSON *json, const char *id)
{
	cJSON *response_id = cJSON_GetObjectItem(json, "id");
	BOOST_CHECK((response_id != NULL) &&
				 (response_id->type == cJSON_String) &&
				 (strcmp(response_id->valuestring, id) == 0));
	cJSON *result = cJSON_GetObjectItem(json, "result");
	BOOST_CHECK(result != NULL);
}

static void check_internal_error(const cJSON *response)
{
	const cJSON *error = cJSON_GetObjectItem(response, "error");

	cJSON *code = cJSON_GetObjectItem(error, "code");
	if (code != NULL) {
		BOOST_CHECK(code->type == cJSON_Number);
		BOOST_CHECK(code->valueint == -32603);
	} else {
		BOOST_FAIL("No code object!");
	}

	cJSON *message = cJSON_GetObjectItem(error, "message");
	if (message != NULL) {
		BOOST_CHECK(message->type == cJSON_String);
		BOOST_CHECK(strcmp(message->valuestring, "Internal error") == 0);
	} else {
		BOOST_FAIL("No message object!");
	}
}

static void check_invalid_params(const cJSON *response)
{
	const cJSON *error = cJSON_GetObjectItem(response, "error");

	const cJSON *code = cJSON_GetObjectItem(error, "code");
	if (code != NULL) {
		BOOST_CHECK(code->type == cJSON_Number);
		BOOST_CHECK(code->valueint == -32602);
	} else {
		BOOST_FAIL("No code object!");
	}

	const cJSON *message = cJSON_GetObjectItem(error, "message");
	if (message != NULL) {
		BOOST_CHECK(message->type == cJSON_String);
		BOOST_CHECK(strcmp(message->valuestring, "Invalid params") == 0);
	} else {
		BOOST_FAIL("No message object!");
	}
}

static cJSON *create_add(const char *path)
{
	cJSON *params = cJSON_CreateObject();
	BOOST_REQUIRE(params != NULL);
	cJSON_AddStringToObject(params, "path", path);
	cJSON_AddItemToObject(params, "value", cJSON_CreateNumber(1234));

	cJSON *root = cJSON_CreateObject();
	cJSON_AddItemToObject(root, "params", params);
	cJSON_AddStringToObject(root, "id", "add_request_1");
	cJSON_AddStringToObject(root, "method", "add");
	return root;
}

static cJSON *create_add_method(const char *path)
{
	cJSON *params = cJSON_CreateObject();
	BOOST_REQUIRE(params != NULL);
	cJSON_AddStringToObject(params, "path", path);

	cJSON *root = cJSON_CreateObject();
	cJSON_AddItemToObject(root, "params", params);
	cJSON_AddStringToObject(root, "id", "add_request_1");
	cJSON_AddStringToObject(root, "method", "add");
	return root;
}

static cJSON *create_change(const char *path)
{
	cJSON *params = cJSON_CreateObject();
	BOOST_REQUIRE(params != NULL);
	cJSON_AddStringToObject(params, "path", path);
	cJSON_AddItemToObject(params, "value", cJSON_CreateNumber(4321));

	cJSON *root = cJSON_CreateObject();
	cJSON_AddItemToObject(root, "params", params);
	cJSON_AddStringToObject(root, "id", "change_request_1");
	cJSON_AddStringToObject(root, "method", "change");
	return root;
}

static bool response_is_error(const cJSON *response)
{
	const cJSON *error = cJSON_GetObjectItem(response, "error");
	return (error != NULL);
}

BOOST_FIXTURE_TEST_CASE(add_state_existing_method, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&owner_peer, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);

	response = add_element_to_peer(&owner_peer, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	check_invalid_params(response);
	cJSON_Delete(response);
	cJSON_Delete(request);
}

BOOST_FIXTURE_TEST_CASE(add_state, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);
	cJSON *params = cJSON_GetObjectItem(request, "params");
	cJSON *json_path = cJSON_GetObjectItem(params, "path");
	cJSON *value = cJSON_GetObjectItem(params, "value");

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);

	struct element *e = get_state(json_path->valuestring);
	BOOST_CHECK(e->value->valueint == value->valueint);
	cJSON_Delete(request);
}

BOOST_FIXTURE_TEST_CASE(add_duplicate_state, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);

	response = add_element_to_peer(&p, request);
	BOOST_REQUIRE(response != NULL);
	check_invalid_params(response);
	cJSON_Delete(response);
	cJSON_Delete(request);
}

BOOST_FIXTURE_TEST_CASE(delete_single_state, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);

	response = remove_element_from_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "remove_element_from_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "remove_element_from_peer() failed!");
	cJSON_Delete(request);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(delete_nonexisting_state, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = remove_element_from_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "remove_element_from_peer() had no response!");
	BOOST_CHECK_MESSAGE(response_is_error(response), "removing non-existant state did not fail!");
	cJSON_Delete(request);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(double_free_state, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);

	response = remove_element_from_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "remove_element_from_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "removing state failed!");
	cJSON_Delete(response);

	response = remove_element_from_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "remove_element_from_peer() had no response!");
	BOOST_CHECK_MESSAGE(response_is_error(response), "double free of state did not fail!");
	cJSON_Delete(request);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(change, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	request = create_change(path);
	cJSON *params = cJSON_GetObjectItem(request, "params");
	cJSON *json_path = cJSON_GetObjectItem(params, "path");
	cJSON *new_value = cJSON_GetObjectItem(params, "value");

	response = change_state(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "change_state() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "change_state() failed!");

	struct element *e = get_state(json_path->valuestring);
	BOOST_CHECK(e->value->valueint == new_value->valueint);
	cJSON_Delete(request);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(change_no_params, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	request = cJSON_CreateObject();
	cJSON_AddStringToObject(request, "id", "change_request_1");
	cJSON_AddStringToObject(request, "method", "change");

	response = change_state(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "change_state() had no response!");
	BOOST_CHECK_MESSAGE(response_is_error(response), "change_state() with no params did not fail!");

	cJSON_Delete(request);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(change_not_by_owner, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	request = create_change(path);

	response = change_state(&set_peer, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "change_state() had no response!");
	BOOST_CHECK_MESSAGE(response_is_error(response), "non-owner change did not fail!");
	cJSON_Delete(response);
	cJSON_Delete(request);
}

BOOST_FIXTURE_TEST_CASE(change_wrong_path, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	request = create_change("/bar/foo/");

	response = change_state(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "change_state() had no response!");
	BOOST_CHECK_MESSAGE(response_is_error(response), "wrong path change did not fail!");
	check_invalid_params(response);
	cJSON_Delete(response);
	cJSON_Delete(request);
}

BOOST_FIXTURE_TEST_CASE(change_on_method, F)
{
	const char path[] = "/foo/bar/";

	cJSON *request = create_add_method(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	request = create_change(path);

	response = change_state(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "change_state() had no response!");
	check_invalid_params(response);
	cJSON_Delete(response);
	cJSON_Delete(request);
}

BOOST_FIXTURE_TEST_CASE(set_on_method, F)
{
	const char path[] = "/foo/bar";
	cJSON *request = create_add_method(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request("request1", path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "change_state() had no response!");
	check_invalid_params(response);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_on_fetchonly, F)
{
	const char path[] = "/foo/bar";
	cJSON *request = create_add(path);
	cJSON *params = cJSON_GetObjectItem(request, "params");
	cJSON_AddItemToObject(params, "fetchOnly", cJSON_CreateTrue());

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request("request1", path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "set_or_call() had no response!");
	check_invalid_params(response);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request("request1", path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");
	BOOST_CHECK_MESSAGE(timer_evs.size() == 1, "No timer_ev was registered!");

	cJSON *routed_message = parse_send_buffer();
	response = create_response_from_message(routed_message);
	cJSON *result = get_result_from_response(response);

	int ret = handle_routing_response(response, result, "result", &p);
	BOOST_CHECK(ret == 0);
	BOOST_CHECK_MESSAGE(timer_evs.size() == 0, "timer_ev was not deregistered!");

	cJSON_Delete(routed_message);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_with_correct_timeout, F)
{
	double timeout_s = 2.22;
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request_with_timeout("request1", path, timeout_s);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");
	BOOST_CHECK_MESSAGE(timer_evs.size() == 1, "No timer_ev was registered!");

	cJSON *routed_message = parse_send_buffer();
	response = create_response_from_message(routed_message);
	cJSON *result = get_result_from_response(response);

	int ret = handle_routing_response(response, result, "result", &p);
	BOOST_CHECK(ret == 0);
	BOOST_CHECK_MESSAGE(timer_evs.size() == 0, "timer_ev was not deregistered!");

	cJSON_Delete(routed_message);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_with_negative_timeout, F)
{
	double timeout_s = -2.22;
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request_with_timeout("request1", path, timeout_s);
	response = set_or_call(&set_peer, set_request, STATE);
	BOOST_REQUIRE_MESSAGE(response != NULL, "set_or_call() had no response!");
	check_invalid_params(response);
	cJSON_Delete(set_request);
	cJSON_Delete(response);
	BOOST_CHECK_MESSAGE(response != NULL, "no error object created for set request with negative timeout");
	BOOST_CHECK_MESSAGE(timer_evs.size() == 0, "timer_ev was registered for set request with negative timeout!");

}

BOOST_FIXTURE_TEST_CASE(set_with_illegal_timeout_object, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request("request1", path);
	cJSON *params = cJSON_GetObjectItem(set_request, "params");
	cJSON_AddStringToObject(params, "timeout", "hello");
	response = set_or_call(&set_peer, set_request, STATE);
	BOOST_REQUIRE_MESSAGE(response != NULL, "set_or_call() had no response!");
	check_invalid_params(response);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE((response != NULL) && (response_is_error(response)), "no error object created for set request with negative timeout");
	BOOST_CHECK_MESSAGE(timer_evs.size() == 0, "timer_ev was registered for set request with illegal timeout object!");
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_wrong_path, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	const char set_path[] = "/bar/foo/";
	cJSON *set_request = create_set_request("request1", set_path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE((response != NULL) && (response_is_error(response)), "no error object created for set request with negative timeout");
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_without_id_without_response, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(request);
	cJSON_Delete(response);

	cJSON *set_request = create_set_request(NULL, path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_wrong_id_type, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(request);
	cJSON_Delete(response);

	cJSON *set_request = cJSON_CreateObject();
	cJSON_AddStringToObject(set_request, "method", "set");
	cJSON_AddTrueToObject(set_request, "id");

	cJSON *params = cJSON_CreateObject();
	cJSON_AddStringToObject(params, "path", path);
	cJSON *new_value = cJSON_CreateNumber(4321);
	cJSON_AddItemToObject(params, "value", new_value);
	cJSON_AddItemToObject(set_request, "params", params);

	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);

	BOOST_CHECK_MESSAGE(response == NULL, "Got response despite wrong request id type!");
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_without_id_with_response, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request(NULL, path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message = parse_send_buffer();
	response = create_response_from_message(routed_message);
	cJSON *result = get_result_from_response(response);

	int ret = handle_routing_response(response, result, "result", &p);
	BOOST_CHECK(ret == 0);

	cJSON_Delete(routed_message);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_with_timeout_before_response, F)
{
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request("request1", path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message = parse_send_buffer();
	response = create_response_from_message(routed_message);
	cJSON *result = get_result_from_response(response);

	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 1, "No timer ev was registered!");
	struct io_event *timer_ev = timer_evs.front();
	enum eventloop_return el_ret = timer_ev->read_function(timer_ev);
	BOOST_CHECK_MESSAGE(el_ret == EL_CONTINUE_LOOP, "timer read function did not returned EL_CONTINUE_LOOP");
	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 0, "timer was not remove from eventloop!");
	cJSON *error_message = parse_send_buffer();
	BOOST_REQUIRE_MESSAGE(error_message != NULL, "Error message does not contain an error object!");
	check_internal_error(error_message);
	cJSON_Delete(error_message);

	int ret = handle_routing_response(response, result, "result", &p);
	BOOST_CHECK_MESSAGE(ret == 0, "Response after timeout not silently ignored!");

	cJSON_Delete(routed_message);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(set_with_timeout_after_response, F)
{
	const char path[] = "/foo/bar/";
	const char request_id[] = "request1";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request(request_id, path);
	response = set_or_call(&set_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message = parse_send_buffer();
	response = create_response_from_message(routed_message);
	cJSON *result = get_result_from_response(response);
	cJSON_Delete(routed_message);

	int ret = handle_routing_response(response, result, "result", &p);
	BOOST_CHECK_MESSAGE(ret == 0, "Response after timeout not silently ignored!");
	cJSON_Delete(response);

	cJSON *error_message = parse_send_buffer();
	BOOST_REQUIRE_MESSAGE(error_message != NULL, "Error message does not contain an error object!");
	check_response(error_message, request_id);
	cJSON_Delete(error_message);

	//BOOST_REQUIRE_MESSAGE(timer_evs.size() == 1, "No timer ev was registered!");
	//struct io_event *timer_ev = timer_evs.front();
	//enum eventloop_return el_ret = timer_ev->read_function(timer_ev);
	//BOOST_CHECK_MESSAGE(el_ret == EL_CONTINUE_LOOP, "timer read function did not returned EL_CONTINUE_LOOP");
	//BOOST_REQUIRE_MESSAGE(timer_evs.size() == 0, "timer was not remove from eventloop!");
	//cJSON *error_message = parse_send_buffer();
	//BOOST_REQUIRE_MESSAGE(error_message != NULL, "Error message does not contain an error object!");
	//check_internal_error(error_message);
	//cJSON_Delete(error_message);

}

BOOST_FIXTURE_TEST_CASE(set_with_destroy_before_response, F)
{
	struct peer setter_peer;
	init_peer(&setter_peer, false, &loop);
	setter_peer.send_message = send_message;

	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request = create_set_request("request1", path);
	response = set_or_call(&setter_peer, set_request, STATE);
	cJSON_Delete(set_request);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message = parse_send_buffer();
	response = create_response_from_message(routed_message);
	cJSON *result = get_result_from_response(response);

	free_peer_resources(&setter_peer);

	int ret = handle_routing_response(response, result, "result", &p);
	BOOST_CHECK_MESSAGE(ret == 0, "Response after timeout/destroy not silently ignored!");

	cJSON_Delete(routed_message);
	cJSON_Delete(response);
}

BOOST_FIXTURE_TEST_CASE(second_set_before_first_response, F)
{
	double timeout_s = 2.22;
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request1 = create_set_request_with_timeout("request1", path, timeout_s);
	response = set_or_call(&set_peer, set_request1, STATE);
	cJSON_Delete(set_request1);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message1 = parse_send_buffer();
	cJSON *response1 = create_response_from_message(routed_message1);
	cJSON *result1 = get_result_from_response(response1);

	cJSON *set_request2 = create_set_request_with_timeout("request2", path, timeout_s);
	response = set_or_call(&set_peer, set_request2, STATE);
	cJSON_Delete(set_request2);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message2 = parse_send_buffer();
	cJSON *response2 = create_response_from_message(routed_message1);
	cJSON *result2 = get_result_from_response(response1);

	int ret = handle_routing_response(response1, result1, "result", &p);
	BOOST_CHECK(ret == 0);
	cJSON_Delete(routed_message1);
	cJSON_Delete(response1);

	ret = handle_routing_response(response2, result2, "result", &p);
	BOOST_CHECK(ret == 0);
	cJSON_Delete(routed_message2);
	cJSON_Delete(response2);
}

BOOST_FIXTURE_TEST_CASE(two_sets_with_first_timeout, F)
{
	double timeout_s = 2.22;
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request1 = create_set_request_with_timeout("request1", path, timeout_s);
	response = set_or_call(&set_peer, set_request1, STATE);
	cJSON_Delete(set_request1);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message1 = parse_send_buffer();
	cJSON *response1 = create_response_from_message(routed_message1);
	cJSON *result1 = get_result_from_response(response1);

	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 1, "No timer ev was registered!");
	struct io_event *timer_ev = timer_evs.front();
	enum eventloop_return el_ret = timer_ev->read_function(timer_ev);
	BOOST_CHECK_MESSAGE(el_ret == EL_CONTINUE_LOOP, "timer read function did not returned EL_CONTINUE_LOOP");
	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 0, "timer was not remove from eventloop!");

	cJSON *error_message = parse_send_buffer();
	BOOST_REQUIRE_MESSAGE(error_message != NULL, "Error message does not contain an error object!");
	check_internal_error(error_message);
	cJSON_Delete(error_message);

	cJSON *set_request2 = create_set_request_with_timeout("request2", path, timeout_s);
	response = set_or_call(&set_peer, set_request2, STATE);
	cJSON_Delete(set_request2);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message2 = parse_send_buffer();
	cJSON *response2 = create_response_from_message(routed_message1);
	cJSON *result2 = get_result_from_response(response1);

	int ret = handle_routing_response(response1, result1, "result", &p);
	BOOST_CHECK_MESSAGE(ret == 0, "Response after timeout not silently ignored!");
	cJSON_Delete(routed_message1);
	cJSON_Delete(response1);

	ret = handle_routing_response(response2, result2, "result", &p);
	BOOST_CHECK(ret == 0);
	cJSON_Delete(routed_message2);
	cJSON_Delete(response2);
}

BOOST_FIXTURE_TEST_CASE(two_sets_all_timeout, F)
{
	double timeout_s = 2.22;
	const char path[] = "/foo/bar/";
	cJSON *request = create_add(path);

	cJSON *response = add_element_to_peer(&p, request);
	BOOST_REQUIRE_MESSAGE(response != NULL, "add_element_to_peer() had no response!");
	BOOST_CHECK_MESSAGE(!response_is_error(response), "add_element_to_peer() failed!");
	cJSON_Delete(response);
	cJSON_Delete(request);

	cJSON *set_request1 = create_set_request_with_timeout("request1", path, timeout_s);
	response = set_or_call(&set_peer, set_request1, STATE);
	cJSON_Delete(set_request1);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message1 = parse_send_buffer();
	cJSON *response1 = create_response_from_message(routed_message1);
	cJSON *result1 = get_result_from_response(response1);

	cJSON *set_request2 = create_set_request_with_timeout("request2", path, timeout_s);
	response = set_or_call(&set_peer, set_request2, STATE);
	cJSON_Delete(set_request2);
	BOOST_CHECK_MESSAGE(response == NULL, "There must be no response when calling set/call");

	cJSON *routed_message2 = parse_send_buffer();
	cJSON *response2 = create_response_from_message(routed_message1);
	cJSON *result2 = get_result_from_response(response1);

	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 2, "No timer ev was registered!");
	struct io_event *timer_ev = timer_evs.front();
	enum eventloop_return el_ret = timer_ev->read_function(timer_ev);
	BOOST_CHECK_MESSAGE(el_ret == EL_CONTINUE_LOOP, "timer read function did not returned EL_CONTINUE_LOOP");
	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 1, "timer was not remove from eventloop!");

	cJSON *error_message = parse_send_buffer();
	BOOST_REQUIRE_MESSAGE(error_message != NULL, "Error message does not contain an error object!");
	check_internal_error(error_message);
	cJSON_Delete(error_message);

	timer_ev = timer_evs.front();
	el_ret = timer_ev->read_function(timer_ev);
	BOOST_CHECK_MESSAGE(el_ret == EL_CONTINUE_LOOP, "timer read function did not returned EL_CONTINUE_LOOP");
	BOOST_REQUIRE_MESSAGE(timer_evs.size() == 0, "timer was not remove from eventloop!");

	error_message = parse_send_buffer();
	BOOST_REQUIRE_MESSAGE(error_message != NULL, "Error message does not contain an error object!");
	check_internal_error(error_message);
	cJSON_Delete(error_message);

	int ret = handle_routing_response(response1, result1, "result", &p);
	BOOST_CHECK_MESSAGE(ret == 0, "Response after timeout not silently ignored!");
	cJSON_Delete(routed_message1);
	cJSON_Delete(response1);

	ret = handle_routing_response(response2, result2, "result", &p);
	BOOST_CHECK(ret == 0);
	cJSON_Delete(routed_message2);
	cJSON_Delete(response2);
}

max_stars_repo_name: mloy/cjet

max_issues_repo_name: mloy/cjet

max_forks_repo_name: mloy/cjet


text:
#ifndef ALLOCGC_GC_LO_ALLOCATOR_HPP
#define ALLOCGC_GC_LO_ALLOCATOR_HPP

#include <mutex>

#include <boost/range/iterator_range.hpp>

#include <liballocgc/gc_alloc.hpp>
#include <liballocgc/details/gc_interface.hpp>
#include <liballocgc/details/gc_cell.hpp>

#include <liballocgc/details/allocators/gc_box.hpp>
#include <liballocgc/details/allocators/allocator_tag.hpp>
#include <liballocgc/details/allocators/sys_allocator.hpp>
#include <liballocgc/details/allocators/list_allocator.hpp>
#include <liballocgc/details/allocators/gc_core_allocator.hpp>
#include <liballocgc/details/allocators/redirection_allocator.hpp>
#include <liballocgc/details/allocators/gc_object_descriptor.hpp>

#include <liballocgc/details/utils/locked_range.hpp>
#include <liballocgc/details/utils/dummy_mutex.hpp>
#include <liballocgc/details/utils/utility.hpp>

#include <liballocgc/details/compacting/forwarding.hpp>

namespace allocgc { namespace details { namespace allocators {

class gc_lo_allocator : private utils::noncopyable, private utils::nonmovable
{
    typedef list_allocator<
            redirection_allocator<gc_core_allocator>,
            utils::dummy_mutex
        > list_alloc_t;

    typedef gc_object_descriptor descriptor_t;
    typedef std::mutex mutex_t;

    class descriptor_iterator : public boost::iterator_adaptor<
              descriptor_iterator
            , typename list_alloc_t::iterator
            , descriptor_t
            , boost::bidirectional_traversal_tag
        >
    {
    public:
        descriptor_iterator(const descriptor_iterator &) noexcept = default;
        descriptor_iterator& operator=(const descriptor_iterator&) noexcept = default;
    private:
        friend class gc_lo_allocator;
        friend class boost::iterator_core_access;

        descriptor_iterator(const typename list_alloc_t::iterator& it)
            : descriptor_iterator::iterator_adaptor_(it)
        {}

        descriptor_t& dereference() const
        {
            return *get_descr(*this->base());
        }
    };

    class memory_iterator : public boost::iterator_adaptor<
              memory_iterator
            , typename list_alloc_t::iterator
            , gc_cell
            , boost::bidirectional_traversal_tag
            , gc_cell
        >
    {
    public:
        memory_iterator(const memory_iterator&) noexcept = default;
        memory_iterator& operator=(const memory_iterator&) noexcept = default;
    private:
        friend class gc_lo_allocator;
        friend class boost::iterator_core_access;

        memory_iterator(const typename list_alloc_t::iterator& it)
            : memory_iterator::iterator_adaptor_(it)
            , m_cell(gc_cell::from_cell_start(get_memblk(*it), get_descr(*it)))
        {}

        gc_cell dereference() const
        {
            return m_cell;
        }

        void increment() noexcept
        {
            ++this->base_reference();
            update_cell(this->base());
        }

        void decrement() noexcept
        {
            --this->base_reference();
            update_cell(this->base());
        }

        void update_cell(const typename list_alloc_t::iterator& it) noexcept
        {
            m_cell = gc_cell::from_cell_start(get_memblk(*it), get_descr(*it));
        }

        gc_cell m_cell;
    };

    typedef boost::iterator_range<memory_iterator> memory_range_type;
public:
    typedef stateful_alloc_tag alloc_tag;

    explicit gc_lo_allocator(gc_core_allocator* core_alloc);
    ~gc_lo_allocator();

    gc_alloc::response allocate(const gc_alloc::request& rqst);

    gc_collect_stat collect(compacting::forwarding& frwd);
    void fix(const compacting::forwarding& frwd);
    void finalize();

    gc_memstat stats();
private:
    static constexpr size_t get_blk_size(size_t alloc_size)
    {
        return align_size(sizeof(descriptor_t) + gc_box::box_size(alloc_size));
    }

    static constexpr size_t get_cell_size(size_t alloc_size)
    {
        return align_size(sizeof(descriptor_t) + gc_box::box_size(alloc_size)) - sizeof(descriptor_t);
    }

    static constexpr size_t align_size(size_t size)
    {
        return list_alloc_t::align_size(size, PAGE_SIZE);
    }

    static constexpr byte* align_by_page(byte* ptr)
    {
        return reinterpret_cast<byte*>(reinterpret_cast<std::uintptr_t>(ptr) & ((~0ull) << PAGE_SIZE_LOG2));
    }

    static constexpr descriptor_t* get_descr(byte* blk)
    {
        return reinterpret_cast<descriptor_t*>(blk);
    }

    static constexpr byte* get_blk_by_descr(descriptor_t* descr)
    {
        return reinterpret_cast<byte*>(descr);
    }

    static constexpr byte* get_memblk(byte* blk)
    {
        return blk + sizeof(descriptor_t);
    }

    void destroy(const descriptor_iterator& it);

    descriptor_iterator descriptors_begin();
    descriptor_iterator descriptors_end();

    memory_iterator memory_begin();
    memory_iterator memory_end();

    byte* allocate_blk(size_t size);
    void  deallocate_blk(byte* ptr, size_t size);

    list_alloc_t m_alloc;
    mutex_t      m_mutex;
};

}}}

#endif //ALLOCGC_GC_LO_ALLOCATOR_HPP

ext: hpp

max_stars_repo_name: eucpp/allocgc

max_issues_repo_name: eucpp/allocgc

max_forks_repo_name: eucpp/allocgc


text:
// Copyright 2008 The Trustees of Indiana University.

// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//  Boost.MultiArray Library
//  Authors: Ronald Garcia
//           Jeremy Siek
//           Andrew Lumsdaine
//  See http://www.boost.org/libs/multi_array for documentation.

//
// resize_from_other.cpp - an experiment in writing a resize function for
// multi_arrays that will use the extents from another to build itself.
//

#include <boost/multi_array.hpp>
#include <boost/static_assert.hpp>
#include <boost/array.hpp>
#include <algorithm>

template <typename T, typename U, std::size_t N>
void
resize_from_MultiArray(boost::multi_array<T,N>& marray, U& other) {

  // U must be a model of MultiArray
  boost::function_requires<
  boost::detail::multi_array::ConstMultiArrayConcept<U,U::dimensionality> >();
  // U better have U::dimensionality == N
  BOOST_STATIC_ASSERT(U::dimensionality == N);

  boost::array<typename boost::multi_array<T,N>::size_type, N> shape;

  std::copy(other.shape(), other.shape()+N, shape.begin());

  marray.resize(shape);

}

#include <iostream>

int main () {

  boost::multi_array<int,2> A(boost::extents[5][4]), B;
  boost::multi_array<int,3> C;

  resize_from_MultiArray(B,A);

#if 0
  resize_from_MultiArray(C,A); // Compile-time error
#endif

  std::cout << B.shape()[0] << ", " << B.shape()[1] << '\n';

}

max_stars_repo_name: jonstewart/boost-svn

max_issues_repo_name: jonstewart/boost-svn

max_forks_repo_name: jonstewart/boost-svn


text:
/* Copyright (C) 2010-2019, The Regents of The University of Michigan.
 All rights reserved.

 This software was developed as part of the The Vulcan project in the Intelligent Robotics Lab
 under the direction of Benjamin Kuipers, kuipers@umich.edu. Use of this code is governed by an
 MIT-style License that can be found at "https://github.com/h2ssh/Vulcan".
*/

/**
* \file     tree_of_maps.cpp
* \author   Collin Johnson
*
* Definition of TreeOfMaps.
*/

#include <hssh/global_topological/mapping/tree_of_maps.h>
#include <hssh/global_topological/mapping/probability_heuristics.h>
#include <hssh/global_topological/debug/hypothesis_tree.h>
#include <utils/algorithm_ext.h>
#include <utils/stub.h>
#include <boost/range/adaptor/map.hpp>

namespace vulcan
{
namespace hssh
{

bool TreeOfMaps::addRootState(StatePtr&& root)
{
    // Can't change the root if any states exist
    if(!states_.empty())
    {
        return false;
    }

    auto rootId = root->id;
    auto success = states_.insert(std::make_pair(rootId, TreeNode(rootId, 0, -1, std::move(root))));

    // If the state was inserted, then increment the id and create a new depth.
    if(success.second)
    {
        depth_ = 0;
        rootId_ = rootId;

        const auto& rootNode = success.first->second;

        // The root starts as complete and a leaf
        leaves_.push_back(rootNode.state.get());
        complete_.push_back(rootNode.state.get());
    }
    else
    {
        std::cerr << "ERROR: TreeOfMaps: Failed to add the root state!\n";
    }

    return success.second;
}

bool TreeOfMaps::addChildState(Id parentId, StatePtr&& child)
{
    // Find the parent node
    auto node = nodeWithId(parentId);

    // If the state doesn't exist, fail away
    if(!node)
    {
        std::cout << "Failed to find parent!\n";
        return false;
    }

    // Create a node for the child state
    auto childId = child->id;
    auto success = states_.insert(std::make_pair(childId, TreeNode(childId,
                                                                   node->depth + 1,
                                                                   parentId,
                                                                   std::move(child))));

    // If the state couldn't be created, then fail.
    if(!success.second)
    {
        std::cout << "Failed to create child tree node.\n";
        return false;
    }

    const auto& childNode = success.first->second;

    // If the parent is no longer a leaf, then remove it from the set of leaves
    if(node->childIds.empty() && !node->hadChildren)
    {
        int numRemoved = utils::erase_remove(leaves_, node->state.get());
        assert(numRemoved == 1);    // the node must be a leaf, so ensure the variant held
    }

    // Save the parent->child link
    node->childIds.push_back(childId);
    node->hadChildren = true;

    leaves_.push_back(childNode.state.get());

    // If this child is deeper than previous complete nodes, update the depth.
    if(depth_ < childNode.depth)
    {
        depth_ = childNode.depth;
        // All existing complete hypotheses are no longer complete
        complete_.clear();
        // The new node is now the only complete node
        complete_.push_back(childNode.state.get());
    }
    else if(childNode.depth == depth_)
    {
        complete_.push_back(childNode.state.get());
    }

    return true;
}

bool TreeOfMaps::changeRootState(Id id)
{
    // Find the new root state
    // If the desired root doesn't exist, then fail
    // Copy all children of the new root to a new states_ map
    // Set the parent of the new root to invalid id.
    // Reassign the existing states.
    // Iterate through the remaining states to identify the leaves and complete hypotheses
    // Adjust the depth of all nodes in the new tree.

    auto newRoot = nodeWithId(id);

    if(!newRoot)
    {
        return false;
    }

    States newStates;
    preorderTraversal(newRoot, [&newStates](TreeNode& node) {
        newStates[node.id] = std::move(node);   // WARNING: states_ is invalid as soon as this line runs!
    });

    states_ = std::move(newStates);
    newRoot = nodeWithId(id);   // newRoot invalidated when constructing newStates, so reassign
    assert(newRoot);
    newRoot->parentId = kInvalidId;
    rootId_ = newRoot->id;

    int depthChange = newRoot->depth;
    depth_ -= depthChange;

    for(auto& node : boost::adaptors::values(states_))
    {
        node.depth -= depthChange;
    }

    findLeaves();
    return true;
}

int TreeOfMaps::numChildren(Id id) const
{
    auto node = nodeWithId(id);
    return node ? node->childIds.size() : 0;
}

int TreeOfMaps::pruneState(Id id)
{
    if(id == rootId_)
    {
        std::cerr << "WARNING: TreeOfMaps: Attempted to prune the root state!\n";
        return 0;
    }

    // If the node doesn't exist, then return without doing anything
    // Otherwise, run a preorder traversal where each node is removed.
    // Also remove from complete and leaves as needed
    auto node = nodeWithId(id);

    if(!node)
    {
        return 0;
    }

    Id parentId = node->parentId;

    if(!removeChild(parentId, id))
    {
        return 0;
    }

    int numRemoved = 1;     // remove the child at this point
    preorderTraversal(node, [&numRemoved,this](TreeNode& node) {
        numRemoved += 1;
        utils::erase_remove(complete_, node.state.get());
        utils::erase_remove(leaves_, node.state.get());
        states_.erase(node.id);     // WARNING: node reference invalidated at this point
    });

    // If no complete nodes exist, then the depth has been reduced by 1 and new complete nodes must be found
    if(complete_.empty())
    {
        std::cout << "Erased all complete maps. Rebuilding leaves.\n";
        --depth_;
        findLeaves();
    }

    // If our parent no longer has children prune it too
    if(states_[parentId].childIds.empty())
    {
        numRemoved += pruneState(parentId);
    }

    return numRemoved;
}

void TreeOfMaps::pruneIncompleteLeaves(void)
{
    std::vector<Id> toErase;
    for(auto& leaf : leaves_)
    {
        if(states_[leaf->id].childIds.empty())
        {
            toErase.push_back(leaf->id);
        }
    }

    for(auto& id : toErase)
    {
        pruneState(id);
    }
}

int TreeOfMaps::pruneLowProbability(double probabilityCutoff)
{
    PRINT_PRETTY_STUB();
    return 0;
}

HypothesisTree TreeOfMaps::toHypothesisTree(const ProbabilityHeuristics& heuristics)
{
    // Make sure leaves are valid when the tree is generated
    findLeaves();

    std::vector<hypothesis_tree_node_t> nodes;
    for(auto& n : boost::adaptors::values(states_))
    {
        hypothesis_tree_node_t node;
        node.id = n.id;
        node.depth = n.depth;
        node.children = n.childIds;
        node.probability = n.state->probability;
        node.probability.estimatedLogPrior = heuristics.logPriorHeuristic(n.depth);
        node.probability.estimatedLogLikelihood = heuristics.logLikelihoodHeuristic(n.depth);
        nodes.push_back(node);
    }

    return HypothesisTree(nodes, rootId_, leaves_.size(), complete_.size());
}

const TopologicalState* TreeOfMaps::stateWithId(Id id) const
{
    auto stateIt = states_.find(id);
    return (stateIt == states_.end()) ? nullptr : stateIt->second.state.get();
}

TreeOfMaps::TreeNode* TreeOfMaps::nodeWithId(Id id)
{
    auto nodeIt = states_.find(id);
    return nodeIt == states_.end() ? nullptr : &(nodeIt->second);
}

const TreeOfMaps::TreeNode* TreeOfMaps::nodeWithId(Id id) const
{
    auto nodeIt = states_.find(id);
    return nodeIt == states_.end() ? nullptr : &(nodeIt->second);
}

bool TreeOfMaps::removeChild(Id parent, Id child)
{
    // If there is a parent node, then remove this reference to the child
    auto parentNode = nodeWithId(parent);
    if(parentNode)
    {
        return utils::erase_remove(parentNode->childIds, child) > 0;
    }

    return false;
}

void TreeOfMaps::findLeaves(void)
{
    leaves_.clear();
    complete_.clear();

    for(auto& node : boost::adaptors::values(states_))
    {
        if(is_leaf(node))
        {
            leaves_.push_back(node.state.get());
        }

        if(node.depth == depth_)
        {
//             assert(is_leaf(node));
            complete_.push_back(node.state.get());
        }
    }

    std::cout << "Found " << leaves_.size() << " leaves and " << complete_.size() << " complete maps at depth "
        << depth_ << '\n';
}

} // namespace hssh
} // namespace vulcan