<commit_before>/**\file euclidean_transformation_validator.cpp
 * \brief Description...
 *
 * @version 1.0
 * @author Carlos Miguel Correia da Costa
 */

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <includes>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#include <dynamic_robot_localization/transformation_validators/euclidean_transformation_validator.h>
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </includes>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

namespace dynamic_robot_localization {

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <imports>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </imports>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// =============================================================================  <public-section>  ============================================================================
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <constructors-destructor>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
EuclideanTransformationValidator::EuclideanTransformationValidator() :
		max_transformation_angle_(1.59),
		max_transformation_distance_(0.1),
		max_new_pose_diff_angle_(1.59),
		max_new_pose_diff_distance_(0.2),
		max_root_mean_square_error_(0.05),
		max_root_mean_square_error_reference_pointcloud_(-1.0),
		max_outliers_percentage_(0.6),
		max_outliers_percentage_reference_pointcloud_(-1.0),
		min_inliers_angular_distribution_(0.125),
		max_outliers_angular_distribution_(0.875) {}

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </constructors-destructor>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <EuclideanTransformationValidator-functions>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
void EuclideanTransformationValidator::setupConfigurationFromParameterServer(ros::NodeHandlePtr& node_handle, ros::NodeHandlePtr& private_node_handle, std::string configuration_namespace) {
	private_node_handle->param(configuration_namespace + "max_transformation_angle", max_transformation_angle_, 0.7);
	private_node_handle->param(configuration_namespace + "max_transformation_distance", max_transformation_distance_, 0.1);
	private_node_handle->param(configuration_namespace + "max_new_pose_diff_angle", max_new_pose_diff_angle_, 1.59);
	private_node_handle->param(configuration_namespace + "max_new_pose_diff_distance", max_new_pose_diff_distance_, 0.2);
	private_node_handle->param(configuration_namespace + "max_root_mean_square_error", max_root_mean_square_error_, 0.05);
	private_node_handle->param(configuration_namespace + "max_root_mean_square_error_reference_pointcloud", max_root_mean_square_error_reference_pointcloud_, -1.0);
	private_node_handle->param(configuration_namespace + "min_overriding_root_mean_square_error", min_overriding_root_mean_square_error_, 0.01);
	private_node_handle->param(configuration_namespace + "max_outliers_percentage", max_outliers_percentage_, 0.6);
	private_node_handle->param(configuration_namespace + "max_outliers_percentage_reference_pointcloud", max_outliers_percentage_reference_pointcloud_, -1.0);
	private_node_handle->param(configuration_namespace + "min_overriding_outliers_percentage", min_overriding_outliers_percentage_, 0.1);
	private_node_handle->param(configuration_namespace + "min_overriding_outliers_percentage_reference_pointcloud", min_overriding_outliers_percentage_reference_pointcloud_, 0.1);
	private_node_handle->param(configuration_namespace + "min_inliers_angular_distribution", min_inliers_angular_distribution_, 0.125);
	private_node_handle->param(configuration_namespace + "max_outliers_angular_distribution", max_outliers_angular_distribution_, 0.875);
}

bool EuclideanTransformationValidator::validateNewLocalizationPose(const tf2::Transform& last_accepted_pose, const tf2::Transform& initial_guess, tf2::Transform& new_pose,
		double root_mean_square_error, double root_mean_square_error_reference_pointcloud, double outliers_percentage, double outliers_percentage_reference_pointcloud, double inliers_angular_distribution, double outliers_angular_distribution) {
	double transform_distance = (new_pose.getOrigin() - initial_guess.getOrigin()).length();
	double transform_angle = std::abs(new_pose.getRotation().normalize().angleShortestPath(initial_guess.getRotation().normalize()));

	double new_pose_distance = (new_pose.getOrigin() - last_accepted_pose.getOrigin()).length();
	double new_pose_angle = std::abs(new_pose.getRotation().normalize().angleShortestPath(last_accepted_pose.getRotation().normalize()));

	std::stringstream validation_info;
	validation_info << "\n\t correction translation: " 								<< transform_distance << " | (max_transformation_distance: " << max_transformation_distance_ << ")"  \
					<< "\n\t correction rotation: " 													<< transform_angle << " | (max_transformation_angle_: " << max_transformation_angle_ << ")"  \
					<< "\n\t new pose diff translation: " 										<< new_pose_distance << " | (max_new_pose_diff_distance_: " << max_new_pose_diff_distance_ << ")"  \
					<< "\n\t new pose diff rotation: " 												<< new_pose_angle << " | (max_new_pose_diff_angle_: " << max_new_pose_diff_angle_ << ")"  \
					<< "\n\t root_mean_square_error: " 												<< root_mean_square_error << " | (max_root_mean_square_error_: " << max_root_mean_square_error_ << ")"  \
					<< "\n\t root_mean_square_error_reference_pointcloud: " 	<< root_mean_square_error_reference_pointcloud << " | (max_root_mean_square_error_reference_pointcloud_: " << max_root_mean_square_error_reference_pointcloud_ << ")"  \
					<< "\n\t outliers_percentage: "														<< outliers_percentage << " | (max_outliers_percentage_: " << max_outliers_percentage_ << ")"  \
					<< "\n\t outliers_percentage_reference_pointcloud: "			<< outliers_percentage_reference_pointcloud << " | (max_outliers_percentage_reference_pointcloud_: " << max_outliers_percentage_reference_pointcloud_ << ")"  \
					<< "\n\t inliers_angular_distribution: "									<< inliers_angular_distribution << " | (min_inliers_angular_distribution_: " << min_inliers_angular_distribution_ << ")"  \
					<< "\n\t outliers_angular_distribution: "									<< outliers_angular_distribution << " | (max_outliers_angular_distribution_: " << max_outliers_angular_distribution_ << ")";

	if (root_mean_square_error < min_overriding_root_mean_square_error_ &&
			outliers_percentage < min_overriding_outliers_percentage_ &&
			outliers_percentage_reference_pointcloud < min_overriding_outliers_percentage_reference_pointcloud_) {
		ROS_DEBUG_STREAM("EuclideanTransformationValidator accepted new pose at time " << ros::Time::now() << " using overriding thresholds -> " << validation_info.str());
		return true;
	}

	if (max_root_mean_square_error_ > 0 && (root_mean_square_error > max_root_mean_square_error_)) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to root_mean_square_error -> " << validation_info.str());
		return false;
	}

	if (max_root_mean_square_error_reference_pointcloud_ > 0 && (root_mean_square_error_reference_pointcloud > max_root_mean_square_error_reference_pointcloud_)) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to root_mean_square_error_reference_pointcloud -> " << validation_info.str());
		return false;
	}

	if (max_outliers_percentage_ > 0 && outliers_percentage > max_outliers_percentage_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_outliers_percentage -> " << validation_info.str());
		return false;
	}

	if (max_outliers_percentage_reference_pointcloud_ > 0 && (outliers_percentage_reference_pointcloud > max_outliers_percentage_reference_pointcloud_)) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_outliers_percentage_reference_pointcloud -> " << validation_info.str());
		return false;
	}

	if (max_transformation_distance_ > 0 && transform_distance > max_transformation_distance_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_transformation_distance -> " << validation_info.str());
		return false;
	}

	if (max_transformation_angle_ > 0 && transform_angle > max_transformation_angle_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_transformation_angle -> " << validation_info.str());
		return false;
	}

	if (max_new_pose_diff_distance_ > 0 && new_pose_distance > max_new_pose_diff_distance_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_new_pose_diff_distance -> " << validation_info.str());
		return false;
	}

	if (max_new_pose_diff_angle_ > 0 && new_pose_angle < max_new_pose_diff_angle_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_new_pose_diff_angle -> " << validation_info.str());
		return false;
	}

	if (min_inliers_angular_distribution_ > 0 && inliers_angular_distribution < min_inliers_angular_distribution_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to min_inliers_angular_distribution -> " << validation_info.str());
		return false;
	}

	if (max_outliers_angular_distribution_ > 0 && outliers_angular_distribution > max_outliers_angular_distribution_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_outliers_angular_distribution -> " << validation_info.str());
		return false;
	}

	ROS_DEBUG_STREAM("EuclideanTransformationValidator accepted new pose at time " << ros::Time::now() << " -> " << validation_info.str());
	return true;
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </EuclideanTransformationValidator-functions>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// =============================================================================  </public-section>  ===========================================================================

// =============================================================================   <protected-section>   =======================================================================
// =============================================================================   </protected-section>  =======================================================================

