<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DLL_WATCHER_HPP
#define DLL_WATCHER_HPP

#include <fstream>

#include <sys/stat.h>

#include "cpp_utils/stop_watch.hpp"

#include "rbm_training_context.hpp"
#include "rbm_traits.hpp"
#include "dbn_traits.hpp"

namespace dll {

template<typename R>
struct default_rbm_watcher {
    cpp::stop_watch<std::chrono::seconds> watch;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        std::cout << "Train RBM with \"" << RBM::desc::template trainer_t<RBM>::name() << "\"" << std::endl;

        rbm.display();

        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << rbm.learning_rate << std::endl;

        if(rbm_traits<RBM>::has_momentum()){
            std::cout << "   momentum=" << rbm.momentum << std::endl;
        }

        if(w_decay(rbm_traits<RBM>::decay()) == decay_type::L1 || w_decay(rbm_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L1)=" << rbm.l1_weight_cost << std::endl;
        }

        if(w_decay(rbm_traits<RBM>::decay()) == decay_type::L2 || w_decay(rbm_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L2)=" << rbm.l2_weight_cost << std::endl;
        }

        if(rbm_traits<RBM>::sparsity_method() == sparsity_method::LEE){
            std::cout << "   Sparsity (Lee): pbias=" << rbm.pbias << std::endl;
            std::cout << "   Sparsity (Lee): pbias_lambda=" << rbm.pbias_lambda << std::endl;
        } else if(rbm_traits<RBM>::sparsity_method() == sparsity_method::GLOBAL_TARGET){
            std::cout << "   sparsity_target(Global)=" << rbm.sparsity_target << std::endl;
        } else if(rbm_traits<RBM>::sparsity_method() == sparsity_method::LOCAL_TARGET){
            std::cout << "   sparsity_target(Local)=" << rbm.sparsity_target << std::endl;
        }
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, const rbm_training_context& context, const RBM& /*rbm*/){
        printf("epoch %ld - Reconstruction error: %.5f - Free energy: %.3f - Sparsity: %.5f\n", epoch,
            context.reconstruction_error, context.free_energy, context.sparsity);
    }

    template<typename RBM = R>
    void training_end(const RBM&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN, typename Enable = void>
struct default_dbn_watcher {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining begin" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        using rbm_t = RBM;
        static constexpr const auto num_visible = rbm_t::num_visible;
        static constexpr const auto num_hidden = rbm_t::num_hidden;

        std::cout << "DBN: Train layer " << I << " (" << num_visible << "->" << num_hidden << ") with " << input_size << " entries" << std::endl;
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining end" << std::endl;
    }

    void fine_tuning_begin(const DBN& dbn){
        std::cout << "Train DBN with \"" << DBN::desc::template trainer_t<DBN>::name() << "\"" << std::endl;
        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << dbn.learning_rate << std::endl;

        if(dbn_traits<DBN>::has_momentum()){
            std::cout << "   momentum=" << dbn.momentum << std::endl;
        }
    }

    void ft_epoch_end(std::size_t epoch, double error, const DBN&){
        printf("epoch %ld - Classification error: %.5f \n", epoch, error);
    }

    void fine_tuning_end(const DBN&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct default_dbn_watcher<DBN, std::enable_if_t<dbn_traits<DBN>::is_convolutional()>> {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/){
        std::cout << "CDBN: Pretraining begin" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        using rbm_t = RBM;

        static constexpr const auto NV = rbm_t::NV;
        static constexpr const auto NH = rbm_t::NH;
        static constexpr const auto K = rbm_t::K;

        printf("CDBN: Train layer %lu (%lux%lu -> %lux%lu (%lu)) with %lu entries \n", I, NV, NV, NH, NH, K, input_size);
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "CDBN: Pretraining end" << std::endl;
    }
};

template<typename DBN>
struct silent_dbn_watcher : default_dbn_watcher<DBN> {
    static constexpr const bool ignore_sub = true;
    static constexpr const bool replace_sub = false;
};

//TODO This is currently useless

template<typename R>
struct histogram_watcher {
    default_rbm_watcher<R> parent;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        parent.training_begin(rbm);
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, double error, double /*free_energy*/, const RBM& rbm){
        parent.epoch_end(epoch, error, rbm);
    }

    template<typename RBM = R>
    void training_end(const RBM& rbm){
        parent.training_end(rbm);
    }

    void generate_hidden_images(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        for(std::size_t j = 0; j < R::num_hidden; ++j){
            auto path = folder + "/h_" + std::to_string(j) + ".dat";
            std::ofstream file(path, std::ios::out);

            if(!file){
                std::cout << "Could not open file " << path << std::endl;
            } else {
                std::size_t i = R::num_visible;
                while(i > 0){
                    --i;

                    auto value = rbm.w(i,j);
                    file << static_cast<std::size_t>(value > 0 ? static_cast<std::size_t>(value * 255.0) << 8 : static_cast<std::size_t>(-value * 255.0) << 16) << " ";
                }

                file << std::endl;
                file.close();
            }
        }
    }

    void generate_histograms(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        generate_histogram(folder + "/weights.dat", rbm.w);
        generate_histogram(folder + "/visibles.dat", rbm.a);
        generate_histogram(folder + "/hiddens.dat", rbm.b);
    }

    template<typename Container>
    void generate_histogram(const std::string& path, const Container& weights){
        std::ofstream file(path, std::ios::out);

        if(!file){
            std::cout << "Could not open file " << path << std::endl;
        } else {
            for(auto& weight : weights){
                file << weight << std::endl;
            }

            file << std::endl;
            file.close();
        }
    }
};

} //end of dll namespace

#endif<commit_msg>Add watcher for dyn_dbn<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DLL_WATCHER_HPP
#define DLL_WATCHER_HPP

#include <fstream>

#include <sys/stat.h>

#include "cpp_utils/stop_watch.hpp"

#include "rbm_training_context.hpp"
#include "rbm_traits.hpp"
#include "dbn_traits.hpp"

namespace dll {

template<typename R>
struct default_rbm_watcher {
    cpp::stop_watch<std::chrono::seconds> watch;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        std::cout << "Train RBM with \"" << RBM::desc::template trainer_t<RBM>::name() << "\"" << std::endl;

        rbm.display();

        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << rbm.learning_rate << std::endl;

        if(rbm_traits<RBM>::has_momentum()){
            std::cout << "   momentum=" << rbm.momentum << std::endl;
        }

        if(w_decay(rbm_traits<RBM>::decay()) == decay_type::L1 || w_decay(rbm_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L1)=" << rbm.l1_weight_cost << std::endl;
        }

        if(w_decay(rbm_traits<RBM>::decay()) == decay_type::L2 || w_decay(rbm_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L2)=" << rbm.l2_weight_cost << std::endl;
        }

        if(rbm_traits<RBM>::sparsity_method() == sparsity_method::LEE){
            std::cout << "   Sparsity (Lee): pbias=" << rbm.pbias << std::endl;
            std::cout << "   Sparsity (Lee): pbias_lambda=" << rbm.pbias_lambda << std::endl;
        } else if(rbm_traits<RBM>::sparsity_method() == sparsity_method::GLOBAL_TARGET){
            std::cout << "   sparsity_target(Global)=" << rbm.sparsity_target << std::endl;
        } else if(rbm_traits<RBM>::sparsity_method() == sparsity_method::LOCAL_TARGET){
            std::cout << "   sparsity_target(Local)=" << rbm.sparsity_target << std::endl;
        }
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, const rbm_training_context& context, const RBM& /*rbm*/){
        printf("epoch %ld - Reconstruction error: %.5f - Free energy: %.3f - Sparsity: %.5f\n", epoch,
            context.reconstruction_error, context.free_energy, context.sparsity);
    }

