<commit_before>#include <RcppArmadillo.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>
#include <string.h>
#include <iostream>
#include <cmath>

#include "rtoarmadillo.h"

// Format for sensor information
struct imu_info{
  std::string name;
  int time_type;
  int data_type;
  int header_size;
  double scale_gyro;
  double scale_acc;
};

// Helper function to create the data structure needed
imu_info get_imu_info(std::string imu_type){

  // Transform imu_type to capitals
  transform(imu_type.begin(), imu_type.end(), imu_type.begin(), ::toupper);

  // Create class definition
  imu_info imu;

  // opted for if/else vs. map to save in constructing all imu types. so, O(n) instead of O(log(n)) =(
  if(imu_type == "IMAR"){
    imu.name          = "IMAR";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 0.10000000*M_PI/180.0/3600.0; // Scale gyro to rad
    imu.scale_acc     = 0.00152588/1000.0;            // scale accel to m/s
  }else if(imu_type == "LN200"){
    imu.name          = "LN200";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 1.0/2097152.0; // Scale gyro to rad
    imu.scale_acc     = 1.0/16384.0;	 // scale accel to m/s
  }else if(imu_type == "LN200IG"){
    imu.name          = "LN200IG";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 1.0/524288.0;    // Scale gyro to rad
    imu.scale_acc     = 1.0/16384.0;		 // scale accel to m/s
  }else if(imu_type == "IXSEA"){
    imu.name          = "IXSEA";
    imu.time_type     = 8; // double
    imu.data_type     = 8; // double
    imu.header_size   = 0;
    imu.scale_gyro    = M_PI/180.0/3600.0; // Scale gyro to rad
    imu.scale_acc     = 0.001;		      	 // scale accel to m/s
  }else if(imu_type == "NAVCHIP_FLT"){
    imu.name          = "NAVCHIP_FLT";
    imu.time_type     = 8; // double
    imu.data_type     = 8; // double
    imu.header_size   = 0;
    imu.scale_gyro    = ((1.0/3600.0)/360.0)*2.0*M_PI; // Scale gyro to rad
    imu.scale_acc     = 0.001;			                   // scale accel to m/s
  }else if(imu_type == "NAVCHIP_INT"){
    imu.name          = "NAVCHIP_INT";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 0.00000625;       // Scale gyro to rad
    imu.scale_acc     = 0.0000390625;			// scale accel to m/s
  }else{
    throw std::runtime_error("The IMU type "+ imu_type + " is not supported");
  }

  return imu;
}

//' Read an IMU Binary File into R
//'
//' The function will take a file location in addition to the type of sensor it
//' came from and read the data into R.
//'
//' @param file_path A \code{string} that contains the full file path.
//' @param imu_type A \code{string} that contains a supported IMU type given below.
//' @details
//' Currently supports the following IMUs:
//' \itemize{
//' \item IMAR
//' \item LN200
//' \item LN200IG
//' \item IXSEA
//' \item NAVCHIP_INT
//' \item NAVCHIP_FLT
//' }
//'
//' We hope to soon be able to support delimited files.
//' @return A matrix with dimensions N x 7, where the columns represent:
//' \describe{
//' \item{Col 0}{Time}
//' \item{Col 1}{Gyro 1}
//' \item{Col 2}{Gyro 2}
//' \item{Col 3}{Gyro 3}
//' \item{Col 4}{Accel 1}
//' \item{Col 5}{Accel 2}
//' \item{Col 6}{Accel 3}
//' }
//' @references
//' Thanks goes to Philipp Clausen of Labo TOPO, EPFL, Switzerland, topo.epfl.ch, Tel:+41(0)21 693 27 55
//' for providing a matlab function that reads in IMUs.
//' The function below is a heavily modified port of MATLAB code into Armadillo/C++.
//'
//' @examples
//' read_imu("F:/Desktop/short_test_data.imu","IXSEA")
// [[Rcpp::export]]
arma::field<arma::mat> read_imu(std::string file_path, std::string imu_type) {

  // -- File Operations

  // Split the file name from the path.
  size_t found = file_path.find_last_of("/\\");

  std::string file_loc = file_path.substr(0,found);
  std::string file_name = file_path.substr(found+1);

  // Open data file - need "r" to read, and "b" to indicate binary (o.w. fails on Windows)
  FILE *fid = fopen((char*)file_path.c_str(),"rb");

  if (fid == NULL){
    throw std::runtime_error("Cannot open the " + file_name + " at " + file_loc);
  }

  // -- Check IMU Type requested

  // Get data structure
  imu_info imu = get_imu_info(imu_type);

  // BitsPerEpoch
  unsigned int BitsPerEpoch = imu.time_type + 6*imu.data_type;

  // Set cursor at end of file
  fseek(fid, 0, SEEK_END);

  // ftell returns the file position (end location)
  double lsize = ftell(fid); // probably could get away with a float here.

  // Count epochs and control it
  double nEpochs = (lsize-imu.header_size)/BitsPerEpoch;

  // Is nEpochs an integer?
  if(trunc(nEpochs) != nEpochs){
    throw std::runtime_error("The file does not have the expected file size. Check the type of IMU or if the file is corrupted.");
  }

  // display info to command window
  std::cout << file_name <<  " contains " << (int)nEpochs << " epochs " << std::endl << "Reading ..." << std::endl;

  // -- Read time

  // Initialize data matrix
  arma::mat data(nEpochs,7);

  // Set cursor at begining of data (e.g. skip header if it exists)
  fseek(fid, imu.header_size, SEEK_SET);

  // Fill the data matrix
  if(imu.data_type == 8){ // Data is only doubles

    double data_buffer[7];

    for(unsigned int i = 0; i < nEpochs; i++){
      fread(&data_buffer, sizeof(double), 7, fid); // double

      for(int j = 0; j < 7; j++){
        data(i,j) = data_buffer[j];
      }
    }

  }else{ // Data is a mix of double then 6 longs

    double time_buffer[1];
    long data_buffer[6];

    for(unsigned int i = 0; i < nEpochs; i++){
      fread(&time_buffer, sizeof(double), 1, fid); // double

      fread(&data_buffer, 4, 6, fid); // long

      data(i,0) = time_buffer[0];

      for(int j = 1; j <= 6; j++){
        data(i,j) = data_buffer[j-1];
      }
    }

  } // end if

  // Close the file connection
  fclose(fid);

  // Data Rate
  double fIMU = 1.0/mean_diff(data.col(0));

  fIMU = round(fIMU);

  //printf("(data @ %.2f Hz, sGr %f sAc %f) ...", fIMU, imu.scale_gyro, imu.scale_acc);

  // Scale data
  data.cols(1,3) *= fIMU * imu.scale_gyro;
  data.cols(4,6) *= fIMU * imu.scale_acc;

  arma::vec stats(3);
  stats(0) = fIMU;
  stats(1) = imu.scale_gyro;
  stats(2) = imu.scale_acc;

  arma::field<arma::mat> out(2);
  out(0) = data;
  out(1) = stats;
  return out;
}

<commit_msg>Clang vs. gcc issue >.<<commit_after>#include <RcppArmadillo.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>
#include <string.h>
#include <iostream>
#include <cmath>

#include "rtoarmadillo.h"

// Format for sensor information
struct imu_info{
  std::string name;
  int time_type;
  int data_type;
  int header_size;
  double scale_gyro;
  double scale_acc;
};

// Helper function to create the data structure needed
imu_info get_imu_info(std::string imu_type){

  // Transform imu_type to capitals
  transform(imu_type.begin(), imu_type.end(), imu_type.begin(), ::toupper);

  // Create class definition
  imu_info imu;

  // opted for if/else vs. map to save in constructing all imu types. so, O(n) instead of O(log(n)) =(
  if(imu_type == "IMAR"){
    imu.name          = "IMAR";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 0.10000000*M_PI/180.0/3600.0; // Scale gyro to rad
    imu.scale_acc     = 0.00152588/1000.0;            // scale accel to m/s
  }else if(imu_type == "LN200"){
    imu.name          = "LN200";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 1.0/2097152.0; // Scale gyro to rad
    imu.scale_acc     = 1.0/16384.0;	 // scale accel to m/s
  }else if(imu_type == "LN200IG"){
    imu.name          = "LN200IG";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 1.0/524288.0;    // Scale gyro to rad
    imu.scale_acc     = 1.0/16384.0;		 // scale accel to m/s
  }else if(imu_type == "IXSEA"){
    imu.name          = "IXSEA";
    imu.time_type     = 8; // double
    imu.data_type     = 8; // double
    imu.header_size   = 0;
    imu.scale_gyro    = M_PI/180.0/3600.0; // Scale gyro to rad
    imu.scale_acc     = 0.001;		      	 // scale accel to m/s
  }else if(imu_type == "NAVCHIP_FLT"){
    imu.name          = "NAVCHIP_FLT";
    imu.time_type     = 8; // double
    imu.data_type     = 8; // double
    imu.header_size   = 0;
    imu.scale_gyro    = ((1.0/3600.0)/360.0)*2.0*M_PI; // Scale gyro to rad
    imu.scale_acc     = 0.001;			                   // scale accel to m/s
  }else if(imu_type == "NAVCHIP_INT"){
    imu.name          = "NAVCHIP_INT";
    imu.time_type     = 8; // double
    imu.data_type     = 4; // long
    imu.header_size   = 0;
    imu.scale_gyro    = 0.00000625;       // Scale gyro to rad
    imu.scale_acc     = 0.0000390625;			// scale accel to m/s
  }else{
    throw std::runtime_error("The IMU type "+ imu_type + " is not supported");
  }

  return imu;
}

