<commit_before>/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/network/handshake.hpp>

#include <cstdint>
#include <functional>
#include <system_error>
#include <bitcoin/bitcoin/constants.hpp>
#include <bitcoin/bitcoin/define.hpp>
#include <bitcoin/bitcoin/error.hpp>
#include <bitcoin/bitcoin/network/channel.hpp>
#include <bitcoin/bitcoin/network/network.hpp>
#include <bitcoin/bitcoin/primitives.hpp>
#include <bitcoin/bitcoin/utility/async_parallel.hpp>
#include <bitcoin/bitcoin/version.hpp>

namespace libbitcoin {
namespace network {

using std::placeholders::_1;
using std::placeholders::_2;

#define BC_USER_AGENT "/libbitcoin:" LIBBITCOIN_VERSION "/"

handshake::handshake(threadpool& pool, uint16_t port, uint32_t start_height)
  : strand_(pool)
{
    // Set fixed values inversion template.
    template_version_.version = bc::protocol_version;
    template_version_.user_agent = BC_USER_AGENT;
    template_version_.services = 1;

    // Set default values inversion template.
    template_version_.start_height = start_height;
    template_version_.address_me.services = template_version_.services;
    template_version_.address_me.ip = bc::localhost_ip_address;
    template_version_.address_me.port = port;
    template_version_.address_you.services = template_version_.services;
    template_version_.address_you.ip = bc::localhost_ip_address;
    template_version_.address_you.port = port;
}

void handshake::start(start_handler handle_start)
{
    discover_external_ip(std::bind(handle_start, _1));
}

void handshake::ready(channel_ptr node,
    handshake::handshake_handler handle_handshake)
{
    constexpr size_t sync = 3;

    // synchrnize three code paths (or error) before calling handle_handshake.
    const auto completion_callback = async_parallel(handle_handshake, sync);

    // Copy the version template and set its timestamp.
    auto session_version = template_version_;
    template_version_.nonce = rand();
    session_version.timestamp = time(nullptr);

    // Since we removed cURL discover_external_ip always returns localhost.
    // The port value was formerly hardwired to bc::protocol_port.

    node->send(session_version,
        strand_.wrap(&handshake::handle_message_sent,
            this, _1, completion_callback));

    node->subscribe_version(
        strand_.wrap(&handshake::receive_version,
            this, _1, _2, node, completion_callback));

    node->subscribe_verack(
        strand_.wrap(&handshake::receive_verack,
            this, _1, _2, completion_callback));
}

void handshake::handle_message_sent(const std::error_code& ec,
    handshake::handshake_handler completion_callback)
{
    completion_callback(ec);
}

void handshake::receive_version(const std::error_code& ec, const version_type&,
    channel_ptr node, handshake::handshake_handler completion_callback)
{
    if (ec)
        completion_callback(ec);
    else
        node->send(verack_type(),
            strand_.wrap(&handshake::handle_message_sent,
                this, _1, completion_callback));
}

void handshake::receive_verack(const std::error_code& ec, const verack_type&,
    handshake::handshake_handler completion_callback)
{
    completion_callback(ec);
}

void handshake::discover_external_ip(discover_ip_handler handle_discover)
{
    strand_.queue(
        &handshake::do_discover_external_ip,
            this, handle_discover);
}

void handshake::do_discover_external_ip(discover_ip_handler handle_discover)
{
    template_version_.address_me.ip = localhost_ip_address;
    handle_discover(error::success, template_version_.address_me.ip);
}

void handshake::fetch_network_address(
    fetch_network_address_handler handle_fetch)
{
    strand_.queue(
        &handshake::do_fetch_network_address,
            this, handle_fetch);
}

void handshake::do_fetch_network_address(
    fetch_network_address_handler handle_fetch)
{
    handle_fetch(error::success, template_version_.address_me);
}

void handshake::set_port(uint16_t port, setter_handler handle_set)
{
    strand_.queue(
        &handshake::do_set_port,
            this, port, handle_set);
}

void handshake::do_set_port(uint16_t port, setter_handler handle_set)
{
    template_version_.address_me.port = port;
    handle_set(error::success);
}

// TODO: deprecate (any reason to set this dynamically)?
void handshake::set_user_agent(const std::string& user_agent,
    setter_handler handle_set)
{
    strand_.queue(
        &handshake::do_set_user_agent,
            this, user_agent, handle_set);
}

// TODO: deprecate (any reason to set this dynamically)?
void handshake::do_set_user_agent(const std::string& user_agent,
    setter_handler handle_set)
{
    template_version_.user_agent = user_agent;
    handle_set(error::success);
}

void handshake::set_start_height(uint64_t height, setter_handler handle_set)
{
    strand_.queue(
        &handshake::do_set_start_height,
            this, height, handle_set);
}

void handshake::do_set_start_height(uint64_t height, setter_handler handle_set)
{
    // We type this method as uint64_t because that is what is returned by
    // fetch_last_height, whcih feeds directly into this method. But start_height
    // is uint32_t in the satoshi network protocol.
    BITCOIN_ASSERT(height <= bc::max_uint32);
    template_version_.start_height = static_cast<uint32_t>(height);
    handle_set(error::success);
}

void finish_connect(const std::error_code& ec, channel_ptr node,
    handshake& shake, network::connect_handler handle_connect)
{
    if (ec)
        handle_connect(ec, node);
    else
        shake.ready(node, std::bind(handle_connect, _1, node));
}

void connect(handshake& shake, network& net, const std::string& hostname,
    uint16_t port, network::connect_handler handle_connect)
{
    net.connect(hostname, port,
        std::bind(finish_connect,
            _1, _2, std::ref(shake), handle_connect));
}

} // namespace network
} // namespace libbitcoin

<commit_msg>Set templated version nonce value on each instance.<commit_after>/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/bitcoin/network/handshake.hpp>

#include <cstdint>
#include <functional>
#include <system_error>
#include <bitcoin/bitcoin/constants.hpp>
#include <bitcoin/bitcoin/define.hpp>
#include <bitcoin/bitcoin/error.hpp>
#include <bitcoin/bitcoin/network/channel.hpp>
#include <bitcoin/bitcoin/network/network.hpp>
#include <bitcoin/bitcoin/primitives.hpp>
#include <bitcoin/bitcoin/utility/async_parallel.hpp>
#include <bitcoin/bitcoin/version.hpp>

namespace libbitcoin {
namespace network {

using std::placeholders::_1;
using std::placeholders::_2;

#define BC_USER_AGENT "/libbitcoin:" LIBBITCOIN_VERSION "/"

handshake::handshake(threadpool& pool, uint16_t port, uint32_t start_height)
  : strand_(pool)
{
    // Set fixed values inversion template.
    template_version_.version = bc::protocol_version;
    template_version_.user_agent = BC_USER_AGENT;
    template_version_.services = 1;

    // Set default values inversion template.
    template_version_.start_height = start_height;
    template_version_.address_me.services = template_version_.services;
    template_version_.address_me.ip = bc::localhost_ip_address;
    template_version_.address_me.port = port;
    template_version_.address_you.services = template_version_.services;
    template_version_.address_you.ip = bc::localhost_ip_address;
    template_version_.address_you.port = port;
}

void handshake::start(start_handler handle_start)
{
    discover_external_ip(std::bind(handle_start, _1));
}

void handshake::ready(channel_ptr node,
    handshake::handshake_handler handle_handshake)
{
    constexpr size_t sync = 3;

    // synchrnize three code paths (or error) before calling handle_handshake.
    const auto completion_callback = async_parallel(handle_handshake, sync);

    // Copy the version template and set its timestamp.
    auto session_version = template_version_;
    session_version.nonce = rand();
    session_version.timestamp = time(nullptr);

    // Since we removed cURL discover_external_ip always returns localhost.
    // The port value was formerly hardwired to bc::protocol_port.

    node->send(session_version,
        strand_.wrap(&handshake::handle_message_sent,
            this, _1, completion_callback));

    node->subscribe_version(
        strand_.wrap(&handshake::receive_version,
            this, _1, _2, node, completion_callback));

    node->subscribe_verack(
        strand_.wrap(&handshake::receive_verack,
            this, _1, _2, completion_callback));
}

void handshake::handle_message_sent(const std::error_code& ec,
    handshake::handshake_handler completion_callback)
{
    completion_callback(ec);
}

void handshake::receive_version(const std::error_code& ec, const version_type&,
    channel_ptr node, handshake::handshake_handler completion_callback)
{
    if (ec)
        completion_callback(ec);
    else
        node->send(verack_type(),
            strand_.wrap(&handshake::handle_message_sent,
                this, _1, completion_callback));
}

void handshake::receive_verack(const std::error_code& ec, const verack_type&,
    handshake::handshake_handler completion_callback)
{
    completion_callback(ec);
}

void handshake::discover_external_ip(discover_ip_handler handle_discover)
{
    strand_.queue(
        &handshake::do_discover_external_ip,
            this, handle_discover);
}

void handshake::do_discover_external_ip(discover_ip_handler handle_discover)
{
    template_version_.address_me.ip = localhost_ip_address;
    handle_discover(error::success, template_version_.address_me.ip);
}

void handshake::fetch_network_address(
    fetch_network_address_handler handle_fetch)
{
    strand_.queue(
        &handshake::do_fetch_network_address,
            this, handle_fetch);
}

void handshake::do_fetch_network_address(
    fetch_network_address_handler handle_fetch)
{
    handle_fetch(error::success, template_version_.address_me);
}

void handshake::set_port(uint16_t port, setter_handler handle_set)
{
    strand_.queue(
        &handshake::do_set_port,
            this, port, handle_set);
}

void handshake::do_set_port(uint16_t port, setter_handler handle_set)
{
    template_version_.address_me.port = port;
    handle_set(error::success);
}

// TODO: deprecate (any reason to set this dynamically)?
void handshake::set_user_agent(const std::string& user_agent,
    setter_handler handle_set)
{
    strand_.queue(
        &handshake::do_set_user_agent,
            this, user_agent, handle_set);
}

// TODO: deprecate (any reason to set this dynamically)?
void handshake::do_set_user_agent(const std::string& user_agent,
    setter_handler handle_set)
{
    template_version_.user_agent = user_agent;
    handle_set(error::success);
}

void handshake::set_start_height(uint64_t height, setter_handler handle_set)
{
    strand_.queue(
        &handshake::do_set_start_height,
            this, height, handle_set);
}

void handshake::do_set_start_height(uint64_t height, setter_handler handle_set)
{
    // We type this method as uint64_t because that is what is returned by
    // fetch_last_height, whcih feeds directly into this method. But start_height
    // is uint32_t in the satoshi network protocol.
    BITCOIN_ASSERT(height <= bc::max_uint32);
    template_version_.start_height = static_cast<uint32_t>(height);
    handle_set(error::success);
}

void finish_connect(const std::error_code& ec, channel_ptr node,
    handshake& shake, network::connect_handler handle_connect)
{
    if (ec)
        handle_connect(ec, node);
    else
        shake.ready(node, std::bind(handle_connect, _1, node));
}

void connect(handshake& shake, network& net, const std::string& hostname,
    uint16_t port, network::connect_handler handle_connect)
{
    net.connect(hostname, port,
        std::bind(finish_connect,
            _1, _2, std::ref(shake), handle_connect));
}

} // namespace network
} // namespace libbitcoin

