<commit_before>// The MIT License (MIT)

// Copyright (c) 2012-2013 Danny Y., Rapptz

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GEARS_COMMAND_LINE_PARSER_HPP
#define GEARS_COMMAND_LINE_PARSER_HPP

#include <map>
#include "details.hpp"
#include "arg.hpp"

namespace gears {
namespace command_line {
class parser {
private:
    std::map<std::string, arg> args;
    std::string program_name;
    std::string program_usage;

    int parse_value(arg& argu, char* argv[], int counter) {
        // next arg isn't a flag or option
        // intersperse values with a space separator
        if(argv[counter] != nullptr && argv[counter][0] != '-') {
            // overwrite value
            argu.value = argv[counter];
            ++counter;
        }

        while(argv[counter] != nullptr && argv[counter][0] != '-') {
            // append the value to the space separated list
            argu.value.push_back(' ');
            argu.value.append(argv[counter++]);
        }

        return counter - 1;
    }

    void parse_short_option(const std::string& option, int& i, char* argv[]) {
        for(auto&& arg : args) {

            auto pos = option.find(arg.second.short_name);

            // Single flag or option with value
            if(option.size() == 2) {
                if(pos != std::string::npos) {
                    if(arg.second.is_value()) {
                        i = parse_value(arg.second, argv, i + 1);
                        break;
                    }

                    // regular flag

                    arg.second.active = true;
                }
            }

            // Grouped character or grouped option
            else if(option.size() > 2) {

                // Grouped option
                if(arg.second.is_value() && option[1] == arg.second.short_name) {
                    arg.second.value.append(std::begin(option) + 2, std::end(option));
                    arg.second.active = true;
                    break;
                }

                // regular flag with grouped characters
                arg.second.active = pos != std::string::npos;
            }
            else {
                // Seems to be neither
                break;
            }
        }
    }
public:
    parser() = default;

    parser(std::initializer_list<arg> l) {
        for(auto&& i : l) {
            args.insert(std::make_pair("--" + i.name, i));
        }
    }

    arg& add(const std::string& name) {
        auto p = args.emplace(std::piecewise_construct,
                              std::forward_as_tuple("--" + name),
                              std::forward_as_tuple(name));
        return (p.first)->second;
    }

    parser& add(const arg& argument) {
        args.insert(std::make_pair("--" + argument.name, argument));
        return *this;
    }

    void parse(int argc, char* argv[]) {
        std::string current;

        if(program_name.empty()) {
            program_name = argv[0];
        }

        for(int i = 1; i < argc; ++i) {
            current = argv[i];

            // Stop parsing if it's --
            if(current == "--")
                break;

            // current arg has equal sign
            auto pos = current.find('=');
            if(pos != std::string::npos) {
                auto it = args.find(current.substr(0, pos));

                // make sure the argument is valid
                if(it != args.end()) {
                    // Override value
                    it->second.value = current.substr(pos + 1);
                }

                continue;
            }

            auto it = args.find(current);

            if(it != args.end()) {

                // value options
                if(it->second.is_value()) {
                    i = parse_value(it->second, argv, i + 1);
                }

                // regular flag

                it->second.active = true;
                continue;
            }

            // short options found
            if(current.front() == '-') {
                parse_short_option(current, i, argv);
            }
            else {
                // otherwise, it is an unrecognised argument
                throw detail::unrecognised_arg(current);
            }
        }
    }

    bool is_active(const std::string& name) const noexcept {
        auto it = args.find("--" + name);
        if(it != args.end()) {
            return it->second.active;
        }
        return false;
    }

    parser& usage(std::string str) noexcept {
        program_usage = std::move(str);
        return *this;
    }

    parser& name(std::string str) noexcept {
        program_name = std::move(str);
        return *this;
    }

    template<typename T = std::string>
    T get(const std::string& str) const {
        const auto& argument = "--" + str;
        auto it = args.find(argument);
        if(it != args.end()) {
            if(it->second.is_value())
                return detail::lexical_cast<T>(it->second.value);
        }

        throw detail::invalid_arg_get(argument);
    }

    template<typename T>
    T get_list(const std::string& str) const {
        const auto& argument = "--" + str;
        auto it = args.find(argument);
        if(it != args.end()) {
            if(it->second.is_value()) {
                T result;
                std::istringstream ss(it->second.value);
                typename T::value_type x;
                while(ss >> x) {
                    detail::insert_impl(result, x);
                }

                return result;
            }
        }

        throw detail::invalid_arg_get(argument);
    }

    void check_required_args() const {
        // loop through every argument to see if the required
        // arguments haven't been provided.
        for(auto&& arg : args) {
            if(arg.second.req && !arg.second.active) {
                throw detail::missing_required_arg(program_name, "--" + arg.second.name);
            }
        }
    }

    #ifndef GEARS_NO_IOSTREAM

    template<typename Elem, typename Traits>
    friend auto operator<<(std::basic_ostream<Elem, Traits>& out, const parser& po) -> decltype(out) {
        out << "usage: " << po.program_name << ' ' << po.program_usage << "\n\n";

        for(auto&& arg : po.args) {
            out << arg.second;
        }

        return out;
    }

    #endif // GEARS_NO_IOSTREAM
};
} // command_line
} // gears

#endif // GEARS_COMMAND_LINE_PARSER_HPP<commit_msg>Fix compilation error with unrecognised arg exception<commit_after>// The MIT License (MIT)

// Copyright (c) 2012-2013 Danny Y., Rapptz

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GEARS_COMMAND_LINE_PARSER_HPP
#define GEARS_COMMAND_LINE_PARSER_HPP

#include <map>
#include "details.hpp"
#include "arg.hpp"

namespace gears {
namespace command_line {
class parser {
private:
    std::map<std::string, arg> args;
    std::string program_name;
    std::string program_usage;

    int parse_value(arg& argu, char* argv[], int counter) {
        // next arg isn't a flag or option
        // intersperse values with a space separator
        if(argv[counter] != nullptr && argv[counter][0] != '-') {
            // overwrite value
            argu.value = argv[counter];
            ++counter;
        }

        while(argv[counter] != nullptr && argv[counter][0] != '-') {
            // append the value to the space separated list
            argu.value.push_back(' ');
            argu.value.append(argv[counter++]);
        }

        return counter - 1;
    }

    void parse_short_option(const std::string& option, int& i, char* argv[]) {
        for(auto&& arg : args) {

            auto pos = option.find(arg.second.short_name);

            // Single flag or option with value
            if(option.size() == 2) {
                if(pos != std::string::npos) {
                    if(arg.second.is_value()) {
                        i = parse_value(arg.second, argv, i + 1);
                        break;
                    }

                    // regular flag

                    arg.second.active = true;
                }
            }

            // Grouped character or grouped option
            else if(option.size() > 2) {

                // Grouped option
                if(arg.second.is_value() && option[1] == arg.second.short_name) {
                    arg.second.value.append(std::begin(option) + 2, std::end(option));
                    arg.second.active = true;
                    break;
                }

                // regular flag with grouped characters
                arg.second.active = pos != std::string::npos;
            }
            else {
                // Seems to be neither
                break;
            }
        }
    }
public:
    parser() = default;

    parser(std::initializer_list<arg> l) {
        for(auto&& i : l) {
            args.insert(std::make_pair("--" + i.name, i));
        }
    }

    arg& add(const std::string& name) {
        auto p = args.emplace(std::piecewise_construct,
                              std::forward_as_tuple("--" + name),
                              std::forward_as_tuple(name));
        return (p.first)->second;
    }

    parser& add(const arg& argument) {
        args.insert(std::make_pair("--" + argument.name, argument));
        return *this;
    }

    void parse(int argc, char* argv[]) {
        std::string current;

        if(program_name.empty()) {
            program_name = argv[0];
        }

        for(int i = 1; i < argc; ++i) {
            current = argv[i];

            // Stop parsing if it's --
            if(current == "--")
                break;

            // current arg has equal sign
            auto pos = current.find('=');
            if(pos != std::string::npos) {
                auto it = args.find(current.substr(0, pos));

                // make sure the argument is valid
                if(it != args.end()) {
                    // Override value
                    it->second.value = current.substr(pos + 1);
                }

                continue;
            }

            auto it = args.find(current);

            if(it != args.end()) {

                // value options
                if(it->second.is_value()) {
                    i = parse_value(it->second, argv, i + 1);
                }

                // regular flag

                it->second.active = true;
                continue;
            }

            // short options found
            if(current.front() == '-') {
                parse_short_option(current, i, argv);
            }
            else {
                // otherwise, it is an unrecognised argument
                throw detail::unrecognised_arg(program_name, current);
            }
        }
    }

    bool is_active(const std::string& name) const noexcept {
        auto it = args.find("--" + name);
        if(it != args.end()) {
            return it->second.active;
        }
        return false;
    }

    parser& usage(std::string str) noexcept {
        program_usage = std::move(str);
        return *this;
    }

    parser& name(std::string str) noexcept {
        program_name = std::move(str);
        return *this;
    }

    template<typename T = std::string>
    T get(const std::string& str) const {
        const auto& argument = "--" + str;
        auto it = args.find(argument);
        if(it != args.end()) {
            if(it->second.is_value())
                return detail::lexical_cast<T>(it->second.value);
        }

        throw detail::invalid_arg_get(argument);
    }

    template<typename T>
    T get_list(const std::string& str) const {
        const auto& argument = "--" + str;
        auto it = args.find(argument);
        if(it != args.end()) {
            if(it->second.is_value()) {
                T result;
                std::istringstream ss(it->second.value);
                typename T::value_type x;
                while(ss >> x) {
                    detail::insert_impl(result, x);
                }

                return result;
            }
        }

        throw detail::invalid_arg_get(argument);
    }

    void check_required_args() const {
        // loop through every argument to see if the required
        // arguments haven't been provided.
        for(auto&& arg : args) {
            if(arg.second.req && !arg.second.active) {
                throw detail::missing_required_arg(program_name, "--" + arg.second.name);
            }
        }
    }

    #ifndef GEARS_NO_IOSTREAM