//' Read an IMU Binary File into R
//'
//' The function will take a file location in addition to the type of sensor it
//' came from and read the data into R.
//'
//' @param file_path A \code{string} that contains the full file path.
//' @param imu_type A \code{string} that contains a supported IMU type given below.
//' @details
//' Currently supports the following IMUs:
//' \itemize{
//' \item IMAR
//' \item LN200
//' \item LN200IG
//' \item IXSEA
//' \item NAVCHIP_INT
//' \item NAVCHIP_FLT
//' }
//'
//' We hope to soon be able to support delimited files.
//' @return A matrix with dimensions N x 7, where the columns represent:
//' \describe{
//' \item{Col 0}{Time}
//' \item{Col 1}{Gyro 1}
//' \item{Col 2}{Gyro 2}
//' \item{Col 3}{Gyro 3}
//' \item{Col 4}{Accel 1}
//' \item{Col 5}{Accel 2}
//' \item{Col 6}{Accel 3}
//' }
//' @references
//' Thanks goes to Philipp Clausen of Labo TOPO, EPFL, Switzerland, topo.epfl.ch, Tel:+41(0)21 693 27 55
//' for providing a matlab function that reads in IMUs.
//' The function below is a heavily modified port of MATLAB code into Armadillo/C++.
//'
//' @examples
//' read_imu("F:/Desktop/short_test_data.imu","IXSEA")
// [[Rcpp::export]]
arma::field<arma::mat> read_imu(std::string file_path, std::string imu_type) {

  // -- File Operations

  // Split the file name from the path.
  size_t found = file_path.find_last_of("/\\");

  std::string file_loc = file_path.substr(0,found);
  std::string file_name = file_path.substr(found+1);

  // Open data file - need "r" to read, and "b" to indicate binary (o.w. fails on Windows)
  FILE *fid = fopen((char*)file_path.c_str(),"rb");

  if (fid == NULL){
    throw std::runtime_error("Cannot open the " + file_name + " at " + file_loc);
  }

  // -- Check IMU Type requested

  // Get data structure
  imu_info imu = get_imu_info(imu_type);

  // BitsPerEpoch
  unsigned int BitsPerEpoch = imu.time_type + 6*imu.data_type;

  // Set cursor at end of file
  fseek(fid, 0, SEEK_END);

  // ftell returns the file position (end location)
  double lsize = ftell(fid); // probably could get away with a float here.

  // Count epochs and control it
  double nEpochs = (lsize-imu.header_size)/BitsPerEpoch;

  // Is nEpochs an integer?
  if(trunc(nEpochs) != nEpochs){
    throw std::runtime_error("The file does not have the expected file size. Check the type of IMU or if the file is corrupted.");
  }

  // display info to command window
  std::cout << file_name <<  " contains " << (int)nEpochs << " epochs " << std::endl << "Reading ..." << std::endl;

  // -- Read time

  // Initialize data matrix
  arma::mat data(nEpochs,7);

  // Set cursor at begining of data (e.g. skip header if it exists)
  fseek(fid, imu.header_size, SEEK_SET);

  // Fill the data matrix
  if(imu.data_type == 8){ // Data is only doubles

    double data_buffer[7];

    for(unsigned int i = 0; i < nEpochs; i++){
      fread(&data_buffer, 8, 7, fid); // double

      for(int j = 0; j < 7; j++){
        data(i,j) = data_buffer[j];
      }
    }

  }else{ // Data is a mix of double then 6 longs

    double time_buffer[1];
    long data_buffer[6];

    for(unsigned int i = 0; i < nEpochs; i++){
      fread(&time_buffer, 8, 1, fid); // double

      fread(&data_buffer, 4, 6, fid); // long

      data(i,0) = time_buffer[0];

      for(int j = 1; j <= 6; j++){
        data(i,j) = data_buffer[j-1];
      }
    }

  } // end if

  // Close the file connection
  fclose(fid);

  // Data Rate
  double fIMU = 1.0/mean_diff(data.col(0));

  fIMU = round(fIMU);

  //printf("(data @ %.2f Hz, sGr %f sAc %f) ...", fIMU, imu.scale_gyro, imu.scale_acc);

  // Scale data
  data.cols(1,3) *= fIMU * imu.scale_gyro;
  data.cols(4,6) *= fIMU * imu.scale_acc;

  arma::vec stats(3);
  stats(0) = fIMU;
  stats(1) = imu.scale_gyro;
  stats(2) = imu.scale_acc;

  arma::field<arma::mat> out(2);
  out(0) = data;
  out(1) = stats;
  return out;
}

<|endoftext|>


<commit_before>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include "helper.hh"

namespace wrencc {

template <typename T>
class LinkedList final : private UnCopyable {
  template <typename _Tp> struct ListNode {
    ListNode<_Tp>* next;
    _Tp value;
  };
  using NodeType = ListNode<T>;

  sz_t size_{};
  NodeType* head_{};
  NodeType* tail_{};

  NodeType* create_aux(const T& value) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, value);
      node->next = nullptr;
    }
    catch (...) {
      SimpleAlloc<NodeType>::deallocate(node);
      throw;
    }
    return node;
  }

  NodeType* create_aux(T&& value) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, std::move(value));
      node->next = nullptr;
    }
    catch (...) {
      SimpleAlloc<NodeType>::deallocate(node);
      throw;
    }
    return node;
  }

  template <typename... Args> NodeType* create_aux(Args&&... args) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, std::forward<Args>(args)...);
      node->next = nullptr;
    }
    catch (...) {
      SimpleAlloc<NodeType>::deallocate(node);
      throw;
    }
    return node;
  }

  void destroy_aux(NodeType* node) noexcept {
    destroy(&node->value);
    SimpleAlloc<NodeType>::deallocate(node);
  }

  void append_aux(NodeType* new_node) {
    if (head_ == nullptr) {
      head_ = tail_ = new_node;
    }
    else {
      tail_->next = new_node;
      tail_ = new_node;
    }
    ++size_;
  }
public:
  LinkedList() noexcept {}
  ~LinkedList() noexcept { clear(); }

  inline bool empty() const noexcept { return size_ == 0; }
  inline sz_t size() const noexcept { return size_; }
  inline NodeType* get_head() const noexcept { return head_; }
  inline NodeType* get_tail() const noexcept { return tail_; }

  void clear() {
    while (head_ != nullptr) {
      auto* node = head_;
      head_ = head_->next;
      destroy_aux(node);
    }
    tail_ = nullptr;
    size_ = 0;
  }

  inline void append(const T& x) { append_aux(create_aux(x)); }
  inline void append(T&& x) { append_aux(create_aux(std::move(x))); }

  template <typename... Args> inline void append(Args&&... args) {
    append_aux(create_aux(std::forward<Args>(args)...));
  }

  T pop_head() {
    NodeType* node = head_;
    if (head_ = head_->value; head_ == nullptr)
      tail_ = nullptr;
    T r = node->value;
    destroy_aux(node);
    --size_;

    return r;
  }

  template <typename Function> inline void for_each(Function&& fn) noexcept {
    for (auto* n = head_; n != nullptr; n = n->next)
      fn(n->value);
  }
};

}
<commit_msg>:bug: fix(list): fixed pop function of linked-list<commit_after>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include "helper.hh"

namespace wrencc {

template <typename T>
class LinkedList final : private UnCopyable {
  template <typename _Tp> struct ListNode {
    ListNode<_Tp>* next;
    _Tp value;
  };
  using NodeType = ListNode<T>;

  sz_t size_{};
  NodeType* head_{};
  NodeType* tail_{};

  NodeType* create_aux(const T& value) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, value);
      node->next = nullptr;
    }
    catch (...) {
      SimpleAlloc<NodeType>::deallocate(node);
      throw;
    }
    return node;
  }

  NodeType* create_aux(T&& value) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, std::move(value));
      node->next = nullptr;
    }
    catch (...) {
      SimpleAlloc<NodeType>::deallocate(node);
      throw;
    }
    return node;
  }

  template <typename... Args> NodeType* create_aux(Args&&... args) {
    NodeType* node = SimpleAlloc<NodeType>::allocate();
    try {
      construct(&node->value, std::forward<Args>(args)...);
      node->next = nullptr;
    }
    catch (...) {
      SimpleAlloc<NodeType>::deallocate(node);
      throw;
    }
    return node;
  }

  void destroy_aux(NodeType* node) noexcept {
    destroy(&node->value);
    SimpleAlloc<NodeType>::deallocate(node);
  }

  void append_aux(NodeType* new_node) {
    if (head_ == nullptr) {
      head_ = tail_ = new_node;
    }
    else {
      tail_->next = new_node;
      tail_ = new_node;
    }
    ++size_;
  }
