<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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 <libtorrent/alert.hpp>
#include <libtorrent/alert_types.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

extern char const* alert_doc;
extern char const* alert_msg_doc;
extern char const* alert_severity_doc;
extern char const* torrent_alert_doc;
extern char const* tracker_alert_doc;
extern char const* tracker_error_alert_doc;
extern char const* tracker_warning_alert_doc;
extern char const* tracker_reply_alert_doc;
extern char const* tracker_announce_alert_doc;
extern char const* hash_failed_alert_doc;
extern char const* peer_ban_alert_doc;
extern char const* peer_error_alert_doc;
extern char const* invalid_request_alert_doc;
extern char const* peer_request_doc;
extern char const* torrent_finished_alert_doc;
extern char const* piece_finished_alert_doc;
extern char const* block_finished_alert_doc;
extern char const* block_downloading_alert_doc;
extern char const* storage_moved_alert_doc;
extern char const* torrent_deleted_alert_doc;
extern char const* torrent_paused_alert_doc;
extern char const* torrent_checked_alert_doc;
extern char const* url_seed_alert_doc;
extern char const* file_error_alert_doc;
extern char const* metadata_failed_alert_doc;
extern char const* metadata_received_alert_doc;
extern char const* listen_failed_alert_doc;
extern char const* listen_succeeded_alert_doc;
extern char const* portmap_error_alert_doc;
extern char const* portmap_alert_doc;
extern char const* fastresume_rejected_alert_doc;
extern char const* peer_blocked_alert_doc;
extern char const* scrape_reply_alert_doc;
extern char const* scrape_failed_alert_doc;
extern char const* udp_error_alert_doc;
extern char const* external_ip_alert_doc;
extern char const* save_resume_data_alert_doc;

void bind_alert()
{
    using boost::noncopyable;

    {
        scope alert_scope = class_<alert, noncopyable>("alert", alert_doc, no_init)
            .def("message", &alert::message, alert_msg_doc)
            .def("what", &alert::what)
            .def("category", &alert::category)
            .def("severity", &alert::severity, alert_severity_doc)
            .def("__str__", &alert::message, alert_msg_doc)
            ;

        enum_<alert::severity_t>("severity_levels")
            .value("debug", alert::debug)
            .value("info", alert::info)
            .value("warning", alert::warning)
            .value("critical", alert::critical)
            .value("fatal", alert::fatal)
            .value("none", alert::none)
            ;

        enum_<alert::category_t>("category_t")
            .value("error_notification", alert::error_notification)
            .value("peer_notification", alert::peer_notification)
            .value("port_mapping_notification", alert::port_mapping_notification)
            .value("storage_notification", alert::storage_notification)
            .value("tracker_notification", alert::tracker_notification)
            .value("debug_notification", alert::debug_notification)
            .value("status_notification", alert::status_notification)
            .value("progress_notification", alert::progress_notification)
            .value("ip_block_notification", alert::ip_block_notification)
            .value("all_categories", alert::all_categories)
            ;
    }

    class_<torrent_alert, bases<alert>, noncopyable>(
        "torrent_alert", torrent_alert_doc, no_init
    )
        .def_readonly("handle", &torrent_alert::handle)
        ;

    class_<tracker_alert, bases<torrent_alert>, noncopyable>(
        "tracker_alert", tracker_alert_doc, no_init
    )
        .def_readonly("url", &tracker_alert::url)
        ;

    class_<peer_alert, bases<torrent_alert>, noncopyable>(
        "peer_alert", no_init
    )
        .def_readonly("ip", &peer_alert::ip)
        .def_readonly("pid", &peer_alert::pid)
    ;
    class_<tracker_error_alert, bases<tracker_alert>, noncopyable>(
        "tracker_error_alert", tracker_error_alert_doc, no_init
    )
        .def_readonly("times_in_row", &tracker_error_alert::times_in_row)
        .def_readonly("status_code", &tracker_error_alert::status_code)
        ;

    class_<tracker_warning_alert, bases<tracker_alert>, noncopyable>(
        "tracker_warning_alert", tracker_warning_alert_doc, no_init
    );

    class_<tracker_reply_alert, bases<tracker_alert>, noncopyable>(
        "tracker_reply_alert", tracker_reply_alert_doc, no_init
    )
        .def_readonly("num_peers", &tracker_reply_alert::num_peers)
        ;

    class_<tracker_announce_alert, bases<tracker_alert>, noncopyable>(
        "tracker_announce_alert", tracker_announce_alert_doc, no_init
    );

    class_<hash_failed_alert, bases<torrent_alert>, noncopyable>(
        "hash_failed_alert", hash_failed_alert_doc, no_init
    )
        .def_readonly("piece_index", &hash_failed_alert::piece_index)
        ;

    class_<peer_ban_alert, bases<peer_alert>, noncopyable>(
        "peer_ban_alert", peer_ban_alert_doc, no_init
    );

    class_<peer_error_alert, bases<peer_alert>, noncopyable>(
        "peer_error_alert", peer_error_alert_doc, no_init
    );

    class_<invalid_request_alert, bases<peer_alert>, noncopyable>(
        "invalid_request_alert", invalid_request_alert_doc, no_init
    )
        .def_readonly("request", &invalid_request_alert::request)
        ;

    class_<peer_request>("peer_request", peer_request_doc)
        .def_readonly("piece", &peer_request::piece)
        .def_readonly("start", &peer_request::start)
        .def_readonly("length", &peer_request::length)
        .def(self == self)
        ;

    class_<torrent_finished_alert, bases<torrent_alert>, noncopyable>(
        "torrent_finished_alert", torrent_finished_alert_doc, no_init
    );

    class_<piece_finished_alert, bases<torrent_alert>, noncopyable>(
        "piece_finished_alert", piece_finished_alert_doc, no_init
    )
        .def_readonly("piece_index", &piece_finished_alert::piece_index)
        ;

    class_<block_finished_alert, bases<peer_alert>, noncopyable>(
        "block_finished_alert", block_finished_alert_doc, no_init
    )
        .def_readonly("block_index", &block_finished_alert::block_index)
        .def_readonly("piece_index", &block_finished_alert::piece_index)
        ;

    class_<block_downloading_alert, bases<peer_alert>, noncopyable>(
        "block_downloading_alert", block_downloading_alert_doc, no_init
    )
        .def_readonly("peer_speedmsg", &block_downloading_alert::peer_speedmsg)
        .def_readonly("block_index", &block_downloading_alert::block_index)
        .def_readonly("piece_index", &block_downloading_alert::piece_index)
        ;

    class_<storage_moved_alert, bases<torrent_alert>, noncopyable>(
        "storage_moved_alert", storage_moved_alert_doc, no_init
    );

    class_<torrent_deleted_alert, bases<torrent_alert>, noncopyable>(
        "torrent_deleted_alert", torrent_deleted_alert_doc, no_init
    );

    class_<torrent_paused_alert, bases<torrent_alert>, noncopyable>(
        "torrent_paused_alert", torrent_paused_alert_doc, no_init
    );

    class_<torrent_checked_alert, bases<torrent_alert>, noncopyable>(
        "torrent_checked_alert", torrent_checked_alert_doc, no_init
    );

    class_<url_seed_alert, bases<torrent_alert>, noncopyable>(
        "url_seed_alert", url_seed_alert_doc, no_init
    )
        .def_readonly("url", &url_seed_alert::url)
        ;

    class_<file_error_alert, bases<torrent_alert>, noncopyable>(
        "file_error_alert", file_error_alert_doc, no_init
    )
        .def_readonly("file", &file_error_alert::file)
        ;

    class_<metadata_failed_alert, bases<torrent_alert>, noncopyable>(
        "metadata_failed_alert", metadata_failed_alert_doc, no_init
    );

    class_<metadata_received_alert, bases<torrent_alert>, noncopyable>(
        "metadata_received_alert", metadata_received_alert_doc, no_init
    );

    class_<listen_failed_alert, bases<alert>, noncopyable>(
        "listen_failed_alert", listen_failed_alert_doc, no_init
    );

    class_<listen_succeeded_alert, bases<alert>, noncopyable>(
        "listen_succeeded_alert", listen_succeeded_alert_doc, no_init
    )
        .def_readonly("endpoint", &listen_succeeded_alert::endpoint)
        ;

    class_<portmap_error_alert, bases<alert>, noncopyable>(
        "portmap_error_alert", portmap_error_alert_doc, no_init
    )
        .def_readonly("mapping", &portmap_error_alert::mapping)
        .def_readonly("type", &portmap_error_alert::type)
        ;

    class_<portmap_alert, bases<alert>, noncopyable>(
        "portmap_alert", portmap_alert_doc, no_init
    )
        .def_readonly("mapping", &portmap_alert::mapping)
        .def_readonly("external_port", &portmap_alert::external_port)
        .def_readonly("type", &portmap_alert::type)
        ;

    class_<fastresume_rejected_alert, bases<torrent_alert>, noncopyable>(
        "fastresume_rejected_alert", fastresume_rejected_alert_doc, no_init
    );

    class_<peer_blocked_alert, bases<alert>, noncopyable>(
        "peer_blocked_alert", peer_blocked_alert_doc, no_init
    )
        .def_readonly("ip", &peer_blocked_alert::ip)
        ;

    class_<scrape_reply_alert, bases<tracker_alert>, noncopyable>(
        "scrape_reply_alert", scrape_reply_alert_doc, no_init
    )
        .def_readonly("incomplete", &scrape_reply_alert::incomplete)
        .def_readonly("complete", &scrape_reply_alert::complete)
        ;

    class_<scrape_failed_alert, bases<tracker_alert>, noncopyable>(
        "scrape_failed_alert", scrape_failed_alert_doc, no_init
    );

    class_<udp_error_alert, bases<alert>, noncopyable>(
        "udp_error_alert", udp_error_alert_doc, no_init
    )
        .def_readonly("endpoint", &udp_error_alert::endpoint)
        ;

    class_<external_ip_alert, bases<alert>, noncopyable>(
        "external_ip_alert", external_ip_alert_doc, no_init
    )
        .def_readonly("external_address", &external_ip_alert::external_address)
        ;

    class_<save_resume_data_alert, bases<torrent_alert>, noncopyable>(
        "save_resume_data_alert", save_resume_data_alert_doc, no_init
    )
        .def_readonly("resume_data", &save_resume_data_alert::resume_data)
        ;

    class_<file_renamed_alert, bases<torrent_alert>, noncopyable>(
        "file_renamed_alert", no_init
    )
        .def_readonly("name", &file_renamed_alert::name)
        ;

    class_<file_rename_failed_alert, bases<torrent_alert>, noncopyable>(
        "file_rename_failed_alert", no_init
    )
        .def_readonly("index", &file_rename_failed_alert::index)
        ;

    class_<torrent_resumed_alert, bases<torrent_alert>, noncopyable>(
        "torrent_resumed_alert", no_init
	);

	class_<state_changed_alert, bases<torrent_alert>, noncopyable>(
	    "state_changed_alert", no_init
	)
	    .def_readonly("state", &state_changed_alert::state)
	    ;

	class_<dht_reply_alert, bases<tracker_alert>, noncopyable>(
	    "dht_reply_alert", no_init
	)
	    .def_readonly("num_peers", &dht_reply_alert::num_peers)
	    ;

	class_<peer_unsnubbed_alert, bases<peer_alert>, noncopyable>(
	    "peer_unsnubbed_alert", no_init
	);

	class_<peer_snubbed_alert, bases<peer_alert>, noncopyable>(
	    "peer_snubbed_alert", no_init
	);

    class_<peer_connect_alert, bases<peer_alert>, noncopyable>(
        "peer_connect_alert", no_init
    );

    class_<peer_disconnected_alert, bases<peer_alert>, noncopyable>(
        "peer_disconnected_alert", no_init
    );

    class_<request_dropped_alert, bases<peer_alert>, noncopyable>(
        "request_dropped_alert", no_init
    )
        .def_readonly("block_index", &request_dropped_alert::block_index)
        .def_readonly("piece_index", &request_dropped_alert::piece_index)
    ;

    class_<block_timeout_alert, bases<peer_alert>, noncopyable>(
        "block_timeout_alert", no_init
    )
        .def_readonly("block_index", &block_timeout_alert::block_index)
        .def_readonly("piece_index", &block_timeout_alert::piece_index)
    ;

    class_<unwanted_block_alert, bases<peer_alert>, noncopyable>(
        "unwanted_block_alert", no_init
    )
        .def_readonly("block_index", &unwanted_block_alert::block_index)
        .def_readonly("piece_index", &unwanted_block_alert::piece_index)
    ;

    class_<torrent_delete_failed_alert, bases<torrent_alert>, noncopyable>(
        "torrent_delete_failed_alert", no_init
    );

    class_<save_resume_data_failed_alert, bases<torrent_alert>, noncopyable>(
        "save_resume_data_failed_alert", no_init
    );

}
<commit_msg>add tracker_error_alert::msg to bindings<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to 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 <libtorrent/alert.hpp>
#include <libtorrent/alert_types.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