    template<typename RBM = R>
    void training_end(const RBM&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN, typename Enable = void>
struct default_dbn_watcher {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining begin" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        using rbm_t = RBM;
        static constexpr const auto num_visible = rbm_t::num_visible;
        static constexpr const auto num_hidden = rbm_t::num_hidden;

        std::cout << "DBN: Train layer " << I << " (" << num_visible << "->" << num_hidden << ") with " << input_size << " entries" << std::endl;
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining end" << std::endl;
    }

    void fine_tuning_begin(const DBN& dbn){
        std::cout << "Train DBN with \"" << DBN::desc::template trainer_t<DBN>::name() << "\"" << std::endl;
        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << dbn.learning_rate << std::endl;

        if(dbn_traits<DBN>::has_momentum()){
            std::cout << "   momentum=" << dbn.momentum << std::endl;
        }
    }

    void ft_epoch_end(std::size_t epoch, double error, const DBN&){
        printf("epoch %ld - Classification error: %.5f \n", epoch, error);
    }

    void fine_tuning_end(const DBN&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct default_dbn_watcher<DBN, std::enable_if_t<dbn_traits<DBN>::is_dynamic()>> {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining begin" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        std::cout << "DBN: Train layer " << I << " with " << input_size << " entries" << std::endl;
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining end" << std::endl;
    }

    void fine_tuning_begin(const DBN& dbn){
        std::cout << "Train DBN with \"" << DBN::desc::template trainer_t<DBN>::name() << "\"" << std::endl;
        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << dbn.learning_rate << std::endl;

        if(dbn_traits<DBN>::has_momentum()){
            std::cout << "   momentum=" << dbn.momentum << std::endl;
        }
    }

    void ft_epoch_end(std::size_t epoch, double error, const DBN&){
        printf("epoch %ld - Classification error: %.5f \n", epoch, error);
    }

    void fine_tuning_end(const DBN&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct default_dbn_watcher<DBN, std::enable_if_t<dbn_traits<DBN>::is_convolutional()>> {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/){
        std::cout << "CDBN: Pretraining begin" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        using rbm_t = RBM;

        static constexpr const auto NV = rbm_t::NV;
        static constexpr const auto NH = rbm_t::NH;
        static constexpr const auto K = rbm_t::K;

        printf("CDBN: Train layer %lu (%lux%lu -> %lux%lu (%lu)) with %lu entries \n", I, NV, NV, NH, NH, K, input_size);
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "CDBN: Pretraining end" << std::endl;
    }
};

template<typename DBN>
struct silent_dbn_watcher : default_dbn_watcher<DBN> {
    static constexpr const bool ignore_sub = true;
    static constexpr const bool replace_sub = false;
};

//TODO This is currently useless

template<typename R>
struct histogram_watcher {
    default_rbm_watcher<R> parent;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        parent.training_begin(rbm);
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, double error, double /*free_energy*/, const RBM& rbm){
        parent.epoch_end(epoch, error, rbm);
    }

    template<typename RBM = R>
    void training_end(const RBM& rbm){
        parent.training_end(rbm);
    }

    void generate_hidden_images(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        for(std::size_t j = 0; j < R::num_hidden; ++j){
            auto path = folder + "/h_" + std::to_string(j) + ".dat";
            std::ofstream file(path, std::ios::out);

            if(!file){
                std::cout << "Could not open file " << path << std::endl;
            } else {
                std::size_t i = R::num_visible;
                while(i > 0){
                    --i;

                    auto value = rbm.w(i,j);
                    file << static_cast<std::size_t>(value > 0 ? static_cast<std::size_t>(value * 255.0) << 8 : static_cast<std::size_t>(-value * 255.0) << 16) << " ";
                }

                file << std::endl;
                file.close();
            }
        }
    }

    void generate_histograms(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        generate_histogram(folder + "/weights.dat", rbm.w);
        generate_histogram(folder + "/visibles.dat", rbm.a);
        generate_histogram(folder + "/hiddens.dat", rbm.b);
    }

    template<typename Container>
    void generate_histogram(const std::string& path, const Container& weights){
        std::ofstream file(path, std::ios::out);

        if(!file){
            std::cout << "Could not open file " << path << std::endl;
        } else {
            for(auto& weight : weights){
                file << weight << std::endl;
            }

            file << std::endl;
            file.close();
        }
    }
};

} //end of dll namespace

#endif
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DLL_WATCHER_HPP
#define DLL_WATCHER_HPP

#include <fstream>

#include <sys/stat.h>

#include "cpp_utils/stop_watch.hpp"

#include "rbm_training_context.hpp"
#include "layer_traits.hpp"
#include "dbn_traits.hpp"

namespace dll {

template<typename R>
struct default_rbm_watcher {
    cpp::stop_watch<std::chrono::seconds> watch;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        std::cout << "Train RBM with \"" << RBM::desc::template trainer_t<RBM,false>::name() << "\"" << std::endl;

        rbm.display();

        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << rbm.learning_rate << std::endl;

        if(layer_traits<RBM>::has_momentum()){
            std::cout << "   momentum=" << rbm.momentum << std::endl;
        }

        if(w_decay(layer_traits<RBM>::decay()) == decay_type::L1 || w_decay(layer_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L1)=" << rbm.l1_weight_cost << std::endl;
        }

        if(w_decay(layer_traits<RBM>::decay()) == decay_type::L2 || w_decay(layer_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L2)=" << rbm.l2_weight_cost << std::endl;
        }

        if(layer_traits<RBM>::sparsity_method() == sparsity_method::LEE){
            std::cout << "   Sparsity (Lee): pbias=" << rbm.pbias << std::endl;
            std::cout << "   Sparsity (Lee): pbias_lambda=" << rbm.pbias_lambda << std::endl;
        } else if(layer_traits<RBM>::sparsity_method() == sparsity_method::GLOBAL_TARGET){
            std::cout << "   sparsity_target(Global)=" << rbm.sparsity_target << std::endl;
        } else if(layer_traits<RBM>::sparsity_method() == sparsity_method::LOCAL_TARGET){
            std::cout << "   sparsity_target(Local)=" << rbm.sparsity_target << std::endl;
        }
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, const rbm_training_context& context, const RBM& /*rbm*/){
        char formatted[1024];
        if(layer_traits<RBM>::free_energy()){
            snprintf(formatted, 1024, "epoch %ld - Reconstruction error: %.5f - Free energy: %.3f - Sparsity: %.5f\n", epoch,
                context.reconstruction_error, context.free_energy, context.sparsity);
        } else {
            snprintf(formatted, 1024, "epoch %ld - Reconstruction error: %.5f - Sparsity: %.5f\n", epoch, context.reconstruction_error, context.sparsity);
        }
        std::cout << formatted;
    }

    template<typename RBM = R>
    void batch_end(const RBM& /* rbm */, const rbm_training_context& context, std::size_t batch, std::size_t batches){
        char formatted[1024];
        sprintf(formatted, "Batch %ld/%ld - Reconstruction error: %.5f - Sparsity: %.5f\n", batch, batches,
            context.batch_error, context.batch_sparsity);
        std::cout << formatted;
    }

    template<typename RBM = R>
    void training_end(const RBM&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct default_dbn_watcher {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/, std::size_t max_epochs){
        std::cout << "DBN: Pretraining begin for " << max_epochs << " epochs" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        using rbm_t = RBM;

        if(input_size > 0){
            std::cout << "DBN: Pretrain layer " << I << " (" << rbm_t::to_short_string() << ") with " << input_size << " entries" << std::endl;
        } else {
            std::cout << "DBN: Pretrain layer " << I << " (" << rbm_t::to_short_string() << ")" << std::endl;
        }
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining finished after " << watch.elapsed() << "s" << std::endl;
    }

    void pretraining_batch(const DBN& /*dbn*/, std::size_t batch){
        std::cout << "DBN: Pretraining batch " << batch << std::endl;
    }

    void fine_tuning_begin(const DBN& dbn){
        std::cout << "Train DBN with \"" << DBN::desc::template trainer_t<DBN>::name() << "\"" << std::endl;
        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << dbn.learning_rate << std::endl;

        if(dbn_traits<DBN>::has_momentum()){
            std::cout << "   momentum=" << dbn.momentum << std::endl;
        }

        if(w_decay(dbn_traits<DBN>::decay()) == decay_type::L1 || w_decay(dbn_traits<DBN>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L1)=" << dbn.l1_weight_cost << std::endl;
        }

        if(w_decay(dbn_traits<DBN>::decay()) == decay_type::L2 || w_decay(dbn_traits<DBN>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L2)=" << dbn.l2_weight_cost << std::endl;
        }
    }

    void ft_epoch_end(std::size_t epoch, double error, const DBN&){
        char formatted[1024];
        snprintf(formatted, 1024, "epoch %ld - Classification error: %.5f \n", epoch, error);
        std::cout << formatted;
    }

    void fine_tuning_end(const DBN&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct silent_dbn_watcher : default_dbn_watcher<DBN> {
    static constexpr const bool ignore_sub = true;
    static constexpr const bool replace_sub = false;
};

//TODO This is currently useless

template<typename R>
struct histogram_watcher {
    default_rbm_watcher<R> parent;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        parent.training_begin(rbm);
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, double error, double /*free_energy*/, const RBM& rbm){
        parent.epoch_end(epoch, error, rbm);
    }

    template<typename RBM = R>
    void batch_end(const RBM& rbm, const rbm_training_context& context, std::size_t batch, std::size_t batches){
        parent.batch_end(rbm, context, batch, batches);
    }

    template<typename RBM = R>
    void training_end(const RBM& rbm){
        parent.training_end(rbm);
    }

    void generate_hidden_images(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        for(std::size_t j = 0; j < R::num_hidden; ++j){
            auto path = folder + "/h_" + std::to_string(j) + ".dat";
            std::ofstream file(path, std::ios::out);

            if(!file){
                std::cout << "Could not open file " << path << std::endl;
            } else {
                std::size_t i = R::num_visible;
                while(i > 0){
                    --i;

                    auto value = rbm.w(i,j);
                    file << static_cast<std::size_t>(value > 0 ? static_cast<std::size_t>(value * 255.0) << 8 : static_cast<std::size_t>(-value * 255.0) << 16) << " ";
                }

                file << std::endl;
                file.close();
            }
        }
    }

    void generate_histograms(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        generate_histogram(folder + "/weights.dat", rbm.w);
        generate_histogram(folder + "/visibles.dat", rbm.a);
        generate_histogram(folder + "/hiddens.dat", rbm.b);
    }

    template<typename Container>
    void generate_histogram(const std::string& path, const Container& weights){
        std::ofstream file(path, std::ios::out);

        if(!file){
            std::cout << "Could not open file " << path << std::endl;
        } else {
            for(auto& weight : weights){
                file << weight << std::endl;
            }

            file << std::endl;
            file.close();
        }
    }
};

} //end of dll namespace

#endif
<commit_msg>Force flush<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DLL_WATCHER_HPP
#define DLL_WATCHER_HPP

#include <fstream>

#include <sys/stat.h>

#include "cpp_utils/stop_watch.hpp"

#include "rbm_training_context.hpp"
#include "layer_traits.hpp"
#include "dbn_traits.hpp"

namespace dll {

template<typename R>
struct default_rbm_watcher {
    cpp::stop_watch<std::chrono::seconds> watch;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        std::cout << "Train RBM with \"" << RBM::desc::template trainer_t<RBM,false>::name() << "\"" << std::endl;

        rbm.display();

        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << rbm.learning_rate << std::endl;

        if(layer_traits<RBM>::has_momentum()){
            std::cout << "   momentum=" << rbm.momentum << std::endl;
        }

        if(w_decay(layer_traits<RBM>::decay()) == decay_type::L1 || w_decay(layer_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L1)=" << rbm.l1_weight_cost << std::endl;
        }

        if(w_decay(layer_traits<RBM>::decay()) == decay_type::L2 || w_decay(layer_traits<RBM>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L2)=" << rbm.l2_weight_cost << std::endl;
        }

