<commit_before>#ifndef LEPP2_FILTERED_VIDEO_SOURCE_H__
#define LEPP2_FILTERED_VIDEO_SOURCE_H__

#include "lepp2/BaseVideoSource.hpp"
#include "lepp2/VideoObserver.hpp"
#include "lepp2/filter/PointFilter.hpp"

#include <algorithm>

#include <boost/enable_shared_from_this.hpp>
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/circular_buffer.hpp>

#include "lepp2/debug/timer.hpp"

/**
 * A struct that is used to describe a single point in space that can be used
 * to index sets and maps of such points.
 */
struct MapPoint {
  int x;
  int y;
  int z;
  MapPoint(int x, int y, int z) : x(x), y(y), z(z) {}
  MapPoint() {}
};

/**
 * Structs that are to be placed in associative containers must be comparable.
 */
bool operator==(MapPoint const& lhs, MapPoint const& rhs) {
  return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
}

/**
 * Provides a hash value for a `MapPoint` in order to allow for it to be
 * placed in boost's map and set.
 */
size_t hash_value(MapPoint const& pt) {
  std::size_t seed = 0;
  boost::hash_combine(seed, pt.x);
  boost::hash_combine(seed, pt.y);
  boost::hash_combine(seed, pt.z);
  return seed;
}

/**
 * ABC.
 * A VideoSource decorator.  It wraps a given VideoSource instance and emits
 * clouds that are filtered versions of the original raw cloud returned by the
 * wrapped `VideoSource`.
 *
 * The cloud it receives is first filtered by applying a number of point-wise
 * filters to each point. The filters that are applied to points (if any) are
 * set dynamically (`setFilter` method).
 *
 * Then, it delegates to a concrete implementation which needs to handle the
 * cloud-level filtering.
 *
 * Concrete implementations need to provide implementations for three protected
 * hook methods that handle the full-cloud filtering at various stages: before
 * the original cloud's points are transformed, after a particular point is
 * transformed, and finally after all points have been transformed.
 *
 * This ABC provides the plumbing required to turn the filtered source into a
 * `VideoSource` making it simple to implement a concrete filter by simply
 * providing implementations for the mentioned hooks.
 */
template<class PointT>
class FilteredVideoSource
    : public VideoSource<PointT>,
      public VideoObserver<PointT>,
      public boost::enable_shared_from_this<FilteredVideoSource<PointT> > {
public:
  using typename VideoSource<PointT>::PointCloudType;
  /**
   * Creates a new FilteredVideoSource which will perform filtering of each
   * cloud generated by the given source and emit such a filtered cloud to its
   * own observers.
   *
   * The FilteredVideoSource instance does not assume ownership of the given
   * source, but shares it.
   */
  FilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : source_(source) {}
  /**
   * Implementation of the VideoSource interface.
   */
  virtual void open();
  /**
   * Implementation of the VideoObserver interface.
   */
  virtual void notifyNewFrame(
      int idx,
      const typename pcl::PointCloud<PointT>::ConstPtr& cloud);

  /**
   * Add a filter that will be applied to individual points before the entire
   * cloud itself is filtered.
   */
  void addFilter(boost::shared_ptr<PointFilter<PointT> > filter) {
    point_filters_.push_back(filter);
  }

protected:
  /**
   * A hook method that concrete implementations of the `FilteredVideoSource`
   * should implement in order to prepare for a new frame's filtering.
   */
  virtual void newFrame() = 0;
  /**
   * A hook method that concrete implementations of the `FilteredVideoSource`
   * should implement to handle new points received in the latest frame.
   *
   * It receives a reference to the cloud that will contain the final filtered
   * representation already, if the implementation wishes to examine or modify
   * it.
   */
  virtual void newPoint(PointT& p, PointCloudType& filtered) = 0;
  /**
   * A hook method that concrete implementations of the `FilteredVideoSource`
   * should implement to return the filtered cloud assembled from the points
   * given by the `newPoint` calls since the previous `newFrame` call.
   * Implementations are free to take into account any historic data and throw
   * away or otherwise modify the points given in `newPoint` calls, though.
   *
   * The filtered cloud should be put into the cloud instance passed as the
   * parameter.
   */
  virtual void getFiltered(PointCloudType& filtered) = 0;

private:
  /**
   * The VideoSource instance that will be filtered by this instance.
   */
  boost::shared_ptr<VideoSource<PointT> > source_;
  /**
   * The filters that are applied to individual points (in the order found in
   * the vector) before passing it off to the concrete cloud filter
   * implementation.
   */
  std::vector<boost::shared_ptr<PointFilter<PointT> > > point_filters_;
};

template<class PointT>
void FilteredVideoSource<PointT>::open() {
  // Start the wrapped VideoSource and make sure that this instance is notified
  // when it emits any new clouds.
  source_->attachObserver(this->shared_from_this());
  source_->open();
}

template<class PointT>
void FilteredVideoSource<PointT>::notifyNewFrame(
    int idx,
    const typename pcl::PointCloud<PointT>::ConstPtr& cloud) {
  Timer t;
  t.start();

  // Prepare the point-wise filters for a new frame.
  {
    size_t sz = point_filters_.size();
    for (size_t i = 0; i < sz; ++i) {
      point_filters_[i]->prepareNext();
    }
  }
  // Prepare the concrete cloud filter implementation for a new frame.
  this->newFrame();

  // Process the cloud received from the wrapped instance and put the filtered
  // result in a new point cloud.
  typename PointCloudType::Ptr cloud_filtered(new PointCloudType());
  PointCloudType& filtered = *cloud_filtered;
  cloud_filtered->is_dense = true;
  cloud_filtered->sensor_origin_ = cloud->sensor_origin_;

  // Apply point-wise filters to each received point and then pass it to the
  // concrete implementation to figure out how to filter the entire cloud.
  for (typename pcl::PointCloud<PointT>::const_iterator it = cloud->begin();
        it != cloud->end();
        ++it) {
    PointT p = *it;
    // Filter out NaN points already, since we're already iterating through the
    // cloud.
    if (!pcl_isfinite(p.x) || !pcl_isfinite(p.y) || !pcl_isfinite(p.z)) {
      continue;
    }

    // Now apply point-wise filters.
    size_t const sz = point_filters_.size();
    bool valid = true;
    for (size_t i = 0; i < sz; ++i) {
      if (!point_filters_[i]->apply(p)) {
        valid = false;
        break;
      }
    }
    // And pass such a filtered/modified point to the cloud-level filter.
    if (valid) this->newPoint(p, filtered);
  }

  // Now we obtain the fully filtered cloud...
  this->getFiltered(filtered);
  // ...and we're done!
  t.stop();

  std::cerr << "Total included points " << cloud_filtered->size() << std::endl;
  std::cerr << "Filtering took " << t.duration() << std::endl;
  // Finally, the cloud that is emitted by this instance is the filtered cloud.
  this->setNextFrame(cloud_filtered);
}

/**
 * An implementation of a `FilteredVideoSource` that only applies the
 * point-wise filters, without performing any additional cloud-level filtering.
 */
template<class PointT>
class SimpleFilteredVideoSource : public FilteredVideoSource<PointT> {
public:
  using typename FilteredVideoSource<PointT>::PointCloudType;

  SimpleFilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : FilteredVideoSource<PointT>(source) {}
protected:
  void newFrame() {}
  void newPoint(PointT& p, PointCloudType& filtered) { filtered.push_back(p); }
  void getFiltered(PointCloudType& filtered) {}
};

/**
 * An implementation of a `FilteredVideoSource` where points are included only
 * if they have been seen in a certain percentage of frames of the last N
 * frames.
 */
template<class PointT>
class ProbFilteredVideoSource : public FilteredVideoSource<PointT> {
public:
  using typename FilteredVideoSource<PointT>::PointCloudType;

  ProbFilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : FilteredVideoSource<PointT>(source) {}
protected:
  void newFrame() { this_frame_.clear(); }

  void newPoint(PointT& p, PointCloudType& filtered) {
    MapPoint map_point = MapPoint(p.x * 100, p.y * 100, p.z * 100);
    uint32_t& ref = all_points_[map_point];
    ref <<= 1;
    ref |= 1;
    this_frame_.insert(map_point);
  }

  void getFiltered(PointCloudType& filtered) {
    boost::unordered_map<MapPoint, uint32_t>::iterator it =
        all_points_.begin();
    while (it != all_points_.end()) {
      if (this_frame_.find(it->first) == this_frame_.end()) {
        it->second <<= 1;
      }
      int count = __builtin_popcount(it->second);
      if (count >= 10) {
        PointT pt;
        pt.x = it->first.x / 100.;
        pt.y = it->first.y / 100.;
        pt.z = it->first.z / 100.;
        filtered.push_back(pt);
      }
      ++it;
    }
  }
private:
  boost::unordered_set<MapPoint> this_frame_;
  boost::unordered_map<MapPoint, uint32_t> all_points_;
};

/**
 * An implementation of a `FilteredVideoSource` that applies a PT1 filter on the
 * stream of clouds.
 */
template<class PointT>
class Pt1FilteredVideoSource : public FilteredVideoSource<PointT> {
public:
  using typename FilteredVideoSource<PointT>::PointCloudType;

  Pt1FilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : FilteredVideoSource<PointT>(source) {}
protected:
  void newFrame() { this_frame_.clear(); }

  void newPoint(PointT& p, PointCloudType& filtered) {
    MapPoint map_point = MapPoint(p.x * 100, p.y * 100, p.z * 100);
    float& ref = all_points_[map_point];
    // TODO Factor out the parameter value to a member constant.
    ref = 0.9*ref + 0.1*10;
    this_frame_.insert(map_point);
  }

  void getFiltered(PointCloudType& filtered) {
    boost::unordered_map<MapPoint, float>::iterator it =
        all_points_.begin();
    while (it != all_points_.end()) {
      if (this_frame_.find(it->first) == this_frame_.end()) {
        it->second = 0.9*it->second + 0.1*0.;
      }
      if (it->second >= 4.) {
        PointT pt;
        pt.x = it->first.x / 100.;
        pt.y = it->first.y / 100.;
        pt.z = it->first.z / 100.;
        filtered.push_back(pt);
      }
      ++it;
    }
  }
private:
  boost::unordered_set<MapPoint> this_frame_;
  boost::unordered_map<MapPoint, float> all_points_;
};
#endif
<commit_msg>ProbFilter: Forget points far away from the current frame<commit_after>#ifndef LEPP2_FILTERED_VIDEO_SOURCE_H__
#define LEPP2_FILTERED_VIDEO_SOURCE_H__

#include "lepp2/BaseVideoSource.hpp"
#include "lepp2/VideoObserver.hpp"
#include "lepp2/filter/PointFilter.hpp"

#include <algorithm>
#include <numeric>

#include <boost/enable_shared_from_this.hpp>
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/circular_buffer.hpp>

#include "lepp2/debug/timer.hpp"

/**
 * A struct that is used to describe a single point in space that can be used
 * to index sets and maps of such points.
 */
struct MapPoint {
  int x;
  int y;
  int z;
  MapPoint(int x, int y, int z) : x(x), y(y), z(z) {}
  MapPoint() {}
};

/**
 * Structs that are to be placed in associative containers must be comparable.
 */
bool operator==(MapPoint const& lhs, MapPoint const& rhs) {
  return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
}

/**
 * Provides a hash value for a `MapPoint` in order to allow for it to be
 * placed in boost's map and set.
 */