extern char const* alert_doc;
extern char const* alert_msg_doc;
extern char const* alert_severity_doc;
extern char const* torrent_alert_doc;
extern char const* tracker_alert_doc;
extern char const* tracker_error_alert_doc;
extern char const* tracker_warning_alert_doc;
extern char const* tracker_reply_alert_doc;
extern char const* tracker_announce_alert_doc;
extern char const* hash_failed_alert_doc;
extern char const* peer_ban_alert_doc;
extern char const* peer_error_alert_doc;
extern char const* invalid_request_alert_doc;
extern char const* peer_request_doc;
extern char const* torrent_finished_alert_doc;
extern char const* piece_finished_alert_doc;
extern char const* block_finished_alert_doc;
extern char const* block_downloading_alert_doc;
extern char const* storage_moved_alert_doc;
extern char const* torrent_deleted_alert_doc;
extern char const* torrent_paused_alert_doc;
extern char const* torrent_checked_alert_doc;
extern char const* url_seed_alert_doc;
extern char const* file_error_alert_doc;
extern char const* metadata_failed_alert_doc;
extern char const* metadata_received_alert_doc;
extern char const* listen_failed_alert_doc;
extern char const* listen_succeeded_alert_doc;
extern char const* portmap_error_alert_doc;
extern char const* portmap_alert_doc;
extern char const* fastresume_rejected_alert_doc;
extern char const* peer_blocked_alert_doc;
extern char const* scrape_reply_alert_doc;
extern char const* scrape_failed_alert_doc;
extern char const* udp_error_alert_doc;
extern char const* external_ip_alert_doc;
extern char const* save_resume_data_alert_doc;

void bind_alert()
{
    using boost::noncopyable;

    {
        scope alert_scope = class_<alert, noncopyable>("alert", alert_doc, no_init)
            .def("message", &alert::message, alert_msg_doc)
            .def("what", &alert::what)
            .def("category", &alert::category)
            .def("severity", &alert::severity, alert_severity_doc)
            .def("__str__", &alert::message, alert_msg_doc)
            ;

        enum_<alert::severity_t>("severity_levels")
            .value("debug", alert::debug)
            .value("info", alert::info)
            .value("warning", alert::warning)
            .value("critical", alert::critical)
            .value("fatal", alert::fatal)
            .value("none", alert::none)
            ;

        enum_<alert::category_t>("category_t")
            .value("error_notification", alert::error_notification)
            .value("peer_notification", alert::peer_notification)
            .value("port_mapping_notification", alert::port_mapping_notification)
            .value("storage_notification", alert::storage_notification)
            .value("tracker_notification", alert::tracker_notification)
            .value("debug_notification", alert::debug_notification)
            .value("status_notification", alert::status_notification)
            .value("progress_notification", alert::progress_notification)
            .value("ip_block_notification", alert::ip_block_notification)
            .value("all_categories", alert::all_categories)
            ;
    }

    class_<torrent_alert, bases<alert>, noncopyable>(
        "torrent_alert", torrent_alert_doc, no_init
    )
        .def_readonly("handle", &torrent_alert::handle)
        ;

    class_<tracker_alert, bases<torrent_alert>, noncopyable>(
        "tracker_alert", tracker_alert_doc, no_init
    )
        .def_readonly("url", &tracker_alert::url)
        ;

    class_<peer_alert, bases<torrent_alert>, noncopyable>(
        "peer_alert", no_init
    )
        .def_readonly("ip", &peer_alert::ip)
        .def_readonly("pid", &peer_alert::pid)
    ;
    class_<tracker_error_alert, bases<tracker_alert>, noncopyable>(
        "tracker_error_alert", tracker_error_alert_doc, no_init
    )
        .def_readonly("msg", &tracker_error_alert::msg)
        .def_readonly("times_in_row", &tracker_error_alert::times_in_row)
        .def_readonly("status_code", &tracker_error_alert::status_code)
        ;

    class_<tracker_warning_alert, bases<tracker_alert>, noncopyable>(
        "tracker_warning_alert", tracker_warning_alert_doc, no_init
    );

    class_<tracker_reply_alert, bases<tracker_alert>, noncopyable>(
        "tracker_reply_alert", tracker_reply_alert_doc, no_init
    )
        .def_readonly("num_peers", &tracker_reply_alert::num_peers)
        ;

    class_<tracker_announce_alert, bases<tracker_alert>, noncopyable>(
        "tracker_announce_alert", tracker_announce_alert_doc, no_init
    );

    class_<hash_failed_alert, bases<torrent_alert>, noncopyable>(
        "hash_failed_alert", hash_failed_alert_doc, no_init
    )
        .def_readonly("piece_index", &hash_failed_alert::piece_index)
        ;

    class_<peer_ban_alert, bases<peer_alert>, noncopyable>(
        "peer_ban_alert", peer_ban_alert_doc, no_init
    );

    class_<peer_error_alert, bases<peer_alert>, noncopyable>(
        "peer_error_alert", peer_error_alert_doc, no_init
    );

    class_<invalid_request_alert, bases<peer_alert>, noncopyable>(
        "invalid_request_alert", invalid_request_alert_doc, no_init
    )
        .def_readonly("request", &invalid_request_alert::request)
        ;

    class_<peer_request>("peer_request", peer_request_doc)
        .def_readonly("piece", &peer_request::piece)
        .def_readonly("start", &peer_request::start)
        .def_readonly("length", &peer_request::length)
        .def(self == self)
        ;

    class_<torrent_finished_alert, bases<torrent_alert>, noncopyable>(
        "torrent_finished_alert", torrent_finished_alert_doc, no_init
    );

    class_<piece_finished_alert, bases<torrent_alert>, noncopyable>(
        "piece_finished_alert", piece_finished_alert_doc, no_init
    )
        .def_readonly("piece_index", &piece_finished_alert::piece_index)
        ;

    class_<block_finished_alert, bases<peer_alert>, noncopyable>(
        "block_finished_alert", block_finished_alert_doc, no_init
    )
        .def_readonly("block_index", &block_finished_alert::block_index)
        .def_readonly("piece_index", &block_finished_alert::piece_index)
        ;

    class_<block_downloading_alert, bases<peer_alert>, noncopyable>(
        "block_downloading_alert", block_downloading_alert_doc, no_init
    )
        .def_readonly("peer_speedmsg", &block_downloading_alert::peer_speedmsg)
        .def_readonly("block_index", &block_downloading_alert::block_index)
        .def_readonly("piece_index", &block_downloading_alert::piece_index)
        ;

    class_<storage_moved_alert, bases<torrent_alert>, noncopyable>(
        "storage_moved_alert", storage_moved_alert_doc, no_init
    );

    class_<torrent_deleted_alert, bases<torrent_alert>, noncopyable>(
        "torrent_deleted_alert", torrent_deleted_alert_doc, no_init
    );

    class_<torrent_paused_alert, bases<torrent_alert>, noncopyable>(
        "torrent_paused_alert", torrent_paused_alert_doc, no_init
    );

    class_<torrent_checked_alert, bases<torrent_alert>, noncopyable>(
        "torrent_checked_alert", torrent_checked_alert_doc, no_init
    );

    class_<url_seed_alert, bases<torrent_alert>, noncopyable>(
        "url_seed_alert", url_seed_alert_doc, no_init
    )
        .def_readonly("url", &url_seed_alert::url)
        ;

    class_<file_error_alert, bases<torrent_alert>, noncopyable>(
        "file_error_alert", file_error_alert_doc, no_init
    )
        .def_readonly("file", &file_error_alert::file)
        ;

    class_<metadata_failed_alert, bases<torrent_alert>, noncopyable>(
        "metadata_failed_alert", metadata_failed_alert_doc, no_init
    );

    class_<metadata_received_alert, bases<torrent_alert>, noncopyable>(
        "metadata_received_alert", metadata_received_alert_doc, no_init
    );

    class_<listen_failed_alert, bases<alert>, noncopyable>(
        "listen_failed_alert", listen_failed_alert_doc, no_init
    );

    class_<listen_succeeded_alert, bases<alert>, noncopyable>(
        "listen_succeeded_alert", listen_succeeded_alert_doc, no_init
    )
        .def_readonly("endpoint", &listen_succeeded_alert::endpoint)
        ;

    class_<portmap_error_alert, bases<alert>, noncopyable>(
        "portmap_error_alert", portmap_error_alert_doc, no_init
    )
        .def_readonly("mapping", &portmap_error_alert::mapping)
        .def_readonly("type", &portmap_error_alert::type)
        ;

    class_<portmap_alert, bases<alert>, noncopyable>(
        "portmap_alert", portmap_alert_doc, no_init
    )
        .def_readonly("mapping", &portmap_alert::mapping)
        .def_readonly("external_port", &portmap_alert::external_port)
        .def_readonly("type", &portmap_alert::type)
        ;

    class_<fastresume_rejected_alert, bases<torrent_alert>, noncopyable>(
        "fastresume_rejected_alert", fastresume_rejected_alert_doc, no_init
    );

    class_<peer_blocked_alert, bases<alert>, noncopyable>(
        "peer_blocked_alert", peer_blocked_alert_doc, no_init
    )
        .def_readonly("ip", &peer_blocked_alert::ip)
        ;

    class_<scrape_reply_alert, bases<tracker_alert>, noncopyable>(
        "scrape_reply_alert", scrape_reply_alert_doc, no_init
    )
        .def_readonly("incomplete", &scrape_reply_alert::incomplete)
        .def_readonly("complete", &scrape_reply_alert::complete)
        ;

    class_<scrape_failed_alert, bases<tracker_alert>, noncopyable>(
        "scrape_failed_alert", scrape_failed_alert_doc, no_init
    );

    class_<udp_error_alert, bases<alert>, noncopyable>(
        "udp_error_alert", udp_error_alert_doc, no_init
    )
        .def_readonly("endpoint", &udp_error_alert::endpoint)
        ;

    class_<external_ip_alert, bases<alert>, noncopyable>(
        "external_ip_alert", external_ip_alert_doc, no_init
    )
        .def_readonly("external_address", &external_ip_alert::external_address)
        ;

    class_<save_resume_data_alert, bases<torrent_alert>, noncopyable>(
        "save_resume_data_alert", save_resume_data_alert_doc, no_init
    )
        .def_readonly("resume_data", &save_resume_data_alert::resume_data)
        ;

    class_<file_renamed_alert, bases<torrent_alert>, noncopyable>(
        "file_renamed_alert", no_init
    )
        .def_readonly("name", &file_renamed_alert::name)
        ;

    class_<file_rename_failed_alert, bases<torrent_alert>, noncopyable>(
        "file_rename_failed_alert", no_init
    )
        .def_readonly("index", &file_rename_failed_alert::index)
        ;

    class_<torrent_resumed_alert, bases<torrent_alert>, noncopyable>(
        "torrent_resumed_alert", no_init
	);

	class_<state_changed_alert, bases<torrent_alert>, noncopyable>(
	    "state_changed_alert", no_init
	)
	    .def_readonly("state", &state_changed_alert::state)
	    ;

	class_<dht_reply_alert, bases<tracker_alert>, noncopyable>(
	    "dht_reply_alert", no_init
	)
	    .def_readonly("num_peers", &dht_reply_alert::num_peers)
	    ;

	class_<peer_unsnubbed_alert, bases<peer_alert>, noncopyable>(
	    "peer_unsnubbed_alert", no_init
	);

	class_<peer_snubbed_alert, bases<peer_alert>, noncopyable>(
	    "peer_snubbed_alert", no_init
	);

    class_<peer_connect_alert, bases<peer_alert>, noncopyable>(
        "peer_connect_alert", no_init
    );

    class_<peer_disconnected_alert, bases<peer_alert>, noncopyable>(
        "peer_disconnected_alert", no_init
    );

    class_<request_dropped_alert, bases<peer_alert>, noncopyable>(
        "request_dropped_alert", no_init
    )
        .def_readonly("block_index", &request_dropped_alert::block_index)
        .def_readonly("piece_index", &request_dropped_alert::piece_index)
    ;

    class_<block_timeout_alert, bases<peer_alert>, noncopyable>(
        "block_timeout_alert", no_init
    )
        .def_readonly("block_index", &block_timeout_alert::block_index)
        .def_readonly("piece_index", &block_timeout_alert::piece_index)
    ;

    class_<unwanted_block_alert, bases<peer_alert>, noncopyable>(
        "unwanted_block_alert", no_init
    )
        .def_readonly("block_index", &unwanted_block_alert::block_index)
        .def_readonly("piece_index", &unwanted_block_alert::piece_index)
    ;

    class_<torrent_delete_failed_alert, bases<torrent_alert>, noncopyable>(
        "torrent_delete_failed_alert", no_init
    );

    class_<save_resume_data_failed_alert, bases<torrent_alert>, noncopyable>(
        "save_resume_data_failed_alert", no_init
    );

}
<|endoftext|>


