<commit_before>// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
namespace internal {

template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
                 T value) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  if (precision > 100000)
    throw std::runtime_error(
        "fuzz mode - avoid large allocation inside snprintf");
#endif
  // Suppress the warning about nonliteral format string.
  int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
  return precision < 0 ? snprintf_ptr(buf, size, format, value)
                       : snprintf_ptr(buf, size, format, precision, value);
}
struct sprintf_specs {
  int precision;
  char type;
  bool alt : 1;

  template <typename Char>
  constexpr explicit sprintf_specs(basic_format_specs<Char> specs)
      : precision(specs.precision), type(specs.type), alt(specs.alt) {}

  constexpr bool has_precision() const { return precision >= 0; }
};

// This is deprecated and is kept only to preserve ABI compatibility.
template <typename Double>
char* sprintf_format(Double value, internal::buffer<char>& buf,
                     sprintf_specs specs) {
  // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
  FMT_ASSERT(buf.capacity() != 0, "empty buffer");

  // Build format string.
  enum { max_format_size = 10 };  // longest format: %#-*.*Lg
  char format[max_format_size];
  char* format_ptr = format;
  *format_ptr++ = '%';
  if (specs.alt || !specs.type) *format_ptr++ = '#';
  if (specs.precision >= 0) {
    *format_ptr++ = '.';
    *format_ptr++ = '*';
  }
  if (std::is_same<Double, long double>::value) *format_ptr++ = 'L';

  char type = specs.type;

  if (type == '%')
    type = 'f';
  else if (type == 0 || type == 'n')
    type = 'g';
#if FMT_MSC_VER
  if (type == 'F') {
    // MSVC's printf doesn't support 'F'.
    type = 'f';
  }
#endif
  *format_ptr++ = type;
  *format_ptr = '\0';

  // Format using snprintf.
  char* start = nullptr;
  char* decimal_point_pos = nullptr;
  for (;;) {
    std::size_t buffer_size = buf.capacity();
    start = &buf[0];
    int result =
        format_float(start, buffer_size, format, specs.precision, value);
    if (result >= 0) {
      unsigned n = internal::to_unsigned(result);
      if (n < buf.capacity()) {
        // Find the decimal point.
        auto p = buf.data();
        auto end = p + n;
        if (*p == '+' || *p == '-') ++p;
        if (specs.type != 'a' && specs.type != 'A') {
          while (p < end && *p >= '0' && *p <= '9') ++p;
          if (p < end && *p != 'e' && *p != 'E') {
            decimal_point_pos = p;
            if (!specs.type) {
              // Keep only one trailing zero after the decimal point.
              ++p;
              if (*p == '0') ++p;
              while (p != end && *p >= '1' && *p <= '9') ++p;
              char* where = p;
              while (p != end && *p == '0') ++p;
              if (p == end || *p < '0' || *p > '9') {
                if (p != end) std::memmove(where, p, to_unsigned(end - p));
                n -= static_cast<unsigned>(p - where);
              }
            }
          }
        }
        buf.resize(n);
        break;  // The buffer is large enough - continue with formatting.
      }
      buf.reserve(n + 1);
    } else {
      // If result is negative we ask to increase the capacity by at least 1,
      // but as std::vector, the buffer grows exponentially.
      buf.reserve(buf.capacity() + 1);
    }
  }
  return decimal_point_pos;
}
}  // namespace internal

template FMT_API char* internal::sprintf_format(double, internal::buffer<char>&,
                                                sprintf_specs);
template FMT_API char* internal::sprintf_format(long double,
                                                internal::buffer<char>&,
                                                sprintf_specs);

template struct FMT_INSTANTIATION_DEF_API internal::basic_data<void>;

// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, internal::float_specs,
                                internal::buffer<char>&) =
    internal::format_float;

#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API internal::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale internal::locale_ref::get<std::locale>() const;
#endif

// Explicit instantiations for char.

template FMT_API std::string internal::grouping_impl<char>(locale_ref);
template FMT_API char internal::thousands_sep_impl(locale_ref);
template FMT_API char internal::decimal_point_impl(locale_ref);

template FMT_API void internal::buffer<char>::append(const char*, const char*);

template FMT_API void internal::arg_map<format_context>::init(
    const basic_format_args<format_context>& args);

template FMT_API std::string internal::vformat<char>(
    string_view, basic_format_args<format_context>);

template FMT_API format_context::iterator internal::vformat_to(
    internal::buffer<char>&, string_view, basic_format_args<format_context>);

template FMT_API int internal::snprintf_float(double, int,
                                              internal::float_specs,
                                              internal::buffer<char>&);
template FMT_API int internal::snprintf_float(long double, int,
                                              internal::float_specs,
                                              internal::buffer<char>&);
template FMT_API int internal::format_float(double, int, internal::float_specs,
                                            internal::buffer<char>&);
template FMT_API int internal::format_float(long double, int,
                                            internal::float_specs,
                                            internal::buffer<char>&);

// Explicit instantiations for wchar_t.

template FMT_API std::string internal::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);
template FMT_API wchar_t internal::decimal_point_impl(locale_ref);

template FMT_API void internal::buffer<wchar_t>::append(const wchar_t*,
                                                        const wchar_t*);

template FMT_API std::wstring internal::vformat<wchar_t>(
    wstring_view, basic_format_args<wformat_context>);
FMT_END_NAMESPACE
<commit_msg>Fix a clang-tidy warning<commit_after>// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
namespace internal {

template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
                 T value) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  if (precision > 100000)
    throw std::runtime_error(
        "fuzz mode - avoid large allocation inside snprintf");
#endif
  // Suppress the warning about nonliteral format string.
  int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
  return precision < 0 ? snprintf_ptr(buf, size, format, value)
                       : snprintf_ptr(buf, size, format, precision, value);
}
struct sprintf_specs {
  int precision;
  char type;
  bool alt : 1;

  template <typename Char>
  constexpr explicit sprintf_specs(basic_format_specs<Char> specs)
      : precision(specs.precision), type(specs.type), alt(specs.alt) {}

  constexpr bool has_precision() const { return precision >= 0; }
};

// This is deprecated and is kept only to preserve ABI compatibility.
template <typename Double>
char* sprintf_format(Double value, internal::buffer<char>& buf,
                     sprintf_specs specs) {
  // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
  FMT_ASSERT(buf.capacity() != 0, "empty buffer");

  // Build format string.
  enum { max_format_size = 10 };  // longest format: %#-*.*Lg
  char format[max_format_size];
  char* format_ptr = format;
  *format_ptr++ = '%';
  if (specs.alt || !specs.type) *format_ptr++ = '#';
  if (specs.precision >= 0) {
    *format_ptr++ = '.';
    *format_ptr++ = '*';
  }
  if (std::is_same<Double, long double>::value) *format_ptr++ = 'L';

  char type = specs.type;

  if (type == '%')
    type = 'f';
  else if (type == 0 || type == 'n')
    type = 'g';
#if FMT_MSC_VER
  if (type == 'F') {
    // MSVC's printf doesn't support 'F'.
    type = 'f';
  }
#endif
  *format_ptr++ = type;
  *format_ptr = '\0';

  // Format using snprintf.
  char* start = nullptr;
  char* decimal_point_pos = nullptr;
  for (;;) {
    std::size_t buffer_size = buf.capacity();
    start = &buf[0];
    int result =
        format_float(start, buffer_size, format, specs.precision, value);
    if (result >= 0) {
      unsigned n = internal::to_unsigned(result);
      if (n < buf.capacity()) {
        // Find the decimal point.
        auto* p = buf.data();
        auto* end = p + n;
        if (*p == '+' || *p == '-') ++p;
        if (specs.type != 'a' && specs.type != 'A') {
          while (p < end && *p >= '0' && *p <= '9') ++p;
          if (p < end && *p != 'e' && *p != 'E') {
            decimal_point_pos = p;
            if (!specs.type) {
              // Keep only one trailing zero after the decimal point.
              ++p;
              if (*p == '0') ++p;
              while (p != end && *p >= '1' && *p <= '9') ++p;
              char* where = p;
              while (p != end && *p == '0') ++p;
              if (p == end || *p < '0' || *p > '9') {
                if (p != end) std::memmove(where, p, to_unsigned(end - p));
                n -= static_cast<unsigned>(p - where);
              }
            }
          }
        }
        buf.resize(n);
        break;  // The buffer is large enough - continue with formatting.
      }
      buf.reserve(n + 1);
    } else {
      // If result is negative we ask to increase the capacity by at least 1,
      // but as std::vector, the buffer grows exponentially.
      buf.reserve(buf.capacity() + 1);
    }
  }
  return decimal_point_pos;
}
}  // namespace internal

template FMT_API char* internal::sprintf_format(double, internal::buffer<char>&,
                                                sprintf_specs);
template FMT_API char* internal::sprintf_format(long double,
                                                internal::buffer<char>&,
                                                sprintf_specs);

template struct FMT_INSTANTIATION_DEF_API internal::basic_data<void>;

// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, internal::float_specs,
                                internal::buffer<char>&) =
    internal::format_float;

#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API internal::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale internal::locale_ref::get<std::locale>() const;
#endif

// Explicit instantiations for char.

template FMT_API std::string internal::grouping_impl<char>(locale_ref);
template FMT_API char internal::thousands_sep_impl(locale_ref);
template FMT_API char internal::decimal_point_impl(locale_ref);

template FMT_API void internal::buffer<char>::append(const char*, const char*);

template FMT_API void internal::arg_map<format_context>::init(
    const basic_format_args<format_context>& args);

template FMT_API std::string internal::vformat<char>(
    string_view, basic_format_args<format_context>);

template FMT_API format_context::iterator internal::vformat_to(
    internal::buffer<char>&, string_view, basic_format_args<format_context>);

template FMT_API int internal::snprintf_float(double, int,
                                              internal::float_specs,
                                              internal::buffer<char>&);
template FMT_API int internal::snprintf_float(long double, int,
                                              internal::float_specs,
                                              internal::buffer<char>&);
template FMT_API int internal::format_float(double, int, internal::float_specs,
                                            internal::buffer<char>&);
template FMT_API int internal::format_float(long double, int,
                                            internal::float_specs,
                                            internal::buffer<char>&);

// Explicit instantiations for wchar_t.

template FMT_API std::string internal::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);
template FMT_API wchar_t internal::decimal_point_impl(locale_ref);

template FMT_API void internal::buffer<wchar_t>::append(const wchar_t*,
                                                        const wchar_t*);

template FMT_API std::wstring internal::vformat<wchar_t>(
    wstring_view, basic_format_args<wformat_context>);
FMT_END_NAMESPACE
<|endoftext|>


<commit_before>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.1.0, packaged on March, 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib 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 General Public License for more details.

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

*****************************************************************************/

//! \file GLC_Object.cpp Implementation of the GLC_Object class.

