<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "clustering/administration/servers/config_client.hpp"

server_config_client_t::server_config_client_t(
        mailbox_manager_t *_mailbox_manager,
        watchable_map_t<peer_id_t, cluster_directory_metadata_t> *_directory_view,
        watchable_map_t<std::pair<peer_id_t, server_id_t>, empty_value_t>
            *_peer_connections_map) :
    mailbox_manager(_mailbox_manager),
    directory_view(_directory_view),
    peer_connections_map(_peer_connections_map),
    directory_subs(
        directory_view,
        std::bind(&server_config_client_t::on_directory_change, this, ph::_1, ph::_2),
        initial_call_t::YES),
    peer_connections_map_subs(
        peer_connections_map,
        std::bind(&server_config_client_t::on_peer_connections_map_change,
            this, ph::_1, ph::_2),
        initial_call_t::YES)
    { }

bool server_config_client_t::set_config(
        const server_id_t &server_id,
        const name_string_t &old_server_name,
        const server_config_t &new_config,
        signal_t *interruptor,
        admin_err_t *error_out) {
    bool name_collision = false, is_noop = false;
    server_config_map.read_all(
    [&](const server_id_t &sid, const server_config_versioned_t *conf) {
        if (sid != server_id && conf->config.name == new_config.name) {
            name_collision = true;
        } else if (sid == server_id && conf->config == new_config) {
            is_noop = true;
        }
    });
    if (name_collision) {
        *error_out = admin_err_t{
            strprintf("Cannot rename server `%s` to `%s` because server `%s` "
                      "already exists.",
                      old_server_name.c_str(), new_config.name.c_str(),
                      new_config.name.c_str()),
            query_state_t::FAILED};
        return false;
    }
    if (is_noop) {
        return true;
    }

    std::string disconnect_msg = strprintf("Lost contact with server `%s` while trying "
        "to change the server configuration. The configuration may or may not have been "
        "changed.", old_server_name.c_str());

    boost::optional<peer_id_t> peer = server_to_peer_map.get_key(server_id);
    if (!static_cast<bool>(peer)) {
        std::string s = strprintf(
            "Could not contact server `%s` while trying to change the server "
            "configuration.  The configuration was not changed.",
            old_server_name.c_str());
        *error_out = admin_err_t{s, query_state_t::FAILED};
        return false;
    }
    server_config_business_card_t bcard;
    directory_view->read_key(*peer, [&](const cluster_directory_metadata_t *md) {
        guarantee(md != nullptr);
        bcard = md->server_config_business_card.get();
    });

    server_config_version_t version;
    {
        promise_t<std::pair<server_config_version_t, std::string> > reply;
        mailbox_t<void(server_config_version_t, std::string)> ack_mailbox(
            mailbox_manager,
            [&](signal_t *, server_config_version_t v, const std::string &m) {
                reply.pulse(std::make_pair(v, m));
            });
        disconnect_watcher_t disconnect_watcher(mailbox_manager, *peer);
        send(mailbox_manager, bcard.set_config_addr,
            new_config, ack_mailbox.get_address());
        wait_any_t waiter(reply.get_ready_signal(), &disconnect_watcher);
        wait_interruptible(&waiter, interruptor);
        if (!reply.is_pulsed()) {
            *error_out = admin_err_t{disconnect_msg, query_state_t::INDETERMINATE};
            return false;
        }
        if (!reply.assert_get_value().second.empty()) {
            guarantee(reply.assert_get_value().first == 0);
            *error_out = admin_err_t{
                strprintf("Error when trying to change the configuration of "
                          "server `%s`: %s The configuration was not changed.",
                          old_server_name.c_str(),
                          reply.assert_get_value().second.c_str()),
                query_state_t::FAILED};
            return false;
        }
        version = reply.assert_get_value().first;
    }

    /* Wait up to 10 seconds for the change to appear in the directory. */
    try {
        signal_timer_t timeout;
        timeout.start(10000);
        wait_any_t waiter(interruptor, &timeout);
        server_config_map.run_key_until_satisfied(
            server_id,
            [&](const server_config_versioned_t *conf) {
                return conf == nullptr || conf->version >= version;
            },
            &waiter);
    } catch (const interrupted_exc_t &) {
        if (interruptor->is_pulsed()) {
            throw;
        }
    }

    return true;
}

void server_config_client_t::install_server_metadata(
        const peer_id_t &peer_id,
        const cluster_directory_metadata_t &metadata) {
    const server_id_t &server_id = metadata.server_id;
    server_to_peer_map.set_key(server_id, peer_id);
    peer_connections_map->read_all(
        [&](const std::pair<peer_id_t, server_id_t> &pair, const empty_value_t *) {
            if (pair.first == peer_id) {
                connections_map.set_key(
                    std::make_pair(server_id, pair.second), empty_value_t());
            }
        });
    server_config_map.set_key(server_id, metadata.server_config);
}

void server_config_client_t::on_directory_change(
        const peer_id_t &peer_id,
        const cluster_directory_metadata_t *metadata) {
    if (metadata != nullptr) {
        if (metadata->peer_type != SERVER_PEER) {
            return;
        }
        const server_id_t &server_id = metadata->server_id;
        if (!static_cast<bool>(peer_to_server_map.get_key(peer_id))) {
            all_server_to_peer_map.insert(std::make_pair(server_id, peer_id));
            peer_to_server_map.set_key(peer_id, server_id);
            install_server_metadata(peer_id, *metadata);
        } else {
            server_config_map.set_key(server_id, metadata->server_config);
        }

    } else {
        boost::optional<server_id_t> server_id = peer_to_server_map.get_key(peer_id);
        if (!static_cast<bool>(server_id)) {
            return;
        }
        for (auto it = all_server_to_peer_map.lower_bound(*server_id); ; ++it) {
            guarantee(it != all_server_to_peer_map.end());
            if (it->second == peer_id) {
                all_server_to_peer_map.erase(it);
                break;
            }
        }
        peer_to_server_map.delete_key(peer_id);
        server_to_peer_map.delete_key(*server_id);
        peer_connections_map->read_all(
            [&](const std::pair<peer_id_t, server_id_t> &pair, const empty_value_t *) {
                if (pair.first == peer_id) {
                    connections_map.delete_key(std::make_pair(*server_id, pair.second));
                }
            });
        server_config_map.delete_key(*server_id);

        /* If there is another connected peer with the same server ID, reinstall its
        values. */
        auto jt = all_server_to_peer_map.find(*server_id);
        if (jt != all_server_to_peer_map.end()) {
            directory_view->read_key(jt->second,
                [&](const cluster_directory_metadata_t *other_metadata) {
                    guarantee(other_metadata != nullptr);
                    guarantee(other_metadata->server_id == *server_id);
                    install_server_metadata(jt->second, *other_metadata);
                });
        }
    }
}

void server_config_client_t::on_peer_connections_map_change(
        const std::pair<peer_id_t, server_id_t> &key,
        const empty_value_t *value) {
    directory_view->read_key(key.first,
    [&](const cluster_directory_metadata_t *metadata) {
        if (metadata != nullptr) {
            if (value != nullptr) {
                connections_map.set_key(
                    std::make_pair(metadata->server_id, key.second), empty_value_t());
            } else {
                connections_map.delete_key(
                    std::make_pair(metadata->server_id, key.second));
            }
        }
    });
}

<commit_msg>Style.<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "clustering/administration/servers/config_client.hpp"

server_config_client_t::server_config_client_t(
        mailbox_manager_t *_mailbox_manager,
        watchable_map_t<peer_id_t, cluster_directory_metadata_t> *_directory_view,
        watchable_map_t<std::pair<peer_id_t, server_id_t>, empty_value_t>
            *_peer_connections_map) :
    mailbox_manager(_mailbox_manager),
    directory_view(_directory_view),
    peer_connections_map(_peer_connections_map),
    directory_subs(
        directory_view,
        std::bind(&server_config_client_t::on_directory_change, this, ph::_1, ph::_2),
        initial_call_t::YES),
    peer_connections_map_subs(
        peer_connections_map,
        std::bind(&server_config_client_t::on_peer_connections_map_change,
            this, ph::_1, ph::_2),
        initial_call_t::YES)
    { }