    template<typename Elem, typename Traits>
    friend auto operator<<(std::basic_ostream<Elem, Traits>& out, const parser& po) -> decltype(out) {
        out << "usage: " << po.program_name << ' ' << po.program_usage << "\n\n";

        for(auto&& arg : po.args) {
            out << arg.second;
        }

        return out;
    }

    #endif // GEARS_NO_IOSTREAM
};
} // command_line
} // gears

#endif // GEARS_COMMAND_LINE_PARSER_HPP<|endoftext|>


<commit_before>#include <bts/blockchain/chain_interface.hpp>
#include <bts/blockchain/operation_factory.hpp>
#include <bts/blockchain/transaction_evaluation_state.hpp>

namespace bts { namespace blockchain {

   transaction_evaluation_state::transaction_evaluation_state( const chain_interface_ptr& current_state, digest_type chain_id )
   :_current_state( current_state ),_chain_id(chain_id),_skip_signature_check(false)
   {
   }

   transaction_evaluation_state::~transaction_evaluation_state()
   {
   }

   void transaction_evaluation_state::reset()
   {
      signed_keys.clear();
      balance.clear();
      deposits.clear();
      withdraws.clear();
      net_delegate_votes.clear();
      required_deposits.clear();
      validation_error.reset();
   }

   bool transaction_evaluation_state::check_signature( const address& a )const
   {
      return  _skip_signature_check || signed_keys.find( a ) != signed_keys.end();
   }

   void transaction_evaluation_state::verify_delegate_id( account_id_type id )const
   {
      auto current_account = _current_state->get_account_record( id );
      if( !current_account ) FC_CAPTURE_AND_THROW( unknown_account_id, (id) );
      if( !current_account->is_delegate() ) FC_CAPTURE_AND_THROW( not_a_delegate, (id) );
   }

   void transaction_evaluation_state::add_required_deposit( const address& owner_key, const asset& amount )
   {
      FC_ASSERT( trx.delegate_slate_id );
      balance_id_type balance_id = withdraw_condition(
                                       withdraw_with_signature( owner_key ),
                                       amount.asset_id, *trx.delegate_slate_id ).get_address();

      auto itr = required_deposits.find( balance_id );
      if( itr == required_deposits.end() )
      {
         required_deposits[balance_id] = amount;
      }
      else
      {
         required_deposits[balance_id] += amount;
      }
   }

   void transaction_evaluation_state::update_delegate_votes()
   {
      auto asset_rec = _current_state->get_asset_record( asset_id_type() );

      for( auto del_vote : net_delegate_votes )
      {
         auto del_rec = _current_state->get_account_record( del_vote.first );
         FC_ASSERT( !!del_rec );
         del_rec->adjust_votes_for( del_vote.second.votes_for );

         _current_state->store_account_record( *del_rec );
      }
   }

   void transaction_evaluation_state::validate_required_fee()
   { try {
      share_type required_fee = _current_state->calculate_data_fee( trx.data_size() );
      asset xts_fees;
      auto fee_itr = balance.find( 0 );
      if( fee_itr != balance.end() ) xts_fees += asset( fee_itr->second, 0);

      xts_fees += alt_fees_paid;

      if( required_fees > xts_fees )
      {
         FC_CAPTURE_AND_THROW( insufficient_fee, (required_fee)(alt_fees_paid)(xts_fees)  );
      }
   } FC_RETHROW_EXCEPTIONS( warn, "" ) }

   /**
    *  Process all fees and update the asset records.
    */
   void transaction_evaluation_state::post_evaluate()
   { try {
      required_fees += asset(_current_state->calculate_data_fee(fc::raw::pack_size(trx)),0);

      balance[0]; // make sure we have something for this.
      for( auto fee : balance )
      {
         if( fee.second < 0 ) FC_CAPTURE_AND_THROW( negative_fee, (fee) );
         if( fee.second > 0 )
         {
            if( fee.first == 0  )
               continue;
            // check to see if there are any open bids to buy the asset
         }

         // lowest ask is someone with XTS offered at a price of USD / XTS, fee.first
         // is an amount of USD which can be converted to price*USD XTS provided we
         // send lowest_ask.index.owner the USD
         omarket_order lowest_ask = _current_state->get_lowest_ask_record( fee.first, 0 );
         if( lowest_ask )
         {
            // fees paid in something other than XTS are discounted 50%
            alt_fees_paid += asset( fee.second/2, fee.first ) * lowest_ask->market_index.order_price;
         }
      }

      for( auto fee : balance )
      {
         if( fee.second < 0 ) FC_CAPTURE_AND_THROW( negative_fee, (fee) );
         if( fee.second > 0 ) // if a fee was paid...
         {
            auto asset_record = _current_state->get_asset_record( fee.first );
            if( !asset_record )
              FC_CAPTURE_AND_THROW( unknown_asset_id, (fee.first) );

            asset_record->collected_fees += fee.second;
            // collecting fees should not decrease share supply.
            // asset_record->current_share_supply -= fee.second;
            _current_state->store_asset_record( *asset_record );
         }
      }

      for( auto required_deposit : required_deposits )
      {
         auto provided_itr = provided_deposits.find( required_deposit.first );

         if( provided_itr->second < required_deposit.second )
            FC_CAPTURE_AND_THROW( missing_deposit, (required_deposit) );
      }

   } FC_RETHROW_EXCEPTIONS( warn, "" ) }

   void transaction_evaluation_state::evaluate( const signed_transaction& trx_arg, bool skip_signature_check )
   { try {
      reset();
      _skip_signature_check = skip_signature_check;
      try {
        if( trx_arg.expiration < _current_state->now() )
        {
           auto expired_by_sec = (trx_arg.expiration - _current_state->now()).to_seconds();
           FC_CAPTURE_AND_THROW( expired_transaction, (trx_arg)(_current_state->now())(expired_by_sec) );
        }
        if( trx_arg.expiration > (_current_state->now() + BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC) )
           FC_CAPTURE_AND_THROW( invalid_transaction_expiration, (trx_arg)(_current_state->now()) );

        auto trx_size = fc::raw::pack_size(trx_arg);
        if(  trx_size > BTS_BLOCKCHAIN_MAX_TRANSACTION_SIZE )
           FC_CAPTURE_AND_THROW( oversized_transaction, (trx_size ) );

        auto trx_id = trx_arg.id();

        if( _current_state->is_known_transaction( trx_id ) )
           FC_CAPTURE_AND_THROW( duplicate_transaction, (trx_id) );

        trx = trx_arg;
        if( !_skip_signature_check )
        {
           auto digest = trx_arg.digest( _chain_id );
           for( auto sig : trx.signatures )
           {
              auto key = fc::ecc::public_key( sig, digest ).serialize();
              signed_keys.insert( address(key) );
              signed_keys.insert( address(pts_address(key,false,56) ) );
              signed_keys.insert( address(pts_address(key,true,56) )  );
              signed_keys.insert( address(pts_address(key,false,0) )  );
              signed_keys.insert( address(pts_address(key,true,0) )   );
           }
        }
        for( auto op : trx.operations )
        {
           evaluate_operation( op );
        }
        post_evaluate();
        validate_required_fee();
        update_delegate_votes();
      }
      catch ( const fc::exception& e )
      {
         validation_error = e;
         throw;
      }
   } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx_arg) ) }

   void transaction_evaluation_state::evaluate_operation( const operation& op )
   {
      operation_factory::instance().evaluate( *this, op );
   }

   void transaction_evaluation_state::adjust_vote( slate_id_type slate_id, share_type amount )
   {
      if( slate_id )
      {
         auto slate = _current_state->get_delegate_slate( slate_id );
         if( !slate ) FC_CAPTURE_AND_THROW( unknown_delegate_slate, (slate_id) );
         for( auto delegate_id : slate->supported_delegates )
         {
            if( BTS_BLOCKCHAIN_ENABLE_NEGATIVE_VOTES && delegate_id < signed_int(0) )
               net_delegate_votes[abs(delegate_id)].votes_for -= amount;
            else
               net_delegate_votes[abs(delegate_id)].votes_for += amount;
         }
      }
   }

   share_type transaction_evaluation_state::get_fees( asset_id_type id )const
   {
      auto itr = balance.find(id);
      if( itr != balance.end() )
         return itr->second;
      return 0;
   }

   /**
    *
    */
   void transaction_evaluation_state::sub_balance( const balance_id_type& balance_id, const asset& amount )
   {
      auto provided_deposit_itr = provided_deposits.find( balance_id );
      if( provided_deposit_itr == provided_deposits.end() )
      {
         provided_deposits[balance_id] = amount;
      }
      else
      {
         provided_deposit_itr->second += amount;
      }

      auto deposit_itr = deposits.find(amount.asset_id);
      if( deposit_itr == deposits.end()  )
      {
         deposits[amount.asset_id] = amount;
      }
      else
      {
         deposit_itr->second += amount;
      }

      auto balance_itr = balance.find(amount.asset_id);
      if( balance_itr != balance.end()  )
      {
          balance_itr->second -= amount.amount;
      }
      else
      {
          balance[amount.asset_id] =  -amount.amount;
      }
   }

   void transaction_evaluation_state::add_balance( const asset& amount )
   {
      auto withdraw_itr = withdraws.find( amount.asset_id );
      if( withdraw_itr == withdraws.end() )
         withdraws[amount.asset_id] = amount;
      else
         withdraw_itr->second += amount;

      auto balance_itr = balance.find( amount.asset_id );
      if( balance_itr == balance.end() )
         balance[amount.asset_id] = amount.amount;
      else
         balance_itr->second += amount.amount;
   }

   /**
    *  Throws if the asset is not known to the blockchain.
    */
   void transaction_evaluation_state::validate_asset( const asset& asset_to_validate )const
   {
      auto asset_rec = _current_state->get_asset_record( asset_to_validate.asset_id );
      if( NOT asset_rec )
         FC_CAPTURE_AND_THROW( unknown_asset_id, (asset_to_validate) );
   }

} } // bts::blockchain
<commit_msg>Resolve #610<commit_after>#include <bts/blockchain/chain_interface.hpp>
#include <bts/blockchain/operation_factory.hpp>
#include <bts/blockchain/transaction_evaluation_state.hpp>