        if(layer_traits<RBM>::sparsity_method() == sparsity_method::LEE){
            std::cout << "   Sparsity (Lee): pbias=" << rbm.pbias << std::endl;
            std::cout << "   Sparsity (Lee): pbias_lambda=" << rbm.pbias_lambda << std::endl;
        } else if(layer_traits<RBM>::sparsity_method() == sparsity_method::GLOBAL_TARGET){
            std::cout << "   sparsity_target(Global)=" << rbm.sparsity_target << std::endl;
        } else if(layer_traits<RBM>::sparsity_method() == sparsity_method::LOCAL_TARGET){
            std::cout << "   sparsity_target(Local)=" << rbm.sparsity_target << std::endl;
        }
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, const rbm_training_context& context, const RBM& /*rbm*/){
        char formatted[1024];
        if(layer_traits<RBM>::free_energy()){
            snprintf(formatted, 1024, "epoch %ld - Reconstruction error: %.5f - Free energy: %.3f - Sparsity: %.5f", epoch,
                context.reconstruction_error, context.free_energy, context.sparsity);
        } else {
            snprintf(formatted, 1024, "epoch %ld - Reconstruction error: %.5f - Sparsity: %.5f", epoch, context.reconstruction_error, context.sparsity);
        }
        std::cout << formatted << std::endl;
    }

    template<typename RBM = R>
    void batch_end(const RBM& /* rbm */, const rbm_training_context& context, std::size_t batch, std::size_t batches){
        char formatted[1024];
        sprintf(formatted, "Batch %ld/%ld - Reconstruction error: %.5f - Sparsity: %.5f", batch, batches,
            context.batch_error, context.batch_sparsity);
        std::cout << formatted << std::endl;
    }

    template<typename RBM = R>
    void training_end(const RBM&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct default_dbn_watcher {
    static constexpr const bool ignore_sub = false;
    static constexpr const bool replace_sub = false;

    cpp::stop_watch<std::chrono::seconds> watch;

    void pretraining_begin(const DBN& /*dbn*/, std::size_t max_epochs){
        std::cout << "DBN: Pretraining begin for " << max_epochs << " epochs" << std::endl;
    }

    template<typename RBM>
    void pretrain_layer(const DBN& /*dbn*/, std::size_t I, std::size_t input_size){
        using rbm_t = RBM;

        if(input_size > 0){
            std::cout << "DBN: Pretrain layer " << I << " (" << rbm_t::to_short_string() << ") with " << input_size << " entries" << std::endl;
        } else {
            std::cout << "DBN: Pretrain layer " << I << " (" << rbm_t::to_short_string() << ")" << std::endl;
        }
    }

    void pretraining_end(const DBN& /*dbn*/){
        std::cout << "DBN: Pretraining finished after " << watch.elapsed() << "s" << std::endl;
    }

    void pretraining_batch(const DBN& /*dbn*/, std::size_t batch){
        std::cout << "DBN: Pretraining batch " << batch << std::endl;
    }

    void fine_tuning_begin(const DBN& dbn){
        std::cout << "Train DBN with \"" << DBN::desc::template trainer_t<DBN>::name() << "\"" << std::endl;
        std::cout << "With parameters:" << std::endl;
        std::cout << "   learning_rate=" << dbn.learning_rate << std::endl;

        if(dbn_traits<DBN>::has_momentum()){
            std::cout << "   momentum=" << dbn.momentum << std::endl;
        }

        if(w_decay(dbn_traits<DBN>::decay()) == decay_type::L1 || w_decay(dbn_traits<DBN>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L1)=" << dbn.l1_weight_cost << std::endl;
        }

        if(w_decay(dbn_traits<DBN>::decay()) == decay_type::L2 || w_decay(dbn_traits<DBN>::decay()) == decay_type::L1L2){
            std::cout << "   weight_cost(L2)=" << dbn.l2_weight_cost << std::endl;
        }
    }

    void ft_epoch_end(std::size_t epoch, double error, const DBN&){
        char formatted[1024];
        snprintf(formatted, 1024, "epoch %ld - Classification error: %.5f", epoch, error);
        std::cout << formatted std::endl;
    }

    void fine_tuning_end(const DBN&){
        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }
};

template<typename DBN>
struct silent_dbn_watcher : default_dbn_watcher<DBN> {
    static constexpr const bool ignore_sub = true;
    static constexpr const bool replace_sub = false;
};

//TODO This is currently useless

template<typename R>
struct histogram_watcher {
    default_rbm_watcher<R> parent;

    template<typename RBM = R>
    void training_begin(const RBM& rbm){
        parent.training_begin(rbm);
    }

    template<typename RBM = R>
    void epoch_end(std::size_t epoch, double error, double /*free_energy*/, const RBM& rbm){
        parent.epoch_end(epoch, error, rbm);
    }

    template<typename RBM = R>
    void batch_end(const RBM& rbm, const rbm_training_context& context, std::size_t batch, std::size_t batches){
        parent.batch_end(rbm, context, batch, batches);
    }

    template<typename RBM = R>
    void training_end(const RBM& rbm){
        parent.training_end(rbm);
    }

    void generate_hidden_images(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        for(std::size_t j = 0; j < R::num_hidden; ++j){
            auto path = folder + "/h_" + std::to_string(j) + ".dat";
            std::ofstream file(path, std::ios::out);

            if(!file){
                std::cout << "Could not open file " << path << std::endl;
            } else {
                std::size_t i = R::num_visible;
                while(i > 0){
                    --i;

                    auto value = rbm.w(i,j);
                    file << static_cast<std::size_t>(value > 0 ? static_cast<std::size_t>(value * 255.0) << 8 : static_cast<std::size_t>(-value * 255.0) << 16) << " ";
                }

                file << std::endl;
                file.close();
            }
        }
    }

    void generate_histograms(std::size_t epoch, const R& rbm){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        generate_histogram(folder + "/weights.dat", rbm.w);
        generate_histogram(folder + "/visibles.dat", rbm.a);
        generate_histogram(folder + "/hiddens.dat", rbm.b);
    }

    template<typename Container>
    void generate_histogram(const std::string& path, const Container& weights){
        std::ofstream file(path, std::ios::out);

        if(!file){
            std::cout << "Could not open file " << path << std::endl;
        } else {
            for(auto& weight : weights){
                file << weight << std::endl;
            }

            file << std::endl;
            file.close();
        }
    }
};

} //end of dll namespace

#endif
<|endoftext|>


<commit_before>#include<iostream>
#include <algorithm>
#include <cv.h>
#include <highgui.h>

using namespace cv;

Mat getMeanMatrix(std::vector<Mat> buffer,int ch){

    //put each channel ch of all frames into vector temp
    std::vector<Mat> temp;
    std::vector<Mat> channels;
    for(int i=0; i<buffer.size();i++){
        split(buffer[i],channels);
        temp.push_back(channels[ch]);
    }

    //sum over all frames in temp (thus over one channel)
    Mat mean = temp[0] / temp.size();
    for(int i=1; i<temp.size();i++){
       mean += temp[i] / temp.size();
    }

    return(mean);

}

bool truePositive(Mat diff, int sensitivity, int ncomp){

        //sort matrix first by row then by column
        Mat sorted;
        sort(diff,sorted,CV_SORT_EVERY_ROW + CV_SORT_DESCENDING);
        sort(sorted,sorted,CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING);
        uchar* tilde = sorted.col(1).data; //1st col then has top ncols values

        //mean of n second 'best' pixels
        int SENS = sensitivity;
        int BEST = ncomp;
        int secondbest = 0;
        for(int i=1; i<BEST; i++){
            secondbest += tilde[i];
        }
        secondbest /= BEST;

        //only find match if it is better then average over following best matches
        //only match if better than random
        return(tilde[0] - secondbest > SENS);
}

Point robustSinglePointTracking(Mat frame, std::vector<Mat> buffer, int sens, int ncomp, int ch=2, bool refresh = true){

        Mat avg = getMeanMatrix(buffer,ch);

        if(refresh){
            buffer.erase(buffer.begin());
            buffer.push_back(frame.clone());
        }

        //substract current frame from average (substract noise/background from signal)
        std::vector<Mat> channels;
        split(frame,channels);

        Mat sub;
        subtract(channels[ch],avg,sub);

        //find brightest point
        Point pt;
        minMaxLoc(sub,NULL,NULL,NULL,&pt);

        if(truePositive(sub,sens,ncomp)){
            return(pt);
        }else{
            return(Point(-1,-1));
        }

}

std::vector<Rect> rasterizeImage(Mat img, Size r){

    std::vector<Rect> raster;
//    for(int i = 0; i < img.rows - r.height; i += r.height){
//       for(int j=0; j < img.cols - r.width; j += r.width){
//            raster.push_back(Rect(Point(j,i),r));
//        }
//    }

    for(int i = 0; i < img.rows; i += r.height){
        Size sz = Size(r.width,r.height);
        if(i + r.height >= img.rows){
            sz.height = img.rows - i;
        }
        for(int j=0; j < img.cols; j += r.width){
            if(j + r.width >= img.cols){
                sz.width = img.cols - j;
                raster.push_back(Rect(Point(j,i),sz));//Size(img.cols - j - 1,r.height)));
            }else{
                raster.push_back(Rect(Point(j,i),sz));
            }
        }
    }

    return(raster);

}
//raster avg image and frame into non-overlapping Rects and perform singlePointTracking in each
std::vector<Point> multiPointTracking(Mat frame, std::vector<Mat> buffer, int width, int height, int sens, int ncomp, int ch=2, bool refresh = true){

    std::vector<Rect> raster = rasterizeImage(frame, Size(width,height));

    std::vector<Point> results;
    for(std::vector<Rect>::iterator it = raster.begin(); it < raster.end(); it++){
        std::vector<Mat> buffer_rasterize;
        for(std::vector<Mat>::iterator it2 = buffer.begin(); it2 < buffer.end(); it2++){
            buffer_rasterize.push_back(Mat(*it2,*it));
        }

        Mat frameROI = Mat(frame,*it);
        Point pt = robustSinglePointTracking(frameROI,buffer_rasterize,sens,ncomp,ch,refresh);
        Point rel; Size sz;
        frameROI.locateROI(sz,rel);

        if(pt.x != -1 && pt.y != -1){
            results.push_back(pt+rel);
        }

    }

    return(results);
}
//std::vector<Point> multiPointTracking(Mat frame, Mat buffer, int ch=2, bool refresh=true){
//
//        Mat avg = getMeanMatrix(buffer,ch);
//
//        if(refresh){
//            buffer.erase(buffer.begin());
//            buffer.push_back(frame.clone());
//        }
//
//        //substract current frame from average (substract noise/background from signal)
//        std::vector<Mat> channels;
//        split(frame,channels);
//
//        Mat sub;
//        subtract(channels[ch],avg,sub);
//
//        //sort matrix first by row then by column
////        Mat sorted;
////        sortIdx(diff,sorted,CV_SORT_EVERY_ROW + CV_SORT_DESCENDING);
////        sortIdx(sorted,sorted,CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING);
////        uchar* tilde = sorted.data; //1st col then has top ncols values
//
//        std::vector<Rect> rois; //vector with regions of interest
//        int count_fails = 0;
//        int MAXFAILS = 8;
//        int WIDTH = 5;
//        int HEIGHT = 5;
//        Size sz = Size(WIDTH,HEIGHT);
//        while(count_fails < MAXFAILS){
//            //find brightest point
//            Point pt;
//            minMaxLoc(sub,NULL,NULL,NULL,&pt);
//
//            bool newROI = true;
//            for(std::vector<Rect>::iterator it = rois.begin(); it < rois.end(); it++){
//                if(*it.contains(pt)){
//                    newROI = false;
//                    break;
//                }
//            }
//            if(newROI){
//                rois.push_back(Rect(pt,sz));
//            }else{
//                cout_fails++;
//            }
//
//            //TODO
//        }
//}

<commit_msg>removed commented out section<commit_after>#include<iostream>
#include <algorithm>
#include <cv.h>
#include <highgui.h>

using namespace cv;

Mat getMeanMatrix(std::vector<Mat> buffer,int ch){

    //put each channel ch of all frames into vector temp
    std::vector<Mat> temp;
    std::vector<Mat> channels;
    for(int i=0; i<buffer.size();i++){
        split(buffer[i],channels);
        temp.push_back(channels[ch]);
    }

    //sum over all frames in temp (thus over one channel)
    Mat mean = temp[0] / temp.size();
    for(int i=1; i<temp.size();i++){
       mean += temp[i] / temp.size();
    }

    return(mean);

}

bool truePositive(Mat diff, int sensitivity, int ncomp){

        //sort matrix first by row then by column
        Mat sorted;
        sort(diff,sorted,CV_SORT_EVERY_ROW + CV_SORT_DESCENDING);
        sort(sorted,sorted,CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING);
        uchar* tilde = sorted.col(1).data; //1st col then has top ncols values

        //mean of n second 'best' pixels
        int SENS = sensitivity;
        int BEST = ncomp;
        int secondbest = 0;
        for(int i=1; i<BEST; i++){
            secondbest += tilde[i];
        }
        secondbest /= BEST;

        //only find match if it is better then average over following best matches
        //only match if better than random
        return(tilde[0] - secondbest > SENS);
}

Point robustSinglePointTracking(Mat frame, std::vector<Mat> buffer, int sens, int ncomp, int ch=2, bool refresh = true){

        Mat avg = getMeanMatrix(buffer,ch);

        if(refresh){
            buffer.erase(buffer.begin());
            buffer.push_back(frame.clone());
        }

        //substract current frame from average (substract noise/background from signal)
        std::vector<Mat> channels;
        split(frame,channels);

        Mat sub;
        subtract(channels[ch],avg,sub);

        //find brightest point
        Point pt;
        minMaxLoc(sub,NULL,NULL,NULL,&pt);

        if(truePositive(sub,sens,ncomp)){
            return(pt);
        }else{
            return(Point(-1,-1));
        }

}

std::vector<Rect> rasterizeImage(Mat img, Size r){

    std::vector<Rect> raster;
//    for(int i = 0; i < img.rows - r.height; i += r.height){
//       for(int j=0; j < img.cols - r.width; j += r.width){
//            raster.push_back(Rect(Point(j,i),r));
//        }
//    }

    for(int i = 0; i < img.rows; i += r.height){
        Size sz = Size(r.width,r.height);
        if(i + r.height >= img.rows){
            sz.height = img.rows - i;
        }
        for(int j=0; j < img.cols; j += r.width){
            if(j + r.width >= img.cols){
                sz.width = img.cols - j;
                raster.push_back(Rect(Point(j,i),sz));//Size(img.cols - j - 1,r.height)));
            }else{
                raster.push_back(Rect(Point(j,i),sz));
            }
        }
    }

    return(raster);

}
//raster avg image and frame into non-overlapping Rects and perform singlePointTracking in each
std::vector<Point> multiPointTracking(Mat frame, std::vector<Mat> buffer, int width, int height, int sens, int ncomp, int ch=2, bool refresh = true){

    std::vector<Rect> raster = rasterizeImage(frame, Size(width,height));

    std::vector<Point> results;
    for(std::vector<Rect>::iterator it = raster.begin(); it < raster.end(); it++){
        std::vector<Mat> buffer_rasterize;
        for(std::vector<Mat>::iterator it2 = buffer.begin(); it2 < buffer.end(); it2++){
            buffer_rasterize.push_back(Mat(*it2,*it));
        }

        Mat frameROI = Mat(frame,*it);
        Point pt = robustSinglePointTracking(frameROI,buffer_rasterize,sens,ncomp,ch,refresh);
        Point rel; Size sz;
        frameROI.locateROI(sz,rel);

        if(pt.x != -1 && pt.y != -1){
            results.push_back(pt+rel);
        }

    }

    return(results);
}

<|endoftext|>


<commit_before>//===--- Compilation.cpp - Compilation Task Implementation ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Compilation.h"

#include "clang/Driver/Action.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
#include <sys/stat.h>
#include <errno.h>

using namespace clang::driver;
using namespace clang;

Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
                         InputArgList *_Args, DerivedArgList *_TranslatedArgs)
  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
    TranslatedArgs(_TranslatedArgs), Redirects(0) {
}

Compilation::~Compilation() {
  delete TranslatedArgs;
  delete Args;

  // Free any derived arg lists.
  for (llvm::DenseMap<std::pair<const ToolChain*, const char*>,
                      DerivedArgList*>::iterator it = TCArgs.begin(),
         ie = TCArgs.end(); it != ie; ++it)
    if (it->second != TranslatedArgs)
      delete it->second;

  // Free the actions, if built.
  for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
       it != ie; ++it)
    delete *it;