<|endoftext|>


<commit_before>#include <iostream>
#include <cstring>
#include <cstdlib>
#include <bitset>

#include <unistd.h>

#define BUFSIZE 8192

enum VintState {
	GET_VINT_WIDTH,
	GET_VINT_DATA
};

class simple_vint{
public:
	uint8_t width;
	uint8_t data[8];

	uint64_t get_int(){
		uint64_t value = 0;
		value = data[width - 1];
		for(int i  = width - 1; i > 0; --i){
			value += ((uint32_t)data[i - 1] << ((width - i) * 8));
		}
		return value;
	}
};

class simple_ebml_element {
public:
	simple_vint id;
	simple_vint size;
	uint8_t* data;
};

int main(int argc, char** argv){
	int len, mask;
	uint8_t buffer[BUFSIZE];

	int total_bytes = 0;
	int from_bytes = 0;
	int to_bytes = 0;

	simple_vint* e_id;
	simple_vint* e_size;

	for(int i = 0; i < argc; i++){
		if((std::strcmp(argv[i], "-f") == 0) && argc > i){
                        from_bytes = std::stoi(argv[i + 1]);
                }else if((std::strcmp(argv[i], "-t") == 0) && argc > i){
                        to_bytes = std::stoi(argv[i + 1]);
                }else if((std::strcmp(argv[i], "-l") == 0) && argc > i){
                        to_bytes = from_bytes + std::stoi(argv[i + 1]);
                }
	}

	if((len = read(STDIN_FILENO, buffer, BUFSIZE)) == -1){
		std::cout << "Uh oh, read error!\n";
		return 1;
	}

	for(int i = 0; i < len;){
		if(total_bytes + i >= to_bytes){
			break;
		}

		std::bitset<8> sbits(buffer[i]);
		std::cout << "Element Start: " << sbits << std::endl;

		e_id = new simple_vint();
		e_id->width = 1;
		mask = 0x80;

		// Find the size of the element id.
		while(!(buffer[i] & mask)){
			mask >>= 1;
			e_id->width += 1;
		}
		std::cout << "Id Vint Width: " << (int)e_id->width << std::endl;

		// Get rid of "vint marker"
		//buffer[i] = 0;
		//buffer[i] ^= mask;

		//vint->data[0] = buffer[i];
		//vint->width = 1;
		//std::cout << "Value: " << std::dec << vint->get_int() << std::endl;

		std::cout << "Id Vint Bytes: ";
		for(int j = 0; j < e_id->width; ++j){
			e_id->data[j] = buffer[i + j];
			std::bitset<8> bits(e_id->data[j]);
			std::cout << bits;
		}
		i += e_id->width;
		std::cout << std::endl;

		std::cout << "Id Hex: 0x";
		for(int j = 0; j < e_id->width; ++j){
			std::cout << std::hex << (int)e_id->data[j];
		}
		std::cout << std::endl;

		std::cout << "Id Value: " << std::dec << e_id->get_int() << std::endl;

		e_size = new simple_vint();
		e_size->width = 1;
		mask = 0x80;

		// Find the size of the element data.
		while(!(buffer[i] & mask)){
			mask >>= 1;
			e_size->width += 1;
		}
		std::cout << "Data Size Vint Width: " << (int)e_size->width << std::endl;

		buffer[i] ^= mask;

		std::cout << "Data Size Vint Bytes: ";
		for(int j = 0; j < e_size->width; ++j){
			e_size->data[j] = buffer[i + j];
			std::bitset<8> bits(e_size->data[j]);
			std::cout << bits;
		}
		i += e_size->width;
		std::cout << std::endl;

		std::cout << "Data Size: " << std::dec << e_size->get_int() << std::endl;

		delete e_id;
		delete e_size;

		std::cout << std::endl;
	}

	total_bytes += len;

	return 0;
}
<commit_msg>Starting to fill out the meat of the data. Supporting EBML data types.<commit_after>#include <iostream>
#include <cstring>
#include <cstdlib>
#include <bitset>

#include <unistd.h>

#define BUFSIZE 8192

enum VintState {
	GET_VINT_WIDTH,
	GET_VINT_DATA
};

class simple_vint{
public:
	uint8_t width;
	uint8_t data[8];

	uint64_t get_int(){
		uint64_t value = 0;
		value = data[width - 1];
		for(int i  = width - 1; i > 0; --i){
			value += ((uint32_t)data[i - 1] << ((width - i) * 8));
		}
		return value;
	}
};

class simple_ebml_element {
public:
	simple_vint id;
	simple_vint size;
	uint8_t* data;
};

int main(int argc, char** argv){
	int len, mask;
	uint8_t buffer[BUFSIZE];

	int total_bytes = 0;
	int from_bytes = 0;
	int to_bytes = 0;

	simple_vint* e_id;
	simple_vint* e_size;

	for(int i = 0; i < argc; i++){
		if((std::strcmp(argv[i], "-f") == 0) && argc > i){
                        from_bytes = std::stoi(argv[i + 1]);
                }else if((std::strcmp(argv[i], "-t") == 0) && argc > i){
                        to_bytes = std::stoi(argv[i + 1]);
                }else if((std::strcmp(argv[i], "-l") == 0) && argc > i){
                        to_bytes = from_bytes + std::stoi(argv[i + 1]);
                }
	}

	if((len = read(STDIN_FILENO, buffer, BUFSIZE)) == -1){
		std::cout << "Uh oh, read error!\n";
		return 1;
	}

	for(int i = 0; i < len;){
		if(to_bytes > 0 && total_bytes + i >= to_bytes){
			break;
		}

		std::bitset<8> sbits(buffer[i]);
		std::cout << "Element Start: " << sbits << std::endl;

		e_id = new simple_vint();
		e_id->width = 1;
		mask = 0x80;

		// Find the size of the element id.
		while(!(buffer[i] & mask)){
			mask >>= 1;
			e_id->width += 1;
		}
		std::cout << "Id Vint Width: " << (int)e_id->width << std::endl;

		// Get rid of "vint marker"
		//buffer[i] = 0;
		//buffer[i] ^= mask;

		//vint->data[0] = buffer[i];
		//vint->width = 1;
		//std::cout << "Value: " << std::dec << vint->get_int() << std::endl;

		std::cout << "Id Vint Bytes: ";
		for(int j = 0; j < e_id->width; ++j){
			e_id->data[j] = buffer[i + j];
			std::bitset<8> bits(e_id->data[j]);
			std::cout << bits;
		}
		i += e_id->width;
		std::cout << std::endl;

		std::cout << "Id Hex: 0x";
		for(int j = 0; j < e_id->width; ++j){
			std::cout << std::hex << (int)e_id->data[j];
		}
		std::cout << std::endl;

		std::cout << "Id Value: " << std::dec << e_id->get_int() << std::endl;

		e_size = new simple_vint();
		e_size->width = 1;
		mask = 0x80;

		std::bitset<8> dbits(buffer[i]);
		std::cout << "Data Size Start: " << dbits << std::endl;

		// Find the size of the element data.
		while(!(buffer[i] & mask)){
			mask >>= 1;
			e_size->width += 1;
		}
		std::cout << "Data Size Vint Width: " << (int)e_size->width << std::endl;

		buffer[i] ^= mask;

		std::cout << "Data Size Vint Bytes: ";
		for(int j = 0; j < e_size->width; ++j){
			e_size->data[j] = buffer[i + j];
			std::bitset<8> bits(e_size->data[j]);
			std::cout << bits;
		}
		i += e_size->width;
		std::cout << std::endl;

		std::cout << "Data Size: " << std::dec << e_size->get_int() << std::endl;

		// 0x1a45dfa3
		if(e_id->get_int() == 440786851){
			std::cout << "-----------------------------\n";
			std::cout << "\tEBML HEADER\n";
			std::cout << "-----------------------------\n";
		// 0x18538067
		}else if(e_id->get_int() == 408125543){
			std::cout << "-----------------------------\n";
			std::cout << "\tSEGMENT\n";
			std::cout << "-----------------------------\n";
		// 0x114d9b74
		}else if(e_id->get_int() == 290298740){
			std::cout << "-----------------------------\n";
			std::cout << "\tSEEK INFO\n";
			std::cout << "-----------------------------\n";
		// 0x4dbb
		}else if(e_id->get_int() == 19899){
                        std::cout << "-----------------------------\n";
                        std::cout << "\tSEEK\n";
                        std::cout << "-----------------------------\n";
		// 0xec
                }else if(e_id->get_int() == 236){
                        std::cout << "-----------------------------\n";
                        std::cout << "\tVOID\n";
                        std::cout << "-----------------------------\n";
			i += e_size->get_int();
		// 0x1549a966
                }else if(e_id->get_int() == 357149030){
                        std::cout << "-----------------------------\n";
                        std::cout << "\tSEGMENT INFO\n";
                        std::cout << "-----------------------------\n";
		// 0x1654ae6b
                }else if(e_id->get_int() == 374648427){
                        std::cout << "-----------------------------\n";
                        std::cout << "\tTRACKS\n";
                        std::cout << "-----------------------------\n";
		// 0xae
                }else if(e_id->get_int() == 174){
                        std::cout << "-----------------------------\n";
                        std::cout << "\tTRACK ENTRY\n";
                        std::cout << "-----------------------------\n";
		// 0xe0
                }else if(e_id->get_int() == 224){
                        std::cout << "-----------------------------\n";
                        std::cout << "\tTRACK VIDEO\n";
                        std::cout << "-----------------------------\n";
                // Other
                }else{
			std::cout << "Data (bytes): " << std::endl;
			std::cout << "-----------------------------\n";
			for(int j = 0, size = e_size->get_int(); j < size; ++j){
				std::cout << "Byte: " << (int)buffer[i + j] << std::endl;
			}
			i += e_size->get_int();
			std::cout << "-----------------------------\n";
		}

		delete e_id;
		delete e_size;
	}

	total_bytes += len;

	return 0;
}
<|endoftext|>