#include "glc_object.h"

//////////////////////////////////////////////////////////////////////
// Constructor/Destructor
//////////////////////////////////////////////////////////////////////

GLC_Object::GLC_Object(const QString& name)
: m_QUuid(QUuid::createUuid())
, m_Uid(glc::GLC_GenID())	// Object ID
, m_Name(name)			// Object Name
{

}
// Copy constructor
GLC_Object::GLC_Object(const GLC_Object& sourceObject)
: m_QUuid(sourceObject.m_QUuid)
, m_Uid(sourceObject.m_Uid)
, m_Name(sourceObject.m_Name)
{
}

GLC_Object::~GLC_Object()
{

}

//////////////////////////////////////////////////////////////////////
// Get function
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Set function
//////////////////////////////////////////////////////////////////////

// Assignement operator
GLC_Object &GLC_Object::operator=(const GLC_Object& object)
{
	if (&object != this)
	{
		m_QUuid= object.m_QUuid;
		m_Uid= object.m_Uid;
		m_Name= object.m_Name;
	}
	return *this;
}

<commit_msg>Code optimisation in assignement operator.<commit_after>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.1.0, packaged on March, 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib 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 General Public License for more details.

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

*****************************************************************************/

//! \file GLC_Object.cpp Implementation of the GLC_Object class.

#include "glc_object.h"

//////////////////////////////////////////////////////////////////////
// Constructor/Destructor
//////////////////////////////////////////////////////////////////////

GLC_Object::GLC_Object(const QString& name)
: m_QUuid(QUuid::createUuid())
, m_Uid(glc::GLC_GenID())	// Object ID
, m_Name(name)			// Object Name
{

}
// Copy constructor
GLC_Object::GLC_Object(const GLC_Object& sourceObject)
: m_QUuid(sourceObject.m_QUuid)
, m_Uid(sourceObject.m_Uid)
, m_Name(sourceObject.m_Name)
{
}

GLC_Object::~GLC_Object()
{

}

//////////////////////////////////////////////////////////////////////
// Get function
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Set function
//////////////////////////////////////////////////////////////////////

// Assignement operator
GLC_Object &GLC_Object::operator=(const GLC_Object& object)
{
	m_QUuid= object.m_QUuid;
	m_Uid= object.m_Uid;
	m_Name= object.m_Name;
	return *this;
}

<|endoftext|>


<commit_before>/*
	main.cpp
	the entrence of the app
*/

#include <basic\common.h>
#include <basic\command_line.h>
#include <basic\stop_watch.h>
#include <basic\process.h>
#include <mesh\mesh.h>
#include <mesh\mesh_io.h>
#include <cuda\cuda_common.h>
#include <cuda\cuda_rvd.h>
#include <cuda\cuda_knn.h>

#include <ctime>

#define KNN

int main(int argc, char** argv){
	using namespace Gpu_Rvd;
	Process::initialize();

	srand((unsigned int)time(0));
	const index_t iteration = 1;

	StopWatch S("total task");
	std::vector<std::string> filenames;
	if (!Cmd::parse_argu(argc, argv, filenames)){
		fprintf(stderr, "failed to parse the argument!");
		return 1;
	}

	std::string mesh_filename = filenames[0];
	std::string points_filename = filenames[0];
	std::string output_filename;
	if (filenames.size() >= 2) {
		points_filename = filenames[1];
	}
	output_filename = (filenames.size() == 3) ? filenames[2] : "C:\\Users\\JWhan\\Desktop\\DATA\\out.eobj";

	Mesh M_in;
	Points Points_in;

	if (!mesh_load_obj(mesh_filename, M_in)){
		fprintf(stderr, "cannot load the mesh from the %s path", mesh_filename);
		return 1;
	}
	points_filename = "C:\\Users\\JWhan\\Desktop\\DATA\\before.xyz";
	//points_filename = "D:\\Project\\Models\\S2.obj";
	std::vector<int> sample_facet;

	/*if (!points_load_obj(points_filename, Points_in)){
		fprintf(stderr, "cannot load the points from the %s path", points_filename);
		return 1;
	}*/

	if (!points_load_xyz(points_filename, Points_in, sample_facet)){
		fprintf(stderr, "cannot load the points from the %s path", points_filename);
		return 1;
	}
	//sample_facet.resize(Points_in.get_vertex_nb());
	//M_in.init_samples(Points_in, 1000, sample_facet);

	if (!points_save_xyz(output_filename, Points_in, sample_facet)){
		std::cerr << "cannot save the points data" << std::endl;
		return 1;
	}
	/*if (!points_save(output_filename, Points_in)){
		std::cerr << "cannot save the points data" << std::endl;
		return 1;
	}*/

	//default settings: k = 20, store_mode
	CudaRestrictedVoronoiDiagram rvd(&M_in, &Points_in, iteration, sample_facet);
	rvd.compute_Rvd();

	S.print_elaspsed_time(std::cout);
	Process::terminate();
	return 0;
}<commit_msg>some changes on main function for testing<commit_after>/*
	main.cpp
	the entrence of the app
*/

#include <basic\common.h>
#include <basic\command_line.h>
#include <basic\stop_watch.h>
#include <basic\process.h>
#include <mesh\mesh.h>
#include <mesh\mesh_io.h>
#include <cuda\cuda_common.h>
#include <cuda\cuda_rvd.h>
#include <cuda\cuda_knn.h>

#include <ctime>

#define KNN

int main(int argc, char** argv){
	using namespace Gpu_Rvd;
	Process::initialize();

	srand((unsigned int)time(0));
	StopWatch S("total task");
	for (int iter = 0; iter < 1; ++iter){
		const index_t iteration = 100;
		std::vector<std::string> filenames;
		if (!Cmd::parse_argu(argc, argv, filenames)){
			fprintf(stderr, "failed to parse the argument!");
			return 1;
		}

		std::string mesh_filename = filenames[0];
		std::string points_filename = filenames[0];
		std::string output_filename;
		if (filenames.size() >= 2) {
			points_filename = filenames[1];
		}
		output_filename = (filenames.size() == 3) ? filenames[2] : "C:\\Users\\JWhan\\Desktop\\DATA\\out.eobj";

		Mesh M_in;
		Points Points_in;

		if (!mesh_load_obj(mesh_filename, M_in)){
			fprintf(stderr, "cannot load the mesh from the %s path", mesh_filename);
			return 1;
		}
		points_filename = "C:\\Users\\JWhan\\Desktop\\DATA\\before.xyz";
		//points_filename = "D:\\Project\\Models\\S2.obj";
		std::vector<int> sample_facet;

		/*if (!points_load_obj(points_filename, Points_in)){
			fprintf(stderr, "cannot load the points from the %s path", points_filename);
			return 1;
			}*/

		if (!points_load_xyz(points_filename, Points_in, sample_facet)){
			fprintf(stderr, "cannot load the points from the %s path", points_filename);
			return 1;
			}
		//sample_facet.resize(Points_in.get_vertex_nb());
		//M_in.init_samples(Points_in, 2000, sample_facet);

		/*if (!points_save_xyz(output_filename, Points_in, sample_facet)){
			std::cerr << "cannot save the points data" << std::endl;
			return 1;
		}*/
		/*if (!points_save(output_filename, Points_in)){
			std::cerr << "cannot save the points data" << std::endl;
			return 1;
			}*/

		//default settings: k = 20, store_mode
		CudaRestrictedVoronoiDiagram rvd(&M_in, &Points_in, iteration, sample_facet);
		rvd.compute_Rvd();
	}
	S.print_elaspsed_time(std::cout);
	Process::terminate();
	return 0;
}<|endoftext|>


<commit_before>#include "warnings-disable.h"

WARNINGS_DISABLE
#include <QtTest/QtTest>

#include <QSettings>

#include "ui_setupdialog.h"
WARNINGS_ENABLE

#include "../qtest-platform.h"

#include "utils.h"

#include <TSettings.h>

#include "compare-settings.h"

#include "setupdialog.h"

#define GET_UI_PAGE(x, PAGETYPE)                                               \
    do                                                                         \
    {                                                                          \
        x = wizard->get_ui();                                                  \
    } while(0)

#define GET_BUTTON(x) wizard->button(SetupDialog::x)

class TestSetupWizard : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();

    void do_nothing();
    void normal_install();
    void cancel_install();
    void skip_install();
    void cli();
    void version_too_low();

private:
    void helper_almost_normal_install(SetupDialog *wizard);
};

void TestSetupWizard::initTestCase()
{
    QCoreApplication::setOrganizationName(TEST_NAME);

    // Use a custom message handler to filter out unwanted messages
    IF_NOT_VISUAL { qInstallMessageHandler(offscreenMessageOutput); }
}

void TestSetupWizard::cleanupTestCase()
{
    TSettings::destroy();

    // Wait up to 5 seconds to delete objects scheduled with ->deleteLater()
    QCoreApplication::processEvents(QEventLoop::AllEvents, 5000);
}

void TestSetupWizard::do_nothing()
{
    SetupDialog *wizard = new SetupDialog();

    // This test is intended to help debug memory leaks.
    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    delete wizard;
}

void TestSetupWizard::helper_almost_normal_install(SetupDialog *wizard)
{
    QSignalSpy sig_cli(wizard, SIGNAL(tarsnapVersionRequested()));
    QSignalSpy sig_register(wizard,
                            SIGNAL(registerMachineRequested(QString, bool)));

    Ui::SetupDialog *ui_cli;
    Ui::SetupDialog *ui_register;

    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    // Page 1
    QVERIFY(wizard->pageTitle() == "Setup wizard");
    GET_BUTTON(NextButton)->click();
    VISUAL_WAIT;

    // Page 2
    QVERIFY(wizard->pageTitle() == "Command-line utilities");
    GET_UI_PAGE(ui_cli, CliPage);
    VISUAL_WAIT;

    // Fake the CLI detection and checking
    QVERIFY(sig_cli.count() == 1);
    wizard->tarsnapVersionResponse(TaskStatus::Completed, "X.Y.Z");
    QVERIFY(ui_cli->cliValidationLabel->text().contains("Tarsnap CLI version"));
    VISUAL_WAIT;

    // Proceed
    GET_BUTTON(NextButton)->click();
    VISUAL_WAIT;

    // Page 3
    QVERIFY(wizard->pageTitle() == "Register with server");
    GET_UI_PAGE(ui_register, RegisterPage);

    // Pretend that we already have a key
    ui_register->useExistingKeyfileButton->click();
    ui_register->machineKeyCombo->setCurrentText("empty.key");
    VISUAL_WAIT;

    // Pretend to register
    GET_BUTTON(NextButton)->click();
    QVERIFY(sig_register.count() == 1);
    wizard->updateLoadingAnimation(false);
    VISUAL_WAIT;

    // Fake a response
    wizard->registerMachineResponse(TaskStatus::Completed, "");
    VISUAL_WAIT;

    // Wait for the test to proceed (for up to 1 second)
    for(int i = 0; i < 10; i++)
    {
        if(wizard->pageTitle() == "Setup complete!")
            break;
        QTest::qWait(100);
    }

    // Page 4
    QVERIFY(wizard->pageTitle() == "Setup complete!");
    VISUAL_WAIT;
}