namespace bts { namespace blockchain {

   transaction_evaluation_state::transaction_evaluation_state( const chain_interface_ptr& current_state, digest_type chain_id )
   :_current_state( current_state ),_chain_id(chain_id),_skip_signature_check(false)
   {
   }

   transaction_evaluation_state::~transaction_evaluation_state()
   {
   }

   void transaction_evaluation_state::reset()
   {
      signed_keys.clear();
      balance.clear();
      deposits.clear();
      withdraws.clear();
      net_delegate_votes.clear();
      required_deposits.clear();
      validation_error.reset();
   }

   bool transaction_evaluation_state::check_signature( const address& a )const
   {
      return  _skip_signature_check || signed_keys.find( a ) != signed_keys.end();
   }

   void transaction_evaluation_state::verify_delegate_id( account_id_type id )const
   {
      auto current_account = _current_state->get_account_record( id );
      if( !current_account ) FC_CAPTURE_AND_THROW( unknown_account_id, (id) );
      if( !current_account->is_delegate() ) FC_CAPTURE_AND_THROW( not_a_delegate, (id) );
   }

   void transaction_evaluation_state::add_required_deposit( const address& owner_key, const asset& amount )
   {
      FC_ASSERT( trx.delegate_slate_id );
      balance_id_type balance_id = withdraw_condition(
                                       withdraw_with_signature( owner_key ),
                                       amount.asset_id, *trx.delegate_slate_id ).get_address();

      auto itr = required_deposits.find( balance_id );
      if( itr == required_deposits.end() )
      {
         required_deposits[balance_id] = amount;
      }
      else
      {
         required_deposits[balance_id] += amount;
      }
   }

   void transaction_evaluation_state::update_delegate_votes()
   {
      auto asset_rec = _current_state->get_asset_record( asset_id_type() );

      for( auto del_vote : net_delegate_votes )
      {
         auto del_rec = _current_state->get_account_record( del_vote.first );
         FC_ASSERT( !!del_rec );
         del_rec->adjust_votes_for( del_vote.second.votes_for );

         _current_state->store_account_record( *del_rec );
      }
   }

   void transaction_evaluation_state::validate_required_fee()
   { try {
      asset xts_fees;
      auto fee_itr = balance.find( 0 );
      if( fee_itr != balance.end() ) xts_fees += asset( fee_itr->second, 0);

      xts_fees += alt_fees_paid;

      if( required_fees > xts_fees )
      {
         FC_CAPTURE_AND_THROW( insufficient_fee, (required_fees)(alt_fees_paid)(xts_fees)  )
      }
   } FC_RETHROW_EXCEPTIONS( warn, "" ) }

   /**
    *  Process all fees and update the asset records.
    */
   void transaction_evaluation_state::post_evaluate()
   { try {
      required_fees += asset(_current_state->calculate_data_fee(fc::raw::pack_size(trx)),0);

      wdump((trx));
      // Should this be here? We may not have fees in XTS now...
      balance[0]; // make sure we have something for this.
      for( auto fee : balance )
      {
         if( fee.second < 0 ) FC_CAPTURE_AND_THROW( negative_fee, (fee) );
         // if the fee is already in XTS or the fee balance is zero, move along...
         if( fee.first == 0 || fee.second == 0 )
           continue;

         // lowest ask is someone with XTS offered at a price of USD / XTS, fee.first
         // is an amount of USD which can be converted to price*USD XTS provided we
         // send lowest_ask.index.owner the USD
         omarket_order lowest_ask = _current_state->get_lowest_ask_record( fee.first, 0 );
         if( lowest_ask )
         {
            // fees paid in something other than XTS are discounted 50%
            alt_fees_paid += asset( fee.second/2, fee.first ) * lowest_ask->market_index.order_price;
         }
      }

      for( auto fee : balance )
      {
         if( fee.second < 0 ) FC_CAPTURE_AND_THROW( negative_fee, (fee) );
         if( fee.second > 0 ) // if a fee was paid...
         {
            auto asset_record = _current_state->get_asset_record( fee.first );
            if( !asset_record )
              FC_CAPTURE_AND_THROW( unknown_asset_id, (fee.first) );

            asset_record->collected_fees += fee.second;
            // collecting fees should not decrease share supply.
            // asset_record->current_share_supply -= fee.second;
            _current_state->store_asset_record( *asset_record );
         }
      }

      for( auto required_deposit : required_deposits )
      {
         auto provided_itr = provided_deposits.find( required_deposit.first );

         if( provided_itr->second < required_deposit.second )
            FC_CAPTURE_AND_THROW( missing_deposit, (required_deposit) );
      }

   } FC_RETHROW_EXCEPTIONS( warn, "" ) }

   void transaction_evaluation_state::evaluate( const signed_transaction& trx_arg, bool skip_signature_check )
   { try {
      reset();
      _skip_signature_check = skip_signature_check;
      try {
        if( trx_arg.expiration < _current_state->now() )
        {
           auto expired_by_sec = (trx_arg.expiration - _current_state->now()).to_seconds();
           FC_CAPTURE_AND_THROW( expired_transaction, (trx_arg)(_current_state->now())(expired_by_sec) );
        }
        if( trx_arg.expiration > (_current_state->now() + BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC) )
           FC_CAPTURE_AND_THROW( invalid_transaction_expiration, (trx_arg)(_current_state->now()) );

        auto trx_size = fc::raw::pack_size(trx_arg);
        if(  trx_size > BTS_BLOCKCHAIN_MAX_TRANSACTION_SIZE )
           FC_CAPTURE_AND_THROW( oversized_transaction, (trx_size ) );

        auto trx_id = trx_arg.id();

        if( _current_state->is_known_transaction( trx_id ) )
           FC_CAPTURE_AND_THROW( duplicate_transaction, (trx_id) );

        trx = trx_arg;
        if( !_skip_signature_check )
        {
           auto digest = trx_arg.digest( _chain_id );
           for( auto sig : trx.signatures )
           {
              auto key = fc::ecc::public_key( sig, digest ).serialize();
              signed_keys.insert( address(key) );
              signed_keys.insert( address(pts_address(key,false,56) ) );
              signed_keys.insert( address(pts_address(key,true,56) )  );
              signed_keys.insert( address(pts_address(key,false,0) )  );
              signed_keys.insert( address(pts_address(key,true,0) )   );
           }
        }
        for( auto op : trx.operations )
        {
           evaluate_operation( op );
        }
        post_evaluate();
        validate_required_fee();
        update_delegate_votes();
      }
      catch ( const fc::exception& e )
      {
         validation_error = e;
         throw;
      }
   } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx_arg) ) }

   void transaction_evaluation_state::evaluate_operation( const operation& op )
   {
      operation_factory::instance().evaluate( *this, op );
   }

   void transaction_evaluation_state::adjust_vote( slate_id_type slate_id, share_type amount )
   {
      if( slate_id )
      {
         auto slate = _current_state->get_delegate_slate( slate_id );
         if( !slate ) FC_CAPTURE_AND_THROW( unknown_delegate_slate, (slate_id) );
         for( auto delegate_id : slate->supported_delegates )
         {
            if( BTS_BLOCKCHAIN_ENABLE_NEGATIVE_VOTES && delegate_id < signed_int(0) )
               net_delegate_votes[abs(delegate_id)].votes_for -= amount;
            else
               net_delegate_votes[abs(delegate_id)].votes_for += amount;
         }
      }
   }

   share_type transaction_evaluation_state::get_fees( asset_id_type id )const
   {
      auto itr = balance.find(id);
      if( itr != balance.end() )
         return itr->second;
      return 0;
   }

   /**
    *
    */
   void transaction_evaluation_state::sub_balance( const balance_id_type& balance_id, const asset& amount )
   {
      auto provided_deposit_itr = provided_deposits.find( balance_id );
      if( provided_deposit_itr == provided_deposits.end() )
      {
         provided_deposits[balance_id] = amount;
      }
      else
      {
         provided_deposit_itr->second += amount;
      }

      auto deposit_itr = deposits.find(amount.asset_id);
      if( deposit_itr == deposits.end()  )
      {
         deposits[amount.asset_id] = amount;
      }
      else
      {
         deposit_itr->second += amount;
      }

      auto balance_itr = balance.find(amount.asset_id);
      if( balance_itr != balance.end()  )
      {
          balance_itr->second -= amount.amount;
      }
      else
      {
          balance[amount.asset_id] =  -amount.amount;
      }
   }

   void transaction_evaluation_state::add_balance( const asset& amount )
   {
      auto withdraw_itr = withdraws.find( amount.asset_id );
      if( withdraw_itr == withdraws.end() )
         withdraws[amount.asset_id] = amount;
      else
         withdraw_itr->second += amount;

      auto balance_itr = balance.find( amount.asset_id );
      if( balance_itr == balance.end() )
         balance[amount.asset_id] = amount.amount;
      else
         balance_itr->second += amount.amount;
   }

   /**
    *  Throws if the asset is not known to the blockchain.
    */
   void transaction_evaluation_state::validate_asset( const asset& asset_to_validate )const
   {
      auto asset_rec = _current_state->get_asset_record( asset_to_validate.asset_id );
      if( NOT asset_rec )
         FC_CAPTURE_AND_THROW( unknown_asset_id, (asset_to_validate) );
   }

} } // bts::blockchain
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/privacy_blacklist/blacklist.h"

#include <algorithm>
#include <limits>
#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "chrome/browser/privacy_blacklist/blacklist_store.h"
#include "chrome/common/url_constants.h"
#include "net/http/http_util.h"

#define STRINGIZE(s) #s

namespace {

const char* const cookie_headers[2] = { "cookie", "set-cookie" };

}  // namespace