bool server_config_client_t::set_config(
        const server_id_t &server_id,
        const name_string_t &old_server_name,
        const server_config_t &new_config,
        signal_t *interruptor,
        admin_err_t *error_out) {
    bool name_collision = false, is_noop = false;
    server_config_map.read_all(
    [&](const server_id_t &sid, const server_config_versioned_t *conf) {
        if (sid != server_id && conf->config.name == new_config.name) {
            name_collision = true;
        } else if (sid == server_id && conf->config == new_config) {
            is_noop = true;
        }
    });
    if (name_collision) {
        *error_out = admin_err_t{
            strprintf("Cannot rename server `%s` to `%s` because server `%s` "
                      "already exists.",
                      old_server_name.c_str(), new_config.name.c_str(),
                      new_config.name.c_str()),
            query_state_t::FAILED};
        return false;
    }
    if (is_noop) {
        return true;
    }

    boost::optional<peer_id_t> peer = server_to_peer_map.get_key(server_id);
    if (!static_cast<bool>(peer)) {
        std::string s = strprintf(
            "Could not contact server `%s` while trying to change the server "
            "configuration.  The configuration was not changed.",
            old_server_name.c_str());
        *error_out = admin_err_t{s, query_state_t::FAILED};
        return false;
    }
    server_config_business_card_t bcard;
    directory_view->read_key(*peer, [&](const cluster_directory_metadata_t *md) {
        guarantee(md != nullptr);
        bcard = md->server_config_business_card.get();
    });

    server_config_version_t version;
    {
        promise_t<std::pair<server_config_version_t, std::string> > reply;
        mailbox_t<void(server_config_version_t, std::string)> ack_mailbox(
            mailbox_manager,
            [&](signal_t *, server_config_version_t v, const std::string &m) {
                reply.pulse(std::make_pair(v, m));
            });
        disconnect_watcher_t disconnect_watcher(mailbox_manager, *peer);
        send(mailbox_manager, bcard.set_config_addr,
            new_config, ack_mailbox.get_address());
        wait_any_t waiter(reply.get_ready_signal(), &disconnect_watcher);
        wait_interruptible(&waiter, interruptor);
        if (!reply.is_pulsed()) {

            std::string disconnect_msg = strprintf(
                "Lost contact with server `%s` while trying "
                "to change the server configuration. The configuration may or may not "
                "have been changed.", old_server_name.c_str());
            *error_out = admin_err_t{disconnect_msg, query_state_t::INDETERMINATE};
            return false;
        }
        if (!reply.assert_get_value().second.empty()) {
            guarantee(reply.assert_get_value().first == 0);
            *error_out = admin_err_t{
                strprintf("Error when trying to change the configuration of "
                          "server `%s`: %s The configuration was not changed.",
                          old_server_name.c_str(),
                          reply.assert_get_value().second.c_str()),
                query_state_t::FAILED};
            return false;
        }
        version = reply.assert_get_value().first;
    }

    /* Wait up to 10 seconds for the change to appear in the directory. */
    try {
        signal_timer_t timeout;
        timeout.start(10000);
        wait_any_t waiter(interruptor, &timeout);
        server_config_map.run_key_until_satisfied(
            server_id,
            [&](const server_config_versioned_t *conf) {
                return conf == nullptr || conf->version >= version;
            },
            &waiter);
    } catch (const interrupted_exc_t &) {
        if (interruptor->is_pulsed()) {
            throw;
        }
    }

    return true;
}

void server_config_client_t::install_server_metadata(
        const peer_id_t &peer_id,
        const cluster_directory_metadata_t &metadata) {
    const server_id_t &server_id = metadata.server_id;
    server_to_peer_map.set_key(server_id, peer_id);
    peer_connections_map->read_all(
        [&](const std::pair<peer_id_t, server_id_t> &pair, const empty_value_t *) {
            if (pair.first == peer_id) {
                connections_map.set_key(
                    std::make_pair(server_id, pair.second), empty_value_t());
            }
        });
    server_config_map.set_key(server_id, metadata.server_config);
}

void server_config_client_t::on_directory_change(
        const peer_id_t &peer_id,
        const cluster_directory_metadata_t *metadata) {
    if (metadata != nullptr) {
        if (metadata->peer_type != SERVER_PEER) {
            return;
        }
        const server_id_t &server_id = metadata->server_id;
        if (!static_cast<bool>(peer_to_server_map.get_key(peer_id))) {
            all_server_to_peer_map.insert(std::make_pair(server_id, peer_id));
            peer_to_server_map.set_key(peer_id, server_id);
            install_server_metadata(peer_id, *metadata);
        } else {
            server_config_map.set_key(server_id, metadata->server_config);
        }

    } else {
        boost::optional<server_id_t> server_id = peer_to_server_map.get_key(peer_id);
        if (!static_cast<bool>(server_id)) {
            return;
        }
        for (auto it = all_server_to_peer_map.lower_bound(*server_id); ; ++it) {
            guarantee(it != all_server_to_peer_map.end());
            if (it->second == peer_id) {
                all_server_to_peer_map.erase(it);
                break;
            }
        }
        peer_to_server_map.delete_key(peer_id);
        server_to_peer_map.delete_key(*server_id);
        peer_connections_map->read_all(
            [&](const std::pair<peer_id_t, server_id_t> &pair, const empty_value_t *) {
                if (pair.first == peer_id) {
                    connections_map.delete_key(std::make_pair(*server_id, pair.second));
                }
            });
        server_config_map.delete_key(*server_id);

        /* If there is another connected peer with the same server ID, reinstall its
        values. */
        auto jt = all_server_to_peer_map.find(*server_id);
        if (jt != all_server_to_peer_map.end()) {
            directory_view->read_key(jt->second,
                [&](const cluster_directory_metadata_t *other_metadata) {
                    guarantee(other_metadata != nullptr);
                    guarantee(other_metadata->server_id == *server_id);
                    install_server_metadata(jt->second, *other_metadata);
                });
        }
    }
}

void server_config_client_t::on_peer_connections_map_change(
        const std::pair<peer_id_t, server_id_t> &key,
        const empty_value_t *value) {
    directory_view->read_key(key.first,
    [&](const cluster_directory_metadata_t *metadata) {
        if (metadata != nullptr) {
            if (value != nullptr) {
                connections_map.set_key(
                    std::make_pair(metadata->server_id, key.second), empty_value_t());
            } else {
                connections_map.delete_key(
                    std::make_pair(metadata->server_id, key.second));
            }
        }
    });
}

<|endoftext|>


<commit_before>#include "Entity.h"

Entity::Entity()
{
}

Entity::~Entity()
{
}<commit_msg>Added missing getComponents function.<commit_after>#include "Entity.h"

Entity::Entity()
{
}

Entity::~Entity()
{
}

const std::map<size_t, Component*>& Entity::getComponents() const
{
    return components;
}<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <fcntl.h>
#include <vector>
#include <iostream>

#include "../src/sha1.h"

int run_tests() {
    int ret = 0;

	// these example text blocks are taken from RFC3174
    std::vector<std::pair<const char*, const char*> > tests;
    tests.push_back(std::pair<const char*, const char*>("abc","a9993e364706816aba3e25717850c26c9cd0d89d"));
    tests.push_back(std::pair<const char*, const char*>("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq","84983e441c3bd26ebaae4aa1f95129e5e54670f1"));
    tests.push_back(std::pair<const char*, const char*>("a","34aa973cd4c4daa4f61eeb2bdbad27316534016f"));
    tests.push_back(std::pair<const char*, const char*>("0123456701234567012345670123456701234567012345670123456701234567","dea356a2cddd90c7a7ecedc5ebb563934f460452"));

    tests.push_back(std::pair<const char*, const char*>("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0ea59bfe8787939816796610c73deb1c625e03ed"));

    std::vector<unsigned int> multiplier;
    multiplier.push_back(1);
    multiplier.push_back(1);
    multiplier.push_back(1000000);
    multiplier.push_back(10);
    multiplier.push_back(8388608);

    int passed = 0;
    int passed_h = 0;
    int passed_c = 0;

    unsigned char sig[SHA1_SIZE], sig2[SHA1_SIZE];
    char str[SHA1_STRING_SIZE];

    /* run our tests */
    for (unsigned int i = 0; i < tests.size(); i++) {
        bool passed_hash = 0;
        bool passed_convert = 0;

        sha1::sha1_t sha1;

        for (unsigned int j = 0; j < multiplier[i]; j++) {
            sha1.process(tests[i].first, strlen(tests[i].first));
        }

        sha1.finish(sig);

        /* convert from the sig to a string rep */
        sha1::sig_to_string(sig, str, sizeof(str));
        if (strcmp(str, tests[i].second) == 0) {
            passed_hash = true;
            passed_h++;
        }

        /* convert from the string back into a MD5 signature */
        sha1::sig_from_string(sig2, str);
        if (memcmp(sig, sig2, SHA1_SIZE) == 0) {
            passed_convert = true;
            passed_c++;
        }

        if (passed_hash and passed_convert) {
            std::cout << "TEST " << i + 1 << " PASSED" << std::endl;
            passed++;
        } else {
            std::cout << "TEST " << i + 1 << " FAILED" << std::endl;
            std::cout << "Hash: " << str << std::endl;
        }
    }

    std::cout << std::endl << "*******************************" << std::endl
              << "    " << passed << " of " << tests.size() << " tests passed" << std::endl;
    if (passed != tests.size()) {
        ret = 1;
        std::cout << std::endl << "   Please notify developer" << std::endl;
        std::cout << "  " << passed_h << " passed hashing check" << std::endl
                  << "  " << passed_h << " passed comparison check" << std::endl;
    }
    std::cout << "*******************************" << std::endl;

	return ret;
}

int read_input(int argc, char** argv) {
    sha1::sha1_t sha1;
    unsigned char* digest;
    const unsigned int buffer_size = 8192;

    assert( argv[1] );

    if (argv[1][0] == '-') {

    }

    /* open the file */
    int fd = open( argv[1], O_RDONLY | O_BINARY, 0 );
    /* handle open failure */
    if( fd == -1 ) {
        fprintf( stderr, "cannot open file %s\n", argv[1] );
        return 1;
        }

    /* prepare to calculate the SHA-1 hash */
    char* buffer = (char*)malloc( buffer_size );
    assert( buffer );

    /* loop through the file */
    int ret;
    while( true ) {
        /* read a chunk of data */
        ret = read( fd, buffer, buffer_size );
        /* check for error and end of file */
        if( ret < 1 ) break;
        /* run this data through the hash function */
        sha1.process(buffer, ret);
        }

    /* close the file */
    close( fd );

    /* there was an error reading the file */
    if( ret == -1 ) {
        fprintf( stderr, "error reading %s.\n", argv[1] );
        return 1;
        }

    /* get the digest */
    sha1.finish(digest);
    assert( digest );
    /* print it out */
    printf( "%s:", argv[1] );
    printf( "\n" );
    fflush( stdout );
    free( digest );
    return 0;
}

int main(int argc, char* argv[])
{
	if( argc == 2 ) {
        return read_input(argc, argv);
	} else {
        return run_tests();
	}
}

<commit_msg>fixes function call for less arguments<commit_after>#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <fcntl.h>
#include <vector>
#include <iostream>

#include "../src/sha1.h"