<commit_before>#include <QCoreApplication>
#include <QCommandLineParser>

#include <QStandardPaths>
#include <QDir>
#include "converter.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    app.setApplicationName("pgserverconverter");
    app.setApplicationVersion("1.0");

    QCommandLineParser parser;
    parser.setApplicationDescription("Convert saved pgadmin3 servers to pgadmin4 db entries");
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption inputFile(QStringList() << "i" << "input",
    #ifdef Q_OS_LINUX
    QCoreApplication::translate("main", "pgadmin3 config file. Defaults to ~/.pgadmin3"),
    #endif
    #ifdef Q_OS_MAC
    QCoreApplication::translate("main", "pgadmin3 config file. Defaults to ~/Library/Preferences/pgadmin3 Preferences"),
    #endif
    #ifdef Q_OS_WIN
    QCoreApplication::translate("main", "pgadmin3 config file. Defaults to the windows registry"),
    #endif
    QCoreApplication::translate("main", "inputfile"));
    parser.addOption(inputFile);

    QCommandLineOption database(QStringList() << "d" << "database",
    #ifdef Q_OS_WIN
    QCoreApplication::translate("main", "Path to pgAdmin4's SQLite database. Defaults to ~/AppData/Roaming/pgadmin/pgadmin4.db"),
    #else
    QCoreApplication::translate("main", "Path to pgAdmin4's SQLite database. Defaults to ~/.pgadmin/pgadmin4.db"),
    #endif
    QCoreApplication::translate("main", "database"));
    parser.addOption(database);

    parser.process(app);

    QString _input;
    QString _db;

    if (parser.isSet("input")) {
        _input = parser.value("input");
    }
    else {
        #ifdef Q_OS_LINUX
        _input = QDir::homePath() + "/.pgadmin3";
        #endif
        #ifdef Q_OS_MAC
        _input = QDir::homePath() + "/Library/Preferences/pgadmin3 Preferences";
        #endif
        #ifdef Q_OS_WIN
        _input = "Windows Registry";
        #endif
    }

    if (parser.isSet("database")) {
        _db = parser.value("database");
    }
    else {
        #ifdef Q_OS_WIN
        _db = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0] + "/../pgadmin/pgadmin4.db";
        #else
        _db = QDir::homePath() + "/.pgadmin/pgadmin4.db";
        #endif
    }

    converter c(_input, _db);
    c.start();
    return app.exec();
}
<commit_msg>touchup<commit_after>#include <QCoreApplication>
#include <QCommandLineParser>

#include <QStandardPaths>
#include <QDir>
#include "converter.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    app.setApplicationName("pgserverconverter");
    app.setApplicationVersion("1.0");

    QCommandLineParser parser;
    parser.setApplicationDescription("Convert saved pgadmin3 servers to pgadmin4 db entries");
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption inputFile(QStringList() << "i" << "input",
#ifdef Q_OS_LINUX
    QCoreApplication::translate("main", "pgadmin3 config file. Defaults to ~/.pgadmin3"),
#endif
#ifdef Q_OS_MAC
    QCoreApplication::translate("main", "pgadmin3 config file. Defaults to ~/Library/Preferences/pgadmin3 Preferences"),
#endif
#ifdef Q_OS_WIN
    QCoreApplication::translate("main", "pgadmin3 config file. Defaults to the windows registry"),
#endif
    QCoreApplication::translate("main", "inputfile"));
    parser.addOption(inputFile);

    QCommandLineOption database(QStringList() << "d" << "database",
#ifdef Q_OS_WIN
    QCoreApplication::translate("main", "Path to pgAdmin4's SQLite database. Defaults to ~/AppData/Roaming/pgadmin/pgadmin4.db"),
#else
    QCoreApplication::translate("main", "Path to pgAdmin4's SQLite database. Defaults to ~/.pgadmin/pgadmin4.db"),
#endif
    QCoreApplication::translate("main", "database"));
    parser.addOption(database);

    parser.process(app);

    QString _input;
    QString _db;

    if (parser.isSet("input")) {
        _input = parser.value("input");
    }
    else {
#ifdef Q_OS_LINUX
        _input = QDir::homePath() + "/.pgadmin3";
#endif
#ifdef Q_OS_MAC
        _input = QDir::homePath() + "/Library/Preferences/pgadmin3 Preferences";
#endif
#ifdef Q_OS_WIN
        _input = "Windows Registry";
#endif
    }

    if (parser.isSet("database")) {
        _db = parser.value("database");
    }
    else {
#ifdef Q_OS_WIN
        _db = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0] + "/../pgadmin/pgadmin4.db";
#else
        _db = QDir::homePath() + "/.pgadmin/pgadmin4.db";
#endif
    }

    converter c(_input, _db);
    c.start();
    return app.exec();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <bits/stl_algo.h>
#include <bitset>
#include <fstream>
#include <chrono>

using namespace std;

typedef struct GraphTree {
    unsigned char symbol;
    unsigned char symbolExtended;
    unsigned long long int nrOfApp;
    GraphTree *parent;
    GraphTree *left;
    GraphTree *right;
    unsigned long long int index;
} ShannonTree;

typedef std::vector<GraphTree *> GraphIndex;

typedef std::map<int, std::pair<GraphTree *, std::string>> MappedSymbols;
typedef std::chrono::duration<int, std::milli> miliseconds_type;

typedef struct GraphSearch {
    std::string code;
    bool type;
    GraphTree *reference;
};

int ENCODE_BITS = 8;
int ESC_VALUE = 257;
int EOS_VALUE = 256;
MappedSymbols symbolMap;
GraphIndex indexedGraph;

auto
        cmp = [](std::pair<unsigned char, unsigned long int> const &a, std::pair<unsigned char, unsigned long int> const &b) {
    return a.second != b.second ? a.second > b.second : a.first < b.first;
};

GraphTree *initGraph() {

    GraphTree *parent, *left, *right;
    parent = new GraphTree;
    left = new GraphTree;
    right = new GraphTree;
    parent->symbol = 0;
    parent->symbolExtended = 0;
    parent->nrOfApp = 2;

    parent->parent = NULL;
    parent->left = left;
    parent->right = right;
    parent->index = 1;

    indexedGraph.push_back(parent);

    left->parent = parent;
    right->parent = parent;

    left->left = NULL;
    left->right = NULL;

    right->left = NULL;
    right->right = NULL;

    left->symbol = 255;
    left->symbolExtended = 1;

    right->symbol = 255;
    right->symbolExtended = 2;

    left->nrOfApp = 1;
    right->nrOfApp = 1;

    left->index = 2;
    right->index = 3;

    indexedGraph.push_back(left);
    indexedGraph.push_back(right);

    symbolMap[right->symbol + right->symbolExtended].first = right;
    symbolMap[right->symbol + right->symbolExtended].second = "1";

    symbolMap[left->symbol + left->symbolExtended].first = left;
    symbolMap[left->symbol + left->symbolExtended].second = "0";

    return parent;

}

/**
* find symbol in alphabet map, if it is first occurence for symbol return a reference for ESC symbol
*/
GraphSearch findSymbol(unsigned char symbol) {
    GraphSearch result;
    if (symbolMap.count(symbol) > 0) {
        result.code = symbolMap[symbol].second;
        result.type = true;
        result.reference = symbolMap[symbol].first;
    } else {
        result.code = symbolMap[ESC_VALUE].second;
        result.type = false;
        result.reference = symbolMap[ESC_VALUE].first;
    }
    return result;

}

void updateSymbol(GraphSearch result) {
    (result.reference)->nrOfApp = (result.reference)->nrOfApp + 1;
}

void addSymbol(GraphSearch result, unsigned char symbol) {
    GraphTree *left, *right;

    left = new GraphTree;
    left->nrOfApp = 1;
    left->right = NULL;
    left->left = NULL;
    left->symbol = symbol;
    left->symbolExtended = 0;
    left->parent = result.reference;
    left->index = (result.reference)->index + 1;

    right = new GraphTree;
    right->nrOfApp = 1;
    right->right = NULL;
    right->left = NULL;
    right->symbol = 255;
    right->symbolExtended = 2;
    right->parent = result.reference;
    right->index = (result.reference)->index + 2;

    (result.reference)->left = left;
    (result.reference)->right = right;
    (result.reference)->nrOfApp = 2;
    (result.reference)->symbol = 0;
    (result.reference)->symbolExtended = 0;

    indexedGraph.push_back(left);
    indexedGraph.push_back(right);

    symbolMap[ESC_VALUE].first = right;

}

void displayIndexedGraph() {
    GraphIndex::size_type iterator;
    for (iterator = 0; iterator < indexedGraph.size(); ++iterator) {
        std::cout << (indexedGraph[iterator])->nrOfApp << " " << (indexedGraph[iterator])->index << " -> " << iterator + 1 << "\n";
    }
}

void displayGraph(GraphTree *root) {
    if ((root->symbol + root->symbolExtended) == 0) {
        std::cout << "Pondere: " << root->nrOfApp << "\n";
        displayGraph(root->left);
        displayGraph(root->right);
    } else {
        std::cout << "Simbol: " << (root->symbol + root->symbolExtended) << "\n";
    }

}

void balanceGraph(GraphTree *node) {
    GraphTree *aux, *changeAux, *parent;
    GraphIndex::size_type iterator, auxIndex;

    for (iterator = node->index - 1; iterator > 0; iterator--) {
        if ((indexedGraph[iterator - 1])->nrOfApp >= node->nrOfApp) {
            break;
        }
    }
    if (iterator == node->index - 1) {
        node->parent->nrOfApp++;
        if (node->parent->parent != NULL) {
            balanceGraph(node->parent);
        }

    }

    if (iterator == node->index - 2) {
        (indexedGraph[iterator - 1])->right = indexedGraph[iterator];
        (indexedGraph[iterator - 1])->left = node;
        indexedGraph[iterator]->index++;
        node->index--;
        indexedGraph[iterator] = node;
        indexedGraph[iterator + 1] = (indexedGraph[iterator - 1])->right;
        balanceGraph(node);
    }

    if (iterator > node->index - 2 && node->index - 2 > 1) {
        aux = indexedGraph[iterator - 1];
        indexedGraph[iterator - 1] = node;
        auxIndex = node->index;
        parent = aux->parent;
        changeAux = node->parent;
        if (iterator % 2 == 0) {
            parent->left = node;
        } else {
            parent->right = node;
        }
        node->parent = parent;

        indexedGraph[auxIndex - 1] = aux;
        if (auxIndex % 2 == 0) {
            changeAux->left = node;
        } else {
            changeAux->right = node;
        }
        balanceGraph(indexedGraph[iterator - 1]);
    }
    std::cout << "\n\n";
}