size_t hash_value(MapPoint const& pt) {
  std::size_t seed = 0;
  boost::hash_combine(seed, pt.x);
  boost::hash_combine(seed, pt.y);
  boost::hash_combine(seed, pt.z);
  return seed;
}

/**
 * ABC.
 * A VideoSource decorator.  It wraps a given VideoSource instance and emits
 * clouds that are filtered versions of the original raw cloud returned by the
 * wrapped `VideoSource`.
 *
 * The cloud it receives is first filtered by applying a number of point-wise
 * filters to each point. The filters that are applied to points (if any) are
 * set dynamically (`setFilter` method).
 *
 * Then, it delegates to a concrete implementation which needs to handle the
 * cloud-level filtering.
 *
 * Concrete implementations need to provide implementations for three protected
 * hook methods that handle the full-cloud filtering at various stages: before
 * the original cloud's points are transformed, after a particular point is
 * transformed, and finally after all points have been transformed.
 *
 * This ABC provides the plumbing required to turn the filtered source into a
 * `VideoSource` making it simple to implement a concrete filter by simply
 * providing implementations for the mentioned hooks.
 */
template<class PointT>
class FilteredVideoSource
    : public VideoSource<PointT>,
      public VideoObserver<PointT>,
      public boost::enable_shared_from_this<FilteredVideoSource<PointT> > {
public:
  using typename VideoSource<PointT>::PointCloudType;
  /**
   * Creates a new FilteredVideoSource which will perform filtering of each
   * cloud generated by the given source and emit such a filtered cloud to its
   * own observers.
   *
   * The FilteredVideoSource instance does not assume ownership of the given
   * source, but shares it.
   */
  FilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : source_(source) {}
  /**
   * Implementation of the VideoSource interface.
   */
  virtual void open();
  /**
   * Implementation of the VideoObserver interface.
   */
  virtual void notifyNewFrame(
      int idx,
      const typename pcl::PointCloud<PointT>::ConstPtr& cloud);

  /**
   * Add a filter that will be applied to individual points before the entire
   * cloud itself is filtered.
   */
  void addFilter(boost::shared_ptr<PointFilter<PointT> > filter) {
    point_filters_.push_back(filter);
  }

protected:
  /**
   * A hook method that concrete implementations of the `FilteredVideoSource`
   * should implement in order to prepare for a new frame's filtering.
   */
  virtual void newFrame() = 0;
  /**
   * A hook method that concrete implementations of the `FilteredVideoSource`
   * should implement to handle new points received in the latest frame.
   *
   * It receives a reference to the cloud that will contain the final filtered
   * representation already, if the implementation wishes to examine or modify
   * it.
   */
  virtual void newPoint(PointT& p, PointCloudType& filtered) = 0;
  /**
   * A hook method that concrete implementations of the `FilteredVideoSource`
   * should implement to return the filtered cloud assembled from the points
   * given by the `newPoint` calls since the previous `newFrame` call.
   * Implementations are free to take into account any historic data and throw
   * away or otherwise modify the points given in `newPoint` calls, though.
   *
   * The filtered cloud should be put into the cloud instance passed as the
   * parameter.
   */
  virtual void getFiltered(PointCloudType& filtered) = 0;

private:
  /**
   * The VideoSource instance that will be filtered by this instance.
   */
  boost::shared_ptr<VideoSource<PointT> > source_;
  /**
   * The filters that are applied to individual points (in the order found in
   * the vector) before passing it off to the concrete cloud filter
   * implementation.
   */
  std::vector<boost::shared_ptr<PointFilter<PointT> > > point_filters_;
};

template<class PointT>
void FilteredVideoSource<PointT>::open() {
  // Start the wrapped VideoSource and make sure that this instance is notified
  // when it emits any new clouds.
  source_->attachObserver(this->shared_from_this());
  source_->open();
}

template<class PointT>
void FilteredVideoSource<PointT>::notifyNewFrame(
    int idx,
    const typename pcl::PointCloud<PointT>::ConstPtr& cloud) {
  Timer t;
  t.start();

  // Prepare the point-wise filters for a new frame.
  {
    size_t sz = point_filters_.size();
    for (size_t i = 0; i < sz; ++i) {
      point_filters_[i]->prepareNext();
    }
  }
  // Prepare the concrete cloud filter implementation for a new frame.
  this->newFrame();

  // Process the cloud received from the wrapped instance and put the filtered
  // result in a new point cloud.
  typename PointCloudType::Ptr cloud_filtered(new PointCloudType());
  PointCloudType& filtered = *cloud_filtered;
  cloud_filtered->is_dense = true;
  cloud_filtered->sensor_origin_ = cloud->sensor_origin_;

  // Apply point-wise filters to each received point and then pass it to the
  // concrete implementation to figure out how to filter the entire cloud.
  for (typename pcl::PointCloud<PointT>::const_iterator it = cloud->begin();
        it != cloud->end();
        ++it) {
    PointT p = *it;
    // Filter out NaN points already, since we're already iterating through the
    // cloud.
    if (!pcl_isfinite(p.x) || !pcl_isfinite(p.y) || !pcl_isfinite(p.z)) {
      continue;
    }

    // Now apply point-wise filters.
    size_t const sz = point_filters_.size();
    bool valid = true;
    for (size_t i = 0; i < sz; ++i) {
      if (!point_filters_[i]->apply(p)) {
        valid = false;
        break;
      }
    }
    // And pass such a filtered/modified point to the cloud-level filter.
    if (valid) this->newPoint(p, filtered);
  }

  // Now we obtain the fully filtered cloud...
  this->getFiltered(filtered);
  // ...and we're done!
  t.stop();

  std::cerr << "Total included points " << cloud_filtered->size() << std::endl;
  std::cerr << "Filtering took " << t.duration() << std::endl;
  // Finally, the cloud that is emitted by this instance is the filtered cloud.
  this->setNextFrame(cloud_filtered);
}

/**
 * An implementation of a `FilteredVideoSource` that only applies the
 * point-wise filters, without performing any additional cloud-level filtering.
 */
template<class PointT>
class SimpleFilteredVideoSource : public FilteredVideoSource<PointT> {
public:
  using typename FilteredVideoSource<PointT>::PointCloudType;

  SimpleFilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : FilteredVideoSource<PointT>(source) {}
protected:
  void newFrame() {}
  void newPoint(PointT& p, PointCloudType& filtered) { filtered.push_back(p); }
  void getFiltered(PointCloudType& filtered) {}
};

/**
 * An implementation of a `FilteredVideoSource` where points are included only
 * if they have been seen in a certain percentage of frames of the last N
 * frames.
 */
template<class PointT>
class ProbFilteredVideoSource : public FilteredVideoSource<PointT> {
public:
  using typename FilteredVideoSource<PointT>::PointCloudType;

  ProbFilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : FilteredVideoSource<PointT>(source) {}
protected:
  void newFrame() {
    this_frame_.clear();
    min_pt.x = std::numeric_limits<int>::max();
    min_pt.y = std::numeric_limits<int>::max();
    min_pt.z = std::numeric_limits<int>::max();
    max_pt.x = std::numeric_limits<int>::min();
    max_pt.y = std::numeric_limits<int>::min();
    max_pt.z = std::numeric_limits<int>::min();
  }

  void newPoint(PointT& p, PointCloudType& filtered) {
    MapPoint map_point = MapPoint(p.x * 100, p.y * 100, p.z * 100);
    uint32_t& ref = all_points_[map_point];
    ref <<= 1;
    ref |= 1;
    this_frame_.insert(map_point);
    // Keep track of the min/max points so that we know the bounding box of
    // the current cloud.
    min_pt.x = std::min(min_pt.x, map_point.x);
    min_pt.y = std::min(min_pt.y, map_point.y);
    min_pt.z = std::min(min_pt.z, map_point.z);
    max_pt.x = std::max(max_pt.x, map_point.x);
    max_pt.y = std::max(max_pt.y, map_point.y);
    max_pt.z = std::max(max_pt.z, map_point.z);
  }

  void getFiltered(PointCloudType& filtered) {
    boost::unordered_map<MapPoint, uint32_t>::iterator it =
        all_points_.begin();
    while (it != all_points_.end()) {
      if (this_frame_.find(it->first) == this_frame_.end()) {
        it->second <<= 1;
      }
      int count = __builtin_popcount(it->second);
      if (count >= 10) {
        PointT pt;
        pt.x = it->first.x / 100.;
        pt.y = it->first.y / 100.;
        pt.z = it->first.z / 100.;
        filtered.push_back(pt);
      }

      // Allow for a bit of leeway with removing points at the very boundary of
      // the bounding box. To do this, the bounding box is increased by 10 [cm]
      // in each direction. Only points within *this* bounding box are kept in
      // the map -- all others removed.
      // TODO See if tweaking these values up/down yields any benefits.
      min_pt.x -= 10;
      min_pt.y -= 10;
      min_pt.z -= 10;
      max_pt.x += 10;
      max_pt.y += 10;
      max_pt.z += 10;
      MapPoint const& pt = it->first;
      if (pt.x < min_pt.x || pt.x > max_pt.x ||
          pt.y < min_pt.y || pt.y > max_pt.y ||
          pt.z < min_pt.z || pt.z > max_pt.z) {
        all_points_.erase(it++);
      } else {
        ++it;
      }
    }
  }
private:
  boost::unordered_set<MapPoint> this_frame_;
  boost::unordered_map<MapPoint, uint32_t> all_points_;
  MapPoint min_pt;
  MapPoint max_pt;
};

/**
 * An implementation of a `FilteredVideoSource` that applies a PT1 filter on the
 * stream of clouds.
 */
template<class PointT>
class Pt1FilteredVideoSource : public FilteredVideoSource<PointT> {
public:
  using typename FilteredVideoSource<PointT>::PointCloudType;

  Pt1FilteredVideoSource(boost::shared_ptr<VideoSource<PointT> > source)
      : FilteredVideoSource<PointT>(source) {}
protected:
  void newFrame() { this_frame_.clear(); }

  void newPoint(PointT& p, PointCloudType& filtered) {
    MapPoint map_point = MapPoint(p.x * 100, p.y * 100, p.z * 100);
    float& ref = all_points_[map_point];
    // TODO Factor out the parameter value to a member constant.
    ref = 0.9*ref + 0.1*10;
    this_frame_.insert(map_point);
  }

  void getFiltered(PointCloudType& filtered) {
    boost::unordered_map<MapPoint, float>::iterator it =
        all_points_.begin();
    while (it != all_points_.end()) {
      if (this_frame_.find(it->first) == this_frame_.end()) {
        it->second = 0.9*it->second + 0.1*0.;
      }
      if (it->second >= 4.) {
        PointT pt;
        pt.x = it->first.x / 100.;
        pt.y = it->first.y / 100.;
        pt.z = it->first.z / 100.;
        filtered.push_back(pt);
      }
      ++it;
    }
  }
private:
  boost::unordered_set<MapPoint> this_frame_;
  boost::unordered_map<MapPoint, float> all_points_;
};
#endif
<|endoftext|>


<commit_before>#include "Adafruit_Sensor.h"

void Adafruit_Sensor::Adafruit_Sensor() {
}

void Adafruit_Sensor::constructor() {
}
<commit_msg>Update Adafruit_Sensor.cpp<commit_after>#include "Adafruit_Sensor.h"

Adafruit_Sensor::Adafruit_Sensor() {
}

void Adafruit_Sensor::constructor() {
}
<|endoftext|>


<commit_before>//
//  lifo-stack-resizing-array.cpp
//  Copyright © 2017 Dylan Brown. All rights reserved.
//