int run_tests() {
    int ret = 0;

	// these example text blocks are taken from RFC3174
    std::vector<std::pair<const char*, const char*> > tests;
    tests.push_back(std::pair<const char*, const char*>("abc","a9993e364706816aba3e25717850c26c9cd0d89d"));
    tests.push_back(std::pair<const char*, const char*>("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq","84983e441c3bd26ebaae4aa1f95129e5e54670f1"));
    tests.push_back(std::pair<const char*, const char*>("a","34aa973cd4c4daa4f61eeb2bdbad27316534016f"));
    tests.push_back(std::pair<const char*, const char*>("0123456701234567012345670123456701234567012345670123456701234567","dea356a2cddd90c7a7ecedc5ebb563934f460452"));

    tests.push_back(std::pair<const char*, const char*>("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0ea59bfe8787939816796610c73deb1c625e03ed"));

    std::vector<unsigned int> multiplier;
    multiplier.push_back(1);
    multiplier.push_back(1);
    multiplier.push_back(1000000);
    multiplier.push_back(10);
    multiplier.push_back(8388608);

    int passed = 0;
    int passed_h = 0;
    int passed_c = 0;

    unsigned char sig[SHA1_SIZE], sig2[SHA1_SIZE];
    char str[SHA1_STRING_SIZE];

    /* run our tests */
    for (unsigned int i = 0; i < tests.size(); i++) {
        bool passed_hash = 0;
        bool passed_convert = 0;

        sha1::sha1_t sha1;

        for (unsigned int j = 0; j < multiplier[i]; j++) {
            sha1.process(tests[i].first, strlen(tests[i].first));
        }

        sha1.finish(sig);

        /* convert from the sig to a string rep */
        sha1::sig_to_string(sig, str);
        if (strcmp(str, tests[i].second) == 0) {
            passed_hash = true;
            passed_h++;
        }

        /* convert from the string back into a MD5 signature */
        sha1::sig_from_string(sig2, str);
        if (memcmp(sig, sig2, SHA1_SIZE) == 0) {
            passed_convert = true;
            passed_c++;
        }

        if (passed_hash and passed_convert) {
            std::cout << "TEST " << i + 1 << " PASSED" << std::endl;
            passed++;
        } else {
            std::cout << "TEST " << i + 1 << " FAILED" << std::endl;
            std::cout << "Hash: " << str << std::endl;
        }
    }

    std::cout << std::endl << "*******************************" << std::endl
              << "    " << passed << " of " << tests.size() << " tests passed" << std::endl;
    if (passed != tests.size()) {
        ret = 1;
        std::cout << std::endl << "   Please notify developer" << std::endl;
        std::cout << "  " << passed_h << " passed hashing check" << std::endl
                  << "  " << passed_h << " passed comparison check" << std::endl;
    }
    std::cout << "*******************************" << std::endl;

	return ret;
}

int read_input(int argc, char** argv) {
    sha1::sha1_t sha1;
    unsigned char* digest;
    const unsigned int buffer_size = 8192;

    assert( argv[1] );

    if (argv[1][0] == '-') {

    }

    /* open the file */
    int fd = open( argv[1], O_RDONLY | O_BINARY, 0 );
    /* handle open failure */
    if( fd == -1 ) {
        fprintf( stderr, "cannot open file %s\n", argv[1] );
        return 1;
        }

    /* prepare to calculate the SHA-1 hash */
    char* buffer = (char*)malloc( buffer_size );
    assert( buffer );

    /* loop through the file */
    int ret;
    while( true ) {
        /* read a chunk of data */
        ret = read( fd, buffer, buffer_size );
        /* check for error and end of file */
        if( ret < 1 ) break;
        /* run this data through the hash function */
        sha1.process(buffer, ret);
        }

    /* close the file */
    close( fd );

    /* there was an error reading the file */
    if( ret == -1 ) {
        fprintf( stderr, "error reading %s.\n", argv[1] );
        return 1;
        }

    /* get the digest */
    sha1.finish(digest);
    assert( digest );
    /* print it out */
    printf( "%s:", argv[1] );
    printf( "\n" );
    fflush( stdout );
    free( digest );
    return 0;
}

int main(int argc, char* argv[])
{
	if( argc == 2 ) {
        return read_input(argc, argv);
	} else {
        return run_tests();
	}
}

<|endoftext|>


<commit_before>#include "Halide.h"

using namespace Halide;

#include <image_io.h>

#include <iostream>
#include <limits>

#include <sys/time.h>

using std::vector;

double now() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    static bool first_call = true;
    static time_t first_sec = 0;
    if (first_call) {
        first_call = false;
        first_sec = tv.tv_sec;
    }
    assert(tv.tv_sec >= first_sec);
    return (tv.tv_sec - first_sec) + (tv.tv_usec / 1000000.0);
}

int main(int argc, char **argv) {
    if (argc < 3) {
        std::cerr << "Usage:\n\t./interpolate in.png out.png\n" << std::endl;
        return 1;
    }

    ImageParam input(Float(32), 3);

    const unsigned int levels = 10;

    Func downsampled[levels];
    Func downx[levels];
    Func interpolated[levels];
    Func upsampled[levels];
    Func upsampledx[levels];
    Var x("x"), y("y"), c("c");

    Func clamped;
    clamped(x, y, c) = input(clamp(x, 0, input.width()-1), clamp(y, 0, input.height()-1), c);

    downsampled[0](x, y, c) = select(c < 3, clamped(x, y, c) * clamped(x, y, 3), clamped(x, y, 3));

    for (unsigned int l = 1; l < levels; ++l) {
        downx[l](x, y, c) = (downsampled[l-1](x*2-1, y, c) +
                             2.0f * downsampled[l-1](x*2, y, c) +
                             downsampled[l-1](x*2+1, y, c)) * 0.25f;
        downsampled[l](x, y, c) = (downx[l](x, y*2-1, c) +
                                   2.0f * downx[l](x, y*2, c) +
                                   downx[l](x, y*2+1, c)) * 0.25f;
    }
    interpolated[levels-1](x, y, c) = downsampled[levels-1](x, y, c);
    for (unsigned int l = levels-2; l < levels; --l) {
        upsampledx[l](x, y, c) = select((x % 2) == 0,
                                        interpolated[l+1](x/2, y, c),
                                        0.5f * (interpolated[l+1](x/2, y, c) +
                                                interpolated[l+1](x/2+1, y, c)));
        upsampled[l](x, y, c) = select((y % 2) == 0,
                                       upsampledx[l](x, y/2, c),
                                       0.5f * (upsampledx[l](x, y/2, c) +
                                               upsampledx[l](x, y/2+1, c)));
        interpolated[l](x, y, c) = downsampled[l](x, y, c) + (1.0f - downsampled[l](x, y, 3)) * upsampled[l](x, y, c);
    }

    Func normalize("normalize");
    normalize(x, y, c) = interpolated[0](x, y, c) / interpolated[0](x, y, 3);

    Func final("final");
    final(x, y, c) = normalize(x, y, c);

    std::cout << "Finished function setup." << std::endl;

    int sched;
    char *target = getenv("HL_TARGET");
    if (target && std::string(target) == "ptx") {
        sched = 4;
    } else {
        sched = 2;
    }

    switch (sched) {
    case 0:
    {
        std::cout << "Flat schedule." << std::endl;
        for (unsigned int l = 0; l < levels; ++l) {
            downsampled[l].compute_root();
            interpolated[l].compute_root();
        }
        final.compute_root();
        break;
    }
    case 1:
    {
        std::cout << "Flat schedule with vectorization." << std::endl;
        for (unsigned int l = 0; l < levels; ++l) {
            downsampled[l].compute_root().vectorize(x,4);
            interpolated[l].compute_root().vectorize(x,4);
        }
        final.compute_root();
        break;
    }
    case 2:
    {
        Var xi, yi;
        std::cout << "Flat schedule with parallelization + vectorization." << std::endl;
        clamped.compute_root().parallel(y).bound(c, 0, 4).reorder(c, x, y).reorder_storage(c, x, y).vectorize(c, 4);
        for (unsigned int l = 1; l < levels-1; ++l) {
            if (l > 0) downsampled[l].compute_root().parallel(y).reorder(c, x, y).reorder_storage(c, x, y).vectorize(c, 4);
            interpolated[l].compute_root().parallel(y).reorder(c, x, y).reorder_storage(c, x, y).vectorize(c, 4);
            interpolated[l].unroll(x, 2).unroll(y, 2);
        }
        final.reorder(c, x, y).bound(c, 0, 3).parallel(y);
        final.tile(x, y, xi, yi, 2, 2).unroll(xi).unroll(yi);
        final.bound(x, 0, input.width());
        final.bound(y, 0, input.height());
        break;
    }
    case 3:
    {
        std::cout << "Flat schedule with vectorization sometimes." << std::endl;
        for (unsigned int l = 0; l < levels; ++l) {
            if (l + 4 < levels) {
                Var yo,yi;
                downsampled[l].compute_root().vectorize(x,4);
                interpolated[l].compute_root().vectorize(x,4);
            } else {
                downsampled[l].compute_root();
                interpolated[l].compute_root();
            }
        }
        final.compute_root();
        break;
    }
    case 4:
    {
        std::cout << "GPU schedule." << std::endl;

        // Some gpus don't have enough memory to process the entire
        // image, so we process the image in tiles.
        Var yo, yi, xo, xi;
        final.reorder(c, x, y).bound(c, 0, 3).vectorize(x, 4);
        final.tile(x, y, xo, yo, xi, yi, input.width()/4, input.height()/4);
        normalize.compute_at(final, xo).reorder(c, x, y).cuda_tile(x, y, 16, 16).unroll(c);

        // Start from level 1 to save memory - level zero will be computed on demand
        for (unsigned int l = 1; l < levels; ++l) {
            int tile_size = 32 >> l;
            if (tile_size < 1) tile_size = 1;
            if (tile_size > 16) tile_size = 16;
            downsampled[l].compute_root().cuda_tile(x, y, c, tile_size, tile_size, 4);
            interpolated[l].compute_at(final, xo).cuda_tile(x, y, c, tile_size, tile_size, 4);
        }

        break;
    }
    default:
        assert(0 && "No schedule with this number.");
    }

    // JIT compile the pipeline eagerly, so we don't interfere with timing
    final.compile_jit();

    Image<float> in_png = load<float>(argv[1]);
    Image<float> out(in_png.width(), in_png.height(), 3);
    assert(in_png.channels() == 4);
    input.set(in_png);

    std::cout << "Running... " << std::endl;
    double min = std::numeric_limits<double>::infinity();
    const unsigned int iters = 20;

    for (unsigned int x = 0; x < iters; ++x) {
        double before = now();
        final.realize(out);
        double after = now();
        double amt = after - before;

        std::cout << "   " << amt * 1000 << std::endl;
        if (amt < min) min = amt;

    }
    std::cout << " took " << min * 1000 << " msec." << std::endl;

    vector<Argument> args;
    args.push_back(input);
    final.compile_to_assembly("test.s", args);

    save(out, argv[2]);

}
<commit_msg>Workaround for a bug in llvm 3.3<commit_after>#include "Halide.h"