  // Free redirections of stdout/stderr.
  if (Redirects) {
    delete Redirects[1];
    delete Redirects[2];
    delete [] Redirects;
  }
}

const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC,
                                                       const char *BoundArch) {
  if (!TC)
    TC = &DefaultToolChain;

  DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)];
  if (!Entry) {
    Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch);
    if (!Entry)
      Entry = TranslatedArgs;
  }

  return *Entry;
}

void Compilation::PrintJob(raw_ostream &OS, const Job &J,
                           const char *Terminator, bool Quote) const {
  if (const Command *C = dyn_cast<Command>(&J)) {
    OS << " \"" << C->getExecutable() << '"';
    for (ArgStringList::const_iterator it = C->getArguments().begin(),
           ie = C->getArguments().end(); it != ie; ++it) {
      OS << ' ';
      if (!Quote && !std::strpbrk(*it, " \"\\$")) {
        OS << *it;
        continue;
      }

      // Quote the argument and escape shell special characters; this isn't
      // really complete but is good enough.
      OS << '"';
      for (const char *s = *it; *s; ++s) {
        if (*s == '"' || *s == '\\' || *s == '$')
          OS << '\\';
        OS << *s;
      }
      OS << '"';
    }
    OS << Terminator;
  } else {
    const JobList *Jobs = cast<JobList>(&J);
    for (JobList::const_iterator
           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
      PrintJob(OS, **it, Terminator, Quote);
  }
}

bool Compilation::CleanupFileList(const ArgStringList &Files,
                                  bool IssueErrors) const {
  bool Success = true;

  for (ArgStringList::const_iterator
         it = Files.begin(), ie = Files.end(); it != ie; ++it) {

    llvm::sys::Path P(*it);
    std::string Error;

    // Don't try to remove files which we don't have write access to (but may be
    // able to remove). Underlying tools may have intentionally not overwritten
    // them.
    if (!P.canWrite())
      continue;

    if (P.eraseFromDisk(false, &Error)) {
      // Failure is only failure if the file exists and is "regular". There is
      // a race condition here due to the limited interface of
      // llvm::sys::Path, we want to know if the removal gave ENOENT.

      // FIXME: Grumble, P.exists() is broken. PR3837.
      struct stat buf;
      if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
                                         (errno != ENOENT)) {
        if (IssueErrors)
          getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
            << Error;
        Success = false;
      }
    }
  }

  return Success;
}

int Compilation::ExecuteCommand(const Command &C,
                                const Command *&FailingCommand) const {
  llvm::sys::Path Prog(C.getExecutable());
  const char **Argv = new const char*[C.getArguments().size() + 2];
  Argv[0] = C.getExecutable();
  std::copy(C.getArguments().begin(), C.getArguments().end(), Argv+1);
  Argv[C.getArguments().size() + 1] = 0;

  if ((getDriver().CCCEcho || getDriver().CCPrintOptions ||
       getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) {
    raw_ostream *OS = &llvm::errs();

    // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the
    // output stream.
    if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) {
      std::string Error;
      OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename,
                                    Error,
                                    llvm::raw_fd_ostream::F_Append);
      if (!Error.empty()) {
        getDriver().Diag(clang::diag::err_drv_cc_print_options_failure)
          << Error;
        FailingCommand = &C;
        delete OS;
        return 1;
      }
    }

    if (getDriver().CCPrintOptions)
      *OS << "[Logging clang options]";

    PrintJob(*OS, C, "\n", /*Quote=*/getDriver().CCPrintOptions);

    if (OS != &llvm::errs())
      delete OS;
  }

  std::string Error;
  int Res =
    llvm::sys::Program::ExecuteAndWait(Prog, Argv,
                                       /*env*/0, Redirects,
                                       /*secondsToWait*/0, /*memoryLimit*/0,
                                       &Error);
  if (!Error.empty()) {
    assert(Res && "Error string set with 0 result code!");
    getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
  }

  if (Res)
    FailingCommand = &C;

  delete[] Argv;
  return Res;
}

