<commit_before>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#pragma once
#include <appbase/application.hpp>
#include <eosio/chain/asset.hpp>
#include <eosio/chain/authority.hpp>
#include <eosio/chain/account_object.hpp>
#include <eosio/chain/block.hpp>
#include <eosio/chain/chain_controller.hpp>
#include <eosio/chain/contracts/contract_table_objects.hpp>
#include <eosio/chain/transaction.hpp>
#include <eosio/chain/contracts/abi_serializer.hpp>

#include <boost/container/flat_set.hpp>

namespace fc { class variant; }

namespace eosio {
   using chain::chain_controller;
   using std::unique_ptr;
   using namespace appbase;
   using chain::name;
   using chain::uint128_t;
   using chain::public_key_type;
   using fc::optional;
   using boost::container::flat_set;
   using chain::asset;
   using chain::authority;
   using chain::account_name;
   using chain::contracts::abi_def;
   using chain::contracts::abi_serializer;

namespace chain_apis {
struct empty{};

struct permission {
   name              perm_name;
   name              parent;
   authority         required_auth;
};

class read_only {
   const chain_controller& db;

public:
   static const string KEYi64;
   static const string KEYstr;
   static const string KEYi128i128;
   static const string KEYi64i64i64;
   static const string PRIMARY;
   static const string SECONDARY;
   static const string TERTIARY;

   read_only(const chain_controller& db)
      : db(db) {}

   using get_info_params = empty;

   struct get_info_results {
      string                  server_version;
      uint32_t                head_block_num = 0;
      uint32_t                last_irreversible_block_num = 0;
      chain::block_id_type    head_block_id;
      fc::time_point_sec      head_block_time;
      account_name            head_block_producer;
      string                  recent_slots;
      double                  participation_rate = 0;
   };
   get_info_results get_info(const get_info_params&) const;

   struct producer_info {
      name                       producer_name;
   };

   struct get_account_results {
      name                       account_name;
      asset                      eos_balance = asset(0,EOS_SYMBOL);
      asset                      staked_balance;
      asset                      unstaking_balance;
      fc::time_point_sec         last_unstaking_time;
      vector<permission>         permissions;
      optional<producer_info>    producer;
   };
   struct get_account_params {
      name account_name;
   };
   get_account_results get_account( const get_account_params& params )const;

   struct get_code_results {
      name                   account_name;
      string                 wast;
      fc::sha256             code_hash;
      optional<abi_def>      abi;
   };

   struct get_code_params {
      name account_name;
   };
   get_code_results get_code( const get_code_params& params )const;

   struct abi_json_to_bin_params {
      name         code;
      name         action;
      fc::variant  args;
   };
   struct abi_json_to_bin_result {
      vector<char>   binargs;
      vector<name>   required_scope;
      vector<name>   required_auth;
   };

   abi_json_to_bin_result abi_json_to_bin( const abi_json_to_bin_params& params )const;

   struct abi_bin_to_json_params {
      name         code;
      name         action;
      vector<char> binargs;
   };
   struct abi_bin_to_json_result {
      fc::variant    args;
      vector<name>   required_scope;
      vector<name>   required_auth;
   };

   abi_bin_to_json_result abi_bin_to_json( const abi_bin_to_json_params& params )const;

   struct get_required_keys_params {
      fc::variant transaction;
      flat_set<public_key_type> available_keys;
   };
   struct get_required_keys_result {
      flat_set<public_key_type> required_keys;
   };

   get_required_keys_result get_required_keys( const get_required_keys_params& params)const;

   struct get_block_params {
      string block_num_or_id;
   };

   struct get_block_results : public chain::signed_block {
      get_block_results( const chain::signed_block& b )
      :signed_block(b),
      id(b.id()),
      block_num(b.block_num()),
      ref_block_prefix( id._hash[1] )
      {}

      chain::block_id_type id;
      uint32_t             block_num = 0;
      uint32_t             ref_block_prefix = 0;
   };

   get_block_results get_block(const get_block_params& params) const;

   struct get_table_rows_params {
      bool        json = false;
      name        scope;
      name        code;
      name        table;
//      string      table_type;
      string      table_key;
      string      lower_bound;
      string      upper_bound;
      uint32_t    limit = 10;
    };

   struct get_table_rows_result {
      vector<fc::variant> rows; ///< one row per item, either encoded as hex String or JSON object
      bool                more; ///< true if last element in data is not the end and sizeof data() < limit
   };

   get_table_rows_result get_table_rows( const get_table_rows_params& params )const;

   void copy_row(const chain::contracts::key_value_object& obj, vector<char>& data)const {
      data.resize( sizeof(uint64_t) + obj.value.size() );
      memcpy( data.data(), &obj.primary_key, sizeof(uint64_t) );
      memcpy( data.data()+sizeof(uint64_t), obj.value.data(), obj.value.size() );
   }

   void copy_row(const chain::contracts::keystr_value_object& obj, vector<char>& data)const {
      data.resize( obj.primary_key.size() + obj.value.size() + 8 );
      fc::datastream<char*> ds(data.data(), data.size());
      fc::raw::pack(ds, obj.primary_key);
      ds.write(obj.value.data(), obj.value.size());
      data.resize(ds.tellp());
   }

   void copy_row(const chain::contracts::key128x128_value_object& obj, vector<char>& data)const {
      data.resize( 2*sizeof(uint128_t) + obj.value.size() );
      memcpy( data.data(), &obj.primary_key, sizeof(uint128_t) );
      memcpy( data.data()+sizeof(uint128_t), &obj.secondary_key, sizeof(uint128_t) );
      memcpy( data.data()+2*sizeof(uint128_t), obj.value.data(), obj.value.size() );
   }

   void copy_row(const chain::contracts::key64x64x64_value_object& obj, vector<char>& data)const {
      data.resize( 3*sizeof(uint64_t) + obj.value.size() );
      memcpy( data.data(), &obj.primary_key, sizeof(uint64_t) );
      memcpy( data.data()+sizeof(uint64_t), &obj.secondary_key, sizeof(uint64_t) );
      memcpy( data.data()+2*sizeof(uint64_t), &obj.tertiary_key, sizeof(uint64_t) );
      memcpy( data.data()+3*sizeof(uint64_t), obj.value.data(), obj.value.size() );
   }

   template <typename IndexType, typename Scope>
   read_only::get_table_rows_result get_table_rows_ex( const read_only::get_table_rows_params& p, const abi_def& abi )const {
      read_only::get_table_rows_result result;
      const auto& d = db.get_database();

      abi_serializer abis;
      abis.set_abi(abi);
      const auto* t_id = d.find<chain::contracts::table_id_object, chain::contracts::by_scope_code_table>(boost::make_tuple(p.scope, p.code, p.table));
      if (t_id != nullptr) {
         const auto &idx = d.get_index<IndexType, Scope>();
         decltype(t_id->id) next_tid(t_id->id._id + 1);
         auto lower = idx.lower_bound(boost::make_tuple(t_id->id));
         auto upper = idx.lower_bound(boost::make_tuple(next_tid));

         if (p.lower_bound.size()) {
            lower = idx.lower_bound(boost::make_tuple(t_id->id, fc::variant(
               p.lower_bound).as<typename IndexType::value_type::key_type>()));
         }
         if (p.upper_bound.size()) {
            upper = idx.lower_bound(boost::make_tuple(t_id->id, fc::variant(
               p.upper_bound).as<typename IndexType::value_type::key_type>()));
         }

         vector<char> data;

         auto end = fc::time_point::now() + fc::microseconds(1000 * 10); /// 10ms max time

         unsigned int count = 0;
         auto itr = lower;
         for (itr = lower; itr != upper; ++itr) {
            copy_row(*itr, data);

            if (p.json) {
               result.rows.emplace_back(abis.binary_to_variant(abis.get_table_type(p.table), data));
            } else {
               result.rows.emplace_back(fc::variant(data));
            }

            if (++count == p.limit || fc::time_point::now() > end) {
               break;
            }
         }
         if (itr != upper) {
            result.more = true;
         }
      }
      return result;
   }

};

class read_write {
   chain_controller& db;
   uint32_t skip_flags;
public:
   read_write(chain_controller& db, uint32_t skip_flags) : db(db), skip_flags(skip_flags) {}

   using push_block_params = chain::signed_block;
   using push_block_results = empty;
   push_block_results push_block(const push_block_params& params);

   using push_transaction_params = fc::variant_object;
   struct push_transaction_results {
      chain::transaction_id_type  transaction_id;
      fc::variant                 processed;
   };
   push_transaction_results push_transaction(const push_transaction_params& params);

   using push_transactions_params  = vector<push_transaction_params>;
   using push_transactions_results = vector<push_transaction_results>;
   push_transactions_results push_transactions(const push_transactions_params& params);
};
} // namespace chain_apis

class chain_plugin : public plugin<chain_plugin> {
public:
   APPBASE_PLUGIN_REQUIRES()

   chain_plugin();
   virtual ~chain_plugin();

   virtual void set_program_options(options_description& cli, options_description& cfg) override;

   void plugin_initialize(const variables_map& options);
   void plugin_startup();
   void plugin_shutdown();

   chain_apis::read_only get_read_only_api() const { return chain_apis::read_only(chain()); }
   chain_apis::read_write get_read_write_api();

   bool accept_block(const chain::signed_block& block, bool currently_syncing);
   void accept_transaction(const chain::signed_transaction& trx);

   bool block_is_on_preferred_chain(const chain::block_id_type& block_id);

   // return true if --skip-transaction-signatures passed to eosd
   bool is_skipping_transaction_signatures() const;

   // Only call this in plugin_initialize() to modify chain_controller constructor configuration
   chain_controller::controller_config& chain_config();
   // Only call this after plugin_startup()!
   chain_controller& chain();
   // Only call this after plugin_startup()!
   const chain_controller& chain() const;

  void get_chain_id (chain::chain_id_type &cid) const;

  static const uint32_t            default_received_block_transaction_execution_time;
  static const uint32_t            default_transaction_execution_time;
  static const uint32_t            default_create_block_transaction_execution_time;

private:
   unique_ptr<class chain_plugin_impl> my;
};

}

FC_REFLECT( eosio::chain_apis::permission, (perm_name)(parent)(required_auth) )
FC_REFLECT(eosio::chain_apis::empty, )
FC_REFLECT(eosio::chain_apis::read_only::get_info_results,
  (server_version)(head_block_num)(last_irreversible_block_num)(head_block_id)(head_block_time)(head_block_producer)
  (recent_slots)(participation_rate))
FC_REFLECT(eosio::chain_apis::read_only::get_block_params, (block_num_or_id))

FC_REFLECT_DERIVED( eosio::chain_apis::read_only::get_block_results, (eosio::chain::signed_block), (id)(block_num)(ref_block_prefix) );
FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) )

FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(table_key)(scope)(code)(table)(lower_bound)(upper_bound)(limit) )
FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more) );

