<commit_before>#include "reconstruction/base.h"
#include <boost/filesystem.hpp>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl_ros/transforms.h>

namespace fs=boost::filesystem;

/** \brief Class constructor. Reads node parameters and initialize some properties.
  * @return
  * \param nh public node handler
  * \param nhp private node handler
  */
reconstruction::ReconstructionBase::ReconstructionBase(
  ros::NodeHandle nh, ros::NodeHandle nhp) : nh_(nh), nh_private_(nhp)
{
  // Read the node parameters
  readParameters();

  // Initialize the stereo slam
  init();
}

/** \brief Timer callback to launch the process
  */
void reconstruction::ReconstructionBase::timerCallback(const ros::WallTimerEvent&)
{
  // Avoid callback overwrite. ROS Timer documentation does no indicate what
  // happens when a timer callback is called before it finish.
  m_.lock ();
  reconstruction::ReconstructionBase::process();
  m_.unlock ();
}

/** \brief Build the 3D environment
  */
void reconstruction::ReconstructionBase::process()
{
  // Read the graph poses
  vector< pair<string, tf::Transform> > cloud_poses;
  if (!readPoses(cloud_poses)) return;

  // Init the kdtree
  const float radius = 0.005;
  pcl::KdTreeFLANN<PointXY> kdtree;

  // Init the voxel grid filter
  pcl::VoxelGrid<PointRGB> grid;
  PointCloud::Ptr cloud_downsampled_ptr(new PointCloud);
  grid.setLeafSize(0.008, 0.008, 0.008);
  grid.setDownsampleAllData(true);

  // Load, convert and accumulate every pointcloud
  PointCloud acc;
  for (uint i=0; i<cloud_poses.size(); i++)
  {
    string file_idx = cloud_poses[i].first;
    ROS_INFO_STREAM("[StereoSlam:] Processing cloud " << file_idx.substr(0,file_idx.length()-4) << "/" << cloud_poses.size()-1);

    // Read the current pointcloud.
    string cloud_filename = params_.clouds_dir + cloud_poses[i].first;
    PointCloud::Ptr cloud(new PointCloud);
    if (pcl::io::loadPCDFile<PointRGB> (cloud_filename, *cloud) == -1)
    {
      ROS_WARN_STREAM("[StereoSlam:] Couldn't read the file: " << cloud_poses[i].first);
      continue;
    }

    // Remove isolated points
    pcl::StatisticalOutlierRemoval<PointRGB> sor;
    sor.setInputCloud(cloud);
    sor.setMeanK(50);
    sor.setStddevMulThresh(1.0);
    sor.filter(*cloud);

    // Transform pointcloud
    pcl_ros::transformPointCloud(*cloud, *cloud, cloud_poses[i].second);

    // First iteration
    if (acc.points.size() == 0)
    {
      acc = *cloud;
      continue;
    }

    // Convert the accumulated cloud to PointXY
    // FIXME: this implies two copies of the accumulated cloud :(
    pcl::PointCloud<PointXY> acc_xy;
    copyPointCloud(acc, acc_xy);

    vector<int> point_idx;
    vector<float> point_distance;
    kdtree.setInputCloud(acc_xy.makeShared());

    int total = 0;
    int added = 0;
    for (uint i=0; i<cloud->points.size(); i++)
    {
      PointXY cur_point;
      cur_point.x = cloud->points[i].x;
      cur_point.y = cloud->points[i].y;
      if (!isfinite(cur_point.x) || !isfinite(cur_point.y))
        continue;

      total++;
      if (kdtree.radiusSearch(cur_point, radius, point_idx, point_distance) <= 0)
      {
        added++;
        acc.push_back(cloud->points[i]);
      }
    }

    ROS_INFO_STREAM("[StereoSlam:] Original size: " << total << ". Finally added: " << added);

    // Filter the accumulated cloud
    grid.setInputCloud(acc.makeShared());
    grid.filter(*cloud_downsampled_ptr);
    acc = *cloud_downsampled_ptr;
  }

  // Save accumulated cloud
  ROS_INFO("[StereoSlam:] Saving pointcloud...");
  pcl::io::savePCDFile(params_.work_dir + "reconstruction.pcd", acc);
  ROS_INFO("[StereoSlam:] Accumulated cloud saved.");
}

/** \brief Reads the reconstruction node parameters
  */
void reconstruction::ReconstructionBase::readParameters()
{
  Params params;

  // Operational directories
  string work_dir;
  nh_private_.param("work_dir", work_dir, string(""));
  if (work_dir[work_dir.length()-1] != '/')
    work_dir += "/";
  params.work_dir = work_dir;
  params.clouds_dir = work_dir + "clouds/";
  params.graph_file = work_dir + "graph_vertices.txt";

  setParams(params);
}

/** \brief Reads the poses file and return the vector with the cloud names and the transformations
  * @return true if poses read correctly, false otherwise
  * \param the vector with the cloud filenames and the transformations
  */
bool reconstruction::ReconstructionBase::readPoses(vector< pair<string, tf::Transform> > &cloud_poses)
{
  // Init
  cloud_poses.clear();

  // Wait until poses file is unblocked
  while(fs::exists(params_.work_dir + ".graph.block"));

  // Get the pointcloud poses file
  ifstream poses_file(params_.graph_file.c_str());
  string line;
  while (getline(poses_file, line))
  {
    int i = 0;
    string cloud_name, value;
    double x, y, z, qx, qy, qz, qw;
    istringstream ss(line);
    while(getline(ss, value, ','))
    {
      if (i == 1)
        cloud_name = value + ".pcd";
      else if (i == 5)
        x = boost::lexical_cast<double>(value);
      else if (i == 6)
        y = boost::lexical_cast<double>(value);
      else if (i == 7)
        z = boost::lexical_cast<double>(value);
      else if (i == 8)
        qx = boost::lexical_cast<double>(value);
      else if (i == 9)
        qy = boost::lexical_cast<double>(value);
      else if (i == 10)
        qz = boost::lexical_cast<double>(value);
      else if (i == 11)
        qw = boost::lexical_cast<double>(value);
      i++;
    }
    // Build the pair and save
    tf::Vector3 t(x, y, z);
    tf::Quaternion q(qx, qy, qz, qw);
    tf::Transform transf(q, t);
    cloud_poses.push_back(make_pair(cloud_name, transf));
  }
  return true;
}

/** \brief Initializes the reconstruction node
  */
void reconstruction::ReconstructionBase::init()
{
  // Init the timer
  //timer_ = nh_.createWallTimer(ros::WallDuration(10), &reconstruction::ReconstructionBase::timerCallback, this);
  reconstruction::ReconstructionBase::process();
}<commit_msg>Reconstuction works now with pointloud pointers<commit_after>#include "reconstruction/base.h"
#include <boost/filesystem.hpp>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl_ros/transforms.h>

namespace fs=boost::filesystem;

/** \brief Class constructor. Reads node parameters and initialize some properties.
  * @return
  * \param nh public node handler
  * \param nhp private node handler
  */
reconstruction::ReconstructionBase::ReconstructionBase(
  ros::NodeHandle nh, ros::NodeHandle nhp) : nh_(nh), nh_private_(nhp)
{
  // Read the node parameters
  readParameters();

  // Initialize the stereo slam
  init();
}

/** \brief Timer callback to launch the process
  */
void reconstruction::ReconstructionBase::timerCallback(const ros::WallTimerEvent&)
{
  // Avoid callback overwrite. ROS Timer documentation does no indicate what
  // happens when a timer callback is called before it finish.
  m_.lock ();
  reconstruction::ReconstructionBase::process();
  m_.unlock ();
}

/** \brief Build the 3D environment
  */
void reconstruction::ReconstructionBase::process()
{
  // Read the graph poses
  vector< pair<string, tf::Transform> > cloud_poses;
  if (!readPoses(cloud_poses)) return;

  // Init the kdtree
  const float radius = 0.005;
  pcl::KdTreeFLANN<PointXY> kdtree;

  // Init the voxel grid filter
  pcl::VoxelGrid<PointRGB> grid;
  PointCloud::Ptr cloud_downsampled_ptr(new PointCloud);
  grid.setLeafSize(0.003, 0.003, 0.003);
  grid.setDownsampleAllData(true);

  // Load, convert and accumulate every pointcloud
  PointCloud::Ptr acc(new PointCloud);
  for (uint i=0; i<cloud_poses.size(); i++)
  {
    string file_idx = cloud_poses[i].first;
    ROS_INFO_STREAM("[StereoSlam:] Processing cloud " << file_idx.substr(0,file_idx.length()-4) << "/" << cloud_poses.size()-1);

    // Read the current pointcloud.
    string cloud_filename = params_.clouds_dir + cloud_poses[i].first;
    PointCloud::Ptr cloud(new PointCloud);
    if (pcl::io::loadPCDFile<PointRGB> (cloud_filename, *cloud) == -1)
    {
      ROS_WARN_STREAM("[StereoSlam:] Couldn't read the file: " << cloud_poses[i].first);
      continue;
    }

    // Remove isolated points
    pcl::StatisticalOutlierRemoval<PointRGB> sor;
    sor.setInputCloud(cloud);
    sor.setMeanK(50);
    sor.setStddevMulThresh(1.0);
    sor.filter(*cloud);

    // Transform pointcloud
    pcl_ros::transformPointCloud(*cloud, *cloud, cloud_poses[i].second);

    // First iteration
    if (acc->points.size() == 0)
    {
      copyPointCloud(*cloud, *acc);
      continue;
    }

    // Convert the accumulated cloud to PointXY
    pcl::PointCloud<PointXY>::Ptr acc_xy(new pcl::PointCloud<PointXY>);
    copyPointCloud(*acc, *acc_xy);

    vector<int> point_idx;
    vector<float> point_distance;
    kdtree.setInputCloud(acc_xy);

    int total = 0;
    int added = 0;
    for (uint i=0; i<cloud->points.size(); i++)
    {
      PointXY cur_point;
      cur_point.x = cloud->points[i].x;
      cur_point.y = cloud->points[i].y;
      if (!isfinite(cur_point.x) || !isfinite(cur_point.y))
        continue;

      total++;
      if (kdtree.radiusSearch(cur_point, radius, point_idx, point_distance) <= 0)
      {
        added++;
        acc->push_back(cloud->points[i]);
      }
    }

    ROS_INFO_STREAM("[StereoSlam:] Original size: " << total << ". Finally added: " << added);

    // Filter the accumulated cloud
    grid.setInputCloud(acc);
    grid.filter(*cloud_downsampled_ptr);
    acc = cloud_downsampled_ptr;
  }

  // Save accumulated cloud
  ROS_INFO("[StereoSlam:] Saving pointcloud...");
  pcl::io::savePCDFile(params_.work_dir + "reconstruction.pcd", *acc);
  ROS_INFO("[StereoSlam:] Accumulated cloud saved.");
}

