<commit_before>/* Copyright (C) 2005-2007, Thorvald Natvig <thorvald@natvig.com>

   All rights reserved.

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

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

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

#include <QtXml>

#include "Server.h"

void Server::initRegister() {
	http = NULL;
	qssReg = NULL;

	connect(&qtTick, SIGNAL(timeout()), this, SLOT(update()));

	if (! qsRegName.isEmpty()) {
		if ((! qsRegName.isEmpty()) && (! qsRegPassword.isEmpty()) && (qurlRegWeb.isValid()) && (qsPassword.isEmpty()))
			qtTick.start(60 * 10);
		else
			log("Registration needs nonempty name, password and url, and the server must not be password protected.");
	} else {
		log("Not registering server as public");
	}
}

void Server::abort() {
	if (http) {
		http->setSocket(NULL);
		http->deleteLater();
		http = NULL;
	}
	if (qssReg) {
		qssReg->deleteLater();
		qssReg = NULL;
	}
}

void Server::update() {
	abort();
	qtTick.start(10 * 60 * 60);

	QDomDocument doc;
	QDomElement root=doc.createElement(QLatin1String("server"));
	doc.appendChild(root);

	QDomElement tag;
	QDomText t;

	tag=doc.createElement(QLatin1String("name"));
	root.appendChild(tag);

	t=doc.createTextNode(qsRegName);
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("host"));
	root.appendChild(tag);

	t=doc.createTextNode(qsRegHost);
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("password"));
	root.appendChild(tag);

	t=doc.createTextNode(qsRegPassword);
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("port"));
	root.appendChild(tag);

	t=doc.createTextNode(QString::number(iPort));
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("url"));
	root.appendChild(tag);

	t=doc.createTextNode(qurlRegWeb.toString());
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("digest"));
	root.appendChild(tag);

	t=doc.createTextNode(getDigest());
	tag.appendChild(t);

	qssReg = new QSslSocket(this);
	qssReg->setLocalCertificate(qscCert);
	qssReg->setPrivateKey(qskKey);

	http = new QHttp(QLatin1String("mumble.hive.no"), QHttp::ConnectionModeHttps, 443, this);
	http->setSocket(qssReg);

	connect(http, SIGNAL(done(bool)), this, SLOT(done(bool)));
	connect(http, SIGNAL(sslErrors ( const QList<QSslError> &)), this, SLOT(regSslError(const QList<QSslError> &)));

	QHttpRequestHeader h(QLatin1String("POST"), QLatin1String("/register.cgi"));
	h.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive"));
	h.setValue(QLatin1String("Host"), QLatin1String("mumble.hive.no"));
	h.setContentType(QLatin1String("text/xml"));
	http->request(h, doc.toString().toUtf8());
}

void Server::done(bool err) {
	if (! http || ! qssReg)
		return;
	if (err) {
		log("Regstration failed: %s", qPrintable(http->errorString()));
	} else {
		QByteArray qba = http->readAll();
		log("Registration: %s", qPrintable(QString(QLatin1String(qba))));
	}
	abort();
}

void Server::regSslError(const QList<QSslError> &errs) {
	foreach(const QSslError &e, errs)
		log("Registration: SSL Handshake error: %s", qPrintable(e.errorString()));
}
<commit_msg>Revert to seconds instead of centiseconds for registration delays<commit_after>/* Copyright (C) 2005-2007, Thorvald Natvig <thorvald@natvig.com>

   All rights reserved.

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

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

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

#include <QtXml>

#include "Server.h"

void Server::initRegister() {
	http = NULL;
	qssReg = NULL;

	connect(&qtTick, SIGNAL(timeout()), this, SLOT(update()));

	if (! qsRegName.isEmpty()) {
		if ((! qsRegName.isEmpty()) && (! qsRegPassword.isEmpty()) && (qurlRegWeb.isValid()) && (qsPassword.isEmpty()))
			qtTick.start(60 * 1000);
		else
			log("Registration needs nonempty name, password and url, and the server must not be password protected.");
	} else {
		log("Not registering server as public");
	}
}

void Server::abort() {
	if (http) {
		http->setSocket(NULL);
		http->deleteLater();
		http = NULL;
	}
	if (qssReg) {
		qssReg->deleteLater();
		qssReg = NULL;
	}
}

void Server::update() {
	abort();
	qtTick.start(1000 * 60 * 60);

	QDomDocument doc;
	QDomElement root=doc.createElement(QLatin1String("server"));
	doc.appendChild(root);

	QDomElement tag;
	QDomText t;

	tag=doc.createElement(QLatin1String("name"));
	root.appendChild(tag);

	t=doc.createTextNode(qsRegName);
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("host"));
	root.appendChild(tag);

	t=doc.createTextNode(qsRegHost);
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("password"));
	root.appendChild(tag);

	t=doc.createTextNode(qsRegPassword);
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("port"));
	root.appendChild(tag);

	t=doc.createTextNode(QString::number(iPort));
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("url"));
	root.appendChild(tag);

	t=doc.createTextNode(qurlRegWeb.toString());
	tag.appendChild(t);

	tag=doc.createElement(QLatin1String("digest"));
	root.appendChild(tag);

	t=doc.createTextNode(getDigest());
	tag.appendChild(t);

	qssReg = new QSslSocket(this);
	qssReg->setLocalCertificate(qscCert);
	qssReg->setPrivateKey(qskKey);

	http = new QHttp(QLatin1String("mumble.hive.no"), QHttp::ConnectionModeHttps, 443, this);
	http->setSocket(qssReg);

	connect(http, SIGNAL(done(bool)), this, SLOT(done(bool)));
	connect(http, SIGNAL(sslErrors ( const QList<QSslError> &)), this, SLOT(regSslError(const QList<QSslError> &)));

	QHttpRequestHeader h(QLatin1String("POST"), QLatin1String("/register.cgi"));
	h.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive"));
	h.setValue(QLatin1String("Host"), QLatin1String("mumble.hive.no"));
	h.setContentType(QLatin1String("text/xml"));
	http->request(h, doc.toString().toUtf8());
}

void Server::done(bool err) {
	if (! http || ! qssReg)
		return;
	if (err) {
		log("Regstration failed: %s", qPrintable(http->errorString()));
	} else {
		QByteArray qba = http->readAll();
		log("Registration: %s", qPrintable(QString(QLatin1String(qba))));
	}
	abort();
}

void Server::regSslError(const QList<QSslError> &errs) {
	foreach(const QSslError &e, errs)
		log("Registration: SSL Handshake error: %s", qPrintable(e.errorString()));
}
<|endoftext|>


<commit_before>#include <ModuleFramework/Module.h>
#include "ModuleFramework/ModuleManager.h"
#include "Tools/StrategyTools.h"
#include <gtest/gtest.h>

using namespace std;

class StrategyToolsTest : public ::testing::Test
{
public:
	StrategyTools* strategyTools;

protected:
  StrategyToolsTest(){}
  virtual void SetUp()
  {
  }

};

TEST_F(StrategyToolsTest, arrangeRobots)
{
  std::vector<Vector2d> setPiecePoints;
  //input of positions
  setPiecePoints.push_back(Vector2d(-1700.0, -1700.0));
  setPiecePoints.push_back(Vector2d(-2400.0,     0.0));
  setPiecePoints.push_back(Vector2d(-1700.0,  1700.0));

  std::vector<int> placesToRobots(3);

  // init
  for(unsigned int i = 0; i < placesToRobots.size(); i++)
  {
    placesToRobots[i] = i;
  }//end for

  std::vector<Vector2d > playersPoints;
  playersPoints.push_back(Vector2d(2400.0,      0.0));
  playersPoints.push_back(Vector2d(3400.0,    500.0));
  playersPoints.push_back(Vector2d(2800.0,   -700.0));
  playersPoints.push_back(Vector2d(-2500.0,     0.0));
  playersPoints.push_back(Vector2d(-1600.0,  1600.0));
  playersPoints.push_back(Vector2d(-1600.0, -1700.0));

  strategyTools->arrangeRobots(playersPoints, setPiecePoints, placesToRobots);

  std::vector<int> expectedPlacesToRobots;
  expectedPlacesToRobots.push_back(0);
  expectedPlacesToRobots.push_back(1);
  expectedPlacesToRobots.push_back(2);

  for(unsigned int i = 0; i < placesToRobots.size(); i++)
  {
    if(placesToRobots[i] != expectedPlacesToRobots[1])
    {
      cout << "Assignement Wrong" << endl;
    }
  }//end for
}//end testArrangeRobots<commit_msg>repaired Test<commit_after>#include <ModuleFramework/Module.h>
#include "ModuleFramework/ModuleManager.h"
#include "Tools/StrategyTools.h"
#include <gtest/gtest.h>

using namespace std;

class StrategyToolsTest : public ::testing::Test
{
public:
	StrategyTools* strategyTools;

protected:
  StrategyToolsTest(){}
  virtual void SetUp()
  {
  }

};

TEST_F(StrategyToolsTest, arrangeRobots)
{
  std::vector<Vector2d> setPiecePoints;
  //input of positions
  setPiecePoints.push_back(Vector2d(-1700.0, -1700.0));
  setPiecePoints.push_back(Vector2d(-2400.0,     0.0));
  setPiecePoints.push_back(Vector2d(-1700.0,  1700.0));

  std::vector<int> placesToRobots(3);

  // init
  for(unsigned int i = 0; i < placesToRobots.size(); i++)
  {
    placesToRobots[i] = i;
  }//end for

  std::vector<Vector2d > playersPoints;
  playersPoints.push_back(Vector2d(2400.0,      0.0));
  playersPoints.push_back(Vector2d(3400.0,    500.0));
  playersPoints.push_back(Vector2d(2800.0,   -700.0));
  playersPoints.push_back(Vector2d(-2500.0,     0.0));
  playersPoints.push_back(Vector2d(-1600.0,  1600.0));
  playersPoints.push_back(Vector2d(-1600.0, -1700.0));

  strategyTools->arrangeRobots(playersPoints, setPiecePoints, placesToRobots);

  std::vector<int> expectedPlacesToRobots;
  expectedPlacesToRobots.push_back(5);
  expectedPlacesToRobots.push_back(3);
  expectedPlacesToRobots.push_back(4);

  ASSERT_EQ(expectedPlacesToRobots[0], placesToRobots[0]);
  ASSERT_EQ(expectedPlacesToRobots[1], placesToRobots[1]);
  ASSERT_EQ(expectedPlacesToRobots[2], placesToRobots[2]);
}//end testArrangeRobots<|endoftext|>


<commit_before>#include "aquila/global.h"
#include "aquila/filter/MelFilter.h"
#include "aquila/filter/MelFilterBank.h"
#include <unittestpp.h>
#include <cstddef>
#include <vector>

template <std::size_t N>
void testMelFilterBankOutput()
{
    Aquila::FrequencyType sampleFrequency = 44100.0;
    Aquila::MelFilterBank filters(sampleFrequency, N);

    for (std::size_t k = 0; k < filters.size(); ++k)
    {
        // create a single spectral peak at middle frequency of k-th Mel filter
        Aquila::SpectrumType spectrum(N);
        Aquila::FrequencyType melFrequency = 100.0 + k * 100.0;
        Aquila::FrequencyType linearFrequency = Aquila::MelFilter::melToLinear(melFrequency);
        std::size_t peakNumber = N  * (linearFrequency / sampleFrequency);
        spectrum[peakNumber] = 5000.0;

        auto output = filters.applyAll(spectrum);

        std::vector<double> expected(filters.size(), 0.0);
        expected[k] = 5000.0;
        CHECK_ARRAY_CLOSE(expected, output, filters.size(), 0.000001);
    }
}

SUITE(MelFilter)
{
    TEST(SampleFrequency)
    {
        Aquila::MelFilterBank filters(22050, 2048);
        CHECK_EQUAL(22050, filters.getSampleFrequency());
    }

    TEST(SpectrumLength)
    {
        Aquila::MelFilterBank filters(22050, 2048);
        CHECK_EQUAL(2048u, filters.getSpectrumLength());
    }

    TEST(FilterOutput1024)
    {
        testMelFilterBankOutput<1024>();
    }

    TEST(FilterOutput2048)
    {
        testMelFilterBankOutput<2048>();
    }

    TEST(FilterOutput4096)
    {
        testMelFilterBankOutput<4096>();
    }
}
<commit_msg>Updated tests for MelFilterBank.<commit_after>#include "aquila/global.h"
#include "aquila/filter/MelFilter.h"
#include "aquila/filter/MelFilterBank.h"
#include <unittestpp.h>
#include <cstddef>
#include <vector>

template <std::size_t N>
void testMelFilterBankOutput()
{
    Aquila::FrequencyType sampleFrequency = 44100.0;
    Aquila::MelFilterBank filters(sampleFrequency, N);

    for (std::size_t k = 0; k < filters.size(); ++k)
    {
        // create a single spectral peak at middle frequency of k-th Mel filter
        Aquila::SpectrumType spectrum(N);
        Aquila::FrequencyType melFrequency = 100.0 + k * 100.0;
        Aquila::FrequencyType linearFrequency = Aquila::MelFilter::melToLinear(melFrequency);
        std::size_t peakNumber = N  * (linearFrequency / sampleFrequency);
        spectrum[peakNumber] = 5000.0;

        auto output = filters.applyAll(spectrum);
        CHECK(output[k] > 0);
    }
}

SUITE(MelFilter)
{
    TEST(SampleFrequency)
    {
        Aquila::MelFilterBank filters(22050, 2048);
        CHECK_EQUAL(22050, filters.getSampleFrequency());
    }

    TEST(SpectrumLength)
    {
        Aquila::MelFilterBank filters(22050, 2048);
        CHECK_EQUAL(2048u, filters.getSpectrumLength());
    }

    TEST(FilterOutput1024)
    {
        testMelFilterBankOutput<1024>();
    }

    TEST(FilterOutput2048)
    {
        testMelFilterBankOutput<2048>();
    }

    TEST(FilterOutput4096)
    {
        testMelFilterBankOutput<4096>();
    }
}
<|endoftext|>


<commit_before>// This test case fails unless an implementation of TLS backend is installed.
// (Exception caught: TLS support is not available.)
// Module glib-networking implements TLS backend.
//
// Even if glib-networking is installed, it's possible that glib does not find it.
// That's very probable if glib and glib-networking are installed with different
// directory prefixes, e.g. glib in /opt/gnome and glib-networking in /usr.
// You can fix that by setting the GIO_EXTRA_MODULES environment variable to
// the directory to search for implementations of gio extension points.
// Example:
//   export GIO_EXTRA_MODULES=/usr/lib/x86_64-linux-gnu/gio/modules
// If you don't know where the implementations of gio extension points are stored,
// search for a file named giomodule.cache.
//
// https://developer.gnome.org/gio/stable/extending-gio.html (G_TLS_BACKEND_EXTENSION_POINT_NAME)
// https://developer.gnome.org/gio/stable/gio-Extension-Points.html
// https://developer.gnome.org/gio/stable/gio-querymodules.html

#include <giomm.h>
#include <iostream>
#include <cstdlib>

bool on_accept_certificate(const Glib::RefPtr<const Gio::TlsCertificate>& cert, Gio::TlsCertificateFlags)
{
  std::cout << "Handshake is ocurring." << std::endl
    << "The server is requesting that its certificate be accepted." <<
    std::endl;

  std::cout << "Outputing certificate data:" << std::endl <<
    cert->property_certificate_pem().get_value();

  auto issuer = cert->get_issuer();

  std::cout << "Outputing the issuer's certificate data:" << std::endl <<
    issuer->property_certificate_pem().get_value();

  std::cout << "Accepting the certificate (completing the handshake)." <<
    std::endl;

  return true;
}

int main(int, char**)
{
  Gio::init();

  const Glib::ustring test_host = "www.google.com";

  std::vector< Glib::RefPtr<Gio::InetAddress> > inet_addresses;

  try
  {
    inet_addresses =
      Gio::Resolver::get_default()->lookup_by_name(test_host);
  }
  catch(const Gio::ResolverError& ex)
  {
    //This happens if it could not resolve the name,
    //for instance if we are not connected to the internet.
    //TODO: Change this test so it can do something useful and succeed even
    //if the testing computer is not connected to the internet.
    std::cerr << "Gio::Resolver::lookup_by_name() threw exception: " << ex.what() << std::endl;
    return EXIT_FAILURE;
  }

  //Actually, it would throw an exception instead of reaching here with 0 addresses resolved.
  if(inet_addresses.size() == 0)
  {
    std::cerr << "Could not resolve test host '" << test_host << "'." <<
      std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "Successfully resolved address of test host '" << test_host <<
    "'." << std::endl;

  auto first_inet_address = inet_addresses[0];

  std::cout << "First address of test host is " <<
    first_inet_address->to_string() << "." << std::endl;

  auto socket =
    Gio::Socket::create(first_inet_address->get_family(),
    Gio::SOCKET_TYPE_STREAM, Gio::SOCKET_PROTOCOL_TCP);

  auto address =
    Gio::InetSocketAddress::create(first_inet_address, 443);

  try
  {
    socket->connect(address);
  }
  catch(const Gio::Error& ex)
  {
    std::cout << "Could not connect socket to " <<
      address->get_address()->to_string() << ":" << address->get_port() <<
      ". Exception: " << ex.what() << std::endl;
    return EXIT_FAILURE;
  }

  if(!socket->is_connected())
  {
    std::cout << "Could not connect socket to " <<
      address->get_address()->to_string() << ":" << address->get_port() <<
      "." << std::endl;
  }

  auto conn = Glib::RefPtr<Gio::TcpConnection>::cast_dynamic(Gio::SocketConnection::create(socket));

  if(!conn || !conn->is_connected())
  {
    std::cout << "Could not establish connection to " <<
      address->get_address()->to_string() << ":" << address->get_port() <<
      "." << std::endl;
    socket->close();
    return EXIT_FAILURE;
  }

  std::cout << "Successfully established connection to " <<
    address->get_address()->to_string() << ":" << address->get_port() <<
    "." << std::endl;

  try
  {
    auto tls_connection =
      Gio::TlsClientConnection::create(conn, address);

    tls_connection->signal_accept_certificate().connect(
      sigc::ptr_fun(&on_accept_certificate));

    tls_connection->handshake();

    std::cout << "Attempting to get the issuer's certificate from the "
      "connection." << std::endl;

    auto issuer_certificate =
      tls_connection->get_peer_certificate()->get_issuer();

    if(!issuer_certificate)
    {
      std::cout << "Could not get the issuer's certificate of the peer." <<
        std::endl;
      return EXIT_FAILURE;
    }
    std::cout << "Successfully retrieved the issuer's certificate." <<
      std::endl;

    std::cout << "Attempting to use the connection's database." << std::endl;
    auto database = tls_connection->get_database();

    std::cout << "Looking up the certificate's issuer in the database." <<
      std::endl;

    auto db_certificate =
      database->lookup_certificate_issuer(issuer_certificate);

    if(!db_certificate)
    {
      std::cout << "The issuer's certificate was not found in the database." << std::endl;
    }
    else
    {
      std::cout << "Successfully found the issuer's certificate in the database." << std::endl;
    }
  }
  catch (const Gio::TlsError& error)
  {
    std::cout << "Exception caught: " << error.what() << "." << std::endl;
    return EXIT_FAILURE;
  }

  conn->close();

  return EXIT_SUCCESS;
}
<commit_msg>tls_client test: Use gnome.org instead of google.org<commit_after>// This test case fails unless an implementation of TLS backend is installed.
// (Exception caught: TLS support is not available.)
// Module glib-networking implements TLS backend.
//
// Even if glib-networking is installed, it's possible that glib does not find it.
// That's very probable if glib and glib-networking are installed with different
// directory prefixes, e.g. glib in /opt/gnome and glib-networking in /usr.
// You can fix that by setting the GIO_EXTRA_MODULES environment variable to
// the directory to search for implementations of gio extension points.
// Example:
//   export GIO_EXTRA_MODULES=/usr/lib/x86_64-linux-gnu/gio/modules
// If you don't know where the implementations of gio extension points are stored,
// search for a file named giomodule.cache.
//
// https://developer.gnome.org/gio/stable/extending-gio.html (G_TLS_BACKEND_EXTENSION_POINT_NAME)
// https://developer.gnome.org/gio/stable/gio-Extension-Points.html
// https://developer.gnome.org/gio/stable/gio-querymodules.html

#include <giomm.h>
#include <iostream>
#include <cstdlib>

bool on_accept_certificate(const Glib::RefPtr<const Gio::TlsCertificate>& cert, Gio::TlsCertificateFlags)
{
  std::cout << "Handshake is ocurring." << std::endl
    << "The server is requesting that its certificate be accepted." <<
    std::endl;

  std::cout << "Outputing certificate data:" << std::endl <<
    cert->property_certificate_pem().get_value();

  auto issuer = cert->get_issuer();

  std::cout << "Outputing the issuer's certificate data:" << std::endl <<
    issuer->property_certificate_pem().get_value();

  std::cout << "Accepting the certificate (completing the handshake)." <<
    std::endl;

  return true;
}

int main(int, char**)
{
  Gio::init();

  const Glib::ustring test_host = "www.gnome.org";

  std::vector< Glib::RefPtr<Gio::InetAddress> > inet_addresses;

  try
  {
    inet_addresses =
      Gio::Resolver::get_default()->lookup_by_name(test_host);
  }
  catch(const Gio::ResolverError& ex)
  {
    //This happens if it could not resolve the name,
    //for instance if we are not connected to the internet.
    //TODO: Change this test so it can do something useful and succeed even
    //if the testing computer is not connected to the internet.
    std::cerr << "Gio::Resolver::lookup_by_name() threw exception: " << ex.what() << std::endl;
    return EXIT_FAILURE;
  }

  //Actually, it would throw an exception instead of reaching here with 0 addresses resolved.
  if(inet_addresses.size() == 0)
  {
    std::cerr << "Could not resolve test host '" << test_host << "'." <<
      std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "Successfully resolved address of test host '" << test_host <<
    "'." << std::endl;

  auto first_inet_address = inet_addresses[0];

  std::cout << "First address of test host is " <<
    first_inet_address->to_string() << "." << std::endl;

  auto socket =
    Gio::Socket::create(first_inet_address->get_family(),
    Gio::SOCKET_TYPE_STREAM, Gio::SOCKET_PROTOCOL_TCP);

  auto address =
    Gio::InetSocketAddress::create(first_inet_address, 443);

  try
  {
    socket->connect(address);
  }
  catch(const Gio::Error& ex)
  {
    std::cout << "Could not connect socket to " <<
      address->get_address()->to_string() << ":" << address->get_port() <<
      ". Exception: " << ex.what() << std::endl;
    return EXIT_FAILURE;
  }

  if(!socket->is_connected())
  {
    std::cout << "Could not connect socket to " <<
      address->get_address()->to_string() << ":" << address->get_port() <<
      "." << std::endl;
  }

  auto conn = Glib::RefPtr<Gio::TcpConnection>::cast_dynamic(Gio::SocketConnection::create(socket));

  if(!conn || !conn->is_connected())
  {
    std::cout << "Could not establish connection to " <<
      address->get_address()->to_string() << ":" << address->get_port() <<
      "." << std::endl;
    socket->close();
    return EXIT_FAILURE;
  }

  std::cout << "Successfully established connection to " <<
    address->get_address()->to_string() << ":" << address->get_port() <<
    "." << std::endl;

  try
  {
    auto tls_connection =
      Gio::TlsClientConnection::create(conn, address);

    tls_connection->signal_accept_certificate().connect(
      sigc::ptr_fun(&on_accept_certificate));

    tls_connection->handshake();

    std::cout << "Attempting to get the issuer's certificate from the "
      "connection." << std::endl;

    auto issuer_certificate =
      tls_connection->get_peer_certificate()->get_issuer();

    if(!issuer_certificate)
    {
      std::cout << "Could not get the issuer's certificate of the peer." <<
        std::endl;
      return EXIT_FAILURE;
    }
    std::cout << "Successfully retrieved the issuer's certificate." <<
      std::endl;

    std::cout << "Attempting to use the connection's database." << std::endl;
    auto database = tls_connection->get_database();

    std::cout << "Looking up the certificate's issuer in the database." <<
      std::endl;

    auto db_certificate =
      database->lookup_certificate_issuer(issuer_certificate);

    if(!db_certificate)
    {
      std::cout << "The issuer's certificate was not found in the database." << std::endl;
    }
    else
    {
      std::cout << "Successfully found the issuer's certificate in the database." << std::endl;
    }
  }
  catch (const Gio::TlsError& error)
  {
    std::cout << "Exception caught: " << error.what() << "." << std::endl;
    return EXIT_FAILURE;
  }

  conn->close();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: filprp.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: kso $ $Date: 2000-10-16 14:53:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SHELL_HXX_
#include "shell.hxx"
#endif
#ifndef _PROV_HXX_
#include "prov.hxx"
#endif
#ifndef _FILPRP_HXX_
#include "filprp.hxx"
#endif

using namespace fileaccess;
using namespace com::sun::star;
using namespace com::sun::star::ucb;

#ifndef _FILINL_HXX_
#include "filinl.hxx"
#endif

XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const rtl::OUString& aUnqPath )
    : m_pMyShell( pMyShell ),
      m_xProvider( pMyShell->m_pProvider ),
      m_count( 0 ),
      m_seq( 0 )
{
    shell::ContentMap::iterator it = m_pMyShell->m_aContent.find( aUnqPath );

    shell::PropertySet& properties = *(it->second.properties);
    shell::PropertySet::iterator it1 = properties.begin();

    m_seq.realloc( properties.size() );

    while( it1 != properties.end() )
    {
        m_seq[ m_count++ ] = beans::Property( it1->getPropertyName(),
                                              it1->getHandle(),
                                              it1->getType(),
                                              it1->getAttributes() );
        ++it1;
    }
}

XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const uno::Sequence< beans::Property >& seq )
    : m_pMyShell( pMyShell ),
      m_count( seq.getLength() ),
      m_seq( seq )
{
}

XPropertySetInfo_impl::~XPropertySetInfo_impl()
{
    m_pMyShell->m_pProvider->release();
}

void SAL_CALL
XPropertySetInfo_impl::acquire(
                  void )
  throw( uno::RuntimeException )
{
  OWeakObject::acquire();
}

void SAL_CALL
XPropertySetInfo_impl::release(
              void )
  throw( uno::RuntimeException )
{
  OWeakObject::release();
}

uno::Any SAL_CALL
XPropertySetInfo_impl::queryInterface(
                     const uno::Type& rType )
  throw( uno::RuntimeException )
{
  uno::Any aRet = cppu::queryInterface( rType,
                    SAL_STATIC_CAST( beans::XPropertySetInfo*,this) );
  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}

beans::Property SAL_CALL
XPropertySetInfo_impl::getPropertyByName(
                     const rtl::OUString& aName )
  throw( beans::UnknownPropertyException,
     uno::RuntimeException)
{
  for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
    if( m_seq[i].Name == aName ) return m_seq[i];

  throw beans::UnknownPropertyException();
}

uno::Sequence< beans::Property > SAL_CALL
XPropertySetInfo_impl::getProperties(
                    void )
  throw( uno::RuntimeException )
{
  return m_seq;
}

sal_Bool SAL_CALL
XPropertySetInfo_impl::hasPropertyByName(
                     const rtl::OUString& aName )
  throw( uno::RuntimeException )
{
  for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
    if( m_seq[i].Name == aName ) return true;
  return false;
}
<commit_msg>Added missing acquire() of shell to XPropertySetInfo_impl ctors.<commit_after>/*************************************************************************
 *
 *  $RCSfile: filprp.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: sb $ $Date: 2000-10-24 13:15:23 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SHELL_HXX_
#include "shell.hxx"
#endif
#ifndef _PROV_HXX_
#include "prov.hxx"
#endif
#ifndef _FILPRP_HXX_
#include "filprp.hxx"
#endif

using namespace fileaccess;
using namespace com::sun::star;
using namespace com::sun::star::ucb;

#ifndef _FILINL_HXX_
#include "filinl.hxx"
#endif

XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const rtl::OUString& aUnqPath )
    : m_pMyShell( pMyShell ),
      m_xProvider( pMyShell->m_pProvider ),
      m_count( 0 ),
      m_seq( 0 )
{
    m_pMyShell->m_pProvider->acquire();

    shell::ContentMap::iterator it = m_pMyShell->m_aContent.find( aUnqPath );

    shell::PropertySet& properties = *(it->second.properties);
    shell::PropertySet::iterator it1 = properties.begin();

    m_seq.realloc( properties.size() );

    while( it1 != properties.end() )
    {
        m_seq[ m_count++ ] = beans::Property( it1->getPropertyName(),
                                              it1->getHandle(),
                                              it1->getType(),
                                              it1->getAttributes() );
        ++it1;
    }
}

XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const uno::Sequence< beans::Property >& seq )
    : m_pMyShell( pMyShell ),
      m_count( seq.getLength() ),
      m_seq( seq )
{
    m_pMyShell->m_pProvider->acquire();
}

XPropertySetInfo_impl::~XPropertySetInfo_impl()
{
    m_pMyShell->m_pProvider->release();
}

void SAL_CALL
XPropertySetInfo_impl::acquire(
                  void )
  throw( uno::RuntimeException )
{
  OWeakObject::acquire();
}

void SAL_CALL
XPropertySetInfo_impl::release(
              void )
  throw( uno::RuntimeException )
{
  OWeakObject::release();
}

uno::Any SAL_CALL
XPropertySetInfo_impl::queryInterface(
                     const uno::Type& rType )
  throw( uno::RuntimeException )
{
  uno::Any aRet = cppu::queryInterface( rType,
                    SAL_STATIC_CAST( beans::XPropertySetInfo*,this) );
  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}

beans::Property SAL_CALL
XPropertySetInfo_impl::getPropertyByName(
                     const rtl::OUString& aName )
  throw( beans::UnknownPropertyException,
     uno::RuntimeException)
{
  for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
    if( m_seq[i].Name == aName ) return m_seq[i];

  throw beans::UnknownPropertyException();
}

uno::Sequence< beans::Property > SAL_CALL
XPropertySetInfo_impl::getProperties(
                    void )
  throw( uno::RuntimeException )
{
  return m_seq;
}

sal_Bool SAL_CALL
XPropertySetInfo_impl::hasPropertyByName(
                     const rtl::OUString& aName )
  throw( uno::RuntimeException )
{
  for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
    if( m_seq[i].Name == aName ) return true;
  return false;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "AdnsHandler.h"

/* system implementation headers */
#include <errno.h>

