<commit_before>#include "commands.h"

using namespace aBuild;

namespace commands {

void build(bool verbose) {
	Workspace ws(".");

	checkingMissingPackages(ws);
	checkingNotNeededPackages(ws);
	checkingInvalidPackages(ws);
	checkingRequiredPackages(ws);

	Graph graph;

	auto allToolchains = getAllToolchains(ws);

	Toolchain toolchain = allToolchains.rbegin()->second;
	std::string toolchainName = ws.accessConfigFile().getToolchain();
	if (allToolchains.find(toolchainName) != allToolchains.end()) {
		toolchain = allToolchains.at(toolchainName);
	}

	std::cout << "Using toolchain: " << toolchain.getName();
	std::cout << std::endl;

	std::unique_ptr<BuildAction> action { new BuildActionClang(&graph, verbose, &ws.accessConfigFile(), toolchain) };

	auto linkingLibFunc         = action->getLinkingLibFunc();
	auto linkingExecFunc        = action->getLinkingExecFunc();
	auto _compileFileCppFunc    = action->getCompileCppFileFunc();
	auto _compileFileCppFuncDep = action->getCompileCppFileFuncDep();
	auto compileFileCFunc       = action->getCompileCFileFunc();
	std::function<void(std::string*)> compileFileCppFunc     = [&] (std::string* p){
		_compileFileCppFunc(p);
		_compileFileCppFuncDep(p);
	};

	// Create dependency tree
	auto projects = ws.getAllRequiredProjects();
	for (auto& e  : projects) {
		auto& project = e.second;
		// Adding linking
		if (project.getType() == "library") {
			graph.addNode(&project, linkingLibFunc);
		} else if (project.getType() == "executable") {
			graph.addNode(&project,  linkingExecFunc);
		} else {
			std::cout<<"invalid type: "<<project.getType()<<std::endl;
		}

		// Adding compile files
		for (auto& f : project.getAllCppFiles()) {
			graph.addNode(&f, compileFileCppFunc);
			graph.addEdge(&f, &project);
		}
		// Adding compile files
		for (auto& f : project.getAllCFiles()) {
			graph.addNode(&f, compileFileCFunc);
			graph.addEdge(&f, &project);
		}
		for (auto const& dep : project.getDependencies()) {
			auto l   = utils::explode(dep, "/");
			auto key = l[l.size() -1];
			graph.addEdge(&projects.at(key), &project);
		}
		for (auto const& dep : project.getOptionalDependencies()) {
			auto l   = utils::explode(dep, "/");
			auto key = l[l.size() -1];
			if (projects.find(key) != projects.end()) {
				graph.addEdge(&projects.at(key), &project);
			}
		}
	}

	graph.visitAllNodes();
}

}

<commit_msg>showing flavor when building<commit_after>#include "commands.h"

using namespace aBuild;

namespace commands {

void build(bool verbose) {
	Workspace ws(".");

	checkingMissingPackages(ws);
	checkingNotNeededPackages(ws);
	checkingInvalidPackages(ws);
	checkingRequiredPackages(ws);

	Graph graph;

	auto allToolchains = getAllToolchains(ws);

	Toolchain toolchain = allToolchains.rbegin()->second;
	std::string toolchainName = ws.accessConfigFile().getToolchain();
	if (allToolchains.find(toolchainName) != allToolchains.end()) {
		toolchain = allToolchains.at(toolchainName);
	}

	std::cout << "Using toolchain: " << toolchain.getName() << std::endl;
	std::cout << "Using flavor:    " << ws.accessConfigFile().getFlavor() << std::endl;

	std::unique_ptr<BuildAction> action { new BuildActionClang(&graph, verbose, &ws.accessConfigFile(), toolchain) };

	auto linkingLibFunc         = action->getLinkingLibFunc();
	auto linkingExecFunc        = action->getLinkingExecFunc();
	auto _compileFileCppFunc    = action->getCompileCppFileFunc();
	auto _compileFileCppFuncDep = action->getCompileCppFileFuncDep();
	auto compileFileCFunc       = action->getCompileCFileFunc();
	std::function<void(std::string*)> compileFileCppFunc     = [&] (std::string* p){
		_compileFileCppFunc(p);
		_compileFileCppFuncDep(p);
	};

	// Create dependency tree
	auto projects = ws.getAllRequiredProjects();
	for (auto& e  : projects) {
		auto& project = e.second;
		// Adding linking
		if (project.getType() == "library") {
			graph.addNode(&project, linkingLibFunc);
		} else if (project.getType() == "executable") {
			graph.addNode(&project,  linkingExecFunc);
		} else {
			std::cout<<"invalid type: "<<project.getType()<<std::endl;
		}

		// Adding compile files
		for (auto& f : project.getAllCppFiles()) {
			graph.addNode(&f, compileFileCppFunc);
			graph.addEdge(&f, &project);
		}
		// Adding compile files
		for (auto& f : project.getAllCFiles()) {
			graph.addNode(&f, compileFileCFunc);
			graph.addEdge(&f, &project);
		}
		for (auto const& dep : project.getDependencies()) {
			auto l   = utils::explode(dep, "/");
			auto key = l[l.size() -1];
			graph.addEdge(&projects.at(key), &project);
		}
		for (auto const& dep : project.getOptionalDependencies()) {
			auto l   = utils::explode(dep, "/");
			auto key = l[l.size() -1];
			if (projects.find(key) != projects.end()) {
				graph.addEdge(&projects.at(key), &project);
			}
		}
	}

	graph.visitAllNodes();
}

}

<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <cstdlib>
#include <lcm/lcm-cpp.hpp>
#include <lcmtypes/drc_lcmtypes.hpp>
#include <std_msgs/Float64.h>
#include <sensor_msgs/JointState.h>
#include <geometry_msgs/Pose.h>
#include <std_srvs/Empty.h>
#include <map>
#include <string>

/**
	A simple translator that listens for a robot state message on the SET_ROBOT_CONFIG channel and sets the robot's pose, joint positions,
	and PID controller setpoints accordingly. If pausePhysics is set to true, the gazebo simulation will be paused after the configuration
	is reset.
**/

class ConfigurationCommandHandler{
	private:

		std::map<std::string, ros::Publisher> setpoint_map;
		ros::Publisher pose_pub;
		ros::Publisher joint_pub;
		ros::NodeHandle config_command_node;

		ros::ServiceClient client;
		bool pausePhysics;