void TestSetupWizard::normal_install()
{
    TARSNAP_CLI_OR_SKIP;

    SetupDialog *wizard = new SetupDialog();

    // Almost complete a normal install
    helper_almost_normal_install(wizard);

    // Finish the install
    GET_BUTTON(FinishButton)->click();
    VISUAL_WAIT;

    // Check resulting init file.  The first can be in any format (for now).
    TSettings settings;
    QSettings target("after-normal-install.conf", QSettings::IniFormat);
    QVERIFY(compareSettings(settings.getQSettings(), &target));

    // Clean up
    delete wizard;
}

void TestSetupWizard::cancel_install()
{
    TARSNAP_CLI_OR_SKIP;

    SetupDialog *wizard = new SetupDialog();

    // Almost complete a normal install
    helper_almost_normal_install(wizard);

    // Close before we actually finish
    QTest::keyEvent(QTest::Click, wizard, Qt::Key_Escape);
    VISUAL_WAIT;

    // Clean up
    delete wizard;

    // Check that we wiped the Tarsnap-related settings
    TSettings  settings;
    QSettings *q = settings.getQSettings();
    q->beginGroup("tarsnap");
    QVERIFY(q->allKeys().length() == 0);
    q->beginGroup("app");
    QVERIFY(q->allKeys().length() == 0);
}

void TestSetupWizard::skip_install()
{
    TARSNAP_CLI_OR_SKIP;

    SetupDialog *wizard = new SetupDialog();

    // Almost complete a normal install
    helper_almost_normal_install(wizard);

    // Now go back to the beginning and skip the install
    GET_BUTTON(BackButton)->click();
    GET_BUTTON(BackButton)->click();
    GET_BUTTON(BackButton)->click();
    VISUAL_WAIT;

    GET_BUTTON(SkipButton)->click();
    VISUAL_WAIT;

    // Check resulting init file.
    TSettings settings;
    QSettings target("after-skip-install.conf", QSettings::IniFormat);
    QVERIFY(compareSettings(settings.getQSettings(), &target));

    // Clean up
    delete wizard;
}

void TestSetupWizard::cli()
{
    SetupDialog *    wizard = new SetupDialog();
    Ui::SetupDialog *ui_cli;

    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    // Advance to CLI page and expand advanced options
    GET_BUTTON(NextButton)->click();
    QVERIFY(wizard->pageTitle() == "Command-line utilities");
    GET_UI_PAGE(ui_cli, CliPage);
    VISUAL_WAIT;

    // We may or may not receive a version query, depending on whether
    // tarsnap is installed, so don't check for this here.
    // (We check "did we receive a version-query signal" in other
    // tarsnap-dependent tests.)
    wizard->tarsnapVersionResponse(TaskStatus::Completed, "X.Y.Z");
    VISUAL_WAIT;

    // App data directory
    ui_cli->appdataPathLineBrowse->setText("fake-dir");
    QVERIFY(ui_cli->cliValidationLabel->text()
            == "Invalid App data directory set.");
    VISUAL_WAIT;
    ui_cli->appdataPathLineBrowse->setText("/tmp");

    // Cache directory
    ui_cli->cachePathLineBrowse->setText("fake-dir");
    QVERIFY(ui_cli->cliValidationLabel->text()
            == "Invalid Tarsnap cache directory set.");
    VISUAL_WAIT;
    ui_cli->cachePathLineBrowse->setText("/tmp");

    // Tarsnap CLI directory
    ui_cli->cliPathLineBrowse->setText("fake-dir");
    QVERIFY(ui_cli->cliValidationLabel->text().contains(
        "Tarsnap utilities not found."));
    VISUAL_WAIT;
    ui_cli->cliPathLineBrowse->setText("/tmp");

    // Fake detecting the binaries
    wizard->tarsnapVersionResponse(TaskStatus::Completed, "X.Y.Z");
    QVERIFY(ui_cli->cliValidationLabel->text().contains("Tarsnap CLI version"));
    VISUAL_WAIT;

    delete wizard;
}

void TestSetupWizard::version_too_low()
{
    SetupDialog *    wizard = new SetupDialog();
    Ui::SetupDialog *ui_cli;

    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    // Advance to CLI page
    GET_BUTTON(NextButton)->click();
    QVERIFY(wizard->pageTitle() == "Command-line utilities");
    GET_UI_PAGE(ui_cli, CliPage);
    VISUAL_WAIT;

    // Fake detecting the binaries with a too-low version number
    wizard->tarsnapVersionResponse(TaskStatus::VersionTooLow, "1.0.1");
    QVERIFY(ui_cli->cliValidationLabel->text().contains("too low"));
    QVERIFY(GET_BUTTON(NextButton)->isEnabled() == false);
    QVERIFY(ui_cli->cliAdvancedWidget->isVisible() == true);
    VISUAL_WAIT;

    delete wizard;
}

QTEST_MAIN(TestSetupWizard)
#include "test-setupwizard.moc"
<commit_msg>test/setupwizard: change order of functions<commit_after>#include "warnings-disable.h"

WARNINGS_DISABLE
#include <QtTest/QtTest>

#include <QSettings>

#include "ui_setupdialog.h"
WARNINGS_ENABLE

#include "../qtest-platform.h"

#include "utils.h"

#include <TSettings.h>

#include "compare-settings.h"

#include "setupdialog.h"

#define GET_UI_PAGE(x, PAGETYPE)                                               \
    do                                                                         \
    {                                                                          \
        x = wizard->get_ui();                                                  \
    } while(0)

#define GET_BUTTON(x) wizard->button(SetupDialog::x)

class TestSetupWizard : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();

    void do_nothing();
    void cli();
    void version_too_low();
    void cancel_install();
    void skip_install();
    void normal_install();

private:
    void helper_almost_normal_install(SetupDialog *wizard);
};

void TestSetupWizard::initTestCase()
{
    QCoreApplication::setOrganizationName(TEST_NAME);

    // Use a custom message handler to filter out unwanted messages
    IF_NOT_VISUAL { qInstallMessageHandler(offscreenMessageOutput); }
}

void TestSetupWizard::cleanupTestCase()
{
    TSettings::destroy();

    // Wait up to 5 seconds to delete objects scheduled with ->deleteLater()
    QCoreApplication::processEvents(QEventLoop::AllEvents, 5000);
}

void TestSetupWizard::do_nothing()
{
    SetupDialog *wizard = new SetupDialog();

    // This test is intended to help debug memory leaks.
    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    delete wizard;
}

void TestSetupWizard::helper_almost_normal_install(SetupDialog *wizard)
{
    QSignalSpy sig_cli(wizard, SIGNAL(tarsnapVersionRequested()));
    QSignalSpy sig_register(wizard,
                            SIGNAL(registerMachineRequested(QString, bool)));

    Ui::SetupDialog *ui_cli;
    Ui::SetupDialog *ui_register;

    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    // Page 1
    QVERIFY(wizard->pageTitle() == "Setup wizard");
    GET_BUTTON(NextButton)->click();
    VISUAL_WAIT;

    // Page 2
    QVERIFY(wizard->pageTitle() == "Command-line utilities");
    GET_UI_PAGE(ui_cli, CliPage);
    VISUAL_WAIT;

    // Fake the CLI detection and checking
    QVERIFY(sig_cli.count() == 1);
    wizard->tarsnapVersionResponse(TaskStatus::Completed, "X.Y.Z");
    QVERIFY(ui_cli->cliValidationLabel->text().contains("Tarsnap CLI version"));
    VISUAL_WAIT;

    // Proceed
    GET_BUTTON(NextButton)->click();
    VISUAL_WAIT;

    // Page 3
    QVERIFY(wizard->pageTitle() == "Register with server");
    GET_UI_PAGE(ui_register, RegisterPage);

    // Pretend that we already have a key
    ui_register->useExistingKeyfileButton->click();
    ui_register->machineKeyCombo->setCurrentText("empty.key");
    VISUAL_WAIT;

    // Pretend to register
    GET_BUTTON(NextButton)->click();
    QVERIFY(sig_register.count() == 1);
    wizard->updateLoadingAnimation(false);
    VISUAL_WAIT;

    // Fake a response
    wizard->registerMachineResponse(TaskStatus::Completed, "");
    VISUAL_WAIT;

    // Wait for the test to proceed (for up to 1 second)
    for(int i = 0; i < 10; i++)
    {
        if(wizard->pageTitle() == "Setup complete!")
            break;
        QTest::qWait(100);
    }

    // Page 4
    QVERIFY(wizard->pageTitle() == "Setup complete!");
    VISUAL_WAIT;
}

void TestSetupWizard::normal_install()
{
    TARSNAP_CLI_OR_SKIP;

    SetupDialog *wizard = new SetupDialog();

    // Almost complete a normal install
    helper_almost_normal_install(wizard);

    // Finish the install
    GET_BUTTON(FinishButton)->click();
    VISUAL_WAIT;

    // Check resulting init file.  The first can be in any format (for now).
    TSettings settings;
    QSettings target("after-normal-install.conf", QSettings::IniFormat);
    QVERIFY(compareSettings(settings.getQSettings(), &target));

    // Clean up
    delete wizard;
}

void TestSetupWizard::cancel_install()
{
    TARSNAP_CLI_OR_SKIP;

    SetupDialog *wizard = new SetupDialog();

    // Almost complete a normal install
    helper_almost_normal_install(wizard);

    // Close before we actually finish
    QTest::keyEvent(QTest::Click, wizard, Qt::Key_Escape);
    VISUAL_WAIT;

    // Clean up
    delete wizard;

    // Check that we wiped the Tarsnap-related settings
    TSettings  settings;
    QSettings *q = settings.getQSettings();
    q->beginGroup("tarsnap");
    QVERIFY(q->allKeys().length() == 0);
    q->beginGroup("app");
    QVERIFY(q->allKeys().length() == 0);
}

void TestSetupWizard::skip_install()
{
    TARSNAP_CLI_OR_SKIP;

    SetupDialog *wizard = new SetupDialog();

    // Almost complete a normal install
    helper_almost_normal_install(wizard);

    // Now go back to the beginning and skip the install
    GET_BUTTON(BackButton)->click();
    GET_BUTTON(BackButton)->click();
    GET_BUTTON(BackButton)->click();
    VISUAL_WAIT;

    GET_BUTTON(SkipButton)->click();
    VISUAL_WAIT;

    // Check resulting init file.
    TSettings settings;
    QSettings target("after-skip-install.conf", QSettings::IniFormat);
    QVERIFY(compareSettings(settings.getQSettings(), &target));

    // Clean up
    delete wizard;
}