#include <iostream>

using namespace std;

template<typename T> class ResizingArrayStack {
public:
    // Self-reflective functions on the status of the stack.
    bool is_empty() { return ( N == 0 ); }
    int size() { return N; }

    void push(T item);
    T pop();

    T* begin() { return &array_ptr[0]; }
    T* end() { return &array_ptr[N]; }

    ~ResizingArrayStack() {
        // Style note for 'modern' C++: prefer unique_ptr to new/delete operators.
        delete [] array_ptr;
    }

private:
    // Allocate space for a traditional array on the heap.
    T* array_ptr = new T[1];
    // Keep track of the space allocated for the array, max_size * sizeof(T).
    int max_size = 1;
    // Keep track of the current number of items on the stack.
    int N = 0;

    void resize(int new_size);
};

template<typename T> void ResizingArrayStack<T>::push(T item)
{
    if (N == max_size) { resize(2 * max_size); }
    // Push to the stack and increment the current count of items.
    array_ptr[N++] = item;
}

template<typename T> T ResizingArrayStack<T>::pop()
{
    // Warning: calling pop() on an empty ResizingArrayStack is UNDEFINED.
    // Remember that max index is N-1, so prefix decrement to pop from the stack.
    T item = array_ptr[--N];
    // Shrink the array if needed.
    if ( N > 0 && N == (max_size / 4) ) { resize(max_size / 2); }
    return item;
}

template<typename T> void ResizingArrayStack<T>::resize(int new_size)
{
    max_size = new_size;
    // Allocate a replacement array with space adequate for the stack.
    T* replacement = new T[max_size];
    // Copy each element into the replacement array.
    for (int i = 0; i < N; i++) {
        replacement[i] = array_ptr[i];
    }
    // Free the memory associated with the old array.
    delete [] array_ptr;
    // Reset the pointer to the newly resized array.
    array_ptr = replacement;
}

int main ()
{
    // Create the stack with type `double`.
    auto lifo_stack = ResizingArrayStack<double>{};
    cout << "Created an empty LIFO stack for double type items, with a resizing array implementation." << endl;

    // Fill the stack.
    lifo_stack.push(1.01);
    lifo_stack.push(2.02);
    lifo_stack.push(3.14);
    lifo_stack.push(4.04);
    cout << "Request status, the LIFO stack has size: " << lifo_stack.size() << endl;
    cout << "Request status, the LIFO stack is empty: " << (lifo_stack.is_empty() ? "true" : "false") << endl;

    // Here we're iterating forward through the array, with an unused variable `i`.
    // It would be nice performance-wise to iterate in reverse without calling pop(), and without triggering a resize.
    for ( auto& i : lifo_stack ) {
        cout << "Current loop iteration has i = " << i << endl;
    }
    // // Alternatively, call lifo_stack.pop(), N times.
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;

    cout << "Request status, the LIFO stack has size: " << lifo_stack.size() << endl;
    cout << "Request status, the LIFO stack is empty: " << (lifo_stack.is_empty() ? "true" : "false") << endl;
}
<commit_msg>Reversed iteration is working with range-based for-loop.<commit_after>//
//  lifo-stack-resizing-array.cpp
//  Copyright © 2017 Dylan Brown. All rights reserved.
//

#include <iostream>
#include <iterator>

template<typename T> class ResizingArrayStack {
public:
    // Self-reflective functions on the status of the stack.
    bool is_empty() { return ( N == 0 ); }
    int size() { return N; }

    void push(T item);
    T pop();

    //----- Begin reversed iteration section -----//
    // Please see the example here, (http://en.cppreference.com/w/cpp/iterator/iterator).
    // Member typedefs inherit from std::iterator.
    class stackIterator: public std::iterator<
                        std::input_iterator_tag,   // iterator_category
                        T,                         // value_type
                        T,                         // difference_type
                        const T*,                  // pointer
                        T                          // reference
                        >{
        int index = 0;
        T* it_ptr = nullptr;
    public:
        stackIterator(int _index = 0, T* _it_ptr = nullptr) { index = _index; it_ptr = _it_ptr; }
        // Prefix ++, equal, unequal, and dereference operators are the minimum required for range based for-loops.
        stackIterator& operator++() { --index; return *this; }  // Here is where we reverse the sequence.
        bool operator==(stackIterator other) { return index == other.index; }
        bool operator!=(stackIterator other) { return !( *this == other ); }
        T operator*() { return it_ptr[index-1]; }
    };

    stackIterator begin() { return stackIterator(N, array_ptr); }
    stackIterator end() {
        N = 0;  // 'Empty' the array.
        max_size = 1;  // Don't waste time calling resize() now.
        return stackIterator(0, array_ptr);
    }
    //----- End reversed iteration section -----//

    ~ResizingArrayStack() {
        // Style note for 'modern' C++: prefer unique_ptr to new/delete operators.
        delete [] array_ptr;
    }

private:
    // Allocate space for a traditional array on the heap.
    T* array_ptr = new T[1];
    // Keep track of the space allocated for the array, max_size * sizeof(T).
    int max_size = 1;
    // Keep track of the current number of items on the stack.
    int N = 0;

    void resize(int new_size);
};

template<typename T> void ResizingArrayStack<T>::push(T item)
{
    if (N == max_size) { resize(2 * max_size); }
    // Push to the stack and increment the current count of items.
    array_ptr[N++] = item;
}

template<typename T> T ResizingArrayStack<T>::pop()
{
    // Warning: calling pop() on an empty ResizingArrayStack is UNDEFINED.
    // Remember that max index is N-1, so prefix decrement to pop from the stack.
    T item = array_ptr[--N];
    // Shrink the array if needed.
    if ( N > 0 && N == (max_size / 4) ) { resize(max_size / 2); }
    return item;
}

template<typename T> void ResizingArrayStack<T>::resize(int new_size)
{
    max_size = new_size;
    // Allocate a replacement array with space adequate for the stack.
    T* replacement = new T[max_size];
    // Copy each element into the replacement array.
    for (int i = 0; i < N; i++) {
        replacement[i] = array_ptr[i];
    }
    // Free the memory associated with the old array.
    delete [] array_ptr;
    // Reset the pointer to the newly resized array.
    array_ptr = replacement;
}

int main ()
{
    using std::cout;
    using std::endl;

    // Create the stack with type `double`.
    auto lifo_stack = ResizingArrayStack<double>{};
    cout << "Created an empty LIFO stack for double type items, with a resizing array implementation." << endl;

    // Fill the stack.
    lifo_stack.push(1.01);
    lifo_stack.push(2.02);
    lifo_stack.push(3.14);
    lifo_stack.push(4.04);
    cout << "Request status, the LIFO stack has size: " << lifo_stack.size() << endl;
    cout << "Request status, the LIFO stack is empty: " << (lifo_stack.is_empty() ? "true" : "false") << endl;

    // It's nice performance-wise to iterate in reverse without calling pop() or triggering a resize.
    for ( auto i : lifo_stack) {
        cout << "Current loop iteration has i = " << i << endl;
    }
    // // Alternatively, call lifo_stack.pop(), N times.
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;
    // cout << "Popped an item from the stack: " << lifo_stack.pop() << endl;

    // The final status of the array should be empty in each case.
    cout << "Request status, the LIFO stack has size: " << lifo_stack.size() << endl;
    cout << "Request status, the LIFO stack is empty: " << (lifo_stack.is_empty() ? "true" : "false") << endl;
}
<|endoftext|>


