<commit_before>//
// Originally written by BjÃrn Fahller (bjorn@fahller.se)
// Modified by Jeff Bush
//
// No rights claimed. The sources are released to the public domain
//
// For license information, please refer to <http://unlicense.org>
//

#include <setjmp.h>
#include <stdlib.h>
#include <iostream>
#include <ostream>
#include <forward_list>
#include <vector>
#include <algorithm>

namespace basic {
  struct stack_frame { jmp_buf buf; };
  std::forward_list<stack_frame> stack;

#define GOSUB                                                           \
  if (!(setjmp((basic::stack.emplace_front(),basic::stack.front().buf)) \
        && (basic::stack.pop_front(),true)))                            \
    goto

#define RETURN if (basic::stack.empty()) return 0; longjmp(basic::stack.front().buf, 1)

  template <typename T, typename U>
  struct separator
  {
    static char const *str() { return ""; }
  };

  template <typename T>
  struct separator<T,T>
  {
    static char const *str() { return ","; }
  };

  inline void type_mismatch() {
    std::cout << "Type mismatch error\n";
    exit(1);
  }

  inline void array_out_of_bounds() {
    std::cout << "Array out of bounds error\n";
    exit(1);
  }

  inline void dimension_error() {
    std::cout << "Array Dimension error\n";
    exit(1);
  }

  inline void illegal_quantity_error() {
    std::cout << "Illegal quantity error\n";
    exit(1);
  }

  class variant
  {
  public:
    variant()
      : isnum(true),
        numval(0)
    {}

    variant(double _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(int _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(const std::string _strval)
      : isnum(false),
        strval(_strval)
    {}

    variant(const char *_strval)
      : isnum(false),
        strval(_strval)
    {}

    double numeric() const {
      if (!isnum)
        type_mismatch();
      return numval;
    }

    std::string string() const {
      if (isnum)
        type_mismatch();
      return strval;
    }
    variant toString() const {
      if (isnum)
        return variant(std::to_string(numval));
      else
        return *this;
    }

    variant toNum() const {
      if (!isnum)
        return variant(stod(strval));
      else
        return *this;
    }

    variant &operator=(const variant &copyfrom) {
      isnum = copyfrom.isnum;
      numval = copyfrom.numval;
      strval = copyfrom.strval;
      return *this;
    }

    // Note that strings in BASIC are 1 based, so subtract 1 from the left
    // index
    variant midStr(const variant &left, const variant &right) const {
      if (isnum || !left.isnum || !right.isnum)
        type_mismatch();

      return variant(strval.substr(int(left.numval) - 1, (int(right.numval) - int(left.numval) + 1)));
    }

    variant leftStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(0, int(count.numval)));
    }

    variant rightStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(strval.length() - int(count.numval) - 1, int(count.numval)));
    }

    variant strlen() const {
      if (isnum)
        type_mismatch();

      return variant((int)strval.length());
    }

    variant operator+(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return variant(numval + op.numval);
      else
        return variant(strval + op.strval);
    }

    variant operator-(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval - op.numval);
    }

    variant operator*(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval * op.numval);
    }

    variant operator/(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval / op.numval);
    }

    bool operator>(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval > op.numval;
      else
        return strval > op.strval;
    }

    bool operator>=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval >= op.numval;
      else
        return strval >= op.strval;
    }

    bool operator<(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval < op.numval;
      else
        return strval < op.strval;
    }

    bool operator<=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval <= op.numval;
      else
        return strval <= op.strval;
    }

    bool operator!=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval != op.numval;
      else
        return strval != op.strval;
    }

    bool operator==(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval == op.numval;
      else
        return strval == op.strval;
    }

    bool isnum;
    double numval;
    std::string strval;
  };

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator+(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) + p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator-(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) - p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator*(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) * p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator/(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) / p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, bool>::type
  operator==(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) == p;
  }

  template <typename T>
  struct is_dimmable
  {
    using DT = typename std::decay<T>::type;
    static constexpr bool value = std::is_integral<DT>::value || std::is_same<DT, variant>::value;
  };

  template <template <typename> class pred, typename ... T>
  struct all_are
  {
    static constexpr bool value = true;
  };

  template <template <typename> class pred, typename H, typename ... T>
  struct all_are<pred, H, T...>
  {
    static constexpr bool value = pred<H>::value && all_are<pred, T...>::value;
  };

  template <typename T>
  T numeric_value(T t) { return t; }

  inline
  long numeric_value(const variant& v) { return long(v.numeric()); }

  class array
  {
  public:
    template <typename ... T, typename = typename std::enable_if<all_are<is_dimmable, T...>::value>::type>
    array(T const & ... t)
      : dimensions{1LU+numeric_value(t)..., 1LU},
        elements(std::accumulate(std::begin(dimensions),
                                 std::end(dimensions),
                                 1U,
                                 [](std::size_t i, std::size_t j){ return i*j;}))
    {}

    template <typename ... T>
    typename std::enable_if<all_are<is_dimmable, T...>::value, variant&>::type
    operator()(T const& ... t) {
      if (sizeof...(t) != dimensions.size() - 1)
        dimension_error();

      long indexes[] { long(numeric_value(t))... };

      auto i = sizeof...(t);
      size_t mul = 1U;
      size_t idx = 0U;
      while (i--)
      {
        if (indexes[i] < 0 || indexes[i] >= dimensions[i])
          array_out_of_bounds();
        idx += indexes[i]*mul;
        mul = dimensions[i];
      }

      return elements[idx];
    }
  private:
    std::vector<std::size_t> dimensions;
    std::vector<variant> elements;
  };

  class printer
  {
    public:
    printer &operator,(const char *s) {
      std::cout  << s;
      return *this;
    }

    printer &operator,(const variant &v) {
      if (v.isnum)
        std::cout << v.numval;
      else
        std::cout << v.strval;

      return *this;
    }

    ~printer() { std::cout << std::endl; }
  };

  class input
  {
  public:
    input& operator,(char const *s) {
      std::cout << s << std::flush;
      return *this;
    }

    input& operator,(variant& v) {
      if (v.isnum)
        std::cin >> v.numval;
      else
        std::cin >> v.strval;

      return *this;
    }
  };

  template <typename T>
  variant to_char_str(T const& t)
  {
    auto n = numeric_value(t);
    char a[] = { char(n), '\0' };
    return variant{a};
  }

  template <std::size_t N>
  inline variant to_asc_val(char const (&a)[N])
  {
    if (N < 2) illegal_quantity_error();
    return variant(double(a[0]));
  }

  inline variant to_asc_val(variant const& v)
  {
    auto s = v.string();
    if (s.empty()) illegal_quantity_error();
    return variant(double(s[0]));
  }

#define INPUT basic::input(),
#define PRINT basic::printer(),
#define IF if (
#define THEN )
#define LET basic::variant
#define GOTO goto
#define FOR { basic::variant& for_loop_variable =
#define TO ;                                   \
           {                                   \
             jmp_buf for_loop_top;             \
             bool for_loop_exit = false;           \
             while (!for_loop_exit)            \
             {                                 \
               if (setjmp(for_loop_top) == 0)  \
               {                               \
                 basic::variant for_loop_step=1;       \
                 basic::variant const for_loop_endval=
#define STEP ;              \
             for_loop_step=

#define NEXT for_loop_variable=for_loop_variable+for_loop_step;                           \
             for_loop_exit=(  (   for_loop_step > 0                      \
                               && for_loop_variable > for_loop_endval)   \
                            ||(   for_loop_step < 0                      \
                               && for_loop_variable < for_loop_endval)); \
             longjmp(for_loop_top, 1);                                   \
             }                                                           \
           }                                                             \
         }                                                               \
       }

#define END exit(0)
#define VAL(x) x.toNum()
#define STR(x) x.toString()
#define MID$(str, left, right) str.midStr(left, right)
#define LEFT$(str, count) str.leftStr(count)
#define RIGHT$(str, count) str.rightStr(count)
#define LEN(str) str.strlen()
#define DIM basic::array
#define RND(x) (double) (rand() & 0xffff)
#define CHR$(num) basic::to_char_str(num)
#define ASC(str) basic::to_asc_val(str)
} // namespace basic
<commit_msg>Fixed RND()<commit_after>//
// Originally written by BjÃrn Fahller (bjorn@fahller.se)
// Modified by Jeff Bush
//
// No rights claimed. The sources are released to the public domain
//
// For license information, please refer to <http://unlicense.org>
//

#include <setjmp.h>
#include <stdlib.h>
#include <iostream>
#include <ostream>
#include <forward_list>
#include <vector>
#include <algorithm>

namespace basic {
  struct stack_frame { jmp_buf buf; };
  std::forward_list<stack_frame> stack;

#define GOSUB                                                           \
  if (!(setjmp((basic::stack.emplace_front(),basic::stack.front().buf)) \
        && (basic::stack.pop_front(),true)))                            \
    goto

#define RETURN if (basic::stack.empty()) return 0; longjmp(basic::stack.front().buf, 1)

  template <typename T, typename U>
  struct separator
  {
    static char const *str() { return ""; }
  };

  template <typename T>
  struct separator<T,T>
  {
    static char const *str() { return ","; }
  };

  inline void type_mismatch() {
    std::cout << "Type mismatch error\n";
    exit(1);
  }

  inline void array_out_of_bounds() {
    std::cout << "Array out of bounds error\n";
    exit(1);
  }

  inline void dimension_error() {
    std::cout << "Array Dimension error\n";
    exit(1);
  }

  inline void illegal_quantity_error() {
    std::cout << "Illegal quantity error\n";
    exit(1);
  }

  class variant
  {
  public:
    variant()
      : isnum(true),
        numval(0)
    {}