using namespace Halide;

#include <image_io.h>

#include <iostream>
#include <limits>

#include <sys/time.h>

using std::vector;

double now() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    static bool first_call = true;
    static time_t first_sec = 0;
    if (first_call) {
        first_call = false;
        first_sec = tv.tv_sec;
    }
    assert(tv.tv_sec >= first_sec);
    return (tv.tv_sec - first_sec) + (tv.tv_usec / 1000000.0);
}

int main(int argc, char **argv) {
    if (argc < 3) {
        std::cerr << "Usage:\n\t./interpolate in.png out.png\n" << std::endl;
        return 1;
    }

    ImageParam input(Float(32), 3);

    const unsigned int levels = 10;

    Func downsampled[levels];
    Func downx[levels];
    Func interpolated[levels];
    Func upsampled[levels];
    Func upsampledx[levels];
    Var x("x"), y("y"), c("c");

    Func clamped;
    clamped(x, y, c) = input(clamp(x, 0, input.width()-1), clamp(y, 0, input.height()-1), c);

    // This triggers a bug in llvm 3.3 (3.2 and trunk are fine), so we
    // rewrite it in a way that doesn't trigger the bug. The rewritten
    // form assumes the input alpha is zero or one.
    // downsampled[0](x, y, c) = select(c < 3, clamped(x, y, c) * clamped(x, y, 3), clamped(x, y, 3));
    downsampled[0](x, y, c) = clamped(x, y, c) * clamped(x, y, 3);

    for (unsigned int l = 1; l < levels; ++l) {
        downx[l](x, y, c) = (downsampled[l-1](x*2-1, y, c) +
                             2.0f * downsampled[l-1](x*2, y, c) +
                             downsampled[l-1](x*2+1, y, c)) * 0.25f;
        downsampled[l](x, y, c) = (downx[l](x, y*2-1, c) +
                                   2.0f * downx[l](x, y*2, c) +
                                   downx[l](x, y*2+1, c)) * 0.25f;
    }
    interpolated[levels-1](x, y, c) = downsampled[levels-1](x, y, c);
    for (unsigned int l = levels-2; l < levels; --l) {
        upsampledx[l](x, y, c) = select((x % 2) == 0,
                                        interpolated[l+1](x/2, y, c),
                                        0.5f * (interpolated[l+1](x/2, y, c) +
                                                interpolated[l+1](x/2+1, y, c)));
        upsampled[l](x, y, c) = select((y % 2) == 0,
                                       upsampledx[l](x, y/2, c),
                                       0.5f * (upsampledx[l](x, y/2, c) +
                                               upsampledx[l](x, y/2+1, c)));
        interpolated[l](x, y, c) = downsampled[l](x, y, c) + (1.0f - downsampled[l](x, y, 3)) * upsampled[l](x, y, c);
    }

    Func normalize("normalize");
    normalize(x, y, c) = interpolated[0](x, y, c) / interpolated[0](x, y, 3);

    Func final("final");
    final(x, y, c) = normalize(x, y, c);

    std::cout << "Finished function setup." << std::endl;

    int sched;
    char *target = getenv("HL_TARGET");
    if (target && std::string(target) == "ptx") {
        sched = 4;
    } else {
        sched = 2;
    }

    switch (sched) {
    case 0:
    {
        std::cout << "Flat schedule." << std::endl;
        for (unsigned int l = 0; l < levels; ++l) {
            downsampled[l].compute_root();
            interpolated[l].compute_root();
        }
        final.compute_root();
        break;
    }
    case 1:
    {
        std::cout << "Flat schedule with vectorization." << std::endl;
        for (unsigned int l = 0; l < levels; ++l) {
            downsampled[l].compute_root().vectorize(x,4);
            interpolated[l].compute_root().vectorize(x,4);
        }
        final.compute_root();
        break;
    }
    case 2:
    {
        Var xi, yi;
        std::cout << "Flat schedule with parallelization + vectorization." << std::endl;
        clamped.compute_root().parallel(y).bound(c, 0, 4).reorder(c, x, y).reorder_storage(c, x, y).vectorize(c, 4);
        for (unsigned int l = 1; l < levels-1; ++l) {
            if (l > 0) downsampled[l].compute_root().parallel(y).reorder(c, x, y).reorder_storage(c, x, y).vectorize(c, 4);
            interpolated[l].compute_root().parallel(y).reorder(c, x, y).reorder_storage(c, x, y).vectorize(c, 4);
            interpolated[l].unroll(x, 2).unroll(y, 2);
        }
        final.reorder(c, x, y).bound(c, 0, 3).parallel(y);
        final.tile(x, y, xi, yi, 2, 2).unroll(xi).unroll(yi);
        final.bound(x, 0, input.width());
        final.bound(y, 0, input.height());
        break;
    }
    case 3:
    {
        std::cout << "Flat schedule with vectorization sometimes." << std::endl;
        for (unsigned int l = 0; l < levels; ++l) {
            if (l + 4 < levels) {
                Var yo,yi;
                downsampled[l].compute_root().vectorize(x,4);
                interpolated[l].compute_root().vectorize(x,4);
            } else {
                downsampled[l].compute_root();
                interpolated[l].compute_root();
            }
        }
        final.compute_root();
        break;
    }
    case 4:
    {
        std::cout << "GPU schedule." << std::endl;

        // Some gpus don't have enough memory to process the entire
        // image, so we process the image in tiles.
        Var yo, yi, xo, xi;
        final.reorder(c, x, y).bound(c, 0, 3).vectorize(x, 4);
        final.tile(x, y, xo, yo, xi, yi, input.width()/4, input.height()/4);
        normalize.compute_at(final, xo).reorder(c, x, y).cuda_tile(x, y, 16, 16).unroll(c);

        // Start from level 1 to save memory - level zero will be computed on demand
        for (unsigned int l = 1; l < levels; ++l) {
            int tile_size = 32 >> l;
            if (tile_size < 1) tile_size = 1;
            if (tile_size > 16) tile_size = 16;
            downsampled[l].compute_root().cuda_tile(x, y, c, tile_size, tile_size, 4);
            interpolated[l].compute_at(final, xo).cuda_tile(x, y, c, tile_size, tile_size, 4);
        }

        break;
    }
    default:
        assert(0 && "No schedule with this number.");
    }

    // JIT compile the pipeline eagerly, so we don't interfere with timing
    final.compile_jit();

    Image<float> in_png = load<float>(argv[1]);
    Image<float> out(in_png.width(), in_png.height(), 3);
    assert(in_png.channels() == 4);
    input.set(in_png);

    std::cout << "Running... " << std::endl;
    double min = std::numeric_limits<double>::infinity();
    const unsigned int iters = 20;

    for (unsigned int x = 0; x < iters; ++x) {
        double before = now();
        final.realize(out);
        double after = now();
        double amt = after - before;

        std::cout << "   " << amt * 1000 << std::endl;
        if (amt < min) min = amt;

    }
    std::cout << " took " << min * 1000 << " msec." << std::endl;

    vector<Argument> args;
    args.push_back(input);
    final.compile_to_assembly("test.s", args);

    save(out, argv[2]);

}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "objectdescription.h"
#include "objectdescription_p.h"

#include <QtCore/QObject>
#include <QtCore/QSet>
#include "factory.h"
#include <QtCore/QStringList>
#include "backendinterface.h"

namespace Phonon
{

ObjectDescriptionData::ObjectDescriptionData(ObjectDescriptionPrivate *dd)
    : d(dd)
{
}

ObjectDescriptionData::~ObjectDescriptionData()
{
    delete d;
}

bool ObjectDescriptionData::operator==(const ObjectDescriptionData &otherDescription) const
{
    if (!isValid()) {
        return !otherDescription.isValid();
    }
    if (!otherDescription.isValid()) {
        return false;
    }
    return *d == *otherDescription.d;
}

int ObjectDescriptionData::index() const
{
    if (!isValid()) {
        return -1;
    }
    return d->index;
}

QString ObjectDescriptionData::name() const
{
    if (!isValid()) {
        return QString();
    }
    return d->name;
}

QString ObjectDescriptionData::description() const
{
    if (!isValid()) {
        return QString();
    }
    return d->description;
}

QVariant ObjectDescriptionData::property(const char *name) const
{
    if (!isValid()) {
        return QVariant();
    }
    return d->properties.value(name);
}

QList<QByteArray> ObjectDescriptionData::propertyNames() const
{
    if (!isValid()) {
        return QList<QByteArray>();
    }
    return d->properties.keys();
}

bool ObjectDescriptionData::isValid() const
{
    return d != 0;
}

ObjectDescriptionData *ObjectDescriptionData::fromIndex(ObjectDescriptionType type, int index)
{
    QObject *b = Factory::backend();
    BackendInterface *iface = qobject_cast<BackendInterface *>(b);
    QSet<int> indexes = iface->objectDescriptionIndexes(type);
    if (indexes.contains(index)) {
        QHash<QByteArray, QVariant> properties = iface->objectDescriptionProperties(type, index);
        return new ObjectDescriptionData(new ObjectDescriptionPrivate(index, properties));
    }
    return new ObjectDescriptionData(0); // invalid
}

} //namespace Phonon
// vim: sw=4 ts=4
<commit_msg>don't crash in fromIndex if no backend is available - thanks to PutHuhn<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "objectdescription.h"
#include "objectdescription_p.h"