<commit_before>/*
   Copyright 2013 Brain Research Institute, Melbourne, Australia

   Written by David Raffelt 10/04/2013

   This file is part of MRtrix.

   MRtrix is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   MRtrix is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <QLabel>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QImage>
#include <QFileDialog>

#include "mrtrix.h"
#include "gui/mrview/window.h"
#include "gui/mrview/mode/base.h"
#include "gui/mrview/tool/screen_capture.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Tool
      {

        ScreenCapture::ScreenCapture (Window& main_window, Dock* parent) :
          Base (main_window, parent)
        {
          QVBoxLayout* main_box = new QVBoxLayout (this);

          QGroupBox* rotate_group_box = new QGroupBox ("Rotate");
          QGridLayout* rotate_layout = new QGridLayout;
          rotate_layout->setContentsMargins (5, 5, 5, 5);
          rotate_layout->setSpacing (5);
          main_box->addWidget (rotate_group_box);
          rotate_group_box->setLayout (rotate_layout);

          rotate_layout->addWidget (new QLabel ("Axis X"), 0, 0);
          rotaton_axis_x = new AdjustButton (this);
          rotate_layout->addWidget (rotaton_axis_x, 0, 1);
          rotaton_axis_x->setValue (0.0);
          rotaton_axis_x->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Y"), 1, 0);
          rotaton_axis_y = new AdjustButton (this);
          rotate_layout->addWidget (rotaton_axis_y, 1, 1);
          rotaton_axis_y->setValue (0.0);
          rotaton_axis_y->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Z"), 2, 0);
          rotaton_axis_z = new AdjustButton (this);
          rotate_layout->addWidget (rotaton_axis_z, 2, 1);
          rotaton_axis_z->setValue (1.0);
          rotaton_axis_z->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Angle"), 3, 0);
          degrees_button = new AdjustButton (this);
          rotate_layout->addWidget (degrees_button, 3, 1);
          degrees_button->setValue (0.0);
          degrees_button->setRate (0.1);

          QGroupBox* output_group_box = new QGroupBox ("Output");
          main_box->addWidget (output_group_box);
          QGridLayout* output_grid_layout = new QGridLayout;
          output_group_box->setLayout (output_grid_layout);

          output_grid_layout->addWidget (new QLabel ("Prefix"), 0, 0);
          prefix_textbox = new QLineEdit ("screenshot", this);
          output_grid_layout->addWidget (prefix_textbox, 0, 1);

          folder_button = new QPushButton ("Select output folder", this);
          folder_button->setToolTip (tr ("Output Folder"));
          connect (folder_button, SIGNAL (clicked()), this, SLOT (select_output_folder_slot ()));
          output_grid_layout->addWidget (folder_button, 1, 0, 1, 2);

          QGroupBox* capture_group_box = new QGroupBox ("Capture");
          main_box->addWidget (capture_group_box);
          QGridLayout* capture_grid_layout = new QGridLayout;
          capture_group_box->setLayout (capture_grid_layout);

          capture_grid_layout->addWidget (new QLabel ("Start Index"), 0, 0);
          start_index = new QSpinBox (this);
          start_index->setMinimum (0);
          start_index->setMaximum (std::numeric_limits<int>::max());
          start_index->setValue (0);
          capture_grid_layout->addWidget (start_index, 0, 1);

          capture_grid_layout->addWidget (new QLabel ("Frames"), 1, 0);
          frames = new QSpinBox (this);
          frames->setMinimum (0);
          frames->setMaximum (std::numeric_limits<int>::max());
          frames->setValue (1);
          capture_grid_layout->addWidget (frames, 1, 1);

          QPushButton* capture = new QPushButton ("Go", this);
          connect (capture, SIGNAL (clicked()), this, SLOT (on_screen_capture()));

          capture_grid_layout->addWidget (capture, 2, 0, 1, 2);

          main_box->addStretch ();

          directory = new QDir();
        }

        void ScreenCapture::on_screen_capture ()
        {
          if (window.snap_to_image ())
            window.set_snap_to_image (false);
          float radians = degrees_button->value() * (M_PI / 180.0);
          std::string folder (directory->path().toUtf8().constData());
          std::string prefix (prefix_textbox->text().toUtf8().constData());
          int first_index = start_index->value();
          int i = first_index;
          for (; i < first_index + frames->value(); ++i) {
            this->window.captureGL (folder + "/" + prefix + printf ("%04d.png", i));
            Math::Versor<float> orientation (this->window.orientation());
            Math::Vector<float> axis (3);
            axis[0] = rotaton_axis_x->value();
            axis[1] = rotaton_axis_y->value();
            axis[2] = rotaton_axis_z->value();
            Math::Versor<float> rotation (radians, axis.ptr());
            orientation *= rotation;
            this->window.set_orientation (orientation);
            this->window.updateGL();
            start_index->setValue (i + 1);
          }
        }

        bool ScreenCapture::select_output_folder_slot ()
        {
          directory->setPath(QFileDialog::getExistingDirectory (this, tr("Directory"), directory->path()));
          QString path (shorten(directory->path().toUtf8().constData(), 20, 0).c_str());
          folder_button->setText(path);
          return true;
        }

      }
    }
  }
}

<commit_msg>Changed screen capture to rotate about image axis (not wrt the camera)<commit_after>/*
   Copyright 2013 Brain Research Institute, Melbourne, Australia

   Written by David Raffelt 10/04/2013

   This file is part of MRtrix.

   MRtrix is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   MRtrix is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <QLabel>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QImage>
#include <QFileDialog>

#include "mrtrix.h"
#include "gui/mrview/window.h"
#include "gui/mrview/mode/base.h"
#include "gui/mrview/tool/screen_capture.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Tool
      {

        ScreenCapture::ScreenCapture (Window& main_window, Dock* parent) :
          Base (main_window, parent)
        {
          QVBoxLayout* main_box = new QVBoxLayout (this);

          QGroupBox* rotate_group_box = new QGroupBox ("Rotate");
          QGridLayout* rotate_layout = new QGridLayout;
          rotate_layout->setContentsMargins (5, 5, 5, 5);
          rotate_layout->setSpacing (5);
          main_box->addWidget (rotate_group_box);
          rotate_group_box->setLayout (rotate_layout);

          rotate_layout->addWidget (new QLabel ("Axis X"), 0, 0);
          rotaton_axis_x = new AdjustButton (this);
          rotate_layout->addWidget (rotaton_axis_x, 0, 1);
          rotaton_axis_x->setValue (0.0);
          rotaton_axis_x->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Y"), 1, 0);
          rotaton_axis_y = new AdjustButton (this);
          rotate_layout->addWidget (rotaton_axis_y, 1, 1);
          rotaton_axis_y->setValue (0.0);
          rotaton_axis_y->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Z"), 2, 0);
          rotaton_axis_z = new AdjustButton (this);
          rotate_layout->addWidget (rotaton_axis_z, 2, 1);
          rotaton_axis_z->setValue (1.0);
          rotaton_axis_z->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Angle"), 3, 0);
          degrees_button = new AdjustButton (this);
          rotate_layout->addWidget (degrees_button, 3, 1);
          degrees_button->setValue (0.0);
          degrees_button->setRate (0.1);

          QGroupBox* output_group_box = new QGroupBox ("Output");
          main_box->addWidget (output_group_box);
          QGridLayout* output_grid_layout = new QGridLayout;
          output_group_box->setLayout (output_grid_layout);

          output_grid_layout->addWidget (new QLabel ("Prefix"), 0, 0);
          prefix_textbox = new QLineEdit ("screenshot", this);
          output_grid_layout->addWidget (prefix_textbox, 0, 1);

          folder_button = new QPushButton ("Select output folder", this);
          folder_button->setToolTip (tr ("Output Folder"));
          connect (folder_button, SIGNAL (clicked()), this, SLOT (select_output_folder_slot ()));
          output_grid_layout->addWidget (folder_button, 1, 0, 1, 2);

          QGroupBox* capture_group_box = new QGroupBox ("Capture");
          main_box->addWidget (capture_group_box);
          QGridLayout* capture_grid_layout = new QGridLayout;
          capture_group_box->setLayout (capture_grid_layout);

          capture_grid_layout->addWidget (new QLabel ("Start Index"), 0, 0);
          start_index = new QSpinBox (this);
          start_index->setMinimum (0);
          start_index->setMaximum (std::numeric_limits<int>::max());
          start_index->setValue (0);
          capture_grid_layout->addWidget (start_index, 0, 1);

          capture_grid_layout->addWidget (new QLabel ("Frames"), 1, 0);
          frames = new QSpinBox (this);
          frames->setMinimum (0);
          frames->setMaximum (std::numeric_limits<int>::max());
          frames->setValue (1);
          capture_grid_layout->addWidget (frames, 1, 1);

          QPushButton* capture = new QPushButton ("Go", this);
          connect (capture, SIGNAL (clicked()), this, SLOT (on_screen_capture()));

          capture_grid_layout->addWidget (capture, 2, 0, 1, 2);

          main_box->addStretch ();

          directory = new QDir();
        }

        void ScreenCapture::on_screen_capture ()
        {
          if (window.snap_to_image ())
            window.set_snap_to_image (false);
          float radians = degrees_button->value() * (M_PI / 180.0);
          std::string folder (directory->path().toUtf8().constData());
          std::string prefix (prefix_textbox->text().toUtf8().constData());
          int first_index = start_index->value();
          int i = first_index;
          for (; i < first_index + frames->value(); ++i) {
            this->window.captureGL (folder + "/" + prefix + printf ("%04d.png", i));
            Math::Versor<float> orientation (this->window.orientation());
            Math::Vector<float> axis (3);
            axis[0] = rotaton_axis_x->value();
            axis[1] = rotaton_axis_y->value();
            axis[2] = rotaton_axis_z->value();
            Math::Versor<float> rotation (radians, axis.ptr());
            rotation *= orientation;
            this->window.set_orientation (rotation);
            this->window.updateGL();
            start_index->setValue (i + 1);
          }
        }

        bool ScreenCapture::select_output_folder_slot ()
        {
          directory->setPath(QFileDialog::getExistingDirectory (this, tr("Directory"), directory->path()));
          QString path (shorten(directory->path().toUtf8().constData(), 20, 0).c_str());
          folder_button->setText(path);
          return true;
        }

      }
    }
  }
}

<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "RoutingInputWidget.h"

#include "MarbleRunnerManager.h"
#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "RouteSkeleton.h"
#include "TinyWebBrowser.h"
#include "MarbleLocale.h"

#include <QtCore/QTimer>
#include <QtGui/QLineEdit>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QMovie>
#include <QtGui/QIcon>
#include <QtXml/QDomDocument>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtCore/QUrl>

namespace Marble {

class RoutingInputWidgetPrivate
{
public:
    QPushButton *m_stateButton;

    QLineEdit *m_lineEdit;

    QPushButton *m_removeButton;

    QPushButton *m_pickButton;

    MarbleRunnerManager *m_runnerManager;

    MarblePlacemarkModel* m_placemarkModel;

    QMovie m_progress;

    QTimer m_progressTimer;

    RouteSkeleton* m_route;

    int m_index;

    QNetworkAccessManager *m_manager;

    QTimer m_nominatimTimer;

    /** Constructor */
    RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent);

    /** Initiate reverse geocoding request to download address */
    void adjustText();
};

RoutingInputWidgetPrivate::RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent) :
        m_lineEdit(0), m_runnerManager(new MarbleRunnerManager(parent)),
        m_placemarkModel(0), m_progress(":/data/bitmaps/progress.mng"),
        m_route(skeleton), m_index(index), m_manager(new QNetworkAccessManager(parent))
{
    m_stateButton = new QPushButton(parent);
    m_stateButton->setToolTip("Center Map here");
    m_stateButton->setEnabled(false);
    m_stateButton->setIcon(QIcon(m_route->pixmap(m_index)));
    m_stateButton->setFlat(true);
    m_stateButton->setMaximumWidth(22);
    m_stateButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    m_lineEdit = new QLineEdit(parent);

    GeoDataCoordinates pos = m_route->at(m_index);
    if (pos.longitude() != 0.0 && pos.latitude() != 0.0) {
        m_lineEdit->setText( pos.toString() );
        m_stateButton->setEnabled(true);
    }

    m_removeButton = new QPushButton(parent);
    /** @todo: Use an icon instead */
    m_removeButton->setText("X");
    m_removeButton->setToolTip("Remove this input field");
    m_removeButton->setFlat(true);
    m_removeButton->setMaximumWidth(12);

    m_pickButton = new QPushButton(parent);
    m_pickButton->setIcon(QIcon(":/data/bitmaps/routing_select.png"));
    m_pickButton->setToolTip("Choose position from the map");
    m_pickButton->setCheckable(true);
    m_pickButton->setFlat(true);
    m_pickButton->setMaximumWidth(22);
    m_pickButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    m_progressTimer.setInterval(100);
    m_nominatimTimer.setInterval(1000);
    m_nominatimTimer.setSingleShot(true);
}

void RoutingInputWidgetPrivate::adjustText()
{
    m_nominatimTimer.start();
}

RoutingInputWidget::RoutingInputWidget(RouteSkeleton *skeleton, int index, QWidget *parent) :
        QWidget(parent), d(new RoutingInputWidgetPrivate(skeleton, index, this))
{
    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(0);

    layout->addWidget(d->m_pickButton);
    layout->addWidget(d->m_stateButton);
    layout->addWidget(d->m_lineEdit);
    layout->addWidget(d->m_removeButton);

    connect(d->m_stateButton, SIGNAL(clicked()),
            this, SLOT(requestActivity()));
    connect(d->m_pickButton, SIGNAL(clicked(bool)),
            this, SLOT(setMapInputModeEnabled(bool)));
    connect(d->m_removeButton, SIGNAL(clicked()),
            this, SLOT(requestRemoval()));

    connect(d->m_runnerManager, SIGNAL(modelChanged(MarblePlacemarkModel*)),
            this, SLOT(setPlacemarkModel(MarblePlacemarkModel*)));
    connect(d->m_lineEdit, SIGNAL(returnPressed()),
            this, SLOT(findPlacemarks()));
    connect(d->m_lineEdit, SIGNAL(textChanged(QString)),
            this, SLOT(setInvalid()));
    connect(&d->m_progressTimer, SIGNAL(timeout()),
            this, SLOT(updateProgress()));
    connect(d->m_runnerManager, SIGNAL(searchFinished(QString)),
            this, SLOT(finishSearch()));
    connect(skeleton, SIGNAL(positionChanged(int, GeoDataCoordinates)),
            this, SLOT(updatePosition(int, GeoDataCoordinates)));
    connect(&d->m_nominatimTimer, SIGNAL(timeout()),
            this, SLOT(startHttpRequest()));
}

RoutingInputWidget::~RoutingInputWidget()
{
    delete d;
}

void RoutingInputWidget::startHttpRequest()
{
    if (!hasTargetPosition())
        return;

    GeoDataCoordinates position = targetPosition();
    QString base = "http://nominatim.openstreetmap.org/reverse?format=xml&addressdetails=0";
    // @todo: Alternative URI with addressdetails=1 could be used for shorther placemark name
    QString query = "&lon=%1&lat=%2&accept-language=%3";
    double lon = position.longitude(GeoDataCoordinates::Degree);
    double lat = position.latitude(GeoDataCoordinates::Degree);
    QString url = QString(base + query).arg(lon).arg(lat).arg(MarbleLocale::languageCode());

    QObject::connect(d->m_manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(handleHttpReply(QNetworkReply*)));

    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "RoutingInputWidget") );

    d->m_manager->get(QNetworkRequest(request));
}

