<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/process.h>
#include <vistk/pipeline/process_exception.h>
#include <vistk/pipeline/stamp.h>

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

/**
 * \file process.cxx
 *
 * \brief Python bindings for \link vistk::process\endlink.
 */

using namespace boost::python;

static void translator(vistk::process_exception const& e);

class wrap_process
  : public vistk::process
  , public wrapper<vistk::process>
{
  public:
    wrap_process(vistk::config_t const& config);
    ~wrap_process();

    void _init();

    void _step();

    void _connect_input_port(port_t const& port, vistk::edge_ref_t edge);
    void _connect_output_port(port_t const& port, vistk::edge_ref_t edge);

    ports_t _input_ports() const;
    ports_t _output_ports() const;

    port_info_t _input_port_info(port_t const& port) const;
    port_info_t _output_port_info(port_t const& port) const;

    vistk::config::keys_t _available_config() const;

    conf_info_t _config_info(vistk::config::key_t const& key) const;

    void _mark_as_complete();
    vistk::stamp_t _heartbeat_stamp() const;

    bool _same_colored_data(vistk::edge_data_t const& data);
    bool _syncd_data(vistk::edge_data_t const& data);
    vistk::datum::datum_type_t _max_status(vistk::edge_data_t const& data);
    void _push_to_edges(vistk::edge_group_t const& edges, vistk::edge_datum_t const& dat);
    vistk::edge_datum_t _grab_from_edge_ref(vistk::edge_ref_t const& edge);
};

BOOST_PYTHON_MODULE(process)
{
  register_exception_translator<
    vistk::process_exception>(translator);

  class_<vistk::process::name_t>("ProcessName");
  class_<vistk::process::names_t>("ProcessNames")
    .def(vector_indexing_suite<vistk::process::names_t>())
  ;
  class_<vistk::process::port_description_t>("PortDescription");
  class_<vistk::process::port_t>("Port");
  class_<vistk::process::ports_t>("Ports")
    .def(vector_indexing_suite<vistk::process::ports_t>())
  ;
  class_<vistk::process::port_type_t>("PortType");
  class_<vistk::process::port_flag_t>("PortFlag");
  class_<vistk::process::port_flags_t>("PortFlags")
    .def("__len__", &vistk::process::port_flags_t::size)
    //.def("__contains__", &port_flags_contains)
    //.def("isdisjoint", &port_flags_isdisjoint)
    //.def("issubset", &port_flags_issubset)
    //.def("issuperset", &port_flags_issuperset)
    //.def("union", &port_flags_union)
    //.def("intersection", &port_flags_intersection)
    //.def("difference", &port_flags_difference)
    //.def("symmetric_difference", &port_flags_symmetric_difference)
    //.def("copy", &port_flags_copy)
    //.def("update", &port_flags_update)
    //.def("intersection_update", &port_flags_intersection_update)
    //.def("difference_update", &port_flags_difference_update)
    //.def("symmetric_difference_update", &port_flags_symmetric_difference_update)
    //.def("add", &port_flags_add)
    //.def("remove", &port_flags_remove)
    //.def("discard", &port_flags_discard)
    //.def("pop", &port_flags_discard)
    .def("clear", &vistk::process::port_flags_t::clear)
  ;
  class_<vistk::process::port_addr_t>("PortAddr");
  class_<vistk::process::port_addrs_t>("PortAddrs")
    .def(vector_indexing_suite<vistk::process::port_addrs_t>())
  ;

  /*
   *class_<vistk::process::port_info, vistk::process::port_info_t>("PortInfo", no_init)
   *  .def(init<vistk::process::port_type_t, vistk::process::port_flags_t, vistk::process::port_description_t>())
   *  .def_readonly("type", &vistk::process::port_info::type)
   *  .def_readonly("flags", &vistk::process::port_info::flags)
   *  .def_readonly("description", &vistk::process::port_info::description)
   *;
   */
  /*
   *class_<vistk::process::conf_info, vistk::process::conf_info_t>("ConfInfo", no_init)
   *  .def(init<vistk::config::value_t, vistk::config::description_t>())
   *  .def_readonly("default", &vistk::process::conf_info::def)
   *  .def_readonly("description", &vistk::process::conf_info::description)
   *;
   */

  class_<wrap_process, boost::noncopyable>("PythonProcess"
    , no_init)
    .def(init<vistk::config_t>())
    .def("init", &vistk::process::init)
    .def("step", &vistk::process::step)
    .def("is_reentrant", &vistk::process::is_reentrant)
    .def("connect_input_port", &vistk::process::connect_input_port)
    .def("connect_output_port", &vistk::process::connect_output_port)
    .def("input_ports", &vistk::process::input_ports)
    .def("output_ports", &vistk::process::output_ports)
    .def("input_port_info", &vistk::process::input_port_info)
    .def("output_port_info", &vistk::process::output_port_info)
    .def("available_config", &vistk::process::available_config)
    .def("config_info", &vistk::process::config_info)
    .def("name", &vistk::process::name)
    .def("type", &vistk::process::type)
    .def_readonly("port_heartbeat", &vistk::process::port_heartbeat)
    .def_readonly("config_name", &vistk::process::config_name)
    .def_readonly("config_type", &vistk::process::config_type)
    .def_readonly("type_any", &vistk::process::type_any)
    .def_readonly("type_none", &vistk::process::type_none)
    .def_readonly("flag_output_const", &vistk::process::flag_output_const)
    .def_readonly("flag_input_mutable", &vistk::process::flag_input_mutable)
    .def_readonly("flag_required", &vistk::process::flag_required)
    .def("_init", &wrap_process::_init)
    .def("_step", &wrap_process::_step)
    .def("_connect_input_port", &wrap_process::_connect_input_port)
    .def("_connect_output_port", &wrap_process::_connect_output_port)
    .def("_input_ports", &wrap_process::_input_ports)
    .def("_output_ports", &wrap_process::_output_ports)
    .def("_input_port_info", &wrap_process::_input_port_info)
    .def("_output_port_info", &wrap_process::_output_port_info)
    .def("_available_config", &wrap_process::_available_config)
    .def("_config_info", &wrap_process::_config_info)
    .def("mark_as_complete", &wrap_process::_mark_as_complete)
    .def("heartbeat_stamp", &wrap_process::_heartbeat_stamp)
    .def("same_colored_data", &wrap_process::_same_colored_data)
    .def("syncd_data", &wrap_process::_syncd_data)
    .def("max_status", &wrap_process::_max_status)
    .def("push_to_edges", &wrap_process::_push_to_edges)
    .def("grab_from_edge", &wrap_process::_grab_from_edge_ref)
  ;
}

void
translator(vistk::process_exception const& e)
{
  PyErr_SetString(PyExc_RuntimeError, e.what());
}

wrap_process
::wrap_process(vistk::config_t const& config)
  : vistk::process(config)
{
}

wrap_process
::~wrap_process()
{
}

void
wrap_process
::_init()
{
  override f = get_override("_init");

  if (f)
  {
    f();
  }
  else
  {
    process::_init();
  }
}

void
wrap_process
::_step()
{
  override f = get_override("_step");

  if (f)
  {
    f();
  }
  else
  {
    process::_step();
  }
}

void
wrap_process
::_connect_input_port(port_t const& port, vistk::edge_ref_t edge)
{
  override f = get_override("_connect_input_port");

  if (f)
  {
    f(port, edge);
  }
  else
  {
    process::_connect_input_port(port, edge);
  }
}

void
wrap_process
::_connect_output_port(port_t const& port, vistk::edge_ref_t edge)
{
  override f = get_override("_connect_output_port");

  if (f)
  {
    f(port, edge);
  }
  else
  {
    process::_connect_output_port(port, edge);
  }
}

vistk::process::ports_t
wrap_process
::_input_ports() const
{
  override f = get_override("_input_ports");

  if (f)
  {
    return f();
  }
  else
  {
    return process::_input_ports();
  }
}

vistk::process::ports_t
wrap_process
::_output_ports() const
{
  override f = get_override("_output_ports");

  if (f)
  {
    return f();
  }
  else
  {
    return process::_output_ports();
  }
}

vistk::process::port_info_t
wrap_process
::_input_port_info(port_t const& port) const
{
  override f = get_override("_input_port_info");

  if (f)
  {
    return f(port);
  }
  else
  {
    return process::_input_port_info(port);
  }
}

vistk::process::port_info_t
wrap_process
::_output_port_info(port_t const& port) const
{
  override f = get_override("_output_port_info");

  if (f)
  {
    return f(port);
  }
  else
  {
    return process::_output_port_info(port);
  }
}

vistk::config::keys_t
wrap_process
::_available_config() const
{
  override f = get_override("_available_config");

  if (f)
  {
    return f();
  }
  else
  {
    return process::_available_config();
  }
}

vistk::process::conf_info_t
wrap_process
::_config_info(vistk::config::key_t const& key) const
{
  override f = get_override("_config_info");

  if (f)
  {
    return f(key);
  }
  else
  {
    return process::_config_info(key);
  }
}

void
wrap_process
::_mark_as_complete()
{
  mark_as_complete();
}

vistk::stamp_t
wrap_process
::_heartbeat_stamp() const
{
  return heartbeat_stamp();
}

bool
wrap_process
::_same_colored_data(vistk::edge_data_t const& data)
{
  return same_colored_data(data);
}

bool
wrap_process
::_syncd_data(vistk::edge_data_t const& data)
{
  return syncd_data(data);
}

vistk::datum::datum_type_t
wrap_process
::_max_status(vistk::edge_data_t const& data)
{
  return max_status(data);
}

void
wrap_process
::_push_to_edges(vistk::edge_group_t const& edges, vistk::edge_datum_t const& dat)
{
  push_to_edges(edges, dat);
}

vistk::edge_datum_t
wrap_process
::_grab_from_edge_ref(vistk::edge_ref_t const& edge)
{
  return grab_from_edge_ref(edge);
}
<commit_msg>Add names for PortAddr accessors<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/process.h>
#include <vistk/pipeline/process_exception.h>
#include <vistk/pipeline/stamp.h>

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

/**
 * \file process.cxx
 *
 * \brief Python bindings for \link vistk::process\endlink.
 */

using namespace boost::python;

static void translator(vistk::process_exception const& e);

class wrap_process
  : public vistk::process
  , public wrapper<vistk::process>
{
  public:
    wrap_process(vistk::config_t const& config);
    ~wrap_process();

    void _init();

    void _step();

    void _connect_input_port(port_t const& port, vistk::edge_ref_t edge);
    void _connect_output_port(port_t const& port, vistk::edge_ref_t edge);

    ports_t _input_ports() const;
    ports_t _output_ports() const;

    port_info_t _input_port_info(port_t const& port) const;
    port_info_t _output_port_info(port_t const& port) const;

    vistk::config::keys_t _available_config() const;

    conf_info_t _config_info(vistk::config::key_t const& key) const;

    void _mark_as_complete();
    vistk::stamp_t _heartbeat_stamp() const;

    bool _same_colored_data(vistk::edge_data_t const& data);
    bool _syncd_data(vistk::edge_data_t const& data);
    vistk::datum::datum_type_t _max_status(vistk::edge_data_t const& data);
    void _push_to_edges(vistk::edge_group_t const& edges, vistk::edge_datum_t const& dat);
    vistk::edge_datum_t _grab_from_edge_ref(vistk::edge_ref_t const& edge);
};

