<commit_before>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/chain/committee_member_evaluator.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/vote.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp>

namespace graphene { namespace chain {

void_result committee_member_create_evaluator::do_evaluate( const committee_member_create_operation& op )
{ try {
   FC_ASSERT(db().get(op.committee_member_account).is_lifetime_member());
   return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

object_id_type committee_member_create_evaluator::do_apply( const committee_member_create_operation& op )
{ try {
   vote_id_type vote_id;
   db().modify(db().get_global_properties(), [&vote_id](global_property_object& p) {
      vote_id = vote_id_type(vote_id_type::committee, p.next_available_vote_id++);
   });

   const auto& new_del_object = db().create<committee_member_object>( [&]( committee_member_object& obj ){
         obj.committee_member_account   = op.committee_member_account;
         obj.vote_id            = vote_id;
         obj.url                = op.url;
   });
   return new_del_object.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result committee_member_update_evaluator::do_evaluate( const committee_member_update_operation& op )
{ try {
   FC_ASSERT(db().get(op.committee_member).committee_member_account == op.committee_member_account);
   return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result committee_member_update_evaluator::do_apply( const committee_member_update_operation& op )
{ try {
   database& _db = db();
   _db.modify(
      _db.get(op.committee_member),
      [&]( committee_member_object& com )
      {
         if( op.new_url.valid() )
            com.url = *op.new_url;
      });
   return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result committee_member_update_global_parameters_evaluator::do_evaluate(
        const committee_member_update_global_parameters_operation& o)
{ try {
   FC_ASSERT(trx_state->_is_proposed_trx);

   auto now = db().head_block_time();
   FC_ASSERT( now > HARDFORK_CORE_1468_TIME || !o.new_parameters.extensions.value.updatable_htlc_options.valid(),
         "Unable to set HTLC parameters until hardfork." );
   if (!HARDFORK_BSIP_40_PASSED( now )) {
      FC_ASSERT( !o.new_parameters.extensions.value.custom_authority_options.valid(),
                 "Unable to set Custom Authority Options until hardfork BSIP 40." );
      FC_ASSERT( !o.new_parameters.current_fees->exists<custom_authority_create_operation>(),
                 "Unable to set Custom Authority operation fees until hardfork BSIP 40." );
      FC_ASSERT( !o.new_parameters.current_fees->exists<custom_authority_update_operation>(),
                 "Unable to set Custom Authority operation fees until hardfork BSIP 40." );
      FC_ASSERT( !o.new_parameters.current_fees->exists<custom_authority_delete_operation>(),
                 "Unable to set Custom Authority operation fees until hardfork BSIP 40." );
   }

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result committee_member_update_global_parameters_evaluator::do_apply(
        const committee_member_update_global_parameters_operation& o)
{ try {
   db().modify(db().get_global_properties(), [&o](global_property_object& p) {
      p.pending_parameters = o.new_parameters;
   });

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

} } // graphene::chain
<commit_msg>Remove unreachable code<commit_after>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/chain/committee_member_evaluator.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/vote.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp>

namespace graphene { namespace chain {

void_result committee_member_create_evaluator::do_evaluate( const committee_member_create_operation& op )
{ try {
   FC_ASSERT(db().get(op.committee_member_account).is_lifetime_member());
   return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

object_id_type committee_member_create_evaluator::do_apply( const committee_member_create_operation& op )
{ try {
   vote_id_type vote_id;
   db().modify(db().get_global_properties(), [&vote_id](global_property_object& p) {
      vote_id = vote_id_type(vote_id_type::committee, p.next_available_vote_id++);
   });

   const auto& new_del_object = db().create<committee_member_object>( [&]( committee_member_object& obj ){
         obj.committee_member_account   = op.committee_member_account;
         obj.vote_id            = vote_id;
         obj.url                = op.url;
   });
   return new_del_object.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result committee_member_update_evaluator::do_evaluate( const committee_member_update_operation& op )
{ try {
   FC_ASSERT(db().get(op.committee_member).committee_member_account == op.committee_member_account);
   return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result committee_member_update_evaluator::do_apply( const committee_member_update_operation& op )
{ try {
   database& _db = db();
   _db.modify(
      _db.get(op.committee_member),
      [&]( committee_member_object& com )
      {
         if( op.new_url.valid() )
            com.url = *op.new_url;
      });
   return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result committee_member_update_global_parameters_evaluator::do_evaluate(
        const committee_member_update_global_parameters_operation& o)
{ try {
   FC_ASSERT(trx_state->_is_proposed_trx);

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result committee_member_update_global_parameters_evaluator::do_apply(
        const committee_member_update_global_parameters_operation& o)
{ try {
   db().modify(db().get_global_properties(), [&o](global_property_object& p) {
      p.pending_parameters = o.new_parameters;
   });

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

} } // graphene::chain
<|endoftext|>


<commit_before>#pragma once
#include <bts/blockchain/chain_database.hpp>
#include <bts/wallet/wallet.hpp>
#include <bts/net/node.hpp>
#include <bts/rpc/rpc_client_api.hpp>
#include <bts/api/common_api.hpp>
#include <bts/rpc_stubs/common_api_client.hpp>
#include <fc/thread/thread.hpp>
#include <fc/log/logger_config.hpp>
#include <memory>
#include <boost/program_options.hpp>

namespace bts { namespace rpc {
  class rpc_server;
  typedef std::shared_ptr<rpc_server> rpc_server_ptr;
} }
namespace bts { namespace cli {
    class cli;
}};

namespace bts { namespace client {

    using namespace bts::blockchain;
    using namespace bts::wallet;

    boost::program_options::variables_map parse_option_variables(int argc, char** argv);
    fc::path get_data_dir(const boost::program_options::variables_map& option_variables);

    namespace detail { class client_impl; }

    using namespace bts::rpc;

    struct rpc_server_config
    {
      rpc_server_config()
      : enable(false),
        rpc_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        httpd_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        htdocs("./htdocs")
      {}

      bool             enable;
      std::string      rpc_user;
      std::string      rpc_password;
      fc::ip::endpoint rpc_endpoint;
      fc::ip::endpoint httpd_endpoint;
      fc::path         htdocs;

      bool is_valid() const; /* Currently just checks if rpc port is set */
    };

    struct chain_server_config
    {
        chain_server_config()
         : enabled(false),
           listen_port(0)
        {}

        bool enabled;
        uint16_t listen_port;
    };

    struct config
    {
       config( ) :
          default_peers(vector<string>{
                  "178.62.50.61:1776",
                  "178.62.50.61:1777",
                  "178.62.50.61:1778",
                  "80.240.133.79:1776",
                  "80.240.133.79:1777",
                  "5.101.106.138:1777",
                  "5.101.106.138:1778",
                  "128.199.137.122:1776",
                  "128.199.137.122:1777",
                  "95.85.33.16:8764",
                  "180.153.142.120:1777",
                  "84.238.140.192:42577"
                  }),
          ignore_console(false),
          use_upnp(true),
          maximum_number_of_connections(BTS_NET_DEFAULT_MAX_CONNECTIONS) ,
          delegate_server( fc::ip::endpoint::from_string("0.0.0.0:0") ),
          default_delegate_peers( vector<string>({"178.62.50.61:9988"}) )
          {
              logging = fc::logging_config::default_config();
          }

          rpc_server_config   rpc;
          vector<string>      default_peers;
          vector<string>      chain_servers;
          chain_server_config chain_server;
          bool                ignore_console;
          bool                use_upnp;
          optional<fc::path>  genesis_config;
          uint16_t            maximum_number_of_connections;
          fc::logging_config  logging;
          fc::ip::endpoint    delegate_server;
          vector<string>      default_delegate_peers;
    };

    /**
     * @class client
     * @brief integrates the network, wallet, and blockchain
     *
     */
    class client : public bts::rpc_stubs::common_api_client,
                   public std::enable_shared_from_this<client>
    {
       public:
         client();
         client(bts::net::simulated_network_ptr network_to_connect_to);

         void simulate_disconnect( bool state );

         virtual ~client();

         void start_networking(std::function<void()> network_started_callback = std::function<void()>());
         void configure_from_command_line(int argc, char** argv);
         fc::future<void> start();
         void open(const path& data_dir,
                   optional<fc::path> genesis_file_path = optional<fc::path>(),
                   std::function<void(uint32_t)> reindex_status_callback = std::function<void(uint32_t)>());

         void init_cli();
         void set_daemon_mode(bool daemon_mode);

         void add_node( const string& ep );

         chain_database_ptr         get_chain()const;
         wallet_ptr                 get_wallet()const;
         bts::rpc::rpc_server_ptr   get_rpc_server()const;
         bts::net::node_ptr         get_node()const;
         fc::path                   get_data_dir()const;

         // returns true if the client is connected to the network
         bool                is_connected() const;
         bts::net::node_id_t get_node_id() const;

         const config& configure(const fc::path& configuration_directory);

         // functions for taking command-line parameters and passing them on to the p2p node
         void listen_on_port( uint16_t port_to_listen, bool wait_if_not_available);
         void accept_incoming_p2p_connections(bool accept);
         void listen_to_p2p_network();
         void connect_to_peer( const string& remote_endpoint );
         void connect_to_p2p_network();

         fc::ip::endpoint get_p2p_listening_endpoint() const;
         bool handle_message(const bts::net::message&, bool sync_mode);
         void sync_status(uint32_t item_type, uint32_t item_count);

       protected:
         virtual bts::api::common_api* get_impl() const override;

       private:
         unique_ptr<detail::client_impl> my;
    };

    typedef shared_ptr<client> client_ptr;

    /* Message broadcast on the network to notify all clients of some important information
      (security vulnerability, new version, that sort of thing) */
    class client_notification
    {
       public:
         fc::time_point_sec         timestamp;
         string                message;
         fc::ecc::compact_signature signature;

         //client_notification();
         fc::sha256 digest() const;
         void sign(const fc::ecc::private_key& key);
         fc::ecc::public_key signee() const;
    };
    typedef shared_ptr<client_notification> client_notification_ptr;

} } // bts::client

extern const std::string BTS_MESSAGE_MAGIC;

FC_REFLECT(bts::client::client_notification, (timestamp)(message)(signature) )
FC_REFLECT( bts::client::rpc_server_config, (enable)(rpc_user)(rpc_password)(rpc_endpoint)(httpd_endpoint)(htdocs) )
FC_REFLECT( bts::client::chain_server_config, (enabled)(listen_port) )
FC_REFLECT( bts::client::config,
            (rpc)(default_peers)(chain_servers)(chain_server)(ignore_console)(logging)
            (delegate_server)
            (default_delegate_peers) )

<commit_msg>Add seed node<commit_after>#pragma once
#include <bts/blockchain/chain_database.hpp>
#include <bts/wallet/wallet.hpp>
#include <bts/net/node.hpp>
#include <bts/rpc/rpc_client_api.hpp>
#include <bts/api/common_api.hpp>
#include <bts/rpc_stubs/common_api_client.hpp>
#include <fc/thread/thread.hpp>
#include <fc/log/logger_config.hpp>
#include <memory>
#include <boost/program_options.hpp>

namespace bts { namespace rpc {
  class rpc_server;
  typedef std::shared_ptr<rpc_server> rpc_server_ptr;
} }
namespace bts { namespace cli {
    class cli;
}};

namespace bts { namespace client {

    using namespace bts::blockchain;
    using namespace bts::wallet;

    boost::program_options::variables_map parse_option_variables(int argc, char** argv);
    fc::path get_data_dir(const boost::program_options::variables_map& option_variables);

    namespace detail { class client_impl; }

    using namespace bts::rpc;

    struct rpc_server_config
    {
      rpc_server_config()
      : enable(false),
        rpc_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        httpd_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        htdocs("./htdocs")
      {}

      bool             enable;
      std::string      rpc_user;
      std::string      rpc_password;
      fc::ip::endpoint rpc_endpoint;
      fc::ip::endpoint httpd_endpoint;
      fc::path         htdocs;

      bool is_valid() const; /* Currently just checks if rpc port is set */
    };

    struct chain_server_config
    {
        chain_server_config()
         : enabled(false),
           listen_port(0)
        {}

        bool enabled;
        uint16_t listen_port;
    };

    struct config
    {
       config( ) :
          default_peers(vector<string>{
                  "178.62.50.61:1776",
                  "80.240.133.79:1776",
                  "5.101.106.138:1777",
                  "128.199.137.122:1776",
                  "95.85.33.16:8764",
                  "180.153.142.120:1777",
                  "84.238.140.192:42577",
                  "104.131.35.149:1776",
                  "178.62.50.61:1777",
                  "80.240.133.79:1777",
                  "5.101.106.138:1778",
                  "128.199.137.122:1777",
                  "178.62.50.61:1778"
                  }),
          ignore_console(false),
          use_upnp(true),
          maximum_number_of_connections(BTS_NET_DEFAULT_MAX_CONNECTIONS) ,
          delegate_server( fc::ip::endpoint::from_string("0.0.0.0:0") ),
          default_delegate_peers( vector<string>({"178.62.50.61:9988"}) )
          {
              logging = fc::logging_config::default_config();
          }

          rpc_server_config   rpc;
          vector<string>      default_peers;
          vector<string>      chain_servers;
          chain_server_config chain_server;
          bool                ignore_console;
          bool                use_upnp;
          optional<fc::path>  genesis_config;
          uint16_t            maximum_number_of_connections;
          fc::logging_config  logging;
          fc::ip::endpoint    delegate_server;
          vector<string>      default_delegate_peers;
    };

    /**
     * @class client
     * @brief integrates the network, wallet, and blockchain
     *
     */
    class client : public bts::rpc_stubs::common_api_client,
                   public std::enable_shared_from_this<client>
    {
       public:
         client();
         client(bts::net::simulated_network_ptr network_to_connect_to);

         void simulate_disconnect( bool state );

         virtual ~client();

         void start_networking(std::function<void()> network_started_callback = std::function<void()>());
         void configure_from_command_line(int argc, char** argv);
         fc::future<void> start();
         void open(const path& data_dir,
                   optional<fc::path> genesis_file_path = optional<fc::path>(),
                   std::function<void(uint32_t)> reindex_status_callback = std::function<void(uint32_t)>());

         void init_cli();
         void set_daemon_mode(bool daemon_mode);

         void add_node( const string& ep );

         chain_database_ptr         get_chain()const;
         wallet_ptr                 get_wallet()const;
         bts::rpc::rpc_server_ptr   get_rpc_server()const;
         bts::net::node_ptr         get_node()const;
         fc::path                   get_data_dir()const;

         // returns true if the client is connected to the network
         bool                is_connected() const;
         bts::net::node_id_t get_node_id() const;

         const config& configure(const fc::path& configuration_directory);

         // functions for taking command-line parameters and passing them on to the p2p node
         void listen_on_port( uint16_t port_to_listen, bool wait_if_not_available);
         void accept_incoming_p2p_connections(bool accept);
         void listen_to_p2p_network();
         void connect_to_peer( const string& remote_endpoint );
         void connect_to_p2p_network();

         fc::ip::endpoint get_p2p_listening_endpoint() const;
         bool handle_message(const bts::net::message&, bool sync_mode);
         void sync_status(uint32_t item_type, uint32_t item_count);

       protected:
         virtual bts::api::common_api* get_impl() const override;

       private:
         unique_ptr<detail::client_impl> my;
    };

    typedef shared_ptr<client> client_ptr;

    /* Message broadcast on the network to notify all clients of some important information
      (security vulnerability, new version, that sort of thing) */
    class client_notification
    {
       public:
         fc::time_point_sec         timestamp;
         string                message;
         fc::ecc::compact_signature signature;

         //client_notification();
         fc::sha256 digest() const;
         void sign(const fc::ecc::private_key& key);
         fc::ecc::public_key signee() const;
    };
    typedef shared_ptr<client_notification> client_notification_ptr;

} } // bts::client

extern const std::string BTS_MESSAGE_MAGIC;

FC_REFLECT(bts::client::client_notification, (timestamp)(message)(signature) )
FC_REFLECT( bts::client::rpc_server_config, (enable)(rpc_user)(rpc_password)(rpc_endpoint)(httpd_endpoint)(htdocs) )
FC_REFLECT( bts::client::chain_server_config, (enabled)(listen_port) )
FC_REFLECT( bts::client::config,
            (rpc)(default_peers)(chain_servers)(chain_server)(ignore_console)(logging)
            (delegate_server)
            (default_delegate_peers) )

<|endoftext|>


<commit_before>#include "../include/Main.h"

//using Poco::StringTokenizer;

int main(int argc, char** argv) {
    if (argc == 4) {
        Transaction* session = new Transaction(argv[1], argv[2], argv[3]);

        string input, username, type, event, seller;
        double balance, price;
        int ticketNum;
        bool success = false;

        while (getline(cin, input)) {
            //cout << "Enter your command." << endl;
            input = rtrim(input);
            // TODO Trim right side of the input
            if (!session->isLoggedIn()) {
                if (input.compare("login") == 0) {
                    // Log in stuff.
                    cout << "enter username" << endl;
                    getline(cin, input);

                    if (session->login(input)) {
                        cout << "login successful" << endl;
                    }
                }
                else if (input.compare("quit") == 0) {
                    session->quit();
                    break;
                }
                else if (input.compare("logout") == 0) {
                    cout << "error: no users logged in" << endl;
                }
                else {
                    cout << "error: invalid command" << endl;
                }
            }
            else {
                if (input.compare("login") == 0) {
                    cout << "error: user is already logged in" << endl;
                }
                else if (input.compare("logout") == 0) {
                    session->logout();
                    cout << "logout successful" << endl;
                }
                else if (input.compare("create") == 0) {
                    cout << "enter username to create" << endl;
                    getline(cin, username);

                    // TODO: Catch create1 testcase
                    // username must be maximum 15 characters

                    cout << "enter account type" << endl;
                    getline(cin, type);

                    //cout << "enter user account balance" << endl;
                    //getline(cin, balance);
                    //cin >> balance;

                    if (session->create(username, type, 0)) {
                        cout << "create successful" << endl;
                    }
                }
                else if (input.compare("delete") == 0) {
                    cout << "enter username" << endl;
                    getline(cin, username);

                    if (session->removeUser(username)) {
                        cout << "delete successful" << endl;
                    }
                }
                else if (input.compare("addcredit") == 0) {
                    if (session->isAdmin()) {
                        cout << "enter username" << endl;
                        getline(cin, username);
                    }

                    if (session->getFileIO()->findUser(username) != -1) {
                        cout << "enter credit amount" << endl;
                        //getline(cin, balance);
                        cin >> balance;
                        bool fail = cin.fail();

                        // Skip to next line
                        string dummy;
                        getline(cin, dummy);

                        if (fail) {
                            cout << "error: invalid credit amount" << endl;
                        }
                        else {
                            success = false;

                            if (!session->isAdmin()) {
                                success = session->addcredit(balance);
                            }
                            else {
                                success = session->addcredit(username, balance);
                            }

                            if (success) {
                                //cout << "new balance: $" << session->getFileIO()->getAccountList()->at(session->getCurrentUser()).getBalance() << endl;
                                cout << "credit added" << endl;
                            }
                        }
                    }
                    else {
                        cout << "error: username does not exist" << endl;
                    }
                }
                else if (input.compare("sell") == 0) {
                    cout << "enter event title" << endl;
                    getline(cin, event);

                    cout << "enter sale price" << endl;
                    //getline(cin, price);
                    cin >> price;

                    cout << "enter number of tickets" << endl;
                    //getline(cin, ticketNum);
                    cin >> ticketNum;

                    if (session->sell(event, price, ticketNum)) {
                        cout << "tickets added" << endl;
                    }
                }
                else if (input.compare("buy") == 0) {
                    cout << "enter event title" << endl;
                    getline(cin, event);

                    cout << "enter number of tickets" << endl;
                    //getline(cin, ticketNum);

                    cin >> ticketNum;
                    bool fail = cin.fail();

                    // Skip to next line
                    string dummy;
                    getline(cin, dummy);

                    if (!fail || ticketNum < 1) {
                        cout << "error: invalid ticket number" << endl;
                    } else {
                        cout << "enter username of seller" << endl;
                        getline(cin, seller);

                        if (session->buy(event, ticketNum, seller)) {
                            cout << "purchase successful" << endl;
                        }
                    }
                }
                else if (input.compare("refund") == 0) {
                    cout << "enter buyer's username" << endl;
                    getline(cin, username);

                    cout << "enter seller's username" << endl;
                    getline(cin, seller);

                    cout << "enter amount to transfer" << endl;
                    //getline(cin, balance);
                    cin >> balance;

                    if (session->refund(username, seller, balance)) {
                        cout << "refund successful" << endl;
                    }
                }
                else {
                    cout << "error: invalid command" << endl;
                }
            }

            //cout << endl;
        }
    }

    //cout << endl;

    return 0;
}
<commit_msg>Fixed: cin integers in main<commit_after>#include "../include/Main.h"

//using Poco::StringTokenizer;

int main(int argc, char** argv) {
    if (argc == 4) {
        Transaction* session = new Transaction(argv[1], argv[2], argv[3]);

        string input, username, type, event, seller;
        double balance, price;
        int ticketNum;
        bool success = false;

        while (getline(cin, input)) {
            //cout << "Enter your command." << endl;
            input = rtrim(input);
            // TODO Trim right side of the input
            if (!session->isLoggedIn()) {
                if (input.compare("login") == 0) {
                    // Log in stuff.
                    cout << "enter username" << endl;
                    getline(cin, input);

                    if (session->login(input)) {
                        cout << "login successful" << endl;
                    }
                }
                else if (input.compare("quit") == 0) {
                    session->quit();
                    break;
                }
                else if (input.compare("logout") == 0) {
                    cout << "error: no users logged in" << endl;
                }
                else {
                    cout << "error: invalid command" << endl;
                }
            }
            else {
                if (input.compare("login") == 0) {
                    cout << "error: user is already logged in" << endl;
                }
                else if (input.compare("logout") == 0) {
                    session->logout();
                    cout << "logout successful" << endl;
                }
                else if (input.compare("create") == 0) {
                    cout << "enter username to create" << endl;
                    getline(cin, username);

                    // TODO: Catch create1 testcase
                    // username must be maximum 15 characters

                    cout << "enter account type" << endl;
                    getline(cin, type);

                    //cout << "enter user account balance" << endl;
                    //getline(cin, balance);
                    //cin >> balance;

                    if (session->create(username, type, 0)) {
                        cout << "create successful" << endl;
                    }
                }
                else if (input.compare("delete") == 0) {
                    cout << "enter username" << endl;
                    getline(cin, username);

                    if (session->removeUser(username)) {
                        cout << "delete successful" << endl;
                    }
                }
                else if (input.compare("addcredit") == 0) {
                    if (session->isAdmin()) {
                        cout << "enter username" << endl;
                        getline(cin, username);
                    }

                    if (session->getFileIO()->findUser(username) != -1) {
                        cout << "enter credit amount" << endl;
                        //getline(cin, balance);
                        cin >> balance;
                        bool fail = cin.fail();

                        // Skip to next line
                        string dummy;
                        getline(cin, dummy);

                        if (fail) {
                            cout << "error: invalid credit amount" << endl;
                        }
                        else {
                            success = false;

                            if (!session->isAdmin()) {
                                success = session->addcredit(balance);
                            }
                            else {
                                success = session->addcredit(username, balance);
                            }

                            if (success) {
                                //cout << "new balance: $" << session->getFileIO()->getAccountList()->at(session->getCurrentUser()).getBalance() << endl;
                                cout << "credit added" << endl;
                            }
                        }
                    }
                    else {
                        cout << "error: username does not exist" << endl;
                    }
                }
                else if (input.compare("sell") == 0) {
                    cout << "enter event title" << endl;
                    getline(cin, event);

                    cout << "enter sale price" << endl;
                    //getline(cin, price);
                    cin >> price;

                    bool fail = cin.fail();

                    // Skip to next line
                    string dummy;
                    getline(cin, dummy);

                    if (fail) {
                        cout << "enter number of tickets" << endl;
                        //getline(cin, ticketNum);
                        cin >> ticketNum;
                        fail = cin.fail();

                        // Skip to next line
                        getline(cin, dummy);

                        if (fail) {
                            if (session->sell(event, price, ticketNum)) {
                                cout << "tickets added" << endl;
                            }
                        }
                    }
                }
                else if (input.compare("buy") == 0) {
                    cout << "enter event title" << endl;
                    getline(cin, event);

                    cout << "enter number of tickets" << endl;
                    //getline(cin, ticketNum);

                    cin >> ticketNum;
                    bool fail = cin.fail();

                    // Skip to next line
                    string dummy;
                    getline(cin, dummy);

                    if (!fail || ticketNum < 1) {
                        cout << "error: invalid ticket number" << endl;
                    } else {
                        cout << "enter username of seller" << endl;
                        getline(cin, seller);

                        if (session->buy(event, ticketNum, seller)) {
                            cout << "purchase successful" << endl;
                        }
                    }
                }
                else if (input.compare("refund") == 0) {
                    cout << "enter buyer's username" << endl;
                    getline(cin, username);

                    cout << "enter seller's username" << endl;
                    getline(cin, seller);

                    cout << "enter amount to transfer" << endl;
                    //getline(cin, balance);
                    cin >> balance;

                    if (session->refund(username, seller, balance)) {
                        cout << "refund successful" << endl;
                    }
                }
                else {
                    cout << "error: invalid command" << endl;
                }
            }

            //cout << endl;
        }
    }

    //cout << endl;

    return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <string.h>
#include "stdsneezy.h"
#include "connect.h"

#define WIZ_KEY_FILE "/mud/prod/lib/IPC_Wiznet"
#define MAIN_PORT 7900
#define BUILD_PORT 8900
#define WIZNET_FORMAT "%s %s"
#define MAX_STRING_LENGTH 4096
#define MAX_INPUT_LENGTH 1024
#define MAX_MSGBUF_LENGTH 2048

int my_ipc_id, other_ipc_id;

key_t keyval;
int qid=-2;
struct mud_msgbuf
{
    long mtype;
    char mtext[MAX_MSGBUF_LENGTH+1];
};

int openQueue()
{
  int oldqid=qid;

  if (qid==-2) {
    extern int gamePort;
    if (gamePort==MAIN_PORT) {
      my_ipc_id = MAIN_PORT;
      other_ipc_id = BUILD_PORT;
    } else {
      my_ipc_id = BUILD_PORT;
      other_ipc_id = MAIN_PORT;
    }
    keyval = ftok(WIZ_KEY_FILE, 'm');
  }
  if ((qid = msgget(keyval, IPC_CREAT|0660)) == -1) {
    vlogf(LOG_BUG, "Unable to msgget keyval %d.", keyval);
    return -1;
  }
  if (oldqid!=qid) {
    vlogf(LOG_BUG, "msgget successful, qid: %d, keyval: %d", qid, keyval);
    oldqid = qid;
  }
  return 1;
}

void closeQueue()
{
    msgctl(qid, IPC_RMID, 0);
    vlogf(LOG_BUG, "closeQueue");
}

void mudSendMessage(int mtype, int ctype, const char *arg)
{
  struct mud_msgbuf qbuf;
  int ret;

  // this is locking is up
  return;

  if (openQueue()<0)
    return;

  if (mtype<=0) {
    vlogf(LOG_BUG, "invalid mtype, must be > 0, setting to 1");
    mtype = 1;
  }
  snprintf(qbuf.mtext, MAX_MSGBUF_LENGTH, "%d %s", ctype, arg);
  qbuf.mtype = mtype;

  if ((ret = msgsnd(qid, (struct msgbuf *)&qbuf, strlen(qbuf.mtext)+1, 0)) == -1)
    vlogf(LOG_BUG, "mudSendMessage: errno: %d ret: %d", errno, ret);
}

void TBeing::mudMessage(TBeing *ch, int channel, const char *arg)
{
  char tbuf[MAX_MSGBUF_LENGTH+1];
  snprintf(tbuf, MAX_MSGBUF_LENGTH, "%s: %s", ch->getName(), arg);
  mudSendMessage(other_ipc_id, channel, tbuf);
}

void recvTextHandler(const char *str)
{
  Descriptor *d;
  char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH], chname[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH-1];
  //  int channel=-1, level=-1;

  str = one_argument(str, arg1);
  str = one_argument(str, arg2);
  str = one_argument(str, chname);
  //  channel = convertTo<int>(arg1);
  //  level = convertTo<int>(arg2);

  snprintf(buf, MAX_STRING_LENGTH, WIZNET_FORMAT, chname, str);

  for (d = descriptor_list; d; d = d->next) {
    TBeing *och;
    och = d->original ? d->original : d->character;
    if (!och)
      continue;
    if (och->hasWizPower(POWER_WIZNET)) {
      och->sendTo(buf);
    } else {
    }
  }
}

void mudRecvMessage()
{
  struct mud_msgbuf qbuf;
  int ret;

  if (openQueue() < 0)
    return;

  while ((ret = msgrcv(qid, (struct msgbuf *)&qbuf, MAX_MSGBUF_LENGTH, my_ipc_id, IPC_NOWAIT)) > 0)
    recvTextHandler(qbuf.mtext);

  if (ret==-1 && errno!=ENOMSG)
    vlogf(LOG_BUG, "mudRecvMessage: errno: %d ret: %d", errno, ret);
}

<commit_msg>set message length max to 256 - the larger value wasn't being accepted set queue permission to 0666 should be working now on the new machine<commit_after>#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <string.h>
#include "stdsneezy.h"
#include "connect.h"

#define WIZ_KEY_FILE "/mud/prod/lib/IPC_Wiznet"
#define WIZNET_FORMAT "%s %s"
#define MAX_MSGBUF_LENGTH 256

int my_ipc_id, other_ipc_id;

key_t keyval;
int qid=-2;
struct mud_msgbuf
{
    long mtype;
    char mtext[MAX_MSGBUF_LENGTH+1];
};

int openQueue()
{
  int oldqid=qid;

  if (qid==-2) {
    extern int gamePort;
    if (gamePort==PROD_GAMEPORT) {
      my_ipc_id = PROD_GAMEPORT;
      other_ipc_id = BUILDER_GAMEPORT;
    } else {
      my_ipc_id = BUILDER_GAMEPORT;
      other_ipc_id = PROD_GAMEPORT;
    }
    keyval = ftok(WIZ_KEY_FILE, 'm');
  }
  if ((qid = msgget(keyval, IPC_CREAT|0666)) == -1) {
    vlogf(LOG_BUG, "Unable to msgget keyval %d, errno: %d.", keyval, errno);
    return -1;
  }
  if (oldqid!=qid) {
    vlogf(LOG_BUG, "msgget successful, qid: %d, keyval: %d", qid, keyval);
    oldqid = qid;
  }
  return 1;
}

void closeQueue()
{
    msgctl(qid, IPC_RMID, 0);
    vlogf(LOG_BUG, "closeQueue");
}

void mudSendMessage(int mtype, int ctype, const char *arg)
{
  struct mud_msgbuf qbuf;
  int ret;

  if (openQueue()<0)
    return;

  if (mtype<=0) {
    vlogf(LOG_BUG, "invalid mtype, must be > 0, setting to 1");
    mtype = 1;
  }
  snprintf(qbuf.mtext, MAX_MSGBUF_LENGTH, "%d %s", ctype, arg);
  qbuf.mtype = mtype;

  if ((ret = msgsnd(qid, (struct msgbuf *)&qbuf, strlen(qbuf.mtext)+1, 0)) == -1)
    vlogf(LOG_BUG, "mudSendMessage: errno: %d ret: %d", errno, ret);
}

void TBeing::mudMessage(TBeing *ch, int channel, const char *arg)
{
  char tbuf[MAX_MSGBUF_LENGTH+1];
  snprintf(tbuf, MAX_MSGBUF_LENGTH, "%s: %s", ch->getName(), arg);
  mudSendMessage(other_ipc_id, channel, tbuf);
}

void recvTextHandler(const char *str)
{
  Descriptor *d;
  char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH], chname[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH-1];
  //  int channel=-1, level=-1;

  str = one_argument(str, arg1);
  str = one_argument(str, arg2);
  str = one_argument(str, chname);
  //  channel = convertTo<int>(arg1);
  //  level = convertTo<int>(arg2);

  snprintf(buf, MAX_STRING_LENGTH, WIZNET_FORMAT, chname, str);

  for (d = descriptor_list; d; d = d->next) {
    TBeing *och;
    och = d->original ? d->original : d->character;
    if (!och)
      continue;
    if (och->hasWizPower(POWER_WIZNET)) {
      och->sendTo(buf);
    } else {
    }
  }
}

void mudRecvMessage()
{
  struct mud_msgbuf qbuf;
  int ret;

  if (openQueue() < 0)
    return;

  while ((ret = msgrcv(qid, (struct msgbuf *)&qbuf, MAX_MSGBUF_LENGTH, my_ipc_id, IPC_NOWAIT)) > 0)
    recvTextHandler(qbuf.mtext);

  if (ret==-1 && errno!=ENOMSG)
    vlogf(LOG_BUG, "mudRecvMessage: errno: %d ret: %d", errno, ret);
}

<|endoftext|>


<commit_before>/*
    kopete.cpp

    Kopete Instant Messenger Main Class

    Copyright (c) 2001-2002  by Duncan Mac-Vicar Prett   <duncan@kde.org>
    Copyright (c) 2002-2003  by Martijn Klingens         <klingens@kde.org>

    Kopete    (c) 2001-2003  by the Kopete developers    <kopete-devel@kde.org>

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

#include "kopeteapplication.h"

#include <qtimer.h>
#include <qregexp.h>

#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>

#include "kopeteaccount.h"
#include "kopeteaccountmanager.h"
#include "kopetecommandhandler.h"
#include "kopetecontactlist.h"
#include "kopeteglobal.h"
#include "kopetemimesourcefactory.h"
#include "kopetemimetypehandler.h"
#include "kopetepluginmanager.h"
#include "kopeteprotocol.h"
#include "kopetestdaction.h"
#include "kopeteuiglobal.h"
#include "kopetewindow.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

KopeteApplication::KopeteApplication()
: KUniqueApplication( true, true, true )
{
	m_isShuttingDown = false;
	m_mainWindow = new KopeteWindow( 0, "mainWindow" );

	/* KMainWindow is very broken from our point of view - it deref()'s the app
	 * when the last visible KMainWindow is destroyed. This is broken for a number
	 * of reasons, not least because it can happen more than once within a single
	 * instance of Kopete. Also, our main window is hidden when it's in the tray,
	 * and closing the last chatwindow when in that state can cause the app to quit.
	 *
	 * KopeteApplication's reference counting scheme is different to that of a normal
	 * KDE application. It works as follows: the KopetePluginManager has a reference
	 * to the application. No windows ever call KMainWindow::closeEvent, so KMainWindow
	 * doesn't stupidly deref() our application. This ensures that the application
	 * reference counting still works properly, and that the application terminates
	 * neither too early (bug 75805) nor too late (bug 71657). - Richard
	 */

	// KApplication sets the reference count to 1 on startup. KopetePluginManager has a
	// reference to us once created, so create it and drop our own reference.
	KopetePluginManager::self();
	deref();

	Kopete::UI::Global::setMainWidget( m_mainWindow );

	/*
	 * FIXME: This is a workaround for a quite odd problem:
	 * When starting up kopete and the msn plugin gets loaded it can bring up
	 * a messagebox, in case the msg configuration is missing. This messagebox
	 * will result in a QApplication::enter_loop() call, an event loop is
	 * created. At this point however the loop_level is 0, because this is all
	 * still inside the KopeteApplication constructor, before the exec() call from main.
	 * When the messagebox is finished the loop_level will drop down to zero and
	 * QApplication thinks the application shuts down (this is usually the case
	 * when the loop_level goes down to zero) . So it emits aboutToQuit(), to
	 * which KApplication is connected and re-emits shutdown() , to which again
	 * KMainWindow (a KopeteWindow instance exists already) is connected. KMainWindow's
	 * shuttingDown() slot calls queryExit() which results in KopeteWindow::queryExit()
	 * calling unloadPlugins() . This of course is wrong and just shouldn't happen.
	 * The workaround is to simply delay the initialization of all this to a point
	 * where the loop_level is already > 0 . That is why I moved all the code from
	 * the constructor to the initialize() method and added this single-shot-timer
	 * setup. (Simon)
	 *
	 * Additionally, it makes the GUI appear less 'blocking' during startup, so
	 * there is a secondary benefit as well here. (Martijn)
	 */
	QTimer::singleShot( 0, this, SLOT( slotLoadPlugins() ) );

	m_mimeFactory = new Kopete::MimeSourceFactory;
	QMimeSourceFactory::addFactory( m_mimeFactory );

	//Create the emoticon installer
	m_emoticonHandler = new Kopete::EmoticonMimeTypeHandler;
}

KopeteApplication::~KopeteApplication()
{
	kdDebug( 14000 ) << k_funcinfo << endl;

	delete m_mainWindow;
	delete m_emoticonHandler;
	delete m_mimeFactory;
	//kdDebug( 14000 ) << k_funcinfo << "Done" << endl;
}

void KopeteApplication::slotLoadPlugins()
{
	//Create the command handler (looks silly)
	KopeteCommandHandler::commandHandler();

	KopeteAccountManager::manager()->load();
	KopeteContactList::contactList()->load();

	KConfig *config = KGlobal::config();

	// Parse command-line arguments
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

	bool showConfigDialog = false;

	config->setGroup( "Plugins" );

	if ( !config->hasGroup( "Plugins" ) )
		showConfigDialog = true;

	// Listen to arguments
	/*
	// TODO: conflicts with emoticon installer and the general meaning
	// of %U in kopete.desktop
	if ( args->count() > 0 )
	{
		showConfigDialog = false;
		for ( int i = 0; i < args->count(); i++ )
			KopetePluginManager::self()->setPluginEnabled( args->arg( i ), true );
	}
	*/

	// Prevent plugins from loading? (--disable=foo,bar)
	QStringList disableArgs = QStringList::split( ',', args->getOption( "disable" ) );
	for ( QStringList::ConstIterator it = disableArgs.begin(); it != disableArgs.end(); ++it )
	{
		showConfigDialog = false;
		KopetePluginManager::self()->setPluginEnabled( *it, false );
	}

	// Load some plugins exclusively? (--load-plugins=foo,bar)
	if ( args->isSet( "load-plugins" ) )
	{
		config->deleteGroup( "Plugins", true );
		showConfigDialog = false;
		QStringList plugins = QStringList::split( ',', args->getOption( "load-plugins" ) );
		for ( QStringList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it )
			KopetePluginManager::self()->setPluginEnabled( *it, true );
	}

	// Disable plugins altogether? (--noplugins)
	if ( !args->isSet( "plugins" ) )
	{
		config->deleteGroup( "Plugins", true );
		showConfigDialog = false;
	}

	config->sync();

	KopetePluginManager::self()->loadAllPlugins();

	connect( KopetePluginManager::self(), SIGNAL( allPluginsLoaded() ),
		this, SLOT( slotAllPluginsLoaded() ));

	//load the default chatwindow
	KopetePluginManager::self()->loadPlugin( "kopete_chatwindow" );

	if( showConfigDialog )
	{
		// No plugins specified. Show the config dialog.
		// FIXME: Although it's a bit stupid it is theoretically possible that a user
		//        explicitly configured Kopete to not load plugins on startup. In this
		//        case we don't want this dialog. We need some other config setting
		//        like a bool hasRunKopeteBefore or so to trigger the loading of the
		//        wizard. Maybe using the last run version number is more useful even
		//        as it also allows for other features. - Martijn
		// FIXME: Of course this is not a too-good GUI because a first-timer would need
		//        some kind of "welcome" dialog or wizard. But for now it's better than
		//        nothing at all. - Martijn
		// FIXME: Possibly we need to influence the showConfigDialog bool based on the
		//        command line arguments processed below. But how exactly? - Martijn
		KAction *action = KopeteStdAction::preferences( 0L );
		action->activate();
		delete action;
	}

}

void KopeteApplication::slotAllPluginsLoaded()
{
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

	// --noconnect not specified?
	if ( args->isSet( "connect" ) )
		KopeteAccountManager::manager()->autoConnect();

	QCStringList connectArgs = args->getOptionList( "autoconnect" );
	for ( QCStringList::ConstIterator i = connectArgs.begin(); i != connectArgs.end(); ++i )
	{
		QString id = QString::fromLatin1( *i );

		QRegExp rx( QString::fromLatin1( "([^\\|]*)\\|\\|(.*)" ) );
		rx.search( id );
		QString protocolId = rx.cap( 1 );
		QString accountId = rx.cap( 2 );

		if ( accountId.isEmpty() )
		{
			if ( protocolId.isEmpty() )
				accountId = id;
			else
				continue;
		}

		QPtrListIterator<KopeteAccount> it( KopeteAccountManager::manager()->accounts() );
		KopeteAccount *account;
		while ( ( account = it.current() ) != 0 )
		{
			++it;

			if ( ( account->accountId() == accountId ) )
			{
				if ( protocolId.isEmpty() || account->protocol()->pluginId() == protocolId )
				{
					account->connect();
					break;
				}
			}
		}
	}

	// Parse any passed URLs/files
	handleURLArgs();
}

int KopeteApplication::newInstance()
{
	kdDebug(14000) << k_funcinfo << endl;
	handleURLArgs();
	return KUniqueApplication::newInstance();
}

void KopeteApplication::handleURLArgs()
{
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
	kdDebug(14000) << k_funcinfo << "called with " << args->count() <<
		" arguments to handle." << endl;

	if ( args->count() > 0 )
	{
		for ( int i = 0; i < args->count(); i++ )
		{
			KURL u( args->url( i ) );
			if ( !u.isValid() )
				continue;

			Kopete::MimeTypeHandler::dispatchURL( u );
		} // END for()
	} // END args->count() > 0
}

void KopeteApplication::quitKopete()
{
	kdDebug( 14000 ) << k_funcinfo << endl;

	if ( !m_isShuttingDown )
	{
		m_isShuttingDown = true;

#if KDE_VERSION < KDE_MAKE_VERSION( 3, 1, 90 )
		// When we close Kopete through KSystemTray, kdelibs will close all open
		// windows first. However, despite the destructive close the main window
		// is _NOT_ yet deleted at this point (it's a scheduled deleteLater()
		// call).
		// Due to a bug in KMainWindow prior to KDE 3.2 calling close() a second
		// time also derefs KApplication a second time, which causes a premature
		// call to KApplication::quit(), so we never go through the plugin
		// manager's shutdown process.
		// Unfortunately we can't assume close() ever being called though,
		// because the code paths not using the system tray still need this.
		// As a workaround we schedule a call to quitKopete() through a timer,
		// so the event loop is processed and the window is already deleted.
		// - Martijn
		QTimer::singleShot( 0, this, SLOT( quitKopete() ) );
		return;
#endif
	}

	if ( !m_mainWindow.isNull() )
		m_mainWindow->close();

	// save the contact list now, just in case a change was made very recently
	// and it hasn't autosaved yet
	KopeteContactList::contactList()->save();
	KopeteAccountManager::manager()->save();

	//unload plugins and shutdown
	KopetePluginManager::self()->shutdown();
}

void KopeteApplication::commitData( QSessionManager &sm )
{
	m_isShuttingDown = true;
	KUniqueApplication::commitData( sm );
}

#include "kopeteapplication.moc"
// vim: set noet ts=4 sts=4 sw=4:
<commit_msg>Fix bug 76323. From the code:<commit_after>/*
    kopete.cpp

    Kopete Instant Messenger Main Class

    Copyright (c) 2001-2002  by Duncan Mac-Vicar Prett   <duncan@kde.org>
    Copyright (c) 2002-2003  by Martijn Klingens         <klingens@kde.org>

    Kopete    (c) 2001-2003  by the Kopete developers    <kopete-devel@kde.org>

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

#include "kopeteapplication.h"

#include <qtimer.h>
#include <qregexp.h>

#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>

#include "kopeteaccount.h"
#include "kopeteaccountmanager.h"
#include "kopetecommandhandler.h"
#include "kopetecontactlist.h"
#include "kopeteglobal.h"
#include "kopetemimesourcefactory.h"
#include "kopetemimetypehandler.h"
#include "kopetepluginmanager.h"
#include "kopeteprotocol.h"
#include "kopetestdaction.h"
#include "kopeteuiglobal.h"
#include "kopetewindow.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

KopeteApplication::KopeteApplication()
: KUniqueApplication( true, true, true )
{
	m_isShuttingDown = false;
	m_mainWindow = new KopeteWindow( 0, "mainWindow" );

	/* KMainWindow is very broken from our point of view - it deref()'s the app
	 * when the last visible KMainWindow is destroyed. This is broken for a number
	 * of reasons, not least because it can happen more than once within a single
	 * instance of Kopete. Also, our main window is hidden when it's in the tray,
	 * and closing the last chatwindow when in that state can cause the app to quit.
	 *
	 * KopeteApplication's reference counting scheme is different to that of a normal
	 * KDE application. It works as follows: the KopetePluginManager has a reference
	 * to the application. No windows ever call KMainWindow::closeEvent, so KMainWindow
	 * doesn't stupidly deref() our application. This ensures that the application
	 * reference counting still works properly, and that the application terminates
	 * neither too early (bug 75805) nor too late (bug 71657). - Richard
	 */

	// KApplication sets the reference count to 1 on startup. KopetePluginManager has a
	// reference to us once created, so create it and drop our own reference.
	KopetePluginManager::self();
	deref();

	Kopete::UI::Global::setMainWidget( m_mainWindow );

	/*
	 * FIXME: This is a workaround for a quite odd problem:
	 * When starting up kopete and the msn plugin gets loaded it can bring up
	 * a messagebox, in case the msg configuration is missing. This messagebox
	 * will result in a QApplication::enter_loop() call, an event loop is
	 * created. At this point however the loop_level is 0, because this is all
	 * still inside the KopeteApplication constructor, before the exec() call from main.
	 * When the messagebox is finished the loop_level will drop down to zero and
	 * QApplication thinks the application shuts down (this is usually the case
	 * when the loop_level goes down to zero) . So it emits aboutToQuit(), to
	 * which KApplication is connected and re-emits shutdown() , to which again
	 * KMainWindow (a KopeteWindow instance exists already) is connected. KMainWindow's
	 * shuttingDown() slot calls queryExit() which results in KopeteWindow::queryExit()
	 * calling unloadPlugins() . This of course is wrong and just shouldn't happen.
	 * The workaround is to simply delay the initialization of all this to a point
	 * where the loop_level is already > 0 . That is why I moved all the code from
	 * the constructor to the initialize() method and added this single-shot-timer
	 * setup. (Simon)
	 *
	 * Additionally, it makes the GUI appear less 'blocking' during startup, so
	 * there is a secondary benefit as well here. (Martijn)
	 */
	QTimer::singleShot( 0, this, SLOT( slotLoadPlugins() ) );

	m_mimeFactory = new Kopete::MimeSourceFactory;
	QMimeSourceFactory::addFactory( m_mimeFactory );

	//Create the emoticon installer
	m_emoticonHandler = new Kopete::EmoticonMimeTypeHandler;
}

KopeteApplication::~KopeteApplication()
{
	kdDebug( 14000 ) << k_funcinfo << endl;

	delete m_mainWindow;
	delete m_emoticonHandler;
	delete m_mimeFactory;
	//kdDebug( 14000 ) << k_funcinfo << "Done" << endl;
}

void KopeteApplication::slotLoadPlugins()
{
	//Create the command handler (looks silly)
	KopeteCommandHandler::commandHandler();

	KopeteAccountManager::manager()->load();
	KopeteContactList::contactList()->load();

	KConfig *config = KGlobal::config();

	// Parse command-line arguments
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

	bool showConfigDialog = false;

	config->setGroup( "Plugins" );

	if ( !config->hasGroup( "Plugins" ) )
		showConfigDialog = true;

	// Listen to arguments
	/*
	// TODO: conflicts with emoticon installer and the general meaning
	// of %U in kopete.desktop
	if ( args->count() > 0 )
	{
		showConfigDialog = false;
		for ( int i = 0; i < args->count(); i++ )
			KopetePluginManager::self()->setPluginEnabled( args->arg( i ), true );
	}
	*/

	// Prevent plugins from loading? (--disable=foo,bar)
	QStringList disableArgs = QStringList::split( ',', args->getOption( "disable" ) );
	for ( QStringList::ConstIterator it = disableArgs.begin(); it != disableArgs.end(); ++it )
	{
		showConfigDialog = false;
		KopetePluginManager::self()->setPluginEnabled( *it, false );
	}

	// Load some plugins exclusively? (--load-plugins=foo,bar)
	if ( args->isSet( "load-plugins" ) )
	{
		config->deleteGroup( "Plugins", true );
		showConfigDialog = false;
		QStringList plugins = QStringList::split( ',', args->getOption( "load-plugins" ) );
		for ( QStringList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it )
			KopetePluginManager::self()->setPluginEnabled( *it, true );
	}

	// Disable plugins altogether? (--noplugins)
	if ( !args->isSet( "plugins" ) )
	{
		config->deleteGroup( "Plugins", true );
		showConfigDialog = false;
	}

	config->sync();

	KopetePluginManager::self()->loadAllPlugins();

	connect( KopetePluginManager::self(), SIGNAL( allPluginsLoaded() ),
		this, SLOT( slotAllPluginsLoaded() ));

	//load the default chatwindow
	KopetePluginManager::self()->loadPlugin( "kopete_chatwindow" );

	if( showConfigDialog )
	{
		// No plugins specified. Show the config dialog.
		// FIXME: Although it's a bit stupid it is theoretically possible that a user
		//        explicitly configured Kopete to not load plugins on startup. In this
		//        case we don't want this dialog. We need some other config setting
		//        like a bool hasRunKopeteBefore or so to trigger the loading of the
		//        wizard. Maybe using the last run version number is more useful even
		//        as it also allows for other features. - Martijn
		// FIXME: Of course this is not a too-good GUI because a first-timer would need
		//        some kind of "welcome" dialog or wizard. But for now it's better than
		//        nothing at all. - Martijn
		// FIXME: Possibly we need to influence the showConfigDialog bool based on the
		//        command line arguments processed below. But how exactly? - Martijn
		KAction *action = KopeteStdAction::preferences( 0L );
		action->activate();
		delete action;
	}

}

void KopeteApplication::slotAllPluginsLoaded()
{
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

	// --noconnect not specified?
	if ( args->isSet( "connect" ) )
		KopeteAccountManager::manager()->autoConnect();

	QCStringList connectArgs = args->getOptionList( "autoconnect" );
	for ( QCStringList::ConstIterator i = connectArgs.begin(); i != connectArgs.end(); ++i )
	{
		QString id = QString::fromLatin1( *i );

		QRegExp rx( QString::fromLatin1( "([^\\|]*)\\|\\|(.*)" ) );
		rx.search( id );
		QString protocolId = rx.cap( 1 );
		QString accountId = rx.cap( 2 );

		if ( accountId.isEmpty() )
		{
			if ( protocolId.isEmpty() )
				accountId = id;
			else
				continue;
		}

		QPtrListIterator<KopeteAccount> it( KopeteAccountManager::manager()->accounts() );
		KopeteAccount *account;
		while ( ( account = it.current() ) != 0 )
		{
			++it;

			if ( ( account->accountId() == accountId ) )
			{
				if ( protocolId.isEmpty() || account->protocol()->pluginId() == protocolId )
				{
					account->connect();
					break;
				}
			}
		}
	}

	// Parse any passed URLs/files
	handleURLArgs();
}

int KopeteApplication::newInstance()
{
	kdDebug(14000) << k_funcinfo << endl;
	handleURLArgs();

	/**
	 * The following three lines work around a problem that
	 * Kopete has since it has multiple main windows so
	 * qapp->mainWidget() returns 0, which breaks the normal
	 * KUniqueApplication::newInstance() behavior that raises
	 * the window when we run a new instance.
	 *
	 * 1. Set the main widget to the contact list window
	 * 2. Call KUniqueApplication::newInstance()
	 * 3. Set the main widget back to 0
	 *
	 * This little workaround fixes the problem. -Matt
	 */

	setMainWidget( m_mainWindow );
	int kUniqAppReturnCode = KUniqueApplication::newInstance();
	setMainWidget( 0L );

	return kUniqAppReturnCode;
}

void KopeteApplication::handleURLArgs()
{
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
	kdDebug(14000) << k_funcinfo << "called with " << args->count() <<
		" arguments to handle." << endl;

	if ( args->count() > 0 )
	{
		for ( int i = 0; i < args->count(); i++ )
		{
			KURL u( args->url( i ) );
			if ( !u.isValid() )
				continue;

			Kopete::MimeTypeHandler::dispatchURL( u );
		} // END for()
	} // END args->count() > 0
}

void KopeteApplication::quitKopete()
{
	kdDebug( 14000 ) << k_funcinfo << endl;

	if ( !m_isShuttingDown )
	{
		m_isShuttingDown = true;

#if KDE_VERSION < KDE_MAKE_VERSION( 3, 1, 90 )
		// When we close Kopete through KSystemTray, kdelibs will close all open
		// windows first. However, despite the destructive close the main window
		// is _NOT_ yet deleted at this point (it's a scheduled deleteLater()
		// call).
		// Due to a bug in KMainWindow prior to KDE 3.2 calling close() a second
		// time also derefs KApplication a second time, which causes a premature
		// call to KApplication::quit(), so we never go through the plugin
		// manager's shutdown process.
		// Unfortunately we can't assume close() ever being called though,
		// because the code paths not using the system tray still need this.
		// As a workaround we schedule a call to quitKopete() through a timer,
		// so the event loop is processed and the window is already deleted.
		// - Martijn
		QTimer::singleShot( 0, this, SLOT( quitKopete() ) );
		return;
#endif
	}

	if ( !m_mainWindow.isNull() )
		m_mainWindow->close();

	// save the contact list now, just in case a change was made very recently
	// and it hasn't autosaved yet
	KopeteContactList::contactList()->save();
	KopeteAccountManager::manager()->save();

	//unload plugins and shutdown
	KopetePluginManager::self()->shutdown();
}

void KopeteApplication::commitData( QSessionManager &sm )
{
	m_isShuttingDown = true;
	KUniqueApplication::commitData( sm );
}

#include "kopeteapplication.moc"
// vim: set noet ts=4 sts=4 sw=4:
<|endoftext|>


<commit_before>#ifndef MS_RTC_RTCP_RECEIVER_REPORT_HPP
#define MS_RTC_RTCP_RECEIVER_REPORT_HPP

#include "common.hpp"
#include "RTC/RTCP/Packet.hpp"
#include "Utils.hpp"
#include <vector>

namespace RTC { namespace RTCP
{
	class ReceiverReport
	{
	public:
		/* Struct for RTCP receiver report. */
		struct Header
		{
			uint32_t ssrc;
			uint32_t fraction_lost:8;
			uint32_t total_lost:24;
			uint32_t last_seq;
			uint32_t jitter;
			uint32_t lsr;
			uint32_t dlsr;
		};

	public:
		static ReceiverReport* Parse(const uint8_t* data, size_t len);

	public:
		// Parsed Report. Points to an external data.
		explicit ReceiverReport(Header* header);
		explicit ReceiverReport(ReceiverReport* report);

		// Locally generated Report. Holds the data internally.
		ReceiverReport();
		~ReceiverReport();

		void Dump();
		size_t Serialize(uint8_t* buffer);
		size_t GetSize();
		uint32_t GetSsrc();
		void SetSsrc(uint32_t ssrc);
		uint8_t GetFractionLost();
		void SetFractionLost(uint8_t fraction_lost);
		int32_t GetTotalLost();
		void SetTotalLost(int32_t total_lost);
		uint32_t GetLastSeq();
		void SetLastSeq(uint32_t last_seq);
		uint32_t GetJitter();
		void SetJitter(uint32_t jitter);
		uint32_t GetLastSenderReport();
		void SetLastSenderReport(uint32_t lsr);
		uint32_t GetDelaySinceLastSenderReport();
		void SetDelaySinceLastSenderReport(uint32_t dlsr);

	private:
		Header* header = nullptr;
		uint8_t raw[sizeof(Header)] = {0};
	};

	class ReceiverReportPacket
		: public Packet
	{
	public:
		typedef std::vector<ReceiverReport*>::iterator Iterator;

	public:
		static ReceiverReportPacket* Parse(const uint8_t* data, size_t len, size_t offset=0);

	public:
		ReceiverReportPacket();
		virtual ~ReceiverReportPacket();

		uint32_t GetSsrc();
		void SetSsrc(uint32_t ssrc);
		void AddReport(ReceiverReport* report);
		Iterator Begin();
		Iterator End();

	/* Pure virtual methods inherited from Packet. */
	public:
		virtual void Dump() override;
		virtual size_t Serialize(uint8_t* buffer) override;
		virtual size_t GetCount() override;
		virtual size_t GetSize() override;

	private:
		// SSRC of packet sender.
		uint32_t ssrc = 0;
		std::vector<ReceiverReport*> reports;
	};

	/* Inline instance methods. */

	inline
	size_t ReceiverReport::GetSize()
	{
		return sizeof(Header);
	}

	inline
	uint32_t ReceiverReport::GetSsrc()
	{
		return (uint32_t)ntohl(this->header->ssrc);
	}

	inline
	void ReceiverReport::SetSsrc(uint32_t ssrc)
	{
		this->header->ssrc = (uint32_t)htonl(ssrc);
	}

	inline
	uint8_t ReceiverReport::GetFractionLost()
	{
		return (uint8_t)Utils::Byte::Get1Byte((uint8_t*)this->header, 4);
	}

	inline
	void ReceiverReport::SetFractionLost(uint8_t fraction_lost)
	{
		Utils::Byte::Set1Byte((uint8_t*)this->header, 4, fraction_lost);
	}

	inline
	int32_t ReceiverReport::GetTotalLost()
	{
		uint32_t value = (uint32_t)Utils::Byte::Get3Bytes((uint8_t*)this->header, 5);

		// Possitive value.
		if (((value >> 23) & 1) == 0)
			return value;

		// Negative value.
		else if (value != 0x0800000)
			value &= ~(1 << 23);

		return -value;
	}

	inline
	void ReceiverReport::SetTotalLost(int32_t total_lost)
	{
		// Get the limit value for possitive and negative total_lost.
		int32_t clamp = (total_lost >= 0) ?
			total_lost > 0x07FFFFF? 0x07FFFFF : total_lost :
			-total_lost > 0x0800000? 0x0800000 : -total_lost;

		uint32_t value = (total_lost >= 0) ?
			(clamp & 0x07FFFFF) : (clamp | 0x0800000);

		Utils::Byte::Set3Bytes((uint8_t*)this->header, 5, value);
	}

	inline
	uint32_t ReceiverReport::GetLastSeq()
	{
		return (uint32_t)ntohl(this->header->last_seq);
	}

	inline
	void ReceiverReport::SetLastSeq(uint32_t last_seq)
	{
		this->header->last_seq = (uint32_t)htonl(last_seq);
	}

	inline
	uint32_t ReceiverReport::GetJitter()
	{
		return (uint32_t)ntohl(this->header->jitter);
	}

	inline
	void ReceiverReport::SetJitter(uint32_t jitter)
	{
		this->header->jitter = (uint32_t)htonl(jitter);
	}

	inline
	uint32_t ReceiverReport::GetLastSenderReport()
	{
		return (uint32_t)ntohl(this->header->lsr);
	}

	inline
	void ReceiverReport::SetLastSenderReport(uint32_t lsr)
	{
		this->header->lsr = (uint32_t)htonl(lsr);
	}

	inline
	uint32_t ReceiverReport::GetDelaySinceLastSenderReport()
	{
		return (uint32_t)ntohl(this->header->dlsr);
	}

	inline
	void ReceiverReport::SetDelaySinceLastSenderReport(uint32_t dlsr)
	{
		this->header->dlsr = (uint32_t)htonl(dlsr);
	}

	/* Inline instance methods. */

	inline
	ReceiverReport::ReceiverReport()
	{
		this->header = reinterpret_cast<Header*>(this->raw);
	}

	inline
	ReceiverReport::ReceiverReport(Header* header) :
		header(header)
	{}

	inline
	ReceiverReport::ReceiverReport(ReceiverReport* report) :
		header(report->header)
	{}

	inline
	ReceiverReport::~ReceiverReport()
	{
	}

	inline
	ReceiverReportPacket::ReceiverReportPacket()
		: Packet(Type::RR)
	{}

	inline
	ReceiverReportPacket::~ReceiverReportPacket()
	{
		for (auto report : this->reports)
		{
			delete report;
		}
	}

	inline
	size_t ReceiverReportPacket::GetCount()
	{
		return this->reports.size();
	}

	inline
	size_t ReceiverReportPacket::GetSize()
	{
		size_t size = sizeof(Packet::CommonHeader) + sizeof(this->ssrc);

		for (auto report : reports)
		{
			size += report->GetSize();
		}

		return size;
	}

	inline
	uint32_t ReceiverReportPacket::GetSsrc()
	{
		return (uint32_t)ntohl(this->ssrc);
	}

	inline
	void ReceiverReportPacket::SetSsrc(uint32_t ssrc)
	{
		this->ssrc = (uint32_t)htonl(ssrc);
	}

	inline
	void ReceiverReportPacket::AddReport(ReceiverReport* report)
	{
		this->reports.push_back(report);
	}

	inline
	ReceiverReportPacket::Iterator ReceiverReportPacket::Begin()
	{
		return this->reports.begin();
	}

	inline
	ReceiverReportPacket::Iterator ReceiverReportPacket::End()
	{
		return this->reports.end();
	}
}}

#endif
<commit_msg>Cosmetic change<commit_after>#ifndef MS_RTC_RTCP_RECEIVER_REPORT_HPP
#define MS_RTC_RTCP_RECEIVER_REPORT_HPP

#include "common.hpp"
#include "RTC/RTCP/Packet.hpp"
#include "Utils.hpp"
#include <vector>

namespace RTC { namespace RTCP
{
	class ReceiverReport
	{
	public:
		/* Struct for RTCP receiver report. */
		struct Header
		{
			uint32_t ssrc;
			uint32_t fraction_lost:8;
			uint32_t total_lost:24;
			uint32_t last_seq;
			uint32_t jitter;
			uint32_t lsr;
			uint32_t dlsr;
		};

	public:
		static ReceiverReport* Parse(const uint8_t* data, size_t len);

	public:
		// Parsed Report. Points to an external data.
		explicit ReceiverReport(Header* header);
		explicit ReceiverReport(ReceiverReport* report);

		// Locally generated Report. Holds the data internally.
		ReceiverReport();
		~ReceiverReport();

		void Dump();
		size_t Serialize(uint8_t* buffer);
		size_t GetSize();
		uint32_t GetSsrc();
		void SetSsrc(uint32_t ssrc);
		uint8_t GetFractionLost();
		void SetFractionLost(uint8_t fraction_lost);
		int32_t GetTotalLost();
		void SetTotalLost(int32_t total_lost);
		uint32_t GetLastSeq();
		void SetLastSeq(uint32_t last_seq);
		uint32_t GetJitter();
		void SetJitter(uint32_t jitter);
		uint32_t GetLastSenderReport();
		void SetLastSenderReport(uint32_t lsr);
		uint32_t GetDelaySinceLastSenderReport();
		void SetDelaySinceLastSenderReport(uint32_t dlsr);

	private:
		Header* header = nullptr;
		uint8_t raw[sizeof(Header)] = {0};
	};

	class ReceiverReportPacket
		: public Packet
	{
	public:
		typedef std::vector<ReceiverReport*>::iterator Iterator;

	public:
		static ReceiverReportPacket* Parse(const uint8_t* data, size_t len, size_t offset=0);

	public:
		ReceiverReportPacket();
		virtual ~ReceiverReportPacket();

		uint32_t GetSsrc();
		void SetSsrc(uint32_t ssrc);
		void AddReport(ReceiverReport* report);
		Iterator Begin();
		Iterator End();

	/* Pure virtual methods inherited from Packet. */
	public:
		virtual void Dump() override;
		virtual size_t Serialize(uint8_t* buffer) override;
		virtual size_t GetCount() override;
		virtual size_t GetSize() override;

	private:
		// SSRC of packet sender.
		uint32_t ssrc = 0;
		std::vector<ReceiverReport*> reports;
	};

	/* Inline instance methods. */

	inline
	size_t ReceiverReport::GetSize()
	{
		return sizeof(Header);
	}

	inline
	uint32_t ReceiverReport::GetSsrc()
	{
		return (uint32_t)ntohl(this->header->ssrc);
	}

	inline
	void ReceiverReport::SetSsrc(uint32_t ssrc)
	{
		this->header->ssrc = (uint32_t)htonl(ssrc);
	}

	inline
	uint8_t ReceiverReport::GetFractionLost()
	{
		return (uint8_t)Utils::Byte::Get1Byte((uint8_t*)this->header, 4);
	}

	inline
	void ReceiverReport::SetFractionLost(uint8_t fraction_lost)
	{
		Utils::Byte::Set1Byte((uint8_t*)this->header, 4, fraction_lost);
	}

	inline
	int32_t ReceiverReport::GetTotalLost()
	{
		uint32_t value = (uint32_t)Utils::Byte::Get3Bytes((uint8_t*)this->header, 5);

		// Possitive value.
		if (((value >> 23) & 1) == 0)
			return value;

		// Negative value.
		if (value != 0x0800000)
			value &= ~(1 << 23);

		return -value;
	}

	inline
	void ReceiverReport::SetTotalLost(int32_t total_lost)
	{
		// Get the limit value for possitive and negative total_lost.
		int32_t clamp = (total_lost >= 0) ?
			total_lost > 0x07FFFFF? 0x07FFFFF : total_lost :
			-total_lost > 0x0800000? 0x0800000 : -total_lost;

		uint32_t value = (total_lost >= 0) ?
			(clamp & 0x07FFFFF) : (clamp | 0x0800000);

		Utils::Byte::Set3Bytes((uint8_t*)this->header, 5, value);
	}

	inline
	uint32_t ReceiverReport::GetLastSeq()
	{
		return (uint32_t)ntohl(this->header->last_seq);
	}

	inline
	void ReceiverReport::SetLastSeq(uint32_t last_seq)
	{
		this->header->last_seq = (uint32_t)htonl(last_seq);
	}

	inline
	uint32_t ReceiverReport::GetJitter()
	{
		return (uint32_t)ntohl(this->header->jitter);
	}

	inline
	void ReceiverReport::SetJitter(uint32_t jitter)
	{
		this->header->jitter = (uint32_t)htonl(jitter);
	}

	inline
	uint32_t ReceiverReport::GetLastSenderReport()
	{
		return (uint32_t)ntohl(this->header->lsr);
	}

	inline
	void ReceiverReport::SetLastSenderReport(uint32_t lsr)
	{
		this->header->lsr = (uint32_t)htonl(lsr);
	}

	inline
	uint32_t ReceiverReport::GetDelaySinceLastSenderReport()
	{
		return (uint32_t)ntohl(this->header->dlsr);
	}

	inline
	void ReceiverReport::SetDelaySinceLastSenderReport(uint32_t dlsr)
	{
		this->header->dlsr = (uint32_t)htonl(dlsr);
	}

	/* Inline instance methods. */

	inline
	ReceiverReport::ReceiverReport()
	{
		this->header = reinterpret_cast<Header*>(this->raw);
	}

	inline
	ReceiverReport::ReceiverReport(Header* header) :
		header(header)
	{}

	inline
	ReceiverReport::ReceiverReport(ReceiverReport* report) :
		header(report->header)
	{}

	inline
	ReceiverReport::~ReceiverReport()
	{
	}

	inline
	ReceiverReportPacket::ReceiverReportPacket()
		: Packet(Type::RR)
	{}

	inline
	ReceiverReportPacket::~ReceiverReportPacket()
	{
		for (auto report : this->reports)
		{
			delete report;
		}
	}

	inline
	size_t ReceiverReportPacket::GetCount()
	{
		return this->reports.size();
	}

	inline
	size_t ReceiverReportPacket::GetSize()
	{
		size_t size = sizeof(Packet::CommonHeader) + sizeof(this->ssrc);

		for (auto report : reports)
		{
			size += report->GetSize();
		}

		return size;
	}

	inline
	uint32_t ReceiverReportPacket::GetSsrc()
	{
		return (uint32_t)ntohl(this->ssrc);
	}

	inline
	void ReceiverReportPacket::SetSsrc(uint32_t ssrc)
	{
		this->ssrc = (uint32_t)htonl(ssrc);
	}

	inline
	void ReceiverReportPacket::AddReport(ReceiverReport* report)
	{
		this->reports.push_back(report);
	}

	inline
	ReceiverReportPacket::Iterator ReceiverReportPacket::Begin()
	{
		return this->reports.begin();
	}

	inline
	ReceiverReportPacket::Iterator ReceiverReportPacket::End()
	{
		return this->reports.end();
	}
}}

#endif
<|endoftext|>


<commit_before><commit_msg>Also backup web service icons<commit_after><|endoftext|>


<commit_before>#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE EquelleMPIBackendTest

#include <memory>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <iterator>
#include <vector>
#include <numeric>
#include <fstream>

#include <boost/test/unit_test.hpp>

#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <zoltan_cpp.h>
#pragma GCC diagnostic pop

#include "equelle/EquelleRuntimeCPU.hpp"
#include "equelle/mpiutils.hpp"
#include "equelle/RuntimeMPI.hpp"
#include "equelle/ZoltanGrid.hpp"
#include "equelle/ZoltanGridMigrator.hpp"

using equelle::MPIInitializer;

BOOST_GLOBAL_FIXTURE( MPIInitializer );

BOOST_AUTO_TEST_CASE( gridExploration )
{
    Opm::parameter::ParameterGroup paramgroup;

    std::unique_ptr<Opm::GridManager> grid ( equelle::createGridManager(paramgroup) );

    BOOST_CHECK_EQUAL( grid->c_grid()->number_of_cells, 6 );
    //equelle::dumpGrid( grid->c_grid() );

}

BOOST_AUTO_TEST_CASE( RuntimeMPI_6x1grid ) {
    equelle::RuntimeMPI runtime;

    //BOOST_CHECK( runtime.zoltan != NULL );

    int ierr;
    void* grid = const_cast<void*>( reinterpret_cast<const void*>(runtime.globalGrid->c_grid() ) );

    if ( equelle::getMPIRank() == 0 ) {
        BOOST_CHECK_EQUAL( runtime.globalGrid->c_grid()->number_of_cells, 6 );
        BOOST_CHECK_EQUAL( equelle::ZoltanGrid::getNumberOfObjects( grid, &ierr ), 6 );

        // Check our querying of the 6x1 grid.
        const auto numCells = runtime.globalGrid->c_grid()->number_of_cells;
        std::vector<unsigned int> cells( numCells );
        for( unsigned int i = 0; i < numCells; ++i ) {
            cells[i] = i;
        }

        std::vector<int> numEdges( numCells, -1 );
        equelle::ZoltanGrid::getNumberOfEdgesMulti( grid, 1, 1, numCells, cells.data(), cells.data(), numEdges.data(),
                                                    &ierr );
        BOOST_CHECK_EQUAL( ierr, ZOLTAN_OK );
        BOOST_CHECK_EQUAL( numEdges[0], 1 );
        BOOST_CHECK_EQUAL( numEdges[1], 2 );
        BOOST_CHECK_EQUAL( numEdges[2], 2 );
        BOOST_CHECK_EQUAL( numEdges[3], 2 );
        BOOST_CHECK_EQUAL( numEdges[4], 2 );
        BOOST_CHECK_EQUAL( numEdges[5], 1 );

        auto totalNumberOfNeighbors = std::accumulate( numEdges.begin(), numEdges.end(), 0 );
        std::vector<ZOLTAN_ID_TYPE> edgeList( totalNumberOfNeighbors, -1 );
        std::vector<int> nbor_procs( edgeList.size() );

        equelle::ZoltanGrid::getEdgeListMulti( grid, 1, 1, numCells,
                                               cells.data(), cells.data(), numEdges.data(),
                                               edgeList.data(), nbor_procs.data(), 0, NULL, &ierr );
        // Cell 0
        BOOST_CHECK_EQUAL( edgeList[0], 1 ); // 0 is neighbor with 1

        // Cell 1
        BOOST_CHECK_EQUAL( edgeList[1], 0 );
        BOOST_CHECK_EQUAL( edgeList[2], 2 );

        // Cell 2
        BOOST_CHECK_EQUAL( edgeList[3], 1 );
        BOOST_CHECK_EQUAL( edgeList[4], 3 );

        // Cell 3
        BOOST_CHECK_EQUAL( edgeList[5], 2 );
        BOOST_CHECK_EQUAL( edgeList[6], 4 );

        // Cell 4UTO
        BOOST_CHECK_EQUAL( edgeList[7], 3 );
        BOOST_CHECK_EQUAL( edgeList[8], 5 );

        // Cell 5
        BOOST_CHECK_EQUAL( edgeList[9], 4 );

        BOOST_CHECK_EQUAL( ierr, ZOLTAN_OK );
    } else {
        BOOST_CHECK_EQUAL( runtime.globalGrid->c_grid()->number_of_cells, 0 );
        BOOST_CHECK_EQUAL( equelle::ZoltanGrid::getNumberOfObjects( grid, &ierr ), 0 );
    }

    auto zr = runtime.computePartition();
    BOOST_CHECK_EQUAL( zr.changes, 1 );

    if ( equelle::getMPIRank() == 0 ) {
        std::ofstream f("rank0-exports");
        equelle::ZoltanGrid::dumpRank0Exports( runtime.globalGrid->c_grid()->number_of_cells, zr, f );
    }
}

BOOST_AUTO_TEST_CASE( RuntimeMPI_6x2grid ) {
    equelle::RuntimeMPI runtime;
    runtime.globalGrid.reset( new Opm::GridManager( 6, 2 ) );

    auto zr = runtime.computePartition();
    BOOST_CHECK_EQUAL( zr.changes, 1 );

    if ( equelle::getMPIRank() == 0 ) {
        std::ofstream f("rank0-6x2-exports");
        equelle::ZoltanGrid::dumpRank0Exports( runtime.globalGrid->c_grid()->number_of_cells, zr, f );
    }
}

BOOST_AUTO_TEST_CASE( ZoltanGridMigratorCallBackSignatures ) {
    // This test really passes when the test compiles.
    std::unique_ptr<Zoltan> zoltan( new Zoltan( MPI_COMM_WORLD ) );
    using equelle::ZoltanGridMigrator;

    ZOLTAN_SAFE_CALL( zoltan->Set_Obj_Size_Fn( ZoltanGridMigrator::cellSize, NULL ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Pack_Obj_Fn( ZoltanGridMigrator::packCell, NULL ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Unpack_Obj_Fn( ZoltanGridMigrator::unpackCell, NULL ) );
}

BOOST_AUTO_TEST_CASE( decompose ) {
    equelle::RuntimeMPI runtime;
    runtime.globalGrid.reset( new Opm::GridManager( 6, 2, 5 ) );

    runtime.decompose();

    BOOST_CHECK( runtime.subGrid.global_cell.size() > 0 );
    int numOwnedCells = runtime.subGrid.global_cell.size() - runtime.subGrid.number_of_ghost_cells;

    int totalCells = 0;
    MPI_Reduce( &numOwnedCells, &totalCells, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD );

    if ( equelle::getMPIRank() == 0 ) {
        BOOST_CHECK_EQUAL( totalCells, runtime.globalGrid->c_grid()->number_of_cells );
    }
}

<commit_msg>Updated test code to new globalGrid behaviour.<commit_after>#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE EquelleMPIBackendTest

#include <memory>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <iterator>
#include <vector>
#include <numeric>
#include <fstream>

#include <boost/test/unit_test.hpp>

#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <zoltan_cpp.h>
#pragma GCC diagnostic pop

#include "equelle/EquelleRuntimeCPU.hpp"
#include "equelle/mpiutils.hpp"
#include "equelle/RuntimeMPI.hpp"
#include "equelle/ZoltanGrid.hpp"
#include "equelle/ZoltanGridMigrator.hpp"

using equelle::MPIInitializer;

BOOST_GLOBAL_FIXTURE( MPIInitializer );

BOOST_AUTO_TEST_CASE( gridExploration )
{
    Opm::parameter::ParameterGroup paramgroup;

    std::unique_ptr<Opm::GridManager> grid ( equelle::createGridManager(paramgroup) );

    BOOST_CHECK_EQUAL( grid->c_grid()->number_of_cells, 6 );
    //equelle::dumpGrid( grid->c_grid() );

}

BOOST_AUTO_TEST_CASE( RuntimeMPI_6x1grid ) {
    equelle::RuntimeMPI runtime;

    //BOOST_CHECK( runtime.zoltan != NULL );

    int ierr;
    void* grid = const_cast<void*>( reinterpret_cast<const void*>(runtime.globalGrid->c_grid() ) );

    BOOST_CHECK_EQUAL( runtime.globalGrid->c_grid()->number_of_cells, 6 );
    BOOST_CHECK_EQUAL( equelle::ZoltanGrid::getNumberOfObjects( grid, &ierr ), 6 );

    // Check our querying of the 6x1 grid.
    const auto numCells = runtime.globalGrid->c_grid()->number_of_cells;
    std::vector<unsigned int> cells( numCells );
    for( unsigned int i = 0; i < numCells; ++i ) {
        cells[i] = i;
    }

    std::vector<int> numEdges( numCells, -1 );
    equelle::ZoltanGrid::getNumberOfEdgesMulti( grid, 1, 1, numCells, cells.data(), cells.data(), numEdges.data(),
                                                &ierr );
    BOOST_CHECK_EQUAL( ierr, ZOLTAN_OK );
    BOOST_CHECK_EQUAL( numEdges[0], 1 );
    BOOST_CHECK_EQUAL( numEdges[1], 2 );
    BOOST_CHECK_EQUAL( numEdges[2], 2 );
    BOOST_CHECK_EQUAL( numEdges[3], 2 );
    BOOST_CHECK_EQUAL( numEdges[4], 2 );
    BOOST_CHECK_EQUAL( numEdges[5], 1 );

    auto totalNumberOfNeighbors = std::accumulate( numEdges.begin(), numEdges.end(), 0 );
    std::vector<ZOLTAN_ID_TYPE> edgeList( totalNumberOfNeighbors, -1 );
    std::vector<int> nbor_procs( edgeList.size() );

    equelle::ZoltanGrid::getEdgeListMulti( grid, 1, 1, numCells,
                                           cells.data(), cells.data(), numEdges.data(),
                                           edgeList.data(), nbor_procs.data(), 0, NULL, &ierr );
    // Cell 0
    BOOST_CHECK_EQUAL( edgeList[0], 1 ); // 0 is neighbor with 1

    // Cell 1
    BOOST_CHECK_EQUAL( edgeList[1], 0 );
    BOOST_CHECK_EQUAL( edgeList[2], 2 );

    // Cell 2
    BOOST_CHECK_EQUAL( edgeList[3], 1 );
    BOOST_CHECK_EQUAL( edgeList[4], 3 );

    // Cell 3
    BOOST_CHECK_EQUAL( edgeList[5], 2 );
    BOOST_CHECK_EQUAL( edgeList[6], 4 );

    // Cell 4UTO
    BOOST_CHECK_EQUAL( edgeList[7], 3 );
    BOOST_CHECK_EQUAL( edgeList[8], 5 );

    // Cell 5
    BOOST_CHECK_EQUAL( edgeList[9], 4 );

    BOOST_CHECK_EQUAL( ierr, ZOLTAN_OK );

    auto zr = runtime.computePartition();
    BOOST_CHECK_EQUAL( zr.changes, 1 );

    if ( equelle::getMPIRank() == 0 ) {
        std::ofstream f("rank0-exports");
        equelle::ZoltanGrid::dumpRank0Exports( runtime.globalGrid->c_grid()->number_of_cells, zr, f );
    }
}

BOOST_AUTO_TEST_CASE( RuntimeMPI_6x2grid ) {
    equelle::RuntimeMPI runtime;
    runtime.globalGrid.reset( new Opm::GridManager( 6, 2 ) );

    auto zr = runtime.computePartition();
    BOOST_CHECK_EQUAL( zr.changes, 1 );

    if ( equelle::getMPIRank() == 0 ) {
        std::ofstream f("rank0-6x2-exports");
        equelle::ZoltanGrid::dumpRank0Exports( runtime.globalGrid->c_grid()->number_of_cells, zr, f );
    }
}

BOOST_AUTO_TEST_CASE( ZoltanGridMigratorCallBackSignatures ) {
    // This test really passes when the test compiles.
    std::unique_ptr<Zoltan> zoltan( new Zoltan( MPI_COMM_WORLD ) );
    using equelle::ZoltanGridMigrator;

    ZOLTAN_SAFE_CALL( zoltan->Set_Obj_Size_Fn( ZoltanGridMigrator::cellSize, NULL ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Pack_Obj_Fn( ZoltanGridMigrator::packCell, NULL ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Unpack_Obj_Fn( ZoltanGridMigrator::unpackCell, NULL ) );
}

BOOST_AUTO_TEST_CASE( decompose ) {
    equelle::RuntimeMPI runtime;
    runtime.globalGrid.reset( new Opm::GridManager( 6, 2, 5 ) );

    runtime.decompose();

    BOOST_CHECK( runtime.subGrid.global_cell.size() > 0 );
    int numOwnedCells = runtime.subGrid.global_cell.size() - runtime.subGrid.number_of_ghost_cells;

    int totalCells = 0;
    MPI_Reduce( &numOwnedCells, &totalCells, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD );

    if ( equelle::getMPIRank() == 0 ) {
        BOOST_CHECK_EQUAL( totalCells, runtime.globalGrid->c_grid()->number_of_cells );
    }
}

<|endoftext|>