FC_REFLECT( eosio::chain_apis::read_only::get_account_results, (account_name)(eos_balance)(staked_balance)(unstaking_balance)(last_unstaking_time)(permissions)(producer) )
FC_REFLECT( eosio::chain_apis::read_only::get_code_results, (account_name)(code_hash)(wast)(abi) )
FC_REFLECT( eosio::chain_apis::read_only::get_account_params, (account_name) )
FC_REFLECT( eosio::chain_apis::read_only::get_code_params, (account_name) )
FC_REFLECT( eosio::chain_apis::read_only::producer_info, (producer_name) )
FC_REFLECT( eosio::chain_apis::read_only::abi_json_to_bin_params, (code)(action)(args) )
FC_REFLECT( eosio::chain_apis::read_only::abi_json_to_bin_result, (binargs)(required_scope)(required_auth) )
FC_REFLECT( eosio::chain_apis::read_only::abi_bin_to_json_params, (code)(action)(binargs) )
FC_REFLECT( eosio::chain_apis::read_only::abi_bin_to_json_result, (args)(required_scope)(required_auth) )
FC_REFLECT( eosio::chain_apis::read_only::get_required_keys_params, (transaction)(available_keys) )
FC_REFLECT( eosio::chain_apis::read_only::get_required_keys_result, (required_keys) )
<commit_msg>Update FC_REFLECT get_table_rows_params to match struct declaration. #1139<commit_after>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#pragma once
#include <appbase/application.hpp>
#include <eosio/chain/asset.hpp>
#include <eosio/chain/authority.hpp>
#include <eosio/chain/account_object.hpp>
#include <eosio/chain/block.hpp>
#include <eosio/chain/chain_controller.hpp>
#include <eosio/chain/contracts/contract_table_objects.hpp>
#include <eosio/chain/transaction.hpp>
#include <eosio/chain/contracts/abi_serializer.hpp>

#include <boost/container/flat_set.hpp>

namespace fc { class variant; }

namespace eosio {
   using chain::chain_controller;
   using std::unique_ptr;
   using namespace appbase;
   using chain::name;
   using chain::uint128_t;
   using chain::public_key_type;
   using fc::optional;
   using boost::container::flat_set;
   using chain::asset;
   using chain::authority;
   using chain::account_name;
   using chain::contracts::abi_def;
   using chain::contracts::abi_serializer;

namespace chain_apis {
struct empty{};

struct permission {
   name              perm_name;
   name              parent;
   authority         required_auth;
};

class read_only {
   const chain_controller& db;

public:
   static const string KEYi64;
   static const string KEYstr;
   static const string KEYi128i128;
   static const string KEYi64i64i64;
   static const string PRIMARY;
   static const string SECONDARY;
   static const string TERTIARY;

   read_only(const chain_controller& db)
      : db(db) {}

   using get_info_params = empty;

   struct get_info_results {
      string                  server_version;
      uint32_t                head_block_num = 0;
      uint32_t                last_irreversible_block_num = 0;
      chain::block_id_type    head_block_id;
      fc::time_point_sec      head_block_time;
      account_name            head_block_producer;
      string                  recent_slots;
      double                  participation_rate = 0;
   };
   get_info_results get_info(const get_info_params&) const;

   struct producer_info {
      name                       producer_name;
   };

   struct get_account_results {
      name                       account_name;
      asset                      eos_balance = asset(0,EOS_SYMBOL);
      asset                      staked_balance;
      asset                      unstaking_balance;
      fc::time_point_sec         last_unstaking_time;
      vector<permission>         permissions;
      optional<producer_info>    producer;
   };
   struct get_account_params {
      name account_name;
   };
   get_account_results get_account( const get_account_params& params )const;

   struct get_code_results {
      name                   account_name;
      string                 wast;
      fc::sha256             code_hash;
      optional<abi_def>      abi;
   };

   struct get_code_params {
      name account_name;
   };
   get_code_results get_code( const get_code_params& params )const;

   struct abi_json_to_bin_params {
      name         code;
      name         action;
      fc::variant  args;
   };
   struct abi_json_to_bin_result {
      vector<char>   binargs;
      vector<name>   required_scope;
      vector<name>   required_auth;
   };

   abi_json_to_bin_result abi_json_to_bin( const abi_json_to_bin_params& params )const;

   struct abi_bin_to_json_params {
      name         code;
      name         action;
      vector<char> binargs;
   };
   struct abi_bin_to_json_result {
      fc::variant    args;
      vector<name>   required_scope;
      vector<name>   required_auth;
   };

   abi_bin_to_json_result abi_bin_to_json( const abi_bin_to_json_params& params )const;

   struct get_required_keys_params {
      fc::variant transaction;
      flat_set<public_key_type> available_keys;
   };
   struct get_required_keys_result {
      flat_set<public_key_type> required_keys;
   };

   get_required_keys_result get_required_keys( const get_required_keys_params& params)const;

   struct get_block_params {
      string block_num_or_id;
   };

   struct get_block_results : public chain::signed_block {
      get_block_results( const chain::signed_block& b )
      :signed_block(b),
      id(b.id()),
      block_num(b.block_num()),
      ref_block_prefix( id._hash[1] )
      {}

      chain::block_id_type id;
      uint32_t             block_num = 0;
      uint32_t             ref_block_prefix = 0;
   };

   get_block_results get_block(const get_block_params& params) const;

   struct get_table_rows_params {
      bool        json = false;
      name        scope;
      name        code;
      name        table;
//      string      table_type;
      string      table_key;
      string      lower_bound;
      string      upper_bound;
      uint32_t    limit = 10;
    };

   struct get_table_rows_result {
      vector<fc::variant> rows; ///< one row per item, either encoded as hex String or JSON object
      bool                more = false; ///< true if last element in data is not the end and sizeof data() < limit
   };

   get_table_rows_result get_table_rows( const get_table_rows_params& params )const;

   void copy_row(const chain::contracts::key_value_object& obj, vector<char>& data)const {
      data.resize( sizeof(uint64_t) + obj.value.size() );
      memcpy( data.data(), &obj.primary_key, sizeof(uint64_t) );
      memcpy( data.data()+sizeof(uint64_t), obj.value.data(), obj.value.size() );
   }

   void copy_row(const chain::contracts::keystr_value_object& obj, vector<char>& data)const {
      data.resize( obj.primary_key.size() + obj.value.size() + 8 );
      fc::datastream<char*> ds(data.data(), data.size());
      fc::raw::pack(ds, obj.primary_key);
      ds.write(obj.value.data(), obj.value.size());
      data.resize(ds.tellp());
   }

   void copy_row(const chain::contracts::key128x128_value_object& obj, vector<char>& data)const {
      data.resize( 2*sizeof(uint128_t) + obj.value.size() );
      memcpy( data.data(), &obj.primary_key, sizeof(uint128_t) );
      memcpy( data.data()+sizeof(uint128_t), &obj.secondary_key, sizeof(uint128_t) );
      memcpy( data.data()+2*sizeof(uint128_t), obj.value.data(), obj.value.size() );
   }

   void copy_row(const chain::contracts::key64x64x64_value_object& obj, vector<char>& data)const {
      data.resize( 3*sizeof(uint64_t) + obj.value.size() );
      memcpy( data.data(), &obj.primary_key, sizeof(uint64_t) );
      memcpy( data.data()+sizeof(uint64_t), &obj.secondary_key, sizeof(uint64_t) );
      memcpy( data.data()+2*sizeof(uint64_t), &obj.tertiary_key, sizeof(uint64_t) );
      memcpy( data.data()+3*sizeof(uint64_t), obj.value.data(), obj.value.size() );
   }

   template <typename IndexType, typename Scope>
   read_only::get_table_rows_result get_table_rows_ex( const read_only::get_table_rows_params& p, const abi_def& abi )const {
      read_only::get_table_rows_result result;
      const auto& d = db.get_database();

      abi_serializer abis;
      abis.set_abi(abi);
      const auto* t_id = d.find<chain::contracts::table_id_object, chain::contracts::by_scope_code_table>(boost::make_tuple(p.scope, p.code, p.table));
      if (t_id != nullptr) {
         const auto &idx = d.get_index<IndexType, Scope>();
         decltype(t_id->id) next_tid(t_id->id._id + 1);
         auto lower = idx.lower_bound(boost::make_tuple(t_id->id));
         auto upper = idx.lower_bound(boost::make_tuple(next_tid));

         if (p.lower_bound.size()) {
            lower = idx.lower_bound(boost::make_tuple(t_id->id, fc::variant(
               p.lower_bound).as<typename IndexType::value_type::key_type>()));
         }
         if (p.upper_bound.size()) {
            upper = idx.lower_bound(boost::make_tuple(t_id->id, fc::variant(
               p.upper_bound).as<typename IndexType::value_type::key_type>()));
         }

         vector<char> data;

         auto end = fc::time_point::now() + fc::microseconds(1000 * 10); /// 10ms max time

         unsigned int count = 0;
         auto itr = lower;
         for (itr = lower; itr != upper; ++itr) {
            copy_row(*itr, data);

            if (p.json) {
               result.rows.emplace_back(abis.binary_to_variant(abis.get_table_type(p.table), data));
            } else {
               result.rows.emplace_back(fc::variant(data));
            }

            if (++count == p.limit || fc::time_point::now() > end) {
               break;
            }
         }
         if (itr != upper) {
            result.more = true;
         }
      }
      return result;
   }

};

class read_write {
   chain_controller& db;
   uint32_t skip_flags;
public:
   read_write(chain_controller& db, uint32_t skip_flags) : db(db), skip_flags(skip_flags) {}

   using push_block_params = chain::signed_block;
   using push_block_results = empty;
   push_block_results push_block(const push_block_params& params);

   using push_transaction_params = fc::variant_object;
   struct push_transaction_results {
      chain::transaction_id_type  transaction_id;
      fc::variant                 processed;
   };
   push_transaction_results push_transaction(const push_transaction_params& params);

   using push_transactions_params  = vector<push_transaction_params>;
   using push_transactions_results = vector<push_transaction_results>;
   push_transactions_results push_transactions(const push_transactions_params& params);
};
} // namespace chain_apis

class chain_plugin : public plugin<chain_plugin> {
public:
   APPBASE_PLUGIN_REQUIRES()

   chain_plugin();
   virtual ~chain_plugin();

   virtual void set_program_options(options_description& cli, options_description& cfg) override;

   void plugin_initialize(const variables_map& options);
   void plugin_startup();
   void plugin_shutdown();

   chain_apis::read_only get_read_only_api() const { return chain_apis::read_only(chain()); }
   chain_apis::read_write get_read_write_api();

   bool accept_block(const chain::signed_block& block, bool currently_syncing);
   void accept_transaction(const chain::signed_transaction& trx);

   bool block_is_on_preferred_chain(const chain::block_id_type& block_id);

   // return true if --skip-transaction-signatures passed to eosd
   bool is_skipping_transaction_signatures() const;

   // Only call this in plugin_initialize() to modify chain_controller constructor configuration
   chain_controller::controller_config& chain_config();
   // Only call this after plugin_startup()!
   chain_controller& chain();
   // Only call this after plugin_startup()!
   const chain_controller& chain() const;

  void get_chain_id (chain::chain_id_type &cid) const;