/* common implementation headers */
#include "network.h"

#ifdef HAVE_ADNS_H

adns_state AdnsHandler::adnsState;

AdnsHandler::AdnsHandler(int _index, struct sockaddr *clientAddr)
  : index(_index), hostname(NULL), adnsQuery(NULL), status(None) {
  // launch the asynchronous query to look up this hostname
  if (adns_submit_reverse
      (adnsState, clientAddr, adns_r_ptr,
       (adns_queryflags)(adns_qf_quoteok_cname|adns_qf_cname_loose), 0,
       &adnsQuery) != 0) {
    DEBUG1("Player [%d] failed to submit reverse resolve query: errno %d\n",
	   index, getErrno());
    adnsQuery = NULL;
    status = Failed;
  } else {
    DEBUG2("Player [%d] submitted reverse resolve query\n", index);
    status = Pending;
  }
}

AdnsHandler::~AdnsHandler() {
  if (adnsQuery) {
    adns_cancel(adnsQuery);
    adnsQuery = NULL;
  }
  if (hostname) {
    free(hostname);
    hostname = NULL;
  }
}

void AdnsHandler::checkDNSResolution() {
  if (!adnsQuery)
    return;

  // check to see if query has completed
  adns_answer *answer;
  if (adns_check(adnsState, &adnsQuery, &answer, 0) != 0) {
    if (getErrno() != EAGAIN) {
      DEBUG1("Player [%d] failed to resolve: errno %d\n", index, getErrno());
      adnsQuery = NULL;
      status = Failed;
    }
    return;
  }

  // we got our reply.
  if (answer->status != adns_s_ok) {
    DEBUG1("Player [%d] got bad status from resolver: %s\n", index,
	   adns_strerror(answer->status));
    free(answer);
    adnsQuery = NULL;
    status = Failed;
    return;
  }

  if (hostname)
    free(hostname); // shouldn't happen, but just in case
  hostname = strdup(*answer->rrs.str);
  DEBUG1("Player [%d] resolved to hostname: %s\n", index, hostname);
  free(answer);
  adnsQuery = NULL;
  status = Succeeded;
  return;
}

