<commit_before>//
//  Sound.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 04/11/2020.
//  Copyright © 2020 Thomas Harte. All rights reserved.
//

#include "Sound.hpp"

#include <cstdio>

using namespace Apple::IIgs::Sound;

void GLU::set_control(uint8_t control) {
	printf("UNIMPLEMENTED: set control %02x\n", control);
}

uint8_t GLU::get_control() {
	return 0;
}

void GLU::set_data(uint8_t data) {
	printf("UNIMPLEMENTED: set data %02x\n", data);
}

uint8_t GLU::get_data() {
	return 0;
}

void GLU::set_address_low(uint8_t low) {
	address_ = uint16_t((address_ & 0xff00) | low);
}

uint8_t GLU::get_address_low() {
	return address_ & 0xff;
}

void GLU::set_address_high(uint8_t high) {
	address_ = uint16_t((high << 8) | (address_ & 0x00ff));
}

uint8_t GLU::get_address_high() {
	return address_ >> 8;
}
<commit_msg>Quietens, for now.<commit_after>//
//  Sound.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 04/11/2020.
//  Copyright © 2020 Thomas Harte. All rights reserved.
//

#include "Sound.hpp"

#include <cstdio>

using namespace Apple::IIgs::Sound;

void GLU::set_control(uint8_t control) {
//	printf("UNIMPLEMENTED: set control %02x\n", control);
}

uint8_t GLU::get_control() {
	return 0;
}

void GLU::set_data(uint8_t data) {
//	printf("UNIMPLEMENTED: set data %02x\n", data);
}

uint8_t GLU::get_data() {
	return 0;
}

void GLU::set_address_low(uint8_t low) {
	address_ = uint16_t((address_ & 0xff00) | low);
}

uint8_t GLU::get_address_low() {
	return address_ & 0xff;
}

void GLU::set_address_high(uint8_t high) {
	address_ = uint16_t((high << 8) | (address_ & 0x00ff));
}

uint8_t GLU::get_address_high() {
	return address_ >> 8;
}
<|endoftext|>


<commit_before>#ifndef UD_IMARKER
#define UD_IMARKER

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

#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#include <sensor_msgs/PointCloud2.h>
#include <std_msgs/String.h>
#include <geometry_msgs/PointStamped.h>

#include <interactive_markers/interactive_marker_server.h>
#include <interactive_markers/menu_handler.h>

#include <pcl/io/pcd_io.h>
#include <pcl/io/vtk_io.h>
#include <pcl/io/ply_io.h>

#include <pcl_ros/point_cloud.h>
#include <pcl/ros/conversions.h>

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/search/kdtree.h>

#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/crop_box.h>

#include <pcl/filters/extract_indices.h>

#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/ModelCoefficients.h>

#include <pcl/features/normal_3d.h>
#include <pcl/features/normal_3d_omp.h>

#include <pcl/surface/mls.h>
#include <pcl/surface/gp3.h>
#include <pcl/surface/poisson.h>
#include <pcl/surface/marching_cubes_rbf.h>

#include <Eigen/Core>

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

#include <cmath>
#include <vector>
#include <math.h>

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

typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloudT;

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

using namespace std;
using namespace visualization_msgs;
using namespace interactive_markers;
using namespace pcl;

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

void plane_slice(pcl::PointCloud<pcl::PointXYZ> &,
		 pcl::PointCloud<pcl::PointXYZ> &,
		 pcl::PointCloud<pcl::PointXYZ> &,
		 pcl::ModelCoefficients &,
		 double);

bool robust_plane_fit(pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::ModelCoefficients &,
		      double);

void cylinder_slice(pcl::PointCloud<pcl::PointXYZ> &,
		    pcl::PointCloud<pcl::PointXYZ> &,
		    pcl::PointCloud<pcl::PointXYZ> &,
		    pcl::ModelCoefficients &,
		    double,
		    double, double);

bool robust_line_fit(pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::ModelCoefficients &,
		      double);

bool robust_cylinder_fit(pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::ModelCoefficients &,
			 double);

bool robust_circle_fit(pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::ModelCoefficients &,
			 double,
                         double);

void compute_line_limits(pcl::PointCloud<pcl::PointXYZ>::Ptr,
			 pcl::ModelCoefficients &,
			 double &, double &);

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

#endif
<commit_msg>Update ud_imarker.hh<commit_after>#ifndef UD_IMARKER
#define UD_IMARKER

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

#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#include <sensor_msgs/PointCloud2.h>
#include <std_msgs/String.h>
#include <geometry_msgs/PointStamped.h>

#include <interactive_markers/interactive_marker_server.h>
#include <interactive_markers/menu_handler.h>

#include <pcl/io/pcd_io.h>
#include <pcl/io/vtk_io.h>
#include <pcl/io/ply_io.h>

#include <pcl_ros/point_cloud.h>
#include <pcl/ros/conversions.h>

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/search/kdtree.h>

#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/crop_box.h>

#include <pcl/filters/extract_indices.h>

#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/ModelCoefficients.h>

#include <pcl/features/normal_3d.h>
#include <pcl/features/normal_3d_omp.h>

#include <pcl/surface/mls.h>
#include <pcl/surface/gp3.h>
#include <pcl/surface/poisson.h>
#include <pcl/surface/marching_cubes_rbf.h>

#include <Eigen/Core>

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

#include <cmath>
#include <vector>
#include <math.h>

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

typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloudT;

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

using namespace std;
using namespace visualization_msgs;
using namespace interactive_markers;
using namespace pcl;

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

void plane_slice(pcl::PointCloud<pcl::PointXYZ> &,
		 pcl::PointCloud<pcl::PointXYZ> &,
		 pcl::PointCloud<pcl::PointXYZ> &,
		 pcl::ModelCoefficients &,
		 double);

bool robust_plane_fit(pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::ModelCoefficients &,
		      double);

void cylinder_slice(pcl::PointCloud<pcl::PointXYZ> &,
		    pcl::PointCloud<pcl::PointXYZ> &,
		    pcl::PointCloud<pcl::PointXYZ> &,
		    pcl::ModelCoefficients &,
		    double,
		    double,
		    double);

bool robust_line_fit(pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::PointCloud<pcl::PointXYZ> &,
		      pcl::ModelCoefficients &,
		      double);

bool robust_cylinder_fit(pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::ModelCoefficients &,
			 double);

bool robust_circle_fit(pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::PointCloud<pcl::PointXYZ> &,
			 pcl::ModelCoefficients &,
			 double,
                         double);

void compute_line_limits(pcl::PointCloud<pcl::PointXYZ>::Ptr,
			 pcl::ModelCoefficients &,
			 double &, double &);

void change_color (pcl::PointCloud<pcl::PointXYZRGB> &,
                         int,
                         int,
                         int)
void segment_color(pcl::PointCloud<pcl::PointXYZRGB> &,
                         pcl::PointIndices::Ptr,
                         int,
                         int)

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

#endif
<|endoftext|>


<commit_before>// RobotBuilder Version: 2.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// C++ from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.

#include "Climber.h"
#include "../RobotMap.h"

Climber::Climber() : Subsystem("Climber") {
    rightMotor = RobotMap::climberRightMotor;
    leftMotor = RobotMap::climberLeftMotor;
    robotDrive21 = RobotMap::climberRobotDrive21;
}

void Climber::InitDefaultCommand() {
	rightMotor->Set(0.0);
	leftMotor->Set(0.0);
}

void Climber::Climb(){
	rightMotor->Set(0.5);
	leftMotor->Set(-0.5);
}

void Climber::ReverseClimb(){
	rightMotor->Set(-0.5);
	leftMotor->Set(0.5);
}
<commit_msg>Only One Motor While Climbing<commit_after>// RobotBuilder Version: 2.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// C++ from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.

#include "Climber.h"
#include "../RobotMap.h"

Climber::Climber() : Subsystem("Climber") {
    rightMotor = RobotMap::climberRightMotor;
    leftMotor = RobotMap::climberLeftMotor;
    robotDrive21 = RobotMap::climberRobotDrive21;
}

void Climber::InitDefaultCommand() {
	leftMotor->Set(0.0);
}

void Climber::Climb(){
	leftMotor->Set(-0.5);
}

void Climber::ReverseClimb(){
	leftMotor->Set(0.5);
}
<|endoftext|>


<commit_before>
#include "BacterialColony.h"
#include "BacterialColonyRedrawCommand.h"
#include "BacterialColonyGUI.h"
#include "CellsViewer.h"
#include "CommandEvents.h"
#include "CellsViewerCommand.h"
#include "itkMetaImageIOFactory.h"
#include "itkPNGImageIOFactory.h"

int main()
{

  // Register factories for expected image file formats
  itk::MetaImageIOFactory::RegisterOneFactory();
  itk::PNGImageIOFactory::RegisterOneFactory();

  bio::CellsViewer * viewer = new bio::CellsViewer;

  bio::BacterialColony::Pointer  colony = bio::BacterialColony::New();

  bio::CellsViewerCommand::Pointer viewerCommand =
                                          bio::CellsViewerCommand::New();

  viewerCommand->SetCellsViewer( viewer );

  itk::Command::Pointer redrawCommand = viewer->GetRedrawCommand();
  colony->AddObserver( bio::TimeStepEvent(), redrawCommand );

  colony->AddObserver( bio::TimeStepEvent(), viewerCommand );

  viewer->SetCellsAggregate( colony );

  bio::BacterialColonyRedrawCommand::Pointer colonyRedrawCommand =
                                    bio::BacterialColonyRedrawCommand::New();

  colonyRedrawCommand->SetBacterialColony( colony );

  viewer->GetNotifier()->AddObserver( fltk::GlDrawEvent(), colonyRedrawCommand );

  colony->SetGrowthRadiusIncrement( 0.01 );

  bio::Bacteria * first = new bio::Bacteria;

  colony->Add( first );

  viewer->Show();

  try
    {
    Fl::run();
    delete viewer;
    }
  catch( itk::ExceptionObject & exception )
    {
    std::cout << "Exception caught !" << std::endl;
    std::cout << "Description : " << exception.GetDescription() << std::endl;
    std::cout << "Location    : " << exception.GetLocation()    << std::endl;
    }

  return 0;

}

<commit_msg>ENH: Several species added in the same interface.<commit_after>
#include "BacterialColony.h"
#include "BacterialColonyGUI.h"
#include "Eukariote.h"
#include "PressureSensitiveBacteria.h"
#include "GradientEatingBacteria.h"
#include "CellsViewer.h"
#include "CommandEvents.h"
#include "CellsViewerCommand.h"
#include "itkMetaImageIOFactory.h"
#include "itkPNGImageIOFactory.h"