<commit_before>#ifndef DESOLIN_BLAS_WRAPPERS_HPP
#define DESOLIN_BLAS_WRAPPERS_HPP

#include <vector>
#include <cstddef>
#include <desolin/file-access/mtl_harwell_boeing_stream.hpp>
#include <desolin/file-access/mtl_entry.hpp>

namespace desolin
{

namespace blas_wrappers
{

template<typename T>
class BLASVector
{
public:
  typedef T value_type;
  typedef std::size_t size_type;

private:
  std::vector<value_type> values;

public:
  BLASVector(const size_type rows) : values(rows)
  {
  }

  BLASVector(const size_type rows, const value_type initial) : values(rows, initial)
  {
  }

  void resize(const size_type rows)
  {
    values.resize(rows);
  }

  inline size_type nrows() const
  {
    return values.size();
  }

  inline value_type* data()
  {
    return &values[0];
  }

  inline const value_type* data() const
  {
    return &values[0];
  }
};

template<typename T>
class BLASGeneralMatrix
{
public:
  typedef T value_type;
  typedef std::size_t size_type;

private:
  const size_type rows;
  const size_type cols;
  std::vector<value_type> values;

public:
  BLASGeneralMatrix(const size_type r, const size_type c) : rows(r), cols(c), values(rows*cols, 0)
  {
  }

  template<typename StreamType>
  explicit BLASGeneralMatrix(StreamType& str) : rows(str.nrows()), cols(str.ncols()), values(rows*cols, 0)
  {
    while(!str.eof())
    {
      desolin::entry2<double> entry;
      str >> entry;
      values[ncols()*entry.row + entry.col] = entry.value;
    }
  }

  inline size_type nrows() const
  {
    return rows;
  }

  inline size_type ncols() const
  {
    return cols;
  }

  inline value_type* data()
  {
    return &values[0];
  }

  inline const value_type* data() const
  {
    return &values[0];
  }
};

}

}
#endif
<commit_msg>Update BLAS wrappers to avoid initialising dense matrices and vectors.<commit_after>#ifndef DESOLIN_BLAS_WRAPPERS_HPP
#define DESOLIN_BLAS_WRAPPERS_HPP

#include <vector>
#include <cstddef>
#include <boost/scoped_array.hpp>
#include <algorithm>
#include <desolin/file-access/mtl_harwell_boeing_stream.hpp>
#include <desolin/file-access/mtl_entry.hpp>

namespace desolin
{

namespace blas_wrappers
{

template<typename T>
class BLASVector
{
public:
  typedef T value_type;
  typedef std::size_t size_type;

private:
  size_type numRows;
  boost::scoped_array<value_type> values;

public:
  BLASVector(const size_type rows) : numRows(rows), values(new value_type[rows])
  {
  }

  BLASVector(const size_type rows, const value_type initial) : numRows(rows), values(new value_type[rows])
  {
    std::fill(values.get(), values.get() + numRows, initial);
  }

  BLASVector(const BLASVector& v) : numRows(v.numRows), values(new value_type[numRows])
  {
    std::copy(v.values.get(), v.values.get() + numRows, values.get());
  }

  void resize(const size_type rows)
  {
    value_type* const newValues = new value_type[rows];
    std::copy(values.get(), newValues, std::min(rows, numRows));

    numRows = rows;
    values.reset(newValues);
  }

  inline size_type nrows() const
  {
    return numRows;
  }

  inline value_type* data()
  {
    return values.get();
  }

  inline const value_type* data() const
  {
    return values.get();
  }
};

template<typename T>
class BLASGeneralMatrix
{
public:
  typedef T value_type;
  typedef std::size_t size_type;

private:
  const size_type rows;
  const size_type cols;
  boost::scoped_array<value_type> values;

public:
  BLASGeneralMatrix(const size_type r, const size_type c) : rows(r), cols(c), values(new value_type[rows*cols])
  {
  }

  template<typename StreamType>
  explicit BLASGeneralMatrix(StreamType& str) : rows(str.nrows()), cols(str.ncols()), values(new value_type[rows*cols])
  {
    std::fill(values.get(), values.get() + rows*cols, T());

    while(!str.eof())
    {
      desolin::entry2<double> entry;
      str >> entry;
      values[ncols()*entry.row + entry.col] = entry.value;
    }
  }

  inline size_type nrows() const
  {
    return rows;
  }

  inline size_type ncols() const
  {
    return cols;
  }

  inline value_type* data()
  {
    return values.get();
  }

  inline const value_type* data() const
  {
    return values.get();
  }
};

}

}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * 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 <organization> 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 EARLIER MENTIONED AUTHORS ``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 <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Utest.h"
#include "TestRegistry.h"
#include "TestResult.h"
#include "Failure.h"
#include "EqualsFailure.h"
#include "NullTest.h"

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

TestResult* Utest::testResult_ = 0;
Utest* Utest::currentTest_ = 0;

Utest::Utest()
    : group_("UndefinedTestGroup")
    , name_("UndefinedTest")
    , file_("UndefinedFile")
    , lineNumber_(0)
    , next_(&NullTest::instance())
{
}

Utest::Utest (const char* groupName,
            const char* testName,
            const char* fileName,
            int lineNumber)
    : group_(groupName)
    , name_(testName)
    , file_(fileName)
    , lineNumber_(lineNumber)
    , next_(&NullTest::instance())
{}

Utest::Utest (const char* groupName,
            const char* testName,
            const char* fileName,
            int lineNumber,
            Utest* nextTest)
    : group_(groupName)
    , name_(testName)
    , file_(fileName)
    , lineNumber_(lineNumber)
    , next_(nextTest)
{}

Utest::~Utest ()
{}

void Utest::run(TestResult& result)
{
  //save test context, so that test class can be tested
  Utest* savedTest = currentTest_;
  TestResult* savedResult = testResult_;

  result.countRun();
  testResult_ = &result;
  currentTest_ = this;
  setup();
  testBody();
  teardown();

  //restore
  currentTest_ = savedTest;
  testResult_ = savedResult;
}

Utest *Utest::getNext() const
  {
    return next_;
  }

Utest* Utest::addTest(Utest *test)
{
  next_ = test;
  return this;
}

int Utest::countTests()
{
	return next_->countTests() + 1;
}

bool Utest::isLast () const
{
	return false;
}

const SimpleString Utest::getName() const
  {
    return SimpleString(name_);
  }

SimpleString Utest::getFormattedName() const
  {
    SimpleString formattedName(getMacroName());
    formattedName += "(";
    formattedName += group_;
    formattedName += ", ";
    formattedName += name_;
    formattedName += ")";

    return formattedName;
  }

void Utest::setFileName(const char* fileName)
{
	file_ = fileName;
}

void Utest::setLineNumber(int lineNumber)
{
	lineNumber_ = lineNumber;
}

void Utest::setGroupName(const char* groupName)
{
	group_ = groupName;
}

void Utest::setTestName(const char* testName)
{
	name_ = testName;
}

const SimpleString Utest::getFile() const
  {
    return SimpleString(file_);
  }

int Utest::getLineNumber() const
  {
    return lineNumber_;
  }

void Utest::setup()
{
}

void Utest::teardown()
{
}

bool Utest::shouldRun(const SimpleString& groupFilter, const SimpleString& nameFilter) const
  {
    SimpleString group(group_);
    SimpleString name(name_);
    if (group.contains(groupFilter) && name.contains(nameFilter))
      return true;

    return false;
  }