void TestSetupWizard::cli()
{
    SetupDialog *    wizard = new SetupDialog();
    Ui::SetupDialog *ui_cli;

    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    // Advance to CLI page and expand advanced options
    GET_BUTTON(NextButton)->click();
    QVERIFY(wizard->pageTitle() == "Command-line utilities");
    GET_UI_PAGE(ui_cli, CliPage);
    VISUAL_WAIT;

    // We may or may not receive a version query, depending on whether
    // tarsnap is installed, so don't check for this here.
    // (We check "did we receive a version-query signal" in other
    // tarsnap-dependent tests.)
    wizard->tarsnapVersionResponse(TaskStatus::Completed, "X.Y.Z");
    VISUAL_WAIT;

    // App data directory
    ui_cli->appdataPathLineBrowse->setText("fake-dir");
    QVERIFY(ui_cli->cliValidationLabel->text()
            == "Invalid App data directory set.");
    VISUAL_WAIT;
    ui_cli->appdataPathLineBrowse->setText("/tmp");

    // Cache directory
    ui_cli->cachePathLineBrowse->setText("fake-dir");
    QVERIFY(ui_cli->cliValidationLabel->text()
            == "Invalid Tarsnap cache directory set.");
    VISUAL_WAIT;
    ui_cli->cachePathLineBrowse->setText("/tmp");

    // Tarsnap CLI directory
    ui_cli->cliPathLineBrowse->setText("fake-dir");
    QVERIFY(ui_cli->cliValidationLabel->text().contains(
        "Tarsnap utilities not found."));
    VISUAL_WAIT;
    ui_cli->cliPathLineBrowse->setText("/tmp");

    // Fake detecting the binaries
    wizard->tarsnapVersionResponse(TaskStatus::Completed, "X.Y.Z");
    QVERIFY(ui_cli->cliValidationLabel->text().contains("Tarsnap CLI version"));
    VISUAL_WAIT;

    delete wizard;
}

void TestSetupWizard::version_too_low()
{
    SetupDialog *    wizard = new SetupDialog();
    Ui::SetupDialog *ui_cli;

    VISUAL_INIT(wizard);
    IF_NOT_VISUAL { wizard->open(); }

    // Advance to CLI page
    GET_BUTTON(NextButton)->click();
    QVERIFY(wizard->pageTitle() == "Command-line utilities");
    GET_UI_PAGE(ui_cli, CliPage);
    VISUAL_WAIT;

    // Fake detecting the binaries with a too-low version number
    wizard->tarsnapVersionResponse(TaskStatus::VersionTooLow, "1.0.1");
    QVERIFY(ui_cli->cliValidationLabel->text().contains("too low"));
    QVERIFY(GET_BUTTON(NextButton)->isEnabled() == false);
    QVERIFY(ui_cli->cliAdvancedWidget->isVisible() == true);
    VISUAL_WAIT;

    delete wizard;
}

QTEST_MAIN(TestSetupWizard)
#include "test-setupwizard.moc"
<|endoftext|>


<commit_before>/*

    Copyright Eli Dupree and Isaac Dupree, 2011, 2012

    This file is part of Lasercake.

    Lasercake is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Lasercake 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef LASERCAKE_INPUT_REPRESENTATION_HPP__
#define LASERCAKE_INPUT_REPRESENTATION_HPP__

#include <algorithm>
#include <set>
#include <vector>

namespace input_representation {

// We abstract from the GUI toolkit so that we can serialize the user-input
// during a frame,
// transfer it over the network consistently,
// change toolkit or support multiple at once if needed,
// and allow simulation code to have a predictable representation of
// input without including any GUI-toolkit headers
// (because the input we need is simple enough that it does not need
// the full force of a GUI toolkit).

// often just a single Unicode character
typedef std::string key_type;

namespace special_keys {
const key_type left_arrow = "←";
const key_type up_arrow = "↑";
const key_type right_arrow = "→";
const key_type down_arrow = "↓";
// Modifier keys? Naming them cross-platform?
// Is this meant for display to the user? storage in persistent save-files?
// which purposes?  (TODO figure these out if we need them)
}

enum pressed_or_released { PRESSED, RELEASED };
typedef std::set<key_type> keys_currently_pressed_t;
typedef std::pair<key_type, pressed_or_released> key_change_t;
typedef std::vector<key_change_t> key_activity_t;

inline bool is_currently_pressed(keys_currently_pressed_t const& keys, key_type const& k) {
  return (keys.find(k) != keys.end());
}
inline bool not_currently_pressed(keys_currently_pressed_t const& keys, key_type const& k) {
  return (keys.find(k) == keys.end());
}
inline int32_t num_times_pressed(key_activity_t const& activity, key_type const& k) {
  return std::count(activity.begin(), activity.end(), key_change_t(k, PRESSED));
}
inline int32_t num_times_released(key_activity_t const& activity, key_type const& k) {
  return std::count(activity.begin(), activity.end(), key_change_t(k, RELEASED));
}

class input_news_t {
public:
  // The default constructor is no keys pressed.
  input_news_t() {}

  input_news_t(
    keys_currently_pressed_t const& keys_currently_pressed,
    key_activity_t const& key_activity_since_last_frame
  ) :
    keys_currently_pressed_(keys_currently_pressed),
    key_activity_since_last_frame_(key_activity_since_last_frame) {}

  static input_news_t merge_immediate_sequence(input_news_t const& directly_prior, input_news_t const& directly_hence) {
    input_news_t result;
    result.keys_currently_pressed_ = directly_hence.keys_currently_pressed_;
    result.key_activity_since_last_frame_.insert(
        result.key_activity_since_last_frame_.end(),
        directly_prior.key_activity_since_last_frame_.begin(), directly_prior.key_activity_since_last_frame_.end());
    result.key_activity_since_last_frame_.insert(
        result.key_activity_since_last_frame_.end(),
        directly_hence.key_activity_since_last_frame_.begin(), directly_hence.key_activity_since_last_frame_.end());
    return result;
  }

  // These are generally useful for continuous actions (e.g. if you're
  // moving forwards while you hold down a key).
  //
  // Worst-case O(log(n)) time where "n" is the number of keys currently pressed.
  bool is_currently_pressed(key_type const& k)const {
    return input_representation::is_currently_pressed(keys_currently_pressed_, k);
  }
  bool not_currently_pressed(key_type const& k)const {
    return input_representation::not_currently_pressed(keys_currently_pressed_, k);
  }

  // These are generally useful for instantaneous actions (e.g. if you
  // launch an atomic missile each time you hit a certain key).  Note that a
  // key might have been pressed and released any number of times in-between frames
  // without being currently pressed at the moment that any frame happens.
  //
  // O(n) in number of keys pressed since last frame (TODO fix if there are ever
  // more than O(1) times that the game reads this per frame.).
  int32_t num_times_pressed(key_type const& k)const {
    return input_representation::num_times_pressed(key_activity_since_last_frame_, k);
  }
  int32_t num_times_released(key_type const& k)const {
    return input_representation::num_times_released(key_activity_since_last_frame_, k);
  }

  keys_currently_pressed_t const& keys_currently_pressed()const { return keys_currently_pressed_; }
  key_activity_t const& key_activity_since_last_frame()const { return key_activity_since_last_frame_; }

  // TODO mouse input (in some form that works despite the fact that users can have different window/screen sizes)

private:
  keys_currently_pressed_t keys_currently_pressed_;
  key_activity_t key_activity_since_last_frame_;
};

} //end namespace input_representation

#endif
<commit_msg>comment input_representation a bit better<commit_after>/*

    Copyright Eli Dupree and Isaac Dupree, 2011, 2012

    This file is part of Lasercake.

    Lasercake is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Lasercake 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lasercake.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef LASERCAKE_INPUT_REPRESENTATION_HPP__
#define LASERCAKE_INPUT_REPRESENTATION_HPP__

#include <algorithm>
#include <set>
#include <vector>

namespace input_representation {

// We abstract from the GUI toolkit so that we can serialize the user-input
// during a frame,
// transfer it over the network consistently,
// change toolkit or support multiple at once if needed,
// and allow simulation code to have a predictable representation of
// input without including any GUI-toolkit headers
// (because the input we need is simple enough that it does not need
// the full force of a GUI toolkit).

// often just a single Unicode character
typedef std::string key_type;

#if 0
// these don't happen at present
namespace special_keys {
const key_type left_arrow = "←";
const key_type up_arrow = "↑";
const key_type right_arrow = "→";
const key_type down_arrow = "↓";
// Modifier keys? Naming them cross-platform?
// Is this meant for display to the user? storage in persistent save-files?
// which purposes?  (TODO figure these out if we need them)
}
#endif

enum pressed_or_released { PRESSED, RELEASED };
// Use set rather than unordered_set because
// (1) the total size is usually small, so it generally doesn't matter
// (2) users control their input very directly, and could intentionally trigger
//       unordered_set's worse-case O(n) time.
// (also, (3), if anything enumerates it, it's in a consistent order)
typedef std::set<key_type> keys_currently_pressed_t;
typedef std::pair<key_type, pressed_or_released> key_change_t;
typedef std::vector<key_change_t> key_activity_t;

inline bool is_currently_pressed(keys_currently_pressed_t const& keys, key_type const& k) {
  return (keys.find(k) != keys.end());
}
inline bool not_currently_pressed(keys_currently_pressed_t const& keys, key_type const& k) {
  return (keys.find(k) == keys.end());
}
inline int32_t num_times_pressed(key_activity_t const& activity, key_type const& k) {
  return std::count(activity.begin(), activity.end(), key_change_t(k, PRESSED));
}
inline int32_t num_times_released(key_activity_t const& activity, key_type const& k) {
  return std::count(activity.begin(), activity.end(), key_change_t(k, RELEASED));
}

class input_news_t {
public:
  // The default constructor is no keys pressed.
  input_news_t() {}

  input_news_t(
    keys_currently_pressed_t const& keys_currently_pressed,
    key_activity_t const& key_activity_since_last_frame
  ) :
    keys_currently_pressed_(keys_currently_pressed),
    key_activity_since_last_frame_(key_activity_since_last_frame) {}

  static input_news_t merge_immediate_sequence(input_news_t const& directly_prior, input_news_t const& directly_hence) {
    input_news_t result;
    result.keys_currently_pressed_ = directly_hence.keys_currently_pressed_;
    result.key_activity_since_last_frame_.insert(
        result.key_activity_since_last_frame_.end(),
        directly_prior.key_activity_since_last_frame_.begin(), directly_prior.key_activity_since_last_frame_.end());
    result.key_activity_since_last_frame_.insert(
        result.key_activity_since_last_frame_.end(),
        directly_hence.key_activity_since_last_frame_.begin(), directly_hence.key_activity_since_last_frame_.end());
    return result;
  }

  // These are generally useful for continuous actions (e.g. if you're
  // moving forwards while you hold down a key).
  //
  // Worst-case O(log(n)) time where "n" is the number of keys currently pressed.
  bool is_currently_pressed(key_type const& k)const {
    return input_representation::is_currently_pressed(keys_currently_pressed_, k);
  }
  bool not_currently_pressed(key_type const& k)const {
    return input_representation::not_currently_pressed(keys_currently_pressed_, k);
  }

  // These are generally useful for instantaneous actions (e.g. if you
  // launch an atomic missile each time you hit a certain key).  Note that a
  // key might have been pressed and released any number of times in-between frames
  // without being currently pressed at the moment that any frame happens.
  //
  // O(n) in number of keys pressed since last frame (TODO fix if there are ever
  // more than O(1) times that the game reads this per frame.).
  int32_t num_times_pressed(key_type const& k)const {
    return input_representation::num_times_pressed(key_activity_since_last_frame_, k);
  }
  int32_t num_times_released(key_type const& k)const {
    return input_representation::num_times_released(key_activity_since_last_frame_, k);
  }

  keys_currently_pressed_t const& keys_currently_pressed()const { return keys_currently_pressed_; }
  key_activity_t const& key_activity_since_last_frame()const { return key_activity_since_last_frame_; }

  // TODO mouse input (in some form that works despite the fact that users can have different window/screen sizes)

private:
  keys_currently_pressed_t keys_currently_pressed_;
  key_activity_t key_activity_since_last_frame_;
};

} //end namespace input_representation

#endif
<|endoftext|>


<commit_before>/*
* SEGS dbtool v0.1
* A database creation and management tool.
*/
#include <iostream>
#include <QtCore/QFileInfo>
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>
#include <QtCore/QCommandLineParser>
#include <QtSql/QtSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>