    variant(double _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(int _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(const std::string _strval)
      : isnum(false),
        strval(_strval)
    {}

    variant(const char *_strval)
      : isnum(false),
        strval(_strval)
    {}

    double numeric() const {
      if (!isnum)
        type_mismatch();
      return numval;
    }

    std::string string() const {
      if (isnum)
        type_mismatch();
      return strval;
    }
    variant toString() const {
      if (isnum)
        return variant(std::to_string(numval));
      else
        return *this;
    }

    variant toNum() const {
      if (!isnum)
        return variant(stod(strval));
      else
        return *this;
    }

    variant &operator=(const variant &copyfrom) {
      isnum = copyfrom.isnum;
      numval = copyfrom.numval;
      strval = copyfrom.strval;
      return *this;
    }

    // Note that strings in BASIC are 1 based, so subtract 1 from the left
    // index
    variant midStr(const variant &left, const variant &right) const {
      if (isnum || !left.isnum || !right.isnum)
        type_mismatch();

      return variant(strval.substr(int(left.numval) - 1, (int(right.numval) - int(left.numval) + 1)));
    }

    variant leftStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(0, int(count.numval)));
    }

    variant rightStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(strval.length() - int(count.numval) - 1, int(count.numval)));
    }

    variant strlen() const {
      if (isnum)
        type_mismatch();

      return variant((int)strval.length());
    }

    variant operator+(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return variant(numval + op.numval);
      else
        return variant(strval + op.strval);
    }

    variant operator-(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval - op.numval);
    }

    variant operator*(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval * op.numval);
    }

    variant operator/(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval / op.numval);
    }

    bool operator>(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval > op.numval;
      else
        return strval > op.strval;
    }

    bool operator>=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval >= op.numval;
      else
        return strval >= op.strval;
    }

    bool operator<(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval < op.numval;
      else
        return strval < op.strval;
    }

    bool operator<=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval <= op.numval;
      else
        return strval <= op.strval;
    }

    bool operator!=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval != op.numval;
      else
        return strval != op.strval;
    }

    bool operator==(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval == op.numval;
      else
        return strval == op.strval;
    }

    bool isnum;
    double numval;
    std::string strval;
  };

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator+(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) + p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator-(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) - p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator*(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) * p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, variant>::type
  operator/(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) / p;
  }

  template <typename T>
  typename std::enable_if<std::is_constructible<variant, T>::value && !std::is_same<typename std::decay<T>::type, variant>::value, bool>::type
  operator==(T&& t, variant const& p)
  {
    return variant(std::forward<T>(t)) == p;
  }

  template <typename T>
  struct is_dimmable
  {
    using DT = typename std::decay<T>::type;
    static constexpr bool value = std::is_integral<DT>::value || std::is_same<DT, variant>::value;
  };

  template <template <typename> class pred, typename ... T>
  struct all_are
  {
    static constexpr bool value = true;
  };

  template <template <typename> class pred, typename H, typename ... T>
  struct all_are<pred, H, T...>
  {
    static constexpr bool value = pred<H>::value && all_are<pred, T...>::value;
  };

  template <typename T>
  T numeric_value(T t) { return t; }

  inline
  long numeric_value(const variant& v) { return long(v.numeric()); }

  class array
  {
  public:
    template <typename ... T, typename = typename std::enable_if<all_are<is_dimmable, T...>::value>::type>
    array(T const & ... t)
      : dimensions{1LU+numeric_value(t)..., 1LU},
        elements(std::accumulate(std::begin(dimensions),
                                 std::end(dimensions),
                                 1U,
                                 [](std::size_t i, std::size_t j){ return i*j;}))
    {}

    template <typename ... T>
    typename std::enable_if<all_are<is_dimmable, T...>::value, variant&>::type
    operator()(T const& ... t) {
      if (sizeof...(t) != dimensions.size() - 1)
        dimension_error();

      long indexes[] { long(numeric_value(t))... };

      auto i = sizeof...(t);
      size_t mul = 1U;
      size_t idx = 0U;
      while (i--)
      {
        if (indexes[i] < 0 || indexes[i] >= dimensions[i])
          array_out_of_bounds();
        idx += indexes[i]*mul;
        mul = dimensions[i];
      }

      return elements[idx];
    }
  private:
    std::vector<std::size_t> dimensions;
    std::vector<variant> elements;
  };

  class printer
  {
    public:
    printer &operator,(const char *s) {
      std::cout  << s;
      return *this;
    }

    printer &operator,(const variant &v) {
      if (v.isnum)
        std::cout << v.numval;
      else
        std::cout << v.strval;

      return *this;
    }

    ~printer() { std::cout << std::endl; }
  };

  class input
  {
  public:
    input& operator,(char const *s) {
      std::cout << s << std::flush;
      return *this;
    }

    input& operator,(variant& v) {
      if (v.isnum)
        std::cin >> v.numval;
      else
        std::cin >> v.strval;

      return *this;
    }
  };

  template <typename T>
  variant to_char_str(T const& t)
  {
    auto n = numeric_value(t);
    char a[] = { char(n), '\0' };
    return variant{a};
  }

  template <std::size_t N>
  inline variant to_asc_val(char const (&a)[N])
  {
    if (N < 2) illegal_quantity_error();
    return variant(double(a[0]));
  }

  inline variant to_asc_val(variant const& v)
  {
    auto s = v.string();
    if (s.empty()) illegal_quantity_error();
    return variant(double(s[0]));
  }

#define INPUT basic::input(),
#define PRINT basic::printer(),
#define IF if (
#define THEN )
#define LET basic::variant
#define GOTO goto
#define FOR { basic::variant& for_loop_variable =
#define TO ;                                   \
           {                                   \
             jmp_buf for_loop_top;             \
             bool for_loop_exit = false;           \
             while (!for_loop_exit)            \
             {                                 \
               if (setjmp(for_loop_top) == 0)  \
               {                               \
                 basic::variant for_loop_step=1;       \
                 basic::variant const for_loop_endval=
#define STEP ;              \
             for_loop_step=

#define NEXT for_loop_variable=for_loop_variable+for_loop_step;                           \
             for_loop_exit=(  (   for_loop_step > 0                      \
                               && for_loop_variable > for_loop_endval)   \
                            ||(   for_loop_step < 0                      \
                               && for_loop_variable < for_loop_endval)); \
             longjmp(for_loop_top, 1);                                   \
             }                                                           \
           }                                                             \
         }                                                               \
       }

#define END exit(0)
#define VAL(x) x.toNum()
#define STR(x) x.toString()
#define MID$(str, left, right) str.midStr(left, right)
#define LEFT$(str, count) str.leftStr(count)
#define RIGHT$(str, count) str.rightStr(count)
#define LEN(str) str.strlen()
#define DIM basic::array
#define RND(x) ((rand() & 0xffff)/65535.0)
#define CHR$(num) basic::to_char_str(num)
#define ASC(str) basic::to_asc_val(str)
} // namespace basic
<|endoftext|>


<commit_before>#include <avr/pgmspace.h>
#include <stdlib.h>

char *to_print;
char *pgmStrToRAM(PROGMEM char *theString) {
	free(to_print);
	to_print=(char *) malloc(strlen_P(theString) + 1);
	strcpy_P(to_print, theString);
	return (to_print);
}<commit_msg>Add include to support SAMD core<commit_after>#include <avr/pgmspace.h>
#include <stdlib.h>
#include <string.h>

char *to_print;
char *pgmStrToRAM(PROGMEM char *theString) {
	free(to_print);
	to_print=(char *) malloc(strlen_P(theString) + 1);
	strcpy_P(to_print, theString);
	return (to_print);
}<|endoftext|>


<commit_before>#pragma once
//#define DEFAULT_LOGGER "blockchain"

#include <bts/blockchain/chain_database.hpp>
#include <bts/blockchain/checkpoints.hpp>
#include <bts/blockchain/config.hpp>
#include <bts/blockchain/genesis_config.hpp>
#include <bts/blockchain/genesis_json.hpp>
#include <bts/blockchain/market_records.hpp>
#include <bts/blockchain/operation_factory.hpp>
#include <bts/blockchain/time.hpp>

#include <bts/db/cached_level_map.hpp>
#include <bts/db/level_map.hpp>

#include <fc/io/fstream.hpp>
#include <fc/io/json.hpp>
#include <fc/io/raw_variant.hpp>
#include <fc/thread/mutex.hpp>
#include <fc/thread/non_preemptable_scope_check.hpp>
#include <fc/thread/unique_lock.hpp>

#include <algorithm>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>

namespace bts { namespace blockchain {

   struct vote_del
   {
      vote_del( int64_t v = 0, account_id_type del = 0 )
      :votes(v),delegate_id(del){}
      int64_t votes = 0;
      account_id_type delegate_id;
      friend bool operator == ( const vote_del& a, const vote_del& b )
      {
         return a.votes == b.votes && a.delegate_id == b.delegate_id;
      }
      friend bool operator < ( const vote_del& a, const vote_del& b )
      {
         if( a.votes != b.votes ) return a.votes > b.votes; /* Reverse so maps sort in descending order */
         return a.delegate_id < b.delegate_id; /* Lowest id wins in ties */
      }
   };

   struct fee_index
   {
      fee_index( share_type fees = 0, transaction_id_type trx = transaction_id_type() )
      :_fees(fees),_trx(trx){}
      share_type          _fees;
      transaction_id_type _trx;
      friend bool operator == ( const fee_index& a, const fee_index& b )
      {
         return a._fees == b._fees && a._trx == b._trx;
      }
      friend bool operator < ( const fee_index& a, const fee_index& b )
      {
         if( a._fees == b._fees ) return a._trx < b._trx; /* Lowest id wins in ties */
         return a._fees > b._fees; /* Reverse so that highest fee is placed first in sorted maps */
      }
   };

   namespace detail
   {
      class chain_database_impl
      {
         public:
            void                                        open_database(const fc::path& data_dir );
            digest_type                                 initialize_genesis( const optional<path>& genesis_file, bool chain_id_only = false );

            std::pair<block_id_type, block_fork_data>   store_and_index( const block_id_type& id, const full_block& blk );
            void                                        clear_pending(  const full_block& blk );
            void                                        switch_to_fork( const block_id_type& block_id );
            void                                        extend_chain( const full_block& blk );
            vector<block_id_type>                       get_fork_history( const block_id_type& id );
            void                                        pop_block();
            void                                        mark_invalid( const block_id_type& id, const fc::exception& reason );
            void                                        mark_included( const block_id_type& id, bool state );
            void                                        verify_header( const full_block&, const public_key_type& block_signee );
            void                                        apply_transactions( const full_block& block,
                                                                            const pending_chain_state_ptr& );
            void                                        pay_delegate( const pending_chain_state_ptr& pending_state,
                                                                      const public_key_type& block_signee )const;
            void                                        save_undo_state( const block_id_type& id,
                                                                         const pending_chain_state_ptr& );
            void                                        update_head_block( const full_block& blk );
            std::vector<block_id_type>                  fetch_blocks_at_number( uint32_t block_num );
            std::pair<block_id_type, block_fork_data>   recursive_mark_as_linked( const std::unordered_set<block_id_type>& ids );
            void                                        recursive_mark_as_invalid( const std::unordered_set<block_id_type>& ids, const fc::exception& reason );