const unsigned int Blacklist::kBlockAll = 1;
const unsigned int Blacklist::kDontSendCookies = 1 << 1;
const unsigned int Blacklist::kDontStoreCookies = 1 << 2;
const unsigned int Blacklist::kDontPersistCookies = 1 << 3;
const unsigned int Blacklist::kDontSendReferrer = 1 << 4;
const unsigned int Blacklist::kDontSendUserAgent = 1 << 5;
const unsigned int Blacklist::kBlockByType = 1 << 6;
const unsigned int Blacklist::kBlockUnsecure = 1 << 7;
const unsigned int Blacklist::kBlockRequest = kBlockAll | kBlockUnsecure;
const unsigned int Blacklist::kBlockResponse = kBlockByType;
const unsigned int Blacklist::kModifySentHeaders =
    kDontSendCookies | kDontSendUserAgent | kDontSendReferrer;
const unsigned int Blacklist::kModifyReceivedHeaders =
    kDontPersistCookies | kDontStoreCookies;
const unsigned int Blacklist::kFilterByHeaders =
    kModifyReceivedHeaders | kBlockByType;

unsigned int Blacklist::String2Attribute(const std::string& s) {
  if (s == STRINGIZE(kBlockAll))
    return kBlockAll;
  else if (s == STRINGIZE(kDontSendCookies))
    return kDontSendCookies;
  else if (s == STRINGIZE(kDontStoreCookies))
    return kDontStoreCookies;
  else if (s == STRINGIZE(kDontPersistCookies))
    return kDontPersistCookies;
  else if (s == STRINGIZE(kDontSendReferrer))
    return kDontSendReferrer;
  else if (s == STRINGIZE(kDontSendUserAgent))
    return kDontSendUserAgent;
  else if (s == STRINGIZE(kBlockByType))
    return kBlockByType;
  else if (s == STRINGIZE(kBlockUnsecure))
    return kBlockUnsecure;
  return 0;
}

// static
bool Blacklist::Matches(const std::string& pattern, const std::string& url) {
  if (pattern.size() > url.size())
    return false;

  std::string::size_type p = 0;
  std::string::size_type u = 0;

  while (pattern[p] != '\0' && url[u] != '\0') {
    if (pattern[p] == '@') {
      while (pattern[++p] == '@');  // Consecutive @ are redundant.

      if (pattern[p] == '\0')
        return true;  // Nothing to match after the @.

      // Look for another wildcard to determine pattern-chunk.
      std::string::size_type tp = pattern.find_first_of("@", p);

      // If it must match until the end, compare the last characters.
      if (tp == std::string::npos) {
        std::string::size_type ur = url.size() - u;
        std::string::size_type pr = pattern.size() - p;
        return (pr <= ur) &&
            (url.compare(url.size() - pr, pr, pattern.c_str() + p) == 0);
      }

      // Else find the pattern chunk which is pattern[p:tp]
      std::string::size_type tu = url.find(pattern.c_str() + p, u, tp - p);
      if (tu == std::string::npos)
        return false;  // Pattern chunk not found.

      // Since tp is strictly greater than p, both u and p always increase.
      u = tu + tp - p;
      p = tp;
      continue;
    }

    // Match non-wildcard character.
    if (pattern[p++] != url[u++])
      return false;
  }
  return pattern[p] == '\0';
}

bool Blacklist::Entry::MatchesType(const std::string& type) const {
  return std::find(types_.begin(), types_.end(), type) != types_.end();
}

bool Blacklist::Entry::IsBlocked(const GURL& url) const {
  return (attributes_ & kBlockAll) ||
    ((attributes_ & kBlockUnsecure) && !url.SchemeIsSecure());
}

Blacklist::Entry::Entry(const std::string& pattern, const Provider* provider,
                        bool is_exception)
    : attributes_(0),
      is_exception_(is_exception),
      pattern_(pattern),
      provider_(provider) {}

void Blacklist::Entry::AddAttributes(unsigned int attributes) {
  attributes_ |= attributes;
}

void Blacklist::Entry::AddType(const std::string& type) {
  types_.push_back(type);
}

void Blacklist::Entry::Merge(const Entry& entry) {
  attributes_ |= entry.attributes_;

  std::copy(entry.types_.begin(), entry.types_.end(),
            std::back_inserter(types_));
}

void Blacklist::Entry::SwapTypes(std::vector<std::string>* types) {
  DCHECK(types);
  types->swap(types_);
}

bool Blacklist::Match::MatchType(const std::string& type) const {
  // No match if any exception matches.
  for (std::vector<const Entry*>::const_iterator i = exception_entries_.begin();
      i != exception_entries_.end(); ++i) {
    if ((*i)->MatchesType(type))
      return false;
  }

  // Otherwise, match if any blacklist entry matches.
  for (std::vector<const Entry*>::const_iterator i = matching_entries_.begin();
      i != matching_entries_.end(); ++i) {
    if ((*i)->MatchesType(type))
      return true;
  }

  return false;
}

bool Blacklist::Match::IsBlocked(const GURL& url) const {
  return (attributes() & kBlockAll) ||
    ((attributes() & kBlockUnsecure) && !url.SchemeIsSecure());
}

Blacklist::Match::Match() : matching_attributes_(0), exception_attributes_(0) {}

void Blacklist::Match::AddEntry(const Entry* entry) {
  if (entry->is_exception()) {
    exception_attributes_ |= entry->attributes();
    exception_entries_.push_back(entry);
  } else {
    matching_attributes_ |= entry->attributes();
    matching_entries_.push_back(entry);
  }
}

Blacklist::Blacklist() {
}

Blacklist::~Blacklist() {
}

void Blacklist::AddEntry(Entry* entry) {
  DCHECK(entry);
  blacklist_.push_back(linked_ptr<Entry>(entry));
}

void Blacklist::AddProvider(Provider* provider) {
  DCHECK(provider);
  providers_.push_back(linked_ptr<Provider>(provider));
}

// Returns a pointer to the Blacklist-owned entry which matches the given
// URL. If no matching Entry is found, returns null.
Blacklist::Match* Blacklist::FindMatch(const GURL& url) const {
  // Never match something which is not http, https or ftp.
  // TODO(idanan): Investigate if this would be an inclusion test instead of an
  // exclusion test and if there are other schemes to test for.
  if (!url.SchemeIs(chrome::kHttpScheme) &&
      !url.SchemeIs(chrome::kHttpsScheme) &&
      !url.SchemeIs(chrome::kFtpScheme))
    return 0;
  std::string url_spec = GetURLAsLookupString(url);
  Match* match = NULL;
  for (EntryList::const_iterator i = blacklist_.begin();
       i != blacklist_.end(); ++i) {
    if (Matches((*i)->pattern(), url_spec)) {
      if (!match)
        match = new Match;
      match->AddEntry(i->get());
    }
  }
  return match;
}

// static
std::string Blacklist::GetURLAsLookupString(const GURL& url) {
  std::string url_spec = url.host() + url.path();
  if (!url.query().empty())
    url_spec = url_spec + "?" + url.query();

  return url_spec;
}

std::string Blacklist::StripCookies(const std::string& header) {
  return net::HttpUtil::StripHeaders(header, cookie_headers, 2);
}

std::string Blacklist::StripCookieExpiry(const std::string& cookie) {
  std::string::size_type delim = cookie.find(';');
  std::string::size_type start = cookie.find("expires=", delim + 1);
  if (start != std::string::npos) {
    std::string::size_type i = start;
    // Make sure only whitespace precedes the expiry until a delimiter.
    while (cookie[--i] != ';')
      if (!IsAsciiWhitespace(cookie[i]))
        return cookie;

    std::string session_cookie(cookie, 0, i);
    std::string::size_type end = cookie.find(';', start + 1);
    if (end != std::string::npos)
      session_cookie.append(cookie.substr(end));
    return session_cookie;
  }
  return cookie;
}
<commit_msg>Whitespace change to clobber build bots.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/privacy_blacklist/blacklist.h"

#include <algorithm>
#include <limits>
#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
#include "chrome/browser/privacy_blacklist/blacklist_store.h"
#include "chrome/common/url_constants.h"
#include "net/http/http_util.h"

#define STRINGIZE(s) #s

namespace {

const char* const cookie_headers[2] = { "cookie", "set-cookie" };

} // namespace

const unsigned int Blacklist::kBlockAll = 1;
const unsigned int Blacklist::kDontSendCookies = 1 << 1;
const unsigned int Blacklist::kDontStoreCookies = 1 << 2;
const unsigned int Blacklist::kDontPersistCookies = 1 << 3;
const unsigned int Blacklist::kDontSendReferrer = 1 << 4;
const unsigned int Blacklist::kDontSendUserAgent = 1 << 5;
const unsigned int Blacklist::kBlockByType = 1 << 6;
const unsigned int Blacklist::kBlockUnsecure = 1 << 7;
const unsigned int Blacklist::kBlockRequest = kBlockAll | kBlockUnsecure;
const unsigned int Blacklist::kBlockResponse = kBlockByType;
const unsigned int Blacklist::kModifySentHeaders =
    kDontSendCookies | kDontSendUserAgent | kDontSendReferrer;
const unsigned int Blacklist::kModifyReceivedHeaders =
    kDontPersistCookies | kDontStoreCookies;
const unsigned int Blacklist::kFilterByHeaders =
    kModifyReceivedHeaders | kBlockByType;

unsigned int Blacklist::String2Attribute(const std::string& s) {
  if (s == STRINGIZE(kBlockAll))
    return kBlockAll;
  else if (s == STRINGIZE(kDontSendCookies))
    return kDontSendCookies;
  else if (s == STRINGIZE(kDontStoreCookies))
    return kDontStoreCookies;
  else if (s == STRINGIZE(kDontPersistCookies))
    return kDontPersistCookies;
  else if (s == STRINGIZE(kDontSendReferrer))
    return kDontSendReferrer;
  else if (s == STRINGIZE(kDontSendUserAgent))
    return kDontSendUserAgent;
  else if (s == STRINGIZE(kBlockByType))
    return kBlockByType;
  else if (s == STRINGIZE(kBlockUnsecure))
    return kBlockUnsecure;
  return 0;
}