// =============================================================================   <private-section>   =========================================================================
// =============================================================================   </private-section>  =========================================================================

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <template instantiations>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </template instantiations>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

} /* namespace dynamic_robot_localization */
<commit_msg>Fixed comparison signal in euclidean transformation validator for max_new_pose_diff_angle threshold.<commit_after>/**\file euclidean_transformation_validator.cpp
 * \brief Description...
 *
 * @version 1.0
 * @author Carlos Miguel Correia da Costa
 */

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <includes>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#include <dynamic_robot_localization/transformation_validators/euclidean_transformation_validator.h>
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </includes>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

namespace dynamic_robot_localization {

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <imports>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </imports>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// =============================================================================  <public-section>  ============================================================================
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <constructors-destructor>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
EuclideanTransformationValidator::EuclideanTransformationValidator() :
		max_transformation_angle_(1.59),
		max_transformation_distance_(0.1),
		max_new_pose_diff_angle_(1.59),
		max_new_pose_diff_distance_(0.2),
		max_root_mean_square_error_(0.05),
		max_root_mean_square_error_reference_pointcloud_(-1.0),
		max_outliers_percentage_(0.6),
		max_outliers_percentage_reference_pointcloud_(-1.0),
		min_inliers_angular_distribution_(0.125),
		max_outliers_angular_distribution_(0.875) {}

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </constructors-destructor>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <EuclideanTransformationValidator-functions>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
void EuclideanTransformationValidator::setupConfigurationFromParameterServer(ros::NodeHandlePtr& node_handle, ros::NodeHandlePtr& private_node_handle, std::string configuration_namespace) {
	private_node_handle->param(configuration_namespace + "max_transformation_angle", max_transformation_angle_, 0.7);
	private_node_handle->param(configuration_namespace + "max_transformation_distance", max_transformation_distance_, 0.1);
	private_node_handle->param(configuration_namespace + "max_new_pose_diff_angle", max_new_pose_diff_angle_, 1.59);
	private_node_handle->param(configuration_namespace + "max_new_pose_diff_distance", max_new_pose_diff_distance_, 0.2);
	private_node_handle->param(configuration_namespace + "max_root_mean_square_error", max_root_mean_square_error_, 0.05);
	private_node_handle->param(configuration_namespace + "max_root_mean_square_error_reference_pointcloud", max_root_mean_square_error_reference_pointcloud_, -1.0);
	private_node_handle->param(configuration_namespace + "min_overriding_root_mean_square_error", min_overriding_root_mean_square_error_, 0.01);
	private_node_handle->param(configuration_namespace + "max_outliers_percentage", max_outliers_percentage_, 0.6);
	private_node_handle->param(configuration_namespace + "max_outliers_percentage_reference_pointcloud", max_outliers_percentage_reference_pointcloud_, -1.0);
	private_node_handle->param(configuration_namespace + "min_overriding_outliers_percentage", min_overriding_outliers_percentage_, 0.1);
	private_node_handle->param(configuration_namespace + "min_overriding_outliers_percentage_reference_pointcloud", min_overriding_outliers_percentage_reference_pointcloud_, 0.1);
	private_node_handle->param(configuration_namespace + "min_inliers_angular_distribution", min_inliers_angular_distribution_, 0.125);
	private_node_handle->param(configuration_namespace + "max_outliers_angular_distribution", max_outliers_angular_distribution_, 0.875);
}

bool EuclideanTransformationValidator::validateNewLocalizationPose(const tf2::Transform& last_accepted_pose, const tf2::Transform& initial_guess, tf2::Transform& new_pose,
		double root_mean_square_error, double root_mean_square_error_reference_pointcloud, double outliers_percentage, double outliers_percentage_reference_pointcloud, double inliers_angular_distribution, double outliers_angular_distribution) {
	double transform_distance = (new_pose.getOrigin() - initial_guess.getOrigin()).length();
	double transform_angle = std::abs(new_pose.getRotation().normalize().angleShortestPath(initial_guess.getRotation().normalize()));

	double new_pose_distance = (new_pose.getOrigin() - last_accepted_pose.getOrigin()).length();
	double new_pose_angle = std::abs(new_pose.getRotation().normalize().angleShortestPath(last_accepted_pose.getRotation().normalize()));

	std::stringstream validation_info;
	validation_info << "\n\t correction translation: " 								<< transform_distance << " | (max_transformation_distance: " << max_transformation_distance_ << ")"  \
					<< "\n\t correction rotation: " 													<< transform_angle << " | (max_transformation_angle_: " << max_transformation_angle_ << ")"  \
					<< "\n\t new pose diff translation: " 										<< new_pose_distance << " | (max_new_pose_diff_distance_: " << max_new_pose_diff_distance_ << ")"  \
					<< "\n\t new pose diff rotation: " 												<< new_pose_angle << " | (max_new_pose_diff_angle_: " << max_new_pose_diff_angle_ << ")"  \
					<< "\n\t root_mean_square_error: " 												<< root_mean_square_error << " | (max_root_mean_square_error_: " << max_root_mean_square_error_ << ")"  \
					<< "\n\t root_mean_square_error_reference_pointcloud: " 	<< root_mean_square_error_reference_pointcloud << " | (max_root_mean_square_error_reference_pointcloud_: " << max_root_mean_square_error_reference_pointcloud_ << ")"  \
					<< "\n\t outliers_percentage: "														<< outliers_percentage << " | (max_outliers_percentage_: " << max_outliers_percentage_ << ")"  \
					<< "\n\t outliers_percentage_reference_pointcloud: "			<< outliers_percentage_reference_pointcloud << " | (max_outliers_percentage_reference_pointcloud_: " << max_outliers_percentage_reference_pointcloud_ << ")"  \
					<< "\n\t inliers_angular_distribution: "									<< inliers_angular_distribution << " | (min_inliers_angular_distribution_: " << min_inliers_angular_distribution_ << ")"  \
					<< "\n\t outliers_angular_distribution: "									<< outliers_angular_distribution << " | (max_outliers_angular_distribution_: " << max_outliers_angular_distribution_ << ")";

	if (root_mean_square_error < min_overriding_root_mean_square_error_ &&
			outliers_percentage < min_overriding_outliers_percentage_ &&
			outliers_percentage_reference_pointcloud < min_overriding_outliers_percentage_reference_pointcloud_) {
		ROS_DEBUG_STREAM("EuclideanTransformationValidator accepted new pose at time " << ros::Time::now() << " using overriding thresholds -> " << validation_info.str());
		return true;
	}

	if (max_root_mean_square_error_ > 0 && (root_mean_square_error > max_root_mean_square_error_)) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to root_mean_square_error -> " << validation_info.str());
		return false;
	}

	if (max_root_mean_square_error_reference_pointcloud_ > 0 && (root_mean_square_error_reference_pointcloud > max_root_mean_square_error_reference_pointcloud_)) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to root_mean_square_error_reference_pointcloud -> " << validation_info.str());
		return false;
	}

	if (max_outliers_percentage_ > 0 && outliers_percentage > max_outliers_percentage_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_outliers_percentage -> " << validation_info.str());
		return false;
	}

	if (max_outliers_percentage_reference_pointcloud_ > 0 && (outliers_percentage_reference_pointcloud > max_outliers_percentage_reference_pointcloud_)) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_outliers_percentage_reference_pointcloud -> " << validation_info.str());
		return false;
	}

	if (max_transformation_distance_ > 0 && transform_distance > max_transformation_distance_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_transformation_distance -> " << validation_info.str());
		return false;
	}

	if (max_transformation_angle_ > 0 && transform_angle > max_transformation_angle_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_transformation_angle -> " << validation_info.str());
		return false;
	}

	if (max_new_pose_diff_distance_ > 0 && new_pose_distance > max_new_pose_diff_distance_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_new_pose_diff_distance -> " << validation_info.str());
		return false;
	}

	if (max_new_pose_diff_angle_ > 0 && new_pose_angle > max_new_pose_diff_angle_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_new_pose_diff_angle -> " << validation_info.str());
		return false;
	}

	if (min_inliers_angular_distribution_ > 0 && inliers_angular_distribution < min_inliers_angular_distribution_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to min_inliers_angular_distribution -> " << validation_info.str());
		return false;
	}

	if (max_outliers_angular_distribution_ > 0 && outliers_angular_distribution > max_outliers_angular_distribution_) {
		ROS_WARN_STREAM("EuclideanTransformationValidator rejected new pose at time " << ros::Time::now() << " due to max_outliers_angular_distribution -> " << validation_info.str());
		return false;
	}

	ROS_DEBUG_STREAM("EuclideanTransformationValidator accepted new pose at time " << ros::Time::now() << " -> " << validation_info.str());
	return true;
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </EuclideanTransformationValidator-functions>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// =============================================================================  </public-section>  ===========================================================================