#include <QtCore/QObject>
#include <QtCore/QSet>
#include "factory.h"
#include <QtCore/QStringList>
#include "backendinterface.h"

namespace Phonon
{

ObjectDescriptionData::ObjectDescriptionData(ObjectDescriptionPrivate *dd)
    : d(dd)
{
}

ObjectDescriptionData::~ObjectDescriptionData()
{
    delete d;
}

bool ObjectDescriptionData::operator==(const ObjectDescriptionData &otherDescription) const
{
    if (!isValid()) {
        return !otherDescription.isValid();
    }
    if (!otherDescription.isValid()) {
        return false;
    }
    return *d == *otherDescription.d;
}

int ObjectDescriptionData::index() const
{
    if (!isValid()) {
        return -1;
    }
    return d->index;
}

QString ObjectDescriptionData::name() const
{
    if (!isValid()) {
        return QString();
    }
    return d->name;
}

QString ObjectDescriptionData::description() const
{
    if (!isValid()) {
        return QString();
    }
    return d->description;
}

QVariant ObjectDescriptionData::property(const char *name) const
{
    if (!isValid()) {
        return QVariant();
    }
    return d->properties.value(name);
}

QList<QByteArray> ObjectDescriptionData::propertyNames() const
{
    if (!isValid()) {
        return QList<QByteArray>();
    }
    return d->properties.keys();
}

bool ObjectDescriptionData::isValid() const
{
    return d != 0;
}

ObjectDescriptionData *ObjectDescriptionData::fromIndex(ObjectDescriptionType type, int index)
{
    QObject *b = Factory::backend();
    BackendInterface *iface = qobject_cast<BackendInterface *>(b);
    if (iface) {
        QSet<int> indexes = iface->objectDescriptionIndexes(type);
        if (indexes.contains(index)) {
            QHash<QByteArray, QVariant> properties = iface->objectDescriptionProperties(type, index);
            return new ObjectDescriptionData(new ObjectDescriptionPrivate(index, properties));
        }
    }
    return new ObjectDescriptionData(0); // invalid
}

} //namespace Phonon
// vim: sw=4 ts=4
<|endoftext|>


<commit_before>/*
 * PartialCsvParser.hpp
 *
 *  Created on: 2014/12/28
 *      Author: nakatani.sho
 */

#ifndef INCLUDE_PARTIALCSVPARSER_HPP_
#define INCLUDE_PARTIALCSVPARSER_HPP_

#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

// Prevent default class methods
#define PREVENT_DEFAULT_CONSTRUCTOR(klass) \
  private: klass();
#define PREVENT_COPY_CONSTRUCTOR(klass) \
  private: klass(const klass&);
#define PREVENT_OBJECT_ASSIGNMENT(klass) \
  private: klass& operator=(const klass&);
#define PREVENT_CLASS_DEFAULT_METHODS(klass) \
  PREVENT_DEFAULT_CONSTRUCTOR(klass); \
  PREVENT_COPY_CONSTRUCTOR(klass); \
  PREVENT_OBJECT_ASSIGNMENT(klass); \

// Assertion also usable with Google Test
#ifdef PCP_GTEST
#include <stdexcept>
#include <string>

class PCPAssertionFailed : public std::runtime_error {
public:
  PCPAssertionFailed(const std::string &cause)
  : std::runtime_error(cause)
  {}
};