const char *AdnsHandler::getHostname() {
  if (status == Pending) {
    checkDNSResolution();
  }
  return hostname;
}

void AdnsHandler::startupResolver() {
  /* start up our resolver if we have ADNS */
  if (adns_init(&adnsState, adns_if_nosigpipe, 0) < 0) {
    perror("ADNS init failed");
    exit(1);
  }
}

#endif

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>only return hostname if lookup has succeeded<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "AdnsHandler.h"

/* system implementation headers */
#include <errno.h>

/* common implementation headers */
#include "network.h"

#ifdef HAVE_ADNS_H

adns_state AdnsHandler::adnsState;

AdnsHandler::AdnsHandler(int _index, struct sockaddr *clientAddr)
  : index(_index), hostname(NULL), adnsQuery(NULL), status(None) {
  // launch the asynchronous query to look up this hostname
  if (adns_submit_reverse
      (adnsState, clientAddr, adns_r_ptr,
       (adns_queryflags)(adns_qf_quoteok_cname|adns_qf_cname_loose), 0,
       &adnsQuery) != 0) {
    DEBUG1("Player [%d] failed to submit reverse resolve query: errno %d\n",
	   index, getErrno());
    adnsQuery = NULL;
    status = Failed;
  } else {
    DEBUG2("Player [%d] submitted reverse resolve query\n", index);
    status = Pending;
  }
}