void encodeSymbol(unsigned char symbol, GraphTree *parent) {
    GraphSearch result;

    result = findSymbol(symbol);
    if (result.type == true) {
        updateSymbol(result);
    } else {
        addSymbol(result, symbol);
    }

    balanceGraph(result.reference);

}

void swapChild(GraphTree *root) {
    GraphTree *aux;
    aux = root->left;
    root->left = root->right;
    root->right = aux;
}

void balanceTree(GraphTree *root) {

    if ((root->symbol + root->symbolExtended) == 0) {
        if (root->left->nrOfApp < root->right->nrOfApp) {
            swapChild(root);
        }
    }
}

void encodeFile() {

}

void compressFile(std::string fileName) {

    GraphTree *huffmanTree;
    huffmanTree = initGraph();
    encodeSymbol('a', huffmanTree);
    encodeSymbol('b', huffmanTree);
    displayIndexedGraph();
    std::cout << "\n\n";
    displayGraph(huffmanTree);
//    balanceTree(huffmanTree);
//    encodeSymbol('b', huffmanTree);
//    balanceTree(huffmanTree);
//    std::cout << "\n\n";
//    displayGraph(huffmanTree);
}

void uncompressFile(std::string fileName) {

}

void displayOptions() {
    std::cout << "Alege fisierul!" << "\n\n Audio:\n";
    std::cout << "\t1.)instr_01.wav\n";
    std::cout << "\t2.)sound_01.wav\n";
    std::cout << "\t3.)speech_01.wav\n";
    std::cout << "\nDocuments:\n";
    std::cout << "\t4.)Documentatie_UMAPID.doc\n";
    std::cout << "\t5.)Documentatie_UMAPID.pdf\n";
    std::cout << "\t6.)Prefata_Undine.txt\n";
    std::cout << "\t7.)show_audio.m\n";
    std::cout << "\t8.)Y04.M\n";
    std::cout << "\nExecutables:\n";
    std::cout << "\t9.)KARMA_DATA482#1_5_V7.mat\n";
    std::cout << "\t10.)quartz.dll\n";
    std::cout << "\t11.)WinRar.exe\n";
    std::cout << "\t12.)WINZIP32.EXE\n";

}

std::ifstream::pos_type filesize(std::string fileName) {
    std::ifstream in(fileName.c_str(), std::ifstream::ate | std::ifstream::binary);
    return in.tellg();
}

void displayInformations(std::string fileName) {
    std::ifstream::pos_type compressedFileSize, fileSize, uncompressedFileSize;
    std::string compressedFileName, uncompressedFileName;

    compressedFileName = fileName + ".psh";
    uncompressedFileName = fileName + ".pshu";

    compressedFileSize = filesize(compressedFileName);
    fileSize = filesize(fileName);
    uncompressedFileSize = filesize(uncompressedFileName);

    std::cout << "Norma: " << (fileSize - uncompressedFileSize) * (fileSize - uncompressedFileSize) << "\n";
    std::cout << "Rata compresie: " << (1 - ((float) compressedFileSize) / ((float) uncompressedFileSize)) * 100 << "%\n";
    std::cout << "Factor compresie:  " << (((float) compressedFileSize) / ((float) fileSize)) * 100 << "%\n";

}

int main() {

    std::vector<std::string> files = {
            ".\\audio\\instr_01.wav",
            ".\\audio\\sound_01.wav",
            ".\\audio\\speech_01.wav",
            ".\\documents\\Documentatie_UMAPID.doc",
            ".\\documents\\Documentatie_UMAPID.pdf",
            ".\\documents\\Prefata_Undine.txt",
            ".\\documents\\show_audio.m",
            ".\\documents\\Y04.M",
            ".\\executables\\KARMA_DATA482#1_5_V7.mat",
            ".\\executables\\quartz.dll",
            ".\\executables\\WinRar.exe",
            ".\\executables\\WINZIP32.EXE",
            ".\\documents\\input.txt",
            "D:\\input.txt",
    };

    int option;
    //displayOptions();
    //std::cout << "Select file!..\n";
    //std::cin >> option;
//    if (option < 1 && option > 14) {
//        std::cout << "Invalid option!";
//        return 0;
//    }
    auto startC = std::chrono::high_resolution_clock::now();

    compressFile(files[2]);
    auto endC = std::chrono::high_resolution_clock::now();
    auto timeC = endC - startC;
    std::cout << "Compressed time: " << std::chrono::duration_cast<miliseconds_type>(timeC).count() << " miliseconds.\n";

    auto startU = std::chrono::high_resolution_clock::now();
//    uncompressFile(files[option - 1]);

    auto endU = std::chrono::high_resolution_clock::now();
    auto timeU = endU - startU;
    std::cout << "Uncompressed time: " << std::chrono::duration_cast<miliseconds_type>(timeU).count() << " miliseconds.\n";
//    displayInformations(files[option - 1]);

    //std::cin >> option;

    return 0;
}<commit_msg>Update encoding second symbol<commit_after>#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <bits/stl_algo.h>
#include <bitset>
#include <fstream>
#include <chrono>

using namespace std;

typedef struct GraphTree {
    unsigned char symbol;
    unsigned char symbolExtended;
    unsigned long long int nrOfApp;
    GraphTree *parent;
    GraphTree *left;
    GraphTree *right;
    unsigned long long int index;
} ShannonTree;

typedef std::vector<GraphTree *> GraphIndex;

typedef std::map<int, std::pair<GraphTree *, std::string>> MappedSymbols;
typedef std::chrono::duration<int, std::milli> miliseconds_type;

typedef struct GraphSearch {
    std::string code;
    bool type;
    GraphTree *reference;
};

int ENCODE_BITS = 8;
int ESC_VALUE = 257;
int EOS_VALUE = 256;
MappedSymbols symbolMap;
GraphIndex indexedGraph;

auto
        cmp = [](std::pair<unsigned char, unsigned long int> const &a, std::pair<unsigned char, unsigned long int> const &b) {
    return a.second != b.second ? a.second > b.second : a.first < b.first;
};

GraphTree *initGraph() {

    GraphTree *parent, *left, *right;
    parent = new GraphTree;
    left = new GraphTree;
    right = new GraphTree;
    parent->symbol = 0;
    parent->symbolExtended = 0;
    parent->nrOfApp = 2;

    parent->parent = NULL;
    parent->left = left;
    parent->right = right;
    parent->index = 1;

    indexedGraph.push_back(parent);

    left->parent = parent;
    right->parent = parent;

    left->left = NULL;
    left->right = NULL;

    right->left = NULL;
    right->right = NULL;

    left->symbol = 255;
    left->symbolExtended = 1;

    right->symbol = 255;
    right->symbolExtended = 2;

    left->nrOfApp = 1;
    right->nrOfApp = 1;

    left->index = 2;
    right->index = 3;

    indexedGraph.push_back(left);
    indexedGraph.push_back(right);

    symbolMap[right->symbol + right->symbolExtended].first = right;
    symbolMap[right->symbol + right->symbolExtended].second = "1";

    symbolMap[left->symbol + left->symbolExtended].first = left;
    symbolMap[left->symbol + left->symbolExtended].second = "0";

    return parent;

}

/**
* find symbol in alphabet map, if it is first occurence for symbol return a reference for ESC symbol
*/
GraphSearch findSymbol(unsigned char symbol) {
    GraphSearch result;
    if (symbolMap.count(symbol) > 0) {
        result.code = symbolMap[symbol].second;
        result.type = true;
        result.reference = symbolMap[symbol].first;
    } else {
        result.code = symbolMap[ESC_VALUE].second;
        result.type = false;
        result.reference = symbolMap[ESC_VALUE].first;
    }
    return result;

}

void updateSymbol(GraphSearch result) {
    (result.reference)->nrOfApp = (result.reference)->nrOfApp + 1;
}

void addSymbol(GraphSearch result, unsigned char symbol) {
    GraphTree *left, *right;

    left = new GraphTree;
    left->nrOfApp = 1;
    left->right = NULL;
    left->left = NULL;
    left->symbol = symbol;
    left->symbolExtended = 0;
    left->parent = result.reference;
    left->index = (result.reference)->index + 1;

    right = new GraphTree;
    right->nrOfApp = 1;
    right->right = NULL;
    right->left = NULL;
    right->symbol = 255;
    right->symbolExtended = 2;
    right->parent = result.reference;
    right->index = (result.reference)->index + 2;

    (result.reference)->left = left;
    (result.reference)->right = right;
    (result.reference)->nrOfApp = 2;
    (result.reference)->symbol = 0;
    (result.reference)->symbolExtended = 0;

    indexedGraph.push_back(left);
    indexedGraph.push_back(right);

    symbolMap[ESC_VALUE].first = right;

}

void displayIndexedGraph() {
    GraphIndex::size_type iterator;
    for (iterator = 0; iterator < indexedGraph.size(); ++iterator) {
        std::cout << (indexedGraph[iterator])->nrOfApp << " " << (indexedGraph[iterator])->index << " -> " << iterator + 1 << "\n";
    }
}

void displayGraph(GraphTree *root) {
    if ((root->symbol + root->symbolExtended) == 0) {
        std::cout << "Pondere: " << root->nrOfApp << "\n";
        displayGraph(root->left);
        displayGraph(root->right);
    } else {
        std::cout << "Simbol: " << (root->symbol + root->symbolExtended) << "\n";
    }

}

void balanceGraph(GraphTree *node) {
    GraphTree *aux, *changeAux, *parent;
    GraphIndex::size_type iterator, auxIndex;

    for (iterator = node->index - 1; iterator > 0; iterator--) {
        if ((indexedGraph[iterator - 1])->nrOfApp >= node->nrOfApp) {
            break;
        }
    }
    if (iterator == node->index - 1) {
        node->parent->nrOfApp++;
        if (node->parent->parent != NULL) {
            balanceGraph(node->parent);
        }
        return void();
    }

    if (iterator == node->index - 2) {
        (indexedGraph[iterator - 1])->right = indexedGraph[iterator];
        (indexedGraph[iterator - 1])->left = node;
        indexedGraph[iterator]->index++;
        node->index--;
        indexedGraph[iterator] = node;
        indexedGraph[iterator + 1] = (indexedGraph[iterator - 1])->right;
        balanceGraph(node);
        return void();
    }

    if ((iterator - (node->index - 2)) > 0 && node->index - 2 >= 0) {
        aux = indexedGraph[iterator - 1];
        indexedGraph[iterator - 1] = node;
        auxIndex = node->index;
        parent = aux->parent;
        changeAux = node->parent;
        if (iterator % 2 == 0) {
            parent->left = node;
        } else {
            parent->right = node;
        }
        node->parent = parent;

        indexedGraph[auxIndex - 1] = aux;
        if (auxIndex % 2 == 0) {
            changeAux->left = node;
        } else {
            changeAux->right = node;
        }
        balanceGraph(indexedGraph[iterator - 1]);
        //return void();
    }
    //return void();
}