BOOST_PYTHON_MODULE(process)
{
  register_exception_translator<
    vistk::process_exception>(translator);

  class_<vistk::process::name_t>("ProcessName");
  class_<vistk::process::names_t>("ProcessNames")
    .def(vector_indexing_suite<vistk::process::names_t>())
  ;
  class_<vistk::process::port_description_t>("PortDescription");
  class_<vistk::process::port_t>("Port");
  class_<vistk::process::ports_t>("Ports")
    .def(vector_indexing_suite<vistk::process::ports_t>())
  ;
  class_<vistk::process::port_type_t>("PortType");
  class_<vistk::process::port_flag_t>("PortFlag");
  class_<vistk::process::port_flags_t>("PortFlags")
    .def("__len__", &vistk::process::port_flags_t::size)
    //.def("__contains__", &port_flags_contains)
    //.def("isdisjoint", &port_flags_isdisjoint)
    //.def("issubset", &port_flags_issubset)
    //.def("issuperset", &port_flags_issuperset)
    //.def("union", &port_flags_union)
    //.def("intersection", &port_flags_intersection)
    //.def("difference", &port_flags_difference)
    //.def("symmetric_difference", &port_flags_symmetric_difference)
    //.def("copy", &port_flags_copy)
    //.def("update", &port_flags_update)
    //.def("intersection_update", &port_flags_intersection_update)
    //.def("difference_update", &port_flags_difference_update)
    //.def("symmetric_difference_update", &port_flags_symmetric_difference_update)
    //.def("add", &port_flags_add)
    //.def("remove", &port_flags_remove)
    //.def("discard", &port_flags_discard)
    //.def("pop", &port_flags_discard)
    .def("clear", &vistk::process::port_flags_t::clear)
  ;
  class_<vistk::process::port_addr_t>("PortAddr")
    .def_readwrite("process", &vistk::process::port_addr_t::first)
    .def_readwrite("port", &vistk::process::port_addr_t::second)
  ;
  class_<vistk::process::port_addrs_t>("PortAddrs")
    .def(vector_indexing_suite<vistk::process::port_addrs_t>())
  ;

  /*
   *class_<vistk::process::port_info, vistk::process::port_info_t>("PortInfo", no_init)
   *  .def(init<vistk::process::port_type_t, vistk::process::port_flags_t, vistk::process::port_description_t>())
   *  .def_readonly("type", &vistk::process::port_info::type)
   *  .def_readonly("flags", &vistk::process::port_info::flags)
   *  .def_readonly("description", &vistk::process::port_info::description)
   *;
   */
  /*
   *class_<vistk::process::conf_info, vistk::process::conf_info_t>("ConfInfo", no_init)
   *  .def(init<vistk::config::value_t, vistk::config::description_t>())
   *  .def_readonly("default", &vistk::process::conf_info::def)
   *  .def_readonly("description", &vistk::process::conf_info::description)
   *;
   */

  class_<wrap_process, boost::noncopyable>("PythonProcess"
    , no_init)
    .def(init<vistk::config_t>())
    .def("init", &vistk::process::init)
    .def("step", &vistk::process::step)
    .def("is_reentrant", &vistk::process::is_reentrant)
    .def("connect_input_port", &vistk::process::connect_input_port)
    .def("connect_output_port", &vistk::process::connect_output_port)
    .def("input_ports", &vistk::process::input_ports)
    .def("output_ports", &vistk::process::output_ports)
    .def("input_port_info", &vistk::process::input_port_info)
    .def("output_port_info", &vistk::process::output_port_info)
    .def("available_config", &vistk::process::available_config)
    .def("config_info", &vistk::process::config_info)
    .def("name", &vistk::process::name)
    .def("type", &vistk::process::type)
    .def_readonly("port_heartbeat", &vistk::process::port_heartbeat)
    .def_readonly("config_name", &vistk::process::config_name)
    .def_readonly("config_type", &vistk::process::config_type)
    .def_readonly("type_any", &vistk::process::type_any)
    .def_readonly("type_none", &vistk::process::type_none)
    .def_readonly("flag_output_const", &vistk::process::flag_output_const)
    .def_readonly("flag_input_mutable", &vistk::process::flag_input_mutable)
    .def_readonly("flag_required", &vistk::process::flag_required)
    .def("_init", &wrap_process::_init)
    .def("_step", &wrap_process::_step)
    .def("_connect_input_port", &wrap_process::_connect_input_port)
    .def("_connect_output_port", &wrap_process::_connect_output_port)
    .def("_input_ports", &wrap_process::_input_ports)
    .def("_output_ports", &wrap_process::_output_ports)
    .def("_input_port_info", &wrap_process::_input_port_info)
    .def("_output_port_info", &wrap_process::_output_port_info)
    .def("_available_config", &wrap_process::_available_config)
    .def("_config_info", &wrap_process::_config_info)
    .def("mark_as_complete", &wrap_process::_mark_as_complete)
    .def("heartbeat_stamp", &wrap_process::_heartbeat_stamp)
    .def("same_colored_data", &wrap_process::_same_colored_data)
    .def("syncd_data", &wrap_process::_syncd_data)
    .def("max_status", &wrap_process::_max_status)
    .def("push_to_edges", &wrap_process::_push_to_edges)
    .def("grab_from_edge", &wrap_process::_grab_from_edge_ref)
  ;
}

void
translator(vistk::process_exception const& e)
{
  PyErr_SetString(PyExc_RuntimeError, e.what());
}

wrap_process
::wrap_process(vistk::config_t const& config)
  : vistk::process(config)
{
}

wrap_process
::~wrap_process()
{
}

void
wrap_process
::_init()
{
  override f = get_override("_init");

  if (f)
  {
    f();
  }
  else
  {
    process::_init();
  }
}

void
wrap_process
::_step()
{
  override f = get_override("_step");

  if (f)
  {
    f();
  }
  else
  {
    process::_step();
  }
}

void
wrap_process
::_connect_input_port(port_t const& port, vistk::edge_ref_t edge)
{
  override f = get_override("_connect_input_port");

  if (f)
  {
    f(port, edge);
  }
  else
  {
    process::_connect_input_port(port, edge);
  }
}

void
wrap_process
::_connect_output_port(port_t const& port, vistk::edge_ref_t edge)
{
  override f = get_override("_connect_output_port");

  if (f)
  {
    f(port, edge);
  }
  else
  {
    process::_connect_output_port(port, edge);
  }
}

vistk::process::ports_t
wrap_process
::_input_ports() const
{
  override f = get_override("_input_ports");

  if (f)
  {
    return f();
  }
  else
  {
    return process::_input_ports();
  }
}

vistk::process::ports_t
wrap_process
::_output_ports() const
{
  override f = get_override("_output_ports");

  if (f)
  {
    return f();
  }
  else
  {
    return process::_output_ports();
  }
}

vistk::process::port_info_t
wrap_process
::_input_port_info(port_t const& port) const
{
  override f = get_override("_input_port_info");

  if (f)
  {
    return f(port);
  }
  else
  {
    return process::_input_port_info(port);
  }
}

vistk::process::port_info_t
wrap_process
::_output_port_info(port_t const& port) const
{
  override f = get_override("_output_port_info");

  if (f)
  {
    return f(port);
  }
  else
  {
    return process::_output_port_info(port);
  }
}

vistk::config::keys_t
wrap_process
::_available_config() const
{
  override f = get_override("_available_config");

  if (f)
  {
    return f();
  }
  else
  {
    return process::_available_config();
  }
}

vistk::process::conf_info_t
wrap_process
::_config_info(vistk::config::key_t const& key) const
{
  override f = get_override("_config_info");

  if (f)
  {
    return f(key);
  }
  else
  {
    return process::_config_info(key);
  }
}

void
wrap_process
::_mark_as_complete()
{
  mark_as_complete();
}

vistk::stamp_t
wrap_process
::_heartbeat_stamp() const
{
  return heartbeat_stamp();
}

bool
wrap_process
::_same_colored_data(vistk::edge_data_t const& data)
{
  return same_colored_data(data);
}

bool
wrap_process
::_syncd_data(vistk::edge_data_t const& data)
{
  return syncd_data(data);
}

vistk::datum::datum_type_t
wrap_process
::_max_status(vistk::edge_data_t const& data)
{
  return max_status(data);
}

void
wrap_process
::_push_to_edges(vistk::edge_group_t const& edges, vistk::edge_datum_t const& dat)
{
  push_to_edges(edges, dat);
}

vistk::edge_datum_t
wrap_process
::_grab_from_edge_ref(vistk::edge_ref_t const& edge)
{
  return grab_from_edge_ref(edge);
}
<|endoftext|>


<commit_before>/*
    Copyright 2013 <copyright holder> <email>

    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 "counter.h"

#include <boost/bind.hpp>

TypedValue::TypedValue(const std::string& unit)
	: _value(0), unit(unit)
{}

uint64_t TypedValue::value() const
{
	return _value;
}

TypedValue TypedValue::autoScale() const
{
	std::string prefix;
	auto value_ = value();
	if (value_ >= 10*1000*1000*1000L) { value_ /= 1000000000; prefix = 'G'; }
	if (value_ >= 10*1000*1000) { value_ /= 1000000; prefix = 'M'; }
	if (value_ >= 10*1000) { value_ /= 1000; prefix = 'K'; }
	TypedValue res(prefix+unit);
	res._value = value_;
	return res;
}

Counter::Counter(const std::string& unit)
	: TypedValue(unit)
{}

uint64_t Counter::operator+=(uint64_t amount)
{
	return _value += amount;
}

uint64_t Counter::reset()
{
	auto res = _value;
	_value = 0;
	return res;
}

InertialValue::InertialValue(float falloff, const std::string& unit)
	: TypedValue(unit), _falloff(falloff)
{}

uint64_t InertialValue::post(uint64_t amount)
{
	return _value = (amount * _falloff) + (_value * (1.0-_falloff));
}

LazyCounter::LazyCounter(TimerService& ts, const std::string& unit, const boost::posix_time::time_duration& granularity, float falloff)
	: Counter(unit), _timer(ts, boost::bind(&LazyCounter::tick, this), granularity), _value(falloff, unit)
{
}

uint64_t LazyCounter::value() const
{
	return _value.value();
}

void LazyCounter::tick()
{
	_value.post(reset());
}

std::ostream& operator<<(std::ostream& tgt, const TypedValue& v)
{
	tgt << v.value() << v.unit;
	return tgt;
}
<commit_msg>[lib/counter]Fix typo.<commit_after>/*
    Copyright 2013 <copyright holder> <email>

    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 "counter.h"

#include <boost/bind.hpp>

TypedValue::TypedValue(const std::string& unit)
	: _value(0), unit(unit)
{}

uint64_t TypedValue::value() const
{
	return _value;
}

TypedValue TypedValue::autoScale() const
{
	std::string prefix;
	auto value_ = value();
	if (value_ >= 10*1000*1000*1000LL) { value_ /= 1000000000; prefix = 'G'; }
	if (value_ >= 10*1000*1000) { value_ /= 1000000; prefix = 'M'; }
	if (value_ >= 10*1000) { value_ /= 1000; prefix = 'K'; }
	TypedValue res(prefix+unit);
	res._value = value_;
	return res;
}

Counter::Counter(const std::string& unit)
	: TypedValue(unit)
{}

uint64_t Counter::operator+=(uint64_t amount)
{
	return _value += amount;
}

uint64_t Counter::reset()
{
	auto res = _value;
	_value = 0;
	return res;
}

InertialValue::InertialValue(float falloff, const std::string& unit)
	: TypedValue(unit), _falloff(falloff)
{}

uint64_t InertialValue::post(uint64_t amount)
{
	return _value = (amount * _falloff) + (_value * (1.0-_falloff));
}

LazyCounter::LazyCounter(TimerService& ts, const std::string& unit, const boost::posix_time::time_duration& granularity, float falloff)
	: Counter(unit), _timer(ts, boost::bind(&LazyCounter::tick, this), granularity), _value(falloff, unit)
{
}

uint64_t LazyCounter::value() const
{
	return _value.value();
}

void LazyCounter::tick()
{
	_value.post(reset());
}

std::ostream& operator<<(std::ostream& tgt, const TypedValue& v)
{
	tgt << v.value() << v.unit;
	return tgt;
}
<|endoftext|>


<commit_before>#include "offeracceptdialogbtc.h"
#include "ui_offeracceptdialogbtc.h"
#include "init.h"
#include "util.h"
#include "offerpaydialog.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "platformstyle.h"
#include "syscoingui.h"
#include <QMessageBox>
#include "rpcserver.h"
#include "pubkey.h"
#include "wallet/wallet.h"
#include "main.h"
#include <QDesktopServices>
#if QT_VERSION < 0x050000
#include <QUrl>
#else
#include <QUrlQuery>
#endif
#include <QPixmap>
#if defined(HAVE_CONFIG_H)
#include "config/syscoin-config.h" /* for USE_QRCODE */
#endif