void RoutingInputWidget::setPlacemarkModel(MarblePlacemarkModel* model)
{
    d->m_placemarkModel = model;
}

void RoutingInputWidget::setTargetPosition(const GeoDataCoordinates &position)
{
    if (!hasInput() || d->m_pickButton->isChecked()) {
        d->m_lineEdit->setText( position.toString() );
    }

    d->m_pickButton->setChecked(false);
    d->m_route->setPosition(d->m_index, position);
    d->m_progressTimer.stop();
    d->m_stateButton->setEnabled(true);
    if (!hasTargetPosition()) {
        d->m_route->setPosition(d->m_index, position);
        emit targetValidityChanged(true);
        d->adjustText();
    }
}

bool RoutingInputWidget::hasTargetPosition() const
{
    GeoDataCoordinates pos = targetPosition();
    return pos.longitude() != 0.0 && pos.latitude() != 0.0;
}

GeoDataCoordinates RoutingInputWidget::targetPosition() const
{
    return d->m_route->at(d->m_index);
}

void RoutingInputWidget::findPlacemarks()
{
    QString text = d->m_lineEdit->text();
    if (text.isEmpty()) {
        setInvalid();
    }
    else {
        d->m_progressTimer.start();
        d->m_runnerManager->newText(text);
    }
}

MarblePlacemarkModel* RoutingInputWidget::searchResultModel()
{
    return d->m_placemarkModel;
}

void RoutingInputWidget::requestActivity()
{
    if (hasTargetPosition()) {
        emit activityRequest(this);
    }
}

void RoutingInputWidget::requestRemoval()
{
    emit removalRequest(this);
}

void RoutingInputWidget::setSimple(bool simple)
{
    d->m_removeButton->setVisible(!simple);
    d->m_stateButton->setVisible(!simple);
    d->m_pickButton->setVisible(!simple);
}

bool RoutingInputWidget::hasInput() const
{
    return !d->m_lineEdit->text().isEmpty();
}

void RoutingInputWidget::setMapInputModeEnabled(bool enabled)
{
   emit mapInputModeEnabled(this, enabled);
}

void RoutingInputWidget::updateProgress()
{
    d->m_progress.jumpToNextFrame();
    QPixmap frame = d->m_progress.currentPixmap();
    d->m_stateButton->setIcon(frame);
}

void RoutingInputWidget::finishSearch()
{
    d->m_progressTimer.stop();
    d->m_stateButton->setIcon(QIcon(d->m_route->pixmap(d->m_index)));
    d->m_stateButton->setEnabled(true);
    emit searchFinished(this);
}

void RoutingInputWidget::setInvalid()
{
    if (!hasTargetPosition()) {
        emit targetValidityChanged(false);
    }
}

void RoutingInputWidget::abortMapInputRequest()
{
    d->m_pickButton->setChecked(false);
}

void RoutingInputWidget::setIndex(int index)
{
    d->m_index = index;
    d->m_stateButton->setEnabled(hasTargetPosition());
    d->m_stateButton->setIcon(QIcon(d->m_route->pixmap(d->m_index)));
}

void RoutingInputWidget::updatePosition(int index, const GeoDataCoordinates &position)
{
    if (index == d->m_index) {
        d->m_lineEdit->setText( position.toString() );
        d->m_stateButton->setEnabled(hasTargetPosition());
        d->m_stateButton->setIcon(d->m_route->pixmap(d->m_index));
        emit targetValidityChanged(hasTargetPosition());
        d->adjustText();
    }
}

void RoutingInputWidget::handleHttpReply( QNetworkReply* reply )
{
    QDomDocument xml;
    if (!xml.setContent(reply->readAll())) {
        qWarning() << "Cannot parse osm nominatim result " << xml.toString();
        return;
    }

    QVector<GeoDataPlacemark> placemarks;
    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName("result");
    if (places.size()==1) {
        QString address = places.item(0).toElement().text();
        d->m_lineEdit->setText(address);
        d->m_lineEdit->setCursorPosition(0);
    }
}

} // namespace Marble

#include "RoutingInputWidget.moc"
<commit_msg>Trigger reverse geocoding at creation time, if needed.<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "RoutingInputWidget.h"

#include "MarbleRunnerManager.h"
#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "RouteSkeleton.h"
#include "TinyWebBrowser.h"
#include "MarbleLocale.h"

#include <QtCore/QTimer>
#include <QtGui/QLineEdit>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QMovie>
#include <QtGui/QIcon>
#include <QtXml/QDomDocument>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtCore/QUrl>

namespace Marble {

class RoutingInputWidgetPrivate
{
public:
    QPushButton *m_stateButton;

    QLineEdit *m_lineEdit;

    QPushButton *m_removeButton;

    QPushButton *m_pickButton;

    MarbleRunnerManager *m_runnerManager;

    MarblePlacemarkModel* m_placemarkModel;

    QMovie m_progress;

    QTimer m_progressTimer;

    RouteSkeleton* m_route;

    int m_index;

    QNetworkAccessManager *m_manager;

    QTimer m_nominatimTimer;

    /** Constructor */
    RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent);

    /** Initiate reverse geocoding request to download address */
    void adjustText();
};

RoutingInputWidgetPrivate::RoutingInputWidgetPrivate(RouteSkeleton *skeleton, int index, QWidget *parent) :
        m_lineEdit(0), m_runnerManager(new MarbleRunnerManager(parent)),
        m_placemarkModel(0), m_progress(":/data/bitmaps/progress.mng"),
        m_route(skeleton), m_index(index), m_manager(new QNetworkAccessManager(parent))
{
    m_stateButton = new QPushButton(parent);
    m_stateButton->setToolTip("Center Map here");
    m_stateButton->setEnabled(false);
    m_stateButton->setIcon(QIcon(m_route->pixmap(m_index)));
    m_stateButton->setFlat(true);
    m_stateButton->setMaximumWidth(22);
    m_stateButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    m_lineEdit = new QLineEdit(parent);

    GeoDataCoordinates pos = m_route->at(m_index);
    if (pos.longitude() != 0.0 && pos.latitude() != 0.0) {
        m_lineEdit->setText( pos.toString() );
        m_stateButton->setEnabled(true);
    }

    m_removeButton = new QPushButton(parent);
    /** @todo: Use an icon instead */
    m_removeButton->setText("X");
    m_removeButton->setToolTip("Remove this input field");
    m_removeButton->setFlat(true);
    m_removeButton->setMaximumWidth(12);

    m_pickButton = new QPushButton(parent);
    m_pickButton->setIcon(QIcon(":/data/bitmaps/routing_select.png"));
    m_pickButton->setToolTip("Choose position from the map");
    m_pickButton->setCheckable(true);
    m_pickButton->setFlat(true);
    m_pickButton->setMaximumWidth(22);
    m_pickButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    m_progressTimer.setInterval(100);
    m_nominatimTimer.setInterval(1000);
    m_nominatimTimer.setSingleShot(true);
}

void RoutingInputWidgetPrivate::adjustText()
{
    m_nominatimTimer.start();
}

RoutingInputWidget::RoutingInputWidget(RouteSkeleton *skeleton, int index, QWidget *parent) :
        QWidget(parent), d(new RoutingInputWidgetPrivate(skeleton, index, this))
{
    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(0);

    layout->addWidget(d->m_pickButton);
    layout->addWidget(d->m_stateButton);
    layout->addWidget(d->m_lineEdit);
    layout->addWidget(d->m_removeButton);

    connect(d->m_stateButton, SIGNAL(clicked()),
            this, SLOT(requestActivity()));
    connect(d->m_pickButton, SIGNAL(clicked(bool)),
            this, SLOT(setMapInputModeEnabled(bool)));
    connect(d->m_removeButton, SIGNAL(clicked()),
            this, SLOT(requestRemoval()));

    connect(d->m_runnerManager, SIGNAL(modelChanged(MarblePlacemarkModel*)),
            this, SLOT(setPlacemarkModel(MarblePlacemarkModel*)));
    connect(d->m_lineEdit, SIGNAL(returnPressed()),
            this, SLOT(findPlacemarks()));
    connect(d->m_lineEdit, SIGNAL(textChanged(QString)),
            this, SLOT(setInvalid()));
    connect(&d->m_progressTimer, SIGNAL(timeout()),
            this, SLOT(updateProgress()));
    connect(d->m_runnerManager, SIGNAL(searchFinished(QString)),
            this, SLOT(finishSearch()));
    connect(skeleton, SIGNAL(positionChanged(int, GeoDataCoordinates)),
            this, SLOT(updatePosition(int, GeoDataCoordinates)));
    connect(&d->m_nominatimTimer, SIGNAL(timeout()),
            this, SLOT(startHttpRequest()));

    d->adjustText();
}

RoutingInputWidget::~RoutingInputWidget()
{
    delete d;
}

void RoutingInputWidget::startHttpRequest()
{
    if (!hasTargetPosition())
        return;

    GeoDataCoordinates position = targetPosition();
    QString base = "http://nominatim.openstreetmap.org/reverse?format=xml&addressdetails=0";
    // @todo: Alternative URI with addressdetails=1 could be used for shorther placemark name
    QString query = "&lon=%1&lat=%2&accept-language=%3";
    double lon = position.longitude(GeoDataCoordinates::Degree);
    double lat = position.latitude(GeoDataCoordinates::Degree);
    QString url = QString(base + query).arg(lon).arg(lat).arg(MarbleLocale::languageCode());

    QObject::connect(d->m_manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(handleHttpReply(QNetworkReply*)));

    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "RoutingInputWidget") );

    d->m_manager->get(QNetworkRequest(request));
}

void RoutingInputWidget::setPlacemarkModel(MarblePlacemarkModel* model)
{
    d->m_placemarkModel = model;
}

void RoutingInputWidget::setTargetPosition(const GeoDataCoordinates &position)
{
    if (!hasInput() || d->m_pickButton->isChecked()) {
        d->m_lineEdit->setText( position.toString() );
    }

    d->m_pickButton->setChecked(false);
    d->m_route->setPosition(d->m_index, position);
    d->m_progressTimer.stop();
    d->m_stateButton->setEnabled(true);
    emit targetValidityChanged(true);
}

bool RoutingInputWidget::hasTargetPosition() const
{
    GeoDataCoordinates pos = targetPosition();
    return pos.longitude() != 0.0 && pos.latitude() != 0.0;
}

GeoDataCoordinates RoutingInputWidget::targetPosition() const
{
    return d->m_route->at(d->m_index);
}

void RoutingInputWidget::findPlacemarks()
{
    QString text = d->m_lineEdit->text();
    if (text.isEmpty()) {
        setInvalid();
    }
    else {
        d->m_progressTimer.start();
        d->m_runnerManager->newText(text);
    }
}

MarblePlacemarkModel* RoutingInputWidget::searchResultModel()
{
    return d->m_placemarkModel;
}

void RoutingInputWidget::requestActivity()
{
    if (hasTargetPosition()) {
        emit activityRequest(this);
    }
}

void RoutingInputWidget::requestRemoval()
{
    emit removalRequest(this);
}

void RoutingInputWidget::setSimple(bool simple)
{
    d->m_removeButton->setVisible(!simple);
    d->m_stateButton->setVisible(!simple);
    d->m_pickButton->setVisible(!simple);
}

bool RoutingInputWidget::hasInput() const
{
    return !d->m_lineEdit->text().isEmpty();
}

void RoutingInputWidget::setMapInputModeEnabled(bool enabled)
{
   emit mapInputModeEnabled(this, enabled);
}