void encodeSymbol(unsigned char symbol, GraphTree *parent) {
    GraphSearch result;

    result = findSymbol(symbol);
    if (result.type == true) {
        updateSymbol(result);
    } else {
        addSymbol(result, symbol);
    }

    balanceGraph(result.reference);

}

void swapChild(GraphTree *root) {
    GraphTree *aux;
    aux = root->left;
    root->left = root->right;
    root->right = aux;
}

void balanceTree(GraphTree *root) {

    if ((root->symbol + root->symbolExtended) == 0) {
        if (root->left->nrOfApp < root->right->nrOfApp) {
            swapChild(root);
        }
    }
}

void encodeFile() {

}

void compressFile(std::string fileName) {

    GraphTree *huffmanTree;
    huffmanTree = initGraph();
    encodeSymbol('a', huffmanTree);
    encodeSymbol('b', huffmanTree);
    displayIndexedGraph();
    std::cout << "\n\n";
    displayGraph(huffmanTree);
//    balanceTree(huffmanTree);
//    encodeSymbol('b', huffmanTree);
//    balanceTree(huffmanTree);
//    std::cout << "\n\n";
//    displayGraph(huffmanTree);
}

void uncompressFile(std::string fileName) {

}

void displayOptions() {
    std::cout << "Alege fisierul!" << "\n\n Audio:\n";
    std::cout << "\t1.)instr_01.wav\n";
    std::cout << "\t2.)sound_01.wav\n";
    std::cout << "\t3.)speech_01.wav\n";
    std::cout << "\nDocuments:\n";
    std::cout << "\t4.)Documentatie_UMAPID.doc\n";
    std::cout << "\t5.)Documentatie_UMAPID.pdf\n";
    std::cout << "\t6.)Prefata_Undine.txt\n";
    std::cout << "\t7.)show_audio.m\n";
    std::cout << "\t8.)Y04.M\n";
    std::cout << "\nExecutables:\n";
    std::cout << "\t9.)KARMA_DATA482#1_5_V7.mat\n";
    std::cout << "\t10.)quartz.dll\n";
    std::cout << "\t11.)WinRar.exe\n";
    std::cout << "\t12.)WINZIP32.EXE\n";

}

std::ifstream::pos_type filesize(std::string fileName) {
    std::ifstream in(fileName.c_str(), std::ifstream::ate | std::ifstream::binary);
    return in.tellg();
}

void displayInformations(std::string fileName) {
    std::ifstream::pos_type compressedFileSize, fileSize, uncompressedFileSize;
    std::string compressedFileName, uncompressedFileName;

    compressedFileName = fileName + ".psh";
    uncompressedFileName = fileName + ".pshu";

    compressedFileSize = filesize(compressedFileName);
    fileSize = filesize(fileName);
    uncompressedFileSize = filesize(uncompressedFileName);

    std::cout << "Norma: " << (fileSize - uncompressedFileSize) * (fileSize - uncompressedFileSize) << "\n";
    std::cout << "Rata compresie: " << (1 - ((float) compressedFileSize) / ((float) uncompressedFileSize)) * 100 << "%\n";
    std::cout << "Factor compresie:  " << (((float) compressedFileSize) / ((float) fileSize)) * 100 << "%\n";

}

int main() {

    std::vector<std::string> files = {
            ".\\audio\\instr_01.wav",
            ".\\audio\\sound_01.wav",
            ".\\audio\\speech_01.wav",
            ".\\documents\\Documentatie_UMAPID.doc",
            ".\\documents\\Documentatie_UMAPID.pdf",
            ".\\documents\\Prefata_Undine.txt",
            ".\\documents\\show_audio.m",
            ".\\documents\\Y04.M",
            ".\\executables\\KARMA_DATA482#1_5_V7.mat",
            ".\\executables\\quartz.dll",
            ".\\executables\\WinRar.exe",
            ".\\executables\\WINZIP32.EXE",
            ".\\documents\\input.txt",
            "D:\\input.txt",
    };

    int option;
    //displayOptions();
    //std::cout << "Select file!..\n";
    //std::cin >> option;
//    if (option < 1 && option > 14) {
//        std::cout << "Invalid option!";
//        return 0;
//    }
    auto startC = std::chrono::high_resolution_clock::now();

    compressFile(files[2]);
    auto endC = std::chrono::high_resolution_clock::now();
    auto timeC = endC - startC;
    std::cout << "Compressed time: " << std::chrono::duration_cast<miliseconds_type>(timeC).count() << " miliseconds.\n";

    auto startU = std::chrono::high_resolution_clock::now();
//    uncompressFile(files[option - 1]);

    auto endU = std::chrono::high_resolution_clock::now();
    auto timeU = endU - startU;
    std::cout << "Uncompressed time: " << std::chrono::duration_cast<miliseconds_type>(timeU).count() << " miliseconds.\n";
//    displayInformations(files[option - 1]);

    //std::cin >> option;

    return 0;
}<|endoftext|>