#ifdef USE_QRCODE
#include <qrencode.h>
#endif
using namespace std;
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

extern const CRPCTable tableRPC;
OfferAcceptDialogBTC::OfferAcceptDialogBTC(const PlatformStyle *platformStyle, QString alias, QString offer, QString quantity, QString notes, QString title, QString currencyCode, QString qstrPrice, QString sellerAlias, QString address, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OfferAcceptDialogBTC), platformStyle(platformStyle), alias(alias), offer(offer), notes(notes), quantity(quantity), title(title), sellerAlias(sellerAlias), address(address)
{
    ui->setupUi(this);
	QString theme = GUIUtil::getThemeName();
	ui->aboutShadeBTC->setPixmap(QPixmap(":/images/" + theme + "/about_btc"));
	double dblPrice = qstrPrice.toDouble()*quantity.toUInt();
	string strfPrice = strprintf("%f", dblPrice);
	QString fprice = QString::fromStdString(strfPrice);
	string strCurrencyCode = currencyCode.toStdString();
	ui->escrowDisclaimer->setText(tr("Please note escrow is not available since you are paying in BTC, only SYS payments can be escrowed. "));
	ui->bitcoinInstructionLabel->setText(tr("After paying for this item, please enter the Bitcoin Transaction ID and click on the confirm button below. You may use the QR Code to the left to scan the payment request into your wallet or click on the Open BTC Wallet if you are on the desktop and have Bitcoin Core installed."));
	ui->acceptMessage->setText(tr("Are you sure you want to purchase %1 of '%2' from merchant: '%3'? To complete your purchase please pay %4 BTC using your Bitcoin wallet.").arg(quantity).arg(title).arg(sellerAlias).arg(fprice));
	string strPrice = strprintf("%f", dblPrice);
	price = QString::fromStdString(strPrice);

	if (!platformStyle->getImagesOnButtons())
	{
		ui->confirmButton->setIcon(QIcon());
		ui->openBtcWalletButton->setIcon(QIcon());
		ui->cancelButton->setIcon(QIcon());

	}
	else
	{
		ui->confirmButton->setIcon(platformStyle->SingleColorIcon(":/icons/" + theme + "/transaction_confirmed"));
		ui->openBtcWalletButton->setIcon(platformStyle->SingleColorIcon(":/icons/" + theme + "/send"));
		ui->cancelButton->setIcon(platformStyle->SingleColorIcon(":/icons/" + theme + "/quit"));
	}
	this->offerPaid = false;
	connect(ui->confirmButton, SIGNAL(clicked()), this, SLOT(acceptPayment()));
	connect(ui->openBtcWalletButton, SIGNAL(clicked()), this, SLOT(openBTCWallet()));

#ifdef USE_QRCODE
	QString message = "Payment for offer ID " + this->offer + " on Syscoin Decentralized Marketplace";
	QString uri = "bitcoin:" + this->address + "?amount=" + price + "&label=" + this->sellerAlias + "&message=" + GUIUtil::HtmlEscape(message);

	ui->lblQRCode->setText("");
    if(!uri.isEmpty())
    {
        // limit URI length
        if (uri.length() > MAX_URI_LENGTH)
        {
            ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
        } else {
            QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
            if (!code)
            {
                ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
                return;
            }
            QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
            myImage.fill(0xffffff);
            unsigned char *p = code->data;
            for (int y = 0; y width; y++)
            {
                for (int x = 0; x width; x++)
                {
                    myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
                    p++;
                }
            }
            QRcode_free(code);
            ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(128, 128));
        }
    }
#endif
}
void OfferAcceptDialogBTC::on_cancelButton_clicked()
{
    reject();
}
OfferAcceptDialogBTC::~OfferAcceptDialogBTC()
{
    delete ui;
}

void OfferAcceptDialogBTC::acceptPayment()
{
	acceptOffer();
}
bool OfferAcceptDialogBTC::CheckPaymentInBTC(const QString &strBTCTxId, const QString& address, const QString& price)
{
	string msg = "https://blockchain.info/tx/" + strBTCTxId.toStdString() + "?format=json";
	LogPrintf("CheckPaymentInBTC %s\n", msg);

	LogPrintf("QNetworkAccessManager\n");
	QNetworkAccessManager *nam = new QNetworkAccessManager(this);
	QUrl url("https://blockchain.info/tx/" + strBTCTxId + "?format=json");
	QNetworkRequest request(url);
	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
	QNetworkReply* reply = nam->get(request);
	reply->ignoreSslErrors();
	int totalTime = 0;
	while(!reply->isFinished())
	{
		totalTime += 100;
		MilliSleep(100);
		if(totalTime > 3000)
			throw runtime_error("Timeout connecting to blockchain.info!");
	}
	if(reply->error() == QNetworkReply::NoError) {

		LogPrintf("response: %s\n", reply->readAll().toStdString().c_str());
		UniValue outerValue(UniValue::VSTR);
		bool read = outerValue.read(reply->readAll().toStdString());
		if (read)
		{
			LogPrintf("gotjson!\n");
			UniValue outerObj = outerValue.get_obj();
			UniValue ratesValue = find_value(outerObj, "rates");
			if (ratesValue.isArray())
			{
			}
		}
	}
	reply->deleteLater();
	return false;

}

bool OfferAcceptDialogBTC::lookup(const QString &lookupid, QString& address, QString& price)
{
	string strError;
	string strMethod = string("offerinfo");
	UniValue params(UniValue::VARR);
	UniValue result;
	params.push_back(lookupid.toStdString());

    try {
        result = tableRPC.execute(strMethod, params);

		if (result.type() == UniValue::VOBJ)
		{
			const UniValue &offerObj = result.get_obj();

			const string &strAddress = find_value(offerObj, "address").get_str();
			const string &strPrice = find_value(offerObj, "price").get_str();
			address = QString::fromStdString(strAddress);
			price = QString::fromStdString(strPrice);
			return true;
		}
	}
	catch (UniValue& objError)
	{
		QMessageBox::critical(this, windowTitle(),
			tr("Could not find this offer, please check the offer ID and that it has been confirmed by the blockchain: ") + lookupid,
				QMessageBox::Ok, QMessageBox::Ok);
		return true;

	}
	catch(std::exception& e)
	{
		QMessageBox::critical(this, windowTitle(),
			tr("There was an exception trying to locate this offer, please check the offer ID and that it has been confirmed by the blockchain: ") + QString::fromStdString(e.what()),
				QMessageBox::Ok, QMessageBox::Ok);
		return true;
	}
	return false;

}
// send offeraccept with offer guid/qty as params and then send offerpay with wtxid (first param of response) as param, using RPC commands.
void OfferAcceptDialogBTC::acceptOffer()
{
		QString address, price;
		if (ui->btctxidEdit->text().trimmed().isEmpty()) {
            ui->btctxidEdit->setText("");
            QMessageBox::information(this, windowTitle(),
            tr("Please enter a valid Bitcoin Transaction ID into the input box and try again"),
                QMessageBox::Ok, QMessageBox::Ok);
            return;
        }
		if(!lookup(this->offer, address, price))
		{
            QMessageBox::information(this, windowTitle(),
            tr("Could not find this offer, please check the offer ID and that it has been confirmed by the blockchain: ") + this->offer,
                QMessageBox::Ok, QMessageBox::Ok);
            return;
		}
		if(!CheckPaymentInBTC(ui->btctxidEdit->text().trimmed(), address, price))
		{
            QMessageBox::information(this, windowTitle(),
            tr("Could not find this payment, please check the Transaction ID and that it has been confirmed by the Bitcoin blockchain: ") + ui->btctxidEdit->text().trimmed(),
                QMessageBox::Ok, QMessageBox::Ok);
            return;
		}

		UniValue params(UniValue::VARR);
		UniValue valError;
		UniValue valResult;
		UniValue valId;
		UniValue result ;
		string strReply;
		string strError;

		string strMethod = string("offeraccept");
		if(this->quantity.toLong() <= 0)
		{
			QMessageBox::critical(this, windowTitle(),
				tr("Invalid quantity when trying to accept offer!"),
				QMessageBox::Ok, QMessageBox::Ok);
			return;
		}
		this->offerPaid = false;
		params.push_back(this->alias.toStdString());
		params.push_back(this->offer.toStdString());
		params.push_back(this->quantity.toStdString());
		params.push_back(this->notes.toStdString());
		params.push_back(ui->btctxidEdit->text().toStdString());

	    try {
            result = tableRPC.execute(strMethod, params);
			if (result.type() != UniValue::VNULL)
			{
				const UniValue &arr = result.get_array();
				string strResult = arr[0].get_str();
				QString offerAcceptTXID = QString::fromStdString(strResult);
				if(offerAcceptTXID != QString(""))
				{
					OfferPayDialog dlg(platformStyle, this->title, this->quantity, this->price, "BTC", this);
					dlg.exec();
					this->offerPaid = true;
					OfferAcceptDialogBTC::accept();
					return;

				}
			}
		}
		catch (UniValue& objError)
		{
			strError = find_value(objError, "message").get_str();
			QMessageBox::critical(this, windowTitle(),
			tr("Error accepting offer: \"%1\"").arg(QString::fromStdString(strError)),
				QMessageBox::Ok, QMessageBox::Ok);
			return;
		}
		catch(std::exception& e)
		{
			QMessageBox::critical(this, windowTitle(),
				tr("General exception when accepting offer"),
				QMessageBox::Ok, QMessageBox::Ok);
			return;
		}

}
void OfferAcceptDialogBTC::openBTCWallet()
{
	QString message = "Payment for offer ID " + this->offer + " on Syscoin Decentralized Marketplace";
	QString uri = "bitcoin:" + this->address + "?amount=" + price + "&label=" + this->sellerAlias + "&message=" + GUIUtil::HtmlEscape(message);
	QDesktopServices::openUrl(QUrl(uri, QUrl::TolerantMode));
}
bool OfferAcceptDialogBTC::getPaymentStatus()
{
	return this->offerPaid;
}
<commit_msg>time<commit_after>#include "offeracceptdialogbtc.h"
#include "ui_offeracceptdialogbtc.h"
#include "init.h"
#include "util.h"
#include "offerpaydialog.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "platformstyle.h"
#include "syscoingui.h"
#include <QMessageBox>
#include "rpcserver.h"
#include "pubkey.h"
#include "wallet/wallet.h"
#include "main.h"
#include <QDesktopServices>
#if QT_VERSION < 0x050000
#include <QUrl>
#else
#include <QUrlQuery>
#endif
#include <QPixmap>
#if defined(HAVE_CONFIG_H)
#include "config/syscoin-config.h" /* for USE_QRCODE */
#endif