#define ASSERT(cond) \
  if (!(cond)) \
    throw PCPAssertionFailed( \
      std::string(__FILE__) + ":" + std::to_string(__LINE__) + " PCPAssertionFailed: " + #cond);

#else /* PCP_GTEST */
#include <cassert>

#define ASSERT(cond) \
  std::assert(cond);

#endif /* PCP_GTEST */

// Macros for error cases
#define PERROR_ABORT(msg) \
  { \
    std::perror((std::string("Fatal from PartialCsvParser ") + std::string(msg)).c_str()); \
    std::abort(); \
  }

namespace PCP {

// Utility functions
inline size_t _filesize(int opened_fd) {
  struct stat st;
  if (fstat(opened_fd, &st) != 0) PERROR_ABORT("while getting stat(2) of file");
  return st.st_size;
}

/**
 * Find a line including specified current_pos.
 * @param text Original text to find a line from.
 * @param text_length_byte Byte length of the original text.
 * @param current_pos Current position taking 0 ~ (text_length - 1).
 * @param line Pointer of start of the current line will be output.
 * @param line_length_byte Byte length of current line (not including line terminator) will be output.
 *
   @verbatim
   \n aaaaaaaaaaa \n bbbbbbbbbbbbb \n cccccccccc \n
                     ^           ^  ^
                    (1)         (2)(3)
   @endverbatim
 *
 * If current_pos is at between (1) and (2), line will point at (1).
 * If current_pos is at (3), line will also point at (1).
 *
   @verbatim
   \n ddddddddd \n eeeeeeeeeee \0
                   ^            ^
                  (1)          (2)
   @endverbatim
 *
 * Consider null character.
 * If current_pos is at between (1) and (2), line will point at (1).
 */
void _get_current_line(
  const char * const text,
  size_t text_length_byte,
  size_t current_pos,
  /* out */
  const char ** line,
  size_t * line_length_byte,
  /* optional */
  char line_terminator = '\n')
{
  ASSERT(text);
  ASSERT(text_length_byte >= 1);
  ASSERT(0 <= current_pos && current_pos <= text_length_byte - 1);

  // \n aaaaaaaaaaaa \n
  //    ^            ^
  //    start        end
  const char *line_start = text + current_pos, *line_end = text + current_pos;

  // search line_start
  while (line_start > text && *(line_start - 1) != line_terminator) --line_start;
  // search line_end
  while (line_end < text + text_length_byte && *line_end != line_terminator) ++line_end;

  *line = line_start;
  *line_length_byte = line_end - line_start;
}

class PartialCsvParser;

class CsvConfig {
public:
  CsvConfig(
    const char * const filepath,
    bool has_header_line = true,
    char field_terminator = ',',
    char line_terminator = '\n',
    char enclosure_char = '"')
  : filepath(filepath), has_header_line(has_header_line),
    field_terminator(field_terminator), line_terminator(line_terminator),
    enclosure_char(enclosure_char)
  {
    if ((fd = open(filepath, O_RDONLY | O_SHLOCK)) == -1)
      PERROR_ABORT((std::string("while opening ") + filepath).c_str());  // TODO 例外を投げる
    csv_size = _filesize(fd);
    csv_text = static_cast<const char *>(mmap(NULL, csv_size, PROT_READ, MAP_PRIVATE, fd, 0));

    std::printf("size=%d\n\n%s\n", csv_size, csv_text);
    // reads header
  }

  ~CsvConfig() {
    if (munmap((void*)csv_text, csv_size) != 0) PERROR_ABORT("while munmap");
    if (close(fd) != 0) PERROR_ABORT("while closing file descriptor");
  }

  size_t filesize() const { return csv_size; }

  size_t body_offset() const;

  std::vector<std::string> headers() const {
    std::vector<std::string> header;  // NRVO optimization may prevent copy when returning this local variable.
    return header;
  }

  PartialCsvParser & generate_partial_parser(size_t read_from, size_t read_to) {
  }

private:
  const char * const filepath;
  const bool has_header_line;
  const char field_terminator;
  const char line_terminator;
  const char enclosure_char;

  int fd;
  size_t csv_size;
  const char * csv_text;

  PREVENT_CLASS_DEFAULT_METHODS(CsvConfig);
};

class PartialCsvParser {
public:
  PartialCsvParser(size_t read_from, size_t read_to) {}

  ~PartialCsvParser() {}

  std::vector<std::string> get_row() {
    std::vector<std::string> row;  // NRVO optimization may prevent copy when returning this local variable.
    return row;
  }

  bool has_more_rows() const {}

  PREVENT_CLASS_DEFAULT_METHODS(PartialCsvParser);
};

}

#endif /* INCLUDE_PARTIALCSVPARSER_HPP_ */
<commit_msg>stop using C++11 std::to_string<commit_after>/*
 * PartialCsvParser.hpp
 *
 *  Created on: 2014/12/28
 *      Author: nakatani.sho
 */

#ifndef INCLUDE_PARTIALCSVPARSER_HPP_
#define INCLUDE_PARTIALCSVPARSER_HPP_

#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

// Prevent default class methods
#define PREVENT_DEFAULT_CONSTRUCTOR(klass) \
  private: klass();
#define PREVENT_COPY_CONSTRUCTOR(klass) \
  private: klass(const klass&);
#define PREVENT_OBJECT_ASSIGNMENT(klass) \
  private: klass& operator=(const klass&);
#define PREVENT_CLASS_DEFAULT_METHODS(klass) \
  PREVENT_DEFAULT_CONSTRUCTOR(klass); \
  PREVENT_COPY_CONSTRUCTOR(klass); \
  PREVENT_OBJECT_ASSIGNMENT(klass); \

// Assertion also usable with Google Test
#ifdef PCP_GTEST
#include <stdexcept>
#include <sstream>
#include <string>

class PCPAssertionFailed : public std::runtime_error {
public:
  PCPAssertionFailed(const std::string &cause)
  : std::runtime_error(cause)
  {}
};

#define ASSERT(cond) \
  if (!(cond)) { \
    std::ostringstream ss; \
    ss << __FILE__ << ":" << __LINE__ << " (in " << __FUNCTION__ << "())" << " PCPAssertionFailed: " << #cond; \
    throw PCPAssertionFailed(ss.str()); \
  }

#else /* PCP_GTEST */
#include <cassert>

#define ASSERT(cond) \
  std::assert(cond);

#endif /* PCP_GTEST */

// Macros for error cases
#define PERROR_ABORT(msg) \
  { \
    std::perror((std::string("Fatal from PartialCsvParser ") + std::string(msg)).c_str()); \
    std::abort(); \
  }

namespace PCP {

// Utility functions
inline size_t _filesize(int opened_fd) {
  struct stat st;
  if (fstat(opened_fd, &st) != 0) PERROR_ABORT("while getting stat(2) of file");
  return st.st_size;
}

/**
 * Find a line including specified current_pos.
 * @param text Original text to find a line from.
 * @param text_length_byte Byte length of the original text.
 * @param current_pos Current position taking 0 ~ (text_length - 1).
 * @param line Pointer of start of the current line will be output.
 * @param line_length_byte Byte length of current line (not including line terminator) will be output.
 *
   @verbatim
   \n aaaaaaaaaaa \n bbbbbbbbbbbbb \n cccccccccc \n
                     ^           ^  ^
                    (1)         (2)(3)
   @endverbatim
 *
 * If current_pos is at between (1) and (2), line will point at (1).
 * If current_pos is at (3), line will also point at (1).
 *
   @verbatim
   \n ddddddddd \n eeeeeeeeeee \0
                   ^            ^
                  (1)          (2)
   @endverbatim
 *
 * Consider null character.
 * If current_pos is at between (1) and (2), line will point at (1).
 */
void _get_current_line(
  const char * const text,
  size_t text_length_byte,
  size_t current_pos,
  /* out */
  const char ** line,
  size_t * line_length_byte,
  /* optional */
  char line_terminator = '\n')
{
  ASSERT(text);
  ASSERT(text_length_byte >= 1);
  ASSERT(0 <= current_pos && current_pos <= text_length_byte - 1);

  // \n aaaaaaaaaaaa \n
  //    ^            ^
  //    start        end
  const char *line_start = text + current_pos, *line_end = text + current_pos;

  // search line_start
  while (line_start > text && *(line_start - 1) != line_terminator) --line_start;
  // search line_end
  while (line_end < text + text_length_byte && *line_end != line_terminator) ++line_end;

  *line = line_start;
  *line_length_byte = line_end - line_start;
}

class PartialCsvParser;

class CsvConfig {
public:
  CsvConfig(
    const char * const filepath,
    bool has_header_line = true,
    char field_terminator = ',',
    char line_terminator = '\n',
    char enclosure_char = '"')
  : filepath(filepath), has_header_line(has_header_line),
    field_terminator(field_terminator), line_terminator(line_terminator),
    enclosure_char(enclosure_char)
  {
    if ((fd = open(filepath, O_RDONLY | O_SHLOCK)) == -1)
      PERROR_ABORT((std::string("while opening ") + filepath).c_str());  // TODO 例外を投げる
    csv_size = _filesize(fd);
    csv_text = static_cast<const char *>(mmap(NULL, csv_size, PROT_READ, MAP_PRIVATE, fd, 0));

    std::printf("size=%d\n\n%s\n", csv_size, csv_text);
    // reads header
  }

  ~CsvConfig() {
    if (munmap((void*)csv_text, csv_size) != 0) PERROR_ABORT("while munmap");
    if (close(fd) != 0) PERROR_ABORT("while closing file descriptor");
  }

  size_t filesize() const { return csv_size; }

  size_t body_offset() const;

  std::vector<std::string> headers() const {
    std::vector<std::string> header;  // NRVO optimization may prevent copy when returning this local variable.
    return header;
  }

  PartialCsvParser & generate_partial_parser(size_t read_from, size_t read_to) {
  }

private:
  const char * const filepath;
  const bool has_header_line;
  const char field_terminator;
  const char line_terminator;
  const char enclosure_char;

  int fd;
  size_t csv_size;
  const char * csv_text;

  PREVENT_CLASS_DEFAULT_METHODS(CsvConfig);
};

class PartialCsvParser {
public:
  PartialCsvParser(size_t read_from, size_t read_to) {}

  ~PartialCsvParser() {}

  std::vector<std::string> get_row() {
    std::vector<std::string> row;  // NRVO optimization may prevent copy when returning this local variable.
    return row;
  }

  bool has_more_rows() const {}

  PREVENT_CLASS_DEFAULT_METHODS(PartialCsvParser);
};

}

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


<commit_before>#include "ctextviewerplugin.h"
#include "ctextviewerwindow.h"
#include "compiler/compiler_warnings_control.h"

#include <QMimeType>

CFileCommanderPlugin * createPlugin()
{
	DISABLE_COMPILER_WARNINGS
	Q_INIT_RESOURCE(icons);
	RESTORE_COMPILER_WARNINGS

	return new CTextViewerPlugin;
}

bool CTextViewerPlugin::canViewFile(const QString& /*fileName*/, const QMimeType& /*type*/) const
{
	return true;
}

CPluginWindow * CTextViewerPlugin::viewFile(const QString& fileName)
{
	QWidget * mainWindow = nullptr;
	for (QWidget* topLevelWidget: QApplication::topLevelWidgets())
	{
		if (topLevelWidget->inherits("QMainWindow"))
		{
			mainWindow = topLevelWidget;
			break;
		}
	}

	CTextViewerWindow * widget = new CTextViewerWindow(mainWindow); // Temporary workaround for https://bugreports.qt.io/browse/QTBUG-61213
	if (widget->loadTextFile(fileName))
		return widget;

	delete widget;
	return nullptr;
}

QString CTextViewerPlugin::name() const
{
	return "Plain text and HTML viewer plugin";
}
<commit_msg>Fixed #173 - no longer attempting to invoke a text viewer when F3 is pressed on a folder<commit_after>#include "ctextviewerplugin.h"
#include "ctextviewerwindow.h"
#include "compiler/compiler_warnings_control.h"

#include <QMimeType>

CFileCommanderPlugin * createPlugin()
{
	DISABLE_COMPILER_WARNINGS
	Q_INIT_RESOURCE(icons);
	RESTORE_COMPILER_WARNINGS

	return new CTextViewerPlugin;
}

bool CTextViewerPlugin::canViewFile(const QString& fileName, const QMimeType& /*type*/) const
{
	return QFileInfo(fileName).isFile();
}

CPluginWindow * CTextViewerPlugin::viewFile(const QString& fileName)
{
	QWidget * mainWindow = nullptr;
	for (QWidget* topLevelWidget: QApplication::topLevelWidgets())
	{
		if (topLevelWidget->inherits("QMainWindow"))
		{
			mainWindow = topLevelWidget;
			break;
		}
	}

	CTextViewerWindow * widget = new CTextViewerWindow(mainWindow); // Temporary workaround for https://bugreports.qt.io/browse/QTBUG-61213
	if (widget->loadTextFile(fileName))
		return widget;

	delete widget;
	return nullptr;
}

QString CTextViewerPlugin::name() const
{
	return "Plain text and HTML viewer plugin";
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2003-2014, Arvid Norberg, Daniel Wallin
All rights reserved.

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

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

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

*/

#ifndef TORRENT_ALERT_HPP_INCLUDED
#define TORRENT_ALERT_HPP_INCLUDED

#include <memory>
#include <deque>
#include <string>
#include <vector>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>

// OVERVIEW
//
// The pop_alerts() function on session is the main interface for retrieving
// alerts (warnings, messages and errors from libtorrent). If no alerts have
// been posted by libtorrent pop_alert() will return an empty list.
//
// By default, only errors are reported. set_alert_mask() can be used to
// specify which kinds of events should be reported. The alert mask is
// comprised by bits from the category_t enum.
//
// Every alert belongs to one or more category. There is a small cost involved
// in posting alerts. Only alerts that belong to an enabled category are
// posted. Setting the alert bitmask to 0 will disable all alerts (except those
// that are non-discardable).
//
// There are other alert base classes that some alerts derive from, all the
// alerts that are generated for a specific torrent are derived from
// torrent_alert, and tracker events derive from tracker_alert.
//

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_TYPEID
#include <typeinfo>
#endif
#endif // TORRENT_NO_DEPRECATE

#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_TYPEID
#include <typeinfo>
#endif
#endif

namespace libtorrent {

	// The ``alert`` class is the base class that specific messages are derived from.
	class TORRENT_EXPORT alert
	{
	public:

#ifndef TORRENT_NO_DEPRECATE
		// only here for backwards compatibility
		enum severity_t { debug, info, warning, critical, fatal, none };
#endif

		// these are bits for the alert_mask used by the session. See set_alert_mask().
		enum category_t
		{
			// Enables alerts that report an error. This includes:
			//
			// * tracker errors
			// * tracker warnings
			// * file errors
			// * resume data failures
			// * web seed errors
			// * .torrent files errors
			// * listen socket errors
			// * port mapping errors
			error_notification = 0x1,

			// Enables alerts when peers send invalid requests, get banned or
			// snubbed.
			peer_notification = 0x2,

			// Enables alerts for port mapping events. For NAT-PMP and UPnP.
			port_mapping_notification = 0x4,

			// Enables alerts for events related to the storage. File errors and
			// synchronization events for moving the storage, renaming files etc.
			storage_notification = 0x8,

			// Enables all tracker events. Includes announcing to trackers,
			// receiving responses, warnings and errors.
			tracker_notification = 0x10,

			// Low level alerts for when peers are connected and disconnected.
			debug_notification = 0x20,

			// Enables alerts for when a torrent or the session changes state.
			status_notification = 0x40,

			// Alerts for when blocks are requested and completed. Also when
			// pieces are completed.
			progress_notification = 0x80,

			// Alerts when a peer is blocked by the ip blocker or port blocker.
			ip_block_notification = 0x100,

			// Alerts when some limit is reached that might limit the download
			// or upload rate.
			performance_warning = 0x200,

			// Alerts on events in the DHT node. For incoming searches or
			// bootstrapping being done etc.
			dht_notification = 0x400,

			// If you enable these alerts, you will receive a stats_alert
			// approximately once every second, for every active torrent.
			// These alerts contain all statistics counters for the interval since
			// the lasts stats alert.
			stats_notification = 0x800,

			// Alerts on RSS related events, like feeds being updated, feed error
			// conditions and successful RSS feed updates. Enabling this categoty
			// will make you receive rss_alert alerts.
			rss_notification = 0x1000,

			// The full bitmask, representing all available categories.
			//
			// since the enum is signed, make sure this isn't
			// interpreted as -1. For instance, boost.python
			// does that and fails when assigning it to an
			// unsigned parameter.
			all_categories = 0x7fffffff
		};

		// hidden
		alert();
		// hidden
		virtual ~alert();

		// a timestamp is automatically created in the constructor
		ptime timestamp() const;

		// returns an integer that is unique to this alert type. It can be
		// compared against a specific alert by querying a static constant called ``alert_type``
		// in the alert. It can be used to determine the run-time type of an alert* in
		// order to cast to that alert type and access specific members.
		//
		// e.g::
		//
		//	std::auto_ptr<alert> a = ses.pop_alert();
		//	switch (a->type())
		//	{
		//		case read_piece_alert::alert_type:
		//		{
		//			read_piece_alert* p = (read_piece_alert*)a.get();
		//			if (p->ec) {
		//				// read_piece failed
		//				break;
		//			}
		//			// use p
		//			break;
		//		}
		//		case file_renamed_alert::alert_type:
		//		{
		//			// etc...
		//		}
		//	}
		virtual int type() const = 0;

		// returns a string literal describing the type of the alert. It does
		// not include any information that might be bundled with the alert.
		virtual char const* what() const = 0;

		// generate a string describing the alert and the information bundled
		// with it. This is mainly intended for debug and development use. It is not suitable
		// to use this for applications that may be localized. Instead, handle each alert
		// type individually and extract and render the information from the alert depending
		// on the locale.
		virtual std::string message() const = 0;

		// returns a bitmask specifying which categories this alert belong to.
		virtual int category() const = 0;

		// determines whether or not an alert is allowed to be discarded
		// when the alert queue is full. There are a few alerts which may not be discared,
		// since they would break the user contract, such as save_resume_data_alert.
		virtual bool discardable() const { return true; }

#ifndef TORRENT_NO_DEPRECATE
		TORRENT_DEPRECATED_PREFIX
		severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif

		// returns a pointer to a copy of the alert.
		virtual std::auto_ptr<alert> clone() const = 0;

	private:
		ptime m_timestamp;
	};

#ifndef TORRENT_NO_DEPRECATE
	struct TORRENT_EXPORT unhandled_alert : std::exception
	{
		unhandled_alert() {}
	};

#ifndef BOOST_NO_TYPEID

	namespace detail {

		struct void_;

		template<class Handler
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_, const Handler& handler
			, const std::type_info& typeid_
			, T0*, BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
		{
			if (typeid_ == typeid(T0))
				handler(*static_cast<T0*>(alert_.get()));
			else
				handle_alert_dispatch(alert_, handler, typeid_
					, BOOST_PP_ENUM_SHIFTED_PARAMS(
					TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
		}

		template<class Handler>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>&
			, const Handler&
			, const std::type_info&
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
		{
			throw unhandled_alert();
		}

	} // namespace detail

	template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
		TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
	struct TORRENT_EXPORT handle_alert
	{
		template<class Handler>
		handle_alert(const std::auto_ptr<alert>& alert_
			, const Handler& handler)
		{
			#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0

			detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
				, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));

			#undef ALERT_POINTER_TYPE
		}
	};

#endif // BOOST_NO_TYPEID
#endif // TORRENT_NO_DEPRECATE

// When you get an alert, you can use ``alert_cast<>`` to attempt to cast the pointer to a
// more specific alert type, in order to query it for more information.
template <class T>
T* alert_cast(alert* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T*>(a);
	return 0;
}
template <class T>
T const* alert_cast(alert const* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T const*>(a);
	return 0;
}

} // namespace libtorrent

#endif // TORRENT_ALERT_HPP_INCLUDED

<commit_msg>attempted no-exceptions build fix<commit_after>/*

Copyright (c) 2003-2014, Arvid Norberg, Daniel Wallin
All rights reserved.

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

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

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

*/

#ifndef TORRENT_ALERT_HPP_INCLUDED
#define TORRENT_ALERT_HPP_INCLUDED

#include <memory>
#include <deque>
#include <string>
#include <vector>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>

// OVERVIEW
//
// The pop_alerts() function on session is the main interface for retrieving
// alerts (warnings, messages and errors from libtorrent). If no alerts have
// been posted by libtorrent pop_alert() will return an empty list.
//
// By default, only errors are reported. set_alert_mask() can be used to
// specify which kinds of events should be reported. The alert mask is
// comprised by bits from the category_t enum.
//
// Every alert belongs to one or more category. There is a small cost involved
// in posting alerts. Only alerts that belong to an enabled category are
// posted. Setting the alert bitmask to 0 will disable all alerts (except those
// that are non-discardable).
//
// There are other alert base classes that some alerts derive from, all the
// alerts that are generated for a specific torrent are derived from
// torrent_alert, and tracker events derive from tracker_alert.
//

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_TYPEID
#include <typeinfo>
#endif
#endif // TORRENT_NO_DEPRECATE

#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_TYPEID
#include <typeinfo>
#endif
#endif

namespace libtorrent {

	// The ``alert`` class is the base class that specific messages are derived from.
	class TORRENT_EXPORT alert
	{
	public:

#ifndef TORRENT_NO_DEPRECATE
		// only here for backwards compatibility
		enum severity_t { debug, info, warning, critical, fatal, none };
#endif

		// these are bits for the alert_mask used by the session. See set_alert_mask().
		enum category_t
		{
			// Enables alerts that report an error. This includes:
			//
			// * tracker errors
			// * tracker warnings
			// * file errors
			// * resume data failures
			// * web seed errors
			// * .torrent files errors
			// * listen socket errors
			// * port mapping errors
			error_notification = 0x1,

			// Enables alerts when peers send invalid requests, get banned or
			// snubbed.
			peer_notification = 0x2,

			// Enables alerts for port mapping events. For NAT-PMP and UPnP.
			port_mapping_notification = 0x4,

			// Enables alerts for events related to the storage. File errors and
			// synchronization events for moving the storage, renaming files etc.
			storage_notification = 0x8,

			// Enables all tracker events. Includes announcing to trackers,
			// receiving responses, warnings and errors.
			tracker_notification = 0x10,

			// Low level alerts for when peers are connected and disconnected.
			debug_notification = 0x20,

			// Enables alerts for when a torrent or the session changes state.
			status_notification = 0x40,

			// Alerts for when blocks are requested and completed. Also when
			// pieces are completed.
			progress_notification = 0x80,

			// Alerts when a peer is blocked by the ip blocker or port blocker.
			ip_block_notification = 0x100,

			// Alerts when some limit is reached that might limit the download
			// or upload rate.
			performance_warning = 0x200,

			// Alerts on events in the DHT node. For incoming searches or
			// bootstrapping being done etc.
			dht_notification = 0x400,

			// If you enable these alerts, you will receive a stats_alert
			// approximately once every second, for every active torrent.
			// These alerts contain all statistics counters for the interval since
			// the lasts stats alert.
			stats_notification = 0x800,

			// Alerts on RSS related events, like feeds being updated, feed error
			// conditions and successful RSS feed updates. Enabling this categoty
			// will make you receive rss_alert alerts.
			rss_notification = 0x1000,

			// The full bitmask, representing all available categories.
			//
			// since the enum is signed, make sure this isn't
			// interpreted as -1. For instance, boost.python
			// does that and fails when assigning it to an
			// unsigned parameter.
			all_categories = 0x7fffffff
		};

		// hidden
		alert();
		// hidden
		virtual ~alert();

		// a timestamp is automatically created in the constructor
		ptime timestamp() const;

		// returns an integer that is unique to this alert type. It can be
		// compared against a specific alert by querying a static constant called ``alert_type``
		// in the alert. It can be used to determine the run-time type of an alert* in
		// order to cast to that alert type and access specific members.
		//
		// e.g::
		//
		//	std::auto_ptr<alert> a = ses.pop_alert();
		//	switch (a->type())
		//	{
		//		case read_piece_alert::alert_type:
		//		{
		//			read_piece_alert* p = (read_piece_alert*)a.get();
		//			if (p->ec) {
		//				// read_piece failed
		//				break;
		//			}
		//			// use p
		//			break;
		//		}
		//		case file_renamed_alert::alert_type:
		//		{
		//			// etc...
		//		}
		//	}
		virtual int type() const = 0;

		// returns a string literal describing the type of the alert. It does
		// not include any information that might be bundled with the alert.
		virtual char const* what() const = 0;

		// generate a string describing the alert and the information bundled
		// with it. This is mainly intended for debug and development use. It is not suitable
		// to use this for applications that may be localized. Instead, handle each alert
		// type individually and extract and render the information from the alert depending
		// on the locale.
		virtual std::string message() const = 0;

		// returns a bitmask specifying which categories this alert belong to.
		virtual int category() const = 0;

		// determines whether or not an alert is allowed to be discarded
		// when the alert queue is full. There are a few alerts which may not be discared,
		// since they would break the user contract, such as save_resume_data_alert.
		virtual bool discardable() const { return true; }

#ifndef TORRENT_NO_DEPRECATE
		TORRENT_DEPRECATED_PREFIX
		severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif

		// returns a pointer to a copy of the alert.
		virtual std::auto_ptr<alert> clone() const = 0;

	private:
		ptime m_timestamp;
	};

#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE
	struct TORRENT_EXPORT unhandled_alert : std::exception
	{
		unhandled_alert() {}
	};

#ifndef BOOST_NO_TYPEID

	namespace detail {

		struct void_;

		template<class Handler
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_, const Handler& handler
			, const std::type_info& typeid_
			, T0*, BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
		{
			if (typeid_ == typeid(T0))
				handler(*static_cast<T0*>(alert_.get()));
			else
				handle_alert_dispatch(alert_, handler, typeid_
					, BOOST_PP_ENUM_SHIFTED_PARAMS(
					TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
		}

		template<class Handler>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>&
			, const Handler&
			, const std::type_info&
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
		{
			throw unhandled_alert();
		}

	} // namespace detail

	template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
		TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
	struct TORRENT_EXPORT handle_alert
	{
		template<class Handler>
		handle_alert(const std::auto_ptr<alert>& alert_
			, const Handler& handler)
		{
			#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0

			detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
				, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));

			#undef ALERT_POINTER_TYPE
		}
	};

#endif // BOOST_NO_TYPEID
#endif // TORRENT_NO_DEPRECATE
#endif // BOOST_NO_EXCEPTIONS

// When you get an alert, you can use ``alert_cast<>`` to attempt to cast the pointer to a
// more specific alert type, in order to query it for more information.
template <class T>
T* alert_cast(alert* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T*>(a);
	return 0;
}
template <class T>
T const* alert_cast(alert const* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T const*>(a);
	return 0;
}

} // namespace libtorrent

#endif // TORRENT_ALERT_HPP_INCLUDED

<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

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

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

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

*/

#ifndef TORRENT_DEBUG_HPP_INCLUDED
#define TORRENT_DEBUG_HPP_INCLUDED

#if defined TORRENT_ASIO_DEBUGGING

#include "libtorrent/assert.hpp"
#include "libtorrent/thread.hpp"

#include <execinfo.h>
#include <map>

std::string demangle(char const* name);

namespace libtorrent
{
	struct async_t
	{
		async_t() : refs(0) {}
		std::string stack;
		int refs;
	};

	extern std::map<std::string, async_t> _async_ops;
	extern int _async_ops_nthreads;
	extern mutex _async_ops_mutex;

	inline void add_outstanding_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		async_t& a = _async_ops[name];
		if (a.stack.empty())
		{
			void* stack[50];
			int size = backtrace(stack, 50);
			char** symbols = backtrace_symbols(stack, size);

			for (int i = 1; i < size; ++i)
			{
				char str[200];
				snprintf(str, sizeof(str), "%d: %s\n", i, demangle(symbols[i]).c_str());
				a.stack += str;
			}

			free(symbols);
		}
		++a.refs;
	}

	inline void complete_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		async_t& a = _async_ops[name];
		TORRENT_ASSERT(a.refs > 0);
		--a.refs;
	}

	inline void async_inc_threads()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		++_async_ops_nthreads;
	}

	inline void async_dec_threads()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		--_async_ops_nthreads;
	}

	inline int log_async()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		int ret = 0;
		for (std::map<std::string, async_t>::iterator i = _async_ops.begin()
			, end(_async_ops.end()); i != end; ++i)
		{
			if (i->second.refs <= _async_ops_nthreads - 1) continue;
			ret += i->second.refs;
			printf("%s: (%d)\n%s\n", i->first.c_str(), i->second.refs, i->second.stack.c_str());
		}
		return ret;
	}
}