public:
  LinkedList() noexcept {}
  ~LinkedList() noexcept { clear(); }

  inline bool empty() const noexcept { return size_ == 0; }
  inline sz_t size() const noexcept { return size_; }
  inline NodeType* get_head() const noexcept { return head_; }
  inline NodeType* get_tail() const noexcept { return tail_; }

  void clear() {
    while (head_ != nullptr) {
      auto* node = head_;
      head_ = head_->next;
      destroy_aux(node);
    }
    tail_ = nullptr;
    size_ = 0;
  }

  inline void append(const T& x) { append_aux(create_aux(x)); }
  inline void append(T&& x) { append_aux(create_aux(std::move(x))); }

  template <typename... Args> inline void append(Args&&... args) {
    append_aux(create_aux(std::forward<Args>(args)...));
  }

  T pop_head() {
    NodeType* node = head_;
    if (head_ = head_->next; head_ == nullptr)
      tail_ = nullptr;
    T r = node->value;
    destroy_aux(node);
    --size_;

    return r;
  }

  template <typename Function> inline void for_each(Function&& fn) noexcept {
    for (auto* n = head_; n != nullptr; n = n->next)
      fn(n->value);
  }
};

}
<|endoftext|>


<commit_before>
/*
    pbrt source code is Copyright(c) 1998-2015
                        Matt Pharr, Greg Humphreys, and Wenzel Jakob.

    This file is part of pbrt.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:

    - Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    - Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 */

#include "stdafx.h"

// core/fileutil.cpp*
#include "pbrt.h"
#include "fileutil.h"
#include <cstdlib>
#include <climits>
#ifndef PBRT_IS_WINDOWS
#include <libgen.h>
#endif

static std::string searchDirectory;

#ifdef PBRT_IS_WINDOWS
bool IsAbsolutePath(const std::string &filename) {
    if (filename.size() == 0) return false;
    return (filename[0] == '\\' || filename[0] == '/' ||
            filename.find(':') != string::npos);
}

std::string AbsolutePath(const std::string &filename) {
    char full[_MAX_PATH];
    if (_fullpath(full, filename.c_str(), _MAX_PATH))
        return std::string(full);
    else
        return filename;
}

std::string ResolveFilename(const std::string &filename) {
    if (searchDirectory.size() == 0 || filename.size() == 0)
        return filename;
    else if (IsAbsolutePath(filename))
        return filename;

    char searchDirectoryEnd = searchDirectory[searchDirectory.size() - 1];
    if (searchDirectoryEnd == '\\' || searchDirectoryEnd == '/')
        return searchDirectory + filename;
    else
        return searchDirectory + "\\" + filename;
}

std::string DirectoryContaining(const std::string &filename) {
    // This code isn't tested but I believe it should work. Might need to add
    // some const_casts to make it compile though.
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char ext[_MAX_EXT];

    errno_t err = _splitpath_s(filename.c_str(), drive, _MAX_DRIVE, dir,
                               _MAX_DIR, nullptr, 0, ext, _MAX_EXT);
    if (err == 0) {
        char fullDir[_MAX_PATH];
        err = _makepath_s(fullDir, _MAX_PATH, drive, dir, nullptr, nullptr);
        if (err == 0) return std::string(fullDir);
    }
    return filename;
}

#else

bool IsAbsolutePath(const std::string &filename) {
    return (filename.size() > 0) && filename[0] == '/';
}

std::string AbsolutePath(const std::string &filename) {
    char full[PATH_MAX];
    if (realpath(filename.c_str(), full))
        return std::string(full);
    else
        return filename;
}

std::string ResolveFilename(const std::string &filename) {
    if (searchDirectory.size() == 0 || filename.size() == 0)
        return filename;
    else if (IsAbsolutePath(filename))
        return filename;
    else if (searchDirectory[searchDirectory.size() - 1] == '/')
        return searchDirectory + filename;
    else
        return searchDirectory + "/" + filename;
}

std::string DirectoryContaining(const std::string &filename) {
    char *t = strdup(filename.c_str());
    std::string result = dirname(t);
    free(t);
    return result;
}

#endif

void SetSearchDirectory(const std::string &dirname) {
    searchDirectory = dirname;
}
<commit_msg>Added missing std:: namespace prefix<commit_after>
/*
    pbrt source code is Copyright(c) 1998-2015
                        Matt Pharr, Greg Humphreys, and Wenzel Jakob.

    This file is part of pbrt.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:

    - Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    - Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 */

#include "stdafx.h"

// core/fileutil.cpp*
#include "pbrt.h"
#include "fileutil.h"
#include <cstdlib>
#include <climits>
#ifndef PBRT_IS_WINDOWS
#include <libgen.h>
#endif

static std::string searchDirectory;

#ifdef PBRT_IS_WINDOWS
bool IsAbsolutePath(const std::string &filename) {
    if (filename.size() == 0) return false;
    return (filename[0] == '\\' || filename[0] == '/' ||
            filename.find(':') != std::string::npos);
}

std::string AbsolutePath(const std::string &filename) {
    char full[_MAX_PATH];
    if (_fullpath(full, filename.c_str(), _MAX_PATH))
        return std::string(full);
    else
        return filename;
}

std::string ResolveFilename(const std::string &filename) {
    if (searchDirectory.size() == 0 || filename.size() == 0)
        return filename;
    else if (IsAbsolutePath(filename))
        return filename;

    char searchDirectoryEnd = searchDirectory[searchDirectory.size() - 1];
    if (searchDirectoryEnd == '\\' || searchDirectoryEnd == '/')
        return searchDirectory + filename;
    else
        return searchDirectory + "\\" + filename;
}

std::string DirectoryContaining(const std::string &filename) {
    // This code isn't tested but I believe it should work. Might need to add
    // some const_casts to make it compile though.
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char ext[_MAX_EXT];

    errno_t err = _splitpath_s(filename.c_str(), drive, _MAX_DRIVE, dir,
                               _MAX_DIR, nullptr, 0, ext, _MAX_EXT);
    if (err == 0) {
        char fullDir[_MAX_PATH];
        err = _makepath_s(fullDir, _MAX_PATH, drive, dir, nullptr, nullptr);
        if (err == 0) return std::string(fullDir);
    }
    return filename;
}

#else

bool IsAbsolutePath(const std::string &filename) {
    return (filename.size() > 0) && filename[0] == '/';
}

std::string AbsolutePath(const std::string &filename) {
    char full[PATH_MAX];
    if (realpath(filename.c_str(), full))
        return std::string(full);
    else
        return filename;
}

std::string ResolveFilename(const std::string &filename) {
    if (searchDirectory.size() == 0 || filename.size() == 0)
        return filename;
    else if (IsAbsolutePath(filename))
        return filename;
    else if (searchDirectory[searchDirectory.size() - 1] == '/')
        return searchDirectory + filename;
    else
        return searchDirectory + "/" + filename;
}

std::string DirectoryContaining(const std::string &filename) {
    char *t = strdup(filename.c_str());
    std::string result = dirname(t);
    free(t);
    return result;
}

#endif