#ifdef USE_QRCODE
#include <qrencode.h>
#endif
using namespace std;
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

extern const CRPCTable tableRPC;
OfferAcceptDialogBTC::OfferAcceptDialogBTC(const PlatformStyle *platformStyle, QString alias, QString offer, QString quantity, QString notes, QString title, QString currencyCode, QString qstrPrice, QString sellerAlias, QString address, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::OfferAcceptDialogBTC), platformStyle(platformStyle), alias(alias), offer(offer), notes(notes), quantity(quantity), title(title), sellerAlias(sellerAlias), address(address)
{
    ui->setupUi(this);
	QString theme = GUIUtil::getThemeName();
	ui->aboutShadeBTC->setPixmap(QPixmap(":/images/" + theme + "/about_btc"));
	double dblPrice = qstrPrice.toDouble()*quantity.toUInt();
	string strfPrice = strprintf("%f", dblPrice);
	QString fprice = QString::fromStdString(strfPrice);
	string strCurrencyCode = currencyCode.toStdString();
	ui->escrowDisclaimer->setText(tr("Please note escrow is not available since you are paying in BTC, only SYS payments can be escrowed. "));
	ui->bitcoinInstructionLabel->setText(tr("After paying for this item, please enter the Bitcoin Transaction ID and click on the confirm button below. You may use the QR Code to the left to scan the payment request into your wallet or click on the Open BTC Wallet if you are on the desktop and have Bitcoin Core installed."));
	ui->acceptMessage->setText(tr("Are you sure you want to purchase %1 of '%2' from merchant: '%3'? To complete your purchase please pay %4 BTC using your Bitcoin wallet.").arg(quantity).arg(title).arg(sellerAlias).arg(fprice));
	string strPrice = strprintf("%f", dblPrice);
	price = QString::fromStdString(strPrice);

	if (!platformStyle->getImagesOnButtons())
	{
		ui->confirmButton->setIcon(QIcon());
		ui->openBtcWalletButton->setIcon(QIcon());
		ui->cancelButton->setIcon(QIcon());

	}
	else
	{
		ui->confirmButton->setIcon(platformStyle->SingleColorIcon(":/icons/" + theme + "/transaction_confirmed"));
		ui->openBtcWalletButton->setIcon(platformStyle->SingleColorIcon(":/icons/" + theme + "/send"));
		ui->cancelButton->setIcon(platformStyle->SingleColorIcon(":/icons/" + theme + "/quit"));
	}
	this->offerPaid = false;
	connect(ui->confirmButton, SIGNAL(clicked()), this, SLOT(acceptPayment()));
	connect(ui->openBtcWalletButton, SIGNAL(clicked()), this, SLOT(openBTCWallet()));

#ifdef USE_QRCODE
	QString message = "Payment for offer ID " + this->offer + " on Syscoin Decentralized Marketplace";
	QString uri = "bitcoin:" + this->address + "?amount=" + price + "&label=" + this->sellerAlias + "&message=" + GUIUtil::HtmlEscape(message);

	ui->lblQRCode->setText("");
    if(!uri.isEmpty())
    {
        // limit URI length
        if (uri.length() > MAX_URI_LENGTH)
        {
            ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
        } else {
            QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
            if (!code)
            {
                ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
                return;
            }
            QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
            myImage.fill(0xffffff);
            unsigned char *p = code->data;
            for (int y = 0; y width; y++)
            {
                for (int x = 0; x width; x++)
                {
                    myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
                    p++;
                }
            }
            QRcode_free(code);
            ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(128, 128));
        }
    }
#endif
}
void OfferAcceptDialogBTC::on_cancelButton_clicked()
{
    reject();
}
OfferAcceptDialogBTC::~OfferAcceptDialogBTC()
{
    delete ui;
}

void OfferAcceptDialogBTC::acceptPayment()
{
	acceptOffer();
}
bool OfferAcceptDialogBTC::CheckPaymentInBTC(const QString &strBTCTxId, const QString& address, const QString& price)
{
	string msg = "https://blockchain.info/tx/" + strBTCTxId.toStdString() + "?format=json";
	LogPrintf("CheckPaymentInBTC %s\n", msg);

	LogPrintf("QNetworkAccessManager\n");
	QNetworkAccessManager *nam = new QNetworkAccessManager(this);
	QUrl url("https://blockchain.info/tx/" + strBTCTxId + "?format=json");
	QNetworkRequest request(url);
	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
	QNetworkReply* reply = nam->get(request);
	reply->ignoreSslErrors();
	int totalTime = 0;
	while(!reply->isFinished())
	{
		totalTime += 100;
		MilliSleep(100);
		if(totalTime > 30000)
			throw runtime_error("Timeout connecting to blockchain.info!");
	}
	if(reply->error() == QNetworkReply::NoError) {

		LogPrintf("response: %s\n", reply->readAll().toStdString().c_str());
		UniValue outerValue(UniValue::VSTR);
		bool read = outerValue.read(reply->readAll().toStdString());
		if (read)
		{
			LogPrintf("gotjson!\n");
			UniValue outerObj = outerValue.get_obj();
			UniValue ratesValue = find_value(outerObj, "rates");
			if (ratesValue.isArray())
			{
			}
		}
	}
	reply->deleteLater();
	return false;

}

bool OfferAcceptDialogBTC::lookup(const QString &lookupid, QString& address, QString& price)
{
	string strError;
	string strMethod = string("offerinfo");
	UniValue params(UniValue::VARR);
	UniValue result;
	params.push_back(lookupid.toStdString());

    try {
        result = tableRPC.execute(strMethod, params);

		if (result.type() == UniValue::VOBJ)
		{
			const UniValue &offerObj = result.get_obj();

			const string &strAddress = find_value(offerObj, "address").get_str();
			const string &strPrice = find_value(offerObj, "price").get_str();
			address = QString::fromStdString(strAddress);
			price = QString::fromStdString(strPrice);
			return true;
		}
	}
	catch (UniValue& objError)
	{
		QMessageBox::critical(this, windowTitle(),
			tr("Could not find this offer, please check the offer ID and that it has been confirmed by the blockchain: ") + lookupid,
				QMessageBox::Ok, QMessageBox::Ok);
		return true;

	}
	catch(std::exception& e)
	{
		QMessageBox::critical(this, windowTitle(),
			tr("There was an exception trying to locate this offer, please check the offer ID and that it has been confirmed by the blockchain: ") + QString::fromStdString(e.what()),
				QMessageBox::Ok, QMessageBox::Ok);
		return true;
	}
	return false;

}
// send offeraccept with offer guid/qty as params and then send offerpay with wtxid (first param of response) as param, using RPC commands.
void OfferAcceptDialogBTC::acceptOffer()
{
		QString address, price;
		if (ui->btctxidEdit->text().trimmed().isEmpty()) {
            ui->btctxidEdit->setText("");
            QMessageBox::information(this, windowTitle(),
            tr("Please enter a valid Bitcoin Transaction ID into the input box and try again"),
                QMessageBox::Ok, QMessageBox::Ok);
            return;
        }
		if(!lookup(this->offer, address, price))
		{
            QMessageBox::information(this, windowTitle(),
            tr("Could not find this offer, please check the offer ID and that it has been confirmed by the blockchain: ") + this->offer,
                QMessageBox::Ok, QMessageBox::Ok);
            return;
		}
		if(!CheckPaymentInBTC(ui->btctxidEdit->text().trimmed(), address, price))
		{
            QMessageBox::information(this, windowTitle(),
            tr("Could not find this payment, please check the Transaction ID and that it has been confirmed by the Bitcoin blockchain: ") + ui->btctxidEdit->text().trimmed(),
                QMessageBox::Ok, QMessageBox::Ok);
            return;
		}

		UniValue params(UniValue::VARR);
		UniValue valError;
		UniValue valResult;
		UniValue valId;
		UniValue result ;
		string strReply;
		string strError;

		string strMethod = string("offeraccept");
		if(this->quantity.toLong() <= 0)
		{
			QMessageBox::critical(this, windowTitle(),
				tr("Invalid quantity when trying to accept offer!"),
				QMessageBox::Ok, QMessageBox::Ok);
			return;
		}
		this->offerPaid = false;
		params.push_back(this->alias.toStdString());
		params.push_back(this->offer.toStdString());
		params.push_back(this->quantity.toStdString());
		params.push_back(this->notes.toStdString());
		params.push_back(ui->btctxidEdit->text().toStdString());

	    try {
            result = tableRPC.execute(strMethod, params);
			if (result.type() != UniValue::VNULL)
			{
				const UniValue &arr = result.get_array();
				string strResult = arr[0].get_str();
				QString offerAcceptTXID = QString::fromStdString(strResult);
				if(offerAcceptTXID != QString(""))
				{
					OfferPayDialog dlg(platformStyle, this->title, this->quantity, this->price, "BTC", this);
					dlg.exec();
					this->offerPaid = true;
					OfferAcceptDialogBTC::accept();
					return;

				}
			}
		}
		catch (UniValue& objError)
		{
			strError = find_value(objError, "message").get_str();
			QMessageBox::critical(this, windowTitle(),
			tr("Error accepting offer: \"%1\"").arg(QString::fromStdString(strError)),
				QMessageBox::Ok, QMessageBox::Ok);
			return;
		}
		catch(std::exception& e)
		{
			QMessageBox::critical(this, windowTitle(),
				tr("General exception when accepting offer"),
				QMessageBox::Ok, QMessageBox::Ok);
			return;
		}

}
void OfferAcceptDialogBTC::openBTCWallet()
{
	QString message = "Payment for offer ID " + this->offer + " on Syscoin Decentralized Marketplace";
	QString uri = "bitcoin:" + this->address + "?amount=" + price + "&label=" + this->sellerAlias + "&message=" + GUIUtil::HtmlEscape(message);
	QDesktopServices::openUrl(QUrl(uri, QUrl::TolerantMode));
}
bool OfferAcceptDialogBTC::getPaymentStatus()
{
	return this->offerPaid;
}
<|endoftext|>