#endif

#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING

#include <string>
#include "libtorrent/config.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/thread.hpp"

#if TORRENT_USE_IOSTREAM
#include <fstream>
#include <iostream>
#endif

namespace libtorrent
{
	// DEBUG API

	struct logger
	{
#if TORRENT_USE_IOSTREAM
		// all log streams share a single file descriptor
		// and re-opens the file for each log line
		// these members are defined in session_impl.cpp
		static std::ofstream log_file;
		static std::string open_filename;
		static mutex file_mutex;
#endif

		~logger()
		{
			mutex::scoped_lock l(file_mutex);
			log_file.close();
		}

		logger(std::string const& logpath, std::string const& filename
			, int instance, bool append)
		{
			char log_name[512];
			snprintf(log_name, sizeof(log_name), "libtorrent_logs%d", instance);
			std::string dir(complete(combine_path(logpath, log_name)));
			error_code ec;
			if (!exists(dir)) create_directories(dir, ec);
			m_filename = combine_path(dir, filename);

			mutex::scoped_lock l(file_mutex);
			open(!append);
			log_file << "\n\n\n*** starting log ***\n";
		}

#if TORRENT_USE_IOSTREAM
		void open(bool truncate)
		{
			if (open_filename == m_filename) return;
			log_file.close();
			log_file.clear();
			log_file.open(m_filename.c_str(), truncate ? std::ios_base::trunc : std::ios_base::app);
			open_filename = m_filename;
			if (!log_file.good())
				fprintf(stderr, "Failed to open logfile %s: %s\n", m_filename.c_str(), strerror(errno));
		}
#endif