  static const uint32_t            default_received_block_transaction_execution_time;
  static const uint32_t            default_transaction_execution_time;
  static const uint32_t            default_create_block_transaction_execution_time;

private:
   unique_ptr<class chain_plugin_impl> my;
};

}

FC_REFLECT( eosio::chain_apis::permission, (perm_name)(parent)(required_auth) )
FC_REFLECT(eosio::chain_apis::empty, )
FC_REFLECT(eosio::chain_apis::read_only::get_info_results,
  (server_version)(head_block_num)(last_irreversible_block_num)(head_block_id)(head_block_time)(head_block_producer)
  (recent_slots)(participation_rate))
FC_REFLECT(eosio::chain_apis::read_only::get_block_params, (block_num_or_id))

FC_REFLECT_DERIVED( eosio::chain_apis::read_only::get_block_results, (eosio::chain::signed_block), (id)(block_num)(ref_block_prefix) );
FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) )

FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(scope)(code)(table)(table_key)(lower_bound)(upper_bound)(limit) )
FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more) );

FC_REFLECT( eosio::chain_apis::read_only::get_account_results, (account_name)(eos_balance)(staked_balance)(unstaking_balance)(last_unstaking_time)(permissions)(producer) )
FC_REFLECT( eosio::chain_apis::read_only::get_code_results, (account_name)(code_hash)(wast)(abi) )
FC_REFLECT( eosio::chain_apis::read_only::get_account_params, (account_name) )
FC_REFLECT( eosio::chain_apis::read_only::get_code_params, (account_name) )
FC_REFLECT( eosio::chain_apis::read_only::producer_info, (producer_name) )
FC_REFLECT( eosio::chain_apis::read_only::abi_json_to_bin_params, (code)(action)(args) )
FC_REFLECT( eosio::chain_apis::read_only::abi_json_to_bin_result, (binargs)(required_scope)(required_auth) )
FC_REFLECT( eosio::chain_apis::read_only::abi_bin_to_json_params, (code)(action)(binargs) )
FC_REFLECT( eosio::chain_apis::read_only::abi_bin_to_json_result, (args)(required_scope)(required_auth) )
FC_REFLECT( eosio::chain_apis::read_only::get_required_keys_params, (transaction)(available_keys) )
FC_REFLECT( eosio::chain_apis::read_only::get_required_keys_result, (required_keys) )
<|endoftext|>


<commit_before>// Copyright 2015 Matt Heard
// http://mattheard.net
// matt@mattheard.net
// @mattheard

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

int main(int argc, char **argv) {
    using std::string;
    const int expectedNumArgs = 2;
    if (argc != expectedNumArgs) {
        const string cmdName = "ConvertToGrey";
        const string argsDesc = " <Image_Path>";
        std::cout << "Usage: " << cmdName << argsDesc << std::endl;
        return -1;
    }
    const string inputFilename = argv[1];
    const cv::Mat srcImg = cv::imread(inputFilename);
    if (!srcImg.data) {
        const string err = "No image data";
        std::cerr << err << std::cout;
        return -1;
    }
    return 0;
}
<commit_msg>Update args list desc<commit_after>// Copyright 2015 Matt Heard
// http://mattheard.net
// matt@mattheard.net
// @mattheard

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