<commit_before>/*****************************************************************************
  randomBedMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "randomBed.h"
#include "version.h"

using namespace std;

// define our program name
#define PROGRAM_NAME "bedtools random"

// define our parameter checking macro
#define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)

// function declarations
void random_help(void);

int random_main(int argc, char* argv[]) {

    // our configuration variables
    bool showHelp = false;

    // input files
    string bedFile = "stdin";
    string genomeFile;

    bool haveGenome       = false;
    bool haveSeed         = false;
    int seed              = -1;
    int length            = 100;
    int numToGenerate     = 1000000;

    for(int i = 1; i < argc; i++) {
        int parameterLength = (int)strlen(argv[i]);

        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
        (PARAMETER_CHECK("--help", 5, parameterLength))) {
            showHelp = true;
        }
    }

    if(showHelp) random_help();

    // do some parsing (all of these parameters require 2 strings)
    for(int i = 1; i < argc; i++) {

        int parameterLength = (int)strlen(argv[i]);

        if(PARAMETER_CHECK("-g", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveGenome = true;
                genomeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-seed", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveSeed = true;
                seed = atoi(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-l", 2, parameterLength)) {
            if ((i+1) < argc) {
                length = atoi(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-n", 2, parameterLength)) {
            if ((i+1) < argc) {
                numToGenerate = atoi(argv[i + 1]);
                i++;
            }
        }
        else {
          cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
            showHelp = true;
        }
    }

    // make sure we have both input files
    if (!haveGenome) {
      cerr << endl << "*****" << endl << "*****ERROR: Need a genome (-g) file. " << endl << "*****" << endl;
      showHelp = true;
    }

    if (!showHelp) {
        BedRandom *br = new BedRandom(genomeFile, numToGenerate, seed, haveSeed, length);
        delete br;
        return 0;
    }
    else {
        random_help();
    }
    return 0;
}

void random_help(void) {

    cerr << "\nTool:    bedtools random (aka randomBed)" << endl;
    cerr << "Version: " << VERSION << "\n";
    cerr << "Summary: Generate random intervals among a genome." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -g <genome>" << endl << endl;

    cerr << "Options: " << endl;

    cerr << "\t-l\t"                << "The length of the intervals to generate." << endl;
    cerr                            << "\t\t- Default = 100." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-n\t"                << "The number of intervals to generate." << endl;
    cerr                            << "\t\t- Default = 1,000,000." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-n\t"                << "Supply an integer seed for the shuffling." << endl;
    cerr                            << "\t\t- By default, the seed is chosen automatically." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-seed\t"             << "Supply an integer seed for the shuffling." << endl;
    cerr                            << "\t\t- By default, the seed is chosen automatically." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1)  The genome file should tab delimited and structured as follows:" << endl;
    cerr << "\t     <chromName><TAB><chromSize>" << endl << endl;
    cerr << "\tFor example, Human (hg19):" << endl;
    cerr << "\tchr1\t249250621" << endl;
    cerr << "\tchr2\t243199373" << endl;
    cerr << "\t..." << endl;
    cerr << "\tchr18_gl000207_random\t4262" << endl << endl;

    cerr << "Tips: " << endl;
    cerr << "\tOne can use the UCSC Genome Browser's MySQL database to extract" << endl;
    cerr << "\tchromosome sizes. For example, H. sapiens:" << endl << endl;
    cerr << "\tmysql --user=genome --host=genome-mysql.cse.ucsc.edu -A -e \\" << endl;
    cerr << "\t\"select chrom, size from hg19.chromInfo\"  > hg19.genome" << endl << endl;

    // end the program here
    exit(1);
}
<commit_msg>correct bt random's help<commit_after>/*****************************************************************************
  randomBedMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
#include "randomBed.h"
#include "version.h"

using namespace std;

// define our program name
#define PROGRAM_NAME "bedtools random"

// define our parameter checking macro
#define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)

// function declarations
void random_help(void);

int random_main(int argc, char* argv[]) {

    // our configuration variables
    bool showHelp = false;

    // input files
    string bedFile = "stdin";
    string genomeFile;

    bool haveGenome       = false;
    bool haveSeed         = false;
    int seed              = -1;
    int length            = 100;
    int numToGenerate     = 1000000;

    for(int i = 1; i < argc; i++) {
        int parameterLength = (int)strlen(argv[i]);

        if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
        (PARAMETER_CHECK("--help", 5, parameterLength))) {
            showHelp = true;
        }
    }

    if(showHelp) random_help();

    // do some parsing (all of these parameters require 2 strings)
    for(int i = 1; i < argc; i++) {

        int parameterLength = (int)strlen(argv[i]);

        if(PARAMETER_CHECK("-g", 2, parameterLength)) {
            if ((i+1) < argc) {
                haveGenome = true;
                genomeFile = argv[i + 1];
                i++;
            }
        }
        else if(PARAMETER_CHECK("-seed", 5, parameterLength)) {
            if ((i+1) < argc) {
                haveSeed = true;
                seed = atoi(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-l", 2, parameterLength)) {
            if ((i+1) < argc) {
                length = atoi(argv[i + 1]);
                i++;
            }
        }
        else if(PARAMETER_CHECK("-n", 2, parameterLength)) {
            if ((i+1) < argc) {
                numToGenerate = atoi(argv[i + 1]);
                i++;
            }
        }
        else {
          cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
            showHelp = true;
        }
    }

    // make sure we have both input files
    if (!haveGenome) {
      cerr << endl << "*****" << endl << "*****ERROR: Need a genome (-g) file. " << endl << "*****" << endl;
      showHelp = true;
    }

    if (!showHelp) {
        BedRandom *br = new BedRandom(genomeFile, numToGenerate, seed, haveSeed, length);
        delete br;
        return 0;
    }
    else {
        random_help();
    }
    return 0;
}

void random_help(void) {

    cerr << "\nTool:    bedtools random (aka randomBed)" << endl;
    cerr << "Version: " << VERSION << "\n";
    cerr << "Summary: Generate random intervals among a genome." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -g <genome>" << endl << endl;

    cerr << "Options: " << endl;

    cerr << "\t-l\t"                << "The length of the intervals to generate." << endl;
    cerr                            << "\t\t- Default = 100." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-n\t"                << "The number of intervals to generate." << endl;
    cerr                            << "\t\t- Default = 1,000,000." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "\t-seed\t"             << "Supply an integer seed for the shuffling." << endl;
    cerr                            << "\t\t- By default, the seed is chosen automatically." << endl;
    cerr                            << "\t\t- (INTEGER)" << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1)  The genome file should tab delimited and structured as follows:" << endl;
    cerr << "\t     <chromName><TAB><chromSize>" << endl << endl;
    cerr << "\tFor example, Human (hg19):" << endl;
    cerr << "\tchr1\t249250621" << endl;
    cerr << "\tchr2\t243199373" << endl;
    cerr << "\t..." << endl;
    cerr << "\tchr18_gl000207_random\t4262" << endl << endl;

    cerr << "Tips: " << endl;
    cerr << "\tOne can use the UCSC Genome Browser's MySQL database to extract" << endl;
    cerr << "\tchromosome sizes. For example, H. sapiens:" << endl << endl;
    cerr << "\tmysql --user=genome --host=genome-mysql.cse.ucsc.edu -A -e \\" << endl;
    cerr << "\t\"select chrom, size from hg19.chromInfo\"  > hg19.genome" << endl << endl;

    // end the program here
    exit(1);
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <iostream>
#include <chrono>
#include <cmath>

using timer = std::chrono::high_resolution_clock;
using microseconds =  std::chrono::microseconds;

double my_pow(double x, size_t n){
    double r = 1.0;

    while(n > 0){
        r *= x;
        --n;
    }

    return r;
}

template<size_t It, size_t Exp>
double bench_my_pow(){
    timer::time_point t0 = timer::now();

    double result = 0;

    for(size_t i = 0; i < It; ++i){
        result += my_pow(double(i), int(Exp));
    }

    timer::time_point t1 = timer::now();
    auto us = std::chrono::duration_cast<microseconds>(t1 - t0);

    std::cout << "my_pow(x, " << Exp << "): " << us.count() << "us" << std::endl;

    return result;
}

template<size_t It, size_t Exp>
double bench_std_pow(){
    timer::time_point t0 = timer::now();

    double result = 0;

    for(size_t i = 0; i < It; ++i){
        result += std::pow(double(i), int(Exp));
    }

    timer::time_point t1 = timer::now();
    auto us = std::chrono::duration_cast<microseconds>(t1 - t0);

    std::cout << "std::pow(x, " << Exp << "): " << us.count() << "us" << std::endl;

    return result;
}

int main(){
    double result = 0;

    result += bench_my_pow<1000, 1>();
    result += bench_std_pow<1000, 1>();

    result += bench_my_pow<1000, 5>();
    result += bench_std_pow<1000, 5>();

    result += bench_my_pow<1000, 10>();
    result += bench_std_pow<1000, 10>();

    result += bench_my_pow<1000, 20>();
    result += bench_std_pow<1000, 20>();

    result += bench_my_pow<1000, 30>();
    result += bench_std_pow<1000, 30>();

    result += bench_my_pow<1000, 40>();
    result += bench_std_pow<1000, 40>();

    result += bench_my_pow<1000, 50>();
    result += bench_std_pow<1000, 50>();

    result += bench_my_pow<1000, 60>();
    result += bench_std_pow<1000, 60>();

    result += bench_my_pow<1000, 70>();
    result += bench_std_pow<1000, 70>();

    result += bench_my_pow<1000, 80>();
    result += bench_std_pow<1000, 80>();

    result += bench_my_pow<1000, 90>();
    result += bench_std_pow<1000, 90>();

    result += bench_my_pow<1000, 100>();
    result += bench_std_pow<1000, 100>();

    result += bench_my_pow<1000, 110>();
    result += bench_std_pow<1000, 110>();

    result += bench_my_pow<1000, 120>();
    result += bench_std_pow<1000, 120>();

    result += bench_my_pow<1000, 130>();
    result += bench_std_pow<1000, 130>();

    result += bench_my_pow<1000, 140>();
    result += bench_std_pow<1000, 140>();

    result += bench_my_pow<1000, 150>();
    result += bench_std_pow<1000, 150>();

    result += bench_my_pow<1000, 160>();
    result += bench_std_pow<1000, 160>();

    result += bench_my_pow<1000, 170>();
    result += bench_std_pow<1000, 170>();

    result += bench_my_pow<1000, 180>();
    result += bench_std_pow<1000, 180>();

    result += bench_my_pow<1000, 190>();
    result += bench_std_pow<1000, 190>();

    result += bench_my_pow<1000, 200>();
    result += bench_std_pow<1000, 200>();

    result += bench_my_pow<1000, 300>();
    result += bench_std_pow<1000, 300>();

    result += bench_my_pow<1000, 400>();
    result += bench_std_pow<1000, 400>();

    result += bench_my_pow<1000, 500>();
    result += bench_std_pow<1000, 500>();

    result += bench_my_pow<1000, 600>();
    result += bench_std_pow<1000, 600>();

    result += bench_my_pow<1000, 700>();
    result += bench_std_pow<1000, 700>();

    result += bench_my_pow<1000, 800>();
    result += bench_std_pow<1000, 800>();

    result += bench_my_pow<1000, 900>();
    result += bench_std_pow<1000, 900>();

    result += bench_my_pow<1000, 1000>();
    result += bench_std_pow<1000, 1000>();

    return (int) result;
}
<commit_msg>New tests for pow<commit_after>//=======================================================================
// Copyright (c) 2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <iostream>
#include <chrono>
#include <cmath>

using timer = std::chrono::high_resolution_clock;
using microseconds =  std::chrono::microseconds;

double my_pow(double x, size_t n){
    double r = 1.0;

    while(n > 0){
        r *= x;
        --n;
    }

    return r;
}

double second_pow(double x, size_t n){
    double r = 1.0;
    double tmp = 1.0;
    int curr = 1;

    while(n){
        tmp = tmp * x;
        if (n & curr){
            r *= tmp;
            n = n & ~curr;
        }

        ++curr;
    }

    return r;
}

double third_pow(double x, size_t y) {
    double z = 1;
    double base = x;

    while (y) {
        if (y & 1) {
            z *= base;
        }
        y >>= 1;
        base *= base;
    }

    return z;
}

template<size_t It, size_t Exp>
double bench_my_pow(){
    timer::time_point t0 = timer::now();

    double result = 0;

    for(size_t i = 0; i < It; ++i){
        result += my_pow(double(i), int(Exp));
    }

    timer::time_point t1 = timer::now();
    auto us = std::chrono::duration_cast<microseconds>(t1 - t0);

    std::cout << "my_pow(x, " << Exp << "): " << us.count() << "us" << std::endl;

    return result;
}

template<size_t It, size_t Exp>
double bench_second_pow(){
    timer::time_point t0 = timer::now();

    double result = 0;

    for(size_t i = 0; i < It; ++i){
        result += second_pow(double(i), int(Exp));
    }

    timer::time_point t1 = timer::now();
    auto us = std::chrono::duration_cast<microseconds>(t1 - t0);

    std::cout << "second_pow(x, " << Exp << "): " << us.count() << "us" << std::endl;

    return result;
}

template<size_t It, size_t Exp>
double bench_third_pow(){
    timer::time_point t0 = timer::now();

    double result = 0;

    for(size_t i = 0; i < It; ++i){
        result += third_pow(double(i), int(Exp));
    }

    timer::time_point t1 = timer::now();
    auto us = std::chrono::duration_cast<microseconds>(t1 - t0);

    std::cout << "third_pow(x, " << Exp << "): " << us.count() << "us" << std::endl;

    return result;
}

template<size_t It, size_t Exp>
double bench_std_pow(){
    timer::time_point t0 = timer::now();

    double result = 0;

    for(size_t i = 0; i < It; ++i){
        result += std::pow(double(i), int(Exp));
    }

    timer::time_point t1 = timer::now();
    auto us = std::chrono::duration_cast<microseconds>(t1 - t0);

    std::cout << "std::pow(x, " << Exp << "): " << us.count() << "us" << std::endl;

    return result;
}

template<size_t It, size_t Exp>
double bench_pow(){
    double result = 0;

    result += bench_my_pow<It, Exp>();
    result += bench_second_pow<It, Exp>();
    result += bench_third_pow<It, Exp>();
    result += bench_std_pow<It, Exp>();

    return result;
}

int main(){
    double result = 0;

    result += bench_pow<5000, 1>();
    result += bench_pow<5000, 5>();
    result += bench_pow<5000, 10>();
    result += bench_pow<5000, 20>();
    result += bench_pow<5000, 30>();
    result += bench_pow<5000, 40>();
    result += bench_pow<5000, 50>();
    result += bench_pow<5000, 60>();
    result += bench_pow<5000, 70>();
    result += bench_pow<5000, 80>();
    result += bench_pow<5000, 90>();
    result += bench_pow<5000, 100>();
    result += bench_pow<5000, 110>();
    result += bench_pow<5000, 120>();
    result += bench_pow<5000, 130>();
    result += bench_pow<5000, 140>();
    result += bench_pow<5000, 150>();
    result += bench_pow<5000, 160>();
    result += bench_pow<5000, 170>();
    result += bench_pow<5000, 180>();
    result += bench_pow<5000, 190>();
    result += bench_pow<5000, 200>();
    result += bench_pow<5000, 300>();
    result += bench_pow<5000, 400>();
    result += bench_pow<5000, 500>();
    result += bench_pow<5000, 600>();
    result += bench_pow<5000, 700>();
    result += bench_pow<5000, 800>();
    result += bench_pow<5000, 900>();
    result += bench_pow<5000, 1000>();

    return (int) result;
}
<|endoftext|>


<commit_before>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2011-12-18 GONG Chen <chen.sst@gmail.com>
//
#include <rime/common.h>
#include <rime/composition.h>
#include <rime/config.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/key_event.h>
#include <rime/schema.h>
#include <rime/gear/ascii_composer.h>

namespace rime {

static struct AsciiModeSwitchStyleDefinition {
  const char* repr;
  AsciiModeSwitchStyle style;
} ascii_mode_switch_styles[] = {
  { "inline_ascii", kAsciiModeSwitchInline },
  { "commit_text", kAsciiModeSwitchCommitText },
  { "commit_code", kAsciiModeSwitchCommitCode },
  { "clear", kAsciiModeSwitchClear },
  { NULL, kAsciiModeSwitchNoop }
};

static void load_bindings(const an<ConfigMap>& src,
                          AsciiModeSwitchKeyBindings* dest) {
  if (!src)
    return;
  for (auto it = src->begin(); it != src->end(); ++it) {
    auto value = As<ConfigValue>(it->second);
    if (!value)
      continue;
    auto* p = ascii_mode_switch_styles;
    while (p->repr && p->repr != value->str())
      ++p;
    if (p->style == kAsciiModeSwitchNoop)
      continue;
    KeyEvent ke;
    if (!ke.Parse(it->first) || ke.modifier() != 0) {
      LOG(WARNING) << "invalid ascii mode switch key: " << it->first;
      continue;
    }
    // save binding
    (*dest)[ke.keycode()] = p->style;
  }
}

AsciiComposer::AsciiComposer(const Ticket& ticket)
    : Processor(ticket) {
  LoadConfig(ticket.schema);
}

AsciiComposer::~AsciiComposer() {
  connection_.disconnect();
}

ProcessResult AsciiComposer::ProcessKeyEvent(const KeyEvent& key_event) {
  if ((key_event.shift() && key_event.ctrl()) ||
      key_event.alt() || key_event.super()) {
    shift_key_pressed_ = ctrl_key_pressed_ = false;
    return kNoop;
  }
  if (caps_lock_switch_style_ != kAsciiModeSwitchNoop) {
    ProcessResult result = ProcessCapsLock(key_event);
    if (result != kNoop)
      return result;
  }
  int ch = key_event.keycode();
  if (ch == XK_Eisu_toggle) {  // Alphanumeric toggle
    if (!key_event.release()) {
      shift_key_pressed_ = ctrl_key_pressed_ = false;
      ToggleAsciiModeWithKey(ch);
      return kAccepted;
    }
    else {
      return kRejected;
    }
  }
  bool is_shift = (ch == XK_Shift_L || ch == XK_Shift_R);
  bool is_ctrl = (ch == XK_Control_L || ch == XK_Control_R);
  if (is_shift || is_ctrl) {
    if (key_event.release()) {
      if (shift_key_pressed_ || ctrl_key_pressed_) {
        auto now = std::chrono::steady_clock::now();
        if (now < toggle_expired_) {
          ToggleAsciiModeWithKey(ch);
        }
        shift_key_pressed_ = ctrl_key_pressed_ = false;
        return kRejected;
      }
    }
    else if (!(shift_key_pressed_ || ctrl_key_pressed_)) {  // first key down
      if (is_shift)
        shift_key_pressed_ = true;
      else
        ctrl_key_pressed_ = true;
      // will not toggle unless the toggle key is released shortly
      const auto toggle_duration_limit = std::chrono::milliseconds(500);
      auto now = std::chrono::steady_clock::now();
      toggle_expired_= now + toggle_duration_limit;
    }
    return kNoop;
  }
  // other keys
  shift_key_pressed_ = ctrl_key_pressed_ = false;
  // possible key binding: Control+x, Shift+space
  if (key_event.ctrl() || (key_event.shift() && ch == XK_space)) {
    return kNoop;
  }
  Context* ctx = engine_->context();
  bool ascii_mode = ctx->get_option("ascii_mode");
  if (ascii_mode) {
    if (!ctx->IsComposing()) {
      return kRejected;  // direct commit
    }
    // edit inline ascii string
    if (!key_event.release() && ch >= 0x20 && ch < 0x80) {
      ctx->PushInput(ch);
      return kAccepted;
    }
  }
  return kNoop;
}

ProcessResult AsciiComposer::ProcessCapsLock(const KeyEvent& key_event) {
  int ch = key_event.keycode();
  if (ch == XK_Caps_Lock) {
    if (!key_event.release()) {
      shift_key_pressed_ = ctrl_key_pressed_ = false;
      // temprarily disable good-old (uppercase) Caps Lock as mode switch key
      // in case the user switched to ascii mode with other keys, eg. with Shift
      if (good_old_caps_lock_ && !toggle_with_caps_) {
        Context* ctx = engine_->context();
        bool ascii_mode = ctx->get_option("ascii_mode");
        if (ascii_mode) {
          return kRejected;
        }
      }
      toggle_with_caps_ = !key_event.caps();
      // NOTE: for Linux, Caps Lock modifier is clear when we are about to
      // turn it on; for Windows it is the opposite:
      // Caps Lock modifier has been set before we process VK_CAPITAL.
      // here we assume IBus' behavior and invert caps with ! operation.
      SwitchAsciiMode(!key_event.caps(), caps_lock_switch_style_);
      return kAccepted;
    }
    else {
      return kRejected;
    }
  }
  if (key_event.caps()) {
    if (!good_old_caps_lock_ &&
        !key_event.release() && !key_event.ctrl() &&
        isascii(ch) && isalpha(ch)) {
      // output ascii characters ignoring Caps Lock
      if (islower(ch))
        ch = toupper(ch);
      else if (isupper(ch))
        ch = tolower(ch);
      engine_->CommitText(string(1, ch));
      return kAccepted;
    }
    else {
      return kRejected;
    }
  }
  return kNoop;
}

void AsciiComposer::LoadConfig(Schema* schema) {
  bindings_.clear();
  caps_lock_switch_style_ = kAsciiModeSwitchNoop;
  good_old_caps_lock_ = false;
  if (!schema)
    return;
  Config* config = schema->config();
  the<Config> preset_config(Config::Require("config")->Create("default"));
  if (!config->GetBool("ascii_composer/good_old_caps_lock",
                       &good_old_caps_lock_)) {
    if (preset_config) {
      preset_config->GetBool("ascii_composer/good_old_caps_lock",
                             &good_old_caps_lock_);
    }
  }
  if (auto bindings = config->GetMap("ascii_composer/switch_key")) {
    load_bindings(bindings, &bindings_);
  }
  else if (auto bindings = preset_config
           ? preset_config->GetMap("ascii_composer/switch_key")
           : nullptr) {
    load_bindings(bindings, &bindings_);
  } else {
    LOG(ERROR) << "Missing ascii bindings.";
    return;
  }
  auto it = bindings_.find(XK_Caps_Lock);
  if (it != bindings_.end()) {
    caps_lock_switch_style_ = it->second;
    if (caps_lock_switch_style_ == kAsciiModeSwitchInline) {  // can't do that
      caps_lock_switch_style_ = kAsciiModeSwitchClear;
    }
  }
}

bool AsciiComposer::ToggleAsciiModeWithKey(int key_code) {
  auto it = bindings_.find(key_code);
  if (it == bindings_.end())
    return false;
  AsciiModeSwitchStyle style = it->second;
  Context* ctx = engine_->context();
  bool ascii_mode = !ctx->get_option("ascii_mode");
  SwitchAsciiMode(ascii_mode, style);
  toggle_with_caps_ = (key_code == XK_Caps_Lock);
  return true;
}

void AsciiComposer::SwitchAsciiMode(bool ascii_mode,
                                    AsciiModeSwitchStyle style) {
  DLOG(INFO) << "ascii mode: " << ascii_mode << ", switch style: " << style;
  Context* ctx = engine_->context();
  if (ctx->IsComposing()) {
    connection_.disconnect();
    // temporary ascii mode in desired manner
    if (style == kAsciiModeSwitchInline) {
      LOG(INFO) << "converting current composition to "
                << (ascii_mode ? "ascii" : "non-ascii") << " mode.";
      if (ascii_mode) {
        connection_ = ctx->update_notifier().connect(
            [this](Context* ctx) { OnContextUpdate(ctx); });
      }
    }
    else if (style == kAsciiModeSwitchCommitText) {
      ctx->ConfirmCurrentSelection();
    }
    else if (style == kAsciiModeSwitchCommitCode) {
      ctx->ClearNonConfirmedComposition();
      ctx->Commit();
    }
    else if (style == kAsciiModeSwitchClear) {
      ctx->Clear();
    }
  }
  // refresh non-confirmed composition with new mode
  ctx->set_option("ascii_mode", ascii_mode);
}

void AsciiComposer::OnContextUpdate(Context* ctx) {
  if (!ctx->IsComposing()) {
    connection_.disconnect();
    // quit temporary ascii mode
    ctx->set_option("ascii_mode", false);
  }
}

}  // namespace rime
<commit_msg>fix(ascii_composer): do not comsume Shift key release<commit_after>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2011-12-18 GONG Chen <chen.sst@gmail.com>
//
#include <rime/common.h>
#include <rime/composition.h>
#include <rime/config.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/key_event.h>
#include <rime/schema.h>
#include <rime/gear/ascii_composer.h>

namespace rime {

static struct AsciiModeSwitchStyleDefinition {
  const char* repr;
  AsciiModeSwitchStyle style;
} ascii_mode_switch_styles[] = {
  { "inline_ascii", kAsciiModeSwitchInline },
  { "commit_text", kAsciiModeSwitchCommitText },
  { "commit_code", kAsciiModeSwitchCommitCode },
  { "clear", kAsciiModeSwitchClear },
  { NULL, kAsciiModeSwitchNoop }
};

static void load_bindings(const an<ConfigMap>& src,
                          AsciiModeSwitchKeyBindings* dest) {
  if (!src)
    return;
  for (auto it = src->begin(); it != src->end(); ++it) {
    auto value = As<ConfigValue>(it->second);
    if (!value)
      continue;
    auto* p = ascii_mode_switch_styles;
    while (p->repr && p->repr != value->str())
      ++p;
    if (p->style == kAsciiModeSwitchNoop)
      continue;
    KeyEvent ke;
    if (!ke.Parse(it->first) || ke.modifier() != 0) {
      LOG(WARNING) << "invalid ascii mode switch key: " << it->first;
      continue;
    }
    // save binding
    (*dest)[ke.keycode()] = p->style;
  }
}

AsciiComposer::AsciiComposer(const Ticket& ticket)
    : Processor(ticket) {
  LoadConfig(ticket.schema);
}

AsciiComposer::~AsciiComposer() {
  connection_.disconnect();
}

ProcessResult AsciiComposer::ProcessKeyEvent(const KeyEvent& key_event) {
  if ((key_event.shift() && key_event.ctrl()) ||
      key_event.alt() || key_event.super()) {
    shift_key_pressed_ = ctrl_key_pressed_ = false;
    return kNoop;
  }
  if (caps_lock_switch_style_ != kAsciiModeSwitchNoop) {
    ProcessResult result = ProcessCapsLock(key_event);
    if (result != kNoop)
      return result;
  }
  int ch = key_event.keycode();
  if (ch == XK_Eisu_toggle) {  // Alphanumeric toggle
    if (!key_event.release()) {
      shift_key_pressed_ = ctrl_key_pressed_ = false;
      ToggleAsciiModeWithKey(ch);
      return kAccepted;
    }
    else {
      return kRejected;
    }
  }
  bool is_shift = (ch == XK_Shift_L || ch == XK_Shift_R);
  bool is_ctrl = (ch == XK_Control_L || ch == XK_Control_R);
  if (is_shift || is_ctrl) {
    if (key_event.release()) {
      if (shift_key_pressed_ || ctrl_key_pressed_) {
        auto now = std::chrono::steady_clock::now();
        if (now < toggle_expired_) {
          ToggleAsciiModeWithKey(ch);
        }
        shift_key_pressed_ = ctrl_key_pressed_ = false;
        return kNoop;
      }
    }
    else if (!(shift_key_pressed_ || ctrl_key_pressed_)) {  // first key down
      if (is_shift)
        shift_key_pressed_ = true;
      else
        ctrl_key_pressed_ = true;
      // will not toggle unless the toggle key is released shortly
      const auto toggle_duration_limit = std::chrono::milliseconds(500);
      auto now = std::chrono::steady_clock::now();
      toggle_expired_= now + toggle_duration_limit;
    }
    return kNoop;
  }
  // other keys
  shift_key_pressed_ = ctrl_key_pressed_ = false;
  // possible key binding: Control+x, Shift+space
  if (key_event.ctrl() || (key_event.shift() && ch == XK_space)) {
    return kNoop;
  }
  Context* ctx = engine_->context();
  bool ascii_mode = ctx->get_option("ascii_mode");
  if (ascii_mode) {
    if (!ctx->IsComposing()) {
      return kRejected;  // direct commit
    }
    // edit inline ascii string
    if (!key_event.release() && ch >= 0x20 && ch < 0x80) {
      ctx->PushInput(ch);
      return kAccepted;
    }
  }
  return kNoop;
}

ProcessResult AsciiComposer::ProcessCapsLock(const KeyEvent& key_event) {
  int ch = key_event.keycode();
  if (ch == XK_Caps_Lock) {
    if (!key_event.release()) {
      shift_key_pressed_ = ctrl_key_pressed_ = false;
      // temprarily disable good-old (uppercase) Caps Lock as mode switch key
      // in case the user switched to ascii mode with other keys, eg. with Shift
      if (good_old_caps_lock_ && !toggle_with_caps_) {
        Context* ctx = engine_->context();
        bool ascii_mode = ctx->get_option("ascii_mode");
        if (ascii_mode) {
          return kRejected;
        }
      }
      toggle_with_caps_ = !key_event.caps();
      // NOTE: for Linux, Caps Lock modifier is clear when we are about to
      // turn it on; for Windows it is the opposite:
      // Caps Lock modifier has been set before we process VK_CAPITAL.
      // here we assume IBus' behavior and invert caps with ! operation.
      SwitchAsciiMode(!key_event.caps(), caps_lock_switch_style_);
      return kAccepted;
    }
    else {
      return kRejected;
    }
  }
  if (key_event.caps()) {
    if (!good_old_caps_lock_ &&
        !key_event.release() && !key_event.ctrl() &&
        isascii(ch) && isalpha(ch)) {
      // output ascii characters ignoring Caps Lock
      if (islower(ch))
        ch = toupper(ch);
      else if (isupper(ch))
        ch = tolower(ch);
      engine_->CommitText(string(1, ch));
      return kAccepted;
    }
    else {
      return kRejected;
    }
  }
  return kNoop;
}

void AsciiComposer::LoadConfig(Schema* schema) {
  bindings_.clear();
  caps_lock_switch_style_ = kAsciiModeSwitchNoop;
  good_old_caps_lock_ = false;
  if (!schema)
    return;
  Config* config = schema->config();
  the<Config> preset_config(Config::Require("config")->Create("default"));
  if (!config->GetBool("ascii_composer/good_old_caps_lock",
                       &good_old_caps_lock_)) {
    if (preset_config) {
      preset_config->GetBool("ascii_composer/good_old_caps_lock",
                             &good_old_caps_lock_);
    }
  }
  if (auto bindings = config->GetMap("ascii_composer/switch_key")) {
    load_bindings(bindings, &bindings_);
  }
  else if (auto bindings = preset_config
           ? preset_config->GetMap("ascii_composer/switch_key")
           : nullptr) {
    load_bindings(bindings, &bindings_);
  } else {
    LOG(ERROR) << "Missing ascii bindings.";
    return;
  }
  auto it = bindings_.find(XK_Caps_Lock);
  if (it != bindings_.end()) {
    caps_lock_switch_style_ = it->second;
    if (caps_lock_switch_style_ == kAsciiModeSwitchInline) {  // can't do that
      caps_lock_switch_style_ = kAsciiModeSwitchClear;
    }
  }
}

bool AsciiComposer::ToggleAsciiModeWithKey(int key_code) {
  auto it = bindings_.find(key_code);
  if (it == bindings_.end())
    return false;
  AsciiModeSwitchStyle style = it->second;
  Context* ctx = engine_->context();
  bool ascii_mode = !ctx->get_option("ascii_mode");
  SwitchAsciiMode(ascii_mode, style);
  toggle_with_caps_ = (key_code == XK_Caps_Lock);
  return true;
}

void AsciiComposer::SwitchAsciiMode(bool ascii_mode,
                                    AsciiModeSwitchStyle style) {
  DLOG(INFO) << "ascii mode: " << ascii_mode << ", switch style: " << style;
  Context* ctx = engine_->context();
  if (ctx->IsComposing()) {
    connection_.disconnect();
    // temporary ascii mode in desired manner
    if (style == kAsciiModeSwitchInline) {
      LOG(INFO) << "converting current composition to "
                << (ascii_mode ? "ascii" : "non-ascii") << " mode.";
      if (ascii_mode) {
        connection_ = ctx->update_notifier().connect(
            [this](Context* ctx) { OnContextUpdate(ctx); });
      }
    }
    else if (style == kAsciiModeSwitchCommitText) {
      ctx->ConfirmCurrentSelection();
    }
    else if (style == kAsciiModeSwitchCommitCode) {
      ctx->ClearNonConfirmedComposition();
      ctx->Commit();
    }
    else if (style == kAsciiModeSwitchClear) {
      ctx->Clear();
    }
  }
  // refresh non-confirmed composition with new mode
  ctx->set_option("ascii_mode", ascii_mode);
}

void AsciiComposer::OnContextUpdate(Context* ctx) {
  if (!ctx->IsComposing()) {
    connection_.disconnect();
    // quit temporary ascii mode
    ctx->set_option("ascii_mode", false);
  }
}

}  // namespace rime
<|endoftext|>


<commit_before>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2014-03-31 Chongyu Zhu <i@lembacon.com>
//
#include <stdint.h> // for uint32_t
#include <utf8.h>
#include <rime/candidate.h>
#include <rime/common.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/dict/vocabulary.h>
#include <rime/gear/charset_filter.h>
#include <boost/locale/encoding.hpp>

namespace rime {

bool is_extended_cjk(uint32_t ch)
{
  if ((ch >= 0x3400 && ch <= 0x4DBF) ||    // CJK Unified Ideographs Extension A
      (ch >= 0x20000 && ch <= 0x2A6DF) ||  // CJK Unified Ideographs Extension B
      (ch >= 0x2A700 && ch <= 0x2B73F) ||  // CJK Unified Ideographs Extension C
      (ch >= 0x2B740 && ch <= 0x2B81F) ||  // CJK Unified Ideographs Extension D
      (ch >= 0x2B820 && ch <= 0x2CEAF) ||  // CJK Unified Ideographs Extension E
      (ch >= 0x2F800 && ch <= 0x2FA1F))    // CJK Compatibility Ideographs Supplement
    return true;

  return false;
}

bool contains_extended_cjk(const string& text)
{
  const char *p = text.c_str();
  uint32_t ch;

  while ((ch = utf8::unchecked::next(p)) != 0) {
    if (is_extended_cjk(ch)) {
      return true;
    }
  }

  return false;
}

// CharsetFilterTranslation

CharsetFilterTranslation::CharsetFilterTranslation(
    an<Translation> translation, const string& charset)
    : translation_(translation), charset_(charset) {
  LocateNextCandidate();
}

bool CharsetFilterTranslation::Next() {
  if (exhausted())
    return false;
  if (!translation_->Next()) {
    set_exhausted(true);
    return false;
  }
  return LocateNextCandidate();
}

an<Candidate> CharsetFilterTranslation::Peek() {
  return translation_->Peek();
}

bool CharsetFilterTranslation::LocateNextCandidate() {
  while (!translation_->exhausted()) {
    auto cand = translation_->Peek();
    if (cand && CharsetFilter::FilterText(cand->text(), charset_))
      return true;
    translation_->Next();
  }
  set_exhausted(true);
  return false;
}

// CharsetFilter

bool CharsetFilter::FilterText(const string& text, const string& charset) {
  if (charset.empty()) return !contains_extended_cjk(text);
  try {
    boost::locale::conv::from_utf(text, charset, boost::locale::conv::method_type::stop);
  }
  catch(boost::locale::conv::conversion_error const& /*ex*/) {
    return false;
  }
  catch(...) {
  }
  return true;
}