		template <class T>
		logger& operator<<(T const& v)
		{
#if TORRENT_USE_IOSTREAM
			mutex::scoped_lock l(file_mutex);
			open(false);
			log_file << v;
#endif
			return *this;
		}

		std::string m_filename;
	};

}

#endif // TORRENT_VERBOSE_LOGGING || TORRENT_LOGGING || TORRENT_ERROR_LOGGING
#endif // TORRENT_DEBUG_HPP_INCLUDED

<commit_msg>debug logging fix<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

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

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

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

*/

#ifndef TORRENT_DEBUG_HPP_INCLUDED
#define TORRENT_DEBUG_HPP_INCLUDED

#if defined TORRENT_ASIO_DEBUGGING

#include "libtorrent/assert.hpp"
#include "libtorrent/thread.hpp"

#include <execinfo.h>
#include <map>

std::string demangle(char const* name);

namespace libtorrent
{
	struct async_t
	{
		async_t() : refs(0) {}
		std::string stack;
		int refs;
	};

	extern std::map<std::string, async_t> _async_ops;
	extern int _async_ops_nthreads;
	extern mutex _async_ops_mutex;

	inline void add_outstanding_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		async_t& a = _async_ops[name];
		if (a.stack.empty())
		{
			void* stack[50];
			int size = backtrace(stack, 50);
			char** symbols = backtrace_symbols(stack, size);

			for (int i = 1; i < size; ++i)
			{
				char str[200];
				snprintf(str, sizeof(str), "%d: %s\n", i, demangle(symbols[i]).c_str());
				a.stack += str;
			}

			free(symbols);
		}
		++a.refs;
	}

	inline void complete_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		async_t& a = _async_ops[name];
		TORRENT_ASSERT(a.refs > 0);
		--a.refs;
	}

	inline void async_inc_threads()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		++_async_ops_nthreads;
	}

	inline void async_dec_threads()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		--_async_ops_nthreads;
	}

	inline int log_async()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		int ret = 0;
		for (std::map<std::string, async_t>::iterator i = _async_ops.begin()
			, end(_async_ops.end()); i != end; ++i)
		{
			if (i->second.refs <= _async_ops_nthreads - 1) continue;
			ret += i->second.refs;
			printf("%s: (%d)\n%s\n", i->first.c_str(), i->second.refs, i->second.stack.c_str());
		}
		return ret;
	}
}

#endif

#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING

#include <string>
#include "libtorrent/config.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/thread.hpp"

#if TORRENT_USE_IOSTREAM
#include <fstream>
#include <iostream>
#endif

namespace libtorrent
{
	// DEBUG API

	struct logger
	{
#if TORRENT_USE_IOSTREAM
		// all log streams share a single file descriptor
		// and re-opens the file for each log line
		// these members are defined in session_impl.cpp
		static std::ofstream log_file;
		static std::string open_filename;
		static mutex file_mutex;
#endif

		~logger()
		{
			mutex::scoped_lock l(file_mutex);
			log_file.close();
			open_filename.clear();
		}

		logger(std::string const& logpath, std::string const& filename
			, int instance, bool append)
		{
			char log_name[512];
			snprintf(log_name, sizeof(log_name), "libtorrent_logs%d", instance);
			std::string dir(complete(combine_path(logpath, log_name)));
			error_code ec;
			if (!exists(dir)) create_directories(dir, ec);
			m_filename = combine_path(dir, filename);

			mutex::scoped_lock l(file_mutex);
			open(!append);
			log_file << "\n\n\n*** starting log ***\n";
		}

#if TORRENT_USE_IOSTREAM
		void open(bool truncate)
		{
			if (open_filename == m_filename) return;
			log_file.close();
			log_file.clear();
			log_file.open(m_filename.c_str(), truncate ? std::ios_base::trunc : std::ios_base::app);
			open_filename = m_filename;
			if (!log_file.good())
				fprintf(stderr, "Failed to open logfile %s: %s\n", m_filename.c_str(), strerror(errno));
		}
#endif

		template <class T>
		logger& operator<<(T const& v)
		{
#if TORRENT_USE_IOSTREAM
			mutex::scoped_lock l(file_mutex);
			open(false);
			log_file << v;
#endif
			return *this;
		}

		std::string m_filename;
	};

}

#endif // TORRENT_VERBOSE_LOGGING || TORRENT_LOGGING || TORRENT_ERROR_LOGGING
#endif // TORRENT_DEBUG_HPP_INCLUDED

<|endoftext|>