// =============================================================================   <protected-section>   =======================================================================
// =============================================================================   </protected-section>  =======================================================================

// =============================================================================   <private-section>   =========================================================================
// =============================================================================   </private-section>  =========================================================================

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <template instantiations>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   </template instantiations>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

} /* namespace dynamic_robot_localization */
<|endoftext|>


<commit_before>#include "postal.h"
#include "geocoder.h"

#include <iostream>
#include <iomanip>

using namespace GeoNLP;

int main(int argc, char *argv[])
{
  Postal postal;
  //postal.set_initialize_every_call(true);

  if (argc < 5)
    {
      std::cout << "Use: " << argv[0] << " dbase postal_global postal_country address\n"
		<< "where\n"
		<< " dbase - path to Geocoder-NLP database folder\n"
		<< " postal_global - path to libpostal database with language classifier\n"
		<< " postal_country - path to libpostal  database covering country\n"
		<< " address - address to be parsed (please enclose it in \" \" to ensure that its a singe argument)\n";
      return -1;
    }

  char *query = argv[4];
  std::vector< Postal::ParseResult > parsed_query;
  Postal::ParseResult nonorm;

  postal.set_postal_datadir(argv[2], argv[3]);
  postal.add_language("da");
  postal.add_language("et");
  postal.add_language("en");
  postal.set_initialize_every_call(true);

  postal.parse(query, parsed_query, nonorm);

  std::cout << "\nAddress parsing before full normalization:\n\n";
  for (auto v: nonorm)
    {
      std::cout << v.first << " ";
      for (auto k: v.second) std::cout << k << " ";
      std::cout << "\n";
    }
  std::cout << "\n";

  std::cout << "Normalization:\n\n";
  for (auto r: parsed_query)
    {
      for (auto v: r)
        {
          std::cout << v.first << " ";
          for (auto k: v.second) std::cout << k << " ";
          std::cout << "\n";
        }
      std::cout << "\n";
    }

  std::cout << std::endl;

  Geocoder geo(argv[1]);
  geo.set_max_queries_per_hierarchy(30);
  geo.set_max_results(25);
  //geo.set_result_language("en");

  std::vector<Geocoder::GeoResult> result;

  std::cout << "Geocoder loaded" << std::endl;

  geo.search(parsed_query, result);

  std::cout << std::setprecision(8);
  std::cout << "Search results: \n\n";
  size_t counter = 0;
  for (const Geocoder::GeoResult &r: result)
    {
      std::cout << r.title << "\n"
		<< r.address << "\n"
		<< r.latitude << ", " << r.longitude << "\n"
		<< r.type << " / " << r.id << " / " << r.admin_levels << " / " << r.levels_resolved << "\n\n";
      counter++;
    }

  std::cout << "Number of results: " << counter << std::endl;

  return 0;
}
<commit_msg>update demo<commit_after>#include "postal.h"
#include "geocoder.h"

#include <iostream>
#include <iomanip>

using namespace GeoNLP;

int main(int argc, char *argv[])
{
  Postal postal;
  //postal.set_initialize_every_call(true);

  if (argc < 5)
    {
      std::cout << "Use: " << argv[0] << " dbase postal_global postal_country address\n"
		<< "where\n"
		<< " dbase - path to Geocoder-NLP database folder\n"
		<< " postal_global - path to libpostal database with language classifier\n"
		<< " postal_country - path to libpostal  database covering country\n"
		<< " address - address to be parsed (please enclose it in \" \" to ensure that its a singe argument)\n";
      return -1;
    }

  char *query = argv[4];
  std::vector< Postal::ParseResult > parsed_query;
  Postal::ParseResult nonorm;

  postal.set_postal_datadir(argv[2], argv[3]);
  // postal.add_language("da");
  // postal.add_language("et");
  // postal.add_language("en");
  postal.set_initialize_every_call(true);

  postal.parse(query, parsed_query, nonorm);

  std::cout << "\nAddress parsing before full normalization:\n\n";
  for (auto v: nonorm)
    {
      std::cout << v.first << " ";
      for (auto k: v.second) std::cout << k << " ";
      std::cout << "\n";
    }
  std::cout << "\n";

  std::cout << "Normalization:\n\n";
  for (auto r: parsed_query)
    {
      for (auto v: r)
        {
          std::cout << v.first << " ";
          for (auto k: v.second) std::cout << k << " ";
          std::cout << "\n";
        }
      std::cout << "\n";
    }

  std::cout << std::endl;

  Geocoder geo(argv[1]);
  geo.set_max_queries_per_hierarchy(30);
  geo.set_max_results(25);
  //geo.set_result_language("en");

  std::vector<Geocoder::GeoResult> result;

  std::cout << "Geocoder loaded" << std::endl;

  geo.search(parsed_query, result);

  std::cout << std::setprecision(8);
  std::cout << "Search results: \n\n";
  size_t counter = 0;
  for (const Geocoder::GeoResult &r: result)
    {
      std::cout << r.title << "\n"
		<< r.address << "\n"
		<< r.latitude << ", " << r.longitude << "\n"
		<< r.type << " / " << r.id << " / " << r.admin_levels << " / " << r.levels_resolved << "\n\n";
      counter++;
    }

  std::cout << "Number of results: " << counter << std::endl;

  return 0;
}
<|endoftext|>


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

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include "testrunner.h"

TestRunner::~TestRunner()
{
        std::vector<std::string>::iterator it;

        for (it = tmp_files.begin(); it != tmp_files.end(); ++it) {
                unlink(it->c_str());
        }
}

void TestRunner::show_result(void) const
{
        std::cout << "-----------------------------------" << std::endl;
        std::cout << "Tests: " << files.size() << std::endl;
        std::cout << "-----------------------------------" << std::endl;
        std::cout << "Passed tests: " << pass << std::endl;
        std::cout << "Failed tests: " << fail << std::endl;
        if (valgrind) {
                std::cout << "Leaked tests: " << leak << std::endl;
        }
        std::cout << "-----------------------------------" << std::endl;
        std::cout << "Time taken: " << (((double)clock() - start_time) / CLOCKS_PER_SEC) << " seconds" << std::endl;
        std::cout << "-----------------------------------" << std::endl;
}

void TestRunner::find(char* dir)
{
        DIR *dp;
        std::fstream filep;
        std::string path;

        // Ignore .log files
        path = std::string(dir);
        if ((path.size()-4 == path.rfind(".log")) || (path.size()-4 == path.rfind(".mem"))) {
                return;
        }

        // If it's not a file, then it must be a directory
        filep.open(dir);
        if (filep.is_open()) {
                filep.close();
                files.push_back(std::string(dir));
        } else if ((dp = opendir(dir)) != NULL) {
                closedir(dp);
                path = std::string(dir);
                if (path[path.size()-1] != '/') {
                        path = path + "/";
                }
                load_folder(path.c_str());
        } else {
                std::cout << "Couldn't open the file or directory specified: " << std::string(dir) << std::endl;
                //exit(1);
                return;
        }
}

void TestRunner::run(void)
{
        FILE *fp;
        std::vector<std::string>::iterator it;
        std::string file_name, tmp_file;
        pcrecpp::RE regex("((?s:.(?!==CODE==))+)\\s*==CODE==\\s*((?s:.(?!==RESULT==))+)\\s*==RESULT==\\s*((?s:.+))\\s+");

        if (!files.size()) {
                std::cout << "No files found.";
                exit(1);
        }

        for (it = files.begin(); it != files.end(); ++it) {
                char result[300] = {0};
                std::string title, source, expect, log_line, command;
                unsigned int filesize;

                file_name = *it;

                tmp_file = file_name + ".tmp";

                regex.FullMatch(read_file(file_name.c_str()), &title, &source, &expect);

                write_file(tmp_file, source);

                if (valgrind) {
                        command = std::string("valgrind -q --tool=memcheck --leak-check=yes --num-callers=30 --log-file=") + file_name + std::string(".mem");
                        command = command + std::string(" ./clever -f ") + tmp_file;
                        fp = _popen(command.c_str(), "r");
                } else {
                        command = std::string("./clever -f ") + tmp_file;
                        fp = _popen(command.c_str(), "r");
                }
                fread(result, 1, sizeof(result)-1, fp);
                fclose(fp);

                // Valgrind log is empty?
                if (valgrind) {
                        filesize = file_size(file_name + std::string(".mem"));
                        if (filesize == 0) {
                                remove(std::string(file_name + std::string(".mem")).c_str());
                        } else {
                                std::cout << "[LEAK] ";
                                leak++;
                        }
                }

                if (pcrecpp::RE(expect).FullMatch(result)) {
                        if ((valgrind && filesize == 0) || !valgrind) {
                                std::cout << "[OKAY] ";
                        }
                        pass++;
                } else {
                        if ((valgrind && filesize == 0) || !valgrind) {
                                std::cout << "[FAIL] ";
                        }
                        log_line = std::string("== Expected ==\n") + expect + std::string("\n");
                        log_line.append(std::string("== Got ==\n") + std::string(result));
                        write_log(file_name,log_line);
                        fail++;
                }

                std::cout << title << " (" << file_name << ")" << std::endl;
        }
}