int main()
{

  // Register factories for expected image file formats
  itk::MetaImageIOFactory::RegisterOneFactory();
  itk::PNGImageIOFactory::RegisterOneFactory();

  bio::CellsViewer * viewer = new bio::CellsViewer;

  bio::BacterialColony::Pointer  colony = bio::BacterialColony::New();

  bio::CellsViewerCommand::Pointer viewerCommand =
                                          bio::CellsViewerCommand::New();

  viewerCommand->SetCellsViewer( viewer );

  itk::Command::Pointer redrawCommand = viewer->GetRedrawCommand();
  colony->AddObserver( bio::TimeStepEvent(), redrawCommand );

  colony->AddObserver( bio::TimeStepEvent(), viewerCommand );

  viewer->SetCellsAggregate( colony );

  viewer->GetNotifier()->AddObserver( fltk::GlDrawEvent(),
                            colony->GetRedrawCommand().GetPointer() );

  // Add All the known species here
  viewer->AddSpeciesEggProducer(
            & bio::Prokariote::CreateEgg,
              bio::Prokariote::GetSpeciesName() );

  viewer->AddSpeciesEggProducer(
            & bio::Bacteria::CreateEgg,
              bio::Bacteria::GetSpeciesName() );

  viewer->AddSpeciesEggProducer(
            & bio::PressureSensitiveBacteria::CreateEgg,
              bio::PressureSensitiveBacteria::GetSpeciesName() );

  viewer->AddSpeciesEggProducer(
            & bio::GradientEatingBacteria::CreateEgg,
              bio::GradientEatingBacteria::GetSpeciesName() );

  viewer->AddSpeciesEggProducer(
            & bio::Eukariote::CreateEgg,
              bio::Eukariote::GetSpeciesName() );

  viewer->Show();

  try
    {
    Fl::run();
    delete viewer;
    }
  catch( itk::ExceptionObject & exception )
    {
    std::cout << "Exception caught !" << std::endl;
    std::cout << "Description : " << exception.GetDescription() << std::endl;
    std::cout << "Location    : " << exception.GetLocation()    << std::endl;
    }

  return 0;

}

<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2011 Razor team
 * Authors:
 *   Christian Surlykke <christian@surlykke.dk>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <math.h>
#include <QDebug>
#include <QtSvg/QSvgRenderer>
#include <QPainter>
#include <QProcess>
#include <QMessageBox>

#include "trayicon.h"
#include "../config/powermanagementsettings.h"

QString IconNamingScheme::iconName(float chargeLevel, bool discharging) const
{
    int i = 0;
    while(i < mChargeLevels.size() - 1 && mChargeLevels.at(i+1) <= chargeLevel) i++;

    return discharging ? mIconNamesDischarging.at(i) : mIconNamesCharging.at(i);
}

IconNamingScheme::IconNamingScheme(QString schemeName, QList<float> chargeLevels, QList<QString> iconNamesCharging, QList<QString> iconNamesDischarging)
{
    mSchemeName = schemeName;
    mChargeLevels = chargeLevels;
    mIconNamesCharging = iconNamesCharging;
    mIconNamesDischarging = iconNamesDischarging;
}

IconNamingScheme* IconNamingScheme::getNamingSchemeForCurrentIconTheme()
{
    static QList<IconNamingScheme*> schemes;

    if (schemes.isEmpty())
    {
        // Freedesktop naming scheme
         schemes << new IconNamingScheme(
                "freedesktop",
                (QList<float>() << 0 << 1 << 20 << 40 << 60),
                (QList<QString>() << "battery-empty" << "battery-caution-charging" << "battery-low-charging"
                                  << "battery-good-charging" <<  "battery-full-charging"),
                (QList<QString>() << "battery-empty" << "battery-caution" << "battery-low" << "battery-good" <<  "battery-full")
                );

         // Oxygen naming scheme
         schemes << new IconNamingScheme(
                "oxygen",
                ((QList<float>()) << 0 << 20 << 40 << 60 << 80 << 99.5),
                ((QList<QString>()) << "battery-charging-low" << "battery-charging-caution" << "battery-charging-040"
                                    << "battery-charging-060" << "battery-charging-080" << "battery-charging"),
                ((QList<QString>()) << "battery-low" << "battery-caution" << "battery-040"
                                    << "battery-060" << "battery-080" << "battery-100")
                );

         // AwOken naming scheme
         schemes << new IconNamingScheme(
                "AwOken",
                ((QList<float>()) << 0 << 20 << 40 << 60 << 80 << 99.5),
                ((QList<QString>()) << "battery-000-charging" << "battery-020-charging" << "battery-040-charging"
                                    << "battery-060-charging" << "battery-080-charging" << "battery-100-charging"),
                ((QList<QString>()) << "battery-000" << "battery-020" << "battery-040"
                                   << "battery-060" << "battery-080" << "battery-100")
                );
    }

    foreach (IconNamingScheme* iconNamingScheme, schemes)
    {
        if (iconNamingScheme->isValidForCurrentIconTheme())
        {
            qDebug() << "Found IconNamingScheme:" << iconNamingScheme->mSchemeName;
            return iconNamingScheme;
        }
    }

    qDebug() << "Found no IconNamingScheme";
    return 0;
}

bool IconNamingScheme::isValidForCurrentIconTheme() const
{
    for (int i = 0; i < mIconNamesCharging.size(); i++)
    {
        qDebug() << "Looking for"  << mIconNamesCharging.at(i);
        if (!QIcon::hasThemeIcon(mIconNamesCharging.at(i)))
        {
            qDebug() << "Not found";
            return false;
        }

        qDebug() << "Looking for"  << mIconNamesDischarging.at(i);
        if (!QIcon::hasThemeIcon(mIconNamesDischarging.at(i)))
        {
            qDebug() << "Not found";
            return false;
        }
    }
    qDebug();

    return true;
}

TrayIcon::TrayIcon(QObject *parent) : QSystemTrayIcon(parent), contextMenu()
{
    contextMenu.addAction(tr("Configure..."), this, SLOT(onConfigureTriggered()));
    contextMenu.addAction(tr("About.."), this, SLOT(onAboutTriggered()));
    setContextMenu(&contextMenu);
}

TrayIcon::~TrayIcon() {}

void TrayIcon::update(bool discharging, double chargeLevel, double lowLevel)
{
    this->discharging = discharging;
    this->chargeLevel = chargeLevel;
    this->lowLevel = lowLevel;

    updateToolTip();
    updateIcon();
}

void TrayIcon::updateToolTip()
{
    QString toolTip = discharging ? tr("discharging") : tr("charging"); // TODO Use states...
    toolTip = toolTip + QString(" - %1 %").arg(chargeLevel, 0, 'f', 1);
    setToolTip(toolTip);
}

void TrayIcon::onConfigureTriggered()
{
    QProcess::startDetached("lxqt-config-powermanagement");
}

void TrayIcon::onAboutTriggered()
{
    QMessageBox::about(0, tr("About"),
                          tr("LXQt Powermanagement:\n"
                             "Powermanagement for the LXQt Desktop Environment\n\n"
                             "Author: Christian Surlykke\n\n"
                             "Copyright 2012-2014"));
}

TrayIconBuiltIn::TrayIconBuiltIn(QObject* parent) :
    TrayIcon(parent)
{
}

TrayIconBuiltIn::~TrayIconBuiltIn()
{
}

bool TrayIconBuiltIn::isProperForCurrentSettings()
{
    return ! PowerManagementSettings().isUseThemeIcons();
}

void TrayIconBuiltIn::updateIcon()
{
    // See http://www.w3.org/TR/SVG/Overview.html
    // and regarding circle-arch in particular:
    // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands

    // We show charge with a segment of a circle.
    // We start at the top of the circle
    // The starting point of the circle segment is at the top (12 o'clock or (0,1) or pi/2
    // and it moves counter-clockwise as the charge increases
    // First we calculate in floating point numbers, using a circle with center
    // in (0,0) and a radius of 1
    double angle = 2*M_PI*chargeLevel/100 + M_PI_2;
    qDebug() << "Angle:"  << angle;
    double segment_endpoint_x = cos(angle);
    double segment_endpoint_y = sin(angle);

    // svg uses a coordinate system with (0,0) at the topmost left corner,
    // y increasing downwards and x increasing left-to-right.
    // We draw the circle segments with center at (100,100) and radius 100 for the
    // outer and radius 60 for the inner. The segments will (unless fully charged,
    // where they go full circle) be radially connected at the endpoints.
    QString chargeGraphics;

    if (chargeLevel < 0.5)
    {
        chargeGraphics = "";
    }
    else if (chargeLevel > 99.5)
    {
        chargeGraphics =
            "<path d='M 100,0 A 100,100 0 1,0 101,0 z M 100,40 A 60,60 0 1,0 101,40 z' stroke-width='0'/>";
    }
    else {
        chargeGraphics =
            QString("<path d='M 100,0 A 100,100 0 %1,0 %2,%3 L %4,%5 A 60,60 0 %1,1 100,40 z'/>")
                .arg(angle > M_PI + M_PI_2 ? 1 : 0)     // %1
                .arg(round(100*(1 + segment_endpoint_x)))    // %2
                .arg(round(100*(1 - segment_endpoint_y)))    // %3
                .arg(round(100*(1 + 0.6*segment_endpoint_x)))    // %4
                .arg(round(100*(1 - 0.6*segment_endpoint_y)));   // %5
    }

    QString chargeColor;
    if (discharging && chargeLevel <= lowLevel + 10)
    {
        chargeColor = "rgb(200,40,40)";
    }
    else if (discharging && chargeLevel <= lowLevel + 30)
    {
        int fac = chargeLevel - lowLevel - 10;
        chargeColor = QString("rgb(%1,%2,40)").arg(40 + 200 - fac*8).arg(40 + fac*8);
    }
    else
        chargeColor = "rgb(40,200,40)";

    QString sign =
            discharging ?
                QString("<path d='M 60,100 h 80' stroke='black' stroke-width='20' />"):                // Minus
                QString("<path d='M 60,100 h 80 M 100,60 v 80' stroke='black' stroke-width='20' />");  // Plus

    QString svg =
        QString("<?xml version='1.0' standalone='no'?>\n"
                "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n"
                "<svg xmlns='http://www.w3.org/2000/svg'  version='1.1' viewBox='0 0 210 210'>\n"
                "    <circle cx='100' cy='100' r='100' fill='rgb(210,210,210)' stroke-width='0'/>\n"
                "    <circle cx='100' cy='100' r='55' fill='rgb(255,255,255)' stroke-width='0'/>\n"
                "    <g fill-rule='evenodd' fill='%2' stroke-width='0'>\n"
                "        %1\n"
                "    </g>\n"
                "    %3\n"
                "</svg>\n").arg(chargeGraphics).arg(chargeColor).arg(sign);

    qDebug() << svg;

    // Paint the svg on a pixmap and create an icon from that.
    QSvgRenderer render(svg.toAscii());
    QPixmap pixmap(render.defaultSize());
    pixmap.fill(QColor(0,0,0,0));
    QPainter painter(&pixmap);
    render.render(&painter);
    setIcon(QIcon(pixmap));
}

TrayIconTheme::TrayIconTheme(IconNamingScheme* iconNamingScheme, QObject* parent)
{
    this->mIconNamingScheme = iconNamingScheme;
}

TrayIconTheme::~TrayIconTheme()
{
}