void SetSearchDirectory(const std::string &dirname) {
    searchDirectory = dirname;
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// QUESO - a library to support the Quantification of Uncertainty
// for Estimation, Simulation and Optimization
//
// Copyright (C) 2008,2009,2010,2011,2012,2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include <queso/RngGsl.h>
#include <gsl/gsl_randist.h>
#include <mpi.h>

namespace QUESO {

// Default constructor ------------------------------
RngGsl::RngGsl()
  :
  RngBase()
{
  UQ_FATAL_TEST_MACRO(true,
                      m_worldRank,
                      "RngGsl::constructor(), default",
                      "should not be used by user");
}

//! Constructor with seed ---------------------------
RngGsl::RngGsl(int seed, int worldRank)
  :
  RngBase(seed,worldRank),
  m_rng         (NULL)
{
  gsl_rng_default_seed = (unsigned long int) m_seed;
  m_rng = gsl_rng_alloc(gsl_rng_ranlxd2);
  UQ_FATAL_TEST_MACRO((m_rng == NULL),
                      m_worldRank,
                      "RngGsl::constructor()",
                      "null m_rng");

//gsl_rng_set(m_rng, gsl_rng_default_seed);
#if 0
  if (m_worldRank == 0) {
    std::cout << "In RngGsl::constructor():"
              << "\n  m_seed = "                                              << m_seed
              << "\n  internal seed = "                                       << gsl_rng_default_seed
            //<< "\n  first generated sample from uniform distribution = "    << gsl_rng_uniform(m_rng)
            //<< "\n  first generated sample from std normal distribution = " << gsl_ran_gaussian(m_rng,1.)
              << std::endl;
  }
#endif
}

// Destructor ---------------------------------------
RngGsl::~RngGsl()
{
  if (m_rng) gsl_rng_free(m_rng);
}

// Sampling methods ---------------------------------
void
RngGsl::resetSeed(int newSeed)
{
  RngBase::resetSeed(newSeed);
  gsl_rng_free(m_rng);

  gsl_rng_default_seed = (unsigned long int) m_seed;
  m_rng = gsl_rng_alloc(gsl_rng_ranlxd2);
  UQ_FATAL_TEST_MACRO((m_rng == NULL),
                      m_worldRank,
                      "RngGsl::resetSeed()",
                      "null m_rng");
  return;
}

// --------------------------------------------------
double
RngGsl::uniformSample() const
{
  return gsl_rng_uniform(m_rng);
}

// --------------------------------------------------
double
RngGsl::gaussianSample(double stdDev) const
{
  return gsl_ran_gaussian(m_rng,stdDev);
}

// --------------------------------------------------
double
RngGsl::betaSample(double alpha, double beta) const
{
  return gsl_ran_beta(m_rng,alpha,beta);
}

// --------------------------------------------------
double
RngGsl::gammaSample(double a, double b) const
{
  return gsl_ran_gamma(m_rng,a,b);
}

}  // End namespace QUESO
<commit_msg>Added rng method for getting a pointer to the gsl_rng object<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// QUESO - a library to support the Quantification of Uncertainty
// for Estimation, Simulation and Optimization
//
// Copyright (C) 2008,2009,2010,2011,2012,2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include <queso/RngGsl.h>
#include <gsl/gsl_randist.h>
#include <mpi.h>

namespace QUESO {

// Default constructor ------------------------------
RngGsl::RngGsl()
  :
  RngBase()
{
  UQ_FATAL_TEST_MACRO(true,
                      m_worldRank,
                      "RngGsl::constructor(), default",
                      "should not be used by user");
}

//! Constructor with seed ---------------------------
RngGsl::RngGsl(int seed, int worldRank)
  :
  RngBase(seed,worldRank),
  m_rng         (NULL)
{
  gsl_rng_default_seed = (unsigned long int) m_seed;
  m_rng = gsl_rng_alloc(gsl_rng_ranlxd2);
  UQ_FATAL_TEST_MACRO((m_rng == NULL),
                      m_worldRank,
                      "RngGsl::constructor()",
                      "null m_rng");

//gsl_rng_set(m_rng, gsl_rng_default_seed);
#if 0
  if (m_worldRank == 0) {
    std::cout << "In RngGsl::constructor():"
              << "\n  m_seed = "                                              << m_seed
              << "\n  internal seed = "                                       << gsl_rng_default_seed
            //<< "\n  first generated sample from uniform distribution = "    << gsl_rng_uniform(m_rng)
            //<< "\n  first generated sample from std normal distribution = " << gsl_ran_gaussian(m_rng,1.)
              << std::endl;
  }
#endif
}

// Destructor ---------------------------------------
RngGsl::~RngGsl()
{
  if (m_rng) gsl_rng_free(m_rng);
}

// Sampling methods ---------------------------------
void
RngGsl::resetSeed(int newSeed)
{
  RngBase::resetSeed(newSeed);
  gsl_rng_free(m_rng);

  gsl_rng_default_seed = (unsigned long int) m_seed;
  m_rng = gsl_rng_alloc(gsl_rng_ranlxd2);
  UQ_FATAL_TEST_MACRO((m_rng == NULL),
                      m_worldRank,
                      "RngGsl::resetSeed()",
                      "null m_rng");
  return;
}

// --------------------------------------------------
double
RngGsl::uniformSample() const
{
  return gsl_rng_uniform(m_rng);
}

// --------------------------------------------------
double
RngGsl::gaussianSample(double stdDev) const
{
  return gsl_ran_gaussian(m_rng,stdDev);
}

// --------------------------------------------------
double
RngGsl::betaSample(double alpha, double beta) const
{
  return gsl_ran_beta(m_rng,alpha,beta);
}

// --------------------------------------------------
double
RngGsl::gammaSample(double a, double b) const
{
  return gsl_ran_gamma(m_rng,a,b);
}

const gsl_rng*
RngGsl::rng() const
{
  return m_rng;
}

}  // End namespace QUESO
<|endoftext|>


<commit_before>#include "text-diff.h"
#include "libmba-diff.h"
#include "text-slice.h"
#include <vector>
#include <string.h>
#include <ostream>
#include <cassert>

using std::move;
using std::ostream;
using std::vector;

static Point previous_column(Point position) {
  assert(position.column > 0);
  position.column--;
  return position;
}

static int MAX_EDIT_DISTANCE = 1024;

Patch text_diff(const Text &old_text, const Text &new_text) {
  Patch result;
  Text empty;
  Text cr{u"\r"};
  Text lf{u"\n"};

  vector<diff_edit> edit_script;

  if (diff(
    old_text.content.data(),
    old_text.content.size(),
    new_text.content.data(),
    new_text.content.size(),
    MAX_EDIT_DISTANCE,
    &edit_script
  ) == -1) {
    result.splice(Point(), old_text.extent(), new_text.extent(), old_text, new_text);
    return result;
  }

  size_t old_offset = 0;
  size_t new_offset = 0;
  Point old_position;
  Point new_position;

  for (struct diff_edit &edit : edit_script) {
    switch (edit.op) {
      case DIFF_MATCH:
        if (edit.len == 0) continue;

        // If the previous change ended between a CR and an LF, then expand
        // that change downward to include the LF.
        if (new_text.at(new_offset) == '\n' &&
            ((old_offset > 0 && old_text.at(old_offset - 1) == '\r') ||
             (new_offset > 0 && new_text.at(new_offset - 1) == '\r'))) {
          result.splice(new_position, Point(1, 0), Point(1, 0), lf, lf);
          old_position.row++;
          old_position.column = 0;
          new_position.row++;
          new_position.column = 0;
        }

        old_offset += edit.len;
        new_offset += edit.len;
        old_position = old_text.position_for_offset(old_offset, 0, false);
        new_position = new_text.position_for_offset(new_offset, 0, false);

        // If the next change starts between a CR and an LF, then expand that
        // change leftward to include the CR.
        if (new_text.at(new_offset - 1) == '\r' &&
            ((old_offset < old_text.size() && old_text.at(old_offset) == '\n') ||
             (new_offset < new_text.size() && new_text.at(new_offset) == '\n'))) {
          result.splice(previous_column(new_position), Point(0, 1), Point(0, 1), cr, cr);
        }
        break;

      case DIFF_DELETE: {
        uint32_t deletion_end = old_offset + edit.len;
        Text deleted_text{old_text.begin() + old_offset, old_text.begin() + deletion_end};
        old_offset = deletion_end;
        Point next_old_position = old_text.position_for_offset(old_offset, 0, false);
        result.splice(new_position, next_old_position.traversal(old_position), Point(), deleted_text, empty);
        old_position = next_old_position;
        break;
      }

      case DIFF_INSERT: {
        uint32_t insertion_end = new_offset + edit.len;
        Text inserted_text{new_text.begin() + new_offset, new_text.begin() + insertion_end};
        new_offset = insertion_end;
        Point next_new_position = new_text.position_for_offset(new_offset, 0, false);
        result.splice(new_position, Point(), next_new_position.traversal(new_position), empty, inserted_text);
        new_position = next_new_position;
        break;
      }
    }
  }

  return result;
}
<commit_msg>Fix fallback behaviour when maximum edit distance is reached during diff<commit_after>#include "text-diff.h"
#include "libmba-diff.h"
#include "text-slice.h"
#include <vector>
#include <string.h>
#include <ostream>
#include <cassert>

using std::move;
using std::ostream;
using std::vector;

static Point previous_column(Point position) {
  assert(position.column > 0);
  position.column--;
  return position;
}

static int MAX_EDIT_DISTANCE = 4 * 1024;

Patch text_diff(const Text &old_text, const Text &new_text) {
  Patch result;
  Text empty;
  Text cr{u"\r"};
  Text lf{u"\n"};

  vector<diff_edit> edit_script;

  int edit_distance = diff(
    old_text.content.data(),
    old_text.content.size(),
    new_text.content.data(),
    new_text.content.size(),
    MAX_EDIT_DISTANCE,
    &edit_script
  );

  if (edit_distance == -1 || edit_distance >= MAX_EDIT_DISTANCE) {
    result.splice(Point(), old_text.extent(), new_text.extent(), old_text, new_text);
    return result;
  }

  size_t old_offset = 0;
  size_t new_offset = 0;
  Point old_position;
  Point new_position;

  for (struct diff_edit &edit : edit_script) {
    switch (edit.op) {
      case DIFF_MATCH:
        if (edit.len == 0) continue;

        // If the previous change ended between a CR and an LF, then expand
        // that change downward to include the LF.
        if (new_text.at(new_offset) == '\n' &&
            ((old_offset > 0 && old_text.at(old_offset - 1) == '\r') ||
             (new_offset > 0 && new_text.at(new_offset - 1) == '\r'))) {
          result.splice(new_position, Point(1, 0), Point(1, 0), lf, lf);
          old_position.row++;
          old_position.column = 0;
          new_position.row++;
          new_position.column = 0;
        }

        old_offset += edit.len;
        new_offset += edit.len;
        old_position = old_text.position_for_offset(old_offset, 0, false);
        new_position = new_text.position_for_offset(new_offset, 0, false);

        // If the next change starts between a CR and an LF, then expand that
        // change leftward to include the CR.
        if (new_text.at(new_offset - 1) == '\r' &&
            ((old_offset < old_text.size() && old_text.at(old_offset) == '\n') ||
             (new_offset < new_text.size() && new_text.at(new_offset) == '\n'))) {
          result.splice(previous_column(new_position), Point(0, 1), Point(0, 1), cr, cr);
        }
        break;

      case DIFF_DELETE: {
        uint32_t deletion_end = old_offset + edit.len;
        Text deleted_text{old_text.begin() + old_offset, old_text.begin() + deletion_end};
        old_offset = deletion_end;
        Point next_old_position = old_text.position_for_offset(old_offset, 0, false);
        result.splice(new_position, next_old_position.traversal(old_position), Point(), deleted_text, empty);
        old_position = next_old_position;
        break;
      }

      case DIFF_INSERT: {
        uint32_t insertion_end = new_offset + edit.len;
        Text inserted_text{new_text.begin() + new_offset, new_text.begin() + insertion_end};
        new_offset = insertion_end;
        Point next_new_position = new_text.position_for_offset(new_offset, 0, false);
        result.splice(new_position, Point(), next_new_position.traversal(new_position), empty, inserted_text);
        new_position = next_new_position;
        break;
      }
    }
  }

  return result;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * This file is part of "Patrick's Programming Library", Version 7 (PPL7).
 * Web: http://www.pfp.de/ppl/
 *
 * $Author$
 * $Revision$
 * $Date$
 * $Id$
 *
 *******************************************************************************
 * Copyright (c) 2013, Patrick Fedick <patrick@pfp.de>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright notice, this
 *       list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER AND CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

#include "prolog.h"
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_LIBMHASH
#define PROTOTYPES 1
#undef HAVE__BOOL
#include <mutils/mhash.h>
#endif

#ifdef HAVE_OPENSSL
#include <openssl/evp.h>
#endif

#ifdef HAVE_LIBZ
#include <zlib.h>
#endif

#include "ppl7.h"
#include "ppl7-crypto.h"

namespace ppl7 {

bool __OpenSSLDigestAdded = false;

Mutex __OpenSSLGlobalMutex;

void InitOpenSSLDigest()
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	__OpenSSLGlobalMutex.lock();
	if (!__OpenSSLDigestAdded) {
		::OpenSSL_add_all_digests();
		__OpenSSLDigestAdded=true;
	}
	__OpenSSLGlobalMutex.unlock();
#endif
}

Digest::Digest()
{
	bytecount=0;
	m=NULL;
	ret=NULL;
	ctx=NULL;
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!__OpenSSLDigestAdded) {
		InitOpenSSLDigest();
	}
#endif
}

Digest::~Digest()
{
#ifdef HAVE_OPENSSL
	free(ret);
	if (ctx) EVP_MD_CTX_destroy((EVP_MD_CTX*)ctx);
#endif
}

Digest::Digest(const String &name)
{
	bytecount=0;
	m=NULL;
	ret=NULL;
	ctx=NULL;
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!__OpenSSLDigestAdded) {
		InitOpenSSLDigest();
	}
	setAlgorithm(name);
#endif
}