// static
bool Blacklist::Matches(const std::string& pattern, const std::string& url) {
  if (pattern.size() > url.size())
    return false;

  std::string::size_type p = 0;
  std::string::size_type u = 0;

  while (pattern[p] != '\0' && url[u] != '\0') {
    if (pattern[p] == '@') {
      while (pattern[++p] == '@');  // Consecutive @ are redundant.

      if (pattern[p] == '\0')
        return true;  // Nothing to match after the @.

      // Look for another wildcard to determine pattern-chunk.
      std::string::size_type tp = pattern.find_first_of("@", p);

      // If it must match until the end, compare the last characters.
      if (tp == std::string::npos) {
        std::string::size_type ur = url.size() - u;
        std::string::size_type pr = pattern.size() - p;
        return (pr <= ur) &&
            (url.compare(url.size() - pr, pr, pattern.c_str() + p) == 0);
      }

      // Else find the pattern chunk which is pattern[p:tp]
      std::string::size_type tu = url.find(pattern.c_str() + p, u, tp - p);
      if (tu == std::string::npos)
        return false;  // Pattern chunk not found.

      // Since tp is strictly greater than p, both u and p always increase.
      u = tu + tp - p;
      p = tp;
      continue;
    }

    // Match non-wildcard character.
    if (pattern[p++] != url[u++])
      return false;
  }
  return pattern[p] == '\0';
}

bool Blacklist::Entry::MatchesType(const std::string& type) const {
  return std::find(types_.begin(), types_.end(), type) != types_.end();
}

bool Blacklist::Entry::IsBlocked(const GURL& url) const {
  return (attributes_ & kBlockAll) ||
    ((attributes_ & kBlockUnsecure) && !url.SchemeIsSecure());
}

Blacklist::Entry::Entry(const std::string& pattern, const Provider* provider,
                        bool is_exception)
    : attributes_(0),
      is_exception_(is_exception),
      pattern_(pattern),
      provider_(provider) {}

void Blacklist::Entry::AddAttributes(unsigned int attributes) {
  attributes_ |= attributes;
}

void Blacklist::Entry::AddType(const std::string& type) {
  types_.push_back(type);
}

void Blacklist::Entry::Merge(const Entry& entry) {
  attributes_ |= entry.attributes_;

  std::copy(entry.types_.begin(), entry.types_.end(),
            std::back_inserter(types_));
}

void Blacklist::Entry::SwapTypes(std::vector<std::string>* types) {
  DCHECK(types);
  types->swap(types_);
}

bool Blacklist::Match::MatchType(const std::string& type) const {
  // No match if any exception matches.
  for (std::vector<const Entry*>::const_iterator i = exception_entries_.begin();
      i != exception_entries_.end(); ++i) {
    if ((*i)->MatchesType(type))
      return false;
  }

  // Otherwise, match if any blacklist entry matches.
  for (std::vector<const Entry*>::const_iterator i = matching_entries_.begin();
      i != matching_entries_.end(); ++i) {
    if ((*i)->MatchesType(type))
      return true;
  }

  return false;
}

bool Blacklist::Match::IsBlocked(const GURL& url) const {
  return (attributes() & kBlockAll) ||
    ((attributes() & kBlockUnsecure) && !url.SchemeIsSecure());
}

Blacklist::Match::Match() : matching_attributes_(0), exception_attributes_(0) {}

void Blacklist::Match::AddEntry(const Entry* entry) {
  if (entry->is_exception()) {
    exception_attributes_ |= entry->attributes();
    exception_entries_.push_back(entry);
  } else {
    matching_attributes_ |= entry->attributes();
    matching_entries_.push_back(entry);
  }
}

Blacklist::Blacklist() {
}

Blacklist::~Blacklist() {
}

void Blacklist::AddEntry(Entry* entry) {
  DCHECK(entry);
  blacklist_.push_back(linked_ptr<Entry>(entry));
}

void Blacklist::AddProvider(Provider* provider) {
  DCHECK(provider);
  providers_.push_back(linked_ptr<Provider>(provider));
}

// Returns a pointer to the Blacklist-owned entry which matches the given
// URL. If no matching Entry is found, returns null.
Blacklist::Match* Blacklist::FindMatch(const GURL& url) const {
  // Never match something which is not http, https or ftp.
  // TODO(idanan): Investigate if this would be an inclusion test instead of an
  // exclusion test and if there are other schemes to test for.
  if (!url.SchemeIs(chrome::kHttpScheme) &&
      !url.SchemeIs(chrome::kHttpsScheme) &&
      !url.SchemeIs(chrome::kFtpScheme))
    return 0;
  std::string url_spec = GetURLAsLookupString(url);
  Match* match = NULL;
  for (EntryList::const_iterator i = blacklist_.begin();
       i != blacklist_.end(); ++i) {
    if (Matches((*i)->pattern(), url_spec)) {
      if (!match)
        match = new Match;
      match->AddEntry(i->get());
    }
  }
  return match;
}

// static
std::string Blacklist::GetURLAsLookupString(const GURL& url) {
  std::string url_spec = url.host() + url.path();
  if (!url.query().empty())
    url_spec = url_spec + "?" + url.query();

  return url_spec;
}

std::string Blacklist::StripCookies(const std::string& header) {
  return net::HttpUtil::StripHeaders(header, cookie_headers, 2);
}

std::string Blacklist::StripCookieExpiry(const std::string& cookie) {
  std::string::size_type delim = cookie.find(';');
  std::string::size_type start = cookie.find("expires=", delim + 1);
  if (start != std::string::npos) {
    std::string::size_type i = start;
    // Make sure only whitespace precedes the expiry until a delimiter.
    while (cookie[--i] != ';')
      if (!IsAsciiWhitespace(cookie[i]))
        return cookie;

    std::string session_cookie(cookie, 0, i);
    std::string::size_type end = cookie.find(';', start + 1);
    if (end != std::string::npos)
      session_cookie.append(cookie.substr(end));
    return session_cookie;
  }
  return cookie;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/translate/translate_manager.h"

#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/translation_service.h"
#include "chrome/browser/tab_contents/language_state.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/translate/translate_infobars_delegates.h"
#include "chrome/browser/translate/translate_prefs.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"

TranslateManager::~TranslateManager() {
}

void TranslateManager::Observe(NotificationType type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::TAB_LANGUAGE_DETERMINED: {
      TabContents* tab = Source<TabContents>(source).ptr();
      std::string language = *(Details<std::string>(details).ptr());
      // We may get this notifications multiple times.  Make sure to translate
      // only once.
      if (!tab->language_state().translation_pending())
        InitiateTranslation(tab, language);
      break;
    }
    case NotificationType::PAGE_TRANSLATED: {
      // Only add translate infobar if it doesn't exist; if it already exists,
      // it would have received the same notification and acted accordingly.
      TabContents* tab = Source<TabContents>(source).ptr();
      int i;
      for (i = 0; i < tab->infobar_delegate_count(); ++i) {
        InfoBarDelegate* info_bar = tab->GetInfoBarDelegateAt(i);
        if (info_bar->AsTranslateInfoBarDelegate())
          break;
      }
      if (i == tab->infobar_delegate_count()) {
        NavigationEntry* entry = tab->controller().GetActiveEntry();
        if (entry) {
          std::pair<std::string, std::string>* language_pair =
              (Details<std::pair<std::string, std::string> >(details).ptr());
          PrefService* prefs = tab->profile()->GetPrefs();
          tab->AddInfoBar(new TranslateInfoBarDelegate(tab, prefs,
              TranslateInfoBarDelegate::kAfterTranslate, entry->url(),
              language_pair->first, language_pair->second));
        }
      }
      break;
    }
    case NotificationType::PROFILE_DESTROYED: {
      Profile* profile = Source<Profile>(source).ptr();
      notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
                                     source);
      size_t count = accept_languages_.erase(profile->GetPrefs());
      // We should know about this profile since we are listening for
      // notifications on it.
      DCHECK(count > 0);
      profile->GetPrefs()->RemovePrefObserver(prefs::kAcceptLanguages, this);
      break;
    }
    case NotificationType::PREF_CHANGED: {
      DCHECK(*Details<std::wstring>(details).ptr() == prefs::kAcceptLanguages);
      PrefService* prefs = Source<PrefService>(source).ptr();
      InitAcceptLanguages(prefs);
      break;
    }
    default:
      NOTREACHED();
  }
}

TranslateManager::TranslateManager() {
  if (!TestEnabled() && !TranslationService::IsTranslationEnabled())
    return;

  notification_registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED,
                              NotificationService::AllSources());
  notification_registrar_.Add(this, NotificationType::PAGE_TRANSLATED,
                              NotificationService::AllSources());
}

void TranslateManager::InitiateTranslation(TabContents* tab,
                                           const std::string& page_lang) {
  PrefService* prefs = tab->profile()->GetPrefs();
  NavigationEntry* entry = tab->controller().GetActiveEntry();
  if (!entry) {
    NOTREACHED();
    return;
  }

  if (!TranslationService::IsSupportedLanguage(page_lang))
    return;  // Nothing to do, we don't support that language.

  std::string ui_lang = TranslationService::GetLanguageCode(
      g_browser_process->GetApplicationLocale());

  // We don't want to translate:
  // - any Chrome specific page (New Tab Page, Download, History... pages).
  // - similar languages (ex: en-US to en).
  // - any user black-listed URLs or user selected language combination.
  // - any language the user configured as accepted languages.
  if (entry->url().SchemeIs("chrome") || page_lang == ui_lang ||
      !TranslatePrefs::CanTranslate(prefs, page_lang, entry->url()) ||
      IsAcceptLanguage(tab, page_lang)) {
    return;
  }

  if (TranslatePrefs::ShouldAutoTranslate(prefs, page_lang, ui_lang)) {
    // The user has previously select "always translate" for this language.
    tab->TranslatePage(page_lang, ui_lang);
    return;
  }

  std::string auto_translate_to = tab->language_state().AutoTranslateTo();
  if (!auto_translate_to.empty()) {
    // This page was navigated through a click from a translated page.
    tab->TranslatePage(page_lang, auto_translate_to);
    return;
  }

  // Prompts the user if he/she wants the page translated.
  tab->AddInfoBar(new TranslateInfoBarDelegate(tab, prefs,
      TranslateInfoBarDelegate::kBeforeTranslate, entry->url(),
      page_lang, ui_lang));
}