bool TrayIconTheme::isProperForCurrentSettings()
{
    return PowerManagementSettings().isUseThemeIcons() && mIconNamingScheme->isValidForCurrentIconTheme();
}

void TrayIconTheme::updateIcon()
{
    QString iconName = mIconNamingScheme->iconName(chargeLevel, discharging);
    setIcon(QIcon::fromTheme(iconName));

}
<commit_msg>Recognize Alec Moskvin as author in 'about' dialog<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2011 Razor team
 * Authors:
 *   Christian Surlykke <christian@surlykke.dk>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <math.h>
#include <QDebug>
#include <QtSvg/QSvgRenderer>
#include <QPainter>
#include <QProcess>
#include <QMessageBox>

#include "trayicon.h"
#include "../config/powermanagementsettings.h"

QString IconNamingScheme::iconName(float chargeLevel, bool discharging) const
{
    int i = 0;
    while(i < mChargeLevels.size() - 1 && mChargeLevels.at(i+1) <= chargeLevel) i++;

    return discharging ? mIconNamesDischarging.at(i) : mIconNamesCharging.at(i);
}

IconNamingScheme::IconNamingScheme(QString schemeName, QList<float> chargeLevels, QList<QString> iconNamesCharging, QList<QString> iconNamesDischarging)
{
    mSchemeName = schemeName;
    mChargeLevels = chargeLevels;
    mIconNamesCharging = iconNamesCharging;
    mIconNamesDischarging = iconNamesDischarging;
}

IconNamingScheme* IconNamingScheme::getNamingSchemeForCurrentIconTheme()
{
    static QList<IconNamingScheme*> schemes;

    if (schemes.isEmpty())
    {
        // Freedesktop naming scheme
         schemes << new IconNamingScheme(
                "freedesktop",
                (QList<float>() << 0 << 1 << 20 << 40 << 60),
                (QList<QString>() << "battery-empty" << "battery-caution-charging" << "battery-low-charging"
                                  << "battery-good-charging" <<  "battery-full-charging"),
                (QList<QString>() << "battery-empty" << "battery-caution" << "battery-low" << "battery-good" <<  "battery-full")
                );

         // Oxygen naming scheme
         schemes << new IconNamingScheme(
                "oxygen",
                ((QList<float>()) << 0 << 20 << 40 << 60 << 80 << 99.5),
                ((QList<QString>()) << "battery-charging-low" << "battery-charging-caution" << "battery-charging-040"
                                    << "battery-charging-060" << "battery-charging-080" << "battery-charging"),
                ((QList<QString>()) << "battery-low" << "battery-caution" << "battery-040"
                                    << "battery-060" << "battery-080" << "battery-100")
                );

         // AwOken naming scheme
         schemes << new IconNamingScheme(
                "AwOken",
                ((QList<float>()) << 0 << 20 << 40 << 60 << 80 << 99.5),
                ((QList<QString>()) << "battery-000-charging" << "battery-020-charging" << "battery-040-charging"
                                    << "battery-060-charging" << "battery-080-charging" << "battery-100-charging"),
                ((QList<QString>()) << "battery-000" << "battery-020" << "battery-040"
                                   << "battery-060" << "battery-080" << "battery-100")
                );
    }

    foreach (IconNamingScheme* iconNamingScheme, schemes)
    {
        if (iconNamingScheme->isValidForCurrentIconTheme())
        {
            qDebug() << "Found IconNamingScheme:" << iconNamingScheme->mSchemeName;
            return iconNamingScheme;
        }
    }

    qDebug() << "Found no IconNamingScheme";
    return 0;
}

bool IconNamingScheme::isValidForCurrentIconTheme() const
{
    for (int i = 0; i < mIconNamesCharging.size(); i++)
    {
        qDebug() << "Looking for"  << mIconNamesCharging.at(i);
        if (!QIcon::hasThemeIcon(mIconNamesCharging.at(i)))
        {
            qDebug() << "Not found";
            return false;
        }

        qDebug() << "Looking for"  << mIconNamesDischarging.at(i);
        if (!QIcon::hasThemeIcon(mIconNamesDischarging.at(i)))
        {
            qDebug() << "Not found";
            return false;
        }
    }
    qDebug();

    return true;
}

TrayIcon::TrayIcon(QObject *parent) : QSystemTrayIcon(parent), contextMenu()
{
    contextMenu.addAction(tr("Configure..."), this, SLOT(onConfigureTriggered()));
    contextMenu.addAction(tr("About.."), this, SLOT(onAboutTriggered()));
    setContextMenu(&contextMenu);
}

TrayIcon::~TrayIcon() {}

void TrayIcon::update(bool discharging, double chargeLevel, double lowLevel)
{
    this->discharging = discharging;
    this->chargeLevel = chargeLevel;
    this->lowLevel = lowLevel;

    updateToolTip();
    updateIcon();
}

void TrayIcon::updateToolTip()
{
    QString toolTip = discharging ? tr("discharging") : tr("charging"); // TODO Use states...
    toolTip = toolTip + QString(" - %1 %").arg(chargeLevel, 0, 'f', 1);
    setToolTip(toolTip);
}

void TrayIcon::onConfigureTriggered()
{
    QProcess::startDetached("lxqt-config-powermanagement");
}

void TrayIcon::onAboutTriggered()
{
    QMessageBox::about(0,
                       tr("About"),
                       tr( "
"
                           "  LXQt Powermanagement
"
                           "  - Powermanagement for the LXQt Desktop Environment"
                           "
"
                           "
"
                           "  Authors:
"
                           "    Christian Surlykke, Alec Moskvin
"
                           "    - and others from the Razor and LXQt projects"
                           "
"
                           "
"
                           "  Copyright © 2012-2014"
                           "
"
                        ));
}

TrayIconBuiltIn::TrayIconBuiltIn(QObject* parent) :
    TrayIcon(parent)
{
}

TrayIconBuiltIn::~TrayIconBuiltIn()
{
}

bool TrayIconBuiltIn::isProperForCurrentSettings()
{
    return ! PowerManagementSettings().isUseThemeIcons();
}

void TrayIconBuiltIn::updateIcon()
{
    // See http://www.w3.org/TR/SVG/Overview.html
    // and regarding circle-arch in particular:
    // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands

    // We show charge with a segment of a circle.
    // We start at the top of the circle
    // The starting point of the circle segment is at the top (12 o'clock or (0,1) or pi/2
    // and it moves counter-clockwise as the charge increases
    // First we calculate in floating point numbers, using a circle with center
    // in (0,0) and a radius of 1
    double angle = 2*M_PI*chargeLevel/100 + M_PI_2;
    qDebug() << "Angle:"  << angle;
    double segment_endpoint_x = cos(angle);
    double segment_endpoint_y = sin(angle);

    // svg uses a coordinate system with (0,0) at the topmost left corner,
    // y increasing downwards and x increasing left-to-right.
    // We draw the circle segments with center at (100,100) and radius 100 for the
    // outer and radius 60 for the inner. The segments will (unless fully charged,
    // where they go full circle) be radially connected at the endpoints.
    QString chargeGraphics;

    if (chargeLevel < 0.5)
    {
        chargeGraphics = "";
    }
    else if (chargeLevel > 99.5)
    {
        chargeGraphics =
            "<path d='M 100,0 A 100,100 0 1,0 101,0 z M 100,40 A 60,60 0 1,0 101,40 z' stroke-width='0'/>";
    }
    else {
        chargeGraphics =
            QString("<path d='M 100,0 A 100,100 0 %1,0 %2,%3 L %4,%5 A 60,60 0 %1,1 100,40 z'/>")
                .arg(angle > M_PI + M_PI_2 ? 1 : 0)     // %1
                .arg(round(100*(1 + segment_endpoint_x)))    // %2
                .arg(round(100*(1 - segment_endpoint_y)))    // %3
                .arg(round(100*(1 + 0.6*segment_endpoint_x)))    // %4
                .arg(round(100*(1 - 0.6*segment_endpoint_y)));   // %5
    }

    QString chargeColor;
    if (discharging && chargeLevel <= lowLevel + 10)
    {
        chargeColor = "rgb(200,40,40)";
    }
    else if (discharging && chargeLevel <= lowLevel + 30)
    {
        int fac = chargeLevel - lowLevel - 10;
        chargeColor = QString("rgb(%1,%2,40)").arg(40 + 200 - fac*8).arg(40 + fac*8);
    }
    else
        chargeColor = "rgb(40,200,40)";

    QString sign =
            discharging ?
                QString("<path d='M 60,100 h 80' stroke='black' stroke-width='20' />"):                // Minus
                QString("<path d='M 60,100 h 80 M 100,60 v 80' stroke='black' stroke-width='20' />");  // Plus

    QString svg =
        QString("<?xml version='1.0' standalone='no'?>\n"
                "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n"
                "<svg xmlns='http://www.w3.org/2000/svg'  version='1.1' viewBox='0 0 210 210'>\n"
                "    <circle cx='100' cy='100' r='100' fill='rgb(210,210,210)' stroke-width='0'/>\n"
                "    <circle cx='100' cy='100' r='55' fill='rgb(255,255,255)' stroke-width='0'/>\n"
                "    <g fill-rule='evenodd' fill='%2' stroke-width='0'>\n"
                "        %1\n"
                "    </g>\n"
                "    %3\n"
                "</svg>\n").arg(chargeGraphics).arg(chargeColor).arg(sign);

    qDebug() << svg;

    // Paint the svg on a pixmap and create an icon from that.
    QSvgRenderer render(svg.toAscii());
    QPixmap pixmap(render.defaultSize());
    pixmap.fill(QColor(0,0,0,0));
    QPainter painter(&pixmap);
    render.render(&painter);
    setIcon(QIcon(pixmap));
}

TrayIconTheme::TrayIconTheme(IconNamingScheme* iconNamingScheme, QObject* parent)
{
    this->mIconNamingScheme = iconNamingScheme;
}

TrayIconTheme::~TrayIconTheme()
{
}

bool TrayIconTheme::isProperForCurrentSettings()
{
    return PowerManagementSettings().isUseThemeIcons() && mIconNamingScheme->isValidForCurrentIconTheme();
}

