text:
#include <ros/ros.h>

#include "fieldtrack/FieldtrackCommon.h"
#include "fieldtrack/PoseEstimator.h"

#include "argus_utils/utils/ParamUtils.h"
#include "argus_utils/geometry/GeometryUtils.h"
#include "argus_utils/synchronization/SynchronizationTypes.h"

#include <nav_msgs/Odometry.h>
#include "fieldtrack/ResetFilter.h"
#include "fieldtrack/TargetState.h"

#include <boost/foreach.hpp>
#include <boost/circular_buffer.hpp>

using namespace argus;

class PoseEstimatorNode
{
public:

	PoseEstimatorNode( ros::NodeHandle& nh, ros::NodeHandle& ph )
	{
		double headLag;
		GetParamRequired( ph, "update_lag", headLag );
		_headLag = ros::Duration( headLag );

		_extrinsicsManager = std::make_shared<ExtrinsicsInterface>( nh, ph );

		_resetServer = ph.advertiseService( "reset",
		                                    &PoseEstimatorNode::ResetCallback,
		                                    this );

		// Subscribe to all update topics
		YAML::Node updateSources;
		GetParamRequired( ph, "update_sources", updateSources );
		YAML::Node::const_iterator iter;
		for( iter = updateSources.begin(); iter != updateSources.end(); iter++ )
		{
			const std::string& sourceName = iter->first.as<std::string>();
			const YAML::Node& info = iter->second;

			std::string topic, type;
			unsigned int buffSize;
			GetParamRequired( info, "topic", topic );
			GetParamRequired( info, "type", type );
			GetParam( info, "buffer_size", buffSize, (unsigned int) 10 );

			if( type == "pose" )
			{
				SubscribeToUpdates<geometry_msgs::PoseStamped>( nh, topic, buffSize, sourceName );
			}
			else if( type == "pose_cov" )
			{
				SubscribeToUpdates<geometry_msgs::PoseWithCovarianceStamped>( nh, topic, buffSize, sourceName );
			}
			else if( type == "transform" )
			{
				SubscribeToUpdates<geometry_msgs::TransformStamped>( nh, topic, buffSize, sourceName );
			}
			else if( type == "imu" )
			{
				SubscribeToUpdates<sensor_msgs::Imu>( nh, topic, buffSize, sourceName );
			}
			else
			{
				throw std::invalid_argument( "Unsupported topic type: " + type );
			}
		}

		bool useVel = false;
		std::string velTopic, velMode;
		if( GetParam( ph, "velocity_mode", velMode ) &&
		    GetParam( ph, "velocity_topic", velTopic ) )
		{
			useVel = true;
			unsigned int buffSize;
			GetParam( ph, "velocity_buff_len", buffSize, (unsigned int) 10 );

			if( velMode == "twist" )
			{
				_velSub = nh.subscribe( velTopic, buffSize, &PoseEstimatorNode::VelocityCallback, this );
				GetParamRequired( ph, "velocity_covariance", _velCov );
			}
			else if( velMode == "twist_with_cov" )
			{
				_velSub = nh.subscribe( velTopic, buffSize, &PoseEstimatorNode::VelocityCovCallback, this );
			}
			else if( velMode == "odom" )
			{
				_velSub = nh.subscribe( velTopic, buffSize, &PoseEstimatorNode::OdomCallback, this );
			}
		}

		// NOTE Buffer 2 times the lag in velocities
		_estimator.Initialize( ph, useVel, _extrinsicsManager, 2*headLag );

		// Parse output parameters
		GetParam( ph, "publish_odom", _publishOdom, false );
		if( _publishOdom )
		{
			ROS_INFO_STREAM( "Publishing odometry output" );
			unsigned int buffLen;
			GetParam( ph, "odom_buff_len", buffLen, (unsigned int) 10 );
			_odomPub = nh.advertise<nav_msgs::Odometry>( "odom", buffLen );
		}

		GetParam( ph, "publish_pose", _publishPose, false );
		if( _publishPose )
		{
			ROS_INFO_STREAM( "Publishing pose output" );
			unsigned int buffLen;
			GetParam( ph, "pose_buff_len", buffLen, (unsigned int) 10 );
			_posePub = nh.advertise<geometry_msgs::PoseStamped>( "pose", buffLen );
		}

		GetParam( ph, "publish_pose_with_cov", _publishPoseCov, false );
		if( _publishPoseCov )
		{
			ROS_INFO_STREAM( "Publishing pose with covariance output" );
			unsigned int buffLen;
			GetParam( ph, "pose_cov_buff_len", buffLen, (unsigned int) 10 );
			_poseCovPub = nh.advertise<geometry_msgs::PoseWithCovarianceStamped>( "pose_with_cov", buffLen );
		}

		GetParam( ph, "publish_info", _publishInfo, false );
		if( _publishInfo )
		{
			ROS_INFO_STREAM( "Publishing info output" );
			unsigned int infoBuffLen;
			GetParam( ph, "info_buff_len", infoBuffLen, (unsigned int) 100 );
			_infoPub = nh.advertise<argus_msgs::FilterStepInfo>( "info", infoBuffLen );
		}

		GetParam( ph, "publish_tf", _publishTf, false );

		// NOTE We have to reset the filter to compensate for the lag, otherwise the
		// first timer call will request it predict to the past
		// NOTE This conditional catches simulated time startup
		_initialized = false;
		if( ros::Time::now() != ros::Time( 0 ) )
		{
			_estimator.Reset( ros::Time::now() - _headLag );
			_initialized = true;
		}

		GetParamRequired( ph, "update_rate", _updateRate );
		_updateTimer = nh.createTimer( ros::Duration( 1.0 / _updateRate ),
		                               &PoseEstimatorNode::TimerCallback,
		                               this );
	}

	template <typename M>
	void SubscribeToUpdates( ros::NodeHandle& nh, const std::string& topic,
	                         unsigned int buffSize, const std::string& sourceName )
	{
		ROS_INFO_STREAM( "Subscribing to " << sourceName << " at " << topic );
		_updateSubs.emplace_back();
		_updateSubs.back() =
		    nh.subscribe<M>( topic, buffSize,
		                     boost::bind( &PoseEstimatorNode::ObservationCallback<M>,
		                                  this,
		                                  _1,
		                                  sourceName ) );
	}

	template <typename M>
	void ObservationCallback( const typename M::ConstPtr& msg, const std::string& sourceName )
	{
		if( _initialized )
		{
			WriteLock lock( _estimatorMutex );
			_estimator.BufferObservation<M>( sourceName, *msg );
		}
		else
		{
			ROS_WARN_STREAM( "Filter is unitialized. Dropping measurement from: " << sourceName );
		}
	}

	// TODO Different velocity input types
	void OdomCallback( const nav_msgs::Odometry::ConstPtr& msg )
	{
		PoseSE3::TangentVector vel = MsgToTangent( msg->twist.twist );
		PoseSE3::CovarianceMatrix cov;
		ParseMatrix( msg->twist.covariance, cov );
		WriteLock lock( _estimatorMutex );
		_estimator.BufferVelocity( msg->header.stamp, vel, cov );
	}

	// TODO Different velocity input types
	void VelocityCallback( const geometry_msgs::TwistStamped::ConstPtr& msg )
	{
		PoseSE3::TangentVector vel = MsgToTangent( msg->twist );
		WriteLock lock( _estimatorMutex );
		_estimator.BufferVelocity( msg->header.stamp, vel, _velCov );
	}

	// TODO Different velocity input types
	void VelocityCovCallback( const geometry_msgs::TwistWithCovarianceStamped::ConstPtr& msg )
	{
		PoseSE3::TangentVector vel = MsgToTangent( msg->twist.twist );
		PoseSE3::CovarianceMatrix cov;
		ParseMatrix( msg->twist.covariance, cov );
		WriteLock lock( _estimatorMutex );
		_estimator.BufferVelocity( msg->header.stamp, vel, cov );
	}

	void TimerCallback( const ros::TimerEvent& event )
	{
		if( !_initialized )
		{
			_estimator.Reset( event.current_real - _headLag );
			_initialized = true;
		}

		ros::Time lagged = event.current_real - _headLag;

		// NOTE We want to make sure we don't try and update the estimator models
		// while they're in use
		// NOTE Don't want to put the lock in the estimator itself since it complicates
		// copy construction
		WriteLock lock( _estimatorMutex );
		std::vector<FilterInfo> info = _estimator.Process( lagged );
		PoseEstimator rollOutEstimator( _estimator );
		lock.unlock();

		rollOutEstimator.Process( event.current_real );

		// TODO Publish Twist, TwistStamped, TwistWithCovarianceStamped modes as well
		if( _publishOdom )
		{
			_odomPub.publish( rollOutEstimator.GetOdom() );
		}
		if( _publishPose )
		{
			_posePub.publish( rollOutEstimator.GetPose() );
		}
		if( _publishPoseCov )
		{
			_poseCovPub.publish( rollOutEstimator.GetPoseWithCovariance() );
		}
		if( _publishInfo )
		{
			FilterInfoMessageVisitor vis;
			BOOST_FOREACH ( const FilterInfo &fi, info )
			{
				_infoPub.publish( boost::apply_visitor( vis, fi ) );
			}
		}
		if( _publishTf )
		{
			// TODO Have a get relative pose method
			nav_msgs::Odometry odom = rollOutEstimator.GetOdom();
			_extrinsicsManager->SetExtrinsics( odom.child_frame_id,
			                                   odom.header.frame_id,
			                                   event.current_real,
			                                   MsgToPose( odom.pose.pose ) );
		}
	}

	bool ResetCallback( fieldtrack::ResetFilter::Request& req,
	                    fieldtrack::ResetFilter::Response& res )
	{
		// NOTE May not want to use ros sleep in sim mode?
		ros::Duration( req.time_to_wait ).sleep();

		VectorType state;
		if( req.state.size() != 0 )
		{
			if( req.state.size() != PoseSE3::VectorDimension )
			{
				ROS_ERROR_STREAM( "Expected " << PoseSE3::VectorDimension << " dim state but got " << req.state.size() );
				return false;
			}
			Eigen::Map<VectorType> stateMap( req.state.data(), req.state.size() );
			state = stateMap;
		}

		MatrixType cov;
		if( req.covariance.size() != 0 )
		{
			if( req.covariance.size() != PoseSE3::TangentDimension * PoseSE3::TangentDimension )
			{
				ROS_ERROR_STREAM( "Expected " << PoseSE3::TangentDimension * PoseSE3::TangentDimension <<
				                  " dim state but got " << req.covariance.size() );
			}
			Eigen::Map<MatrixType> covMap( req.covariance.data(),
			                               PoseSE3::TangentDimension,
			                               PoseSE3::TangentDimension );
			cov = covMap;
		}

		_estimator.Reset( req.filter_time, state, cov );

		_initialized = !req.filter_time.isZero();
		_updateTimer.stop();
		_updateTimer.start();
		return true;
	}

	EIGEN_MAKE_ALIGNED_OPERATOR_NEW;

private:

	bool _initialized;

	ExtrinsicsInterface::Ptr _extrinsicsManager;
	std::vector<ros::Subscriber> _updateSubs;

	bool _publishOdom;
	ros::Publisher _odomPub;
	bool _publishPose;
	ros::Publisher _posePub;
	bool _publishPoseCov;
	ros::Publisher _poseCovPub;
	bool _publishInfo;
	ros::Publisher _infoPub;
	bool _publishTf;

	ros::Subscriber _velSub;
	PoseSE3::CovarianceMatrix _velCov;

	ros::ServiceServer _resetServer;
	ros::Timer _updateTimer;
	double _updateRate;

	ros::Duration _headLag;
	PoseEstimator _estimator;
	Mutex _estimatorMutex;
};