void RoutingInputWidget::updateProgress()
{
    d->m_progress.jumpToNextFrame();
    QPixmap frame = d->m_progress.currentPixmap();
    d->m_stateButton->setIcon(frame);
}

void RoutingInputWidget::finishSearch()
{
    d->m_progressTimer.stop();
    d->m_stateButton->setIcon(QIcon(d->m_route->pixmap(d->m_index)));
    d->m_stateButton->setEnabled(true);
    emit searchFinished(this);
}

void RoutingInputWidget::setInvalid()
{
    if (!hasTargetPosition()) {
        emit targetValidityChanged(false);
    }
}

void RoutingInputWidget::abortMapInputRequest()
{
    d->m_pickButton->setChecked(false);
}

void RoutingInputWidget::setIndex(int index)
{
    d->m_index = index;
    d->m_stateButton->setEnabled(hasTargetPosition());
    d->m_stateButton->setIcon(QIcon(d->m_route->pixmap(d->m_index)));
}

void RoutingInputWidget::updatePosition(int index, const GeoDataCoordinates &position)
{
    if (index == d->m_index) {
        d->m_lineEdit->setText( position.toString() );
        d->m_stateButton->setEnabled(hasTargetPosition());
        d->m_stateButton->setIcon(d->m_route->pixmap(d->m_index));
        emit targetValidityChanged(hasTargetPosition());
        d->adjustText();
    }
}

void RoutingInputWidget::handleHttpReply( QNetworkReply* reply )
{
    QDomDocument xml;
    if (!xml.setContent(reply->readAll())) {
        qWarning() << "Cannot parse osm nominatim result " << xml.toString();
        return;
    }

    QVector<GeoDataPlacemark> placemarks;
    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName("result");
    if (places.size()==1) {
        QString address = places.item(0).toElement().text();
        d->m_lineEdit->setText(address);
        d->m_lineEdit->setCursorPosition(0);
    }
}

} // namespace Marble

#include "RoutingInputWidget.moc"
<|endoftext|>


<commit_before>/**
* Developer: Minhas Kamal (BSSE-0509, IIT, DU)
* Date: 17.Aug.2014, 11.Dec.2014, 30.Aug.2015
**/

#include <stdio.h>
#include <time.h>
#include <iostream>

using namespace std;

char* decode(int i);
int remember=0;

int main(){
    FILE *file = fopen("Record.log", "a");
    fprintf(file, "0");
    fclose(file);

    FILE *inputFile, *outputFile;

    if((inputFile=fopen("Record.log", "r"))==NULL || (outputFile=fopen("Data.log", "a"))==NULL){
        printf("ERROR!!!");
        return 1;
    }

    int num;
    char date[30];
    char ch = fgetc(inputFile);
    while(ch!=EOF){

        if(ch=='\t'){
            fprintf(outputFile, ">>\n");

            fscanf(inputFile, "%d", &num);
            while(num!=0){
                fprintf(outputFile, "%s", decode(num));
                fscanf(inputFile, "%d", &num);
            }
        }else{
            fgets(date, 30, inputFile);
            fprintf(outputFile, "%c%s", ch, date);
        }

        ch = fgetc(inputFile);
    }

    fclose(inputFile);
    fclose(outputFile);

    return 0;
}

char* decode(int i){
    char* ch;

    if(remember==i){
        ch="";
        return ch;
    }else{
        remember=0;
        return ch;//
    }

    switch(i){
    case 1:
        ch="[LC]";
        remember=i;
        break;
    case 2:
        ch="[RC]";
        remember=i;
        break;
    case 8:
        ch="[<B]";
        break;
    case 9:
        ch="[TAB]";
        break;
    case 13:
        ch="\n";
        break;
    case 16:
        ch="[SH]";
        remember=i;
        break;
    case 17:
        ch="[CTR]";
        remember=i;
        break;
    case 18:
        ch="[ALT]";
        break;
    case 19:
        ch="[PAUSE]";
        ch="";
        break;
    case 20:
        ch="[CAP]";
        break;
    case 27:
        ch="[ESC]";
        break;
    case 32:
        ch=" ";
        break;
    case 33:
        ch="[PgUp]";
        break;
    case 34:
        ch="[PgDn]";
        break;
    /*
    case 37:
        ch="";
        break;
    case 38:
        ch="";
        break;
    case 39:
        ch="";
        break;
    case 40:
        ch="";
        break;
    case 41:
        ch="";
        break;
    case 42:
        ch="";
        break;
    case 43:
        ch="";
        break;
    case 44:
        ch="";
        break;
        */
    case 45:
        ch="[INS]";
        break;
	case 46:
        ch="[DEL]";
        break;
	case 47:
        ch="/";
        break;
	case 48:
        ch="0";
        break;
	case 49:
        ch="1";
        break;
	case 50:
        ch="2";
        break;
	case 51:
        ch="3";
        break;
	case 52:
        ch="4";
        break;
	case 53:
        ch="5";
        break;
	case 54:
        ch="6";
        break;
	case 55:
        ch="7";
        break;
	case 56:
        ch="8";
        break;
	case 57:
        ch="9";
        break;
	case 65:
        ch="a";
        break;
	case 66:
        ch="b";
        break;
	case 67:
        ch="c";
        break;
	case 68:
        ch="d";
        break;
	case 69:
        ch="e";
        break;
	case 70:
        ch="f";
        break;
	case 71:
        ch="g";
        break;
	case 72:
        ch="h";
        break;
	case 73:
        ch="i";
        break;
	case 74:
        ch="j";
        break;
	case 75:
        ch="k";
        break;
	case 76:
        ch="l";
        break;
	case 77:
        ch="m";
        break;
	case 78:
        ch="n";
        break;
	case 79:
        ch="o";
        break;
	case 80:
        ch="p";
        break;
	case 81:
        ch="q";
        break;
	case 82:
        ch="r";
        break;
	case 83:
        ch="s";
        break;
	case 84:
        ch="t";
        break;
	case 85:
        ch="u";
        break;
	case 86:
        ch="v";
        break;
	case 87:
        ch="w";
        break;
	case 88:
        ch="x";
        break;
	case 89:
        ch="y";
        break;
	case 90:
        ch="z";
        break;
	case 91:
        ch="[STRT]";
        break;
	case 92:
        ch="\\";
        break;
	case 93:
        ch="[MNU]";
        break;
	case 96:
        ch="0";
        break;
	case 97:
        ch="1";
        break;
	case 98:
        ch="2";
        break;
	case 99:
        ch="3";
        break;
	case 100:
        ch="4";
        break;
	case 101:
        ch="5";
        break;
	case 102:
        ch="6";
        break;
	case 103:
        ch="7";
        break;
	case 104:
        ch="8";
        break;
	case 105:
        ch="9";
        break;
	case 106:
        ch="*";
        break;
	case 107:
        ch="+";
        break;
	case 109:
        ch="-";
        break;
	case 110:
        ch=".";
        break;
	case 111:
        ch="/";
        break;
	case 112:
        ch="[f1]";
        break;
	case 113:
        ch="[f2]";
        break;
	case 114:
        ch="[f3]";
        break;
	case 115:
        ch="[f4]";
        break;
	case 116:
        ch="[f5]";
        break;
	case 117:
        ch="[f6]";
        break;
	case 118:
        ch="[f7]";
        break;
	case 119:
        ch="[f8]";
        break;
	case 120:
        ch="[f9]";
        break;
	case 121:
        ch="[f10]";
        break;
	case 122:
        ch="[f11]";
        break;
	case 123:
        ch="[f12]";
        break;
	case 124:
        ch="|";
        break;
	case 144:
        ch="[NUM]";
        break;
    case 150:
        ch="-";
        break;
    /*
    case 151:
        ch="";
        break;
    case 152:
        ch="";
        break;
    case 153:
        ch="";
        break;
    case 154:
        ch="";
        break;
    case 155:
        ch="";
        break;
    case 156:
        ch="";
        break;
    case 157:
        ch="";
        break;
    case 158:
        ch="";
        break;
    case 159:
        ch="";
        break;
    case 160:
        ch="";
        break;
    case 161:
        ch="";
        break;
    case 162:
        ch="";  //[CTR]
        break;
    case 163:
        ch="";  //[CTR]
        break;
    case 164:
        ch="";  //[ALT]
        break;
    case 165:
        ch="";  //[ALT]
        break;
    case 166:
        ch="";
        break;
    case 167:
        ch="";
        break;
    case 168:
        ch="";
        break;
    case 169:
        ch="";
        break;
    case 170:
        ch="";
        break;
    case 171:
        ch="";
        break;
    case 172:
        ch="";
        break;
    case 173:
        ch="";
        break;
    case 174:
        ch="";
        break;
    case 175:
        ch="";
        break;
    case 176:
        ch="";
        break;
    case 177:
        ch="";
        break;
    case 178:
        ch="";
        break;
    case 179:
        ch="";
        break;
    case 180:
        ch="";
        break;
    case 181:
        ch="";
        break;
    case 182:
        ch="";
        break;
    case 183:
        ch="";
        break;
    case 184:
        ch="";
        break;
    case 185:
        ch="";
        break;
    */
    case 186:
        ch=";";
        break;
    case 187:
        ch="=";
        break;
    case 188:
        ch=",";
        break;
    case 189:
        ch="-";
        break;
    case 190:
        ch=".";
        break;
    case 191:
        ch="/";
        break;
    case 192:
        ch="`";
        break;
    /*
    case 193:
        ch="";
        break;
    case 194:
        ch="";
        break;
    case 195:
        ch="";
        break;
    case 196:
        ch="";
        break;
    case 197:
        ch="";
        break;
    case 198:
        ch="";
        break;
    case 199:
        ch="";
        break;
    case 200:
        ch="";
        break;
    case 201:
        ch="";
        break;
    case 202:
        ch="";
        break;
    case 203:
        ch="";
        break;
    case 204:
        ch="";
        break;
    case 205:
        ch="";
        break;
    case 206:
        ch="";
        break;
    case 207:
        ch="";
        break;
    case 208:
        ch="";
        break;
    case 209:
        ch="";
        break;
    case 210:
        ch="";
        break;
    case 211:
        ch="";
        break;
    case 212:
        ch="";
        break;
    case 213:
        ch="";
        break;
    case 214:
        ch="";
        break;
    case 215:
        ch="";
        break;
    case 216:
        ch="";
        break;
    case 217:
        ch="";
        break;
    case 218:
        ch="";
        break;
        */
    case 219:
        ch="[";
        break;
    case 220:
        ch="\\";
        break;
    case 221:
        ch="]";
        break;
    case 222:
        ch="'";
        break;
    /*
    case 223:
        ch="";
        break;
    case 224:
        ch="";
        break;
    case 225:
        ch="";
        break;
    case 226:
        ch="";
        break;
    case 227:
        ch="";
        break;
    case 228:
        ch="";
        break;
    case 229:
        ch="";
        break;
    case 230:
        ch="";
        break;
    case 231:
        ch="";
        break;
    case 232:
        ch="";
        break;
    case 233:
        ch="";
        break;
    case 234:
        ch="";
        break;
    case 235:
        ch="";
        break;
    case 236:
        ch="";
        break;
    case 237:
        ch="";
        break;
    case 238:
        ch="";
        break;
    case 239:
        ch="";
        break;
    case 240:
        ch="";
        break;
    case 241:
        ch="";
        break;
    case 242:
        ch="";
        break;
    case 243:
        ch="";
        break;
    case 244:
        ch="";
        break;
    case 245:
        ch="";
        break;
    case 246:
        ch="";
        break;
    case 247:
        ch="";
        break;
    case 248:
        ch="";
        break;
    case 249:
        ch="";
        break;
    case 250:
        ch="";
        break;
    */
    default:
        ch="[U?]";
        remember=i;
    }

    return ch;
}
<commit_msg>trojan cockroach<commit_after>/**
* Developer: Minhas Kamal (BSSE-0509, IIT, DU)
* Date: 17.Aug.2014, 11.Dec.2014, 30.Aug.2015
**/

