<commit_before>// -*- C++ -*-
/**
 * \file Heap.cc
 * \author Stetson Bost
 * \brief Implements the details of the Heap class
 */

#include "Heap.h"

#include <cassert>
#include <cstddef>
#include <iostream>
#include <vector>

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap>::Heap() : data_(new std::vector<Item>) {
}

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap>::Heap(const Heap& heap) {
  // vector assignment
  *data_ = *heap.data_;
}

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap> Heap<Item, isMaxHeap>::operator=(const Heap& heap) {
  *data_ = *heap.data_;
}

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap>::~Heap() {
  delete data_;
  data_ = nullptr;
}

template <class Item, bool isMaxHeap>
size_t Heap<Item, isMaxHeap>::size() const {
  return data_->size();
}

template <class Item, bool isMaxHeap>
bool Heap<Item, isMaxHeap>::isEmpty() const {
  return data_->empty();
}

template <class Item, bool isMaxHeap>
Item& Heap<Item, isMaxHeap>::peekTop() const {
  // assumes that first element of data exists
  return *data_->begin();
}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::insert(const Item& value) {
  // add value to bottom of heap
  data_->push_back(value);
  // get an iterator for the value
  iterator valueIter = iterator(size() - 1, data_);

  // if value is not at root, make an iterator pointing to value's parent
  if (valueIter != begin()) {
    iterator parentIter = parent(valueIter)

    // Now move the value to the correct position in the Heap

    if (isMaxHeap) {
      // For Max Heap:

      // if value is greater than parent, swap value and parent
      while (*valueIter > *parentIter) {
        swap(valueIter, parentIter);
        valueIter = parentIter;
        // if value is not at root, make update parent iterator
        if (valueIter.index_ != begin()) {
          parentIter = parent(valueIter);
        } else {
          // otherwise, the value is in the appropriate place
          break;
        }
      }
    } else {
      // For Min Heap:

      // if value is less than parent, swap value and parent
      while (*valueIter < *parentIter) {
        swap(valueIter, parentIter);
        valueIter = parentIter;
        // if value is not at root, make update parent iterator
        if (valueIter.index_ != begin()) {
          parentIter = parent(valueIter);
        } else {
          // otherwise, the value is in the appropriate place
          break;
        }
      }
    }
  }
}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::erase(iterator& iter) {
  if (size() > 0) {
    iterator lastIter = --end();
    // swap value pointed to by iter with last element
    swap(iter, lastIter);
  }

  // remove value (which must be at end)
  data_->pop_back();

  // Move values in heap to correct positions
  // iter still points to same position but probably differnt value
  if (size() > 1 && iter.index_ != size() - 1) {

    if (isMaxHeap) {
      // For Max Heap:

      iterator lchild = lchild(iter);
      iterator rchild = rchild(iter);
      // stop if there are no children (rchild.data_ will also be nullptr)
      if (lchild.data_ == nullptr) {
        return;
      }
      // only has lchild
      // while *iter is less than either of it's children:
      // TODO: need to deal with case where 1 or both children do not exist
      // swap *iter with the lesser child

    } else {
      // For Min Heap:

    }
  }

}

template <class Item, bool isMaxHeap>
Item& Heap<Item, isMaxHeap>::removeTop() {
  // save value of top (to be returned)
  Item topValue = data_[0];
  // erase the top (includes readjusting heap structure)
  iterator top = iterator(0, data_);
  erase(top);
  // return value of top
  return topValue;
}

template <class Item, bool isMaxHeap>
bool Heap<Item, isMaxHeap>::operator==(const Heap<Item, isMaxHeap>& rhs) const {

}

template <class Item, bool isMaxHeap>
bool Heap<Item, isMaxHeap>::operator!=(const Heap<Item, isMaxHeap>& rhs) const {

}