int main( int argc, char ** argv )
{
	ros::init( argc, argv, "pose_estimator_node" );

	ros::NodeHandle nh;
	ros::NodeHandle ph( "~" );
	PoseEstimatorNode estimator( nh, ph );

	unsigned int numThreads;
	GetParam( ph, "num_threads", numThreads, (unsigned int) 1 );
	ros::AsyncSpinner spinner( numThreads );
	spinner.start();
	ros::waitForShutdown();

	return 0;
}

ext: cpp

max_stars_repo_name: Humhu/fieldtrack

max_issues_repo_name: Humhu/fieldtrack

max_forks_repo_name: Humhu/fieldtrack


text:
#include "tun.hpp"

#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <glog/logging.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <boost/program_options.hpp>
#include <atomic>
#include <iomanip>
#include <utility>

using boost::asio::ip::udp;
using namespace std;

constexpr size_t max_length = 65536;
enum class Type { Server, Client };

template <typename T>
class Counter {
public:
  Counter(std::string name) :name(move(name)) { }

  void Increase(T delta) {
    counter += delta;
  }
  std::string PrintSinceLastUpdate() {
    T value = counter;
    auto now = chrono::high_resolution_clock::now();
    std::chrono::duration<double> d = now - last_update;
    auto d1 = d.count() == 0 ? 1 : d.count();
    auto rate = (value - last_value) / d1;
    last_value = value;
    last_update = now;

    std::stringstream ss;
    ss << name << ": " << std::setw(2) << rate << " B/s";
    return ss.str();
  }
private:
  std::atomic<T> counter{};
  T last_value{};
  std::chrono::high_resolution_clock::time_point last_update{};
  std::string name;
};

void run(boost::asio::io_context& io_context,
    const std::string &host,
    unsigned short port,
    Type type,
    int tunfd) {

  udp::socket local_sock(io_context, udp::endpoint(
      boost::asio::ip::make_address_v4(type == Type::Server ? host : "0.0.0.0"), type == Type::Server ? port : 0));

  udp::endpoint peer_endpoint(
      boost::asio::ip::make_address_v4(type == Type::Server ? "0.0.0.0" : host), type == Type::Server ? 0 : port);

  std::atomic<bool> connected = false;
  Counter<int64_t> counters[] = {{"sent_tun"}, {"received_tun"}, {"sent_sock"}, {"received_sock"}};

  thread sock2tun([&local_sock, type, tunfd, &peer_endpoint, &connected, &counters]() {
    udp::endpoint sender_endpoint;
    for (;;) {
      char data[max_length];
      size_t length = local_sock.receive_from(
          boost::asio::buffer(data, max_length), sender_endpoint);

      counters[3].Increase(length);

      if (type == Type::Server) {
        peer_endpoint = sender_endpoint;
        connected = true;
      } else {
        if (peer_endpoint.size() && sender_endpoint != peer_endpoint)
          continue; // just ignore
      }

      auto nwrite = write(tunfd, data, length);
      CHECK(nwrite == length);
      counters[0].Increase(nwrite);
    }
  });

  thread tun2sock([&local_sock, type, tunfd, &peer_endpoint, &connected, &counters]() {
    for (;;) {
      char data[max_length];
      auto nread = read(tunfd, data, max_length);
      CHECK(nread > 0);
      counters[1].Increase(nread);

      if (type == Type::Server && !connected) {
        continue;
      }
      auto nwrite = local_sock.send_to(boost::asio::buffer(data, nread), peer_endpoint);
      CHECK(nwrite == nread);
      counters[2].Increase(nread);
    }
  });

  thread([&]() {
    while (true) {
      std::this_thread::sleep_for(std::chrono::seconds(1));
      stringstream ss;
      for (auto &counter : counters) {
        ss << counter.PrintSinceLastUpdate() << ", ";
      }
      LOG(WARNING) << ss.str();
    }
  }).detach();

  sock2tun.join();
  tun2sock.join();
}

namespace po = boost::program_options;

int main(int argc, char* argv[]) {
  try {
    std::string tun_if_name;
    std::string host;
    unsigned short port;
    bool is_server{};

    po::options_description desc_env;
    desc_env.add_options()
        ("tun-if-name", po::value(&tun_if_name)->default_value("tun1"))

        ("host", po::value(&host)->default_value(""))
        ("port", po::value(&port)->default_value(1234))
        ("server,s", po::value(&is_server))
        ;

    po::variables_map vm_env;

    boost::program_options::store(
        boost::program_options::parse_command_line(argc, argv, desc_env),
        vm_env
    );
    boost::program_options::notify(vm_env);

    Type type = is_server ? Type::Server : Type::Client;

    boost::asio::io_context io_context;
    char tundevname[32] = {0};
    strcpy(tundevname, tun_if_name.c_str());
    int tunfd = tun_alloc(tundevname, IFF_TUN | IFF_NO_PI);
    if (tunfd < 0) {
      perror("tunalloc");
      abort();
    }
    run(io_context, host, port, type, tunfd);
  }
  catch (std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}


text:
#include "catch.hpp"
#include <Eigen/core>
#include <squanch/IgaAlgorithms.h>
#include <squanch/Line.h>
#include <squanch/Extrude.h>
#include "DebugTools.h"

TEST_CASE("exture", "[extrude]")
{
  SECTION("rectangle")
  {
    using namespace squanch;
    using namespace Eigen;
    // create a line
    Line<double, Vector3d> line;
    line.p1 = Vector3d(5, 0, 0);
    line.p2 = Vector3d(10, 0, 0);

    squanch::Model<double> model;
    Eigen::VectorXd r = Eigen::VectorXd::Zero(4);

    auto&& nline = line.to_nurbs(model);
    Eigen::Vector4d vec(0, 10, 0, 0);
    auto&& rect = squanch::extrude(model, nline, vec);

    std::array<double, 2> u;
    std::array<unsigned int, 2> span;
    Eigen::VectorXd weights(4);
    Eigen::Vector4d p;
    for (size_t i = 0; i < 11; ++i) {
      u[0] = i * 0.1;
      span[0] = find_span(rect.curves()[0].knots(), rect.curves()[0].p(), u[0]);
      for (size_t j = 0; j < 11; ++j) {
        u[1] = j * 0.1;
        span[1] = find_span(rect.curves()[1].knots(), rect.curves()[1].p(), u[1]);
        gather_weights(model, rect, span, weights);
        compute_nurbs_basis(rect, span, u, weights, r);
        compute_model_coordinate(model, rect, span, r, p);

        REQUIRE(p.x() == Approx(5.0 + u[0] * 5));
        REQUIRE(p.y() == Approx(u[1] * 10));
        REQUIRE(p.z() == Approx(0));
        REQUIRE(p.w() == Approx(1));
      }
    }
  }

  SECTION("cube")
  {
    using namespace squanch;
    using namespace Eigen;
    // create a line
    Line<double, Vector3d> line;
    line.p1 = Vector3d(5, 0, 0);
    line.p2 = Vector3d(10, 0, 0);

    int id_s = 0;
    squanch::Model<double> model;
    Eigen::VectorXd r = Eigen::VectorXd::Zero(8);
    Eigen::VectorXd weights(8);

    auto&& nline = line.to_nurbs(model);
    Eigen::Vector4d vec(0, 10, 0, 0);
    auto&& rect = squanch::extrude(model, nline, vec);
    Eigen::Vector4d vec2(0, 0, 7.5, 0);
    auto&& cube = squanch::extrude(model, rect, vec2);

    std::array<double, 3> u;
    std::array<unsigned int, 3> span;
    Eigen::Vector4d p;
    for (size_t i = 0; i < 11; ++i) {
      u[0] = i * 0.1;
      span[0] = find_span(cube.curves()[0].knots(), cube.curves()[0].p(), u[0]);
      for (size_t j = 0; j < 11; ++j) {
        u[1] = j * 0.1;
        span[1] = find_span(cube.curves()[1].knots(), cube.curves()[1].p(), u[1]);
        for (size_t k = 0; k < 11; ++k) {
          u[2] = k * 0.1;
          span[2] = find_span(cube.curves()[2].knots(), cube.curves()[2].p(), u[2]);

          gather_weights(model, cube, span, weights);
          compute_nurbs_basis(cube, span, u, weights, r);
          compute_model_coordinate(model, cube, span, r, p);

          REQUIRE(p.x() == Approx(5.0 + u[0] * 5));
          REQUIRE(p.y() == Approx(u[1] * 10));
          REQUIRE(p.z() == Approx(u[2] * 7.5));
          REQUIRE(p.w() == Approx(1));
        }
      }
    }
  }
}

max_stars_repo_name: tuncb/squanch

max_issues_repo_name: tuncb/squanch

max_forks_repo_name: tuncb/squanch


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

#define BOOST_TEST_MODULE as_waksman_components_test

#include <boost/test/unit_test.hpp>

#include <nil/crypto3/algebra/curves/bn128.hpp>
#include <nil/crypto3/algebra/curves/edwards.hpp>
#include <nil/crypto3/algebra/curves/mnt4.hpp>
#include <nil/crypto3/algebra/curves/mnt6.hpp>

#include <nil/crypto3/zk/snark/components/routing/as_waksman_components.hpp>

using namespace nil::crypto3;
using namespace nil::crypto3::zk;
using namespace nil::crypto3::algebra;

template<typename FieldType>
void test_as_waksman_routing_component(const std::size_t num_packets, const std::size_t packet_size) {
    components::blueprint<FieldType> bp;
    integer_permutation permutation(num_packets);
    permutation.random_shuffle();

    std::vector<components::blueprint_variable_vector<FieldType>> randbits(num_packets), outbits(num_packets);
    for (std::size_t packet_idx = 0; packet_idx < num_packets; ++packet_idx) {
        randbits[packet_idx].allocate(bp, packet_size);
        outbits[packet_idx].allocate(bp, packet_size);

        for (std::size_t bit_idx = 0; bit_idx < packet_size; ++bit_idx) {
            bp.val(randbits[packet_idx][bit_idx]) =
                (rand() % 2) ? FieldType::value_type::zero() : FieldType::value_type::zero();
        }
    }
    as_waksman_routing_component<FieldType> r(bp, num_packets, randbits, outbits);
    r.generate_r1cs_constraints();

    r.generate_r1cs_witness(permutation);

    BOOST_CHECK(bp.is_satisfied());
    for (std::size_t packet_idx = 0; packet_idx < num_packets; ++packet_idx) {
        for (std::size_t bit_idx = 0; bit_idx < packet_size; ++bit_idx) {
            BOOST_CHECK(bp.val(outbits[permutation.get(packet_idx)][bit_idx]) == bp.val(randbits[packet_idx][bit_idx]));
        }
    }

    bp.val(components::blueprint_variable<FieldType>(10)) = typename FieldType::value_type(12345);
    BOOST_CHECK(!bp.is_satisfied());
}

BOOST_AUTO_TEST_SUITE(as_waksman_components_test_suite)

BOOST_AUTO_TEST_CASE(as_waksman_components_test) {
}

BOOST_AUTO_TEST_SUITE_END()


text:
/*
 * Copyright (c) 2020, EDEL LLC <http://www.edelsys.com>
 * All Rights Reserved
 *
 * Licensed under the MIT License;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "muroute/funtcpclient.h"

#include <glog/logging.h>

#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>

#include "muqueue/erqperiodic.h"
#include "muroute/muroute.h"

using namespace fflow;
using namespace fflow::proto;
using namespace boost::asio;
using namespace boost::asio::ip;

EdgeTcpClient::EdgeTcpClient() : tcpSocket(*this) {
  AbstractEdgeInterface::name = "EdgeTcpClient";
}

EdgeTcpClient::~EdgeTcpClient() {
  stop();
  if (dontuseme.joinable()) dontuseme.join();
}

bool EdgeTcpClient::open(uint32_t _port) { return open("127.0.0.1", _port); }

// iface is an ip address
bool EdgeTcpClient::open(const std::string &iface, uint32_t _port) {
  bool ret = true;

  try {
    remoteEndpoint = boost::asio::ip::tcp::endpoint(
        boost::asio::ip::address::from_string(iface), _port);

    VLOG(1) << " connecting to " << remoteEndpoint.address().to_string();
    VLOG(2) << remoteEndpoint.address().to_string() << ":" << _port;
    VLOG(2) << selfEndpoint.address().to_string();
    VLOG(2) << bcast.to_string();
    VLOG(2) << "---\n";

    tcpSocket.connect(remoteEndpoint);

    recv_top();

    // announce route info periodically
    //    add_periodic<void>(([&](void) -> void { notifyrouteinfo(); }),
    //    .27, 1.0);

    // start io service
    dontuseme = std::thread([&] { run(); });
    dontuseme.detach();

  } catch (const std::exception &ex) {
    LOG(ERROR) << ex.what();
    ret = false;
  }

  return ret;
}

void EdgeTcpClient::sendtoraw(std::vector<uint8_t> &msg,
                              const native_addr_t & /*to*/,
                              const native_addr_t & /*from*/,
                              uint32_t from_edge_id) {
  std::array<ioas::const_buffer, 1> buf;

  if (from_edge_id == edge_id) {
    VLOG(6) << "Message Loop DETECTED";
    return;
  }

  buf[0] = ioas::buffer(&msg[0], msg.size());

  tcpSocket.async_write_some(buf,
                             [&](const ioas_err_t &, std::size_t) -> void {});
}