void TrayIconTheme::updateIcon()
{
    QString iconName = mIconNamingScheme->iconName(chargeLevel, discharging);
    setIcon(QIcon::fromTheme(iconName));

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "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 Qt Company Ltd 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
    treeitem.cpp

    A container for items of data supplied by the simple tree model.
*/

#include "treeitem.h"

#include <QStringList>
#include <QMessageBox>

#include <assert.h>

using namespace tln::docutils;

//! [0]

const QString TreeItem::default_header_attribute_name_string = "Attribute name";
const QString TreeItem::default_header_attribute_value_string = "Attribue value";
const QString TreeItem::default_header_element_name_string = "Element/node name";
const QString TreeItem::default_header_element_value_string = "Element value";
const QString TreeItem::default_element_name_string = "Sample_element";
const QString TreeItem::default_element_value_string = "Sample_value";
const QString TreeItem::attribute_element_name_string = "*attribute*";
const QString TreeItem::attribute_element_value_string = "*attribute*";

const QString TreeItem::forbidden_tag_name_characters = R"(^:\-\+\.\,!@#$%&*;~`"'<\^\(\)\\/\|\?\[\]\{\} )";

TreeItem::TreeItem(const QVector<QVariant> &data, TreeItem *parent, QObject *qparent, TreeItemType type)
	: QObject(qparent)
	, itemType(type)
	, tag_name_validator(QRegularExpression("[^0-9" + forbidden_tag_name_characters + "][" + forbidden_tag_name_characters + "]*"))
{
	parentItem = parent;
    itemData = data;

	bool data_empty = true;
	for (int i = 0; i < data.size(); ++i)
	{
		if (!data.at(i).toString().isEmpty())
			data_empty = false;
	}
	if(data_empty)
		populateColumnsWithDefaultValues();

	return;
}
//! [0]

//! [1]
TreeItem::~TreeItem()
{
    qDeleteAll(childItems);
	qDeleteAll(attributeItems);
}
//! [1]

//! [2]
TreeItem *TreeItem::child(int number)
{
	if (number >= attributeCount())
		return childItems.value(number - attributeCount());
	else
		return attributeItems.value(number);
}

TreeItem * TreeItem::element(const int number)
{
	if (number < 0 || number >= childItems.size())
		return nullptr;

	return childItems.value(number);
}

TreeItem * TreeItem::attribute(const int number)
{
	if (number < 0 || number > attributeItems.size())
		return nullptr;
	return attributeItems.value(number);
}
//! [2]

//! [3]
int TreeItem::childCount() const
{
    return childItems.count();
}
//! [3]

//! [4]
int TreeItem::childNumber() const
{
    if (parentItem)
        return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));

    return 0;
}
//! [4]

//! [5]
int TreeItem::columnCount() const
{
    return itemData.count();
}
int TreeItem::attributeCount() const
{
	return attributeItems.count();
}
//! [5]

//! [6]
QVariant TreeItem::data(int column) const
{
    return itemData.value(column);
}
//! [6]

//! [7]
bool TreeItem::insertChildren(int position, int count, int columns)
{
    if (position < 0 || position > (childItems.size() + attributeItems.size()) || count <= 0 || itemType == TreeItemType::ATTRIBUTE)
        return false;

	if (childItems.size() == 0 && itemType != TreeItemType::HEADER)
	{
		this->setData(elementValueColumn, QVariant(""));
		this->itemType = TreeItemType::NODE;
	}

    for (int row = 0; row < count; ++row) {
        QVector<QVariant> data(columns);
        TreeItem *item = new TreeItem(data, this, this);
        childItems.insert(position, item);
    }

    return true;
}
//! [7]

bool TreeItem::insertAttributes(int position, int count, int columns)
{
	if (position < 0 || position > attributeItems.size() || count <= 0 || itemType == TreeItemType::ATTRIBUTE)
		return false;

	for (int row = 0; row < count; ++row)
	{
		QVector<QVariant> data(columns);

		TreeItem *item = nullptr;
		//if (attributeItems.size() != 0)
		//{
			item = new TreeItem(data, this, this, TreeItemType::ATTRIBUTE);
		//}
		//else
		//{
			//item = new TreeItem(data, nullptr, this, TreeItemType::ATTRIBUTE);
			//this->setData(attributeNameColumn, item->data(attributeNameColumn));
			//this->setData(attributeValueColumn, item->data(attributeValueColumn));
		//}
		attributeItems.insert(position, item);
	}

	return true;
}

//! [8]
bool TreeItem::insertColumns(int position, int columns)
{
    if (position < 0 || position > itemData.size())
        return false;

    for (int column = 0; column < columns; ++column)
        itemData.insert(position, QVariant());

    foreach (TreeItem *child, childItems)
        child->insertColumns(position, columns);

    return true;
}
//! [8]

//! [9]
TreeItem *TreeItem::parent()
{
    return parentItem;
}
//! [9]

//! [10]
bool TreeItem::removeChildren(int position, int count)
{
    if (position < 0 || position + count > childItems.size())
        return false;

    for (int row = 0; row < count; ++row)
        delete childItems.takeAt(position);

	// if all the children have been removed, the node becomes an element:
	if (this->childCount() == 0)
	{
		assert(this->type() == TreeItemType::NODE || this->type() == TreeItemType::HEADER);
		if (this->type() != TreeItemType::HEADER)
			this->itemType = TreeItemType::ELEMENT;
	}

    return true;
}
//! [10]

bool TreeItem::removeColumns(int position, int columns)
{
    if (position < 0 || position + columns > itemData.size())
        return false;

    for (int column = 0; column < columns; ++column)
        itemData.remove(position);

    foreach (TreeItem *child, childItems)
        child->removeColumns(position, columns);

    return true;
}

//! [11]
bool TreeItem::setData(int column, const QVariant &value)
{
    if (column < 0 || column >= itemData.size())
        return false;

	if (childCount() == 0 || column != 1)
	{
		if (column == 0)
		{
			int pos = 0;
			QValidator::State state = tag_name_validator.validate(value.toString(), pos);
			if (state == QValidator::Acceptable)
				itemData[column] = value;
			else
			{
				QMessageBox::information(nullptr, "XKMLGen", tr("Incorrect tag name."));
				return false;
			}
		}
		else
		{
			itemData[column] = value;
		}
	}
	// it means that the element is a node and someone tries to edit its value column:
	else
	{
		emit changeOfNodeValueAttempted(itemData[0]);
		return false;
	}

	return true;
}
void TreeItem::populateColumnsWithDefaultValues()
{
	switch (type())
	{
	case TreeItemType::ELEMENT:
		this->setData(elementNameColumn, default_element_name_string);
		this->setData(elementValueColumn, default_element_value_string);
		break;
	case TreeItemType::ATTRIBUTE:
		this->setData(elementNameColumn, attribute_element_name_string);
		this->setData(elementValueColumn, attribute_element_value_string);
		break;
	case TreeItemType::NODE:
		this->setData(elementNameColumn, default_element_name_string);
		break;
	case TreeItemType::HEADER:
		this->setData(elementNameColumn, default_header_element_name_string);
		this->setData(elementValueColumn, default_header_element_value_string);
		this->setData(attributeNameColumn, default_header_element_name_string);
		this->setData(attributeValueColumn, default_header_attribute_value_string);
		break;
	}

	return;
}
//! [11]
<commit_msg>Incorrect tag name bug while reading attributes fixed.<commit_after>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "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 Qt Company Ltd 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
    treeitem.cpp

    A container for items of data supplied by the simple tree model.
*/

#include "treeitem.h"

#include <QStringList>
#include <QMessageBox>

#include <assert.h>

using namespace tln::docutils;

//! [0]

const QString TreeItem::default_header_attribute_name_string = "Attribute name";
const QString TreeItem::default_header_attribute_value_string = "Attribue value";
const QString TreeItem::default_header_element_name_string = "Element/node name";
const QString TreeItem::default_header_element_value_string = "Element value";
const QString TreeItem::default_element_name_string = "Sample_element";
const QString TreeItem::default_element_value_string = "Sample_value";
const QString TreeItem::attribute_element_name_string = "*attribute*";
const QString TreeItem::attribute_element_value_string = "*attribute*";

const QString TreeItem::forbidden_tag_name_characters = R"(^:\-\+\.\,!@#$%&*;~`"'<\^\(\)\\/\|\?\[\]\{\} )";

TreeItem::TreeItem(const QVector<QVariant> &data, TreeItem *parent, QObject *qparent, TreeItemType type)
	: QObject(qparent)
	, itemType(type)
	, tag_name_validator(QRegularExpression("[^0-9" + forbidden_tag_name_characters + "][" + forbidden_tag_name_characters + "]*"))
{
	parentItem = parent;
    itemData = data;

	bool data_empty = true;
	for (int i = 0; i < data.size(); ++i)
	{
		if (!data.at(i).toString().isEmpty())
			data_empty = false;
	}
	if(data_empty)
		populateColumnsWithDefaultValues();

	return;
}
//! [0]

//! [1]
TreeItem::~TreeItem()
{
    qDeleteAll(childItems);
	qDeleteAll(attributeItems);
}
//! [1]

//! [2]
TreeItem *TreeItem::child(int number)
{
	if (number >= attributeCount())
		return childItems.value(number - attributeCount());
	else
		return attributeItems.value(number);
}

TreeItem * TreeItem::element(const int number)
{
	if (number < 0 || number >= childItems.size())
		return nullptr;

	return childItems.value(number);
}

TreeItem * TreeItem::attribute(const int number)
{
	if (number < 0 || number > attributeItems.size())
		return nullptr;
	return attributeItems.value(number);
}
//! [2]

//! [3]
int TreeItem::childCount() const
{
    return childItems.count();
}
//! [3]

//! [4]
int TreeItem::childNumber() const
{
    if (parentItem)
        return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));

    return 0;
}
//! [4]

//! [5]
int TreeItem::columnCount() const
{
    return itemData.count();
}
int TreeItem::attributeCount() const
{
	return attributeItems.count();
}
//! [5]

//! [6]
QVariant TreeItem::data(int column) const
{
    return itemData.value(column);
}
//! [6]

//! [7]
bool TreeItem::insertChildren(int position, int count, int columns)
{
    if (position < 0 || position > (childItems.size() + attributeItems.size()) || count <= 0 || itemType == TreeItemType::ATTRIBUTE)
        return false;

	if (childItems.size() == 0 && itemType != TreeItemType::HEADER)
	{
		this->setData(elementValueColumn, QVariant(""));
		this->itemType = TreeItemType::NODE;
	}

    for (int row = 0; row < count; ++row) {
        QVector<QVariant> data(columns);
        TreeItem *item = new TreeItem(data, this, this);
        childItems.insert(position, item);
    }

    return true;
}
//! [7]

bool TreeItem::insertAttributes(int position, int count, int columns)
{
	if (position < 0 || position > attributeItems.size() || count <= 0 || itemType == TreeItemType::ATTRIBUTE)
		return false;

	for (int row = 0; row < count; ++row)
	{
		QVector<QVariant> data(columns);

		TreeItem *item = nullptr;
		//if (attributeItems.size() != 0)
		//{
			item = new TreeItem(data, this, this, TreeItemType::ATTRIBUTE);
		//}
		//else
		//{
			//item = new TreeItem(data, nullptr, this, TreeItemType::ATTRIBUTE);
			//this->setData(attributeNameColumn, item->data(attributeNameColumn));
			//this->setData(attributeValueColumn, item->data(attributeValueColumn));
		//}
		attributeItems.insert(position, item);
	}

	return true;
}

//! [8]
bool TreeItem::insertColumns(int position, int columns)
{
    if (position < 0 || position > itemData.size())
        return false;

    for (int column = 0; column < columns; ++column)
        itemData.insert(position, QVariant());

    foreach (TreeItem *child, childItems)
        child->insertColumns(position, columns);

    return true;
}
//! [8]

