<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XalanNumberFormat.hpp"
#include "DOMStringHelper.hpp"

XalanNumberFormat::XalanNumberFormat() :
	m_isGroupingUsed(false),
	m_groupingSeparator(XALAN_STATIC_UCODE_STRING(",")),
	m_groupingSize(3)	// Default to US values
{
}

XalanNumberFormat::~XalanNumberFormat()
{
}

XalanDOMString
XalanNumberFormat::format(double		theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(DoubleToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::format(int	theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(LongToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::format(unsigned int	theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(UnsignedLongToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::format(long	theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(LongToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::applyGrouping(const XalanDOMString& value)
/*
 * Convert a string value using the currently active values for grouping size
 * and separator; returns the converted string
 */
{
	if (!m_isGroupingUsed) return value;
	if (m_groupingSize == 0) return value;
	const unsigned int len = length(value);
	if (len == 0) return value;

	const unsigned int	bufsize = len + len/m_groupingSize + 1;

	XalanDOMChar* const		buffer = new XalanDOMChar[bufsize];

	XalanDOMChar*			p = buffer + bufsize - 1;

	*p-- = 0;	// null terminate

	for (unsigned int i = 0, ix = len - 1; i < len; i++, ix--)
	{
		const XalanDOMChar		c = charAt(value, ix);

		if (i && !(i% m_groupingSize))
		{
			// Could be a multiple character separator??
			for (int j= m_groupingSeparator.length()-1; j>=0; j--)
				*p-- = charAt(m_groupingSeparator, j);
		}

		*p-- = c;
	}

	XalanDOMString s(++p);

	delete [] buffer;

	return s;
}

XalanDOMString
XalanNumberFormat::format(unsigned long	theValue)
{
	// $$$ ToDo: Fix this!
	return UnsignedLongToDOMString(theValue);
}

bool
XalanNumberFormat::isGroupingUsed() const
{
	return m_isGroupingUsed;
}

void
XalanNumberFormat::setGroupingUsed(bool bUsed)
{
	m_isGroupingUsed = bUsed;
}

void
XalanNumberFormat::setGroupingSize(unsigned long	size)
{
	assert(size > 0);

	m_groupingSize = size;
}

void
XalanNumberFormat::setGroupingSeparator(const XalanDOMString&	s)
{
	m_groupingSeparator = s;
}
<commit_msg>Added array_auto_ptr to protect dynamic allocation.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XalanNumberFormat.hpp"

#include "DOMStringHelper.hpp"
#include "STLHelper.hpp"

XalanNumberFormat::XalanNumberFormat() :
	m_isGroupingUsed(false),
	m_groupingSeparator(XALAN_STATIC_UCODE_STRING(",")),
	m_groupingSize(3)	// Default to US values
{
}

XalanNumberFormat::~XalanNumberFormat()
{
}

XalanDOMString
XalanNumberFormat::format(double		theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(DoubleToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::format(int	theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(LongToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::format(unsigned int	theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(UnsignedLongToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::format(long	theValue)
{
	// $$$ ToDo: Fix this!
	return applyGrouping(LongToDOMString(theValue));
}

XalanDOMString
XalanNumberFormat::applyGrouping(const XalanDOMString& value)
/*
 * Convert a string value using the currently active values for grouping size
 * and separator; returns the converted string
 */
{
	if (!m_isGroupingUsed) return value;
	if (m_groupingSize == 0) return value;
	const unsigned int len = length(value);
	if (len == 0) return value;

	const unsigned int	bufsize = len + len/m_groupingSize + 1;

	XalanDOMChar* const		buffer = new XalanDOMChar[bufsize];

	array_auto_ptr<XalanDOMChar>	theGuard(buffer);

	XalanDOMChar*			p = buffer + bufsize - 1;

	*p-- = 0;	// null terminate

	for (unsigned int i = 0, ix = len - 1; i < len; i++, ix--)
	{
		const XalanDOMChar		c = charAt(value, ix);

		if (i && !(i% m_groupingSize))
		{
			// Could be a multiple character separator??
			for (int j= m_groupingSeparator.length()-1; j>=0; j--)
				*p-- = charAt(m_groupingSeparator, j);
		}

		*p-- = c;
	}

	return XalanDOMString(++p);
}

XalanDOMString
XalanNumberFormat::format(unsigned long	theValue)
{
	// $$$ ToDo: Fix this!
	return UnsignedLongToDOMString(theValue);
}

bool
XalanNumberFormat::isGroupingUsed() const
{
	return m_isGroupingUsed;
}

void
XalanNumberFormat::setGroupingUsed(bool bUsed)
{
	m_isGroupingUsed = bUsed;
}

void
XalanNumberFormat::setGroupingSize(unsigned long	size)
{
	assert(size > 0);

	m_groupingSize = size;
}

void
XalanNumberFormat::setGroupingSeparator(const XalanDOMString&	s)
{
	m_groupingSeparator = s;
}
<|endoftext|>


<commit_before>#include <sys/epoll.h>
#include <unistd.h>

#include "exemodel/timeree.hpp"
#include "exemodel/poll_tools.hpp"

namespace exemodel{
timeree::timeree(struct timercycle interval, bool oneshot)
:pollee(::timerfd_create(CLOCK_MONOTONIC,TFD_CLOEXEC),uint32_t(::EPOLLIN | ::EPOLLERR))
{
	m_value.tv_sec = interval.sec;
	m_value.tv_nsec = interval.nsec;
	setmodel(oneshot);
}

timeree::~timeree()
{
}

void timeree::start(void)
{
	//start timer
	struct itimerspec tmpTime = {
		m_interval,
		m_value,
	};
	int ret = timerfd_settime(_fd_(), 0, &tmpTime, NULL);
	validate_ret(ret,"start timer error!\n");
}

void timeree::stop(void)
{
	//stop timer
	struct itimerspec tmpTime = {
		 m_interval,
		 {0,0},
	};
	int ret = timerfd_settime(_fd_(), 0, &tmpTime, NULL);
	validate_ret(ret,"stop timer error!\n");
}

void timeree::setcycle(struct timercycle cycle)
{
	//reset cycle
	if((cycle.nsec!=0)||(cycle.sec!=0))
	{
		m_value.tv_sec=cycle.sec;
		m_value.tv_nsec=cycle.nsec;
	}else
	{
		std::cout << "WARNING:: cycle cann't set zero!" << std::endl;
	}

}

void timeree::setmodel(bool oneshot)
{
	//set model
	if(oneshot)             //ONCE
	{
		m_interval.tv_nsec=0;
		m_interval.tv_sec=0;
	}
	else               //LOOP
	{
		m_interval.tv_nsec=1;
	}
}

void timeree::dispose(poller & mgr, uint32_t evts)
{
	if(evts & EPOLLERR){
	      printf("timer error occurd fd %d\n",_fd_());
	      return;
	}
	//read the timeout information
	uint64_t buf = 0;
	ssize_t ret = ::read(_fd_(), &buf, sizeof(buf));
	if(ret != sizeof(buf)){
		printf("read error!\n");
		return;
		}

	if(evts & EPOLLIN){
		timeree::args_t args = { mgr, *this, evts };
		this->exe(args);

	}
}

}
<commit_msg>only care EPOLLIN for timer<commit_after>#include <sys/epoll.h>
#include <unistd.h>

#include "exemodel/timeree.hpp"
#include "exemodel/poll_tools.hpp"

namespace exemodel{
timeree::timeree(struct timercycle interval, bool oneshot)
:pollee(::timerfd_create(CLOCK_MONOTONIC,TFD_CLOEXEC),uint32_t(::EPOLLIN))
{
	m_value.tv_sec = interval.sec;
	m_value.tv_nsec = interval.nsec;
	setmodel(oneshot);
}

timeree::~timeree()
{
}

void timeree::start(void)
{
	//start timer
	struct itimerspec tmpTime = {
		m_interval,
		m_value,
	};
	int ret = ::timerfd_settime(_fd_(), 0, &tmpTime, NULL);
	validate_ret(ret,"start timer error!\n");
}

void timeree::stop(void)
{
	//stop timer
	struct itimerspec tmpTime = {
		 m_interval,
		 {0,0},
	};
	int ret = ::timerfd_settime(_fd_(), 0, &tmpTime, NULL);
	validate_ret(ret,"stop timer error!\n");
}

void timeree::setcycle(struct timercycle cycle)
{
	//reset cycle
	if((cycle.nsec!=0)||(cycle.sec!=0))
	{
		m_value.tv_sec=cycle.sec;
		m_value.tv_nsec=cycle.nsec;
	}else
	{
		std::cout << "WARNING:: cycle cann't set zero!" << std::endl;
	}

}

void timeree::setmodel(bool oneshot)
{
	//set model
	if(oneshot)             //ONCE
	{
		m_interval.tv_nsec=0;
		m_interval.tv_sec=0;
	}
	else               //LOOP
	{
		m_interval.tv_nsec=1;
	}
}

void timeree::dispose(poller & mgr, uint32_t evts)
{
	uint64_t buf = 0;
	ssize_t ret = ::read(_fd_(), &buf, sizeof(buf));
	if(ret != sizeof(buf)){
		std::cout << "read error!" << std::endl;
		return;
	}

	timeree::args_t args = { mgr, *this, evts };
	this->exe(args);
}

}
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <unordered_map>

#include "optional.hpp"

#include "json.hpp"

#include "RawLicenseKey.hpp"
#include "LicenseKey.hpp"
#include "LicenseKeyChecker.hpp"

namespace serialkeymanager_com {

using json = nlohmann::json;
using json_exception = nlohmann::detail::exception;

// Helper class to work with the FieldsToReturn parameter when
// making a Activate request to the Web API.
//
// This class is not terribly important and the FieldsToReturn
// parameter should usually be set server side by setting
// a Feature Lock for the license key
struct FieldsToReturn {
  static const int ID = 1 << 1;
  static const int KEY = 1 << 2;
  static const int NOTES = 1 << 3;
  static const int GLOBALID = 1 << 4;
  static const int CUSTOMER = 1 << 5;
  static const int ACTIVATEDMACHINES = 1 << 6;
  static const int MAXNOOFMACHINES = 1 << 8;
  static const int ALLOWEDMACHINES = 1 << 7;
  static const int DATAOBJECTS = 1 << 9;

  static bool expect_id(int n) {
    return n == 0 || (n & ID);
  }

  static bool expect_key(int n) {
    return n == 0 || (n & KEY);
  }

  static bool expect_notes(int n) {
    return n == 0 || (n & NOTES);
  }

  static bool expect_global_id(int n) {
    return n == 0 || (n & GLOBALID);
  }

  static bool expect_customer(int n) {
    return n == 0 || (n & CUSTOMER);
  }

  static bool expect_activated_machines(int n) {
    return n == 0 || (n & ACTIVATEDMACHINES);
  }

  static bool expect_maxnoofmachines(int n) {
    return n == 0 || (n & MAXNOOFMACHINES);
  }

  static bool expect_allowed_machines(int n) {
    return n == 0 || (n & ALLOWEDMACHINES);
  }

  static bool expect_dataobjects(int n) {
    return n == 0 || (n & DATAOBJECTS);
  }
};

// Function for handling a response to an Activate request from
// the SKM Web API
template<typename SignatureVerifier>
optional<RawLicenseKey>
handle_activate
  ( SignatureVerifier const& signature_verifier
  , std::string const& response
  )
{
  json j;
  try {
    j = json::parse(response);
  } catch (json_exception & e) {
    return nullopt;
  }

  return RawLicenseKey::make(signature_verifier, j["licenseKey"], j["signature"]);
}

// Function for handling a response to an Deactivate request from
// the SKM Web API
template<typename SignatureVerifier>
bool
handle_deactivate
  ( SignatureVerifier const& signature_verifier
  , std::string const& response
  )
{
  json j;
  try {
  j = json::parse(response);
  } catch (json_exception & e) {
    return false;
  }

  return j["Result"] == 0;
}

// This class makes it possible to interact with the SKM Web API. Among the
// various methods available in the Web API the only ones currently supported
// in the C++ API are Activate and Deactivate.
//
// This class uses two policy classes, SignatureVerifier and RequestHandler,
// which are responsible for handling verification of signatures and making
// requests to the Web API, respectivly.
template<typename RequestHandler, typename SignatureVerifier>
class basic_SKM
{
public:
  basic_SKM() { }

  // Make an Activate request to the SKM Web API
  //
  // Arguments:
  //   token - acces token to use
  //   product_id - the product id
  //   key - the serial key string, e.g. ABCDE-EFGHI-JKLMO-PQRST
  //   machine_code - the machine code, i.e. a string that identifies a device
  //                  for activation.
  //
  // Returns:
  //   An optional with a RawLicenseKey representing if the request was
  //   successful or not.
  optional<RawLicenseKey>
  activate
    ( std::string token
    , std::string product_id
    , std::string key
    , std::string machine_code
    , int fields_to_return = 0
    )
  {
    std::unordered_map<std::string,std::string> args;
    args["token"] = token;
    args["ProductId"] = product_id;
    args["Key"] = key;
    args["Sign"] = "true";
    args["MachineCode"] = machine_code;
    args["FieldsToReturn"] = fields_to_return;
    args["SignMethod"] = "1";
    args["v"] = 1;

    std::string url = request_handler.build_url("Activate", args);

    std::string response = request_handler.make_request(url);

    return handle_activate(this->signature_verifier, response);
  }

  // Make an Deactivate request to the SKM Web API
  //
  // Arguments:
  //   token - acces token to use
  //   product_id - the product id
  //   key - the serial key string, e.g. ABCDE-EFGHI-JKLMO-PQRST
  //   machine_code - the machine code, i.e. a string that identifies a device
  //                  for activation.
  //
  // Returns:
  //   A boolean representing if the request was successful or not.
  bool
  deactivate
    ( std::string token
    , std::string product_id
    , std::string key
    , std::string machine_code
    )
  {
    std::unordered_map<std::string,std::string> args;
    args["token"] = token;
    args["ProductId"] = product_id;
    args["Key"] = key;
    args["MachineCode"] = machine_code;
    args["v"] = 1;

    std::string url = request_handler.build_url("Deactivate", args);

    std::string response = request_handler.make_request(url);

    return handle_deactivate(this->signature_verifier, response);
  }

  SignatureVerifier signature_verifier;
  RequestHandler request_handler;
};

} // namespace serialkeymanager_com
<commit_msg>Adding some more checks so exceptions dont escape<commit_after>#pragma once

#include <string>
#include <unordered_map>

#include "optional.hpp"

#include "json.hpp"

#include "RawLicenseKey.hpp"
#include "LicenseKey.hpp"
#include "LicenseKeyChecker.hpp"

namespace serialkeymanager_com {

using json = nlohmann::json;
using json_exception = nlohmann::detail::exception;

// Helper class to work with the FieldsToReturn parameter when
// making a Activate request to the Web API.
//
// This class is not terribly important and the FieldsToReturn
// parameter should usually be set server side by setting
// a Feature Lock for the license key
struct FieldsToReturn {
  static const int ID = 1 << 1;
  static const int KEY = 1 << 2;
  static const int NOTES = 1 << 3;
  static const int GLOBALID = 1 << 4;
  static const int CUSTOMER = 1 << 5;
  static const int ACTIVATEDMACHINES = 1 << 6;
  static const int MAXNOOFMACHINES = 1 << 8;
  static const int ALLOWEDMACHINES = 1 << 7;
  static const int DATAOBJECTS = 1 << 9;

  static bool expect_id(int n) {
    return n == 0 || (n & ID);
  }

  static bool expect_key(int n) {
    return n == 0 || (n & KEY);
  }

  static bool expect_notes(int n) {
    return n == 0 || (n & NOTES);
  }

  static bool expect_global_id(int n) {
    return n == 0 || (n & GLOBALID);
  }

  static bool expect_customer(int n) {
    return n == 0 || (n & CUSTOMER);
  }

  static bool expect_activated_machines(int n) {
    return n == 0 || (n & ACTIVATEDMACHINES);
  }

  static bool expect_maxnoofmachines(int n) {
    return n == 0 || (n & MAXNOOFMACHINES);
  }

  static bool expect_allowed_machines(int n) {
    return n == 0 || (n & ALLOWEDMACHINES);
  }

  static bool expect_dataobjects(int n) {
    return n == 0 || (n & DATAOBJECTS);
  }
};

// Function for handling a response to an Activate request from
// the SKM Web API
template<typename SignatureVerifier>
optional<RawLicenseKey>
handle_activate
  ( SignatureVerifier const& signature_verifier
  , std::string const& response
  )
{
  json j;
  try {
    j = json::parse(response);
  } catch (json_exception & e) {
    return nullopt;
  }

  if (!j["licenseKey"].is_string() || !j["signature"].is_string()) {
    return nullopt;
  }

  return RawLicenseKey::make(signature_verifier, j["licenseKey"], j["signature"]);
}

// Function for handling a response to an Deactivate request from
// the SKM Web API
template<typename SignatureVerifier>
bool
handle_deactivate
  ( SignatureVerifier const& signature_verifier
  , std::string const& response
  )
{
  json j;
  try {
  j = json::parse(response);
  } catch (json_exception & e) {
    return false;
  }

  if (!j["Result"].is_number_integer()) {
    return false;
  }

  return j["Result"] == 0;
}

// This class makes it possible to interact with the SKM Web API. Among the
// various methods available in the Web API the only ones currently supported
// in the C++ API are Activate and Deactivate.
//
// This class uses two policy classes, SignatureVerifier and RequestHandler,
// which are responsible for handling verification of signatures and making
// requests to the Web API, respectivly.
template<typename RequestHandler, typename SignatureVerifier>
class basic_SKM
{
public:
  basic_SKM() { }

  // Make an Activate request to the SKM Web API
  //
  // Arguments:
  //   token - acces token to use
  //   product_id - the product id
  //   key - the serial key string, e.g. ABCDE-EFGHI-JKLMO-PQRST
  //   machine_code - the machine code, i.e. a string that identifies a device
  //                  for activation.
  //
  // Returns:
  //   An optional with a RawLicenseKey representing if the request was
  //   successful or not.
  optional<RawLicenseKey>
  activate
    ( std::string token
    , std::string product_id
    , std::string key
    , std::string machine_code
    , int fields_to_return = 0
    )
  {
    std::unordered_map<std::string,std::string> args;
    args["token"] = token;
    args["ProductId"] = product_id;
    args["Key"] = key;
    args["Sign"] = "true";
    args["MachineCode"] = machine_code;
    args["FieldsToReturn"] = fields_to_return;
    args["SignMethod"] = "1";
    args["v"] = 1;

    std::string url = request_handler.build_url("Activate", args);

    std::string response = request_handler.make_request(url);

    return handle_activate(this->signature_verifier, response);
  }

  // Make an Deactivate request to the SKM Web API
  //
  // Arguments:
  //   token - acces token to use
  //   product_id - the product id
  //   key - the serial key string, e.g. ABCDE-EFGHI-JKLMO-PQRST
  //   machine_code - the machine code, i.e. a string that identifies a device
  //                  for activation.
  //
  // Returns:
  //   A boolean representing if the request was successful or not.
  bool
  deactivate
    ( std::string token
    , std::string product_id
    , std::string key
    , std::string machine_code
    )
  {
    std::unordered_map<std::string,std::string> args;
    args["token"] = token;
    args["ProductId"] = product_id;
    args["Key"] = key;
    args["MachineCode"] = machine_code;
    args["v"] = 1;

    std::string url = request_handler.build_url("Deactivate", args);

    std::string response = request_handler.make_request(url);

    return handle_deactivate(this->signature_verifier, response);
  }

  SignatureVerifier signature_verifier;
  RequestHandler request_handler;
};

} // namespace serialkeymanager_com
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014-2015 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <limits>

#include "MainWindow.hpp"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    go_(new GameOptions) {
    ui->setupUi(this);
    setWindowIcon(QIcon(":/images/bin_game.ico"));
    default_font_ = ui->gameBoard->font();
}

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

int MainWindow::getDeskSize_impl() const {
    return ui->boardsSize->value();
}

int MainWindow::getWinNumber_impl() const {
    return ui->scoreNumber->value();
}

int MainWindow::getTimeNumber_impl() const {
    return ui->timeNumber->value();
}

void MainWindow::finish_impl(bool fail, int score,
                             int steps_number) const {
    QString result = (fail) ? "You're loser..." :
                     "You're winner!";
    QString score_str = "Your score is " +
                        QString::number(score);
    QString steps = "You've completed the game in " +
                    QString::number(steps_number) +
                    " moves.";
    ui->resultLabel->setText(result);
    ui->scoreLabel->setText(score_str);
    ui->stepLabel->setText(steps);
}

void MainWindow::sendHelpMessage_impl() const {
    QMessageBox help;
    help.setText("Some useful help information.");
    help.setInformativeText("");
    help.exec();
}

void MainWindow::startGame_impl(int row_number) {
    game_ = GuiGame::make(this, row_number);
    game_->controller->initialStateOfBoard();
    setBoardsModel();
    configureBoard(row_number);
}

void MainWindow::errorHandling_impl(std::exception& e) const {
    QString what = QString::fromStdString(e.what());
    QString error = "The error occurred."
                    "

Contact developers! "
                    "pdolgov99@gmail.com";
    what = what.replace("&", "&");
    what = what.replace("'", "'");
    what = what.replace("<", "<");
    what = what.replace(">", ">");
    what = what.replace("\"", """);
    QString m = error + "

" + what;
    QErrorMessage::qtHandler()->resize(400, 300);
    QErrorMessage::qtHandler()->showMessage(m);
}

void MainWindow::resizeBoardsContent(int boards_size) {
    if (boards_size <= Gui::RESIZE_MAX) {
        QTimer::singleShot(Gui::WAIT_TIME, this,
                           SLOT(resizeBoardsContent_deferred()));
    }
}

void MainWindow::resizeEvent(QResizeEvent* event) {
    QWidget* current_page = ui->stackedWidget
                            ->currentWidget();
    if (current_page == ui->gamepage) {
        QMainWindow::resizeEvent(event);
        int boards_size = game_->desk->getRowNumber();
        resizeBoardsContent(boards_size);
    }
}

void MainWindow::setBoardsModel() {
    ui->gameBoard->setModel(game_->t_model.data());
}

void MainWindow::configureBoard(int row_number) {
    ui->gameBoard
    ->setSelectionMode(QAbstractItemView::NoSelection);
    ui->gameBoard->horizontalHeader()
    ->setResizeMode(QHeaderView::Stretch);
    ui->gameBoard->verticalHeader()
    ->setResizeMode(QHeaderView::Stretch);
}

void MainWindow::preparingToPlay() {
    int boards_size = getDeskSize_impl();
    startGame_impl(boards_size);
}

void MainWindow::finishActions(int steps_number) {
    const GameDesk* desk = game_->desk.data();
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
    ui->stackedWidget->setCurrentWidget(ui->resultpage);
}

bool MainWindow::endOfGame() const {
    const GameDesk* desk = game_->desk.data();
    if (go_->game_type_ == SCORE_MODE) {
        return checkFail(*desk);
    } else if (go_->game_type_ == WIN_MODE) {
        return checkFail(*desk) || checkWin(*desk,
                                            go_->win_number_);
    } else {
        int current_time = time(NULL);
        bool time_is_up =
            (current_time - go_->starting_time_) >= go_->time_number_ * 60;
        return checkFail(*desk) || time_is_up;
    }
}

void MainWindow::tryToMove() {
    try {
        game_->controller->replace(go_->current_step_);
    } catch (...) {
    }
}

void MainWindow::settingOfScore() {
    int max_int = std::numeric_limits<int>::max();
    int boards_size = game_->desk->getRowNumber();
    int square = boards_size * boards_size;
    // Minimum possible: board's square * 2 + 1
    ui->scoreNumber->setRange(square * 2 + 1, max_int);
    // Default value: board's square * 4
    ui->scoreNumber->setValue(square * 4);
}

void MainWindow::settingOfTime() {
    int max_int = std::numeric_limits<int>::max();
    ui->timeNumber->setRange(1, max_int);
    ui->timeNumber->setValue(Rules::DEFAULT_TIME);
}

void MainWindow::settingOfSize() {
    ui->boardsSize->setRange(Rules::MIN_WIDTH,
                             Rules::MAX_WIDTH);
    ui->boardsSize->setValue(Gui::DEFAULT_SIZE);
}

void MainWindow::setInitialParameters() {
    go_->steps_number_ = 0;
    go_->first_click_ = true;
    ui->stackedWidget->setCurrentWidget(ui->gamepage);
    int boards_size = game_->desk->getRowNumber();
    resizeBoardsContent(boards_size);
}

void MainWindow::on_quitButton_clicked() {
    QApplication::quit();
}

void MainWindow::on_winButton_clicked() {
    go_->game_type_ = WIN_MODE;
    settingOfSize();
    ui->stackedWidget->setCurrentWidget(ui->inputpage);
}

void MainWindow::on_timeButton_clicked() {
    go_->game_type_ = TIME_MODE;
    settingOfSize();
    ui->stackedWidget->setCurrentWidget(ui->inputpage);
}

void MainWindow::on_scoreButton_clicked() {
    go_->game_type_ = SCORE_MODE;
    settingOfSize();
    ui->stackedWidget->setCurrentWidget(ui->inputpage);
}

void MainWindow::on_startButton_clicked() {
    try {
        preparingToPlay();
        if (go_->game_type_ == SCORE_MODE) {
            setInitialParameters();
        } else if (go_->game_type_ == WIN_MODE) {
            settingOfScore();
            ui->stackedWidget
            ->setCurrentWidget(ui->winInputpage);
        } else {
            settingOfTime();
            ui->stackedWidget
            ->setCurrentWidget(ui->timeInputpage);
        }
    } catch (std::exception& e) {
        errorHandling_impl(e);
    }
}

void MainWindow::on_playButton_clicked() {
    go_->time_number_ = getTimeNumber_impl();
    go_->starting_time_ = time(NULL);
    setInitialParameters();
}

void MainWindow::on_playButton2_clicked() {
    go_->win_number_ = getWinNumber_impl();
    setInitialParameters();
}

void MainWindow::on_gameBoard_clicked(const QModelIndex&
                                      index) {
    int desk_size = game_->desk->getRowNumber();
    Point p = getModelIndex(index, desk_size);
    if (go_->first_click_) {
        go_->first_click_ = false;
        go_->current_step_.p1 = p;
    } else {
        if (endOfGame()) {
            finishActions(go_->steps_number_);
        } else {
            go_->current_step_.p2 = p;
            tryToMove();
            game_->t_model->updateData();
            go_->steps_number_++;
            go_->first_click_ = true;
        }
    }
}

void MainWindow::on_endButton_clicked() {
    ui->stackedWidget->setCurrentWidget(ui->startpage);
}

void MainWindow::resizeBoardsContent_deferred() {
    // Use the first row because heights of all
    // rows are equal
    int row_height = ui->gameBoard->rowHeight(0);
    ui->gameBoard
    ->setFont(QFont("Helvetica",
                    Gui::NUMBER_PROPORTION * row_height));
}
<commit_msg>setFont() in MainWindow::resizeBoardsContent()<commit_after>/*
 * Copyright (C) 2014-2015 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <limits>

#include "MainWindow.hpp"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    go_(new GameOptions) {
    ui->setupUi(this);
    setWindowIcon(QIcon(":/images/bin_game.ico"));
    default_font_ = ui->gameBoard->font();
}

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

int MainWindow::getDeskSize_impl() const {
    return ui->boardsSize->value();
}

int MainWindow::getWinNumber_impl() const {
    return ui->scoreNumber->value();
}

int MainWindow::getTimeNumber_impl() const {
    return ui->timeNumber->value();
}

void MainWindow::finish_impl(bool fail, int score,
                             int steps_number) const {
    QString result = (fail) ? "You're loser..." :
                     "You're winner!";
    QString score_str = "Your score is " +
                        QString::number(score);
    QString steps = "You've completed the game in " +
                    QString::number(steps_number) +
                    " moves.";
    ui->resultLabel->setText(result);
    ui->scoreLabel->setText(score_str);
    ui->stepLabel->setText(steps);
}

void MainWindow::sendHelpMessage_impl() const {
    QMessageBox help;
    help.setText("Some useful help information.");
    help.setInformativeText("");
    help.exec();
}

void MainWindow::startGame_impl(int row_number) {
    game_ = GuiGame::make(this, row_number);
    game_->controller->initialStateOfBoard();
    setBoardsModel();
    configureBoard(row_number);
}

void MainWindow::errorHandling_impl(std::exception& e) const {
    QString what = QString::fromStdString(e.what());
    QString error = "The error occurred."
                    "

Contact developers! "
                    "pdolgov99@gmail.com";
    what = what.replace("&", "&");
    what = what.replace("'", "'");
    what = what.replace("<", "<");
    what = what.replace(">", ">");
    what = what.replace("\"", """);
    QString m = error + "

" + what;
    QErrorMessage::qtHandler()->resize(400, 300);
    QErrorMessage::qtHandler()->showMessage(m);
}

void MainWindow::resizeBoardsContent(int boards_size) {
    if (boards_size <= Gui::RESIZE_MAX) {
        QTimer::singleShot(Gui::WAIT_TIME, this,
                           SLOT(resizeBoardsContent_deferred()));
    } else {
        ui->gameBoard->setFont(default_font_);
    }
}

void MainWindow::resizeEvent(QResizeEvent* event) {
    QWidget* current_page = ui->stackedWidget
                            ->currentWidget();
    if (current_page == ui->gamepage) {
        QMainWindow::resizeEvent(event);
        int boards_size = game_->desk->getRowNumber();
        resizeBoardsContent(boards_size);
    }
}

void MainWindow::setBoardsModel() {
    ui->gameBoard->setModel(game_->t_model.data());
}

void MainWindow::configureBoard(int row_number) {
    ui->gameBoard
    ->setSelectionMode(QAbstractItemView::NoSelection);
    ui->gameBoard->horizontalHeader()
    ->setResizeMode(QHeaderView::Stretch);
    ui->gameBoard->verticalHeader()
    ->setResizeMode(QHeaderView::Stretch);
}

void MainWindow::preparingToPlay() {
    int boards_size = getDeskSize_impl();
    startGame_impl(boards_size);
}

void MainWindow::finishActions(int steps_number) {
    const GameDesk* desk = game_->desk.data();
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
    ui->stackedWidget->setCurrentWidget(ui->resultpage);
}

bool MainWindow::endOfGame() const {
    const GameDesk* desk = game_->desk.data();
    if (go_->game_type_ == SCORE_MODE) {
        return checkFail(*desk);
    } else if (go_->game_type_ == WIN_MODE) {
        return checkFail(*desk) || checkWin(*desk,
                                            go_->win_number_);
    } else {
        int current_time = time(NULL);
        bool time_is_up =
            (current_time - go_->starting_time_) >= go_->time_number_ * 60;
        return checkFail(*desk) || time_is_up;
    }
}

void MainWindow::tryToMove() {
    try {
        game_->controller->replace(go_->current_step_);
    } catch (...) {
    }
}

void MainWindow::settingOfScore() {
    int max_int = std::numeric_limits<int>::max();
    int boards_size = game_->desk->getRowNumber();
    int square = boards_size * boards_size;
    // Minimum possible: board's square * 2 + 1
    ui->scoreNumber->setRange(square * 2 + 1, max_int);
    // Default value: board's square * 4
    ui->scoreNumber->setValue(square * 4);
}

void MainWindow::settingOfTime() {
    int max_int = std::numeric_limits<int>::max();
    ui->timeNumber->setRange(1, max_int);
    ui->timeNumber->setValue(Rules::DEFAULT_TIME);
}

void MainWindow::settingOfSize() {
    ui->boardsSize->setRange(Rules::MIN_WIDTH,
                             Rules::MAX_WIDTH);
    ui->boardsSize->setValue(Gui::DEFAULT_SIZE);
}

void MainWindow::setInitialParameters() {
    go_->steps_number_ = 0;
    go_->first_click_ = true;
    ui->stackedWidget->setCurrentWidget(ui->gamepage);
    int boards_size = game_->desk->getRowNumber();
    resizeBoardsContent(boards_size);
}

void MainWindow::on_quitButton_clicked() {
    QApplication::quit();
}

void MainWindow::on_winButton_clicked() {
    go_->game_type_ = WIN_MODE;
    settingOfSize();
    ui->stackedWidget->setCurrentWidget(ui->inputpage);
}

void MainWindow::on_timeButton_clicked() {
    go_->game_type_ = TIME_MODE;
    settingOfSize();
    ui->stackedWidget->setCurrentWidget(ui->inputpage);
}

void MainWindow::on_scoreButton_clicked() {
    go_->game_type_ = SCORE_MODE;
    settingOfSize();
    ui->stackedWidget->setCurrentWidget(ui->inputpage);
}

void MainWindow::on_startButton_clicked() {
    try {
        preparingToPlay();
        if (go_->game_type_ == SCORE_MODE) {
            setInitialParameters();
        } else if (go_->game_type_ == WIN_MODE) {
            settingOfScore();
            ui->stackedWidget
            ->setCurrentWidget(ui->winInputpage);
        } else {
            settingOfTime();
            ui->stackedWidget
            ->setCurrentWidget(ui->timeInputpage);
        }
    } catch (std::exception& e) {
        errorHandling_impl(e);
    }
}

void MainWindow::on_playButton_clicked() {
    go_->time_number_ = getTimeNumber_impl();
    go_->starting_time_ = time(NULL);
    setInitialParameters();
}

void MainWindow::on_playButton2_clicked() {
    go_->win_number_ = getWinNumber_impl();
    setInitialParameters();
}

void MainWindow::on_gameBoard_clicked(const QModelIndex&
                                      index) {
    int desk_size = game_->desk->getRowNumber();
    Point p = getModelIndex(index, desk_size);
    if (go_->first_click_) {
        go_->first_click_ = false;
        go_->current_step_.p1 = p;
    } else {
        if (endOfGame()) {
            finishActions(go_->steps_number_);
        } else {
            go_->current_step_.p2 = p;
            tryToMove();
            game_->t_model->updateData();
            go_->steps_number_++;
            go_->first_click_ = true;
        }
    }
}

void MainWindow::on_endButton_clicked() {
    ui->stackedWidget->setCurrentWidget(ui->startpage);
}

void MainWindow::resizeBoardsContent_deferred() {
    // Use the first row because heights of all
    // rows are equal
    int row_height = ui->gameBoard->rowHeight(0);
    ui->gameBoard
    ->setFont(QFont("Helvetica",
                    Gui::NUMBER_PROPORTION * row_height));
}
<|endoftext|>


<commit_before>/*
 * rkf78.hpp
 *
 *  Created on: Wed Mar 16 2016
 *      Author: zhengfaxiang
 */

#ifndef RKF78_HPP_
#define RKF78_HPP_

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <string>
#include <stdexcept>
using namespace std;

template<class T, int dim>
class RKF78{
private:
    static const T a[13];       // rk78 parameters
    static const T b[13][12];   // rk78 parameters
    T K[13][dim];               // runge-kutta parameters
    T R[dim];                   // error
    T z[13][dim];               // make calculation of Ks easier
    void GetZ(int l, T y[dim]);
    void RungeKuttaParams78(T t, T h, T y[dim]);
    void GetY(T y[dim]);
public:
    long step;                  // step
    T (*f[dim])(T t, T y[dim]); // functions to solve
    void rkf78(T& h, T& t, T ynow[dim], T hmin, T TOL);
    void solve(T hinit, T hmin, T y0[dim], T TOL, T begin, T end,
               const char *filename);
};

template<class T, int dim>
const T RKF78<T, dim>::a[13] = {
    0.0, 2.0/27.0, 1.0/9.0, 1.0/6.0, 5.0/12.0, 0.5,
    5.0/6.0, 1.0/6.0, 2.0/3.0, 1.0/3.0, 1.0, 0.0, 1.0
};

template<class T, int dim>
const T RKF78<T, dim>::b[13][12] = {
    {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {2.0/27.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {1.0/36.0, 1.0/12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {1.0/24.0, 0.0, 1.0/8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {5.0/12.0, 0.0, -25.0/16.0, 25.0/16.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
     0.0, 0.0, },
    {1.0/20.0, 0.0, 0.0, 1.0/4.0, 1.0/5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
     0.0},
    {-25.0/108.0, 0.0, 0.0, 125.0/108.0, -65.0/27.0, 125.0/54.0, 0.0,
     0.0, 0.0, 0.0, 0.0, 0.0},
    {31.0/300, 0.0, 0.0, 0.0, 61.0/225.0, -2.0/9.0, 13.0/900.0, 0.0,
     0.0, 0.0, 0.0, 0.0},
    {2.0, 0.0, 0.0, -53.0/6.0, 704.0/45.0, -107.0/9.0, 67.0/90.0, 3.0,
     0.0, 0.0, 0.0, 0.0},
    {-91.0/108.0, 0.0, 0.0, 23.0/108.0, -976.0/135.0, 311.0/54.0, -19.0/60.0,
     17.0/6.0, -1.0/12.0, 0.0, 0.0, 0.0},
    {2383.0/4100, 0.0, 0.0, -341.0/164.0, 4496.0/1025.0, -301.0/82.0,
     2133.0/4100.0, 45.0/82.0, 45.0/164.0, 18.0/41.0, 0.0, 0.0},
    {3.0/205.0, 0.0, 0.0, 0.0, 0.0, -6.0/41.0, -3.0/205.0, -3.0/41.0,
     3.0/41.0, 6.0/41.0, 0.0, 0.0},
    {-1777.0/4100.0, 0.0, 0.0, -341.0/164.0, 4496.0/1025.0, -289.0/82.0,
     2193.0/4100.0, 51.0/82.0, 33.0/164.0, 12.0/41.0, 0.0, 1.0}
};

template<class T, int dim>
void RKF78<T, dim>::GetZ(int l, T y[dim]) {
    T tmp[dim];
    for (int i=0; i < dim; i++) {
        tmp[i] = 0;
    }
    if (l != 0) {
        for (int i=0; i < dim; i++) {
            for (int j=0; j < l; j++) {
                tmp[i] += K[j][i] * b[l][j];
            }
        }
    }
    for (int i=0; i < dim; i++) {
        z[l][i] = y[i] + tmp[i];
    }
}

template<class T, int dim>
void RKF78<T, dim>::RungeKuttaParams78(T t, T h, T y[dim]) {
    // get runge-kutta parameters
    for (int j=0; j < 13; j++) {
        GetZ(j, y);
        for (int i=0; i < dim; i++) {
            K[j][i] = h * (*f[i])(t + h * a[j], z[j]);
        }
    }
}

template<class T, int dim>
void RKF78<T, dim>::GetY(T y[dim]) {
    // get y using runge-kutta parameters
    for (int i=0; i < dim; i++) {
        y[i] += K[5][i] * 34.0 / 105.0 +
            (K[6][i] + K[7][i]) * 9.0 / 35.0 +
            (K[8][i] + K[9][i]) * 9.0 / 280.0 +
            (K[11][i] + K[12][i]) * 41.0 / 840.0;
    }
}

template<class T, int dim>
void RKF78<T, dim>::rkf78(T& h, T& t, T y[dim], T hmin, T TOL) {
    // function to apply the runge-kutta-fehlberg method for one step
    for (;;) {
        RungeKuttaParams78(t, h, y);  // get Ks
        for (int i=0; i < dim; i++) {      // finding errors
            R[i] = (fabs(K[0][i] + K[10][i] - K[11][i] - K[12][i])\
                    * h * 41.0 / 810.0);
        }
        T MaxErr = *max_element(R, R + dim); // maximium value of array R
        // T q=pow(TOL / (MaxErr * 2.0), 1.0 / 7.0);
        if (MaxErr < TOL) {
            GetY(y);         // get Ys
            // increase pace if error is too small
            if (MaxErr < TOL / 10) {
                h *= 2.0;
            }
            t += h;
            break;
        }
        else {
            h /= 2.0;
            if (h < hmin){     // error handling
                throw invalid_argument("Minimum h exceeded!");
            }
        }
    }
}

template<class T, int dim>
void RKF78<T, dim>::solve(T hinit, T hmin, T y[dim], T TOL, T begin, T end,
           const char *filename) {
    // function to apply the runge-kutta-fehlberg method
    // open a file in write mode.
    ofstream outfile;
    outfile.open(filename, ios::out);
    T t = begin;                // begin of t
    T h = hinit;                 // begin of h
    step = 0;                   // step
    // output header
    cout<<setw(28)<<"t"<<setw(28)<<"h";
    outfile<<setw(28)<<"t"<<setw(28)<<"h";
    for (int i=0; i < dim; i++) {
        // convert number to string
        ostringstream convert;
        convert << i;
        string yi = "y" + convert.str();
        cout<<setw(28)<<yi;
        outfile<<setw(28)<<yi;
    }
    cout<<endl;
    outfile<<endl;
    for (;t < end;) {
        rkf78(h, t, y, hmin, TOL); // calculate one step
        step++;                       // step plus one
        // output result
        cout<<setiosflags(ios::scientific)
            <<setprecision(18)<<setw(28)<<t
            <<setw(28)<<h;
        outfile<<setiosflags(ios::scientific)
               <<setprecision(18)<<setw(28)<<t
               <<setw(28)<<h;
        for (int i=0; i < dim; i++) {
            cout<<setiosflags(ios::scientific)<<setprecision(18)
                <<setw(28)<<y[i];
            outfile<<setiosflags(ios::scientific)<<setprecision(18)
                   <<setw(28)<<y[i];
        }
        cout<<endl;
        outfile<<endl;
    }
    outfile.close();                    // close the opened file.
    cout<<"Procedure completed!"<<endl; // end
}

#endif  /* RKF78_HPP_ */
<commit_msg>update<commit_after>/*
 * rkf78.hpp
 *
 *  Created on: Wed Mar 16 2016
 *      Author: zhengfaxiang
 */

#ifndef RKF78_HPP_
#define RKF78_HPP_

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <string>
#include <stdexcept>
using namespace std;

template<class T, int dim>
class RKF78{
private:
    static const T a[13];       // rk78 parameters
    static const T b[13][12];   // rk78 parameters
    T K[13][dim];               // runge-kutta parameters
    T R[dim];                   // error
    T z[13][dim];               // make calculation of Ks easier
    void GetZ(int l, T y[dim]);
    void RungeKuttaParams78(T t, T h, T y[dim]);
    void GetY(T y[dim]);
public:
    long step;                  // step
    T (*f[dim])(T t, T y[dim]); // functions to solve
    void rkf78(T& h, T& t, T ynow[dim], T hmin, T TOL);
    void solve(T hinit, T hmin, T y0[dim], T TOL, T begin, T end,
               const char *filename);
};

template<class T, int dim>
const T RKF78<T, dim>::a[13] = {
    0.0, 2.0/27.0, 1.0/9.0, 1.0/6.0, 5.0/12.0, 0.5,
    5.0/6.0, 1.0/6.0, 2.0/3.0, 1.0/3.0, 1.0, 0.0, 1.0
};

template<class T, int dim>
const T RKF78<T, dim>::b[13][12] = {
    {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {2.0/27.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {1.0/36.0, 1.0/12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {1.0/24.0, 0.0, 1.0/8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    {5.0/12.0, 0.0, -25.0/16.0, 25.0/16.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
     0.0, 0.0, },
    {1.0/20.0, 0.0, 0.0, 1.0/4.0, 1.0/5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
     0.0},
    {-25.0/108.0, 0.0, 0.0, 125.0/108.0, -65.0/27.0, 125.0/54.0, 0.0,
     0.0, 0.0, 0.0, 0.0, 0.0},
    {31.0/300, 0.0, 0.0, 0.0, 61.0/225.0, -2.0/9.0, 13.0/900.0, 0.0,
     0.0, 0.0, 0.0, 0.0},
    {2.0, 0.0, 0.0, -53.0/6.0, 704.0/45.0, -107.0/9.0, 67.0/90.0, 3.0,
     0.0, 0.0, 0.0, 0.0},
    {-91.0/108.0, 0.0, 0.0, 23.0/108.0, -976.0/135.0, 311.0/54.0, -19.0/60.0,
     17.0/6.0, -1.0/12.0, 0.0, 0.0, 0.0},
    {2383.0/4100, 0.0, 0.0, -341.0/164.0, 4496.0/1025.0, -301.0/82.0,
     2133.0/4100.0, 45.0/82.0, 45.0/164.0, 18.0/41.0, 0.0, 0.0},
    {3.0/205.0, 0.0, 0.0, 0.0, 0.0, -6.0/41.0, -3.0/205.0, -3.0/41.0,
     3.0/41.0, 6.0/41.0, 0.0, 0.0},
    {-1777.0/4100.0, 0.0, 0.0, -341.0/164.0, 4496.0/1025.0, -289.0/82.0,
     2193.0/4100.0, 51.0/82.0, 33.0/164.0, 12.0/41.0, 0.0, 1.0}
};

template<class T, int dim>
void RKF78<T, dim>::GetZ(int l, T y[dim]) {
    T tmp[dim];
    for (int i=0; i < dim; i++) {
        tmp[i] = 0;
    }
    if (l != 0) {
        for (int i=0; i < dim; i++) {
            for (int j=0; j < l; j++) {
                tmp[i] += K[j][i] * b[l][j];
            }
        }
    }
    for (int i=0; i < dim; i++) {
        z[l][i] = y[i] + tmp[i];
    }
}

template<class T, int dim>
void RKF78<T, dim>::RungeKuttaParams78(T t, T h, T y[dim]) {
    // get runge-kutta parameters
    for (int j=0; j < 13; j++) {
        GetZ(j, y);
        for (int i=0; i < dim; i++) {
            K[j][i] = h * (*f[i])(t + h * a[j], z[j]);
        }
    }
}

template<class T, int dim>
void RKF78<T, dim>::GetY(T y[dim]) {
    // get y using runge-kutta parameters
    for (int i=0; i < dim; i++) {
        y[i] += K[5][i] * 34.0 / 105.0 +
            (K[6][i] + K[7][i]) * 9.0 / 35.0 +
            (K[8][i] + K[9][i]) * 9.0 / 280.0 +
            (K[11][i] + K[12][i]) * 41.0 / 840.0;
    }
}

template<class T, int dim>
void RKF78<T, dim>::rkf78(T& h, T& t, T y[dim], T hmin, T TOL) {
    // function to apply the runge-kutta-fehlberg method for one step
    for (;;) {
        RungeKuttaParams78(t, h, y);  // get Ks
        for (int i=0; i < dim; i++) {      // finding errors
            R[i] = (fabs(K[0][i] + K[10][i] - K[11][i] - K[12][i])\
                    * h * 41.0 / 810.0);
        }
        T MaxErr = *max_element(R, R + dim); // maximium value of array R
        // T q=pow(TOL / (MaxErr * 2.0), 1.0 / 7.0);
        if (MaxErr < TOL) {
            GetY(y);         // get Ys
            // increase pace if error is too small
            if (MaxErr < TOL / 10) {
                h *= 2.0;
            }
            t += h;
            break;
        }
        else {
            h /= 2.0;
            if (h < hmin){     // error handling
                throw invalid_argument("Minimum h exceeded!");
            }
        }
    }
}

template<class T, int dim>
void RKF78<T, dim>::solve(T hinit, T hmin, T y[dim], T TOL, T begin, T end,
           const char *filename) {
    // function to apply the runge-kutta-fehlberg method
    // open a file in write mode.
    ofstream outfile;
    outfile.open(filename, ios::out);
    T t = begin;                // begin of t
    T h = hinit;                // begin of h
    step = 0;                   // step
    // output header
    cout<<setw(28)<<"t"<<setw(28)<<"h";
    outfile<<setw(28)<<"t"<<setw(28)<<"h";
    for (int i=0; i < dim; i++) {
        // convert number to string
        ostringstream convert;
        convert << i;
        string yi = "y" + convert.str();
        cout<<setw(28)<<yi;
        outfile<<setw(28)<<yi;
    }
    cout<<endl;
    outfile<<endl;
    for (;t < end;) {
        rkf78(h, t, y, hmin, TOL); // calculate one step
        step++;                       // step plus one
        // output result
        cout<<setiosflags(ios::scientific)
            <<setprecision(18)<<setw(28)<<t
            <<setw(28)<<h;
        outfile<<setiosflags(ios::scientific)
               <<setprecision(18)<<setw(28)<<t
               <<setw(28)<<h;
        for (int i=0; i < dim; i++) {
            cout<<setiosflags(ios::scientific)<<setprecision(18)
                <<setw(28)<<y[i];
            outfile<<setiosflags(ios::scientific)<<setprecision(18)
                   <<setw(28)<<y[i];
        }
        cout<<endl;
        outfile<<endl;
    }
    outfile.close();                    // close the opened file.
    cout<<"Procedure completed!"<<endl; // end
}

#endif  /* RKF78_HPP_ */
<|endoftext|>


<commit_before>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
#include <memory>

class bitset
{
public:
	explicit
		bitset(size_t size) /*strong*/;

	bitset(bitset const & other) = delete;
	auto operator =(bitset const & other)->bitset & = delete;

	bitset(bitset && other) = delete;
	auto operator =(bitset && other)->bitset & = delete;

	auto set(size_t index) /*strong*/ -> void;
	auto reset(size_t index) /*strong*/ -> void;
	auto test(size_t index) /*strong*/ -> bool;

	auto size() /*noexcept*/ -> size_t;
	auto counter() /*noexcept*/ -> size_t;

private:
	std::unique_ptr<bool[]>  ptr_;
	size_t size_;
	size_t counter_;
};

bitset::bitset(size_t size) : ptr_(std::make_unique<bool[]>(size)), size_(size), counter_(0) {}

auto bitset::set(size_t index) -> void
{ if (index >= 0 && index < size_) {
	ptr_[index] = true;
	++counter_; }
	else throw;
}

auto bitset::reset(size_t index) -> void
{	if (index >= 0 && index < size_)
	{
		ptr_[index] = false;
		--counter_;
	}
else throw;
}

auto bitset::test(size_t index) -> bool
{
	if (index >= 0 && index < size_)
	{
		return !ptr_[index];
	}
	else throw;

}
auto bitset::size() -> size_t
{
	return size_;
}

auto bitset::counter() -> size_t
{
	return counter_;
}

template <typename T>
class allocator
{
public:
	explicit
		allocator(std::size_t size = 0) /*strong*/;
	allocator(allocator const & other) /*strong*/;
	auto operator =(allocator const & other)->allocator & = delete;
	~allocator();

	auto resize() /*strong*/ -> void;

	auto construct(T * ptr, T const & value) /*strong*/ -> void;
	auto destroy(T * ptr) /*noexcept*/ -> void;

	auto get() /*noexcept*/ -> T *;
	auto get() const /*noexcept*/ -> T const *;

	auto count() const /*noexcept*/ -> size_t;
	auto full() const /*noexcept*/ -> bool;
	auto empty() const /*noexcept*/ -> bool;
private:
	auto destroy(T * first, T * last) /*noexcept*/ -> void;
	auto swap(allocator & other) /*noexcept*/ -> void;

	T * ptr_;
	size_t size_;
	std::unique_ptr<bitset> map_;
};

template <typename T>
class stack
{
public:
	explicit
		stack(size_t size = 0);
	auto operator =(stack const & other) /*strong*/ -> stack &;

	auto empty() const /*noexcept*/ -> bool;
	auto count() const /*noexcept*/ -> size_t;

	auto push(T const & value) /*strong*/ -> void;
	auto pop() /*strong*/ -> void;
	auto top() /*strong*/ -> T &;
	auto top() const /*strong*/ -> T const &;

private:
	allocator<T> allocator_;

	auto throw_is_empty() const -> void;
};

template <typename T>
allocator<T>::allocator(size_t size) : ptr_((T*)(operator new(size*sizeof(T)))), size_(size), map_(std::make_unique<bitset>(size)) {};

template<typename T>
	allocator<T>::allocator(allocator const& other) :
ptr_(static_cast<T*>(operator new(other.size_))),
size_(other.size_), map_(std::make_unique<bitset>(size_)){
	for (size_t i; i < size_; i++)
		construct(ptr_ + i, other.ptr_[i]);
}
template<typename T>
allocator<T>::~allocator() { operator delete(ptr_); }

template<typename T>
auto allocator<T>::resize() -> void
{
	allocator<T> buff(size_ * 2 + (size_ == 0));
	for (size_t i = 0; i < size_; i++) construct(buff.ptr_ + i, ptr_[i]);
	this->swap(buff);
}

template<typename T>
auto allocator<T>::construct(T * ptr, T const & value)->void {
	if (ptr >= ptr_&&ptr < ptr_ + size_&&map_->test(ptr - ptr_)) {
		new(ptr)T(value);
		map_->set(ptr - ptr_);
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * ptr) -> void {
	ptr->~T();
	map_->reset(ptr-ptr_);
}

template<typename T>
auto allocator<T>::destroy(T * first, T * last) -> void
{
	for (; first != last; ++first) {
		destroy(&*first);
	}
}

template<typename T>
auto allocator<T>::get()-> T* {
	return ptr_;
}

template<typename T>
auto allocator<T>::get() const -> T const * {
	return ptr_;
}

template<typename T>
auto allocator<T>::count() const -> size_t
{
	return map_->counter();
}

template<typename T>
auto allocator<T>::full() const -> bool
{
	return map_->counter()==size_;
}

template<typename T>
auto allocator<T>::empty() const -> bool
{
	return map_->counter()==0;
}

template<typename T>
auto allocator<T>::swap(allocator & other) -> void {
	std::swap(ptr_, other.ptr_);
	std::swap(map_, other.map_);
	std::swap(size_, other.size_);
}

template <typename T>
size_t stack<T>::count() const
{
	return allocator_.count_;
}
template <typename T>
stack<T>::stack(size_t size) :allocator<T>(size) {}

template <typename T>
void stack<T>::push(T const &item) {
	if (allocator_.full()) allocator_.resize();
	allocator_.construct(allocator_.get() + this->count(), item;
}
template<typename T>
void stack<T>::pop()
{
	if (this->count() > 0)
		allocator_.destroy(allocator_.get() + this->count());
	else throw_is_empty();
}
template<typename T>
auto stack<T>::top() -> T &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::top() const -> T const &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::throw_is_empty() const -> void
{
		throw("Stack is empty!");
}

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
		stack<T> temp(right.size_);
		while (temp.count_ < right.count_) {
			construct(temp.ptr_ + temp.count_, right.ptr_[temp.count_]);
			++temp.count_;
		}
		this->swap(temp);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool {
	return allocator_.empty;

#endif
<commit_msg>Update stack.hpp<commit_after>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
#include <memory>

class bitset
{
public:
	explicit
		bitset(size_t size) /*strong*/;

	bitset(bitset const & other) = delete;
	auto operator =(bitset const & other)->bitset & = delete;

	bitset(bitset && other) = delete;
	auto operator =(bitset && other)->bitset & = delete;

	auto set(size_t index) /*strong*/ -> void;
	auto reset(size_t index) /*strong*/ -> void;
	auto test(size_t index) /*strong*/ -> bool;

	auto size() /*noexcept*/ -> size_t;
	auto counter() /*noexcept*/ -> size_t;

private:
	std::unique_ptr<bool[]>  ptr_;
	size_t size_;
	size_t counter_;
};

bitset::bitset(size_t size) : ptr_(std::make_unique<bool[]>(size)), size_(size), counter_(0) {}

auto bitset::set(size_t index) -> void
{ if (index >= 0 && index < size_) {
	ptr_[index] = true;
	++counter_; }
	else throw;
}

auto bitset::reset(size_t index) -> void
{	if (index >= 0 && index < size_)
	{
		ptr_[index] = false;
		--counter_;
	}
else throw;
}

auto bitset::test(size_t index) -> bool
{
	if (index >= 0 && index < size_)
	{
		return !ptr_[index];
	}
	else throw;

}
auto bitset::size() -> size_t
{
	return size_;
}

auto bitset::counter() -> size_t
{
	return counter_;
}

template <typename T>
class allocator
{
public:
	explicit
		allocator(std::size_t size = 0) /*strong*/;
	allocator(allocator const & other) /*strong*/;
	auto operator =(allocator const & other)->allocator & = delete;
	~allocator();

	auto resize() /*strong*/ -> void;

	auto construct(T * ptr, T const & value) /*strong*/ -> void;
	auto destroy(T * ptr) /*noexcept*/ -> void;

	auto get() /*noexcept*/ -> T *;
	auto get() const /*noexcept*/ -> T const *;

	auto count() const /*noexcept*/ -> size_t;
	auto full() const /*noexcept*/ -> bool;
	auto empty() const /*noexcept*/ -> bool;
private:
	auto destroy(T * first, T * last) /*noexcept*/ -> void;
	auto swap(allocator & other) /*noexcept*/ -> void;

	T * ptr_;
	size_t size_;
	std::unique_ptr<bitset> map_;
};

template <typename T>
class stack
{
public:
	explicit
		stack(size_t size = 0);
	auto operator =(stack const & other) /*strong*/ -> stack &;

	auto empty() const /*noexcept*/ -> bool;
	auto count() const /*noexcept*/ -> size_t;

	auto push(T const & value) /*strong*/ -> void;
	auto pop() /*strong*/ -> void;
	auto top() /*strong*/ -> T &;
	auto top() const /*strong*/ -> T const &;

private:
	allocator<T> allocator_;

	auto throw_is_empty() const -> void;
};

template <typename T>
allocator<T>::allocator(size_t size) : ptr_((T*)(operator new(size*sizeof(T)))), size_(size), map_(std::make_unique<bitset>(size)) {};

template<typename T>
	allocator<T>::allocator(allocator const& other) :
ptr_(static_cast<T*>(operator new(other.size_))),
size_(other.size_), map_(std::make_unique<bitset>(size_)){
	for (size_t i; i < size_; i++)
		construct(ptr_ + i, other.ptr_[i]);
}
template<typename T>
allocator<T>::~allocator() { operator delete(ptr_); }

template<typename T>
auto allocator<T>::resize() -> void
{
	allocator<T> buff(size_ * 2 + (size_ == 0));
	for (size_t i = 0; i < size_; i++) construct(buff.ptr_ + i, ptr_[i]);
	this->swap(buff);
}

template<typename T>
auto allocator<T>::construct(T * ptr, T const & value)->void {
	if (ptr >= ptr_&&ptr < ptr_ + size_&&map_->test(ptr - ptr_)) {
		new(ptr)T(value);
		map_->set(ptr - ptr_);
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * ptr) -> void {
	ptr->~T();
	map_->reset(ptr-ptr_);
}

template<typename T>
auto allocator<T>::destroy(T * first, T * last) -> void
{
	for (; first != last; ++first) {
		destroy(&*first);
	}
}

template<typename T>
auto allocator<T>::get()-> T* {
	return ptr_;
}

template<typename T>
auto allocator<T>::get() const -> T const * {
	return ptr_;
}

template<typename T>
auto allocator<T>::count() const -> size_t
{
	return map_->counter();
}

template<typename T>
auto allocator<T>::full() const -> bool
{
	return map_->counter()==size_;
}

template<typename T>
auto allocator<T>::empty() const -> bool
{
	return map_->counter()==0;
}

template<typename T>
auto allocator<T>::swap(allocator & other) -> void {
	std::swap(ptr_, other.ptr_);
	std::swap(map_, other.map_);
	std::swap(size_, other.size_);
}

template <typename T>
size_t stack<T>::count() const
{
	return allocator_.count_;
}
template <typename T>
stack<T>::stack(size_t size) :allocator<T>(size) {}

template <typename T>
void stack<T>::push(T const &item) {
	if (allocator_.full()) allocator_.resize();
	allocator_.construct(allocator_.get() + this->count(), item);
}
template<typename T>
void stack<T>::pop()
{
	if (this->count() > 0)
		allocator_.destroy(allocator_.get() + this->count());
	else throw_is_empty();
}
template<typename T>
auto stack<T>::top() -> T &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::top() const -> T const &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::throw_is_empty() const -> void
{
		throw("Stack is empty!");
}

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
		stack<T> temp(right.size_);
		while (temp.count_ < right.count_) {
			construct(temp.ptr_ + temp.count_, right.ptr_[temp.count_]);
			++temp.count_;
		}
		this->swap(temp);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool {
	return allocator_.empty;

#endif
<|endoftext|>


<commit_before>#ifndef STACK_HPP
#define STACK_HPP
#include <cstdlib>
#include <iostream>
#include <memory>
using namespace std;

template <typename T>
class stack
{
public:
	stack();
	size_t count() const;
	void push(T const &);
	T pop();
	~stack();
	T top();
	stack(const stack &b);
	stack & operator=(const stack &b);
	bool operator==(stack const & _s);
private:
	size_t array_size_;
	size_t count_;
	T * array_;
};
template<typename T>
T*copy_new(const T*arr,size_t count,size_t array_size)
{T*l=new T[array_size];
std::copy(arr,arr+count,l);
return;}
#include "stack.cpp"
#endif
<commit_msg>Update stack.hpp<commit_after>#ifndef STACK_HPP
#define STACK_HPP
#include <cstdlib>
#include <iostream>
#include <memory>
using namespace std;

template <typename T>
class stack
{
public:
	stack();
	size_t count() const;
	void push(T const &);
	T pop();
	~stack();
	stack(const stack &b);
	stack & operator=(const stack &b);
	bool operator==(stack const & _s);
private:
	size_t array_size_;
	size_t count_;
	T * array_;
};
template<typename T>
T*copy_new(const T*arr,size_t count,size_t array_size)
{T*l=new T[array_size];
std::copy(arr,arr+count,l);
return;}
#include "stack.cpp"
#endif
<|endoftext|>


<commit_before>
#include <iostream>
#include <chrono>
#include <thread>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>

// get command for launching the Stem script
char** getStemProcess()
{
  const char** args = new const char* [3];
  args[0] = "python\0";
  args[1] = "/var/lib/tor-onions/client.py\0";
  args[2] = NULL;
  return const_cast<char**>(args);
}

// get commmand for launching the onions-client executable
char** getOnionsClientProcess()
{
  const char** args = new const char* [2];
  args[0] = "onions-client\0";
  args[1] = "--output\0";
  args[2] = "TorBrowser/OnioNS/client.log\0";
  args[3] = NULL;
  return const_cast<char**>(args);
}

// start a child process based on the given commands
pid_t startProcess(char** args)
{  // http://www.cplusplus.com/forum/lounge/17684/
  pid_t pid = fork();

  switch (pid)
  {
    case -1:
      std::cerr << "Uh-Oh! fork() failed.\n";
      exit(1);
    case 0:                   // Child process
      execvp(args[0], args);  // Execute the program
      std::cerr << "Failed to execute process!\n";
      exit(1);
    default: /* Parent process */
      std::cout << "Process \"" << args[0] << "\" created, pid " << pid << "\n";
      // wait(&pid);
      return pid;
  }
}

// test if a localhost port is open or not
bool isOpen(int port)
{  // https://theredblacktree.wordpress.com/2013/09/30/how-to-check-if-a-port-is-open-or-not-in-c-unixlinux/

  std::cout << "Testing..." << std::endl;
  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0)
  {
    std::cerr << "Error opening socket!" << std::endl;
    return false;
  }

  struct hostent* server = gethostbyname("127.0.0.1");
  if (server == NULL)
  {
    std::cerr << "ERROR, no such host" << std::endl;
    return false;
  }

  struct sockaddr_in serv_addr;
  bzero((char*)&serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  bcopy((char*)server->h_addr, (char*)&serv_addr.sin_addr.s_addr,
        server->h_length);

  serv_addr.sin_port = htons(port);
  bool isOpen =
      connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) >= 0;
  close(sockfd);
  std::cout << "Result: " << isOpen << std::endl;
  return isOpen;
}

int main(int argc, char* argv[])
{
  // start Tor
  std::cout << "Launching Tor..." << std::endl;
  argv[0] = const_cast<char*>("TorBrowser/Tor/torbin");
  pid_t torP = startProcess(argv);

  // wait for Tor's control port to be available
  while (!isOpen(9151))
  {
    // https://stackoverflow.com/questions/5278582
    if (waitpid(torP, NULL, WNOHANG) != 0)  // test for existence of Tor
      return EXIT_FAILURE;  // if the Tor Browser was closed, then quit
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
  }

  // start the onions-client executable
  std::cout << "Launching OnioNS client software..." << std::endl;
  pid_t ocP = startProcess(getOnionsClientProcess());  // launch onions-client

  // wait until onions-client has established a connection
  while (!isOpen(9053))
  {
    if (waitpid(torP, NULL, WNOHANG) != 0 || waitpid(ocP, NULL, WNOHANG) != 0)
      return EXIT_FAILURE;
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
  }

  // launch the Stem script
  std::cout << "Launching OnioNS-TBB software..." << std::endl;
  startProcess(getStemProcess());

  wait(&torP);  // wait for Tor to exit
}
<commit_msg>fixed #9<commit_after>
#include <iostream>
#include <chrono>
#include <thread>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>

// get command for launching the Stem script
char** getStemProcess()
{
  const char** args = new const char* [3];
  args[0] = "python\0";
  args[1] = "/var/lib/tor-onions/client.py\0";
  args[2] = NULL;
  return const_cast<char**>(args);
}

// get commmand for launching the onions-client executable
char** getOnionsClientProcess()
{
  const char** args = new const char* [4];
  args[0] = "onions-client\0";
  args[1] = "--output\0";
  args[2] = "TorBrowser/OnioNS/client.log\0";
  args[3] = NULL;
  return const_cast<char**>(args);
}

// start a child process based on the given commands
pid_t startProcess(char** args)
{  // http://www.cplusplus.com/forum/lounge/17684/
  pid_t pid = fork();

  switch (pid)
  {
    case -1:
      std::cerr << "Uh-Oh! fork() failed.\n";
      exit(1);
    case 0:                   // Child process
      execvp(args[0], args);  // Execute the program
      std::cerr << "Failed to execute process!\n";
      exit(1);
    default: /* Parent process */
      std::cout << "Process \"" << args[0] << "\" created, pid " << pid << "\n";
      // wait(&pid);
      return pid;
  }
}

// test if a localhost port is open or not
bool isOpen(int port)
{  // https://theredblacktree.wordpress.com/2013/09/30/how-to-check-if-a-port-is-open-or-not-in-c-unixlinux/

  std::cout << "Testing..." << std::endl;
  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0)
  {
    std::cerr << "Error opening socket!" << std::endl;
    return false;
  }

  struct hostent* server = gethostbyname("127.0.0.1");
  if (server == NULL)
  {
    std::cerr << "ERROR, no such host" << std::endl;
    return false;
  }

  struct sockaddr_in serv_addr;
  bzero((char*)&serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  bcopy((char*)server->h_addr, (char*)&serv_addr.sin_addr.s_addr,
        server->h_length);

  serv_addr.sin_port = htons(port);
  bool isOpen =
      connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) >= 0;
  close(sockfd);
  std::cout << "Result: " << isOpen << std::endl;
  return isOpen;
}

int main(int argc, char* argv[])
{
  // start Tor
  std::cout << "Launching Tor..." << std::endl;
  argv[0] = const_cast<char*>("TorBrowser/Tor/torbin");
  pid_t torP = startProcess(argv);

  // wait for Tor's control port to be available
  while (!isOpen(9151))
  {
    // https://stackoverflow.com/questions/5278582
    if (waitpid(torP, NULL, WNOHANG) != 0)  // test for existence of Tor
      return EXIT_FAILURE;  // if the Tor Browser was closed, then quit
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
  }

  // start the onions-client executable
  std::cout << "Launching OnioNS client software..." << std::endl;
  pid_t ocP = startProcess(getOnionsClientProcess());  // launch onions-client

  // wait until onions-client has established a connection
  while (!isOpen(9053))
  {
    if (waitpid(torP, NULL, WNOHANG) != 0 || waitpid(ocP, NULL, WNOHANG) != 0)
      return EXIT_FAILURE;
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
  }

  // launch the Stem script
  std::cout << "Launching OnioNS-TBB software..." << std::endl;
  startProcess(getStemProcess());

  wait(&torP);  // wait for Tor to exit
}
<|endoftext|>


<commit_before>#include "rtkTest.h"
#include "itkRandomImageSource.h"
#include "rtkConstantImageSource.h"
#include "rtkInterpolatorWithKnownWeightsImageFilter.h"
#include "rtkSplatWithKnownWeightsImageFilter.h"
#include "rtkPhasesToInterpolationWeights.h"
#include "rtkJosephBackProjectionImageFilter.h"
#include "rtkJosephForwardProjectionImageFilter.h"
#include "rtkMacro.h"

#include <itkImageFileReader.h>

/**
 * \file rtkinterpolatesplatadjointtest.cxx
 *
 * \brief Tests whether InterpolatorWithKnownWeightsImageFilter and
 * SplatWithKnownWeightsImageFilter are the adjoint of one another.
 *
 * This test generates a random 4D volume "f" and a random 3D volume "v",
 * and compares the scalar products <Sf , v> and <f, S* v>, where S is the
 * interpolation operator and S* is the splat operator. If S* is indeed
 * the adjoint of S, these scalar products are equal.
 *
 * \author Cyril Mory
 */

int main(int, char** )
{
  const unsigned int Dimension = 3;
  typedef float                                    OutputPixelType;

  typedef itk::Image< OutputPixelType, Dimension > VolumeType;
  typedef itk::Image< OutputPixelType, Dimension + 1 > VolumeSeriesType;

#if FAST_TESTS_NO_CHECKS
  const unsigned int NumberOfSlices = 3;
#else
  const unsigned int NumberOfSlices = 64;
#endif

  // Random image sources
  typedef itk::RandomImageSource< VolumeType > RandomVolumeSourceType;
  RandomVolumeSourceType::Pointer randomVolumeSource  = RandomVolumeSourceType::New();

  typedef itk::RandomImageSource< VolumeSeriesType > RandomVolumeSeriesSourceType;
  RandomVolumeSeriesSourceType::Pointer randomVolumeSeriesSource  = RandomVolumeSeriesSourceType::New();

  // Constant sources
  typedef rtk::ConstantImageSource< VolumeType > ConstantVolumeSourceType;
  ConstantVolumeSourceType::Pointer constantVolumeSource  = ConstantVolumeSourceType::New();

  typedef rtk::ConstantImageSource< VolumeSeriesType > ConstantVolumeSeriesSourceType;
  ConstantVolumeSeriesSourceType::Pointer constantVolumeSeriesSource  = ConstantVolumeSeriesSourceType::New();

  // Volume metadata
  VolumeSeriesType::PointType fourDOrigin;
  VolumeSeriesType::SizeType fourDSize;
  VolumeSeriesType::SpacingType fourDSpacing;

  fourDOrigin[0] = -127.;
  fourDOrigin[1] = -127.;
  fourDOrigin[2] = -127.;
  fourDOrigin[3] = 0.;
#if FAST_TESTS_NO_CHECKS
  fourDSize[0] = 2;
  fourDSize[1] = 2;
  fourDSize[2] = 2;
  fourDSize[3] = 2;
  fourDSpacing[0] = 252.;
  fourDSpacing[1] = 252.;
  fourDSpacing[2] = 252.;
  fourDSpacing[3] = 1.;
#else
  fourDSize[0] = 64;
  fourDSize[1] = 64;
  fourDSize[2] = 64;
  fourDSize[3] = 5;
  fourDSpacing[0] = 4.;
  fourDSpacing[1] = 4.;
  fourDSpacing[2] = 4.;
  fourDSpacing[3] = 1.;
#endif
  randomVolumeSeriesSource->SetOrigin( fourDOrigin );
  randomVolumeSeriesSource->SetSpacing( fourDSpacing );
  randomVolumeSeriesSource->SetSize( fourDSize );
  randomVolumeSeriesSource->SetMin( 0. );
  randomVolumeSeriesSource->SetMax( 1. );

  constantVolumeSeriesSource->SetOrigin( fourDOrigin );
  constantVolumeSeriesSource->SetSpacing( fourDSpacing );
  constantVolumeSeriesSource->SetSize( fourDSize );
  constantVolumeSeriesSource->SetConstant( 0. );

  // Volume metadata
  VolumeType::PointType origin;
  VolumeType::SizeType size;
  VolumeType::SpacingType spacing;

  origin[0] = -255.;
  origin[1] = -255.;
  origin[2] = -255.;
#if FAST_TESTS_NO_CHECKS
  size[0] = 2;
  size[1] = 2;
  size[2] = NumberOfSlices;
  spacing[0] = 504.;
  spacing[1] = 504.;
  spacing[2] = 504.;
#else
  size[0] = 64;
  size[1] = 64;
  size[2] = NumberOfSlices;
  spacing[0] = 8.;
  spacing[1] = 8.;
  spacing[2] = 8.;
#endif
  randomVolumeSource->SetOrigin( origin );
  randomVolumeSource->SetSpacing( spacing );
  randomVolumeSource->SetSize( size );
  randomVolumeSource->SetMin( 0. );
  randomVolumeSource->SetMax( 1. );

  constantVolumeSource->SetOrigin( origin );
  constantVolumeSource->SetSpacing( spacing );
  constantVolumeSource->SetSize( size );
  constantVolumeSource->SetConstant( 0. );

  // Update all sources
  TRY_AND_EXIT_ON_ITK_EXCEPTION( randomVolumeSeriesSource->Update() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( constantVolumeSeriesSource->Update() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( randomVolumeSource->Update() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( constantVolumeSource->Update() );

  // Read the phases file
  rtk::PhasesToInterpolationWeights::Pointer phaseReader = rtk::PhasesToInterpolationWeights::New();
  phaseReader->SetFileName(std::string(RTK_DATA_ROOT) +
                           std::string("/Input/Phases/phases_slow.txt"));
  phaseReader->SetNumberOfReconstructedPhases( fourDSize[3] );
  phaseReader->Update();

  std::cout << "\n\n****** 4D to 3D (interpolation) ******" << std::endl;

  typedef rtk::InterpolatorWithKnownWeightsImageFilter<VolumeType, VolumeSeriesType> InterpolateFilterType;
  InterpolateFilterType::Pointer fw = InterpolateFilterType::New();
  fw->SetInputVolume(constantVolumeSource->GetOutput());
  fw->SetInputVolumeSeries(randomVolumeSeriesSource->GetOutput());
  fw->SetWeights(phaseReader->GetOutput());
  TRY_AND_EXIT_ON_ITK_EXCEPTION( fw->Update() );

  std::cout << "\n\n****** 3D to 4D (splat) ******" << std::endl;

  typedef rtk::SplatWithKnownWeightsImageFilter<VolumeSeriesType, VolumeType> SplatFilterType;
  SplatFilterType::Pointer bp = SplatFilterType::New();
  bp->SetInputVolumeSeries(constantVolumeSeriesSource->GetOutput());
  bp->SetInputVolume(randomVolumeSource->GetOutput());
  bp->SetWeights(phaseReader->GetOutput());
  TRY_AND_EXIT_ON_ITK_EXCEPTION( bp->Update() );

  CheckScalarProducts<VolumeSeriesType, VolumeType>(randomVolumeSeriesSource->GetOutput(), bp->GetOutput(), randomVolumeSource->GetOutput(), fw->GetOutput());
  std::cout << "\n\nTest PASSED! " << std::endl;

  return EXIT_SUCCESS;
}
<commit_msg>Cosmetics (changed variable names)<commit_after>#include "rtkTest.h"
#include "itkRandomImageSource.h"
#include "rtkConstantImageSource.h"
#include "rtkInterpolatorWithKnownWeightsImageFilter.h"
#include "rtkSplatWithKnownWeightsImageFilter.h"
#include "rtkPhasesToInterpolationWeights.h"
#include "rtkJosephBackProjectionImageFilter.h"
#include "rtkJosephForwardProjectionImageFilter.h"
#include "rtkMacro.h"

#include <itkImageFileReader.h>

/**
 * \file rtkinterpolatesplatadjointtest.cxx
 *
 * \brief Tests whether InterpolatorWithKnownWeightsImageFilter and
 * SplatWithKnownWeightsImageFilter are the adjoint of one another.
 *
 * This test generates a random 4D volume "f" and a random 3D volume "v",
 * and compares the scalar products <Sf , v> and <f, S* v>, where S is the
 * interpolation operator and S* is the splat operator. If S* is indeed
 * the adjoint of S, these scalar products are equal.
 *
 * \author Cyril Mory
 */

int main(int, char** )
{
  const unsigned int Dimension = 3;
  typedef float                                    OutputPixelType;

  typedef itk::Image< OutputPixelType, Dimension > VolumeType;
  typedef itk::Image< OutputPixelType, Dimension + 1 > VolumeSeriesType;

#if FAST_TESTS_NO_CHECKS
  const unsigned int NumberOfSlices = 3;
#else
  const unsigned int NumberOfSlices = 64;
#endif

  // Random image sources
  typedef itk::RandomImageSource< VolumeType > RandomVolumeSourceType;
  RandomVolumeSourceType::Pointer randomVolumeSource  = RandomVolumeSourceType::New();

  typedef itk::RandomImageSource< VolumeSeriesType > RandomVolumeSeriesSourceType;
  RandomVolumeSeriesSourceType::Pointer randomVolumeSeriesSource  = RandomVolumeSeriesSourceType::New();

  // Constant sources
  typedef rtk::ConstantImageSource< VolumeType > ConstantVolumeSourceType;
  ConstantVolumeSourceType::Pointer constantVolumeSource  = ConstantVolumeSourceType::New();

  typedef rtk::ConstantImageSource< VolumeSeriesType > ConstantVolumeSeriesSourceType;
  ConstantVolumeSeriesSourceType::Pointer constantVolumeSeriesSource  = ConstantVolumeSeriesSourceType::New();

  // Volume metadata
  VolumeSeriesType::PointType fourDOrigin;
  VolumeSeriesType::SizeType fourDSize;
  VolumeSeriesType::SpacingType fourDSpacing;

  fourDOrigin[0] = -127.;
  fourDOrigin[1] = -127.;
  fourDOrigin[2] = -127.;
  fourDOrigin[3] = 0.;
#if FAST_TESTS_NO_CHECKS
  fourDSize[0] = 2;
  fourDSize[1] = 2;
  fourDSize[2] = 2;
  fourDSize[3] = 2;
  fourDSpacing[0] = 252.;
  fourDSpacing[1] = 252.;
  fourDSpacing[2] = 252.;
  fourDSpacing[3] = 1.;
#else
  fourDSize[0] = 64;
  fourDSize[1] = 64;
  fourDSize[2] = 64;
  fourDSize[3] = 5;
  fourDSpacing[0] = 4.;
  fourDSpacing[1] = 4.;
  fourDSpacing[2] = 4.;
  fourDSpacing[3] = 1.;
#endif
  randomVolumeSeriesSource->SetOrigin( fourDOrigin );
  randomVolumeSeriesSource->SetSpacing( fourDSpacing );
  randomVolumeSeriesSource->SetSize( fourDSize );
  randomVolumeSeriesSource->SetMin( 0. );
  randomVolumeSeriesSource->SetMax( 1. );

  constantVolumeSeriesSource->SetOrigin( fourDOrigin );
  constantVolumeSeriesSource->SetSpacing( fourDSpacing );
  constantVolumeSeriesSource->SetSize( fourDSize );
  constantVolumeSeriesSource->SetConstant( 0. );

  // Volume metadata
  VolumeType::PointType origin;
  VolumeType::SizeType size;
  VolumeType::SpacingType spacing;

  origin[0] = -255.;
  origin[1] = -255.;
  origin[2] = -255.;
#if FAST_TESTS_NO_CHECKS
  size[0] = 2;
  size[1] = 2;
  size[2] = NumberOfSlices;
  spacing[0] = 504.;
  spacing[1] = 504.;
  spacing[2] = 504.;
#else
  size[0] = 64;
  size[1] = 64;
  size[2] = NumberOfSlices;
  spacing[0] = 8.;
  spacing[1] = 8.;
  spacing[2] = 8.;
#endif
  randomVolumeSource->SetOrigin( origin );
  randomVolumeSource->SetSpacing( spacing );
  randomVolumeSource->SetSize( size );
  randomVolumeSource->SetMin( 0. );
  randomVolumeSource->SetMax( 1. );

  constantVolumeSource->SetOrigin( origin );
  constantVolumeSource->SetSpacing( spacing );
  constantVolumeSource->SetSize( size );
  constantVolumeSource->SetConstant( 0. );

  // Update all sources
  TRY_AND_EXIT_ON_ITK_EXCEPTION( randomVolumeSeriesSource->Update() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( constantVolumeSeriesSource->Update() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( randomVolumeSource->Update() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( constantVolumeSource->Update() );

  // Read the phases file
  rtk::PhasesToInterpolationWeights::Pointer phaseReader = rtk::PhasesToInterpolationWeights::New();
  phaseReader->SetFileName(std::string(RTK_DATA_ROOT) +
                           std::string("/Input/Phases/phases_slow.txt"));
  phaseReader->SetNumberOfReconstructedPhases( fourDSize[3] );
  phaseReader->Update();

  std::cout << "\n\n****** 4D to 3D (interpolation) ******" << std::endl;

  typedef rtk::InterpolatorWithKnownWeightsImageFilter<VolumeType, VolumeSeriesType> InterpolateFilterType;
  InterpolateFilterType::Pointer interp = InterpolateFilterType::New();
  interp->SetInputVolume(constantVolumeSource->GetOutput());
  interp->SetInputVolumeSeries(randomVolumeSeriesSource->GetOutput());
  interp->SetWeights(phaseReader->GetOutput());
  TRY_AND_EXIT_ON_ITK_EXCEPTION( interp->Update() );

  std::cout << "\n\n****** 3D to 4D (splat) ******" << std::endl;

  typedef rtk::SplatWithKnownWeightsImageFilter<VolumeSeriesType, VolumeType> SplatFilterType;
  SplatFilterType::Pointer splat = SplatFilterType::New();
  splat->SetInputVolumeSeries(constantVolumeSeriesSource->GetOutput());
  splat->SetInputVolume(randomVolumeSource->GetOutput());
  splat->SetWeights(phaseReader->GetOutput());

// If ITK version < 4.4, try to force the splat filter to use several threads
// Splat filter should display a warning and revert to single threading
#if !(ITK_VERSION_MAJOR > 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR >= 4))
  splat->SetNumberOfThreads(2);
#endif

  TRY_AND_EXIT_ON_ITK_EXCEPTION( splat->Update() );

  CheckScalarProducts<VolumeSeriesType, VolumeType>(randomVolumeSeriesSource->GetOutput(), splat->GetOutput(), randomVolumeSource->GetOutput(), interp->GetOutput());
  std::cout << "\n\nTest PASSED! " << std::endl;

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright 2017 Nest Labs, Inc.
//
// 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.

#ifndef DETECTORGRAPH_INCLUDE_TOPIC_HPP_
#define DETECTORGRAPH_INCLUDE_TOPIC_HPP_

#include "vertex.hpp"
#include "subscriberinterface.hpp"
#include "topicstate.hpp"
#include "dgassert.hpp"

#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
// LITE_BEGIN
#include "detectorgraphliteconfig.hpp"
#include "sequencecontainer-lite.hpp"
// LITE_END
#else
// FULL_BEGIN
#include "sharedptr.hpp"
#include <vector>
#include <typeinfo>
// FULL_END
#endif

// Necessary for Post-C++11 type checking
#if __cplusplus >= 201103L
#include <type_traits>
#endif

namespace DetectorGraph
{

class Graph;

/**
 * @brief Provide interface for a topic
 */
class BaseTopic : public Vertex
{
public:
#if !defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
    virtual std::list< ptr::shared_ptr<const TopicState> > GetCurrentTopicStates() const = 0;
#endif
    virtual TopicStateIdType GetId() const = 0;

    virtual VertexType GetVertexType() const { return Vertex::kTopicVertex; }

protected:
    void MarkChildrenState(VertexSearchState aNewState)
    {
#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
        // LITE_BEGIN
        for (unsigned vIdx = 0; vIdx < GetOutEdges().size(); ++vIdx)
        {
            GetOutEdges()[vIdx]->SetState(aNewState);
        }
        // LITE_END
#else
        // FULL_BEGIN
        for (std::list<Vertex*>::iterator vIt = GetOutEdges().begin();
            vIt != GetOutEdges().end();
            ++vIt)
        {
            (*vIt)->SetState(aNewState);
        }
        // FULL_END
#endif
    }
};
/**
 * @brief Manage data and its handler
 *
 * It is a data transport system with publish / subscribe semantics.
 *
 * # Internals #
 * `std::vector<T> mCurrentValues` is the holder for current values in the topic.
 *
 * This vector is cleared once per evaluation at either:
 * - The first Publish call during an evaluation pass (cleared
 * before adding new value)
 * - Topic is processed, and no further data will be Published to it
 *
 * The intended behavior is to have this vector always contain all the
 * data for a single evaluation pass - or nothing if that's the case.
 */
template<class T>
class Topic : public BaseTopic
{
    // Post-C++11 type checking
#if __cplusplus >= 201103L
    static_assert(std::is_base_of<TopicState, T>::value, "T must inherit from TopicState");
#endif

public:

#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
    typedef SequenceContainer<T, DetectorGraphConfig::kMaxNumberOfTopicStates> ValuesContainer;
#else
    typedef std::vector<T> ValuesContainer;
#endif

    Topic()
    {
        // Pre-C++11 type checking.
#if __cplusplus < 201103L
        (void)static_cast<TopicState*>((T*)0);
#endif
    }

#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
    Topic(Graph* registry);
#endif

    /**
     * @brief Append data to its vector
     */
    void Publish(const T& arPayload)
    {
        if (Vertex::GetState() != kVertexProcessing)
        {
            mCurrentValues.clear();
            Vertex::SetState(kVertexProcessing);
        }

        mCurrentValues.push_back(arPayload);
    }

    virtual void ProcessVertex()
    {
        // TODO(DGRAPH-5): This maintains the old detector graph state style
        // if we want to preserve topic states until they're touched we can
        // remove this clearing here.
        if (Vertex::GetState() == kVertexClear)
        {
            mCurrentValues.clear();
        }

        if (Vertex::GetState() == kVertexProcessing)
        {
            Vertex::SetState(kVertexDone);
            MarkChildrenState(kVertexProcessing);
        }
    }

    /**
     * @brief Pass pending data to its handler
     */
    void DispatchIntoSubscriber(SubscriberInterface<T>* aSubscriber)
    {
        if (Vertex::GetState() == kVertexDone)
        {
            for (unsigned valueIdx = 0; valueIdx < mCurrentValues.size(); ++valueIdx)
            {
                aSubscriber->Evaluate(mCurrentValues[valueIdx]);
            }
        }
    }

    /**
     * @brief Returns true if the new Data is available.
     *
     * New data is signaled by the Topic having been Processed and containing
     * in storage.
     */
    inline bool HasNewValue() const
    {
        return (Vertex::GetState() == DetectorGraph::Vertex::kVertexDone);
    }

    /**
     * @brief Returns reference to the new/latest value in the topic.
     *
     * This method is a direct forwarding of the internal STL container and as
     * such, calling GetNewValue on an empty Topic is undefined.
     *
     * On debug builds, a DG_ASSERT will check that the Topic contains a value.
     */
    inline const T& GetNewValue() const
    {
        DG_ASSERT(HasNewValue());
        return mCurrentValues.back();
    }

    const ValuesContainer& GetCurrentValues() const
    {
        return mCurrentValues;
    }

    virtual TopicStateIdType GetId() const
    {
        return TopicState::GetId<T>();
    }

    virtual ~Topic()
    {}

#if !defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
// FULL_BEGIN
    virtual std::list<ptr::shared_ptr<const TopicState> > GetCurrentTopicStates() const
    {
        std::list<ptr::shared_ptr<const TopicState> > tCurrentTopicStates;

        for (typename std::vector<T>::const_iterator valueIt = mCurrentValues.begin();
                valueIt != mCurrentValues.end();
                ++valueIt)
        {
            tCurrentTopicStates.push_back(ptr::shared_ptr<TopicState>(new T(*valueIt)));
        }

        return tCurrentTopicStates;
    }
// FULL_END
#endif

private:
    /*
     * @brief List of current data in topic. @sa Topic.
     */
    ValuesContainer mCurrentValues;
};

} // namespace DetectorGraph

#endif // DETECTORGRAPH_INCLUDE_TOPIC_HPP_
<commit_msg>Made Topic.hpp use iterators to make it version agnostic<commit_after>// Copyright 2017 Nest Labs, Inc.
//
// 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.

#ifndef DETECTORGRAPH_INCLUDE_TOPIC_HPP_
#define DETECTORGRAPH_INCLUDE_TOPIC_HPP_

#include "vertex.hpp"
#include "subscriberinterface.hpp"
#include "topicstate.hpp"
#include "dgassert.hpp"

#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
// LITE_BEGIN
#include "detectorgraphliteconfig.hpp"
#include "sequencecontainer-lite.hpp"
// LITE_END
#else
// FULL_BEGIN
#include "sharedptr.hpp"
#include <vector>
#include <typeinfo>
// FULL_END
#endif

// Necessary for Post-C++11 type checking
#if __cplusplus >= 201103L
#include <type_traits>
#endif

namespace DetectorGraph
{

class Graph;

/**
 * @brief Provide interface for a topic
 */
class BaseTopic : public Vertex
{
public:
#if !defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
    virtual std::list< ptr::shared_ptr<const TopicState> > GetCurrentTopicStates() const = 0;
#endif
    virtual TopicStateIdType GetId() const = 0;

    virtual VertexType GetVertexType() const { return Vertex::kTopicVertex; }

protected:
    void MarkChildrenState(VertexSearchState aNewState)
    {
        for (VertexPtrContainer::iterator vIt = GetOutEdges().begin();
            vIt != GetOutEdges().end();
            ++vIt)
        {
            (*vIt)->SetState(aNewState);
        }
    }
};
/**
 * @brief Manage data and its handler
 *
 * It is a data transport system with publish / subscribe semantics.
 *
 * # Internals #
 * `std::vector<T> mCurrentValues` is the holder for current values in the topic.
 *
 * This vector is cleared once per evaluation at either:
 * - The first Publish call during an evaluation pass (cleared
 * before adding new value)
 * - Topic is processed, and no further data will be Published to it
 *
 * The intended behavior is to have this vector always contain all the
 * data for a single evaluation pass - or nothing if that's the case.
 */
template<class T>
class Topic : public BaseTopic
{
    // Post-C++11 type checking
#if __cplusplus >= 201103L
    static_assert(std::is_base_of<TopicState, T>::value, "T must inherit from TopicState");
#endif

public:

#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
    typedef SequenceContainer<T, DetectorGraphConfig::kMaxNumberOfTopicStates> ValuesContainer;
#else
    typedef std::vector<T> ValuesContainer;
#endif

    Topic()
    {
        // Pre-C++11 type checking.
#if __cplusplus < 201103L
        (void)static_cast<TopicState*>((T*)0);
#endif
    }

#if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
    Topic(Graph* registry);
#endif

    /**
     * @brief Append data to its vector
     */
    void Publish(const T& arPayload)
    {
        if (Vertex::GetState() != kVertexProcessing)
        {
            mCurrentValues.clear();
            Vertex::SetState(kVertexProcessing);
        }

        mCurrentValues.push_back(arPayload);
    }

    virtual void ProcessVertex()
    {
        // TODO(DGRAPH-5): This maintains the old detector graph state style
        // if we want to preserve topic states until they're touched we can
        // remove this clearing here.
        if (Vertex::GetState() == kVertexClear)
        {
            mCurrentValues.clear();
        }

        if (Vertex::GetState() == kVertexProcessing)
        {
            Vertex::SetState(kVertexDone);
            MarkChildrenState(kVertexProcessing);
        }
    }

    /**
     * @brief Pass pending data to its handler
     */
    void DispatchIntoSubscriber(SubscriberInterface<T>* aSubscriber)
    {
        if (Vertex::GetState() == kVertexDone)
        {
            for (unsigned valueIdx = 0; valueIdx < mCurrentValues.size(); ++valueIdx)
            {
                aSubscriber->Evaluate(mCurrentValues[valueIdx]);
            }
        }
    }

    /**
     * @brief Returns true if the new Data is available.
     *
     * New data is signaled by the Topic having been Processed and containing
     * in storage.
     */
    inline bool HasNewValue() const
    {
        return (Vertex::GetState() == DetectorGraph::Vertex::kVertexDone);
    }

    /**
     * @brief Returns reference to the new/latest value in the topic.
     *
     * This method is a direct forwarding of the internal STL container and as
     * such, calling GetNewValue on an empty Topic is undefined.
     *
     * On debug builds, a DG_ASSERT will check that the Topic contains a value.
     */
    inline const T& GetNewValue() const
    {
        DG_ASSERT(HasNewValue());
        return mCurrentValues.back();
    }

    const ValuesContainer& GetCurrentValues() const
    {
        return mCurrentValues;
    }

    virtual TopicStateIdType GetId() const
    {
        return TopicState::GetId<T>();
    }

    virtual ~Topic()
    {}

#if !defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
// FULL_BEGIN
    virtual std::list<ptr::shared_ptr<const TopicState> > GetCurrentTopicStates() const
    {
        std::list<ptr::shared_ptr<const TopicState> > tCurrentTopicStates;

        for (typename std::vector<T>::const_iterator valueIt = mCurrentValues.begin();
                valueIt != mCurrentValues.end();
                ++valueIt)
        {
            tCurrentTopicStates.push_back(ptr::shared_ptr<TopicState>(new T(*valueIt)));
        }

        return tCurrentTopicStates;
    }
// FULL_END
#endif

private:
    /*
     * @brief List of current data in topic. @sa Topic.
     */
    ValuesContainer mCurrentValues;
};

} // namespace DetectorGraph

#endif // DETECTORGRAPH_INCLUDE_TOPIC_HPP_
<|endoftext|>