QString segs = "segs";
QString segs_game = "segs_game";

QTextStream& qout()
{
    static QTextStream ts( stdout );
    return ts;
}

bool fileExists(QString path)
{
    QFileInfo check_file("./" + path);
    return check_file.exists() && check_file.isFile();
}

void Pause(void)
{
    qout().flush();
    qout() << endl << "Press ENTER to continue...";
    qout().flush();
    std::cin.ignore(100000, '\n');  // Ignore characters until an ENTER (newline) is received.
    return;
}

int main(int argc, char **argv)
{
    QCoreApplication app(argc,argv);
    QCoreApplication::setApplicationName("segs-dbtool");
    QCoreApplication::setApplicationVersion("0.1");

    QCommandLineParser parser;
    parser.setApplicationDescription("SEGS database management utility");
    parser.addHelpOption();
    parser.addVersionOption();

    qout() << parser.applicationDescription() << " v" << QCoreApplication::applicationVersion() << endl << endl;

    parser.addPositionalArgument("file", QCoreApplication::translate("main", "Database Script file to import."));

    // A boolean option with multiple names (-f, --force)
    QCommandLineOption forceOption(QStringList() << "f" << "force",
        QCoreApplication::translate("main", "Overwrite existing database files. THIS CANNOT BE UNDONE."));
    parser.addOption(forceOption);

    parser.process(app);

    const QStringList args = parser.positionalArguments();

    bool forced = parser.isSet(forceOption);
    bool nofile = args.isEmpty();

    // Check if dbtool is being run from server directory
    qout() << "Checking current folder...";
    if(!fileExists("./authserver")) {
        qout() << "SEGS dbtool must be run from the SEGS root folder (where authserver resides)" << endl;
        Pause();
        return 0;
    }
    qout() << "OK" << endl;

    // Check if database already exists
    qout() << "Checking for existing databases..." << endl;
    if((fileExists(segs) || fileExists(segs_game)) && !forced) {
        if(fileExists(segs))
            qout() << "WARNING! Database " << segs << " already exists." << endl;
        if(fileExists(segs_game))
            qout() << "WARNING! Database " << segs_game << " already exists." << endl;
        qout() << "Run dbtool with -f option to overwrite existing databases. THIS CANNOT BE UNDONE." << endl;
        Pause();
        return 0;
    }

    qout() << "Creating database files...";
    QString db_path;
    if(nofile)
        db_path = "./input.sql";
    else
        db_path = args.at(0);

    // Should probably classify all of this so we can call it twice, once for segs and again for segs_game
    QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE" );
    db.setDatabaseName( "./output.sql" );

    if( !db.open() )
    {
      qDebug() << db.lastError();
      qFatal( "Failed to connect to database." );
    }

    qDebug( "Connected!" );
    qout() << "COMPLETED!!" << endl;

    QSqlQuery qry;
    QFile db_template(segs);
    if(db_template.open(QFile::ReadOnly))
        qry.exec(db_template.readAll());

    // Close our db
    db.close();

    Pause();
    return 0;
}
<commit_msg>dbtool v2, now with more qDebug and better import!<commit_after>/*
* SEGS dbtool v0.2 dated 2017-11-04
* A database creation and management tool.
*/
#include <iostream>
#include <QtCore/QFileInfo>
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>
#include <QtCore/QCommandLineParser>
#include <QtSql/QtSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>

QString segs = "segs";
QString segs_game = "segs_game";

QTextStream& qout()
{
    static QTextStream ts( stdout );
    return ts;
}

bool fileExists(QString path)
{
    QFileInfo check_file("./" + path);
    return check_file.exists() && check_file.isFile();
}

void Pause(void)
{
    qInfo() << endl << "Press ENTER to continue...";
    std::cin.ignore(100000, '\n');  // Ignore characters until an ENTER (newline) is received.
    return;
}

void errorHandler(QtMsgType type, const char *msg)
{
    switch (type) {
        case QtDebugMsg:
            fprintf(stderr, "%s\n", msg);
            break;
        case QtWarningMsg:
            fprintf(stderr, "\033[1;33mWarning\033[0m: %s\n", msg);
            break;
        case QtCriticalMsg:
            fprintf(stderr, "\033[31mCritical\033[0m: %s\n", msg);
            break;
        case QtFatalMsg:
            fprintf(stderr, "\033[31mFatal\033[0m: %s\n", msg);
            abort();
    }
}

int main(int argc, char **argv)
{
    qInstallMsgHandler(errorHandler);
    QCoreApplication app(argc,argv);
    QCoreApplication::setApplicationName("segs-dbtool");
    QCoreApplication::setApplicationVersion("0.2");

    QCommandLineParser parser;
    parser.setApplicationDescription("SEGS database management utility");
    parser.addHelpOption();
    parser.addVersionOption();

    qDebug() << parser.applicationDescription() << " v" << QCoreApplication::applicationVersion() << endl;

    parser.addPositionalArgument("file", QCoreApplication::translate("main", "Database Script file to import."));

    // A boolean option with multiple names (-f, --force)
    QCommandLineOption forceOption(QStringList() << "f" << "force",
        QCoreApplication::translate("main", "Overwrite existing database files. THIS CANNOT BE UNDONE."));
    parser.addOption(forceOption);

    parser.process(app);

    const QStringList args = parser.positionalArguments();

    bool forced = parser.isSet(forceOption);
    bool nofile = args.isEmpty();

    // Check if dbtool is being run from server directory
    qInfo() << "Checking current directory for authserver...";
    if(!fileExists("./authserver")) {
        qDebug() << "SEGS dbtool must be run from the SEGS root folder (where authserver resides)";
        Pause();
        return 0;
    }
    qInfo() << "OK";

    // Check if database already exists
    qInfo() << "Checking for existing databases...";
    if((fileExists(segs) || fileExists(segs_game)) && !forced) {
        if(fileExists(segs))
            qWarning() << "WARNING! Database " << segs << " already exists.";
        if(fileExists(segs_game))
            qWarning() << "WARNING! Database " << segs_game << " already exists.";
        qDebug() << "Run dbtool with -f option to overwrite existing databases. THIS CANNOT BE UNDONE.";
        Pause();
        return 0;
    }

    qInfo() << "Creating database files...";
    QStringList db_files;
    if(nofile)
        db_files << "./default_dbs/segs" << "./default_dbs/segs_game";
    else
        db_files << args;

    // Let's itterate over db_files and create database files
    for (int i = 0; i < db_files.size(); ++i)
    {
        QFile db_template(db_file.at(i));
        int last_slash = db_template.at(i).lastIndexOf('/',-1);
        QFile db_path("./" + db_template.at(i).midRef(last_slash+1,-1)); // filename only: ./segs

        // Otherwise, import contents of db_template into db_path
        QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE" );
        db.setDatabaseName( db_path );

        if( !db.open() )
        {
            qDebug() << db.lastError();
            qFatal() << "Failed to connect to database. Please check error messages for details.";
            Pause();
            return 0;
        }
        qDebug() << "Created new database!";

        QSqlQuery qry;
        if(db_template.open(QFile::ReadOnly))
            qry.exec(db_template.readAll());

        // Close our db
        db.close();
        qInfo() << "COMPLETED importing " << db_template << "!";
    }

    Pause();
    return 0;
}
<|endoftext|>