template <class Item, bool isMaxHeap>
Item* Heap<Item, isMaxHeap>::find(const Item& value) const {

}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::outputAllValues() const {
  for (iterator iter = begin(); iter != end() ; ++iter) {
    std::cout << *iter;
  }
  std::cout << std::endl;
}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::swap(iterator& value1, iterator& value2) {
  Item& temp = *value1;
  *value1 = *value2;
  *value2 = temp;
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator
    Heap<Item, isMaxHeap>::parent(iterator& child)  const {
  // if child is not top
  if (child.index_ != 0) {
    size_t parent = ((child.index_ + 1) / 2) - 1;
    return iterator(parent, data_);
  }
  // if child is top
  retun iterator(0, data_)
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator
    Heap<Item, isMaxHeap>::lchild(iterator& parent) const {
  size_t lchild = (parent.index_ * 2) + 1;
  // if lchild is valid
  if (lchild < size()) {
    return iterator(lchild, data_);
  }
  // if lchild is not valid
  return iterator(0, nullptr);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator
    Heap<Item, isMaxHeap>::rchild(iterator& parent) const {
  size_t rchild = (parent.index_ * 2) + 2;
  // if rchild is valid
  if (rchild < size()) {
    return iterator(rchild, data_);
  }
  // if rchild is not valid
  return iterator(0, nullptr);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator Heap<Item, isMaxHeap>::begin() const {
  return iterator(0, data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator Heap<Item, isMaxHeap>::end() const {
  return iterator(size(), data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::const_iterator Heap<Item, isMaxHeap>::cbegin()
    const {
  return const_iterator(0, data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::const_iterator Heap<Item, isMaxHeap>::cend()
    const {
  return const_iterator(size(), data_);
}
<commit_msg>Finish heap erase<commit_after>// -*- C++ -*-
/**
 * \file Heap.cc
 * \author Stetson Bost
 * \brief Implements the details of the Heap class
 */

#include "Heap.h"

#include <cassert>
#include <cstddef>
#include <iostream>
#include <vector>

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap>::Heap() : data_(new std::vector<Item>) {
}

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap>::Heap(const Heap& heap) {
  // vector assignment
  *data_ = *heap.data_;
}

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap> Heap<Item, isMaxHeap>::operator=(const Heap& heap) {
  *data_ = *heap.data_;
}

template <class Item, bool isMaxHeap>
Heap<Item, isMaxHeap>::~Heap() {
  delete data_;
  data_ = nullptr;
}

template <class Item, bool isMaxHeap>
size_t Heap<Item, isMaxHeap>::size() const {
  return data_->size();
}

template <class Item, bool isMaxHeap>
bool Heap<Item, isMaxHeap>::isEmpty() const {
  return data_->empty();
}

template <class Item, bool isMaxHeap>
Item& Heap<Item, isMaxHeap>::peekTop() const {
  // assumes that first element of data exists
  return *data_->begin();
}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::insert(const Item& value) {
  // add value to bottom of heap
  data_->push_back(value);
  // get an iterator for the value
  iterator valueIter = iterator(size() - 1, data_);

  // if value is not at root, make an iterator pointing to value's parent
  if (valueIter != begin()) {
    iterator parentIter = parent(valueIter);

    // Now move the value to the correct position in the Heap

    if (isMaxHeap) {
      // For Max Heap:

      // if value is greater than parent, swap value and parent
      while (*valueIter > *parentIter) {
        swap(valueIter, parentIter);
        valueIter = parentIter;
        // if value is not at root, make update parent iterator
        if (valueIter.index_ != begin()) {
          parentIter = parent(valueIter);
        } else {
          // otherwise, the value is in the appropriate place
          break;
        }
      }
    } else {
      // For Min Heap:

      // if value is less than parent, swap value and parent
      while (*valueIter < *parentIter) {
        swap(valueIter, parentIter);
        valueIter = parentIter;
        // if value is not at root, make update parent iterator
        if (valueIter.index_ != begin()) {
          parentIter = parent(valueIter);
        } else {
          // otherwise, the value is in the appropriate place
          break;
        }
      }
    }
  }
}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::erase(iterator& iter) {
  if (size() > 0) {
    iterator lastIter = --end();
    // swap value pointed to by iter with last element
    swap(iter, lastIter);
  }

  // remove value (which must be at end)
  data_->pop_back();

  // Move values in heap to correct positions
  // iter still points to same position but probably differnt value
  if (size() > 1 && iter.index_ != size() - 1) {

    // iterators for both children
    iterator lchild = lchild(iter);
    iterator rchild = rchild(iter);

    if (isMaxHeap) {
      // For Max Heap:

      // loop until return
      while (true) {

        // there are no children (rchild.data_ will also be nullptr)
        if (lchild.data_ == nullptr) {
          // Heap is valid
          return;
        }

        // only has lchild
        if (rchild.data_ == nullptr) {
          // swap lchild and iter
          if (*lchild > *iter) {
            swap(lchild, iter);
          }
          // Heap is valid
          return;
        }

        // lchild and rchild both exist and
        if (*rchild > *iter || *lchild > *iter) {
          // rchild should be on top
          if (*rchild > *lchild) {
            swap(rchild, iter);
            iter = rchild;
          } else {
            swap(lchild, iter);
            iter = lchild;
          }

          // get iterators for new children
          lchild = lchild(iter);
          rchild = rchild(iter);

          // now loop again

        } else {
          // Heap is valid
          return;
        }
      }

    } else {
      // For Min Heap:

      // loop until return
      while (true) {

        // there are no children (rchild.data_ will also be nullptr)
        if (lchild.data_ == nullptr) {
          // Heap is valid
          return;
        }

        // only has lchild
        if (rchild.data_ == nullptr) {
          // swap lchild and iter
          if (*lchild < *iter) {
            swap(lchild, iter);
          }
          // Heap is valid
          return;
        }

        // lchild and rchild both exist and
        if (*rchild < *iter || *lchild < *iter) {
          // rchild should be on top
          if (*rchild < *lchild) {
            swap(rchild, iter);
            iter = rchild;
          } else {
            swap(lchild, iter);
            iter = lchild;
          }

          // get iterators for new children
          lchild = lchild(iter);
          rchild = rchild(iter);

          // now loop again

        } else {
          // Heap is valid
          return;
        }
      }
    }
  }

}

template <class Item, bool isMaxHeap>
Item& Heap<Item, isMaxHeap>::removeTop() {
  // save value of top (to be returned)
  Item topValue = data_[0];
  // erase the top (includes readjusting heap structure)
  iterator top = iterator(0, data_);
  erase(top);
  // return value of top
  return topValue;
}

template <class Item, bool isMaxHeap>
bool Heap<Item, isMaxHeap>::operator==(const Heap<Item, isMaxHeap>& rhs) const {

}

template <class Item, bool isMaxHeap>
bool Heap<Item, isMaxHeap>::operator!=(const Heap<Item, isMaxHeap>& rhs) const {

}

template <class Item, bool isMaxHeap>
Item* Heap<Item, isMaxHeap>::find(const Item& value) const {

}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::outputAllValues() const {
  for (iterator iter = begin(); iter != end() ; ++iter) {
    std::cout << *iter;
  }
  std::cout << std::endl;
}

template <class Item, bool isMaxHeap>
void Heap<Item, isMaxHeap>::swap(iterator& value1, iterator& value2) {
  Item& temp = *value1;
  *value1 = *value2;
  *value2 = temp;
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator
    Heap<Item, isMaxHeap>::parent(iterator& child)  const {
  // if child is not top
  if (child.index_ != 0) {
    size_t parent = ((child.index_ + 1) / 2) - 1;
    return iterator(parent, data_);
  }
  // if child is top
  return iterator(0, data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator
    Heap<Item, isMaxHeap>::lchild(iterator& parent) const {
  size_t lchild = (parent.index_ * 2) + 1;
  // if lchild is valid
  if (lchild < size()) {
    return iterator(lchild, data_);
  }
  // if lchild is not valid
  return iterator(0, nullptr);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator
    Heap<Item, isMaxHeap>::rchild(iterator& parent) const {
  size_t rchild = (parent.index_ * 2) + 2;
  // if rchild is valid
  if (rchild < size()) {
    return iterator(rchild, data_);
  }
  // if rchild is not valid
  return iterator(0, nullptr);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator Heap<Item, isMaxHeap>::begin() const {
  return iterator(0, data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::iterator Heap<Item, isMaxHeap>::end() const {
  return iterator(size(), data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::const_iterator Heap<Item, isMaxHeap>::cbegin()
    const {
  return const_iterator(0, data_);
}

template <class Item, bool isMaxHeap>
typename Heap<Item, isMaxHeap>::const_iterator Heap<Item, isMaxHeap>::cend()
    const {
  return const_iterator(size(), data_);
}
<|endoftext|>


<commit_before>void Hlib()
{
  gSystem->Load("libMinuit.so");
  gSystem->Load("libVMC.so");
  gSystem->Load("libESD.so");
  gSystem->Load("libSTEER.so");
  gSystem->Load("libCDB.so");

  gSystem->Load("libRAWDatasim.so");

  gSystem->Load("libHMPIDbase.so");
  gSystem->Load("libHMPIDsim.so");
  gSystem->Load("libHMPIDrec.so");

  gROOT->LoadMacro("Hmenu.C");
}
<commit_msg>2 more libraries inside<commit_after>void Hlib()
{
  gSystem->Load("libMinuit.so");
  gSystem->Load("libVMC.so");
  gSystem->Load("libESD.so");
  gSystem->Load("libSTEER.so");
  gSystem->Load("libCDB.so");

  gSystem->Load("libEVGEN.so");
  gSystem->Load("libSTRUCT.so");

  gSystem->Load("libRAWDatasim.so");

  gSystem->Load("libHMPIDbase.so");
  gSystem->Load("libHMPIDsim.so");
  gSystem->Load("libHMPIDrec.so");

  gROOT->LoadMacro("Hmenu.C");
}
<|endoftext|>


<commit_before>#include <Arduino.h>

#include "timer.h"

Timer *timer_init(void (*cb)(void)) {
    Timer *timer = (Timer *) malloc(sizeof(Timer));
    timer->code = 0;
    timer->active = 0;
    timer->timeout = 10000;
    timer->updated = 0;
    timer->cb = cb;
    return timer;
}

void timer_set(Timer *timer, uint8_t code, unsigned long timeout) {
    timer->code = code;
    timer->active = 1;
    timer->timeout = timeout;
    timer->updated = millis();
}

void timer_update(Timer *timer) {
    if (millis() - timer->updated < timer->timeout) {
        return;
    }
    timer->active = 0;
    timer->cb();
}
<commit_msg>Fix timer timing out when inactive<commit_after>#include <Arduino.h>

#include "timer.h"

Timer *timer_init(void (*cb)(void)) {
    Timer *timer = (Timer *) malloc(sizeof(Timer));
    timer->code = 0;
    timer->active = 0;
    timer->timeout = 10000;
    timer->updated = 0;
    timer->cb = cb;
    return timer;
}

void timer_set(Timer *timer, uint8_t code, unsigned long timeout) {
    timer->code = code;
    timer->active = 1;
    timer->timeout = timeout;
    timer->updated = millis();
}

void timer_update(Timer *timer) {
    if (!timer->active || millis() - timer->updated < timer->timeout) {
        return;
    }
    timer->active = 0;
    timer->cb();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/videoio.hpp>

template<class T>
T base_name(T const & path, T const & delims = "/\\")
{
  return path.substr(path.find_last_of(delims) + 1);
}
template<class T>
T remove_extension(T const & filename)
{
  typename T::size_type const p(filename.find_last_of('.'));
  return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
}

void help(const char* path) {

    std::string progname = remove_extension(base_name<std::string>(path));

    std::cout << std::endl
        << "Shows the view of the chosen camera" << std::endl
        << "usage: " << progname << " [options]" << std::endl
        << "usage: " << progname << " <camera-id> <width> <height>" << std::endl
        << "\toptions:" << std::endl
        << "\t -e: enumerates the cameras in the system" << std::endl;
}

struct camera_info {
    int32_t     id;
    cv::Size    frame_size;
    int32_t     fps;
};

std::vector<camera_info> enum_available_cameras() {
    std::vector<camera_info> cameras;

    int32_t device_counts = 0;
    while (true) {
        cv::VideoCapture camera;
        if (!camera.open(device_counts)) {
            break;
        }

        cameras.push_back({
            device_counts,
            cv::Size(
                (int32_t)camera.get(CV_CAP_PROP_FRAME_WIDTH),
                (int32_t)camera.get(CV_CAP_PROP_FRAME_HEIGHT)),
            (int32_t)camera.get(CV_CAP_PROP_FPS)
        });

        ++device_counts;
        camera.release();
    }

    return cameras;
}

int main(int32_t argc, char* argv[]) {

    try {
        std::string options =
            "{help h usage| |}"
            "{enum e| |Enumerate available cameras|}"
            "{@camera|0|Camera to show|}"
            "{@width|1280|Desired frame width|}"
            "{@height|720|desired frame height|}"
            "{@fps|30|desired frame-rate|}";

        cv::CommandLineParser parser(argc, argv, options);

        if (parser.has("help"))
        {
            help(argv[0]);
            return EXIT_SUCCESS;
        }

        // Users wants to know the cameras availables
        if (parser.has("e")) {
            auto cameras = enum_available_cameras();
            return EXIT_SUCCESS;
        }

        // Create a camera info for the given command line's arguments
        camera_info ci = {
            parser.get<int32_t>("@camera"),
            cv::Size(
                parser.get<int32_t>("@width"),
                parser.get<int32_t>("@height")),
            parser.get<int32_t>("@fps")
        };

        cv::VideoCapture vc;
        if (!vc.open(ci.id)) {
            std::cerr << "Camera " << ci.id << " is not available!" << std::endl;
            help(argv[0]);
            return EXIT_FAILURE;
        }

        vc.set(CV_CAP_PROP_FRAME_WIDTH, (double)ci.frame_size.width);
        vc.set(CV_CAP_PROP_FRAME_HEIGHT, (double)ci.frame_size.height);
        vc.set(CV_CAP_PROP_FPS, (double)ci.fps);

        camera_info camera = {
            ci.id,
            cv::Size(
                (int32_t)vc.get(CV_CAP_PROP_FRAME_WIDTH),
                (int32_t)vc.get(CV_CAP_PROP_FRAME_HEIGHT)),
            (int32_t)vc.get(CV_CAP_PROP_FPS)
        };

        std::cout << std::endl
            << "Camera id: " << camera.id
            << " (" << camera.frame_size.width
            << "x" << camera.frame_size.height
            << "@" << camera.fps << ")"
            << std::endl;

        const std::string window_name("Camera Show");
        cv::namedWindow(window_name);

        cv::Mat frame;
        while (vc.grab() && vc.retrieve(frame)) {
            cv::imshow(window_name, frame);

            auto key = cv::waitKey((int32_t)(1000.0/camera.fps));
            if (key == 27) // ESCAPE
                break;

            printf("FPS: %d\r", camera.fps);
        }

    } catch (cv::Exception& cv_exc) {
        std::cerr << cv_exc.msg << std::endl;
        help(argv[0]);
        std::exit(EXIT_FAILURE);
    }

    return EXIT_SUCCESS;
}<commit_msg>Better use of the parser interface<commit_after>#include <iostream>
#include <string>
#include <vector>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/videoio.hpp>

template<class T>
T base_name(T const & path, T const & delims = "/\\")
{
  return path.substr(path.find_last_of(delims) + 1);
}
template<class T>
T remove_extension(T const & filename)
{
  typename T::size_type const p(filename.find_last_of('.'));
  return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
}

void help(const char* path) {

    std::string progname = remove_extension(base_name<std::string>(path));

    std::cout << std::endl
        << "Shows the view of the chosen camera" << std::endl
        << "usage: " << progname << " [options]" << std::endl
        << "usage: " << progname << " <camera-id> <width> <height> <fps>" << std::endl
        << "\toptions:" << std::endl
        << "\t -e: enumerates the cameras in the system" << std::endl;
}

struct camera_info {
    int32_t     id;
    cv::Size    frame_size;
    int32_t     fps;
};

std::vector<camera_info> enum_available_cameras() {
    std::vector<camera_info> cameras;

    int32_t device_counts = 0;
    while (true) {
        cv::VideoCapture camera;
        if (!camera.open(device_counts)) {
            break;
        }

        cameras.push_back({
            device_counts,
            cv::Size(
                (int32_t)camera.get(CV_CAP_PROP_FRAME_WIDTH),
                (int32_t)camera.get(CV_CAP_PROP_FRAME_HEIGHT)),
            (int32_t)camera.get(CV_CAP_PROP_FPS)
        });

        ++device_counts;
        camera.release();
    }

    return cameras;
}

int main(int32_t argc, char* argv[]) {

    try {
        std::string options =
            "{help h usage| |}"
            "{enum e| |Enumerates available cameras|}"
            "{@camera|0|Camera to show|}"
            "{@width|1280|Desired frame width|}"
            "{@height|720|Desired frame height|}"
            "{@fps|30|Desired frame-rate|}";

        cv::CommandLineParser parser(argc, argv, options);
        parser.about("Shows the view of the chosen camera");

        if (parser.has("help")) {
            parser.printMessage();
            return EXIT_SUCCESS;
        }

        if (!parser.check()) {
            parser.printErrors();
            return EXIT_FAILURE;
        }

        // Users wants to know the cameras availables
        if (parser.has("e")) {
            auto cameras = enum_available_cameras();
            return EXIT_SUCCESS;
        }

        // Create a camera info for the given command line's arguments
        camera_info ci = {
            parser.get<int32_t>("@camera"),
            cv::Size(
                parser.get<int32_t>("@width"),
                parser.get<int32_t>("@height")),
            parser.get<int32_t>("@fps")
        };

        cv::VideoCapture vc;
        if (!vc.open(ci.id)) {
            std::cerr << "Camera " << ci.id << " is not available!" << std::endl;
            help(argv[0]);
            return EXIT_FAILURE;
        }

        vc.set(CV_CAP_PROP_FRAME_WIDTH, (double)ci.frame_size.width);
        vc.set(CV_CAP_PROP_FRAME_HEIGHT, (double)ci.frame_size.height);
        vc.set(CV_CAP_PROP_FPS, (double)ci.fps);

        camera_info camera = {
            ci.id,
            cv::Size(
                (int32_t)vc.get(CV_CAP_PROP_FRAME_WIDTH),
                (int32_t)vc.get(CV_CAP_PROP_FRAME_HEIGHT)),
            (int32_t)vc.get(CV_CAP_PROP_FPS)
        };

        std::cout << std::endl
            << "Camera id: " << camera.id
            << " (" << camera.frame_size.width
            << "x" << camera.frame_size.height
            << "@" << camera.fps << ")"
            << std::endl;

        const std::string window_name("Camera Show");
        cv::startWindowThread();
        cv::namedWindow(window_name);

        cv::Mat frame;
        while (vc.grab() && vc.retrieve(frame)) {
            cv::imshow(window_name, frame);

            auto key = cv::waitKey((int32_t)(1000.0/camera.fps));
            if (key == 27) // ESCAPE
                break;

            printf("FPS: %d\r", camera.fps);
        }

    } catch (cv::Exception& cv_exc) {
        std::cerr << cv_exc.msg << std::endl;
        std::exit(EXIT_FAILURE);
    }

    return EXIT_SUCCESS;
}<|endoftext|>


<commit_before>/// \file stream.cpp
/// Utilities for handling streams.

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include "json.h"
#include "stream.h"
#include "procs.h"
#include "config.h"
#include "socket.h"
#include "defines.h"
#include "shared_memory.h"
#include "dtsc.h"

std::string Util::getTmpFolder() {
  std::string dir;
  char * tmp_char = 0;
  if (!tmp_char) {
    tmp_char = getenv("TMP");
  }
  if (!tmp_char) {
    tmp_char = getenv("TEMP");
  }
  if (!tmp_char) {
    tmp_char = getenv("TMPDIR");
  }
  if (tmp_char) {
    dir = tmp_char;
    dir += "/mist";
  } else {
#if defined(_WIN32) || defined(_CYGWIN_)
    dir = "C:/tmp/mist";
#else
    dir = "/tmp/mist";
#endif
  }
  if (access(dir.c_str(), 0) != 0) {
    mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); //attempt to create mist folder - ignore failures
  }
  return dir + "/";
}

/// Filters the streamname, removing invalid characters and converting all
/// letters to lowercase. If a '?' character is found, everything following
/// that character is deleted. The original string is modified. If a '+'
/// exists, then only the part before the + is sanitized.
void Util::sanitizeName(std::string & streamname) {
  //strip anything that isn't numbers, digits or underscores
  size_t index = streamname.find('+');
  if(index != std::string::npos){
    std::string preplus = streamname.substr(0,index);
    sanitizeName(preplus);
    streamname = preplus +"+"+streamname.substr(index+1);
    return;
  }
  for (std::string::iterator i = streamname.end() - 1; i >= streamname.begin(); --i) {
    if (*i == '?') {
      streamname.erase(i, streamname.end());
      break;
    }
    if ( !isalpha( *i) && !isdigit( *i) && *i != '_' && *i != '+' && *i != '.'){
      streamname.erase(i);
    } else {
      *i = tolower(*i);
    }
  }
}

/// Starts a process for a VoD stream.
bool Util::startInput(std::string streamname, std::string filename, bool forkFirst) {
  IPC::sharedPage mistConfOut("!mistConfig", 4*1024*1024);
  IPC::semaphore configLock("!mistConfLock", O_CREAT | O_RDWR, ACCESSPERMS, 1);
  configLock.wait();
  DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);

  sanitizeName(streamname);
  std::string smp = streamname.substr(0, streamname.find('+'));
  //check if smp (everything before +) exists
  DTSC::Scan stream_cfg = config.getMember("streams").getMember(smp);
  if (!stream_cfg){
    DEBUG_MSG(DLVL_MEDIUM, "Stream %s not configured", streamname.c_str());
    configLock.post();//unlock the config semaphore
    return false;
  }

  //If starting without filename parameter, check if the stream is already active.
  //If yes, don't activate again to prevent duplicate inputs.
  //It's still possible a duplicate starts anyway, this is caught in the inputs initializer.
  //Note: this uses the _whole_ stream name, including + (if any).
  //This means "test+a" and "test+b" have separate locks and do not interact with each other.
  if (!filename.size()){
    IPC::semaphore playerLock(std::string("/lock_" + streamname).c_str(), O_CREAT | O_RDWR, ACCESSPERMS, 1);
    if (!playerLock.tryWait()) {
      playerLock.close();
      DEBUG_MSG(DLVL_MEDIUM, "Stream %s already active - not activating again", streamname.c_str());
      configLock.post();//unlock the config semaphore
      return true;
    }
    playerLock.post();
    playerLock.close();
    filename = stream_cfg.getMember("source").asString();
  }

  std::string player_bin;
  bool selected = false;
  long long int curPrio = -1;
  //check in curConf for capabilities-inputs-<naam>-priority/source_match
  DTSC::Scan inputs = config.getMember("capabilities").getMember("inputs");
  DTSC::Scan input;
  unsigned int input_size = inputs.getSize();
  for (unsigned int i = 0; i < input_size; ++i){
    input = inputs.getIndice(i);

    //if match voor current stream && priority is hoger dan wat we al hebben
    if (curPrio < input.getMember("priority").asInt()){
      std::string source = input.getMember("source_match").asString();
      std::string front = source.substr(0,source.find('*'));
      std::string back = source.substr(source.find('*')+1);
      DEBUG_MSG(DLVL_MEDIUM, "Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(), input.getMember("name").asString().c_str(), source.c_str());

      if (filename.substr(0,front.size()) == front && filename.substr(filename.size()-back.size()) == back){
        player_bin = Util::getMyPath() + "MistIn" + input.getMember("name").asString();
        curPrio = input.getMember("priority").asInt();
        selected = true;
      }
    }
  }

  if (!selected){
    configLock.post();//unlock the config semaphore
    FAIL_MSG("No compatible input found for stream %s: %s", streamname.c_str(), filename.c_str());
    return false;
  }

  //copy the neccessary arguments to separate storage so we can unlock the config semaphore safely
  std::map<std::string, std::string> str_args;
  //check required parameters
  DTSC::Scan required = input.getMember("required");
  unsigned int req_size = required.getSize();
  for (unsigned int i = 0; i < req_size; ++i){
    std::string opt = required.getIndiceName(i);
    if (!stream_cfg.getMember(opt)){
      configLock.post();//unlock the config semaphore
      FAIL_MSG("Required parameter %s for stream %s missing", opt.c_str(), streamname.c_str());
      return false;
    }
    str_args[required.getIndice(i).getMember("option").asString()] = stream_cfg.getMember(opt).asString();
  }
  //check optional parameters
  DTSC::Scan optional = input.getMember("optional");
  unsigned int opt_size = optional.getSize();
  for (unsigned int i = 0; i < opt_size; ++i){
    std::string opt = optional.getIndiceName(i);
    DEBUG_MSG(DLVL_VERYHIGH, "Checking optional %u: %s", i, opt.c_str());
    if (stream_cfg.getMember(opt)){
      str_args[optional.getIndice(i).getMember("option").asString()] = stream_cfg.getMember(opt).asString();
    }
  }

  //finally, unlock the config semaphore
  configLock.post();

  INFO_MSG("Starting %s -s %s %s", player_bin.c_str(), streamname.c_str(), filename.c_str());
  char * argv[30] = {(char *)player_bin.c_str(), (char *)"-s", (char *)streamname.c_str(), (char *)filename.c_str()};
  int argNum = 3;
  std::string debugLvl;
  if (Util::Config::printDebugLevel != DEBUG && !str_args.count("--debug")){
    debugLvl = JSON::Value((long long)Util::Config::printDebugLevel).asString();
    argv[++argNum] = (char *)"--debug";
    argv[++argNum] = (char *)debugLvl.c_str();
  }
  for (std::map<std::string, std::string>::iterator it = str_args.begin(); it != str_args.end(); ++it){
    argv[++argNum] = (char *)it->first.c_str();
    argv[++argNum] = (char *)it->second.c_str();
  }
  argv[++argNum] = (char *)0;

  int pid = 0;
  if (forkFirst){
    DEBUG_MSG(DLVL_DONTEVEN, "Forking");
    pid = fork();
    if (pid == -1) {
      FAIL_MSG("Forking process for stream %s failed: %s", streamname.c_str(), strerror(errno));
      return false;
    }
  }else{
    DEBUG_MSG(DLVL_DONTEVEN, "Not forking");
  }

  if (pid == 0){
    DEBUG_MSG(DLVL_DONTEVEN, "execvp");
    execvp(argv[0], argv);
    FAIL_MSG("Starting process %s for stream %s failed: %s", argv[0], streamname.c_str(), strerror(errno));
    _exit(42);
  }
  return true;
}
<commit_msg>Decreased debug message verbosity some.<commit_after>/// \file stream.cpp
/// Utilities for handling streams.

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include "json.h"
#include "stream.h"
#include "procs.h"
#include "config.h"
#include "socket.h"
#include "defines.h"
#include "shared_memory.h"
#include "dtsc.h"

std::string Util::getTmpFolder() {
  std::string dir;
  char * tmp_char = 0;
  if (!tmp_char) {
    tmp_char = getenv("TMP");
  }
  if (!tmp_char) {
    tmp_char = getenv("TEMP");
  }
  if (!tmp_char) {
    tmp_char = getenv("TMPDIR");
  }
  if (tmp_char) {
    dir = tmp_char;
    dir += "/mist";
  } else {
#if defined(_WIN32) || defined(_CYGWIN_)
    dir = "C:/tmp/mist";
#else
    dir = "/tmp/mist";
#endif
  }
  if (access(dir.c_str(), 0) != 0) {
    mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); //attempt to create mist folder - ignore failures
  }
  return dir + "/";
}

/// Filters the streamname, removing invalid characters and converting all
/// letters to lowercase. If a '?' character is found, everything following
/// that character is deleted. The original string is modified. If a '+'
/// exists, then only the part before the + is sanitized.
void Util::sanitizeName(std::string & streamname) {
  //strip anything that isn't numbers, digits or underscores
  size_t index = streamname.find('+');
  if(index != std::string::npos){
    std::string preplus = streamname.substr(0,index);
    sanitizeName(preplus);
    streamname = preplus +"+"+streamname.substr(index+1);
    return;
  }
  for (std::string::iterator i = streamname.end() - 1; i >= streamname.begin(); --i) {
    if (*i == '?') {
      streamname.erase(i, streamname.end());
      break;
    }
    if ( !isalpha( *i) && !isdigit( *i) && *i != '_' && *i != '+' && *i != '.'){
      streamname.erase(i);
    } else {
      *i = tolower(*i);
    }
  }
}

/// Starts a process for a VoD stream.
bool Util::startInput(std::string streamname, std::string filename, bool forkFirst) {
  IPC::sharedPage mistConfOut("!mistConfig", 4*1024*1024);
  IPC::semaphore configLock("!mistConfLock", O_CREAT | O_RDWR, ACCESSPERMS, 1);
  configLock.wait();
  DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);

  sanitizeName(streamname);
  std::string smp = streamname.substr(0, streamname.find('+'));
  //check if smp (everything before +) exists
  DTSC::Scan stream_cfg = config.getMember("streams").getMember(smp);
  if (!stream_cfg){
    DEBUG_MSG(DLVL_MEDIUM, "Stream %s not configured", streamname.c_str());
    configLock.post();//unlock the config semaphore
    return false;
  }

  //If starting without filename parameter, check if the stream is already active.
  //If yes, don't activate again to prevent duplicate inputs.
  //It's still possible a duplicate starts anyway, this is caught in the inputs initializer.
  //Note: this uses the _whole_ stream name, including + (if any).
  //This means "test+a" and "test+b" have separate locks and do not interact with each other.
  if (!filename.size()){
    IPC::semaphore playerLock(std::string("/lock_" + streamname).c_str(), O_CREAT | O_RDWR, ACCESSPERMS, 1);
    if (!playerLock.tryWait()) {
      playerLock.close();
      DEBUG_MSG(DLVL_MEDIUM, "Stream %s already active - not activating again", streamname.c_str());
      configLock.post();//unlock the config semaphore
      return true;
    }
    playerLock.post();
    playerLock.close();
    filename = stream_cfg.getMember("source").asString();
  }

  std::string player_bin;
  bool selected = false;
  long long int curPrio = -1;
  //check in curConf for capabilities-inputs-<naam>-priority/source_match
  DTSC::Scan inputs = config.getMember("capabilities").getMember("inputs");
  DTSC::Scan input;
  unsigned int input_size = inputs.getSize();
  for (unsigned int i = 0; i < input_size; ++i){
    input = inputs.getIndice(i);

    //if match voor current stream && priority is hoger dan wat we al hebben
    if (curPrio < input.getMember("priority").asInt()){
      std::string source = input.getMember("source_match").asString();
      std::string front = source.substr(0,source.find('*'));
      std::string back = source.substr(source.find('*')+1);
      DEBUG_MSG(DLVL_MEDIUM, "Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(), input.getMember("name").asString().c_str(), source.c_str());

      if (filename.substr(0,front.size()) == front && filename.substr(filename.size()-back.size()) == back){
        player_bin = Util::getMyPath() + "MistIn" + input.getMember("name").asString();
        curPrio = input.getMember("priority").asInt();
        selected = true;
      }
    }
  }

  if (!selected){
    configLock.post();//unlock the config semaphore
    FAIL_MSG("No compatible input found for stream %s: %s", streamname.c_str(), filename.c_str());
    return false;
  }

  //copy the neccessary arguments to separate storage so we can unlock the config semaphore safely
  std::map<std::string, std::string> str_args;
  //check required parameters
  DTSC::Scan required = input.getMember("required");
  unsigned int req_size = required.getSize();
  for (unsigned int i = 0; i < req_size; ++i){
    std::string opt = required.getIndiceName(i);
    if (!stream_cfg.getMember(opt)){
      configLock.post();//unlock the config semaphore
      FAIL_MSG("Required parameter %s for stream %s missing", opt.c_str(), streamname.c_str());
      return false;
    }
    str_args[required.getIndice(i).getMember("option").asString()] = stream_cfg.getMember(opt).asString();
  }
  //check optional parameters
  DTSC::Scan optional = input.getMember("optional");
  unsigned int opt_size = optional.getSize();
  for (unsigned int i = 0; i < opt_size; ++i){
    std::string opt = optional.getIndiceName(i);
    DEBUG_MSG(DLVL_VERYHIGH, "Checking optional %u: %s", i, opt.c_str());
    if (stream_cfg.getMember(opt)){
      str_args[optional.getIndice(i).getMember("option").asString()] = stream_cfg.getMember(opt).asString();
    }
  }

  //finally, unlock the config semaphore
  configLock.post();

  DEBUG_MSG(DLVL_MEDIUM, "Starting %s -s %s %s", player_bin.c_str(), streamname.c_str(), filename.c_str());
  char * argv[30] = {(char *)player_bin.c_str(), (char *)"-s", (char *)streamname.c_str(), (char *)filename.c_str()};
  int argNum = 3;
  std::string debugLvl;
  if (Util::Config::printDebugLevel != DEBUG && !str_args.count("--debug")){
    debugLvl = JSON::Value((long long)Util::Config::printDebugLevel).asString();
    argv[++argNum] = (char *)"--debug";
    argv[++argNum] = (char *)debugLvl.c_str();
  }
  for (std::map<std::string, std::string>::iterator it = str_args.begin(); it != str_args.end(); ++it){
    argv[++argNum] = (char *)it->first.c_str();
    argv[++argNum] = (char *)it->second.c_str();
  }
  argv[++argNum] = (char *)0;

  int pid = 0;
  if (forkFirst){
    DEBUG_MSG(DLVL_DONTEVEN, "Forking");
    pid = fork();
    if (pid == -1) {
      FAIL_MSG("Forking process for stream %s failed: %s", streamname.c_str(), strerror(errno));
      return false;
    }
  }else{
    DEBUG_MSG(DLVL_DONTEVEN, "Not forking");
  }

  if (pid == 0){
    DEBUG_MSG(DLVL_DONTEVEN, "execvp");
    execvp(argv[0], argv);
    FAIL_MSG("Starting process %s for stream %s failed: %s", argv[0], streamname.c_str(), strerror(errno));
    _exit(42);
  }
  return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, Cloudera, inc.

#include <boost/assign/list_of.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <time.h>

#include "common/row.h"
#include "common/schema.h"
#include "gutil/stringprintf.h"
#include "tablet/layer.h"
#include "tablet/layer-test-base.h"
#include "util/env.h"
#include "util/status.h"
#include "util/stopwatch.h"
#include "util/test_macros.h"

namespace kudu {
namespace tablet {

using std::tr1::unordered_set;

// TODO: add test which calls CopyNextRows on an iterator with no more
// rows - i think it segfaults!

// Test round-trip writing and reading back a layer with
// multiple columns. Does not test any modifications.
TEST_F(TestLayer, TestLayerRoundTrip) {
  WriteTestLayer();

  // Now open the Layer for read
  shared_ptr<Layer> l;
  ASSERT_STATUS_OK(OpenTestLayer(&l));

  // First iterate over all columns
  LOG_TIMING(INFO, "Iterating over all columns") {
    IterateProjection(*l, schema_, n_rows_);
  }

  // Now iterate only over the key column
  Schema proj_key(boost::assign::list_of
                  (ColumnSchema("key", STRING)),
                  1);

  LOG_TIMING(INFO, "Iterating over only key column") {
    IterateProjection(*l, proj_key, n_rows_);
  }

  // Now iterate only over the non-key column
  Schema proj_val(boost::assign::list_of
                  (ColumnSchema("val", UINT32)),
                  1);
  LOG_TIMING(INFO, "Iterating over only val column") {
    IterateProjection(*l, proj_val, n_rows_);
  }

  // Test that CheckRowPresent returns correct results

  // 1. Check a key which comes before all keys in layer
  {
    Slice key("h");
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_FALSE(present);
  }

  // 2. Check a key which comes after all keys in layer
  {
    Slice key("z");
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_FALSE(present);
  }

  // 3. Check a key which is not present, but comes between present
  // keys
  {
    Slice key("hello 00000000000049x");
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_FALSE(present);
  }

  // 4. Check a key which is present
  {
    char buf[256];
    FormatKey(49, buf, sizeof(buf));
    Slice key(buf);
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_TRUE(present);
  }
}

// Test writing a layer, and then updating some rows in it.
TEST_F(TestLayer, TestLayerUpdate) {
  WriteTestLayer();

  // Now open the Layer for read
  shared_ptr<Layer> l;
  ASSERT_STATUS_OK(OpenTestLayer(&l));

  // Add an update to the delta tracker for a number of keys
  // which exist. These updates will change the value to
  // equal idx*5 (whereas in the original data, value = idx)
  unordered_set<uint32_t> updated;
  UpdateExistingRows(l.get(), 0.1f, &updated);
  ASSERT_EQ(updated.size(), l->delta_tracker_->dms_->Count());

  // Try to add an update for a key not in the file (but which falls
  // between two valid keys)
  Slice bad_key = Slice("hello 00000000000049x");
  ASSERT_TRUE(l->UpdateRow(&bad_key, RowChangeList(Slice())).IsNotFound());

  // Now read back the value column, and verify that the updates
  // are visible.
  VerifyUpdates(*l, updated);
}

TEST_F(TestLayer, TestDMSFlush) {
  WriteTestLayer();

  unordered_set<uint32_t> updated;

  // Now open the Layer for read
  {
    shared_ptr<Layer> l;
    ASSERT_STATUS_OK(OpenTestLayer(&l));

    // Add an update to the delta tracker for a number of keys
    // which exist. These updates will change the value to
    // equal idx*5 (whereas in the original data, value = idx)
    UpdateExistingRows(l.get(), 0.01f, &updated);
    ASSERT_EQ(updated.size(), l->delta_tracker_->dms_->Count());

    l->FlushDeltas();

    // Check that the Layer's DMS has now been emptied.
    ASSERT_EQ(0, l->delta_tracker_->dms_->Count());

    // Now read back the value column, and verify that the updates
    // are visible.
    VerifyUpdates(*l, updated);
  }

  // Close and re-open the layer and ensure that the updates were
  // persistent.
  {
    shared_ptr<Layer> l;
    ASSERT_STATUS_OK(OpenTestLayer(&l));

    // Now read back the value column, and verify that the updates
    // are visible.
    VerifyUpdates(*l, updated);
  }
}

} // namespace tablet
} // namespace kudu

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  google::ParseCommandLineFlags(&argc, &argv, true);
  return RUN_ALL_TESTS();
}
<commit_msg>layer-test: allow update fraction to be configured<commit_after>// Copyright (c) 2012, Cloudera, inc.

#include <boost/assign/list_of.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <time.h>

#include "common/row.h"
#include "common/schema.h"
#include "gutil/stringprintf.h"
#include "tablet/layer.h"
#include "tablet/layer-test-base.h"
#include "util/env.h"
#include "util/status.h"
#include "util/stopwatch.h"
#include "util/test_macros.h"

DEFINE_double(update_fraction, 0.1f, "fraction of rows to update");

namespace kudu {
namespace tablet {

using std::tr1::unordered_set;

// TODO: add test which calls CopyNextRows on an iterator with no more
// rows - i think it segfaults!

// Test round-trip writing and reading back a layer with
// multiple columns. Does not test any modifications.
TEST_F(TestLayer, TestLayerRoundTrip) {
  WriteTestLayer();

  // Now open the Layer for read
  shared_ptr<Layer> l;
  ASSERT_STATUS_OK(OpenTestLayer(&l));

  // First iterate over all columns
  LOG_TIMING(INFO, "Iterating over all columns") {
    IterateProjection(*l, schema_, n_rows_);
  }

  // Now iterate only over the key column
  Schema proj_key(boost::assign::list_of
                  (ColumnSchema("key", STRING)),
                  1);

  LOG_TIMING(INFO, "Iterating over only key column") {
    IterateProjection(*l, proj_key, n_rows_);
  }

  // Now iterate only over the non-key column
  Schema proj_val(boost::assign::list_of
                  (ColumnSchema("val", UINT32)),
                  1);
  LOG_TIMING(INFO, "Iterating over only val column") {
    IterateProjection(*l, proj_val, n_rows_);
  }

  // Test that CheckRowPresent returns correct results

  // 1. Check a key which comes before all keys in layer
  {
    Slice key("h");
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_FALSE(present);
  }

  // 2. Check a key which comes after all keys in layer
  {
    Slice key("z");
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_FALSE(present);
  }

  // 3. Check a key which is not present, but comes between present
  // keys
  {
    Slice key("hello 00000000000049x");
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_FALSE(present);
  }

  // 4. Check a key which is present
  {
    char buf[256];
    FormatKey(49, buf, sizeof(buf));
    Slice key(buf);
    LayerKeyProbe probe(schema_, &key);
    bool present;
    ASSERT_STATUS_OK(l->CheckRowPresent(probe, &present));
    ASSERT_TRUE(present);
  }
}

// Test writing a layer, and then updating some rows in it.
TEST_F(TestLayer, TestLayerUpdate) {
  WriteTestLayer();

  // Now open the Layer for read
  shared_ptr<Layer> l;
  ASSERT_STATUS_OK(OpenTestLayer(&l));

  // Add an update to the delta tracker for a number of keys
  // which exist. These updates will change the value to
  // equal idx*5 (whereas in the original data, value = idx)
  unordered_set<uint32_t> updated;
  UpdateExistingRows(l.get(), FLAGS_update_fraction, &updated);
  ASSERT_EQ(updated.size(), l->delta_tracker_->dms_->Count());

  // Try to add an update for a key not in the file (but which falls
  // between two valid keys)
  Slice bad_key = Slice("hello 00000000000049x");
  ASSERT_TRUE(l->UpdateRow(&bad_key, RowChangeList(Slice())).IsNotFound());

  // Now read back the value column, and verify that the updates
  // are visible.
  VerifyUpdates(*l, updated);
}

TEST_F(TestLayer, TestDMSFlush) {
  WriteTestLayer();

  unordered_set<uint32_t> updated;

  // Now open the Layer for read
  {
    shared_ptr<Layer> l;
    ASSERT_STATUS_OK(OpenTestLayer(&l));

    // Add an update to the delta tracker for a number of keys
    // which exist. These updates will change the value to
    // equal idx*5 (whereas in the original data, value = idx)
    UpdateExistingRows(l.get(), FLAGS_update_fraction, &updated);
    ASSERT_EQ(updated.size(), l->delta_tracker_->dms_->Count());

    l->FlushDeltas();

    // Check that the Layer's DMS has now been emptied.
    ASSERT_EQ(0, l->delta_tracker_->dms_->Count());

    // Now read back the value column, and verify that the updates
    // are visible.
    VerifyUpdates(*l, updated);
  }

  // Close and re-open the layer and ensure that the updates were
  // persistent.
  {
    shared_ptr<Layer> l;
    ASSERT_STATUS_OK(OpenTestLayer(&l));

    // Now read back the value column, and verify that the updates
    // are visible.
    VerifyUpdates(*l, updated);
  }
}

} // namespace tablet
} // namespace kudu

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  google::ParseCommandLineFlags(&argc, &argv, true);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "SystemUtility.h"

#ifdef _WIN32
#include <windows.h>
#else
#include "../Base/ASCString.h"
#endif

#include "FileSystem/FileSystem.h"

//#include "AVSUtils.h"
//#include "File.h"

namespace OOX
{
    CPath::CPath() : m_strFilename(L"")
    {
    }
    CPath::CPath(const CString& sName, bool bIsNorm) : m_strFilename(sName)
    {
		if (bIsNorm)
			Normalize();
    }
    CPath::CPath(LPCSTR& sName, bool bIsNorm) : m_strFilename(sName)
    {
		if (bIsNorm)
			Normalize();
    }
    CPath::CPath(LPCWSTR& sName, bool bIsNorm) : m_strFilename(sName)
    {
		if (bIsNorm)
			Normalize();
    }

    CPath::CPath(const CPath& oSrc)
    {
        *this = oSrc;
		//   Normalize  oSrc
		//Normalize();
    }

    CPath& CPath::operator=(const CPath& oSrc)
    {
        m_strFilename = oSrc.m_strFilename;
		//   Normalize  oSrc
		//Normalize();
        return *this;
    }
	CPath& CPath::operator=(const CString& oSrc)
    {
        m_strFilename = oSrc;
		Normalize();
        return *this;
    }
    CPath& CPath::operator=(LPCSTR oSrc)
    {
        m_strFilename = oSrc;
        Normalize();
        return *this;
    }
    CPath& CPath::operator=(LPCWSTR oSrc)
    {
        m_strFilename = oSrc;
        Normalize();
        return *this;
    }

	AVSINLINE CString CPath::GetExtention(bool bIsPoint) const
    {
        int nFind = m_strFilename.ReverseFind('.');
        if (-1 == nFind)
            return _T("");

        if (!bIsPoint)
            ++nFind;

        return m_strFilename.Mid(nFind);
    }
    AVSINLINE CString CPath::GetDirectory(bool bIsSlash) const
    {
        int nPos = m_strFilename.ReverseFind('\\');
        if (-1 == nPos)
        {
            return m_strFilename;
        }
        else
        {
            if (bIsSlash)
                ++nPos;
            return m_strFilename.Mid(0, nPos);
        }
    }
    AVSINLINE CString CPath::GetPath() const
    {
        return m_strFilename;
    }
}

namespace OOX
{
    bool CSystemUtility::CreateFile(const CString& strFileName)
    {
        std::string path_string = stringWstingToUtf8String(strFileName);
        FILE * pFile = fopen (path_string.c_str(), "wb");
        if (NULL != pFile)
        {
            fclose (pFile);
            return true;
        }

        return false;

    }

    bool CSystemUtility::IsFileExist(const CString& strFileName)
    {
        return FileSystem::File::Exists(strFileName);
    }
    bool CSystemUtility::IsFileExist(const CPath& oPath)
    {
        return IsFileExist(oPath.GetPath());
    }

    CString CSystemUtility::GetDirectoryName(const CString& strFileName)
    {
        CPath oPath(strFileName);
        return oPath.GetDirectory();
    }

    int CSystemUtility::GetFilesCount(const CString& strDirPath, const bool& bRecursive)
    {
        return FileSystem::Directory::GetFilesCount(strDirPath, bRecursive);
    }

    CString CSystemUtility::GetFileExtention(const CString& strFileName)
    {
        CPath oPath(strFileName);
        return oPath.GetExtention();
    }

    bool CSystemUtility::CreateDirectories(const CPath& oPath)
    {
        return FileSystem::Directory::CreateDirectories(oPath.m_strFilename);
    }

    void CSystemUtility::ReplaceExtention(CString& strName, CString& str1, CString& str2)
    {
        return;
    }
}
<commit_msg>win build<commit_after>#include "SystemUtility.h"

#ifdef _WIN32
#include <windows.h>
#else
#include "../Base/ASCString.h"
#endif

#include "FileSystem/FileSystem.h"

//#include "AVSUtils.h"
//#include "File.h"

namespace OOX
{
    CPath::CPath() : m_strFilename(L"")
    {
    }
    CPath::CPath(const CString& sName, bool bIsNorm) : m_strFilename(sName)
    {
		if (bIsNorm)
			Normalize();
    }
    CPath::CPath(LPCSTR& sName, bool bIsNorm) : m_strFilename(sName)
    {
		if (bIsNorm)
			Normalize();
    }
    CPath::CPath(LPCWSTR& sName, bool bIsNorm) : m_strFilename(sName)
    {
		if (bIsNorm)
			Normalize();
    }

    CPath::CPath(const CPath& oSrc)
    {
        *this = oSrc;
		//   Normalize  oSrc
		//Normalize();
    }

    CPath& CPath::operator=(const CPath& oSrc)
    {
        m_strFilename = oSrc.m_strFilename;
		//   Normalize  oSrc
		//Normalize();
        return *this;
    }
	CPath& CPath::operator=(const CString& oSrc)
    {
        m_strFilename = oSrc;
		Normalize();
        return *this;
    }
    CPath& CPath::operator=(LPCSTR oSrc)
    {
        m_strFilename = oSrc;
        Normalize();
        return *this;
    }
    CPath& CPath::operator=(LPCWSTR oSrc)
    {
        m_strFilename = oSrc;
        Normalize();
        return *this;
    }

	AVSINLINE CString CPath::GetExtention(bool bIsPoint) const
    {
        int nFind = m_strFilename.ReverseFind('.');
        if (-1 == nFind)
            return _T("");

        if (!bIsPoint)
            ++nFind;

        return m_strFilename.Mid(nFind);
    }
    AVSINLINE CString CPath::GetDirectory(bool bIsSlash) const
    {
        int nPos = m_strFilename.ReverseFind('\\');
        if (-1 == nPos)
        {
            return m_strFilename;
        }
        else
        {
            if (bIsSlash)
                ++nPos;
            return m_strFilename.Mid(0, nPos);
        }
    }
    AVSINLINE CString CPath::GetPath() const
    {
        return m_strFilename;
    }
}

namespace OOX
{
    bool CSystemUtility::CreateFile(const CString& strFileName)
    {
#ifdef _WIN32
		BSTR strPath = strFileName.AllocSysString();
        HANDLE hResult = ::CreateFile(strPath, GENERIC_READ, 0, NULL,
            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        SysFreeString(strPath);

        if (hResult == INVALID_HANDLE_VALUE)
            return false;
        if (!CloseHandle(hResult))
            return false;

        return true;
#else
        std::string path_string = stringWstingToUtf8String(strFileName);
        FILE * pFile = fopen (path_string.c_str(), "wb");
        if (NULL != pFile)
        {
            fclose (pFile);
            return true;
        }

        return false;
#endif
    }

    bool CSystemUtility::IsFileExist(const CString& strFileName)
    {
        return FileSystem::File::Exists(strFileName);
    }
    bool CSystemUtility::IsFileExist(const CPath& oPath)
    {
        return IsFileExist(oPath.GetPath());
    }

    CString CSystemUtility::GetDirectoryName(const CString& strFileName)
    {
        CPath oPath(strFileName);
        return oPath.GetDirectory();
    }

    int CSystemUtility::GetFilesCount(const CString& strDirPath, const bool& bRecursive)
    {
        return FileSystem::Directory::GetFilesCount(strDirPath, bRecursive);
    }

    CString CSystemUtility::GetFileExtention(const CString& strFileName)
    {
        CPath oPath(strFileName);
        return oPath.GetExtention();
    }

    bool CSystemUtility::CreateDirectories(const CPath& oPath)
    {
        return FileSystem::Directory::CreateDirectories(oPath.m_strFilename);
    }

    void CSystemUtility::ReplaceExtention(CString& strName, CString& str1, CString& str2)
    {
        return;
    }
}
<|endoftext|>


<commit_before>// Source : https://oj.leetcode.com/problems/next-permutation/
// Author : Hao Chen
// Date   : 2014-08-21

/**********************************************************************************
*
* Implement next permutation, which rearranges numbers into the lexicographically next
* greater permutation of numbers.
*
* If such arrangement is not possible, it must rearrange it as the lowest possible order
* (ie, sorted in ascending order).
*
* The replacement must be in-place, do not allocate extra memory.
*
* Here are some examples. Inputs are in the left-hand column and its corresponding outputs
* are in the right-hand column.
*
*   1,2,3 → 1,3,2
*   3,2,1 → 1,2,3
*   1,1,5 → 1,5,1
*
**********************************************************************************/

/*
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
...
*/

#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void nextPermutation(vector<int> &num) {

    if(num.size()<=1) return;

    for(int i=num.size()-1; i>0; i--) {
        if (num[i-1] < num[i]){
            int j = num.size()-1;
            while( num[i-1] >= num[j]) {
                //pass;
                j--;
            }
            int tmp = num[j];
            num[j] = num[i-1];
            num[i-1] = tmp;
            reverse(num.begin()+i, num.end());
            return;
        }
        if (i == 1 ){
            reverse(num.begin(), num.end());
            return;
        }
    }

}

void printVector(vector<int> &num) {
    for(int i=0; i<num.size(); i++) {
        cout << num[i] << " ";
    }
    cout <<endl;
}
bool isBeginVector(vector<int> &num) {
    for(int i=0; i<num.size(); i++) {
        if(num[i] != i+1) {
            return false;
        }
    }
    return true;
}

int main(int argc, char** argv)
{
    int n = 4;
    if (argc>1){
        n = atoi(argv[1]);
    }
    vector<int> num;
    for(int i=1; i<=n; i++){
        num.push_back(i);
    }

    while(true){
        printVector(num);
        nextPermutation(num);
        if(isBeginVector(num)){
            break;
        }
    }
    return 0;
}
<commit_msg>add some explaination<commit_after>// Source : https://oj.leetcode.com/problems/next-permutation/
// Author : Hao Chen
// Date   : 2014-08-21

/**********************************************************************************
*
* Implement next permutation, which rearranges numbers into the lexicographically next
* greater permutation of numbers.
*
* If such arrangement is not possible, it must rearrange it as the lowest possible order
* (ie, sorted in ascending order).
*
* The replacement must be in-place, do not allocate extra memory.
*
* Here are some examples. Inputs are in the left-hand column and its corresponding outputs
* are in the right-hand column.
*
*   1,2,3 → 1,3,2
*   3,2,1 → 1,2,3
*   1,1,5 → 1,5,1
*
**********************************************************************************/

/*
 * Take a look the following continuous permutation, can you find the patern?
 *
 *    1 2 3 4
 *    1 2 4 3
 *    1 3 2 4
 *    1 3 4 2
 *    1 4 2 3
 *    1 4 3 2
 *    2 1 3 4
 *    ...
 *
 * The pattern as below:
 *
 *    1) find the first place which num[i-1] < num[i]
 *    2) find the first number from n-1 to i which >= num[i-1]
 *    3) swap the 2) num with num[i-1]
 *    4) sort the sub-array [i, n) //actuall sort is fine as well
 *
 * For example:
 *
 *     1 4 3 2   <-- 1) find the first place which num[i-1] < num[i]
 *     ^
 *
 *     1 4 3 2   <-- 2) find the first number from n-1 to i which >= num[i-1]
 *     ^     ^
 *
 *     2 4 3 1   <-- 3) swap them
 *     ^     ^
 *
 *     2 4 3 1   <-- 4) sort
 *       ^   ^
 *
 *     2 1 3 4
 *
 * Edge Case:
 *
 *     4 3 2 1, the next permutation is 1 2 3 4
 */

#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void nextPermutation(vector<int> &num) {

    if(num.size()<=1) return;

    for(int i=num.size()-1; i>0; i--) {
        if (num[i-1] < num[i]){
            int j = num.size()-1;
            while( num[i-1] >= num[j]) {
                //pass;
                j--;
            }
            int tmp = num[j];
            num[j] = num[i-1];
            num[i-1] = tmp;
            //sort works as well
            //sort(num.begin()+i, num.end());
            reverse(num.begin()+i, num.end());
            return;
        }
        //edge case: 4 3 2 1
        if (i == 1 ){
            //sort works as well
            //sort(num.begin(), num.end());
            reverse(num.begin(), num.end());
            return;
        }
    }

}

void printVector(vector<int> &num) {
    for(int i=0; i<num.size(); i++) {
        cout << num[i] << " ";
    }
    cout <<endl;
}
bool isBeginVector(vector<int> &num) {
    for(int i=0; i<num.size(); i++) {
        if(num[i] != i+1) {
            return false;
        }
    }
    return true;
}

int main(int argc, char** argv)
{
    int n = 4;
    if (argc>1){
        n = atoi(argv[1]);
    }
    vector<int> num;
    for(int i=1; i<=n; i++){
        num.push_back(i);
    }

    while(true){
        printVector(num);
        nextPermutation(num);
        if(isBeginVector(num)){
            break;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// Unit tests for alert system

#include "alert.h"
#include "chain.h"
#include "chainparams.h"
#include "clientversion.h"
#include "data/alertTests.raw.h"
#include "main.h" // For PartitionCheck
#include "serialize.h"
#include "streams.h"
#include "util.h"
#include "utilstrencodings.h"

#include "test/test_bitcoin.h"

#include <fstream>

#include <boost/filesystem/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>

#if 0
//
// alertTests contains 7 alerts, generated with this code:
// (SignAndSave code not shown, alert signing key is secret)
//
{
    CAlert alert;
    alert.nRelayUntil   = 60;
    alert.nExpiration   = 24 * 60 * 60;
    alert.nID           = 1;
    alert.nCancel       = 0;   // cancels previous messages up to this ID number
    alert.nMinVer       = 0;  // These versions are protocol versions
    alert.nMaxVer       = 999001;
    alert.nPriority     = 1;
    alert.strComment    = "Alert comment";
    alert.strStatusBar  = "Alert 1";

    SignAndSave(alert, "test/alertTests");

    alert.setSubVer.insert(std::string("/Satoshi:0.1.0/"));
    alert.strStatusBar  = "Alert 1 for Satoshi 0.1.0";
    SignAndSave(alert, "test/alertTests");

    alert.setSubVer.insert(std::string("/Satoshi:0.2.0/"));
    alert.strStatusBar  = "Alert 1 for Satoshi 0.1.0, 0.2.0";
    SignAndSave(alert, "test/alertTests");

    alert.setSubVer.clear();
    ++alert.nID;
    alert.nCancel = 1;
    alert.nPriority = 100;
    alert.strStatusBar  = "Alert 2, cancels 1";
    SignAndSave(alert, "test/alertTests");

    alert.nExpiration += 60;
    ++alert.nID;
    SignAndSave(alert, "test/alertTests");

    ++alert.nID;
    alert.nMinVer = 11;
    alert.nMaxVer = 22;
    SignAndSave(alert, "test/alertTests");

    ++alert.nID;
    alert.strStatusBar  = "Alert 2 for Satoshi 0.1.0";
    alert.setSubVer.insert(std::string("/Satoshi:0.1.0/"));
    SignAndSave(alert, "test/alertTests");

    ++alert.nID;
    alert.nMinVer = 0;
    alert.nMaxVer = 999999;
    alert.strStatusBar  = "Evil Alert'; /bin/ls; echo '";
    alert.setSubVer.clear();
    SignAndSave(alert, "test/alertTests");
}
#endif

struct ReadAlerts : public TestingSetup
{
    ReadAlerts()
    {
        std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests));
        CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
        try {
            while (!stream.eof())
            {
                CAlert alert;
                stream >> alert;
                alerts.push_back(alert);
            }
        }
        catch (const std::exception&) { }
    }
    ~ReadAlerts() { }

    static std::vector<std::string> read_lines(boost::filesystem::path filepath)
    {
        std::vector<std::string> result;

        std::ifstream f(filepath.string().c_str());
        std::string line;
        while (std::getline(f,line))
            result.push_back(line);

        return result;
    }

    std::vector<CAlert> alerts;
};

BOOST_FIXTURE_TEST_SUITE(Alert_tests, ReadAlerts)

BOOST_AUTO_TEST_CASE(AlertApplies)
{
    SetMockTime(11);
    const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();

    BOOST_FOREACH(const CAlert& alert, alerts)
    {
        BOOST_CHECK(alert.CheckSignature(alertKey));
    }

    BOOST_CHECK(alerts.size() >= 3);

    // Matches:
    BOOST_CHECK(alerts[0].AppliesTo(1, ""));
    BOOST_CHECK(alerts[0].AppliesTo(999001, ""));
    BOOST_CHECK(alerts[0].AppliesTo(1, "/Satoshi:11.11.11/"));

    BOOST_CHECK(alerts[1].AppliesTo(1, "/Satoshi:0.1.0/"));
    BOOST_CHECK(alerts[1].AppliesTo(999001, "/Satoshi:0.1.0/"));

    BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.1.0/"));
    BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.2.0/"));

    // Don't match:
    BOOST_CHECK(!alerts[0].AppliesTo(-1, ""));
    BOOST_CHECK(!alerts[0].AppliesTo(999002, ""));

    BOOST_CHECK(!alerts[1].AppliesTo(1, ""));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0"));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.1.0"));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0/"));
    BOOST_CHECK(!alerts[1].AppliesTo(-1, "/Satoshi:0.1.0/"));
    BOOST_CHECK(!alerts[1].AppliesTo(999002, "/Satoshi:0.1.0/"));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.2.0/"));

    BOOST_CHECK(!alerts[2].AppliesTo(1, "/Satoshi:0.3.0/"));

    SetMockTime(0);
}

BOOST_AUTO_TEST_CASE(AlertNotify)
{
    SetMockTime(11);
    const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();

    boost::filesystem::path temp = GetTempPath() / "alertnotify.txt";
    boost::filesystem::remove(temp);

    mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string();

    BOOST_FOREACH(CAlert alert, alerts)
        alert.ProcessAlert(alertKey, false);

    std::vector<std::string> r = read_lines(temp);
    BOOST_CHECK_EQUAL(r.size(), 4u);

// Windows built-in echo semantics are different than posixy shells. Quotes and
// whitespace are printed literally.

#ifndef WIN32
    BOOST_CHECK_EQUAL(r[0], "Alert 1");
    BOOST_CHECK_EQUAL(r[1], "Alert 2, cancels 1");
    BOOST_CHECK_EQUAL(r[2], "Alert 2, cancels 1");
    BOOST_CHECK_EQUAL(r[3], "Evil Alert; /bin/ls; echo "); // single-quotes should be removed
#else
    BOOST_CHECK_EQUAL(r[0], "'Alert 1' ");
    BOOST_CHECK_EQUAL(r[1], "'Alert 2, cancels 1' ");
    BOOST_CHECK_EQUAL(r[2], "'Alert 2, cancels 1' ");
    BOOST_CHECK_EQUAL(r[3], "'Evil Alert; /bin/ls; echo ' ");
#endif
    boost::filesystem::remove(temp);

    SetMockTime(0);
}

static bool falseFunc() { return false; }

BOOST_AUTO_TEST_CASE(PartitionAlert)
{
    // Test PartitionCheck
    CCriticalSection csDummy;
    CBlockIndex indexDummy[100];
    CChainParams& params = Params(CBaseChainParams::MAIN);
    int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing;

    // Generate fake blockchain timestamps relative to
    // an arbitrary time:
    int64_t now = 1427379054;
    SetMockTime(now);
    for (int i = 0; i < 100; i++)
    {
        indexDummy[i].phashBlock = NULL;
        if (i == 0) indexDummy[i].pprev = NULL;
        else indexDummy[i].pprev = &indexDummy[i-1];
        indexDummy[i].nHeight = i;
        indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing;
        // Other members don't matter, the partition check code doesn't
        // use them
    }

    // Test 1: chain with blocks every nPowTargetSpacing seconds,
    // as normal, no worries:
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(strMiscWarning.empty());

    // Test 2: go 3.5 hours without a block, expect a warning:
    now += 3*60*60+30*60;
    SetMockTime(now);
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(!strMiscWarning.empty());
    BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
    strMiscWarning = "";

    // Test 3: test the "partition alerts only go off once per day"
    // code:
    now += 60*10;
    SetMockTime(now);
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(strMiscWarning.empty());

    // Test 4: get 2.5 times as many blocks as expected:
    now += 60*60*24; // Pretend it is a day later
    SetMockTime(now);
    int64_t quickSpacing = nPowTargetSpacing*2/5;
    for (int i = 0; i < 100; i++) // Tweak chain timestamps:
        indexDummy[i].nTime = now - (100-i)*quickSpacing;
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(!strMiscWarning.empty());
    BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
    strMiscWarning = "";

    SetMockTime(0);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Use unique name for AlertNotify tempfile<commit_after>// Copyright (c) 2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// Unit tests for alert system

#include "alert.h"
#include "chain.h"
#include "chainparams.h"
#include "clientversion.h"
#include "data/alertTests.raw.h"
#include "main.h" // For PartitionCheck
#include "serialize.h"
#include "streams.h"
#include "util.h"
#include "utilstrencodings.h"

#include "test/test_bitcoin.h"

#include <fstream>

#include <boost/filesystem/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>

#if 0
//
// alertTests contains 7 alerts, generated with this code:
// (SignAndSave code not shown, alert signing key is secret)
//
{
    CAlert alert;
    alert.nRelayUntil   = 60;
    alert.nExpiration   = 24 * 60 * 60;
    alert.nID           = 1;
    alert.nCancel       = 0;   // cancels previous messages up to this ID number
    alert.nMinVer       = 0;  // These versions are protocol versions
    alert.nMaxVer       = 999001;
    alert.nPriority     = 1;
    alert.strComment    = "Alert comment";
    alert.strStatusBar  = "Alert 1";

    SignAndSave(alert, "test/alertTests");

    alert.setSubVer.insert(std::string("/Satoshi:0.1.0/"));
    alert.strStatusBar  = "Alert 1 for Satoshi 0.1.0";
    SignAndSave(alert, "test/alertTests");

    alert.setSubVer.insert(std::string("/Satoshi:0.2.0/"));
    alert.strStatusBar  = "Alert 1 for Satoshi 0.1.0, 0.2.0";
    SignAndSave(alert, "test/alertTests");

    alert.setSubVer.clear();
    ++alert.nID;
    alert.nCancel = 1;
    alert.nPriority = 100;
    alert.strStatusBar  = "Alert 2, cancels 1";
    SignAndSave(alert, "test/alertTests");

    alert.nExpiration += 60;
    ++alert.nID;
    SignAndSave(alert, "test/alertTests");

    ++alert.nID;
    alert.nMinVer = 11;
    alert.nMaxVer = 22;
    SignAndSave(alert, "test/alertTests");

    ++alert.nID;
    alert.strStatusBar  = "Alert 2 for Satoshi 0.1.0";
    alert.setSubVer.insert(std::string("/Satoshi:0.1.0/"));
    SignAndSave(alert, "test/alertTests");

    ++alert.nID;
    alert.nMinVer = 0;
    alert.nMaxVer = 999999;
    alert.strStatusBar  = "Evil Alert'; /bin/ls; echo '";
    alert.setSubVer.clear();
    SignAndSave(alert, "test/alertTests");
}
#endif

struct ReadAlerts : public TestingSetup
{
    ReadAlerts()
    {
        std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests));
        CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
        try {
            while (!stream.eof())
            {
                CAlert alert;
                stream >> alert;
                alerts.push_back(alert);
            }
        }
        catch (const std::exception&) { }
    }
    ~ReadAlerts() { }

    static std::vector<std::string> read_lines(boost::filesystem::path filepath)
    {
        std::vector<std::string> result;

        std::ifstream f(filepath.string().c_str());
        std::string line;
        while (std::getline(f,line))
            result.push_back(line);

        return result;
    }

    std::vector<CAlert> alerts;
};

BOOST_FIXTURE_TEST_SUITE(Alert_tests, ReadAlerts)

BOOST_AUTO_TEST_CASE(AlertApplies)
{
    SetMockTime(11);
    const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();

    BOOST_FOREACH(const CAlert& alert, alerts)
    {
        BOOST_CHECK(alert.CheckSignature(alertKey));
    }

    BOOST_CHECK(alerts.size() >= 3);

    // Matches:
    BOOST_CHECK(alerts[0].AppliesTo(1, ""));
    BOOST_CHECK(alerts[0].AppliesTo(999001, ""));
    BOOST_CHECK(alerts[0].AppliesTo(1, "/Satoshi:11.11.11/"));

    BOOST_CHECK(alerts[1].AppliesTo(1, "/Satoshi:0.1.0/"));
    BOOST_CHECK(alerts[1].AppliesTo(999001, "/Satoshi:0.1.0/"));

    BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.1.0/"));
    BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.2.0/"));

    // Don't match:
    BOOST_CHECK(!alerts[0].AppliesTo(-1, ""));
    BOOST_CHECK(!alerts[0].AppliesTo(999002, ""));

    BOOST_CHECK(!alerts[1].AppliesTo(1, ""));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0"));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.1.0"));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0/"));
    BOOST_CHECK(!alerts[1].AppliesTo(-1, "/Satoshi:0.1.0/"));
    BOOST_CHECK(!alerts[1].AppliesTo(999002, "/Satoshi:0.1.0/"));
    BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.2.0/"));

    BOOST_CHECK(!alerts[2].AppliesTo(1, "/Satoshi:0.3.0/"));

    SetMockTime(0);
}

BOOST_AUTO_TEST_CASE(AlertNotify)
{
    SetMockTime(11);
    const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();

    boost::filesystem::path temp = GetTempPath() /
        boost::filesystem::unique_path("alertnotify-%%%%.txt");

    mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string();

    BOOST_FOREACH(CAlert alert, alerts)
        alert.ProcessAlert(alertKey, false);

    std::vector<std::string> r = read_lines(temp);
    BOOST_CHECK_EQUAL(r.size(), 4u);

// Windows built-in echo semantics are different than posixy shells. Quotes and
// whitespace are printed literally.

#ifndef WIN32
    BOOST_CHECK_EQUAL(r[0], "Alert 1");
    BOOST_CHECK_EQUAL(r[1], "Alert 2, cancels 1");
    BOOST_CHECK_EQUAL(r[2], "Alert 2, cancels 1");
    BOOST_CHECK_EQUAL(r[3], "Evil Alert; /bin/ls; echo "); // single-quotes should be removed
#else
    BOOST_CHECK_EQUAL(r[0], "'Alert 1' ");
    BOOST_CHECK_EQUAL(r[1], "'Alert 2, cancels 1' ");
    BOOST_CHECK_EQUAL(r[2], "'Alert 2, cancels 1' ");
    BOOST_CHECK_EQUAL(r[3], "'Evil Alert; /bin/ls; echo ' ");
#endif
    boost::filesystem::remove(temp);

    SetMockTime(0);
}

static bool falseFunc() { return false; }

BOOST_AUTO_TEST_CASE(PartitionAlert)
{
    // Test PartitionCheck
    CCriticalSection csDummy;
    CBlockIndex indexDummy[100];
    CChainParams& params = Params(CBaseChainParams::MAIN);
    int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing;

    // Generate fake blockchain timestamps relative to
    // an arbitrary time:
    int64_t now = 1427379054;
    SetMockTime(now);
    for (int i = 0; i < 100; i++)
    {
        indexDummy[i].phashBlock = NULL;
        if (i == 0) indexDummy[i].pprev = NULL;
        else indexDummy[i].pprev = &indexDummy[i-1];
        indexDummy[i].nHeight = i;
        indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing;
        // Other members don't matter, the partition check code doesn't
        // use them
    }

    // Test 1: chain with blocks every nPowTargetSpacing seconds,
    // as normal, no worries:
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(strMiscWarning.empty());

    // Test 2: go 3.5 hours without a block, expect a warning:
    now += 3*60*60+30*60;
    SetMockTime(now);
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(!strMiscWarning.empty());
    BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
    strMiscWarning = "";

    // Test 3: test the "partition alerts only go off once per day"
    // code:
    now += 60*10;
    SetMockTime(now);
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(strMiscWarning.empty());

    // Test 4: get 2.5 times as many blocks as expected:
    now += 60*60*24; // Pretend it is a day later
    SetMockTime(now);
    int64_t quickSpacing = nPowTargetSpacing*2/5;
    for (int i = 0; i < 100; i++) // Tweak chain timestamps:
        indexDummy[i].nTime = now - (100-i)*quickSpacing;
    PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
    BOOST_CHECK(!strMiscWarning.empty());
    BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
    strMiscWarning = "";

    SetMockTime(0);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>//===- lib/Linker/Linker.cpp - Basic Linker functionality  ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains basic Linker functionality that all usages will need.
//
//===----------------------------------------------------------------------===//

#include "llvm/Linker.h"
#include "llvm/Module.h"
#include "llvm/Bytecode/Reader.h"
#include <iostream>

using namespace llvm;

Linker::Linker(const std::string& progname, unsigned flags)
  : Composite(0)
  , LibPaths()
  , Flags(flags)
  , Error()
  , ProgramName(progname)
{
  Composite = new Module(progname);
}

Linker::Linker(const std::string& progname, Module* aModule, unsigned flags)
  : Composite(aModule)
  , LibPaths()
  , Flags(flags)
  , Error()
  , ProgramName(progname)
{
}

Linker::~Linker() {
  delete Composite;
}

bool
Linker::error(const std::string& message) {
  Error = message;
  if (!(Flags&QuietErrors)) {
    std::cerr << ProgramName << ": error: " << message << "\n";
  }
  return true;
}

bool
Linker::warning(const std::string& message) {
  Error = message;
  if (!(Flags&QuietErrors)) {
    std::cerr << ProgramName << ": warning: " << message << "\n";
  }
  return false;
}

void
Linker::verbose(const std::string& message) {
  if (Flags&Verbose) {
    std::cerr << "  " << message << "\n";
  }
}

void
Linker::addPath(const sys::Path& path) {
  assert(path.isDirectory() && "Can only insert directories into the path");
  LibPaths.push_back(path);
}

void
Linker::addPaths(const std::vector<std::string>& paths) {
  for (unsigned i = 0; i != paths.size(); ++i) {
    sys::Path aPath;
    aPath.setDirectory(paths[i]);
    LibPaths.push_back(aPath);
  }
}

void
Linker::addSystemPaths() {
  sys::Path::GetBytecodeLibraryPaths(LibPaths);
  LibPaths.insert(LibPaths.begin(),sys::Path("./"));
}

Module*
Linker::releaseModule() {
  Module* result = Composite;
  LibPaths.clear();
  Error.clear();
  Composite = 0;
  Flags = 0;
  return result;
}

// LoadObject - Read in and parse the bytecode file named by FN and return the
// module it contains (wrapped in an auto_ptr), or auto_ptr<Module>() and set
// Error if an error occurs.
std::auto_ptr<Module>
Linker::LoadObject(const sys::Path &FN) {
  std::string ParseErrorMessage;
  Module *Result = ParseBytecodeFile(FN.toString(), &ParseErrorMessage);
  if (Result)
    return std::auto_ptr<Module>(Result);
  Error = "Bytecode file '" + FN.toString() + "' could not be loaded";
  if (ParseErrorMessage.size())
    Error += ": " + ParseErrorMessage;
  return std::auto_ptr<Module>();
}

// IsLibrary - Determine if "Name" is a library in "Directory". Return
// a non-empty sys::Path if its found, an empty one otherwise.
static inline sys::Path IsLibrary(const std::string& Name,
                                  const sys::Path& Directory) {

  assert(Directory.isDirectory() && "Need to specify a directory");
  sys::Path FullPath(Directory);
  FullPath.appendFile("lib" + Name);

  FullPath.appendSuffix("a");
  if (FullPath.isArchive())
    return FullPath;

  FullPath.elideSuffix();
  FullPath.appendSuffix("bca");
  if (FullPath.isArchive())
    return FullPath;

  FullPath.elideSuffix();
  FullPath.appendSuffix(&(LTDL_SHLIB_EXT[1]));
  if (FullPath.isDynamicLibrary())
    return FullPath;

  FullPath.clear();
  return FullPath;
}

/// FindLib - Try to convert Filename into the name of a file that we can open,
/// if it does not already name a file we can open, by first trying to open
/// Filename, then libFilename.[suffix] for each of a set of several common
/// library suffixes, in each of the directories in LibPaths. Returns an empty
/// Path if no matching file can be found.
///
sys::Path
Linker::FindLib(const std::string &Filename)
{
  // Determine if the pathname can be found as it stands.
  sys::Path FilePath(Filename);
  if (FilePath.readable() &&
      (FilePath.isArchive() || FilePath.isDynamicLibrary()))
    return FilePath;

  // Iterate over the directories in Paths to see if we can find the library
  // there.
  for (unsigned Index = 0; Index != LibPaths.size(); ++Index) {
    sys::Path Directory(LibPaths[Index]);
    sys::Path FullPath = IsLibrary(Filename,Directory);
    if (!FullPath.isEmpty())
      return FullPath;
  }
  return sys::Path();
}
<commit_msg>Fix a compile error. config.h is now needed because DataTypes.h doesn't include it any more.<commit_after>//===- lib/Linker/Linker.cpp - Basic Linker functionality  ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains basic Linker functionality that all usages will need.
//
//===----------------------------------------------------------------------===//

#include "llvm/Linker.h"
#include "llvm/Module.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Config/config.h"
#include <iostream>

using namespace llvm;

Linker::Linker(const std::string& progname, unsigned flags)
  : Composite(0)
  , LibPaths()
  , Flags(flags)
  , Error()
  , ProgramName(progname)
{
  Composite = new Module(progname);
}

Linker::Linker(const std::string& progname, Module* aModule, unsigned flags)
  : Composite(aModule)
  , LibPaths()
  , Flags(flags)
  , Error()
  , ProgramName(progname)
{
}

Linker::~Linker() {
  delete Composite;
}

bool
Linker::error(const std::string& message) {
  Error = message;
  if (!(Flags&QuietErrors)) {
    std::cerr << ProgramName << ": error: " << message << "\n";
  }
  return true;
}

bool
Linker::warning(const std::string& message) {
  Error = message;
  if (!(Flags&QuietErrors)) {
    std::cerr << ProgramName << ": warning: " << message << "\n";
  }
  return false;
}

void
Linker::verbose(const std::string& message) {
  if (Flags&Verbose) {
    std::cerr << "  " << message << "\n";
  }
}

void
Linker::addPath(const sys::Path& path) {
  assert(path.isDirectory() && "Can only insert directories into the path");
  LibPaths.push_back(path);
}

void
Linker::addPaths(const std::vector<std::string>& paths) {
  for (unsigned i = 0; i != paths.size(); ++i) {
    sys::Path aPath;
    aPath.setDirectory(paths[i]);
    LibPaths.push_back(aPath);
  }
}

void
Linker::addSystemPaths() {
  sys::Path::GetBytecodeLibraryPaths(LibPaths);
  LibPaths.insert(LibPaths.begin(),sys::Path("./"));
}

Module*
Linker::releaseModule() {
  Module* result = Composite;
  LibPaths.clear();
  Error.clear();
  Composite = 0;
  Flags = 0;
  return result;
}

// LoadObject - Read in and parse the bytecode file named by FN and return the
// module it contains (wrapped in an auto_ptr), or auto_ptr<Module>() and set
// Error if an error occurs.
std::auto_ptr<Module>
Linker::LoadObject(const sys::Path &FN) {
  std::string ParseErrorMessage;
  Module *Result = ParseBytecodeFile(FN.toString(), &ParseErrorMessage);
  if (Result)
    return std::auto_ptr<Module>(Result);
  Error = "Bytecode file '" + FN.toString() + "' could not be loaded";
  if (ParseErrorMessage.size())
    Error += ": " + ParseErrorMessage;
  return std::auto_ptr<Module>();
}

// IsLibrary - Determine if "Name" is a library in "Directory". Return
// a non-empty sys::Path if its found, an empty one otherwise.
static inline sys::Path IsLibrary(const std::string& Name,
                                  const sys::Path& Directory) {

  assert(Directory.isDirectory() && "Need to specify a directory");
  sys::Path FullPath(Directory);
  FullPath.appendFile("lib" + Name);

  FullPath.appendSuffix("a");
  if (FullPath.isArchive())
    return FullPath;

  FullPath.elideSuffix();
  FullPath.appendSuffix("bca");
  if (FullPath.isArchive())
    return FullPath;

  FullPath.elideSuffix();
  FullPath.appendSuffix(&(LTDL_SHLIB_EXT[1]));
  if (FullPath.isDynamicLibrary())
    return FullPath;

  FullPath.clear();
  return FullPath;
}

/// FindLib - Try to convert Filename into the name of a file that we can open,
/// if it does not already name a file we can open, by first trying to open
/// Filename, then libFilename.[suffix] for each of a set of several common
/// library suffixes, in each of the directories in LibPaths. Returns an empty
/// Path if no matching file can be found.
///
sys::Path
Linker::FindLib(const std::string &Filename)
{
  // Determine if the pathname can be found as it stands.
  sys::Path FilePath(Filename);
  if (FilePath.readable() &&
      (FilePath.isArchive() || FilePath.isDynamicLibrary()))
    return FilePath;

  // Iterate over the directories in Paths to see if we can find the library
  // there.
  for (unsigned Index = 0; Index != LibPaths.size(); ++Index) {
    sys::Path Directory(LibPaths[Index]);
    sys::Path FullPath = IsLibrary(Filename,Directory);
    if (!FullPath.isEmpty())
      return FullPath;
  }
  return sys::Path();
}
<|endoftext|>