AdnsHandler::~AdnsHandler() {
  if (adnsQuery) {
    adns_cancel(adnsQuery);
    adnsQuery = NULL;
  }
  if (hostname) {
    free(hostname);
    hostname = NULL;
  }
}

void AdnsHandler::checkDNSResolution() {
  if (!adnsQuery)
    return;

  // check to see if query has completed
  adns_answer *answer;
  if (adns_check(adnsState, &adnsQuery, &answer, 0) != 0) {
    if (getErrno() != EAGAIN) {
      DEBUG1("Player [%d] failed to resolve: errno %d\n", index, getErrno());
      adnsQuery = NULL;
      status = Failed;
    }
    return;
  }

  // we got our reply.
  if (answer->status != adns_s_ok) {
    DEBUG1("Player [%d] got bad status from resolver: %s\n", index,
	   adns_strerror(answer->status));
    free(answer);
    adnsQuery = NULL;
    status = Failed;
    return;
  }

  if (hostname)
    free(hostname); // shouldn't happen, but just in case
  hostname = strdup(*answer->rrs.str);
  DEBUG1("Player [%d] resolved to hostname: %s\n", index, hostname);
  free(answer);
  adnsQuery = NULL;
  status = Succeeded;
  return;
}

const char *AdnsHandler::getHostname() {
  if (status == Pending) {
    checkDNSResolution();
  }
  if (status == Succeeded)
    return hostname;

  return NULL;
}

void AdnsHandler::startupResolver() {
  /* start up our resolver if we have ADNS */
  if (adns_init(&adnsState, adns_if_nosigpipe, 0) < 0) {
    perror("ADNS init failed");
    exit(1);
  }
}

#endif

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>// request.cpp
//
#include "request.h"
#include "requestfields.h"

#include "player.h"
#include "event/types.h"
#include "network/response.h"

#include <string>

namespace xim {
namespace network {

using namespace xim::event;

/*
 * Excerpt from the Official Unwrittten Boostcraft Style Guide:
 *
 * Preprocessor Macros
 * -------------------
 * These are to be eschewed whenever there is a reasonable alternative. Macros
 * have many pitfalls, including obfuscation of source code and loss of type
 * safety. If there's a way to accomplish your goal without using macros, don't
 * use macros.
 *
 * Here are some great things to NOT use macros for:
 *
 *  Preprocessor Macro Use                              Punishment
 *  ---------------------------------------------------------------------------
 *   #defining constants                                Slap on the wrist
 *   "Inlining" function-like code                      That's a paddling
 *   Hiding ugly code                                   Twenty lashes
 *   Generic programming                                Waterboarding
 *   Implementing mini-DSLs in the preprocessor         Firing squad
 *
 * That said, sometimes using macros can really improve the readability and
 * maintainability of a piece of code. When that happens, and there's not any
 * obvious way of refactoring the code to obviate the need for macros, just use
 * some macros rather than write ugly code.
 *
 * So, with that in mind...
 */

/**
 * Ugly code-hiding mini-DSL for packet field specs!
 *
 * These macros ease the definition of data layouts for request packets. They
 * can only be used in the body of Request subclasses.
 *
 *  BEGIN_FIELDS    Marks the start of fields section in a Request class.
 *  END_FIELDS      REQUIRED to end the fields section.
 *  BYTE,SHORT,ETC. Binds a member variable of the class to a typed position
 *                  in the packet's data layout.
 *
 *  Example:
 *
 *  struct SomePacket : public Request {
 *      int32_t theNumber;
 *      std::string theString;
 *      BEGIN_FIELDS
 *          INT         (theNumber)
 *          STRING_UTF8 (theString)
 *      END_FIELDS
 *  };
 */

#define BEGIN_FIELDS    size_t read(boost::asio::streambuf & buf) \
                        { \
                            int cur_field = 0; \

#define FIELD(type,v)       if (this->fields_read_ == cur_field++) { \
                                size_t needed = type(buf, v); \
                                if (needed) \
                                    return needed; \
                                else \
                                    ++this->fields_read_; \
                            }

#define END_FIELDS          return 0; \
                        }

#define BOOLEAN(v)  FIELD(readBool, v)
#define BYTE(v)     FIELD(readByte, v)
#define SHORT(v)    FIELD(readShort, v)
#define INT(v)      FIELD(readInt, v)
#define LONG(v)     FIELD(readLong, v)
#define FLOAT(v)    FIELD(readFloat, v)
#define DOUBLE(v)   FIELD(readDouble, v)
#define STRING_UTF8(v) FIELD(readStringUtf8, v)
#define STRING_UCS2(v) FIELD(readStringUcs2, v)

namespace packets {

/*
 * 0x00 KEEP ALIVE
 */
struct KeepAlive : public Request
{
    size_t read(boost::asio::streambuf&) { return 0; }
    void dispatch(player_ptr p) const
    {
        // No event dispatch on keepalive; just ping back
        p->deliver(keepalive());
    }
};

/*
 * 0x01 LOGIN REQUEST
 */
struct LoginRequest : public Request
{
    int32_t version;
    std::string username;
    int64_t seed;
    int8_t dimension;