bool CharsetFilter::FilterDictEntry(an<DictEntry> entry) {
  return entry && FilterText(entry->text);
}

CharsetFilter::CharsetFilter(const Ticket& ticket)
    : Filter(ticket), TagMatching(ticket) {
}

an<Translation> CharsetFilter::Apply(
    an<Translation> translation, CandidateList* candidates) {
  if (name_space_.empty() && !engine_->context()->get_option("extended_charset")) {
    return New<CharsetFilterTranslation>(translation);
  }
  if (!name_space_.empty() && engine_->context()->get_option(name_space_)) {
    return New<CharsetFilterTranslation>(translation, name_space_);
  }
  return translation;
}

}  // namespace rime
<commit_msg>add cjk_ext f filtration. (#128)<commit_after>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2014-03-31 Chongyu Zhu <i@lembacon.com>
//
#include <stdint.h> // for uint32_t
#include <utf8.h>
#include <rime/candidate.h>
#include <rime/common.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/dict/vocabulary.h>
#include <rime/gear/charset_filter.h>
#include <boost/locale/encoding.hpp>

namespace rime {

bool is_extended_cjk(uint32_t ch)
{
  if ((ch >= 0x3400 && ch <= 0x4DBF) ||    // CJK Unified Ideographs Extension A
      (ch >= 0x20000 && ch <= 0x2A6DF) ||  // CJK Unified Ideographs Extension B
      (ch >= 0x2A700 && ch <= 0x2B73F) ||  // CJK Unified Ideographs Extension C
      (ch >= 0x2B740 && ch <= 0x2B81F) ||  // CJK Unified Ideographs Extension D
      (ch >= 0x2B820 && ch <= 0x2CEAF) ||  // CJK Unified Ideographs Extension E
      (ch >= 0x2CEB0 && ch <= 0x2EBEF) ||  // CJK Unified Ideographs Extension F
      (ch >= 0x2F800 && ch <= 0x2FA1F))    // CJK Compatibility Ideographs Supplement
    return true;

  return false;
}

bool contains_extended_cjk(const string& text)
{
  const char *p = text.c_str();
  uint32_t ch;

  while ((ch = utf8::unchecked::next(p)) != 0) {
    if (is_extended_cjk(ch)) {
      return true;
    }
  }

  return false;
}

// CharsetFilterTranslation

CharsetFilterTranslation::CharsetFilterTranslation(
    an<Translation> translation, const string& charset)
    : translation_(translation), charset_(charset) {
  LocateNextCandidate();
}

bool CharsetFilterTranslation::Next() {
  if (exhausted())
    return false;
  if (!translation_->Next()) {
    set_exhausted(true);
    return false;
  }
  return LocateNextCandidate();
}

an<Candidate> CharsetFilterTranslation::Peek() {
  return translation_->Peek();
}

bool CharsetFilterTranslation::LocateNextCandidate() {
  while (!translation_->exhausted()) {
    auto cand = translation_->Peek();
    if (cand && CharsetFilter::FilterText(cand->text(), charset_))
      return true;
    translation_->Next();
  }
  set_exhausted(true);
  return false;
}

// CharsetFilter

bool CharsetFilter::FilterText(const string& text, const string& charset) {
  if (charset.empty()) return !contains_extended_cjk(text);
  try {
    boost::locale::conv::from_utf(text, charset, boost::locale::conv::method_type::stop);
  }
  catch(boost::locale::conv::conversion_error const& /*ex*/) {
    return false;
  }
  catch(...) {
  }
  return true;
}

bool CharsetFilter::FilterDictEntry(an<DictEntry> entry) {
  return entry && FilterText(entry->text);
}

CharsetFilter::CharsetFilter(const Ticket& ticket)
    : Filter(ticket), TagMatching(ticket) {
}

an<Translation> CharsetFilter::Apply(
    an<Translation> translation, CandidateList* candidates) {
  if (name_space_.empty() && !engine_->context()->get_option("extended_charset")) {
    return New<CharsetFilterTranslation>(translation);
  }
  if (!name_space_.empty() && engine_->context()->get_option(name_space_)) {
    return New<CharsetFilterTranslation>(translation, name_space_);
  }
  return translation;
}

}  // namespace rime
<|endoftext|>


<commit_before>//
//  __ParseBridge-Android.cpp
//  roll-eat
//
//  Created by Zinge on 5/16/16.
//
//

#include "ee/core/JniUtils.hpp"
#include "ee/core/Logger.hpp"
#include "ee/core/MessageBridge.hpp"
#include "ee/core/internal/JniMethodInfo.hpp"
#include "ee/core/internal/JniString.hpp"

namespace ee {
namespace core {
namespace {
extern "C" {
JNIEXPORT jstring JNICALL Java_com_ee_core_internal_MessageBridge_callCpp(
    JNIEnv* env, jobject instance, jstring tag_, jstring msg_) {
    const char* tag = env->GetStringUTFChars(tag_, nullptr);
    const char* msg = env->GetStringUTFChars(msg_, nullptr);

    auto result = MessageBridge::getInstance().callCpp(tag, msg);

    env->ReleaseStringUTFChars(tag_, tag);
    env->ReleaseStringUTFChars(msg_, msg);

    return env->NewStringUTF(result.c_str());
}
} // extern "C"
} // namespace

std::string MessageBridge::call(const std::string& tag,
                                const std::string& msg) {
    auto methodInfo = JniUtils::getStaticMethodInfo(
        "com/ee/core/MessageBridge", "staticCall",
        "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");

    if (methodInfo == nullptr) {
        throw std::runtime_error("Method not found!");
    }

    auto tag_java = JniUtils::toJavaString(tag);
    auto msg_java = JniUtils::toJavaString(msg);

    jobject response = methodInfo->getEnv()->CallStaticObjectMethod(
        methodInfo->getClass(), methodInfo->getMethodId(), tag_java->get(),
        msg_java->get());

    jstring response_java = static_cast<jstring>(response);
    auto result = JniUtils::toString(response_java);

    methodInfo->getEnv()->DeleteLocalRef(response);

    return result;
}
} // namespace core
} // namespace ee
<commit_msg>Fix unsatistified link error.<commit_after>//
//  __ParseBridge-Android.cpp
//  roll-eat
//
//  Created by Zinge on 5/16/16.
//
//

#include "ee/core/JniUtils.hpp"
#include "ee/core/Logger.hpp"
#include "ee/core/MessageBridge.hpp"
#include "ee/core/internal/JniMethodInfo.hpp"
#include "ee/core/internal/JniString.hpp"

namespace ee {
namespace core {
namespace {
extern "C" {
JNIEXPORT jstring JNICALL Java_com_ee_core_MessageBridge_callCpp(
    JNIEnv* env, jobject instance, jstring tag_, jstring msg_) {
    const char* tag = env->GetStringUTFChars(tag_, nullptr);
    const char* msg = env->GetStringUTFChars(msg_, nullptr);

    auto result = MessageBridge::getInstance().callCpp(tag, msg);

    env->ReleaseStringUTFChars(tag_, tag);
    env->ReleaseStringUTFChars(msg_, msg);

    return env->NewStringUTF(result.c_str());
}
} // extern "C"
} // namespace

std::string MessageBridge::call(const std::string& tag,
                                const std::string& msg) {
    auto methodInfo = JniUtils::getStaticMethodInfo(
        "com/ee/core/MessageBridge", "staticCall",
        "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");

    if (methodInfo == nullptr) {
        throw std::runtime_error("Method not found!");
    }

    auto tag_java = JniUtils::toJavaString(tag);
    auto msg_java = JniUtils::toJavaString(msg);

    jobject response = methodInfo->getEnv()->CallStaticObjectMethod(
        methodInfo->getClass(), methodInfo->getMethodId(), tag_java->get(),
        msg_java->get());

    jstring response_java = static_cast<jstring>(response);
    auto result = JniUtils::toString(response_java);

    methodInfo->getEnv()->DeleteLocalRef(response);

    return result;
}
} // namespace core
} // namespace ee
<|endoftext|>