            void                                        execute_markets(const fc::time_point_sec& timestamp, const pending_chain_state_ptr& pending_state );
            void                                        update_random_seed( const secret_hash_type& new_secret,
                                                                            const pending_chain_state_ptr& pending_state );
            void                                        update_active_delegate_list(const full_block& block_data,
                                                                                const pending_chain_state_ptr& pending_state );

            void                                        update_delegate_production_info( const full_block& block_data,
                                                                                const pending_chain_state_ptr& pending_state,
                                                                                const public_key_type& block_signee );

            void                                        revalidate_pending();

            fc::future<void> _revalidate_pending;
            fc::mutex        _push_block_mutex;

            /**
             *  Used to track the cumulative effect of all pending transactions that are known,
             *  new incomming transactions are evaluated relative to this state.
             *
             *  After a new block is pushed this state is recalculated based upon what ever
             *  pending transactions remain.
             */
            pending_chain_state_ptr                                                     _pending_trx_state;

            chain_database*                                                             self = nullptr;
            unordered_set<chain_observer*>                                              _observers;
            digest_type                                                                 _chain_id;
            bool                                                                        _skip_signature_verification;
            share_type                                                                  _relay_fee;

            bts::db::cached_level_map<uint32_t, std::vector<market_transaction>>        _market_transactions_db;
            bts::db::level_map<slate_id_type, delegate_slate>                           _slate_db;
            bts::db::level_map<uint32_t, std::vector<block_id_type>>                    _fork_number_db;
            bts::db::level_map<block_id_type,block_fork_data>                           _fork_db;
            bts::db::cached_level_map<uint32_t, fc::variant>                            _property_db;
#if 0
            bts::db::level_map<proposal_id_type, proposal_record>                       _proposal_db;
            bts::db::level_map<proposal_vote_id_type, proposal_vote>                    _proposal_vote_db;
#endif

            /** the data required to 'undo' the changes a block made to the database */
            bts::db::level_map<block_id_type,pending_chain_state>                       _undo_state_db;

            // blocks in the current 'official' chain.
            bts::db::level_map<uint32_t,block_id_type>                                  _block_num_to_id_db;
            // all blocks from any fork..
            bts::db::level_map<block_id_type,block_record>                              _block_id_to_block_record_db;

            bts::db::level_map<block_id_type,full_block>                                _block_id_to_block_data_db;

            std::unordered_set<transaction_id_type>                                     _known_transactions;
            bts::db::level_map<transaction_id_type,transaction_record>                  _id_to_transaction_record_db;

            signed_block_header                                                         _head_block_header;
            block_id_type                                                               _head_block_id;

            bts::db::level_map<transaction_id_type, signed_transaction>                 _pending_transaction_db;
            std::map<fee_index, transaction_evaluation_state_ptr>                       _pending_fee_index;

            bts::db::level_map<asset_id_type, asset_record>                             _asset_db;
            bts::db::level_map<string, asset_id_type>                                   _symbol_index_db;

            bts::db::level_map<balance_id_type, balance_record>                         _balance_db;

            bts::db::cached_level_map<account_id_type, account_record>                  _account_db;
            bts::db::cached_level_map<string, account_id_type>                          _account_index_db;
            bts::db::cached_level_map<address, account_id_type>                         _address_to_account_db;

            bts::db::cached_level_map<vote_del, int>                                    _delegate_vote_index_db;

            bts::db::level_map<time_point_sec, slot_record>                             _slot_record_db;

            bts::db::level_map<burn_record_key, burn_record_value>                      _burn_db;

            bts::db::cached_level_map<market_index_key, order_record>                   _ask_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _bid_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _relative_ask_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _relative_bid_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _short_db;
            bts::db::cached_level_map<market_index_key, collateral_record>              _collateral_db;
            bts::db::cached_level_map<feed_index, feed_record>                          _feed_db;

            bts::db::level_map<std::pair<asset_id_type,asset_id_type>, market_status>   _market_status_db;
            bts::db::level_map<market_history_key, market_history_record>               _market_history_db;

            std::map<operation_type_enum, std::deque<operation>>                        _recent_operations;
      };
  } // end namespace bts::blockchain::detail
} } // end namespace bts::blockchain

FC_REFLECT_TYPENAME( std::vector<bts::blockchain::block_id_type> )
FC_REFLECT( bts::blockchain::vote_del, (votes)(delegate_id) )
FC_REFLECT( bts::blockchain::fee_index, (_fees)(_trx) )
<commit_msg>Convert more level_maps to cached_level_maps<commit_after>#pragma once
//#define DEFAULT_LOGGER "blockchain"

#include <bts/blockchain/chain_database.hpp>
#include <bts/blockchain/checkpoints.hpp>
#include <bts/blockchain/config.hpp>
#include <bts/blockchain/genesis_config.hpp>
#include <bts/blockchain/genesis_json.hpp>
#include <bts/blockchain/market_records.hpp>
#include <bts/blockchain/operation_factory.hpp>
#include <bts/blockchain/time.hpp>

#include <bts/db/cached_level_map.hpp>
#include <bts/db/level_map.hpp>

#include <fc/io/fstream.hpp>
#include <fc/io/json.hpp>
#include <fc/io/raw_variant.hpp>
#include <fc/thread/mutex.hpp>
#include <fc/thread/non_preemptable_scope_check.hpp>
#include <fc/thread/unique_lock.hpp>

#include <algorithm>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>

namespace bts { namespace blockchain {

   struct vote_del
   {
      vote_del( int64_t v = 0, account_id_type del = 0 )
      :votes(v),delegate_id(del){}
      int64_t votes = 0;
      account_id_type delegate_id;
      friend bool operator == ( const vote_del& a, const vote_del& b )
      {
         return a.votes == b.votes && a.delegate_id == b.delegate_id;
      }
      friend bool operator < ( const vote_del& a, const vote_del& b )
      {
         if( a.votes != b.votes ) return a.votes > b.votes; /* Reverse so maps sort in descending order */
         return a.delegate_id < b.delegate_id; /* Lowest id wins in ties */
      }
   };

   struct fee_index
   {
      fee_index( share_type fees = 0, transaction_id_type trx = transaction_id_type() )
      :_fees(fees),_trx(trx){}
      share_type          _fees;
      transaction_id_type _trx;
      friend bool operator == ( const fee_index& a, const fee_index& b )
      {
         return a._fees == b._fees && a._trx == b._trx;
      }
      friend bool operator < ( const fee_index& a, const fee_index& b )
      {
         if( a._fees == b._fees ) return a._trx < b._trx; /* Lowest id wins in ties */
         return a._fees > b._fees; /* Reverse so that highest fee is placed first in sorted maps */
      }
   };

   namespace detail
   {
      class chain_database_impl
      {
         public:
            void                                        open_database(const fc::path& data_dir );
            digest_type                                 initialize_genesis( const optional<path>& genesis_file, bool chain_id_only = false );

            std::pair<block_id_type, block_fork_data>   store_and_index( const block_id_type& id, const full_block& blk );
            void                                        clear_pending(  const full_block& blk );
            void                                        switch_to_fork( const block_id_type& block_id );
            void                                        extend_chain( const full_block& blk );
            vector<block_id_type>                       get_fork_history( const block_id_type& id );
            void                                        pop_block();
            void                                        mark_invalid( const block_id_type& id, const fc::exception& reason );
            void                                        mark_included( const block_id_type& id, bool state );
            void                                        verify_header( const full_block&, const public_key_type& block_signee );
            void                                        apply_transactions( const full_block& block,
                                                                            const pending_chain_state_ptr& );
            void                                        pay_delegate( const pending_chain_state_ptr& pending_state,
                                                                      const public_key_type& block_signee )const;
            void                                        save_undo_state( const block_id_type& id,
                                                                         const pending_chain_state_ptr& );
            void                                        update_head_block( const full_block& blk );
            std::vector<block_id_type>                  fetch_blocks_at_number( uint32_t block_num );
            std::pair<block_id_type, block_fork_data>   recursive_mark_as_linked( const std::unordered_set<block_id_type>& ids );
            void                                        recursive_mark_as_invalid( const std::unordered_set<block_id_type>& ids, const fc::exception& reason );

            void                                        execute_markets(const fc::time_point_sec& timestamp, const pending_chain_state_ptr& pending_state );
            void                                        update_random_seed( const secret_hash_type& new_secret,
                                                                            const pending_chain_state_ptr& pending_state );
            void                                        update_active_delegate_list(const full_block& block_data,
                                                                                const pending_chain_state_ptr& pending_state );

            void                                        update_delegate_production_info( const full_block& block_data,
                                                                                const pending_chain_state_ptr& pending_state,
                                                                                const public_key_type& block_signee );

            void                                        revalidate_pending();

            fc::future<void> _revalidate_pending;
            fc::mutex        _push_block_mutex;

            /**
             *  Used to track the cumulative effect of all pending transactions that are known,
             *  new incomming transactions are evaluated relative to this state.
             *
             *  After a new block is pushed this state is recalculated based upon what ever
             *  pending transactions remain.
             */
            pending_chain_state_ptr                                                     _pending_trx_state;

            chain_database*                                                             self = nullptr;
            unordered_set<chain_observer*>                                              _observers;
            digest_type                                                                 _chain_id;
            bool                                                                        _skip_signature_verification;
            share_type                                                                  _relay_fee;

            bts::db::cached_level_map<uint32_t, std::vector<market_transaction>>        _market_transactions_db;
            bts::db::cached_level_map<slate_id_type, delegate_slate>                    _slate_db;
            bts::db::level_map<uint32_t, std::vector<block_id_type>>                    _fork_number_db;
            bts::db::level_map<block_id_type,block_fork_data>                           _fork_db;
            bts::db::cached_level_map<uint32_t, fc::variant>                            _property_db;
#if 0
            bts::db::level_map<proposal_id_type, proposal_record>                       _proposal_db;
            bts::db::level_map<proposal_vote_id_type, proposal_vote>                    _proposal_vote_db;
#endif