bool Utest::assertTrue(bool condition, const char* conditionString, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (!(condition))
    {
      SimpleString message("CHECK(");
      message += conditionString;
      message += ") failed";
      Failure _f(this, fileName, lineNumber, message);
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

bool Utest::assertCstrEqual(const char* expected, const char* actual, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (strcmp(expected, actual) != 0)
    {
      EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual));
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

bool Utest::assertLongsEqual(long expected, long actual, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (expected != actual)
    {
      EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual));
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

bool Utest::assertDoublesEqual(double expected, double actual, double threshold, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (fabs(expected-actual) > threshold)
    {
      EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual));
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

void Utest::fail(const char *text, const char* fileName, int lineNumber)
{
  Failure _f(this, fileName, lineNumber, text);
  testResult_->addFailure (_f);
}

<commit_msg>Fixed a small bug<commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * 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 <organization> 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 EARLIER MENTIONED AUTHORS ``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 <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Utest.h"
#include "TestRegistry.h"
#include "TestResult.h"
#include "Failure.h"
#include "EqualsFailure.h"
#include "NullTest.h"

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

TestResult* Utest::testResult_ = 0;
Utest* Utest::currentTest_ = 0;

Utest::Utest()
    : group_("UndefinedTestGroup")
    , name_("UndefinedTest")
    , file_("UndefinedFile")
    , lineNumber_(0)
    , next_(&NullTest::instance())
{
}

Utest::Utest (const char* groupName,
            const char* testName,
            const char* fileName,
            int lineNumber)
    : group_(groupName)
    , name_(testName)
    , file_(fileName)
    , lineNumber_(lineNumber)
    , next_(&NullTest::instance())
{}

Utest::Utest (const char* groupName,
            const char* testName,
            const char* fileName,
            int lineNumber,
            Utest* nextTest)
    : group_(groupName)
    , name_(testName)
    , file_(fileName)
    , lineNumber_(lineNumber)
    , next_(nextTest)
{}

Utest::~Utest ()
{}

void Utest::run(TestResult& result)
{
  //save test context, so that test class can be tested
  Utest* savedTest = currentTest_;
  TestResult* savedResult = testResult_;

  result.countRun();
  testResult_ = &result;
  currentTest_ = this;
  setup();
  testBody();
  teardown();

  //restore
  currentTest_ = savedTest;
  testResult_ = savedResult;
}

Utest *Utest::getNext() const
  {
    return next_;
  }

Utest* Utest::addTest(Utest *test)
{
  next_ = test;
  return this;
}

int Utest::countTests()
{
	return next_->countTests() + 1;
}

bool Utest::isLast () const
{
	return false;
}

const SimpleString Utest::getName() const
  {
    return SimpleString(name_);
  }

const SimpleString Utest::getGroup() const
{
	return SimpleString(group_);
}

SimpleString Utest::getFormattedName() const
  {
    SimpleString formattedName(getMacroName());
    formattedName += "(";
    formattedName += group_;
    formattedName += ", ";
    formattedName += name_;
    formattedName += ")";

    return formattedName;
  }

void Utest::setFileName(const char* fileName)
{
	file_ = fileName;
}

void Utest::setLineNumber(int lineNumber)
{
	lineNumber_ = lineNumber;
}

void Utest::setGroupName(const char* groupName)
{
	group_ = groupName;
}

void Utest::setTestName(const char* testName)
{
	name_ = testName;
}

const SimpleString Utest::getFile() const
  {
    return SimpleString(file_);
  }

int Utest::getLineNumber() const
  {
    return lineNumber_;
  }

void Utest::setup()
{
}

void Utest::teardown()
{
}

bool Utest::shouldRun(const SimpleString& groupFilter, const SimpleString& nameFilter) const
  {
    SimpleString group(group_);
    SimpleString name(name_);
    if (group.contains(groupFilter) && name.contains(nameFilter))
      return true;

    return false;
  }

bool Utest::assertTrue(bool condition, const char* conditionString, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (!(condition))
    {
      SimpleString message("CHECK(");
      message += conditionString;
      message += ") failed";
      Failure _f(this, fileName, lineNumber, message);
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

bool Utest::assertCstrEqual(const char* expected, const char* actual, const char* fileName, int lineNumber)
{
	testResult_->countCheck();
	if (actual == 0 && expected == 0) return true;
	if (actual == 0) {
		EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom("(null)"));
		testResult_->addFailure (_f);
		return false;
	}
	if (expected == 0) {
		EqualsFailure _f(this, fileName, lineNumber, StringFrom("(null)"), StringFrom(actual));
		testResult_->addFailure (_f);
		return false;
	}
	if (strcmp(expected, actual) != 0) {
		EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual));
		testResult_->addFailure (_f);
		return false;
	}
	return true;
}

bool Utest::assertLongsEqual(long expected, long actual, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (expected != actual)
    {
      EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual));
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

bool Utest::assertDoublesEqual(double expected, double actual, double threshold, const char* fileName, int lineNumber)
{
  testResult_->countCheck();
  if (fabs(expected-actual) > threshold)
    {
      EqualsFailure _f(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual));
      testResult_->addFailure (_f);
      return false;
    }
  return true;
}

void Utest::fail(const char *text, const char* fileName, int lineNumber)
{
  Failure _f(this, fileName, lineNumber, text);
  testResult_->addFailure (_f);
}

<|endoftext|>


<commit_before>/*! \file DegRateNuclide.cpp
    \brief Implements the DegRateNuclide class used by the Generic Repository
    \author Kathryn D. Huff
 */
#include <iostream>
#include <fstream>
#include <deque>
#include <time.h>
#include <assert.h>