void EdgeTcpClient::notifyrouteinfo() {
  std::shared_ptr<__muflow_packet__> msg =
      std::make_shared<__muflow_packet__>(FLOWPROTO_ID_ROUTEINFO);

  msg->alloc(sizeof(uint32_t) * ports_in_use.size());

  int i = 0;
  for (const auto port : ports_in_use) {
    *reinterpret_cast<uint32_t *>(&msg->payload[i * sizeof(uint32_t)]) =
        htonl(port);
  }

  // prepare buffers
  std::array<ioas::const_buffer, 1> buf;
  buf[0] = ioas::buffer(&msg->msgdata[0], msg->msgdata.size());

  // send ports announcements to ports
  for (__UNUSED__ const auto &port : ports_in_use) {
    tcpSocket.async_write_some(
        buf, [&](const ioas_err_t &error, std::size_t) -> void {
          if (error) {
            LOG(WARNING) << error.message() << std::endl;
          }
        });
  }
}

// FIMXE: bottleneck
void EdgeTcpClient::recv_top() {
  std::array<ioas::mutable_buffer, 1> buf;

  msgdata.resize(TR_MAX_PAYLOAD_LEN);

  buf[0] = ioas::buffer(&msgdata[0], msgdata.size());

  ioas_err_t error;
  tcpSocket.async_read_some(
      buf, [this](const ioas_err_t &error, std::size_t bytes) -> void {
        std::vector<uint8_t> _msgdata(msgdata.begin(), msgdata.begin() + bytes);

        recv_bottom(_msgdata, error);
      });
}

/// \todo need length of packet to be passed here
void EdgeTcpClient::recv_bottom(std::vector<uint8_t> msgdata,
                                const ioas_err_t &error) {
  if (!error) {
    if (remoteEndpoint != selfEndpoint) {
      struct sockaddr_in sa;
      sa.sin_addr.s_addr = htonl(remoteEndpoint.address().to_v4().to_ulong());
      sa.sin_port = htons(remoteEndpoint.port());

      native_addr_t naddr;
      naddr.typ = FLOWADDR_UNICAST;
      naddr.addr.in = sa;
      naddr.len = sizeof(sa);

      if (recv_cb) recv_cb(edge_id, msgdata, naddr);
    }
  }

  recv_top();
}

ext: cc

max_stars_repo_name: edelsys/colibri

max_issues_repo_name: edelsys/colibri

max_forks_repo_name: edelsys/colibri


text:
////////////////////////////////////////////////////////////////////////////////////////////////////
// PagesToJson.cpp
// Copyright (c) 2018 Pdfix. All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////

#include "pdfixsdksamples/PagesToJson.h"

// system
#include <string>
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
// project
#include "Pdfix.h"
#include "pdfixsdksamples/ExtractText.h"

using namespace PDFixSDK;
using namespace boost::property_tree;

namespace PagesToJson {
  void ProcessPage(PdfPage* page, ptree& json, int flags) {
    json.put("number", page->GetNumber() + 1);

    if (flags & kFlagExportGeometry) {
      auto crop = page->GetCropBox();
      json.put("width", crop.right - crop.left);
      json.put("height", crop.top - crop.bottom);
      json.put("rotate", page->GetRotate());
    }

    if (flags & kFlagExportText) {
      std::stringstream ss;
      ExtractText::GetPageText(page, ss);
      json.put("text", ss.str());
    }
  }

  // Extract all documents bookmars into json.
  void Run(
    const std::wstring& open_path,                      // source PDF document
    const std::wstring& password,                       // open document password
    std::ostream& output,                               // output stream
    int export_flags,                                   // export flags
    int page_num                                        // page number to process
  ) {
    // initialize Pdfix
    if (!Pdfix_init(Pdfix_MODULE_NAME))
      throw std::runtime_error("Pdfix initialization fail");

    Pdfix* pdfix = GetPdfix();
    if (!pdfix)
      throw std::runtime_error("GetPdfix fail");

    PdfDoc* doc = nullptr;
    doc = pdfix->OpenDoc(open_path.c_str(), password.c_str());
    if (!doc)
      throw PdfixException();

    int from_page = page_num == -1 ? 0 : page_num;
    int to_page = page_num == -1 ? doc->GetNumPages() - 1 : page_num;

    ptree pages_root;

    for (int i = from_page; i <= to_page; i++) {
      std::unique_ptr<PdfPage, decltype(page_deleter)> page(doc->AcquirePage(i), page_deleter);
      if (!page)
        throw PdfixException();

      ptree page_json;
      ProcessPage(page.get(), page_json, export_flags);
      pages_root.push_back(std::make_pair("", page_json));
    }

    ptree output_json;
    output_json.add_child("pages", pages_root);

    write_json(output, output_json, false);

    doc->Close();
    pdfix->Destroy();
  }
}

max_stars_repo_name: laoola/ProjectCode

max_issues_repo_name: laoola/ProjectCode

max_forks_repo_name: laoola/ProjectCode


text:
//
// Copyright 2018 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "pxr/pxr.h"
#include "pxr/usd/usd/zipFile.h"
#include "pxr/usd/ar/asset.h"
#include "pxr/usd/ar/resolvedPath.h"
#include "pxr/usd/ar/resolver.h"

#include "pxr/base/arch/fileSystem.h"
#include "pxr/base/tf/diagnostic.h"
#include "pxr/base/tf/errorMark.h"
#include "pxr/base/tf/pathUtils.h"
#include "pxr/base/tf/safeOutputFile.h"

#include <boost/crc.hpp>

#include <cstdint>
#include <ctime>
#include <vector>

PXR_NAMESPACE_OPEN_SCOPE

namespace
{

// Metafunction that determines if a T instance can be read/written by simple
// bitwise copy.
//
// XXX: This could be std::is_trivially_copyable, but that isn't implemented in
//      older versions of gcc.
template <class T>
struct _IsBitwiseReadWrite {
    static const bool value =
        std::is_enum<T>::value ||
        std::is_arithmetic<T>::value ||
        std::is_trivial<T>::value;
};

struct _InputStream {
    _InputStream(const char* buffer, size_t size, size_t offset = 0)
        : _cur(buffer + offset)
        , _size(size)
        , _buffer(buffer)
    { }

    size_t RemainingSize() const
    {
        return _size - (_cur - _buffer);
    }

    template <class T>
    void Read(T* dest)
    {
        static_assert(_IsBitwiseReadWrite<T>::value,
                      "Cannot memcpy to non-trivially-copyable type");
        memcpy(reinterpret_cast<char*>(dest), _cur, sizeof(T));
        _cur += sizeof(T);
    }

    inline void Read(void* dest, size_t nBytes)
    {
        memcpy(dest, _cur, nBytes);
        _cur += nBytes;
    }

    inline void Advance(size_t offset)
    {
        _cur += offset;
    }

    inline size_t Tell() const
    {
        return (_cur - _buffer);
    }

    inline const char* TellMemoryAddress() const
    {
        return _cur;
    }

private:
    const char* _cur;
    size_t _size;
    const char* _buffer;
};

struct _OutputStream
{
    _OutputStream(FILE* f) : _f(f) { }

    template <class T>
    inline void Write(const T& value)
    {
        static_assert(_IsBitwiseReadWrite<T>::value,
                      "Cannot fwrite non-trivially-copyable type");
        fwrite(&value, sizeof(T), 1, _f);
    }

    inline void Write(const char* buffer, size_t numBytes)
    {
        fwrite(buffer, /* size = */ 1, /* count = */ numBytes, _f);
    }

    inline long Tell() const
    {
        return ftell(_f);
    }

private:
    FILE* _f;
};

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

// Local file header for each file in the zip archive.
//
// See section 4.3.7 in zip file specification for more details.
struct _LocalFileHeader
{
    static const uint32_t Signature = 0x04034b50;

    struct Fixed {
        uint32_t signature;
        uint16_t versionForExtract;
        uint16_t bits;
        uint16_t compressionMethod;
        uint16_t lastModTime;
        uint16_t lastModDate;
        uint32_t crc32;
        uint32_t compressedSize;
        uint32_t uncompressedSize;
        uint16_t filenameLength;
        uint16_t extraFieldLength;
    };

    static const size_t FixedSize =
        sizeof(uint32_t) * 4 + sizeof(uint16_t) * 7;
    static_assert(sizeof(Fixed) >= FixedSize, "");

    // Fixed-length header
    Fixed f;

    // NOTE:
    // const char* values below do not point to null-terminated strings.
    // Use indicated memory ranges.

    // Filename in [filenameStart, filenameStart + f.filenameLength)
    const char* filenameStart;
    // Extra data in [extraFieldStart, extraFieldStart + f.extraFieldLength)
    const char* extraFieldStart;
    // File data in [dataStart, dataStart + f.compressedSize)
    const char* dataStart;

    // Return true if the required signature is stored in this header.
    bool IsValid() const
    {
        return f.signature == Signature;
    }
};

// Read _LocalFileHeader from input stream. Returns an invalid _LocalFileHeader
// if an error occurs or the input stream is too small.
_LocalFileHeader
_ReadLocalFileHeader(_InputStream& src)
{
    // If the source does not have enough bytes to accommodate the
    // fixed-sized portion of the header, bail out so we don't try to
    // read off the end of the source.
    if (src.RemainingSize() < _LocalFileHeader::FixedSize) {
        return _LocalFileHeader();
    }

    _LocalFileHeader h;

    // If signature is not the expected value, reset the source back to
    // its original position and bail.
    src.Read(&h.f.signature);
    if (!h.IsValid()) {
        src.Advance(-sizeof(decltype(h.f.signature)));
        return _LocalFileHeader();
    }

    src.Read(&h.f.versionForExtract);
    src.Read(&h.f.bits);
    src.Read(&h.f.compressionMethod);
    src.Read(&h.f.lastModTime);
    src.Read(&h.f.lastModDate);
    src.Read(&h.f.crc32);
    src.Read(&h.f.compressedSize);
    src.Read(&h.f.uncompressedSize);
    src.Read(&h.f.filenameLength);
    src.Read(&h.f.extraFieldLength);

    if (src.RemainingSize() < h.f.filenameLength) {
        return _LocalFileHeader();
    }

    h.filenameStart = src.TellMemoryAddress();
    src.Advance(h.f.filenameLength);

    if (src.RemainingSize() < h.f.extraFieldLength) {
        return _LocalFileHeader();
    }

    h.extraFieldStart = src.TellMemoryAddress();
    src.Advance(h.f.extraFieldLength);

    if (src.RemainingSize() < h.f.compressedSize) {
        return _LocalFileHeader();
    }

    h.dataStart = src.TellMemoryAddress();
    src.Advance(h.f.compressedSize);

    return h;
}

// Write given _LocalFileHeader to given output stream.
void
_WriteLocalFileHeader(_OutputStream& out, const _LocalFileHeader& h)
{
    out.Write(h.f.signature);
    out.Write(h.f.versionForExtract);
    out.Write(h.f.bits);
    out.Write(h.f.compressionMethod);
    out.Write(h.f.lastModTime);
    out.Write(h.f.lastModDate);
    out.Write(h.f.crc32);
    out.Write(h.f.compressedSize);
    out.Write(h.f.uncompressedSize);
    out.Write(h.f.filenameLength);
    out.Write(h.f.extraFieldLength);
    out.Write(h.filenameStart, h.f.filenameLength);
    out.Write(h.extraFieldStart, h.f.extraFieldLength);
    out.Write(h.dataStart, h.f.compressedSize);
}

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

// Central directory header for each file in the zip archive. These headers
// are stored after the data for the last file.
//
// See section 4.3.12 in zip file specification for more details.
struct _CentralDirectoryHeader
{
    static const uint32_t Signature = 0x02014b50;