            /** the data required to 'undo' the changes a block made to the database */
            bts::db::level_map<block_id_type,pending_chain_state>                       _undo_state_db;

            // blocks in the current 'official' chain.
            bts::db::level_map<uint32_t,block_id_type>                                  _block_num_to_id_db;
            // all blocks from any fork..
            bts::db::level_map<block_id_type,block_record>                              _block_id_to_block_record_db;

            bts::db::level_map<block_id_type,full_block>                                _block_id_to_block_data_db;

            std::unordered_set<transaction_id_type>                                     _known_transactions;
            bts::db::level_map<transaction_id_type,transaction_record>                  _id_to_transaction_record_db;

            signed_block_header                                                         _head_block_header;
            block_id_type                                                               _head_block_id;

            bts::db::level_map<transaction_id_type, signed_transaction>                 _pending_transaction_db;
            std::map<fee_index, transaction_evaluation_state_ptr>                       _pending_fee_index;

            bts::db::cached_level_map<asset_id_type, asset_record>                      _asset_db;
            bts::db::cached_level_map<string, asset_id_type>                            _symbol_index_db;

            bts::db::level_map<balance_id_type, balance_record>                         _balance_db;

            bts::db::cached_level_map<account_id_type, account_record>                  _account_db;
            bts::db::cached_level_map<string, account_id_type>                          _account_index_db;
            bts::db::cached_level_map<address, account_id_type>                         _address_to_account_db;

            bts::db::cached_level_map<vote_del, int>                                    _delegate_vote_index_db;

            bts::db::level_map<time_point_sec, slot_record>                             _slot_record_db;

            bts::db::level_map<burn_record_key, burn_record_value>                      _burn_db;

            bts::db::cached_level_map<market_index_key, order_record>                   _ask_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _bid_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _relative_ask_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _relative_bid_db;
            bts::db::cached_level_map<market_index_key, order_record>                   _short_db;
            bts::db::cached_level_map<market_index_key, collateral_record>              _collateral_db;
            bts::db::cached_level_map<feed_index, feed_record>                          _feed_db;

            bts::db::cached_level_map<std::pair<asset_id_type,asset_id_type>, market_status> _market_status_db;
            bts::db::level_map<market_history_key, market_history_record>               _market_history_db;

            std::map<operation_type_enum, std::deque<operation>>                        _recent_operations;
      };
  } // end namespace bts::blockchain::detail
} } // end namespace bts::blockchain

FC_REFLECT_TYPENAME( std::vector<bts::blockchain::block_id_type> )
FC_REFLECT( bts::blockchain::vote_del, (votes)(delegate_id) )
FC_REFLECT( bts::blockchain::fee_index, (_fees)(_trx) )
<|endoftext|>


<commit_before>// Copyright (c) 2012-2013, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. 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.
//
// 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 <cstring>
#ifdef _WIN32
	#include <windows.h>
#else
	#include <stdint.h>
	#include <unistd.h>
	#include <sys/mman.h>
#endif
#include "hook.h"

Hook::Hook()
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{}

Hook::Hook(void *src, void *dst)
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{
	Install(src, dst);
}

Hook::~Hook() {
	Remove();
}

bool Hook::Install() {
	if (installed_) {
		return false;
	}

	// Set write permission
	Unprotect(src_, kJmpInstrSize);

	// Store the code we are going to overwrite (probably to copy it back later)
	memcpy(code_, src_, kJmpInstrSize);

	// E9 - jump near, relative
	unsigned char JMP = 0xE9;
	memcpy(src_, &JMP, 1);

	// Jump address is relative to the next instruction's address
	size_t offset = (int)dst_ - ((int)src_ + kJmpInstrSize);
	memcpy((void*)((int)src_ + 1), &offset, kJmpInstrSize - 1);

	installed_ = true;
	return true;
}

bool Hook::Install(void *src, void *dst) {
	if (installed_) {
		return false;
	}

    src_ = src;
	dst_ = dst;
	return Install();
}

bool Hook::Remove() {
	if (!installed_) {
		return false;
	}

	std::memcpy(src_, code_, kJmpInstrSize);
	installed_ = false;
	return true;
}

bool Hook::IsInstalled() const {
	return installed_;
}

// static
void *Hook::GetTargetAddress(void *jmp) {
	if (*reinterpret_cast<unsigned char*>(jmp) == 0xE9) {
		int next_instr = reinterpret_cast<int>(reinterpret_cast<char*>(jmp) + kJmpInstrSize);
		int rel_addr = *reinterpret_cast<int*>(reinterpret_cast<char*>(jmp) + 1);
		int abs_addr = rel_addr + next_instr;
		return reinterpret_cast<void*>(abs_addr);
	}
	return nullptr;
}

// static
void Hook::Unprotect(void *address, int size) {
	#ifdef _WIN32
		DWORD oldProtect;
		VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldProtect);
	#else
		size_t pagesize = getpagesize();
		size_t where = ((reinterpret_cast<uint32_t>(address) / pagesize) * pagesize);
		size_t count = (size / pagesize) * pagesize + pagesize * 2;
		mprotect(reinterpret_cast<void*>(where), count, PROT_READ | PROT_WRITE | PROT_EXEC);
	#endif
}
<commit_msg>Replace size_t and int with std:intptr_t in pointer arithmetic<commit_after>// Copyright (c) 2012-2013, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. 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.
//
// 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 <cstdint>
#include <cstring>
#ifdef _WIN32
	#include <windows.h>
#else
	#include <stdint.h>
	#include <unistd.h>
	#include <sys/mman.h>
#endif
#include "hook.h"

Hook::Hook()
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{}

Hook::Hook(void *src, void *dst)
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{
	Install(src, dst);
}

Hook::~Hook() {
	Remove();
}

bool Hook::Install() {
	if (installed_) {
		return false;
	}

	// Set write permission
	Unprotect(src_, kJmpInstrSize);

	// Store the code we are going to overwrite (probably to copy it back later)
	memcpy(code_, src_, kJmpInstrSize);

	// E9 - jump near, relative
	std::uint8_t JMP = 0xE9;
	memcpy(src_, &JMP, 1);

	// Jump address is relative to the next instruction's address
	std::intptr_t offset = (std::intptr_t)dst_ - ((std::intptr_t)src_ + kJmpInstrSize);
	memcpy((void*)((std::intptr_t)src_ + 1), &offset, kJmpInstrSize - 1);

	installed_ = true;
	return true;
}

bool Hook::Install(void *src, void *dst) {
	if (installed_) {
		return false;
	}

    src_ = src;
	dst_ = dst;
	return Install();
}

bool Hook::Remove() {
	if (!installed_) {
		return false;
	}

	std::memcpy(src_, code_, kJmpInstrSize);
	installed_ = false;
	return true;
}

bool Hook::IsInstalled() const {
	return installed_;
}

// static
void *Hook::GetTargetAddress(void *jmp) {
	if (*reinterpret_cast<unsigned char*>(jmp) == 0xE9) {
		std::intptr_t next_instr = reinterpret_cast<std::intptr_t>(reinterpret_cast<char*>(jmp) + kJmpInstrSize);
		std::intptr_t rel_addr = *reinterpret_cast<std::intptr_t*>(reinterpret_cast<char*>(jmp) + 1);
		std::intptr_t abs_addr = rel_addr + next_instr;
		return reinterpret_cast<void*>(abs_addr);
	}
	return nullptr;
}

// static
void Hook::Unprotect(void *address, int size) {
	#ifdef _WIN32
		DWORD oldProtect;
		VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldProtect);
	#else
		int pagesize = getpagesize();
		std::intptr_t where = ((reinterpret_cast<std::intptr_t>(address) / pagesize) * pagesize);
		std::intptr_t count = (size / pagesize) * pagesize + pagesize * 2;
		mprotect(reinterpret_cast<void*>(where), count, PROT_READ | PROT_WRITE | PROT_EXEC);
	#endif
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "crypto/signature_verifier_win.h"

#include "crypto/rsa_private_key.h"
#include "omaha/base/debug.h"
#include "omaha/base/logging.h"

namespace {

// Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the
// WINAPI calling convention.
void* WINAPI MyCryptAlloc(size_t size) {
  return malloc(size);
}

void WINAPI MyCryptFree(void* p) {
  free(p);
}

}  // namespace

namespace crypto {

SignatureVerifierWin::SignatureVerifierWin() : hash_object_(0), public_key_(0) {
  if (FAILED(CryptAcquireContextWithFallback(PROV_RSA_AES,
                                             provider_.receive()))) {
    provider_.reset();
  }
}

SignatureVerifierWin::~SignatureVerifierWin() {
}

bool SignatureVerifierWin::VerifyInit(ALG_ID algorithm_id,
                                      const uint8_t* signature,
                                      size_t signature_len,
                                      const uint8_t* public_key_info,
                                      size_t public_key_info_len) {
  if (algorithm_id != CALG_SHA_256 && algorithm_id != CALG_SHA1) {
    REPORT_LOG(LE, (_T("[VerifyInit][Invalid signature algorithm][%d]"),
                    algorithm_id));
    return false;
  }

  signature_.reserve(signature_len);
  // CryptoAPI uses big integers in the little-endian byte order, so we need
  // to first swap the order of signature bytes.
  for (int i = signature_len - 1; i >= 0; --i)
    signature_.push_back(signature[i]);

  CRYPT_DECODE_PARA decode_para;
  decode_para.cbSize = sizeof(decode_para);
  decode_para.pfnAlloc = MyCryptAlloc;
  decode_para.pfnFree = MyCryptFree;
  CERT_PUBLIC_KEY_INFO* cert_public_key_info = NULL;
  DWORD struct_len = 0;
  BOOL ok;
  ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                           X509_PUBLIC_KEY_INFO,
                           public_key_info,
                           public_key_info_len,
                           CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
                           &decode_para,
                           &cert_public_key_info,
                           &struct_len);
  if (!ok)
    return false;