bool TranslateManager::IsAcceptLanguage(TabContents* tab,
                                        const std::string& language) {
  PrefService* pref_service = tab->profile()->GetPrefs();
  PrefServiceLanguagesMap::const_iterator iter =
      accept_languages_.find(pref_service);
  if (iter == accept_languages_.end()) {
    InitAcceptLanguages(pref_service);
    // Listen for this profile going away, in which case we would need to clear
    // the accepted languages for the profile.
    notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
                                Source<Profile>(tab->profile()));
    // Also start listening for changes in the accept languages.
    tab->profile()->GetPrefs()->AddPrefObserver(prefs::kAcceptLanguages, this);

    iter = accept_languages_.find(pref_service);
  }

  return iter->second.count(language) != 0;
}

void TranslateManager::InitAcceptLanguages(PrefService* prefs) {
  // We have been asked for this profile, build the languages.
  std::wstring accept_langs_str = prefs->GetString(prefs::kAcceptLanguages);
  std::vector<std::string> accept_langs_list;
  LanguageSet accept_langs_set;
  SplitString(WideToASCII(accept_langs_str), ',', &accept_langs_list);
  std::vector<std::string>::const_iterator iter;
  for (iter = accept_langs_list.begin();
       iter != accept_langs_list.end(); ++iter) {
    // Get rid of the locale extension if any (ex: en-US -> en), but for Chinese
    // for which the CLD reports zh-CN and zh-TW.
    std::string accept_lang(*iter);
    size_t index = iter->find("-");
    if (index != std::string::npos && *iter != "zh-CN" && *iter != "zh-TW")
      accept_lang = iter->substr(0, iter->length() - index - 1);
    accept_langs_set.insert(accept_lang);
  }
  accept_languages_[prefs] = accept_langs_set;
}
<commit_msg>Revert my previous fix for UI tests, it breaks the unit-tests.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/translate/translate_manager.h"

#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/translation_service.h"
#include "chrome/browser/tab_contents/language_state.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/translate/translate_infobars_delegates.h"
#include "chrome/browser/translate/translate_prefs.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"

TranslateManager::~TranslateManager() {
}

void TranslateManager::Observe(NotificationType type,
                               const NotificationSource& source,
                               const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::TAB_LANGUAGE_DETERMINED: {
      TabContents* tab = Source<TabContents>(source).ptr();
      std::string language = *(Details<std::string>(details).ptr());
      // We may get this notifications multiple times.  Make sure to translate
      // only once.
      if (!tab->language_state().translation_pending())
        InitiateTranslation(tab, language);
      break;
    }
    case NotificationType::PAGE_TRANSLATED: {
      // Only add translate infobar if it doesn't exist; if it already exists,
      // it would have received the same notification and acted accordingly.
      TabContents* tab = Source<TabContents>(source).ptr();
      int i;
      for (i = 0; i < tab->infobar_delegate_count(); ++i) {
        InfoBarDelegate* info_bar = tab->GetInfoBarDelegateAt(i);
        if (info_bar->AsTranslateInfoBarDelegate())
          break;
      }
      if (i == tab->infobar_delegate_count()) {
        NavigationEntry* entry = tab->controller().GetActiveEntry();
        if (entry) {
          std::pair<std::string, std::string>* language_pair =
              (Details<std::pair<std::string, std::string> >(details).ptr());
          PrefService* prefs = tab->profile()->GetPrefs();
          tab->AddInfoBar(new TranslateInfoBarDelegate(tab, prefs,
              TranslateInfoBarDelegate::kAfterTranslate, entry->url(),
              language_pair->first, language_pair->second));
        }
      }
      break;
    }
    case NotificationType::PROFILE_DESTROYED: {
      Profile* profile = Source<Profile>(source).ptr();
      notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
                                     source);
      size_t count = accept_languages_.erase(profile->GetPrefs());
      // We should know about this profile since we are listening for
      // notifications on it.
      DCHECK(count > 0);
      profile->GetPrefs()->RemovePrefObserver(prefs::kAcceptLanguages, this);
      break;
    }
    case NotificationType::PREF_CHANGED: {
      DCHECK(*Details<std::wstring>(details).ptr() == prefs::kAcceptLanguages);
      PrefService* prefs = Source<PrefService>(source).ptr();
      InitAcceptLanguages(prefs);
      break;
    }
    default:
      NOTREACHED();
  }
}

TranslateManager::TranslateManager() {
  if (TestEnabled() && !TranslationService::IsTranslationEnabled())
    return;

  notification_registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED,
                              NotificationService::AllSources());
  notification_registrar_.Add(this, NotificationType::PAGE_TRANSLATED,
                              NotificationService::AllSources());
}

void TranslateManager::InitiateTranslation(TabContents* tab,
                                           const std::string& page_lang) {
  PrefService* prefs = tab->profile()->GetPrefs();
  NavigationEntry* entry = tab->controller().GetActiveEntry();
  if (!entry) {
    NOTREACHED();
    return;
  }

  if (!TranslationService::IsSupportedLanguage(page_lang))
    return;  // Nothing to do, we don't support that language.

  std::string ui_lang = TranslationService::GetLanguageCode(
      g_browser_process->GetApplicationLocale());

  // We don't want to translate:
  // - any Chrome specific page (New Tab Page, Download, History... pages).
  // - similar languages (ex: en-US to en).
  // - any user black-listed URLs or user selected language combination.
  // - any language the user configured as accepted languages.
  if (entry->url().SchemeIs("chrome") || page_lang == ui_lang ||
      !TranslatePrefs::CanTranslate(prefs, page_lang, entry->url()) ||
      IsAcceptLanguage(tab, page_lang)) {
    return;
  }

  if (TranslatePrefs::ShouldAutoTranslate(prefs, page_lang, ui_lang)) {
    // The user has previously select "always translate" for this language.
    tab->TranslatePage(page_lang, ui_lang);
    return;
  }

  std::string auto_translate_to = tab->language_state().AutoTranslateTo();
  if (!auto_translate_to.empty()) {
    // This page was navigated through a click from a translated page.
    tab->TranslatePage(page_lang, auto_translate_to);
    return;
  }

  // Prompts the user if he/she wants the page translated.
  tab->AddInfoBar(new TranslateInfoBarDelegate(tab, prefs,
      TranslateInfoBarDelegate::kBeforeTranslate, entry->url(),
      page_lang, ui_lang));
}

bool TranslateManager::IsAcceptLanguage(TabContents* tab,
                                        const std::string& language) {
  PrefService* pref_service = tab->profile()->GetPrefs();
  PrefServiceLanguagesMap::const_iterator iter =
      accept_languages_.find(pref_service);
  if (iter == accept_languages_.end()) {
    InitAcceptLanguages(pref_service);
    // Listen for this profile going away, in which case we would need to clear
    // the accepted languages for the profile.
    notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
                                Source<Profile>(tab->profile()));
    // Also start listening for changes in the accept languages.
    tab->profile()->GetPrefs()->AddPrefObserver(prefs::kAcceptLanguages, this);

    iter = accept_languages_.find(pref_service);
  }

  return iter->second.count(language) != 0;
}