    struct Fixed {
        uint32_t signature;
        uint16_t versionMadeBy;
        uint16_t versionForExtract;
        uint16_t bits;
        uint16_t compressionMethod;
        uint16_t lastModTime;
        uint16_t lastModDate;
        uint32_t crc32;
        uint32_t compressedSize;
        uint32_t uncompressedSize;
        uint16_t filenameLength;
        uint16_t extraFieldLength;
        uint16_t commentLength;
        uint16_t diskNumberStart;
        uint16_t internalAttrs;
        uint32_t externalAttrs;
        uint32_t localHeaderOffset;
    };

    static const size_t FixedSize =
        sizeof(uint32_t) * 6 + sizeof(uint16_t) * 11;
    static_assert(sizeof(Fixed) >= FixedSize, "");

    // Fixed-length header
    Fixed f;

    // NOTE:
    // const char* values below do not point to null-terminated strings.
    // Use indicated memory ranges.

    // Filename in [filenameStart, filenameStart + f.filenameLength)
    const char* filenameStart;
    // Extra data in [extraFieldStart, extraFieldStart + f.extraFieldLength)
    const char* extraFieldStart;
    // Comment in [commentStart, commentStart + f.commentLength)
    const char* commentStart;

    // Return true if the required signature is stored in this header.
    bool IsValid() const
    {
        return f.signature == Signature;
    }
};

// Write given _CentralDirectoryHeader to given output stream.
void
_WriteCentralDirectoryHeader(
    _OutputStream& out, const _CentralDirectoryHeader& h)
{
    out.Write(h.f.signature);
    out.Write(h.f.versionMadeBy);
    out.Write(h.f.versionForExtract);
    out.Write(h.f.bits);
    out.Write(h.f.compressionMethod);
    out.Write(h.f.lastModTime);
    out.Write(h.f.lastModDate);
    out.Write(h.f.crc32);
    out.Write(h.f.compressedSize);
    out.Write(h.f.uncompressedSize);
    out.Write(h.f.filenameLength);
    out.Write(h.f.extraFieldLength);
    out.Write(h.f.commentLength);
    out.Write(h.f.diskNumberStart);
    out.Write(h.f.internalAttrs);
    out.Write(h.f.externalAttrs);
    out.Write(h.f.localHeaderOffset);
    out.Write(h.filenameStart, h.f.filenameLength);
    out.Write(h.extraFieldStart, h.f.extraFieldLength);
    out.Write(h.commentStart, h.f.commentLength);
}

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

// End of central directory record for zip archive. This header is stored
// after the last central directory header.
struct _EndOfCentralDirectoryRecord
{
    static const uint32_t Signature = 0x06054b50;

    struct Fixed {
        uint32_t signature;
        uint16_t diskNumber;
        uint16_t diskNumberForCentralDir;
        uint16_t numCentralDirEntriesOnDisk;
        uint16_t numCentralDirEntries;
        uint32_t centralDirLength;
        uint32_t centralDirOffset;
        uint16_t commentLength;
    };

    static const size_t FixedSize =
        sizeof(uint32_t) * 3 + sizeof(uint16_t) * 5;
    static_assert(sizeof(Fixed) >= FixedSize, "");

    // Fixed-length header
    Fixed f;

    // NOTE:
    // const char* values below do not point to null-terminated strings.
    // Use indicated memory ranges.

    // Comment in [commentStart, commentStart + f.commentLength)
    const char* commentStart;

    // Return true if the required signature is stored in this header.
    bool IsValid() const
    {
        return f.signature == Signature;
    }
};

// Write given _EndOfCentralDirectoryRecord to given output stream.
void
_WriteEndOfCentralDirectoryRecord(
    _OutputStream& out, const _EndOfCentralDirectoryRecord& r)
{
    out.Write(r.f.signature);
    out.Write(r.f.diskNumber);
    out.Write(r.f.diskNumberForCentralDir);
    out.Write(r.f.numCentralDirEntriesOnDisk);
    out.Write(r.f.numCentralDirEntries);
    out.Write(r.f.centralDirLength);
    out.Write(r.f.centralDirOffset);
    out.Write(r.f.commentLength);
    out.Write(r.commentStart, r.f.commentLength);
}

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

// Per usdz specifications, file data must be aligned to 64 byte boundaries.
// UsdZipFileWriter adds padding bytes to the 'extra' extensible data field
// described in section 4.5 of the zip specification to achieve this. This
// is complicated by the requirement that each entry in the 'extra' field
// be preceded by a 4 byte header.

struct _ExtraFieldHeader
{
    uint16_t headerId;
    uint16_t dataSize;
};

constexpr size_t _HeaderSize = sizeof(uint16_t) * 2;
constexpr size_t _DataAlignment = 64;

// Maximum size of buffer needed for padding bytes.
constexpr size_t _PaddingBufferSize = _HeaderSize + _DataAlignment;

// Compute the number of padding bytes (including header) needed to align
// data at the given offset to the required alignment.
uint16_t
_ComputeExtraFieldPaddingSize(size_t offset)
{
    uint16_t requiredPadding = _DataAlignment - (offset % _DataAlignment);
    if (requiredPadding == _DataAlignment) {
        requiredPadding = 0;
    }
    else if (requiredPadding < _HeaderSize) {
        // If the amount of padding needed is too small to contain the header,
        // bump the size up while maintaining the required alignment.
        requiredPadding += _DataAlignment;
    }
    return requiredPadding;
}

// Fill the given extraFieldBuffer to accommodate the specified number of
// padding bytes. For convenience, returns extraFieldBuffer.
const char*
_PrepareExtraFieldPadding(
    char (&extraFieldBuffer)[_PaddingBufferSize],
    uint16_t numPaddingBytes)
{
    if (numPaddingBytes == 0) {
        return nullptr;
    }

    TF_VERIFY(numPaddingBytes >= _HeaderSize);
    TF_VERIFY(numPaddingBytes <= sizeof(extraFieldBuffer));

    _ExtraFieldHeader header;
    header.headerId = 0x1986; // Arbitrarily chosen, unreserved ID.
    header.dataSize = numPaddingBytes - _HeaderSize;

    memcpy(extraFieldBuffer, &header.headerId, sizeof(header.headerId)) ;
    memcpy(extraFieldBuffer + sizeof(header.headerId),
        &header.dataSize, sizeof(header.dataSize));

    return extraFieldBuffer;
}

} // end anonymous namespace

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

class UsdZipFile::_Impl
{
public:
    _Impl(std::shared_ptr<const char>&& buffer_, size_t size_)
        : storage(std::move(buffer_))
        , buffer(storage.get())
        , size(size_)
    { }

    std::shared_ptr<const char> storage;

    // This is the same as storage.get(), but saved separately to simplify
    // code so they don't have to call storage.get() all the time.
    const char* buffer;
    size_t size;
};

UsdZipFile
UsdZipFile::Open(const std::string& filePath)
{
    std::shared_ptr<ArAsset> asset = ArGetResolver().OpenAsset(
        ArResolvedPath(filePath));
    if (!asset) {
        return UsdZipFile();
    }

    return Open(asset);
}

UsdZipFile
UsdZipFile::Open(const std::shared_ptr<ArAsset>& asset)
{
    if (!asset) {
        TF_CODING_ERROR("Invalid asset");
        return UsdZipFile();
    }

    std::shared_ptr<const char> buffer = asset->GetBuffer();
    if (!buffer) {
        TF_RUNTIME_ERROR("Could not retrieve buffer from asset");
        return UsdZipFile();
    }

    return UsdZipFile(std::shared_ptr<_Impl>(
        new _Impl(std::move(buffer), asset->GetSize())));
}

UsdZipFile::UsdZipFile(std::shared_ptr<_Impl>&& impl)
    : _impl(std::move(impl))
{
}

UsdZipFile::UsdZipFile()
{
}

UsdZipFile::~UsdZipFile()
{
}

void
UsdZipFile::DumpContents() const
{
    printf("    Offset\t      Comp\t    Uncomp\tName\n");
    printf("    ------\t      ----\t    ------\t----\n");

    size_t n = 0;
    for (auto it = begin(), e = end(); it != e; ++it, ++n) {
        const FileInfo info = it.GetFileInfo();
        printf("%10zu\t%10zu\t%10zu\t%s\n",
            info.dataOffset, info.size, info.uncompressedSize,
            it->c_str());
    }

    printf("----------\n");
    printf("%zu files total\n", n);
}

UsdZipFile::Iterator
UsdZipFile::Find(const std::string& path) const
{
    return std::find(begin(), end(), path);
}

UsdZipFile::Iterator
UsdZipFile::begin() const
{
    return Iterator(_impl.get());
}

UsdZipFile::Iterator
UsdZipFile::end() const
{
    return Iterator();
}

UsdZipFile::Iterator::Iterator()
    : _impl(nullptr)
    , _offset(0)
{
}

UsdZipFile::Iterator::Iterator(const _Impl* impl)
    : _impl(impl)
    , _offset(0)
{
    _InputStream src(_impl->buffer, _impl->size, _offset);
    if (!_ReadLocalFileHeader(src).IsValid()) {
        *this = Iterator();
    }
}

UsdZipFile::Iterator::reference
UsdZipFile::Iterator::operator*() const
{
    _InputStream src(_impl->buffer, _impl->size, _offset);
    _LocalFileHeader h = _ReadLocalFileHeader(src);
    return std::string(h.filenameStart, h.f.filenameLength);
}

UsdZipFile::Iterator::pointer
UsdZipFile::Iterator::operator->() const
{
    return _ArrowProxy(this->operator*());
}

UsdZipFile::Iterator&
UsdZipFile::Iterator::operator++()
{
    // Advance past the file the iterator is currently pointing
    // to, then check if we can read the next file header. If not,
    // we've hit the end.
    _InputStream src(_impl->buffer, _impl->size, _offset);
    _ReadLocalFileHeader(src);

    size_t newOffset = src.Tell();
    const _LocalFileHeader newHeader = _ReadLocalFileHeader(src);
    if (newHeader.IsValid()) {
        _offset = newOffset;
    }
    else {
        *this = Iterator();
    }
    return *this;
}

UsdZipFile::Iterator
UsdZipFile::Iterator::operator++(int)
{
    Iterator it(*this);
    ++*this;
    return it;
}

bool
UsdZipFile::Iterator::operator==(const Iterator& rhs) const
{
    return _impl == rhs._impl && _offset == rhs._offset;
}

bool
UsdZipFile::Iterator::operator!=(const Iterator& rhs) const
{
    return !(*this == rhs);
}