/** \brief Reads the reconstruction node parameters
  */
void reconstruction::ReconstructionBase::readParameters()
{
  Params params;

  // Operational directories
  string work_dir;
  nh_private_.param("work_dir", work_dir, string(""));
  if (work_dir[work_dir.length()-1] != '/')
    work_dir += "/";
  params.work_dir = work_dir;
  params.clouds_dir = work_dir + "clouds/";
  params.graph_file = work_dir + "graph_vertices.txt";

  setParams(params);
}

/** \brief Reads the poses file and return the vector with the cloud names and the transformations
  * @return true if poses read correctly, false otherwise
  * \param the vector with the cloud filenames and the transformations
  */
bool reconstruction::ReconstructionBase::readPoses(vector< pair<string, tf::Transform> > &cloud_poses)
{
  // Init
  cloud_poses.clear();

  // Wait until poses file is unblocked
  while(fs::exists(params_.work_dir + ".graph.block"));

  // Get the pointcloud poses file
  ifstream poses_file(params_.graph_file.c_str());
  string line;
  while (getline(poses_file, line))
  {
    int i = 0;
    string cloud_name, value;
    double x, y, z, qx, qy, qz, qw;
    istringstream ss(line);
    while(getline(ss, value, ','))
    {
      if (i == 1)
        cloud_name = value + ".pcd";
      else if (i == 5)
        x = boost::lexical_cast<double>(value);
      else if (i == 6)
        y = boost::lexical_cast<double>(value);
      else if (i == 7)
        z = boost::lexical_cast<double>(value);
      else if (i == 8)
        qx = boost::lexical_cast<double>(value);
      else if (i == 9)
        qy = boost::lexical_cast<double>(value);
      else if (i == 10)
        qz = boost::lexical_cast<double>(value);
      else if (i == 11)
        qw = boost::lexical_cast<double>(value);
      i++;
    }
    // Build the pair and save
    tf::Vector3 t(x, y, z);
    tf::Quaternion q(qx, qy, qz, qw);
    tf::Transform transf(q, t);
    cloud_poses.push_back(make_pair(cloud_name, transf));
  }
  return true;
}

/** \brief Initializes the reconstruction node
  */
void reconstruction::ReconstructionBase::init()
{
  // Init the timer
  //timer_ = nh_.createWallTimer(ros::WallDuration(10), &reconstruction::ReconstructionBase::timerCallback, this);
  reconstruction::ReconstructionBase::process();
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2013, 2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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
 * OWNER 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.
 *
 * Authors: Andreas Sandberg
 */

/** @file
 * Base class for ARM GIC implementations
 */

#ifndef __DEV_ARM_BASE_GIC_H__
#define __DEV_ARM_BASE_GIC_H__

#include "dev/io_device.hh"

class Platform;
class RealView;
class ThreadContext;

struct ArmInterruptPinParams;
struct ArmPPIParams;
struct ArmSPIParams;
struct BaseGicParams;

class BaseGic :  public PioDevice
{
  public:
    typedef BaseGicParams Params;

    BaseGic(const Params *p);
    virtual ~BaseGic();

    const Params * params() const;

    /**
     * Post an interrupt from a device that is connected to the GIC.
     *
     * Depending on the configuration, the GIC will pass this interrupt
     * on through to a CPU.
     *
     * @param num number of interrupt to send
     */
    virtual void sendInt(uint32_t num) = 0;

    /**
     * Interface call for private peripheral interrupts.
     *
     * @param num number of interrupt to send
     * @param cpu CPU to forward interrupt to
     */
    virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0;
    virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0;

    /**
     * Clear an interrupt from a device that is connected to the GIC.
     *
     * Depending on the configuration, the GIC may de-assert it's CPU
     * line.
     *
     * @param num number of interrupt to send
     */
    virtual void clearInt(uint32_t num) = 0;

  protected:
    /** Platform this GIC belongs to. */
    Platform *platform;
};

class BaseGicRegisters
{
  public:
    virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
    virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;

    virtual void writeDistributor(ContextID ctx, Addr daddr,
                                  uint32_t data) = 0;
    virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
};

/**
 * Generic representation of an Arm interrupt pin.
 */
class ArmInterruptPin : public SimObject
{
  public:
    ArmInterruptPin(const ArmInterruptPinParams *p);

  public: /* Public interface */
    /**
     * Set the thread context owning this interrupt.
     *
     * This method is used to set the thread context for interrupts
     * that are thread/CPU-specific. Only devices that are used in
     * such a context are expected to call this method.
     */
    void setThreadContext(ThreadContext *tc);

    /** Signal an interrupt */
    virtual void raise() = 0;
    /** Clear a signalled interrupt */
    virtual void clear() = 0;

  protected:
    /**
     * Get the target context ID of this interrupt.
     *
     * @pre setThreadContext() must have been called prior to calling
     * this method.
     */
    ContextID targetContext() const;

    /**
     * Pointer to the thread context that owns this interrupt in case
     * it is a thread-/CPU-private interrupt
     */
    const ThreadContext *threadContext;

    /** Arm platform to use for interrupt generation */
    RealView *const platform;
    /** Interrupt number to generate */
    const uint32_t intNum;
};

class ArmSPI : public ArmInterruptPin
{
  public:
    ArmSPI(const ArmSPIParams *p);

    void raise() override;
    void clear() override;
};

class ArmPPI : public ArmInterruptPin
{
  public:
    ArmPPI(const ArmPPIParams *p);

    void raise() override;
    void clear() override;
};

#endif
<commit_msg>dev-arm: Create a getter for ArmInterruptPin ID number<commit_after>/*
 * Copyright (c) 2012-2013, 2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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
 * OWNER 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.
 *
 * Authors: Andreas Sandberg
 */

/** @file
 * Base class for ARM GIC implementations
 */

#ifndef __DEV_ARM_BASE_GIC_H__
#define __DEV_ARM_BASE_GIC_H__

#include "dev/io_device.hh"

class Platform;
class RealView;
class ThreadContext;

struct ArmInterruptPinParams;
struct ArmPPIParams;
struct ArmSPIParams;
struct BaseGicParams;

class BaseGic :  public PioDevice
{
  public:
    typedef BaseGicParams Params;

    BaseGic(const Params *p);
    virtual ~BaseGic();

    const Params * params() const;

    /**
     * Post an interrupt from a device that is connected to the GIC.
     *
     * Depending on the configuration, the GIC will pass this interrupt
     * on through to a CPU.
     *
     * @param num number of interrupt to send
     */
    virtual void sendInt(uint32_t num) = 0;

    /**
     * Interface call for private peripheral interrupts.
     *
     * @param num number of interrupt to send
     * @param cpu CPU to forward interrupt to
     */
    virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0;
    virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0;

    /**
     * Clear an interrupt from a device that is connected to the GIC.
     *
     * Depending on the configuration, the GIC may de-assert it's CPU
     * line.
     *
     * @param num number of interrupt to send
     */
    virtual void clearInt(uint32_t num) = 0;

  protected:
    /** Platform this GIC belongs to. */
    Platform *platform;
};

class BaseGicRegisters
{
  public:
    virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
    virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;

    virtual void writeDistributor(ContextID ctx, Addr daddr,
                                  uint32_t data) = 0;
    virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
};

/**
 * Generic representation of an Arm interrupt pin.
 */
class ArmInterruptPin : public SimObject
{
  public:
    ArmInterruptPin(const ArmInterruptPinParams *p);

  public: /* Public interface */
    /**
     * Set the thread context owning this interrupt.
     *
     * This method is used to set the thread context for interrupts
     * that are thread/CPU-specific. Only devices that are used in
     * such a context are expected to call this method.
     */
    void setThreadContext(ThreadContext *tc);

    /** Get interrupt number */
    uint32_t num() const { return intNum; }

    /** Signal an interrupt */
    virtual void raise() = 0;
    /** Clear a signalled interrupt */
    virtual void clear() = 0;

  protected:
    /**
     * Get the target context ID of this interrupt.
     *
     * @pre setThreadContext() must have been called prior to calling
     * this method.
     */
    ContextID targetContext() const;

    /**
     * Pointer to the thread context that owns this interrupt in case
     * it is a thread-/CPU-private interrupt
     */
    const ThreadContext *threadContext;

    /** Arm platform to use for interrupt generation */
    RealView *const platform;
    /** Interrupt number to generate */
    const uint32_t intNum;
};

class ArmSPI : public ArmInterruptPin
{
  public:
    ArmSPI(const ArmSPIParams *p);

    void raise() override;
    void clear() override;
};

class ArmPPI : public ArmInterruptPin
{
  public:
    ArmPPI(const ArmPPIParams *p);

    void raise() override;
    void clear() override;
};

#endif
<|endoftext|>


<commit_before>#include "devicedetection.h"
#include "config/configuration.h"
#include "devicedetectionprocessor.h"
#include "deviceselectiontablemodel.h"
#include "events/events.h"
#include "miomain.h"
#include "ui_devicedetection.h"

#include <QStandardItemModel>
#include <QTimer>

DeviceDetection::DeviceDetection(QWidget *parent)
	: QDialog(parent), ui(new Ui::DeviceDetection) {
	connect(this, SIGNAL(openDefaultDevice()), parent,
			SLOT(openDefaultDevice()));
	ui->setupUi(this);
	readSettings();
	detectionProcessor = new DeviceDetectionProcessor(this);
	QTimer::singleShot(1000, this, SLOT(startDeviceDetection()));
}

DeviceDetection::~DeviceDetection() { delete ui; }

void DeviceDetection::customEvent(QEvent *e) {
	if (e->type() == (QEvent::Type)PROGRESS_EVENT_TYPE) {
		ui->progressBar->setValue(((ProgressEvent *)e)->getValue());
	}
}

void DeviceDetection::startDeviceDetection() {
	int maximum = detectionProcessor->getMidiOutPortCount() *
				  detectionProcessor->getMidiInPortCount();
	ui->progressBar->setMaximum(maximum);
	ui->progressBar->setMinimum(0);
	ui->progressBar->setValue(0);
	detectionProcessor->startDeviceDetection();
	Devices *devices = Configuration::getInstance().getDevices();
	DeviceSelectionTableModel *deviceModel =
		new DeviceSelectionTableModel(devices);
	ui->tableView->setModel(deviceModel);
	ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}

void DeviceDetection::on_buttonBox_accepted() {
	writeSettings();
	emit openDefaultDevice();
}

void DeviceDetection::setProgressBar(int value) {
	ui->progressBar->setValue(value);
}

void DeviceDetection::writeSettings() {
	QSettings *settings = Configuration::getInstance().getSettings();
	settings->beginGroup("DeviceDetectionWindow");
	settings->setValue("size", size());
	settings->setValue("pos", pos());
	settings->endGroup();
}

void DeviceDetection::readSettings() {
	QSettings *settings = Configuration::getInstance().getSettings();
	settings->beginGroup("DeviceDetectionWindow");
	resize(settings->value("size", QSize(400, 400)).toSize());
	move(settings->value("pos", QPoint(200, 200)).toPoint());
	settings->endGroup();
}

void DeviceDetection::closeEvent(QCloseEvent *event) {
	writeSettings();
	event->accept();
}
<commit_msg>use modern style casts<commit_after>#include "devicedetection.h"
#include "config/configuration.h"
#include "devicedetectionprocessor.h"
#include "deviceselectiontablemodel.h"
#include "events/events.h"
#include "miomain.h"
#include "ui_devicedetection.h"

#include <QStandardItemModel>
#include <QTimer>

DeviceDetection::DeviceDetection(QWidget *parent)
	: QDialog(parent), ui(new Ui::DeviceDetection) {
	connect(this, SIGNAL(openDefaultDevice()), parent,
			SLOT(openDefaultDevice()));
	ui->setupUi(this);
	readSettings();
	detectionProcessor = new DeviceDetectionProcessor(this);
	QTimer::singleShot(1000, this, SLOT(startDeviceDetection()));
}

DeviceDetection::~DeviceDetection() { delete ui; }

void DeviceDetection::customEvent(QEvent *e) {
	if (e->type() == static_cast<QEvent::Type>(PROGRESS_EVENT_TYPE)) {
		ui->progressBar->setValue(
			static_cast<int>((dynamic_cast<ProgressEvent *>(e))->getValue()));
	}
}

void DeviceDetection::startDeviceDetection() {
	unsigned int maximum = detectionProcessor->getMidiOutPortCount() *
						   detectionProcessor->getMidiInPortCount();
	ui->progressBar->setMaximum(static_cast<int>(maximum));
	ui->progressBar->setMinimum(0);
	ui->progressBar->setValue(0);
	detectionProcessor->startDeviceDetection();
	Devices *devices = Configuration::getInstance().getDevices();
	DeviceSelectionTableModel *deviceModel =
		new DeviceSelectionTableModel(devices);
	ui->tableView->setModel(deviceModel);
	ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}

void DeviceDetection::on_buttonBox_accepted() {
	writeSettings();
	emit openDefaultDevice();
}

void DeviceDetection::setProgressBar(int value) {
	ui->progressBar->setValue(value);
}

void DeviceDetection::writeSettings() {
	QSettings *settings = Configuration::getInstance().getSettings();
	settings->beginGroup("DeviceDetectionWindow");
	settings->setValue("size", size());
	settings->setValue("pos", pos());
	settings->endGroup();
}

void DeviceDetection::readSettings() {
	QSettings *settings = Configuration::getInstance().getSettings();
	settings->beginGroup("DeviceDetectionWindow");
	resize(settings->value("size", QSize(400, 400)).toSize());
	move(settings->value("pos", QPoint(200, 200)).toPoint());
	settings->endGroup();
}

void DeviceDetection::closeEvent(QCloseEvent *event) {
	writeSettings();
	event->accept();
}
<|endoftext|>


<commit_before>/*
 * ####                                                ####
 * ####                                                ####
 * ####                                                ####      ##
 * ####                                                ####    ####
 * ####  ############  ############  ####  ##########  ####  ####
 * ####  ####    ####  ####    ####  ####  ####        ########
 * ####  ####    ####  ####    ####  ####  ####        ########
 * ####  ####    ####  ####    ####  ####  ####        ####  ####
 * ####  ####    ####  ####    ####  ####  ####        ####    ####
 * ####  ############  ############  ####  ##########  ####      ####
 *                             ####                                ####
 * ################################                                  ####
 *            __      __              __              __      __       ####
 *   |  |    |  |    [__)    |_/     (__     |__|    |  |    [__)        ####
 *   |/\|    |__|    |  \    |  \    .__)    |  |    |__|    |             ##
 *
 *
 * DU-INO Arduino Library - Function Module
 * Aaron Mavrinac <aaron@logick.ca>
 */

#include "du-ino_mcp4922.h"
#include "du-ino_function.h"

#define TRIG_MS     5

DUINO_Function::DUINO_Function(uint16_t sc)
  : switch_config(sc)
{
  // compute digital output mask
  out_mask = 0x30 || (~switch_config & 0x0F);

  // configure pins
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);

  for(uint8_t i = 0; i < 4; ++i)
    pinMode(i, switch_config & (1 << i) ? INPUT : OUTPUT);

  // configure DACs
  for(uint8_t i = 0; i < 2; ++i)
    dac[i] = new DUINO_MCP4922(i + 6);
}