int Compilation::ExecuteJob(const Job &J,
                            const Command *&FailingCommand) const {
  if (const Command *C = dyn_cast<Command>(&J)) {
    return ExecuteCommand(*C, FailingCommand);
  } else {
    const JobList *Jobs = cast<JobList>(&J);
    for (JobList::const_iterator
           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
      if (int Res = ExecuteJob(**it, FailingCommand))
        return Res;
    return 0;
  }
}

void Compilation::initCompilationForDiagnostics(void) {
  // Free actions and jobs.
  DeleteContainerPointers(Actions);
  Jobs.clear();

  // Clear temporary/results file lists.
  TempFiles.clear();
  ResultFiles.clear();

  // Remove any user specified output.  Claim any unclaimed arguments, so as
  // to avoid emitting warnings about unused args.
  OptSpecifier OutputOpts[] = { options::OPT_o, options::OPT_MD,
                                options::OPT_MMD };
  for (unsigned i = 0; i != sizeof(OutputOpts)/sizeof(OutputOpts[0]); ++i) {
    if (TranslatedArgs->hasArg(OutputOpts[i]))
      TranslatedArgs->eraseArg(OutputOpts[i]);
  }
  TranslatedArgs->ClaimAllArgs();

  // Redirect stdout/stderr to /dev/null.
  Redirects = new const llvm::sys::Path*[3]();
  Redirects[1] = new const llvm::sys::Path();
  Redirects[2] = new const llvm::sys::Path();
}

StringRef Compilation::getSysRoot(void) const {
  return getDriver().SysRoot;
}
<commit_msg>Canonicalize loop.<commit_after>//===--- Compilation.cpp - Compilation Task Implementation ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Compilation.h"

#include "clang/Driver/Action.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
#include <sys/stat.h>
#include <errno.h>

using namespace clang::driver;
using namespace clang;

Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
                         InputArgList *_Args, DerivedArgList *_TranslatedArgs)
  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
    TranslatedArgs(_TranslatedArgs), Redirects(0) {
}

Compilation::~Compilation() {
  delete TranslatedArgs;
  delete Args;

  // Free any derived arg lists.
  for (llvm::DenseMap<std::pair<const ToolChain*, const char*>,
                      DerivedArgList*>::iterator it = TCArgs.begin(),
         ie = TCArgs.end(); it != ie; ++it)
    if (it->second != TranslatedArgs)
      delete it->second;

  // Free the actions, if built.
  for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
       it != ie; ++it)
    delete *it;

  // Free redirections of stdout/stderr.
  if (Redirects) {
    delete Redirects[1];
    delete Redirects[2];
    delete [] Redirects;
  }
}

const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC,
                                                       const char *BoundArch) {
  if (!TC)
    TC = &DefaultToolChain;

  DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)];
  if (!Entry) {
    Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch);
    if (!Entry)
      Entry = TranslatedArgs;
  }

  return *Entry;
}

void Compilation::PrintJob(raw_ostream &OS, const Job &J,
                           const char *Terminator, bool Quote) const {
  if (const Command *C = dyn_cast<Command>(&J)) {
    OS << " \"" << C->getExecutable() << '"';
    for (ArgStringList::const_iterator it = C->getArguments().begin(),
           ie = C->getArguments().end(); it != ie; ++it) {
      OS << ' ';
      if (!Quote && !std::strpbrk(*it, " \"\\$")) {
        OS << *it;
        continue;
      }

      // Quote the argument and escape shell special characters; this isn't
      // really complete but is good enough.
      OS << '"';
      for (const char *s = *it; *s; ++s) {
        if (*s == '"' || *s == '\\' || *s == '$')
          OS << '\\';
        OS << *s;
      }
      OS << '"';
    }
    OS << Terminator;
  } else {
    const JobList *Jobs = cast<JobList>(&J);
    for (JobList::const_iterator
           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
      PrintJob(OS, **it, Terminator, Quote);
  }
}

bool Compilation::CleanupFileList(const ArgStringList &Files,
                                  bool IssueErrors) const {
  bool Success = true;

  for (ArgStringList::const_iterator
         it = Files.begin(), ie = Files.end(); it != ie; ++it) {

    llvm::sys::Path P(*it);
    std::string Error;

    // Don't try to remove files which we don't have write access to (but may be
    // able to remove). Underlying tools may have intentionally not overwritten
    // them.
    if (!P.canWrite())
      continue;

    if (P.eraseFromDisk(false, &Error)) {
      // Failure is only failure if the file exists and is "regular". There is
      // a race condition here due to the limited interface of
      // llvm::sys::Path, we want to know if the removal gave ENOENT.

      // FIXME: Grumble, P.exists() is broken. PR3837.
      struct stat buf;
      if (::stat(P.c_str(), &buf) == 0 ? (buf.st_mode & S_IFMT) == S_IFREG :
                                         (errno != ENOENT)) {
        if (IssueErrors)
          getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
            << Error;
        Success = false;
      }
    }
  }

  return Success;
}

int Compilation::ExecuteCommand(const Command &C,
                                const Command *&FailingCommand) const {
  llvm::sys::Path Prog(C.getExecutable());
  const char **Argv = new const char*[C.getArguments().size() + 2];
  Argv[0] = C.getExecutable();
  std::copy(C.getArguments().begin(), C.getArguments().end(), Argv+1);
  Argv[C.getArguments().size() + 1] = 0;

  if ((getDriver().CCCEcho || getDriver().CCPrintOptions ||
       getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) {
    raw_ostream *OS = &llvm::errs();

    // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the
    // output stream.
    if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) {
      std::string Error;
      OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename,
                                    Error,
                                    llvm::raw_fd_ostream::F_Append);
      if (!Error.empty()) {
        getDriver().Diag(clang::diag::err_drv_cc_print_options_failure)
          << Error;
        FailingCommand = &C;
        delete OS;
        return 1;
      }
    }

    if (getDriver().CCPrintOptions)
      *OS << "[Logging clang options]";

    PrintJob(*OS, C, "\n", /*Quote=*/getDriver().CCPrintOptions);

    if (OS != &llvm::errs())
      delete OS;
  }

  std::string Error;
  int Res =
    llvm::sys::Program::ExecuteAndWait(Prog, Argv,
                                       /*env*/0, Redirects,
                                       /*secondsToWait*/0, /*memoryLimit*/0,
                                       &Error);
  if (!Error.empty()) {
    assert(Res && "Error string set with 0 result code!");
    getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
  }

  if (Res)
    FailingCommand = &C;

  delete[] Argv;
  return Res;
}

int Compilation::ExecuteJob(const Job &J,
                            const Command *&FailingCommand) const {
  if (const Command *C = dyn_cast<Command>(&J)) {
    return ExecuteCommand(*C, FailingCommand);
  } else {
    const JobList *Jobs = cast<JobList>(&J);
    for (JobList::const_iterator
           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
      if (int Res = ExecuteJob(**it, FailingCommand))
        return Res;
    return 0;
  }
}

void Compilation::initCompilationForDiagnostics(void) {
  // Free actions and jobs.
  DeleteContainerPointers(Actions);
  Jobs.clear();

  // Clear temporary/results file lists.
  TempFiles.clear();
  ResultFiles.clear();

  // Remove any user specified output.  Claim any unclaimed arguments, so as
  // to avoid emitting warnings about unused args.
  OptSpecifier OutputOpts[] = { options::OPT_o, options::OPT_MD,
                                options::OPT_MMD };
  for (unsigned i = 0, e = sizeof(OutputOpts)/sizeof(OutputOpts[0]); i != e;
       ++i) {
    if (TranslatedArgs->hasArg(OutputOpts[i]))
      TranslatedArgs->eraseArg(OutputOpts[i]);
  }
  TranslatedArgs->ClaimAllArgs();

  // Redirect stdout/stderr to /dev/null.
  Redirects = new const llvm::sys::Path*[3]();
  Redirects[1] = new const llvm::sys::Path();
  Redirects[2] = new const llvm::sys::Path();
}

StringRef Compilation::getSysRoot(void) const {
  return getDriver().SysRoot;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012, Broadcom Europe Ltd
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 copyright holder 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 HOLDER 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.
 */

//
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bcm_host.h"

extern "C" {
    #include "ilclient.h"
}

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include "mouse.h"

using boost::asio::ip::tcp;
using namespace std;

enum {
    max_length = 1024
};

static int start_decode_video(char* host, char* port) {
    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
    OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
    COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *video_render = NULL, *clock = NULL;
    COMPONENT_T * list[5];
    TUNNEL_T tunnel[4];
    ILCLIENT_T *client;
    int status = 0;
    unsigned int data_len = 0;

    memset(list, 0, sizeof (list));
    memset(tunnel, 0, sizeof (tunnel));

    if ((client = ilclient_init()) == NULL) {
        return -3;
    }

    if (OMX_Init() != OMX_ErrorNone) {
        ilclient_destroy(client);
        return -4;
    }

    // create video_decode
    if (ilclient_create_component(client, &video_decode, "video_decode", (ILCLIENT_CREATE_FLAGS_T)(ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0)
        status = -14;
    list[0] = video_decode;

    // create video_render
    if (status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
        status = -14;
    list[1] = video_render;

    // create clock
    if (status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0)
        status = -14;
    list[2] = clock;

    memset(&cstate, 0, sizeof (cstate));
    cstate.nSize = sizeof (cstate);
    cstate.nVersion.nVersion = OMX_VERSION;
    cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
    cstate.nWaitMask = 1;
    if (clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone)
        status = -13;

    // create video_scheduler
    if (status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0)
        status = -14;
    list[3] = video_scheduler;

    set_tunnel(tunnel, video_decode, 131, video_scheduler, 10);
    set_tunnel(tunnel + 1, video_scheduler, 11, video_render, 90);
    set_tunnel(tunnel + 2, clock, 80, video_scheduler, 12);

    // setup clock tunnel first
    if (status == 0 && ilclient_setup_tunnel(tunnel + 2, 0, 0) != 0)
        status = -15;
    else
        ilclient_change_component_state(clock, OMX_StateExecuting);

    if (status == 0)
        ilclient_change_component_state(video_decode, OMX_StateIdle);

    memset(&format, 0, sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE));
    format.nSize = sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE);
    format.nVersion.nVersion = OMX_VERSION;
    format.nPortIndex = 130;
    format.eCompressionFormat = OMX_VIDEO_CodingAVC;

    if (status == 0 &&
        OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone &&
        ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) {
        OMX_BUFFERHEADERTYPE *buf;
        int port_settings_changed = 0;
        int first_packet = 1;

        ilclient_change_component_state(video_decode, OMX_StateExecuting);

        boost::asio::io_service io_service;

        tcp::resolver resolver(io_service);
        tcp::resolver::query query(tcp::v4(), host, port);
        tcp::resolver::iterator iterator = resolver.resolve(query);

        tcp::socket s(io_service);
        boost::asio::connect(s, iterator);
        s.set_option(tcp::no_delay(true));

        boost::asio::write(s, boost::asio::buffer("a", 2));

        while ((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) {
            // feed data and wait until we get port settings changed
            unsigned char *dest = buf->pBuffer;

            int bufferSize = min(buf->nAllocLen, 10 * 1024);
            data_len += boost::asio::read(s, boost::asio::buffer(dest, bufferSize));

            if (port_settings_changed == 0 &&
                ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) ||
                (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1,
                ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) {
                port_settings_changed = 1;

                if (ilclient_setup_tunnel(tunnel, 0, 0) != 0) {
                    status = -7;
                    break;
                }

                ilclient_change_component_state(video_scheduler, OMX_StateExecuting);

                // now setup tunnel to video_render
                if (ilclient_setup_tunnel(tunnel + 1, 0, 1000) != 0) {
                    status = -12;
                    break;
                }

                ilclient_change_component_state(video_render, OMX_StateExecuting);
            }
            if (!data_len)
                break;

            buf->nFilledLen = data_len;
            data_len = 0;

            buf->nOffset = 0;
            if (first_packet) {
                buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
                first_packet = 0;
            } else
                buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;

            if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) {
                status = -6;
                break;
            }
        }

        buf->nFilledLen = 0;
        buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;

        if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone)
            status = -20;

        // wait for EOS from render
        ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,
            ILCLIENT_BUFFER_FLAG_EOS, 10000);

        // need to flush the renderer to allow video_decode to disable its input port
        ilclient_flush_tunnels(tunnel, 0);

        ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);
    }

    ilclient_disable_tunnel(tunnel);
    ilclient_disable_tunnel(tunnel + 1);
    ilclient_disable_tunnel(tunnel + 2);
    ilclient_teardown_tunnels(tunnel);

    ilclient_state_transition(list, OMX_StateIdle);
    ilclient_state_transition(list, OMX_StateLoaded);

    ilclient_cleanup_components(list);

    OMX_Deinit();

    ilclient_destroy(client);
    return status;
}