<commit_before>// @(#)root/gui:$Name:  $:$Id: TGPicture.cxx,v 1.5 2003/12/15 08:54:29 brun Exp $
// Author: Fons Rademakers   01/01/98

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
/**************************************************************************

    This source is based on Xclass95, a Win95-looking GUI toolkit.
    Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.

    Xclass95 is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

**************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGPicture & TGPicturePool                                            //
//                                                                      //
// The TGPicture class implements pictures and icons used in the        //
// different GUI elements and widgets. The TGPicturePool class          //
// implements a TGPicture cache. TGPictures are created, managed and    //
// destroyed by the TGPicturePool.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGPicture.h"
#include "TGResourcePool.h"
#include "THashTable.h"
#include "TSystem.h"
#include "TGWindow.h"
#include "TVirtualX.h"

TGGC *TGSelectedPicture::fgSelectedGC = 0;

ClassImp(TGPicture)
ClassImp(TGSelectedPicture)
ClassImp(TGPicturePool)

//______________________________________________________________________________
const TGPicture *TGPicturePool::GetPicture(const char *name)
{
   // Get a picture from the picture pool. Picture must be freed using
   // TGPicturePool::FreePicture(). If picture is not found 0 is returned.

   if (!fPicList)
      fPicList = new THashTable(50);

   TString pname = name;

   if (pname.EndsWith(".xpm")) {
      pname = gSystem->ExpandPathName(gSystem->UnixPathName(pname.Data()));
   }
   TGPicture *pic;

   pic = (TGPicture *)fPicList->FindObject(pname.Data());
   if (pic && !pic->IsScaled()) {
      if (pic->fPic == kNone)
         return 0;
      pic->AddReference();
      return pic;
   }

   pic = new TGPicture(pname.Data());
   pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
   pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
   pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;

   char *picnam = gSystem->Which(fPath.Data(), pname.Data(), kReadPermission);
   if (!picnam) {
      fPicList->Add(pic);
      return 0;
   }

   if (gVirtualX->CreatePictureFromFile(fClient->GetDefaultRoot()->GetId(), picnam,
                                    pic->fPic, pic->fMask,
                                    pic->fAttributes)) {
      fPicList->Add(pic);
   } else {
      delete pic;
      pic = new TGPicture(name);
      fPicList->Add(pic);
      pic = 0;
   }

   delete [] picnam;

   return pic;
}

//______________________________________________________________________________
const TGPicture *TGPicturePool::GetPicture(const char *name,
                                           UInt_t new_width, UInt_t new_height)
{
   // Get picture with specified size from pool (picture will be scaled if
   // necessary). Picture must be freed using TGPicturePool::FreePicture(). If
   // picture is not found 0 is returned.

   if (!fPicList)
      fPicList = new THashTable(50);

   TString pname = name;

   if (pname.EndsWith(".xpm")) {
      pname = gSystem->ExpandPathName(gSystem->UnixPathName(pname.Data()));
   }

   TGPicture *pic;

   const char *hname = TGPicture::HashName(pname.Data(), new_width, new_height);
   pic = (TGPicture *)fPicList->FindObject(hname);
   if (pic && pic->GetWidth() == new_width && pic->GetHeight() == new_height) {
      if (pic->fPic == kNone)
         return 0;
      pic->AddReference();
      return pic;
   }

   pic = new TGPicture(hname, kTRUE);
   pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
   pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
   pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;

   char *picnam = gSystem->Which(fPath.Data(), pname.Data(), kReadPermission);
   if (!picnam) {
      pic->fAttributes.fWidth  = new_width;
      pic->fAttributes.fHeight = new_height;
      fPicList->Add(pic);
      return 0;
   }

#ifndef GDK_WIN32
   char **data;
   if (!gVirtualX->ReadPictureDataFromFile(picnam, &data)) {
      delete pic;
      delete [] picnam;
      return 0;
   }
   delete [] picnam;

   Int_t    colors, chars, headersize, totalheight;
   UInt_t   width, height;
   Double_t xscale, yscale;
   Bool_t   retc;

   sscanf(data[0], "%u %u %d %d", &width, &height, &colors, &chars);
   headersize = colors + 1;
   yscale = (Double_t) new_height / (Double_t) height;
   xscale = (Double_t) new_width / (Double_t) width;
   totalheight = (colors + new_height + 1);

   if ((width != new_width) || (height != new_height)) {
      char **smalldata;
      Int_t    i, x1, y1, pixels;
      Double_t x, y;

      smalldata = new char* [totalheight + 1];

      smalldata[0] = new char[30];
      for (i = 1; i < headersize; i++)
         smalldata[i] = new char [strlen(data[i]) + 1];

      for (i = headersize; i < totalheight + 1; i++)
         smalldata[i] = new char[(new_width * chars) + 1];

      sprintf(smalldata[0], "%u %u %d %d", new_width, new_height, colors, chars);

      for (i = 1; i < headersize; i++) strcpy(smalldata[i], data[i]);

      y = headersize;
      for (y1 = headersize; y1 < (Int_t)new_height + headersize; y1++) {
         x = 0;
         for (x1 = 0; x1 < (Int_t)new_width; x1++) {
            for (pixels = 0; pixels < chars; pixels++)
               smalldata[y1][x1+pixels] = data[(Int_t)y][(Int_t)x + pixels];
            x += 1.0 / xscale;
         }
         smalldata[y1][x1] = '\0';
         y += 1.0 / yscale;
      }

      retc = gVirtualX->CreatePictureFromData(fClient->GetDefaultRoot()->GetId(), smalldata,
                                         pic->fPic, pic->fMask,
                                         pic->fAttributes);

      for (i = 0; i < totalheight + 1; i++)
         delete [] smalldata[i];
      delete [] smalldata;

   } else {
      retc = gVirtualX->CreatePictureFromData(fClient->GetDefaultRoot()->GetId(), data,
                                              pic->fPic, pic->fMask,
                                              pic->fAttributes);
   }

   gVirtualX->DeletePictureData(data);
#else
   Bool_t retc = gVirtualX->CreatePictureFromFile(fClient->GetDefaultRoot()->GetId(),
                                                  picnam, pic->fPic, pic->fMask,
                                                  pic->fAttributes);
   delete [] picnam;
#endif

   if (!retc) {
      delete pic;
      return 0;
   }

   fPicList->Add(pic);
   return pic;
}

//______________________________________________________________________________
void TGPicturePool::FreePicture(const TGPicture *fpic)
{
   // Remove picture from cache if nobody is using it anymore.

   if (!fPicList) return;

   TGPicture *pic = (TGPicture *)fPicList->FindObject(fpic);
   if (pic) {
      if (pic->RemoveReference() == 0) {
         fPicList->Remove(pic);
         delete pic;
      }
   }
}

//______________________________________________________________________________
TGPicturePool::~TGPicturePool()
{
   // Delete picture cache.

   if (fPicList) {
      fPicList->Delete();
      delete fPicList;
   }
}

//______________________________________________________________________________
void TGPicturePool::Print(Option_t *) const
{
   // List all pictures in the pool.

   if (fPicList)
      fPicList->Print();
   else
      Info("Print", "no pictures in picture pool");
}

//______________________________________________________________________________
void TGPicture::Draw(Handle_t id, GContext_t gc, Int_t x, Int_t y) const
{
   // Draw a picture.

   GCValues_t gcv;

   gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
   gcv.fClipMask = fMask;
   gcv.fClipXOrigin = x;
   gcv.fClipYOrigin = y;
   gVirtualX->ChangeGC(gc, &gcv);
   gVirtualX->CopyArea(fPic, id, gc, 0, 0, fAttributes.fWidth, fAttributes.fHeight,
                  x, y);
   gcv.fMask = kGCClipMask;
   gcv.fClipMask = kNone;
   gVirtualX->ChangeGC(gc, &gcv);
}

//______________________________________________________________________________
TGPicture::~TGPicture()
{
   // Delete picture object.

   if (fPic != kNone)
      gVirtualX->DeletePixmap(fPic);
   if (fMask != kNone)
      gVirtualX->DeletePixmap(fMask);
   if (fAttributes.fPixels)
      delete [] fAttributes.fPixels;
}

//______________________________________________________________________________
const char *TGPicture::HashName(const char *name, Int_t width, Int_t height)
{
   // Static function returning a unique name used to look up a picture.
   // The unique name has the form "name__widthxheight".

   static char hashName[256];

   sprintf(hashName, "%s__%dx%d", name, width, height);

   return hashName;
}

//______________________________________________________________________________
void TGPicture::Print(Option_t *) const
{
   // Print picture info.

   Printf("TGPicture: %s,%sref cnt = %u", GetName(),
          fScaled ? " scaled, " : " ", References());
}

//______________________________________________________________________________
TGSelectedPicture::TGSelectedPicture(const TGClient *client, const TGPicture *p) :
   TGPicture("")
{
   // Create a "selected" looking picture based on the original TGPicture.

   GCValues_t gcv;
   UInt_t     w, h;

   fClient = client;
   Window_t root  = fClient->GetDefaultRoot()->GetId();

   w = p->GetWidth();
   h = p->GetHeight();

   fPic  = gVirtualX->CreatePixmap(root, w, h);
   fMask = p->GetMask();

   fAttributes.fWidth  = w;
   fAttributes.fHeight = h;

   gVirtualX->CopyArea(p->GetPicture(), fPic, GetSelectedGC()(), 0, 0, w, h, 0, 0);

   gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
   gcv.fClipMask = p->GetMask();
   gcv.fClipXOrigin = 0;
   gcv.fClipYOrigin = 0;
   GetSelectedGC().SetAttributes(&gcv);

   gVirtualX->FillRectangle(fPic, GetSelectedGC()(), 0, 0, w, h);

   GetSelectedGC().SetClipMask(kNone);
}

//______________________________________________________________________________
TGSelectedPicture::~TGSelectedPicture()
{
   // Delete selected picture.

   // fMask was borrowed so should not be deleted by ~TGPicture.
   fMask = kNone;
}

//______________________________________________________________________________
TGGC &TGSelectedPicture::GetSelectedGC()
{
   if (!fgSelectedGC) {
      fgSelectedGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
      fgSelectedGC->SetForeground(gClient->GetResourcePool()->GetSelectedBgndColor());
      fgSelectedGC->SetBackground(gClient->GetResourcePool()->GetBlackColor());
      fgSelectedGC->SetFillStyle(kFillStippled);
      fgSelectedGC->SetStipple(gClient->GetResourcePool()->GetCheckeredBitmap());
   }
   return *fgSelectedGC;
}
<commit_msg>In TGPicturePool::GetPicture invert the logic with #ifndef GDK_WIN32<commit_after>// @(#)root/gui:$Name:  $:$Id: TGPicture.cxx,v 1.6 2004/02/18 16:17:33 rdm Exp $
// Author: Fons Rademakers   01/01/98

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
/**************************************************************************

    This source is based on Xclass95, a Win95-looking GUI toolkit.
    Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.

    Xclass95 is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

**************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGPicture & TGPicturePool                                            //
//                                                                      //
// The TGPicture class implements pictures and icons used in the        //
// different GUI elements and widgets. The TGPicturePool class          //
// implements a TGPicture cache. TGPictures are created, managed and    //
// destroyed by the TGPicturePool.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGPicture.h"
#include "TGResourcePool.h"
#include "THashTable.h"
#include "TSystem.h"
#include "TGWindow.h"
#include "TVirtualX.h"

TGGC *TGSelectedPicture::fgSelectedGC = 0;

ClassImp(TGPicture)
ClassImp(TGSelectedPicture)
ClassImp(TGPicturePool)

//______________________________________________________________________________
const TGPicture *TGPicturePool::GetPicture(const char *name)
{
   // Get a picture from the picture pool. Picture must be freed using
   // TGPicturePool::FreePicture(). If picture is not found 0 is returned.

   if (!fPicList)
      fPicList = new THashTable(50);

   TString pname = name;

   if (pname.EndsWith(".xpm")) {
      pname = gSystem->ExpandPathName(gSystem->UnixPathName(pname.Data()));
   }
   TGPicture *pic;

   pic = (TGPicture *)fPicList->FindObject(pname.Data());
   if (pic && !pic->IsScaled()) {
      if (pic->fPic == kNone)
         return 0;
      pic->AddReference();
      return pic;
   }

   pic = new TGPicture(pname.Data());
   pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
   pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
   pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;

   char *picnam = gSystem->Which(fPath.Data(), pname.Data(), kReadPermission);
   if (!picnam) {
      fPicList->Add(pic);
      return 0;
   }

   if (gVirtualX->CreatePictureFromFile(fClient->GetDefaultRoot()->GetId(), picnam,
                                    pic->fPic, pic->fMask,
                                    pic->fAttributes)) {
      fPicList->Add(pic);
   } else {
      delete pic;
      pic = new TGPicture(name);
      fPicList->Add(pic);
      pic = 0;
   }

   delete [] picnam;

   return pic;
}

//______________________________________________________________________________
const TGPicture *TGPicturePool::GetPicture(const char *name,
                                           UInt_t new_width, UInt_t new_height)
{
   // Get picture with specified size from pool (picture will be scaled if
   // necessary). Picture must be freed using TGPicturePool::FreePicture(). If
   // picture is not found 0 is returned.

   if (!fPicList)
      fPicList = new THashTable(50);

   TString pname = name;

   if (pname.EndsWith(".xpm")) {
      pname = gSystem->ExpandPathName(gSystem->UnixPathName(pname.Data()));
   }

   TGPicture *pic;

   const char *hname = TGPicture::HashName(pname.Data(), new_width, new_height);
   pic = (TGPicture *)fPicList->FindObject(hname);
   if (pic && pic->GetWidth() == new_width && pic->GetHeight() == new_height) {
      if (pic->fPic == kNone)
         return 0;
      pic->AddReference();
      return pic;
   }

   pic = new TGPicture(hname, kTRUE);
   pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
   pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
   pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;

   char *picnam = gSystem->Which(fPath.Data(), pname.Data(), kReadPermission);
   if (!picnam) {
      pic->fAttributes.fWidth  = new_width;
      pic->fAttributes.fHeight = new_height;
      fPicList->Add(pic);
      return 0;
   }

#ifdef GDK_WIN32
   Bool_t retc = gVirtualX->CreatePictureFromFile(fClient->GetDefaultRoot()->GetId(),
                                                  picnam, pic->fPic, pic->fMask,
                                                  pic->fAttributes);
   delete [] picnam;
#else
   char **data;
   if (!gVirtualX->ReadPictureDataFromFile(picnam, &data)) {
      delete pic;
      delete [] picnam;
      return 0;
   }
   delete [] picnam;

   Int_t    colors, chars, headersize, totalheight;
   UInt_t   width, height;
   Double_t xscale, yscale;
   Bool_t   retc;

   sscanf(data[0], "%u %u %d %d", &width, &height, &colors, &chars);
   headersize = colors + 1;
   yscale = (Double_t) new_height / (Double_t) height;
   xscale = (Double_t) new_width / (Double_t) width;
   totalheight = (colors + new_height + 1);

   if ((width != new_width) || (height != new_height)) {
      char **smalldata;
      Int_t    i, x1, y1, pixels;
      Double_t x, y;

      smalldata = new char* [totalheight + 1];

      smalldata[0] = new char[30];
      for (i = 1; i < headersize; i++)
         smalldata[i] = new char [strlen(data[i]) + 1];

      for (i = headersize; i < totalheight + 1; i++)
         smalldata[i] = new char[(new_width * chars) + 1];

      sprintf(smalldata[0], "%u %u %d %d", new_width, new_height, colors, chars);

      for (i = 1; i < headersize; i++) strcpy(smalldata[i], data[i]);

      y = headersize;
      for (y1 = headersize; y1 < (Int_t)new_height + headersize; y1++) {
         x = 0;
         for (x1 = 0; x1 < (Int_t)new_width; x1++) {
            for (pixels = 0; pixels < chars; pixels++)
               smalldata[y1][x1+pixels] = data[(Int_t)y][(Int_t)x + pixels];
            x += 1.0 / xscale;
         }
         smalldata[y1][x1] = '\0';
         y += 1.0 / yscale;
      }

      retc = gVirtualX->CreatePictureFromData(fClient->GetDefaultRoot()->GetId(), smalldata,
                                         pic->fPic, pic->fMask,
                                         pic->fAttributes);

      for (i = 0; i < totalheight + 1; i++)
         delete [] smalldata[i];
      delete [] smalldata;

   } else {
      retc = gVirtualX->CreatePictureFromData(fClient->GetDefaultRoot()->GetId(), data,
                                              pic->fPic, pic->fMask,
                                              pic->fAttributes);
   }

   gVirtualX->DeletePictureData(data);
#endif

   if (!retc) {
      delete pic;
      return 0;
   }

   fPicList->Add(pic);
   return pic;
}

//______________________________________________________________________________
void TGPicturePool::FreePicture(const TGPicture *fpic)
{
   // Remove picture from cache if nobody is using it anymore.

   if (!fPicList) return;

   TGPicture *pic = (TGPicture *)fPicList->FindObject(fpic);
   if (pic) {
      if (pic->RemoveReference() == 0) {
         fPicList->Remove(pic);
         delete pic;
      }
   }
}

//______________________________________________________________________________
TGPicturePool::~TGPicturePool()
{
   // Delete picture cache.

   if (fPicList) {
      fPicList->Delete();
      delete fPicList;
   }
}

//______________________________________________________________________________
void TGPicturePool::Print(Option_t *) const
{
   // List all pictures in the pool.

   if (fPicList)
      fPicList->Print();
   else
      Info("Print", "no pictures in picture pool");
}

//______________________________________________________________________________
void TGPicture::Draw(Handle_t id, GContext_t gc, Int_t x, Int_t y) const
{
   // Draw a picture.

   GCValues_t gcv;

   gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
   gcv.fClipMask = fMask;
   gcv.fClipXOrigin = x;
   gcv.fClipYOrigin = y;
   gVirtualX->ChangeGC(gc, &gcv);
   gVirtualX->CopyArea(fPic, id, gc, 0, 0, fAttributes.fWidth, fAttributes.fHeight,
                  x, y);
   gcv.fMask = kGCClipMask;
   gcv.fClipMask = kNone;
   gVirtualX->ChangeGC(gc, &gcv);
}

//______________________________________________________________________________
TGPicture::~TGPicture()
{
   // Delete picture object.

   if (fPic != kNone)
      gVirtualX->DeletePixmap(fPic);
   if (fMask != kNone)
      gVirtualX->DeletePixmap(fMask);
   if (fAttributes.fPixels)
      delete [] fAttributes.fPixels;
}

//______________________________________________________________________________
const char *TGPicture::HashName(const char *name, Int_t width, Int_t height)
{
   // Static function returning a unique name used to look up a picture.
   // The unique name has the form "name__widthxheight".

   static char hashName[256];

   sprintf(hashName, "%s__%dx%d", name, width, height);

   return hashName;
}

//______________________________________________________________________________
void TGPicture::Print(Option_t *) const
{
   // Print picture info.

   Printf("TGPicture: %s,%sref cnt = %u", GetName(),
          fScaled ? " scaled, " : " ", References());
}

//______________________________________________________________________________
TGSelectedPicture::TGSelectedPicture(const TGClient *client, const TGPicture *p) :
   TGPicture("")
{
   // Create a "selected" looking picture based on the original TGPicture.

   GCValues_t gcv;
   UInt_t     w, h;

   fClient = client;
   Window_t root  = fClient->GetDefaultRoot()->GetId();

   w = p->GetWidth();
   h = p->GetHeight();

   fPic  = gVirtualX->CreatePixmap(root, w, h);
   fMask = p->GetMask();

   fAttributes.fWidth  = w;
   fAttributes.fHeight = h;

   gVirtualX->CopyArea(p->GetPicture(), fPic, GetSelectedGC()(), 0, 0, w, h, 0, 0);

   gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
   gcv.fClipMask = p->GetMask();
   gcv.fClipXOrigin = 0;
   gcv.fClipYOrigin = 0;
   GetSelectedGC().SetAttributes(&gcv);

   gVirtualX->FillRectangle(fPic, GetSelectedGC()(), 0, 0, w, h);

   GetSelectedGC().SetClipMask(kNone);
}

//______________________________________________________________________________
TGSelectedPicture::~TGSelectedPicture()
{
   // Delete selected picture.

   // fMask was borrowed so should not be deleted by ~TGPicture.
   fMask = kNone;
}

//______________________________________________________________________________
TGGC &TGSelectedPicture::GetSelectedGC()
{
   if (!fgSelectedGC) {
      fgSelectedGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
      fgSelectedGC->SetForeground(gClient->GetResourcePool()->GetSelectedBgndColor());
      fgSelectedGC->SetBackground(gClient->GetResourcePool()->GetBlackColor());
      fgSelectedGC->SetFillStyle(kFillStippled);
      fgSelectedGC->SetStipple(gClient->GetResourcePool()->GetCheckeredBitmap());
   }
   return *fgSelectedGC;
}
<|endoftext|>


<commit_before>/*
  Copyright (c) 2012 Stuart Walsh

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

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

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

#include "stdinc.h"
#include <string>
#include <uv.h>
#include <utility>
#include "connection.h"
#include "system.h"
#include "client.h"
#include "server.h"

using std::getline;
using std::pair;

unordered_map<Connection *, ConnectionPtr> Connection::connections;

Connection::Connection() : parser(Parser::get_default()), dns_state(Reverse)
{
  Logging::debug << "Created Connection: " << this << Logging::endl;
}

Connection::~Connection()
{
  Client::disconnected(client);
  Client::remove(client);
  Logging::debug << "Destroyed Connection: " << this << Logging::endl;
}

void Connection::accept(uv_stream_t *server_handle)
{
  sockaddr_storage addr;
  sockaddr_in *addr4;
  sockaddr_in6 *addr6;
  char ipstr[INET6_ADDRSTRLEN];
  int addrlen = sizeof(addr);
  int ret;

  handle = shared_ptr<uv_tcp_t>(new uv_tcp_t);

  uv_tcp_init(uv_default_loop(), handle.get());

  ret = uv_accept(server_handle, reinterpret_cast<uv_stream_t *>(handle.get()));
  if(ret < 0)
    throw runtime_error(System::uv_perror("Unable to accept connection"));

  ret = uv_tcp_getpeername(handle.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen);
  switch(addr.ss_family)
  {
  case AF_INET:
    addr4 = reinterpret_cast<sockaddr_in *>(&addr);
    uv_ip4_name(addr4, ipstr, sizeof(ipstr));
    break;
  case AF_INET6:
    addr6 = reinterpret_cast<sockaddr_in6 *>(&addr);
    uv_ip6_name(addr6, ipstr, sizeof(ipstr));
    break;
  }

  host = ipstr;

  handle->data = this;

  stringstream ss;
  ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Looking up your hostname";
  client->send(ss.str());

  DnsCallbackState *state = new DnsCallbackState();
  state->af_type = addr.ss_family;
  state->connection = this;

  if(addr.ss_family == AF_INET)
  {
    state->addrlen = sizeof(in_addr);
    state->addr = new char[addrlen];
    memcpy(state->addr, &addr4->sin_addr, addrlen);
  }
  else
  {
    state->addrlen = sizeof(in6_addr);
    state->addr = new char[addrlen];
    memcpy(state->addr, &addr6->sin6_addr, addrlen);
  }

  client->set_host(ipstr);

  ares_gethostbyaddr(System::get_ares_channel(), state->addr, state->addrlen, state->af_type, on_dns, state);

  Logging::debug << "Accepted connection from: " << ipstr << Logging::endl;
}

void Connection::send(const char *buffer, size_t len)
{
  uv_buf_t buf;
  uv_write_t *req = new uv_write_t;

  buf.base = const_cast<char*>(buffer);
  buf.len = len;
  uv_write(req, reinterpret_cast<uv_stream_t*>(handle.get()), &buf, 1, on_write);
}

void Connection::send(string buffer)
{
  send(buffer.c_str(), buffer.length());
}

void Connection::read(uv_stream_t *stream, ssize_t nread, uv_buf_t buf)
{
  string debug_str;

  if(nread < 0)
  {
    if(buf.base != NULL)
      free_buffer(buf);

    uv_close(reinterpret_cast<uv_handle_t *>(handle.get()), on_close);
    return;
  }

  if(nread == 0)
  {
    free_buffer(buf);
    return;
  }

  debug_str.insert(0, buf.base, nread);

  read_buffer.write(buf.base, nread);
  string line;

  while(getline(read_buffer, line))
  {
    if(read_buffer.eof())
    {
      read_buffer.clear();
      read_buffer << line;
      break;
    }

    if(line[line.length() - 1] == '\r')
      line.erase(line.length() - 1, 1);

    Logging::debug << "Complete command found '" << line << "'" << Logging::endl;

    parser.parse(client, line);
  }

  if(read_buffer.fail())
    read_buffer.clear();

  free_buffer(buf);
}

void Connection::dns_done(int status, hostent *hostent, DnsCallbackState *state)
{
  stringstream ss;

  if(status != ARES_SUCCESS)
  {
    delete state->addr;
    delete state;
    ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Couldn't look up your hostname";
    client->send(ss.str());

    uv_read_start(reinterpret_cast<uv_stream_t *>(handle.get()), on_buf_alloc, on_read);

    return;
  }

  switch(dns_state)
  {
  case Reverse:
    ares_gethostbyname(System::get_ares_channel(), hostent->h_name, state->af_type, on_dns, state);
    state->name = hostent->h_name;
    dns_state = Forward;
    break;
  case Forward:
    if(memcmp(state->addr, hostent->h_addr_list[0], state->addrlen) != 0)
    {
      ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Your forward and reverse DNS don't match, ignoring";
      client->send(ss.str());
    }
    else
    {
      ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Found your hostname";
      client->send(ss.str());
      client->set_host(hostent->h_name);
    }

    dns_state = Done;

    delete state->addr;
    delete state;

    uv_read_start(reinterpret_cast<uv_stream_t *>(handle.get()), on_buf_alloc, on_read);

    break;
  }
}

string Connection::get_host() const
{
  return host;
}

void Connection::set_client(const ClientPtr ptr)
{
  client = ptr;
}

// Statics
void Connection::add(ConnectionPtr connection)
{
  connections.insert(pair<Connection *, ConnectionPtr>(connection.get(), connection));
}

uv_buf_t Connection::on_buf_alloc(uv_handle_t *handle, size_t size)
{
  uv_buf_t buf;

  buf.len = size;
  buf.base = new char[size]();

  return buf;
}

void Connection::on_read(uv_stream_t *stream, ssize_t nread, uv_buf_t buf)
{
  Connection *connection = static_cast<Connection *>(stream->data);

  connection->read(stream, nread, buf);
}

void Connection::on_close(uv_handle_t *handle)
{
  Connection *connection = static_cast<Connection *>(handle->data);

  connections.erase(connection);
  connection->client->clear_connection();
}

void Connection::on_write(uv_write_t *req, int status)
{
  delete req;
}

void Connection::on_dns(void *arg, int status, int timeouts, hostent *hostent)
{
  DnsCallbackState *state = static_cast<DnsCallbackState *>(arg);
  Connection *connection = state->connection;

  connection->dns_done(status, hostent, state);
}

void Connection::free_buffer(uv_buf_t &buf)
{
  delete[] buf.base;
  buf.base = 0;
  buf.len = 0;
}
<commit_msg>use array delete as it's an array<commit_after>/*
  Copyright (c) 2012 Stuart Walsh

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

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

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

#include "stdinc.h"
#include <string>
#include <uv.h>
#include <utility>
#include "connection.h"
#include "system.h"
#include "client.h"
#include "server.h"

using std::getline;
using std::pair;

unordered_map<Connection *, ConnectionPtr> Connection::connections;

Connection::Connection() : parser(Parser::get_default()), dns_state(Reverse)
{
  Logging::debug << "Created Connection: " << this << Logging::endl;
}

Connection::~Connection()
{
  Client::disconnected(client);
  Client::remove(client);
  Logging::debug << "Destroyed Connection: " << this << Logging::endl;
}

void Connection::accept(uv_stream_t *server_handle)
{
  sockaddr_storage addr;
  sockaddr_in *addr4;
  sockaddr_in6 *addr6;
  char ipstr[INET6_ADDRSTRLEN];
  int addrlen = sizeof(addr);
  int ret;

  handle = shared_ptr<uv_tcp_t>(new uv_tcp_t);

  uv_tcp_init(uv_default_loop(), handle.get());

  ret = uv_accept(server_handle, reinterpret_cast<uv_stream_t *>(handle.get()));
  if(ret < 0)
    throw runtime_error(System::uv_perror("Unable to accept connection"));

  ret = uv_tcp_getpeername(handle.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen);
  switch(addr.ss_family)
  {
  case AF_INET:
    addr4 = reinterpret_cast<sockaddr_in *>(&addr);
    uv_ip4_name(addr4, ipstr, sizeof(ipstr));
    break;
  case AF_INET6:
    addr6 = reinterpret_cast<sockaddr_in6 *>(&addr);
    uv_ip6_name(addr6, ipstr, sizeof(ipstr));
    break;
  }

  host = ipstr;

  handle->data = this;

  stringstream ss;
  ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Looking up your hostname";
  client->send(ss.str());

  DnsCallbackState *state = new DnsCallbackState();
  state->af_type = addr.ss_family;
  state->connection = this;

  if(addr.ss_family == AF_INET)
  {
    state->addrlen = sizeof(in_addr);
    state->addr = new char[addrlen];
    memcpy(state->addr, &addr4->sin_addr, addrlen);
  }
  else
  {
    state->addrlen = sizeof(in6_addr);
    state->addr = new char[addrlen];
    memcpy(state->addr, &addr6->sin6_addr, addrlen);
  }

  client->set_host(ipstr);

  ares_gethostbyaddr(System::get_ares_channel(), state->addr, state->addrlen, state->af_type, on_dns, state);

  Logging::debug << "Accepted connection from: " << ipstr << Logging::endl;
}

void Connection::send(const char *buffer, size_t len)
{
  uv_buf_t buf;
  uv_write_t *req = new uv_write_t;

  buf.base = const_cast<char*>(buffer);
  buf.len = len;
  uv_write(req, reinterpret_cast<uv_stream_t*>(handle.get()), &buf, 1, on_write);
}

void Connection::send(string buffer)
{
  send(buffer.c_str(), buffer.length());
}

void Connection::read(uv_stream_t *stream, ssize_t nread, uv_buf_t buf)
{
  string debug_str;

  if(nread < 0)
  {
    if(buf.base != NULL)
      free_buffer(buf);

    uv_close(reinterpret_cast<uv_handle_t *>(handle.get()), on_close);
    return;
  }

  if(nread == 0)
  {
    free_buffer(buf);
    return;
  }

  debug_str.insert(0, buf.base, nread);

  read_buffer.write(buf.base, nread);
  string line;

  while(getline(read_buffer, line))
  {
    if(read_buffer.eof())
    {
      read_buffer.clear();
      read_buffer << line;
      break;
    }

    if(line[line.length() - 1] == '\r')
      line.erase(line.length() - 1, 1);

    Logging::debug << "Complete command found '" << line << "'" << Logging::endl;

    parser.parse(client, line);
  }

  if(read_buffer.fail())
    read_buffer.clear();

  free_buffer(buf);
}

void Connection::dns_done(int status, hostent *hostent, DnsCallbackState *state)
{
  stringstream ss;

  if(status != ARES_SUCCESS)
  {
    delete[] state->addr;
    delete state;
    ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Couldn't look up your hostname";
    client->send(ss.str());

    uv_read_start(reinterpret_cast<uv_stream_t *>(handle.get()), on_buf_alloc, on_read);

    return;
  }

  switch(dns_state)
  {
  case Reverse:
    ares_gethostbyname(System::get_ares_channel(), hostent->h_name, state->af_type, on_dns, state);
    state->name = hostent->h_name;
    dns_state = Forward;
    break;
  case Forward:
    if(memcmp(state->addr, hostent->h_addr_list[0], state->addrlen) != 0)
    {
      ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Your forward and reverse DNS don't match, ignoring";
      client->send(ss.str());
    }
    else
    {
      ss << ":" << Server::get_me()->str() << " NOTICE " << client->str() << " :*** Found your hostname";
      client->send(ss.str());
      client->set_host(hostent->h_name);
    }

    dns_state = Done;

    delete[] state->addr;
    delete state;

    uv_read_start(reinterpret_cast<uv_stream_t *>(handle.get()), on_buf_alloc, on_read);

    break;
  }
}

string Connection::get_host() const
{
  return host;
}

void Connection::set_client(const ClientPtr ptr)
{
  client = ptr;
}

// Statics
void Connection::add(ConnectionPtr connection)
{
  connections.insert(pair<Connection *, ConnectionPtr>(connection.get(), connection));
}

uv_buf_t Connection::on_buf_alloc(uv_handle_t *handle, size_t size)
{
  uv_buf_t buf;

  buf.len = size;
  buf.base = new char[size]();

  return buf;
}

void Connection::on_read(uv_stream_t *stream, ssize_t nread, uv_buf_t buf)
{
  Connection *connection = static_cast<Connection *>(stream->data);

  connection->read(stream, nread, buf);
}

void Connection::on_close(uv_handle_t *handle)
{
  Connection *connection = static_cast<Connection *>(handle->data);

  connections.erase(connection);
  connection->client->clear_connection();
}

void Connection::on_write(uv_write_t *req, int status)
{
  delete req;
}

void Connection::on_dns(void *arg, int status, int timeouts, hostent *hostent)
{
  DnsCallbackState *state = static_cast<DnsCallbackState *>(arg);
  Connection *connection = state->connection;

  connection->dns_done(status, hostent, state);
}

void Connection::free_buffer(uv_buf_t &buf)
{
  delete[] buf.base;
  buf.base = 0;
  buf.len = 0;
}
<|endoftext|>