    BEGIN_FIELDS
        INT         (version)
        STRING_UCS2 (username)
        LONG        (seed)
        BYTE        (dimension)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        LoginRequestEvent e(p, username, version);
        async_fire(e);
    }
};

/*
 * 0x02 HANDSHAKE
 */
struct Handshake : public Request
{
    std::string username;

    BEGIN_FIELDS
        STRING_UCS2 (username)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->handshake(username);
    }
};

/*
 * 0x03 CHAT MESSAGE
 */
struct ChatMessage : public Request
{
    std::string message;

    BEGIN_FIELDS
        STRING_UCS2 (message)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        ChatEvent e(p, message);
        async_fire(e);
    }
};

/*
 * 0x07 USE ENTITY
 */
struct UseEntity : public Request
{
    int32_t user;
    int32_t target;
    bool leftclick;

    BEGIN_FIELDS
        INT         (user)
        INT         (target)
        BOOLEAN     (leftclick)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x09 RESPAWN
 */
struct Respawn : public Request
{
    int8_t world;

    BEGIN_FIELDS
        BYTE        (world)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: respawn event
    }
};

/*
 * 0x0A PLAYER ONGROUND
 */
struct PlayerOnGround : public Request
{
    bool onground;

    BEGIN_FIELDS
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        PlayerOnGroundEvent e(p, onground);
        async_fire(e);
    }
};

/*
 * 0x0B PLAYER POSITION
 */
struct PlayerPosition : public Request
{
    double x, y, z, stance;
    bool onground;

    BEGIN_FIELDS
        DOUBLE      (x)
        DOUBLE      (y)
        DOUBLE      (stance)
        DOUBLE      (z)
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->updatePosition({x, z, y});

        PlayerOnGroundEvent g(p, onground);
        async_fire(g);

        PlayerPositionEvent e(p, {x, z, y});
        async_fire(e);
    }
};

/*
 * 0x0C PLAYER LOOK
 */
struct PlayerLook : public Request
{
    float pitch, yaw;
    bool onground;

    BEGIN_FIELDS
        FLOAT       (yaw)
        FLOAT       (pitch)
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        PlayerOnGroundEvent g(p, onground);
        async_fire(g);

        PlayerLookEvent e(p, yaw, pitch);
        async_fire(e);
    }
};

/*
 * 0x0D PLAYER POSITION AND LOOK
 */
struct PlayerPositionAndLook : public Request
{
    double x, y, z, stance;
    float pitch, yaw;
    bool onground;

    BEGIN_FIELDS
        DOUBLE      (x)
        DOUBLE      (y)
        DOUBLE      (stance)
        DOUBLE      (z)
        FLOAT       (yaw)
        FLOAT       (pitch)
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->updatePosition({x, z, y});

        PlayerOnGroundEvent g(p, onground);
        async_fire(g);

        PlayerLookEvent l(p, yaw, pitch);
        async_fire(l);

        PlayerPositionEvent e(p, {x, z, y});
        async_fire(e);
    }
};

/*
 * 0x0E PLAYER DIGGING
 */
struct Digging : public Request
{
    int8_t status;
    int32_t x;
    int8_t  y;
    int32_t z;
    int8_t face;

    BEGIN_FIELDS
        BYTE        (status)
        INT         (x)
        BYTE        (y)
        INT         (z)
        BYTE        (face)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        if (status == 0)
            p->deliver(chatmessage("I'm a dwarf and I'm digging a hole!"));
        else if (status == 2)
            p->deliver(chatmessage("Diggy diggy hole!"));
        else if (status == 4)
            p->deliver(chatmessage("Give a hoot; don't pollute!"));
    }
};

/*
 * 0x0F PLAYER BLOCK PLACEMENT
 */
struct BlockPlacement : public Request
{
    int32_t x, z;
    int8_t y;
    int8_t direction;
    int16_t itemid;
    int8_t amount;
    int16_t damage;

    BEGIN_FIELDS
        INT         (x)
        BYTE        (y)
        INT         (z)
        BYTE        (direction)
        SHORT       (itemid)
        if (itemid != -1) {
            BYTE        (amount)
            SHORT       (damage)
        }
    END_FIELDS

    void dispatch(player_ptr p) const
    {

    }
};

/*
 * 0x10 HOLDING CHANGE
 */
struct HoldingChange : public Request
{
    int16_t slot;

    BEGIN_FIELDS
       SHORT        (slot)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
        Response r;
        r << (int8_t)0x36;
        r << (int32_t)0 << (int16_t)1 << (int32_t)0;
        r << (int8_t)0 << (int8_t)16;
        p->deliver(r);
    }
};

/*
 * 0x12 ENTITY ANIMATION
 */
struct Animation : public Request
{
    int32_t eid;
    int8_t anim;

    BEGIN_FIELDS
        INT         (eid)
        BYTE        (anim)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x13 STANCE CHANGE
 */
struct Stance : public Request
{
    int32_t eid;
    int8_t action;  // 1 = crouch, 2 = uncrouch, 3 = leave bed

    BEGIN_FIELDS
        INT         (eid)
        BYTE        (action)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x65 CLOSE WINDOW
 */
struct CloseWindow : public Request
{
    int8_t windowid;

    BEGIN_FIELDS
        BYTE        (windowid)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x66 WINDOW CLICK
 */
struct ClickWindow : public Request
{
    int8_t windowid;
    int16_t slot;
    bool rclick;
    bool shift;
    int16_t actionid;
    int16_t itemid;
    int8_t  itemcount;
    int16_t itemuses;

    BEGIN_FIELDS
        BYTE        (windowid)
        SHORT       (slot)
        BOOLEAN     (rclick)
        SHORT       (actionid)
        BOOLEAN     (shift)
        SHORT       (itemid)
        if (itemid != -1)
        {
            BYTE    (itemcount)
            SHORT   (itemuses)
        }
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0xFF DISCONNECT
 */
struct Disconnect : public Request
{
    std::string message;

    BEGIN_FIELDS
        STRING_UCS2 (message)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->stop(message);
    }
};

} // namespace packets

#define REQUEST_CASE(num, type) case num: return ptr(new type());

std::unique_ptr<Request> makerequest(int type)
{
    typedef std::unique_ptr<Request> ptr;
    using namespace packets;

    switch(type)
    {
        REQUEST_CASE(0x00, KeepAlive)
        REQUEST_CASE(0x01, LoginRequest)
        REQUEST_CASE(0x02, Handshake)
        REQUEST_CASE(0x03, ChatMessage)
        REQUEST_CASE(0x07, UseEntity)
        REQUEST_CASE(0x09, Respawn)
        REQUEST_CASE(0x0A, PlayerOnGround)
        REQUEST_CASE(0x0B, PlayerPosition)
        REQUEST_CASE(0x0C, PlayerLook)
        REQUEST_CASE(0x0D, PlayerPositionAndLook)
        REQUEST_CASE(0x0E, Digging)
        REQUEST_CASE(0x0F, BlockPlacement)
        REQUEST_CASE(0x10, HoldingChange)
        REQUEST_CASE(0x12, Animation)
        REQUEST_CASE(0x13, Stance)
        REQUEST_CASE(0x65, CloseWindow)
        REQUEST_CASE(0x66, ClickWindow)
        REQUEST_CASE(0xFF, Disconnect)

    default:
        {
            std::stringstream ss;
            ss << "Unrecognized packet ID " << std::hex << type;
            throw std::runtime_error(ss.str());
        }
    }
}

}} // namespace xim::network
<commit_msg>Store player's yaw and pitch<commit_after>// request.cpp
//
#include "request.h"
#include "requestfields.h"

#include "player.h"
#include "event/types.h"
#include "network/response.h"

#include <string>

namespace xim {
namespace network {

using namespace xim::event;

/*
 * Excerpt from the Official Unwrittten Boostcraft Style Guide:
 *
 * Preprocessor Macros
 * -------------------
 * These are to be eschewed whenever there is a reasonable alternative. Macros
 * have many pitfalls, including obfuscation of source code and loss of type
 * safety. If there's a way to accomplish your goal without using macros, don't
 * use macros.
 *
 * Here are some great things to NOT use macros for:
 *
 *  Preprocessor Macro Use                              Punishment
 *  ---------------------------------------------------------------------------
 *   #defining constants                                Slap on the wrist
 *   "Inlining" function-like code                      That's a paddling
 *   Hiding ugly code                                   Twenty lashes
 *   Generic programming                                Waterboarding
 *   Implementing mini-DSLs in the preprocessor         Firing squad
 *
 * That said, sometimes using macros can really improve the readability and
 * maintainability of a piece of code. When that happens, and there's not any
 * obvious way of refactoring the code to obviate the need for macros, just use
 * some macros rather than write ugly code.
 *
 * So, with that in mind...
 */

/**
 * Ugly code-hiding mini-DSL for packet field specs!
 *
 * These macros ease the definition of data layouts for request packets. They
 * can only be used in the body of Request subclasses.
 *
 *  BEGIN_FIELDS    Marks the start of fields section in a Request class.
 *  END_FIELDS      REQUIRED to end the fields section.
 *  BYTE,SHORT,ETC. Binds a member variable of the class to a typed position
 *                  in the packet's data layout.
 *
 *  Example:
 *
 *  struct SomePacket : public Request {
 *      int32_t theNumber;
 *      std::string theString;
 *      BEGIN_FIELDS
 *          INT         (theNumber)
 *          STRING_UTF8 (theString)
 *      END_FIELDS
 *  };
 */

#define BEGIN_FIELDS    size_t read(boost::asio::streambuf & buf) \
                        { \
                            int cur_field = 0; \

#define FIELD(type,v)       if (this->fields_read_ == cur_field++) { \
                                size_t needed = type(buf, v); \
                                if (needed) \
                                    return needed; \
                                else \
                                    ++this->fields_read_; \
                            }

#define END_FIELDS          return 0; \
                        }

#define BOOLEAN(v)  FIELD(readBool, v)
#define BYTE(v)     FIELD(readByte, v)
#define SHORT(v)    FIELD(readShort, v)
#define INT(v)      FIELD(readInt, v)
#define LONG(v)     FIELD(readLong, v)
#define FLOAT(v)    FIELD(readFloat, v)
#define DOUBLE(v)   FIELD(readDouble, v)
#define STRING_UTF8(v) FIELD(readStringUtf8, v)
#define STRING_UCS2(v) FIELD(readStringUcs2, v)

namespace packets {

/*
 * 0x00 KEEP ALIVE
 */
struct KeepAlive : public Request
{
    size_t read(boost::asio::streambuf&) { return 0; }
    void dispatch(player_ptr p) const
    {
        // No event dispatch on keepalive; just ping back
        p->deliver(keepalive());
    }
};

/*
 * 0x01 LOGIN REQUEST
 */
struct LoginRequest : public Request
{
    int32_t version;
    std::string username;
    int64_t seed;
    int8_t dimension;