//! [9]
TreeItem *TreeItem::parent()
{
    return parentItem;
}
//! [9]

//! [10]
bool TreeItem::removeChildren(int position, int count)
{
    if (position < 0 || position + count > childItems.size())
        return false;

    for (int row = 0; row < count; ++row)
        delete childItems.takeAt(position);

	// if all the children have been removed, the node becomes an element:
	if (this->childCount() == 0)
	{
		assert(this->type() == TreeItemType::NODE || this->type() == TreeItemType::HEADER);
		if (this->type() != TreeItemType::HEADER)
			this->itemType = TreeItemType::ELEMENT;
	}

    return true;
}
//! [10]

bool TreeItem::removeColumns(int position, int columns)
{
    if (position < 0 || position + columns > itemData.size())
        return false;

    for (int column = 0; column < columns; ++column)
        itemData.remove(position);

    foreach (TreeItem *child, childItems)
        child->removeColumns(position, columns);

    return true;
}

//! [11]
bool TreeItem::setData(int column, const QVariant &value)
{
    if (column < 0 || column >= itemData.size())
        return false;

	if (childCount() == 0 || column != 1)
	{
		if (column == 0)
		{
			int pos = 0;
			QValidator::State state = tag_name_validator.validate(value.toString(), pos);
			if (state == QValidator::Acceptable || this->type() == TreeItemType::ATTRIBUTE || this->type() == TreeItemType::HEADER)
				itemData[column] = value;
			else
			{
				QMessageBox::information(nullptr, "XKMLGen", tr("Incorrect tag name."));
				return false;
			}
		}
		else
		{
			itemData[column] = value;
		}
	}
	// it means that the element is a node and someone tries to edit its value column:
	else
	{
		emit changeOfNodeValueAttempted(itemData[0]);
		return false;
	}

	return true;
}
void TreeItem::populateColumnsWithDefaultValues()
{
	switch (type())
	{
	case TreeItemType::ELEMENT:
		this->setData(elementNameColumn, default_element_name_string);
		this->setData(elementValueColumn, default_element_value_string);
		break;
	case TreeItemType::ATTRIBUTE:
		this->setData(elementNameColumn, attribute_element_name_string);
		this->setData(elementValueColumn, attribute_element_value_string);
		break;
	case TreeItemType::NODE:
		this->setData(elementNameColumn, default_element_name_string);
		break;
	case TreeItemType::HEADER:
		this->setData(elementNameColumn, default_header_element_name_string);
		this->setData(elementValueColumn, default_header_element_value_string);
		this->setData(attributeNameColumn, default_header_element_name_string);
		this->setData(attributeValueColumn, default_header_attribute_value_string);
		break;
	}

	return;
}
//! [11]
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2015 Bitcoin Spinoff Toolkit developers
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <iostream>
#include <bitcoin/bitcoin.hpp>
#include "bitcoin/bst/generate.h"

using namespace std;

void test_signing_check()
{
    string testEncodedAddress = "15BWWGJRtB8Z9NXmMAp94whujUK6SrmRwT";
    string messageToSign = "hey there";
    string signatureString = "HxXI251uSorWtrqkZejCljYlU+6s861evqN6u3IyYJVSaqYooYzvuSCf6TA0B+wJDOkqljz0fQgkvKjJHiBJgRg=";

    string result = bst::getVerificationMessage(testEncodedAddress, messageToSign, signatureString);
    cout << result << endl;
}

void test_recover_signature()
{
    string testEncodedAddress = "15BWWGJRtB8Z9NXmMAp94whujUK6SrmRwT";
    string messageToSign = "hey there";
    string signatureString = "HxXI251uSorWtrqkZejCljYlU+6s861evqN6u3IyYJVSaqYooYzvuSCf6TA0B+wJDOkqljz0fQgkvKjJHiBJgRg=";
    cout << testEncodedAddress << endl;

    vector<uint8_t> paymentVector = vector<uint8_t>(20);
    bool result = bst::recover_address(messageToSign, signatureString, paymentVector);
    bc::short_hash sh;
    copy(paymentVector.begin(), paymentVector.end(), sh.begin());
    bc::payment_address address(0, sh);
    cout << result << " " << address.encoded() << endl;
}

void test_string_encode_decode()
{
    string vectorString = "01AF0F10";
    vector<uint8_t> testVec;
    bst::decodeVector(vectorString, testVec);
    stringstream ss;
    bst::prettyPrintVector(testVec, ss);
    string s = ss.str();
    cout << vectorString << endl << s << endl;
}

void test_string_encode_decode2()
{
    string vectorString = "992fa68a35e9706f5ce12036803df00ff3003dc6";
    vector<uint8_t> testVec;
    bst::decodeVector(vectorString, testVec);
    stringstream ss;
    bst::prettyPrintVector(testVec, ss);
    string s = ss.str();
    cout << vectorString << endl << s << endl;
}

void test_address_encoding()
{
    string short_hash = "992fa68a35e9706f5ce12036803df00ff3003dc6";
    vector<uint8_t> hashVec;
    bst::decodeVector(short_hash, hashVec);
    bc::short_hash sh;
    copy(hashVec.begin(), hashVec.end(), sh.begin());
    bc::payment_address address(111, sh);
    cout << address.encoded();
}

void test_store_p2pkhs()
{
    string transaction1 = "76A9142345FBB2B00E115C98C1D6E975C99B5431DE9CDE88AC";
    string transaction2 = "76A914992FA68A35E9706F5CE12036803DF00FF3003DC688AC";
    vector<uint8_t> vector1;
    vector<uint8_t> vector2;
    bst::decodeVector(transaction1, vector1);
    bst::decodeVector(transaction2, vector2);

    bst::snapshot_preparer preparer;
    bst::prepareForUTXOs(preparer);
    bst::writeUTXO(preparer, vector1, 24900000000);
    bst::writeUTXO(preparer, vector2, 99998237);
    vector<uint8_t> block_hash = vector<uint8_t>(32);
    bst::writeSnapshot(preparer, block_hash);
    bst::printSnapshot();
}

void test_store_p2pkhs_and_p2sh()
{
    string transaction1 = "76A9142345FBB2B00E115C98C1D6E975C99B5431DE9CDE88AC";
    string transaction2 = "a91489a16fbc4929fc7c83ada40641411c09fe4b76d887";
    vector<uint8_t> vector1;
    vector<uint8_t> vector2;
    bst::decodeVector(transaction1, vector1);
    bst::decodeVector(transaction2, vector2);

    bst::snapshot_preparer preparer;
    bst::prepareForUTXOs(preparer);
    bst::writeUTXO(preparer, vector1, 10);
    bst::writeUTXO(preparer, vector2, 20);
    vector<uint8_t> block_hash = vector<uint8_t>(32);
    bst::writeSnapshot(preparer, block_hash);
    bst::printSnapshot();
}

void test_store_and_claim()
{
    string transaction1 = "76A9142345FBB2B00E115C98C1D6E975C99B5431DE9CDE88AC";
    string transaction2 = "76A914992FA68A35E9706F5CE12036803DF00FF3003DC688AC";
    string transaction3 = "2102f91ca5628d8a77fbf8e12fd098fdd871bdcb61c84cc3abf111a747b26ff6a2cbac";
    string transaction4 = "a91489a16fbc4929fc7c83ada40641411c09fe4b76d887";
    vector<uint8_t> vector1;
    vector<uint8_t> vector2;
    vector<uint8_t> vector3;
    vector<uint8_t> vector4;
    bst::decodeVector(transaction1, vector1);
    bst::decodeVector(transaction2, vector2);
    bst::decodeVector(transaction3, vector3);
    bst::decodeVector(transaction4, vector4);
    bst::snapshot_preparer preparer;
    bst::prepareForUTXOs(preparer);
    bst::writeUTXO(preparer, vector1, 24900000000);
    bst::writeUTXO(preparer, vector2, 99998237);
    bst::writeUTXO(preparer, vector3, 5000000643);
    bst::writeUTXO(preparer, vector4, 123456);
    vector<uint8_t> block_hash = vector<uint8_t>(32);
    bst::writeSnapshot(preparer, block_hash);
    string claim = "I claim funds.";
    string signature = "Hxc0sSkslD2mFE3HtHzIDRqSutQBiAQ+TxrsgVPeL3jWbXtcusuD77MTX7Tc/hJsQtVrbZsf9xpSDs+6Khx7nNk=";
    string signature2 = "H3ys4y9vnG2cvneZMo33Vvv1kQTKr2iCcBZZe78OFl8VaPbXYNwLVTtTh5K7Qu4MpdOQiVo+6SHq6pPSzdBm7PQ=";
    string signature3 = "IIuXyLFeU+HVJnv9TPAGXnCnc0bCOi+enwjIWxsO5FmaMdVNBcRrkYGB07Qbdkghd+0XhnaUL3O+X+h4dzb0Kio=";

    bst::snapshot_reader reader;
    bst::openSnapshot(reader);
    uint64_t amount = bst::getP2PKHAmount(reader, claim, signature);
    cout << "found amount " << amount << endl;
    amount = bst::getP2PKHAmount(reader, claim, signature2);
    cout << "found amount " << amount << endl;
    amount = bst::getP2PKHAmount(reader, claim, signature3);
    cout << "found amount " << amount << endl;

    // now for the p2sh finale
    string transaction_string = "0100000001a9dd2ae0a5d513a336a2c61db3472e260443eb79ffbd07e154829574c1fa2f3901000000fc00"
            "473044022062b5798436e9524c267f5c03c0601743db0cd3e57722c87a48a51d3af4089ccc02200f00f9e244e1fc6fa8141a4e90fa"
            "43b0423d5eda7a1d6d9eb6f6a375337ceda30147304402204ae544e90a9cdf70db7a571cc44a7dcdc0c9f5cbffea6172d7d8ef625d"
            "ea0758022074c3fa6437c60a762dd49075d80855eec78ea27fafff5e78fb70e07985c9f833014c69522102f91ca5628d8a77fbf8e1"
            "2fd098fdd871bdcb61c84cc3abf111a747b26ff6a2cb2103b708d33d5452ce8232fe096220ad2aaea4aa68ce0f0869e6321e93c88c"
            "f5ce082103917f030d239db795047bb5eb66713838221134e103eee2da5619c0cd938e6f6953aeffffffff0170c9fa020000000019"
            "76a914f2f5bbdea2763591bb5c7552df7d6fe46204bc7588ac00000000";
    string p2sh_address = "2N5nwxNF6Fe91RPExcwcaqPPpV14CSo9cEc";
    amount = bst::getP2SHAmount(reader, transaction_string, p2sh_address, 0);
    cout << "found amount " << amount << endl;
}