int main(int argc, char **argv) {
    using std::string;
    const int expectedNumArgs = 3;
    if (argc != expectedNumArgs) {
        const string cmdName = "ConvertToGrey";
        const string argsDesc = " <Image_Path> <Reduce_By>";
        std::cout << "Usage: " << cmdName << argsDesc << std::endl;
        return -1;
    }
    const string inputFilename = argv[1];
    const cv::Mat srcImg = cv::imread(inputFilename);
    if (!srcImg.data) {
        const string err = "No image data";
        std::cerr << err << std::cout;
        return -1;
    }
    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2015 Matt Heard
// http://mattheard.net
// matt@mattheard.net
// @mattheard

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

using cv::Mat;

Mat buildLookUpTable(const int divideWith) {
    const int rows = 1;
    const int cols = 256;
    const int type = CV_8U;
    const Mat table(rows, cols, type);
    for (int i = 0; i < 256; ++i) {
        const int reduced = divideWith * (i / divideWith);
        table.data[i] = (uchar) reduced;
    }
    return table;
}

int main(int argc, char **argv) {
    using std::string;
    const int expectedNumArgs = 3;
    if (argc != expectedNumArgs) {
        const string cmdName = "ConvertToGrey";
        const string argsDesc = " <Image_Path> <Reduce_By>";
        std::cout << "Usage: " << cmdName << argsDesc << std::endl;
        return -1;
    }
    const string inputFilename = argv[1];
    const Mat srcImg = cv::imread(inputFilename);
    if (!srcImg.data) {
        const string err = "No image data";
        std::cerr << err << std::endl;
        return -1;
    }
    const int divideWith = atoi(argv[2]);
    if (divideWith < 1) {
        std::cout << "Invalid number entered for dividing." << std::endl;
        return -1;
    }
    const Mat lookUpTable = buildLookUpTable(divideWith);
    Mat dstImg;
    LUT(srcImg, lookUpTable, dstImg);
    const string outputFilename = "reduced.jpg";
    imwrite(outputFilename, dstImg);
    return 0;
}
<commit_msg>Correct usage msg<commit_after>// Copyright 2015 Matt Heard
// http://mattheard.net
// matt@mattheard.net
// @mattheard

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

using cv::Mat;

Mat buildLookUpTable(const int divideWith) {
    const int rows = 1;
    const int cols = 256;
    const int type = CV_8U;
    const Mat table(rows, cols, type);
    for (int i = 0; i < 256; ++i) {
        const int reduced = divideWith * (i / divideWith);
        table.data[i] = (uchar) reduced;
    }
    return table;
}

int main(int argc, char **argv) {
    using std::string;
    const int expectedNumArgs = 3;
    if (argc != expectedNumArgs) {
        const string cmdName = "ReduceColours";
        const string argsDesc = " <Image_Path> <Reduce_By>";
        std::cout << "Usage: " << cmdName << argsDesc << std::endl;
        return -1;
    }
    const string inputFilename = argv[1];
    const Mat srcImg = cv::imread(inputFilename);
    if (!srcImg.data) {
        const string err = "No image data";
        std::cerr << err << std::endl;
        return -1;
    }
    const int divideWith = atoi(argv[2]);
    if (divideWith < 1) {
        std::cout << "Invalid number entered for dividing." << std::endl;
        return -1;
    }
    const Mat lookUpTable = buildLookUpTable(divideWith);
    Mat dstImg;
    LUT(srcImg, lookUpTable, dstImg);
    const string outputFilename = "reduced.jpg";
    imwrite(outputFilename, dstImg);
    return 0;
}
<|endoftext|>


<commit_before>/*
** Copyright 2012 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#ifndef CCB_TIMESTAMP_HH
#  define CCB_TIMESTAMP_HH

#  include <ctime>
#  include <istream>
#  include "com/centreon/broker/namespace.hh"

CCB_BEGIN()

/**
 *  @class timestamp timestamp.hh "com/centreon/broker/timestamp.hh"
 *  @brief Timestamp class.
 *
 *  Holds the time.
 */
struct        timestamp {
public:
  /**
   *  Default constructor.
   *
   *  Time is not defined.
   */
              timestamp() : _sec((time_t)-1) {}

  /**
   *  Build from a time_t.
   *
   *  @param[in] t Time expressed in time_t.
   */
              timestamp(std::time_t t) : _sec(t) {}

  /**
   *  Copy constructor.
   *
   *  @param[in] right Object to copy.
   */
              timestamp(timestamp const& right) : _sec(right._sec) {}

  /**
   *  Destructor.
   */
              ~timestamp() {}

  /**
   *  Assignment operator.
   *
   *  @param[in] right Object to copy.
   *
   *  @return This object.
   */
  timestamp&  operator=(timestamp const& right) {
    if (this != &right)
      _sec = right._sec;
    return (*this);
  }

  /**
   *  Get timestamp as time_t.
   *
   *  @return Timestamp as time_t.
   */
              operator std::time_t() const {
    return (_sec);
  }

  /**
   *  Get timestamp as time_t.
   *
   *  @return Timestamp as time_t.
   */
  std::time_t get_time_t() const {
    return (_sec);
  }

  /**
   *  Is this a null timestamp ?
   *
   *  @return  True if this is a null timestamp.
   */
  bool is_null() const {
    return (_sec == (time_t)-1);
  }

  /**
   *  Clear the timestamp.
   */
  void clear() {
    _sec = (time_t)-1;
  }

  /**
   *  Comparison function.
   *
   *  @param[in] left   The left object.
   *  @param[in] right  The right object.
   *
   *  @return           True if this object is less than the other.
   */
  static bool less(timestamp const& left, timestamp const& right) {
    if (left.is_null() && !right.is_null())
      return (false);
    else if (!left.is_null() && right.is_null())
      return (true);
    else
      return (left._sec < right._sec);
  }

  /**
   *  Return a timestamp from now.
   *
   *  @return  A timestamp set to present time, present day.
   */
  static timestamp now() {
    return (::time(NULL));
  }

  static timestamp max() {
    return (timestamp());
  }

  // Data.
  std::time_t _sec;
};

/**
 *  Stream operator for timestamp.
 *
 *  @param[in] stream  The stream.
 *  @param[in] ts      The timestamp.
 *
 *  @return            Reference to the stream.
 */
inline std::istream& operator>>(std::istream& stream, timestamp& ts) {
  std::time_t s;
  stream >> s;
  ts = timestamp(s);
  return (stream);
}

CCB_END()

#endif // !CCB_TIMESTAMP_HH
<commit_msg>core: make 0 an invalid timestamp value.<commit_after>/*
** Copyright 2012,2015-2016 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#ifndef CCB_TIMESTAMP_HH
#  define CCB_TIMESTAMP_HH

#  include <ctime>
#  include <istream>
#  include "com/centreon/broker/namespace.hh"

CCB_BEGIN()

/**
 *  @class timestamp timestamp.hh "com/centreon/broker/timestamp.hh"
 *  @brief Timestamp class.
 *
 *  Holds the time.
 */
struct        timestamp {
public:
  /**
   *  Default constructor.
   *
   *  Time is not defined.
   */
              timestamp() : _sec((time_t)-1) {}

  /**
   *  Build from a time_t.
   *
   *  @param[in] t Time expressed in time_t.
   */
              timestamp(std::time_t t) : _sec(t) {}

  /**
   *  Copy constructor.
   *
   *  @param[in] right Object to copy.
   */
              timestamp(timestamp const& right) : _sec(right._sec) {}

  /**
   *  Destructor.
   */
              ~timestamp() {}

  /**
   *  Assignment operator.
   *
   *  @param[in] right Object to copy.
   *
   *  @return This object.
   */
  timestamp&  operator=(timestamp const& right) {
    if (this != &right)
      _sec = right._sec;
    return (*this);
  }

  /**
   *  Get timestamp as time_t.
   *
   *  @return Timestamp as time_t.
   */
              operator std::time_t() const {
    return (_sec);
  }

  /**
   *  Get timestamp as time_t.
   *
   *  @return Timestamp as time_t.
   */
  std::time_t get_time_t() const {
    return (_sec);
  }

  /**
   *  Is this a null timestamp ?
   *
   *  @return  True if this is a null timestamp.
   */
  bool is_null() const {
    return ((_sec == (time_t)-1)
            || (_sec == (time_t)0));
  }

  /**
   *  Clear the timestamp.
   */
  void clear() {
    _sec = (time_t)-1;
  }

  /**
   *  Comparison function.
   *
   *  @param[in] left   The left object.
   *  @param[in] right  The right object.
   *
   *  @return           True if this object is less than the other.
   */
  static bool less(timestamp const& left, timestamp const& right) {
    if (left.is_null() && !right.is_null())
      return (false);
    else if (!left.is_null() && right.is_null())
      return (true);
    else
      return (left._sec < right._sec);
  }

  /**
   *  Return a timestamp from now.
   *
   *  @return  A timestamp set to present time, present day.
   */
  static timestamp now() {
    return (::time(NULL));
  }

  static timestamp max() {
    return (timestamp());
  }

  // Data.
  std::time_t _sec;
};

/**
 *  Stream operator for timestamp.
 *
 *  @param[in] stream  The stream.
 *  @param[in] ts      The timestamp.
 *
 *  @return            Reference to the stream.
 */
inline std::istream& operator>>(std::istream& stream, timestamp& ts) {
  std::time_t s;
  stream >> s;
  ts = timestamp(s);
  return (stream);
}

CCB_END()

#endif // !CCB_TIMESTAMP_HH
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.
 */

/*
 * Zip alignment tool
 */
#include "ZipFile.h"

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

using namespace android;

/*
 * Show program usage.
 */
void usage(void)
{
    fprintf(stderr, "Zip alignment utility\n");
    fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
    fprintf(stderr,
        "Usage: zipalign [-f] [-v] <align> infile.zip outfile.zip\n"
        "       zipalign -c [-v] <align> infile.zip\n\n" );
    fprintf(stderr,
        "  <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
    fprintf(stderr, "  -c: check alignment only (does not modify file)\n");
    fprintf(stderr, "  -f: overwrite existing outfile.zip\n");
    fprintf(stderr, "  -v: verbose output\n");
}

/*
 * Copy all entries from "pZin" to "pZout", aligning as needed.
 */
static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment)
{
    int numEntries = pZin->getNumEntries();
    ZipEntry* pEntry;
    int bias = 0;
    status_t status;

    for (int i = 0; i < numEntries; i++) {
        ZipEntry* pNewEntry;
        int padding = 0;

        pEntry = pZin->getEntryByIndex(i);
        if (pEntry == NULL) {
            fprintf(stderr, "ERROR: unable to retrieve entry %d\n", i);
            return 1;
        }

        if (pEntry->isCompressed()) {
            /* copy the entry without padding */
            //printf("--- %s: orig at %ld len=%ld (compressed)\n",
            //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
            //    (long) pEntry->getUncompressedLen());

        } else {
            /*
             * Copy the entry, adjusting as required.  We assume that the
             * file position in the new file will be equal to the file
             * position in the original.
             */
            long newOffset = pEntry->getFileOffset() + bias;
            padding = (alignment - (newOffset % alignment)) % alignment;

            //printf("--- %s: orig at %ld(+%d) len=%ld, adding pad=%d\n",
            //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
            //    bias, (long) pEntry->getUncompressedLen(), padding);
        }

        status = pZout->add(pZin, pEntry, padding, &pNewEntry);
        if (status != NO_ERROR)
            return 1;
        bias += padding;
        //printf(" added '%s' at %ld (pad=%d)\n",
        //    pNewEntry->getFileName(), (long) pNewEntry->getFileOffset(),
        //    padding);
    }

    return 0;
}

/*
 * Process a file.  We open the input and output files, failing if the
 * output file exists and "force" wasn't specified.
 */
static int process(const char* inFileName, const char* outFileName,
    int alignment, bool force)
{
    ZipFile zin, zout;

    //printf("PROCESS: align=%d in='%s' out='%s' force=%d\n",
    //    alignment, inFileName, outFileName, force);

    /* this mode isn't supported -- do a trivial check */
    if (strcmp(inFileName, outFileName) == 0) {
        fprintf(stderr, "Input and output can't be same file\n");
        return 1;
    }

    /* don't overwrite existing unless given permission */
    if (!force && access(outFileName, F_OK) == 0) {
        fprintf(stderr, "Output file '%s' exists\n", outFileName);
        return 1;
    }

    if (zin.open(inFileName, ZipFile::kOpenReadOnly) != NO_ERROR) {
        fprintf(stderr, "Unable to open '%s' as zip archive\n", inFileName);
        return 1;
    }
    if (zout.open(outFileName,
            ZipFile::kOpenReadWrite|ZipFile::kOpenCreate|ZipFile::kOpenTruncate)
        != NO_ERROR)
    {
        fprintf(stderr, "Unable to open '%s' as zip archive\n", inFileName);
        return 1;
    }

    int result = copyAndAlign(&zin, &zout, alignment);
    if (result != 0) {
        printf("zipalign: failed rewriting '%s' to '%s'\n",
            inFileName, outFileName);
    }
    return result;
}

/*
 * Verify the alignment of a zip archive.
 */
static int verify(const char* fileName, int alignment, bool verbose)
{
    ZipFile zipFile;
    bool foundBad = false;

    if (verbose)
        printf("Verifying alignment of %s (%d)...\n", fileName, alignment);

    if (zipFile.open(fileName, ZipFile::kOpenReadOnly) != NO_ERROR) {
        fprintf(stderr, "Unable to open '%s' for verification\n", fileName);
        return 1;
    }

    int numEntries = zipFile.getNumEntries();
    ZipEntry* pEntry;

    for (int i = 0; i < numEntries; i++) {
        pEntry = zipFile.getEntryByIndex(i);
        if (pEntry->isCompressed()) {
            if (verbose) {
                printf("%8ld %s (OK - compressed)\n",
                    (long) pEntry->getFileOffset(), pEntry->getFileName());
            }
        } else {
            long offset = pEntry->getFileOffset();
            if ((offset % alignment) != 0) {
                if (verbose) {
                    printf("%8ld %s (BAD - %ld)\n",
                        (long) offset, pEntry->getFileName(),
                        offset % alignment);
                }
                foundBad = true;
            } else {
                if (verbose) {
                    printf("%8ld %s (OK)\n",
                        (long) offset, pEntry->getFileName());
                }
            }
        }
    }

    if (verbose)
        printf("Verification %s\n", foundBad ? "FAILED" : "succesful");

    return foundBad ? 1 : 0;
}

/*
 * Parse args.
 */
int main(int argc, char* const argv[])
{
    bool wantUsage = false;
    bool check = false;
    bool force = false;
    bool verbose = false;
    int result = 1;
    int alignment;
    char* endp;

    if (argc < 4) {
        wantUsage = true;
        goto bail;
    }

    argc--;
    argv++;

    while (argc && argv[0][0] == '-') {
        const char* cp = argv[0] +1;

        while (*cp != '\0') {
            switch (*cp) {
            case 'c':
                check = true;
                break;
            case 'f':
                force = true;
                break;
            case 'v':
                verbose = true;
                break;
            default:
                fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
                wantUsage = true;
                goto bail;
            }

            cp++;
        }

        argc--;
        argv++;
    }

    if (!((check && argc == 2) || (!check && argc == 3))) {
        wantUsage = true;
        goto bail;
    }

    alignment = strtol(argv[0], &endp, 10);
    if (*endp != '\0' || alignment <= 0) {
        fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
        wantUsage = true;
        goto bail;
    }

    if (check) {
        /* check existing archive for correct alignment */
        result = verify(argv[1], alignment, verbose);
    } else {
        /* create the new archive */
        result = process(argv[1], argv[2], alignment, force);

        /* trust, but verify */
        if (result == 0)
            result = verify(argv[2], alignment, verbose);
    }

bail:
    if (wantUsage) {
        usage();
        result = 2;
    }

    return result;
}
<commit_msg>Fix reporting wrong error message for zipalign output file<commit_after>/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.
 */

/*
 * Zip alignment tool
 */
#include "ZipFile.h"

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

using namespace android;

/*
 * Show program usage.
 */
void usage(void)
{
    fprintf(stderr, "Zip alignment utility\n");
    fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
    fprintf(stderr,
        "Usage: zipalign [-f] [-v] <align> infile.zip outfile.zip\n"
        "       zipalign -c [-v] <align> infile.zip\n\n" );
    fprintf(stderr,
        "  <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
    fprintf(stderr, "  -c: check alignment only (does not modify file)\n");
    fprintf(stderr, "  -f: overwrite existing outfile.zip\n");
    fprintf(stderr, "  -v: verbose output\n");
}

/*
 * Copy all entries from "pZin" to "pZout", aligning as needed.
 */
static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment)
{
    int numEntries = pZin->getNumEntries();
    ZipEntry* pEntry;
    int bias = 0;
    status_t status;

    for (int i = 0; i < numEntries; i++) {
        ZipEntry* pNewEntry;
        int padding = 0;

        pEntry = pZin->getEntryByIndex(i);
        if (pEntry == NULL) {
            fprintf(stderr, "ERROR: unable to retrieve entry %d\n", i);
            return 1;
        }

        if (pEntry->isCompressed()) {
            /* copy the entry without padding */
            //printf("--- %s: orig at %ld len=%ld (compressed)\n",
            //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
            //    (long) pEntry->getUncompressedLen());

        } else {
            /*
             * Copy the entry, adjusting as required.  We assume that the
             * file position in the new file will be equal to the file
             * position in the original.
             */
            long newOffset = pEntry->getFileOffset() + bias;
            padding = (alignment - (newOffset % alignment)) % alignment;

            //printf("--- %s: orig at %ld(+%d) len=%ld, adding pad=%d\n",
            //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
            //    bias, (long) pEntry->getUncompressedLen(), padding);
        }

        status = pZout->add(pZin, pEntry, padding, &pNewEntry);
        if (status != NO_ERROR)
            return 1;
        bias += padding;
        //printf(" added '%s' at %ld (pad=%d)\n",
        //    pNewEntry->getFileName(), (long) pNewEntry->getFileOffset(),
        //    padding);
    }

    return 0;
}

/*
 * Process a file.  We open the input and output files, failing if the
 * output file exists and "force" wasn't specified.
 */
static int process(const char* inFileName, const char* outFileName,
    int alignment, bool force)
{
    ZipFile zin, zout;

    //printf("PROCESS: align=%d in='%s' out='%s' force=%d\n",
    //    alignment, inFileName, outFileName, force);

    /* this mode isn't supported -- do a trivial check */
    if (strcmp(inFileName, outFileName) == 0) {
        fprintf(stderr, "Input and output can't be same file\n");
        return 1;
    }

    /* don't overwrite existing unless given permission */
    if (!force && access(outFileName, F_OK) == 0) {
        fprintf(stderr, "Output file '%s' exists\n", outFileName);
        return 1;
    }

    if (zin.open(inFileName, ZipFile::kOpenReadOnly) != NO_ERROR) {
        fprintf(stderr, "Unable to open '%s' as zip archive\n", inFileName);
        return 1;
    }
    if (zout.open(outFileName,
            ZipFile::kOpenReadWrite|ZipFile::kOpenCreate|ZipFile::kOpenTruncate)
        != NO_ERROR)
    {
        fprintf(stderr, "Unable to open '%s' as zip archive\n", outFileName);
        return 1;
    }

    int result = copyAndAlign(&zin, &zout, alignment);
    if (result != 0) {
        printf("zipalign: failed rewriting '%s' to '%s'\n",
            inFileName, outFileName);
    }
    return result;
}

/*
 * Verify the alignment of a zip archive.
 */
static int verify(const char* fileName, int alignment, bool verbose)
{
    ZipFile zipFile;
    bool foundBad = false;

    if (verbose)
        printf("Verifying alignment of %s (%d)...\n", fileName, alignment);

    if (zipFile.open(fileName, ZipFile::kOpenReadOnly) != NO_ERROR) {
        fprintf(stderr, "Unable to open '%s' for verification\n", fileName);
        return 1;
    }

    int numEntries = zipFile.getNumEntries();
    ZipEntry* pEntry;

    for (int i = 0; i < numEntries; i++) {
        pEntry = zipFile.getEntryByIndex(i);
        if (pEntry->isCompressed()) {
            if (verbose) {
                printf("%8ld %s (OK - compressed)\n",
                    (long) pEntry->getFileOffset(), pEntry->getFileName());
            }
        } else {
            long offset = pEntry->getFileOffset();
            if ((offset % alignment) != 0) {
                if (verbose) {
                    printf("%8ld %s (BAD - %ld)\n",
                        (long) offset, pEntry->getFileName(),
                        offset % alignment);
                }
                foundBad = true;
            } else {
                if (verbose) {
                    printf("%8ld %s (OK)\n",
                        (long) offset, pEntry->getFileName());
                }
            }
        }
    }

    if (verbose)
        printf("Verification %s\n", foundBad ? "FAILED" : "succesful");

    return foundBad ? 1 : 0;
}

/*
 * Parse args.
 */
int main(int argc, char* const argv[])
{
    bool wantUsage = false;
    bool check = false;
    bool force = false;
    bool verbose = false;
    int result = 1;
    int alignment;
    char* endp;

    if (argc < 4) {
        wantUsage = true;
        goto bail;
    }

    argc--;
    argv++;

    while (argc && argv[0][0] == '-') {
        const char* cp = argv[0] +1;

        while (*cp != '\0') {
            switch (*cp) {
            case 'c':
                check = true;
                break;
            case 'f':
                force = true;
                break;
            case 'v':
                verbose = true;
                break;
            default:
                fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
                wantUsage = true;
                goto bail;
            }

            cp++;
        }

        argc--;
        argv++;
    }

    if (!((check && argc == 2) || (!check && argc == 3))) {
        wantUsage = true;
        goto bail;
    }

    alignment = strtol(argv[0], &endp, 10);
    if (*endp != '\0' || alignment <= 0) {
        fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
        wantUsage = true;
        goto bail;
    }

    if (check) {
        /* check existing archive for correct alignment */
        result = verify(argv[1], alignment, verbose);
    } else {
        /* create the new archive */
        result = process(argv[1], argv[2], alignment, force);

        /* trust, but verify */
        if (result == 0)
            result = verify(argv[2], alignment, verbose);
    }

bail:
    if (wantUsage) {
        usage();
        result = 2;
    }

    return result;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/window_capturer.h"

#include <assert.h>
#include <windows.h>

#include "webrtc/modules/desktop_capture/desktop_frame_win.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {

namespace {

typedef HRESULT (WINAPI *DwmIsCompositionEnabledFunc)(BOOL* enabled);

// Coverts a zero-terminated UTF-16 string to UTF-8. Returns an empty string if
// error occurs.
std::string Utf16ToUtf8(const WCHAR* str) {
  int len_utf8 = WideCharToMultiByte(CP_UTF8, 0, str, -1,
                                     NULL, 0, NULL, NULL);
  if (len_utf8 <= 0)
    return std::string();
  std::string result(len_utf8, '\0');
  int rv = WideCharToMultiByte(CP_UTF8, 0, str, -1,
                               &*(result.begin()), len_utf8, NULL, NULL);
  if (rv != len_utf8)
    assert(false);

  return result;
}

BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
  WindowCapturer::WindowList* list =
      reinterpret_cast<WindowCapturer::WindowList*>(param);

  // Skip windows that are invisible, minimized, have no title, or are owned,
  // unless they have the app window style set.
  int len = GetWindowTextLength(hwnd);
  HWND owner = GetWindow(hwnd, GW_OWNER);
  LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
  if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) ||
      (owner && !(exstyle & WS_EX_APPWINDOW))) {
    return TRUE;
  }

  // Skip the Program Manager window and the Start button.
  const size_t kClassLength = 256;
  WCHAR class_name[kClassLength];
  GetClassName(hwnd, class_name, kClassLength);
  // Skip Program Manager window and the Start button. This is the same logic
  // that's used in Win32WindowPicker in libjingle. Consider filtering other
  // windows as well (e.g. toolbars).
  if (wcscmp(class_name, L"Progman") == 0 || wcscmp(class_name, L"Button") == 0)
    return TRUE;

  WindowCapturer::Window window;
  window.id = reinterpret_cast<WindowCapturer::WindowId>(hwnd);

  const size_t kTitleLength = 500;
  WCHAR window_title[kTitleLength];
  // Truncate the title if it's longer than kTitleLength.
  GetWindowText(hwnd, window_title, kTitleLength);
  window.title = Utf16ToUtf8(window_title);

  // Skip windows when we failed to convert the title or it is empty.
  if (window.title.empty())
    return TRUE;

  list->push_back(window);

  return TRUE;
}