	public:
		ConfigurationCommandHandler(ros::NodeHandle &node): config_command_node(node) {

	 		pose_pub = config_command_node.advertise<geometry_msgs::Pose>("/atlas/set_pose",10);
	 		joint_pub = config_command_node.advertise<sensor_msgs::JointState>("/atlas/configuration",10);

			setpoint_map.insert(std::make_pair("l_arm_elx",config_command_node.advertise<std_msgs::Float64>("/l_arm_elx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_ely",config_command_node.advertise<std_msgs::Float64>("/l_arm_ely_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_mwx",config_command_node.advertise<std_msgs::Float64>("/l_arm_mwx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_shx",config_command_node.advertise<std_msgs::Float64>("/l_arm_shx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_usy",config_command_node.advertise<std_msgs::Float64>("/l_arm_usy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_uwy",config_command_node.advertise<std_msgs::Float64>("/l_arm_uwy_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("r_arm_elx",config_command_node.advertise<std_msgs::Float64>("/r_arm_elx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_ely",config_command_node.advertise<std_msgs::Float64>("/r_arm_ely_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_mwx",config_command_node.advertise<std_msgs::Float64>("/r_arm_mwx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_shx",config_command_node.advertise<std_msgs::Float64>("/r_arm_shx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_usy",config_command_node.advertise<std_msgs::Float64>("/r_arm_usy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_uwy",config_command_node.advertise<std_msgs::Float64>("/r_arm_uwy_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("l_leg_kny",config_command_node.advertise<std_msgs::Float64>("/l_leg_kny_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_lax",config_command_node.advertise<std_msgs::Float64>("/l_leg_lax_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_lhy",config_command_node.advertise<std_msgs::Float64>("/l_leg_lhy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_mhx",config_command_node.advertise<std_msgs::Float64>("/l_leg_mhx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_uay",config_command_node.advertise<std_msgs::Float64>("/l_leg_uay_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_uhz",config_command_node.advertise<std_msgs::Float64>("/l_leg_uhz_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("r_leg_kny",config_command_node.advertise<std_msgs::Float64>("/r_leg_kny_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_lax",config_command_node.advertise<std_msgs::Float64>("/r_leg_lax_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_lhy",config_command_node.advertise<std_msgs::Float64>("/r_leg_lhy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_mhx",config_command_node.advertise<std_msgs::Float64>("/r_leg_mhx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_uay",config_command_node.advertise<std_msgs::Float64>("/r_leg_uay_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_uhz",config_command_node.advertise<std_msgs::Float64>("/r_leg_uhz_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("neck_ay",config_command_node.advertise<std_msgs::Float64>("/neck_ay_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("back_lbz",config_command_node.advertise<std_msgs::Float64>("/back_lbz_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("back_mby",config_command_node.advertise<std_msgs::Float64>("/back_mby_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("back_ubx",config_command_node.advertise<std_msgs::Float64>("/back_ubx_position_controller/command",10)));

			pausePhysics = false;
			client = config_command_node.serviceClient<std_srvs::Empty>("/gazebo/pause_physics");
		}
		~ConfigurationCommandHandler() {}

		void configuration_command_callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::robot_state_t* msg)
		{
			// set robot pose
			geometry_msgs::Pose pose_msg;
			pose_msg.position = geometry_msgs::Point();
			pose_msg.position.x = msg->origin_position.translation.x;
			pose_msg.position.y = msg->origin_position.translation.y;
			pose_msg.position.z = msg->origin_position.translation.z;

			pose_msg.orientation = geometry_msgs::Quaternion();
			pose_msg.orientation.x = msg->origin_position.rotation.x;
			pose_msg.orientation.y = msg->origin_position.rotation.y;
			pose_msg.orientation.z = msg->origin_position.rotation.z;
			pose_msg.orientation.w = msg->origin_position.rotation.w;

			// set robot joint config
			sensor_msgs::JointState joint_msg;
			for (int i=0; i<msg->num_joints; i++) {
			    joint_msg.name.push_back(msg->joint_name[i]);
			    joint_msg.position.push_back(msg->joint_position[i]);
			}

			if(ros::ok()) {
				joint_pub.publish(joint_msg);
				pose_pub.publish(pose_msg);
			}

			// set PID goals
			std_msgs::Float64 position_command_msg;
			for (int i=0; i<msg->num_joints; i++) {
			    // should we instead publish all joints at the same time?
			    position_command_msg.data = msg->joint_position[i];
				if(ros::ok()) {
					setpoint_map[msg->joint_name[i]].publish(position_command_msg);
				}
			}

			// pause gazebo
			if(pausePhysics && ros::ok()) {
		  		std_srvs::Empty srv;
		  		if (!client.call(srv)) {
					ROS_ERROR("Failed to pause gazebo.");
		  		}
			}
		}
};

int main(int argc,char** argv) {
	ros::init(argc,argv,"config_command_publisher",ros::init_options::NoSigintHandler);
    ros::NodeHandle config_command_node;

	lcm::LCM listener;
	if(!listener.good())
		return 1;
	ConfigurationCommandHandler handlerObject(config_command_node);

	//LCM subscription
	listener.subscribe("SET_ROBOT_CONFIG",&ConfigurationCommandHandler::configuration_command_callback,&handlerObject);

	while(0 == listener.handle());
	return 0;
}

<commit_msg>physics is now paused in the config command lcm2ros translator before setting the robot pose and config<commit_after>#include <ros/ros.h>
#include <cstdlib>
#include <lcm/lcm-cpp.hpp>
#include <lcmtypes/drc_lcmtypes.hpp>
#include <std_msgs/Float64.h>
#include <sensor_msgs/JointState.h>
#include <geometry_msgs/Pose.h>
#include <std_srvs/Empty.h>
#include <map>
#include <string>

/**
	A simple translator that listens for a robot state message on the SET_ROBOT_CONFIG channel and sets the robot's pose, joint positions,
	and PID controller setpoints accordingly. If pausePhysics is set to true, the gazebo simulation will be paused after the configuration
	is reset.
**/

class ConfigurationCommandHandler{
	private:

		std::map<std::string, ros::Publisher> setpoint_map;
		ros::Publisher pose_pub;
		ros::Publisher joint_pub;
		ros::NodeHandle config_command_node;

		ros::ServiceClient client;
		bool pausePhysics;

	public:
		ConfigurationCommandHandler(ros::NodeHandle &node): config_command_node(node) {

	 		pose_pub = config_command_node.advertise<geometry_msgs::Pose>("/atlas/set_pose",10);
	 		joint_pub = config_command_node.advertise<sensor_msgs::JointState>("/atlas/configuration",10);

			setpoint_map.insert(std::make_pair("l_arm_elx",config_command_node.advertise<std_msgs::Float64>("/l_arm_elx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_ely",config_command_node.advertise<std_msgs::Float64>("/l_arm_ely_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_mwx",config_command_node.advertise<std_msgs::Float64>("/l_arm_mwx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_shx",config_command_node.advertise<std_msgs::Float64>("/l_arm_shx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_usy",config_command_node.advertise<std_msgs::Float64>("/l_arm_usy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_arm_uwy",config_command_node.advertise<std_msgs::Float64>("/l_arm_uwy_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("r_arm_elx",config_command_node.advertise<std_msgs::Float64>("/r_arm_elx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_ely",config_command_node.advertise<std_msgs::Float64>("/r_arm_ely_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_mwx",config_command_node.advertise<std_msgs::Float64>("/r_arm_mwx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_shx",config_command_node.advertise<std_msgs::Float64>("/r_arm_shx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_usy",config_command_node.advertise<std_msgs::Float64>("/r_arm_usy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_arm_uwy",config_command_node.advertise<std_msgs::Float64>("/r_arm_uwy_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("l_leg_kny",config_command_node.advertise<std_msgs::Float64>("/l_leg_kny_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_lax",config_command_node.advertise<std_msgs::Float64>("/l_leg_lax_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_lhy",config_command_node.advertise<std_msgs::Float64>("/l_leg_lhy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_mhx",config_command_node.advertise<std_msgs::Float64>("/l_leg_mhx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_uay",config_command_node.advertise<std_msgs::Float64>("/l_leg_uay_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("l_leg_uhz",config_command_node.advertise<std_msgs::Float64>("/l_leg_uhz_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("r_leg_kny",config_command_node.advertise<std_msgs::Float64>("/r_leg_kny_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_lax",config_command_node.advertise<std_msgs::Float64>("/r_leg_lax_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_lhy",config_command_node.advertise<std_msgs::Float64>("/r_leg_lhy_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_mhx",config_command_node.advertise<std_msgs::Float64>("/r_leg_mhx_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_uay",config_command_node.advertise<std_msgs::Float64>("/r_leg_uay_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("r_leg_uhz",config_command_node.advertise<std_msgs::Float64>("/r_leg_uhz_position_controller/command",10)));

			setpoint_map.insert(std::make_pair("neck_ay",config_command_node.advertise<std_msgs::Float64>("/neck_ay_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("back_lbz",config_command_node.advertise<std_msgs::Float64>("/back_lbz_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("back_mby",config_command_node.advertise<std_msgs::Float64>("/back_mby_position_controller/command",10)));
			setpoint_map.insert(std::make_pair("back_ubx",config_command_node.advertise<std_msgs::Float64>("/back_ubx_position_controller/command",10)));

			pausePhysics = true;
			client = config_command_node.serviceClient<std_srvs::Empty>("/gazebo/pause_physics");
		}
		~ConfigurationCommandHandler() {}

		void configuration_command_callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::robot_state_t* msg)
		{
			// pause gazebo
			if(pausePhysics && ros::ok()) {
		  		std_srvs::Empty srv;
		  		if (!client.call(srv)) {
					ROS_ERROR("Failed to pause gazebo.");
		  		}
			}

			// set robot pose
			geometry_msgs::Pose pose_msg;
			pose_msg.position = geometry_msgs::Point();
			pose_msg.position.x = msg->origin_position.translation.x;
			pose_msg.position.y = msg->origin_position.translation.y;
			pose_msg.position.z = msg->origin_position.translation.z;

			pose_msg.orientation = geometry_msgs::Quaternion();
			pose_msg.orientation.x = msg->origin_position.rotation.x;
			pose_msg.orientation.y = msg->origin_position.rotation.y;
			pose_msg.orientation.z = msg->origin_position.rotation.z;
			pose_msg.orientation.w = msg->origin_position.rotation.w;

			// set robot joint config
			sensor_msgs::JointState joint_msg;
			for (int i=0; i<msg->num_joints; i++) {
			    joint_msg.name.push_back(msg->joint_name[i]);
			    joint_msg.position.push_back(msg->joint_position[i]);
			}

			if(ros::ok()) {
				joint_pub.publish(joint_msg);
				pose_pub.publish(pose_msg);
			}

			// set PID goals
			std_msgs::Float64 position_command_msg;
			for (int i=0; i<msg->num_joints; i++) {
			    // should we instead publish all joints at the same time?
			    position_command_msg.data = msg->joint_position[i];
				if(ros::ok()) {
					setpoint_map[msg->joint_name[i]].publish(position_command_msg);
				}
			}

		}
};

int main(int argc,char** argv) {
	ros::init(argc,argv,"config_command_publisher",ros::init_options::NoSigintHandler);
    ros::NodeHandle config_command_node;

	lcm::LCM listener;
	if(!listener.good())
		return 1;
	ConfigurationCommandHandler handlerObject(config_command_node);

	//LCM subscription
	listener.subscribe("SET_ROBOT_CONFIG",&ConfigurationCommandHandler::configuration_command_callback,&handlerObject);

	while(0 == listener.handle());
	return 0;
}

<|endoftext|>


<commit_before>#include "list.h"
#include "gtest/gtest.h"
#include <string>

class listTest : public testing::Test {
 protected:
  virtual void SetUp() {
    list_1.insert(list_1.begin(), 10);
    int_iter = list_1.insert(list_1.end(), 30);
    int_iter = list_1.insert(int_iter, 20);
    str = "a string";
  }
  virtual void TearDown() {}
  // class constant

  // setup fixtures
  ::list<int> list_1;
  ::list<int> list_2;
  list<int> list_empty;
  ::list<std::string> list_str;
  list<int>::iterator int_iter;
  list<std::string>::iterator str_iter;
  std::string str;
};

class listIteratorTest : public testing::Test {
  // try to make friend with list_const_iterator DOES NOT WORK here
  // because friendship must be made before template is resolved:
  // friend class list_const_iterator<int>;
 protected:
  virtual void SetUp() {
    head_ = new listNode<int> (0);
    head_->next_ = new listNode<int> (10);
    tail_ = head_->next_->next_ = new listNode<int> (20);
    head_->next_->prev_ = head_;
    tail_->prev_ = head_->next_;
    c_iter = list_const_iterator<int> (head_);
    c_iter_1 = list_const_iterator<int> (head_->next_);
    iter = list_iterator<int> (head_);
    iter_1 = list_iterator<int> (head_->next_);
  }

  virtual void TearDown() {
    delete tail_;
    delete head_->next_;
    delete head_;
  }
  listNode<int>* head_;
  listNode<int>* tail_;
  list_const_iterator<int> c_iter;
  list_const_iterator<int> c_iter_1;
  list_iterator<int> iter;
  list_iterator<int> iter_1;

};

// test the helper class listNodeTest
// this is a canonical example of writing testable code:
// to test private members, just write another helper class
// and make its data public
TEST(listHelperTest, ListNode) {
  int element_1 = 100;
  std::string element_2("Hello world");
  listNode<int> node_1(element_1);
  listNode<std::string> node_2(element_2);
  EXPECT_EQ(element_1, node_1.element_);
  EXPECT_EQ(element_2, node_2.element_);
  EXPECT_EQ(nullptr, node_2.prev_);
  EXPECT_EQ(nullptr, node_2.next_);
  // test the move constructor for node:
  listNode<int> node_3(std::move(element_1));
  listNode<std::string> node_4(std::move(element_2));
  EXPECT_EQ(100, node_3.element_);
  EXPECT_EQ("Hello world", node_4.element_);
  EXPECT_TRUE(element_2.empty());
}

TEST_F(listIteratorTest, ConstIterator) {
  list_const_iterator<int> c_iter_temp = c_iter;
  // testing increment and decrement of const_iterator
  EXPECT_EQ(++c_iter_temp, c_iter_1);
  EXPECT_EQ(--c_iter_temp, c_iter);
  EXPECT_EQ(c_iter_temp++, c_iter);
  EXPECT_EQ(c_iter_temp, c_iter_1);
  EXPECT_EQ(c_iter_temp--, c_iter_1);
  EXPECT_EQ(c_iter_temp, c_iter);
  EXPECT_TRUE(c_iter_temp == c_iter);
  EXPECT_TRUE(c_iter_temp != c_iter_1);

  // testing access capability of const_iterator
  EXPECT_EQ(0, *c_iter_temp);
  EXPECT_EQ(10, *(++c_iter_temp));
  EXPECT_EQ(20, *(++c_iter_temp));
  EXPECT_EQ(10, *(--c_iter_temp));

  // testing non-modifying capability of const_iterator:
  // will not even compile:
  //*c_iter_temp = 100;
}

TEST_F(listIteratorTest, Iterator) {
  list_iterator<int> iter_temp = iter;
  // testing increment and decrement of iterator
  // which are all inherited from base
  EXPECT_EQ(++iter_temp, iter_1);
  EXPECT_EQ(--iter_temp, iter);
  EXPECT_EQ(iter_temp++, iter);
  EXPECT_EQ(iter_temp, iter_1);
  EXPECT_EQ(iter_temp--, iter_1);
  EXPECT_EQ(iter_temp, iter);
  EXPECT_TRUE(iter_temp == iter);
  EXPECT_TRUE(iter_temp != iter_1);

  // testing access capability of iterator
  EXPECT_EQ(0, *iter_temp);
  EXPECT_EQ(10, *(++iter_temp));
  EXPECT_EQ(20, *(++iter_temp));
  EXPECT_EQ(10, *(--iter_temp));

  // testing modifying capability of iterator:
  *iter_temp = 100;
  EXPECT_EQ(*iter_temp, 100);
}

TEST_F(listTest, DefaultCtor) {
  EXPECT_EQ(0u, list_empty.size());
  EXPECT_TRUE(list_empty.empty());
}

TEST_F(listTest, CopyCtor) {

}

TEST_F(listTest, BeginEnd) {
  EXPECT_EQ(list_empty.begin(), list_empty.end());
  // decrement pass begin() and increment pass end() should be ok
  EXPECT_NO_FATAL_FAILURE(--list_empty.begin());
  EXPECT_NO_FATAL_FAILURE(++list_empty.end());
}

TEST_F(listTest, InsertLvalue) {
  // iter is pointing to tail_
  list<int>::iterator iter = list_empty.begin();
  // testing iterator insert (iterator, const E&)
  int x = 10;
  list<int>::iterator ret_iter = list_empty.insert(iter, x);
  EXPECT_TRUE(--iter == ret_iter);
  // iter--;
  EXPECT_EQ(*ret_iter, 10);
  EXPECT_EQ(list_empty.size(), 1);
  EXPECT_EQ(++ret_iter, list_empty.end());
  --ret_iter; // set ret_iter to point to 10
  ret_iter = list_empty.insert(ret_iter, x + 10);
  EXPECT_EQ(list_empty.size(), 2);
  EXPECT_EQ(*ret_iter, 20);
  EXPECT_EQ(*(++ret_iter), 10);
  EXPECT_TRUE(++ret_iter == list_empty.end());

  // insert pass begin() and pass end() should fail
  // the following would not even compile:
  // list_empty.insert(++list_empty.end(), 100);
  // list_empty.insert(--list_empty.begin(), 100);
}

TEST_F(listTest, InsertRvalue) {
  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), std::move(str));
  EXPECT_EQ(*str_iter, "a string");
  EXPECT_TRUE(str_iter == list_str.begin());
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, InsertConstObject) {
  // insert const object by lvalue:
  const std::string const_str("const string");
  const std::string CONST_STR(const_str);

  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), const_str);
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);

  // insert const objects by rvalue:
  // std::move automatically degrade to a copy insert
  str_iter = list_str.insert(list_str.begin(), std::move(const_str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);
}

TEST_F(listTest, EraseAtIter) {
  int_iter = list_1.erase(list_1.begin()); // erase 10
  EXPECT_EQ(list_1.size(), 2);
  EXPECT_EQ(*list_1.begin(), 20);
  EXPECT_EQ(*int_iter, 20);
  int_iter = list_1.erase(int_iter); // erase 20
  int_iter = list_1.erase(int_iter); // erase 30
  // test for seg fault if erase end()
  // it trigers a memory leak error right before core dump,
  // which it is expected. Turned off when running memtest
  //EXPECT_DEATH(int_iter = list_1.erase(list_1.end()), "");
}

TEST_F(listTest, PushFront) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_front(100);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 100);

  list_1.push_front(200);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 200);
  EXPECT_EQ(*(++list_1.begin()), 100);
  EXPECT_TRUE(--(++list_1.begin()) == list_1.begin());

  // rvalue version
  old_size = list_str.size();
  list_str.push_front(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*list_str.begin(), "a string");
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, PushBack) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_back(1000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 1000);

  list_1.push_back(2000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 2000);
  EXPECT_EQ(*(--(--list_1.end())), 1000);
  EXPECT_TRUE(++(--list_1.end()) == list_1.end());

  // rvalue version
  old_size = list_str.size();
  list_str.push_back(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*(--list_str.end()), "a string");
  EXPECT_TRUE(str.empty());
}
<commit_msg>list: add tests for copy ctor<commit_after>#include "list.h"
#include "gtest/gtest.h"
#include <string>

class listTest : public testing::Test {
 protected:
  virtual void SetUp() {
    list_1.insert(list_1.begin(), 10);
    int_iter = list_1.insert(list_1.end(), 30);
    int_iter = list_1.insert(int_iter, 20);
    str = "a string";
  }
  virtual void TearDown() {}
  // class constant

  // setup fixtures
  ::list<int> list_1;
  ::list<int> list_2;
  list<int> list_empty;
  ::list<std::string> list_str;
  list<int>::iterator int_iter;
  list<std::string>::iterator str_iter;
  std::string str;
};

class listIteratorTest : public testing::Test {
  // try to make friend with list_const_iterator DOES NOT WORK here
  // because friendship must be made before template is resolved:
  // friend class list_const_iterator<int>;
 protected:
  virtual void SetUp() {
    head_ = new listNode<int> (0);
    head_->next_ = new listNode<int> (10);
    tail_ = head_->next_->next_ = new listNode<int> (20);
    head_->next_->prev_ = head_;
    tail_->prev_ = head_->next_;
    c_iter = list_const_iterator<int> (head_);
    c_iter_1 = list_const_iterator<int> (head_->next_);
    iter = list_iterator<int> (head_);
    iter_1 = list_iterator<int> (head_->next_);
  }

  virtual void TearDown() {
    delete tail_;
    delete head_->next_;
    delete head_;
  }
  listNode<int>* head_;
  listNode<int>* tail_;
  list_const_iterator<int> c_iter;
  list_const_iterator<int> c_iter_1;
  list_iterator<int> iter;
  list_iterator<int> iter_1;

};

// test the helper class listNodeTest
// this is a canonical example of writing testable code:
// to test private members, just write another helper class
// and make its data public
TEST(listHelperTest, ListNode) {
  int element_1 = 100;
  std::string element_2("Hello world");
  listNode<int> node_1(element_1);
  listNode<std::string> node_2(element_2);
  EXPECT_EQ(element_1, node_1.element_);
  EXPECT_EQ(element_2, node_2.element_);
  EXPECT_EQ(nullptr, node_2.prev_);
  EXPECT_EQ(nullptr, node_2.next_);
  // test the move constructor for node:
  listNode<int> node_3(std::move(element_1));
  listNode<std::string> node_4(std::move(element_2));
  EXPECT_EQ(100, node_3.element_);
  EXPECT_EQ("Hello world", node_4.element_);
  EXPECT_TRUE(element_2.empty());
}

TEST_F(listIteratorTest, ConstIterator) {
  list_const_iterator<int> c_iter_temp = c_iter;
  // testing increment and decrement of const_iterator
  EXPECT_EQ(++c_iter_temp, c_iter_1);
  EXPECT_EQ(--c_iter_temp, c_iter);
  EXPECT_EQ(c_iter_temp++, c_iter);
  EXPECT_EQ(c_iter_temp, c_iter_1);
  EXPECT_EQ(c_iter_temp--, c_iter_1);
  EXPECT_EQ(c_iter_temp, c_iter);
  EXPECT_TRUE(c_iter_temp == c_iter);
  EXPECT_TRUE(c_iter_temp != c_iter_1);

  // testing access capability of const_iterator
  EXPECT_EQ(0, *c_iter_temp);
  EXPECT_EQ(10, *(++c_iter_temp));
  EXPECT_EQ(20, *(++c_iter_temp));
  EXPECT_EQ(10, *(--c_iter_temp));

  // testing non-modifying capability of const_iterator:
  // will not even compile:
  //*c_iter_temp = 100;
}

TEST_F(listIteratorTest, Iterator) {
  list_iterator<int> iter_temp = iter;
  // testing increment and decrement of iterator
  // which are all inherited from base
  EXPECT_EQ(++iter_temp, iter_1);
  EXPECT_EQ(--iter_temp, iter);
  EXPECT_EQ(iter_temp++, iter);
  EXPECT_EQ(iter_temp, iter_1);
  EXPECT_EQ(iter_temp--, iter_1);
  EXPECT_EQ(iter_temp, iter);
  EXPECT_TRUE(iter_temp == iter);
  EXPECT_TRUE(iter_temp != iter_1);

  // testing access capability of iterator
  EXPECT_EQ(0, *iter_temp);
  EXPECT_EQ(10, *(++iter_temp));
  EXPECT_EQ(20, *(++iter_temp));
  EXPECT_EQ(10, *(--iter_temp));

  // testing modifying capability of iterator:
  *iter_temp = 100;
  EXPECT_EQ(*iter_temp, 100);
}

TEST_F(listTest, DefaultCtor) {
  EXPECT_EQ(0u, list_empty.size());
  EXPECT_TRUE(list_empty.empty());
}

TEST_F(listTest, CopyCtor) {
  for (int i = 0; i < 100; i++) {
    list_1.push_back(i);
  }
  const list<int> list_temp = list_1;
  EXPECT_EQ(list_temp.size(), list_1.size());
  int_iter = list_1.begin();
  list<int>::const_iterator temp_iter = list_temp.begin();
  while(temp_iter != list_temp.end()
        && int_iter != list_1.end())
  {
    EXPECT_EQ(*temp_iter++, *int_iter++);
  }

  // edge case: empty list
  list<int> list_nothing = list_empty;
  EXPECT_TRUE(list_nothing.empty());
}

TEST_F(listTest, BeginEnd) {
  EXPECT_EQ(list_empty.begin(), list_empty.end());
  // decrement pass begin() and increment pass end() should be ok
  EXPECT_NO_FATAL_FAILURE(--list_empty.begin());
  EXPECT_NO_FATAL_FAILURE(++list_empty.end());
}

TEST_F(listTest, InsertLvalue) {
  // iter is pointing to tail_
  list<int>::iterator iter = list_empty.begin();
  // testing iterator insert (iterator, const E&)
  int x = 10;
  list<int>::iterator ret_iter = list_empty.insert(iter, x);
  EXPECT_TRUE(--iter == ret_iter);
  // iter--;
  EXPECT_EQ(*ret_iter, 10);
  EXPECT_EQ(list_empty.size(), 1);
  EXPECT_EQ(++ret_iter, list_empty.end());
  --ret_iter; // set ret_iter to point to 10
  ret_iter = list_empty.insert(ret_iter, x + 10);
  EXPECT_EQ(list_empty.size(), 2);
  EXPECT_EQ(*ret_iter, 20);
  EXPECT_EQ(*(++ret_iter), 10);
  EXPECT_TRUE(++ret_iter == list_empty.end());

  // insert pass begin() and pass end() should fail
  // the following would not even compile:
  // list_empty.insert(++list_empty.end(), 100);
  // list_empty.insert(--list_empty.begin(), 100);
}

TEST_F(listTest, InsertRvalue) {
  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), std::move(str));
  EXPECT_EQ(*str_iter, "a string");
  EXPECT_TRUE(str_iter == list_str.begin());
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, InsertConstObject) {
  // insert const object by lvalue:
  const std::string const_str("const string");
  const std::string CONST_STR(const_str);

  size_t old_size = list_str.size();
  str_iter = list_str.insert(list_str.begin(), const_str);
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);

  // insert const objects by rvalue:
  // std::move automatically degrade to a copy insert
  str_iter = list_str.insert(list_str.begin(), std::move(const_str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*str_iter, CONST_STR);
  EXPECT_EQ(const_str, CONST_STR);
}

TEST_F(listTest, EraseAtIter) {
  int_iter = list_1.erase(list_1.begin()); // erase 10
  EXPECT_EQ(list_1.size(), 2);
  EXPECT_EQ(*list_1.begin(), 20);
  EXPECT_EQ(*int_iter, 20);
  int_iter = list_1.erase(int_iter); // erase 20
  int_iter = list_1.erase(int_iter); // erase 30
  // test for seg fault if erase end()
  // it trigers a memory leak error right before core dump,
  // which it is expected. Turned off when running memtest
  //EXPECT_DEATH(int_iter = list_1.erase(list_1.end()), "");
}

TEST_F(listTest, PushFront) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_front(100);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 100);

  list_1.push_front(200);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*list_1.begin(), 200);
  EXPECT_EQ(*(++list_1.begin()), 100);
  EXPECT_TRUE(--(++list_1.begin()) == list_1.begin());

  // rvalue version
  old_size = list_str.size();
  list_str.push_front(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*list_str.begin(), "a string");
  EXPECT_TRUE(str.empty());
}

TEST_F(listTest, PushBack) {
  // lvalue version
  size_t old_size = list_1.size();
  list_1.push_back(1000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 1000);

  list_1.push_back(2000);
  EXPECT_EQ(++old_size, list_1.size());
  EXPECT_EQ(*(--list_1.end()), 2000);
  EXPECT_EQ(*(--(--list_1.end())), 1000);
  EXPECT_TRUE(++(--list_1.end()) == list_1.end());

  // rvalue version
  old_size = list_str.size();
  list_str.push_back(std::move(str));
  EXPECT_EQ(++old_size, list_str.size());
  EXPECT_EQ(*(--list_str.end()), "a string");
  EXPECT_TRUE(str.empty());
}
<|endoftext|>


<commit_before><commit_msg>latest<commit_after><|endoftext|>


<commit_before>#include "AliMCAuxHandler.h"
#include "AliAnalysisManager.h"
#include <TError.h>
#include <AliLog.h>
#include <TFile.h>
#include <TClonesArray.h>
#include <TROOT.h>
#include <AliStack.h>
#include <AliMCEvent.h>

ClassImp(AliMCAuxHandler)
#if 0 // For Emacs - do not remove
;
#endif

//____________________________________________________________________
AliMCAuxHandler::AliMCAuxHandler(const char* name,
				       const char* what,
				       AliMCEventHandler* parent)
  : AliMCEventHandler(name, what),
    fParent(parent),
    fFile(0),
    fTree(0),
    fDir(0),
    fArray(0),
    fNEvents(0),
    fNEventsPerFile(0),
    fNEventsInContainer(0),
    fEvent(0),
    fFileNumber(0),
    fTreeName(""),
    fFileBase("")
{
  // Constructor
  //
  // Parameters:
  //   name The name
}

//____________________________________________________________________
TString*
AliMCAuxHandler::GetParentPath() const
{
  if (!fParent) {
    AliWarning("No parent");
    return 0;
  }
  return fParent->GetInputPath();
}

//____________________________________________________________________
Bool_t
AliMCAuxHandler::Init(Option_t* opt)
{
  // Initialize the input
  //
  // @param opt Options
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::Init(\"%s\")", opt);

  TString option(opt);
  if (option.EqualTo("proof") || option.EqualTo("local")) return true;

  TString t = "Tree";
  TString b = "";
  TClass* cl = gROOT->GetClass(GetTitle());
  if (cl) {
    if (cl->InheritsFrom("AliHit")) {
      t += "H";
      b =  "Hits";
    }
    else if (cl->InheritsFrom("AliSDigit")) {
      t += "S";
      b =  "SDigits";
    }
    else if (cl->InheritsFrom("AliDigit")) {
      t += "D";
      b =  "Digits";
    }
    else
      t = "";
  }
  if (!t.IsNull()) fTreeName = t;
  if (!b.IsNull()) fFileBase = b;

  fArray = new TClonesArray(GetTitle());

  TTree* treeE = fParent->GetTree();
  if (!treeE) {
    AliError("Parent does not have an events tree");
    return false;
  }

  // Get number of events in this directory
  fNEventsPerFile = -1;
  fNEvents        = treeE->GetEntries();
  fEvent          = 0;
  fFileNumber     = 0;

  if (!OpenFile(fFileNumber)) return false;

  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::BeginEvent(Long64_t entry)
{
  // Called at the beginning of an event
  //
  // @param entry Entry in tree
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::BeginEvent(%lld)", entry);

  if (entry == -1)
    fEvent++;
  else
    fEvent = entry;

  if (fEvent >= fNEvents) {
    AliWarningF("Event number out of range %d/%d", fEvent, fNEvents);
    return false;
  }

  if (fNEventsPerFile < 0) {
    TTree* treeK = fParent->TreeK();
    if (!treeK) {
      AliError("Parent does not have a kinematics tree");
      return false;
    }

    TFile* fileK = treeK->GetCurrentFile();
    if (!fileK) {
      AliError("Kinematics tree has no associated file");
      return false;
    }
    // Get the number of events per file
    fNEventsPerFile = fileK->GetNkeys() - fileK->GetNProcessIDs();
  }
  return LoadEvent(fEvent);
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::Notify(const char* path)
{
  // Called when the input file is changed
  //
  // @param path New path
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::Notify(\"%s\")", path);
  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::FinishEvent()
{
  // Called at the end of an event
  //
  // @return true on success
  AliDebug(10,"AliMCAuxHandler::FinishEvent()");
  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::Terminate()
{
  // Called at the end of a job
  //
  // @return true on success
  AliDebug(10,"AliMCAuxHandler::Terminate()");
  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::TerminateIO()
{
  // Called at the end of a sub-job
  //
  // @return true on success
  AliDebug(10,"AliMCAuxHandler::TerminateIO()");
  return true;
}

//____________________________________________________________________
void
AliMCAuxHandler::ResetIO()
{
  // Reset the I/O
  //
  //
  AliDebug(10,"AliMCAuxHandler::ResetIO()");

  TString* path = GetParentPath();
  AliDebugF(10,"Got parent path %s", path ? path->Data() : "null");

  if (fFile) {
    delete fFile;
    fFile = 0;
  }
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::OpenFile(Int_t fileNo)
{
  TString* path = GetParentPath();
  AliDebugF(10,"Got parent path %s", path ? path->Data() : "null");
  if (!path) return false;

  TString ext("");
  if (fileNo > 0) ext = TString::Format("%d", fileNo);

  TString w(GetTitle());
  if (w.EndsWith("s")) w.Chop();

  TString fn = TString::Format("%s%s.%s%s.root",
			       path->Data(), GetName(),
			       fFileBase.Data(), ext.Data());
  Info("Init", "Opening %s", fn.Data());
  fFile = TFile::Open(fn, "READ");
  if (!fFile) {
    AliErrorF("Failed to open %s", fn.Data());
    return false;
  }

  return true;
}

//____________________________________________________________________
Bool_t
AliMCAuxHandler::LoadEvent(Int_t iev)
{
  // Load an event
  //
  // @param iev Event number
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::LoadEvent(%d)", iev);

  Int_t iNew = iev / fNEventsPerFile;
  if (iNew != fFileNumber) {
    fFileNumber = iNew;
    if (!OpenFile(fFileNumber)) return false;
  }
  if (!fFile) return false;

  TString folder = TString::Format("Event%d", iev);
  fFile->GetObject(folder, fDir);
  if (!fDir) {
    AliWarningF("Folder %s not found in file", folder.Data());
    return false;
  }

  fDir->GetObject(fTreeName, fTree);
  if (!fTree) {
    AliWarningF("Folder %s does not contain the %s tree %s",
		folder.Data(), GetTitle(), fTreeName.Data());
    return false;
  }

  fTree->SetBranchAddress(GetName(), &fArray);
  return true;
}

//____________________________________________________________________
Int_t
AliMCAuxHandler::GetNEntry() const
{
  if (!fTree) return 0;
  return fTree->GetEntries();
}

//____________________________________________________________________
TClonesArray*
AliMCAuxHandler::GetEntryArray(Int_t entry)
{
  if (!fTree) return 0;
  if (!fArray) return 0;
  if (entry < 0 || entry >= fTree->GetEntries()) {
    AliErrorF("Entry # %d out of bounds [0,%lld]",
	      entry, fTree->GetEntries());
    return 0;
  }
  fArray->Clear();

  if (fTree->GetEntry(entry) <= 0) return 0;

  return fArray;
}

//____________________________________________________________________
AliMCAuxHandler*
AliMCAuxHandler::Create(const char* name, const char* what)
{
  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AliMCAuxHandler::Create", "No analysis manager");
    return 0;
  }

  AliVEventHandler* vmc = mgr->GetMCtruthEventHandler();
  if (!vmc) {
    ::Error("AliMCAuxHandler::Create", "No MC truth handler");
    return 0;
  }

  AliMCEventHandler* mc = dynamic_cast<AliMCEventHandler*>(vmc);
  if (!mc) {
    ::Error("AliMCAuxHandler::Create",
	    "MC truth handler not a AliMCEventHandler, but %s",
	    vmc->ClassName());
    return 0;
  }

  AliMCAuxHandler* ret = new AliMCAuxHandler(name, what, mc);
  mc->AddSubsidiaryHandler(ret);

  return ret;
}

//____________________________________________________________________
TClonesArray*
AliMCAuxHandler::GetParticleArray(AliMCAuxHandler* handler,
				     Int_t particle)
{
  if (!handler) {
    ::Error("AliMCAuxHandler::GetArray", "No handler passed");
    return 0;
  }

  AliMCEventHandler* mc = handler->GetParent();
  if (!mc) {
    ::Error("AliMCAuxHandler::GetArray", "Handler has no parent");
    return 0;
  }

  AliMCEvent* event = mc->MCEvent();
  if (!event) {
    ::Error("AliMCAuxHandler::GetArray", "No MC event");
    return 0;
  }

  AliStack* stack = event->Stack();
  if (!event) {
    ::Error("AliMCAuxHandler::GetArray", "Event has no stack");
    return 0;
  }

  handler->GetArray()->Clear();
  TTree* tree = handler->GetTree();
  if (!tree) {
    ::Error("AliMCAuxHandler::GetArray", "Handler has no tree");
    return 0;
  }

  Int_t treeIdx = stack->TreeKEntry(particle);
  if (treeIdx < 0 || treeIdx >= tree->GetEntries()) {
    ::Error("AliMCAuxHandler::GetArray",
	    "Index %d of %d out of bounds [0,%lld]", treeIdx, particle,
	    tree->GetEntries()-1);
    return 0;
  }

  tree->GetEntry(treeIdx);

  return handler->GetArray();
}

//____________________________________________________________________
//
// EOF
//
<commit_msg>Fixed check of returned pointer to AliStack object<commit_after>#include "AliMCAuxHandler.h"
#include "AliAnalysisManager.h"
#include <TError.h>
#include <AliLog.h>
#include <TFile.h>
#include <TClonesArray.h>
#include <TROOT.h>
#include <AliStack.h>
#include <AliMCEvent.h>

ClassImp(AliMCAuxHandler)
#if 0 // For Emacs - do not remove
;
#endif

//____________________________________________________________________
AliMCAuxHandler::AliMCAuxHandler(const char* name,
				       const char* what,
				       AliMCEventHandler* parent)
  : AliMCEventHandler(name, what),
    fParent(parent),
    fFile(0),
    fTree(0),
    fDir(0),
    fArray(0),
    fNEvents(0),
    fNEventsPerFile(0),
    fNEventsInContainer(0),
    fEvent(0),
    fFileNumber(0),
    fTreeName(""),
    fFileBase("")
{
  // Constructor
  //
  // Parameters:
  //   name The name
}

//____________________________________________________________________
TString*
AliMCAuxHandler::GetParentPath() const
{
  if (!fParent) {
    AliWarning("No parent");
    return 0;
  }
  return fParent->GetInputPath();
}

//____________________________________________________________________
Bool_t
AliMCAuxHandler::Init(Option_t* opt)
{
  // Initialize the input
  //
  // @param opt Options
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::Init(\"%s\")", opt);

  TString option(opt);
  if (option.EqualTo("proof") || option.EqualTo("local")) return true;

  TString t = "Tree";
  TString b = "";
  TClass* cl = gROOT->GetClass(GetTitle());
  if (cl) {
    if (cl->InheritsFrom("AliHit")) {
      t += "H";
      b =  "Hits";
    }
    else if (cl->InheritsFrom("AliSDigit")) {
      t += "S";
      b =  "SDigits";
    }
    else if (cl->InheritsFrom("AliDigit")) {
      t += "D";
      b =  "Digits";
    }
    else
      t = "";
  }
  if (!t.IsNull()) fTreeName = t;
  if (!b.IsNull()) fFileBase = b;

  fArray = new TClonesArray(GetTitle());

  TTree* treeE = fParent->GetTree();
  if (!treeE) {
    AliError("Parent does not have an events tree");
    return false;
  }

  // Get number of events in this directory
  fNEventsPerFile = -1;
  fNEvents        = treeE->GetEntries();
  fEvent          = 0;
  fFileNumber     = 0;

  if (!OpenFile(fFileNumber)) return false;

  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::BeginEvent(Long64_t entry)
{
  // Called at the beginning of an event
  //
  // @param entry Entry in tree
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::BeginEvent(%lld)", entry);

  if (entry == -1)
    fEvent++;
  else
    fEvent = entry;

  if (fEvent >= fNEvents) {
    AliWarningF("Event number out of range %d/%d", fEvent, fNEvents);
    return false;
  }

  if (fNEventsPerFile < 0) {
    TTree* treeK = fParent->TreeK();
    if (!treeK) {
      AliError("Parent does not have a kinematics tree");
      return false;
    }

    TFile* fileK = treeK->GetCurrentFile();
    if (!fileK) {
      AliError("Kinematics tree has no associated file");
      return false;
    }
    // Get the number of events per file
    fNEventsPerFile = fileK->GetNkeys() - fileK->GetNProcessIDs();
  }
  return LoadEvent(fEvent);
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::Notify(const char* path)
{
  // Called when the input file is changed
  //
  // @param path New path
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::Notify(\"%s\")", path);
  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::FinishEvent()
{
  // Called at the end of an event
  //
  // @return true on success
  AliDebug(10,"AliMCAuxHandler::FinishEvent()");
  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::Terminate()
{
  // Called at the end of a job
  //
  // @return true on success
  AliDebug(10,"AliMCAuxHandler::Terminate()");
  return true;
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::TerminateIO()
{
  // Called at the end of a sub-job
  //
  // @return true on success
  AliDebug(10,"AliMCAuxHandler::TerminateIO()");
  return true;
}

//____________________________________________________________________
void
AliMCAuxHandler::ResetIO()
{
  // Reset the I/O
  //
  //
  AliDebug(10,"AliMCAuxHandler::ResetIO()");

  TString* path = GetParentPath();
  AliDebugF(10,"Got parent path %s", path ? path->Data() : "null");

  if (fFile) {
    delete fFile;
    fFile = 0;
  }
}
//____________________________________________________________________
Bool_t
AliMCAuxHandler::OpenFile(Int_t fileNo)
{
  TString* path = GetParentPath();
  AliDebugF(10,"Got parent path %s", path ? path->Data() : "null");
  if (!path) return false;

  TString ext("");
  if (fileNo > 0) ext = TString::Format("%d", fileNo);

  TString w(GetTitle());
  if (w.EndsWith("s")) w.Chop();

  TString fn = TString::Format("%s%s.%s%s.root",
			       path->Data(), GetName(),
			       fFileBase.Data(), ext.Data());
  Info("Init", "Opening %s", fn.Data());
  fFile = TFile::Open(fn, "READ");
  if (!fFile) {
    AliErrorF("Failed to open %s", fn.Data());
    return false;
  }

  return true;
}

//____________________________________________________________________
Bool_t
AliMCAuxHandler::LoadEvent(Int_t iev)
{
  // Load an event
  //
  // @param iev Event number
  //
  // @return true on success
  AliDebugF(10,"AliMCAuxHandler::LoadEvent(%d)", iev);

  Int_t iNew = iev / fNEventsPerFile;
  if (iNew != fFileNumber) {
    fFileNumber = iNew;
    if (!OpenFile(fFileNumber)) return false;
  }
  if (!fFile) return false;

  TString folder = TString::Format("Event%d", iev);
  fFile->GetObject(folder, fDir);
  if (!fDir) {
    AliWarningF("Folder %s not found in file", folder.Data());
    return false;
  }

  fDir->GetObject(fTreeName, fTree);
  if (!fTree) {
    AliWarningF("Folder %s does not contain the %s tree %s",
		folder.Data(), GetTitle(), fTreeName.Data());
    return false;
  }

  fTree->SetBranchAddress(GetName(), &fArray);
  return true;
}

//____________________________________________________________________
Int_t
AliMCAuxHandler::GetNEntry() const
{
  if (!fTree) return 0;
  return fTree->GetEntries();
}

//____________________________________________________________________
TClonesArray*
AliMCAuxHandler::GetEntryArray(Int_t entry)
{
  if (!fTree) return 0;
  if (!fArray) return 0;
  if (entry < 0 || entry >= fTree->GetEntries()) {
    AliErrorF("Entry # %d out of bounds [0,%lld]",
	      entry, fTree->GetEntries());
    return 0;
  }
  fArray->Clear();

  if (fTree->GetEntry(entry) <= 0) return 0;

  return fArray;
}

//____________________________________________________________________
AliMCAuxHandler*
AliMCAuxHandler::Create(const char* name, const char* what)
{
  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AliMCAuxHandler::Create", "No analysis manager");
    return 0;
  }

  AliVEventHandler* vmc = mgr->GetMCtruthEventHandler();
  if (!vmc) {
    ::Error("AliMCAuxHandler::Create", "No MC truth handler");
    return 0;
  }

  AliMCEventHandler* mc = dynamic_cast<AliMCEventHandler*>(vmc);
  if (!mc) {
    ::Error("AliMCAuxHandler::Create",
	    "MC truth handler not a AliMCEventHandler, but %s",
	    vmc->ClassName());
    return 0;
  }

  AliMCAuxHandler* ret = new AliMCAuxHandler(name, what, mc);
  mc->AddSubsidiaryHandler(ret);

  return ret;
}

//____________________________________________________________________
TClonesArray*
AliMCAuxHandler::GetParticleArray(AliMCAuxHandler* handler,
				     Int_t particle)
{
  if (!handler) {
    ::Error("AliMCAuxHandler::GetArray", "No handler passed");
    return 0;
  }

  AliMCEventHandler* mc = handler->GetParent();
  if (!mc) {
    ::Error("AliMCAuxHandler::GetArray", "Handler has no parent");
    return 0;
  }

  AliMCEvent* event = mc->MCEvent();
  if (!event) {
    ::Error("AliMCAuxHandler::GetArray", "No MC event");
    return 0;
  }

  AliStack* stack = event->Stack();
  if (!stack) {
    ::Error("AliMCAuxHandler::GetArray", "Event has no stack");
    return 0;
  }

  handler->GetArray()->Clear();
  TTree* tree = handler->GetTree();
  if (!tree) {
    ::Error("AliMCAuxHandler::GetArray", "Handler has no tree");
    return 0;
  }

  Int_t treeIdx = stack->TreeKEntry(particle);
  if (treeIdx < 0 || treeIdx >= tree->GetEntries()) {
    ::Error("AliMCAuxHandler::GetArray",
	    "Index %d of %d out of bounds [0,%lld]", treeIdx, particle,
	    tree->GetEntries()-1);
    return 0;
  }

  tree->GetEntry(treeIdx);

  return handler->GetArray();
}

//____________________________________________________________________
//
// EOF
//
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "modules/crypto/NormalizeAlgorithm.h"

#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "public/platform/WebCryptoAlgorithm.h"
#include "public/platform/WebCryptoAlgorithmParams.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferView.h"
#include "wtf/HashMap.h"
#include "wtf/Uint8Array.h"
#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"

namespace WebCore {

namespace {

struct AlgorithmNameMapping {
    const char* const algorithmName;
    WebKit::WebCryptoAlgorithmId algorithmId;
};

// Indicates that the algorithm doesn't support the specified operation.
const int UnsupportedOp = -1;

// Either UnsupportedOp, or a value from WebKit::WebCryptoAlgorithmParamsType
typedef int AlgorithmParamsForOperation;

struct OperationParamsMapping {
    WebKit::WebCryptoAlgorithmId algorithmId;
    AlgorithmOperation operation;
    AlgorithmParamsForOperation params;
};

const AlgorithmNameMapping algorithmNameMappings[] = {
    {"AES-CBC", WebKit::WebCryptoAlgorithmIdAesCbc},
    {"HMAC", WebKit::WebCryptoAlgorithmIdHmac},
    {"RSASSA-PKCS1-v1_5", WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5},
    {"SHA-1", WebKit::WebCryptoAlgorithmIdSha1},
    {"SHA-224", WebKit::WebCryptoAlgorithmIdSha224},
    {"SHA-256", WebKit::WebCryptoAlgorithmIdSha256},
    {"SHA-384", WebKit::WebCryptoAlgorithmIdSha384},
    {"SHA-512", WebKit::WebCryptoAlgorithmIdSha512},
};

// What operations each algorithm supports, and what parameters it expects.
const OperationParamsMapping operationParamsMappings[] = {
    // AES-CBC (section 18.10.)
    {WebKit::WebCryptoAlgorithmIdAesCbc, Decrypt, WebKit::WebCryptoAlgorithmParamsTypeAesCbcParams},
    {WebKit::WebCryptoAlgorithmIdAesCbc, Encrypt, WebKit::WebCryptoAlgorithmParamsTypeAesCbcParams},
    {WebKit::WebCryptoAlgorithmIdAesCbc, GenerateKey, WebKit::WebCryptoAlgorithmParamsTypeAesKeyGenParams},
    {WebKit::WebCryptoAlgorithmIdAesCbc, ImportKey, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // HMAC (section 18.14.)
    {WebKit::WebCryptoAlgorithmIdHmac, Sign, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},
    {WebKit::WebCryptoAlgorithmIdHmac, Verify, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},
    {WebKit::WebCryptoAlgorithmIdHmac, GenerateKey, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},
    {WebKit::WebCryptoAlgorithmIdHmac, ImportKey, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},

    // RSASSA-PKCS1-v1_5 (section 18.4.)
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Sign, WebKit::WebCryptoAlgorithmParamsTypeRsaSsaParams},
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Verify, WebKit::WebCryptoAlgorithmParamsTypeRsaSsaParams},
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, GenerateKey, WebKit::WebCryptoAlgorithmParamsTypeRsaKeyGenParams},
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, ImportKey, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // SHA-1 (section 18.16.)
    {WebKit::WebCryptoAlgorithmIdSha1, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // SHA-224 (section 18.16.)
    {WebKit::WebCryptoAlgorithmIdSha224, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // SHA-256 (section 18.16.)
    {WebKit::WebCryptoAlgorithmIdSha256, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // SHA-384 (section 18.16.)
    {WebKit::WebCryptoAlgorithmIdSha384, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // SHA-512 (section 18.16.)
    {WebKit::WebCryptoAlgorithmIdSha512, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},
};

// This structure describes an algorithm and its supported operations.
struct AlgorithmInfo {
    AlgorithmInfo()
        : algorithmName(0)
    {
        for (size_t i = 0; i < WTF_ARRAY_LENGTH(paramsForOperation); ++i)
            paramsForOperation[i] = UnsupportedOp;
    }

    WebKit::WebCryptoAlgorithmId algorithmId;
    const char* algorithmName;
    AlgorithmParamsForOperation paramsForOperation[NumberOfAlgorithmOperations];
};

// AlgorithmRegistry enumerates each of the different algorithms and its
// parameters. This describes the same information as the static tables above,
// but in a more convenient runtime form.
class AlgorithmRegistry {
public:
    static const AlgorithmInfo* lookupAlgorithmByName(const String& algorithmName);

private:
    AlgorithmRegistry();

    // Algorithm name to ID.
    typedef HashMap<String, WebKit::WebCryptoAlgorithmId, CaseFoldingHash> AlgorithmNameToIdMap;
    AlgorithmNameToIdMap m_algorithmNameToId;

    // Algorithm ID to information.
    AlgorithmInfo m_algorithms[WebKit::NumberOfWebCryptoAlgorithmId];
};

const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmByName(const String& algorithmName)
{
    DEFINE_STATIC_LOCAL(AlgorithmRegistry, registry, ());

    AlgorithmNameToIdMap::const_iterator it = registry.m_algorithmNameToId.find(algorithmName);
    if (it == registry.m_algorithmNameToId.end())
        return 0;
    return &registry.m_algorithms[it->value];
}

AlgorithmRegistry::AlgorithmRegistry()
{
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(algorithmNameMappings); ++i) {
        const AlgorithmNameMapping& mapping = algorithmNameMappings[i];
        m_algorithmNameToId.add(mapping.algorithmName, mapping.algorithmId);
        m_algorithms[mapping.algorithmId].algorithmName = mapping.algorithmName;
        m_algorithms[mapping.algorithmId].algorithmId = mapping.algorithmId;
    }

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(operationParamsMappings); ++i) {
        const OperationParamsMapping& mapping = operationParamsMappings[i];
        m_algorithms[mapping.algorithmId].paramsForOperation[mapping.operation] = mapping.params;
    }
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseAesCbcParams(const Dictionary& raw)
{
    RefPtr<ArrayBufferView> iv;
    if (!raw.get("iv", iv) || !iv)
        return nullptr;

    if (iv->byteLength() != 16)
        return nullptr;

    return adoptPtr(new WebKit::WebCryptoAesCbcParams(static_cast<unsigned char*>(iv->baseAddress()), iv->byteLength()));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseAesKeyGenParams(const Dictionary& raw)
{
    int32_t length;
    if (!raw.get("length", length))
        return nullptr;
    if (length < 0 || length > 0xFFFF)
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoAesKeyGenParams(length));
}

bool parseHash(const Dictionary& raw, WebKit::WebCryptoAlgorithm& hash)
{
    Dictionary rawHash;
    if (!raw.get("hash", rawHash))
        return false;

    TrackExceptionState es;
    return normalizeAlgorithm(rawHash, Digest, hash, es);
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseHmacParams(const Dictionary& raw)
{
    WebKit::WebCryptoAlgorithm hash;
    if (!parseHash(raw, hash))
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoHmacParams(hash));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseRsaSsaParams(const Dictionary& raw)
{
    WebKit::WebCryptoAlgorithm hash;
    if (!parseHash(raw, hash))
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoRsaSsaParams(hash));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseRsaKeyGenParams(const Dictionary& raw)
{
    // FIXME: This is losing precision; modulusLength is supposed to be a uint32
    int32_t modulusLength;
    if (!raw.get("modulusLength", modulusLength))
        return nullptr;
    if (modulusLength < 0)
        return nullptr;

    RefPtr<Uint8Array> publicExponent;
    if (!raw.get("publicExponent", publicExponent) || !publicExponent)
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoRsaKeyGenParams(modulusLength, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteLength()));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseAlgorithmParams(const Dictionary& raw, WebKit::WebCryptoAlgorithmParamsType type)
{
    switch (type) {
    case WebKit::WebCryptoAlgorithmParamsTypeNone:
        return nullptr;
    case WebKit::WebCryptoAlgorithmParamsTypeAesCbcParams:
        return parseAesCbcParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeAesKeyGenParams:
        return parseAesKeyGenParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeHmacParams:
        return parseHmacParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeRsaSsaParams:
        return parseRsaSsaParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeRsaKeyGenParams:
        return parseRsaKeyGenParams(raw);
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

const AlgorithmInfo* algorithmInfo(const Dictionary& raw, ExceptionState& es)
{
    String algorithmName;
    if (!raw.get("name", algorithmName)) {
        es.throwDOMException(NotSupportedError);
        return 0;
    }

    if (!algorithmName.containsOnlyASCII()) {
        es.throwDOMException(SyntaxError);
        return 0;
    }

    const AlgorithmInfo* info = AlgorithmRegistry::lookupAlgorithmByName(algorithmName);
    if (!info) {
        es.throwDOMException(NotSupportedError);
        return 0;
    }

    return info;
}

} // namespace

// FIXME: Throw the correct exception types!
// This implementation corresponds with:
// http://www.w3.org/TR/WebCryptoAPI/#algorithm-normalizing-rules
bool normalizeAlgorithm(const Dictionary& raw, AlgorithmOperation op, WebKit::WebCryptoAlgorithm& algorithm, ExceptionState& es)
{
    const AlgorithmInfo* info = algorithmInfo(raw, es);
    if (!info)
        return false;

    if (info->paramsForOperation[op] == UnsupportedOp) {
        es.throwDOMException(NotSupportedError);
        return false;
    }

    WebKit::WebCryptoAlgorithmParamsType paramsType = static_cast<WebKit::WebCryptoAlgorithmParamsType>(info->paramsForOperation[op]);
    OwnPtr<WebKit::WebCryptoAlgorithmParams> params = parseAlgorithmParams(raw, paramsType);

    if (!params && paramsType != WebKit::WebCryptoAlgorithmParamsTypeNone) {
        es.throwDOMException(NotSupportedError);
        return false;
    }

    algorithm = WebKit::WebCryptoAlgorithm(info->algorithmId, info->algorithmName, params.release());
    return true;
}

} // namespace WebCore
<commit_msg>Remove references to specific WebCrypto section number in code comments.<commit_after>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "modules/crypto/NormalizeAlgorithm.h"

#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "public/platform/WebCryptoAlgorithm.h"
#include "public/platform/WebCryptoAlgorithmParams.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferView.h"
#include "wtf/HashMap.h"
#include "wtf/Uint8Array.h"
#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"

namespace WebCore {

namespace {

struct AlgorithmNameMapping {
    const char* const algorithmName;
    WebKit::WebCryptoAlgorithmId algorithmId;
};

// Indicates that the algorithm doesn't support the specified operation.
const int UnsupportedOp = -1;

// Either UnsupportedOp, or a value from WebKit::WebCryptoAlgorithmParamsType
typedef int AlgorithmParamsForOperation;

struct OperationParamsMapping {
    WebKit::WebCryptoAlgorithmId algorithmId;
    AlgorithmOperation operation;
    AlgorithmParamsForOperation params;
};

const AlgorithmNameMapping algorithmNameMappings[] = {
    {"AES-CBC", WebKit::WebCryptoAlgorithmIdAesCbc},
    {"HMAC", WebKit::WebCryptoAlgorithmIdHmac},
    {"RSASSA-PKCS1-v1_5", WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5},
    {"SHA-1", WebKit::WebCryptoAlgorithmIdSha1},
    {"SHA-224", WebKit::WebCryptoAlgorithmIdSha224},
    {"SHA-256", WebKit::WebCryptoAlgorithmIdSha256},
    {"SHA-384", WebKit::WebCryptoAlgorithmIdSha384},
    {"SHA-512", WebKit::WebCryptoAlgorithmIdSha512},
};

// What operations each algorithm supports, and what parameters it expects.
const OperationParamsMapping operationParamsMappings[] = {
    // AES-CBC
    {WebKit::WebCryptoAlgorithmIdAesCbc, Decrypt, WebKit::WebCryptoAlgorithmParamsTypeAesCbcParams},
    {WebKit::WebCryptoAlgorithmIdAesCbc, Encrypt, WebKit::WebCryptoAlgorithmParamsTypeAesCbcParams},
    {WebKit::WebCryptoAlgorithmIdAesCbc, GenerateKey, WebKit::WebCryptoAlgorithmParamsTypeAesKeyGenParams},
    {WebKit::WebCryptoAlgorithmIdAesCbc, ImportKey, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // HMAC
    {WebKit::WebCryptoAlgorithmIdHmac, Sign, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},
    {WebKit::WebCryptoAlgorithmIdHmac, Verify, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},
    {WebKit::WebCryptoAlgorithmIdHmac, GenerateKey, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},
    {WebKit::WebCryptoAlgorithmIdHmac, ImportKey, WebKit::WebCryptoAlgorithmParamsTypeHmacParams},

    // RSASSA-PKCS1-v1_5
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Sign, WebKit::WebCryptoAlgorithmParamsTypeRsaSsaParams},
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Verify, WebKit::WebCryptoAlgorithmParamsTypeRsaSsaParams},
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, GenerateKey, WebKit::WebCryptoAlgorithmParamsTypeRsaKeyGenParams},
    {WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, ImportKey, WebKit::WebCryptoAlgorithmParamsTypeNone},

    // SHA-*
    {WebKit::WebCryptoAlgorithmIdSha1, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},
    {WebKit::WebCryptoAlgorithmIdSha224, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},
    {WebKit::WebCryptoAlgorithmIdSha256, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},
    {WebKit::WebCryptoAlgorithmIdSha384, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},
    {WebKit::WebCryptoAlgorithmIdSha512, Digest, WebKit::WebCryptoAlgorithmParamsTypeNone},
};

// This structure describes an algorithm and its supported operations.
struct AlgorithmInfo {
    AlgorithmInfo()
        : algorithmName(0)
    {
        for (size_t i = 0; i < WTF_ARRAY_LENGTH(paramsForOperation); ++i)
            paramsForOperation[i] = UnsupportedOp;
    }

    WebKit::WebCryptoAlgorithmId algorithmId;
    const char* algorithmName;
    AlgorithmParamsForOperation paramsForOperation[NumberOfAlgorithmOperations];
};

// AlgorithmRegistry enumerates each of the different algorithms and its
// parameters. This describes the same information as the static tables above,
// but in a more convenient runtime form.
class AlgorithmRegistry {
public:
    static const AlgorithmInfo* lookupAlgorithmByName(const String& algorithmName);

private:
    AlgorithmRegistry();

    // Algorithm name to ID.
    typedef HashMap<String, WebKit::WebCryptoAlgorithmId, CaseFoldingHash> AlgorithmNameToIdMap;
    AlgorithmNameToIdMap m_algorithmNameToId;

    // Algorithm ID to information.
    AlgorithmInfo m_algorithms[WebKit::NumberOfWebCryptoAlgorithmId];
};

const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmByName(const String& algorithmName)
{
    DEFINE_STATIC_LOCAL(AlgorithmRegistry, registry, ());

    AlgorithmNameToIdMap::const_iterator it = registry.m_algorithmNameToId.find(algorithmName);
    if (it == registry.m_algorithmNameToId.end())
        return 0;
    return &registry.m_algorithms[it->value];
}

AlgorithmRegistry::AlgorithmRegistry()
{
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(algorithmNameMappings); ++i) {
        const AlgorithmNameMapping& mapping = algorithmNameMappings[i];
        m_algorithmNameToId.add(mapping.algorithmName, mapping.algorithmId);
        m_algorithms[mapping.algorithmId].algorithmName = mapping.algorithmName;
        m_algorithms[mapping.algorithmId].algorithmId = mapping.algorithmId;
    }

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(operationParamsMappings); ++i) {
        const OperationParamsMapping& mapping = operationParamsMappings[i];
        m_algorithms[mapping.algorithmId].paramsForOperation[mapping.operation] = mapping.params;
    }
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseAesCbcParams(const Dictionary& raw)
{
    RefPtr<ArrayBufferView> iv;
    if (!raw.get("iv", iv) || !iv)
        return nullptr;

    if (iv->byteLength() != 16)
        return nullptr;

    return adoptPtr(new WebKit::WebCryptoAesCbcParams(static_cast<unsigned char*>(iv->baseAddress()), iv->byteLength()));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseAesKeyGenParams(const Dictionary& raw)
{
    int32_t length;
    if (!raw.get("length", length))
        return nullptr;
    if (length < 0 || length > 0xFFFF)
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoAesKeyGenParams(length));
}

bool parseHash(const Dictionary& raw, WebKit::WebCryptoAlgorithm& hash)
{
    Dictionary rawHash;
    if (!raw.get("hash", rawHash))
        return false;

    TrackExceptionState es;
    return normalizeAlgorithm(rawHash, Digest, hash, es);
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseHmacParams(const Dictionary& raw)
{
    WebKit::WebCryptoAlgorithm hash;
    if (!parseHash(raw, hash))
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoHmacParams(hash));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseRsaSsaParams(const Dictionary& raw)
{
    WebKit::WebCryptoAlgorithm hash;
    if (!parseHash(raw, hash))
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoRsaSsaParams(hash));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseRsaKeyGenParams(const Dictionary& raw)
{
    // FIXME: This is losing precision; modulusLength is supposed to be a uint32
    int32_t modulusLength;
    if (!raw.get("modulusLength", modulusLength))
        return nullptr;
    if (modulusLength < 0)
        return nullptr;

    RefPtr<Uint8Array> publicExponent;
    if (!raw.get("publicExponent", publicExponent) || !publicExponent)
        return nullptr;
    return adoptPtr(new WebKit::WebCryptoRsaKeyGenParams(modulusLength, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteLength()));
}

PassOwnPtr<WebKit::WebCryptoAlgorithmParams> parseAlgorithmParams(const Dictionary& raw, WebKit::WebCryptoAlgorithmParamsType type)
{
    switch (type) {
    case WebKit::WebCryptoAlgorithmParamsTypeNone:
        return nullptr;
    case WebKit::WebCryptoAlgorithmParamsTypeAesCbcParams:
        return parseAesCbcParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeAesKeyGenParams:
        return parseAesKeyGenParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeHmacParams:
        return parseHmacParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeRsaSsaParams:
        return parseRsaSsaParams(raw);
    case WebKit::WebCryptoAlgorithmParamsTypeRsaKeyGenParams:
        return parseRsaKeyGenParams(raw);
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

const AlgorithmInfo* algorithmInfo(const Dictionary& raw, ExceptionState& es)
{
    String algorithmName;
    if (!raw.get("name", algorithmName)) {
        es.throwDOMException(NotSupportedError);
        return 0;
    }

    if (!algorithmName.containsOnlyASCII()) {
        es.throwDOMException(SyntaxError);
        return 0;
    }

    const AlgorithmInfo* info = AlgorithmRegistry::lookupAlgorithmByName(algorithmName);
    if (!info) {
        es.throwDOMException(NotSupportedError);
        return 0;
    }

    return info;
}

} // namespace

// FIXME: Throw the correct exception types!
// This implementation corresponds with:
// http://www.w3.org/TR/WebCryptoAPI/#algorithm-normalizing-rules
bool normalizeAlgorithm(const Dictionary& raw, AlgorithmOperation op, WebKit::WebCryptoAlgorithm& algorithm, ExceptionState& es)
{
    const AlgorithmInfo* info = algorithmInfo(raw, es);
    if (!info)
        return false;

    if (info->paramsForOperation[op] == UnsupportedOp) {
        es.throwDOMException(NotSupportedError);
        return false;
    }

    WebKit::WebCryptoAlgorithmParamsType paramsType = static_cast<WebKit::WebCryptoAlgorithmParamsType>(info->paramsForOperation[op]);
    OwnPtr<WebKit::WebCryptoAlgorithmParams> params = parseAlgorithmParams(raw, paramsType);

    if (!params && paramsType != WebKit::WebCryptoAlgorithmParamsTypeNone) {
        es.throwDOMException(NotSupportedError);
        return false;
    }

    algorithm = WebKit::WebCryptoAlgorithm(info->algorithmId, info->algorithmName, params.release());
    return true;
}

} // namespace WebCore
<|endoftext|>


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

#include "SurgSim/Framework/FrameworkConvert.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Framework/SceneElement.h"
#include "SurgSim/Framework/PoseComponent.h"
#include "SurgSim/Math/MathConvert.h"
#include "SurgSim/Math/OdeSolverEulerExplicit.h"
#include "SurgSim/Math/OdeSolverEulerExplicitModified.h"
#include "SurgSim/Math/OdeSolverEulerImplicit.h"
#include "SurgSim/Math/OdeSolverRungeKutta4.h"
#include "SurgSim/Math/OdeSolverLinearEulerExplicit.h"
#include "SurgSim/Math/OdeSolverLinearEulerExplicitModified.h"
#include "SurgSim/Math/OdeSolverLinearEulerImplicit.h"
#include "SurgSim/Math/OdeSolverLinearRungeKutta4.h"
#include "SurgSim/Math/OdeSolverLinearStatic.h"
#include "SurgSim/Math/OdeSolverStatic.h"
#include "SurgSim/Math/OdeState.h"
#include "SurgSim/Physics/DeformableRepresentation.h"
#include "SurgSim/Physics/DeformableCollisionRepresentation.h"

namespace SurgSim
{

namespace Physics
{

DeformableRepresentation::DeformableRepresentation(const std::string& name) :
	Representation(name),
	SurgSim::Math::OdeEquation(),
	m_numDofPerNode(0),
	m_integrationScheme(SurgSim::Math::INTEGRATIONSCHEME_EXPLICIT_EULER)
{
	SURGSIM_ADD_SERIALIZABLE_PROPERTY(DeformableRepresentation, SurgSim::Math::IntegrationScheme, IntegrationScheme,
									  getIntegrationScheme, setIntegrationScheme);
	SURGSIM_ADD_SERIALIZABLE_PROPERTY(DeformableRepresentation, std::shared_ptr<SurgSim::Collision::Representation>,
									  CollisionRepresentation, getCollisionRepresentation, setCollisionRepresentation);
}

DeformableRepresentation::~DeformableRepresentation()
{
}
void DeformableRepresentation::resetState()
{
	Representation::resetState();

	// Reminder: m_initialState is being held in OdeEquation
	*m_currentState  = *m_initialState;
	*m_previousState = *m_initialState;
	// m_newState does not need to be reset, it is a temporary variable
	*m_finalState    = *m_initialState;
}

void DeformableRepresentation::setInitialState(
	std::shared_ptr<SurgSim::Math::OdeState> initialState)
{
	// This initializes and allocates the m_initialState data member
	m_initialState = initialState;

	m_previousState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);
	m_currentState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);
	m_newState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);
	m_finalState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);

	// Set the representation number of degree of freedom
	setNumDof(m_initialState->getNumDof());

	SurgSim::Math::resizeVector(&m_externalGeneralizedForce, getNumDof(), true);
	SurgSim::Math::resizeMatrix(&m_externalGeneralizedStiffness, getNumDof(), getNumDof(), true);
	SurgSim::Math::resizeMatrix(&m_externalGeneralizedDamping, getNumDof(), getNumDof(), true);
}

const std::shared_ptr<SurgSim::Math::OdeState> DeformableRepresentation::getCurrentState() const
{
	return m_currentState;
}

const std::shared_ptr<SurgSim::Math::OdeState> DeformableRepresentation::getPreviousState() const
{
	return m_previousState;
}

const std::shared_ptr<SurgSim::Math::OdeState> DeformableRepresentation::getFinalState() const
{
	return m_finalState;
}

size_t DeformableRepresentation::getNumDofPerNode() const
{
	return m_numDofPerNode;
}

void DeformableRepresentation::setIntegrationScheme(SurgSim::Math::IntegrationScheme integrationScheme)
{
	SURGSIM_ASSERT(!isAwake()) << "You cannot set the integration scheme after the component has been awoken";
	m_integrationScheme = integrationScheme;
}

SurgSim::Math::IntegrationScheme DeformableRepresentation::getIntegrationScheme() const
{
	return m_integrationScheme;
}

const SurgSim::Math::Vector& DeformableRepresentation::getExternalGeneralizedForce() const
{
	return m_externalGeneralizedForce;
}

const SurgSim::Math::Matrix& DeformableRepresentation::getExternalGeneralizedStiffness() const
{
	return m_externalGeneralizedStiffness;
}

const SurgSim::Math::Matrix& DeformableRepresentation::getExternalGeneralizedDamping() const
{
	return m_externalGeneralizedDamping;
}

const SurgSim::Math::Matrix& DeformableRepresentation::getComplianceMatrix() const
{
	SURGSIM_ASSERT(m_odeSolver) << "Ode solver not initialized, it should have been initialized on wake-up";

	return m_odeSolver->getCompliance();
}

void DeformableRepresentation::update(double dt)
{
	if (! isActive())
	{
		return;
	}

	SURGSIM_ASSERT(m_odeSolver != nullptr) <<
										   "Ode solver has not been set yet. Did you call beforeUpdate() ?";
	SURGSIM_ASSERT(m_initialState != nullptr) <<
			"Initial state has not been set yet. Did you call setInitialState() ?";

	// Solve the ode
	m_odeSolver->solve(dt, *m_currentState, m_newState.get());

	// Back up the current state into the previous state (by swapping)
	m_currentState.swap(m_previousState);
	// Make the new state, the current state (by swapping)
	m_currentState.swap(m_newState);

	if (!m_currentState->isValid())
	{
		SURGSIM_LOG(SurgSim::Framework::Logger::getDefaultLogger(), DEBUG)
				<< getName() << " deactivated :" << std::endl
				<< "position=(" << m_currentState->getPositions().transpose() << ")" << std::endl
				<< "velocity=(" << m_currentState->getVelocities().transpose() << ")" << std::endl;

		setActive(false);
	}
}

void DeformableRepresentation::afterUpdate(double dt)
{
	if (! isActive())
	{
		return;
	}

	driveSceneElementPose(SurgSim::Math::RigidTransform3d::Identity());

	// Back up the current state into the final state
	*m_finalState = *m_currentState;

	// Reset the external generalized force, stiffness and damping
	m_externalGeneralizedForce.setZero();
	m_externalGeneralizedStiffness.setZero();
	m_externalGeneralizedDamping.setZero();
}

void DeformableRepresentation::applyCorrection(double dt,
		const Eigen::VectorBlock<SurgSim::Math::Vector>& deltaVelocity)
{
	if (!isActive())
	{
		return;
	}

	m_currentState->getPositions() += deltaVelocity * dt;
	m_currentState->getVelocities() += deltaVelocity;

	if (!m_currentState->isValid())
	{
		SURGSIM_LOG(SurgSim::Framework::Logger::getDefaultLogger(), DEBUG)
				<< getName() << " deactivated :" << std::endl
				<< "position=(" << m_currentState->getPositions() << ")" << std::endl
				<< "velocity=(" << m_currentState->getVelocities() << ")" << std::endl;

		setActive(false);
	}
}

void DeformableRepresentation::deactivateAndReset(void)
{
	SURGSIM_LOG(SurgSim::Framework::Logger::getDefaultLogger(), DEBUG)
			<< getName() << " deactivated and reset:" << std::endl
			<< "position=(" << m_currentState->getPositions() << ")" << std::endl
			<< "velocity=(" << m_currentState->getVelocities() << ")" << std::endl;

	resetState();
	setActive(false);
}

void DeformableRepresentation::setCollisionRepresentation(
	std::shared_ptr<SurgSim::Collision::Representation> representation)
{
	if (m_collisionRepresentation != representation)
	{
		// If we have an old collision representation clear the dependency if it was a deformable collision
		// representation
		auto oldCollisionRep =
			std::dynamic_pointer_cast<DeformableCollisionRepresentation>(m_collisionRepresentation);
		if (oldCollisionRep != nullptr)
		{
			oldCollisionRep->setDeformableRepresentation(nullptr);
		}

		Representation::setCollisionRepresentation(representation);

		// If its a RigidCollisionRepresentation connect with this representation
		auto newCollisionRep = std::dynamic_pointer_cast<DeformableCollisionRepresentation>(representation);
		if (newCollisionRep != nullptr)
		{
			newCollisionRep->setDeformableRepresentation(
				std::static_pointer_cast<DeformableRepresentation>(getSharedPtr()));
		}
	}
}

bool DeformableRepresentation::doWakeUp()
{
	using SurgSim::Math::OdeSolverEulerExplicit;
	using SurgSim::Math::OdeSolverEulerExplicitModified;
	using SurgSim::Math::OdeSolverEulerImplicit;
	using SurgSim::Math::OdeSolverRungeKutta4;
	using SurgSim::Math::OdeSolverStatic;
	using SurgSim::Math::OdeSolverLinearEulerExplicit;
	using SurgSim::Math::OdeSolverLinearEulerExplicitModified;
	using SurgSim::Math::OdeSolverLinearEulerImplicit;
	using SurgSim::Math::OdeSolverLinearRungeKutta4;
	using SurgSim::Math::OdeSolverLinearStatic;

	using SurgSim::Math::LinearSolveAndInverseDenseMatrix;

	// Transform the state with the initial pose
	transformState(m_initialState, getPose());
	*m_previousState = *m_initialState;
	*m_currentState = *m_initialState;
	*m_newState = *m_initialState;
	*m_finalState = *m_initialState;

	// Since the pose is now embedded in the state, reset element and local pose to identity.
	setLocalPose(SurgSim::Math::RigidTransform3d::Identity());
	std::shared_ptr<SurgSim::Framework::SceneElement> sceneElement = getSceneElement();
	if (sceneElement != nullptr)
	{
		sceneElement->setPose(SurgSim::Math::RigidTransform3d::Identity());
	}

	// Set the ode solver using the chosen integration scheme
	switch (m_integrationScheme)
	{
		case SurgSim::Math::INTEGRATIONSCHEME_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverEulerExplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_MODIFIED_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverEulerExplicitModified>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_IMPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverEulerImplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_STATIC:
			m_odeSolver = std::make_shared<OdeSolverStatic>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_RUNGE_KUTTA_4:
			m_odeSolver = std::make_shared<OdeSolverRungeKutta4>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverLinearEulerExplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_MODIFIED_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverLinearEulerExplicitModified>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_IMPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverLinearEulerImplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_STATIC:
			m_odeSolver = std::make_shared<OdeSolverLinearStatic>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_RUNGE_KUTTA_4:
			m_odeSolver = std::make_shared<OdeSolverLinearRungeKutta4>(this);
			break;
		default:
			SURGSIM_LOG_WARNING(SurgSim::Framework::Logger::getDefaultLogger())
					<< "Ode solver (integration scheme) not initialized, the integration scheme is invalid";
			return false;
	}

	// No assumption is made on the linear solver, we instantiate a general dense matrix solver
	m_odeSolver->setLinearSolver(std::make_shared<LinearSolveAndInverseDenseMatrix>());

	return true;
}

}; // namespace Physics

}; // namespace SurgSim
<commit_msg>Remove remaining uses of resizeVector and resizeMatrix<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2012-2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Framework/FrameworkConvert.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Framework/SceneElement.h"
#include "SurgSim/Framework/PoseComponent.h"
#include "SurgSim/Math/MathConvert.h"
#include "SurgSim/Math/OdeSolverEulerExplicit.h"
#include "SurgSim/Math/OdeSolverEulerExplicitModified.h"
#include "SurgSim/Math/OdeSolverEulerImplicit.h"
#include "SurgSim/Math/OdeSolverRungeKutta4.h"
#include "SurgSim/Math/OdeSolverLinearEulerExplicit.h"
#include "SurgSim/Math/OdeSolverLinearEulerExplicitModified.h"
#include "SurgSim/Math/OdeSolverLinearEulerImplicit.h"
#include "SurgSim/Math/OdeSolverLinearRungeKutta4.h"
#include "SurgSim/Math/OdeSolverLinearStatic.h"
#include "SurgSim/Math/OdeSolverStatic.h"
#include "SurgSim/Math/OdeState.h"
#include "SurgSim/Physics/DeformableRepresentation.h"
#include "SurgSim/Physics/DeformableCollisionRepresentation.h"

namespace SurgSim
{

namespace Physics
{

DeformableRepresentation::DeformableRepresentation(const std::string& name) :
	Representation(name),
	SurgSim::Math::OdeEquation(),
	m_numDofPerNode(0),
	m_integrationScheme(SurgSim::Math::INTEGRATIONSCHEME_EXPLICIT_EULER)
{
	SURGSIM_ADD_SERIALIZABLE_PROPERTY(DeformableRepresentation, SurgSim::Math::IntegrationScheme, IntegrationScheme,
									  getIntegrationScheme, setIntegrationScheme);
	SURGSIM_ADD_SERIALIZABLE_PROPERTY(DeformableRepresentation, std::shared_ptr<SurgSim::Collision::Representation>,
									  CollisionRepresentation, getCollisionRepresentation, setCollisionRepresentation);
}

DeformableRepresentation::~DeformableRepresentation()
{
}
void DeformableRepresentation::resetState()
{
	Representation::resetState();

	// Reminder: m_initialState is being held in OdeEquation
	*m_currentState  = *m_initialState;
	*m_previousState = *m_initialState;
	// m_newState does not need to be reset, it is a temporary variable
	*m_finalState    = *m_initialState;
}

void DeformableRepresentation::setInitialState(
	std::shared_ptr<SurgSim::Math::OdeState> initialState)
{
	// This initializes and allocates the m_initialState data member
	m_initialState = initialState;

	m_previousState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);
	m_currentState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);
	m_newState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);
	m_finalState = std::make_shared<SurgSim::Math::OdeState>(*m_initialState);

	// Set the representation number of degree of freedom
	setNumDof(m_initialState->getNumDof());

	m_externalGeneralizedForce.resize(getNumDof());
	m_externalGeneralizedStiffness.resize(getNumDof(), getNumDof());
	m_externalGeneralizedDamping.resize(getNumDof(), getNumDof());
	m_externalGeneralizedForce.setZero();
	m_externalGeneralizedStiffness.setZero();
	m_externalGeneralizedDamping.setZero();
}

const std::shared_ptr<SurgSim::Math::OdeState> DeformableRepresentation::getCurrentState() const
{
	return m_currentState;
}

const std::shared_ptr<SurgSim::Math::OdeState> DeformableRepresentation::getPreviousState() const
{
	return m_previousState;
}

const std::shared_ptr<SurgSim::Math::OdeState> DeformableRepresentation::getFinalState() const
{
	return m_finalState;
}

size_t DeformableRepresentation::getNumDofPerNode() const
{
	return m_numDofPerNode;
}

void DeformableRepresentation::setIntegrationScheme(SurgSim::Math::IntegrationScheme integrationScheme)
{
	SURGSIM_ASSERT(!isAwake()) << "You cannot set the integration scheme after the component has been awoken";
	m_integrationScheme = integrationScheme;
}

SurgSim::Math::IntegrationScheme DeformableRepresentation::getIntegrationScheme() const
{
	return m_integrationScheme;
}

const SurgSim::Math::Vector& DeformableRepresentation::getExternalGeneralizedForce() const
{
	return m_externalGeneralizedForce;
}

const SurgSim::Math::Matrix& DeformableRepresentation::getExternalGeneralizedStiffness() const
{
	return m_externalGeneralizedStiffness;
}

const SurgSim::Math::Matrix& DeformableRepresentation::getExternalGeneralizedDamping() const
{
	return m_externalGeneralizedDamping;
}

const SurgSim::Math::Matrix& DeformableRepresentation::getComplianceMatrix() const
{
	SURGSIM_ASSERT(m_odeSolver) << "Ode solver not initialized, it should have been initialized on wake-up";

	return m_odeSolver->getCompliance();
}

void DeformableRepresentation::update(double dt)
{
	if (! isActive())
	{
		return;
	}

	SURGSIM_ASSERT(m_odeSolver != nullptr) <<
										   "Ode solver has not been set yet. Did you call beforeUpdate() ?";
	SURGSIM_ASSERT(m_initialState != nullptr) <<
			"Initial state has not been set yet. Did you call setInitialState() ?";

	// Solve the ode
	m_odeSolver->solve(dt, *m_currentState, m_newState.get());

	// Back up the current state into the previous state (by swapping)
	m_currentState.swap(m_previousState);
	// Make the new state, the current state (by swapping)
	m_currentState.swap(m_newState);

	if (!m_currentState->isValid())
	{
		SURGSIM_LOG(SurgSim::Framework::Logger::getDefaultLogger(), DEBUG)
				<< getName() << " deactivated :" << std::endl
				<< "position=(" << m_currentState->getPositions().transpose() << ")" << std::endl
				<< "velocity=(" << m_currentState->getVelocities().transpose() << ")" << std::endl;

		setActive(false);
	}
}

void DeformableRepresentation::afterUpdate(double dt)
{
	if (! isActive())
	{
		return;
	}

	driveSceneElementPose(SurgSim::Math::RigidTransform3d::Identity());

	// Back up the current state into the final state
	*m_finalState = *m_currentState;

	// Reset the external generalized force, stiffness and damping
	m_externalGeneralizedForce.setZero();
	m_externalGeneralizedStiffness.setZero();
	m_externalGeneralizedDamping.setZero();
}

void DeformableRepresentation::applyCorrection(double dt,
		const Eigen::VectorBlock<SurgSim::Math::Vector>& deltaVelocity)
{
	if (!isActive())
	{
		return;
	}

	m_currentState->getPositions() += deltaVelocity * dt;
	m_currentState->getVelocities() += deltaVelocity;

	if (!m_currentState->isValid())
	{
		SURGSIM_LOG(SurgSim::Framework::Logger::getDefaultLogger(), DEBUG)
				<< getName() << " deactivated :" << std::endl
				<< "position=(" << m_currentState->getPositions() << ")" << std::endl
				<< "velocity=(" << m_currentState->getVelocities() << ")" << std::endl;

		setActive(false);
	}
}

void DeformableRepresentation::deactivateAndReset(void)
{
	SURGSIM_LOG(SurgSim::Framework::Logger::getDefaultLogger(), DEBUG)
			<< getName() << " deactivated and reset:" << std::endl
			<< "position=(" << m_currentState->getPositions() << ")" << std::endl
			<< "velocity=(" << m_currentState->getVelocities() << ")" << std::endl;

	resetState();
	setActive(false);
}

void DeformableRepresentation::setCollisionRepresentation(
	std::shared_ptr<SurgSim::Collision::Representation> representation)
{
	if (m_collisionRepresentation != representation)
	{
		// If we have an old collision representation clear the dependency if it was a deformable collision
		// representation
		auto oldCollisionRep =
			std::dynamic_pointer_cast<DeformableCollisionRepresentation>(m_collisionRepresentation);
		if (oldCollisionRep != nullptr)
		{
			oldCollisionRep->setDeformableRepresentation(nullptr);
		}

		Representation::setCollisionRepresentation(representation);

		// If its a RigidCollisionRepresentation connect with this representation
		auto newCollisionRep = std::dynamic_pointer_cast<DeformableCollisionRepresentation>(representation);
		if (newCollisionRep != nullptr)
		{
			newCollisionRep->setDeformableRepresentation(
				std::static_pointer_cast<DeformableRepresentation>(getSharedPtr()));
		}
	}
}

bool DeformableRepresentation::doWakeUp()
{
	using SurgSim::Math::OdeSolverEulerExplicit;
	using SurgSim::Math::OdeSolverEulerExplicitModified;
	using SurgSim::Math::OdeSolverEulerImplicit;
	using SurgSim::Math::OdeSolverRungeKutta4;
	using SurgSim::Math::OdeSolverStatic;
	using SurgSim::Math::OdeSolverLinearEulerExplicit;
	using SurgSim::Math::OdeSolverLinearEulerExplicitModified;
	using SurgSim::Math::OdeSolverLinearEulerImplicit;
	using SurgSim::Math::OdeSolverLinearRungeKutta4;
	using SurgSim::Math::OdeSolverLinearStatic;

	using SurgSim::Math::LinearSolveAndInverseDenseMatrix;

	// Transform the state with the initial pose
	transformState(m_initialState, getPose());
	*m_previousState = *m_initialState;
	*m_currentState = *m_initialState;
	*m_newState = *m_initialState;
	*m_finalState = *m_initialState;

	// Since the pose is now embedded in the state, reset element and local pose to identity.
	setLocalPose(SurgSim::Math::RigidTransform3d::Identity());
	std::shared_ptr<SurgSim::Framework::SceneElement> sceneElement = getSceneElement();
	if (sceneElement != nullptr)
	{
		sceneElement->setPose(SurgSim::Math::RigidTransform3d::Identity());
	}

	// Set the ode solver using the chosen integration scheme
	switch (m_integrationScheme)
	{
		case SurgSim::Math::INTEGRATIONSCHEME_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverEulerExplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_MODIFIED_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverEulerExplicitModified>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_IMPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverEulerImplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_STATIC:
			m_odeSolver = std::make_shared<OdeSolverStatic>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_RUNGE_KUTTA_4:
			m_odeSolver = std::make_shared<OdeSolverRungeKutta4>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverLinearEulerExplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_MODIFIED_EXPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverLinearEulerExplicitModified>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_IMPLICIT_EULER:
			m_odeSolver = std::make_shared<OdeSolverLinearEulerImplicit>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_STATIC:
			m_odeSolver = std::make_shared<OdeSolverLinearStatic>(this);
			break;
		case SurgSim::Math::INTEGRATIONSCHEME_LINEAR_RUNGE_KUTTA_4:
			m_odeSolver = std::make_shared<OdeSolverLinearRungeKutta4>(this);
			break;
		default:
			SURGSIM_LOG_WARNING(SurgSim::Framework::Logger::getDefaultLogger())
					<< "Ode solver (integration scheme) not initialized, the integration scheme is invalid";
			return false;
	}

	// No assumption is made on the linear solver, we instantiate a general dense matrix solver
	m_odeSolver->setLinearSolver(std::make_shared<LinearSolveAndInverseDenseMatrix>());

	return true;
}

}; // namespace Physics

}; // namespace SurgSim
<|endoftext|>