void TranslateManager::InitAcceptLanguages(PrefService* prefs) {
  // We have been asked for this profile, build the languages.
  std::wstring accept_langs_str = prefs->GetString(prefs::kAcceptLanguages);
  std::vector<std::string> accept_langs_list;
  LanguageSet accept_langs_set;
  SplitString(WideToASCII(accept_langs_str), ',', &accept_langs_list);
  std::vector<std::string>::const_iterator iter;
  for (iter = accept_langs_list.begin();
       iter != accept_langs_list.end(); ++iter) {
    // Get rid of the locale extension if any (ex: en-US -> en), but for Chinese
    // for which the CLD reports zh-CN and zh-TW.
    std::string accept_lang(*iter);
    size_t index = iter->find("-");
    if (index != std::string::npos && *iter != "zh-CN" && *iter != "zh-TW")
      accept_lang = iter->substr(0, iter->length() - index - 1);
    accept_langs_set.insert(accept_lang);
  }
  accept_languages_[prefs] = accept_langs_set;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

// Basic test is flaky on Mac
// http://crbug.com/49324
#if defined(OS_MAC)
#define MAYBE_Basic FLAKY_Basic
#else
#define MAYBE_Basic Basic
#endif

namespace {

std::wstring AutocompleteResultAsString(const AutocompleteResult& result) {
  std::wstring output(StringPrintf(L"{%d} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::wstring provider_name(ASCIIToWide(match.provider->name()));
    output.append(StringPrintf(L"[\"%ls\" by \"%ls\"] ",
                               match.contents.c_str(),
                               provider_name.c_str()));
  }
  return output;
}

}  // namespace

class AutocompleteBrowserTest : public InProcessBrowserTest {
 protected:
  LocationBar* GetLocationBar() const {
    return browser()->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController() const {
    return GetLocationBar()->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }

  void WaitForHistoryBackendToLoad() {
    HistoryService* history_service =
        browser()->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
    if (!history_service->BackendLoaded())
      ui_test_utils::WaitForNotification(NotificationType::HISTORY_LOADED);
  }
};

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Basic) {
  LocationBar* location_bar = GetLocationBar();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
  // platforms.

  location_bar->FocusLocation(true);

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(L"chrome", location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->RevertAll();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");
  location_bar->Revert();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Autocomplete) {
  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForHistoryBackendToLoad();

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  {
    autocomplete_controller->Start(L"chrome", std::wstring(),
                                   true, false, true);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(std::wstring(), location_bar->location_entry()->GetText());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(1U, result.size()) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    location_bar->Revert();

    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());
    EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
  // http://code.google.com/p/chromium/issues/detail?id=38385
  // Make sure that tabbing away from an empty omnibar causes a revert
  // and select all.
  LocationBar* location_bar = GetLocationBar();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  location_bar->location_entry()->SetUserText(L"");
  browser()->AddTabWithURL(
      GURL(chrome::kAboutBlankURL), GURL(), PageTransition::START_PAGE,
      -1, TabStripModel::ADD_SELECTED, NULL, std::string());
  ui_test_utils::WaitForNavigation(
      &browser()->GetSelectedTabContents()->controller());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  browser()->CloseTab();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
}
<commit_msg>Disable AutocompleteBrowserTest.Basic instead of FLAKY_<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

// Basic test is crashy on Mac
// http://crbug.com/49324
#if defined(OS_MAC)
#define MAYBE_Basic DISABLED_Basic
#else
#define MAYBE_Basic Basic
#endif

namespace {

std::wstring AutocompleteResultAsString(const AutocompleteResult& result) {
  std::wstring output(StringPrintf(L"{%d} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::wstring provider_name(ASCIIToWide(match.provider->name()));
    output.append(StringPrintf(L"[\"%ls\" by \"%ls\"] ",
                               match.contents.c_str(),
                               provider_name.c_str()));
  }
  return output;
}

}  // namespace

class AutocompleteBrowserTest : public InProcessBrowserTest {
 protected:
  LocationBar* GetLocationBar() const {
    return browser()->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController() const {
    return GetLocationBar()->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }

  void WaitForHistoryBackendToLoad() {
    HistoryService* history_service =
        browser()->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
    if (!history_service->BackendLoaded())
      ui_test_utils::WaitForNotification(NotificationType::HISTORY_LOADED);
  }
};

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Basic) {
  LocationBar* location_bar = GetLocationBar();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
  // platforms.

  location_bar->FocusLocation(true);

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(L"chrome", location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->RevertAll();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");
  location_bar->Revert();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Autocomplete) {
  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForHistoryBackendToLoad();

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  {
    autocomplete_controller->Start(L"chrome", std::wstring(),
                                   true, false, true);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(std::wstring(), location_bar->location_entry()->GetText());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(1U, result.size()) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    location_bar->Revert();

    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());
    EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
  // http://code.google.com/p/chromium/issues/detail?id=38385
  // Make sure that tabbing away from an empty omnibar causes a revert
  // and select all.
  LocationBar* location_bar = GetLocationBar();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  location_bar->location_entry()->SetUserText(L"");
  browser()->AddTabWithURL(
      GURL(chrome::kAboutBlankURL), GURL(), PageTransition::START_PAGE,
      -1, TabStripModel::ADD_SELECTED, NULL, std::string());
  ui_test_utils::WaitForNavigation(
      &browser()->GetSelectedTabContents()->controller());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  browser()->CloseTab();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
}
<|endoftext|>


<commit_before><commit_msg>Add tracking of database actions to NetworkActionPredictor.<commit_after><|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 * Point Cloud Library (PCL) - www.pointclouds.org
 * Copyright (c) 2009-2012, Willow Garage, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 * * Neither the name of Willow Garage, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/common/time.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/io/pcd_io.h>
#include <pcl/pcl_macros.h>

#include <pcl/console/print.h>
#include <pcl/console/parse.h>

#include <pcl/outofcore/outofcore.h>
#include <pcl/outofcore/outofcore_impl.h>

// todo: Read clouds as PointCloud2 so we don't need to define PointT explicitly.
//       This also requires our octree to take PointCloud2 as an input.
typedef pcl::PointXYZRGBA PointT;

using namespace pcl;
using namespace pcl::outofcore;

using pcl::console::parse_argument;
using pcl::console::parse_file_extension_argument;
using pcl::console::find_switch;
using pcl::console::print_error;
using pcl::console::print_warn;
using pcl::console::print_info;

#include <boost/foreach.hpp>

typedef octree_base<octree_disk_container<PointT> , PointT> octree_disk;

const int OCTREE_DEPTH (0);
const int OCTREE_RESOLUTION (1);

PointCloud<PointT>::Ptr
getCloudFromFile (boost::filesystem::path pcd_path)
{
  // Read PCD file
  PointCloud<PointT>::Ptr cloud (new PointCloud<PointT> ());

  print_info ("Reading: %s ", pcd_path.c_str ());

  if (io::loadPCDFile<PointT> (pcd_path.string (), *cloud) == -1) //* load the file
  {
    PCL_ERROR ("Couldn't read file\n");
    exit (-1);
  }

  print_info ("(%d)\n", (cloud->width * cloud->height));
  return cloud;
}

int
outofcoreProcess (std::vector<boost::filesystem::path> pcd_paths, boost::filesystem::path root_dir,
                  int depth, double resolution, int build_octree_with, bool gen_lod, bool overwrite)
{
  // Bounding box min/max pts
  PointT min_pt, max_pt;

  // Iterate over all pcd files resizing min/max
  for (size_t i = 0; i < pcd_paths.size (); i++)
  {

    // Get cloud
    PointCloud<PointT>::Ptr cloud = getCloudFromFile (pcd_paths[i]);

    PointT tmp_min_pt, tmp_max_pt;

    if (i == 0)
    {
      // Get initial min/max
      getMinMax3D (*cloud, min_pt, max_pt);
    }
    else
    {
      getMinMax3D (*cloud, tmp_min_pt, tmp_max_pt);

      // Resize new min
      if (tmp_min_pt.x < min_pt.x)
        min_pt.x = tmp_min_pt.x;
      if (tmp_min_pt.y < min_pt.y)
        min_pt.y = tmp_min_pt.y;
      if (tmp_min_pt.z < min_pt.z)
        min_pt.z = tmp_min_pt.z;

      // Resize new max
      if (tmp_max_pt.x > max_pt.x)
        max_pt.x = tmp_max_pt.x;
      if (tmp_max_pt.y > max_pt.y)
        max_pt.y = tmp_max_pt.y;
      if (tmp_max_pt.z > max_pt.z)
        max_pt.z = tmp_max_pt.z;
    }
  }

  std::cout << "Bounds: " << min_pt << " - " << max_pt << std::endl;

  // The bounding box of the root node of the out-of-core octree must be specified
  const double bounding_box_min[3] = {min_pt.x, min_pt.y, min_pt.z};
  const double bounding_box_max[3] = {max_pt.x, max_pt.y, max_pt.z};

//arbitrarily large bounding box
//  const double bounding_box_min[3] = { -1e8, -1e8, -1e8 };
//  const double bounding_box_max[3] = { 1e8, 1e8, 1e8 };

  //specify the directory and the root node's meta data file with a
  //".oct_idx" extension (currently it must be this extension)
  boost::filesystem::path octree_path_on_disk (root_dir / "tree.oct_idx");

  print_info ("Writing: %s\n", octree_path_on_disk.c_str ());
  //make sure there isn't an octree there already
  if (boost::filesystem::exists (octree_path_on_disk))
  {
    if (overwrite)
    {
      boost::filesystem::remove_all (root_dir);
    }
    else
    {
      PCL_ERROR ("There's already an octree in the default location. Check the tree directory\n");
      return (-1);
    }
  }

  octree_disk *outofcore_octree;

  //create the out-of-core data structure (typedef'd above)
  if (build_octree_with == OCTREE_DEPTH)
  {
    outofcore_octree = new octree_disk (depth, bounding_box_min, bounding_box_max, octree_path_on_disk, "ECEF");
  }
  else
  {
    outofcore_octree = new octree_disk (bounding_box_min, bounding_box_max, resolution, octree_path_on_disk, "ECEF");
  }

  uint64_t total_pts = 0;

  // Iterate over all pcd files adding points to the octree
  for (size_t i = 0; i < pcd_paths.size (); i++)
  {

    PointCloud<PointT>::Ptr cloud = getCloudFromFile (pcd_paths[i]);

    uint64_t pts = 0;

    //load the points into the outofcore octree
    if (gen_lod)
    {
      print_info ("  Generating LODs\n");
      pts = outofcore_octree->addPointCloud_and_genLOD (cloud);
    }
    else
    {
      pts = outofcore_octree->addPointCloud (cloud);
    }
    print_info ("Successfully added %lu points\n",pts);
    assert ( pts == cloud->points.size () );

    total_pts += pts;
  }

  print_info ("Added a total of %lu from %d clouds\n",total_pts, pcd_paths.size ());

  double x, y;
  outofcore_octree->getBinDimension (x, y);

  print_info ("  Depth: %i\n", outofcore_octree->getDepth ());
  print_info ("  Resolution: [%f, %f]\n", x, y);

  //free outofcore data structure; the destructor forces buffer flush to disk
  delete outofcore_octree;

  return 0;
}

void
printHelp (int, char **argv)
{
  print_info ("This program is used to process pcd fiels into an outofcore data structure viewable by the");
  print_info ("pcl_outofcore_viewer\n\n");
  print_info ("%s <options> <input>.pcd <output_tree_dir>\n", argv[0]);
  print_info ("\n");
  print_info ("Options:\n");
  print_info ("\t -depth <resolution>           \t Octree depth\n");
  print_info ("\t -resolution <resolution>      \t Octree resolution\n");
  print_info ("\t -gen_lod                      \t Generate octree LODs\n");
  print_info ("\t -overwrite                    \t Overwrite existing octree\n");
  print_info ("\t -h                            \t Display help\n");
  print_info ("\n");
}

int
main (int argc, char* argv[])
{
  // Check for help (-h) flag
  if (argc > 1)
  {
    if (find_switch (argc, argv, "-h"))
    {
      printHelp (argc, argv);
      return (-1);
    }
  }

  // If no arguments specified
  if (argc - 1 < 1)
  {
    printHelp (argc, argv);
    return (-1);
  }

  // Defaults
  int depth = 4;
  double resolution = .1;
  bool gen_lod = false;
  bool overwrite = false;
  int build_octree_with = OCTREE_DEPTH;

  // If both depth and resolution specified
  if (find_switch (argc, argv, "-depth") && find_switch (argc, argv, "-resolution"))
  {
    PCL_ERROR ("Both -depth and -resolution specified, please specify one (Mutually exclusive)\n");
  }
  // Just resolution specified (Update how we build the tree)
  else if (find_switch (argc, argv, "-resolution"))
  {
    build_octree_with = OCTREE_RESOLUTION;
  }

  // Parse options
  parse_argument (argc, argv, "-depth", depth);
  parse_argument (argc, argv, "-resolution", resolution);
  gen_lod = find_switch (argc, argv, "-gen_lod");
  overwrite = find_switch (argc, argv, "-overwrite");

  // Parse non-option arguments for pcd files
  std::vector<int> file_arg_indices = parse_file_extension_argument (argc, argv, ".pcd");

  std::vector<boost::filesystem::path> pcd_paths;
  for (size_t i = 0; i < file_arg_indices.size (); i++)
  {
    boost::filesystem::path pcd_path (argv[file_arg_indices[i]]);
    if (!boost::filesystem::exists (pcd_path))
    {
      PCL_WARN ("File %s doesn't exist", pcd_path.string ().c_str ());
      continue;
    }
    pcd_paths.push_back (pcd_path);

  }

  // Check if we should process any files
  if (pcd_paths.size () < 1)
  {
    PCL_ERROR ("No .pcd files specified\n");
    return -1;
  }

  // Get root directory
  boost::filesystem::path root_dir (argv[argc - 1]);

  // Check if a root directory was specified, use directory of pcd file
  if (root_dir.extension () == ".pcd")
    root_dir = root_dir.parent_path () / "tree";

  return outofcoreProcess (pcd_paths, root_dir, depth, resolution, build_octree_with, gen_lod, overwrite);
}
<commit_msg>keep the default point type XYZ in outofcore_process for now<commit_after>/*
 * Software License Agreement (BSD License)
 *
 * Point Cloud Library (PCL) - www.pointclouds.org
 * Copyright (c) 2009-2012, Willow Garage, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 * * Neither the name of Willow Garage, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/common/time.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/io/pcd_io.h>
#include <pcl/pcl_macros.h>

#include <pcl/console/print.h>
#include <pcl/console/parse.h>

#include <pcl/outofcore/outofcore.h>
#include <pcl/outofcore/outofcore_impl.h>

// todo: Read clouds as PointCloud2 so we don't need to define PointT explicitly.
//       This also requires our octree to take PointCloud2 as an input.
typedef pcl::PointXYZ PointT;

using namespace pcl;
using namespace pcl::outofcore;

using pcl::console::parse_argument;
using pcl::console::parse_file_extension_argument;
using pcl::console::find_switch;
using pcl::console::print_error;
using pcl::console::print_warn;
using pcl::console::print_info;

#include <boost/foreach.hpp>

typedef octree_base<octree_disk_container<PointT> , PointT> octree_disk;

const int OCTREE_DEPTH (0);
const int OCTREE_RESOLUTION (1);

PointCloud<PointT>::Ptr
getCloudFromFile (boost::filesystem::path pcd_path)
{
  // Read PCD file
  PointCloud<PointT>::Ptr cloud (new PointCloud<PointT> ());

  print_info ("Reading: %s ", pcd_path.c_str ());

  if (io::loadPCDFile<PointT> (pcd_path.string (), *cloud) == -1) //* load the file
  {
    PCL_ERROR ("Couldn't read file\n");
    exit (-1);
  }

  print_info ("(%d)\n", (cloud->width * cloud->height));
  return cloud;
}

int
outofcoreProcess (std::vector<boost::filesystem::path> pcd_paths, boost::filesystem::path root_dir,
                  int depth, double resolution, int build_octree_with, bool gen_lod, bool overwrite)
{
  // Bounding box min/max pts
  PointT min_pt, max_pt;

  // Iterate over all pcd files resizing min/max
  for (size_t i = 0; i < pcd_paths.size (); i++)
  {

    // Get cloud
    PointCloud<PointT>::Ptr cloud = getCloudFromFile (pcd_paths[i]);

    PointT tmp_min_pt, tmp_max_pt;

    if (i == 0)
    {
      // Get initial min/max
      getMinMax3D (*cloud, min_pt, max_pt);
    }
    else
    {
      getMinMax3D (*cloud, tmp_min_pt, tmp_max_pt);

      // Resize new min
      if (tmp_min_pt.x < min_pt.x)
        min_pt.x = tmp_min_pt.x;
      if (tmp_min_pt.y < min_pt.y)
        min_pt.y = tmp_min_pt.y;
      if (tmp_min_pt.z < min_pt.z)
        min_pt.z = tmp_min_pt.z;

      // Resize new max
      if (tmp_max_pt.x > max_pt.x)
        max_pt.x = tmp_max_pt.x;
      if (tmp_max_pt.y > max_pt.y)
        max_pt.y = tmp_max_pt.y;
      if (tmp_max_pt.z > max_pt.z)
        max_pt.z = tmp_max_pt.z;
    }
  }

  std::cout << "Bounds: " << min_pt << " - " << max_pt << std::endl;

  // The bounding box of the root node of the out-of-core octree must be specified
  const double bounding_box_min[3] = {min_pt.x, min_pt.y, min_pt.z};
  const double bounding_box_max[3] = {max_pt.x, max_pt.y, max_pt.z};

//arbitrarily large bounding box
//  const double bounding_box_min[3] = { -1e8, -1e8, -1e8 };
//  const double bounding_box_max[3] = { 1e8, 1e8, 1e8 };

  //specify the directory and the root node's meta data file with a
  //".oct_idx" extension (currently it must be this extension)
  boost::filesystem::path octree_path_on_disk (root_dir / "tree.oct_idx");

  print_info ("Writing: %s\n", octree_path_on_disk.c_str ());
  //make sure there isn't an octree there already
  if (boost::filesystem::exists (octree_path_on_disk))
  {
    if (overwrite)
    {
      boost::filesystem::remove_all (root_dir);
    }
    else
    {
      PCL_ERROR ("There's already an octree in the default location. Check the tree directory\n");
      return (-1);
    }
  }

  octree_disk *outofcore_octree;

  //create the out-of-core data structure (typedef'd above)
  if (build_octree_with == OCTREE_DEPTH)
  {
    outofcore_octree = new octree_disk (depth, bounding_box_min, bounding_box_max, octree_path_on_disk, "ECEF");
  }
  else
  {
    outofcore_octree = new octree_disk (bounding_box_min, bounding_box_max, resolution, octree_path_on_disk, "ECEF");
  }

  uint64_t total_pts = 0;

  // Iterate over all pcd files adding points to the octree
  for (size_t i = 0; i < pcd_paths.size (); i++)
  {

    PointCloud<PointT>::Ptr cloud = getCloudFromFile (pcd_paths[i]);

    uint64_t pts = 0;

    //load the points into the outofcore octree
    if (gen_lod)
    {
      print_info ("  Generating LODs\n");
      pts = outofcore_octree->addPointCloud_and_genLOD (cloud);
    }
    else
    {
      pts = outofcore_octree->addPointCloud (cloud);
    }
    print_info ("Successfully added %lu points\n",pts);
    assert ( pts == cloud->points.size () );

    total_pts += pts;
  }

  print_info ("Added a total of %lu from %d clouds\n",total_pts, pcd_paths.size ());

  double x, y;
  outofcore_octree->getBinDimension (x, y);

  print_info ("  Depth: %i\n", outofcore_octree->getDepth ());
  print_info ("  Resolution: [%f, %f]\n", x, y);

  //free outofcore data structure; the destructor forces buffer flush to disk
  delete outofcore_octree;

  return 0;
}

void
printHelp (int, char **argv)
{
  print_info ("This program is used to process pcd fiels into an outofcore data structure viewable by the");
  print_info ("pcl_outofcore_viewer\n\n");
  print_info ("%s <options> <input>.pcd <output_tree_dir>\n", argv[0]);
  print_info ("\n");
  print_info ("Options:\n");
  print_info ("\t -depth <resolution>           \t Octree depth\n");
  print_info ("\t -resolution <resolution>      \t Octree resolution\n");
  print_info ("\t -gen_lod                      \t Generate octree LODs\n");
  print_info ("\t -overwrite                    \t Overwrite existing octree\n");
  print_info ("\t -h                            \t Display help\n");
  print_info ("\n");
}

int
main (int argc, char* argv[])
{
  // Check for help (-h) flag
  if (argc > 1)
  {
    if (find_switch (argc, argv, "-h"))
    {
      printHelp (argc, argv);
      return (-1);
    }
  }

  // If no arguments specified
  if (argc - 1 < 1)
  {
    printHelp (argc, argv);
    return (-1);
  }

  // Defaults
  int depth = 4;
  double resolution = .1;
  bool gen_lod = false;
  bool overwrite = false;
  int build_octree_with = OCTREE_DEPTH;

  // If both depth and resolution specified
  if (find_switch (argc, argv, "-depth") && find_switch (argc, argv, "-resolution"))
  {
    PCL_ERROR ("Both -depth and -resolution specified, please specify one (Mutually exclusive)\n");
  }
  // Just resolution specified (Update how we build the tree)
  else if (find_switch (argc, argv, "-resolution"))
  {
    build_octree_with = OCTREE_RESOLUTION;
  }

  // Parse options
  parse_argument (argc, argv, "-depth", depth);
  parse_argument (argc, argv, "-resolution", resolution);
  gen_lod = find_switch (argc, argv, "-gen_lod");
  overwrite = find_switch (argc, argv, "-overwrite");

  // Parse non-option arguments for pcd files
  std::vector<int> file_arg_indices = parse_file_extension_argument (argc, argv, ".pcd");

  std::vector<boost::filesystem::path> pcd_paths;
  for (size_t i = 0; i < file_arg_indices.size (); i++)
  {
    boost::filesystem::path pcd_path (argv[file_arg_indices[i]]);
    if (!boost::filesystem::exists (pcd_path))
    {
      PCL_WARN ("File %s doesn't exist", pcd_path.string ().c_str ());
      continue;
    }
    pcd_paths.push_back (pcd_path);

  }

  // Check if we should process any files
  if (pcd_paths.size () < 1)
  {
    PCL_ERROR ("No .pcd files specified\n");
    return -1;
  }

  // Get root directory
  boost::filesystem::path root_dir (argv[argc - 1]);

  // Check if a root directory was specified, use directory of pcd file
  if (root_dir.extension () == ".pcd")
    root_dir = root_dir.parent_path () / "tree";

  return outofcoreProcess (pcd_paths, root_dir, depth, resolution, build_octree_with, gen_lod, overwrite);
}
<|endoftext|>