Digest::Digest(Algorithm algorithm)
{
	bytecount=0;
	m=NULL;
	ret=NULL;
	ctx=NULL;
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!__OpenSSLDigestAdded) {
		InitOpenSSLDigest();
	}
	setAlgorithm(algorithm);
#endif
}

void Digest::setAlgorithm(const String &name)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	m=EVP_get_digestbyname((const char*)name);
	if (!m) {
		throw InvalidAlgorithmException("%s",(const char*)name);
	}
	if (!ctx) {
		ctx=EVP_MD_CTX_create();
		if (!ctx) throw OutOfMemoryException();
	} else {
		reset();
	}
	EVP_DigestInit_ex((EVP_MD_CTX*)ctx,(const EVP_MD*)m, NULL);
#endif
}

void Digest::setAlgorithm(Algorithm algorithm)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else

	switch(algorithm) {
#ifndef OPENSSL_NO_MD4
		case Algo_MD4: m=EVP_md4(); break;
#endif
#ifndef OPENSSL_NO_MD5
		case Algo_MD5: m=EVP_md5(); break;
#endif
#ifndef OPENSSL_NO_SHA
		case Algo_SHA1: m=EVP_sha1(); break;
		case Algo_ECDSA: m=EVP_ecdsa(); break;

#endif
#ifndef OPENSSL_NO_SHA256
		case Algo_SHA224: m=EVP_sha224(); break;
		case Algo_SHA256: m=EVP_sha256(); break;
#endif
#ifndef OPENSSL_NO_SHA512
		case Algo_SHA384: m=EVP_sha384(); break;
		case Algo_SHA512: m=EVP_sha512(); break;
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
		case Algo_WHIRLPOOL: m=EVP_whirlpool(); break;
#endif
#endif
#ifndef OPENSSL_NO_RIPEMD
		case Algo_RIPEMD160: m=EVP_ripemd160(); break;
#endif

		default: throw InvalidAlgorithmException();
	}
	if (!m) {
		throw InvalidAlgorithmException("%i",algorithm);
	}
	if (!ctx) {
		ctx=EVP_MD_CTX_create();
		if (!ctx) throw OutOfMemoryException();
	} else {
		reset();
	}
	EVP_DigestInit_ex((EVP_MD_CTX*)ctx,(const EVP_MD*)m, NULL);
#endif
}

void Digest::addData(const void *data, size_t size)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!m) throw NoAlgorithmSpecifiedException();
	EVP_DigestUpdate((EVP_MD_CTX*)ctx,data,size);
	bytecount+=size;
#endif
}

void Digest::addData(const ByteArrayPtr &data)
{
	addData(data.ptr(),data.size());
}

void Digest::addData(const String &data)
{
	addData(data.getPtr(),data.size());
}

void Digest::addData(const WideString &data)
{
	addData(data.getPtr(),data.size());
}

void Digest::addData(FileObject &file)
{
	file.seek(0);
	size_t bsize=1024*1024*1;		// We allocate 1 MB maximum
	ppluint64 fsize=file.size();
	if (fsize<bsize) bsize=fsize;	// or filesize if file is < 1 MB
	void *buffer=malloc(bsize);
	if (!buffer) {
		throw OutOfMemoryException();
	}
	ppluint64 rest=fsize;
	try {
		while(rest) {
			size_t bytes=rest;
			if (bytes>bsize) bytes=bsize;
			if (!file.read(buffer,bytes)) {
				throw ReadException();
			}
			addData(buffer,bytes);
			rest-=bytes;
		}
	} catch (...) {
		free(buffer);
		throw;
	}
	free(buffer);

}

void Digest::addFile(const String &filename)
{
	File ff;
	ff.open(filename,File::READ);
	addData(ff);
}

ppluint64 Digest::bytesHashed() const
{
	return bytecount;
}

void Digest::saveDigest(ByteArray &result)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	result=getDigest();
#endif
}

void Digest::saveDigest(String &result)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	ByteArray ba=getDigest();
	result=ba.toHex();
#endif
}

void Digest::saveDigest(WideString &result)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	ByteArray ba=getDigest();
	result=ba.toHex();
#endif
}

ByteArray Digest::getDigest()
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	unsigned int len;
	if (!ret) {
		ret=(unsigned char*)malloc(EVP_MAX_MD_SIZE);
		if (!ret) throw OutOfMemoryException();
	}
	EVP_DigestFinal((EVP_MD_CTX*)ctx,ret,&len);
	EVP_MD_CTX_cleanup((EVP_MD_CTX*)ctx);
	EVP_DigestInit_ex((EVP_MD_CTX*)ctx,(const EVP_MD*)m, NULL);
	bytecount=0;
	return ByteArray(ret,len);
#endif
}

void Digest::reset()
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!m) throw NoAlgorithmSpecifiedException();
	if (!ctx) throw NoAlgorithmSpecifiedException();
	EVP_MD_CTX_cleanup((EVP_MD_CTX*)ctx);
	EVP_DigestInit((EVP_MD_CTX*)ctx,(const EVP_MD*)m);
	bytecount=0;
#endif
}

ByteArray Digest::hash(const ByteArrayPtr &data, Algorithm algorithm)
{
	Digest dig(algorithm);
	dig.addData(data);
	return dig.getDigest();
}

ByteArray Digest::hash(const ByteArrayPtr &data, const String &algorithmName)
{
	Digest dig(algorithmName);
	dig.addData(data);
	return dig.getDigest();
}

ByteArray Digest::md4(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_MD4);
}

ByteArray Digest::md5(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_MD5);
}

ByteArray Digest::sha1(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA1);
}

ByteArray Digest::sha224(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA224);
}

ByteArray Digest::sha256(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA256);
}

ByteArray Digest::sha384(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA384);
}

ByteArray Digest::sha512(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA512);
}

ByteArray Digest::ecdsa(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_ECDSA);
}

ppluint32 Digest::crc32(const ByteArrayPtr &data)
{
#ifdef HAVE_LIBZ
	uLong crc=::crc32(0L,Z_NULL,0);
	return ::crc32(crc,(const Bytef*)data.ptr(),(uInt)data.size());
#endif
	return Crc32(data.ptr(),data.size());
}