  ok = CryptImportPublicKeyInfo(provider_,
                                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                cert_public_key_info, public_key_.receive());
  free(cert_public_key_info);
  if (!ok)
    return false;

  ok = CryptCreateHash(provider_, algorithm_id, 0, 0, hash_object_.receive());
  if (!ok)
    return false;

  return true;
}

void SignatureVerifierWin::VerifyUpdate(const uint8_t* data_part,
                                        size_t data_part_len) {
  CryptHashData(hash_object_, data_part, data_part_len, 0);
}

bool SignatureVerifierWin::VerifyFinal() {
  BOOL ok = CryptVerifySignature(hash_object_, &signature_[0],
                                 static_cast<DWORD>(signature_.size()),
                                 public_key_, NULL, 0);
  Reset();
  if (!ok)
    return false;

  return true;
}

void SignatureVerifierWin::Reset() {
  hash_object_.reset();
  public_key_.reset();
  signature_.clear();
}

}  // namespace crypto

<commit_msg>Add logging to diagnose DmClientRequestTest.FetchPolicies unit test failures.<commit_after>// Copyright (c) 2011 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 "crypto/signature_verifier_win.h"

#include "crypto/rsa_private_key.h"
#include "omaha/base/debug.h"
#include "omaha/base/error.h"
#include "omaha/base/logging.h"

namespace {

// Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the
// WINAPI calling convention.
void* WINAPI MyCryptAlloc(size_t size) {
  return malloc(size);
}

void WINAPI MyCryptFree(void* p) {
  free(p);
}

}  // namespace

namespace crypto {

SignatureVerifierWin::SignatureVerifierWin() : hash_object_(0), public_key_(0) {
  if (FAILED(CryptAcquireContextWithFallback(PROV_RSA_AES,
                                             provider_.receive()))) {
    provider_.reset();
  }
}

SignatureVerifierWin::~SignatureVerifierWin() {
}

bool SignatureVerifierWin::VerifyInit(ALG_ID algorithm_id,
                                      const uint8_t* signature,
                                      size_t signature_len,
                                      const uint8_t* public_key_info,
                                      size_t public_key_info_len) {
  if (algorithm_id != CALG_SHA_256 && algorithm_id != CALG_SHA1) {
    REPORT_LOG(LE, (_T("[VerifyInit][Invalid signature algorithm][%d]"),
                    algorithm_id));
    return false;
  }

  signature_.reserve(signature_len);
  // CryptoAPI uses big integers in the little-endian byte order, so we need
  // to first swap the order of signature bytes.
  for (int i = signature_len - 1; i >= 0; --i)
    signature_.push_back(signature[i]);

  CRYPT_DECODE_PARA decode_para;
  decode_para.cbSize = sizeof(decode_para);
  decode_para.pfnAlloc = MyCryptAlloc;
  decode_para.pfnFree = MyCryptFree;
  CERT_PUBLIC_KEY_INFO* cert_public_key_info = NULL;
  DWORD struct_len = 0;
  BOOL ok;
  ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                           X509_PUBLIC_KEY_INFO,
                           public_key_info,
                           public_key_info_len,
                           CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
                           &decode_para,
                           &cert_public_key_info,
                           &struct_len);
  if (!ok) {
    HRESULT hr = omaha::HRESULTFromLastError();
    REPORT_LOG(LE, (_T("[VerifyInit][CryptDecodeObjectEx failed][%#x]"), hr));
    return false;
  }

  ok = CryptImportPublicKeyInfo(provider_,
                                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                cert_public_key_info, public_key_.receive());
  free(cert_public_key_info);
  if (!ok) {
    HRESULT hr = omaha::HRESULTFromLastError();
    REPORT_LOG(LE, (_T("[VerifyInit][CryptImportPublicKeyInfo failed][%#x]"),
                    hr));
    return false;
  }

  ok = CryptCreateHash(provider_, algorithm_id, 0, 0, hash_object_.receive());
  if (!ok) {
    HRESULT hr = omaha::HRESULTFromLastError();
    REPORT_LOG(LE, (_T("[VerifyFinal][CryptVerifySignature failed][%#x]"), hr));
    return false;
  }

  return true;
}

void SignatureVerifierWin::VerifyUpdate(const uint8_t* data_part,
                                        size_t data_part_len) {
  BOOL ok = CryptHashData(hash_object_, data_part, data_part_len, 0);
  if (!ok) {
    HRESULT hr = omaha::HRESULTFromLastError();
    REPORT_LOG(LE, (_T("[VerifyUpdate][CryptHashData failed][%#x]"), hr));
  }
}

bool SignatureVerifierWin::VerifyFinal() {
  BOOL ok = CryptVerifySignature(hash_object_, &signature_[0],
                                 static_cast<DWORD>(signature_.size()),
                                 public_key_, NULL, 0);
  Reset();
  if (!ok) {
    HRESULT hr = omaha::HRESULTFromLastError();
    REPORT_LOG(LE, (_T("[VerifyFinal][CryptVerifySignature failed][%#x]"), hr));
    return false;
  }

  return true;
}

void SignatureVerifierWin::Reset() {
  hash_object_.reset();
  public_key_.reset();
  signature_.clear();
}

}  // namespace crypto

<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkBlobSpatialObject.txx"
#include "itkEllipseSpatialObject.txx"
#include "itkGaussianSpatialObject.txx"
#include "itkGroupSpatialObject.txx"
#include "itkImageSpatialObject.txx"
#include "itkLandmarkSpatialObject.txx"
#include "itkLineSpatialObject.txx"
#include "itkLineSpatialObjectPoint.txx"
#include "itkMeshSpatialObject.txx"
#include "itkMetaBlobConverter.txx"
#include "itkMetaEllipseConverter.txx"
#include "itkMetaEvent.h"
#include "itkMetaGaussianConverter.txx"
#include "itkMetaGroupConverter.txx"
#include "itkMetaImageConverter.txx"
#include "itkMetaLandmarkConverter.txx"
#include "itkMetaLineConverter.txx"
#include "itkMetaSceneConverter.txx"
#include "itkMetaSurfaceConverter.txx"
#include "itkMetaTubeConverter.txx"
#include "itkPlaneSpatialObject.txx"
#include "itkPointBasedSpatialObject.txx"
#include "itkPolygonGroupOrientation.h"
#include "itkPolygonGroupSpatialObject.txx"
#include "itkPolygonSpatialObject.txx"
#include "itkSceneSpatialObject.txx"
#include "itkSpatialObject.txx"
#include "itkSpatialObjectPoint.txx"
#include "itkSpatialObjectProperty.txx"
#include "itkSurfaceSpatialObject.txx"
#include "itkSurfaceSpatialObjectPoint.txx"
#include "itkTubeSpatialObject.txx"
#include "itkTubeSpatialObjectPoint.txx"
#include "itkAffineGeometryFrame.h"
#include "itkAffineGeometryFrame.txx"
#include "itkSpatialObjectTreeContainer.h"
#include "itkSpatialObjectTreeContainer.txx"
#include "itkSpatialObjectTreeNode.h"
#include "itkAffineGeometryFrame.h"
#include "itkAffineGeometryFrame.txx"

int main ( int , char*  )
{

  return 0;
}

<commit_msg>ENH: added somne recent classes.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAffineGeometryFrame.txx"
#include "itkBlobSpatialObject.txx"
#include "itkEllipseSpatialObject.txx"
#include "itkGaussianSpatialObject.txx"
#include "itkGroupSpatialObject.txx"
#include "itkImageMaskSpatialObject.txx"
#include "itkImageSpatialObject.txx"
#include "itkLandmarkSpatialObject.txx"
#include "itkLineSpatialObject.txx"
#include "itkLineSpatialObjectPoint.txx"
#include "itkMeshSpatialObject.txx"
#include "itkMetaBlobConverter.txx"
#include "itkMetaEllipseConverter.txx"
#include "itkMetaEvent.h"
#include "itkMetaGaussianConverter.txx"
#include "itkMetaGroupConverter.txx"
#include "itkMetaImageConverter.txx"
#include "itkMetaLandmarkConverter.txx"
#include "itkMetaLineConverter.txx"
#include "itkMetaMeshConverter.txx"
#include "itkMetaSceneConverter.txx"
#include "itkMetaSurfaceConverter.txx"
#include "itkMetaTubeConverter.txx"
#include "itkPlaneSpatialObject.txx"
#include "itkPointBasedSpatialObject.txx"
#include "itkPolygonGroupOrientation.h"
#include "itkPolygonGroupSpatialObject.txx"
#include "itkPolygonSpatialObject.txx"
#include "itkSceneSpatialObject.txx"
#include "itkSpatialObject.txx"
#include "itkSpatialObjectPoint.txx"
#include "itkSpatialObjectProperty.txx"
#include "itkSpatialObjectTreeContainer.txx"
#include "itkSpatialObjectTreeNode.h"
#include "itkSurfaceSpatialObject.txx"
#include "itkSurfaceSpatialObjectPoint.txx"
#include "itkTubeSpatialObject.txx"
#include "itkTubeSpatialObjectPoint.txx"

int main ( int , char*  )
{

  return 0;
}

<|endoftext|>


<commit_before>// @(#)root/mathmore:$Id$
// Author: L. Moneta Wed Dec 20 14:36:31 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 * This library is free software; you can redistribute it and/or      *
 * modify it under the terms of the GNU General Public License        *
 * as published by the Free Software Foundation; either version 2     *
 * of the License, or (at your option) any later version.             *
 *                                                                    *
 * This library is distributed in the hope that it will be useful,    *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
 * General Public License for more details.                           *
 *                                                                    *
 * You should have received a copy of the GNU General Public License  *
 * along with this library (see file COPYING); if not, write          *
 * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
 * 330, Boston, MA 02111-1307 USA, or contact the author.             *
 *                                                                    *
 **********************************************************************/

// implementation file for class MultiNumGradFunction

#include "Math/MultiNumGradFunction.h"
#include <limits>
#include <cmath>

#ifndef ROOT_Math_Derivator
#include "Math/Derivator.h"
#endif

namespace ROOT {