#include <stdio.h>
#include <time.h>
#include <iostream>

using namespace std;

char* decode(int i);
int remember=0;

int main(){
    FILE *file = fopen("Record.log", "a");
    fprintf(file, "0");
    fclose(file);

    FILE *inputFile, *outputFile;

    if((inputFile=fopen("Record.log", "r"))==NULL || (outputFile=fopen("Data.log", "a"))==NULL){
        printf("ERROR!!!");
        return 1;
    }

    int num;
    char date[30];
    char ch = fgetc(inputFile);
    while(ch!=EOF){

        if(ch=='\t'){
            fprintf(outputFile, ">>\n");

            fscanf(inputFile, "%d", &num);
            while(num!=0){
                fprintf(outputFile, "%s", decode(num));
                fscanf(inputFile, "%d", &num);
            }
        }else{
            fgets(date, 30, inputFile);
            fprintf(outputFile, "%c%s", ch, date);
        }

        ch = fgetc(inputFile);
    }

    fclose(inputFile);
    fclose(outputFile);

    return 0;
}

char* decode(int i){
    char* ch;

    if(remember==i){
        ch="";
        return ch;
    }else{
        remember=0;
        return ch; // :)
    }

    switch(i){
    case 1:
        ch="[LC]";
        remember=i;
        break;
    case 2:
        ch="[RC]";
        remember=i;
        break;
    case 8:
        ch="[<B]";
        break;
    case 9:
        ch="[TAB]";
        break;
    case 13:
        ch="\n";
        break;
    case 16:
        ch="[SH]";
        remember=i;
        break;
    case 17:
        ch="[CTR]";
        remember=i;
        break;
    case 18:
        ch="[ALT]";
        break;
    case 19:
        ch="[PAUSE]";
        ch="";
        break;
    case 20:
        ch="[CAP]";
        break;
    case 27:
        ch="[ESC]";
        break;
    case 32:
        ch=" ";
        break;
    case 33:
        ch="[PgUp]";
        break;
    case 34:
        ch="[PgDn]";
        break;
    /*
    case 37:
        ch="";
        break;
    case 38:
        ch="";
        break;
    case 39:
        ch="";
        break;
    case 40:
        ch="";
        break;
    case 41:
        ch="";
        break;
    case 42:
        ch="";
        break;
    case 43:
        ch="";
        break;
    case 44:
        ch="";
        break;
        */
    case 45:
        ch="[INS]";
        break;
	case 46:
        ch="[DEL]";
        break;
	case 47:
        ch="/";
        break;
	case 48:
        ch="0";
        break;
	case 49:
        ch="1";
        break;
	case 50:
        ch="2";
        break;
	case 51:
        ch="3";
        break;
	case 52:
        ch="4";
        break;
	case 53:
        ch="5";
        break;
	case 54:
        ch="6";
        break;
	case 55:
        ch="7";
        break;
	case 56:
        ch="8";
        break;
	case 57:
        ch="9";
        break;
	case 65:
        ch="a";
        break;
	case 66:
        ch="b";
        break;
	case 67:
        ch="c";
        break;
	case 68:
        ch="d";
        break;
	case 69:
        ch="e";
        break;
	case 70:
        ch="f";
        break;
	case 71:
        ch="g";
        break;
	case 72:
        ch="h";
        break;
	case 73:
        ch="i";
        break;
	case 74:
        ch="j";
        break;
	case 75:
        ch="k";
        break;
	case 76:
        ch="l";
        break;
	case 77:
        ch="m";
        break;
	case 78:
        ch="n";
        break;
	case 79:
        ch="o";
        break;
	case 80:
        ch="p";
        break;
	case 81:
        ch="q";
        break;
	case 82:
        ch="r";
        break;
	case 83:
        ch="s";
        break;
	case 84:
        ch="t";
        break;
	case 85:
        ch="u";
        break;
	case 86:
        ch="v";
        break;
	case 87:
        ch="w";
        break;
	case 88:
        ch="x";
        break;
	case 89:
        ch="y";
        break;
	case 90:
        ch="z";
        break;
	case 91:
        ch="[STRT]";
        break;
	case 92:
        ch="\\";
        break;
	case 93:
        ch="[MNU]";
        break;
	case 96:
        ch="0";
        break;
	case 97:
        ch="1";
        break;
	case 98:
        ch="2";
        break;
	case 99:
        ch="3";
        break;
	case 100:
        ch="4";
        break;
	case 101:
        ch="5";
        break;
	case 102:
        ch="6";
        break;
	case 103:
        ch="7";
        break;
	case 104:
        ch="8";
        break;
	case 105:
        ch="9";
        break;
	case 106:
        ch="*";
        break;
	case 107:
        ch="+";
        break;
	case 109:
        ch="-";
        break;
	case 110:
        ch=".";
        break;
	case 111:
        ch="/";
        break;
	case 112:
        ch="[f1]";
        break;
	case 113:
        ch="[f2]";
        break;
	case 114:
        ch="[f3]";
        break;
	case 115:
        ch="[f4]";
        break;
	case 116:
        ch="[f5]";
        break;
	case 117:
        ch="[f6]";
        break;
	case 118:
        ch="[f7]";
        break;
	case 119:
        ch="[f8]";
        break;
	case 120:
        ch="[f9]";
        break;
	case 121:
        ch="[f10]";
        break;
	case 122:
        ch="[f11]";
        break;
	case 123:
        ch="[f12]";
        break;
	case 124:
        ch="|";
        break;
	case 144:
        ch="[NUM]";
        break;
    case 150:
        ch="-";
        break;
    /*
    case 151:
        ch="";
        break;
    case 152:
        ch="";
        break;
    case 153:
        ch="";
        break;
    case 154:
        ch="";
        break;
    case 155:
        ch="";
        break;
    case 156:
        ch="";
        break;
    case 157:
        ch="";
        break;
    case 158:
        ch="";
        break;
    case 159:
        ch="";
        break;
    case 160:
        ch="";
        break;
    case 161:
        ch="";
        break;
    case 162:
        ch="";  //[CTR]
        break;
    case 163:
        ch="";  //[CTR]
        break;
    case 164:
        ch="";  //[ALT]
        break;
    case 165:
        ch="";  //[ALT]
        break;
    case 166:
        ch="";
        break;
    case 167:
        ch="";
        break;
    case 168:
        ch="";
        break;
    case 169:
        ch="";
        break;
    case 170:
        ch="";
        break;
    case 171:
        ch="";
        break;
    case 172:
        ch="";
        break;
    case 173:
        ch="";
        break;
    case 174:
        ch="";
        break;
    case 175:
        ch="";
        break;
    case 176:
        ch="";
        break;
    case 177:
        ch="";
        break;
    case 178:
        ch="";
        break;
    case 179:
        ch="";
        break;
    case 180:
        ch="";
        break;
    case 181:
        ch="";
        break;
    case 182:
        ch="";
        break;
    case 183:
        ch="";
        break;
    case 184:
        ch="";
        break;
    case 185:
        ch="";
        break;
    */
    case 186:
        ch=";";
        break;
    case 187:
        ch="=";
        break;
    case 188:
        ch=",";
        break;
    case 189:
        ch="-";
        break;
    case 190:
        ch=".";
        break;
    case 191:
        ch="/";
        break;
    case 192:
        ch="`";
        break;
    /*
    case 193:
        ch="";
        break;
    case 194:
        ch="";
        break;
    case 195:
        ch="";
        break;
    case 196:
        ch="";
        break;
    case 197:
        ch="";
        break;
    case 198:
        ch="";
        break;
    case 199:
        ch="";
        break;
    case 200:
        ch="";
        break;
    case 201:
        ch="";
        break;
    case 202:
        ch="";
        break;
    case 203:
        ch="";
        break;
    case 204:
        ch="";
        break;
    case 205:
        ch="";
        break;
    case 206:
        ch="";
        break;
    case 207:
        ch="";
        break;
    case 208:
        ch="";
        break;
    case 209:
        ch="";
        break;
    case 210:
        ch="";
        break;
    case 211:
        ch="";
        break;
    case 212:
        ch="";
        break;
    case 213:
        ch="";
        break;
    case 214:
        ch="";
        break;
    case 215:
        ch="";
        break;
    case 216:
        ch="";
        break;
    case 217:
        ch="";
        break;
    case 218:
        ch="";
        break;
        */
    case 219:
        ch="[";
        break;
    case 220:
        ch="\\";
        break;
    case 221:
        ch="]";
        break;
    case 222:
        ch="'";
        break;
    /*
    case 223:
        ch="";
        break;
    case 224:
        ch="";
        break;
    case 225:
        ch="";
        break;
    case 226:
        ch="";
        break;
    case 227:
        ch="";
        break;
    case 228:
        ch="";
        break;
    case 229:
        ch="";
        break;
    case 230:
        ch="";
        break;
    case 231:
        ch="";
        break;
    case 232:
        ch="";
        break;
    case 233:
        ch="";
        break;
    case 234:
        ch="";
        break;
    case 235:
        ch="";
        break;
    case 236:
        ch="";
        break;
    case 237:
        ch="";
        break;
    case 238:
        ch="";
        break;
    case 239:
        ch="";
        break;
    case 240:
        ch="";
        break;
    case 241:
        ch="";
        break;
    case 242:
        ch="";
        break;
    case 243:
        ch="";
        break;
    case 244:
        ch="";
        break;
    case 245:
        ch="";
        break;
    case 246:
        ch="";
        break;
    case 247:
        ch="";
        break;
    case 248:
        ch="";
        break;
    case 249:
        ch="";
        break;
    case 250:
        ch="";
        break;
    */
    default:
        ch="[U?]";
        remember=i;
    }

    return ch;
}
<|endoftext|>


<commit_before>/*
 *  timing.cpp
 *
 *  Copyright The Mbed TLS Contributors
 *  Copyright (C) 2021, Arm Limited, All Rights Reserved
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_TIMING_ALT)

#include "mbedtls/timing.h"
#include "drivers/Timeout.h"
#include "drivers/Timer.h"
#include "drivers/LowPowerTimer.h"
#include <chrono>

extern "C" {
    volatile int mbedtls_timing_alarmed = 0;
};

static void handle_alarm(void)
{
    mbedtls_timing_alarmed = 1;
}

extern "C" void mbedtls_set_alarm(int seconds)
{
    static mbed::Timeout t;
    mbedtls_timing_alarmed = 0;

    t.attach(handle_alarm, std::chrono::seconds(seconds));
}

// The static Mbed timer here is initialized once only.
// Mbed TLS can have multiple timers (mbedtls_timing_hr_time) derived
// from the Mbed timer.
#if DEVICE_LPTICKER
static mbed::LowPowerTimer timer;
#elif DEVICE_USTICKER
static mbed::Timer timer;
#else
#error "MBEDTLS_TIMING_C requires either LPTICKER or USTICKER"
#endif
static int timer_init = 0;

#if !defined(HAVE_HARDCLOCK)
#define HAVE_HARDCLOCK

extern "C" unsigned long mbedtls_timing_hardclock(void)
{
    if (timer_init == 0) {
        timer.reset();
        timer.start();
        timer_init = 1;
    }

    return timer.elapsed_time().count();
}
#endif /* !HAVE_HARDCLOCK */