class WindowCapturerWin : public WindowCapturer {
 public:
  WindowCapturerWin();
  virtual ~WindowCapturerWin();

  // WindowCapturer interface.
  virtual bool GetWindowList(WindowList* windows) OVERRIDE;
  virtual bool SelectWindow(WindowId id) OVERRIDE;

  // DesktopCapturer interface.
  virtual void Start(Callback* callback) OVERRIDE;
  virtual void Capture(const DesktopRegion& region) OVERRIDE;

 private:
  bool IsAeroEnabled();

  Callback* callback_;

  // HWND and HDC for the currently selected window or NULL if window is not
  // selected.
  HWND window_;

  // dwmapi.dll is used to determine if desktop compositing is enabled.
  HMODULE dwmapi_library_;
  DwmIsCompositionEnabledFunc is_composition_enabled_func_;

  DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin);
};

WindowCapturerWin::WindowCapturerWin()
    : callback_(NULL),
      window_(NULL) {
  // Try to load dwmapi.dll dynamically since it is not available on XP.
  dwmapi_library_ = LoadLibrary(L"dwmapi.dll");
  if (dwmapi_library_) {
    is_composition_enabled_func_ =
        reinterpret_cast<DwmIsCompositionEnabledFunc>(
            GetProcAddress(dwmapi_library_, "DwmIsCompositionEnabled"));
    assert(is_composition_enabled_func_);
  } else {
    is_composition_enabled_func_ = NULL;
  }
}

WindowCapturerWin::~WindowCapturerWin() {
  if (dwmapi_library_)
    FreeLibrary(dwmapi_library_);
}

bool WindowCapturerWin::IsAeroEnabled() {
  BOOL result = FALSE;
  if (is_composition_enabled_func_)
    is_composition_enabled_func_(&result);
  return result != FALSE;
}

bool WindowCapturerWin::GetWindowList(WindowList* windows) {
  WindowList result;
  LPARAM param = reinterpret_cast<LPARAM>(&result);
  if (!EnumWindows(&WindowsEnumerationHandler, param))
    return false;
  windows->swap(result);
  return true;
}

bool WindowCapturerWin::SelectWindow(WindowId id) {
  HWND window = reinterpret_cast<HWND>(id);
  if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window))
    return false;
  window_ = window;
  return true;
}

void WindowCapturerWin::Start(Callback* callback) {
  assert(!callback_);
  assert(callback);

  callback_ = callback;
}

void WindowCapturerWin::Capture(const DesktopRegion& region) {
  if (!window_) {
    LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError();
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  // Stop capturing if the window has been minimized or hidden.
  if (IsIconic(window_) || !IsWindowVisible(window_)) {
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  RECT rect;
  if (!GetWindowRect(window_, &rect)) {
    LOG(LS_WARNING) << "Failed to get window size: " << GetLastError();
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  HDC window_dc = GetWindowDC(window_);
  if (!window_dc) {
    LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError();
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  scoped_ptr<DesktopFrameWin> frame(DesktopFrameWin::Create(
      DesktopSize(rect.right - rect.left, rect.bottom - rect.top),
      NULL, window_dc));
  if (!frame.get()) {
    ReleaseDC(window_, window_dc);
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  HDC mem_dc = CreateCompatibleDC(window_dc);
  SelectObject(mem_dc, frame->bitmap());
  BOOL result = FALSE;

  // When desktop composition (Aero) is enabled each window is rendered to a
  // private buffer allowing BitBlt() to get the window content even if the
  // window is occluded. PrintWindow() is slower but lets rendering the window
  // contents to an off-screen device context when Aero is not available.
  // PrintWindow() is not supported by some applications.

  // If Aero is enabled, we prefer BitBlt() because it's faster and avoids
  // window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may
  // render occluding windows on top of the desired window.

  if (!IsAeroEnabled())
    result = PrintWindow(window_, mem_dc, 0);

  // Aero is enabled or PrintWindow() failed, use BitBlt.
  if (!result) {
    result = BitBlt(mem_dc, 0, 0, frame->size().width(), frame->size().height(),
                    window_dc, 0, 0, SRCCOPY);
  }

  if (!result) {
    LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed.";
    frame.reset();
  }

  SelectObject(mem_dc, NULL);
  DeleteDC(mem_dc);
  ReleaseDC(window_, window_dc);

  callback_->OnCaptureCompleted(frame.release());
}

}  // namespace

// static
WindowCapturer* WindowCapturer::Create() {
  return new WindowCapturerWin();
}

}  // namespace webrtc
<commit_msg>Fix WindowCapturerWin to capture window decorations after window size changes.<commit_after>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/window_capturer.h"

#include <assert.h>
#include <windows.h>

#include "webrtc/modules/desktop_capture/desktop_frame_win.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {

namespace {

typedef HRESULT (WINAPI *DwmIsCompositionEnabledFunc)(BOOL* enabled);

// Coverts a zero-terminated UTF-16 string to UTF-8. Returns an empty string if
// error occurs.
std::string Utf16ToUtf8(const WCHAR* str) {
  int len_utf8 = WideCharToMultiByte(CP_UTF8, 0, str, -1,
                                     NULL, 0, NULL, NULL);
  if (len_utf8 <= 0)
    return std::string();
  std::string result(len_utf8, '\0');
  int rv = WideCharToMultiByte(CP_UTF8, 0, str, -1,
                               &*(result.begin()), len_utf8, NULL, NULL);
  if (rv != len_utf8)
    assert(false);

  return result;
}

BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
  WindowCapturer::WindowList* list =
      reinterpret_cast<WindowCapturer::WindowList*>(param);

  // Skip windows that are invisible, minimized, have no title, or are owned,
  // unless they have the app window style set.
  int len = GetWindowTextLength(hwnd);
  HWND owner = GetWindow(hwnd, GW_OWNER);
  LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
  if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) ||
      (owner && !(exstyle & WS_EX_APPWINDOW))) {
    return TRUE;
  }

  // Skip the Program Manager window and the Start button.
  const size_t kClassLength = 256;
  WCHAR class_name[kClassLength];
  GetClassName(hwnd, class_name, kClassLength);
  // Skip Program Manager window and the Start button. This is the same logic
  // that's used in Win32WindowPicker in libjingle. Consider filtering other
  // windows as well (e.g. toolbars).
  if (wcscmp(class_name, L"Progman") == 0 || wcscmp(class_name, L"Button") == 0)
    return TRUE;

  WindowCapturer::Window window;
  window.id = reinterpret_cast<WindowCapturer::WindowId>(hwnd);

  const size_t kTitleLength = 500;
  WCHAR window_title[kTitleLength];
  // Truncate the title if it's longer than kTitleLength.
  GetWindowText(hwnd, window_title, kTitleLength);
  window.title = Utf16ToUtf8(window_title);

  // Skip windows when we failed to convert the title or it is empty.
  if (window.title.empty())
    return TRUE;

  list->push_back(window);

  return TRUE;
}

class WindowCapturerWin : public WindowCapturer {
 public:
  WindowCapturerWin();
  virtual ~WindowCapturerWin();

  // WindowCapturer interface.
  virtual bool GetWindowList(WindowList* windows) OVERRIDE;
  virtual bool SelectWindow(WindowId id) OVERRIDE;

  // DesktopCapturer interface.
  virtual void Start(Callback* callback) OVERRIDE;
  virtual void Capture(const DesktopRegion& region) OVERRIDE;

 private:
  bool IsAeroEnabled();

  Callback* callback_;

  // HWND and HDC for the currently selected window or NULL if window is not
  // selected.
  HWND window_;

  // dwmapi.dll is used to determine if desktop compositing is enabled.
  HMODULE dwmapi_library_;
  DwmIsCompositionEnabledFunc is_composition_enabled_func_;

  DesktopSize previous_size_;

  DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin);
};