ppluint32 Digest::adler32(const ByteArrayPtr &data)
{
     const unsigned char *buffer = (const unsigned char *)data.ptr();
     size_t buflength=data.size();
     ppluint32 s1 = 1;
     ppluint32 s2 = 0;

     for (size_t n = 0; n < buflength; n++) {
        s1 = (s1 + buffer[n]) % 65521;
        s2 = (s2 + s1) % 65521;
     }
     return (s2 << 16) | s1;
  }
}
<commit_msg>Digest: fixed compatibility with OpenSSL >= 1.1.x<commit_after>/*******************************************************************************
 * This file is part of "Patrick's Programming Library", Version 7 (PPL7).
 * Web: http://www.pfp.de/ppl/
 *
 * $Author$
 * $Revision$
 * $Date$
 * $Id$
 *
 *******************************************************************************
 * Copyright (c) 2013, Patrick Fedick <patrick@pfp.de>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright notice, this
 *       list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER AND CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

#include "prolog.h"
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_LIBMHASH
#define PROTOTYPES 1
#undef HAVE__BOOL
#include <mutils/mhash.h>
#endif

#ifdef HAVE_OPENSSL
#include <openssl/evp.h>
#endif

#ifdef HAVE_LIBZ
#include <zlib.h>
#endif

#include "ppl7.h"
#include "ppl7-crypto.h"

namespace ppl7 {

bool __OpenSSLDigestAdded = false;

Mutex __OpenSSLGlobalMutex;

void InitOpenSSLDigest()
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	__OpenSSLGlobalMutex.lock();
	if (!__OpenSSLDigestAdded) {
		::OpenSSL_add_all_digests();
		__OpenSSLDigestAdded=true;
	}
	__OpenSSLGlobalMutex.unlock();
#endif
}

Digest::Digest()
{
	bytecount=0;
	m=NULL;
	ret=NULL;
	ctx=NULL;
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!__OpenSSLDigestAdded) {
		InitOpenSSLDigest();
	}
#endif
}

Digest::~Digest()
{
#ifdef HAVE_OPENSSL
	free(ret);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	if (ctx) EVP_MD_CTX_free((EVP_MD_CTX*)ctx);
#else
	if (ctx) EVP_MD_CTX_destroy((EVP_MD_CTX*)ctx);
#endif

#endif
}

Digest::Digest(const String &name)
{
	bytecount=0;
	m=NULL;
	ret=NULL;
	ctx=NULL;
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!__OpenSSLDigestAdded) {
		InitOpenSSLDigest();
	}
	setAlgorithm(name);
#endif
}

Digest::Digest(Algorithm algorithm)
{
	bytecount=0;
	m=NULL;
	ret=NULL;
	ctx=NULL;
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!__OpenSSLDigestAdded) {
		InitOpenSSLDigest();
	}
	setAlgorithm(algorithm);
#endif
}

void Digest::setAlgorithm(const String &name)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	m=EVP_get_digestbyname((const char*)name);
	if (!m) {
		throw InvalidAlgorithmException("%s",(const char*)name);
	}
	if (!ctx) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		ctx=EVP_MD_CTX_new();
#else
		ctx=EVP_MD_CTX_create();
#endif
		if (!ctx) throw OutOfMemoryException();
	} else {
		reset();
	}
	EVP_DigestInit_ex((EVP_MD_CTX*)ctx,(const EVP_MD*)m, NULL);
#endif
}

void Digest::setAlgorithm(Algorithm algorithm)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else

	switch(algorithm) {
#ifndef OPENSSL_NO_MD4
		case Algo_MD4: m=EVP_md4(); break;
#endif
#ifndef OPENSSL_NO_MD5
		case Algo_MD5: m=EVP_md5(); break;
#endif
#ifndef OPENSSL_NO_SHA
		case Algo_SHA1: m=EVP_sha1(); break;
		case Algo_ECDSA:
#if OPENSSL_VERSION_NUMBER < 0x10100000L
			m=EVP_ecdsa(); break;
#endif
#endif
#ifndef OPENSSL_NO_SHA256
		case Algo_SHA224: m=EVP_sha224(); break;
		case Algo_SHA256: m=EVP_sha256(); break;
#endif
#ifndef OPENSSL_NO_SHA512
		case Algo_SHA384: m=EVP_sha384(); break;
		case Algo_SHA512: m=EVP_sha512(); break;
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
		case Algo_WHIRLPOOL: m=EVP_whirlpool(); break;
#endif
#endif
#ifndef OPENSSL_NO_RIPEMD
		case Algo_RIPEMD160: m=EVP_ripemd160(); break;
#endif

		default: throw InvalidAlgorithmException();
	}
	if (!m) {
		throw InvalidAlgorithmException("%i",algorithm);
	}
	if (!ctx) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		ctx=EVP_MD_CTX_new();
#else
		ctx=EVP_MD_CTX_create();
#endif
		if (!ctx) throw OutOfMemoryException();
	} else {
		reset();
	}
	EVP_DigestInit_ex((EVP_MD_CTX*)ctx,(const EVP_MD*)m, NULL);
#endif
}

void Digest::addData(const void *data, size_t size)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!m) throw NoAlgorithmSpecifiedException();
	EVP_DigestUpdate((EVP_MD_CTX*)ctx,data,size);
	bytecount+=size;
#endif
}

void Digest::addData(const ByteArrayPtr &data)
{
	addData(data.ptr(),data.size());
}

void Digest::addData(const String &data)
{
	addData(data.getPtr(),data.size());
}

void Digest::addData(const WideString &data)
{
	addData(data.getPtr(),data.size());
}

void Digest::addData(FileObject &file)
{
	file.seek(0);
	size_t bsize=1024*1024*1;		// We allocate 1 MB maximum
	ppluint64 fsize=file.size();
	if (fsize<bsize) bsize=fsize;	// or filesize if file is < 1 MB
	void *buffer=malloc(bsize);
	if (!buffer) {
		throw OutOfMemoryException();
	}
	ppluint64 rest=fsize;
	try {
		while(rest) {
			size_t bytes=rest;
			if (bytes>bsize) bytes=bsize;
			if (!file.read(buffer,bytes)) {
				throw ReadException();
			}
			addData(buffer,bytes);
			rest-=bytes;
		}
	} catch (...) {
		free(buffer);
		throw;
	}
	free(buffer);

}

void Digest::addFile(const String &filename)
{
	File ff;
	ff.open(filename,File::READ);
	addData(ff);
}

ppluint64 Digest::bytesHashed() const
{
	return bytecount;
}

void Digest::saveDigest(ByteArray &result)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	result=getDigest();
#endif
}

void Digest::saveDigest(String &result)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	ByteArray ba=getDigest();
	result=ba.toHex();
#endif
}

void Digest::saveDigest(WideString &result)
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	ByteArray ba=getDigest();
	result=ba.toHex();
#endif
}

ByteArray Digest::getDigest()
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	unsigned int len;
	if (!ret) {
		ret=(unsigned char*)malloc(EVP_MAX_MD_SIZE);
		if (!ret) throw OutOfMemoryException();
	}
	EVP_DigestFinal((EVP_MD_CTX*)ctx,ret,&len);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	EVP_MD_CTX_reset((EVP_MD_CTX*)ctx);
#else
	EVP_MD_CTX_cleanup((EVP_MD_CTX*)ctx);
#endif
	EVP_DigestInit_ex((EVP_MD_CTX*)ctx,(const EVP_MD*)m, NULL);
	bytecount=0;
	return ByteArray(ret,len);
#endif
}

void Digest::reset()
{
#ifndef HAVE_OPENSSL
	throw UnsupportedFeatureException("OpenSSL");
#else
	if (!m) throw NoAlgorithmSpecifiedException();
	if (!ctx) throw NoAlgorithmSpecifiedException();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	EVP_MD_CTX_reset((EVP_MD_CTX*)ctx);
#else
	EVP_MD_CTX_cleanup((EVP_MD_CTX*)ctx);
#endif
	EVP_DigestInit((EVP_MD_CTX*)ctx,(const EVP_MD*)m);
	bytecount=0;
#endif
}

ByteArray Digest::hash(const ByteArrayPtr &data, Algorithm algorithm)
{
	Digest dig(algorithm);
	dig.addData(data);
	return dig.getDigest();
}

ByteArray Digest::hash(const ByteArrayPtr &data, const String &algorithmName)
{
	Digest dig(algorithmName);
	dig.addData(data);
	return dig.getDigest();
}

ByteArray Digest::md4(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_MD4);
}

ByteArray Digest::md5(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_MD5);
}

ByteArray Digest::sha1(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA1);
}

ByteArray Digest::sha224(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA224);
}

ByteArray Digest::sha256(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA256);
}

ByteArray Digest::sha384(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA384);
}

ByteArray Digest::sha512(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_SHA512);
}

ByteArray Digest::ecdsa(const ByteArrayPtr &data)
{
	return Digest::hash(data,Algo_ECDSA);
}

ppluint32 Digest::crc32(const ByteArrayPtr &data)
{
#ifdef HAVE_LIBZ
	uLong crc=::crc32(0L,Z_NULL,0);
	return ::crc32(crc,(const Bytef*)data.ptr(),(uInt)data.size());
#endif
	return Crc32(data.ptr(),data.size());
}

ppluint32 Digest::adler32(const ByteArrayPtr &data)
{
     const unsigned char *buffer = (const unsigned char *)data.ptr();
     size_t buflength=data.size();
     ppluint32 s1 = 1;
     ppluint32 s2 = 0;

     for (size_t n = 0; n < buflength; n++) {
        s1 = (s1 + buffer[n]) % 65521;
        s2 = (s2 + s1) % 65521;
     }
     return (s2 << 16) | s1;
  }
}
<|endoftext|>


<commit_before>class Solution {
public:
    int hIndex(vector<int>& citations) {

        sort(citations.begin(), citations.end());

        int h = citations.size();

        int i = 0;
        for(int i = 0;i < citations.size();i++)
        {
            if(citations[i] >= h)
                break;
            h--;
        }

        return h;
    }
};<commit_msg>274. H-Index<commit_after>class Solution {
public:
    int hIndex(vector<int>& citations) {
        sort(citations.begin(), citations.end());
        int h = citations.size();
        for (int i = 0;i < citations.size();i++) {
            if (citations[i] >= h)
                break;
            h--;
        }
        return h;
    }
};
<|endoftext|>


<commit_before>// Vsevolod Ivanov

#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <chrono>
#include <restinio/all.hpp>
#include <http_parser.h>

template <typename LAMBDA>
void do_with_socket(LAMBDA && lambda, const std::string & addr = "127.0.0.1",
                                      std::uint16_t port = 8080)
{
    restinio::asio_ns::io_context io_context;
    restinio::asio_ns::ip::tcp::socket socket{io_context};

    restinio::asio_ns::ip::tcp::resolver resolver{io_context};
    restinio::asio_ns::ip::tcp::resolver::query
        query{restinio::asio_ns::ip::tcp::v4(), addr, std::to_string(port)};
    restinio::asio_ns::ip::tcp::resolver::iterator iterator = resolver.resolve(query);

    restinio::asio_ns::connect(socket, iterator);

    lambda(socket, io_context);
    socket.close();
}

inline void do_request(const std::string & request,
                       const std::string & addr, std::uint16_t port,
                       http_parser &parser, http_parser_settings &settings)
{
    std::string result;
    do_with_socket([&](auto & socket, auto & io_context){
        // write request
        restinio::asio_ns::streambuf b;
        std::ostream req_stream(&b);
        req_stream << request;
        restinio::asio_ns::write(socket, b);
        // read response
        std::array<char, 1024> m_read_buffer;
        socket.async_read_some(restinio::asio_ns::buffer(m_read_buffer), [&](auto ec, size_t length){
            std::vector<char> data;
            data.insert(std::end(data), std::begin(m_read_buffer), std::begin(m_read_buffer) + length);

            auto nparsed = http_parser_execute(&parser, &settings, data.data(), data.size());
            if (HPE_OK != parser.http_errno && HPE_PAUSED != parser.http_errno){
                auto err = HTTP_PARSER_ERRNO(&parser);
                std::cerr << "Couldn't parse the response: " << http_errno_name(err) << std::endl;
            }
        });
        io_context.run();
    }, addr, port);
}

std::string create_http_request(const restinio::http_request_header_t header,
                                const restinio::http_header_fields_t header_fields,
                                const restinio::http_connection_header_t connection)
{
    std::stringstream request;

    request << restinio::method_to_string(header.method()) << " " <<
               header.request_target() << " " <<
               "HTTP/" << header.http_major() << "." << header.http_minor() << "\r\n";

    for (auto header_field: header_fields)
        request << header_field.name() << ": " << header_field.value() << "\r\n";

    std::string conn_str;
    switch (connection)
    {
        case restinio::http_connection_header_t::keep_alive:
            conn_str = "keep-alive";
            break;
        case restinio::http_connection_header_t::close:
            conn_str = "close";
            break;
        case restinio::http_connection_header_t::upgrade:
            throw std::invalid_argument("upgrade");
            break;
    }
    request << "Connection: " << conn_str << "\r\n\r\n";

    return request.str();
}

int main(const int argc, char* argv[])
{
    if (argc < 4){
        std::cerr << "Insufficient arguments! Needs <addr> <port> <target>" << std::endl;
        return 1;
    }
    const std::string addr = argv[1];
    const in_port_t port = atoi(argv[2]);
    const std::string target = argv[3];

    restinio::http_request_header_t header;
    header.request_target(target);
    header.method(restinio::http_method_t::http_get);

    restinio::http_header_fields_t header_fields;
    header_fields.append_field(restinio::http_field_t::host,
                               (addr + ":" + std::to_string(port)).c_str());
    header_fields.append_field(restinio::http_field_t::user_agent, "RESTinio client");
    header_fields.append_field(restinio::http_field_t::accept, "*/*");

    auto connection = restinio::http_connection_header_t::keep_alive;

    // build request
    auto request = create_http_request(header, header_fields, connection);
    printf(request.c_str());

    // setup http_parser & callbacks
    http_parser_settings settings; // = restinio::impl::create_parser_settings();
    http_parser_settings_init(&settings);
    settings.on_url = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on url cb\n");
        return 0;
    };
    settings.on_header_field = [](http_parser * parser, const char * at, size_t length) -> int {
        printf("on header field cb\n");
        return 0;
    };
    settings.on_header_value = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on header value cb\n");
        return 0;
    };
    settings.on_headers_complete = []( http_parser * parser ) -> int {
        printf("on headers complete cb\n");
        return 0;
    };
    settings.on_body = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on body cb\n");
        return 0;
    };
    settings.on_message_complete = [](http_parser * parser) -> int {
        printf("on message complete cb\n");
        return 0;
    };
    settings.on_status = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on status cb code=%i message=%s\n", parser->status_code, std::string(at, length).c_str());
        return 0;
    };
    http_parser *m_parser = new http_parser();
    http_parser_init(m_parser, HTTP_RESPONSE);

    // send request and give parser for response processing
    do_request(request, addr, port, *m_parser, settings);

    return 0;
}
<commit_msg>cpp/restinio: add client post feature<commit_after>// Vsevolod Ivanov