uint8_t DUINO_Function::digital_read(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack > 9 && jack < 15 && switch_config & (1 << pin))
    return digitalRead(pin);
  else
    return 0;
}

float DUINO_Function::analog_read(uint8_t jack)
{
  uint8_t pin;
  switch(jack)
  {
    case 0:
      pin = A0;
      break;
    case 1:
      pin = A1;
      break;
    case 2:
      pin = A2;
      break;
    case 3:
      pin = A3;
      break;
    default:
      return 0.0;
  }

  // value * (20 / (2^10 - 1)) - 10
  return float(analogRead(pin)) * 0.019550342130987292 - 10.0;
}

void DUINO_Function::gate(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack < 6 && out_mask & (1 << pin))
    digitalWrite(pin, HIGH);
}

void DUINO_Function::multi_gate(uint8_t jacks)
{
  for(uint8_t i = 0; i < 6; ++i)
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, HIGH);
}

void DUINO_Function::clear(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack < 6 && out_mask & (1 << pin))
    digitalWrite(pin, LOW);
}

void DUINO_Function::multi_clear(uint8_t jacks)
{
  for(uint8_t i = 0; i < 6; ++i)
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, LOW);
}

void DUINO_Function::trig(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack < 6 && out_mask & (1 << pin))
  {
    digitalWrite(pin, HIGH);
    delay(TRIG_MS);
    digitalWrite(pin, LOW);
  }
}

void DUINO_Function::multi_trig(uint8_t jacks)
{
  for(uint8_t i = 0; i < 6; ++i)
  {
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, HIGH);
    delay(TRIG_MS);
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, LOW);
  }
}

void DUINO_Function::analog_write(uint8_t dac_pin, float value)
{
  if(dac_pin > 4)
    return;

  // (value + 10) * ((2^12 - 1) / 20)
  uint16_t data = (value + 10.0) * 204.75;

  // DAC output
  dac[dac_pin >> 1]->output(dac_pin & 1, data);
}
<commit_msg>Fix enum conversion.<commit_after>/*
 * ####                                                ####
 * ####                                                ####
 * ####                                                ####      ##
 * ####                                                ####    ####
 * ####  ############  ############  ####  ##########  ####  ####
 * ####  ####    ####  ####    ####  ####  ####        ########
 * ####  ####    ####  ####    ####  ####  ####        ########
 * ####  ####    ####  ####    ####  ####  ####        ####  ####
 * ####  ####    ####  ####    ####  ####  ####        ####    ####
 * ####  ############  ############  ####  ##########  ####      ####
 *                             ####                                ####
 * ################################                                  ####
 *            __      __              __              __      __       ####
 *   |  |    |  |    [__)    |_/     (__     |__|    |  |    [__)        ####
 *   |/\|    |__|    |  \    |  \    .__)    |  |    |__|    |             ##
 *
 *
 * DU-INO Arduino Library - Function Module
 * Aaron Mavrinac <aaron@logick.ca>
 */

#include "du-ino_mcp4922.h"
#include "du-ino_function.h"

#define TRIG_MS     5

DUINO_Function::DUINO_Function(uint16_t sc)
  : switch_config(sc)
{
  // compute digital output mask
  out_mask = 0x30 || (~switch_config & 0x0F);

  // configure pins
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);

  for(uint8_t i = 0; i < 4; ++i)
    pinMode(i, switch_config & (1 << i) ? INPUT : OUTPUT);

  // configure DACs
  for(uint8_t i = 0; i < 2; ++i)
    dac[i] = new DUINO_MCP4922(i + 6);
}

uint8_t DUINO_Function::digital_read(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack > 9 && jack < 15 && switch_config & (1 << pin))
    return digitalRead(pin);
  else
    return 0;
}

float DUINO_Function::analog_read(uint8_t jack)
{
  uint8_t pin;
  switch(jack)
  {
    case 0:
      pin = A0;
      break;
    case 1:
      pin = A1;
      break;
    case 2:
      pin = A2;
      break;
    case 3:
      pin = A3;
      break;
    default:
      return 0.0;
  }

  // value * (20 / (2^10 - 1)) - 10
  return float(analogRead(pin)) * 0.019550342130987292 - 10.0;
}

void DUINO_Function::gate(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack < 6 && out_mask & (1 << pin))
    digitalWrite(pin, HIGH);
}

void DUINO_Function::multi_gate(uint8_t jacks)
{
  for(uint8_t i = 0; i < 6; ++i)
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, HIGH);
}

void DUINO_Function::clear(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack < 6 && out_mask & (1 << pin))
    digitalWrite(pin, LOW);
}

void DUINO_Function::multi_clear(uint8_t jacks)
{
  for(uint8_t i = 0; i < 6; ++i)
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, LOW);
}

void DUINO_Function::trig(uint8_t jack)
{
  uint8_t pin = 14 - jack;

  if(jack < 6 && out_mask & (1 << pin))
  {
    digitalWrite(pin, HIGH);
    delay(TRIG_MS);
    digitalWrite(pin, LOW);
  }
}

void DUINO_Function::multi_trig(uint8_t jacks)
{
  for(uint8_t i = 0; i < 6; ++i)
  {
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, HIGH);
    delay(TRIG_MS);
    if(jacks & out_mask & (1 << i))
      digitalWrite(i, LOW);
  }
}