char *key_name[] = {
    "first",
    "second (or middle)",
    "third"
};

struct SendStruct {
    int type;
    int x;
    int y;
    int button;
    int keycode;
};

static void FillRect( void *image, int pitch, int x, int y, int w, int h, int val )
{
    int         row;
    int         col;

    uint32_t *line = (uint32_t *)image + y * (pitch>>2) + x;

    for ( row = 0; row < h; row++ )
    {
        for ( col = 0; col < w; col++ )
        {
            line[col] = val;
        }
        line += (pitch>>2);
    }
}

void mouseKeyboardThread(char* host, char* port)
{
    boost::asio::io_service io_service;

    tcp::resolver resolver(io_service);
    tcp::resolver::query query(tcp::v4(), host, port);
    tcp::resolver::iterator iterator = resolver.resolve(query);

    tcp::socket s(io_service);
    boost::asio::connect(s, iterator);
	s.set_option(tcp::no_delay(true));

    boost::asio::write(s, boost::asio::buffer("b", 2));

    Display *display;
    XEvent xevent;
    Window window;

    if( (display = XOpenDisplay(NULL)) == NULL )
        return;

    window = DefaultRootWindow(display);
    XAllowEvents(display, AsyncBoth, CurrentTime);

    XGrabPointer(display,
                 window,
                 1,
                 PointerMotionMask | ButtonPressMask | ButtonReleaseMask ,
                 GrabModeAsync,
                 GrabModeAsync,
                 None,
                 None,
                 CurrentTime);

    XGrabKeyboard(display, window, false, GrabModeAsync, GrabModeAsync, CurrentTime);

    Mouse mouse;

    while(1) {
        XNextEvent(display, &xevent);
        int mykey;
        SendStruct send;
        SendStruct* sendPtr = &send;
        switch (xevent.type) {
            case MotionNotify:
                send.type = 0;
                send.x = xevent.xmotion.x_root;
                send.y = xevent.xmotion.y_root;

                mouse.move(send.x, send.y);

                //printf("Mouse move      : [%d, %d]\n", xevent.xmotion.x_root, xevent.xmotion.y_root);
                break;
            case ButtonPress:
                send.type = 1;
                send.button = xevent.xbutton.button;
                //printf("Button pressed  : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
            case ButtonRelease:
                send.type = 2;
                send.button = xevent.xbutton.button;
                //printf("Button released : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
            case KeyPress:
                mykey = XKeycodeToKeysym(display, xevent.xkey.keycode, 0);
                //printf("KeyPress : %s, %d\n", XKeysymToString(mykey), mykey);

                send.type = 3;
                send.keycode = mykey;

                if (xevent.xkey.keycode == 27 || xevent.xkey.keycode == 9) {
                    return;
                }
                break;
            case KeyRelease:
                mykey = XKeycodeToKeysym(display, xevent.xkey.keycode, 0);

                send.type = 4;
                send.keycode = mykey;

                //printf("KeyRelease : %s, %d\n", XKeysymToString(mykey), mykey);
                break;
        }
        boost::asio::write(s, boost::asio::buffer(sendPtr, sizeof(SendStruct)));
    }

    mouse.close();
}

int main(int argc, char **argv) {
    std::cout << "Version 0.9" << endl;

    if (argc != 3)
    {
      std::cerr << "Usage: ./client <host> <port>\n";
      return 1;
    }

    char* host = argv[1];
    char* port = argv[2];

    bcm_host_init();

    boost::thread t(&mouseKeyboardThread, host, port);
    start_decode_video(host, port);
    t.join();
}<commit_msg>update<commit_after>/*
Copyright (c) 2012, Broadcom Europe Ltd
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 copyright holder 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 HOLDER 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.
 */

//
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bcm_host.h"

extern "C" {
    #include "ilclient.h"
}

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include "mouse.h"

using boost::asio::ip::tcp;
using namespace std;

enum {
    max_length = 1024
};

static int start_decode_video(char* host, char* port) {
    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
    OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
    COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *video_render = NULL, *clock = NULL;
    COMPONENT_T * list[5];
    TUNNEL_T tunnel[4];
    ILCLIENT_T *client;
    int status = 0;
    unsigned int data_len = 0;

    memset(list, 0, sizeof (list));
    memset(tunnel, 0, sizeof (tunnel));

    if ((client = ilclient_init()) == NULL) {
        return -3;
    }

    if (OMX_Init() != OMX_ErrorNone) {
        ilclient_destroy(client);
        return -4;
    }

    // create video_decode
    if (ilclient_create_component(client, &video_decode, "video_decode", (ILCLIENT_CREATE_FLAGS_T)(ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0)
        status = -14;
    list[0] = video_decode;

    // create video_render
    if (status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
        status = -14;
    list[1] = video_render;

    // create clock
    if (status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0)
        status = -14;
    list[2] = clock;

    memset(&cstate, 0, sizeof (cstate));
    cstate.nSize = sizeof (cstate);
    cstate.nVersion.nVersion = OMX_VERSION;
    cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
    cstate.nWaitMask = 1;
    if (clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone)
        status = -13;

    // create video_scheduler
    if (status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0)
        status = -14;
    list[3] = video_scheduler;

    set_tunnel(tunnel, video_decode, 131, video_scheduler, 10);
    set_tunnel(tunnel + 1, video_scheduler, 11, video_render, 90);
    set_tunnel(tunnel + 2, clock, 80, video_scheduler, 12);

    // setup clock tunnel first
    if (status == 0 && ilclient_setup_tunnel(tunnel + 2, 0, 0) != 0)
        status = -15;
    else
        ilclient_change_component_state(clock, OMX_StateExecuting);

    if (status == 0)
        ilclient_change_component_state(video_decode, OMX_StateIdle);

    memset(&format, 0, sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE));
    format.nSize = sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE);
    format.nVersion.nVersion = OMX_VERSION;
    format.nPortIndex = 130;
    format.eCompressionFormat = OMX_VIDEO_CodingAVC;

    if (status == 0 &&
        OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone &&
        ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) {
        OMX_BUFFERHEADERTYPE *buf;
        int port_settings_changed = 0;
        int first_packet = 1;

        ilclient_change_component_state(video_decode, OMX_StateExecuting);

        boost::asio::io_service io_service;

        tcp::resolver resolver(io_service);
        tcp::resolver::query query(tcp::v4(), host, port);
        tcp::resolver::iterator iterator = resolver.resolve(query);

        tcp::socket s(io_service);
        boost::asio::connect(s, iterator);
        s.set_option(tcp::no_delay(true));

        boost::asio::write(s, boost::asio::buffer("a", 2));

        while ((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) {
            // feed data and wait until we get port settings changed
            unsigned char *dest = buf->pBuffer;

            int bufferSize = std::min((int)buf->nAllocLen, 10 * 1024);
            data_len += boost::asio::read(s, boost::asio::buffer(dest, bufferSize));

            if (port_settings_changed == 0 &&
                ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) ||
                (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1,
                ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) {
                port_settings_changed = 1;

                if (ilclient_setup_tunnel(tunnel, 0, 0) != 0) {
                    status = -7;
                    break;
                }

                ilclient_change_component_state(video_scheduler, OMX_StateExecuting);

                // now setup tunnel to video_render
                if (ilclient_setup_tunnel(tunnel + 1, 0, 1000) != 0) {
                    status = -12;
                    break;
                }

                ilclient_change_component_state(video_render, OMX_StateExecuting);
            }
            if (!data_len)
                break;

            buf->nFilledLen = data_len;
            data_len = 0;

            buf->nOffset = 0;
            if (first_packet) {
                buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
                first_packet = 0;
            } else
                buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;

            if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) {
                status = -6;
                break;
            }
        }

        buf->nFilledLen = 0;
        buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;

        if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone)
            status = -20;

        // wait for EOS from render
        ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,
            ILCLIENT_BUFFER_FLAG_EOS, 10000);

        // need to flush the renderer to allow video_decode to disable its input port
        ilclient_flush_tunnels(tunnel, 0);

        ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);
    }

    ilclient_disable_tunnel(tunnel);
    ilclient_disable_tunnel(tunnel + 1);
    ilclient_disable_tunnel(tunnel + 2);
    ilclient_teardown_tunnels(tunnel);

    ilclient_state_transition(list, OMX_StateIdle);
    ilclient_state_transition(list, OMX_StateLoaded);

    ilclient_cleanup_components(list);

    OMX_Deinit();

    ilclient_destroy(client);
    return status;
}