   namespace Math {

double MultiNumGradFunction::fgEps = 0.001;

double MultiNumGradFunction::DoDerivative (const double * x, unsigned int icoord  ) const {
      // calculate derivative using mathcore derivator class
   // step size can be changes using SetDerivPrecision()

   static double kPrecision = std::sqrt ( std::numeric_limits<double>::epsilon() );
   double x0 = x[icoord];
   double step = std::max( fgEps* std::abs(x0), 8.0*kPrecision*(std::abs(x0) + kPrecision) );
   return ROOT::Math::Derivator::Eval(*fFunc, x, icoord, step);
}

void MultiNumGradFunction::SetDerivPrecision(double eps) { fgEps = eps; }

double MultiNumGradFunction::GetDerivPrecision( ) { return fgEps; }

   } // end namespace Math

} // end namespace ROOT
<commit_msg>fix problem on Solaris<commit_after>// @(#)root/mathmore:$Id$
// Author: L. Moneta Wed Dec 20 14:36:31 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 * This library is free software; you can redistribute it and/or      *
 * modify it under the terms of the GNU General Public License        *
 * as published by the Free Software Foundation; either version 2     *
 * of the License, or (at your option) any later version.             *
 *                                                                    *
 * This library is distributed in the hope that it will be useful,    *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
 * General Public License for more details.                           *
 *                                                                    *
 * You should have received a copy of the GNU General Public License  *
 * along with this library (see file COPYING); if not, write          *
 * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
 * 330, Boston, MA 02111-1307 USA, or contact the author.             *
 *                                                                    *
 **********************************************************************/

// implementation file for class MultiNumGradFunction

#include "Math/MultiNumGradFunction.h"
#include <limits>
#include <cmath>
#include <algorithm>    // needed for std::max on Solaris

#ifndef ROOT_Math_Derivator
#include "Math/Derivator.h"
#endif

namespace ROOT {

   namespace Math {

double MultiNumGradFunction::fgEps = 0.001;

double MultiNumGradFunction::DoDerivative (const double * x, unsigned int icoord  ) const {
      // calculate derivative using mathcore derivator class
   // step size can be changes using SetDerivPrecision()

   static double kPrecision = std::sqrt ( std::numeric_limits<double>::epsilon() );
   double x0 = x[icoord];
   double step = std::max( fgEps* std::abs(x0), 8.0*kPrecision*(std::abs(x0) + kPrecision) );
   return ROOT::Math::Derivator::Eval(*fFunc, x, icoord, step);
}

void MultiNumGradFunction::SetDerivPrecision(double eps) { fgEps = eps; }

double MultiNumGradFunction::GetDerivPrecision( ) { return fgEps; }

   } // end namespace Math

} // end namespace ROOT
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "jingle/glue/thread_wrapper.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"

namespace jingle_glue {

struct JingleThreadWrapper::PendingSend {
  PendingSend(const talk_base::Message& message_value)
      : sending_thread(JingleThreadWrapper::current()),
        message(message_value),
        done_event(true, false) {
    DCHECK(sending_thread);
  }

  JingleThreadWrapper* sending_thread;
  talk_base::Message message;
  base::WaitableEvent done_event;
};

base::LazyInstance<base::ThreadLocalPointer<JingleThreadWrapper> >
    g_jingle_thread_wrapper = LAZY_INSTANCE_INITIALIZER;

// static
void JingleThreadWrapper::EnsureForCurrentThread() {
  if (JingleThreadWrapper::current() == NULL) {
    g_jingle_thread_wrapper.Get().Set(
        new JingleThreadWrapper(MessageLoop::current()));
  }

  DCHECK_EQ(talk_base::Thread::Current(), current());
}

// static
JingleThreadWrapper* JingleThreadWrapper::current() {
  return g_jingle_thread_wrapper.Get().Get();
}

JingleThreadWrapper::JingleThreadWrapper(MessageLoop* message_loop)
    : talk_base::Thread(NULL),
      message_loop_(message_loop),
      send_allowed_(false),
      last_task_id_(0),
      pending_send_event_(true, false) {
  DCHECK_EQ(message_loop_, MessageLoop::current());

  talk_base::ThreadManager::Instance()->UnwrapCurrentThread();
  talk_base::ThreadManager::Instance()->SetCurrentThread(this);
  talk_base::MessageQueueManager::Instance()->Add(this);
  message_loop_->AddDestructionObserver(this);

  WrapCurrent();
}

JingleThreadWrapper::~JingleThreadWrapper() {
}

void JingleThreadWrapper::WillDestroyCurrentMessageLoop() {
  DCHECK_EQ(talk_base::Thread::Current(), current());
  UnwrapCurrent();
  g_jingle_thread_wrapper.Get().Set(NULL);
  talk_base::ThreadManager::Instance()->SetCurrentThread(NULL);
  talk_base::MessageQueueManager::Instance()->Remove(this);
  message_loop_->RemoveDestructionObserver(this);
  delete this;
}

void JingleThreadWrapper::Post(
    talk_base::MessageHandler* handler, uint32 message_id,
    talk_base::MessageData* data, bool time_sensitive) {
  PostTaskInternal(0, handler, message_id, data);
}

void JingleThreadWrapper::PostDelayed(
    int delay_ms, talk_base::MessageHandler* handler,
    uint32 message_id, talk_base::MessageData* data) {
  PostTaskInternal(delay_ms, handler, message_id, data);
}

void JingleThreadWrapper::Clear(talk_base::MessageHandler* handler, uint32 id,
                                talk_base::MessageList* removed) {
  base::AutoLock auto_lock(lock_);

  for (MessagesQueue::iterator it = messages_.begin();
       it != messages_.end();) {
    MessagesQueue::iterator next = it;
    ++next;

    if (it->second.Match(handler, id)) {
      if (removed) {
        removed->push_back(it->second);
      } else {
        delete it->second.pdata;
      }
      messages_.erase(it);
    }

    it = next;
  }

  for (std::list<PendingSend*>::iterator it = pending_send_messages_.begin();
       it != pending_send_messages_.end();) {
    std::list<PendingSend*>::iterator next = it;
    ++next;

    if ((*it)->message.Match(handler, id)) {
      if (removed) {
        removed ->push_back((*it)->message);
      } else {
        delete (*it)->message.pdata;
      }
      (*it)->done_event.Signal();
      pending_send_messages_.erase(it);
    }

    it = next;
  }
}

void JingleThreadWrapper::Send(talk_base::MessageHandler *handler, uint32 id,
                               talk_base::MessageData *data) {
  if (fStop_)
    return;

  JingleThreadWrapper* current_thread = JingleThreadWrapper::current();
  DCHECK(current_thread != NULL) << "Send() can be called only from a "
      "thread that has JingleThreadWrapper.";

  talk_base::Message message;
  message.phandler = handler;
  message.message_id = id;
  message.pdata = data;

  if (current_thread == this) {
    handler->OnMessage(&message);
    return;
  }

  // Send message from a thread different than |this|.

  // Allow inter-thread send only from threads that have
  // |send_allowed_| flag set.
  DCHECK(current_thread->send_allowed_) << "Send()'ing synchronous "
      "messages is not allowed from the current thread.";

  PendingSend pending_send(message);
  {
    base::AutoLock auto_lock(lock_);
    pending_send_messages_.push_back(&pending_send);
  }

  // Need to signal |pending_send_event_| here in case the thread is
  // sending message to another thread.
  pending_send_event_.Signal();
  message_loop_->PostTask(FROM_HERE,
                          base::Bind(&JingleThreadWrapper::ProcessPendingSends,
                                     base::Unretained(this)));

  while (!pending_send.done_event.IsSignaled()) {
    base::WaitableEvent* events[] = {&pending_send.done_event,
                                     &current_thread->pending_send_event_};
    size_t event = base::WaitableEvent::WaitMany(events, arraysize(events));
    DCHECK(event == 0 || event == 1);

    if (event == 1)
      current_thread->ProcessPendingSends();
  }
}

void JingleThreadWrapper::ProcessPendingSends() {
  while (true) {
    PendingSend* pending_send = NULL;
    {
      base::AutoLock auto_lock(lock_);
      if (!pending_send_messages_.empty()) {
        pending_send = pending_send_messages_.front();
        pending_send_messages_.pop_front();
      } else {
        // Reset the event while |lock_| is still locked.
        pending_send_event_.Reset();
        break;
      }
    }
    if (pending_send) {
      pending_send->message.phandler->OnMessage(&pending_send->message);
      pending_send->done_event.Signal();
    }
  }
}

void JingleThreadWrapper::PostTaskInternal(
    int delay_ms, talk_base::MessageHandler* handler,
    uint32 message_id, talk_base::MessageData* data) {
  int task_id;
  talk_base::Message message;
  message.phandler = handler;
  message.message_id = message_id;
  message.pdata = data;
  {
    base::AutoLock auto_lock(lock_);
    task_id = ++last_task_id_;
    messages_.insert(std::pair<int, talk_base::Message>(task_id, message));
  }

  if (delay_ms <= 0) {
    message_loop_->PostTask(FROM_HERE,
                            base::Bind(&JingleThreadWrapper::RunTask,
                                       base::Unretained(this), task_id));
  } else {
    message_loop_->PostDelayedTask(FROM_HERE,
                                   base::Bind(&JingleThreadWrapper::RunTask,
                                              base::Unretained(this), task_id),
                                   base::TimeDelta::FromMilliseconds(delay_ms));
  }
}

void JingleThreadWrapper::RunTask(int task_id) {
  bool have_message = false;
  talk_base::Message message;
  {
    base::AutoLock auto_lock(lock_);
    MessagesQueue::iterator it = messages_.find(task_id);
    if (it != messages_.end()) {
      have_message = true;
      message = it->second;
      messages_.erase(it);
    }
  }

  if (have_message) {
    if (message.message_id == talk_base::MQID_DISPOSE) {
      DCHECK(message.phandler == NULL);
      delete message.pdata;
    } else {
      message.phandler->OnMessage(&message);
    }
  }
}

// All methods below are marked as not reached. See comments in the
// header for more details.
void JingleThreadWrapper::Quit() {
  NOTREACHED();
}

bool JingleThreadWrapper::IsQuitting() {
  NOTREACHED();
  return false;
}

void JingleThreadWrapper::Restart() {
  NOTREACHED();
}

bool JingleThreadWrapper::Get(talk_base::Message*, int, bool) {
  NOTREACHED();
  return false;
}

bool JingleThreadWrapper::Peek(talk_base::Message*, int) {
  NOTREACHED();
  return false;
}

void JingleThreadWrapper::PostAt(uint32, talk_base::MessageHandler*,
                                 uint32, talk_base::MessageData*) {
  NOTREACHED();
}

void JingleThreadWrapper::Dispatch(talk_base::Message* message) {
  NOTREACHED();
}

void JingleThreadWrapper::ReceiveSends() {
  NOTREACHED();
}

int JingleThreadWrapper::GetDelay() {
  NOTREACHED();
  return 0;
}

void JingleThreadWrapper::Stop() {
  NOTREACHED();
}

void JingleThreadWrapper::Run() {
  NOTREACHED();
}

}  // namespace jingle_glue
<commit_msg>Currently when talk_base::Thread exists, Clear(NULL) is called from its destructor. But JingleThreadWrapper never gets a chance to remove pending messages from its queue. <commit_after>// Copyright (c) 2012 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 "jingle/glue/thread_wrapper.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"