WindowCapturerWin::WindowCapturerWin()
    : callback_(NULL),
      window_(NULL) {
  // Try to load dwmapi.dll dynamically since it is not available on XP.
  dwmapi_library_ = LoadLibrary(L"dwmapi.dll");
  if (dwmapi_library_) {
    is_composition_enabled_func_ =
        reinterpret_cast<DwmIsCompositionEnabledFunc>(
            GetProcAddress(dwmapi_library_, "DwmIsCompositionEnabled"));
    assert(is_composition_enabled_func_);
  } else {
    is_composition_enabled_func_ = NULL;
  }
}

WindowCapturerWin::~WindowCapturerWin() {
  if (dwmapi_library_)
    FreeLibrary(dwmapi_library_);
}

bool WindowCapturerWin::IsAeroEnabled() {
  BOOL result = FALSE;
  if (is_composition_enabled_func_)
    is_composition_enabled_func_(&result);
  return result != FALSE;
}

bool WindowCapturerWin::GetWindowList(WindowList* windows) {
  WindowList result;
  LPARAM param = reinterpret_cast<LPARAM>(&result);
  if (!EnumWindows(&WindowsEnumerationHandler, param))
    return false;
  windows->swap(result);
  return true;
}

bool WindowCapturerWin::SelectWindow(WindowId id) {
  HWND window = reinterpret_cast<HWND>(id);
  if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window))
    return false;
  window_ = window;
  previous_size_.set(0, 0);
  return true;
}

void WindowCapturerWin::Start(Callback* callback) {
  assert(!callback_);
  assert(callback);

  callback_ = callback;
}