char *key_name[] = {
    "first",
    "second (or middle)",
    "third"
};

struct SendStruct {
    int type;
    int x;
    int y;
    int button;
    int keycode;
};

static void FillRect( void *image, int pitch, int x, int y, int w, int h, int val )
{
    int         row;
    int         col;

    uint32_t *line = (uint32_t *)image + y * (pitch>>2) + x;

    for ( row = 0; row < h; row++ )
    {
        for ( col = 0; col < w; col++ )
        {
            line[col] = val;
        }
        line += (pitch>>2);
    }
}

void mouseKeyboardThread(char* host, char* port)
{
    boost::asio::io_service io_service;

    tcp::resolver resolver(io_service);
    tcp::resolver::query query(tcp::v4(), host, port);
    tcp::resolver::iterator iterator = resolver.resolve(query);

    tcp::socket s(io_service);
    boost::asio::connect(s, iterator);
	s.set_option(tcp::no_delay(true));

    boost::asio::write(s, boost::asio::buffer("b", 2));

    Display *display;
    XEvent xevent;
    Window window;

    if( (display = XOpenDisplay(NULL)) == NULL )
        return;

    window = DefaultRootWindow(display);
    XAllowEvents(display, AsyncBoth, CurrentTime);

    XGrabPointer(display,
                 window,
                 1,
                 PointerMotionMask | ButtonPressMask | ButtonReleaseMask ,
                 GrabModeAsync,
                 GrabModeAsync,
                 None,
                 None,
                 CurrentTime);

    XGrabKeyboard(display, window, false, GrabModeAsync, GrabModeAsync, CurrentTime);

    Mouse mouse;

    while(1) {
        XNextEvent(display, &xevent);
        int mykey;
        SendStruct send;
        SendStruct* sendPtr = &send;
        switch (xevent.type) {
            case MotionNotify:
                send.type = 0;
                send.x = xevent.xmotion.x_root;
                send.y = xevent.xmotion.y_root;

                mouse.move(send.x, send.y);

                //printf("Mouse move      : [%d, %d]\n", xevent.xmotion.x_root, xevent.xmotion.y_root);
                break;
            case ButtonPress:
                send.type = 1;
                send.button = xevent.xbutton.button;
                //printf("Button pressed  : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
            case ButtonRelease:
                send.type = 2;
                send.button = xevent.xbutton.button;
                //printf("Button released : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
            case KeyPress:
                mykey = XKeycodeToKeysym(display, xevent.xkey.keycode, 0);
                //printf("KeyPress : %s, %d\n", XKeysymToString(mykey), mykey);

                send.type = 3;
                send.keycode = mykey;

                if (xevent.xkey.keycode == 27 || xevent.xkey.keycode == 9) {
                    return;
                }
                break;
            case KeyRelease:
                mykey = XKeycodeToKeysym(display, xevent.xkey.keycode, 0);

                send.type = 4;
                send.keycode = mykey;

                //printf("KeyRelease : %s, %d\n", XKeysymToString(mykey), mykey);
                break;
        }
        boost::asio::write(s, boost::asio::buffer(sendPtr, sizeof(SendStruct)));
    }

    mouse.close();
}

int main(int argc, char **argv) {
    std::cout << "Version 0.9" << endl;

    if (argc != 3)
    {
      std::cerr << "Usage: ./client <host> <port>\n";
      return 1;
    }

    char* host = argv[1];
    char* port = argv[2];

    bcm_host_init();

    boost::thread t(&mouseKeyboardThread, host, port);
    start_decode_video(host, port);
    t.join();
}<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	タイトル
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/format.hpp"
#include "scenes_base.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	タイトル・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class title {

		uint8_t		count_;

	public:
		//-------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-------------------------------------------------------------//
		title() { }

		//-------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-------------------------------------------------------------//
		void init()
		{
			count_ = 90;  // 1.5sec

			at_scenes_base().at_render().clear(0);
			at_scenes_base().at_render().line(0, 0, 480-1, 272-1,
				scenes_base::RENDER::COLOR::White);
			at_scenes_base().at_render().line(0, 480 - 1, 0, 272-1,
				scenes_base::RENDER::COLOR::White);
		}

		//-------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-------------------------------------------------------------//
		void service()
		{
			if(count_ > 0) {
				--count_;
			} else {
				change_scene(scenes_id::root_menu);
			}
		}
	};
}
<commit_msg>update: load title image<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	タイトル
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/format.hpp"
#include "scenes_base.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	タイトル・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class title {

		typedef scenes_base::RENDER RENDER;

		uint8_t		count_;
		bool		logo_;

	public:
		//-------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-------------------------------------------------------------//
		title() : count_(0), logo_(false) { }

		//-------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-------------------------------------------------------------//
		void init()
		{
			auto& render = at_scenes_base().at_render();

			count_ = 90;  // 1.5sec
			logo_ = false;

			render.clear(RENDER::COLOR::White);
		}

		//-------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-------------------------------------------------------------//
		void service()
		{
			if(count_ > 0) {
				--count_;
				if(!logo_ && fatfs_get_mount() != 0) {
					auto& bmp = at_scenes_base().at_bmp();
					utils::file_io fin;
					if(fin.open("HRC_logo_s.bmp", "rb")) {
						img::img_info ifo;
						if(bmp.info(fin, ifo)) {
							int16_t xo = (RENDER::width  - ifo.width) / 2;
							int16_t yo = (RENDER::height - ifo.height) / 2;
							bmp.set_draw_offset(xo, yo);
							logo_ = bmp.load(fin);
							if(logo_) count_ = 90;
						}
						fin.close();
					}
				}
			} else {
				change_scene(scenes_id::root_menu);
			}
		}
	};
}
<|endoftext|>


<commit_before>#include "Xmodem.h"

/**
 * Construct an Xmodem instance.
 *
 * @param serial port to use
 */
Xmodem::Xmodem(Stream& serial) {
#ifdef ARDUINO
  _serial = &serial;
#else
  _serial = *serial;
#endif // ifdef ARDUINO
}

/**
 * Send a file over the serial port.
 * @param file file to send
 */
int Xmodem::send(File* file) {
  _file = file;
  _packetNumber = 1;

  while (true) {
    int c = serialRead();
    if (c != -1) {
      Serial.print("got 0x");
      Serial.println(c, HEX);
      break;
    }
    delay(100);
  }

  int status = 0;
  while (true) {
    size_t bytesRead = readPacket();
    if (bytesRead > 0) {
      status = sendPacket();
      if (status < 0) {
        break;
      }
    }
    if (bytesRead < PACKET_SIZE) {
      break;
    }
  }
  serialWrite(EOT);
  delay(1);
  serialRead();
  return status;
}

/**
 * @internal
 *
 * Send the current packet over the serial port.
 * @return -1 if error
 */
int Xmodem::sendPacket() {
  serialWrite(STX);
  serialWrite(_packetNumber);
  serialWrite(255 - _packetNumber);
  serialWrite(_packet, PACKET_SIZE);
  serialWrite((_crc >> 8) & 0xff);
  serialWrite(_crc & 0xff);
  // Serial.println("block sent, waiting for ACK/NAK ");

  int c;
  while (true) {
    c = serialRead();
    if (c == NAK) {
      // Serial.println("got NAK, resending");
      delay(5);
      return sendPacket();
    }
    else if (c == ACK) {
      // Serial.println("got ACK, continuing");
      _packetNumber++;
      return 0;
    }
    else if (c == CAN) {
      // Serial.println("got CAN, stopping");
      return -1;
    }
    if (c != -1) {
      // Serial.print(" 0x");
      // Serial.println(c, HEX);
    }
    // Serial.print('.');
    delay(500);
  }
}

/**
 * Read current packet from current file. Pad the packet with PAD_CHAR if the
 * file has less than PACKET_SIZE bytes left to read.
 *
 * @return the number of bytes read from the file
 */
size_t Xmodem::readPacket() {
  // TODO pad after instead
  for (size_t i = 0; i < PACKET_SIZE; i++) {
    _packet[i] = PAD_CHAR;
  }

  size_t bytesRead = fileRead(_packet, PACKET_SIZE);
  // for (size_t i = bytesRead; i < PACKET_SIZE; i++) {
  //   _packet[i] = PAD_CHAR;
  // }

  _crc = crc_init();
  _crc = crc_update(_crc, _packet, PACKET_SIZE);
  _crc = crc_finalize(_crc);

  return bytesRead;
}

/**
 * @internal
 *
 * Read a block from a file.
 *
 * @param  buffer  buffer to hold data read from file
 * @param  count   number of bytes to read from file
 * @return         number of bytes actually read
 */