void test_validate_multisig()
{
    string transaction_string = "0100000001a9dd2ae0a5d513a336a2c61db3472e260443eb79ffbd07e154829574c1fa2f3901000000fc00"
        "473044022062b5798436e9524c267f5c03c0601743db0cd3e57722c87a48a51d3af4089ccc02200f00f9e244e1fc6fa8141a4e90fa"
        "43b0423d5eda7a1d6d9eb6f6a375337ceda30147304402204ae544e90a9cdf70db7a571cc44a7dcdc0c9f5cbffea6172d7d8ef625d"
        "ea0758022074c3fa6437c60a762dd49075d80855eec78ea27fafff5e78fb70e07985c9f833014c69522102f91ca5628d8a77fbf8e1"
        "2fd098fdd871bdcb61c84cc3abf111a747b26ff6a2cb2103b708d33d5452ce8232fe096220ad2aaea4aa68ce0f0869e6321e93c88c"
        "f5ce082103917f030d239db795047bb5eb66713838221134e103eee2da5619c0cd938e6f6953aeffffffff0170c9fa020000000019"
        "76a914f2f5bbdea2763591bb5c7552df7d6fe46204bc7588ac00000000";
    bc::data_chunk transaction_chunk;
    bc::decode_base16(transaction_chunk, transaction_string);
    bc::transaction_type transaction;
    bc::satoshi_load(transaction_chunk.begin(), transaction_chunk.end(), transaction);

    string output_string = "a91489a16fbc4929fc7c83ada40641411c09fe4b76d887";
    bc::data_chunk output_chunk;
    bc::decode_base16(output_chunk, output_string);
    bc::script_type output_script = bc::parse_script(output_chunk);

    bc::script_type input_script = transaction.inputs[0].script;
    bool result = output_script.run(input_script, transaction, 0);

    cout << bc::pretty(transaction) << endl;
    cout << bc::pretty(output_script) << endl;
    cout << "result " << result << endl;
}