void TestRunner::write_file(std::string& name, std::string& source)
{
        std::ofstream file(name.c_str());

        file << source;
        file.close();

        tmp_files.push_back(name);
}

std::string TestRunner::read_file(const char* name) const
{
        std::string source, line;
        std::ifstream file;

        file.open(name);

        if (!file) {
                std::cout << "Couldn't open file " << name << std::endl;
                exit(1);
        }

        while (!file.eof()) {
                getline(file, line);
                source += line + '\n';
        }
        file.close();

        return source;
}

void TestRunner::load_folder(const char* dir)
{
        DIR *dp, *dpr;
        struct dirent *dirp;
        std::string path,file;

        if ((dp = opendir(dir)) != NULL) {
                while ((dirp = readdir(dp)) != NULL) {
                        if (strcmp(dirp->d_name, ".") == 0 ||
                                strcmp(dirp->d_name, "..") == 0 ||
                                strstr(dirp->d_name, ".tmp") ||
                                strstr(dirp->d_name, ".svn")) {
                                continue;
                        }
                        // Ignore .log files
                        file = std::string(dirp->d_name);
                        if ((file.size()-4 == file.rfind(".log")) || (file.size()-4 == file.rfind(".mem"))) {
                                continue;
                        }
                        // Is this a folder or a file?
                        path = std::string(dir) + std::string(dirp->d_name) + "/";
                        if ((dpr = opendir(path.c_str())) != NULL) {
                                closedir(dpr);
                                load_folder(path.c_str());
                        } else {
                                path = std::string(dir) + std::string(dirp->d_name);
                                files.push_back(path.c_str());
                        }
                }
                closedir(dp);
        }
}

std::string TestRunner::extract_folder(const char* file) const
{
        std::string path;
        size_t found;

        path = std::string(file);
        found = path.rfind("/");
        if (found != path.npos) {
                path = path.substr(0,found+1);
        }

        return path;
}

void TestRunner::write_log(std::string testname, std::string message) {
        FILE *log;

        testname = testname + ".log";
        log = fopen(testname.c_str(),"w");
        if (log) {
                fputs(message.c_str(),log);
                fclose(log);
        }
}

unsigned int TestRunner::file_size(std::string file) {
        std::ifstream stream;
        unsigned int length;

        stream.open(file.c_str());
        if (stream.is_open()) {
                stream.seekg(0,std::ios::end);
                length = stream.tellg();
                stream.close();

                return length;
        }

        return 0;
}

// ---------------------

void usage(void)
{
        std::cout << "Clever Language - Testrunner" << std::endl;
        std::cout << "Usage: testrunner [options] path-of-test-file/dir" << std::endl;
        std::cout << "\t-m: run valgrind on each test" << std::endl;
}