namespace jingle_glue {

struct JingleThreadWrapper::PendingSend {
  PendingSend(const talk_base::Message& message_value)
      : sending_thread(JingleThreadWrapper::current()),
        message(message_value),
        done_event(true, false) {
    DCHECK(sending_thread);
  }

  JingleThreadWrapper* sending_thread;
  talk_base::Message message;
  base::WaitableEvent done_event;
};

base::LazyInstance<base::ThreadLocalPointer<JingleThreadWrapper> >
    g_jingle_thread_wrapper = LAZY_INSTANCE_INITIALIZER;

// static
void JingleThreadWrapper::EnsureForCurrentThread() {
  if (JingleThreadWrapper::current() == NULL) {
    g_jingle_thread_wrapper.Get().Set(
        new JingleThreadWrapper(MessageLoop::current()));
  }

  DCHECK_EQ(talk_base::Thread::Current(), current());
}

// static
JingleThreadWrapper* JingleThreadWrapper::current() {
  return g_jingle_thread_wrapper.Get().Get();
}

JingleThreadWrapper::JingleThreadWrapper(MessageLoop* message_loop)
    : talk_base::Thread(NULL),
      message_loop_(message_loop),
      send_allowed_(false),
      last_task_id_(0),
      pending_send_event_(true, false) {
  DCHECK_EQ(message_loop_, MessageLoop::current());

  talk_base::ThreadManager::Instance()->UnwrapCurrentThread();
  talk_base::ThreadManager::Instance()->SetCurrentThread(this);
  talk_base::MessageQueueManager::Instance()->Add(this);
  message_loop_->AddDestructionObserver(this);

  WrapCurrent();
}

JingleThreadWrapper::~JingleThreadWrapper() {
  Clear(NULL, talk_base::MQID_ANY, NULL);
}

void JingleThreadWrapper::WillDestroyCurrentMessageLoop() {
  DCHECK_EQ(talk_base::Thread::Current(), current());
  UnwrapCurrent();
  g_jingle_thread_wrapper.Get().Set(NULL);
  talk_base::ThreadManager::Instance()->SetCurrentThread(NULL);
  talk_base::MessageQueueManager::Instance()->Remove(this);
  message_loop_->RemoveDestructionObserver(this);
  delete this;
}

void JingleThreadWrapper::Post(
    talk_base::MessageHandler* handler, uint32 message_id,
    talk_base::MessageData* data, bool time_sensitive) {
  PostTaskInternal(0, handler, message_id, data);
}

void JingleThreadWrapper::PostDelayed(
    int delay_ms, talk_base::MessageHandler* handler,
    uint32 message_id, talk_base::MessageData* data) {
  PostTaskInternal(delay_ms, handler, message_id, data);
}

void JingleThreadWrapper::Clear(talk_base::MessageHandler* handler, uint32 id,
                                talk_base::MessageList* removed) {
  base::AutoLock auto_lock(lock_);

  for (MessagesQueue::iterator it = messages_.begin();
       it != messages_.end();) {
    MessagesQueue::iterator next = it;
    ++next;

    if (it->second.Match(handler, id)) {
      if (removed) {
        removed->push_back(it->second);
      } else {
        delete it->second.pdata;
      }
      messages_.erase(it);
    }

    it = next;
  }

  for (std::list<PendingSend*>::iterator it = pending_send_messages_.begin();
       it != pending_send_messages_.end();) {
    std::list<PendingSend*>::iterator next = it;
    ++next;

    if ((*it)->message.Match(handler, id)) {
      if (removed) {
        removed ->push_back((*it)->message);
      } else {
        delete (*it)->message.pdata;
      }
      (*it)->done_event.Signal();
      pending_send_messages_.erase(it);
    }

    it = next;
  }
}

void JingleThreadWrapper::Send(talk_base::MessageHandler *handler, uint32 id,
                               talk_base::MessageData *data) {
  if (fStop_)
    return;

  JingleThreadWrapper* current_thread = JingleThreadWrapper::current();
  DCHECK(current_thread != NULL) << "Send() can be called only from a "
      "thread that has JingleThreadWrapper.";

  talk_base::Message message;
  message.phandler = handler;
  message.message_id = id;
  message.pdata = data;

  if (current_thread == this) {
    handler->OnMessage(&message);
    return;
  }

  // Send message from a thread different than |this|.

  // Allow inter-thread send only from threads that have
  // |send_allowed_| flag set.
  DCHECK(current_thread->send_allowed_) << "Send()'ing synchronous "
      "messages is not allowed from the current thread.";

  PendingSend pending_send(message);
  {
    base::AutoLock auto_lock(lock_);
    pending_send_messages_.push_back(&pending_send);
  }

  // Need to signal |pending_send_event_| here in case the thread is
  // sending message to another thread.
  pending_send_event_.Signal();
  message_loop_->PostTask(FROM_HERE,
                          base::Bind(&JingleThreadWrapper::ProcessPendingSends,
                                     base::Unretained(this)));

  while (!pending_send.done_event.IsSignaled()) {
    base::WaitableEvent* events[] = {&pending_send.done_event,
                                     &current_thread->pending_send_event_};
    size_t event = base::WaitableEvent::WaitMany(events, arraysize(events));
    DCHECK(event == 0 || event == 1);

    if (event == 1)
      current_thread->ProcessPendingSends();
  }
}

void JingleThreadWrapper::ProcessPendingSends() {
  while (true) {
    PendingSend* pending_send = NULL;
    {
      base::AutoLock auto_lock(lock_);
      if (!pending_send_messages_.empty()) {
        pending_send = pending_send_messages_.front();
        pending_send_messages_.pop_front();
      } else {
        // Reset the event while |lock_| is still locked.
        pending_send_event_.Reset();
        break;
      }
    }
    if (pending_send) {
      pending_send->message.phandler->OnMessage(&pending_send->message);
      pending_send->done_event.Signal();
    }
  }
}

void JingleThreadWrapper::PostTaskInternal(
    int delay_ms, talk_base::MessageHandler* handler,
    uint32 message_id, talk_base::MessageData* data) {
  int task_id;
  talk_base::Message message;
  message.phandler = handler;
  message.message_id = message_id;
  message.pdata = data;
  {
    base::AutoLock auto_lock(lock_);
    task_id = ++last_task_id_;
    messages_.insert(std::pair<int, talk_base::Message>(task_id, message));
  }

  if (delay_ms <= 0) {
    message_loop_->PostTask(FROM_HERE,
                            base::Bind(&JingleThreadWrapper::RunTask,
                                       base::Unretained(this), task_id));
  } else {
    message_loop_->PostDelayedTask(FROM_HERE,
                                   base::Bind(&JingleThreadWrapper::RunTask,
                                              base::Unretained(this), task_id),
                                   base::TimeDelta::FromMilliseconds(delay_ms));
  }
}

void JingleThreadWrapper::RunTask(int task_id) {
  bool have_message = false;
  talk_base::Message message;
  {
    base::AutoLock auto_lock(lock_);
    MessagesQueue::iterator it = messages_.find(task_id);
    if (it != messages_.end()) {
      have_message = true;
      message = it->second;
      messages_.erase(it);
    }
  }

  if (have_message) {
    if (message.message_id == talk_base::MQID_DISPOSE) {
      DCHECK(message.phandler == NULL);
      delete message.pdata;
    } else {
      message.phandler->OnMessage(&message);
    }
  }
}

// All methods below are marked as not reached. See comments in the
// header for more details.
void JingleThreadWrapper::Quit() {
  NOTREACHED();
}

bool JingleThreadWrapper::IsQuitting() {
  NOTREACHED();
  return false;
}

void JingleThreadWrapper::Restart() {
  NOTREACHED();
}

bool JingleThreadWrapper::Get(talk_base::Message*, int, bool) {
  NOTREACHED();
  return false;
}

bool JingleThreadWrapper::Peek(talk_base::Message*, int) {
  NOTREACHED();
  return false;
}

void JingleThreadWrapper::PostAt(uint32, talk_base::MessageHandler*,
                                 uint32, talk_base::MessageData*) {
  NOTREACHED();
}

void JingleThreadWrapper::Dispatch(talk_base::Message* message) {
  NOTREACHED();
}

void JingleThreadWrapper::ReceiveSends() {
  NOTREACHED();
}

int JingleThreadWrapper::GetDelay() {
  NOTREACHED();
  return 0;
}

void JingleThreadWrapper::Stop() {
  NOTREACHED();
}

void JingleThreadWrapper::Run() {
  NOTREACHED();
}

}  // namespace jingle_glue
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "directory_description.h"
#include "directory_comparer.h"
#include "list_directory.h"
#include "directory_mismatch.h"