    BEGIN_FIELDS
        INT         (version)
        STRING_UCS2 (username)
        LONG        (seed)
        BYTE        (dimension)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        LoginRequestEvent e(p, username, version);
        async_fire(e);
    }
};

/*
 * 0x02 HANDSHAKE
 */
struct Handshake : public Request
{
    std::string username;

    BEGIN_FIELDS
        STRING_UCS2 (username)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->handshake(username);
    }
};

/*
 * 0x03 CHAT MESSAGE
 */
struct ChatMessage : public Request
{
    std::string message;

    BEGIN_FIELDS
        STRING_UCS2 (message)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        ChatEvent e(p, message);
        async_fire(e);
    }
};

/*
 * 0x07 USE ENTITY
 */
struct UseEntity : public Request
{
    int32_t user;
    int32_t target;
    bool leftclick;

    BEGIN_FIELDS
        INT         (user)
        INT         (target)
        BOOLEAN     (leftclick)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x09 RESPAWN
 */
struct Respawn : public Request
{
    int8_t world;

    BEGIN_FIELDS
        BYTE        (world)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: respawn event
    }
};

/*
 * 0x0A PLAYER ONGROUND
 */
struct PlayerOnGround : public Request
{
    bool onground;

    BEGIN_FIELDS
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        PlayerOnGroundEvent e(p, onground);
        async_fire(e);
    }
};

/*
 * 0x0B PLAYER POSITION
 */
struct PlayerPosition : public Request
{
    double x, y, z, stance;
    bool onground;

    BEGIN_FIELDS
        DOUBLE      (x)
        DOUBLE      (y)
        DOUBLE      (stance)
        DOUBLE      (z)
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->updatePosition({x, z, y});

        PlayerOnGroundEvent g(p, onground);
        async_fire(g);

        PlayerPositionEvent e(p, {x, z, y});
        async_fire(e);
    }
};

/*
 * 0x0C PLAYER LOOK
 */
struct PlayerLook : public Request
{
    float pitch, yaw;
    bool onground;

    BEGIN_FIELDS
        FLOAT       (yaw)
        FLOAT       (pitch)
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->updateLook(yaw, pitch);
        PlayerOnGroundEvent g(p, onground);
        async_fire(g);

        PlayerLookEvent e(p, yaw, pitch);
        async_fire(e);
    }
};

/*
 * 0x0D PLAYER POSITION AND LOOK
 */
struct PlayerPositionAndLook : public Request
{
    double x, y, z, stance;
    float pitch, yaw;
    bool onground;

    BEGIN_FIELDS
        DOUBLE      (x)
        DOUBLE      (y)
        DOUBLE      (stance)
        DOUBLE      (z)
        FLOAT       (yaw)
        FLOAT       (pitch)
        BOOLEAN     (onground)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->updatePosition({x, z, y});
        p->updateLook(yaw, pitch);

        PlayerOnGroundEvent g(p, onground);
        async_fire(g);

        PlayerLookEvent l(p, yaw, pitch);
        async_fire(l);

        PlayerPositionEvent e(p, {x, z, y});
        async_fire(e);
    }
};

/*
 * 0x0E PLAYER DIGGING
 */
struct Digging : public Request
{
    int8_t status;
    int32_t x;
    int8_t  y;
    int32_t z;
    int8_t face;

    BEGIN_FIELDS
        BYTE        (status)
        INT         (x)
        BYTE        (y)
        INT         (z)
        BYTE        (face)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        if (status == 0)
            p->deliver(chatmessage("I'm a dwarf and I'm digging a hole!"));
        else if (status == 2)
            p->deliver(chatmessage("Diggy diggy hole!"));
        else if (status == 4)
            p->deliver(chatmessage("Give a hoot; don't pollute!"));
    }
};

/*
 * 0x0F PLAYER BLOCK PLACEMENT
 */
struct BlockPlacement : public Request
{
    int32_t x, z;
    int8_t y;
    int8_t direction;
    int16_t itemid;
    int8_t amount;
    int16_t damage;

    BEGIN_FIELDS
        INT         (x)
        BYTE        (y)
        INT         (z)
        BYTE        (direction)
        SHORT       (itemid)
        if (itemid != -1) {
            BYTE        (amount)
            SHORT       (damage)
        }
    END_FIELDS

    void dispatch(player_ptr p) const
    {

    }
};

/*
 * 0x10 HOLDING CHANGE
 */
struct HoldingChange : public Request
{
    int16_t slot;

    BEGIN_FIELDS
       SHORT        (slot)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
        Response r;
        r << (int8_t)0x36;
        r << (int32_t)0 << (int16_t)1 << (int32_t)0;
        r << (int8_t)0 << (int8_t)16;
        p->deliver(r);
    }
};

/*
 * 0x12 ENTITY ANIMATION
 */
struct Animation : public Request
{
    int32_t eid;
    int8_t anim;

    BEGIN_FIELDS
        INT         (eid)
        BYTE        (anim)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x13 STANCE CHANGE
 */
struct Stance : public Request
{
    int32_t eid;
    int8_t action;  // 1 = crouch, 2 = uncrouch, 3 = leave bed

    BEGIN_FIELDS
        INT         (eid)
        BYTE        (action)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x65 CLOSE WINDOW
 */
struct CloseWindow : public Request
{
    int8_t windowid;

    BEGIN_FIELDS
        BYTE        (windowid)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0x66 WINDOW CLICK
 */
struct ClickWindow : public Request
{
    int8_t windowid;
    int16_t slot;
    bool rclick;
    bool shift;
    int16_t actionid;
    int16_t itemid;
    int8_t  itemcount;
    int16_t itemuses;

    BEGIN_FIELDS
        BYTE        (windowid)
        SHORT       (slot)
        BOOLEAN     (rclick)
        SHORT       (actionid)
        BOOLEAN     (shift)
        SHORT       (itemid)
        if (itemid != -1)
        {
            BYTE    (itemcount)
            SHORT   (itemuses)
        }
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        // TODO: implement dispatch
    }
};

/*
 * 0xFF DISCONNECT
 */
struct Disconnect : public Request
{
    std::string message;

    BEGIN_FIELDS
        STRING_UCS2 (message)
    END_FIELDS

    void dispatch(player_ptr p) const
    {
        p->stop(message);
    }
};

} // namespace packets

#define REQUEST_CASE(num, type) case num: return ptr(new type());

std::unique_ptr<Request> makerequest(int type)
{
    typedef std::unique_ptr<Request> ptr;
    using namespace packets;

    switch(type)
    {
        REQUEST_CASE(0x00, KeepAlive)
        REQUEST_CASE(0x01, LoginRequest)
        REQUEST_CASE(0x02, Handshake)
        REQUEST_CASE(0x03, ChatMessage)
        REQUEST_CASE(0x07, UseEntity)
        REQUEST_CASE(0x09, Respawn)
        REQUEST_CASE(0x0A, PlayerOnGround)
        REQUEST_CASE(0x0B, PlayerPosition)
        REQUEST_CASE(0x0C, PlayerLook)
        REQUEST_CASE(0x0D, PlayerPositionAndLook)
        REQUEST_CASE(0x0E, Digging)
        REQUEST_CASE(0x0F, BlockPlacement)
        REQUEST_CASE(0x10, HoldingChange)
        REQUEST_CASE(0x12, Animation)
        REQUEST_CASE(0x13, Stance)
        REQUEST_CASE(0x65, CloseWindow)
        REQUEST_CASE(0x66, ClickWindow)
        REQUEST_CASE(0xFF, Disconnect)

    default:
        {
            std::stringstream ss;
            ss << "Unrecognized packet ID " << std::hex << type;
            throw std::runtime_error(ss.str());
        }
    }
}

}} // namespace xim::network
<|endoftext|>


<commit_before>#ifndef MJOLNIR_TEST_MAKE_EMPTY_INPUT_HPP
#define MJOLNIR_TEST_MAKE_EMPTY_INPUT_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/util/string.hpp>