#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <chrono>
#include <restinio/all.hpp>
#include <http_parser.h>

template <typename LAMBDA>
void do_with_socket(LAMBDA && lambda, const std::string & addr = "127.0.0.1",
                                      std::uint16_t port = 8080)
{
    restinio::asio_ns::io_context io_context;
    restinio::asio_ns::ip::tcp::socket socket{io_context};

    restinio::asio_ns::ip::tcp::resolver resolver{io_context};
    restinio::asio_ns::ip::tcp::resolver::query
        query{restinio::asio_ns::ip::tcp::v4(), addr, std::to_string(port)};
    restinio::asio_ns::ip::tcp::resolver::iterator iterator = resolver.resolve(query);

    restinio::asio_ns::connect(socket, iterator);

    lambda(socket, io_context);
    socket.close();
}

inline void do_request(const std::string & request,
                       const std::string & addr, std::uint16_t port,
                       http_parser &parser, http_parser_settings &settings)
{
    std::string result;
    do_with_socket([&](auto & socket, auto & io_context){
        // write request
        restinio::asio_ns::streambuf b;
        std::ostream req_stream(&b);
        req_stream << request;
        restinio::asio_ns::write(socket, b);
        // read response
        std::array<char, 1024> m_read_buffer;
        socket.async_read_some(restinio::asio_ns::buffer(m_read_buffer), [&](auto ec, size_t length){
            std::vector<char> data;
            data.insert(std::end(data), std::begin(m_read_buffer), std::begin(m_read_buffer) + length);

            auto nparsed = http_parser_execute(&parser, &settings, data.data(), data.size());
            if (HPE_OK != parser.http_errno && HPE_PAUSED != parser.http_errno){
                auto err = HTTP_PARSER_ERRNO(&parser);
                std::cerr << "Couldn't parse the response: " << http_errno_name(err) << std::endl;
            }
        });
        io_context.run();
    }, addr, port);
}

std::string create_http_request(const restinio::http_request_header_t header,
                                const restinio::http_header_fields_t header_fields,
                                const restinio::http_connection_header_t connection,
                                const std::string body)
{
    std::stringstream request;

    request << restinio::method_to_string(header.method()) << " " <<
               header.request_target() << " " <<
               "HTTP/" << header.http_major() << "." << header.http_minor() << "\r\n";
    for (auto header_field: header_fields)
        request << header_field.name() << ": " << header_field.value() << "\r\n";

    std::string conn_str;
    switch (connection)
    {
        case restinio::http_connection_header_t::keep_alive:
            conn_str = "keep-alive";
            break;
        case restinio::http_connection_header_t::close:
            conn_str = "close";
            break;
        case restinio::http_connection_header_t::upgrade:
            throw std::invalid_argument("upgrade");
            break;
    }
    request << "Connection: " << conn_str << "\r\n";
    if (!body.empty()){
        request << "Content-Length: " << body.size() << "\r\n\r\n";
        request << body;
    }
    request << "\r\n\r\n";

    return request.str();
}