<commit_before>/*
The MIT License

Copyright (c) 2010 Bryan Ivory bivory+textureatlas@gmail.com

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 <assert.h>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>

#include "png.hpp"
#include "TexturePacker.h"
#include "tclap/CmdLine.h"

#define VERSION "2010.09.06"

class TextureInfo;

class TextureAtlasInfoVisitor
   {
   public:
      virtual void visit(TextureInfo &im_info,
                         int x, int y, int width, int height, bool rot90) = 0;
   };

class TextureInfo
   {
   public:
      TextureInfo(int index, std::string path)
         : idx(index), im_path(path)
      {
      im = new png::image<png::rgba_pixel>(im_path,
            png::convert_color_space<png::rgba_pixel>());
      }

      void index(size_t i) { idx = i; }
      int index() const { return idx; }
      std::string path() const { return im_path; }
      png::image<png::rgba_pixel>* image() const { return im; }

      void writeTo(png::image< png::rgba_pixel > &outimage,
                   const size_t offset_x, const size_t offset_y,
                   const size_t out_width, const size_t out_height,
                   const bool rotate90)
      {
      for(size_t out_y = offset_y; out_y < (offset_y + out_height); ++out_y)
         {
         for(size_t out_x = offset_x; out_x < (offset_x + out_width); ++out_x)
            {
            if (rotate90)
               {
               size_t rot_y = im->get_height() - (out_x - offset_x) - 1;
               size_t rot_x = (out_y - offset_y);
               png::rgba_pixel px = (*im)[rot_y][rot_x];
               outimage[out_y][out_x] = px;
               }
            else
               {
               size_t rot_y = out_y - offset_y;
               size_t rot_x = out_x - offset_x;
               outimage[out_y][out_x] = (*im)[rot_y][rot_x];
               }
            }
         }
      }

   private:
      int                           idx;
      std::string                   im_path;
      png::image<png::rgba_pixel>*   im;
   };

class TextureAtlasInfo
   {
   public:
      TextureAtlasInfo(size_t atlas_width, size_t atlas_height, size_t im_count)
         : atlas_max_width(atlas_width), atlas_max_height(atlas_height),
            atlas_unused_pixels(0), images()
      {
      atlas = TEXTURE_PACKER::createTexturePacker();
      atlas->setTextureCount(im_count);
      }

      ~TextureAtlasInfo(void)
      {
      delete(atlas);
      }

      bool addTexture(TextureInfo* im_info)
      {
      png::image<png::rgba_pixel>* im = im_info->image();
      bool fit = atlas->wouldTextureFit(im->get_width(), im->get_height(),
                                        true, false,
                                        atlas_max_width, atlas_max_height);

      if (!fit)
         {
         return false;
         }

      atlas->addTexture(im->get_width(), im->get_height());
      im_info->index(atlas->getTextureCount() - 1);
      images.push_back(im_info);
      return true;
      }

      void packTextures(void)
      {
      int w, h;
      atlas_unused_pixels = atlas->packTextures(w, h, true, false);
      atlas_max_width = w;
      atlas_max_height = h;
      }

      size_t packedCount(void) { return atlas->getTextureCount(); }
      size_t packedUnusedPixels(void) { return atlas_unused_pixels; }
      size_t packedWidth(void) { return atlas_max_width; }
      size_t packedHeight(void) { return atlas_max_height; }

      void visit(TextureAtlasInfoVisitor &taiv)
      {
      for(std::list<TextureInfo *>::iterator images_iter = images.begin();
          images_iter != images.end();
          images_iter++)
         {
         TextureInfo* im_info = *images_iter;
         int x, y, width, height;
         bool rot90;
         rot90 = atlas->getTextureLocation(im_info->index(),
                                           x, y, width, height);

         taiv.visit(*im_info, x, y, width, height, rot90);
         }

      }

   private:
      size_t                           atlas_unused_pixels;
      size_t                           atlas_max_width;
      size_t                           atlas_max_height;
      TEXTURE_PACKER::TexturePacker*   atlas;
      std::list<TextureInfo *>         images;
   };

class TextureAtlasInfoWriteVisitor : public TextureAtlasInfoVisitor
   {
   public:
   TextureAtlasInfoWriteVisitor(std::string path, size_t w, size_t h) :
      out_image_path(path), out_image(w, h)
      {
      }

   ~TextureAtlasInfoWriteVisitor(void)
      {
      out_image.write(out_image_path + ".png");
      }

   void visit(TextureInfo &im_info,
              int x, int y, int width, int height, bool rot90)
      {
      im_info.writeTo(out_image, x, y, width, height, rot90);
      }

   private:
   png::image<png::rgba_pixel> out_image;
   std::string                 out_image_path;
   };

class TextureAtlasInfoDebugWriteVisitor : public TextureAtlasInfoVisitor
   {
   public:
   TextureAtlasInfoDebugWriteVisitor(std::string path,
                                     size_t w, size_t h,
                                     size_t num_packed, size_t unused) :
      out_image_path(path), out_image_width(w), out_image_height(h)
      {
      std::cout << "Packed " << num_packed << " images to " << path << ".png"
         << " with " << unused << " unused area "
         << "Width (" << w << ") x Height (" << h  << ")"
         << std::endl;
      }

   ~TextureAtlasInfoDebugWriteVisitor(void)
      {
      std::cout << std::endl;
      }

   void visit(TextureInfo &im_info,
              int x, int y, int width, int height, bool rot90)
      {
      std::cout << im_info.path() << " => ";
      if (rot90) std::cout << "rotated 90 ";
      std::cout  << "x: " << x << " "
         << "y: " << y << " "
         << "width: " << width << " "
         << "height: " << height << " "
         << std::endl;
      }

   private:
   std::string                   out_image_path;
   size_t                        out_image_width;
   size_t                        out_image_height;
   };

class TextureAtlasInfoCSVWriteVisitor : public TextureAtlasInfoVisitor
   {
   public:
   TextureAtlasInfoCSVWriteVisitor(std::string path, size_t w, size_t h) :
      out_image_path(path), out_image_width(w), out_image_height(h)
      {
      }

   ~TextureAtlasInfoCSVWriteVisitor(void)
      {
      }

   void visit(TextureInfo &im_info,
              int x, int y, int width, int height, bool rot90)
      {
      }

   private:
   std::string                   out_image_path;
   size_t                        out_image_width;
   size_t                        out_image_height;
   };

int
main(int argc, char* argv[])
{
std::string                                  out_atlas_name = "";
size_t                                       out_atlas_height = 0;
size_t                                       out_atlas_width = 0;
std::vector<std::string>                     image_names;
std::list<TextureAtlasInfo *>                atlases;

// Read in the command line arguements
try
   {
   TCLAP::CmdLine cmd("Creates a texture atlas from a list of PNG files.",
                      ' ', VERSION, true);

   // Output atlas file name
   TCLAP::ValueArg<std::string> out_atlas_name_arg(
         "o","out_name",
         "Output atlas image's file name.",
         false, "out_atlas", "string");
   cmd.add(out_atlas_name_arg);

   // Output atlas image dimensions
   TCLAP::ValueArg<size_t> out_atlas_width_arg(
         "x","out_width",
         "Maximum output atlas image's width.",
         false, 1024, "pixels");
   cmd.add(out_atlas_width_arg);

   TCLAP::ValueArg<size_t> out_atlas_height_arg(
         "y","out_height",
         "Maximum output atlas image's height.",
         false, 1024, "pixels");
   cmd.add(out_atlas_height_arg);

   // Input image files
   TCLAP::UnlabeledMultiArg<std::string> in_image_names_arg(
         "in_names", "List of the image filenames.", true, "PNG file path");
   cmd.add(in_image_names_arg);

   cmd.parse(argc, argv);
   out_atlas_name = out_atlas_name_arg.getValue();
   out_atlas_width = out_atlas_width_arg.getValue();
   out_atlas_height = out_atlas_height_arg.getValue();
   image_names = in_image_names_arg.getValue();
   }
catch (TCLAP::ArgException &e)
   {
   std::cerr << "Error: " << e.error() << " for arg " << e.argId() << std::endl;
   return 1;
   }

// Create the initial texture atlas
atlases.push_back(new TextureAtlasInfo(out_atlas_width, out_atlas_height,
                                       image_names.size()));

// Load the textures
for(size_t idx = 0; idx < image_names.size(); idx++)
   {
   try
      {
      // Load the image
      TextureInfo* ti = new TextureInfo(idx, image_names[idx]);
      if (ti->image()->get_width() > out_atlas_width ||
          ti->image()->get_height() > out_atlas_height)
         {
         std::cerr << "Error: " << ti->path() << " is too big!" << std::endl;
         std::cerr << "Image dimensions: " << ti->image()->get_width()
            << " x " << ti->image()->get_height() << std::endl;
         std::cerr << "Atlas dimensions: " << out_atlas_width
            << " x " << out_atlas_height << std::endl;
         return 1;
         }

      // Add to the atlas
      TextureAtlasInfo* tai = atlases.back();
      if (!tai->addTexture(ti))
         {
         // Create a new atlas
         TextureAtlasInfo* tai_next = new TextureAtlasInfo(out_atlas_width,
                                                           out_atlas_height,
                                                           image_names.size());
         tai_next->addTexture(ti);
         atlases.push_back(tai_next);
         }
      }
   catch(png::std_error &e)
      {
      std::cerr << e.what() << std::endl;
      return 1;
      }
   }

// Pack and write out the atlases
int idx = 0;
for(std::list<TextureAtlasInfo *>::iterator atlases_iter = atlases.begin();
    atlases_iter != atlases.end();
    atlases_iter++, idx++)
   {
   std::ostringstream oss;
   oss << out_atlas_name << "_" << idx;
   std::string atlas_name(oss.str());

   TextureAtlasInfo* tai = *atlases_iter;
   tai->packTextures();

   TextureAtlasInfoWriteVisitor tai_writer(atlas_name,
                                           tai->packedWidth(),
                                           tai->packedHeight());
   TextureAtlasInfoDebugWriteVisitor tai_debug(atlas_name,
                                               tai->packedWidth(),
                                               tai->packedHeight(),
                                               tai->packedCount(),
                                               tai->packedUnusedPixels());
   tai->visit(tai_writer);
   tai->visit(tai_debug);
   }

return 0;
}

<commit_msg>Added command line option for suppressing processing info to stdout<commit_after>/*
The MIT License

Copyright (c) 2010 Bryan Ivory bivory+textureatlas@gmail.com

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 <assert.h>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>

#include "png.hpp"
#include "TexturePacker.h"
#include "tclap/CmdLine.h"

#define VERSION "2010.09.06"

class TextureInfo;

class TextureAtlasInfoVisitor
   {
   public:
      virtual void visit(TextureInfo &im_info,
                         int x, int y, int width, int height, bool rot90) = 0;
   };

class TextureInfo
   {
   public:
      TextureInfo(int index, std::string path)
         : idx(index), im_path(path)
      {
      im = new png::image<png::rgba_pixel>(im_path,
            png::convert_color_space<png::rgba_pixel>());
      }

      void index(size_t i) { idx = i; }
      int index() const { return idx; }
      std::string path() const { return im_path; }
      png::image<png::rgba_pixel>* image() const { return im; }

      void writeTo(png::image< png::rgba_pixel > &outimage,
                   const size_t offset_x, const size_t offset_y,
                   const size_t out_width, const size_t out_height,
                   const bool rotate90)
      {
      for(size_t out_y = offset_y; out_y < (offset_y + out_height); ++out_y)
         {
         for(size_t out_x = offset_x; out_x < (offset_x + out_width); ++out_x)
            {
            if (rotate90)
               {
               size_t rot_y = im->get_height() - (out_x - offset_x) - 1;
               size_t rot_x = (out_y - offset_y);
               png::rgba_pixel px = (*im)[rot_y][rot_x];
               outimage[out_y][out_x] = px;
               }
            else
               {
               size_t rot_y = out_y - offset_y;
               size_t rot_x = out_x - offset_x;
               outimage[out_y][out_x] = (*im)[rot_y][rot_x];
               }
            }
         }
      }

   private:
      int                           idx;
      std::string                   im_path;
      png::image<png::rgba_pixel>*   im;
   };

class TextureAtlasInfo
   {
   public:
      TextureAtlasInfo(size_t atlas_width, size_t atlas_height, size_t im_count)
         : atlas_max_width(atlas_width), atlas_max_height(atlas_height),
            atlas_unused_pixels(0), images()
      {
      atlas = TEXTURE_PACKER::createTexturePacker();
      atlas->setTextureCount(im_count);
      }

      ~TextureAtlasInfo(void)
      {
      delete(atlas);
      }

      bool addTexture(TextureInfo* im_info)
      {
      png::image<png::rgba_pixel>* im = im_info->image();
      bool fit = atlas->wouldTextureFit(im->get_width(), im->get_height(),
                                        true, false,
                                        atlas_max_width, atlas_max_height);

      if (!fit)
         {
         return false;
         }

      atlas->addTexture(im->get_width(), im->get_height());
      im_info->index(atlas->getTextureCount() - 1);
      images.push_back(im_info);
      return true;
      }

      void packTextures(void)
      {
      int w, h;
      atlas_unused_pixels = atlas->packTextures(w, h, true, false);
      atlas_max_width = w;
      atlas_max_height = h;
      }

      size_t packedCount(void) { return atlas->getTextureCount(); }
      size_t packedUnusedPixels(void) { return atlas_unused_pixels; }
      size_t packedWidth(void) { return atlas_max_width; }
      size_t packedHeight(void) { return atlas_max_height; }

      void visit(TextureAtlasInfoVisitor &taiv)
      {
      for(std::list<TextureInfo *>::iterator images_iter = images.begin();
          images_iter != images.end();
          images_iter++)
         {
         TextureInfo* im_info = *images_iter;
         int x, y, width, height;
         bool rot90;
         rot90 = atlas->getTextureLocation(im_info->index(),
                                           x, y, width, height);

         taiv.visit(*im_info, x, y, width, height, rot90);
         }

      }

   private:
      size_t                           atlas_unused_pixels;
      size_t                           atlas_max_width;
      size_t                           atlas_max_height;
      TEXTURE_PACKER::TexturePacker*   atlas;
      std::list<TextureInfo *>         images;
   };

class TextureAtlasInfoWriteVisitor : public TextureAtlasInfoVisitor
   {
   public:
   TextureAtlasInfoWriteVisitor(std::string path, size_t w, size_t h) :
      out_image_path(path), out_image(w, h)
      {
      }

   ~TextureAtlasInfoWriteVisitor(void)
      {
      out_image.write(out_image_path + ".png");
      }

   void visit(TextureInfo &im_info,
              int x, int y, int width, int height, bool rot90)
      {
      im_info.writeTo(out_image, x, y, width, height, rot90);
      }

   private:
   png::image<png::rgba_pixel> out_image;
   std::string                 out_image_path;
   };

class TextureAtlasInfoDebugWriteVisitor : public TextureAtlasInfoVisitor
   {
   public:
   static std::string name() { return "debug"; }

   TextureAtlasInfoDebugWriteVisitor(std::string path,
                                     size_t w, size_t h,
                                     size_t num_packed, size_t unused) :
      out_image_path(path), out_image_width(w), out_image_height(h)
      {
      std::cout << "Packed " << num_packed << " images to " << path << ".png"
         << " with " << unused << " unused area "
         << "Width (" << w << ") x Height (" << h  << ")"
         << std::endl;
      }

   ~TextureAtlasInfoDebugWriteVisitor(void)
      {
      std::cout << std::endl;
      }

   void visit(TextureInfo &im_info,
              int x, int y, int width, int height, bool rot90)
      {
      std::cout << im_info.path() << " => ";
      if (rot90) std::cout << "rotated 90 ";
      std::cout  << "x: " << x << " "
         << "y: " << y << " "
         << "width: " << width << " "
         << "height: " << height << " "
         << std::endl;
      }

   private:
   std::string                   out_image_path;
   size_t                        out_image_width;
   size_t                        out_image_height;
   };

class TextureAtlasInfoCSVWriteVisitor : public TextureAtlasInfoVisitor
   {
   public:
   TextureAtlasInfoCSVWriteVisitor(std::string path, size_t w, size_t h) :
      out_image_path(path), out_image_width(w), out_image_height(h)
      {
      }

   ~TextureAtlasInfoCSVWriteVisitor(void)
      {
      }

   void visit(TextureInfo &im_info,
              int x, int y, int width, int height, bool rot90)
      {
      }

   private:
   std::string                   out_image_path;
   size_t                        out_image_width;
   size_t                        out_image_height;
   };

int
main(int argc, char* argv[])
{
std::string                                  out_atlas_name = "";
size_t                                       out_atlas_height = 0;
size_t                                       out_atlas_width = 0;
std::vector<std::string>                     out_visitors_str;
std::vector<std::string>                     image_names;
std::list<TextureAtlasInfo *>                atlases;

// Read in the command line arguements
try
   {
   TCLAP::CmdLine cmd("Creates a texture atlas from a list of PNG files.",
                      ' ', VERSION, true);

   // Output atlas file name
   TCLAP::ValueArg<std::string> out_atlas_name_arg(
         "o","out_name",
         "Output atlas image's file name.",
         false, "out_atlas", "string");
   cmd.add(out_atlas_name_arg);

   // Output atlas image dimensions
   TCLAP::ValueArg<size_t> out_atlas_width_arg(
         "x","out_width",
         "Maximum output atlas image's width.",
         false, 1024, "pixels");
   cmd.add(out_atlas_width_arg);

   TCLAP::ValueArg<size_t> out_atlas_height_arg(
         "y","out_height",
         "Maximum output atlas image's height.",
         false, 1024, "pixels");
   cmd.add(out_atlas_height_arg);

   // Input image files
   TCLAP::UnlabeledMultiArg<std::string> in_image_names_arg(
         "in_names", "List of the image filenames.", true, "PNG file path");
   cmd.add(in_image_names_arg);

   // Output visitors
   TCLAP::SwitchArg quiet_arg("q", "quiet",
                              "Suppress processing information output.", false);
   cmd.add(quiet_arg);

   TCLAP::MultiArg<std::string> out_vistors_arg("i", "info_writers",
                                                "Atlas information writers.",
                                                false, "string");
   cmd.add(out_vistors_arg);

   // Parse the command line options
   cmd.parse(argc, argv);
   out_atlas_name = out_atlas_name_arg.getValue();
   out_atlas_width = out_atlas_width_arg.getValue();
   out_atlas_height = out_atlas_height_arg.getValue();

   if (!quiet_arg.getValue())
      {
      out_visitors_str.push_back(TextureAtlasInfoDebugWriteVisitor::name());
      }

#if 0
   out_visitors_str = out_vistors_arg.getValue();
#endif

   image_names = in_image_names_arg.getValue();
   }
catch (TCLAP::ArgException &e)
   {
   std::cerr << "Error: " << e.error() << " for arg " << e.argId() << std::endl;
   return 1;
   }

// Create the initial texture atlas
atlases.push_back(new TextureAtlasInfo(out_atlas_width, out_atlas_height,
                                       image_names.size()));

// Load the textures
for(size_t idx = 0; idx < image_names.size(); idx++)
   {
   try
      {
      // Load the image
      TextureInfo* ti = new TextureInfo(idx, image_names[idx]);
      if (ti->image()->get_width() > out_atlas_width ||
          ti->image()->get_height() > out_atlas_height)
         {
         std::cerr << "Error: " << ti->path() << " is too big!" << std::endl;
         std::cerr << "Image dimensions: " << ti->image()->get_width()
            << " x " << ti->image()->get_height() << std::endl;
         std::cerr << "Atlas dimensions: " << out_atlas_width
            << " x " << out_atlas_height << std::endl;
         return 1;
         }

      // Add to the atlas
      TextureAtlasInfo* tai = atlases.back();
      if (!tai->addTexture(ti))
         {
         // Create a new atlas
         TextureAtlasInfo* tai_next = new TextureAtlasInfo(out_atlas_width,
                                                           out_atlas_height,
                                                           image_names.size());
         tai_next->addTexture(ti);
         atlases.push_back(tai_next);
         }
      }
   catch(png::std_error &e)
      {
      std::cerr << e.what() << std::endl;
      return 1;
      }
   }

// Pack and write out the atlases
int idx = 0;
for(std::list<TextureAtlasInfo *>::iterator atlases_iter = atlases.begin();
    atlases_iter != atlases.end();
    atlases_iter++, idx++)
   {
   std::ostringstream oss;
   oss << out_atlas_name << "_" << idx;
   std::string atlas_name(oss.str());

   TextureAtlasInfo* tai = *atlases_iter;
   tai->packTextures();

   TextureAtlasInfoWriteVisitor tai_writer(atlas_name,
                                           tai->packedWidth(),
                                           tai->packedHeight());
   tai->visit(tai_writer);

   // Ugly way to do this.
   for(std::vector<std::string>::iterator vis_iter = out_visitors_str.begin();
       vis_iter != out_visitors_str.end();
       vis_iter++)
      {
      TextureAtlasInfoVisitor* taiv = NULL;

      if (vis_iter->compare(TextureAtlasInfoDebugWriteVisitor::name()) == 0)
         {
         taiv = new TextureAtlasInfoDebugWriteVisitor(atlas_name,
                                                   tai->packedWidth(),
                                                   tai->packedHeight(),
                                                   tai->packedCount(),
                                                   tai->packedUnusedPixels());
         }

      if (taiv != NULL)
         {
         tai->visit(*taiv);
         delete taiv;
         }
      }

   }

return 0;
}

<|endoftext|>


<commit_before>#include "dbusgateway.h"

#include <boost/shared_ptr.hpp>
#include "logger.h"
#include "types.h"

DbusGateway::DbusGateway(const Config& config_in, command::Channel* command_channel_in)
    : stop(false), config(config_in), command_channel(command_channel_in), swlm(config) {
  dbus_threads_init_default();
  dbus_error_init(&err);
  conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
  if (dbus_error_is_set(&err)) {
    LOGGER_LOG(LVL_error, "D-Bus Connection Error: " << err.message);
    dbus_error_free(&err);
    return;
  }

  int ret = dbus_bus_request_name(conn, config_in.dbus.interface.c_str(), DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
    LOGGER_LOG(LVL_error, "Cannot request D-Bus name '"
                              << config_in.dbus.interface << "' as primary owner. D-Bus communication disabled");
    return;
  }
  thread = boost::thread(boost::bind(&DbusGateway::run, this));
}

DbusGateway::~DbusGateway() {
  stop = true;
  if (!thread.try_join_for(boost::chrono::seconds(10))) {
    LOGGER_LOG(LVL_error, "join()-ing DBusGateway thread timed out");
  }
  dbus_bus_release_name(conn, config.dbus.interface.c_str(), NULL);
  dbus_connection_unref(conn);
}

void DbusGateway::processEvent(const boost::shared_ptr<event::BaseEvent>& event) {
  if (event->variant == "DownloadComplete") {
    event::DownloadComplete* download_complete_event = static_cast<event::DownloadComplete*>(event.get());
    swlm.downloadComplete(download_complete_event->download_complete.update_image,
                          download_complete_event->download_complete.signature);
    fireDownloadCompleteEvent(download_complete_event->download_complete);
  } else if (event->variant == "InstalledSoftwareNeeded") {
    fireInstalledSoftwareNeededEvent();
  } else if (event->variant == "UpdateAvailable") {
    event::UpdateAvailable* update_available_event = static_cast<event::UpdateAvailable*>(event.get());
    fireUpdateAvailableEvent(update_available_event->update_vailable);
  }
}

void DbusGateway::fireInstalledSoftwareNeededEvent() {
  DBusMessage* msg;
  msg = dbus_message_new_signal(config.dbus.path.c_str(), config.dbus.interface.c_str(), "InstalledSoftwareNeeded");

  dbus_connection_send(conn, msg, NULL);

  dbus_message_unref(msg);
}

void DbusGateway::fireUpdateAvailableEvent(const data::UpdateAvailable& update_available) {
  DBusMessage* msg;
  DBusMessageIter iter;

  msg = dbus_message_new_signal(config.dbus.path.c_str(), config.dbus.interface.c_str(), "UpdateAvailable");

  dbus_message_iter_init_append(msg, &iter);

  DBusMessageIter sub_iter;
  dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub_iter);
  const char* update_id = update_available.update_id.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &update_id);
  const char* description = update_available.description.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &description);
  const char* signature = update_available.signature.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &signature);
  unsigned long long size = update_available.size;
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_UINT64, &size);

  dbus_message_iter_close_container(&iter, &sub_iter);

  dbus_connection_send(conn, msg, NULL);

  dbus_message_unref(msg);
}

void DbusGateway::fireDownloadCompleteEvent(const data::DownloadComplete& download_complete) {
  DBusMessage* msg;
  DBusMessageIter iter;

  msg = dbus_message_new_signal(config.dbus.path.c_str(), config.dbus.interface.c_str(), "DownloadComplete");
  dbus_message_iter_init_append(msg, &iter);

  DBusMessageIter sub_iter;
  dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub_iter);
  const char* update_id = download_complete.update_id.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &update_id);
  const char* update_image = download_complete.update_image.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &update_image);
  const char* signature = download_complete.signature.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &signature);
  dbus_message_iter_close_container(&iter, &sub_iter);

  dbus_connection_send(conn, msg, NULL);
  dbus_message_unref(msg);
}

void DbusGateway::run() {
  DBusMessage* msg;
  char* string_param = NULL;
  DBusMessageIter args;

  while (true) {
    dbus_connection_read_write(conn, 0);
    msg = dbus_connection_pop_message(conn);
    if (NULL == msg) {
      boost::this_thread::sleep_for(boost::chrono::seconds(1));
      if (stop) {
        return;
      }
      continue;
    }

    if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "initiateDownload") ||
        dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "abortDownload") ||
        dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "updateReport")) {
      if (!dbus_message_iter_init(msg, &args) || DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
        LOGGER_LOG(LVL_error, "D-Bus method initiateDownload called with wrong arguments");
        dbus_message_unref(msg);
        continue;
      } else {
        dbus_message_iter_get_basic(&args, &string_param);
      }
    }
    if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "initiateDownload")) {
      *command_channel << boost::shared_ptr<command::StartDownload>(new command::StartDownload(string_param));
    } else if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "abortDownload")) {
      *command_channel << boost::shared_ptr<command::AbortDownload>(new command::AbortDownload(string_param));
    } else if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "updateReport")) {
      data::UpdateReport update_report;
      update_report.update_id = string_param;
      if (dbus_message_iter_next(&args) && DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&args)) {
        DBusMessageIter operation_result_args;
        int results_count = dbus_message_iter_get_element_count(&args);
        dbus_message_iter_recurse(&args, &operation_result_args);
        do {
          try {
            update_report.operation_results.push_back(getOperationResult(&operation_result_args));
          } catch (...) {
            LOGGER_LOG(LVL_error, "D-Bus method 'updateReport' called with wrong arguments");
          }
          dbus_message_iter_next(&operation_result_args);
          results_count--;
        } while (results_count);

      } else {
        LOGGER_LOG(LVL_error, "D-Bus method called with wrong arguments");
        dbus_message_unref(msg);
        continue;
      }
      *command_channel << boost::shared_ptr<command::SendUpdateReport>(new command::SendUpdateReport(update_report));
    }

    int message_type = dbus_message_get_type(msg);
    LOGGER_LOG(LVL_trace, "Got D-Bus message type:" << dbus_message_type_to_string(message_type));
    if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) {
      DBusMessage* reply = dbus_message_new_method_return(msg);
      dbus_bool_t ok = dbus_connection_send(conn, reply, NULL);
      if (!ok) {
        LOGGER_LOG(LVL_error, "D-Bus method send failed");
      }
      dbus_connection_flush(conn);

      dbus_message_unref(reply);
    }
    dbus_message_unref(msg);
  }
}

data::OperationResult DbusGateway::getOperationResult(DBusMessageIter* iter) {
  DBusMessageIter subiter, dict_iter, variant_iter;
  char* string_param;
  int int_param;
  data::OperationResult result;
  int params = dbus_message_iter_get_element_count(iter);
  dbus_message_iter_recurse(iter, &subiter);
  if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(iter)) {
    while (params) {
      dbus_message_iter_recurse(&subiter, &dict_iter);
      dbus_message_iter_get_basic(&dict_iter, &string_param);
      dbus_message_iter_next(&dict_iter);
      dbus_message_iter_recurse(&dict_iter, &variant_iter);
      if (std::string(string_param) == "id") {
        dbus_message_iter_get_basic(&variant_iter, &string_param);
        result.id = string_param;
        dbus_message_iter_next(&subiter);
      } else if (std::string(string_param) == "result_code") {
        dbus_message_iter_get_basic(&variant_iter, &int_param);
        result.result_code = (data::UpdateResultCode)int_param;
        dbus_message_iter_next(&subiter);
      } else if (std::string(string_param) == "result_text") {
        dbus_message_iter_get_basic(&variant_iter, &string_param);
        result.result_text = string_param;
        dbus_message_iter_next(&subiter);
      }
      params--;
    }
  }
  return result;
}
<commit_msg>Do not use newer API<commit_after>#include "dbusgateway.h"

#include <boost/shared_ptr.hpp>
#include "logger.h"
#include "types.h"

DbusGateway::DbusGateway(const Config& config_in, command::Channel* command_channel_in)
    : stop(false), config(config_in), command_channel(command_channel_in), swlm(config) {
  dbus_threads_init_default();
  dbus_error_init(&err);
  conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
  if (dbus_error_is_set(&err)) {
    LOGGER_LOG(LVL_error, "D-Bus Connection Error: " << err.message);
    dbus_error_free(&err);
    return;
  }

  int ret = dbus_bus_request_name(conn, config_in.dbus.interface.c_str(), DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
    LOGGER_LOG(LVL_error, "Cannot request D-Bus name '"
                              << config_in.dbus.interface << "' as primary owner. D-Bus communication disabled");
    return;
  }
  thread = boost::thread(boost::bind(&DbusGateway::run, this));
}

DbusGateway::~DbusGateway() {
  stop = true;
  if (!thread.try_join_for(boost::chrono::seconds(10))) {
    LOGGER_LOG(LVL_error, "join()-ing DBusGateway thread timed out");
  }
  dbus_bus_release_name(conn, config.dbus.interface.c_str(), NULL);
  dbus_connection_unref(conn);
}

void DbusGateway::processEvent(const boost::shared_ptr<event::BaseEvent>& event) {
  if (event->variant == "DownloadComplete") {
    event::DownloadComplete* download_complete_event = static_cast<event::DownloadComplete*>(event.get());
    swlm.downloadComplete(download_complete_event->download_complete.update_image,
                          download_complete_event->download_complete.signature);
    fireDownloadCompleteEvent(download_complete_event->download_complete);
  } else if (event->variant == "InstalledSoftwareNeeded") {
    fireInstalledSoftwareNeededEvent();
  } else if (event->variant == "UpdateAvailable") {
    event::UpdateAvailable* update_available_event = static_cast<event::UpdateAvailable*>(event.get());
    fireUpdateAvailableEvent(update_available_event->update_vailable);
  }
}

void DbusGateway::fireInstalledSoftwareNeededEvent() {
  DBusMessage* msg;
  msg = dbus_message_new_signal(config.dbus.path.c_str(), config.dbus.interface.c_str(), "InstalledSoftwareNeeded");

  dbus_connection_send(conn, msg, NULL);

  dbus_message_unref(msg);
}

void DbusGateway::fireUpdateAvailableEvent(const data::UpdateAvailable& update_available) {
  DBusMessage* msg;
  DBusMessageIter iter;

  msg = dbus_message_new_signal(config.dbus.path.c_str(), config.dbus.interface.c_str(), "UpdateAvailable");

  dbus_message_iter_init_append(msg, &iter);

  DBusMessageIter sub_iter;
  dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub_iter);
  const char* update_id = update_available.update_id.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &update_id);
  const char* description = update_available.description.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &description);
  const char* signature = update_available.signature.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &signature);
  unsigned long long size = update_available.size;
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_UINT64, &size);

  dbus_message_iter_close_container(&iter, &sub_iter);

  dbus_connection_send(conn, msg, NULL);

  dbus_message_unref(msg);
}

void DbusGateway::fireDownloadCompleteEvent(const data::DownloadComplete& download_complete) {
  DBusMessage* msg;
  DBusMessageIter iter;

  msg = dbus_message_new_signal(config.dbus.path.c_str(), config.dbus.interface.c_str(), "DownloadComplete");
  dbus_message_iter_init_append(msg, &iter);

  DBusMessageIter sub_iter;
  dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub_iter);
  const char* update_id = download_complete.update_id.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &update_id);
  const char* update_image = download_complete.update_image.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &update_image);
  const char* signature = download_complete.signature.c_str();
  dbus_message_iter_append_basic(&sub_iter, DBUS_TYPE_STRING, &signature);
  dbus_message_iter_close_container(&iter, &sub_iter);

  dbus_connection_send(conn, msg, NULL);
  dbus_message_unref(msg);
}

void DbusGateway::run() {
  DBusMessage* msg;
  char* string_param = NULL;
  DBusMessageIter args;

  while (true) {
    dbus_connection_read_write(conn, 0);
    msg = dbus_connection_pop_message(conn);
    if (NULL == msg) {
      boost::this_thread::sleep_for(boost::chrono::seconds(1));
      if (stop) {
        return;
      }
      continue;
    }

    if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "initiateDownload") ||
        dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "abortDownload") ||
        dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "updateReport")) {
      if (!dbus_message_iter_init(msg, &args) || DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
        LOGGER_LOG(LVL_error, "D-Bus method initiateDownload called with wrong arguments");
        dbus_message_unref(msg);
        continue;
      } else {
        dbus_message_iter_get_basic(&args, &string_param);
      }
    }
    if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "initiateDownload")) {
      *command_channel << boost::shared_ptr<command::StartDownload>(new command::StartDownload(string_param));
    } else if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "abortDownload")) {
      *command_channel << boost::shared_ptr<command::AbortDownload>(new command::AbortDownload(string_param));
    } else if (dbus_message_is_method_call(msg, config.dbus.interface.c_str(), "updateReport")) {
      data::UpdateReport update_report;
      update_report.update_id = string_param;
      if (dbus_message_iter_next(&args) && DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&args)) {
        DBusMessageIter operation_result_args;
        dbus_message_iter_recurse(&args, &operation_result_args);
        do {
          try {
            update_report.operation_results.push_back(getOperationResult(&operation_result_args));
          } catch (...) {
            LOGGER_LOG(LVL_error, "D-Bus method 'updateReport' called with wrong arguments");
          }
        } while (dbus_message_iter_next(&operation_result_args));

      } else {
        LOGGER_LOG(LVL_error, "D-Bus method called with wrong arguments");
        dbus_message_unref(msg);
        continue;
      }
      *command_channel << boost::shared_ptr<command::SendUpdateReport>(new command::SendUpdateReport(update_report));
    }

    int message_type = dbus_message_get_type(msg);
    LOGGER_LOG(LVL_trace, "Got D-Bus message type:" << dbus_message_type_to_string(message_type));
    if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) {
      DBusMessage* reply = dbus_message_new_method_return(msg);
      dbus_bool_t ok = dbus_connection_send(conn, reply, NULL);
      if (!ok) {
        LOGGER_LOG(LVL_error, "D-Bus method send failed");
      }
      dbus_connection_flush(conn);

      dbus_message_unref(reply);
    }
    dbus_message_unref(msg);
  }
}

data::OperationResult DbusGateway::getOperationResult(DBusMessageIter* iter) {
  DBusMessageIter subiter, dict_iter, variant_iter;
  char* string_param;
  int int_param;
  data::OperationResult result;
  int params = dbus_message_iter_get_element_count(iter);
  dbus_message_iter_recurse(iter, &subiter);
  if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(iter)) {
    while (params) {
      dbus_message_iter_recurse(&subiter, &dict_iter);
      dbus_message_iter_get_basic(&dict_iter, &string_param);
      dbus_message_iter_next(&dict_iter);
      dbus_message_iter_recurse(&dict_iter, &variant_iter);
      if (std::string(string_param) == "id") {
        dbus_message_iter_get_basic(&variant_iter, &string_param);
        result.id = string_param;
        dbus_message_iter_next(&subiter);
      } else if (std::string(string_param) == "result_code") {
        dbus_message_iter_get_basic(&variant_iter, &int_param);
        result.result_code = (data::UpdateResultCode)int_param;
        dbus_message_iter_next(&subiter);
      } else if (std::string(string_param) == "result_text") {
        dbus_message_iter_get_basic(&variant_iter, &string_param);
        result.result_text = string_param;
        dbus_message_iter_next(&subiter);
      }
      params--;
    }
  }
  return result;
}
<|endoftext|>