const char*
UsdZipFile::Iterator::GetFile() const
{
    _InputStream src(_impl->buffer, _impl->size, _offset);
    const _LocalFileHeader h = _ReadLocalFileHeader(src);
    return h.dataStart;
}

UsdZipFile::FileInfo
UsdZipFile::Iterator::GetFileInfo() const
{
    _InputStream src(_impl->buffer, _impl->size, _offset);
    const _LocalFileHeader h = _ReadLocalFileHeader(src);

    FileInfo f;
    f.dataOffset = h.dataStart - _impl->buffer;
    f.size = h.f.compressedSize;
    f.uncompressedSize = h.f.uncompressedSize;
    f.compressionMethod = h.f.compressionMethod;
    f.encrypted = h.f.bits & 0x1; // Per 4.4.4, bit 0 is set if encrypted
    return f;
}

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

namespace
{
// Compute last modified date and time for given file in MS-DOS format.
std::pair<uint16_t, uint16_t>
_ModTimeAndDate(const std::string& filename)
{
    double mtime = 0;
    ArchGetModificationTime(filename.c_str(), &mtime);

    const std::time_t t = static_cast<std::time_t>(mtime);
    const std::tm* localTime = std::localtime(&t);

    // MS-DOS time encoding is a 16-bit value where:
    // - bits 0-4: second divided by 2
    // - bits 5-10: minute (0-59)
    // - bits 11-15: hour (0-23)
    uint16_t modTime =
        static_cast<uint16_t>(localTime->tm_hour) << 11 |
        static_cast<uint16_t>(localTime->tm_min) << 5 |
        static_cast<uint16_t>(localTime->tm_sec / 2);

    // MS-DOS date encoding is a 16-bit value where:
    // - bits 0-4: day of the month (1-31)
    // - bits 5-8: month (1-12)
    // - bits 9-15: year offset from 1980
    uint16_t modDate =
        static_cast<uint16_t>(localTime->tm_year - 80) << 9 |
        static_cast<uint16_t>(localTime->tm_mon + 1) << 5 |
        static_cast<uint16_t>(localTime->tm_mday);

    return std::make_pair(modTime, modDate);
}

// Compute CRC32 checksum for given file per zip specification
uint32_t
_Crc32(const ArchConstFileMapping& file)
{
    boost::crc_32_type result;
    result.process_block(
        file.get(), file.get() + ArchGetFileMappingLength(file));
    return result.checksum();
}

// Sanitize the given path to conform to zip file specifications:
//
//   4.4.17.1 The name of the file, with optional relative path.
//   The path stored MUST not contain a drive or
//   device letter, or a leading slash.  All slashes
//   MUST be forward slashes '/' as opposed to
//   backwards slashes '\' for compatibility with Amiga
//   and UNIX file systems etc.  If input came from standard
//   input, there is no file name field.
std::string
_ZipFilePath(const std::string& filePath)
{
    // TfNormPath will flip all backslashes to forward slashes and
    // strip drive letters.
    std::string result =
        TfNormPath(filePath, /* stripDriveSpecifier = */ true);

    // Strip off any initial slashes.
    result = TfStringTrimLeft(result, "/");
    return result;
}

} // end anonymous namespace

class UsdZipFileWriter::_Impl
{
public:
    _Impl(TfSafeOutputFile&& out)
        : outputFile(std::move(out))
    {
    }

    TfSafeOutputFile outputFile;

    // Record for each file added to the zip file:
    //  - File path in zip file
    //  - Fixed portion of local file header
    //  - Offset from beginning of zip file to start of local file header
    using _Record =
        std::tuple<std::string, _LocalFileHeader::Fixed, uint32_t>;
    std::vector<_Record> addedFiles;
};

UsdZipFileWriter
UsdZipFileWriter::CreateNew(const std::string& filePath)
{
    TfErrorMark mark;
    TfSafeOutputFile outputFile = TfSafeOutputFile::Replace(filePath);
    if (!mark.IsClean()) {
        return UsdZipFileWriter();
    }

    return UsdZipFileWriter(std::unique_ptr<_Impl>(
        new _Impl(std::move(outputFile))));
}

UsdZipFileWriter::UsdZipFileWriter()
{
}

UsdZipFileWriter::UsdZipFileWriter(std::unique_ptr<_Impl>&& impl)
    : _impl(std::move(impl))
{
}

UsdZipFileWriter::UsdZipFileWriter(UsdZipFileWriter&& rhs)
    : _impl(std::move(rhs._impl))
{
}

UsdZipFileWriter&
UsdZipFileWriter::operator=(UsdZipFileWriter&& rhs)
{
    if (this != &rhs) {
        _impl = std::move(rhs._impl);
    }
    return *this;
}

UsdZipFileWriter::~UsdZipFileWriter()
{
    if (_impl) {
        Save();
    }
}

std::string
UsdZipFileWriter::AddFile(
    const std::string& filePath,
    const std::string& filePathInArchiveIn)
{
    if (!_impl) {
        TF_CODING_ERROR("File is not open for writing");
        return std::string();
    }

    const std::string& filePathInArchive =
        filePathInArchiveIn.empty() ? filePath : filePathInArchiveIn;

    // Conform the file path we're writing into the archive to make sure
    // it follows zip file specifications.
    const std::string zipFilePath = _ZipFilePath(filePathInArchive);

    // Check if this file has already been written to this zip archive; if so,
    // just skip it.
    if (std::find_if(
            _impl->addedFiles.begin(), _impl->addedFiles.end(),
            [&zipFilePath](const _Impl::_Record& r) {
                return std::get<0>(r) == zipFilePath;
            }) != _impl->addedFiles.end()) {
        return zipFilePath;
    }

    _OutputStream outStream(_impl->outputFile.Get());

    std::string err;
    ArchConstFileMapping mapping = ArchMapFileReadOnly(filePath, &err);
    if (!mapping) {
        TF_RUNTIME_ERROR(
            "Failed to map '%s': %s", filePath.c_str(), err.c_str());
        return std::string();
    }

    // Set up local file header
    _LocalFileHeader h;
    h.f.signature = _LocalFileHeader::Signature;
    h.f.versionForExtract = 10; // Default value
    h.f.bits = 0;
    h.f.compressionMethod = 0; // No compression
    std::tie(h.f.lastModTime, h.f.lastModDate) = _ModTimeAndDate(filePath);
    h.f.crc32 = _Crc32(mapping);
    h.f.compressedSize = ArchGetFileMappingLength(mapping);
    h.f.uncompressedSize = ArchGetFileMappingLength(mapping);
    h.f.filenameLength = zipFilePath.length();

    const uint32_t offset = outStream.Tell();
    const size_t dataOffset =
        offset + _LocalFileHeader::FixedSize + h.f.filenameLength;
    h.f.extraFieldLength = _ComputeExtraFieldPaddingSize(dataOffset);

    h.filenameStart = zipFilePath.data();

    char extraFieldBuffer[_PaddingBufferSize] = { 0 };
    h.extraFieldStart = _PrepareExtraFieldPadding(
        extraFieldBuffer, h.f.extraFieldLength);

    h.dataStart = mapping.get();

    _WriteLocalFileHeader(outStream, h);
    _impl->addedFiles.emplace_back(zipFilePath, h.f, offset);

    return zipFilePath;
}

bool
UsdZipFileWriter::Save()
{
    if (!_impl) {
        TF_CODING_ERROR("File is not open for writing");
        return false;
    }

    _OutputStream outStream(_impl->outputFile.Get());

    // Write central directory headers for each file added to the zip archive.
    const long centralDirectoryStart = outStream.Tell();

    for (const _Impl::_Record& record : _impl->addedFiles) {
        const std::string& fileToZip = std::get<0>(record);
        const _LocalFileHeader::Fixed& localHeader = std::get<1>(record);
        uint32_t offset = std::get<2>(record);

        _CentralDirectoryHeader h;
        h.f.signature = _CentralDirectoryHeader::Signature;
        h.f.versionMadeBy = 0;
        h.f.versionForExtract = localHeader.versionForExtract;
        h.f.bits = localHeader.bits;
        h.f.compressionMethod = localHeader.compressionMethod;
        h.f.lastModTime = localHeader.lastModTime;
        h.f.lastModDate = localHeader.lastModDate;
        h.f.crc32 = localHeader.crc32;
        h.f.compressedSize = localHeader.compressedSize;
        h.f.uncompressedSize = localHeader.uncompressedSize;
        h.f.filenameLength = localHeader.filenameLength;
        h.f.extraFieldLength = localHeader.extraFieldLength;
        h.f.commentLength = 0;
        h.f.diskNumberStart = 0;
        h.f.internalAttrs = 0;
        h.f.externalAttrs = 0;
        h.f.localHeaderOffset = offset;
        h.filenameStart = fileToZip.data();

        char extraFieldBuffer[_PaddingBufferSize] = { 0 };
        h.extraFieldStart = _PrepareExtraFieldPadding(
            extraFieldBuffer, h.f.extraFieldLength);

        h.commentStart = nullptr;

        _WriteCentralDirectoryHeader(outStream, h);
    }

    const long centralDirectoryEnd = outStream.Tell();

    // Write the end of central directory record.
    {
        _EndOfCentralDirectoryRecord r;
        r.f.signature = _EndOfCentralDirectoryRecord::Signature;
        r.f.diskNumber = 0;
        r.f.diskNumberForCentralDir = 0;
        r.f.numCentralDirEntriesOnDisk = _impl->addedFiles.size();
        r.f.numCentralDirEntries = _impl->addedFiles.size();
        r.f.centralDirLength = (centralDirectoryEnd - centralDirectoryStart);
        r.f.centralDirOffset = centralDirectoryStart;
        r.f.commentLength = 0;
        r.commentStart = nullptr;

        _WriteEndOfCentralDirectoryRecord(outStream, r);
    }

    _impl->outputFile.Close();
    _impl.reset();

    return true;
}

void
UsdZipFileWriter::Discard()
{
    if (!_impl) {
        TF_CODING_ERROR("File is not open for writing");
        return;
    }

    _impl->outputFile.Discard();
    _impl.reset();
}

PXR_NAMESPACE_CLOSE_SCOPE


text:
// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef IPOD_FUNCTORS_HPP
#define IPOD_FUNCTORS_HPP
#include <boost/msm/front/euml/euml.hpp>