void WindowCapturerWin::Capture(const DesktopRegion& region) {
  if (!window_) {
    LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError();
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  // Stop capturing if the window has been minimized or hidden.
  if (IsIconic(window_) || !IsWindowVisible(window_)) {
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  RECT rect;
  if (!GetWindowRect(window_, &rect)) {
    LOG(LS_WARNING) << "Failed to get window size: " << GetLastError();
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  HDC window_dc = GetWindowDC(window_);
  if (!window_dc) {
    LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError();
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  scoped_ptr<DesktopFrameWin> frame(DesktopFrameWin::Create(
      DesktopSize(rect.right - rect.left, rect.bottom - rect.top),
      NULL, window_dc));
  if (!frame.get()) {
    ReleaseDC(window_, window_dc);
    callback_->OnCaptureCompleted(NULL);
    return;
  }

  HDC mem_dc = CreateCompatibleDC(window_dc);
  SelectObject(mem_dc, frame->bitmap());
  BOOL result = FALSE;

  // When desktop composition (Aero) is enabled each window is rendered to a
  // private buffer allowing BitBlt() to get the window content even if the
  // window is occluded. PrintWindow() is slower but lets rendering the window
  // contents to an off-screen device context when Aero is not available.
  // PrintWindow() is not supported by some applications.
  //
  // If Aero is enabled, we prefer BitBlt() because it's faster and avoids
  // window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may
  // render occluding windows on top of the desired window.
  //
  // When composition is enabled the DC returned by GetWindowDC() doesn't always
  // have window frame rendered correctly. Windows renders it only once and then
  // caches the result between captures. We hack it around by calling
  // PrintWindow() whenever window size changes - it somehow affects what we
  // get from BitBlt() on the subsequent captures.

  if (!IsAeroEnabled() ||
      (!previous_size_.is_empty() && !previous_size_.equals(frame->size()))) {
    result = PrintWindow(window_, mem_dc, 0);
  }

  // Aero is enabled or PrintWindow() failed, use BitBlt.
  if (!result) {
    result = BitBlt(mem_dc, 0, 0, frame->size().width(), frame->size().height(),
                    window_dc, 0, 0, SRCCOPY);
  }

  SelectObject(mem_dc, NULL);
  DeleteDC(mem_dc);
  ReleaseDC(window_, window_dc);

  previous_size_ = frame->size();

  if (!result) {
    LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed.";
    frame.reset();
  }

  callback_->OnCaptureCompleted(frame.release());
}

}  // namespace

// static
WindowCapturer* WindowCapturer::Create() {
  return new WindowCapturerWin();
}

}  // namespace webrtc
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/video_coding/utility/quality_scaler.h"

#include <algorithm>
#include <cmath>

namespace webrtc {

namespace {
// Threshold constant used until first downscale (to permit fast rampup).
static const int kMeasureSecondsFastUpscale = 2;
static const int kMeasureSecondsUpscale = 5;
static const int kMeasureSecondsDownscale = 5;
static const int kFramedropPercentThreshold = 60;
// Min width/height to downscale to, set to not go below QVGA, but with some
// margin to permit "almost-QVGA" resolutions, such as QCIF.
static const int kMinDownscaleDimension = 140;
// Initial resolutions corresponding to a bitrate. Aa bit above their actual
// values to permit near-VGA and near-QVGA resolutions to use the same
// mechanism.
static const int kVgaBitrateThresholdKbps = 500;
static const int kVgaNumPixels = 700 * 500;  // 640x480
static const int kQvgaBitrateThresholdKbps = 250;
static const int kQvgaNumPixels = 400 * 300;  // 320x240
}  // namespace

// QP thresholds are chosen to be high enough to be hit in practice when quality
// is good, but also low enough to not cause a flip-flop behavior (e.g. going up
// in resolution shouldn't give so bad quality that we should go back down).

const int QualityScaler::kLowVp8QpThreshold = 29;
const int QualityScaler::kBadVp8QpThreshold = 95;

#if defined(WEBRTC_IOS)
const int QualityScaler::kLowH264QpThreshold = 32;
const int QualityScaler::kBadH264QpThreshold = 42;
#else
const int QualityScaler::kLowH264QpThreshold = 24;
const int QualityScaler::kBadH264QpThreshold = 37;
#endif

// Default values. Should immediately get set to something more sensible.
QualityScaler::QualityScaler()
    : average_qp_(kMeasureSecondsUpscale * 30),
      framedrop_percent_(kMeasureSecondsUpscale * 30),
      low_qp_threshold_(-1) {}

void QualityScaler::Init(int low_qp_threshold,
                         int high_qp_threshold,
                         int initial_bitrate_kbps,
                         int width,
                         int height,
                         int fps) {
  low_qp_threshold_ = low_qp_threshold;
  high_qp_threshold_ = high_qp_threshold;
  downscale_shift_ = 0;

  fast_rampup_ = true;

  ClearSamples();
  ReportFramerate(fps);

  const int init_width = width;
  const int init_height = height;
  if (initial_bitrate_kbps > 0) {
    int init_num_pixels = width * height;
    if (initial_bitrate_kbps < kVgaBitrateThresholdKbps)
      init_num_pixels = kVgaNumPixels;
    if (initial_bitrate_kbps < kQvgaBitrateThresholdKbps)
      init_num_pixels = kQvgaNumPixels;
    while (width * height > init_num_pixels) {
      ++downscale_shift_;
      width /= 2;
      height /= 2;
    }
  }
  UpdateTargetResolution(init_width, init_height);
  ReportFramerate(fps);
}

// Report framerate(fps) to estimate # of samples.
void QualityScaler::ReportFramerate(int framerate) {
  // Use a faster window for upscaling initially.
  // This enables faster initial rampups without risking strong up-down
  // behavior later.
  num_samples_upscale_ = framerate * (fast_rampup_ ? kMeasureSecondsFastUpscale
                                                   : kMeasureSecondsUpscale);
  num_samples_downscale_ = framerate * kMeasureSecondsDownscale;

  average_qp_ =
      MovingAverage(std::max(num_samples_upscale_, num_samples_downscale_));
  framedrop_percent_ =
      MovingAverage(std::max(num_samples_upscale_, num_samples_downscale_));
}

void QualityScaler::ReportQP(int qp) {
  framedrop_percent_.AddSample(0);
  average_qp_.AddSample(qp);
}

void QualityScaler::ReportDroppedFrame() {
  framedrop_percent_.AddSample(100);
}

void QualityScaler::OnEncodeFrame(int width, int height) {
  // Should be set through InitEncode -> Should be set by now.
  RTC_DCHECK_GE(low_qp_threshold_, 0);
  if (target_res_.width != width || target_res_.height != height) {
    UpdateTargetResolution(width, height);
  }

  // Check if we should scale down due to high frame drop.
  const auto drop_rate = framedrop_percent_.GetAverage(num_samples_downscale_);
  if (drop_rate && *drop_rate >= kFramedropPercentThreshold) {
    ScaleDown();
    return;
  }

  // Check if we should scale up or down based on QP.
  const auto avg_qp_down = average_qp_.GetAverage(num_samples_downscale_);
  if (avg_qp_down && *avg_qp_down > high_qp_threshold_) {
    ScaleDown();
    return;
  }
  const auto avg_qp_up = average_qp_.GetAverage(num_samples_upscale_);
  if (avg_qp_up && *avg_qp_up <= low_qp_threshold_) {
    // QP has been low. We want to try a higher resolution.
    ScaleUp();
    return;
  }
}

void QualityScaler::ScaleUp() {
  downscale_shift_ = std::max(0, downscale_shift_ - 1);
  ClearSamples();
}

void QualityScaler::ScaleDown() {
  downscale_shift_ = std::min(maximum_shift_, downscale_shift_ + 1);
  ClearSamples();
  // If we've scaled down, wait longer before scaling up again.
  if (fast_rampup_) {
    fast_rampup_ = false;
    num_samples_upscale_ = (num_samples_upscale_ / kMeasureSecondsFastUpscale) *
                           kMeasureSecondsUpscale;
  }
}

QualityScaler::Resolution QualityScaler::GetScaledResolution() const {
  const int frame_width = target_res_.width >> downscale_shift_;
  const int frame_height = target_res_.height >> downscale_shift_;
  return Resolution{frame_width, frame_height};
}

rtc::scoped_refptr<VideoFrameBuffer> QualityScaler::GetScaledBuffer(
    const rtc::scoped_refptr<VideoFrameBuffer>& frame) {
  Resolution res = GetScaledResolution();
  const int src_width = frame->width();
  const int src_height = frame->height();

  if (res.width == src_width && res.height == src_height)
    return frame;
  rtc::scoped_refptr<I420Buffer> scaled_buffer =
      pool_.CreateBuffer(res.width, res.height);

  scaled_buffer->ScaleFrom(frame);

  return scaled_buffer;
}

void QualityScaler::UpdateTargetResolution(int width, int height) {
  if (width < kMinDownscaleDimension || height < kMinDownscaleDimension) {
    maximum_shift_ = 0;
  } else {
    maximum_shift_ = static_cast<int>(
        std::log2(std::min(width, height) / kMinDownscaleDimension));
  }
  target_res_ = Resolution{width, height};
}

void QualityScaler::ClearSamples() {
  framedrop_percent_.Reset();
  average_qp_.Reset();
}

}  // namespace webrtc
<commit_msg>Fix undefined reference to log2 on android<commit_after>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/video_coding/utility/quality_scaler.h"

#include <math.h>

#include <algorithm>

// TODO(kthelgason): Some versions of Android have issues with log2.
// See https://code.google.com/p/android/issues/detail?id=212634 for details
#if defined(WEBRTC_ANDROID)
#define log2(x) (log(x) / log(2))
#endif

namespace webrtc {

namespace {
// Threshold constant used until first downscale (to permit fast rampup).
static const int kMeasureSecondsFastUpscale = 2;
static const int kMeasureSecondsUpscale = 5;
static const int kMeasureSecondsDownscale = 5;
static const int kFramedropPercentThreshold = 60;
// Min width/height to downscale to, set to not go below QVGA, but with some
// margin to permit "almost-QVGA" resolutions, such as QCIF.
static const int kMinDownscaleDimension = 140;
// Initial resolutions corresponding to a bitrate. Aa bit above their actual
// values to permit near-VGA and near-QVGA resolutions to use the same
// mechanism.
static const int kVgaBitrateThresholdKbps = 500;
static const int kVgaNumPixels = 700 * 500;  // 640x480
static const int kQvgaBitrateThresholdKbps = 250;
static const int kQvgaNumPixels = 400 * 300;  // 320x240
}  // namespace

// QP thresholds are chosen to be high enough to be hit in practice when quality
// is good, but also low enough to not cause a flip-flop behavior (e.g. going up
// in resolution shouldn't give so bad quality that we should go back down).

const int QualityScaler::kLowVp8QpThreshold = 29;
const int QualityScaler::kBadVp8QpThreshold = 95;

#if defined(WEBRTC_IOS)
const int QualityScaler::kLowH264QpThreshold = 32;
const int QualityScaler::kBadH264QpThreshold = 42;
#else
const int QualityScaler::kLowH264QpThreshold = 24;
const int QualityScaler::kBadH264QpThreshold = 37;
#endif

// Default values. Should immediately get set to something more sensible.
QualityScaler::QualityScaler()
    : average_qp_(kMeasureSecondsUpscale * 30),
      framedrop_percent_(kMeasureSecondsUpscale * 30),
      low_qp_threshold_(-1) {}

void QualityScaler::Init(int low_qp_threshold,
                         int high_qp_threshold,
                         int initial_bitrate_kbps,
                         int width,
                         int height,
                         int fps) {
  low_qp_threshold_ = low_qp_threshold;
  high_qp_threshold_ = high_qp_threshold;
  downscale_shift_ = 0;

  fast_rampup_ = true;

  ClearSamples();
  ReportFramerate(fps);

  const int init_width = width;
  const int init_height = height;
  if (initial_bitrate_kbps > 0) {
    int init_num_pixels = width * height;
    if (initial_bitrate_kbps < kVgaBitrateThresholdKbps)
      init_num_pixels = kVgaNumPixels;
    if (initial_bitrate_kbps < kQvgaBitrateThresholdKbps)
      init_num_pixels = kQvgaNumPixels;
    while (width * height > init_num_pixels) {
      ++downscale_shift_;
      width /= 2;
      height /= 2;
    }
  }
  UpdateTargetResolution(init_width, init_height);
  ReportFramerate(fps);
}

// Report framerate(fps) to estimate # of samples.
void QualityScaler::ReportFramerate(int framerate) {
  // Use a faster window for upscaling initially.
  // This enables faster initial rampups without risking strong up-down
  // behavior later.
  num_samples_upscale_ = framerate * (fast_rampup_ ? kMeasureSecondsFastUpscale
                                                   : kMeasureSecondsUpscale);
  num_samples_downscale_ = framerate * kMeasureSecondsDownscale;

  average_qp_ =
      MovingAverage(std::max(num_samples_upscale_, num_samples_downscale_));
  framedrop_percent_ =
      MovingAverage(std::max(num_samples_upscale_, num_samples_downscale_));
}

void QualityScaler::ReportQP(int qp) {
  framedrop_percent_.AddSample(0);
  average_qp_.AddSample(qp);
}

void QualityScaler::ReportDroppedFrame() {
  framedrop_percent_.AddSample(100);
}

void QualityScaler::OnEncodeFrame(int width, int height) {
  // Should be set through InitEncode -> Should be set by now.
  RTC_DCHECK_GE(low_qp_threshold_, 0);
  if (target_res_.width != width || target_res_.height != height) {
    UpdateTargetResolution(width, height);
  }

  // Check if we should scale down due to high frame drop.
  const auto drop_rate = framedrop_percent_.GetAverage(num_samples_downscale_);
  if (drop_rate && *drop_rate >= kFramedropPercentThreshold) {
    ScaleDown();
    return;
  }

  // Check if we should scale up or down based on QP.
  const auto avg_qp_down = average_qp_.GetAverage(num_samples_downscale_);
  if (avg_qp_down && *avg_qp_down > high_qp_threshold_) {
    ScaleDown();
    return;
  }
  const auto avg_qp_up = average_qp_.GetAverage(num_samples_upscale_);
  if (avg_qp_up && *avg_qp_up <= low_qp_threshold_) {
    // QP has been low. We want to try a higher resolution.
    ScaleUp();
    return;
  }
}

void QualityScaler::ScaleUp() {
  downscale_shift_ = std::max(0, downscale_shift_ - 1);
  ClearSamples();
}

void QualityScaler::ScaleDown() {
  downscale_shift_ = std::min(maximum_shift_, downscale_shift_ + 1);
  ClearSamples();
  // If we've scaled down, wait longer before scaling up again.
  if (fast_rampup_) {
    fast_rampup_ = false;
    num_samples_upscale_ = (num_samples_upscale_ / kMeasureSecondsFastUpscale) *
                           kMeasureSecondsUpscale;
  }
}

QualityScaler::Resolution QualityScaler::GetScaledResolution() const {
  const int frame_width = target_res_.width >> downscale_shift_;
  const int frame_height = target_res_.height >> downscale_shift_;
  return Resolution{frame_width, frame_height};
}

rtc::scoped_refptr<VideoFrameBuffer> QualityScaler::GetScaledBuffer(
    const rtc::scoped_refptr<VideoFrameBuffer>& frame) {
  Resolution res = GetScaledResolution();
  const int src_width = frame->width();
  const int src_height = frame->height();

  if (res.width == src_width && res.height == src_height)
    return frame;
  rtc::scoped_refptr<I420Buffer> scaled_buffer =
      pool_.CreateBuffer(res.width, res.height);

  scaled_buffer->ScaleFrom(frame);

  return scaled_buffer;
}

void QualityScaler::UpdateTargetResolution(int width, int height) {
  if (width < kMinDownscaleDimension || height < kMinDownscaleDimension) {
    maximum_shift_ = 0;
  } else {
    maximum_shift_ = static_cast<int>(
        log2(std::min(width, height) / kMinDownscaleDimension));
  }
  target_res_ = Resolution{width, height};
}

void QualityScaler::ClearSamples() {
  framedrop_percent_.Reset();
  average_qp_.Reset();
}

}  // namespace webrtc
<|endoftext|>


<commit_before>#include <cmath>
#include <Eigen/Eigenvalues>
#include <esn/create_network_nsli.h>
#include <network_nsli.h>

namespace ESN {

    std::unique_ptr< Network > CreateNetwork(
        const NetworkParamsNSLI & params )
    {
        return std::unique_ptr< NetworkNSLI >( new NetworkNSLI( params ) );
    }

    NetworkNSLI::NetworkNSLI( const NetworkParamsNSLI & params )
        : mParams( params )
        , mIn( params.inputCount )
        , mWIn( params.neuronCount, params.inputCount )
        , mX( params.neuronCount )
        , mW( params.neuronCount, params.neuronCount )
        , mOut( params.outputCount )
        , mWOut( params.outputCount, params.neuronCount )
    {
        if ( params.inputCount <= 0 )
            throw std::invalid_argument(
                "NetworkParamsNSLI::inputCount must be not null" );
        if ( params.neuronCount <= 0 )
            throw std::invalid_argument(
                "NetworkParamsNSLI::neuronCount must be not null" );
        if ( params.outputCount <= 0 )
            throw std::invalid_argument(
                "NetworkParamsNSLI::outputCount must be not null" );
        if ( !( params.leakingRate > 0.0 && params.leakingRate <= 1.0 ) )
            throw std::invalid_argument(
                "NetworkParamsNSLI::leakingRate must be withing "
                "interval [0,1)" );

        mWIn = Eigen::MatrixXf::Random(
            params.neuronCount, params.inputCount ).sparseView();

        Eigen::MatrixXf randomWeights = Eigen::MatrixXf::Random(
            params.neuronCount, params.neuronCount );
        float spectralRadius =
            randomWeights.eigenvalues().cwiseAbs().maxCoeff();
        mW = ( randomWeights / spectralRadius ).sparseView() ;
    }

    NetworkNSLI::~NetworkNSLI()
    {
    }

    void NetworkNSLI::SetInputs( const std::vector< float > & inputs )
    {
        if ( inputs.size() != mIn.rows() )
            throw std::invalid_argument( "Wrong size of the input vector" );
        mIn = Eigen::Map< Eigen::VectorXf >(
            const_cast< float * >( inputs.data() ), inputs.size() );
    }

    void NetworkNSLI::Step( float step )
    {
        mX = ( 1 - mParams.leakingRate ) * mX +
            mParams.leakingRate * ( mWIn * mIn + mW * mX ).unaryExpr(
                [] ( float x ) -> float { return std::tanh( x ); } );
        mOut = mWOut * mX;
    }

    void NetworkNSLI::Train(
        const std::vector< std::vector< float > > & inputs,
        const std::vector< std::vector< float > > & outputs )
    {
        if ( inputs.size() == 0 )
            throw std::invalid_argument(
                "Number of samples must be not null" );
        if ( inputs.size() != outputs.size() )
            throw std::invalid_argument(
                "Number of input and output samples must be equal" );
    }

} // namespace ESN
<commit_msg>esn : NetworkNSLI : Step : check argument 'step'<commit_after>#include <cmath>
#include <Eigen/Eigenvalues>
#include <esn/create_network_nsli.h>
#include <network_nsli.h>

namespace ESN {

    std::unique_ptr< Network > CreateNetwork(
        const NetworkParamsNSLI & params )
    {
        return std::unique_ptr< NetworkNSLI >( new NetworkNSLI( params ) );
    }

    NetworkNSLI::NetworkNSLI( const NetworkParamsNSLI & params )
        : mParams( params )
        , mIn( params.inputCount )
        , mWIn( params.neuronCount, params.inputCount )
        , mX( params.neuronCount )
        , mW( params.neuronCount, params.neuronCount )
        , mOut( params.outputCount )
        , mWOut( params.outputCount, params.neuronCount )
    {
        if ( params.inputCount <= 0 )
            throw std::invalid_argument(
                "NetworkParamsNSLI::inputCount must be not null" );
        if ( params.neuronCount <= 0 )
            throw std::invalid_argument(
                "NetworkParamsNSLI::neuronCount must be not null" );
        if ( params.outputCount <= 0 )
            throw std::invalid_argument(
                "NetworkParamsNSLI::outputCount must be not null" );
        if ( !( params.leakingRate > 0.0 && params.leakingRate <= 1.0 ) )
            throw std::invalid_argument(
                "NetworkParamsNSLI::leakingRate must be withing "
                "interval [0,1)" );

        mWIn = Eigen::MatrixXf::Random(
            params.neuronCount, params.inputCount ).sparseView();

        Eigen::MatrixXf randomWeights = Eigen::MatrixXf::Random(
            params.neuronCount, params.neuronCount );
        float spectralRadius =
            randomWeights.eigenvalues().cwiseAbs().maxCoeff();
        mW = ( randomWeights / spectralRadius ).sparseView() ;
    }

    NetworkNSLI::~NetworkNSLI()
    {
    }

    void NetworkNSLI::SetInputs( const std::vector< float > & inputs )
    {
        if ( inputs.size() != mIn.rows() )
            throw std::invalid_argument( "Wrong size of the input vector" );
        mIn = Eigen::Map< Eigen::VectorXf >(
            const_cast< float * >( inputs.data() ), inputs.size() );
    }

    void NetworkNSLI::Step( float step )
    {
        if ( step <= 0.0f )
            throw std::invalid_argument(
                "Step size must be positive value" );

        mX = ( 1 - mParams.leakingRate ) * mX +
            mParams.leakingRate * ( mWIn * mIn + mW * mX ).unaryExpr(
                [] ( float x ) -> float { return std::tanh( x ); } );
        mOut = mWOut * mX;
    }

    void NetworkNSLI::Train(
        const std::vector< std::vector< float > > & inputs,
        const std::vector< std::vector< float > > & outputs )
    {
        if ( inputs.size() == 0 )
            throw std::invalid_argument(
                "Number of samples must be not null" );
        if ( inputs.size() != outputs.size() )
            throw std::invalid_argument(
                "Number of input and output samples must be equal" );
    }

} // namespace ESN
<|endoftext|>


<commit_before>bool onSegment(Point p, Point q, Point r)
{
    if (cross(toVec(p,r),toVec(p,q)) == 0 &&
		q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
        q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
       return true;

    return false;
}
<commit_msg>arrumando identacao<commit_after>bool onSegment(Point p, Point q, Point r)
{
    if (cross(toVec(p,r),toVec(p,q)) == 0 &&
        q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
        q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
       return true;

    return false;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMutexFunctionLock.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/

#include "vtkMutexFunctionLock.h"

// Description:
// Construct a new vtkMutexFunctionLock
vtkMutexFunctionLock::vtkMutexFunctionLock(void )
{
  this->mutex_var = vtkMutexLock::New();
}

// Description:
// Destruct the vtkMutexFunctionLock
vtkMutexFunctionLock::~vtkMutexFunctionLock(void )
{
  delete this->mutex_var;
}

// Description:
// Print method for vtkMutexFunctionLock
void vtkMutexFunctionLock::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);
  this->mutex_var->PrintSelf(os,indent);
}

// Description:
// Lock method for vtkMutexFunctionLock
void vtkMutexFunctionLock::StartLock(void )
{
  if (this->mutex_var != NULL)
    this->mutex_var->Lock();
}

// Description:
// Unlock method for vtkMutexFunctionLock
void vtkMutexFunctionLock::EndLock(void )
{
  if (this->mutex_var != NULL)
    this->mutex_var->Unlock();
}

<commit_msg>FIX: Style Errors<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMutexFunctionLock.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/

#include "vtkMutexFunctionLock.h"

// Description:
// Construct a new vtkMutexFunctionLock
vtkMutexFunctionLock::vtkMutexFunctionLock(void )
{
  this->MutexVar = vtkMutexLock::New();
}

// Description:
// Destruct the vtkMutexFunctionLock
vtkMutexFunctionLock::~vtkMutexFunctionLock(void )
{
  delete this->MutexVar;
}

// Description:
// Print method for vtkMutexFunctionLock
void vtkMutexFunctionLock::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);
  this->MutexVar->PrintSelf(os,indent);
}

// Description:
// Lock method for vtkMutexFunctionLock
void vtkMutexFunctionLock::StartLock(void )
{
  if (this->MutexVar != NULL)
    this->MutexVar->Lock();
}

// Description:
// Unlock method for vtkMutexFunctionLock
void vtkMutexFunctionLock::EndLock(void )
{
  if (this->MutexVar != NULL)
    this->MutexVar->Unlock();
}

<|endoftext|>


<commit_before>/**communications clients avec les sockets TCP en C.
* AUTHORS:
*/
//Si nous sommes sous Windows
#include <winsock2.h>
typedef int socklen_t;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
//#include <conio.h>

#define PORT 20019

void envoie(char *msg, SOCKET sock){
	int taille = (int)strlen(msg)+1;
	if(send(sock, &taille, sizeof(taille), 0) != -1){
		send(sock, msg, taille, 0);
	}
}

char* recoit(SOCKET* sock){
	char *recu;
	int err, taille;

	err=recv(sock, &taille, sizeof(taille), 0); //la taille des donnees
	if(err != -1){
		recv(sock, recu, sizeof(taille), 0); //reception des donnees
	}

	return res;
}

void interpretor(char *data){

}

void* un_client(void * sock){
	char* msg= "";
	do{
		msg = recoit((int) sock);
	}while( strcmp(msg, "EXIT"));

	//fermer la connexion
	printf("fermeture de la socket client\n");
	closesocket(csock);
}

void main(int argc, char **args){

	WSADATA	WSAData;
  	WSAStartup(MAKEWORD(2,2),&WSAData);

	//creation et parametrage du socket
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	SOCKET csock;
	SOCKADDR_IN ssin, ccsin;
	ssin.sin_addr.s_addr = inet_addr("127.0.0.1");
	ssin.sin_family = AF_INET;
	ssin.sin_port = htons(PORT);

  	//code a executer
  	printf("Demarrage du serveur sur le port %d...\n", PORT);

	//etablir une communication
	int err_bind = bind(sock, (SOCKADDR*) &ssin, sizeof(ssin));
	listen(sock, 5);

	socklen_t taille = sizeof(csin);

	while(true){
		csock = accept(sock, (SOCKADDR*)&ccsin, &taille);

		printf("connexion du client %s:%d...\n", inet_ntoa(ccsin.sin_addr), htons(ccsin.sin_port));

		//creation d'un thread pour gerer le client
		pthread_t client;
		int err_thr = pthread_create(&client, NULL, un_client, (void*) &csock);

	}

	printf("fermeture de la socket serveur\n");

	closesocket(sock);

	WSACleanup();

}
<commit_msg>socket<commit_after>/**communications clients avec les sockets TCP en C.
* AUTHORS:
*/
//Si nous sommes sous Windows
#include <winsock2.h>
typedef int socklen_t;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
//#include <conio.h>

#define PORT 20019

void envoie(char *msg, SOCKET sock){
	int taille = (int)strlen(msg)+1;
	if(send(sock, &taille, sizeof(taille), 0) != -1){
		send(sock, msg, taille, 0);
	}
}

char* recoit(SOCKET* sock){
	char *recu;
	int err, taille;

	err=recv(sock, &taille, sizeof(taille), 0); //la taille des donnees
	if(err != -1){
		recv(sock, recu, sizeof(taille), 0); //reception des donnees
	}

	return res;
}

void interpretor(char *data){

}

void* un_client(void * sock){
	char* msg= "";
	do{
		msg = recoit((int) sock);
	}while( strcmp(msg, "EXIT"));

	//fermer la connexion
	printf("fermeture de la socket client\n");
	closesocket(csock);
}

void main(int argc, char **args){

	WSADATA	WSAData;
  	WSAStartup(MAKEWORD(2,2),&WSAData);

	//creation et parametrage du socket
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	SOCKET csock;
	SOCKADDR_IN ssin, ccsin;
	ssin.sin_addr.s_addr = inet_addr("127.0.0.1");
	ssin.sin_family = AF_INET;
	ssin.sin_port = htons(PORT);

  	//code a executer
  	printf("Demarrage du serveur sur le port %d...\n", PORT);

	//etablir une communication
	int err_bind = bind(sock, (SOCKADDR*) &ssin, sizeof(ssin));
	listen(sock, 5);

	socklen_t taille = sizeof(csin);

	while(true){
		csock = accept(sock, (SOCKADDR*)&ccsin, &taille);

		printf("connexion du client %s:%d...\n", inet_ntoa(ccsin.sin_addr), htons(ccsin.sin_port));

		//reception
		system("pwd");
		//creation d'un thread pour gerer le client
		pthread_t client;
		int err_thr = pthread_create(&client, NULL, un_client, (void*) &csock);

	}

	printf("fermeture de la socket serveur\n");

	closesocket(sock);

	WSACleanup();

}
<|endoftext|>