#include "CycException.h"
#include "InputXML.h"
#include "Logger.h"
#include "Timer.h"
#include "DegRateNuclide.h"
#include "Material.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DegRateNuclide::DegRateNuclide(){
  set_deg_rate(0);
  tot_deg_ = 0;
  last_degraded_ = 0;
  wastes_ = deque<mat_rsrc_ptr>();

  vec_hist_ = VecHist();
  conc_hist_ = ConcHist();
  update_vec_hist(0);
  update_conc_hist(0);

  set_geom(GeometryPtr(new Geometry()));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DegRateNuclide::~DegRateNuclide(){
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::init(xmlNodePtr cur){
  // move the xml pointer to the current model
  cur = XMLinput->get_xpath_element(cur,"model/DegRateNuclide");
  double deg_rate = strtod(XMLinput->get_xpath_content(cur, "degradation"), NULL);
  init(deg_rate);
  LOG(LEV_DEBUG2,"GRDRNuc") << "The DegRateNuclide Class init(cur) function has been called";;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::init(double deg_rate) {
  set_deg_rate(deg_rate);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NuclideModel* DegRateNuclide::copy(NuclideModel* src){
  DegRateNuclide* src_ptr = dynamic_cast<DegRateNuclide*>(src);

  set_deg_rate(src_ptr->deg_rate_);
  tot_deg_ = 0;
  wastes_ = deque<mat_rsrc_ptr>();

  set_geom(GeometryPtr(new Geometry()));
  geom_->copy(src_ptr->geom(), src_ptr->geom()->centroid());

  vec_hist_ = VecHist();
  conc_hist_ = ConcHist();
  update_vec_hist(TI->time());
  update_conc_hist(TI->time());

  return (NuclideModel*)this;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::print(){
    LOG(LEV_DEBUG2,"GRDRNuc") << "DegRateNuclide Model";;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::absorb(mat_rsrc_ptr matToAdd)
{
  // Get the given DegRateNuclide's contaminant material.
  // add the material to it with the material absorb function.
  // each nuclide model should override this function
  LOG(LEV_DEBUG2,"GRDRNuc") << "DegRateNuclide is absorbing material: ";
  matToAdd->print();
  wastes_.push_back(matToAdd);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::extract(mat_rsrc_ptr matToRem)
{
  // Get the given DegRateNuclide's contaminant material.
  // add the material to it with the material extract function.
  // each nuclide model should override this function
  LOG(LEV_DEBUG2,"GRDRNuc") << "DegRateNuclide" << "is extracting material: ";
  matToRem->print() ;
  mat_rsrc_ptr left_over = mat_rsrc_ptr(new Material());
  while (!wastes_.empty()){
    left_over->absorb(wastes_.back());
    wastes_.pop_back();
  }
  left_over->extract(matToRem);
  wastes_.push_back(left_over);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::transportNuclides(int time){
  // This should transport the nuclides through the component.
  // It will likely rely on the internal flux and will produce an external flux.
  update_degradation(time, deg_rate_);
  update_vec_hist(time);
  update_conc_hist(time);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::set_deg_rate(double deg_rate){
  if( deg_rate < 0 || deg_rate > 1 ) {
    string msg = "The DegRateNuclide degradation rate range is 0 to 1, inclusive.";
    msg += " The value provided was ";
    msg += deg_rate;
    msg += ".";
    throw CycRangeException(msg);
  } else {
    deg_rate_ = deg_rate;
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::contained_mass(int time){
  return vec_hist(time).second;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::contained_mass(){
  return contained_mass(last_degraded_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> DegRateNuclide::source_term_bc(){
  return make_pair(contained_vec(last_degraded_),
      tot_deg()*contained_mass(last_degraded_));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::dirichlet_bc(){
  IsoConcMap dirichlet, whole_vol;
  whole_vol = conc_hist(last_degraded_);
  IsoConcMap::const_iterator it;
  for( it=whole_vol.begin(); it!=whole_vol.end(); ++it){
    dirichlet.insert(make_pair((*it).first, tot_deg()*(*it).second));
  }
  return dirichlet;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::neumann_bc(){
  /// @TODO This is just a placeholder
  return conc_hist(last_degraded_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::cauchy_bc(){
  /// @TODO This is just a placeholder
  return conc_hist(last_degraded_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::update_conc_hist(int time){
  return update_conc_hist(time, wastes_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::update_conc_hist(int time, deque<mat_rsrc_ptr> mats){

  IsoConcMap to_ret;

  pair<IsoVector, double> sum_pair;
  sum_pair = sum_mats(mats);

  CompMap::iterator it;
  if(sum_pair.second != 0 && geom_->volume() != numeric_limits<double>::infinity()) {
    double scale = sum_pair.second/geom_->volume();
    CompMapPtr curr_comp = sum_pair.first.comp();
    for(it = (*curr_comp).begin(); it != (*curr_comp).end(); ++it) {
      to_ret.insert(make_pair((*it).first, ((*it).second)*scale));
    }
  } else {
    to_ret.insert(make_pair( 92235, 0));
  }
  conc_hist_.insert(make_pair(time, to_ret));
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> DegRateNuclide::sum_mats(deque<mat_rsrc_ptr> mats){
  IsoVector vec;
  CompMapPtr sum_comp = CompMapPtr(new CompMap(MASS));
  double kg = 0;

  if( mats.size() != 0 ){
    CompMapPtr comp_to_add;
    deque<mat_rsrc_ptr>::iterator mat;
    int iso;
    CompMap::iterator comp;

    for(mat = mats.begin(); mat != mats.end(); ++mat){
      comp_to_add = (*mat)->unnormalizeComp(MASS);
      kg += (*mat)->mass(KG);
      for(comp = (*comp_to_add).begin(); comp != (*comp_to_add).end(); ++comp) {
        iso = comp->first;
        if(sum_comp->count(iso)!=0) {
          (*sum_comp)[iso] = (*sum_comp)[iso] + comp->second;
        } else {
          (*sum_comp)[iso] = comp->second;
        }
      }
    }
  } else {
    (*sum_comp)[92235] = 0;
  }
  vec = IsoVector(sum_comp);
  return make_pair(vec, kg);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::update_degradation(int time, double deg_rate){
  assert(last_degraded_ <= time);
  assert(deg_rate<=1.0 && deg_rate >= 0.0);
  double total;
  total = tot_deg() + deg_rate*(time - last_degraded_);
  tot_deg_ = min(1.0, total);
  last_degraded_ = time;

  return tot_deg_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::tot_deg(){
  return tot_deg_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::update_vec_hist(int time){
  vec_hist_[ time ] = sum_mats(wastes_) ;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoVector DegRateNuclide::contained_vec(int time){
  IsoVector to_ret = vec_hist(time).first;
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> DegRateNuclide::vec_hist(int time){
  pair<IsoVector, double> to_ret;
  VecHist::iterator it;
  it = vec_hist_.find(time);
  if( time == last_degraded_ || it != vec_hist_.end() ){
    to_ret = (*it).second;
  } else {
    to_ret = make_pair(IsoVector(),0);
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::conc_hist(int time){
  IsoConcMap to_ret;
  ConcHist::iterator it;
  it = conc_hist_.find(time);
  if( time == last_degraded_ && it != conc_hist_.end() ){
    to_ret = (*it).second;
  } else {
    to_ret.insert(make_pair(92235,0)); // zero
  }
  return to_ret;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Concentration DegRateNuclide::conc_hist(int time, Iso tope){
  Concentration to_ret;
  IsoConcMap conc_map = conc_hist(time);
  IsoConcMap::iterator it;
  it = conc_map.find(tope);
  if(it != conc_map.end()){
    to_ret = (*it).second;
  }else{
    to_ret = 0;
  }
  return to_ret;
}

<commit_msg>assertion failure DegRateNuclide.cpp:261"<commit_after>/*! \file DegRateNuclide.cpp
    \brief Implements the DegRateNuclide class used by the Generic Repository
    \author Kathryn D. Huff
 */
#include <iostream>
#include <fstream>
#include <deque>
#include <time.h>
#include <assert.h>

#include "CycException.h"
#include "InputXML.h"
#include "Logger.h"
#include "Timer.h"
#include "DegRateNuclide.h"
#include "Material.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DegRateNuclide::DegRateNuclide(){
  set_deg_rate(0);
  tot_deg_ = 0;
  last_degraded_ = 0;
  wastes_ = deque<mat_rsrc_ptr>();

  vec_hist_ = VecHist();
  conc_hist_ = ConcHist();
  update_vec_hist(0);
  update_conc_hist(0);

  set_geom(GeometryPtr(new Geometry()));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DegRateNuclide::~DegRateNuclide(){
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::init(xmlNodePtr cur){
  // move the xml pointer to the current model
  cur = XMLinput->get_xpath_element(cur,"model/DegRateNuclide");
  double deg_rate = strtod(XMLinput->get_xpath_content(cur, "degradation"), NULL);
  init(deg_rate);
  LOG(LEV_DEBUG2,"GRDRNuc") << "The DegRateNuclide Class init(cur) function has been called";;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::init(double deg_rate) {
  set_deg_rate(deg_rate);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NuclideModel* DegRateNuclide::copy(NuclideModel* src){
  DegRateNuclide* src_ptr = dynamic_cast<DegRateNuclide*>(src);

  set_deg_rate(src_ptr->deg_rate_);
  tot_deg_ = 0;
  last_degraded_ = TI->time();
  wastes_ = deque<mat_rsrc_ptr>();

  set_geom(GeometryPtr(new Geometry()));
  geom_->copy(src_ptr->geom(), src_ptr->geom()->centroid());

  vec_hist_ = VecHist();
  conc_hist_ = ConcHist();
  update_vec_hist(TI->time());
  update_conc_hist(TI->time());

  return (NuclideModel*)this;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::print(){
    LOG(LEV_DEBUG2,"GRDRNuc") << "DegRateNuclide Model";;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::absorb(mat_rsrc_ptr matToAdd)
{
  // Get the given DegRateNuclide's contaminant material.
  // add the material to it with the material absorb function.
  // each nuclide model should override this function
  LOG(LEV_DEBUG2,"GRDRNuc") << "DegRateNuclide is absorbing material: ";
  matToAdd->print();
  wastes_.push_back(matToAdd);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::extract(mat_rsrc_ptr matToRem)
{
  // Get the given DegRateNuclide's contaminant material.
  // add the material to it with the material extract function.
  // each nuclide model should override this function
  LOG(LEV_DEBUG2,"GRDRNuc") << "DegRateNuclide" << "is extracting material: ";
  matToRem->print() ;
  mat_rsrc_ptr left_over = mat_rsrc_ptr(new Material());
  while (!wastes_.empty()){
    left_over->absorb(wastes_.back());
    wastes_.pop_back();
  }
  left_over->extract(matToRem);
  wastes_.push_back(left_over);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::transportNuclides(int the_time){
  // This should transport the nuclides through the component.
  // It will likely rely on the internal flux and will produce an external flux.
  update_degradation(the_time, deg_rate_);
  update_vec_hist(the_time);
  update_conc_hist(the_time);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::set_deg_rate(double deg_rate){
  if( deg_rate < 0 || deg_rate > 1 ) {
    string msg = "The DegRateNuclide degradation rate range is 0 to 1, inclusive.";
    msg += " The value provided was ";
    msg += deg_rate;
    msg += ".";
    throw CycRangeException(msg);
  } else {
    deg_rate_ = deg_rate;
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::contained_mass(int the_time){
  return vec_hist(the_time).second;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::contained_mass(){
  return contained_mass(last_degraded_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> DegRateNuclide::source_term_bc(){
  return make_pair(contained_vec(last_degraded_),
      tot_deg()*contained_mass(last_degraded_));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::dirichlet_bc(){
  IsoConcMap dirichlet, whole_vol;
  whole_vol = conc_hist(last_degraded_);
  IsoConcMap::const_iterator it;
  for( it=whole_vol.begin(); it!=whole_vol.end(); ++it){
    dirichlet.insert(make_pair((*it).first, tot_deg()*(*it).second));
  }
  return dirichlet;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::neumann_bc(){
  /// @TODO This is just a placeholder
  return conc_hist(last_degraded_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::cauchy_bc(){
  /// @TODO This is just a placeholder
  return conc_hist(last_degraded_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::update_conc_hist(int the_time){
  return update_conc_hist(the_time, wastes_);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::update_conc_hist(int the_time, deque<mat_rsrc_ptr> mats){
  assert(last_degraded_ <= the_time);

  IsoConcMap to_ret;

  pair<IsoVector, double> sum_pair;
  sum_pair = vec_hist(the_time);

  CompMap::iterator it;
  if(sum_pair.second != 0 && geom_->volume() != numeric_limits<double>::infinity()) {
    double scale = sum_pair.second/geom_->volume();
    CompMapPtr curr_comp = sum_pair.first.comp();
    for(it = (*curr_comp).begin(); it != (*curr_comp).end(); ++it) {
      to_ret.insert(make_pair((*it).first, ((*it).second)*scale));
    }
  } else {
    to_ret.insert(make_pair( 92235, 0));
  }
  conc_hist_.insert(make_pair(the_time, to_ret));
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> DegRateNuclide::sum_mats(deque<mat_rsrc_ptr> mats){
  IsoVector vec;
  CompMapPtr sum_comp = CompMapPtr(new CompMap(MASS));
  double kg = 0;

  if( mats.size() != 0 ){
    CompMapPtr comp_to_add;
    deque<mat_rsrc_ptr>::iterator mat;
    int iso;
    CompMap::iterator comp;

    for(mat = mats.begin(); mat != mats.end(); ++mat){
      comp_to_add = (*mat)->unnormalizeComp(MASS);
      kg += (*mat)->mass(KG);
      for(comp = (*comp_to_add).begin(); comp != (*comp_to_add).end(); ++comp) {
        iso = comp->first;
        if(sum_comp->count(iso)!=0) {
          (*sum_comp)[iso] = (*sum_comp)[iso] + comp->second;
        } else {
          (*sum_comp)[iso] = comp->second;
        }
      }
    }
  } else {
    (*sum_comp)[92235] = 0;
  }
  vec = IsoVector(sum_comp);
  return make_pair(vec, kg);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::update_degradation(int the_time, double deg_rate){
  assert(last_degraded_ <= the_time);
  assert(deg_rate<=1.0 && deg_rate >= 0.0);
  double total;
  total = tot_deg() + deg_rate*(the_time - last_degraded_);
  tot_deg_ = min(1.0, total);
  last_degraded_ = the_time;

  return tot_deg_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double DegRateNuclide::tot_deg(){
  return tot_deg_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DegRateNuclide::update_vec_hist(int the_time){
  vec_hist_[ the_time ] = sum_mats(wastes_) ;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoVector DegRateNuclide::contained_vec(int the_time){
  IsoVector to_ret = vec_hist(the_time).first;
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> DegRateNuclide::vec_hist(int the_time){
  pair<IsoVector, double> to_ret;
  VecHist::const_iterator it;
  if(vec_hist_.size() != 0) {it = vec_hist_.find(the_time);}
  if(the_time == last_degraded_ || it != vec_hist_.end() ){
    to_ret = (*it).second;
    assert(to_ret.second < 1000 );
  } else {
    CompMapPtr zero_comp = CompMapPtr(new CompMap(MASS));
    (*zero_comp)[92235] = 0;
    to_ret = make_pair(IsoVector(zero_comp),0);
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap DegRateNuclide::conc_hist(int the_time){
  IsoConcMap to_ret;
  ConcHist::iterator it;
  it = conc_hist_.find(the_time);
  if( the_time == last_degraded_ && it != conc_hist_.end() ){
    to_ret = (*it).second;
  } else {
    to_ret.insert(make_pair(92235,0)); // zero
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Concentration DegRateNuclide::conc_hist(int the_time, Iso tope){
  Concentration to_ret;
  IsoConcMap conc_map = conc_hist(the_time);
  IsoConcMap::iterator it;
  it = conc_map.find(tope);
  if(it != conc_map.end()){
    to_ret = (*it).second;
  }else{
    to_ret = 0;
  }
  return to_ret;
}

<|endoftext|>


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

#ifndef vk_Context_hpp
#define vk_Context_hpp

#include "Config.hpp"
#include "Memset.hpp"
#include "Stream.hpp"
#include "System/Types.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkFormat.hpp"

#include <vector>

namespace vk {

class Buffer;
class Device;
class ImageView;
class PipelineLayout;

struct VertexInputBinding
{
	Buffer *buffer = nullptr;
	VkDeviceSize offset = 0;
	VkDeviceSize size = 0;
	VkDeviceSize stride = 0;
};

struct IndexBuffer
{
	inline VkIndexType getIndexType() const { return indexType; }
	void setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type);
	void getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const;

private:
	int bytesPerIndex() const;

	VertexInputBinding binding;
	VkIndexType indexType;
};

struct Attachments
{
	ImageView *colorBuffer[sw::MAX_COLOR_BUFFERS] = {};
	ImageView *depthBuffer = nullptr;
	ImageView *stencilBuffer = nullptr;

	VkFormat colorFormat(int index) const;
	VkFormat depthFormat() const;
};

struct Inputs
{
	Inputs(const VkPipelineVertexInputStateCreateInfo *vertexInputState);

	void updateDescriptorSets(const DescriptorSet::Array &dso,
	                          const DescriptorSet::Bindings &ds,
	                          const DescriptorSet::DynamicOffsets &ddo);
	inline const DescriptorSet::Array &getDescriptorSetObjects() const { return descriptorSetObjects; }
	inline const DescriptorSet::Bindings &getDescriptorSets() const { return descriptorSets; }
	inline const DescriptorSet::DynamicOffsets &getDescriptorDynamicOffsets() const { return descriptorDynamicOffsets; }
	inline const sw::Stream &getStream(uint32_t i) const { return stream[i]; }

	void bindVertexInputs(int firstInstance, bool dynamicInstanceStride);
	void setVertexInputBinding(const VertexInputBinding vertexInputBindings[]);
	void advanceInstanceAttributes(bool dynamicInstanceStride);
	VkDeviceSize getVertexStride(uint32_t i, bool dynamicVertexStride) const;
	VkDeviceSize getInstanceStride(uint32_t i, bool dynamicVertexStride) const;

private:
	VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
	DescriptorSet::Array descriptorSetObjects = {};
	DescriptorSet::Bindings descriptorSets = {};
	DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
	sw::Stream stream[sw::MAX_INTERFACE_COMPONENTS / 4];
};

struct BlendState : sw::Memset<BlendState>
{
	BlendState()
	    : Memset(this, 0)
	{}

	BlendState(bool alphaBlendEnable,
	           VkBlendFactor sourceBlendFactor,
	           VkBlendFactor destBlendFactor,
	           VkBlendOp blendOperation,
	           VkBlendFactor sourceBlendFactorAlpha,
	           VkBlendFactor destBlendFactorAlpha,
	           VkBlendOp blendOperationAlpha)
	    : Memset(this, 0)
	    , alphaBlendEnable(alphaBlendEnable)
	    , sourceBlendFactor(sourceBlendFactor)
	    , destBlendFactor(destBlendFactor)
	    , blendOperation(blendOperation)
	    , sourceBlendFactorAlpha(sourceBlendFactorAlpha)
	    , destBlendFactorAlpha(destBlendFactorAlpha)
	    , blendOperationAlpha(blendOperationAlpha)
	{}

	bool alphaBlendEnable;
	VkBlendFactor sourceBlendFactor;
	VkBlendFactor destBlendFactor;
	VkBlendOp blendOperation;
	VkBlendFactor sourceBlendFactorAlpha;
	VkBlendFactor destBlendFactorAlpha;
	VkBlendOp blendOperationAlpha;
};

struct DynamicState
{
	VkViewport viewport;
	VkRect2D scissor;
	sw::float4 blendConstants;
	float depthBiasConstantFactor = 0.0f;
	float depthBiasClamp = 0.0f;
	float depthBiasSlopeFactor = 0.0f;
	float minDepthBounds = 0.0f;
	float maxDepthBounds = 0.0f;
	float lineWidth = 0.0f;

	VkCullModeFlags cullMode = VK_CULL_MODE_NONE;
	VkBool32 depthBoundsTestEnable = VK_FALSE;
	VkCompareOp depthCompareOp = VK_COMPARE_OP_NEVER;
	VkBool32 depthTestEnable = VK_FALSE;
	VkBool32 depthWriteEnable = VK_FALSE;
	VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	VkPrimitiveTopology primitiveTopology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
	uint32_t scissorCount = 0;
	VkRect2D scissors[vk::MAX_VIEWPORTS] = {};
	VkStencilFaceFlags faceMask = (VkStencilFaceFlags)0;
	VkStencilOpState frontStencil = {};
	VkStencilOpState backStencil = {};
	VkBool32 stencilTestEnable = VK_FALSE;
	uint32_t viewportCount = 0;
	VkRect2D viewports[vk::MAX_VIEWPORTS] = {};
	VkBool32 rasterizerDiscardEnable = VK_FALSE;
	VkBool32 depthBiasEnable = VK_FALSE;
	VkBool32 primitiveRestartEnable = VK_FALSE;
};

struct GraphicsState
{
	GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo, const PipelineLayout *layout, bool robustBufferAccess);

	const GraphicsState combineStates(const DynamicState &dynamicState) const;

	inline const PipelineLayout *getPipelineLayout() const { return pipelineLayout; }
	inline bool getRobustBufferAccess() const { return robustBufferAccess; }
	inline VkPrimitiveTopology getTopology() const { return topology; }

	inline VkProvokingVertexModeEXT getProvokingVertexMode() const { return provokingVertexMode; }

	inline VkStencilOpState getFrontStencil() const { return frontStencil; }
	inline VkStencilOpState getBackStencil() const { return backStencil; }

	// Pixel processor states
	inline VkCullModeFlags getCullMode() const { return cullMode; }
	inline VkFrontFace getFrontFace() const { return frontFace; }
	inline VkPolygonMode getPolygonMode() const { return polygonMode; }
	inline VkLineRasterizationModeEXT getLineRasterizationMode() const { return lineRasterizationMode; }

	inline float getConstantDepthBias() const { return depthBiasEnable ? constantDepthBias : 0; }
	inline float getSlopeDepthBias() const { return depthBiasEnable ? slopeDepthBias : 0; }
	inline float getDepthBiasClamp() const { return depthBiasEnable ? depthBiasClamp : 0; }
	inline float getMinDepthBounds() const { return minDepthBounds; }
	inline float getMaxDepthBounds() const { return maxDepthBounds; }
	inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; }
	inline bool getDepthClampEnable() const { return depthClampEnable; }
	inline bool getDepthClipEnable() const { return depthClipEnable; }

	// Pixel processor states
	inline bool hasRasterizerDiscard() const { return rasterizerDiscard; }
	inline VkCompareOp getDepthCompareMode() const { return depthCompareMode; }

	inline float getLineWidth() const { return lineWidth; }

	inline unsigned int getMultiSampleMask() const { return multiSampleMask; }
	inline int getSampleCount() const { return sampleCount; }
	inline bool hasSampleShadingEnabled() const { return sampleShadingEnable; }
	inline float getMinSampleShading() const { return minSampleShading; }
	inline bool hasAlphaToCoverage() const { return alphaToCoverage; }

	inline bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; }
	inline const VkRect2D &getScissor() const { return scissor; }
	inline const VkViewport &getViewport() const { return viewport; }
	inline const sw::float4 &getBlendConstants() const { return blendConstants; }

	bool isDrawPoint(bool polygonModeAware) const;
	bool isDrawLine(bool polygonModeAware) const;
	bool isDrawTriangle(bool polygonModeAware) const;

	BlendState getBlendState(int index, const Attachments &attachments, bool fragmentContainsKill) const;

	int colorWriteActive(int index, const Attachments &attachments) const;
	bool depthWriteActive(const Attachments &attachments) const;
	bool depthTestActive(const Attachments &attachments) const;
	bool stencilActive(const Attachments &attachments) const;
	bool depthBoundsTestActive(const Attachments &attachments) const;

	inline bool hasDynamicVertexStride() const { return dynamicStateFlags.dynamicVertexInputBindingStride; }
	inline bool hasDynamicTopology() const { return dynamicStateFlags.dynamicPrimitiveTopology; }

private:
	struct DynamicStateFlags
	{
		bool dynamicViewport : 1;
		bool dynamicScissor : 1;
		bool dynamicLineWidth : 1;
		bool dynamicDepthBias : 1;
		bool dynamicBlendConstants : 1;
		bool dynamicDepthBounds : 1;
		bool dynamicStencilCompareMask : 1;
		bool dynamicStencilWriteMask : 1;
		bool dynamicStencilReference : 1;
		bool dynamicCullMode : 1;
		bool dynamicFrontFace : 1;
		bool dynamicPrimitiveTopology : 1;
		bool dynamicViewportWithCount : 1;
		bool dynamicScissorWithCount : 1;
		bool dynamicVertexInputBindingStride : 1;
		bool dynamicDepthTestEnable : 1;
		bool dynamicDepthWriteEnable : 1;
		bool dynamicDepthCompareOp : 1;
		bool dynamicDepthBoundsTestEnable : 1;
		bool dynamicStencilTestEnable : 1;
		bool dynamicStencilOp : 1;
		bool dynamicRasterizerDiscardEnable : 1;
		bool dynamicDepthBiasEnable : 1;
		bool dynamicPrimitiveRestartEnable : 1;
	};

	static DynamicStateFlags ParseDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo);
	void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo *depthStencilState);
	void setColorBlendState(const VkPipelineColorBlendStateCreateInfo *colorBlendState);

	VkBlendFactor blendFactor(VkBlendOp blendOperation, VkBlendFactor blendFactor) const;
	VkBlendOp blendOperation(VkBlendOp blendOperation, VkBlendFactor sourceBlendFactor, VkBlendFactor destBlendFactor, vk::Format format) const;

	bool alphaBlendActive(int index, const Attachments &attachments, bool fragmentContainsKill) const;
	bool colorWriteActive(const Attachments &attachments) const;

	const PipelineLayout *pipelineLayout = nullptr;
	const bool robustBufferAccess = false;
	const DynamicStateFlags dynamicStateFlags = {};
	VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;

	VkProvokingVertexModeEXT provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;

	bool stencilEnable = false;
	VkStencilOpState frontStencil = {};
	VkStencilOpState backStencil = {};

	// Pixel processor states
	VkCullModeFlags cullMode = 0;
	VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
	VkLineRasterizationModeEXT lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;

	bool depthBiasEnable = false;
	float constantDepthBias = 0.0f;
	float slopeDepthBias = 0.0f;
	float depthBiasClamp = 0.0f;
	float minDepthBounds = 0.0f;
	float maxDepthBounds = 0.0f;
	bool depthRangeUnrestricted = false;

	// Pixel processor states
	bool rasterizerDiscard = false;
	bool depthBoundsTestEnable = false;
	bool depthTestEnable = false;
	VkCompareOp depthCompareMode = VK_COMPARE_OP_NEVER;
	bool depthWriteEnable = false;
	bool depthClampEnable = false;
	bool depthClipEnable = false;

	float lineWidth = 0.0f;

	int colorWriteMask[sw::MAX_COLOR_BUFFERS] = {};  // RGBA
	unsigned int multiSampleMask = 0;
	int sampleCount = 0;
	bool alphaToCoverage = false;

	bool sampleShadingEnable = false;
	float minSampleShading = 0.0f;

	bool primitiveRestartEnable = false;
	VkRect2D scissor = {};
	VkViewport viewport = {};
	sw::float4 blendConstants = {};

	BlendState blendState[sw::MAX_COLOR_BUFFERS] = {};
};

}  // namespace vk

#endif  // vk_Context_hpp
<commit_msg>Fix using uninitialized blend constants<commit_after>// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef vk_Context_hpp
#define vk_Context_hpp

#include "Config.hpp"
#include "Memset.hpp"
#include "Stream.hpp"
#include "System/Types.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkFormat.hpp"

#include <vector>

namespace vk {

class Buffer;
class Device;
class ImageView;
class PipelineLayout;

struct VertexInputBinding
{
	Buffer *buffer = nullptr;
	VkDeviceSize offset = 0;
	VkDeviceSize size = 0;
	VkDeviceSize stride = 0;
};

struct IndexBuffer
{
	inline VkIndexType getIndexType() const { return indexType; }
	void setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type);
	void getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const;

private:
	int bytesPerIndex() const;

	VertexInputBinding binding;
	VkIndexType indexType;
};

struct Attachments
{
	ImageView *colorBuffer[sw::MAX_COLOR_BUFFERS] = {};
	ImageView *depthBuffer = nullptr;
	ImageView *stencilBuffer = nullptr;

	VkFormat colorFormat(int index) const;
	VkFormat depthFormat() const;
};

struct Inputs
{
	Inputs(const VkPipelineVertexInputStateCreateInfo *vertexInputState);

	void updateDescriptorSets(const DescriptorSet::Array &dso,
	                          const DescriptorSet::Bindings &ds,
	                          const DescriptorSet::DynamicOffsets &ddo);
	inline const DescriptorSet::Array &getDescriptorSetObjects() const { return descriptorSetObjects; }
	inline const DescriptorSet::Bindings &getDescriptorSets() const { return descriptorSets; }
	inline const DescriptorSet::DynamicOffsets &getDescriptorDynamicOffsets() const { return descriptorDynamicOffsets; }
	inline const sw::Stream &getStream(uint32_t i) const { return stream[i]; }

	void bindVertexInputs(int firstInstance, bool dynamicInstanceStride);
	void setVertexInputBinding(const VertexInputBinding vertexInputBindings[]);
	void advanceInstanceAttributes(bool dynamicInstanceStride);
	VkDeviceSize getVertexStride(uint32_t i, bool dynamicVertexStride) const;
	VkDeviceSize getInstanceStride(uint32_t i, bool dynamicVertexStride) const;

private:
	VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
	DescriptorSet::Array descriptorSetObjects = {};
	DescriptorSet::Bindings descriptorSets = {};
	DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
	sw::Stream stream[sw::MAX_INTERFACE_COMPONENTS / 4];
};

struct BlendState : sw::Memset<BlendState>
{
	BlendState()
	    : Memset(this, 0)
	{}

	BlendState(bool alphaBlendEnable,
	           VkBlendFactor sourceBlendFactor,
	           VkBlendFactor destBlendFactor,
	           VkBlendOp blendOperation,
	           VkBlendFactor sourceBlendFactorAlpha,
	           VkBlendFactor destBlendFactorAlpha,
	           VkBlendOp blendOperationAlpha)
	    : Memset(this, 0)
	    , alphaBlendEnable(alphaBlendEnable)
	    , sourceBlendFactor(sourceBlendFactor)
	    , destBlendFactor(destBlendFactor)
	    , blendOperation(blendOperation)
	    , sourceBlendFactorAlpha(sourceBlendFactorAlpha)
	    , destBlendFactorAlpha(destBlendFactorAlpha)
	    , blendOperationAlpha(blendOperationAlpha)
	{}

	bool alphaBlendEnable;
	VkBlendFactor sourceBlendFactor;
	VkBlendFactor destBlendFactor;
	VkBlendOp blendOperation;
	VkBlendFactor sourceBlendFactorAlpha;
	VkBlendFactor destBlendFactorAlpha;
	VkBlendOp blendOperationAlpha;
};

struct DynamicState
{
	VkViewport viewport = {};
	VkRect2D scissor = {};
	sw::float4 blendConstants = {};
	float depthBiasConstantFactor = 0.0f;
	float depthBiasClamp = 0.0f;
	float depthBiasSlopeFactor = 0.0f;
	float minDepthBounds = 0.0f;
	float maxDepthBounds = 0.0f;
	float lineWidth = 0.0f;

	VkCullModeFlags cullMode = VK_CULL_MODE_NONE;
	VkBool32 depthBoundsTestEnable = VK_FALSE;
	VkCompareOp depthCompareOp = VK_COMPARE_OP_NEVER;
	VkBool32 depthTestEnable = VK_FALSE;
	VkBool32 depthWriteEnable = VK_FALSE;
	VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	VkPrimitiveTopology primitiveTopology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
	uint32_t scissorCount = 0;
	VkRect2D scissors[vk::MAX_VIEWPORTS] = {};
	VkStencilFaceFlags faceMask = (VkStencilFaceFlags)0;
	VkStencilOpState frontStencil = {};
	VkStencilOpState backStencil = {};
	VkBool32 stencilTestEnable = VK_FALSE;
	uint32_t viewportCount = 0;
	VkRect2D viewports[vk::MAX_VIEWPORTS] = {};
	VkBool32 rasterizerDiscardEnable = VK_FALSE;
	VkBool32 depthBiasEnable = VK_FALSE;
	VkBool32 primitiveRestartEnable = VK_FALSE;
};

struct GraphicsState
{
	GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo, const PipelineLayout *layout, bool robustBufferAccess);

	const GraphicsState combineStates(const DynamicState &dynamicState) const;

	inline const PipelineLayout *getPipelineLayout() const { return pipelineLayout; }
	inline bool getRobustBufferAccess() const { return robustBufferAccess; }
	inline VkPrimitiveTopology getTopology() const { return topology; }

	inline VkProvokingVertexModeEXT getProvokingVertexMode() const { return provokingVertexMode; }

	inline VkStencilOpState getFrontStencil() const { return frontStencil; }
	inline VkStencilOpState getBackStencil() const { return backStencil; }

	// Pixel processor states
	inline VkCullModeFlags getCullMode() const { return cullMode; }
	inline VkFrontFace getFrontFace() const { return frontFace; }
	inline VkPolygonMode getPolygonMode() const { return polygonMode; }
	inline VkLineRasterizationModeEXT getLineRasterizationMode() const { return lineRasterizationMode; }

	inline float getConstantDepthBias() const { return depthBiasEnable ? constantDepthBias : 0; }
	inline float getSlopeDepthBias() const { return depthBiasEnable ? slopeDepthBias : 0; }
	inline float getDepthBiasClamp() const { return depthBiasEnable ? depthBiasClamp : 0; }
	inline float getMinDepthBounds() const { return minDepthBounds; }
	inline float getMaxDepthBounds() const { return maxDepthBounds; }
	inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; }
	inline bool getDepthClampEnable() const { return depthClampEnable; }
	inline bool getDepthClipEnable() const { return depthClipEnable; }

	// Pixel processor states
	inline bool hasRasterizerDiscard() const { return rasterizerDiscard; }
	inline VkCompareOp getDepthCompareMode() const { return depthCompareMode; }

	inline float getLineWidth() const { return lineWidth; }

	inline unsigned int getMultiSampleMask() const { return multiSampleMask; }
	inline int getSampleCount() const { return sampleCount; }
	inline bool hasSampleShadingEnabled() const { return sampleShadingEnable; }
	inline float getMinSampleShading() const { return minSampleShading; }
	inline bool hasAlphaToCoverage() const { return alphaToCoverage; }

	inline bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; }
	inline const VkRect2D &getScissor() const { return scissor; }
	inline const VkViewport &getViewport() const { return viewport; }
	inline const sw::float4 &getBlendConstants() const { return blendConstants; }

	bool isDrawPoint(bool polygonModeAware) const;
	bool isDrawLine(bool polygonModeAware) const;
	bool isDrawTriangle(bool polygonModeAware) const;

	BlendState getBlendState(int index, const Attachments &attachments, bool fragmentContainsKill) const;

	int colorWriteActive(int index, const Attachments &attachments) const;
	bool depthWriteActive(const Attachments &attachments) const;
	bool depthTestActive(const Attachments &attachments) const;
	bool stencilActive(const Attachments &attachments) const;
	bool depthBoundsTestActive(const Attachments &attachments) const;

	inline bool hasDynamicVertexStride() const { return dynamicStateFlags.dynamicVertexInputBindingStride; }
	inline bool hasDynamicTopology() const { return dynamicStateFlags.dynamicPrimitiveTopology; }

private:
	struct DynamicStateFlags
	{
		bool dynamicViewport : 1;
		bool dynamicScissor : 1;
		bool dynamicLineWidth : 1;
		bool dynamicDepthBias : 1;
		bool dynamicBlendConstants : 1;
		bool dynamicDepthBounds : 1;
		bool dynamicStencilCompareMask : 1;
		bool dynamicStencilWriteMask : 1;
		bool dynamicStencilReference : 1;
		bool dynamicCullMode : 1;
		bool dynamicFrontFace : 1;
		bool dynamicPrimitiveTopology : 1;
		bool dynamicViewportWithCount : 1;
		bool dynamicScissorWithCount : 1;
		bool dynamicVertexInputBindingStride : 1;
		bool dynamicDepthTestEnable : 1;
		bool dynamicDepthWriteEnable : 1;
		bool dynamicDepthCompareOp : 1;
		bool dynamicDepthBoundsTestEnable : 1;
		bool dynamicStencilTestEnable : 1;
		bool dynamicStencilOp : 1;
		bool dynamicRasterizerDiscardEnable : 1;
		bool dynamicDepthBiasEnable : 1;
		bool dynamicPrimitiveRestartEnable : 1;
	};

	static DynamicStateFlags ParseDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo);
	void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo *depthStencilState);
	void setColorBlendState(const VkPipelineColorBlendStateCreateInfo *colorBlendState);

	VkBlendFactor blendFactor(VkBlendOp blendOperation, VkBlendFactor blendFactor) const;
	VkBlendOp blendOperation(VkBlendOp blendOperation, VkBlendFactor sourceBlendFactor, VkBlendFactor destBlendFactor, vk::Format format) const;

	bool alphaBlendActive(int index, const Attachments &attachments, bool fragmentContainsKill) const;
	bool colorWriteActive(const Attachments &attachments) const;

	const PipelineLayout *pipelineLayout = nullptr;
	const bool robustBufferAccess = false;
	const DynamicStateFlags dynamicStateFlags = {};
	VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;

	VkProvokingVertexModeEXT provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;

	bool stencilEnable = false;
	VkStencilOpState frontStencil = {};
	VkStencilOpState backStencil = {};

	// Pixel processor states
	VkCullModeFlags cullMode = 0;
	VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
	VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
	VkLineRasterizationModeEXT lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;

	bool depthBiasEnable = false;
	float constantDepthBias = 0.0f;
	float slopeDepthBias = 0.0f;
	float depthBiasClamp = 0.0f;
	float minDepthBounds = 0.0f;
	float maxDepthBounds = 0.0f;
	bool depthRangeUnrestricted = false;

	// Pixel processor states
	bool rasterizerDiscard = false;
	bool depthBoundsTestEnable = false;
	bool depthTestEnable = false;
	VkCompareOp depthCompareMode = VK_COMPARE_OP_NEVER;
	bool depthWriteEnable = false;
	bool depthClampEnable = false;
	bool depthClipEnable = false;

	float lineWidth = 0.0f;

	int colorWriteMask[sw::MAX_COLOR_BUFFERS] = {};  // RGBA
	unsigned int multiSampleMask = 0;
	int sampleCount = 0;
	bool alphaToCoverage = false;

	bool sampleShadingEnable = false;
	float minSampleShading = 0.0f;

	bool primitiveRestartEnable = false;
	VkRect2D scissor = {};
	VkViewport viewport = {};
	sw::float4 blendConstants = {};

	BlendState blendState[sw::MAX_COLOR_BUFFERS] = {};
};

}  // namespace vk

#endif  // vk_Context_hpp
<|endoftext|>


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

#include "VMPool.h"

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <assert.h>
#include <stdexcept>
#include <iomanip>
#include <vector>

void VMPool::add_object(xmlNodePtr node) {
        if ( node == 0 || node->children == 0 || node->children->next == 0 ) {
              FassLog::log("VMPOOL", Log::ERROR,
              "XML Node does not represent a valid Virtual Machine");
              return;
        }

        VirtualMachine* vm = new VirtualMachine(node);

        objects.insert(pair<int, VirtualMachine*>(vm->get_oid(), vm));

        ostringstream   oss;
        oss << "Inserting VM object with ID: " << vm->get_oid() << "\n";
        FassLog::log("VMPOOL", Log::DDEBUG, oss);
}

void VMPool::flush() {
        map<int, VirtualMachine*>::iterator it;

        for (it = objects.begin(); it != objects.end(); it++) {
            delete it->second;
        }

        objects.clear();
}

int VMPool::set_up() {
        int rc;
        ostringstream   oss;

        // clean the pool to get updated data from OpenNebula
        VMPool::flush();

        // load the complete pool of VMs from OpenNebula
        xmlrpc_c::value result;

        rc = load_vms(result);

        if ( rc != 0 ) {
            FassLog::log("VMPOOL", Log::ERROR,
                         "Could not retrieve VM pool info from ONE");
            return -1;
        }

        // read the response
        vector<xmlrpc_c::value> values =
               xmlrpc_c::value_array(result).vectorValueValue();
        bool   success = xmlrpc_c::value_boolean(values[0]);

        // OpenNebula says failure
        if (!success) {
            string message = xmlrpc_c::value_string(values[1]);

            oss << "Oned returned failure... Error: " << message << "\n";
            FassLog::log("VMPOOL", Log::ERROR, oss);
            return -1;
        }

        // the output of the one.vmpool.info method is always a string
        string vmlist(static_cast<string>(xmlrpc_c::value_string(values[1])));
        // parse the response and select only pending/rescheduling VMs
        xmlInitParser();
        xml_parse(vmlist);
        std::vector<xmlNodePtr> nodes;
        int n_nodes;
        n_nodes = get_nodes
        ("/VM_POOL/VM[STATE=1 or ((LCM_STATE=3 or LCM_STATE=16) and RESCHED=1)]",
        nodes);

        oss << "I got " << n_nodes << " pending VMs!";
        FassLog::log("VMPOOL", Log::DEBUG, oss);

         for (unsigned int i = 0 ; i < nodes.size(); i++) {
            VMPool::add_object(nodes[i]);
        }

        // free_nodes(nodes);

        // clean global variables that might have been allocated by the parser
        xmlCleanupParser();

    return rc;
}

int VMPool::load_vms(xmlrpc_c::value &result) {
    try {
        xmlrpc_c::paramList plist;
        plist.add(xmlrpc_c::value_int(-2));
        plist.add(xmlrpc_c::value_int(-1));
        plist.add(xmlrpc_c::value_int(-1));
        plist.add(xmlrpc_c::value_int(-1));

        client->call("one.vmpool.info", plist, &result);

        return 0;
    }
    catch (exception const& e) {
        ostringstream   oss;
        oss << "Exception raised: " << e.what();

        FassLog::log("VMPool", Log::ERROR, oss);

        return -1;
    }
}

bool VMPool::xml_parse(const string &xml_doc) {
    // copied from ONE ObjectXML
    xmlDocPtr xml = xmlReadMemory(xml_doc.c_str(), xml_doc.length(),
                                  0, 0, XML_PARSE_HUGE);
    if (xml == 0) {
        throw runtime_error("Error parsing XML Document");
        return false;
    }

    ctx = xmlXPathNewContext(xml);

    if (ctx == 0) {
        xmlFreeDoc(xml);
        throw runtime_error("Unable to create new XPath context");
        return false;
    }

    return true;
}

int VMPool::get_nodes(const string& xpath_expr,
                      std::vector<xmlNodePtr>& content) {
    // copied from ONE
    xmlXPathObjectPtr obj;

    obj = xmlXPathEvalExpression(
        reinterpret_cast<const xmlChar *>(xpath_expr.c_str()), ctx);

        if (obj == 0) {
        return 0;
    }

    if (obj->nodesetval == 0) {
        xmlXPathFreeObject(obj);
        return 0;
    }

    xmlNodeSetPtr ns = obj->nodesetval;
    int           size = ns->nodeNr;
    int           num_nodes = 0;
    xmlNodePtr    cur;

    for (int i = 0; i < size; ++i) {
        cur = xmlCopyNode(ns->nodeTab[i], 1);

        if ( cur == 0 || cur->type != XML_ELEMENT_NODE ) {
            xmlFreeNode(cur);
            continue;
        }

        content.push_back(cur);
        num_nodes++;
    }

    xmlXPathFreeObject(obj);

    return num_nodes;
}
/*
int VMPool::update(int vid) const //, const string &st) const
{
    xmlrpc_c::value result;

    try
    {
        client->call("one.vm.update", "is", &result, vid); //, st.c_str());
    }
    catch (exception const& e)
    {
        return -1;
    }

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

#include "VMPool.h"

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <assert.h>
#include <stdexcept>
#include <iomanip>
#include <vector>

void VMPool::add_object(xmlNodePtr node) {
        if ( node == 0 || node->children == 0 || node->children->next == 0 ) {
              FassLog::log("VMPOOL", Log::ERROR,
              "XML Node does not represent a valid Virtual Machine");
              return;
        }

        VirtualMachine* vm = new VirtualMachine(node);

        objects.insert(pair<int, VirtualMachine*>(vm->get_oid(), vm));

        ostringstream   oss;
        oss << "Inserting VM object with ID: " << vm->get_oid() << "\n";
        FassLog::log("VMPOOL", Log::DDEBUG, oss);
}

void VMPool::flush() {
        map<int, VirtualMachine*>::iterator it;

        for (it = objects.begin(); it != objects.end(); it++) {
            delete it->second;
        }

        objects.clear();
}

int VMPool::set_up() {
        int rc;
        ostringstream   oss;

        // clean the pool to get updated data from OpenNebula
        VMPool::flush();

        // load the complete pool of VMs from OpenNebula
        xmlrpc_c::value result;

        rc = load_vms(result);

        if ( rc != 0 ) {
            FassLog::log("VMPOOL", Log::ERROR,
                         "Could not retrieve VM pool info from ONE");
            return -1;
        }

        // read the response
        vector<xmlrpc_c::value> values =
               xmlrpc_c::value_array(result).vectorValueValue();
        bool   success = xmlrpc_c::value_boolean(values[0]);

        // OpenNebula says failure
        if (!success) {
            string message = xmlrpc_c::value_string(values[1]);

            oss << "Oned returned failure... Error: " << message << "\n";
            FassLog::log("VMPOOL", Log::ERROR, oss);
            return -1;
        }

        // the output of the one.vmpool.info method is always a string
        string vmlist(static_cast<string>(xmlrpc_c::value_string(values[1])));
        // parse the response and select only pending/rescheduling VMs
        xmlInitParser();
        xml_parse(vmlist);
        std::vector<xmlNodePtr> nodes;
        int n_nodes;
  n_nodes = get_nodes
  ("/VM_POOL/VM[STATE=1 or ((LCM_STATE=3 or LCM_STATE=16) and RESCHED=1)]",
  nodes);

        oss << "I got " << n_nodes << " pending VMs!";
        FassLog::log("VMPOOL", Log::DEBUG, oss);

         for (unsigned int i = 0 ; i < nodes.size(); i++) {
            VMPool::add_object(nodes[i]);
        }

        // free_nodes(nodes);

        // clean global variables that might have been allocated by the parser
        xmlCleanupParser();

    return rc;
}

int VMPool::load_vms(xmlrpc_c::value &result) {
    try {
        xmlrpc_c::paramList plist;
        plist.add(xmlrpc_c::value_int(-2));
        plist.add(xmlrpc_c::value_int(-1));
        plist.add(xmlrpc_c::value_int(-1));
        plist.add(xmlrpc_c::value_int(-1));

        client->call("one.vmpool.info", plist, &result);

        return 0;
    }
    catch (exception const& e) {
        ostringstream   oss;
        oss << "Exception raised: " << e.what();

        FassLog::log("VMPool", Log::ERROR, oss);

        return -1;
    }
}

bool VMPool::xml_parse(const string &xml_doc) {
    // copied from ONE ObjectXML
    xmlDocPtr xml = xmlReadMemory(xml_doc.c_str(), xml_doc.length(),
                                  0, 0, XML_PARSE_HUGE);
    if (xml == 0) {
        throw runtime_error("Error parsing XML Document");
        return false;
    }

    ctx = xmlXPathNewContext(xml);

    if (ctx == 0) {
        xmlFreeDoc(xml);
        throw runtime_error("Unable to create new XPath context");
        return false;
    }

    return true;
}

int VMPool::get_nodes(const string& xpath_expr,
                      std::vector<xmlNodePtr>& content) {
    // copied from ONE
    xmlXPathObjectPtr obj;

    obj = xmlXPathEvalExpression(
        reinterpret_cast<const xmlChar *>(xpath_expr.c_str()), ctx);

        if (obj == 0) {
        return 0;
    }

    if (obj->nodesetval == 0) {
        xmlXPathFreeObject(obj);
        return 0;
    }

    xmlNodeSetPtr ns = obj->nodesetval;
    int           size = ns->nodeNr;
    int           num_nodes = 0;
    xmlNodePtr    cur;

    for (int i = 0; i < size; ++i) {
        cur = xmlCopyNode(ns->nodeTab[i], 1);

        if ( cur == 0 || cur->type != XML_ELEMENT_NODE ) {
            xmlFreeNode(cur);
            continue;
        }

        content.push_back(cur);
        num_nodes++;
    }

    xmlXPathFreeObject(obj);

    return num_nodes;
}
/*
int VMPool::update(int vid) const //, const string &st) const
{
    xmlrpc_c::value result;

    try
    {
        client->call("one.vm.update", "is", &result, vid); //, st.c_str());
    }
    catch (exception const& e)
    {
        return -1;
    }

	return 0;
}
*/
<|endoftext|>