size_t Xmodem::fileRead(uint8_t *buffer, size_t count) {
#ifdef ARDUINO
  return _file->read(buffer, count);
#else
  return fread(buffer, 1, count, _file);
#endif // ifdef ARDUINO
}

/**
 * @internal
 *
 * Write a block of data to the serial port.
 *
 * @param  buffer data to write
 * @param  count  number of bytes to write
 * @return        number of bytes actually written
 */
size_t Xmodem::serialWrite(uint8_t *buffer, size_t count) {
#ifdef ARDUINO
  // Serial.println("writing block");

  uint8_t *current = buffer;
  int remaining = count;
  int batchSize = 128;
  size_t written = 0;
  while (remaining > 0) {
    int currentBatchSize = min(batchSize, remaining);
    written += _serial->write(current, currentBatchSize);
    current += currentBatchSize;
    remaining -= currentBatchSize;
  }
  return written;

#else
  return write(_serial, buffer, count);
#endif // ifdef ARDUINO
}

/**
 * @internal
 *
 * Write a byte to the serial port.
 *
 * @param  c byte to write
 * @return c if byte written, or -1 if error
 */
int Xmodem::serialWrite(uint8_t c) {
#ifdef ARDUINO
  // Serial.print("write: ");
  // Serial.println(c, HEX);
  return _serial->write(c);
#else
  return write(_serial, &c, 1);
#endif // ifdef ARDUINO
}

/**
 * @internal
 *
 * Read a byte from the serial port.
 *
 * @return byte read, or -1 no data is available to read
 */
int Xmodem::serialRead() {
#ifdef ARDUINO
  int c = _serial->read();
  // Serial.print("read: ");
  // Serial.println(c, HEX);
  return c;
#else
  uint8_t c;
  size_t bytesRead = read(_serial, &c, 1);
  fprintf(stderr, "read: 0x%02x\n", c);
  if (bytesRead == 0) {
    return -1;
  }
  else {
    return (int)c;
  }
#endif // ifdef ARDUINO
}
<commit_msg>cleanup for merge to main<commit_after>#include "Xmodem.h"

/**
 * Construct an Xmodem instance.
 *
 * @param serial port to use
 */
Xmodem::Xmodem(Stream& serial) {
#ifdef ARDUINO
  _serial = &serial;
#else
  _serial = *serial;
#endif // ifdef ARDUINO
}

/**
 * Send a file over the serial port.
 * @param file file to send
 */
int Xmodem::send(File* file) {
  _file = file;
  _packetNumber = 1;

  while (true) {
    int c = serialRead();
    if (c != -1) {
      break;
    }
    delay(100);
  }

  int status = 0;
  while (true) {
    size_t bytesRead = readPacket();
    if (bytesRead > 0) {
      status = sendPacket();
      if (status < 0) {
        break;
      }
    }
    if (bytesRead < PACKET_SIZE) {
      break;
    }
  }
  serialWrite(EOT);
  delay(1);
  serialRead();
  return status;
}

/**
 * @internal
 *
 * Send the current packet over the serial port and handle response.
 *
 *  + ACK - r
 * @return -1 if error
 */
int Xmodem::sendPacket() {
  serialWrite(STX);
  serialWrite(_packetNumber);
  serialWrite(255 - _packetNumber);
  serialWrite(_packet, PACKET_SIZE);
  serialWrite((_crc >> 8) & 0xff);
  serialWrite(_crc & 0xff);

  int c;
  while (true) {
    c = serialRead();
    if (c == NAK) {
      delay(5);
      return sendPacket();
    }
    else if (c == ACK) {
      _packetNumber++;
      return 0;
    }
    else if (c == CAN) {
      return -1;
    }
    delay(500);
  }
}

/**
 * Read current packet from current file. Pad the packet with PAD_CHAR if the
 * file has less than PACKET_SIZE bytes left to read.
 *
 * @return the number of bytes read from the file
 */
size_t Xmodem::readPacket() {
  size_t bytesRead = fileRead(_packet, PACKET_SIZE);
  for (size_t i = bytesRead; i < PACKET_SIZE; i++) {
    _packet[i] = PAD_CHAR;
  }

  _crc = crc_init();
  _crc = crc_update(_crc, _packet, PACKET_SIZE);
  _crc = crc_finalize(_crc);

  return bytesRead;
}

/**
 * @internal
 *
 * Read a block from a file.
 *
 * @param  buffer  buffer to hold data read from file
 * @param  count   number of bytes to read from file
 * @return         number of bytes actually read
 */
size_t Xmodem::fileRead(uint8_t *buffer, size_t count) {
#ifdef ARDUINO
  return _file->read(buffer, count);
#else
  return fread(buffer, 1, count, _file);
#endif // ifdef ARDUINO
}

/**
 * @internal
 *
 * Write a block of data to the serial port.
 *
 * @param  buffer data to write
 * @param  count  number of bytes to write
 * @return        number of bytes actually written
 */
size_t Xmodem::serialWrite(uint8_t *buffer, size_t count) {
#ifdef ARDUINO
  // Serial.println("writing block");

  uint8_t *current = buffer;
  int remaining = count;
  int batchSize = 128;
  size_t written = 0;
  while (remaining > 0) {
    int currentBatchSize = min(batchSize, remaining);
    written += _serial->write(current, currentBatchSize);
    current += currentBatchSize;
    remaining -= currentBatchSize;
  }
  return written;

#else
  return write(_serial, buffer, count);
#endif // ifdef ARDUINO
}

/**
 * @internal
 *
 * Write a byte to the serial port.
 *
 * @param  c byte to write
 * @return c if byte written, or -1 if error
 */
int Xmodem::serialWrite(uint8_t c) {
#ifdef ARDUINO
  return _serial->write(c);
#else
  return write(_serial, &c, 1);
#endif // ifdef ARDUINO
}

/**
 * @internal
 *
 * Read a byte from the serial port.
 *
 * @return byte read, or -1 no data is available to read
 */
int Xmodem::serialRead() {
#ifdef ARDUINO
  return _serial->read();
#else
  uint8_t c;
  size_t bytesRead = read(_serial, &c, 1);
  if (bytesRead == 0) {
    return -1;
  }
  else {
    return (int)c;
  }
#endif // ifdef ARDUINO
}
<|endoftext|>


<commit_before>#include "libtorrent/natpmp.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/connection_queue.hpp"
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/intrusive_ptr.hpp>
#include <iostream>

using namespace libtorrent;

void callback(int mapping, address extip, int port, error_code const& err)
{
	std::cerr
		<< "mapping: " << mapping
		<< ", port: " << port
		<< ", external-IP: " << print_address(extip)
		<< ", error: \"" << err.message() << "\"\n";
}

void log_callback(char const* line)
{
	std::cerr << line << std::endl;
}

int main(int argc, char* argv[])
{
	io_service ios;
	std::string user_agent = "test agent";

	if (argc != 3)
	{
		std::cerr << "usage: " << argv[0] << " tcp-port udp-port" << std::endl;
		return 1;
	}

	connection_queue cc(ios);
	boost::intrusive_ptr<natpmp> natpmp_handler = new natpmp(ios, address_v4()
		, &callback, &log_callback);

	deadline_timer timer(ios);

	int tcp_map = natpmp_handler->add_mapping(natpmp::tcp, atoi(argv[1]), atoi(argv[1]));
	int udp_map = natpmp_handler->add_mapping(natpmp::udp, atoi(argv[2]), atoi(argv[2]));

	error_code ec;
	timer.expires_from_now(seconds(2), ec);
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));
	std::cerr << "mapping ports TCP: " << argv[1]
		<< " UDP: " << argv[2] << std::endl;

	ios.reset();
	ios.run(ec);
	timer.expires_from_now(seconds(2), ec);
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));
	std::cerr << "removing mapping " << tcp_map << std::endl;
	natpmp_handler->delete_mapping(tcp_map);

	ios.reset();
	ios.run(ec);
	std::cerr << "removing mappings" << std::endl;
	natpmp_handler->close();

	ios.reset();
	ios.run(ec);
	std::cerr << "closing" << std::endl;
}

<commit_msg>build fix for test_natpmp<commit_after>#include "libtorrent/natpmp.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/socket_io.hpp"
#include "libtorrent/connection_queue.hpp"
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/intrusive_ptr.hpp>
#include <iostream>

using namespace libtorrent;

void callback(int mapping, address extip, int port, error_code const& err)
{
	std::cerr
		<< "mapping: " << mapping
		<< ", port: " << port
		<< ", external-IP: " << print_address(extip)
		<< ", error: \"" << err.message() << "\"\n";
}

void log_callback(char const* line)
{
	std::cerr << line << std::endl;
}

int main(int argc, char* argv[])
{
	io_service ios;
	std::string user_agent = "test agent";

	if (argc != 3)
	{
		std::cerr << "usage: " << argv[0] << " tcp-port udp-port" << std::endl;
		return 1;
	}

	connection_queue cc(ios);
	boost::intrusive_ptr<natpmp> natpmp_handler = new natpmp(ios, address_v4()
		, &callback, &log_callback);

	deadline_timer timer(ios);

	int tcp_map = natpmp_handler->add_mapping(natpmp::tcp, atoi(argv[1]), atoi(argv[1]));
	int udp_map = natpmp_handler->add_mapping(natpmp::udp, atoi(argv[2]), atoi(argv[2]));

	error_code ec;
	timer.expires_from_now(seconds(2), ec);
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));
	std::cerr << "mapping ports TCP: " << argv[1]
		<< " UDP: " << argv[2] << std::endl;

	ios.reset();
	ios.run(ec);
	timer.expires_from_now(seconds(2), ec);
	timer.async_wait(boost::bind(&io_service::stop, boost::ref(ios)));
	std::cerr << "removing mapping " << tcp_map << std::endl;
	natpmp_handler->delete_mapping(tcp_map);

	ios.reset();
	ios.run(ec);
	std::cerr << "removing mappings" << std::endl;
	natpmp_handler->close();

	ios.reset();
	ios.run(ec);
	std::cerr << "closing" << std::endl;
}

<|endoftext|>