extern "C" unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset)
{
    if (timer_init == 0) {
        timer.reset();
        timer.start();
        timer_init = 1;
    }

    if (reset) {
        val->start = std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count();
        return 0;
    } else {
        return std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count() - val->start;
    }
}

/**
 * Note: The following implementations come from the default timing.c
 * from Mbed TLS. They are disabled in timing.c when MBEDTLS_TIMING_ALT
 * is defined, but the implementation is nonetheless applicable to
 * Mbed OS, so we copy them over.
 */

extern "C" void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
{
    mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;

    ctx->int_ms = int_ms;
    ctx->fin_ms = fin_ms;

    if (fin_ms != 0) {
        (void) mbedtls_timing_get_timer(&ctx->timer, 1);
    }
}

extern "C" int mbedtls_timing_get_delay(void *data)
{
    mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
    unsigned long elapsed_ms;

    if (ctx->fin_ms == 0) {
        return -1;
    }

    elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0);

    if (elapsed_ms >= ctx->fin_ms) {
        return 2;
    }

    if (elapsed_ms >= ctx->int_ms) {
        return 1;
    }

    return 0;
}

#endif // MBEDTLS_TIMING_ALT
<commit_msg>mbedtls: Use LowPowerTimeout for mbedtls_set_alarm() if available<commit_after>/*
 *  timing.cpp
 *
 *  Copyright The Mbed TLS Contributors
 *  Copyright (C) 2021, Arm Limited, All Rights Reserved
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_TIMING_ALT)

#include "mbedtls/timing.h"
#include "drivers/Timeout.h"
#include "drivers/LowPowerTimeout.h"
#include "drivers/Timer.h"
#include "drivers/LowPowerTimer.h"
#include <chrono>

extern "C" {
    volatile int mbedtls_timing_alarmed = 0;
};

static void handle_alarm(void)
{
    mbedtls_timing_alarmed = 1;
}

extern "C" void mbedtls_set_alarm(int seconds)
{
#if DEVICE_LPTICKER
    static mbed::LowPowerTimeout t;
#elif DEVICE_USTICKER
    static mbed::Timeout t;
#else
#error "MBEDTLS_TIMING_C requires either LPTICKER or USTICKER"
#endif

    mbedtls_timing_alarmed = 0;

    t.attach(handle_alarm, std::chrono::seconds(seconds));
}

// The static Mbed timer here is initialized once only.
// Mbed TLS can have multiple timers (mbedtls_timing_hr_time) derived
// from the Mbed timer.
#if DEVICE_LPTICKER
static mbed::LowPowerTimer timer;
#elif DEVICE_USTICKER
static mbed::Timer timer;
#else
#error "MBEDTLS_TIMING_C requires either LPTICKER or USTICKER"
#endif
static int timer_init = 0;

#if !defined(HAVE_HARDCLOCK)
#define HAVE_HARDCLOCK

extern "C" unsigned long mbedtls_timing_hardclock(void)
{
    if (timer_init == 0) {
        timer.reset();
        timer.start();
        timer_init = 1;
    }

    return timer.elapsed_time().count();
}
#endif /* !HAVE_HARDCLOCK */

extern "C" unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset)
{
    if (timer_init == 0) {
        timer.reset();
        timer.start();
        timer_init = 1;
    }

    if (reset) {
        val->start = std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count();
        return 0;
    } else {
        return std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count() - val->start;
    }
}

/**
 * Note: The following implementations come from the default timing.c
 * from Mbed TLS. They are disabled in timing.c when MBEDTLS_TIMING_ALT
 * is defined, but the implementation is nonetheless applicable to
 * Mbed OS, so we copy them over.
 */

extern "C" void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
{
    mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;

    ctx->int_ms = int_ms;
    ctx->fin_ms = fin_ms;

    if (fin_ms != 0) {
        (void) mbedtls_timing_get_timer(&ctx->timer, 1);
    }
}

extern "C" int mbedtls_timing_get_delay(void *data)
{
    mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
    unsigned long elapsed_ms;

    if (ctx->fin_ms == 0) {
        return -1;
    }

    elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0);

    if (elapsed_ms >= ctx->fin_ms) {
        return 2;
    }

    if (elapsed_ms >= ctx->int_ms) {
        return 1;
    }

    return 0;
}

#endif // MBEDTLS_TIMING_ALT
<|endoftext|>


<commit_before>#ifndef CDPI_BYTES_HPP
#define CDPI_BYTES_HPP

#include "cdpi_common.hpp"

#include <string.h>

#include <list>
#include <string>
#include <vector>

#include <boost/shared_array.hpp>

class cdpi_bytes {
public:
    cdpi_bytes() : m_pos(0), m_len(0) { }
    cdpi_bytes(const char *str) { *this = str; }
    cdpi_bytes(boost::shared_array<char> ptr, int len) : m_ptr(ptr),
                                                         m_pos(0),
                                                         m_len(len) { }
    cdpi_bytes(const cdpi_bytes &rhs) { *this = rhs; }

    cdpi_bytes & operator = (const char *str) {
        int len = strlen(str);
        m_ptr = boost::shared_array<char>(new char[len]);
        memcpy(m_ptr.get(), str, len);
        m_len = len;
        m_pos = 0;

        return *this;
    }

    cdpi_bytes & operator = (const cdpi_bytes &rhs) {
        m_ptr = rhs.m_ptr;
        m_len = rhs.m_len;
        m_pos = rhs.m_pos;

        return *this;
    }

    bool operator == (const cdpi_bytes &rhs) const {
        if (m_len != rhs.m_len)
            return false;

        return memcmp(m_ptr.get() + m_pos, rhs.m_ptr.get() + rhs.m_pos,
                      m_len) == 0;
    }

    bool operator < (const cdpi_bytes &rhs) const {
        if (m_len == rhs.m_len)
            return memcmp(m_ptr.get() + m_pos, rhs.m_ptr.get() + rhs.m_pos,
                          m_len) < 0;

        int len = m_len < rhs.m_len ? m_len : len;
        int result;

        result = memcmp(m_ptr.get() + m_pos, rhs.m_ptr.get() + rhs.m_pos, len);
        if (result < 0) {
            return true;
        } else if (result > 0) {
            return false;
        } else {
            return m_len < rhs.m_len;
        }

        return false;
    }

    bool operator > (const cdpi_bytes &rhs) const {
        return rhs < *this;
    }

    void fill_zero() {
        memset(m_ptr.get() + m_pos, 0, m_len);
    }

    void alloc(size_t len) {
        m_ptr = boost::shared_array<char>(new char[len]);

        if (m_ptr.get() == NULL) {
            PERROR();
            exit(-1);
        }

        m_len = len;
    }

    void set_buf(char *buf, int len) {
        m_ptr = boost::shared_array<char>(new char[len]);
        memcpy(m_ptr.get(), buf, len);

        m_len = len;
        m_pos = 0;
    }

    void clear() {
        m_ptr.reset();
        m_pos = 0;
        m_len = 0;
    }

    boost::shared_array<char> m_ptr;
    int m_pos;
    int m_len;
};

int read_bytes_ec(const std::list<cdpi_bytes> &bytes, char *buf, int len,
                  char c);
int read_bytes(std::list<cdpi_bytes> &bytes, char *buf, int len);
int skip_bytes(std::list<cdpi_bytes> &bytes, int len);
int find_char(const char *buf, int len, char c);
void get_digest(cdpi_bytes &md_value, const char *alg, const char *buf,
                unsigned int len);
std::string bin2str(const char *buf, int len);
void print_binary(const char *buf, int len);
void to_lower_str(std::string &str);
void decompress_gzip(const char *buf, int len, std::string &out_buf);
void decompress_zlib(const char *buf, int len, std::string &out_buf);

#endif // CDPI_BYTES_HPP
<commit_msg>fixed a bug<commit_after>#ifndef CDPI_BYTES_HPP
#define CDPI_BYTES_HPP

#include "cdpi_common.hpp"

#include <string.h>

#include <list>
#include <string>
#include <vector>

#include <boost/shared_array.hpp>

class cdpi_bytes {
public:
    cdpi_bytes() : m_pos(0), m_len(0) { }
    cdpi_bytes(const char *str) { *this = str; }
    cdpi_bytes(boost::shared_array<char> ptr, int len) : m_ptr(ptr),
                                                         m_pos(0),
                                                         m_len(len) { }
    cdpi_bytes(const cdpi_bytes &rhs) { *this = rhs; }

    cdpi_bytes & operator = (const char *str) {
        int len = strlen(str);
        m_ptr = boost::shared_array<char>(new char[len]);
        memcpy(m_ptr.get(), str, len);
        m_len = len;
        m_pos = 0;

        return *this;
    }

    cdpi_bytes & operator = (const cdpi_bytes &rhs) {
        m_ptr = rhs.m_ptr;
        m_len = rhs.m_len;
        m_pos = rhs.m_pos;

        return *this;
    }

    bool operator == (const cdpi_bytes &rhs) const {
        if (m_len != rhs.m_len)
            return false;

        return memcmp(m_ptr.get() + m_pos, rhs.m_ptr.get() + rhs.m_pos,
                      m_len) == 0;
    }

    bool operator < (const cdpi_bytes &rhs) const {
        if (m_len == rhs.m_len)
            return memcmp(m_ptr.get() + m_pos, rhs.m_ptr.get() + rhs.m_pos,
                          m_len) < 0;

        int len = m_len < rhs.m_len ? m_len : rhs.m_len;
        int result;

        result = memcmp(m_ptr.get() + m_pos, rhs.m_ptr.get() + rhs.m_pos, len);
        if (result < 0) {
            return true;
        } else if (result > 0) {
            return false;
        } else {
            return m_len < rhs.m_len;
        }

        return false;
    }

    bool operator > (const cdpi_bytes &rhs) const {
        return rhs < *this;
    }

    void fill_zero() {
        memset(m_ptr.get() + m_pos, 0, m_len);
    }

    void alloc(size_t len) {
        m_ptr = boost::shared_array<char>(new char[len]);

        if (m_ptr.get() == NULL) {
            PERROR();
            exit(-1);
        }

        m_len = len;
    }

    void set_buf(char *buf, int len) {
        m_ptr = boost::shared_array<char>(new char[len]);
        memcpy(m_ptr.get(), buf, len);

        m_len = len;
        m_pos = 0;
    }

    void clear() {
        m_ptr.reset();
        m_pos = 0;
        m_len = 0;
    }

    boost::shared_array<char> m_ptr;
    int m_pos;
    int m_len;
};

int read_bytes_ec(const std::list<cdpi_bytes> &bytes, char *buf, int len,
                  char c);
int read_bytes(std::list<cdpi_bytes> &bytes, char *buf, int len);
int skip_bytes(std::list<cdpi_bytes> &bytes, int len);
int find_char(const char *buf, int len, char c);
void get_digest(cdpi_bytes &md_value, const char *alg, const char *buf,
                unsigned int len);
std::string bin2str(const char *buf, int len);
void print_binary(const char *buf, int len);
void to_lower_str(std::string &str);
void decompress_gzip(const char *buf, int len, std::string &out_buf);
void decompress_zlib(const char *buf, int len, std::string &out_buf);

#endif // CDPI_BYTES_HPP
<|endoftext|>