void DUINO_Function::analog_write(uint8_t dac_pin, float value)
{
  if(dac_pin > 4)
    return;

  // (value + 10) * ((2^12 - 1) / 20)
  uint16_t data = (value + 10.0) * 204.75;

  // DAC output
  dac[dac_pin >> 1]->output((DUINO_MCP4922::Channel)(dac_pin & 1), data);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dp_script.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:32:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "dp_script.hrc"
#include "dp_lib_container.h"
#include "dp_backend.h"
#include "dp_ucb.h"
#include "rtl/uri.hxx"
#include "ucbhelper/content.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "cppuhelper/implbase1.hxx"
#include "svtools/inettype.hxx"
#include "com/sun/star/util/XUpdatable.hpp"
#include "com/sun/star/script/XLibraryContainer.hpp"
#include <memory>

using namespace ::dp_misc;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using ::rtl::OUString;
namespace css = ::com::sun::star;

namespace dp_registry {
namespace backend {
namespace script {
namespace {

typedef ::cppu::ImplInheritanceHelper1<
    ::dp_registry::backend::PackageRegistryBackend, util::XUpdatable > t_helper;

//==============================================================================
class BackendImpl : public t_helper
{
    class PackageImpl : public ::dp_registry::backend::Package
    {
        BackendImpl * getMyBackend() const {
            return static_cast<BackendImpl *>(m_myBackend.get());
        }

        const OUString m_scriptURL;
        const OUString m_dialogURL;
        OUString m_dialogName;

        // Package
        virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
            ::osl::ResettableMutexGuard & guard,
            ::rtl::Reference<AbortChannel> const & abortChannel,
            Reference<XCommandEnvironment> const & xCmdEnv );
        virtual void processPackage_(
            ::osl::ResettableMutexGuard & guard,
            bool registerPackage,
            ::rtl::Reference<AbortChannel> const & abortChannel,
            Reference<XCommandEnvironment> const & xCmdEnv );

    public:
        PackageImpl(
            ::rtl::Reference<BackendImpl> const & myBackend,
            OUString const & url,
            Reference<XCommandEnvironment> const &xCmdEnv,
            OUString const & scriptURL, OUString const & dialogURL );
    };
    friend class PackageImpl;

    // PackageRegistryBackend
    virtual Reference<deployment::XPackage> bindPackage_(
        OUString const & url, OUString const & mediaType,
        Reference<XCommandEnvironment> const & xCmdEnv );

    Reference<css::script::XLibraryContainer> m_xScriptLibs;
    Reference<css::script::XLibraryContainer> m_xDialogLibs;
    ::std::auto_ptr<LibraryContainer> m_basic_script_libs;
    ::std::auto_ptr<LibraryContainer> m_dialog_libs;

    const Reference<deployment::XPackageTypeInfo> m_xBasicLibTypeInfo;
    const Reference<deployment::XPackageTypeInfo> m_xDialogLibTypeInfo;
    Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;

public:
    BackendImpl( Sequence<Any> const & args,
                 Reference<XComponentContext> const & xComponentContext,
                 OUString const & implName );

    // XUpdatable
    virtual void SAL_CALL update() throw (RuntimeException);

    // XPackageRegistry
    virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
    getSupportedPackageTypes() throw (RuntimeException);
};

//______________________________________________________________________________
BackendImpl::PackageImpl::PackageImpl(
    ::rtl::Reference<BackendImpl> const & myBackend,
    OUString const & url,
    Reference<XCommandEnvironment> const &xCmdEnv,
    OUString const & scriptURL, OUString const & dialogURL )
    : Package( myBackend.get(), url,
               OUString(), OUString(), // will be late-initialized
               scriptURL.getLength() > 0 ? myBackend->m_xBasicLibTypeInfo
                                         : myBackend->m_xDialogLibTypeInfo ),
      m_scriptURL( scriptURL ),
      m_dialogURL( dialogURL )
{
    // name, displayName:
    if (dialogURL.getLength() > 0) {
        m_dialogName = LibraryContainer::get_libname(
            dialogURL, xCmdEnv, myBackend->getComponentContext() );
    }
    if (scriptURL.getLength() > 0) {
        m_name = LibraryContainer::get_libname(
            scriptURL, xCmdEnv, myBackend->getComponentContext() );
    }
    else
        m_name = m_dialogName;
    m_displayName = m_name;
}

//______________________________________________________________________________
BackendImpl::BackendImpl(
    Sequence<Any> const & args,
    Reference<XComponentContext> const & xComponentContext,
    OUString const & implName )
    : t_helper( args, xComponentContext, implName ),
      m_xBasicLibTypeInfo( new Package::TypeInfo(
                               OUSTR("application/"
                                     "vnd.sun.star.basic-library"),
                               OUString() /* no file filter */,
                               getResourceString(RID_STR_BASIC_LIB),
                               RID_IMG_SCRIPTLIB, RID_IMG_SCRIPTLIB_HC ) ),
      m_xDialogLibTypeInfo( new Package::TypeInfo(
                                OUSTR("application/"
                                      "vnd.sun.star.dialog-library"),
                                OUString() /* no file filter */,
                                getResourceString(RID_STR_DIALOG_LIB),
                                RID_IMG_DIALOGLIB, RID_IMG_DIALOGLIB_HC ) ),
      m_typeInfos( 2 )
{
    m_typeInfos[ 0 ] = m_xBasicLibTypeInfo;
    m_typeInfos[ 1 ] = m_xDialogLibTypeInfo;

    OSL_ASSERT( ! transientMode() );
    if (office_is_running())
    {
        m_xScriptLibs.set(
            xComponentContext->getServiceManager()->createInstanceWithContext(
                OUSTR("com.sun.star.script.ApplicationScriptLibraryContainer"),
                xComponentContext ), UNO_QUERY_THROW );
        m_xDialogLibs.set(
            xComponentContext->getServiceManager()->createInstanceWithContext(
                OUSTR("com.sun.star.script.ApplicationDialogLibraryContainer"),
                xComponentContext ), UNO_QUERY_THROW );
    }
    else
    {
        OUString basic_path(
            m_eContext == CONTEXT_USER
            ? OUSTR("vnd.sun.star.expand:${$SYSBINDIR/"
                    SAL_CONFIGFILE("bootstrap")
                    ":UserInstallation}/user/basic")
            : OUSTR("vnd.sun.star.expand:${$SYSBINDIR/"
                    SAL_CONFIGFILE("bootstrap")
                    ":BaseInstallation}/share/basic") );
        m_basic_script_libs.reset(
            new LibraryContainer(
                makeURL( basic_path, OUSTR("script.xlc") ),
                getMutex(),
                xComponentContext ) );
        m_dialog_libs.reset(
            new LibraryContainer(
                makeURL( basic_path, OUSTR("dialog.xlc") ),
                getMutex(),
                xComponentContext ) );
    }
}

// XUpdatable
//______________________________________________________________________________
void BackendImpl::update() throw (RuntimeException)
{
    const Reference<XCommandEnvironment> xCmdEnv;
    if (m_basic_script_libs.get() != 0) {
        try {
            m_basic_script_libs->init(xCmdEnv);
            m_basic_script_libs->flush(xCmdEnv);
        }
        catch (RuntimeException &) {
            throw;
        }
        catch (Exception & exc) {
            (void) exc;
            OSL_ENSURE( 0, ::rtl::OUStringToOString(
                            exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
        }
    }
    if (m_dialog_libs.get() != 0) {
        try {
            m_dialog_libs->init(xCmdEnv);
            m_dialog_libs->flush(xCmdEnv);
        }
        catch (RuntimeException &) {
            throw;
        }
        catch (Exception & exc) {
            (void) exc;
            OSL_ENSURE( 0, ::rtl::OUStringToOString(
                            exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
        }
    }
}

// XPackageRegistry
//______________________________________________________________________________
Sequence< Reference<deployment::XPackageTypeInfo> >
BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
{
    return m_typeInfos;
}

// PackageRegistryBackend
//______________________________________________________________________________
Reference<deployment::XPackage> BackendImpl::bindPackage_(
    OUString const & url, OUString const & mediaType_,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    OUString mediaType( mediaType_ );
    if (mediaType.getLength() == 0)
    {
        // detect media-type:
        ::ucb::Content ucbContent;
        if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
            ucbContent.isFolder())
        {
            // probe for script.xlb:
            if (create_ucb_content(
                    0, makeURL( url, OUSTR("script.xlb") ),
                    xCmdEnv, false /* no throw */ ))
                mediaType = OUSTR("application/vnd.sun.star.basic-library");
            // probe for dialog.xlb:
            else if (create_ucb_content(
                         0, makeURL( url, OUSTR("dialog.xlb") ),
                         xCmdEnv, false /* no throw */ ))
                mediaType = OUSTR("application/vnd.sun.star.dialog-library");
        }
        if (mediaType.getLength() == 0)
            throw lang::IllegalArgumentException(
                StrCannotDetectMediaType::get() + url,
                static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
    }

    String type, subType;
    INetContentTypeParameterList params;
    if (INetContentTypes::parse( mediaType, type, subType, &params ))
    {
        if (type.EqualsIgnoreCaseAscii("application"))
        {
            if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.basic-library"))
            {
                OUString dialogURL( makeURL( url, OUSTR("dialog.xlb") ) );
                if (! create_ucb_content(
                        0, dialogURL, xCmdEnv, false /* no throw */ )) {
                    dialogURL = OUString();
                }
                return new PackageImpl( this, url, xCmdEnv,
                                        makeURL( url, OUSTR("script.xlb") ),
                                        dialogURL );
            }
            else if (subType.EqualsIgnoreCaseAscii(
                         "vnd.sun.star.dialog-library")) {
                return new PackageImpl( this, url, xCmdEnv,
                                        OUString() /* no script lib */,
                                        makeURL( url, OUSTR("dialog.xlb") ) );
            }
        }
    }
    throw lang::IllegalArgumentException(
        StrUnsupportedMediaType::get() + mediaType,
        static_cast<OWeakObject *>(this),
        static_cast<sal_Int16>(-1) );
}

//##############################################################################

// Package
//______________________________________________________________________________
beans::Optional< beans::Ambiguous<sal_Bool> >
BackendImpl::PackageImpl::isRegistered_(
    ::osl::ResettableMutexGuard & guard,
    ::rtl::Reference<AbortChannel> const & abortChannel,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    BackendImpl * that = getMyBackend();
    bool reg = false;
    if (m_scriptURL.getLength() > 0) {
        if (that->m_xScriptLibs.is())
            reg = that->m_xScriptLibs->hasByName( m_name );
        else
            reg = that->m_basic_script_libs->has( m_name, xCmdEnv );
    }
    else {
        if (that->m_xDialogLibs.is())
            reg = that->m_xDialogLibs->hasByName( m_dialogName );
        else
            reg = that->m_dialog_libs->has( m_dialogName, xCmdEnv );
    }
    return beans::Optional< beans::Ambiguous<sal_Bool> >(
        true /* IsPresent */,
        beans::Ambiguous<sal_Bool>( reg, false /* IsAmbiguous */ ) );
}

//______________________________________________________________________________
void BackendImpl::PackageImpl::processPackage_(
    ::osl::ResettableMutexGuard & guard,
    bool registerPackage,
    ::rtl::Reference<AbortChannel> const & abortChannel,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    BackendImpl * that = getMyBackend();
    if (registerPackage)
    {
        if (m_scriptURL.getLength() > 0) {
            if (that->m_xScriptLibs.is())
                that->m_xScriptLibs->createLibraryLink(
                    m_name, m_scriptURL, false /* ! read-only */ );
            else
                that->m_basic_script_libs->insert(
                    m_name, m_scriptURL, xCmdEnv );
        }
        if (m_dialogURL.getLength() > 0) {
            if (that->m_xDialogLibs.is())
                that->m_xDialogLibs->createLibraryLink(
                    m_dialogName, m_dialogURL, false /* ! read-only */ );
            else
                that->m_dialog_libs->insert(
                    m_dialogName, m_dialogURL, xCmdEnv );
        }
    }
    else // revokePackage()
    {
        try {
            if (m_scriptURL.getLength() > 0) {
                if (that->m_xScriptLibs.is())
                    that->m_xScriptLibs->removeLibrary( m_name );
                else
                    that->m_basic_script_libs->remove(
                        m_name, m_scriptURL, xCmdEnv );
            }
            if (m_dialogURL.getLength() > 0) {
                if (that->m_xDialogLibs.is())
                    that->m_xDialogLibs->removeLibrary( m_dialogName );
                else
                    that->m_dialog_libs->remove(
                        m_dialogName, m_dialogURL, xCmdEnv );
            }
        }
        catch (lang::WrappedTargetException & exc) {
            // unwrap WrappedTargetException:
            ::cppu::throwException( exc.TargetException );
        }
    }
}

} // anon namespace

//==============================================================================
OUString SAL_CALL getImplementationName()
{
    return OUSTR("com.sun.star.comp.deployment.script.PackageRegistryBackend");
}

//==============================================================================
Reference<XInterface> SAL_CALL create(
    Sequence<Any> const & args,
    Reference<XComponentContext> const & xComponentContext )
{
    return static_cast< ::cppu::OWeakObject * >(
        new BackendImpl( args, xComponentContext, getImplementationName() ) );
}

} // namespace script
} // namespace backend
} // namespace dp_registry

<commit_msg>INTEGRATION: CWS dbo510 (1.6.40); FILE MERGED 2005/11/10 15:48:55 dbo 1.6.40.2: adopted to revised SreviceDecl Issue number: Submitted by: Reviewed by: 2005/11/01 22:16:00 dbo 1.6.40.1: adopted to ServiceDecl Issue number: Submitted by: Reviewed by:<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dp_script.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2006-03-06 10:23:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "dp_script.hrc"
#include "dp_lib_container.h"
#include "dp_backend.h"
#include "dp_ucb.h"
#include "rtl/uri.hxx"
#include "ucbhelper/content.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "cppuhelper/implbase1.hxx"
#include "comphelper/servicedecl.hxx"
#include "svtools/inettype.hxx"
#include "com/sun/star/util/XUpdatable.hpp"
#include "com/sun/star/script/XLibraryContainer.hpp"
#include <memory>

using namespace ::dp_misc;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using ::rtl::OUString;
namespace css = ::com::sun::star;

namespace dp_registry {
namespace backend {
namespace script {
namespace {

typedef ::cppu::ImplInheritanceHelper1<
    ::dp_registry::backend::PackageRegistryBackend, util::XUpdatable > t_helper;

//==============================================================================
class BackendImpl : public t_helper
{
    class PackageImpl : public ::dp_registry::backend::Package
    {
        BackendImpl * getMyBackend() const {
            return static_cast<BackendImpl *>(m_myBackend.get());
        }

        const OUString m_scriptURL;
        const OUString m_dialogURL;
        OUString m_dialogName;

        // Package
        virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
            ::osl::ResettableMutexGuard & guard,
            ::rtl::Reference<AbortChannel> const & abortChannel,
            Reference<XCommandEnvironment> const & xCmdEnv );
        virtual void processPackage_(
            ::osl::ResettableMutexGuard & guard,
            bool registerPackage,
            ::rtl::Reference<AbortChannel> const & abortChannel,
            Reference<XCommandEnvironment> const & xCmdEnv );

    public:
        PackageImpl(
            ::rtl::Reference<BackendImpl> const & myBackend,
            OUString const & url,
            Reference<XCommandEnvironment> const &xCmdEnv,
            OUString const & scriptURL, OUString const & dialogURL );
    };
    friend class PackageImpl;

    // PackageRegistryBackend
    virtual Reference<deployment::XPackage> bindPackage_(
        OUString const & url, OUString const & mediaType,
        Reference<XCommandEnvironment> const & xCmdEnv );

    Reference<css::script::XLibraryContainer> m_xScriptLibs;
    Reference<css::script::XLibraryContainer> m_xDialogLibs;
    ::std::auto_ptr<LibraryContainer> m_basic_script_libs;
    ::std::auto_ptr<LibraryContainer> m_dialog_libs;

    const Reference<deployment::XPackageTypeInfo> m_xBasicLibTypeInfo;
    const Reference<deployment::XPackageTypeInfo> m_xDialogLibTypeInfo;
    Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;

public:
    BackendImpl( Sequence<Any> const & args,
                 Reference<XComponentContext> const & xComponentContext );

    // XUpdatable
    virtual void SAL_CALL update() throw (RuntimeException);

    // XPackageRegistry
    virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
    getSupportedPackageTypes() throw (RuntimeException);
};

//______________________________________________________________________________
BackendImpl::PackageImpl::PackageImpl(
    ::rtl::Reference<BackendImpl> const & myBackend,
    OUString const & url,
    Reference<XCommandEnvironment> const &xCmdEnv,
    OUString const & scriptURL, OUString const & dialogURL )
    : Package( myBackend.get(), url,
               OUString(), OUString(), // will be late-initialized
               scriptURL.getLength() > 0 ? myBackend->m_xBasicLibTypeInfo
                                         : myBackend->m_xDialogLibTypeInfo ),
      m_scriptURL( scriptURL ),
      m_dialogURL( dialogURL )
{
    // name, displayName:
    if (dialogURL.getLength() > 0) {
        m_dialogName = LibraryContainer::get_libname(
            dialogURL, xCmdEnv, myBackend->getComponentContext() );
    }
    if (scriptURL.getLength() > 0) {
        m_name = LibraryContainer::get_libname(
            scriptURL, xCmdEnv, myBackend->getComponentContext() );
    }
    else
        m_name = m_dialogName;
    m_displayName = m_name;
}

//______________________________________________________________________________
BackendImpl::BackendImpl(
    Sequence<Any> const & args,
    Reference<XComponentContext> const & xComponentContext )
    : t_helper( args, xComponentContext ),
      m_xBasicLibTypeInfo( new Package::TypeInfo(
                               OUSTR("application/"
                                     "vnd.sun.star.basic-library"),
                               OUString() /* no file filter */,
                               getResourceString(RID_STR_BASIC_LIB),
                               RID_IMG_SCRIPTLIB, RID_IMG_SCRIPTLIB_HC ) ),
      m_xDialogLibTypeInfo( new Package::TypeInfo(
                                OUSTR("application/"
                                      "vnd.sun.star.dialog-library"),
                                OUString() /* no file filter */,
                                getResourceString(RID_STR_DIALOG_LIB),
                                RID_IMG_DIALOGLIB, RID_IMG_DIALOGLIB_HC ) ),
      m_typeInfos( 2 )
{
    m_typeInfos[ 0 ] = m_xBasicLibTypeInfo;
    m_typeInfos[ 1 ] = m_xDialogLibTypeInfo;

    OSL_ASSERT( ! transientMode() );
    if (office_is_running())
    {
        m_xScriptLibs.set(
            xComponentContext->getServiceManager()->createInstanceWithContext(
                OUSTR("com.sun.star.script.ApplicationScriptLibraryContainer"),
                xComponentContext ), UNO_QUERY_THROW );
        m_xDialogLibs.set(
            xComponentContext->getServiceManager()->createInstanceWithContext(
                OUSTR("com.sun.star.script.ApplicationDialogLibraryContainer"),
                xComponentContext ), UNO_QUERY_THROW );
    }
    else
    {
        OUString basic_path(
            m_eContext == CONTEXT_USER
            ? OUSTR("vnd.sun.star.expand:${$SYSBINDIR/"
                    SAL_CONFIGFILE("bootstrap")
                    ":UserInstallation}/user/basic")
            : OUSTR("vnd.sun.star.expand:${$SYSBINDIR/"
                    SAL_CONFIGFILE("bootstrap")
                    ":BaseInstallation}/share/basic") );
        m_basic_script_libs.reset(
            new LibraryContainer(
                makeURL( basic_path, OUSTR("script.xlc") ),
                getMutex(),
                xComponentContext ) );
        m_dialog_libs.reset(
            new LibraryContainer(
                makeURL( basic_path, OUSTR("dialog.xlc") ),
                getMutex(),
                xComponentContext ) );
    }
}

// XUpdatable
//______________________________________________________________________________
void BackendImpl::update() throw (RuntimeException)
{
    const Reference<XCommandEnvironment> xCmdEnv;
    if (m_basic_script_libs.get() != 0) {
        try {
            m_basic_script_libs->init(xCmdEnv);
            m_basic_script_libs->flush(xCmdEnv);
        }
        catch (RuntimeException &) {
            throw;
        }
        catch (Exception & exc) {
            (void) exc;
            OSL_ENSURE( 0, ::rtl::OUStringToOString(
                            exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
        }
    }
    if (m_dialog_libs.get() != 0) {
        try {
            m_dialog_libs->init(xCmdEnv);
            m_dialog_libs->flush(xCmdEnv);
        }
        catch (RuntimeException &) {
            throw;
        }
        catch (Exception & exc) {
            (void) exc;
            OSL_ENSURE( 0, ::rtl::OUStringToOString(
                            exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
        }
    }
}

// XPackageRegistry
//______________________________________________________________________________
Sequence< Reference<deployment::XPackageTypeInfo> >
BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
{
    return m_typeInfos;
}

// PackageRegistryBackend
//______________________________________________________________________________
Reference<deployment::XPackage> BackendImpl::bindPackage_(
    OUString const & url, OUString const & mediaType_,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    OUString mediaType( mediaType_ );
    if (mediaType.getLength() == 0)
    {
        // detect media-type:
        ::ucb::Content ucbContent;
        if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
            ucbContent.isFolder())
        {
            // probe for script.xlb:
            if (create_ucb_content(
                    0, makeURL( url, OUSTR("script.xlb") ),
                    xCmdEnv, false /* no throw */ ))
                mediaType = OUSTR("application/vnd.sun.star.basic-library");
            // probe for dialog.xlb:
            else if (create_ucb_content(
                         0, makeURL( url, OUSTR("dialog.xlb") ),
                         xCmdEnv, false /* no throw */ ))
                mediaType = OUSTR("application/vnd.sun.star.dialog-library");
        }
        if (mediaType.getLength() == 0)
            throw lang::IllegalArgumentException(
                StrCannotDetectMediaType::get() + url,
                static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
    }

    String type, subType;
    INetContentTypeParameterList params;
    if (INetContentTypes::parse( mediaType, type, subType, &params ))
    {
        if (type.EqualsIgnoreCaseAscii("application"))
        {
            if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.basic-library"))
            {
                OUString dialogURL( makeURL( url, OUSTR("dialog.xlb") ) );
                if (! create_ucb_content(
                        0, dialogURL, xCmdEnv, false /* no throw */ )) {
                    dialogURL = OUString();
                }
                return new PackageImpl( this, url, xCmdEnv,
                                        makeURL( url, OUSTR("script.xlb") ),
                                        dialogURL );
            }
            else if (subType.EqualsIgnoreCaseAscii(
                         "vnd.sun.star.dialog-library")) {
                return new PackageImpl( this, url, xCmdEnv,
                                        OUString() /* no script lib */,
                                        makeURL( url, OUSTR("dialog.xlb") ) );
            }
        }
    }
    throw lang::IllegalArgumentException(
        StrUnsupportedMediaType::get() + mediaType,
        static_cast<OWeakObject *>(this),
        static_cast<sal_Int16>(-1) );
}

//##############################################################################

// Package
//______________________________________________________________________________
beans::Optional< beans::Ambiguous<sal_Bool> >
BackendImpl::PackageImpl::isRegistered_(
    ::osl::ResettableMutexGuard & guard,
    ::rtl::Reference<AbortChannel> const & abortChannel,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    BackendImpl * that = getMyBackend();
    bool reg = false;
    if (m_scriptURL.getLength() > 0) {
        if (that->m_xScriptLibs.is())
            reg = that->m_xScriptLibs->hasByName( m_name );
        else
            reg = that->m_basic_script_libs->has( m_name, xCmdEnv );
    }
    else {
        if (that->m_xDialogLibs.is())
            reg = that->m_xDialogLibs->hasByName( m_dialogName );
        else
            reg = that->m_dialog_libs->has( m_dialogName, xCmdEnv );
    }
    return beans::Optional< beans::Ambiguous<sal_Bool> >(
        true /* IsPresent */,
        beans::Ambiguous<sal_Bool>( reg, false /* IsAmbiguous */ ) );
}

//______________________________________________________________________________
void BackendImpl::PackageImpl::processPackage_(
    ::osl::ResettableMutexGuard & guard,
    bool registerPackage,
    ::rtl::Reference<AbortChannel> const & abortChannel,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    BackendImpl * that = getMyBackend();
    if (registerPackage)
    {
        if (m_scriptURL.getLength() > 0) {
            if (that->m_xScriptLibs.is())
                that->m_xScriptLibs->createLibraryLink(
                    m_name, m_scriptURL, false /* ! read-only */ );
            else
                that->m_basic_script_libs->insert(
                    m_name, m_scriptURL, xCmdEnv );
        }
        if (m_dialogURL.getLength() > 0) {
            if (that->m_xDialogLibs.is())
                that->m_xDialogLibs->createLibraryLink(
                    m_dialogName, m_dialogURL, false /* ! read-only */ );
            else
                that->m_dialog_libs->insert(
                    m_dialogName, m_dialogURL, xCmdEnv );
        }
    }
    else // revokePackage()
    {
        try {
            if (m_scriptURL.getLength() > 0) {
                if (that->m_xScriptLibs.is())
                    that->m_xScriptLibs->removeLibrary( m_name );
                else
                    that->m_basic_script_libs->remove(
                        m_name, m_scriptURL, xCmdEnv );
            }
            if (m_dialogURL.getLength() > 0) {
                if (that->m_xDialogLibs.is())
                    that->m_xDialogLibs->removeLibrary( m_dialogName );
                else
                    that->m_dialog_libs->remove(
                        m_dialogName, m_dialogURL, xCmdEnv );
            }
        }
        catch (lang::WrappedTargetException & exc) {
            // unwrap WrappedTargetException:
            ::cppu::throwException( exc.TargetException );
        }
    }
}

} // anon namespace

namespace sdecl = comphelper::service_decl;
extern sdecl::ServiceDecl const serviceDecl(
    sdecl::class_<BackendImpl, sdecl::with_args<true> >(),
    "com.sun.star.comp.deployment.script.PackageRegistryBackend",
    BACKEND_SERVICE_NAME );

} // namespace script
} // namespace backend
} // namespace dp_registry

<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "heap.h"
#include "dbug.h"
#include <rtdefs.h>
#include <RTcmix.h>
#include <Instrument.h>
#include <ugens.h> // for rtcmix_warn()
#include <algorithm>
#include <assert.h>

RTQueue::~RTQueue()
{
	for (InstrumentListIterator it = mInstrumentList.begin();
		 it != mInstrumentList.end();
		 ++it) {
		(*it).second->unref();
	}
}

bool RTQueue::sortElems (const RTQueue::Element& x,const RTQueue::Element& y)
{
	return (x.first < y.first);
}

// Push an element to end of the RTQueue

void RTQueue::push(Instrument *inInst, FRAMETYPE chunkstart)
{
	Element element(chunkstart, inInst);
	mInstrumentList.insert(std::upper_bound(mInstrumentList.begin(), mInstrumentList.end(), element, sortElems), element);
	inInst->ref();
}

// Pop an element of the top of the RTQueue

Instrument *	RTQueue::pop(FRAMETYPE *pChunkStart)
{
	if (mInstrumentList.empty()) {
		rtcmix_warn("rtQueue", "attempt to pop empty RTQueue\n");
		return NULL;
	}
	*pChunkStart = mInstrumentList.back().first;	// frame loc
	Instrument *outInst = mInstrumentList.back().second;	// inst
	outInst->unref();
	mInstrumentList.pop_back();
	return outInst;
}

// Return the starting sample chunk of the top Instrument

FRAMETYPE RTQueue::nextChunk()
{
	return mInstrumentList.back().first;
}

void RTQueue::print() {

}

<commit_msg>FIxed ordering mistake in inst queue.<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "heap.h"
#include "dbug.h"
#include <rtdefs.h>
#include <RTcmix.h>
#include <Instrument.h>
#include <ugens.h> // for rtcmix_warn()
#include <algorithm>
#include <assert.h>

RTQueue::~RTQueue()
{
	for (InstrumentListIterator it = mInstrumentList.begin();
		 it != mInstrumentList.end();
		 ++it) {
		(*it).second->unref();
	}
}

bool RTQueue::sortElems (const RTQueue::Element& x,const RTQueue::Element& y)
{
	return (x.first > y.first);
}

// Push an element to end of the RTQueue

void RTQueue::push(Instrument *inInst, FRAMETYPE chunkstart)
{
	Element element(chunkstart, inInst);
	mInstrumentList.insert(std::lower_bound(mInstrumentList.begin(), mInstrumentList.end(), element, sortElems), element);
	inInst->ref();
}

// Pop an element of the top of the RTQueue

Instrument *	RTQueue::pop(FRAMETYPE *pChunkStart)
{
	if (mInstrumentList.empty()) {
		rtcmix_warn("rtQueue", "attempt to pop empty RTQueue\n");
		return NULL;
	}
	*pChunkStart = mInstrumentList.back().first;	// frame loc
	Instrument *outInst = mInstrumentList.back().second;	// inst
	outInst->unref();
	mInstrumentList.pop_back();
	return outInst;
}

// Return the starting sample chunk of the top Instrument

FRAMETYPE RTQueue::nextChunk()
{
	return mInstrumentList.back().first;
}

void RTQueue::print() {

}

<|endoftext|>


<commit_before>/*
 The MIT License (MIT)

 Copyright (c) [2016] [BTC.COM]

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
#include "EthConsensus.h"

#include <algorithm>
#include <glog/logging.h>

// The hard fork Constantinople of Ethereum mainnet
int EthConsensus::kHardForkConstantinopleHeight_ = 7280000;

void EthConsensus::setHardForkConstantinopleHeight(int height) {
  kHardForkConstantinopleHeight_ = height;
  LOG(INFO) << "Height of Ethereum Constantinople Hard Fork: "
            << kHardForkConstantinopleHeight_;
}

EthConsensus::Chain EthConsensus::getChain(std::string chainStr) {
  // toupper
  std::transform(chainStr.begin(), chainStr.end(), chainStr.begin(), ::toupper);

  if (chainStr == "CLASSIC") {
    return Chain::CLASSIC;
  } else if (chainStr == "FOUNDATION") {
    return Chain::FOUNDATION;
  } else {
    return Chain::UNKNOWN;
  }
}

std::string EthConsensus::getChainStr(const Chain chain) {
  switch (chain) {
  case Chain::CLASSIC:
    return "CLASSIC";
  case Chain::FOUNDATION:
    return "FOUNDATION";
  case Chain::UNKNOWN:
    return "UNKNOWN";
  }
  // should not be here
  return "UNKNOWN";
}

// The "static" block reward for the winning block.
// Uncle block rewards are not included.
int64_t EthConsensus::getStaticBlockReward(int nHeight, Chain chain) {
  switch (chain) {
  case Chain::CLASSIC:
    return getStaticBlockRewardClassic(nHeight);
  case Chain::FOUNDATION:
    return getStaticBlockRewardFoundation(nHeight);
  case Chain::UNKNOWN:
    return 0;
  }
  // should not be here
  return 0;
}

// static block rewards of Ethereum Classic Main Network
// The implementation followed ECIP-1017:
// https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1017.md
int64_t EthConsensus::getStaticBlockRewardClassic(int nHeight) {
  const int64_t blockEra = (nHeight - 1) / 5000000 + 1;

  // The blockEra is 2 in 2018.
  // Avoid calculations by giving the result directly.
  if (blockEra == 2) {
    return 4e+18;
  }

  int64_t reward = 5e+18;

  for (int i = 1; i < blockEra; i++) {
    // ECIP-1017: all rewards will be reduced at a constant rate of 20% upon
    // entering a new Era. reward *= 0.8 (avoid converts to float)
    reward = reward * 8 / 10;
  }

  return reward;
}

// static block rewards of Ethereum Main Network
int64_t EthConsensus::getStaticBlockRewardFoundation(int nHeight) {
  // Constantinople fork at block 7080000 on Mainnet.
  if (nHeight >= kHardForkConstantinopleHeight_) {
    return 2e+18;
  }
  // Ethereum Main Network has a static block reward (3 Ether) before height
  // 7080000.
  return 3e+18;
}

double EthConsensus::getUncleBlockRewardRatio(int nHeight, Chain chain) {
  switch (chain) {
  case Chain::CLASSIC:
    return getUncleBlockRewardRatioClassic(nHeight);
  case Chain::FOUNDATION:
    return getUncleBlockRewardRatioFoundation(nHeight);
  case Chain::UNKNOWN:
    return 0.0;
  }
  // should not be here
  return 0.0;
}

// uncle block reward radio of Ethereum Classic Main Network
// The implementation followed ECIP-1017:
// https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1017.md
double EthConsensus::getUncleBlockRewardRatioClassic(int nHeight) {
  // Assume that there is only one height lower than the main chain block

  const int64_t blockEra = (nHeight - 1) / 5000000 + 1;

  if (blockEra == 1) {
    // The blockEra 1 is special
    return 7.0 / 8.0;
  } else if (blockEra == 2) {
    // The blockEra is 2 in 2018.
    // Avoid calculations by giving the result directly.
    return 1.0 / 32.0;
  }

  double radio = 1.0 / 32.0;

  for (int i = 2; i < blockEra; i++) {
    // ECIP-1017: all rewards will be reduced at a constant rate of 20% upon
    // entering a new Era.
    radio *= 0.8;
  }

  return radio;
}

double EthConsensus::getUncleBlockRewardRatioFoundation(int /*nHeight*/) {
  // Assume that there is only one height lower than the main chain block
  return 7.0 / 8.0;
}
<commit_msg>amend etc block reward<commit_after>/*
 The MIT License (MIT)

 Copyright (c) [2016] [BTC.COM]

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
#include "EthConsensus.h"

#include <algorithm>
#include <glog/logging.h>

// The hard fork Constantinople of Ethereum mainnet
int EthConsensus::kHardForkConstantinopleHeight_ = 7280000;

void EthConsensus::setHardForkConstantinopleHeight(int height) {
  kHardForkConstantinopleHeight_ = height;
  LOG(INFO) << "Height of Ethereum Constantinople Hard Fork: "
            << kHardForkConstantinopleHeight_;
}

EthConsensus::Chain EthConsensus::getChain(std::string chainStr) {
  // toupper
  std::transform(chainStr.begin(), chainStr.end(), chainStr.begin(), ::toupper);

  if (chainStr == "CLASSIC") {
    return Chain::CLASSIC;
  } else if (chainStr == "FOUNDATION") {
    return Chain::FOUNDATION;
  } else {
    return Chain::UNKNOWN;
  }
}

std::string EthConsensus::getChainStr(const Chain chain) {
  switch (chain) {
  case Chain::CLASSIC:
    return "CLASSIC";
  case Chain::FOUNDATION:
    return "FOUNDATION";
  case Chain::UNKNOWN:
    return "UNKNOWN";
  }
  // should not be here
  return "UNKNOWN";
}

// The "static" block reward for the winning block.
// Uncle block rewards are not included.
int64_t EthConsensus::getStaticBlockReward(int nHeight, Chain chain) {
  switch (chain) {
  case Chain::CLASSIC:
    return getStaticBlockRewardClassic(nHeight);
  case Chain::FOUNDATION:
    return getStaticBlockRewardFoundation(nHeight);
  case Chain::UNKNOWN:
    return 0;
  }
  // should not be here
  return 0;
}

// static block rewards of Ethereum Classic Main Network
// The implementation followed ECIP-1017:
// https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1017.md
int64_t EthConsensus::getStaticBlockRewardClassic(int nHeight) {
  const int64_t blockEra = (nHeight - 1) / 5000000 + 1;

  // The blockEra is 2 in 2018.
  // Avoid calculations by giving the result directly.
  if (blockEra == 2) {
    return 4e+18;
  }

  int64_t reward = 5e+18;

  for (int i = 1; i < blockEra; i++) {
    // ECIP-1017: all rewards will be reduced at a constant rate of 20% upon
    // entering a new Era. reward *= 0.8 (avoid converts to float)
    reward = reward * 0.8;
  }

  return reward;
}

// static block rewards of Ethereum Main Network
int64_t EthConsensus::getStaticBlockRewardFoundation(int nHeight) {
  // Constantinople fork at block 7080000 on Mainnet.
  if (nHeight >= kHardForkConstantinopleHeight_) {
    return 2e+18;
  }
  // Ethereum Main Network has a static block reward (3 Ether) before height
  // 7080000.
  return 3e+18;
}

double EthConsensus::getUncleBlockRewardRatio(int nHeight, Chain chain) {
  switch (chain) {
  case Chain::CLASSIC:
    return getUncleBlockRewardRatioClassic(nHeight);
  case Chain::FOUNDATION:
    return getUncleBlockRewardRatioFoundation(nHeight);
  case Chain::UNKNOWN:
    return 0.0;
  }
  // should not be here
  return 0.0;
}

// uncle block reward radio of Ethereum Classic Main Network
// The implementation followed ECIP-1017:
// https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1017.md
double EthConsensus::getUncleBlockRewardRatioClassic(int nHeight) {
  // Assume that there is only one height lower than the main chain block

  const int64_t blockEra = (nHeight - 1) / 5000000 + 1;

  if (blockEra == 1) {
    // The blockEra 1 is special
    return 7.0 / 8.0;
  } else if (blockEra == 2) {
    // The blockEra is 2 in 2018.
    // Avoid calculations by giving the result directly.
    return 1.0 / 32.0;
  }

  double radio = 1.0 / 32.0;

  for (int i = 2; i < blockEra; i++) {
    // ECIP-1017: all rewards will be reduced at a constant rate of 20% upon
    // entering a new Era.
    radio *= 0.8;
  }

  return radio;
}

double EthConsensus::getUncleBlockRewardRatioFoundation(int /*nHeight*/) {
  // Assume that there is only one height lower than the main chain block
  return 7.0 / 8.0;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 DeepCortex GmbH <legal@eventql.io>
 * Authors:
 *   - Laura Schlimmer <laura@eventql.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include <iostream>
#include <unistd.h>
#include "eventql/eventql.h"
#include "eventql/util/application.h"
#include "eventql/util/io/inputstream.h"
#include "eventql/util/io/TerminalOutputStream.h"
#include "eventql/util/cli/flagparser.h"
#include "eventql/cli/benchmark.h"

int main(int argc, const char** argv) {
  cli::FlagParser flags;

  flags.defineFlag(
      "host",
      cli::FlagParser::T_STRING,
      false,
      "h",
      "localhost",
      "eventql server hostname",
      "<host>");

  flags.defineFlag(
      "port",
      cli::FlagParser::T_INTEGER,
      false,
      "p",
      "9175",
      "eventql server port",
      "<port>");

  flags.defineFlag(
      "database",
      cli::FlagParser::T_STRING,
      false,
      "d",
      NULL,
      "database",
      "<db>");

  flags.defineFlag(
      "connections",
      cli::FlagParser::T_INTEGER,
      false,
      "c",
      "10",
      "number of connections",
      "<threads>");

  flags.defineFlag(
      "rate",
      cli::FlagParser::T_INTEGER,
      false,
      "r",
      "1",
      "number of requests per second",
      "<rate>");

  flags.defineFlag(
      "num",
      cli::FlagParser::T_INTEGER,
      false,
      "n",
      NULL,
      "total number of request (inifite if unset)",
      "<rate>");

  flags.defineFlag(
      "help",
      cli::FlagParser::T_SWITCH,
      false,
      "?",
      NULL,
      "help",
      "<help>");

  flags.defineFlag(
      "version",
      cli::FlagParser::T_SWITCH,
      false,
      "v",
      NULL,
      "print version",
      "<switch>");

  Application::init();
  auto stdout_os = TerminalOutputStream::fromStream(OutputStream::getStdout());

  try {
    flags.parseArgv(argc, argv);
  } catch (const std::exception& e) {
    std::cerr << StringUtil::format("ERROR: $0\n", e.what());
    return 1;
  }

  Vector<String> cmd_argv = flags.getArgv();
  bool print_help = flags.isSet("help");
  bool print_version = flags.isSet("version");
  if (print_version || print_help) {
    stdout_os->print(
        StringUtil::format(
            "EventQL $0 ($1)\n"
            "Copyright (c) 2016, DeepCortex GmbH. All rights reserved.\n\n",
            eventql::kVersionString,
            eventql::kBuildID));
  }

  if (print_version) {
    return 1;
  }

  if (print_help) {
    stdout_os->print(
        "Usage: $ evqlslap [OPTIONS]\n\n"
        "   -h, --host <hostname>     Set the EventQL server hostname\n"
        "   -p, --port <port>         Set the EventQL server port\n"
        "   -D, --database <db>       Select a database\n"
        "   -c, --connections <num>   Number of concurrent connections\n"
        "   -r, --rate <rate>         Maximum rate of requests in RPS\n"
        "   -n, --num <num>           Maximum total number of request (default is inifite)\n"
        "   -?, --help                Display the help text and exit\n"
        "   -v, --version             Display the version of this binary and exit\n");

    return 1;
  }

  auto request_handler = []() {
    usleep(1000);
    return ReturnCode::success();
  };

  auto num = flags.isSet("num") ? flags.getInt("num") : -1;
  auto on_progress = [&stdout_os, &num](eventql::cli::BenchmarkStats* stats) {
    try {
      stdout_os->eraseLine();
      auto line = StringUtil::format(
          "\rRunning... rate=$0r/s, avg_runtime=$1ms, total=$2",
          stats->getRollingRPS(),
          stats->getRollingAverageRuntime() / double(kMicrosPerMilli),
          stats->getTotalRequestCount());

      if (num > 0) {
        line += StringUtil::format(
            " ($0%)",
            double(stats->getTotalRequestCount()) / double(num) * 100.0);
      }

      line += StringUtil::format(
          ", running=$0, errors=$1 ($2%)",
          stats->getRunningRequestCount(),
          stats->getTotalErrorCount(),
          stats->getTotalErrorRate() * 100.0f);
      stdout_os->print(line);
    } catch (const std::exception& e) {
      /* fallthrough */
    }
  };

  eventql::cli::Benchmark benchmark(
      flags.getInt("connections"),
      flags.getInt("rate"),
      num);

  benchmark.setRequestHandler(request_handler);
  benchmark.setProgressCallback(on_progress);
  benchmark.setProgressRateLimit(kMicrosPerSecond / 10);

  auto rc = benchmark.connect(
      flags.getString("host"),
      flags.getInt("port"),
      {});

  if (rc.isSuccess()) {
    rc = benchmark.run();
  }

  stdout_os->eraseLine();

  if (rc.isSuccess()) {
    std::cout << "success" << std::endl;
    return 0;
  } else {
    std::cerr << "ERROR: " << rc.getMessage() << std::endl;
    return 1;
  }

  return 0;
}

<commit_msg>better number formatting<commit_after>/**
 * Copyright (c) 2016 DeepCortex GmbH <legal@eventql.io>
 * Authors:
 *   - Laura Schlimmer <laura@eventql.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include <iostream>
#include <unistd.h>
#include "eventql/eventql.h"
#include "eventql/util/application.h"
#include "eventql/util/io/inputstream.h"
#include "eventql/util/io/TerminalOutputStream.h"
#include "eventql/util/cli/flagparser.h"
#include "eventql/cli/benchmark.h"

int main(int argc, const char** argv) {
  cli::FlagParser flags;

  flags.defineFlag(
      "host",
      cli::FlagParser::T_STRING,
      false,
      "h",
      "localhost",
      "eventql server hostname",
      "<host>");

  flags.defineFlag(
      "port",
      cli::FlagParser::T_INTEGER,
      false,
      "p",
      "9175",
      "eventql server port",
      "<port>");

  flags.defineFlag(
      "database",
      cli::FlagParser::T_STRING,
      false,
      "d",
      NULL,
      "database",
      "<db>");

  flags.defineFlag(
      "connections",
      cli::FlagParser::T_INTEGER,
      false,
      "c",
      "10",
      "number of connections",
      "<threads>");

  flags.defineFlag(
      "rate",
      cli::FlagParser::T_INTEGER,
      false,
      "r",
      "1",
      "number of requests per second",
      "<rate>");

  flags.defineFlag(
      "num",
      cli::FlagParser::T_INTEGER,
      false,
      "n",
      NULL,
      "total number of request (inifite if unset)",
      "<rate>");

  flags.defineFlag(
      "help",
      cli::FlagParser::T_SWITCH,
      false,
      "?",
      NULL,
      "help",
      "<help>");

  flags.defineFlag(
      "version",
      cli::FlagParser::T_SWITCH,
      false,
      "v",
      NULL,
      "print version",
      "<switch>");

  Application::init();
  auto stdout_os = TerminalOutputStream::fromStream(OutputStream::getStdout());

  try {
    flags.parseArgv(argc, argv);
  } catch (const std::exception& e) {
    std::cerr << StringUtil::format("ERROR: $0\n", e.what());
    return 1;
  }

  Vector<String> cmd_argv = flags.getArgv();
  bool print_help = flags.isSet("help");
  bool print_version = flags.isSet("version");
  if (print_version || print_help) {
    stdout_os->print(
        StringUtil::format(
            "EventQL $0 ($1)\n"
            "Copyright (c) 2016, DeepCortex GmbH. All rights reserved.\n\n",
            eventql::kVersionString,
            eventql::kBuildID));
  }

  if (print_version) {
    return 1;
  }

  if (print_help) {
    stdout_os->print(
        "Usage: $ evqlslap [OPTIONS]\n\n"
        "   -h, --host <hostname>     Set the EventQL server hostname\n"
        "   -p, --port <port>         Set the EventQL server port\n"
        "   -D, --database <db>       Select a database\n"
        "   -c, --connections <num>   Number of concurrent connections\n"
        "   -r, --rate <rate>         Maximum rate of requests in RPS\n"
        "   -n, --num <num>           Maximum total number of request (default is inifite)\n"
        "   -?, --help                Display the help text and exit\n"
        "   -v, --version             Display the version of this binary and exit\n");

    return 1;
  }

  auto request_handler = []() {
    usleep(1000);
    return ReturnCode::success();
  };

  auto num = flags.isSet("num") ? flags.getInt("num") : -1;
  auto on_progress = [&stdout_os, &num](eventql::cli::BenchmarkStats* stats) {
    fprintf(
        stdout,
        "\rRunning... rate=%7.4fr/s, avg_runtime=%4.4fms, total=%llu",
        stats->getRollingRPS(),
        stats->getRollingAverageRuntime() / double(kMicrosPerMilli),
        stats->getTotalRequestCount());

    if (num > 0) {
      fprintf(
          stdout,
          " (%2.2f%%)",
          double(stats->getTotalRequestCount()) / double(num) * 100.0);
    }

    fprintf(
        stdout,
        ", running=%llu, errors=%llu (%2.3f%%)",
        stats->getRunningRequestCount(),
        stats->getTotalErrorCount(),
        stats->getTotalErrorRate() * 100.0f);
    fflush(stdout);
  };

  eventql::cli::Benchmark benchmark(
      flags.getInt("connections"),
      flags.getInt("rate"),
      num);

  benchmark.setRequestHandler(request_handler);
  benchmark.setProgressCallback(on_progress);
  benchmark.setProgressRateLimit(kMicrosPerSecond / 10);

  auto rc = benchmark.connect(
      flags.getString("host"),
      flags.getInt("port"),
      {});

  if (rc.isSuccess()) {
    rc = benchmark.run();
  }

  if (rc.isSuccess()) {
    std::cout << "\nsuccess" << std::endl;
    return 0;
  } else {
    std::cerr << "ERROR: " << rc.getMessage() << std::endl;
    return 1;
  }

  return 0;
}

<|endoftext|>


<commit_before>/* peer.cc
   Mathieu Stefani, 12 August 2015

*/

#include <iostream>
#include <stdexcept>

#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <pistache/async.h>
#include <pistache/peer.h>
#include <pistache/transport.h>

namespace Pistache {
namespace Tcp {

namespace {
struct ConcretePeer : Peer {
  ConcretePeer() = default;
  ConcretePeer(Fd fd, const Address &addr, void *ssl) : Peer(fd, addr, ssl) {}
};
} // namespace

Peer::Peer(Fd fd, const Address &addr, void *ssl)
    : fd_(fd), addr(addr), ssl_(ssl) {}

Peer::~Peer() {
#ifdef PISTACHE_USE_SSL
  if (ssl_)
    SSL_free(static_cast<SSL *>(ssl_));
#endif /* PISTACHE_USE_SSL */
}

std::shared_ptr<Peer> Peer::Create(Fd fd, const Address &addr) {
  return std::make_shared<ConcretePeer>(fd, addr, nullptr);
}

std::shared_ptr<Peer> Peer::CreateSSL(Fd fd, const Address &addr, void *ssl) {
  return std::make_shared<ConcretePeer>(fd, addr, ssl);
}

const Address &Peer::address() const { return addr; }

const std::string &Peer::hostname() {
  if (hostname_.empty()) {
    char host[NI_MAXHOST];
    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    if (inet_pton(AF_INET, addr.host().c_str(), &sa.sin_addr) == 0) {
      hostname_ = addr.host();
    } else {
      if (!getnameinfo((struct sockaddr *)&sa, sizeof(sa), host, sizeof(host),
                       NULL, 0 // Service info
                       ,
                       NI_NAMEREQD // Raise an error if name resolution failed
                       )) {
        hostname_.assign((char *)host);
      }
    }
  }
  return hostname_;
}

#ifdef PISTACHE_USE_SSL
void *Peer::ssl() const { return ssl_; }
#endif /* PISTACHE_USE_SSL */

int Peer::fd() const {
  if (fd_ == -1) {
    throw std::runtime_error("The peer has no associated fd");
  }

  return fd_;
}

void Peer::putData(std::string name,
                   std::shared_ptr<Pistache::Http::Private::ParserBase> data) {
  auto it = data_.find(name);
  if (it != std::end(data_)) {
    throw std::runtime_error("The data already exists");
  }

  data_.insert(std::make_pair(std::move(name), std::move(data)));
}

std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::getData(std::string name) const {
  auto data = tryGetData(std::move(name));
  if (data == nullptr) {
    throw std::runtime_error("The data does not exist");
  }

  return data;
}

std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::tryGetData(std::string(name)) const {
  auto it = data_.find(name);
  if (it == std::end(data_))
    return nullptr;

  return it->second;
}

Async::Promise<ssize_t> Peer::send(const RawBuffer &buffer, int flags) {
  return transport()->asyncWrite(fd_, buffer, flags);
}

std::ostream &operator<<(std::ostream &os, Peer &peer) {
  const auto &addr = peer.address();
  os << "(" << addr.host() << ", " << addr.port() << ") [" << peer.hostname()
     << "]";
  return os;
}

void Peer::associateTransport(Transport *transport) { transport_ = transport; }

Transport *Peer::transport() const {
  if (!transport_)
    throw std::logic_error("Orphaned peer");

  return transport_;
}

} // namespace Tcp
} // namespace Pistache
<commit_msg>Delete useless ifdef in peer.cc<commit_after>/* peer.cc
   Mathieu Stefani, 12 August 2015

*/

#include <iostream>
#include <stdexcept>

#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <pistache/async.h>
#include <pistache/peer.h>
#include <pistache/transport.h>

namespace Pistache {
namespace Tcp {

namespace {
struct ConcretePeer : Peer {
  ConcretePeer() = default;
  ConcretePeer(Fd fd, const Address &addr, void *ssl) : Peer(fd, addr, ssl) {}
};
} // namespace

Peer::Peer(Fd fd, const Address &addr, void *ssl)
    : fd_(fd), addr(addr), ssl_(ssl) {}

Peer::~Peer() {
#ifdef PISTACHE_USE_SSL
  if (ssl_)
    SSL_free(static_cast<SSL *>(ssl_));
#endif /* PISTACHE_USE_SSL */
}

std::shared_ptr<Peer> Peer::Create(Fd fd, const Address &addr) {
  return std::make_shared<ConcretePeer>(fd, addr, nullptr);
}

std::shared_ptr<Peer> Peer::CreateSSL(Fd fd, const Address &addr, void *ssl) {
  return std::make_shared<ConcretePeer>(fd, addr, ssl);
}

const Address &Peer::address() const { return addr; }

const std::string &Peer::hostname() {
  if (hostname_.empty()) {
    char host[NI_MAXHOST];
    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    if (inet_pton(AF_INET, addr.host().c_str(), &sa.sin_addr) == 0) {
      hostname_ = addr.host();
    } else {
      if (!getnameinfo((struct sockaddr *)&sa, sizeof(sa), host, sizeof(host),
                       NULL, 0 // Service info
                       ,
                       NI_NAMEREQD // Raise an error if name resolution failed
                       )) {
        hostname_.assign((char *)host);
      }
    }
  }
  return hostname_;
}

void *Peer::ssl() const { return ssl_; }

int Peer::fd() const {
  if (fd_ == -1) {
    throw std::runtime_error("The peer has no associated fd");
  }

  return fd_;
}

void Peer::putData(std::string name,
                   std::shared_ptr<Pistache::Http::Private::ParserBase> data) {
  auto it = data_.find(name);
  if (it != std::end(data_)) {
    throw std::runtime_error("The data already exists");
  }

  data_.insert(std::make_pair(std::move(name), std::move(data)));
}

std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::getData(std::string name) const {
  auto data = tryGetData(std::move(name));
  if (data == nullptr) {
    throw std::runtime_error("The data does not exist");
  }

  return data;
}

std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::tryGetData(std::string(name)) const {
  auto it = data_.find(name);
  if (it == std::end(data_))
    return nullptr;

  return it->second;
}

Async::Promise<ssize_t> Peer::send(const RawBuffer &buffer, int flags) {
  return transport()->asyncWrite(fd_, buffer, flags);
}

std::ostream &operator<<(std::ostream &os, Peer &peer) {
  const auto &addr = peer.address();
  os << "(" << addr.host() << ", " << addr.port() << ") [" << peer.hostname()
     << "]";
  return os;
}

void Peer::associateTransport(Transport *transport) { transport_ = transport; }

Transport *Peer::transport() const {
  if (!transport_)
    throw std::logic_error("Orphaned peer");

  return transport_;
}

} // namespace Tcp
} // namespace Pistache
<|endoftext|>