void test()
{
    list_directory lister;
    directory_description* a(lister.read("C:\\Projects\\kitschensync - Kopie"));
    directory_description* b(lister.read("T:\\kitschensync"));

    directory_comparer dc;
    directory_mismatch* diffs = dc.compare_directories(a, b);
    if (diffs)
    {
        const directory_description* newer;
        const directory_description* older;

        diffs->dump();

        relationship_order ro = diffs->determine_relationship(&newer, &older);
        if (ro != relationship_order::undefined)
        {
            printf("--------------------------------------------\r\n");
            printf("%s is newer than %s\r\n",
                newer->get_path(),
                older->get_path());
            printf("--------------------------------------------\r\n");
            DWORD t0 = GetTickCount();
            diffs->apply_changes(ro, directory_sync_mode::copy_missing_objects_and_delete_obsolete_ones);
            printf("Time to sync directories: %ld ms.\r\n", GetTickCount() - t0);
        }
        else
        {
            printf("*** WARNING: was unable to determine relationship between these two directories...\r\n");
            diffs->dump();
        }
        delete diffs;
    }
    else
    {
        printf("Great: directories are identical!\r\n");
    }
    delete diffs;
    delete a;
    delete b;
}

int _tmain(int, _TCHAR* [])
{
    test();
#ifdef _DEBUG
    _CrtDumpMemoryLeaks();
#endif
    return 0;
}

<commit_msg>Fixed access-denied issues<commit_after>#include "stdafx.h"
#include "directory_description.h"
#include "directory_comparer.h"
#include "list_directory.h"
#include "directory_mismatch.h"

void test()
{
    list_directory lister;
    directory_description* a(lister.read("C:\\Projects\\kitschensync - Kopie"));
    directory_description* b(lister.read("T:\\kitschensync"));

    directory_comparer dc;
    directory_mismatch* diffs = dc.compare_directories(a, b);
    if (diffs)
    {
        const directory_description* newer;
        const directory_description* older;

        diffs->dump();

        relationship_order ro = diffs->determine_relationship(&newer, &older);
        if (ro != relationship_order::undefined)
        {
            printf("--------------------------------------------\r\n");
            printf("%s is newer than %s\r\n",
                newer->get_path(),
                older->get_path());
            printf("--------------------------------------------\r\n");
            DWORD t0 = GetTickCount();
            diffs->apply_changes(ro, directory_sync_mode::copy_missing_objects_and_delete_obsolete_ones);
            printf("Time to sync directories: %ld ms.\r\n", GetTickCount() - t0);
        }
        else
        {
            printf("*** WARNING: was unable to determine relationship between these two directories...\r\n");
            diffs->dump();
        }
        delete diffs;
        diffs = nullptr;
    }
    else
    {
        printf("Great: directories are identical!\r\n");
    }
    delete a;
    delete b;
}

int _tmain(int, _TCHAR* [])
{
    test();
#ifdef _DEBUG
    _CrtDumpMemoryLeaks();
#endif
    getchar();
    return 0;
}

<|endoftext|>


<commit_before>
#include <cstring>
#include <stdexcept>
#include <sys/mman.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <fcntl.h>
#include <unistd.h>
#include <drm_fourcc.h>
#include <drm.h>
#include <drm_mode.h>

#include <kms++/kms++.h>

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

using namespace std;

namespace kms
{

DumbFramebuffer::DumbFramebuffer(Card &card, uint32_t width, uint32_t height, const string& fourcc)
	:DumbFramebuffer(card, width, height, FourCCToPixelFormat(fourcc))
{
}

DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format)
	:Framebuffer(card, width, height), m_format(format)
{
	Create();
}

DumbFramebuffer::~DumbFramebuffer()
{
	Destroy();
}

void DumbFramebuffer::Create()
{
	int r;

	const PixelFormatInfo& format_info = get_pixel_format_info(m_format);

	m_num_planes = format_info.num_planes;

	for (int i = 0; i < format_info.num_planes; ++i) {
		const PixelFormatPlaneInfo& pi = format_info.planes[i];
		FramebufferPlane& plane = m_planes[i];

		/* create dumb buffer */
		struct drm_mode_create_dumb creq = drm_mode_create_dumb();
		creq.width = width();
		creq.height = height() / pi.ysub;
		creq.bpp = pi.bitspp;
		r = drmIoctl(card().fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq);
		if (r)
			throw invalid_argument(string("DRM_IOCTL_MODE_CREATE_DUMB failed") + strerror(errno));

		plane.handle = creq.handle;
		plane.stride = creq.pitch;
		plane.size = creq.height * creq.pitch;
		plane.offset = 0;
		plane.map = 0;
		plane.prime_fd = -1;
	}

	/* create framebuffer object for the dumb-buffer */
	uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle };
	uint32_t pitches[4] = { m_planes[0].stride, m_planes[1].stride };
	uint32_t offsets[4] = {  m_planes[0].offset, m_planes[1].offset };
	uint32_t id;
	r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(),
			  bo_handles, pitches, offsets, &id, 0);
	if (r)
		throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));

	set_id(id);
}

void DumbFramebuffer::Destroy()
{
	/* delete framebuffer */
	drmModeRmFB(card().fd(), id());

	for (uint i = 0; i < m_num_planes; ++i) {
		FramebufferPlane& plane = m_planes[i];

		/* unmap buffer */
		if (plane.map)
			munmap(plane.map, plane.size);

		/* delete dumb buffer */
		struct drm_mode_destroy_dumb dreq = drm_mode_destroy_dumb();
		dreq.handle = plane.handle;
		drmIoctl(card().fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
		if (plane.prime_fd >= 0)
			::close(plane.prime_fd);
	}
}

uint8_t* DumbFramebuffer::map(unsigned plane)
{
	FramebufferPlane& p = m_planes[plane];

	if (p.map)
		return p.map;

	/* prepare buffer for memory mapping */
	struct drm_mode_map_dumb mreq = drm_mode_map_dumb();
	mreq.handle = p.handle;
	int r = drmIoctl(card().fd(), DRM_IOCTL_MODE_MAP_DUMB, &mreq);
	if (r)
		throw invalid_argument(string("DRM_IOCTL_MODE_MAP_DUMB failed") + strerror(errno));

	/* perform actual memory mapping */
	p.map = (uint8_t *)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
					  card().fd(), mreq.offset);
	if (p.map == MAP_FAILED)
		throw invalid_argument(string("mmap failed: ") + strerror(errno));

	return p.map;
}

int DumbFramebuffer::prime_fd(unsigned int plane)
{
	if (m_planes[plane].prime_fd >= 0)
		return m_planes[plane].prime_fd;

	int r = drmPrimeHandleToFD(card().fd(), m_planes[plane].handle,
				   DRM_CLOEXEC, &m_planes[plane].prime_fd);
	if (r)
		throw std::runtime_error("drmPrimeHandleToFD failed");

	return m_planes[plane].prime_fd;
}

}
<commit_msg>Fix error prints<commit_after>
#include <cstring>
#include <stdexcept>
#include <sys/mman.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <fcntl.h>
#include <unistd.h>
#include <drm_fourcc.h>
#include <drm.h>
#include <drm_mode.h>

#include <kms++/kms++.h>

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

using namespace std;

namespace kms
{

DumbFramebuffer::DumbFramebuffer(Card &card, uint32_t width, uint32_t height, const string& fourcc)
	:DumbFramebuffer(card, width, height, FourCCToPixelFormat(fourcc))
{
}

DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format)
	:Framebuffer(card, width, height), m_format(format)
{
	Create();
}

DumbFramebuffer::~DumbFramebuffer()
{
	Destroy();
}

void DumbFramebuffer::Create()
{
	int r;

	const PixelFormatInfo& format_info = get_pixel_format_info(m_format);

	m_num_planes = format_info.num_planes;

	for (int i = 0; i < format_info.num_planes; ++i) {
		const PixelFormatPlaneInfo& pi = format_info.planes[i];
		FramebufferPlane& plane = m_planes[i];

		/* create dumb buffer */
		struct drm_mode_create_dumb creq = drm_mode_create_dumb();
		creq.width = width();
		creq.height = height() / pi.ysub;
		creq.bpp = pi.bitspp;
		r = drmIoctl(card().fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq);
		if (r)
			throw invalid_argument(string("DRM_IOCTL_MODE_CREATE_DUMB failed: ") + strerror(errno));

		plane.handle = creq.handle;
		plane.stride = creq.pitch;
		plane.size = creq.height * creq.pitch;
		plane.offset = 0;
		plane.map = 0;
		plane.prime_fd = -1;
	}

	/* create framebuffer object for the dumb-buffer */
	uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle };
	uint32_t pitches[4] = { m_planes[0].stride, m_planes[1].stride };
	uint32_t offsets[4] = {  m_planes[0].offset, m_planes[1].offset };
	uint32_t id;
	r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(),
			  bo_handles, pitches, offsets, &id, 0);
	if (r)
		throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));

	set_id(id);
}

void DumbFramebuffer::Destroy()
{
	/* delete framebuffer */
	drmModeRmFB(card().fd(), id());

	for (uint i = 0; i < m_num_planes; ++i) {
		FramebufferPlane& plane = m_planes[i];

		/* unmap buffer */
		if (plane.map)
			munmap(plane.map, plane.size);

		/* delete dumb buffer */
		struct drm_mode_destroy_dumb dreq = drm_mode_destroy_dumb();
		dreq.handle = plane.handle;
		drmIoctl(card().fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
		if (plane.prime_fd >= 0)
			::close(plane.prime_fd);
	}
}

uint8_t* DumbFramebuffer::map(unsigned plane)
{
	FramebufferPlane& p = m_planes[plane];

	if (p.map)
		return p.map;

	/* prepare buffer for memory mapping */
	struct drm_mode_map_dumb mreq = drm_mode_map_dumb();
	mreq.handle = p.handle;
	int r = drmIoctl(card().fd(), DRM_IOCTL_MODE_MAP_DUMB, &mreq);
	if (r)
		throw invalid_argument(string("DRM_IOCTL_MODE_MAP_DUMB failed: ") + strerror(errno));

	/* perform actual memory mapping */
	p.map = (uint8_t *)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
					  card().fd(), mreq.offset);
	if (p.map == MAP_FAILED)
		throw invalid_argument(string("mmap failed: ") + strerror(errno));

	return p.map;
}

int DumbFramebuffer::prime_fd(unsigned int plane)
{
	if (m_planes[plane].prime_fd >= 0)
		return m_planes[plane].prime_fd;

	int r = drmPrimeHandleToFD(card().fd(), m_planes[plane].handle,
				   DRM_CLOEXEC, &m_planes[plane].prime_fd);
	if (r)
		throw std::runtime_error("drmPrimeHandleToFD failed");

	return m_planes[plane].prime_fd;
}

}
<|endoftext|>