int main(const int argc, char* argv[])
{
    if (argc < 5){
        std::cerr << "Insufficient arguments! Needs <method> <addr> <port> <target> <body_if_any>" << std::endl;
        return 1;
    }
    const std::string method_str = argv[1];
    const std::string addr = argv[2];
    const in_port_t port = atoi(argv[3]);
    const std::string target = argv[4];
    const std::string body = argv[5] ? argv[5] : "";

    restinio::http_request_header_t header;
    header.request_target(target);
    restinio::http_method_t method;
    if (method_str == "get")
        method = restinio::http_method_t::http_get;
    else if (method_str == "post")
        method = restinio::http_method_t::http_post;
    else
        throw std::invalid_argument(method_str);
    header.method(method);

    restinio::http_header_fields_t header_fields;
    header_fields.append_field(restinio::http_field_t::host,
                               (addr + ":" + std::to_string(port)).c_str());
    header_fields.append_field(restinio::http_field_t::user_agent, "RESTinio client");
    header_fields.append_field(restinio::http_field_t::accept, "*/*");

    // build request
    auto connection = restinio::http_connection_header_t::keep_alive;
    auto request = create_http_request(header, header_fields, connection, body);
    printf(request.c_str());
    return 1;

    // setup http_parser & callbacks
    http_parser_settings settings; // = restinio::impl::create_parser_settings();
    http_parser_settings_init(&settings);
    settings.on_url = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on url cb\n");
        return 0;
    };
    settings.on_header_field = [](http_parser * parser, const char * at, size_t length) -> int {
        printf("on header field cb\n");
        return 0;
    };
    settings.on_header_value = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on header value cb\n");
        return 0;
    };
    settings.on_headers_complete = []( http_parser * parser ) -> int {
        printf("on headers complete cb\n");
        return 0;
    };
    settings.on_body = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on body cb\n");
        return 0;
    };
    settings.on_message_complete = [](http_parser * parser) -> int {
        printf("on message complete cb\n");
        return 0;
    };
    settings.on_status = []( http_parser * parser, const char * at, size_t length ) -> int {
        printf("on status cb code=%i message=%s\n", parser->status_code, std::string(at, length).c_str());
        return 0;
    };
    http_parser *m_parser = new http_parser();
    http_parser_init(m_parser, HTTP_RESPONSE);

    // send request and give parser for response processing
    do_request(request, addr, port, *m_parser, settings);

    return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 * Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>                           *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation; either version 2.1 of the License,               *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPENCL_PROGRAM_HPP
#define CPPA_OPENCL_PROGRAM_HPP

#include <memory>

#include "cppa/opencl/global.hpp"
#include "cppa/opencl/smart_ptr.hpp"

namespace cppa { namespace opencl {

template<typename Signature>
class actor_facade;

class program {

    template<typename Signature>
    friend class actor_facade;

 public:

    static program create(const char* kernel_source);

 private:

    //program();
    program(context_ptr context, program_ptr program);

    context_ptr m_context;
    program_ptr m_program;

};

} } // namespace cppa::opencl

#endif // CPPA_OPENCL_PROGRAM_HPP
<commit_msg>added doxygen comments to cppa::opencl::program<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 * Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>                           *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation; either version 2.1 of the License,               *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPENCL_PROGRAM_HPP
#define CPPA_OPENCL_PROGRAM_HPP

#include <memory>

#include "cppa/opencl/global.hpp"
#include "cppa/opencl/smart_ptr.hpp"

namespace cppa { namespace opencl {

template<typename Signature>
class actor_facade;

/**
 * @brief A wrapper for OpenCL's cl_program.
 */
class program {

    template<typename Signature>
    friend class actor_facade;

 public:

    /**
     * @brief Factory method, that creates a cppa::opencl::program
     *        from a given @p kernel_source.
     * @returns A program object.
     */
    static program create(const char* kernel_source);

 private:

    program(context_ptr context, program_ptr program);

    context_ptr m_context;
    program_ptr m_program;

};

} } // namespace cppa::opencl

#endif // CPPA_OPENCL_PROGRAM_HPP
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <cstring>
#include <stdexcept>

#include "../../Headers/genotype/gene.hpp"
#include "../../Headers/Utility/jsmn.h"
#include "../../Headers/type.hpp"
#include "../../Headers/training/parameters.hpp"
#include "../../Headers/utility/random.hpp"

using namespace Hippocrates::Genotype;

Gene::Gene() {
	SetRandomWeight();
}

Gene::Gene(std::string json) {
	jsmn_parser parser;
	jsmn_init(&parser);
	jsmntok_t tokens[256];

	std::size_t token_count = jsmn_parse(&parser, json.c_str(), json.length(), tokens, 256);

	for (std::size_t i = 0; i < token_count - 1; i++) {
		auto key = json.substr(tokens[i].start, tokens[i].end - tokens[i].start);
		auto value = json.substr(tokens[i + 1].start, tokens[i + 1].end - tokens[i + 1].start);

		if (key == "historicalMarking") {
			HIPPOCRATES_SSCANF(value.c_str(), "%zu", &historicalMarking);
		} else
		if (key == "to") {
			HIPPOCRATES_SSCANF(value.c_str(), "%zu", &to);
		} else
		if (key == "weight") {
			weight = stof(value);
		} else
		if (key == "isEnabled") {
			isEnabled = value == "true";
		} else
		if (key == "isRecursive") {
			isRecursive = value == "true";
		}
	}
}

auto Gene::operator==(const Gene & other) const -> bool
{
	if (historicalMarking == other.historicalMarking
	 || (from == other.from
	    && to == other.to)) {
		if (isRecursive != other.isRecursive)
			throw std::logic_error("Two identical genes have different recursive flags");
		return true;
	}
	return false;
}

auto Gene::SetRandomWeight() -> void {
	weight = Utility::Random::Number(Training::GetParameters().ranges.minWeight, Training::GetParameters().ranges.maxWeight);
}

auto Gene::GetJSON() const -> std::string {
	auto BoolToString = [](bool b) {
		return b ? "true" : "false";
	};
	std::string s("{\"historicalMarking\":");
	s += std::to_string(historicalMarking);
	s += ",\"from\":";
	s += std::to_string(from);
	s += ",\"to\":";
	s += std::to_string(to);
	s += ",\"weight\":";
	s += std::to_string(weight);
	s += ",\"isEnabled\":";
	s += BoolToString(isEnabled);
	s += ",\"isRecursive\":";
	s += BoolToString(isRecursive);
	s += "}";
	return s;
}

<commit_msg>Fix case<commit_after>#include <stdlib.h>
#include <cstring>
#include <stdexcept>

#include "../../Headers/genotype/gene.hpp"
#include "../../Headers/utility/jsmn.h"
#include "../../Headers/type.hpp"
#include "../../Headers/training/parameters.hpp"
#include "../../Headers/utility/random.hpp"

using namespace Hippocrates::Genotype;

Gene::Gene() {
	SetRandomWeight();
}

Gene::Gene(std::string json) {
	jsmn_parser parser;
	jsmn_init(&parser);
	jsmntok_t tokens[256];

	std::size_t token_count = jsmn_parse(&parser, json.c_str(), json.length(), tokens, 256);

	for (std::size_t i = 0; i < token_count - 1; i++) {
		auto key = json.substr(tokens[i].start, tokens[i].end - tokens[i].start);
		auto value = json.substr(tokens[i + 1].start, tokens[i + 1].end - tokens[i + 1].start);

		if (key == "historicalMarking") {
			HIPPOCRATES_SSCANF(value.c_str(), "%zu", &historicalMarking);
		} else
		if (key == "to") {
			HIPPOCRATES_SSCANF(value.c_str(), "%zu", &to);
		} else
		if (key == "weight") {
			weight = stof(value);
		} else
		if (key == "isEnabled") {
			isEnabled = value == "true";
		} else
		if (key == "isRecursive") {
			isRecursive = value == "true";
		}
	}
}

auto Gene::operator==(const Gene & other) const -> bool
{
	if (historicalMarking == other.historicalMarking
	 || (from == other.from
	    && to == other.to)) {
		if (isRecursive != other.isRecursive)
			throw std::logic_error("Two identical genes have different recursive flags");
		return true;
	}
	return false;
}

auto Gene::SetRandomWeight() -> void {
	weight = Utility::Random::Number(Training::GetParameters().ranges.minWeight, Training::GetParameters().ranges.maxWeight);
}

auto Gene::GetJSON() const -> std::string {
	auto BoolToString = [](bool b) {
		return b ? "true" : "false";
	};
	std::string s("{\"historicalMarking\":");
	s += std::to_string(historicalMarking);
	s += ",\"from\":";
	s += std::to_string(from);
	s += ",\"to\":";
	s += std::to_string(to);
	s += ",\"weight\":";
	s += std::to_string(weight);
	s += ",\"isEnabled\":";
	s += BoolToString(isEnabled);
	s += ",\"isRecursive\":";
	s += BoolToString(isRecursive);
	s += "}";
	return s;
}

<|endoftext|>