int main(int argc, char *argv[])
{
        TestRunner testrunner;
        int start_paths = 1;

        if (argc == 1) {
                usage();
                return 1;
        } else {
                if (std::string(argv[1]) == std::string("-m")) {
                        if (argc == 2) {
                                // ./testrunner -m?
                                usage();
                                return 1;
                        }
                        // ./testrunner -m <something here>?
                        testrunner.valgrind = true;
                        start_paths = 2;
                } else {
                        // ./testrunner <something here>
                        testrunner.valgrind = false;
                        start_paths = 1;
                }
        }

        for (; start_paths < argc; start_paths++) {
                testrunner.find(argv[start_paths]);
        }
        testrunner.run();
        testrunner.show_result();

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

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include "testrunner.h"

TestRunner::~TestRunner()
{
        std::vector<std::string>::iterator it;

        for (it = tmp_files.begin(); it != tmp_files.end(); ++it) {
                unlink(it->c_str());
        }
}

void TestRunner::show_result(void) const
{
        std::cout << "-----------------------------------" << std::endl;
        std::cout << "Tests: " << files.size() << std::endl;
        std::cout << "-----------------------------------" << std::endl;
        std::cout << "Passed tests: " << pass << std::endl;
        std::cout << "Failed tests: " << fail << std::endl;
        if (valgrind) {
                std::cout << "Leaked tests: " << leak << std::endl;
        }
        std::cout << "-----------------------------------" << std::endl;
        std::cout << "Time taken: " << (((double)clock() - start_time) / CLOCKS_PER_SEC) << " seconds" << std::endl;
        std::cout << "-----------------------------------" << std::endl;
}

void TestRunner::find(char* dir)
{
        DIR *dp;
        std::fstream filep;
        std::string path;

        // Ignore .log files
        path = std::string(dir);
        if ((path.size()-4 == path.rfind(".log")) || (path.size()-4 == path.rfind(".mem"))) {
                return;
        }

        // If it's not a file, then it must be a directory
        filep.open(dir);
        if (filep.is_open()) {
                filep.close();
                files.push_back(std::string(dir));
        } else if ((dp = opendir(dir)) != NULL) {
                closedir(dp);
                path = std::string(dir);
                if (path[path.size()-1] != '/') {
                        path = path + "/";
                }
                load_folder(path.c_str());
        } else {
                std::cout << "Couldn't open the file or directory specified: " << std::string(dir) << std::endl;
                //exit(1);
                return;
        }
}

void TestRunner::run(void)
{
        FILE *fp;
        std::vector<std::string>::iterator it;
        std::string file_name, tmp_file;
        pcrecpp::RE regex("((?s:.(?!==CODE==))+)\\s*==CODE==\\s*((?s:.(?!==RESULT==))+)\\s*==RESULT==\\s*((?s:.+))\\s+");

        if (!files.size()) {
                std::cout << "No files found.";
                exit(1);
        }

        for (it = files.begin(); it != files.end(); ++it) {
                char result[300] = {0};
                std::string title, source, expect, log_line, command;
                unsigned int filesize;

                file_name = *it;

                tmp_file = file_name + ".tmp";

                regex.FullMatch(read_file(file_name.c_str()), &title, &source, &expect);

                write_file(tmp_file, source);

                if (valgrind) {
                        command = std::string("valgrind -q --tool=memcheck --leak-check=yes --num-callers=30 --log-file=") + file_name + std::string(".mem");
                        command = command + std::string(" ./clever -f ") + tmp_file;
                        fp = popen(command.c_str(), "r");
                } else {
                        command = std::string("./clever -f ") + tmp_file;
                        fp = popen(command.c_str(), "r");
                }
                fread(result, 1, sizeof(result)-1, fp);
                fclose(fp);

                // Valgrind log is empty?
                if (valgrind) {
                        filesize = file_size(file_name + std::string(".mem"));
                        if (filesize == 0) {
                                remove(std::string(file_name + std::string(".mem")).c_str());
                        } else {
                                std::cout << "[LEAK] ";
                                leak++;
                        }
                }

                if (pcrecpp::RE(expect).FullMatch(result)) {
                        if ((valgrind && filesize == 0) || !valgrind) {
                                std::cout << "[OKAY] ";
                        }
                        pass++;
                } else {
                        if ((valgrind && filesize == 0) || !valgrind) {
                                std::cout << "[FAIL] ";
                        }
                        log_line = std::string("== Expected ==\n") + expect + std::string("\n");
                        log_line.append(std::string("== Got ==\n") + std::string(result));
                        write_log(file_name,log_line);
                        fail++;
                }

                std::cout << title << " (" << file_name << ")" << std::endl;
        }
}

void TestRunner::write_file(std::string& name, std::string& source)
{
        std::ofstream file(name.c_str());

        file << source;
        file.close();

        tmp_files.push_back(name);
}

std::string TestRunner::read_file(const char* name) const
{
        std::string source, line;
        std::ifstream file;

        file.open(name);

        if (!file) {
                std::cout << "Couldn't open file " << name << std::endl;
                exit(1);
        }

        while (!file.eof()) {
                getline(file, line);
                source += line + '\n';
        }
        file.close();

        return source;
}

void TestRunner::load_folder(const char* dir)
{
        DIR *dp, *dpr;
        struct dirent *dirp;
        std::string path,file;

        if ((dp = opendir(dir)) != NULL) {
                while ((dirp = readdir(dp)) != NULL) {
                        if (strcmp(dirp->d_name, ".") == 0 ||
                                strcmp(dirp->d_name, "..") == 0 ||
                                strstr(dirp->d_name, ".tmp") ||
                                strstr(dirp->d_name, ".svn")) {
                                continue;
                        }
                        // Ignore .log files
                        file = std::string(dirp->d_name);
                        if ((file.size()-4 == file.rfind(".log")) || (file.size()-4 == file.rfind(".mem"))) {
                                continue;
                        }
                        // Is this a folder or a file?
                        path = std::string(dir) + std::string(dirp->d_name) + "/";
                        if ((dpr = opendir(path.c_str())) != NULL) {
                                closedir(dpr);
                                load_folder(path.c_str());
                        } else {
                                path = std::string(dir) + std::string(dirp->d_name);
                                files.push_back(path.c_str());
                        }
                }
                closedir(dp);
        }
}

std::string TestRunner::extract_folder(const char* file) const
{
        std::string path;
        size_t found;

        path = std::string(file);
        found = path.rfind("/");
        if (found != path.npos) {
                path = path.substr(0,found+1);
        }

        return path;
}

void TestRunner::write_log(std::string testname, std::string message) {
        FILE *log;

        testname = testname + ".log";
        log = fopen(testname.c_str(),"w");
        if (log) {
                fputs(message.c_str(),log);
                fclose(log);
        }
}

unsigned int TestRunner::file_size(std::string file) {
        std::ifstream stream;
        unsigned int length;

        stream.open(file.c_str());
        if (stream.is_open()) {
                stream.seekg(0,std::ios::end);
                length = stream.tellg();
                stream.close();

                return length;
        }

        return 0;
}

// ---------------------

void usage(void)
{
        std::cout << "Clever Language - Testrunner" << std::endl;
        std::cout << "Usage: testrunner [options] path-of-test-file/dir" << std::endl;
        std::cout << "\t-m: run valgrind on each test" << std::endl;
}

int main(int argc, char *argv[])
{
        TestRunner testrunner;
        int start_paths = 1;

        if (argc == 1) {
                usage();
                return 1;
        } else {
                if (std::string(argv[1]) == std::string("-m")) {
                        if (argc == 2) {
                                // ./testrunner -m?
                                usage();
                                return 1;
                        }
                        // ./testrunner -m <something here>?
                        testrunner.valgrind = true;
                        start_paths = 2;
                } else {
                        // ./testrunner <something here>
                        testrunner.valgrind = false;
                        start_paths = 1;
                }
        }

        for (; start_paths < argc; start_paths++) {
                testrunner.find(argv[start_paths]);
        }
        testrunner.run();
        testrunner.show_result();

        return 0;
}<|endoftext|>


<commit_before>// *************************************************************************
// * GSM TA/ME library
// *
// * File:    gsm_parser.cc
// *
// * Purpose: Parser to parse MA/TA result strings
// *
// * Author:  Peter Hofmann (software@pxh.de)
// *
// * Created: 13.5.1999
// *************************************************************************

#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_parser.h>
#include <gsmlib/gsm_nls.h>
#include <ctype.h>
#include <assert.h>
#include <sstream>

using namespace gsmlib;

// Parser members

int Parser::nextChar(bool skipWhiteSpace)
{
  if (skipWhiteSpace)
    while (_i < _s.length() && isspace(_s[_i])) ++_i;

  if (_i == _s.length())
    {
      _eos = true;
      return -1;
    }

  return _s[_i++];
}

bool Parser::checkEmptyParameter(bool allowNoParameter) throw(GsmException)
{
  int c = nextChar();
  if (c == ',' || c == -1)
    {
      if (allowNoParameter)
	{
	  putBackChar();
	  return true;
	}
      else
	throwParseException(_("expected parameter"));

      putBackChar();
    }
  return false;
}

std::string Parser::parseString2(bool stringWithQuotationMarks)
  throw(GsmException)
{
  int c;
  std::string result;
  if (parseChar('"', true))  // OK, std::string starts and ends with quotation mark
    if (stringWithQuotationMarks)
      {
	// read till end of line
	while ((c = nextChar(false)) != -1)
	  result += c;

	// check for """ at end of line
	if (result.length() == 0 || result[result.length() - 1]  != '"')
	  throwParseException(_("expected '\"'"));

	// remove """ at the end
	result.resize(result.length() - 1);
      }
    else
      {
	// read till next """
	while ((c = nextChar(false)) != '"')
	  if (c == -1)
	    throwParseException();
	  else
	    result += c;
      }
  else                          // std::string ends with "," or EOL
    {
      c = nextChar(false);
      while (c != ',' && c != -1)
	{
	  result += c;
	  c = nextChar(false);
	}
      if (c == ',') putBackChar();
    }

  return result;
}

int Parser::parseInt2() throw(GsmException)
{
  std::string s;
  int c;
  int result;

  while (isdigit(c = nextChar())) s += c;

  putBackChar();
  if (s.length() == 0)
    throwParseException(_("expected number"));

  std::istringstream is(s.c_str());
  is >> result;
  return result;
}

void Parser::throwParseException(std::string message) throw(GsmException)
{
  std::ostringstream os;
  if (message.length() == 0)
    throw GsmException(stringPrintf(_("unexpected end of std::string '%s'"),
                                    _s.c_str()), ParserError);
  else
    throw GsmException(message +
                       stringPrintf(_(" (at position %d of std::string '%s')"), _i,
                                    _s.c_str()), ParserError);
}

Parser::Parser(std::string s) : _i(0), _s(s), _eos(false)
{
}

bool Parser::parseChar(char c, bool allowNoChar) throw(GsmException)
{
  if (nextChar() != c)
    {
      if (allowNoChar)
	{
	  putBackChar();
	  return false;
	}
      else
	throwParseException(stringPrintf(_("expected '%c'"), c));
    }
  return true;
}

std::vector<std::string> Parser::parseStringList(bool allowNoList)
  throw(GsmException)
{
  // handle case of empty parameter
  std::vector<std::string> result;
  if (checkEmptyParameter(allowNoList)) return result;

  parseChar('(');
  if (nextChar() != ')')
    {
      putBackChar();
      while (1)
	{
	  result.push_back(parseString());
	  int c = nextChar();
	  if (c == ')')
	    break;
	  if (c == -1)
	    throwParseException();
	  if (c != ',')
	    throwParseException(_("expected ')' or ','"));
	}
    }

  return result;
}

std::vector<bool> Parser::parseIntList(bool allowNoList)
  throw(GsmException)
{
  // handle case of empty parameter
  bool isRange = false;
  std::vector<bool> result;
  int resultCapacity = 0;
  unsigned int saveI = _i;

  if (checkEmptyParameter(allowNoList)) return result;

  // check for the case of a integer list consisting of only one parameter
  // some TAs omit the parentheses in this case
  if (isdigit(nextChar()))
    {
      putBackChar();
      int num = parseInt();
      result.resize(num + 1, false);
      result[num] = true;
      return result;
    }
  putBackChar();

  // run in two passes
  // pass 0: find capacity needed for result
  // pass 1: resize result and fill it in
  for (int pass = 0; pass < 2; ++pass)
    {
      if (pass == 1)
	{
	  _i = saveI;
	  result.resize(resultCapacity + 1, false);
	}

      parseChar('(');
      if (nextChar() != ')')
	{
	  putBackChar();
	  int lastInt = -1;
	  while (1)
	    {
	      int thisInt = parseInt();

	      if (isRange)
		{
		  assert(lastInt != -1);
		  if (lastInt <= thisInt)
		    for (int i = lastInt; i < thisInt; ++i)
		      {
			if (i > resultCapacity)
			  resultCapacity = i;
			if (pass == 1)
			  result[i] = true;
		      }
		  else
		    for (int i = thisInt; i < lastInt; ++i)
		      {
			if (i > resultCapacity)
			  resultCapacity = i;
			if (pass == 1)
			  result[i] = true;
		      }
		  isRange = false;
		}

	      if (thisInt > resultCapacity)
		resultCapacity = thisInt;
	      if (pass == 1)
		result[thisInt] = true;
	      lastInt = thisInt;

	      int c = nextChar();
	      if (c == ')')
		break;

	      if (c == -1)
		throwParseException();

	      if (c != ',' && c != '-')
		throwParseException(_("expected ')', ',' or '-'"));

	      if (c == ',')
		isRange = false;
	      else                      // is '-'
		if (isRange)
		  throwParseException(_("range of the form a-b-c not allowed"));
		else
		  isRange = true;
	    }
	}
    }
  if (isRange)
    throwParseException(_("range of the form a- no allowed"));
  return result;
}

std::vector<ParameterRange> Parser::parseParameterRangeList(bool allowNoList)
  throw(GsmException)
{
  // handle case of empty parameter
  std::vector<ParameterRange> result;
  if (checkEmptyParameter(allowNoList)) return result;

  result.push_back(parseParameterRange());
  while (parseComma(true))
    {
      result.push_back(parseParameterRange());
    }

  return result;
}

ParameterRange Parser::parseParameterRange(bool allowNoParameterRange)
  throw(GsmException)
{
  // handle case of empty parameter
  ParameterRange result;
  if (checkEmptyParameter(allowNoParameterRange)) return result;

  parseChar('(');
  result._parameter = parseString();
  parseComma();
  result._range = parseRange(false, true);
  parseChar(')');

  return result;
}

IntRange Parser::parseRange(bool allowNoRange, bool allowNonRange)
  throw(GsmException)
{
  // handle case of empty parameter
  IntRange result;
  if (checkEmptyParameter(allowNoRange)) return result;

  parseChar('(');
  result._low = parseInt();
  // allow non-ranges is allowNonRange == true
  if (parseChar('-', allowNonRange))
    result._high = parseInt();
  parseChar(')');

  return result;
}

int Parser::parseInt(bool allowNoInt) throw(GsmException)
{
  // handle case of empty parameter
  int result = NOT_SET;
  if (checkEmptyParameter(allowNoInt)) return result;

  result = parseInt2();

  return result;
}

std::string Parser::parseString(bool allowNoString,
				bool stringWithQuotationMarks)
  throw(GsmException)
{
  // handle case of empty parameter
  std::string result;
  if (checkEmptyParameter(allowNoString)) return result;

  result = parseString2(stringWithQuotationMarks);

  return result;
}

bool Parser::parseComma(bool allowNoComma) throw(GsmException)
{
  if (nextChar() != ',')
    {
      if(allowNoComma)
	{
	  putBackChar();
	  return false;
	}
      else
	throwParseException(_("expected comma"));
    }
  return true;
}

std::string Parser::parseEol() throw(GsmException)
{
  std::string result;
  int c;

  while ((c = nextChar()) != -1) result += c;
  return result;
}

void Parser::checkEol() throw(GsmException)
{
  if (nextChar() != -1)
    {
      putBackChar();
      throwParseException(_("expected end of line"));
    }
}

std::string Parser::getEol()
{
  std::string result;
  int c;
  unsigned int saveI = _i;
  bool saveEos = _eos;

  while ((c = nextChar()) != -1) result += c;
  _i = saveI;
  _eos = saveEos;
  return result;
}
<commit_msg>fix parseInt2 expected number<commit_after>// *************************************************************************
// * GSM TA/ME library
// *
// * File:    gsm_parser.cc
// *
// * Purpose: Parser to parse MA/TA result strings
// *
// * Author:  Peter Hofmann (software@pxh.de)
// *
// * Created: 13.5.1999
// *************************************************************************

#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_parser.h>
#include <gsmlib/gsm_nls.h>
#include <ctype.h>
#include <assert.h>
#include <sstream>

using namespace gsmlib;

// Parser members

int Parser::nextChar(bool skipWhiteSpace)
{
  if (skipWhiteSpace)
    while (_i < _s.length() && isspace(_s[_i])) ++_i;

  if (_i == _s.length())
    {
      _eos = true;
      return -1;
    }

  return _s[_i++];
}

bool Parser::checkEmptyParameter(bool allowNoParameter) throw(GsmException)
{
  int c = nextChar();
  if (c == ',' || c == -1)
    {
      if (allowNoParameter)
	{
	  putBackChar();
	  return true;
	}
      else
	throwParseException(_("expected parameter"));

    }
  putBackChar();
  return false;
}

std::string Parser::parseString2(bool stringWithQuotationMarks)
  throw(GsmException)
{
  int c;
  std::string result;
  if (parseChar('"', true))  // OK, std::string starts and ends with quotation mark
    if (stringWithQuotationMarks)
      {
	// read till end of line
	while ((c = nextChar(false)) != -1)
	  result += c;

	// check for """ at end of line
	if (result.length() == 0 || result[result.length() - 1]  != '"')
	  throwParseException(_("expected '\"'"));

	// remove """ at the end
	result.resize(result.length() - 1);
      }
    else
      {
	// read till next """
	while ((c = nextChar(false)) != '"')
	  if (c == -1)
	    throwParseException();
	  else
	    result += c;
      }
  else                          // std::string ends with "," or EOL
    {
      c = nextChar(false);
      while (c != ',' && c != -1)
	{
	  result += c;
	  c = nextChar(false);
	}
      if (c == ',') putBackChar();
    }

  return result;
}

int Parser::parseInt2() throw(GsmException)
{
  std::string s;
  int c;
  int result;

  while (isdigit(c = nextChar())) s += c;

  putBackChar();
  if (s.length() == 0)
    throwParseException(_("expected number"));

  std::istringstream is(s.c_str());
  is >> result;
  return result;
}

void Parser::throwParseException(std::string message) throw(GsmException)
{
  std::ostringstream os;
  if (message.length() == 0)
    throw GsmException(stringPrintf(_("unexpected end of std::string '%s'"),
                                    _s.c_str()), ParserError);
  else
    throw GsmException(message +
                       stringPrintf(_(" (at position %d of std::string '%s')"), _i,
                                    _s.c_str()), ParserError);
}

Parser::Parser(std::string s) : _i(0), _s(s), _eos(false)
{
}

bool Parser::parseChar(char c, bool allowNoChar) throw(GsmException)
{
  if (nextChar() != c)
    {
      if (allowNoChar)
	{
	  putBackChar();
	  return false;
	}
      else
	throwParseException(stringPrintf(_("expected '%c'"), c));
    }
  return true;
}

std::vector<std::string> Parser::parseStringList(bool allowNoList)
  throw(GsmException)
{
  // handle case of empty parameter
  std::vector<std::string> result;
  if (checkEmptyParameter(allowNoList)) return result;

  parseChar('(');
  if (nextChar() != ')')
    {
      putBackChar();
      while (1)
	{
	  result.push_back(parseString());
	  int c = nextChar();
	  if (c == ')')
	    break;
	  if (c == -1)
	    throwParseException();
	  if (c != ',')
	    throwParseException(_("expected ')' or ','"));
	}
    }

  return result;
}

std::vector<bool> Parser::parseIntList(bool allowNoList)
  throw(GsmException)
{
  // handle case of empty parameter
  bool isRange = false;
  std::vector<bool> result;
  int resultCapacity = 0;
  unsigned int saveI = _i;

  if (checkEmptyParameter(allowNoList)) return result;

  // check for the case of a integer list consisting of only one parameter
  // some TAs omit the parentheses in this case
  if (isdigit(nextChar()))
    {
      putBackChar();
      int num = parseInt();
      result.resize(num + 1, false);
      result[num] = true;
      return result;
    }
  putBackChar();

  // run in two passes
  // pass 0: find capacity needed for result
  // pass 1: resize result and fill it in
  for (int pass = 0; pass < 2; ++pass)
    {
      if (pass == 1)
	{
	  _i = saveI;
	  result.resize(resultCapacity + 1, false);
	}

      parseChar('(');
      if (nextChar() != ')')
	{
	  putBackChar();
	  int lastInt = -1;
	  while (1)
	    {
	      int thisInt = parseInt();

	      if (isRange)
		{
		  assert(lastInt != -1);
		  if (lastInt <= thisInt)
		    for (int i = lastInt; i < thisInt; ++i)
		      {
			if (i > resultCapacity)
			  resultCapacity = i;
			if (pass == 1)
			  result[i] = true;
		      }
		  else
		    for (int i = thisInt; i < lastInt; ++i)
		      {
			if (i > resultCapacity)
			  resultCapacity = i;
			if (pass == 1)
			  result[i] = true;
		      }
		  isRange = false;
		}

	      if (thisInt > resultCapacity)
		resultCapacity = thisInt;
	      if (pass == 1)
		result[thisInt] = true;
	      lastInt = thisInt;

	      int c = nextChar();
	      if (c == ')')
		break;

	      if (c == -1)
		throwParseException();

	      if (c != ',' && c != '-')
		throwParseException(_("expected ')', ',' or '-'"));

	      if (c == ',')
		isRange = false;
	      else                      // is '-'
		if (isRange)
		  throwParseException(_("range of the form a-b-c not allowed"));
		else
		  isRange = true;
	    }
	}
    }
  if (isRange)
    throwParseException(_("range of the form a- no allowed"));
  return result;
}

std::vector<ParameterRange> Parser::parseParameterRangeList(bool allowNoList)
  throw(GsmException)
{
  // handle case of empty parameter
  std::vector<ParameterRange> result;
  if (checkEmptyParameter(allowNoList)) return result;

  result.push_back(parseParameterRange());
  while (parseComma(true))
    {
      result.push_back(parseParameterRange());
    }

  return result;
}

ParameterRange Parser::parseParameterRange(bool allowNoParameterRange)
  throw(GsmException)
{
  // handle case of empty parameter
  ParameterRange result;
  if (checkEmptyParameter(allowNoParameterRange)) return result;

  parseChar('(');
  result._parameter = parseString();
  parseComma();
  result._range = parseRange(false, true);
  parseChar(')');

  return result;
}

IntRange Parser::parseRange(bool allowNoRange, bool allowNonRange)
  throw(GsmException)
{
  // handle case of empty parameter
  IntRange result;
  if (checkEmptyParameter(allowNoRange)) return result;

  parseChar('(');
  result._low = parseInt();
  // allow non-ranges is allowNonRange == true
  if (parseChar('-', allowNonRange))
    result._high = parseInt();
  parseChar(')');

  return result;
}

int Parser::parseInt(bool allowNoInt) throw(GsmException)
{
  // handle case of empty parameter
  int result = NOT_SET;
  if (checkEmptyParameter(allowNoInt)) return result;

  result = parseInt2();

  return result;
}

std::string Parser::parseString(bool allowNoString,
				bool stringWithQuotationMarks)
  throw(GsmException)
{
  // handle case of empty parameter
  std::string result;
  if (checkEmptyParameter(allowNoString)) return result;

  result = parseString2(stringWithQuotationMarks);

  return result;
}

bool Parser::parseComma(bool allowNoComma) throw(GsmException)
{
  if (nextChar() != ',')
    {
      if(allowNoComma)
	{
	  putBackChar();
	  return false;
	}
      else
	throwParseException(_("expected comma"));
    }
  return true;
}

std::string Parser::parseEol() throw(GsmException)
{
  std::string result;
  int c;

  while ((c = nextChar()) != -1) result += c;
  return result;
}

void Parser::checkEol() throw(GsmException)
{
  if (nextChar() != -1)
    {
      putBackChar();
      throwParseException(_("expected end of line"));
    }
}

std::string Parser::getEol()
{
  std::string result;
  int c;
  unsigned int saveI = _i;
  bool saveEos = _eos;

  while ((c = nextChar()) != -1) result += c;
  _i = saveI;
  _eos = saveEos;
  return result;
}
<|endoftext|>


<commit_before>#include "hdfscpp.h"

#include <iostream>

#include <assert.h>

#include "filebuf.h"
#include <vector>

#include <zlib.h>
/**********************************************************************/

/** Reads a int written by java's DataOutput#writeInt
 *
 * FIXME Move to propper namespace
 */
inline int32_t ReadInt(tmacam::filebuf* data) {
	assert(sizeof(int32_t) == 4);
	const char* bytes = data->read(sizeof(int32_t));
	return (((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) |
		 ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff));
}

/**********************************************************************/
namespace tmacam {

class HdfsDumpReader {
public:
    static const size_t kDefaultBufferSize =  10<<20; // 10 MB

    HdfsDumpReader(hdfs::FileSystem* fs,
                   const char* path,
                   size_t buffer_size = kDefaultBufferSize);

    bool HasNext();

    tmacam::filebuf GetNext();

    void ReadFile();
private:
    hdfs::FileSystem* fs_;
    std::string path_;
    hdfs::File file_;
    tOffset file_size_;
    size_t buffer_size_;
    std::vector<char> buffer_;
    // Used for iteration control and state-keeping
    size_t bytes_read_;
    tmacam::filebuf available_data_;
    const tmacam::filebuf empty_file_buffer_;

    // No copy, no atribution and no default constructor for this class
    DISALLOW_COPY_AND_ASSIGN(HdfsDumpReader);
    HdfsDumpReader();
};

HdfsDumpReader::HdfsDumpReader(hdfs::FileSystem* fs, const char* path,
                   size_t buffer_size) :
    fs_(fs),
    path_(path),
    file_(*fs, path, O_RDONLY, buffer_size, 0, 0),
    file_size_(0), // we will get to you in a momment, sir
    buffer_size_(buffer_size),
    buffer_(buffer_size),
    bytes_read_(0),
    available_data_(),
    empty_file_buffer_()
{
    hdfs::FileInfoList file_info;
    fs_->GetPathInfo(path, &file_info);
    file_size_ = file_info->mSize;
    std::cout << "Constructor " << file_.Available() << std::endl;
}

bool HdfsDumpReader::HasNext()
{
    // We won't be done untill we have read all the file and
    // there is nothing left in available_data_ to be read.
    return (bytes_read_ < file_size_) || !available_data_.eof();
}

tmacam::filebuf HdfsDumpReader::GetNext()
{
    // Missing closures?
    /* First of all, remember that this code originally was  something along
     * the lines:
     *
     * for (bytes_read_ = 0; bytes_read_ < file_size_;) {
     *   (...)
     *   try {
     *      while(!available_data_.eof()) {
     *          (...)
     *          // yield data unit
     *      }
     *  } catch (std::out_of_range) {
     *      (...)
     *  }
     *
     * Missing closures now?
     *
     * Using Pread() and exceptions for doing this is ugly and lame.
     * We should have used Read() and proper tests but, you know what,
     * this works and is easy to understand -- and this scores +1 in
     * my book.
     */

    assert(HasNext()); // Simplify corner cases for the next if
    // Do we need to perform a read operation? Can we perform a read?
    if (available_data_.eof() && (bytes_read_ < file_size_)) {
        tSize read_length = file_.Pread(bytes_read_, &buffer_[0], buffer_size_);
        bytes_read_ += read_length;
        available_data_ = tmacam::filebuf(&buffer_[0], read_length);
    }

    return tmacam::filebuf();
}

void HdfsDumpReader::ReadFile()
{
    size_t data_left_len = 0;

    for (bytes_read_ = 0; bytes_read_ < file_size_;) {
        /* Using Pread() and exceptions for doing this is ugly and lame.
         * We should have used Read() and proper tests but, you know what,
         * this works and is easy to understand -- and this scores +1 in
         * my book.
         */
        tSize read_length = file_.Pread(bytes_read_, &buffer_[0], buffer_size_);
        bytes_read_ += read_length;

        available_data_ = tmacam::filebuf(&buffer_[0], read_length);

        std::cout << "READ " << read_length << std::endl;

        try {
            while (!available_data_.eof()) {
                // Save current progress
                data_left_len = available_data_.len();
                // Read header, payload and CRC. Abort if payload is too big
                int32_t payload_len = ReadInt(&available_data_);
                assert(payload_len + 2*sizeof(int32_t) < buffer_size_);
                const char* payload_data = available_data_.read(payload_len);
                int32_t expected_checksum = ReadInt(&available_data_);
#ifndef DUMPREADER_FAST_PASS
                // Calc CRC32
                uLong crc = crc32(0L, (const Bytef*)payload_data, payload_len);
                if (expected_checksum != static_cast<int32_t>(crc)) {
                    std::cerr << "CRC MISSMATCH -- found " << crc <<
                        " expected" << expected_checksum <<
                        std::endl;
                    exit(EXIT_FAILURE);
                }
#endif
                std::cout << "P: " <<  payload_len << std::endl;
            }
        } catch(std::out_of_range) {
            std::cout << "ooops " <<  std::endl;
            // not enough data...
            // rewind reading position
            bytes_read_ -= data_left_len;
        }
    }
}

}; // namespace tmacam

/**********************************************************************/

void ShowUsage()
{
    std::cerr << "Usage: hdfsls <path> " << std::endl;
}

int main(int argc, char* argv[])
{
    using namespace tmacam;

    // Check command line arguments
    if ( argc != 2) {
        std::cerr << "Wrong number of arguments" << std::endl;
        ShowUsage();
        exit(EXIT_FAILURE);
    }
    const char* path = argv[1];

    // Connect to HDFS / get filesystem handle
    hdfs::FileSystem fs;

    // Path is a file, right?
    if (!fs.Exists(path)) {
        std::cerr << "Path '" << path << "' does not exist." << std::endl;
        exit(EXIT_FAILURE);
    }
    hdfs::FileInfoList path_info;
    fs.GetPathInfo(path, &path_info);
    if (path_info->mKind != kObjectKindFile ) {
        std::cerr << "Path '" << path << "' is not a regular file."
                  << std::endl;
        exit(EXIT_FAILURE);
    }

    HdfsDumpReader reader(&fs, path);

    reader.ReadFile();

	return 0;
}

// vim: et ai sts=4 ts=4 sw=4
<commit_msg>HdfsDumpReader::GetNext() initial code landed.<commit_after>#include "hdfscpp.h"

#include <iostream>

#include <assert.h>

#include "filebuf.h"
#include <vector>

#include <zlib.h>
/**********************************************************************/

/** Reads a int written by java's DataOutput#writeInt
 *
 * FIXME Move to propper namespace
 */
inline int32_t ReadInt(tmacam::filebuf* data) {
	assert(sizeof(int32_t) == 4);
	const char* bytes = data->read(sizeof(int32_t));
	return (((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) |
		 ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff));
}

/**********************************************************************/
namespace tmacam {

class HdfsDumpReader {
public:
    static const size_t kDefaultBufferSize =  10<<20; // 10 MB

    HdfsDumpReader(hdfs::FileSystem* fs,
                   const char* path,
                   size_t buffer_size = kDefaultBufferSize);

    bool HasNext();

    tmacam::filebuf GetNext();

    void ReadFile();
private:
    hdfs::FileSystem* fs_;
    std::string path_;
    hdfs::File file_;
    tOffset file_size_;
    size_t buffer_size_;
    std::vector<char> buffer_;
    // Used for iteration control and state-keeping
    size_t bytes_read_;
    tmacam::filebuf available_data_;
    const tmacam::filebuf empty_file_buffer_;

    // No copy, no atribution and no default constructor for this class
    DISALLOW_COPY_AND_ASSIGN(HdfsDumpReader);
    HdfsDumpReader();
};

HdfsDumpReader::HdfsDumpReader(hdfs::FileSystem* fs, const char* path,
                   size_t buffer_size) :
    fs_(fs),
    path_(path),
    file_(*fs, path, O_RDONLY, buffer_size, 0, 0),
    file_size_(0), // we will get to you in a momment, sir
    buffer_size_(buffer_size),
    buffer_(buffer_size),
    bytes_read_(0),
    available_data_(),
    empty_file_buffer_()
{
    hdfs::FileInfoList file_info;
    fs_->GetPathInfo(path, &file_info);
    file_size_ = file_info->mSize;
    std::cout << "Constructor " << file_.Available() << std::endl;
}

bool HdfsDumpReader::HasNext()
{
    // We won't be done untill we have read all the file and
    // there is nothing left in available_data_ to be read.
    return (bytes_read_ < file_size_) || !available_data_.eof();
}

tmacam::filebuf HdfsDumpReader::GetNext()
{
    // Missing closures?
    /* First of all, remember that this code originally was  something along
     * the lines:
     *
     * for (bytes_read_ = 0; bytes_read_ < file_size_;) {
     *   (...)
     *   try {
     *      while(!available_data_.eof()) {
     *          (...)
     *          // yield data unit
     *      }
     *  } catch (std::out_of_range) {
     *      (...)
     *  }
     *
     * Missing closures now?
     *
     * Using Pread() and exceptions for doing this is ugly and lame.
     * We should have used Read() and proper tests but, you know what,
     * this works and is easy to understand -- and this scores +1 in
     * my book.
     */

    assert(HasNext()); // Simplify corner cases for the next if

    // Do we need to perform a read operation? Can we perform a read?
    if (available_data_.eof() && (bytes_read_ < file_size_)) {
        tSize read_length = file_.Pread(bytes_read_, &buffer_[0], buffer_size_);
        bytes_read_ += read_length;
        available_data_ = tmacam::filebuf(&buffer_[0], read_length);
    }

    // Save current progress
    size_t data_left_len = available_data_.len();

    try {
        assert(data_left_len);
        const char* pkt_start = available_data_.current;
        // Read header, payload and CRC. Abort if payload is too big
        int32_t payload_len = ReadInt(&available_data_);
        assert(payload_len + 2*sizeof(int32_t) < buffer_size_);
        const char* payload_data = available_data_.read(payload_len);
        int32_t expected_checksum = ReadInt(&available_data_);
#ifndef DUMPREADER_FAST_PASS
        // Calc CRC32
        uLong crc = crc32(0L, (const Bytef*)payload_data, payload_len);
        if (expected_checksum != static_cast<int32_t>(crc)) {
            std::cerr << "CRC MISSMATCH -- found " << crc <<
                " expected" << expected_checksum <<
                std::endl;
            exit(EXIT_FAILURE);
        }
#endif
        // Ok, pkt content was read and is sane. Return it.
        size_t pkt_len = data_left_len - available_data_.len();
        return tmacam::filebuf(pkt_start, pkt_len);
        std::cout << "P: " <<  payload_len << std::endl;
    } catch(std::out_of_range) {
        std::cout << "ooops " <<  std::endl;
        // not enough data...
        // rewind reading position
        bytes_read_ -= data_left_len;
        // and retry
        return GetNext();
    }
}

void HdfsDumpReader::ReadFile()
{
    size_t data_left_len = 0;

    for (bytes_read_ = 0; bytes_read_ < file_size_;) {
        /* Using Pread() and exceptions for doing this is ugly and lame.
         * We should have used Read() and proper tests but, you know what,
         * this works and is easy to understand -- and this scores +1 in
         * my book.
         */
        tSize read_length = file_.Pread(bytes_read_, &buffer_[0], buffer_size_);
        bytes_read_ += read_length;

        available_data_ = tmacam::filebuf(&buffer_[0], read_length);

        std::cout << "READ " << read_length << std::endl;

        try {
            while (!available_data_.eof()) {
                // Save current progress
                data_left_len = available_data_.len();
                // Read header, payload and CRC. Abort if payload is too big
                int32_t payload_len = ReadInt(&available_data_);
                assert(payload_len + 2*sizeof(int32_t) < buffer_size_);
                const char* payload_data = available_data_.read(payload_len);
                int32_t expected_checksum = ReadInt(&available_data_);
#ifndef DUMPREADER_FAST_PASS
                // Calc CRC32
                uLong crc = crc32(0L, (const Bytef*)payload_data, payload_len);
                if (expected_checksum != static_cast<int32_t>(crc)) {
                    std::cerr << "CRC MISSMATCH -- found " << crc <<
                        " expected" << expected_checksum <<
                        std::endl;
                    exit(EXIT_FAILURE);
                }
#endif
                std::cout << "P: " <<  payload_len << std::endl;
            }
        } catch(std::out_of_range) {
            std::cout << "ooops " <<  std::endl;
            // not enough data...
            // rewind reading position
            bytes_read_ -= data_left_len;
        }
    }
}

}; // namespace tmacam

/**********************************************************************/

void ShowUsage()
{
    std::cerr << "Usage: hdfsls <path> " << std::endl;
}

int main(int argc, char* argv[])
{
    using namespace tmacam;

    // Check command line arguments
    if ( argc != 2) {
        std::cerr << "Wrong number of arguments" << std::endl;
        ShowUsage();
        exit(EXIT_FAILURE);
    }
    const char* path = argv[1];

    // Connect to HDFS / get filesystem handle
    hdfs::FileSystem fs;

    // Path is a file, right?
    if (!fs.Exists(path)) {
        std::cerr << "Path '" << path << "' does not exist." << std::endl;
        exit(EXIT_FAILURE);
    }
    hdfs::FileInfoList path_info;
    fs.GetPathInfo(path, &path_info);
    if (path_info->mKind != kObjectKindFile ) {
        std::cerr << "Path '" << path << "' is not a regular file."
                  << std::endl;
        exit(EXIT_FAILURE);
    }

    HdfsDumpReader reader(&fs, path);

    reader.ReadFile();

	return 0;
}

// vim: et ai sts=4 ts=4 sw=4
<|endoftext|>


<commit_before>//===- InstrProfilingRuntime.cpp - PGO runtime initialization -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

extern "C" {

#include "InstrProfiling.h"

extern int __llvm_profile_runtime;
int __llvm_profile_runtime;

}

namespace {

class RegisterAtExit {
public:
  RegisterAtExit() { __llvm_profile_register_write_file_atexit(); }
};

RegisterAtExit Registration;

}
<commit_msg>InstrProf: Remove redundant declaration<commit_after>//===- InstrProfilingRuntime.cpp - PGO runtime initialization -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

extern "C" {

#include "InstrProfiling.h"

int __llvm_profile_runtime;

}

namespace {

class RegisterAtExit {
public:
  RegisterAtExit() { __llvm_profile_register_write_file_atexit(); }
};

RegisterAtExit Registration;

}
<|endoftext|>