int main() {
    //test_validate_multisig();
    //test_store_p2pkhs_and_p2sh();
    test_store_and_claim();

    return 0;
}<commit_msg>making tests more unit-testy<commit_after>/**
 * Copyright (C) 2015 Bitcoin Spinoff Toolkit developers
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <iostream>
#include <bitcoin/bitcoin.hpp>
#include "bitcoin/bst/generate.h"

using namespace std;

void test_signing_check()
{
    string testEncodedAddress = "15BWWGJRtB8Z9NXmMAp94whujUK6SrmRwT";
    string messageToSign = "hey there";
    string signatureString = "HxXI251uSorWtrqkZejCljYlU+6s861evqN6u3IyYJVSaqYooYzvuSCf6TA0B+wJDOkqljz0fQgkvKjJHiBJgRg=";

    string expected = "wow, we verified this";
    string result = bst::getVerificationMessage(testEncodedAddress, messageToSign, signatureString);
    if (result != expected)
    {
        cout << "test_signing_check---" << endl;
        cout << "expected: " << expected << endl;
        cout << "result  : " << result << endl;
    }
}

void test_recover_signature()
{
    string testEncodedAddress = "15BWWGJRtB8Z9NXmMAp94whujUK6SrmRwT";
    string messageToSign = "hey there";
    string signatureString = "HxXI251uSorWtrqkZejCljYlU+6s861evqN6u3IyYJVSaqYooYzvuSCf6TA0B+wJDOkqljz0fQgkvKjJHiBJgRg=";

    vector<uint8_t> paymentVector = vector<uint8_t>(20);
    bool result = bst::recover_address(messageToSign, signatureString, paymentVector);
    if (! result)
    {
        cout << "test_recover_signature---" << endl;
        cout << "failed to recover address" << endl;
    }
    bc::short_hash sh;
    copy(paymentVector.begin(), paymentVector.end(), sh.begin());
    bc::payment_address address(0, sh);
    string recoveredAddress = address.encoded();
    if (testEncodedAddress != recoveredAddress)
    {
        cout << "test_recover_signature---" << endl;
        cout << "expected: " << testEncodedAddress << endl;
        cout << "result:   " << recoveredAddress << endl;
    }
}

// only really tests libbitcoin, ignore
void test_address_encoding()
{
    string short_hash = "992fa68a35e9706f5ce12036803df00ff3003dc6";
    vector<uint8_t> hashVec;
    bst::decodeVector(short_hash, hashVec);
    bc::short_hash sh;
    copy(hashVec.begin(), hashVec.end(), sh.begin());
    bc::payment_address address(111, sh);
    cout << address.encoded();
}

void test_store_p2pkhs()
{
    string transaction1 = "76A9142345FBB2B00E115C98C1D6E975C99B5431DE9CDE88AC";
    string transaction2 = "76A914992FA68A35E9706F5CE12036803DF00FF3003DC688AC";
    vector<uint8_t> vector1;
    vector<uint8_t> vector2;
    bst::decodeVector(transaction1, vector1);
    bst::decodeVector(transaction2, vector2);

    bst::snapshot_preparer preparer;
    bst::prepareForUTXOs(preparer);
    bst::writeUTXO(preparer, vector1, 24900000000);
    bst::writeUTXO(preparer, vector2, 99998237);
    vector<uint8_t> block_hash = vector<uint8_t>(32);
    bst::writeSnapshot(preparer, block_hash);
    bst::printSnapshot();
}

void test_store_p2pkhs_and_p2sh()
{
    string transaction1 = "76A9142345FBB2B00E115C98C1D6E975C99B5431DE9CDE88AC";
    string transaction2 = "a91489a16fbc4929fc7c83ada40641411c09fe4b76d887";
    vector<uint8_t> vector1;
    vector<uint8_t> vector2;
    bst::decodeVector(transaction1, vector1);
    bst::decodeVector(transaction2, vector2);

    bst::snapshot_preparer preparer;
    bst::prepareForUTXOs(preparer);
    bst::writeUTXO(preparer, vector1, 10);
    bst::writeUTXO(preparer, vector2, 20);
    vector<uint8_t> block_hash = vector<uint8_t>(32);
    bst::writeSnapshot(preparer, block_hash);
    bst::printSnapshot();
}

void test_store_and_claim()
{
    string transaction1 = "76A9142345FBB2B00E115C98C1D6E975C99B5431DE9CDE88AC";
    string transaction2 = "76A914992FA68A35E9706F5CE12036803DF00FF3003DC688AC";
    string transaction3 = "2102f91ca5628d8a77fbf8e12fd098fdd871bdcb61c84cc3abf111a747b26ff6a2cbac";
    string transaction4 = "a91489a16fbc4929fc7c83ada40641411c09fe4b76d887";
    vector<uint8_t> vector1;
    vector<uint8_t> vector2;
    vector<uint8_t> vector3;
    vector<uint8_t> vector4;
    bst::decodeVector(transaction1, vector1);
    bst::decodeVector(transaction2, vector2);
    bst::decodeVector(transaction3, vector3);
    bst::decodeVector(transaction4, vector4);
    bst::snapshot_preparer preparer;
    preparer.debug = false;
    bst::prepareForUTXOs(preparer);
    bst::writeUTXO(preparer, vector1, 24900000000);
    bst::writeUTXO(preparer, vector2, 99998237);
    bst::writeUTXO(preparer, vector3, 5000000643);
    bst::writeUTXO(preparer, vector4, 123456);
    vector<uint8_t> block_hash = vector<uint8_t>(32);
    bst::writeSnapshot(preparer, block_hash);
    string claim = "I claim funds.";
    string signature = "Hxc0sSkslD2mFE3HtHzIDRqSutQBiAQ+TxrsgVPeL3jWbXtcusuD77MTX7Tc/hJsQtVrbZsf9xpSDs+6Khx7nNk=";
    string signature2 = "H3ys4y9vnG2cvneZMo33Vvv1kQTKr2iCcBZZe78OFl8VaPbXYNwLVTtTh5K7Qu4MpdOQiVo+6SHq6pPSzdBm7PQ=";
    string signature3 = "IIuXyLFeU+HVJnv9TPAGXnCnc0bCOi+enwjIWxsO5FmaMdVNBcRrkYGB07Qbdkghd+0XhnaUL3O+X+h4dzb0Kio=";

    bst::snapshot_reader reader;
    bst::openSnapshot(reader);
    uint64_t expected = 24900000000;
    uint64_t amount = bst::getP2PKHAmount(reader, claim, signature);
    if (amount != expected)
    {
        cout << "test_store_and_claim--- 1" << endl;
        cout << "expected: " << expected << endl;
        cout << "result  : " << amount << endl;
    }
    expected = 99998237;
    amount = bst::getP2PKHAmount(reader, claim, signature2);
    if (amount != expected)
    {
        cout << "test_store_and_claim--- 2" << endl;
        cout << "expected: " << expected << endl;
        cout << "result  : " << amount << endl;
    }
    expected = 5000000643;
    amount = bst::getP2PKHAmount(reader, claim, signature3);
    if (amount != expected)
    {
        cout << "test_store_and_claim--- 3" << endl;
        cout << "expected: " << expected << endl;
        cout << "result  : " << amount << endl;
    }

    // now for the p2sh finale
    string transaction_string = "0100000001a9dd2ae0a5d513a336a2c61db3472e260443eb79ffbd07e154829574c1fa2f3901000000fc00"
            "473044022062b5798436e9524c267f5c03c0601743db0cd3e57722c87a48a51d3af4089ccc02200f00f9e244e1fc6fa8141a4e90fa"
            "43b0423d5eda7a1d6d9eb6f6a375337ceda30147304402204ae544e90a9cdf70db7a571cc44a7dcdc0c9f5cbffea6172d7d8ef625d"
            "ea0758022074c3fa6437c60a762dd49075d80855eec78ea27fafff5e78fb70e07985c9f833014c69522102f91ca5628d8a77fbf8e1"
            "2fd098fdd871bdcb61c84cc3abf111a747b26ff6a2cb2103b708d33d5452ce8232fe096220ad2aaea4aa68ce0f0869e6321e93c88c"
            "f5ce082103917f030d239db795047bb5eb66713838221134e103eee2da5619c0cd938e6f6953aeffffffff0170c9fa020000000019"
            "76a914f2f5bbdea2763591bb5c7552df7d6fe46204bc7588ac00000000";
    string p2sh_address = "2N5nwxNF6Fe91RPExcwcaqPPpV14CSo9cEc";
    expected = 123456;
    amount = bst::getP2SHAmount(reader, transaction_string, p2sh_address, 0);
    if (amount != expected)
    {
        cout << "test_store_and_claim--- 4" << endl;
        cout << "expected: " << expected << endl;
        cout << "result  : " << amount << endl;
    }
}

// only tests libbitcoin code, ignore
void test_validate_multisig()
{
    string transaction_string = "0100000001a9dd2ae0a5d513a336a2c61db3472e260443eb79ffbd07e154829574c1fa2f3901000000fc00"
        "473044022062b5798436e9524c267f5c03c0601743db0cd3e57722c87a48a51d3af4089ccc02200f00f9e244e1fc6fa8141a4e90fa"
        "43b0423d5eda7a1d6d9eb6f6a375337ceda30147304402204ae544e90a9cdf70db7a571cc44a7dcdc0c9f5cbffea6172d7d8ef625d"
        "ea0758022074c3fa6437c60a762dd49075d80855eec78ea27fafff5e78fb70e07985c9f833014c69522102f91ca5628d8a77fbf8e1"
        "2fd098fdd871bdcb61c84cc3abf111a747b26ff6a2cb2103b708d33d5452ce8232fe096220ad2aaea4aa68ce0f0869e6321e93c88c"
        "f5ce082103917f030d239db795047bb5eb66713838221134e103eee2da5619c0cd938e6f6953aeffffffff0170c9fa020000000019"
        "76a914f2f5bbdea2763591bb5c7552df7d6fe46204bc7588ac00000000";
    bc::data_chunk transaction_chunk;
    bc::decode_base16(transaction_chunk, transaction_string);
    bc::transaction_type transaction;
    bc::satoshi_load(transaction_chunk.begin(), transaction_chunk.end(), transaction);

    string output_string = "a91489a16fbc4929fc7c83ada40641411c09fe4b76d887";
    bc::data_chunk output_chunk;
    bc::decode_base16(output_chunk, output_string);
    bc::script_type output_script = bc::parse_script(output_chunk);

    bc::script_type input_script = transaction.inputs[0].script;
    bool result = output_script.run(input_script, transaction, 0);

    cout << bc::pretty(transaction) << endl;
    cout << bc::pretty(output_script) << endl;
    cout << "result " << result << endl;
}

void test_all()
{
    test_signing_check();
    test_recover_signature();
    test_store_and_claim();
}

int main() {
    //test_validate_multisig();
    //test_store_p2pkhs_and_p2sh();
    //test_store_and_claim();
    test_all();

    return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/util/util.hpp>

#include <nix/base/IDimensions.hpp>

#include <string>
#include <cstdlib>
#include <mutex>
#include <random>
#include <math.h>

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
#include <boost/random.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

using namespace std;

namespace nix {
namespace util {

// Base32hex alphabet (RFC 4648)
const char*  ID_ALPHABET = "0123456789abcdefghijklmnopqrstuv";
// Unit scaling, SI only, substitutions for micro and ohm...
const string  PREFIXES = "(Y|Z|E|P|T|G|M|k|h|da|d|c|m|u|n|p|f|a|z|y)";
const string  UNITS = "(m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L|Ohm|%|dB|rad)";
const string  POWER = "(\\^[+-]?[1-9]\\d*)";

const map<string, double> PREFIX_FACTORS = {{"y", 1.0e-24}, {"z", 1.0e-21}, {"a", 1.0e-18}, {"f", 1.0e-15},
    {"p", 1.0e-12}, {"n",1.0e-9}, {"u", 1.0e-6}, {"m", 1.0e-3}, {"c", 1.0e-2}, {"d",1.0e-1}, {"da", 1.0e1}, {"h", 1.0e2},
    {"k", 1.0e3}, {"M",1.0e6}, {"G", 1.0e9}, {"T", 1.0e12}, {"P", 1.0e15}, {"E",1.0e18}, {"Z", 1.0e21}, {"Y", 1.0e24}};

string createId() {
    static boost::mt19937 ran(std::time(0));
    static boost::uuids::basic_random_generator<boost::mt19937> gen(&ran);
    boost::uuids::uuid u = gen();
    return boost::uuids::to_string(u);
}

string timeToStr(time_t time) {
    using namespace boost::posix_time;
    ptime timetmp = from_time_t(time);
    return to_iso_string(timetmp);
}

time_t strToTime(const string &time) {
    using namespace boost::posix_time;
    ptime timetmp(from_iso_string(time));
    ptime epoch(boost::gregorian::date(1970, 1, 1));
    return (timetmp - epoch).total_seconds();
}

time_t getTime() {
    return time(NULL);
}

void deblankString(std::string &str) {
    typedef std::string::value_type char_type;

    // c > 0 check is for windows where isblank asserts c > -1 && < 256
    str.erase(std::remove_if(str.begin(),
                             str.end(),
                             [](char_type c) { return c > 0 && std::isblank(c); }),
              str.end());
}

std::string deblankString(const std::string &str) {
    std::string str_copy = str;
    deblankString(str_copy);
    return str_copy;
}

bool nameCheck(const std::string &name) {
    return name.find("/") == std::string::npos;
}

std::string nameSanitizer(const std::string &name) {
    std::string str_copy = name;
    size_t pos = str_copy.find("/");

    while(pos != std::string::npos) {
        str_copy = str_copy.replace(pos, 1, "_");
        pos = str_copy.find("/");
    }

    return str_copy;
}

std::string unitSanitizer(const std::string &unit) {
     std::string new_unit = deblankString(unit);
     while (new_unit.find("mu") != string::npos) {
          size_t pos = new_unit.find("mu");
          new_unit = new_unit.replace(pos, 2, "u");
     }
     while (new_unit.find("µ") != string::npos) {
          size_t pos = new_unit.find("µ");
          new_unit = new_unit.replace(pos, 2, "u");
     }
     return new_unit;
}

void splitUnit(const string &combinedUnit, string &prefix, string &unit, string &power) {
    boost::regex prefix_and_unit_and_power(PREFIXES + UNITS + POWER);
    boost::regex prefix_and_unit(PREFIXES + UNITS);
    boost::regex unit_and_power(UNITS + POWER);
    boost::regex unit_only(UNITS);
    boost::regex prefix_only(PREFIXES);

    if (boost::regex_match(combinedUnit, prefix_and_unit_and_power)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        string suffix = m.suffix();
        boost::regex_search(suffix, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, unit_and_power)) {
        prefix = "";
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, prefix_and_unit)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        unit = m.suffix();
        power = "";
    } else {
        unit = combinedUnit;
        prefix = "";
        power = "";
    }
}

void splitCompoundUnit(const std::string &compoundUnit, std::vector<std::string> &atomicUnits) {
    string s = compoundUnit;
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    boost::regex separator("(\\*|/)");
    boost::match_results<std::string::const_iterator> m;

    while (boost::regex_search(s, m, opt_prefix_and_unit_and_power) && (m.suffix().length() > 0)) {
        string suffix = m.suffix();
        atomicUnits.push_back(m[0]);
        s = suffix.substr(1);
    }
    atomicUnits.push_back(m[0]);
}

bool isSIUnit(const string &unit) {
    return isAtomicSIUnit(unit) || isCompoundSIUnit(unit);
}

bool isAtomicSIUnit(const string &unit) {
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    return boost::regex_match(unit, opt_prefix_and_unit_and_power);
}

bool isCompoundSIUnit(const string &unit) {
    string atomic_unit = PREFIXES + "?" + UNITS + POWER + "?";
    boost::regex compound_unit("(" + atomic_unit + "(\\*|/))+"+ atomic_unit);
    return boost::regex_match(unit, compound_unit);
}

std::string dimTypeToStr(const nix::DimensionType &dtype) {
    std::stringstream s;
    s << dtype;
    return s.str();
}

bool isScalable(const string &unitA, const string &unitB) {
    if (!(isSIUnit(unitA) && isSIUnit(unitB))) {
        return false;
    }
    string a_unit, a_prefix, a_power;
    string b_unit, b_prefix, b_power;
    splitUnit(unitA, a_prefix, a_unit, a_power);
    splitUnit(unitB, b_prefix, b_unit, b_power);
    if (!(a_unit == b_unit) || !(a_power == b_power) ) {
        return false;
    }
    return true;
}

bool isScalable(const vector<string> &unitsA, const vector<string> &unitsB) {
    bool scalable = true;

    if (unitsA.size() != unitsB.size()) {
        return false;
    }

    auto itA = unitsA.begin();
    auto itB = unitsB.begin();
    while (scalable && itA != unitsA.end()) {
        scalable = isScalable(*itA, *itB);
        ++itA;
        ++itB;
    }

    return scalable;
}

bool isSetAtSamePos(const vector<string> &unitsA, const vector<string> &unitsB) {
    bool set_same = true;

    if (unitsA.size() != unitsB.size()) {
        return false;
    }

    auto itA = unitsA.begin();
    auto itB = unitsB.begin();
    while (set_same && itA != unitsA.end()) {
        set_same = (*itA).empty() == (*itB).empty();
        ++itA;
        ++itB;
    }

    return set_same;
}

double getSIScaling(const string &originUnit, const string &destinationUnit) {
    double scaling = 1.0;
    if (!isScalable(originUnit, destinationUnit)) {
        throw nix::InvalidUnit("Origin unit and destination unit are not scalable versions of the same SI unit!",
                               "nix::util::getSIScaling");
    }

    string org_unit, org_prefix, org_power;
    string dest_unit, dest_prefix, dest_power;
    splitUnit(originUnit, org_prefix, org_unit, org_power);
    splitUnit(destinationUnit, dest_prefix, dest_unit, dest_power);

    if ((org_prefix == dest_prefix) && (org_power == dest_power)) {
        return scaling;
    }
    if (dest_prefix.empty() && !org_prefix.empty()) {
        scaling = PREFIX_FACTORS.at(org_prefix);
    } else if (org_prefix.empty() && !dest_prefix.empty()) {
        scaling = 1.0 / PREFIX_FACTORS.at(dest_prefix);
    } else if (!org_prefix.empty() && !dest_prefix.empty()) {
        scaling = PREFIX_FACTORS.at(org_prefix) / PREFIX_FACTORS.at(dest_prefix);
    }
    if (!org_power.empty()) {
        int power = std::stoi(org_power);
        scaling = pow(scaling, power);
    }
    return scaling;
}

void applyPolynomial(const std::vector<double> &coefficients,
                     double origin,
                     const double *input,
                     double *output,
                     size_t n) {

    if (!coefficients.size()) {
        // if we have no coefficients, i.e no polynomial specified we
        // should still apply the the origin transformation
        for (size_t k = 0; k < n; k++) {
            output[k] = input[k] - origin;
        }

    } else {

        for (size_t k = 0; k < n; k++) {
            const double x = input[k] - origin;
            double value = 0.0;
            double term = 1.0;
            for (size_t i = 0; i < coefficients.size(); i++) {
                value += coefficients[i] * term;
                term *= x;
            }
            output[k] = value;
        }
    }
}

bool looksLikeUUID(const std::string &id) {
    // we don't want a complete check, just a glance
    // uuid form is: 8-4-4-4-12 = 36 [8, 13, 18, 23, ]
    return id.size() == 36 && id[8] == '-' && id[13] == '-' && id[18] == '-' && id[23] =='-';
}

} // namespace util
} // namespace nix
<commit_msg>[util] split_compound unit returns correct units<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/util/util.hpp>

#include <nix/base/IDimensions.hpp>

#include <string>
#include <cstdlib>
#include <mutex>
#include <random>
#include <math.h>

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
#include <boost/random.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

using namespace std;

namespace nix {
namespace util {

// Base32hex alphabet (RFC 4648)
const char*  ID_ALPHABET = "0123456789abcdefghijklmnopqrstuv";
// Unit scaling, SI only, substitutions for micro and ohm...
const string  PREFIXES = "(Y|Z|E|P|T|G|M|k|h|da|d|c|m|u|n|p|f|a|z|y)";
const string  UNITS = "(m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L|Ohm|%|dB|rad)";
const string  POWER = "(\\^[+-]?[1-9]\\d*)";

const map<string, double> PREFIX_FACTORS = {{"y", 1.0e-24}, {"z", 1.0e-21}, {"a", 1.0e-18}, {"f", 1.0e-15},
    {"p", 1.0e-12}, {"n",1.0e-9}, {"u", 1.0e-6}, {"m", 1.0e-3}, {"c", 1.0e-2}, {"d",1.0e-1}, {"da", 1.0e1}, {"h", 1.0e2},
    {"k", 1.0e3}, {"M",1.0e6}, {"G", 1.0e9}, {"T", 1.0e12}, {"P", 1.0e15}, {"E",1.0e18}, {"Z", 1.0e21}, {"Y", 1.0e24}};

string createId() {
    static boost::mt19937 ran(std::time(0));
    static boost::uuids::basic_random_generator<boost::mt19937> gen(&ran);
    boost::uuids::uuid u = gen();
    return boost::uuids::to_string(u);
}

string timeToStr(time_t time) {
    using namespace boost::posix_time;
    ptime timetmp = from_time_t(time);
    return to_iso_string(timetmp);
}

time_t strToTime(const string &time) {
    using namespace boost::posix_time;
    ptime timetmp(from_iso_string(time));
    ptime epoch(boost::gregorian::date(1970, 1, 1));
    return (timetmp - epoch).total_seconds();
}

time_t getTime() {
    return time(NULL);
}

void deblankString(std::string &str) {
    typedef std::string::value_type char_type;

    // c > 0 check is for windows where isblank asserts c > -1 && < 256
    str.erase(std::remove_if(str.begin(),
                             str.end(),
                             [](char_type c) { return c > 0 && std::isblank(c); }),
              str.end());
}

std::string deblankString(const std::string &str) {
    std::string str_copy = str;
    deblankString(str_copy);
    return str_copy;
}

bool nameCheck(const std::string &name) {
    return name.find("/") == std::string::npos;
}

std::string nameSanitizer(const std::string &name) {
    std::string str_copy = name;
    size_t pos = str_copy.find("/");

    while(pos != std::string::npos) {
        str_copy = str_copy.replace(pos, 1, "_");
        pos = str_copy.find("/");
    }

    return str_copy;
}

std::string unitSanitizer(const std::string &unit) {
     std::string new_unit = deblankString(unit);
     while (new_unit.find("mu") != string::npos) {
          size_t pos = new_unit.find("mu");
          new_unit = new_unit.replace(pos, 2, "u");
     }
     while (new_unit.find("µ") != string::npos) {
          size_t pos = new_unit.find("µ");
          new_unit = new_unit.replace(pos, 2, "u");
     }
     return new_unit;
}

void splitUnit(const string &combinedUnit, string &prefix, string &unit, string &power) {
    boost::regex prefix_and_unit_and_power(PREFIXES + UNITS + POWER);
    boost::regex prefix_and_unit(PREFIXES + UNITS);
    boost::regex unit_and_power(UNITS + POWER);
    boost::regex unit_only(UNITS);
    boost::regex prefix_only(PREFIXES);

    if (boost::regex_match(combinedUnit, prefix_and_unit_and_power)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        string suffix = m.suffix();
        boost::regex_search(suffix, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, unit_and_power)) {
        prefix = "";
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, prefix_and_unit)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        unit = m.suffix();
        power = "";
    } else {
        unit = combinedUnit;
        prefix = "";
        power = "";
    }
}

void invertPower(std::string &unit) {
    string p, u, pow;
    util::splitUnit(unit, p, u, pow);
    if (pow.empty()) {
        unit = (p + u + "^-1");
    } else {
        if (pow[0] == '-') {
            unit = p + u + "^" + pow.substr(1);
        } else {
            unit = p + u + "^-" + pow;
        }
    }
}

void splitCompoundUnit(const std::string &compoundUnit, std::vector<std::string> &atomicUnits) {
    string s = compoundUnit;
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    boost::regex separator("(\\*|/)");
    boost::match_results<std::string::const_iterator> m;
    string sep;
    while (boost::regex_search(s, m, opt_prefix_and_unit_and_power) && (m.suffix().length() > 0)) {
        string suffix = m.suffix();
        util::deblankString(suffix);
        if (sep == "/") {
            string unit = m[0];
            invertPower(unit);
            atomicUnits.push_back(unit);
        } else {
            atomicUnits.push_back(m[0]);
        }
        sep = suffix[0];
        s = suffix.substr(1);
    }
    if (sep == "/") {
        string unit = m[0];
        invertPower(unit);
        atomicUnits.push_back(unit);
    } else {
        atomicUnits.push_back(m[0]);
    }
}

bool isSIUnit(const string &unit) {
    return isAtomicSIUnit(unit) || isCompoundSIUnit(unit);
}

bool isAtomicSIUnit(const string &unit) {
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    return boost::regex_match(unit, opt_prefix_and_unit_and_power);
}

bool isCompoundSIUnit(const string &unit) {
    string atomic_unit = PREFIXES + "?" + UNITS + POWER + "?";
    boost::regex compound_unit("(" + atomic_unit + "(\\*|/))+"+ atomic_unit);
    return boost::regex_match(unit, compound_unit);
}

std::string dimTypeToStr(const nix::DimensionType &dtype) {
    std::stringstream s;
    s << dtype;
    return s.str();
}

bool isScalable(const string &unitA, const string &unitB) {
    if (!(isSIUnit(unitA) && isSIUnit(unitB))) {
        return false;
    }
    string a_unit, a_prefix, a_power;
    string b_unit, b_prefix, b_power;
    splitUnit(unitA, a_prefix, a_unit, a_power);
    splitUnit(unitB, b_prefix, b_unit, b_power);
    if (!(a_unit == b_unit) || !(a_power == b_power) ) {
        return false;
    }
    return true;
}

bool isScalable(const vector<string> &unitsA, const vector<string> &unitsB) {
    bool scalable = true;

    if (unitsA.size() != unitsB.size()) {
        return false;
    }

    auto itA = unitsA.begin();
    auto itB = unitsB.begin();
    while (scalable && itA != unitsA.end()) {
        scalable = isScalable(*itA, *itB);
        ++itA;
        ++itB;
    }

    return scalable;
}

bool isSetAtSamePos(const vector<string> &unitsA, const vector<string> &unitsB) {
    bool set_same = true;

    if (unitsA.size() != unitsB.size()) {
        return false;
    }

    auto itA = unitsA.begin();
    auto itB = unitsB.begin();
    while (set_same && itA != unitsA.end()) {
        set_same = (*itA).empty() == (*itB).empty();
        ++itA;
        ++itB;
    }

    return set_same;
}

double getSIScaling(const string &originUnit, const string &destinationUnit) {
    double scaling = 1.0;
    if (!isScalable(originUnit, destinationUnit)) {
        throw nix::InvalidUnit("Origin unit and destination unit are not scalable versions of the same SI unit!",
                               "nix::util::getSIScaling");
    }

    string org_unit, org_prefix, org_power;
    string dest_unit, dest_prefix, dest_power;
    splitUnit(originUnit, org_prefix, org_unit, org_power);
    splitUnit(destinationUnit, dest_prefix, dest_unit, dest_power);

    if ((org_prefix == dest_prefix) && (org_power == dest_power)) {
        return scaling;
    }
    if (dest_prefix.empty() && !org_prefix.empty()) {
        scaling = PREFIX_FACTORS.at(org_prefix);
    } else if (org_prefix.empty() && !dest_prefix.empty()) {
        scaling = 1.0 / PREFIX_FACTORS.at(dest_prefix);
    } else if (!org_prefix.empty() && !dest_prefix.empty()) {
        scaling = PREFIX_FACTORS.at(org_prefix) / PREFIX_FACTORS.at(dest_prefix);
    }
    if (!org_power.empty()) {
        int power = std::stoi(org_power);
        scaling = pow(scaling, power);
    }
    return scaling;
}

void applyPolynomial(const std::vector<double> &coefficients,
                     double origin,
                     const double *input,
                     double *output,
                     size_t n) {

    if (!coefficients.size()) {
        // if we have no coefficients, i.e no polynomial specified we
        // should still apply the the origin transformation
        for (size_t k = 0; k < n; k++) {
            output[k] = input[k] - origin;
        }

    } else {

        for (size_t k = 0; k < n; k++) {
            const double x = input[k] - origin;
            double value = 0.0;
            double term = 1.0;
            for (size_t i = 0; i < coefficients.size(); i++) {
                value += coefficients[i] * term;
                term *= x;
            }
            output[k] = value;
        }
    }
}

bool looksLikeUUID(const std::string &id) {
    // we don't want a complete check, just a glance
    // uuid form is: 8-4-4-4-12 = 36 [8, 13, 18, 23, ]
    return id.size() == 36 && id[8] == '-' && id[13] == '-' && id[18] == '-' && id[23] =='-';
}

} // namespace util
} // namespace nix
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

int p[50]={0};

void Init(){

	p[2]=p[3]=p[5]=p[7]=p[11]=p[13]=p[17]=p[23]=p[29]=p[31]=1;

	return ;
}

int a[30]={0};
int count1;
int m;
int add(int cur,int i){

	int sum=0;

	REP(j,0,m-2){
		sum+=a[cur-j];
	}
	sum+=i;
	if(p[sum]==1){
		return 1;
	}
	else{
		return 0;
	}

}
int n;

int dfs(int cur){
	REP(i,0,9){
		//print(i);
		if(add(cur,i)){
			print(i);
			if(cur==n+5){
				count1++;
			}else{
				a[cur++]=i;
				dfs(cur);
			}

		}
	}
}
void Solve(){
	scanf("%d%d",&n,&m);
	dfs(5);
	cout<<count1<<endl;
	return ;
}

int main(){
#ifdef LOCAL
	freopen("uoj18025.in","r",stdin);
#endif

 	int t;
 	scanf("%d",&t);
	Init(),Solve();
	return 0;
}<commit_msg>update uoj18025<commit_after>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

int p[50]={0};

void Init(){

	p[2]=p[3]=p[5]=p[7]=p[11]=p[13]=p[17]=p[23]=p[29]=p[31]=1;

	return ;
}

int a[30]={0};
int count1;
int m;
int add(int cur,int i){

	int sum=0;

	REP(j,0,m-2){
		sum+=a[cur-j];
	}
	sum+=i;
	if(p[sum]==1){
		return 1;
	}
	else{
		return 0;
	}

}
int n;

int dfs(int cur){
	REP(i,0,9){
		//print(i);
		if(add(cur,i)){
			//print(i);
			if(cur==n+5){
				count1++;
			}else{
				a[cur++]=i;
				dfs(cur);
			}

		}
	}
}
void Solve(){
	scanf("%d%d",&n,&m);
	dfs(5);
	cout<<count1<<endl;
	return ;
}

int main(){
#ifdef LOCAL
	freopen("uoj18025.in","r",stdin);
#endif

 	int t;
 	scanf("%d",&t);
	Init(),Solve();
	return 0;
}<|endoftext|>