namespace mjolnir
{
namespace test
{

// make a minimal input file that contains no particle, no forcefield.
// It contains only parameters that are needed to pass read_input() functions.
inline toml::value make_empty_input()
{
    using namespace toml::literals::toml_literals;
    return u8R"(
[files]
output.prefix = "empty"
output.format = "xyz"
output.path   = "./"

[units]
length = "angstrom"
energy = "kcal/mol"

[simulator]
type            = "MolecularDynamics"
precision       = "double"
boundary_type   = "Unlimited"
total_step      = 1
save_step       = 1
delta_t         = 0.1
integrator.type = "VelocityVerlet"

[[systems]]
attributes.temperature = 300.0
boundary_shape         = {}
particles              = []

[[forcefields]]
# nothing!
)"_toml;
}

} // test
} // mjolnir
#endif// MJOLNIR_TEST_MAKE_EMPTY_INPUT_HPP
<commit_msg>test: update template sample input<commit_after>#ifndef MJOLNIR_TEST_MAKE_EMPTY_INPUT_HPP
#define MJOLNIR_TEST_MAKE_EMPTY_INPUT_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/util/string.hpp>

namespace mjolnir
{
namespace test
{

// make a minimal input file that contains no particle, no forcefield.
// It contains only parameters that are needed to pass read_input() functions.
inline toml::value make_empty_input()
{
    using namespace toml::literals::toml_literals;
    return u8R"(
[files]
output.prefix = "empty"
output.format = "xyz"
output.path   = "./"

[units]
length = "angstrom"
energy = "kcal/mol"

[simulator]
type            = "MolecularDynamics"
precision       = "double"
boundary_type   = "Unlimited"
seed            = 1
total_step      = 1
save_step       = 1
delta_t         = 0.1
integrator.type = "VelocityVerlet"

[[systems]]
attributes.temperature = 300.0
boundary_shape         = {}
particles              = []

[[forcefields]]
# nothing!
)"_toml;
}

} // test
} // mjolnir
#endif// MJOLNIR_TEST_MAKE_EMPTY_INPUT_HPP
<|endoftext|>


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

#include "mock_sampler.h"
#include "util/concurrency/threadpool.h"

namespace veles {
namespace util {

using testing::Mock;
using testing::Return;
using testing::Expectation;
using testing::_;

/*****************************************************************************/
/* Helpers */
/*****************************************************************************/

QByteArray prepare_data(size_t size) {
  QByteArray result;
  for (size_t i = 0; i < size; ++i) {
    result.push_back(static_cast<char>(i % 127));
  }
  return result;
}

int MockCallback::getCallCount() {
  return calls_;
}

void MockCallback::resetCallCount() {
  calls_ = 0;
}

void MockCallback::operator()() {
  ++calls_;
}

/*****************************************************************************/
/* Small data (no sampling required) */
/*****************************************************************************/

TEST(ISamplerSmallData, basic) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  ASSERT_EQ(100, sampler.getSampleSize());
  ASSERT_EQ(data[0], sampler[0]);
  ASSERT_EQ(data[10], sampler[10]);
  ASSERT_EQ(data[99], sampler[sampler.getSampleSize() - 1]);
}

TEST(ISamplerSmallData, setRange) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  sampler.setRange(40, 50);
  ASSERT_EQ(10, sampler.getSampleSize());
  ASSERT_EQ(40, sampler.getRange().first);
  ASSERT_EQ(50, sampler.getRange().second);
  for (int i = 0; i < 10; ++i) {
    ASSERT_EQ(data[i + 40], sampler[i]);
  }
}

TEST(ISamplerSmallData, offsets) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  ASSERT_EQ(0, sampler.getFileOffset(0));
  ASSERT_EQ(33, sampler.getFileOffset(33));
  ASSERT_EQ(99, sampler.getFileOffset(99));
  ASSERT_EQ(0, sampler.getSampleOffset(0));
  ASSERT_EQ(33, sampler.getSampleOffset(33));
  ASSERT_EQ(99, sampler.getSampleOffset(99));
}

TEST(ISamplerSmallData, offsetsAfterSetRange) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  sampler.setRange(40, 50);
  ASSERT_EQ(40, sampler.getFileOffset(0));
  ASSERT_EQ(45, sampler.getFileOffset(5));
  ASSERT_EQ(49, sampler.getFileOffset(9));
  ASSERT_EQ(0, sampler.getSampleOffset(40));
  ASSERT_EQ(5, sampler.getSampleOffset(45));
  ASSERT_EQ(9, sampler.getSampleOffset(49));
}

/*****************************************************************************/
/* Synchronous sampling */
/*****************************************************************************/

TEST(ISamplerWithSampling, basic) {
  auto data = prepare_data(100);
  testing::NiceMock<MockSampler> sampler(data);
  Expectation init1 = EXPECT_CALL(sampler, prepareResample(_));
  Expectation init2 = EXPECT_CALL(sampler, applyResample(_))
    .After(init1);
  sampler.setSampleSize(10);
  EXPECT_CALL(sampler, getRealSampleSize())
    .After(init2)
    .WillRepeatedly(Return(10));
  ASSERT_EQ(10, sampler.getSampleSize());
  EXPECT_CALL(sampler, getSampleByte(0))
    .WillOnce(Return(0));
  ASSERT_EQ(data[0], sampler[0]);
  EXPECT_CALL(sampler, getSampleByte(5))
    .WillOnce(Return(33));
  ASSERT_EQ(data[33], sampler[5]);
  EXPECT_CALL(sampler, getSampleByte(9))
    .WillOnce(Return(99));
  ASSERT_EQ(data[99], sampler[9]);
}

TEST(ISamplerWithSampling, offsets) {
  auto data = prepare_data(100);
  testing::NiceMock<MockSampler> sampler(data);
  sampler.setSampleSize(10);
  ON_CALL(sampler, getRealSampleSize())
    .WillByDefault(Return(10));
  EXPECT_CALL(sampler, getFileOffsetImpl(5))
    .Times(1)
    .WillOnce(Return(50));
  ASSERT_EQ(0, sampler.getFileOffset(0));
  ASSERT_EQ(99, sampler.getFileOffset(9));
  ASSERT_EQ(50, sampler.getFileOffset(5));

  EXPECT_CALL(sampler, getSampleOffsetImpl(50))
    .Times(1)
    .WillOnce(Return(5));
  ASSERT_EQ(0, sampler.getSampleOffset(0));
  ASSERT_EQ(9, sampler.getSampleOffset(99));
  ASSERT_EQ(5, sampler.getSampleOffset(50));
  }

TEST(ISamplerWithSampling, offsetsAfterSetRange) {
  auto data = prepare_data(100);
  testing::NiceMock<MockSampler> sampler(data);
  sampler.setSampleSize(10);
  sampler.setRange(40, 60);
  ON_CALL(sampler, getRealSampleSize())
    .WillByDefault(Return(10));
  EXPECT_CALL(sampler, getFileOffsetImpl(5))
    .Times(1)
    .WillOnce(Return(10));
  ASSERT_EQ(40, sampler.getFileOffset(0));
  ASSERT_EQ(59, sampler.getFileOffset(9));
  ASSERT_EQ(50, sampler.getFileOffset(5));

  EXPECT_CALL(sampler, getSampleOffsetImpl(10))
    .Times(1)
    .WillOnce(Return(5));
  ASSERT_EQ(0, sampler.getSampleOffset(40));
  ASSERT_EQ(9, sampler.getSampleOffset(59));
  ASSERT_EQ(5, sampler.getSampleOffset(50));
}

TEST(ISamplerWithSampling, getDataFromIsampler) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  Expectation init1 = EXPECT_CALL(sampler, prepareResample(_));
  Expectation init2 = EXPECT_CALL(sampler, applyResample(_))
    .After(init1);
  sampler.setSampleSize(10);
  ASSERT_EQ(100, sampler.proxy_getDataSize());
  ASSERT_EQ(0, sampler.proxy_getDataByte(0));
  ASSERT_EQ(5, sampler.proxy_getDataByte(5));
  ASSERT_EQ(99, sampler.proxy_getDataByte(99));
  Mock::VerifyAndClear(&sampler);
  Expectation update1 = EXPECT_CALL(sampler, prepareResample(_));
  Expectation update2 = EXPECT_CALL(sampler, applyResample(_))
    .After(update1);
  sampler.setRange(40, 60);
  ASSERT_EQ(20, sampler.proxy_getDataSize());
  ASSERT_EQ(40, sampler.proxy_getDataByte(0));
  ASSERT_EQ(45, sampler.proxy_getDataByte(5));
  ASSERT_EQ(59, sampler.proxy_getDataByte(19));
}

/*****************************************************************************/
/* Asynchronous interface */
/*****************************************************************************/

TEST(ISamplerAsynchronous, addAndClearCallbacks) {
  threadpool::mockTopic("visualisation");
  auto data = prepare_data(100);
  MockCallback mc1, mc2, mc3;
  mc1.resetCallCount();
  mc2.resetCallCount();
  mc3.resetCallCount();
  testing::NiceMock<MockSampler> sampler(data);

  sampler.setSampleSize(10);
  sampler.allowAsynchronousResampling(true);
  sampler.registerResampleCallback(std::ref(mc1));
  auto cb2_id = sampler.registerResampleCallback(std::ref(mc2));
  sampler.registerResampleCallback(std::ref(mc3));

  sampler.resample();
  ASSERT_EQ(1, mc1.getCallCount());
  ASSERT_EQ(1, mc2.getCallCount());
  ASSERT_EQ(1, mc3.getCallCount());

  mc1.resetCallCount();
  mc2.resetCallCount();
  mc3.resetCallCount();
  sampler.removeResampleCallback(cb2_id);
  sampler.resample();
  ASSERT_EQ(1, mc1.getCallCount());
  ASSERT_EQ(0, mc2.getCallCount());
  ASSERT_EQ(1, mc3.getCallCount());

  mc1.resetCallCount();
  mc2.resetCallCount();
  mc3.resetCallCount();
  sampler.clearResampleCallbacks();
  sampler.resample();
  ASSERT_EQ(0, mc1.getCallCount());
  ASSERT_EQ(0, mc2.getCallCount());
  ASSERT_EQ(0, mc3.getCallCount());
}