BOOST_MSM_EUML_ACTION(NotHolding_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: NotHolding" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(Holding_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: Holding" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(NotPlaying_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: NotPlaying" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(NoMenuMode_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: NoMenuMode" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(NoOnOffButton_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: NoOnOffButton" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(OffDown_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: OffDown" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(PlayerOff_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: PlayerOff" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(CheckMiddleButton_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: CheckMiddleButton" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(Playing_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM& fsm,STATE& )
    {
        std::cout << "entering: Playing" << std::endl;
        std::cout << "playing song:" << fsm.get_attribute(m_SongIndex) << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(WaitingForNextPrev_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: WaitingForNextPrev" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(Paused_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: Paused" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(WaitingForEnd_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: OffDown" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(NoForward_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: NoForward" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(ForwardPressed_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: ForwardPressed" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(ForwardPressed_Exit)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "leaving: ForwardPressed" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(FastForward_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: FastForward" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(FastForward_Exit)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "leaving: FastForward" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(StdDisplay_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: StdDisplay" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(SetPosition_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: SetPosition" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(SetMark_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: SetMark" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(PlayingExit_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: PlayingExit" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(WaitingForSongChoice_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: WaitingForSongChoice" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(StartCurrentSong_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: StartCurrentSong" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(MenuExit_Entry)
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM&,STATE& )
    {
        std::cout << "entering: MenuExit" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(show_selected_song)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
    {
        std::cout << "selecting song:" << fsm.get_attribute(m_SongIndex) << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(do_fast_forward)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
    {
        std::cout << "moving song forward..." << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(show_playing_song)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
    {
        std::cout << "playing song:" << fsm.get_attribute(m_SongIndex) << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(show_player_off)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
    {
        std::cout << "turning player off" << std::endl;
    }
};
BOOST_MSM_EUML_ACTION(show_player_on)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
    {
        std::cout << "turning player on" << std::endl;
    }
};
#endif

ext: hpp

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
/**
 * @file swiftHelper.cc
 * @author Michal Wrona
 * @copyright (C) 2016 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

#include "swiftHelper.h"
#include "logging.h"

#include <folly/FBString.h>
#include <folly/FBVector.h>
#include <folly/Range.h>
#include <glog/stl_logging.h>
#include <boost/version.hpp>

#undef BOOST_BIND_NO_PLACEHOLDERS
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#define BOOST_BIND_NO_PLACEHOLDERS

namespace std {
template <> struct hash<Poco::Net::HTTPResponse::HTTPStatus> {
    size_t operator()(const Poco::Net::HTTPResponse::HTTPStatus &p) const
    {
        return std::hash<int>()(static_cast<int>(p));
    }
};
}

namespace one {
namespace helpers {

namespace {

std::unordered_map<Poco::Net::HTTPResponse::HTTPStatus, std::errc> errors = {
    {Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND,
        std::errc::no_such_file_or_directory},
    {Poco::Net::HTTPResponse::HTTPStatus::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE,
        std::errc::no_such_file_or_directory},
    {Poco::Net::HTTPResponse::HTTPStatus::HTTP_REQUEST_TIMEOUT,
        std::errc::timed_out},
    {Poco::Net::HTTPResponse::HTTPStatus::HTTP_LENGTH_REQUIRED,
        std::errc::invalid_argument},
    {Poco::Net::HTTPResponse::HTTPStatus::HTTP_UNAUTHORIZED,
        std::errc::permission_denied},
};

template <typename Outcome>
std::error_code getReturnCode(const Outcome &outcome)
{
    auto statusCode = outcome->getResponse()->getStatus();

    auto error = std::errc::io_error;
    auto search = errors.find(statusCode);
    if (search != errors.end())
        error = search->second;

    return std::error_code(static_cast<int>(error), std::system_category());
}

template <typename Outcome>
void throwOnError(folly::fbstring operation, const Outcome &outcome)
{
    if (outcome->getError().code == Swift::SwiftError::SWIFT_OK)
        return;

    auto code = getReturnCode(outcome);
    auto reason =
        "'" + operation.toStdString() + "': " + outcome->getError().msg;

    throw std::system_error{code, std::move(reason)};
}
}

SwiftHelper::SwiftHelper(folly::fbstring containerName,
    const folly::fbstring &authUrl, const folly::fbstring &tenantName,
    const folly::fbstring &userName, const folly::fbstring &password,
    Timeout timeout)
    : m_auth{authUrl, tenantName, userName, password}
    , m_containerName{std::move(containerName)}
    , m_timeout{std::move(timeout)}
{
}

folly::IOBufQueue SwiftHelper::getObject(
    const folly::fbstring &key, const off_t offset, const std::size_t size)
{
    auto &account = m_auth.getAccount();

    Swift::Container container(&account, m_containerName.toStdString());
    Swift::Object object(&container, key.toStdString());

    auto headers = std::vector<Swift::HTTPHeader>({Swift::HTTPHeader("Range",
        rangeToString(offset, static_cast<off_t>(offset + size - 1)))});
    auto getResponse = std::unique_ptr<Swift::SwiftResult<std::istream *>>(
        object.swiftGetObjectContent(nullptr, &headers));
    throwOnError("getObject", getResponse);

    folly::IOBufQueue buf{folly::IOBufQueue::cacheChainLength()};
    char *data = static_cast<char *>(buf.preallocate(size, size).first);

    const auto newTail =
        std::copy(std::istreambuf_iterator<char>{*getResponse->getPayload()},
            std::istreambuf_iterator<char>{}, data);

    buf.postallocate(newTail - data);
    return buf;
}

off_t SwiftHelper::getObjectsSize(
    const folly::fbstring &prefix, const std::size_t objectSize)
{
    auto &account = m_auth.getAccount();

    Swift::Container container(&account, m_containerName.toStdString());
    std::vector<Swift::HTTPHeader> params{
        {Swift::HTTPHeader("prefix", adjustPrefix(prefix))}};

    auto listResponse = std::unique_ptr<Swift::SwiftResult<std::istream *>>(
        container.swiftListObjects(
            Swift::HEADER_FORMAT_APPLICATION_JSON, &params, true));
    throwOnError("getObjectsSize", listResponse);

    boost::property_tree::ptree pt;
    boost::property_tree::read_json(*listResponse->getPayload(), pt);
    if (pt.size() == 0) {
        return 0;
    }

    auto key = pt.get<folly::fbstring>(".name");
    auto size = pt.get<uint64_t>(".bytes");

    return getObjectId(std::move(key)) * objectSize + size;
}

std::size_t SwiftHelper::putObject(
    const folly::fbstring &key, folly::IOBufQueue buf)
{
    auto &account = m_auth.getAccount();

    Swift::Container container(&account, m_containerName.toStdString());
    Swift::Object object(&container, key.toStdString());

    auto iobuf = buf.empty() ? folly::IOBuf::create(0) : buf.move();
    if (iobuf->isChained()) {
        iobuf->unshare();
        iobuf->coalesce();
    }

    auto createResponse = std::unique_ptr<Swift::SwiftResult<int *>>(
        object.swiftCreateReplaceObject(
            reinterpret_cast<const char *>(iobuf->data()), iobuf->length(),
            true));

    throwOnError("putObject", createResponse);

    return iobuf->length();
}

void SwiftHelper::deleteObjects(const folly::fbvector<folly::fbstring> &keys)
{
    auto &account = m_auth.getAccount();

    Swift::Container container(&account, m_containerName.toStdString());
    for (auto offset = 0u; offset < keys.size(); offset += MAX_DELETE_OBJECTS) {
        std::vector<std::string> keyBatch;

        const std::size_t batchSize =
            std::min<std::size_t>(keys.size() - offset, MAX_DELETE_OBJECTS);

        for (auto &key : folly::range(keys.begin(), keys.begin() + batchSize))
            keyBatch.emplace_back(key.toStdString());

        auto deleteResponse =
            std::unique_ptr<Swift::SwiftResult<std::istream *>>{
                container.swiftDeleteObjects(std::move(keyBatch))};

        throwOnError("deleteObjects", deleteResponse);
    }
}

folly::fbvector<folly::fbstring> SwiftHelper::listObjects(
    const folly::fbstring &prefix)
{
    auto &account = m_auth.getAccount();

    Swift::Container container(&account, m_containerName.toStdString());
    auto params = std::vector<Swift::HTTPHeader>(
        {Swift::HTTPHeader("prefix", adjustPrefix(prefix)),
            Swift::HTTPHeader("limit", std::to_string(MAX_LIST_OBJECTS))});

    folly::fbvector<folly::fbstring> objectsList;
    while (true) {
        if (!objectsList.empty()) {
            params.pop_back();
            params.push_back(
                Swift::HTTPHeader("marker", objectsList.back().toStdString()));
        }

        auto listResponse = std::unique_ptr<Swift::SwiftResult<std::istream *>>(
            container.swiftListObjects(
                Swift::HEADER_FORMAT_TEXT_XML, &params, true));

        throwOnError("listObjects", listResponse);

        auto lines = 0;
        for (std::string name;
             std::getline(*listResponse->getPayload(), name);) {
            ++lines;
            objectsList.emplace_back(std::move(name));
        }

        if (lines != MAX_LIST_OBJECTS)
            break;
    };

    return objectsList;
}

SwiftHelper::Authentication::Authentication(const folly::fbstring &authUrl,
    const folly::fbstring &tenantName, const folly::fbstring &userName,
    const folly::fbstring &password)
{
    m_authInfo.username = userName.toStdString();
    m_authInfo.password = password.toStdString();
    m_authInfo.authUrl = authUrl.toStdString();
    m_authInfo.tenantName = tenantName.toStdString();
    m_authInfo.method = Swift::AuthenticationMethod::KEYSTONE;
}

Swift::Account &SwiftHelper::Authentication::getAccount()
{
    std::lock_guard<std::mutex> guard{m_authMutex};
    if (m_account)
        return *m_account;

    auto authResponse = std::unique_ptr<Swift::SwiftResult<Swift::Account *>>(
        Swift::Account::authenticate(m_authInfo, true));
    throwOnError("authenticate", authResponse);

    m_account = std::unique_ptr<Swift::Account>(authResponse->getPayload());
    authResponse->setPayload(nullptr);

    return *m_account;
}

} // namespace helpers
} // namespace one

max_stars_repo_name: kzemek/helpers

max_issues_repo_name: kzemek/helpers

max_forks_repo_name: kzemek/helpers


text:
#ifndef SPLINECLASS_H
#define SPLINECLASS_H

#include <stdexcept>
#include <opencv2/core/core.hpp>
#include <Eigen/Dense>
#include <eigen3/Eigen/src/Core/Matrix.h>
#include <opencv2/opencv.hpp>
#include <opencv/cxeigen.hpp>
#include <chrono>

#include <alglibinternal.h>
#include <interpolation.h>
#include <math.h>
#include <malloc.h>
#include <random>

void test(){
    alglib::real_1d_array X, Z;
}

bool sortX(const Eigen::Vector2f &a, const Eigen::Vector2f &b)
{
    return a(0) < b(0);
}

bool sortY(const Eigen::Vector2f &a, const Eigen::Vector2f &b)
{
    return a(1) < b(1);
}

std::vector<Eigen::Vector2f> getPointsFromVectors(const Eigen::Vector2f &x, const Eigen::Vector2f &z) {
    Eigen::MatrixXf pts_m(x.rows(), x.cols()+z.cols());
    pts_m << x, z;
    long num_pts = x.size();
    std::vector<Eigen::Vector2f> pts(num_pts);
    for(int i=0; i<num_pts; i++)
    {
        pts[i] = pts_m.row(i);
    }
    return pts;
}

bool closestDistance(Eigen::MatrixXf& design_pts, Eigen::MatrixXf& targets, float threshold=0.1, bool debug=false){
    for(int i=0; i<targets.rows(); i++){
        float lowest_l2 = std::numeric_limits<float>::infinity();
        //Eigen::Vector2f closest_point;
        for(int j=0; j<design_pts.rows(); j++){
            if(std::isnan(design_pts(j,0))) continue;
            float l2 = sqrt(pow(targets(i,0)-design_pts(j,0),2) + pow(targets(i,1)-design_pts(j,2),2));
            if(l2 < lowest_l2){
                lowest_l2 = l2;
                //closest_point = Eigen::Vector2f(design_pts(j,0), design_pts(j,2));
            }
            //std::cout << "[" << design_pts(j,0) << ", " << design_pts(j,2) << "]" << std::endl;
        }
        if(lowest_l2 > threshold) return true;
    }
    return false;
}

Eigen::MatrixXf makeRandomWithInputs(Eigen::Vector2f p0, const std::vector<Eigen::Vector2f>& inputs, float height, float width, int num_random_pts, float smoothing_constant, int sample_pts, bool hack=false)
{
    std::random_device seeder;
    std::mt19937 engine(seeder());
    std::uniform_real_distribution<float> dist_x(p0(0), p0(0)+width); // uniform, unbiased
    std::uniform_real_distribution<float> dist_z(p0(1), p0(1)+height); // uniform, unbiased

    std::vector<Eigen::Vector2f> pts;
    for(int i =0; i< num_random_pts; i++)
    {
        if(hack) break;
        float x = dist_x(engine);
        float z = dist_z(engine);
        pts.emplace_back(Eigen::Vector2f(x,z));
    }

    // Handle Inputs
    for(const auto& inp : inputs){
        std::normal_distribution<float> dist_x{inp[0],0.3};
        std::normal_distribution<float> dist_z{inp[1],0.3};
        float x = dist_x(engine);
        float z = dist_z(engine);
        pts.emplace_back(Eigen::Vector2f(x,z));
    }

    std::sort(pts.begin(), pts.end(), sortX); //sort points from

    std::vector<double> x_sorted, z_sorted;
    for(const auto& pt: pts)
    {
        x_sorted.push_back(pt(0));
        z_sorted.push_back(pt(1));
    }

    alglib::real_1d_array X, Z;
    X.setcontent(x_sorted.size(), &(x_sorted[0]));
    Z.setcontent(z_sorted.size(), &(z_sorted[0]));
    alglib::ae_int_t info;
    alglib::spline1dinterpolant s;
    alglib::spline1dfitreport rep;
    double rho = smoothing_constant;
    alglib::spline1dfitpenalized(X, Z, 50, rho, info, s, rep);

    Eigen::VectorXf x = Eigen::VectorXf::LinSpaced(sample_pts, p0(0), p0(0)+width);
    Eigen::VectorXf z(x.size());

    for(int i=0; i < x.size(); i++)
    {
        z(i) = alglib::spline1dcalc(s,x(i));
    }

    Eigen::MatrixXf pts_out;
    pts_out.resize(x.size(), 2);
    for(int i=0; i<x.size(); i++){
        pts_out(i, 0) = x(i);
        pts_out(i, 1) = z(i);
    }

    return pts_out;
}

Eigen::MatrixXf makeRandom(Eigen::Vector2f p0, float height, float width, int num_random_pts, float smoothing_constant, int sample_pts)
{
    std::random_device seeder;
    std::mt19937 engine(seeder());
    std::uniform_real_distribution<float> dist_x(p0(0), p0(0)+width); // uniform, unbiased
    std::uniform_real_distribution<float> dist_z(p0(1), p0(1)+height); // uniform, unbiased

    std::vector<Eigen::Vector2f> pts;
    for(int i =0; i< num_random_pts; i++)
    {
        float x = dist_x(engine);
        float z = dist_z(engine);
        pts.emplace_back(Eigen::Vector2f(x,z));
    }

    std::sort(pts.begin(), pts.end(), sortX); //sort points from

    std::vector<double> x_sorted, z_sorted;
    for(const auto& pt: pts)
    {
        x_sorted.push_back(pt(0));
        z_sorted.push_back(pt(1));
    }

    alglib::real_1d_array X, Z;
    X.setcontent(x_sorted.size(), &(x_sorted[0]));
    Z.setcontent(z_sorted.size(), &(z_sorted[0]));
    alglib::ae_int_t info;
    alglib::spline1dinterpolant s;
    alglib::spline1dfitreport rep;
    double rho = smoothing_constant;
    alglib::spline1dfitpenalized(X, Z, 50, rho, info, s, rep);

    Eigen::VectorXf x = Eigen::VectorXf::LinSpaced(sample_pts, p0(0), p0(0)+width);
    Eigen::VectorXf z(x.size());

    for(int i=0; i < x.size(); i++)
    {
        z(i) = alglib::spline1dcalc(s,x(i));
    }

    Eigen::MatrixXf pts_out;
    pts_out.resize(x.size(), 2);
    for(int i=0; i<x.size(); i++){
        pts_out(i, 0) = x(i);
        pts_out(i, 1) = z(i);
    }

    return pts_out;
}

Eigen::MatrixXf makeSpline(std::vector<Eigen::Vector2f> pts, Eigen::Vector2f p0, float width, float smoothing_constant, int sample_pts, float basis, bool swap=false)
{
    if(swap)
        std::sort(pts.begin(), pts.end(), sortY); //sort points from
    else
        std::sort(pts.begin(), pts.end(), sortX); //sort points from

    std::vector<double> x_sorted, z_sorted;
    for(const auto& pt: pts)
    {
        if(swap){
            x_sorted.push_back(pt(1));
            z_sorted.push_back(pt(0));
        }else{
            x_sorted.push_back(pt(0));
            z_sorted.push_back(pt(1));
        }
    }

    alglib::real_1d_array X, Z;
    X.setcontent(x_sorted.size(), &(x_sorted[0]));
    Z.setcontent(z_sorted.size(), &(z_sorted[0]));
    alglib::ae_int_t info;
    alglib::spline1dinterpolant s;
    alglib::spline1dfitreport rep;
    double rho = smoothing_constant;
    alglib::spline1dfitpenalized(X, Z, basis, rho, info, s, rep);

    Eigen::VectorXf x = Eigen::VectorXf::LinSpaced(sample_pts, p0(0), p0(0)+width);
    Eigen::VectorXf z(x.size());

    for(int i=0; i < x.size(); i++)
    {
        z(i) = alglib::spline1dcalc(s,x(i));
    }

    Eigen::MatrixXf pts_out;
    pts_out.resize(x.size(), 2);
    for(int i=0; i<x.size(); i++){
        if(swap){
            pts_out(i, 1) = x(i);
            pts_out(i, 0) = z(i);
        }else{
            pts_out(i, 0) = x(i);
            pts_out(i, 1) = z(i);
        }
    }

    return pts_out;
}

void removeNan(std::vector<float>& x){
    x.erase(std::remove_if(std::begin(x), std::end(x), [](const float& value) { return std::isnan(value); }), std::end(x));
}

int convolve_sse(float* in, int input_length,
                 float* kernel,	int kernel_length, float* out)
{
    float* in_padded = (float*)(alloca(sizeof(float) * (input_length + 8)));

    __m128* kernel_many = (__m128*)(alloca(16 * kernel_length));
    __m128 block;

    __m128 prod;
    __m128 acc;

    // surrounding zeroes, before and after
    _mm_storeu_ps(in_padded, _mm_set1_ps(0));
    memcpy(&in_padded[4], in, sizeof(float) * input_length);
    _mm_storeu_ps(in_padded + input_length + 4, _mm_set1_ps(0));

    // Repeat each kernal value across a 4-vector
    int i;
    for (i = 0; i < kernel_length; i++) {
        kernel_many[i] = _mm_set1_ps(kernel[i]); // broadcast
    }

    for (i = 0; i < input_length + kernel_length - 4; i += 4) {

        // Zero the accumulator
        acc = _mm_setzero_ps();

        int startk = i > (input_length - 1) ? i - (input_length - 1) : 0;
        int endk = (i + 3) < kernel_length ? (i + 3) : kernel_length - 1;

        /* After this loop, we have computed 4 output samples
        * for the price of one.
        * */
        for (int k = startk; k <= endk; k++) {

            // Load 4-float data block. These needs to be an unaliged
            // load (_mm_loadu_ps) as we step one sample at a time.
            block = _mm_loadu_ps(in_padded + 4 + i - k);
            prod = _mm_mul_ps(block, kernel_many[k]);

            // Accumulate the 4 parallel values
            acc = _mm_add_ps(acc, prod);
        }
        _mm_storeu_ps(out + i, acc);
    }

    // Left-overs
    for (; i < input_length + kernel_length - 1; i++) {

        out[i] = 0.0;
        int startk = i >= input_length ? i - input_length + 1 : 0;
        int endk = i < kernel_length ? i : kernel_length - 1;
        for (int k = startk; k <= endk; k++) {
            out[i] += in[i - k] * kernel[k];
        }
    }

    return 0;
}

int convolve_naive(float* in, int input_length,
                   float* kernel,	int kernel_length, float* out)
{
    for (int i = 0; i < input_length + kernel_length - 1; i++) {
        out[i] = 0.0;
        int startk = i >= input_length ? i - input_length + 1 : 0;
        int endk = i < kernel_length ? i : kernel_length - 1;
        for (int k = startk; k <= endk; k++) {
            out[i] += in[i - k] * kernel[k];
        }
    }

    return 0;
}

std::vector<float> convolve(std::vector<float>& input, std::vector<float>& kernel, int mode = 0){
    std::vector<float> output;
    int M = input.size();
    int N = kernel.size();
    output.resize(M + N - 1);
    convolve_sse(input.data(), M, kernel.data(), N, output.data());

    if(mode == 0) return output;
    else if(mode == 1){
        output.erase(output.begin(), output.begin() + N-1);
        for(int i=0; i<N-1; i++) output.pop_back();
        return output;
    }

    return output;

}

std::vector<float> runningMean(std::vector<float>& x, int N){
    std::vector<float> cumsum = {0};
    std::vector<float> moving_aves;
    for(int i=1; i<x.size()+1; i++){
        cumsum.emplace_back(cumsum[i-1] + x[i-1]);
        if(i >= N){
            float moving_ave = (cumsum[i] - cumsum[i-N])/(float)N;
            moving_aves.emplace_back(moving_ave);
        }
    }
    return moving_aves;
}

float squaredSum(std::vector<float>& x){
    float sum = 0;
    for(auto& item : x) sum += pow(item,2);
    return sum;
}

std::vector<float> peakFinding(std::vector<float>& x, int N){
    std::vector<std::pair<int, float>> array;

    for(int i=1; i<x.size()-1; i++){
        float left_pt;
        float mid_pt;
        float right_pt;
        if(i >= N && i < x.size()-N){
            left_pt = x[i-N];
            mid_pt = x[i];
            right_pt = x[i+N];
        }else if(i >=1 && i < N){
            left_pt = x[0];
            mid_pt = x[i];
            right_pt = x[i+N];
        }else if(i >= x.size()-N && i < x.size()-1){
            left_pt = x[i-N];
            mid_pt = x[i];
            right_pt = x[x.size()-1];
        }

        auto left_dist = mid_pt - left_pt;
        auto right_dist = right_pt - mid_pt;

        if(copysignf(1.0, left_dist) != copysignf(1.0, right_dist)){
            auto dist = std::min(fabs(left_dist), fabs(right_dist));
            if(dist > 0.12) array.emplace_back(std::pair<int,float>(i, dist));
        }
    }

    std::vector<float> peaks;
    std::vector<std::pair<int, float>> clusters;
    std::vector<std::pair<int, float>> curr_cluster;

    for(int i=0; i<array.size(); i++){
        bool still_adding = false;
        if(curr_cluster.size() == 0){
            curr_cluster.emplace_back(array[i]);
            still_adding = true;
        }else if(abs(curr_cluster.back().first - array[i].first) < N){
            curr_cluster.emplace_back(array[i]);
            still_adding = true;
        }

        if(!still_adding || (i+1 == array.size())){
            float maxsize = 0;
            std::pair<int, float> best_item;
            for(auto& item : curr_cluster){
                if(item.second > maxsize){
                    maxsize = item.second;
                    best_item = item;
                }
            }
            clusters.emplace_back(best_item);
            peaks.emplace_back(maxsize);
            curr_cluster.clear();
        }
    }

    return peaks;
}

template<typename T>
std::vector<T> arange(T start, T stop, T step = 1, bool include=false) {
    std::vector<T> values;
    for (T value = start; value < stop; value += step)
        values.push_back(value);
    if(include) values.push_back(stop);
    return values;
}

void setCol(Eigen::MatrixXf& matrix, int colnum, float val){
    for(int i=0; i<matrix.rows(); i++){
        matrix(i, colnum) = val;
    }
}

void eigenXSort(Eigen::MatrixXf& matrix)
{
    std::vector<Eigen::VectorXf> vec;
    for (int64_t i = 0; i < matrix.rows(); ++i)
        vec.push_back(matrix.row(i));
    std::sort(vec.begin(), vec.end(), [](Eigen::VectorXf const& t1, Eigen::VectorXf const& t2){ return t1(0) < t2(0); } );
    for (int64_t i = 0; i < matrix.rows(); ++i)
        matrix.row(i) = vec[i];
};

std::vector<int> eigenAngleSort(Eigen::MatrixXf& matrix)
{
    std::vector<int> idx(matrix.rows());
    iota(idx.begin(), idx.end(), 0);
    std::vector<float> angs;
    for (int64_t i = 0; i < matrix.rows(); ++i) {
        float angle = -((atan2f(matrix(i,1), matrix(i,0)) * 180 / M_PI) - 90);
        angs.emplace_back(angle);
    }
    std::sort(idx.begin(), idx.end(),
         [&angs](int i1, int i2) {return angs[i1] < angs[i2];});
    Eigen::MatrixXf matrix_copy = matrix;
    for(int i=0; i<idx.size(); i++){
        matrix.row(i) = matrix_copy.row(idx[i]);
    }
    return idx;
};

std::vector<std::vector<int>> splitVector(const std::vector<int>& idx, int split_count){
    int each_contains = (int)(((float)idx.size() / (float)split_count));
    int remainder = idx.size() % split_count;
    std::vector<std::vector<int>> splits;
    for(int j=0; j<split_count; j++){
        if(j == split_count - 1)
            splits.emplace_back(std::vector<int>(idx.begin() + j*each_contains, idx.begin() + j*each_contains + each_contains + remainder));
        else
            splits.emplace_back(std::vector<int>(idx.begin() + j*each_contains, idx.begin() + j*each_contains + each_contains));
    }
    return splits;
}

template <class T>
void reorder(std::vector<T>& vA, std::vector<size_t>& vOrder)
{
    assert(vA.size() == vOrder.size());
    // for all elements to put in place
    for( size_t i = 0; i < vA.size(); ++i )
    {
        // while vOrder[i] is not yet in place
        // every swap places at least one element in it's proper place
        while(       vOrder[i] !=   vOrder[vOrder[i]] )
        {
            std::swap( vA[vOrder[i]], vA[vOrder[vOrder[i]]] );
            std::swap(    vOrder[i],     vOrder[vOrder[i]] );
        }
    }
}

template< class T >
void reorder_naive(std::vector<T>& vA, const std::vector<size_t>& vOrder)
{
    assert(vA.size() == vOrder.size());
    std::vector<T> vCopy = vA; // Can we avoid this?
    for(int i = 0; i < vOrder.size(); ++i)
        vA[i] = vCopy[ vOrder[i] ];
}

std::vector<std::vector<std::vector<int>>> generateContPerms(int index_count, int split_count){
    struct custom_sort
    {
        inline bool operator() (const std::vector<int>& struct1, const std::vector<int>& struct2)
        {
            return (struct1[0] < struct2[0]);
        }
    };
    // Generate all continious permutations
    std::vector<int> idx(index_count);
    iota(idx.begin(), idx.end(), 0);
    std::vector<std::vector<int>> permutations;
    do {
        permutations.emplace_back(idx);
    } while (std::next_permutation(idx.begin(), idx.end()));
    std::vector<std::vector<std::vector<int>>> contiguous_perms;
    std::map<std::string, int> hash;
    for(const auto& perm : permutations){
        std::vector<std::vector<int>> splits = splitVector(perm, split_count);
        // Check if each split is continuous
        bool sorted = true;
        for(const auto& split : splits){
            if(!std::is_sorted(split.begin(), split.end())) sorted = false;
        }
        // Sort my splits
        std::sort(splits.begin(), splits.end(), custom_sort());
        if(sorted) {
            // Generate Key
            std::string s = "";
            for(const auto& split : splits){
                for(const auto& v : split) s+=std::to_string(v);
                s+="-";
            }
            if(hash.count(s)) continue;
            else hash[s] = 1;
            contiguous_perms.emplace_back(splits);
        }
    }
    return contiguous_perms;
}

void removeRow(Eigen::MatrixXf& matrix, unsigned int rowToRemove)
{
    unsigned int numRows = matrix.rows()-1;
    unsigned int numCols = matrix.cols();

    if( rowToRemove < numRows )
        matrix.block(rowToRemove,0,numRows-rowToRemove,numCols) = matrix.block(rowToRemove+1,0,numRows-rowToRemove,numCols);

    matrix.conservativeResize(numRows,numCols);
}

Eigen::MatrixXf customSort(const Eigen::MatrixXf& matrix, const std::vector<int>& custom_order){
    if(matrix.rows() == custom_order.size()) {
        Eigen::MatrixXf matrix_copy = matrix;
        for (int i = 0; i < custom_order.size(); i++) {
            matrix_copy.row(i) = matrix.row(custom_order[i]);
        }
        return matrix_copy;
    }else if(matrix.rows() > custom_order.size()){
        Eigen::MatrixXf matrix_copy;
        matrix_copy.resize(custom_order.size(), matrix.cols());
        for (int i = 0; i < custom_order.size(); i++) {
            matrix_copy.row(i) = matrix.row(custom_order[i]);
        }
        return matrix_copy;
    }else{
        throw std::runtime_error("custom_sort error");
    }
}

std::string getKey(const std::vector<int>& custom_order){
    std::string s = "";
    for(const auto& i : custom_order){
        s += std::to_string(i);
        s += "-";
    }
    return s;
}

void removeRows(Eigen::MatrixXf& matrix, std::vector<int>& to_remove){
    int count = 0;
    for(auto& row : to_remove){
        removeRow(matrix, row-count);
        count++;
    }
}

template <typename T>
std::vector<T> linspace(T a, T b, size_t N) {
    T h = (b - a) / static_cast<T>(N-1);
    std::vector<T> xs(N);
    typename std::vector<T>::iterator x;
    T val;
    for (x = xs.begin(), val = a; x != xs.end(); ++x, val += h)
        *x = val;
    return xs;
}

Eigen::MatrixXf fitBSpline(const Eigen::MatrixXf& input_pts_x, int mode = 0, bool hack=1){
    // Hack
    Eigen::MatrixXf input_pts = input_pts_x;

//    // HACK
//    if(input_pts.rows() == 1){
//        input_pts.resize(3,3);
//        ROS_ERROR("Hack");
//        input_pts.row(0) = input_pts_x.row(0);
//        input_pts.row(1) = input_pts_x.row(0);
//        input_pts.row(2) = input_pts_x.row(0);
////        input_pts.row(3) = input_pts_x.row(0);
////        input_pts.row(4) = input_pts_x.row(0);
//
//        input_pts(0,0) -= 0.1;
//        input_pts(1,0) -= 0.0;
//        input_pts(2,0) += 0.1;
//
//        input_pts(1,1) -= 0.1;
//
////        input_pts(0,1) += 0.1;
////        input_pts(1,1) -= 0.1;
////        input_pts(2,1) -= 0.0;
////        input_pts(3,1) -= 0.1;
////        input_pts(4,1) += 0.1;
////
////        input_pts(0,0) -= 0.1;
////        input_pts(1,0) -= 0.1;
////        input_pts(2,0) -= 0.0;
////        input_pts(3,0) += 0.1;
////        input_pts(4,0) += 0.1;
//
//        std::cout << input_pts << std::endl;
//    }

    // Copy
    Eigen::MatrixXf inputs = input_pts;

    if(hack){
        // Reverse Rows
        inputs = input_pts.colwise().reverse();

        // Add two control points at end
        Eigen::Vector3f c1 = Eigen::Vector3f((inputs(0,0)+inputs(1,0))/2.,(inputs(0,1)+inputs(1,1))/2.,(inputs(0,2)+inputs(1,2))/2.);
        int in = inputs.rows()-1;
        Eigen::Vector3f c2 = Eigen::Vector3f((inputs(in,0)+inputs(in-1,0))/2.,(inputs(in,1)+inputs(in-1,1))/2.,(inputs(in,2)+inputs(in-1,2))/2.);
        inputs.conservativeResize(inputs.rows()+2, inputs.cols());
        inputs.row(inputs.rows()-2) = c1;
        inputs.row(inputs.rows()-1) = c2;
    }

    // Initialize entry
    int n = inputs.rows() - 2;
    int n1 = n+1;
    std::vector<float> dx(n, 0);
    std::vector<float> dy(n, 0);

    // First and Last Derivs
    if(mode == 0){
        dx[0] = inputs(n, 0) - inputs(0, 0);
        dy[0] = inputs(n, 1) - inputs(0, 1);
        dx[n-1] = -(inputs(n1, 0) - inputs(n-1, 0));
        dy[n-1] = -(inputs(n1, 1) - inputs(n-1, 1));
    }else if(mode == 1){
        float DIV = 3.;
        dx[0] = (inputs(1, 0) - inputs(0, 0))/DIV;
        dy[0] = (inputs(1, 1) - inputs(0, 1))/DIV;
        dx[n-1] = (inputs(n-1, 0) - inputs(n-2, 0))/DIV;
        dy[n-1] = (inputs(n-1, 1) - inputs(n-2, 1))/DIV;
    }

    // Fill other control derivs
    std::vector<float> Ax(n, 0);
    std::vector<float> Ay(n, 0);
    std::vector<float> Bi(n, 0);
    Bi[1] = -1./inputs(1, 2);
    Ax[1] = -(inputs(2, 0) - inputs(0, 0) - dx[0])*Bi[1];
    Ay[1] = -(inputs(2, 1) - inputs(0, 1) - dy[0])*Bi[1];
    for(int i=2; i<n-1; i++){
        Bi[i] = -1/(inputs(i,2) + Bi[i-1]);
        Ax[i] = -(inputs(i+1,0) - inputs(i-1,0) - Ax[i-1])*Bi[i];
        Ay[i] = -(inputs(i+1,1) - inputs(i-1,1) - Ay[i-1])*Bi[i];
    }
    for(int i=n-2; i>0; i--){
        dx[i] = Ax[i] + dx[i+1]*Bi[i];
        dy[i] = Ay[i] + dy[i+1]*Bi[i];
    }

    // Interpolate
    std::vector<Eigen::Vector2f> paths = {Eigen::Vector2f(inputs(0,0), inputs(0,1))};
    for(int i=0; i<n-1; i++){
        // Distance
        float dist = sqrt(pow((inputs(i,0) - inputs(i+1,0)),2) + pow((inputs(i,1) - inputs(i+1,1)),2));
        float count = (float)((int)(dist/0.01));

        // Interpolate
        float extend = 0.1;
        auto ts = linspace<float>(0.-extend, 1+extend-(1./count), count);
        for(auto t: ts){
            float t1 = 1-t;
            float t12 = t1*t1;
            float t2 = t*t;
            float B0 = t1*t12;
            float B1 = 3*t*t12;
            float B2 = 3*t2*t1;
            float B3 = t*t2;
            float X = (inputs(i,0)*B0 + (inputs(i,0) + dx[i])*B1 +
                 (inputs(i+1,0) - dx[i+1])*B2 + inputs(i+1,0)*B3);
            float Y = (inputs(i,1)*B0 + (inputs(i,1) + dy[i])*B1 +
                 (inputs(i+1,1) - dy[i+1])*B2 + inputs(i+1,1)*B3);
            paths.emplace_back(Eigen::Vector2f(X,Y));
        }
    }

    // Special Case for 1 item
    if(paths.size() == 1){
        Eigen::Vector2f lVec = paths[0];
        Eigen::Vector2f rVec = paths[0];
        lVec(0) += 0.2;
        rVec(0) -= 0.2;
        paths.emplace_back(lVec);
        paths.emplace_back(rVec);
    }

    if(hack){
        std::reverse(paths.begin(), paths.end());
    }

    // Convert to eigen
    Eigen::MatrixXf outputs;
    outputs.resize(paths.size(),2);
    for(int i=0; i<paths.size(); i++){
        outputs(i,0) = paths[i](0);
        outputs(i,1) = paths[i](1);
    }

    return outputs;
}

#endif

max_stars_repo_name: CMU-Light-Curtains/ObjectDetection

max_issues_repo_name: CMU-Light-Curtains/ObjectDetection

max_forks_repo_name: CMU-Light-Curtains/ObjectDetection