TEST(ISamplerAsynchronous, prepareAndApplySample) {
  threadpool::mockTopic("visualisation");
  auto data = prepare_data(100);
  MockCallback mc;
  mc.resetCallCount();
  testing::StrictMock<MockSampler> sampler(data);
  EXPECT_CALL(sampler, prepareResample(_))
    .WillOnce(Return(nullptr));
  EXPECT_CALL(sampler, applyResample(nullptr));
  sampler.setSampleSize(10);
  sampler.wait();
  ASSERT_TRUE(sampler.isFinished());
}

}  // namespace util
}  // namespace veles
<commit_msg>Fix renaming bug<commit_after>/*
 * Copyright 2016 CodiLime
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "mock_sampler.h"
#include "util/concurrency/threadpool.h"

namespace veles {
namespace util {

using testing::Mock;
using testing::Return;
using testing::Expectation;
using testing::_;

/*****************************************************************************/
/* Helpers */
/*****************************************************************************/

QByteArray prepare_data(size_t size) {
  QByteArray result;
  for (size_t i = 0; i < size; ++i) {
    result.push_back(static_cast<char>(i % 127));
  }
  return result;
}

int MockCallback::getCallCount() {
  return calls_;
}

void MockCallback::resetCallCount() {
  calls_ = 0;
}

void MockCallback::operator()() {
  ++calls_;
}

/*****************************************************************************/
/* Small data (no sampling required) */
/*****************************************************************************/

TEST(ISamplerSmallData, basic) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  ASSERT_EQ(100, sampler.getSampleSize());
  ASSERT_EQ(data[0], sampler[0]);
  ASSERT_EQ(data[10], sampler[10]);
  ASSERT_EQ(data[99], sampler[sampler.getSampleSize() - 1]);
}

TEST(ISamplerSmallData, setRange) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  sampler.setRange(40, 50);
  ASSERT_EQ(10, sampler.getSampleSize());
  ASSERT_EQ(40, sampler.getRange().first);
  ASSERT_EQ(50, sampler.getRange().second);
  for (int i = 0; i < 10; ++i) {
    ASSERT_EQ(data[i + 40], sampler[i]);
  }
}

TEST(ISamplerSmallData, offsets) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  ASSERT_EQ(0, sampler.getFileOffset(0));
  ASSERT_EQ(33, sampler.getFileOffset(33));
  ASSERT_EQ(99, sampler.getFileOffset(99));
  ASSERT_EQ(0, sampler.getSampleOffset(0));
  ASSERT_EQ(33, sampler.getSampleOffset(33));
  ASSERT_EQ(99, sampler.getSampleOffset(99));
}

TEST(ISamplerSmallData, offsetsAfterSetRange) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  sampler.setSampleSize(120);
  sampler.setRange(40, 50);
  ASSERT_EQ(40, sampler.getFileOffset(0));
  ASSERT_EQ(45, sampler.getFileOffset(5));
  ASSERT_EQ(49, sampler.getFileOffset(9));
  ASSERT_EQ(0, sampler.getSampleOffset(40));
  ASSERT_EQ(5, sampler.getSampleOffset(45));
  ASSERT_EQ(9, sampler.getSampleOffset(49));
}

/*****************************************************************************/
/* Synchronous sampling */
/*****************************************************************************/

TEST(ISamplerWithSampling, basic) {
  auto data = prepare_data(100);
  testing::NiceMock<MockSampler> sampler(data);
  Expectation init1 = EXPECT_CALL(sampler, prepareResample(_));
  Expectation init2 = EXPECT_CALL(sampler, applyResample(_))
    .After(init1);
  sampler.setSampleSize(10);
  EXPECT_CALL(sampler, getRealSampleSize())
    .After(init2)
    .WillRepeatedly(Return(10));
  ASSERT_EQ(10, sampler.getSampleSize());
  EXPECT_CALL(sampler, getSampleByte(0))
    .WillOnce(Return(0));
  ASSERT_EQ(data[0], sampler[0]);
  EXPECT_CALL(sampler, getSampleByte(5))
    .WillOnce(Return(33));
  ASSERT_EQ(data[33], sampler[5]);
  EXPECT_CALL(sampler, getSampleByte(9))
    .WillOnce(Return(99));
  ASSERT_EQ(data[99], sampler[9]);
}

TEST(ISamplerWithSampling, offsets) {
  auto data = prepare_data(100);
  testing::NiceMock<MockSampler> sampler(data);
  sampler.setSampleSize(10);
  ON_CALL(sampler, getRealSampleSize())
    .WillByDefault(Return(10));
  EXPECT_CALL(sampler, getFileOffsetImpl(5))
    .Times(1)
    .WillOnce(Return(50));
  ASSERT_EQ(0, sampler.getFileOffset(0));
  ASSERT_EQ(99, sampler.getFileOffset(9));
  ASSERT_EQ(50, sampler.getFileOffset(5));

  EXPECT_CALL(sampler, getSampleOffsetImpl(50))
    .Times(1)
    .WillOnce(Return(5));
  ASSERT_EQ(0, sampler.getSampleOffset(0));
  ASSERT_EQ(9, sampler.getSampleOffset(99));
  ASSERT_EQ(5, sampler.getSampleOffset(50));
  }

TEST(ISamplerWithSampling, offsetsAfterSetRange) {
  auto data = prepare_data(100);
  testing::NiceMock<MockSampler> sampler(data);
  sampler.setSampleSize(10);
  sampler.setRange(40, 60);
  ON_CALL(sampler, getRealSampleSize())
    .WillByDefault(Return(10));
  EXPECT_CALL(sampler, getFileOffsetImpl(5))
    .Times(1)
    .WillOnce(Return(10));
  ASSERT_EQ(40, sampler.getFileOffset(0));
  ASSERT_EQ(59, sampler.getFileOffset(9));
  ASSERT_EQ(50, sampler.getFileOffset(5));

  EXPECT_CALL(sampler, getSampleOffsetImpl(10))
    .Times(1)
    .WillOnce(Return(5));
  ASSERT_EQ(0, sampler.getSampleOffset(40));
  ASSERT_EQ(9, sampler.getSampleOffset(59));
  ASSERT_EQ(5, sampler.getSampleOffset(50));
}

TEST(ISamplerWithSampling, getDataFromIsampler) {
  auto data = prepare_data(100);
  testing::StrictMock<MockSampler> sampler(data);
  Expectation init1 = EXPECT_CALL(sampler, prepareResample(_));
  Expectation init2 = EXPECT_CALL(sampler, applyResample(_))
    .After(init1);
  sampler.setSampleSize(10);
  ASSERT_EQ(100, sampler.proxy_getDataSize());
  ASSERT_EQ(0, sampler.proxy_getDataByte(0));
  ASSERT_EQ(5, sampler.proxy_getDataByte(5));
  ASSERT_EQ(99, sampler.proxy_getDataByte(99));
  Mock::VerifyAndClear(&sampler);
  Expectation update1 = EXPECT_CALL(sampler, prepareResample(_));
  Expectation update2 = EXPECT_CALL(sampler, applyResample(_))
    .After(update1);
  sampler.setRange(40, 60);
  ASSERT_EQ(20, sampler.proxy_getDataSize());
  ASSERT_EQ(40, sampler.proxy_getDataByte(0));
  ASSERT_EQ(45, sampler.proxy_getDataByte(5));
  ASSERT_EQ(59, sampler.proxy_getDataByte(19));
}

/*****************************************************************************/
/* Asynchronous interface */
/*****************************************************************************/

TEST(ISamplerAsynchronous, addAndClearCallbacks) {
  threadpool::mockTopic("visualization");
  auto data = prepare_data(100);
  MockCallback mc1, mc2, mc3;
  mc1.resetCallCount();
  mc2.resetCallCount();
  mc3.resetCallCount();
  testing::NiceMock<MockSampler> sampler(data);

  sampler.setSampleSize(10);
  sampler.allowAsynchronousResampling(true);
  sampler.registerResampleCallback(std::ref(mc1));
  auto cb2_id = sampler.registerResampleCallback(std::ref(mc2));
  sampler.registerResampleCallback(std::ref(mc3));

  sampler.resample();
  ASSERT_EQ(1, mc1.getCallCount());
  ASSERT_EQ(1, mc2.getCallCount());
  ASSERT_EQ(1, mc3.getCallCount());

  mc1.resetCallCount();
  mc2.resetCallCount();
  mc3.resetCallCount();
  sampler.removeResampleCallback(cb2_id);
  sampler.resample();
  ASSERT_EQ(1, mc1.getCallCount());
  ASSERT_EQ(0, mc2.getCallCount());
  ASSERT_EQ(1, mc3.getCallCount());

  mc1.resetCallCount();
  mc2.resetCallCount();
  mc3.resetCallCount();
  sampler.clearResampleCallbacks();
  sampler.resample();
  ASSERT_EQ(0, mc1.getCallCount());
  ASSERT_EQ(0, mc2.getCallCount());
  ASSERT_EQ(0, mc3.getCallCount());
}

TEST(ISamplerAsynchronous, prepareAndApplySample) {
  threadpool::mockTopic("visualization");
  auto data = prepare_data(100);
  MockCallback mc;
  mc.resetCallCount();
  testing::StrictMock<MockSampler> sampler(data);
  EXPECT_CALL(sampler, prepareResample(_))
    .WillOnce(Return(nullptr));
  EXPECT_CALL(sampler, applyResample(nullptr));
  sampler.setSampleSize(10);
  sampler.wait();
  ASSERT_TRUE(sampler.isFinished());
}

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