<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include "main.hxx"

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/logstreams.hh>
#include <vector>

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/fmatrix.hh>
# include <dune/common/densematrix.hh>
# include <dune/common/fvector.hh>
# include <dune/common/dynmatrix.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/densevector.hh>

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/fmatrix.hh>
#include <dune/stuff/la/container/common.hh>
#if HAVE_EIGEN
# include <dune/stuff/la/container/eigen.hh>
#endif
#if HAVE_DUNE_ISTL
# include <dune/stuff/la/container/istl.hh>
#endif

using namespace Dune::Stuff::Common;
using namespace std;

//define types and expected values for the typed tests
template< class MatrixType >
struct MatrixStringTestDouble
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1.000000 2.000000; 3.000000 4.000000]", toString(fromString<MatrixType>("[1.0 2; 3.0 4]")));
    EXPECT_THROW(fromString<MatrixType>("[1 2; 3 4]", 3, 3), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class MatrixType >
struct MatrixStringTestChar
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1 2; 3 4]", toString(fromString<MatrixType>("[1 2; 3 4]")));
    EXPECT_THROW(fromString<MatrixType>("[1 2; 3 4]", 3, 3), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class VectorType >
struct VectorStringTestDouble
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1.000000 2.000000 3.000000]", toString(fromString<VectorType>("[1.0 2 3.0]")));
    EXPECT_THROW(fromString<VectorType>("[1.0 2 3.0]", 4), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class VectorType >
struct VectorStringTestInt
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1 2 3]", toString(fromString<VectorType>("[1 2 3]")));
    EXPECT_THROW(fromString<VectorType>("[1 2 3]", 4), Dune::Stuff::Exceptions::configuration_error);
  }
};

typedef testing::Types< std::vector< double >
                    , Dune::Stuff::LA::CommonDenseVector< double >
                    , Dune::DynamicVector< double >
                    , Dune::FieldVector< double, 3 >
                    , Dune::Stuff::Common::FieldVector< double, 3 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseVector< double >
                    , Dune::Stuff::LA::EigenMappedDenseVector< double >
#endif
#if HAVE_DUNE_ISTL
                    , Dune::Stuff::LA::IstlDenseVector< double >
#endif
                    > VectorTypesDouble;

typedef testing::Types< std::vector< int >
                    , Dune::Stuff::LA::CommonDenseVector< int >
                    , Dune::DynamicVector< int >
                    , Dune::FieldVector< int, 3 >
                    , Dune::Stuff::Common::FieldVector< int, 3 >
#if HAVE_DUNE_ISTL
                    , Dune::Stuff::LA::IstlDenseVector< int >
#endif
                    > VectorTypesInt;

typedef testing::Types< Dune::DynamicMatrix< double >
                    , Dune::Stuff::LA::CommonDenseMatrix< double >
                    , Dune::Stuff::Common::FieldMatrix< double, 2, 2 >
                    , Dune::FieldMatrix< double, 2, 2 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseMatrix< double >
#endif
                    > MatrixTypesDouble;

typedef testing::Types< Dune::DynamicMatrix< char >
                    , Dune::Stuff::LA::CommonDenseMatrix< char >
                    , Dune::Stuff::Common::FieldMatrix< char, 2, 2 >
                    , Dune::FieldMatrix< char, 2, 2 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseMatrix< char >
#endif
                    > MatrixTypesChar;

// fromString/toString tests for vector and matrix types
TYPED_TEST_CASE(MatrixStringTestDouble, MatrixTypesDouble);
TYPED_TEST(MatrixStringTestDouble, CheckDouble) {
  this->check();
}

TYPED_TEST_CASE(MatrixStringTestChar, MatrixTypesChar);
TYPED_TEST(MatrixStringTestChar, CheckChar) {
  this->check();
}

TYPED_TEST_CASE(VectorStringTestDouble, VectorTypesDouble);
TYPED_TEST(VectorStringTestDouble, CheckDouble) {
  this->check();
}

TYPED_TEST_CASE(VectorStringTestInt, VectorTypesInt);
TYPED_TEST(VectorStringTestInt, CheckInt) {
  this->check();
}

// Additional fromString/toString tests
TEST(StringTest, ConvertTo) {
  EXPECT_EQ("9",toString(fromString<int>("9")));
  EXPECT_EQ("P",toString(fromString<char>("P")));
  EXPECT_EQ(double(0.1),
            fromString<double>(toString<double>(0.1)));
  EXPECT_EQ("0.100006",
            toString(fromString<double>("0.1000055511151231257827021181583404541015625")));
  EXPECT_EQ("1",toString(fromString<bool>("1")));
  EXPECT_EQ("0",toString(fromString<bool>("0")));
  EXPECT_EQ("-1",toString(fromString<long>("-1")));
}

TEST(StringTest, ConvertFrom) {
  EXPECT_EQ(9,fromString<int>("9"));
  EXPECT_EQ(0,fromString<int>("0"));
  EXPECT_EQ('p',fromString<char>(toString('p')));
  EXPECT_EQ(-1,fromString<char>(toString(char(-1))));
  EXPECT_THROW(fromString<char>("sd"),Dune::Stuff::Exceptions::wrong_input_given);
  EXPECT_EQ(true,fromString<bool>("1"));
  EXPECT_EQ(true,fromString<bool>("true"));
  EXPECT_EQ(false,fromString<bool>("0"));
  EXPECT_EQ(false,fromString<bool>("false"));
  EXPECT_THROW(fromString<int>(""), std::invalid_argument);
}

// Hex, whitespacify, tokenize, stringFromTime tests
TEST(StringTest, Hex) {
//disabled the following test for Intel compiler because it causes compilation failures for no obvious reason
#ifndef __INTEL_COMPILER
  EXPECT_GT(boost::lexical_cast<HexToString<unsigned long> >(cout), 0u);
#endif
  EXPECT_EQ(boost::lexical_cast<HexToString<unsigned long> >("0x00000F"), 15u);
}

TEST(StringTest, Whitespace) {
  EXPECT_EQ("---------", whitespaceify("\t\t\t\t\t\t\t\t\t", '-'));
}

TEST(StringTest, Tokenizer) {
  const string seps(" \t;");
  const string msg("a t\tkk;;g");
  const vector<string> tokens_default     = {"a", "t", "kk", "", "g"};
  const vector<string> tokens_compressed  = {"a", "t", "kk", "g"};
  EXPECT_EQ(tokens_default,    tokenize(msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(tokens_compressed, tokenize(msg, seps, boost::algorithm::token_compress_on));
  const string num_msg("-1 2;;4");
  vector<int> numbers_default = {-1,2,0,4};
  vector<int> numbers_compressed = {-1,2,4};
  EXPECT_EQ(numbers_default,    tokenize<int>(num_msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(numbers_compressed, tokenize<int>(num_msg, seps, boost::algorithm::token_compress_on));
}

TEST(StringTest, TimeString) {
  string ts = stringFromTime(-1);
}

<commit_msg>[test.common_string] added another boolean testcase<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include "main.hxx"

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/logstreams.hh>
#include <vector>

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/fmatrix.hh>
# include <dune/common/densematrix.hh>
# include <dune/common/fvector.hh>
# include <dune/common/dynmatrix.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/densevector.hh>

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/fmatrix.hh>
#include <dune/stuff/la/container/common.hh>
#if HAVE_EIGEN
# include <dune/stuff/la/container/eigen.hh>
#endif
#if HAVE_DUNE_ISTL
# include <dune/stuff/la/container/istl.hh>
#endif

using namespace Dune::Stuff::Common;
using namespace std;

//define types and expected values for the typed tests
template< class MatrixType >
struct MatrixStringTestDouble
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1.000000 2.000000; 3.000000 4.000000]", toString(fromString<MatrixType>("[1.0 2; 3.0 4]")));
    EXPECT_THROW(fromString<MatrixType>("[1 2; 3 4]", 3, 3), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class MatrixType >
struct MatrixStringTestChar
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1 2; 3 4]", toString(fromString<MatrixType>("[1 2; 3 4]")));
    EXPECT_THROW(fromString<MatrixType>("[1 2; 3 4]", 3, 3), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class VectorType >
struct VectorStringTestDouble
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1.000000 2.000000 3.000000]", toString(fromString<VectorType>("[1.0 2 3.0]")));
    EXPECT_THROW(fromString<VectorType>("[1.0 2 3.0]", 4), Dune::Stuff::Exceptions::configuration_error);
  }
};

template< class VectorType >
struct VectorStringTestInt
  : public ::testing::Test
{
  void check() const
  {
    EXPECT_EQ("[1 2 3]", toString(fromString<VectorType>("[1 2 3]")));
    EXPECT_THROW(fromString<VectorType>("[1 2 3]", 4), Dune::Stuff::Exceptions::configuration_error);
  }
};

typedef testing::Types< std::vector< double >
                    , Dune::Stuff::LA::CommonDenseVector< double >
                    , Dune::DynamicVector< double >
                    , Dune::FieldVector< double, 3 >
                    , Dune::Stuff::Common::FieldVector< double, 3 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseVector< double >
                    , Dune::Stuff::LA::EigenMappedDenseVector< double >
#endif
#if HAVE_DUNE_ISTL
                    , Dune::Stuff::LA::IstlDenseVector< double >
#endif
                    > VectorTypesDouble;

typedef testing::Types< std::vector< int >
                    , Dune::Stuff::LA::CommonDenseVector< int >
                    , Dune::DynamicVector< int >
                    , Dune::FieldVector< int, 3 >
                    , Dune::Stuff::Common::FieldVector< int, 3 >
#if HAVE_DUNE_ISTL
                    , Dune::Stuff::LA::IstlDenseVector< int >
#endif
                    > VectorTypesInt;

typedef testing::Types< Dune::DynamicMatrix< double >
                    , Dune::Stuff::LA::CommonDenseMatrix< double >
                    , Dune::Stuff::Common::FieldMatrix< double, 2, 2 >
                    , Dune::FieldMatrix< double, 2, 2 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseMatrix< double >
#endif
                    > MatrixTypesDouble;

typedef testing::Types< Dune::DynamicMatrix< char >
                    , Dune::Stuff::LA::CommonDenseMatrix< char >
                    , Dune::Stuff::Common::FieldMatrix< char, 2, 2 >
                    , Dune::FieldMatrix< char, 2, 2 >
#if HAVE_EIGEN
                    , Dune::Stuff::LA::EigenDenseMatrix< char >
#endif
                    > MatrixTypesChar;

// fromString/toString tests for vector and matrix types
TYPED_TEST_CASE(MatrixStringTestDouble, MatrixTypesDouble);
TYPED_TEST(MatrixStringTestDouble, CheckDouble) {
  this->check();
}

TYPED_TEST_CASE(MatrixStringTestChar, MatrixTypesChar);
TYPED_TEST(MatrixStringTestChar, CheckChar) {
  this->check();
}

TYPED_TEST_CASE(VectorStringTestDouble, VectorTypesDouble);
TYPED_TEST(VectorStringTestDouble, CheckDouble) {
  this->check();
}

TYPED_TEST_CASE(VectorStringTestInt, VectorTypesInt);
TYPED_TEST(VectorStringTestInt, CheckInt) {
  this->check();
}

// Additional fromString/toString tests
TEST(StringTest, ConvertTo) {
  EXPECT_EQ("9",toString(fromString<int>("9")));
  EXPECT_EQ("P",toString(fromString<char>("P")));
  EXPECT_EQ(double(0.1),
            fromString<double>(toString<double>(0.1)));
  EXPECT_EQ("0.100006",
            toString(fromString<double>("0.1000055511151231257827021181583404541015625")));
  EXPECT_EQ("1",toString(fromString<bool>("1")));
  EXPECT_EQ("0",toString(fromString<bool>("0")));
  EXPECT_EQ("-1",toString(fromString<long>("-1")));
}

TEST(StringTest, ConvertFrom) {
  EXPECT_EQ(9,fromString<int>("9"));
  EXPECT_EQ(0,fromString<int>("0"));
  EXPECT_EQ('p',fromString<char>(toString('p')));
  EXPECT_EQ(-1,fromString<char>(toString(char(-1))));
  EXPECT_THROW(fromString<char>("sd"),Dune::Stuff::Exceptions::wrong_input_given);
  EXPECT_EQ(true,fromString<bool>("1"));
  EXPECT_EQ(true,fromString<bool>("true"));
  EXPECT_EQ(true,fromString<bool>("True"));
  EXPECT_EQ(false,fromString<bool>("0"));
  EXPECT_EQ(false,fromString<bool>("false"));
  EXPECT_EQ(false,fromString<bool>("False"));
  EXPECT_THROW(fromString<int>(""), std::invalid_argument);
}

// Hex, whitespacify, tokenize, stringFromTime tests
TEST(StringTest, Hex) {
//disabled the following test for Intel compiler because it causes compilation failures for no obvious reason
#ifndef __INTEL_COMPILER
  EXPECT_GT(boost::lexical_cast<HexToString<unsigned long> >(cout), 0u);
#endif
  EXPECT_EQ(boost::lexical_cast<HexToString<unsigned long> >("0x00000F"), 15u);
}

TEST(StringTest, Whitespace) {
  EXPECT_EQ("---------", whitespaceify("\t\t\t\t\t\t\t\t\t", '-'));
}

TEST(StringTest, Tokenizer) {
  const string seps(" \t;");
  const string msg("a t\tkk;;g");
  const vector<string> tokens_default     = {"a", "t", "kk", "", "g"};
  const vector<string> tokens_compressed  = {"a", "t", "kk", "g"};
  EXPECT_EQ(tokens_default,    tokenize(msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(tokens_compressed, tokenize(msg, seps, boost::algorithm::token_compress_on));
  const string num_msg("-1 2;;4");
  vector<int> numbers_default = {-1,2,0,4};
  vector<int> numbers_compressed = {-1,2,4};
  EXPECT_EQ(numbers_default,    tokenize<int>(num_msg, seps, boost::algorithm::token_compress_off));
  EXPECT_EQ(numbers_compressed, tokenize<int>(num_msg, seps, boost::algorithm::token_compress_on));
}

TEST(StringTest, TimeString) {
  string ts = stringFromTime(-1);
}

<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

using namespace std;

/**
 * Given a triangle, find the minimum path sum from top to bottom.
 * Each step you may move to adjacent numbers on the row below.
 *
 * For example, given the following triangle
 *   [
 *        [2],
 *       [3,4],
 *      [6,5,7],
 *     [4,1,8,3]
 *   ]
 * The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
 * */

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        for(int i = triangle.size() - 2; i != 0; i--) {
            for(int j = 0; j < i + 1; j++) {
                triangle[i][j] = min(triangle[i][j + 1], triangle[i + 1][j + 1]) + triangle[i][j];
            }
        }

        return triangle[0][0];
    }
};<commit_msg>fix bugs<commit_after>#include <iostream>
#include <vector>

using namespace std;

/**
 * Given a triangle, find the minimum path sum from top to bottom.
 * Each step you may move to adjacent numbers on the row below.
 *
 * For example, given the following triangle
 *   [
 *        [2],
 *       [3,4],
 *      [6,5,7],
 *     [4,1,8,3]
 *   ]
 * The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
 *
 * 状态方程: f[j][j]表示从(i, j)出发,路径的最小和.
 *      f[i][j] = min(f[i + 1][j], f[i + 1][j + 1]) + f[i][j];
 * */

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        for(int i = triangle.size() - 2; i != 0; i--) {
            for(int j = 0; j < i + 1; j++) {
                triangle[i][j] = min(triangle[i + 1][j], triangle[i + 1][j + 1]) + triangle[i][j];
            }
        }

        return triangle[0][0];
    }
};<|endoftext|>


<commit_before>#include "smoother.h"
#include "functions.h"

namespace {

const int kLookupSize = 1024;

double my_hard(double x, double a, double) {
  return func_hard(x, a);
}

typedef double (*SigmoidFunc)(double, double, double);
SigmoidFunc GetFunc(Sigmoid s) {
  switch (s) {
    case SIGMOID_HARD: return &my_hard;
    case SIGMOID_LINEAR: return &func_linear;
    case SIGMOID_HERMITE: return &func_hermite;
    case SIGMOID_SIN: return &func_sin;
    default:
    case SIGMOID_SMOOTH: return &func_smooth;
  }
}

double mix(double x, double y, double m) {
  return x + m * (y - x);
}

double sigmoid_ab(SigmoidFunc f, double sn, double x, double a, double b) {
  return (*f)(x, a, sn)*(1.0 - (*f)(x, b, sn));
}

double sigmoid_mix(SigmoidFunc f, double sm, double x, double y, double m) {
  return x + (*f)(m, 0.5, sm) * (y - x);
}

double clamp01(double x) {
  return x > 1.0 ? 1.0 : x < 0.0 ? 0.0 : x;
}

}  // namespace

Smoother::Smoother(const pp::Size& size, const SmootherConfig& config)
    : size_(size),
      config_(config),
      dirty_(true),
      lookup_(pp::Size(kLookupSize, kLookupSize)) {
}

void Smoother::SetConfig(const SmootherConfig& config) {
  config_ = config;
  dirty_ = true;
}

void Smoother::Apply(const AlignedReals& buf1, const AlignedReals& buf2,
                     AlignedReals* out) const {
  assert(!dirty_);
  switch (config_.timestep.type) {
    default:
    case TIMESTEP_DISCRETE:
      Apply_Discrete(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH1:
      Apply_Smooth1(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH2:
      Apply_Smooth2(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH3:
      Apply_Smooth3(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH4:
      Apply_Smooth4(buf1.data(), buf2.data(), out->data());
      break;
  }
}

void Smoother::MakeLookup() {
  for (int i = 0; i < kLookupSize; ++i) {
    for (int j = 0; j < kLookupSize; ++j) {
      double n = static_cast<double>(i)/kLookupSize;
      double m = static_cast<double>(j)/kLookupSize;
      lookup_[i * kLookupSize + j] = clamp01(CalculateValue(n, m));
    }
  }

  dirty_ = false;
}

double Smoother::CalculateValue(double n, double m) const {
  SigmoidFunc ab_func = GetFunc(config_.sigmoid);
  SigmoidFunc mix_func = GetFunc(config_.mix);

  switch (config_.mode) {
    case SIGMOID_MODE_1:
      return mix(
          sigmoid_ab(ab_func, config_.sn, n, config_.b1, config_.b2),
          sigmoid_ab(ab_func, config_.sn, n, config_.d1, config_.d2),
          m);
    case SIGMOID_MODE_2:
      return sigmoid_mix(
          mix_func,
          config_.sm,
          sigmoid_ab(ab_func, config_.sn, n, config_.b1, config_.b2),
          sigmoid_ab(ab_func, config_.sn, n, config_.d1, config_.d2),
          m);
    case SIGMOID_MODE_3:
      return sigmoid_ab(
          ab_func,
          config_.sn,
          n,
          mix(config_.b1, config_.d1, m),
          mix(config_.b2, config_.d2, m));
    default:
    case SIGMOID_MODE_4:
      return sigmoid_ab(
          ab_func,
          config_.sn,
          n,
          sigmoid_mix(mix_func, config_.sm, config_.b1, config_.d1, m),
          sigmoid_mix(mix_func, config_.sm, config_.b2, config_.d2, m));
  }
}

double Smoother::Lookup(double n, double m) const {
  return lookup_[static_cast<int>(n * kLookupSize) * kLookupSize +
    static_cast<int>(m * kLookupSize)];
}

void Smoother::Apply_Discrete(const double* an, const double* am,
                              double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    na[i] = Lookup(an[i], am[i]);
  }
}

void Smoother::Apply_Smooth1(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(na[i] + config_.timestep.dt * (2 * f - 1));
  }
}

void Smoother::Apply_Smooth2(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(na[i] + config_.timestep.dt * (f - na[i]));
  }
}

void Smoother::Apply_Smooth3(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(am[i] + config_.timestep.dt * (2 * f - 1));
  }
}

void Smoother::Apply_Smooth4(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(am[i] + config_.timestep.dt * (f - am[i]));
  }
}
<commit_msg>reduced smoother lookup size<commit_after>#include "smoother.h"
#include "functions.h"

namespace {

const int kLookupSize = 512;

double my_hard(double x, double a, double) {
  return func_hard(x, a);
}

typedef double (*SigmoidFunc)(double, double, double);
SigmoidFunc GetFunc(Sigmoid s) {
  switch (s) {
    case SIGMOID_HARD: return &my_hard;
    case SIGMOID_LINEAR: return &func_linear;
    case SIGMOID_HERMITE: return &func_hermite;
    case SIGMOID_SIN: return &func_sin;
    default:
    case SIGMOID_SMOOTH: return &func_smooth;
  }
}

double mix(double x, double y, double m) {
  return x + m * (y - x);
}

double sigmoid_ab(SigmoidFunc f, double sn, double x, double a, double b) {
  return (*f)(x, a, sn)*(1.0 - (*f)(x, b, sn));
}

double sigmoid_mix(SigmoidFunc f, double sm, double x, double y, double m) {
  return x + (*f)(m, 0.5, sm) * (y - x);
}

double clamp01(double x) {
  return x > 1.0 ? 1.0 : x < 0.0 ? 0.0 : x;
}

}  // namespace

Smoother::Smoother(const pp::Size& size, const SmootherConfig& config)
    : size_(size),
      config_(config),
      dirty_(true),
      lookup_(pp::Size(kLookupSize, kLookupSize)) {
}

void Smoother::SetConfig(const SmootherConfig& config) {
  config_ = config;
  dirty_ = true;
}

void Smoother::Apply(const AlignedReals& buf1, const AlignedReals& buf2,
                     AlignedReals* out) const {
  assert(!dirty_);
  switch (config_.timestep.type) {
    default:
    case TIMESTEP_DISCRETE:
      Apply_Discrete(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH1:
      Apply_Smooth1(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH2:
      Apply_Smooth2(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH3:
      Apply_Smooth3(buf1.data(), buf2.data(), out->data());
      break;
    case TIMESTEP_SMOOTH4:
      Apply_Smooth4(buf1.data(), buf2.data(), out->data());
      break;
  }
}

void Smoother::MakeLookup() {
  for (int i = 0; i < kLookupSize; ++i) {
    for (int j = 0; j < kLookupSize; ++j) {
      double n = static_cast<double>(i)/kLookupSize;
      double m = static_cast<double>(j)/kLookupSize;
      lookup_[i * kLookupSize + j] = clamp01(CalculateValue(n, m));
    }
  }

  dirty_ = false;
}

double Smoother::CalculateValue(double n, double m) const {
  SigmoidFunc ab_func = GetFunc(config_.sigmoid);
  SigmoidFunc mix_func = GetFunc(config_.mix);

  switch (config_.mode) {
    case SIGMOID_MODE_1:
      return mix(
          sigmoid_ab(ab_func, config_.sn, n, config_.b1, config_.b2),
          sigmoid_ab(ab_func, config_.sn, n, config_.d1, config_.d2),
          m);
    case SIGMOID_MODE_2:
      return sigmoid_mix(
          mix_func,
          config_.sm,
          sigmoid_ab(ab_func, config_.sn, n, config_.b1, config_.b2),
          sigmoid_ab(ab_func, config_.sn, n, config_.d1, config_.d2),
          m);
    case SIGMOID_MODE_3:
      return sigmoid_ab(
          ab_func,
          config_.sn,
          n,
          mix(config_.b1, config_.d1, m),
          mix(config_.b2, config_.d2, m));
    default:
    case SIGMOID_MODE_4:
      return sigmoid_ab(
          ab_func,
          config_.sn,
          n,
          sigmoid_mix(mix_func, config_.sm, config_.b1, config_.d1, m),
          sigmoid_mix(mix_func, config_.sm, config_.b2, config_.d2, m));
  }
}

double Smoother::Lookup(double n, double m) const {
  return lookup_[static_cast<int>(n * kLookupSize) * kLookupSize +
    static_cast<int>(m * kLookupSize)];
}

void Smoother::Apply_Discrete(const double* an, const double* am,
                              double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    na[i] = Lookup(an[i], am[i]);
  }
}

void Smoother::Apply_Smooth1(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(na[i] + config_.timestep.dt * (2 * f - 1));
  }
}

void Smoother::Apply_Smooth2(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(na[i] + config_.timestep.dt * (f - na[i]));
  }
}

void Smoother::Apply_Smooth3(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(am[i] + config_.timestep.dt * (2 * f - 1));
  }
}

void Smoother::Apply_Smooth4(const double* an, const double* am,
                             double* na) const {
  int count = size_.width() * size_.height();
  for (int i = 0; i < count; ++i) {
    double f = Lookup(an[i], am[i]);
    na[i] = clamp01(am[i] + config_.timestep.dt * (f - am[i]));
  }
}
<|endoftext|>


<commit_before>#ifdef WIN32
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
    #include <conio.h>
    #include <winsock2.h>
typedef  int socklen_t;

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#endif

#include <iostream>
#include <fstream>
#include <deque>
#include <vector>
#include <ctime>
#include <event.h>
#include <sys/stat.h>
#include <zlib.h>
#include "logger.h"
#include "constants.h"

#include "tools.h"

#include "user.h"
#include "map.h"
#include "chat.h"
#include "nbt.h"
#include "packets.h"

extern int setnonblock(int fd);

void buf_write_callback(struct bufferevent *bev, void *arg)
{
}

void buf_error_callback(struct bufferevent *bev, short what, void *arg)
{
  User *client = (User *)arg;
  bufferevent_free(client->buf_ev);

#ifdef WIN32
  closesocket(client->fd);
#else
  close(client->fd);
#endif

  remUser(client->fd);
}

void buf_read_callback(struct bufferevent *incoming, void *arg)
{
  uint32 i = 0;

  User *user=(User *)arg;

  int read = 1;

  uint8 *buf = new uint8[2048];

  //Push data to buffer
  while(read)
  {
    if(read = bufferevent_read(incoming, buf, 2048))
    {
      for(int i = 0;i<read;i++)
      {
        user->buffer.push_back(buf[i]);
      }
    }
  }

  delete [] buf;

  while(user->buffer.size()>0)
  {
    // If not waiting more data
    if(!user->waitForData)
    {
      user->action = user->buffer.front();
      user->buffer.pop_front();
      printf("Action: 0x%x\n", user->action);
    }
    else
    {
       user->waitForData = false;
    }

    //Variable len package
    if(PacketHandler::get().packets[user->action].len==PACKET_VARIABLE_LEN)
    {
      //Call specific function
      int (PacketHandler::*varLenFunction)(User *)=PacketHandler::get().packets[user->action].varLenFunction;
      int curpos=(PacketHandler::get().*varLenFunction)(user);
      if(curpos==PACKET_NEED_MORE_DATA)
      {
        user->waitForData = true;
        return;
      }
    }
    if(PacketHandler::get().packets[user->action].len==PACKET_DOES_NOT_EXIST)
    {
      printf("Unknown action: 0x%x\n", user->action);
      bufferevent_free(user->buf_ev);
      #ifdef WIN32
        closesocket(user->fd);
      #else
        close(user->fd);
      #endif
      remUser(user->fd);
    }
    else
    {
      if(user->buffer.size()<PacketHandler::get().packets[user->action].len)
      {
        user->waitForData = true;
        return;
      }
      //Store data to dynamic array
      uint8 *data = new uint8 [PacketHandler::get().packets[user->action].len];
      if(PacketHandler::get().packets[user->action].len)
      {
        std::copy(user->buffer.begin(),user->buffer.begin()+PacketHandler::get().packets[user->action].len,data);
      }

      //Call specific function
      void (PacketHandler::*function)(uint8 *, User *)=PacketHandler::get().packets[user->action].function;
      (PacketHandler::get().*function)(data,user);

      //Release data array
      delete [] data;

      //Package completely received, remove from buffer
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+PacketHandler::get().packets[user->action].len);
    }

  } //End while

}

void accept_callback(int fd,
                     short ev,
                     void *arg)
{
  int client_fd;
  struct sockaddr_in client_addr;
  socklen_t client_len = sizeof(client_addr);

  client_fd = accept(fd,
                     (struct sockaddr *)&client_addr,
                     &client_len);
  if (client_fd < 0)
    {
      LOG("Client: accept() failed");
      return;
    }
  User *client = addUser(client_fd,generateEID());
  setnonblock(client_fd);

  client->buf_ev = bufferevent_new(client_fd,
                                   buf_read_callback,
                                   buf_write_callback,
                                   buf_error_callback,
                                   client);

  bufferevent_enable(client->buf_ev, EV_READ);
}
<commit_msg>disabled socket debug printing<commit_after>#ifdef WIN32
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
    #include <conio.h>
    #include <winsock2.h>
typedef  int socklen_t;

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#endif

#include <iostream>
#include <fstream>
#include <deque>
#include <vector>
#include <ctime>
#include <event.h>
#include <sys/stat.h>
#include <zlib.h>
#include "logger.h"
#include "constants.h"

#include "tools.h"

#include "user.h"
#include "map.h"
#include "chat.h"
#include "nbt.h"
#include "packets.h"

extern int setnonblock(int fd);

void buf_write_callback(struct bufferevent *bev, void *arg)
{
}

void buf_error_callback(struct bufferevent *bev, short what, void *arg)
{
  User *client = (User *)arg;
  bufferevent_free(client->buf_ev);

#ifdef WIN32
  closesocket(client->fd);
#else
  close(client->fd);
#endif

  remUser(client->fd);
}

void buf_read_callback(struct bufferevent *incoming, void *arg)
{
  uint32 i = 0;

  User *user=(User *)arg;

  int read = 1;

  uint8 *buf = new uint8[2048];

  //Push data to buffer
  while(read)
  {
    if(read = bufferevent_read(incoming, buf, 2048))
    {
      for(int i = 0;i<read;i++)
      {
        user->buffer.push_back(buf[i]);
      }
    }
  }

  delete [] buf;

  while(user->buffer.size()>0)
  {
    // If not waiting more data
    if(!user->waitForData)
    {
      user->action = user->buffer.front();
      user->buffer.pop_front();
      //printf("Action: 0x%x\n", user->action);
    }
    else
    {
       user->waitForData = false;
    }

    //Variable len package
    if(PacketHandler::get().packets[user->action].len==PACKET_VARIABLE_LEN)
    {
      //Call specific function
      int (PacketHandler::*varLenFunction)(User *)=PacketHandler::get().packets[user->action].varLenFunction;
      int curpos=(PacketHandler::get().*varLenFunction)(user);
      if(curpos==PACKET_NEED_MORE_DATA)
      {
        user->waitForData = true;
        return;
      }
    }
    if(PacketHandler::get().packets[user->action].len==PACKET_DOES_NOT_EXIST)
    {
      printf("Unknown action: 0x%x\n", user->action);
      bufferevent_free(user->buf_ev);
      #ifdef WIN32
        closesocket(user->fd);
      #else
        close(user->fd);
      #endif
      remUser(user->fd);
    }
    else
    {
      if(user->buffer.size()<PacketHandler::get().packets[user->action].len)
      {
        user->waitForData = true;
        return;
      }
      //Store data to dynamic array
      uint8 *data = new uint8 [PacketHandler::get().packets[user->action].len];
      if(PacketHandler::get().packets[user->action].len)
      {
        std::copy(user->buffer.begin(),user->buffer.begin()+PacketHandler::get().packets[user->action].len,data);
      }

      //Call specific function
      void (PacketHandler::*function)(uint8 *, User *)=PacketHandler::get().packets[user->action].function;
      (PacketHandler::get().*function)(data,user);

      //Release data array
      delete [] data;

      //Package completely received, remove from buffer
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+PacketHandler::get().packets[user->action].len);
    }

  } //End while

}

void accept_callback(int fd,
                     short ev,
                     void *arg)
{
  int client_fd;
  struct sockaddr_in client_addr;
  socklen_t client_len = sizeof(client_addr);

  client_fd = accept(fd,
                     (struct sockaddr *)&client_addr,
                     &client_len);
  if (client_fd < 0)
    {
      LOG("Client: accept() failed");
      return;
    }
  User *client = addUser(client_fd,generateEID());
  setnonblock(client_fd);

  client->buf_ev = bufferevent_new(client_fd,
                                   buf_read_callback,
                                   buf_write_callback,
                                   buf_error_callback,
                                   client);

  bufferevent_enable(client->buf_ev, EV_READ);
}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <iostream>
#include <chrono>
#include <thread>
#include <string>
#include <fstream>
#include <sstream>
#include <getopt.h>

// Set sensible default values for network interface and sampling period
const int DEFAULT_ITERATIONS = 0;
const std::string DEFAULT_NETWORK_INTERFACE = "eth0";
const std::string DEFAULT_LOG_FILE = "";
const int DEFAULT_PERIOD = 1;

namespace {
  /// Internal data structure for command line arguments
  struct CommandLineArguments {
    unsigned long long int iterations = DEFAULT_ITERATIONS;
    std::string log_file = DEFAULT_LOG_FILE;
    std::string network_interface = DEFAULT_NETWORK_INTERFACE;
    int period = DEFAULT_PERIOD;
  };

  /// Internal data structure for statistical data sample
  struct Sample {
    // Timestamp values may be signed
    long long int date = 0;
    long long int steady = 0;

    // All other values are defined as unsigned
    unsigned long long int cpu_user = 0;
    unsigned long long int cpu_nice = 0;
    unsigned long long int cpu_system = 0;
    unsigned long long int cpu_idle = 0;
    unsigned long long int cpu_iowait = 0;
    unsigned long long int cpu_irq = 0;
    unsigned long long int cpu_softirq = 0;
    unsigned long long int cpu_steal = 0;
    unsigned long long int cpu_guest = 0;
    unsigned long long int cpu_guest_nice = 0;
    unsigned long long int memory_total = 0;
    unsigned long long int memory_used = 0;
    unsigned long long int swap_total = 0;
    unsigned long long int swap_used = 0;
    unsigned long long int network_received = 0;
    unsigned long long int network_sent = 0;
  };
}

/// Print usage information
void print_usage(std::ostream& os = std::cerr) {
  os << "usage: sss-mon [-f] [-h] [-i INTERFACE] [-p PERIOD] [LOGFILE]\n"
     << "\n"
     << "sss-mon gathers information on the current CPU load, memory usage, \n"
     << "and network traffic and writes it to stdout or a log file. Once \n"
     << "started, it runs continuously until killed, unless a maximum number\n"
     << "of iterations is specified on the command line.\n"
     << "\n"
     << "positional arguments:\n"
     << "  LOGFILE               Write data to LOGFILE instead of stdout.\n"
     << "\n"
     << "optional arguments:\n"
     << "  -f, --field-names     Print space-separated list of field names\n"
     << "                        to stdout and exit.\n"
     << "  -h, --help            Show this help message and exit.\n"
     << "  -n, --iterations ITERATIONS\n"
     << "                        Number of samples to gather. Must be a \n"
     << "                        non-negative integer value. If set to zero, \n"
     << "                        sss-mon continues indefinitely until killed \n"
     << "                        (default: " << DEFAULT_ITERATIONS << ").\n"
     << "  -i, --network-interface INTERFACE\n"
     << "                        Gather traffic statistics for the given\n"
     << "                        network interface. INTERFACE must be a valid\n"
     << "                        interface in '/proc/net/dev' (default: "
     << DEFAULT_NETWORK_INTERFACE << ").\n"
     << "  -p, --period PERIOD   Set sampling period (in seconds). Must be a\n"
     << "                        positive integer value (default: "
     << DEFAULT_PERIOD << ").\n"
     << "\n"
     << "For each sample, a space-separated list of the following fields is\n"
     << "written to stdout or a log file and terminated by a newline \n"
     << "character (\\n):\n"
     << "  date                  Unix timestamp in milliseconds.\n"
     << "  steady                A steady timestamp (not necessarily since\n"
     << "                        Unix epoch) for robust time-average \n"
     << "                        calculations in microseconds.\n"
     << "  cpu_user              CPU time spent in user mode.\n"
     << "  cpu_nice              CPU time spent in user mode with low \n"
     << "                        priority (nice).\n"
     << "  cpu_system            CPU time spent in system mode.\n"
     << "  cpu_idle              CPU time spent in the idle task.\n"
     << "  cpu_iowait            CPU time waiting for I/O to complete.\n"
     << "  cpu_irq               CPU time servicing interrupts.\n"
     << "  cpu_softirq           CPU time ervicing softirqs.\n"
     << "  cpu_steal             CPU stolen time, which is the time spent in\n"
     << "                        other operating systems when running in a \n"
     << "                        virtualized environment.\n"
     << "  cpu_guest             CPU time spent running a virtual CPU for \n"
     << "                        guest operating systems under the control of\n"
     << "                        the Linux kernel.\n"
     << "  cpu_guest_nice        CPU time spent running a niced guest \n"
     << "                        (virtual CPU for guest operating systems\n"
     << "                        under the control of the Linux kernel).\n"
     << "  memory_total          Total usable RAM (in bytes).\n"
     << "  memory_used           Memory currently in use (in bytes).\n"
     << "  swap_total            Total amount of swap space (in bytes).\n"
     << "  swap_used             Swap space currently in use (in bytes).\n"
     << "  network_received      Total bytes received (in bytes).\n"
     << "  network_sent          Total bytes sent (in bytes).\n"
     << "\n"
     << "The recorded information is gathered from the 'proc' filesystem (see\n"
     << "also 'man proc'). CPU data is from '/proc/stat', memory data is from\n"
     << "'/proc/meminfo', and network data is from '/proc/net/dev'.\n";
  os.flush();
}

/// Parse command line options
CommandLineArguments parse_arguments(int argc, char* argv[]) {
  CommandLineArguments args;

  // Parse option arguments
  while (true) {
    // Create structure with long options
    static struct option long_options[] = {
      {"field-names", no_argument, nullptr, 'f'},
      {"help", no_argument, nullptr, 'h'},
      {"iterations", required_argument, nullptr, 'n'},
      {"network-interface", required_argument, nullptr, 'i'},
      {"period", required_argument, nullptr, 'p'},
      {nullptr, 0, nullptr, 0}
    };

    // Get next argument
    const int c = getopt_long(argc, argv, "fhn:l:i:p:", long_options, nullptr);

    // Exit loop if end of options is reached
    if (c == -1) {
      break;
    }

    // Handle argument
    switch (c) {
      // Print field names and quit
      case 'f':
        {
          std::cout << "date"
                    << " steady"
                    << " cpu_user"
                    << " cpu_nice"
                    << " cpu_system"
                    << " cpu_idle"
                    << " cpu_iowait"
                    << " cpu_irq"
                    << " cpu_softirq"
                    << " cpu_steal"
                    << " cpu_guest"
                    << " cpu_guest_nice"
                    << " memory_total"
                    << " memory_used"
                    << " swap_total"
                    << " swap_used"
                    << " network_received"
                    << " network_sent"
                    << std::endl;
          exit(0);
        }

      // Show usage information and quit
      case 'h':
        {
          print_usage(std::cout);
          exit(0);
        }

      // Set number of iterations
      case 'n':
        {
          // Try to parse argument as integer
          std::istringstream arg(optarg);
          arg >> args.iterations;

          // Handle bad arguments
          if (arg.fail()
              || arg.get() != std::istringstream::traits_type::eof()) {
            std::cerr << "error: argument to '-n|--iterations' (" << optarg
                      << ") is not an integer" << std::endl;
            exit(2);
          }
          break;
        }

      // Set network interface
      case 'i':
        {
          args.network_interface = optarg;
          break;
        }

      // Set sampling period
      case 'p':
        {
          // Try to parse argument as integer
          std::istringstream arg(optarg);
          arg >> args.period;

          // Handle bad arguments
          if (arg.fail()
              || arg.get() != std::istringstream::traits_type::eof()) {
            std::cerr << "error: argument to '-p|--period' (" << optarg
                      << ") is not an integer" << std::endl;
            exit(2);
          } else if (args.period < 1) {
            std::cerr << "error: argument to '-p|--period' (" << optarg
                      << ") is less than one" << std::endl;
            exit(2);
          }
          break;
        }

      // If an unknown/bad argument was encountered, show usage and quit
      case '?':
        {
          print_usage();
          exit(2);
          break;
        }

      // The default should never be reached and signifies an unknown problem
      default:
        {
          std::cerr << "error: unknown error while parsing command line "
                    << "arguments" << std::endl;
          exit(1);
        }
    }
  }

  // Parse for optional log file
  if (optind < argc) {
    args.log_file = argv[optind];
    if (args.log_file == "") {
      std::cerr << "error: log file name is empty" << std::endl;
      exit(2);
    }
  }

  return args;
}

/// Gather data sample
Sample sample(const std::string& network_interface) {
  // Create sample object
  Sample s{};

  // Current point in time as reference
  s.date = std::chrono::duration_cast<std::chrono::milliseconds>(
      std::chrono::system_clock::now().time_since_epoch()).count();

  // Steady clock timestamp for robust time-average calculation
  s.steady = std::chrono::duration_cast<std::chrono::microseconds>(
      std::chrono::steady_clock::now().time_since_epoch()).count();

  // CPU statistics
  {
    // Open file
    std::ifstream in("/proc/stat");
    std::string line;

    // Read first line with cumulated values
    std::getline(in, line);
    std::istringstream l(line);

    // Read first word and throw it away (will probably be 'cpu')
    std::string dump;
    l >> dump;

    // Read and convert CPU statistics
    l >> s.cpu_user;
    l >> s.cpu_nice;
    l >> s.cpu_system;
    l >> s.cpu_idle;
    l >> s.cpu_iowait;
    l >> s.cpu_irq;
    l >> s.cpu_softirq;
    l >> s.cpu_steal;
    l >> s.cpu_guest;
    l >> s.cpu_guest_nice;
  }

  // Memory usage
  {
    // Open file
    std::ifstream in("/proc/meminfo");

    // Read file line by line and parse each line for relevant data
    unsigned long long int memory_free = 0;
    unsigned long long int buffers = 0;
    unsigned long long int cached = 0;
    unsigned long long int swap_free = 0;
    for (std::string line; std::getline(in, line); ) {
      // Extract data type
      std::istringstream l(line);
      std::string type;
      l >> type;

      // Store data depending on type
      if (type == "MemTotal:") {
        l >> s.memory_total;
      } else if (type == "MemFree:") {
        l >> memory_free;
      } else if (type == "Buffers:") {
        l >> buffers;
      } else if (type == "Cached:") {
        l >> cached;
      } else if (type == "SwapTotal:") {
        l >> s.swap_total;
      } else if (type == "SwapFree:") {
        l >> swap_free;
      }
    }

    // Calculate used memory and used swap space
    s.memory_used = s.memory_total - memory_free - buffers - cached;
    s.swap_used = s.swap_total - swap_free;

    // Convert values from kibibytes to bytes
    s.memory_total *= 1024;
    s.memory_used *= 1024;
    s.swap_total *= 1024;
    s.swap_used *= 1024;
  }

  // Bytes received/sent on network interface
  {
    // Open file
    std::ifstream in("/proc/net/dev");

    // Read file line by line until selected interface is found
    for (std::string line; std::getline(in, line); ) {
      // Extract interface name
      std::istringstream l(line);
      std::string interface;
      l >> interface;

      // If specified interface is found, read data and exit loop
      if (interface == network_interface + ":") {
        // Bytes received is the 2nd value
        l >> s.network_received;

        // Bytes sent is the 10th value
        for (int i = 0; i < 8; i++) {
          l >> s.network_sent;
        }
        break;
      }
    }
  }

  return s;
}

int main(int argc, char* argv[]) {
  // Parse command line arguments
  const auto args = parse_arguments(argc, argv);

  // Open log file if specified
  std::ofstream log_file;
  if (args.log_file != "") {
    log_file.open(args.log_file, std::ios::out | std::ios::app);
    if (!log_file.good()) {
      std::cerr << "error: could not open log file '" << args.log_file
                << "' for writing" << std::endl;
      std::exit(1);
    }
    std::cout << "Writing data to '" << args.log_file << "'..." << std::endl;
  }

  // Set output stream to use
  std::ostream os(args.log_file == "" ? std::cout.rdbuf() : log_file.rdbuf());

  // Begin main loop
  for (unsigned long long int iteration = 0;;) {
    // Obtain sample
    const Sample s = sample(args.network_interface);

    // Print all data to stdout
    os << s.date
       << " " << s.steady
       << " " << s.cpu_user
       << " " << s.cpu_nice
       << " " << s.cpu_system
       << " " << s.cpu_idle
       << " " << s.cpu_iowait
       << " " << s.cpu_irq
       << " " << s.cpu_softirq
       << " " << s.cpu_steal
       << " " << s.cpu_guest
       << " " << s.cpu_guest_nice
       << " " << s.memory_total
       << " " << s.memory_used
       << " " << s.swap_total
       << " " << s.swap_used
       << " " << s.network_received
       << " " << s.network_sent
       << std::endl;

    // Increment interation counter
    iteration++;

    // Exit main loop if maximum number of iterations is reached
    if (args.iterations > 0 && iteration >= args.iterations) {
      break;
    }

    // Sleep until next sample time
    std::this_thread::sleep_for(std::chrono::seconds(args.period));
  }
}
<commit_msg>Add CPU load data<commit_after>#include <cstdlib>
#include <iostream>
#include <chrono>
#include <thread>
#include <string>
#include <fstream>
#include <sstream>
#include <getopt.h>

// Set sensible default values for network interface and sampling period
const int DEFAULT_ITERATIONS = 0;
const std::string DEFAULT_NETWORK_INTERFACE = "eth0";
const std::string DEFAULT_LOG_FILE = "";
const int DEFAULT_PERIOD = 1;

namespace {
  /// Internal data structure for command line arguments
  struct CommandLineArguments {
    unsigned long long int iterations = DEFAULT_ITERATIONS;
    std::string log_file = DEFAULT_LOG_FILE;
    std::string network_interface = DEFAULT_NETWORK_INTERFACE;
    int period = DEFAULT_PERIOD;
  };

  /// Internal data structure for statistical data sample
  struct Sample {
    // Timestamp values may be signed
    long long int date = 0;
    long long int steady = 0;

    // All other values are defined as unsigned
    double cpu_load_1m = 0.0;
    double cpu_load_5m = 0.0;
    double cpu_load_15m = 0.0;
    unsigned long long int cpu_time_user = 0;
    unsigned long long int cpu_time_nice = 0;
    unsigned long long int cpu_time_system = 0;
    unsigned long long int cpu_time_idle = 0;
    unsigned long long int cpu_time_iowait = 0;
    unsigned long long int cpu_time_irq = 0;
    unsigned long long int cpu_time_softirq = 0;
    unsigned long long int cpu_time_steal = 0;
    unsigned long long int cpu_time_guest = 0;
    unsigned long long int cpu_time_guest_nice = 0;
    unsigned long long int memory_total = 0;
    unsigned long long int memory_used = 0;
    unsigned long long int swap_total = 0;
    unsigned long long int swap_used = 0;
    unsigned long long int network_received = 0;
    unsigned long long int network_sent = 0;
  };
}

/// Print usage information
void print_usage(std::ostream& os = std::cerr) {
  os << "usage: sss-mon [-f] [-h] [-i INTERFACE] [-p PERIOD] [LOGFILE]\n"
     << "\n"
     << "sss-mon gathers information on the current CPU load, memory usage, \n"
     << "and network traffic and writes it to stdout or a log file. Once \n"
     << "started, it runs continuously until killed, unless a maximum number\n"
     << "of iterations is specified on the command line.\n"
     << "\n"
     << "positional arguments:\n"
     << "  LOGFILE               Write data to LOGFILE instead of stdout.\n"
     << "\n"
     << "optional arguments:\n"
     << "  -f, --field-names     Print space-separated list of field names\n"
     << "                        to stdout and exit.\n"
     << "  -h, --help            Show this help message and exit.\n"
     << "  -n, --iterations ITERATIONS\n"
     << "                        Number of samples to gather. Must be a \n"
     << "                        non-negative integer value. If set to zero, \n"
     << "                        sss-mon continues indefinitely until killed \n"
     << "                        (default: " << DEFAULT_ITERATIONS << ").\n"
     << "  -i, --network-interface INTERFACE\n"
     << "                        Gather traffic statistics for the given\n"
     << "                        network interface. INTERFACE must be a valid\n"
     << "                        interface in '/proc/net/dev' (default: "
     << DEFAULT_NETWORK_INTERFACE << ").\n"
     << "  -p, --period PERIOD   Set sampling period (in seconds). Must be a\n"
     << "                        positive integer value (default: "
     << DEFAULT_PERIOD << ").\n"
     << "\n"
     << "For each sample, a space-separated list of the following fields is\n"
     << "written to stdout or a log file and terminated by a newline \n"
     << "character (\\n):\n"
     << "  date                  Unix timestamp in milliseconds.\n"
     << "  steady                A steady timestamp (not necessarily since\n"
     << "                        Unix epoch) for robust time-average \n"
     << "                        calculations in microseconds.\n"
     << "  cpu_load_1m           CPU load average (1 minute average).\n"
     << "  cpu_load_5m           CPU load average (5 minute average).\n"
     << "  cpu_load_15m          CPU load average (15 minute average).\n"
     << "  cpu_time_user         CPU time spent in user mode.\n"
     << "  cpu_time_nice         CPU time spent in user mode with low \n"
     << "                        priority (nice).\n"
     << "  cpu_time_system       CPU time spent in system mode.\n"
     << "  cpu_time_idle         CPU time spent in the idle task.\n"
     << "  cpu_time_iowait       CPU time waiting for I/O to complete.\n"
     << "  cpu_time_irq          CPU time servicing interrupts.\n"
     << "  cpu_time_softirq      CPU time ervicing softirqs.\n"
     << "  cpu_time_steal        CPU stolen time, which is the time spent in\n"
     << "                        other operating systems when running in a \n"
     << "                        virtualized environment.\n"
     << "  cpu_time_guest        CPU time spent running a virtual CPU for \n"
     << "                        guest operating systems under the control of\n"
     << "                        the Linux kernel.\n"
     << "  cpu_time_guest_nice   CPU time spent running a niced guest \n"
     << "                        (virtual CPU for guest operating systems\n"
     << "                        under the control of the Linux kernel).\n"
     << "  memory_total          Total usable RAM (in bytes).\n"
     << "  memory_used           Memory currently in use (in bytes).\n"
     << "  swap_total            Total amount of swap space (in bytes).\n"
     << "  swap_used             Swap space currently in use (in bytes).\n"
     << "  network_received      Total bytes received (in bytes).\n"
     << "  network_sent          Total bytes sent (in bytes).\n"
     << "\n"
     << "The recorded information is gathered from the 'proc' filesystem (see\n"
     << "also 'man proc'). CPU data is from '/proc/loadavg' and '/proc/stat',\n"
     << "memory data is from '/proc/meminfo', and network data is from\n"
     << "'/proc/net/dev'.\n";
  os.flush();
}

/// Parse command line options
CommandLineArguments parse_arguments(int argc, char* argv[]) {
  CommandLineArguments args;

  // Parse option arguments
  while (true) {
    // Create structure with long options
    static struct option long_options[] = {
      {"field-names", no_argument, nullptr, 'f'},
      {"help", no_argument, nullptr, 'h'},
      {"iterations", required_argument, nullptr, 'n'},
      {"network-interface", required_argument, nullptr, 'i'},
      {"period", required_argument, nullptr, 'p'},
      {nullptr, 0, nullptr, 0}
    };

    // Get next argument
    const int c = getopt_long(argc, argv, "fhn:l:i:p:", long_options, nullptr);

    // Exit loop if end of options is reached
    if (c == -1) {
      break;
    }

    // Handle argument
    switch (c) {
      // Print field names and quit
      case 'f':
        {
          std::cout << "date"
                    << " steady"
                    << " cpu_load_1m"
                    << " cpu_load_5m"
                    << " cpu_load_15m"
                    << " cpu_time_user"
                    << " cpu_time_nice"
                    << " cpu_time_system"
                    << " cpu_time_idle"
                    << " cpu_time_iowait"
                    << " cpu_time_irq"
                    << " cpu_time_softirq"
                    << " cpu_time_steal"
                    << " cpu_time_guest"
                    << " cpu_time_guest_nice"
                    << " memory_total"
                    << " memory_used"
                    << " swap_total"
                    << " swap_used"
                    << " network_received"
                    << " network_sent"
                    << std::endl;
          exit(0);
        }

      // Show usage information and quit
      case 'h':
        {
          print_usage(std::cout);
          exit(0);
        }

      // Set number of iterations
      case 'n':
        {
          // Try to parse argument as integer
          std::istringstream arg(optarg);
          arg >> args.iterations;

          // Handle bad arguments
          if (arg.fail()
              || arg.get() != std::istringstream::traits_type::eof()) {
            std::cerr << "error: argument to '-n|--iterations' (" << optarg
                      << ") is not an integer" << std::endl;
            exit(2);
          }
          break;
        }

      // Set network interface
      case 'i':
        {
          args.network_interface = optarg;
          break;
        }

      // Set sampling period
      case 'p':
        {
          // Try to parse argument as integer
          std::istringstream arg(optarg);
          arg >> args.period;

          // Handle bad arguments
          if (arg.fail()
              || arg.get() != std::istringstream::traits_type::eof()) {
            std::cerr << "error: argument to '-p|--period' (" << optarg
                      << ") is not an integer" << std::endl;
            exit(2);
          } else if (args.period < 1) {
            std::cerr << "error: argument to '-p|--period' (" << optarg
                      << ") is less than one" << std::endl;
            exit(2);
          }
          break;
        }

      // If an unknown/bad argument was encountered, show usage and quit
      case '?':
        {
          print_usage();
          exit(2);
          break;
        }

      // The default should never be reached and signifies an unknown problem
      default:
        {
          std::cerr << "error: unknown error while parsing command line "
                    << "arguments" << std::endl;
          exit(1);
        }
    }
  }

  // Parse for optional log file
  if (optind < argc) {
    args.log_file = argv[optind];
    if (args.log_file == "") {
      std::cerr << "error: log file name is empty" << std::endl;
      exit(2);
    }
  }

  return args;
}

/// Gather data sample
Sample sample(const std::string& network_interface) {
  // Create sample object
  Sample s{};

  // Current point in time as reference
  s.date = std::chrono::duration_cast<std::chrono::milliseconds>(
      std::chrono::system_clock::now().time_since_epoch()).count();

  // Steady clock timestamp for robust time-average calculation
  s.steady = std::chrono::duration_cast<std::chrono::microseconds>(
      std::chrono::steady_clock::now().time_since_epoch()).count();

  // CPU load averages
  {
    // Open file
    std::ifstream in("/proc/loadavg");

    // Read line
    std::string line;
    std::getline(in, line);
    std::istringstream l(line);

    // Read and convert CPU load averages
    l >> s.cpu_load_1m;
    l >> s.cpu_load_5m;
    l >> s.cpu_load_15m;
  }

  // CPU statistics
  {
    // Open file
    std::ifstream in("/proc/stat");

    // Read first line with cumulated values
    std::string line;
    std::getline(in, line);
    std::istringstream l(line);

    // Read first word and throw it away (will probably be 'cpu')
    std::string dump;
    l >> dump;

    // Read and convert CPU statistics
    l >> s.cpu_time_user;
    l >> s.cpu_time_nice;
    l >> s.cpu_time_system;
    l >> s.cpu_time_idle;
    l >> s.cpu_time_iowait;
    l >> s.cpu_time_irq;
    l >> s.cpu_time_softirq;
    l >> s.cpu_time_steal;
    l >> s.cpu_time_guest;
    l >> s.cpu_time_guest_nice;
  }

  // Memory usage
  {
    // Open file
    std::ifstream in("/proc/meminfo");

    // Read file line by line and parse each line for relevant data
    unsigned long long int memory_free = 0;
    unsigned long long int buffers = 0;
    unsigned long long int cached = 0;
    unsigned long long int swap_free = 0;
    for (std::string line; std::getline(in, line); ) {
      // Extract data type
      std::istringstream l(line);
      std::string type;
      l >> type;

      // Store data depending on type
      if (type == "MemTotal:") {
        l >> s.memory_total;
      } else if (type == "MemFree:") {
        l >> memory_free;
      } else if (type == "Buffers:") {
        l >> buffers;
      } else if (type == "Cached:") {
        l >> cached;
      } else if (type == "SwapTotal:") {
        l >> s.swap_total;
      } else if (type == "SwapFree:") {
        l >> swap_free;
      }
    }

    // Calculate used memory and used swap space
    s.memory_used = s.memory_total - memory_free - buffers - cached;
    s.swap_used = s.swap_total - swap_free;

    // Convert values from kibibytes to bytes
    s.memory_total *= 1024;
    s.memory_used *= 1024;
    s.swap_total *= 1024;
    s.swap_used *= 1024;
  }

  // Bytes received/sent on network interface
  {
    // Open file
    std::ifstream in("/proc/net/dev");

    // Read file line by line until selected interface is found
    for (std::string line; std::getline(in, line); ) {
      // Extract interface name
      std::istringstream l(line);
      std::string interface;
      l >> interface;

      // If specified interface is found, read data and exit loop
      if (interface == network_interface + ":") {
        // Bytes received is the 2nd value
        l >> s.network_received;

        // Bytes sent is the 10th value
        for (int i = 0; i < 8; i++) {
          l >> s.network_sent;
        }
        break;
      }
    }
  }

  return s;
}

int main(int argc, char* argv[]) {
  // Parse command line arguments
  const auto args = parse_arguments(argc, argv);

  // Open log file if specified
  std::ofstream log_file;
  if (args.log_file != "") {
    log_file.open(args.log_file, std::ios::out | std::ios::app);
    if (!log_file.good()) {
      std::cerr << "error: could not open log file '" << args.log_file
                << "' for writing" << std::endl;
      std::exit(1);
    }
    std::cout << "Writing data to '" << args.log_file << "'..." << std::endl;
  }

  // Set output stream to use
  std::ostream os(args.log_file == "" ? std::cout.rdbuf() : log_file.rdbuf());

  // Begin main loop
  for (unsigned long long int iteration = 0;;) {
    // Obtain sample
    const Sample s = sample(args.network_interface);

    // Print all data to stdout
    os << s.date
       << " " << s.steady
       << " " << s.cpu_load_1m
       << " " << s.cpu_load_5m
       << " " << s.cpu_load_15m
       << " " << s.cpu_time_user
       << " " << s.cpu_time_nice
       << " " << s.cpu_time_system
       << " " << s.cpu_time_idle
       << " " << s.cpu_time_iowait
       << " " << s.cpu_time_irq
       << " " << s.cpu_time_softirq
       << " " << s.cpu_time_steal
       << " " << s.cpu_time_guest
       << " " << s.cpu_time_guest_nice
       << " " << s.memory_total
       << " " << s.memory_used
       << " " << s.swap_total
       << " " << s.swap_used
       << " " << s.network_received
       << " " << s.network_sent
       << std::endl;

    // Increment interation counter
    iteration++;

    // Exit main loop if maximum number of iterations is reached
    if (args.iterations > 0 && iteration >= args.iterations) {
      break;
    }

    // Sleep until next sample time
    std::this_thread::sleep_for(std::chrono::seconds(args.period));
  }
}
<|endoftext|>


<commit_before>// BrainCloudClient.cpp
// BrainCloudLib
// Copyright 2016 bitHeads, Inc. All Rights Reserved.

#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

#include "braincloud/BrainCloudClient.h"

#include "braincloud/internal/Device.h"
#include "braincloud/internal/JsonUtil.h"
#include "braincloud/internal/URLRequestMethod.h"

namespace BrainCloud
{
    // Define all static member variables.
    bool BrainCloudClient::EnableSingletonMode = false;
    const char * BrainCloudClient::SingletonUseErrorMessage =
            "Singleton usage is disabled. If called by mistake, use your own variable that holds an instance of the bcWrapper/bcClient.";

    BrainCloudClient * BrainCloudClient::_instance = NULL;
    std::string BrainCloudClient::s_brainCloudClientVersion = "3.11.2";
    const char* BC_SERVER_URL = "https://sharedprod.braincloudservers.com/dispatcherv2";

    /**
     * Constructor
     */
    BrainCloudClient::BrainCloudClient() :
        _brainCloudComms(IBrainCloudComms::create(this)),
        _rttComms(new RTTComms(this)),
        _asyncMatchService(new BrainCloudAsyncMatch(this)),
        _authenticationService(new BrainCloudAuthentication(this)),
        _chatService(new BrainCloudChat(this)),
        _dataStreamService(new BrainCloudDataStream(this)),
        _entityService(new BrainCloudEntity(this)),
        _eventService(new BrainCloudEvent(this)),
        _fileService(new BrainCloudFile(this)),
        _friendService(new BrainCloudFriend(this)),
        _gamificationService(new BrainCloudGamification(this)),
        _globalAppService(new BrainCloudGlobalApp(this)),
        _globalEntityService(new BrainCloudGlobalEntity(this)),
        _globalStatisticsService(new BrainCloudGlobalStatistics(this)),
        _groupService(new BrainCloudGroup(this)),
        _identityService(new BrainCloudIdentity(this)),
        _lobbyService(new BrainCloudLobby(this)),
        _mailService(new BrainCloudMail(this)),
        _matchmakingService(new BrainCloudMatchmaking(this)),
        _messagingService(new BrainCloudMessaging(this)),
        _oneWayMatchService(new BrainCloudOneWayMatch(this)),
        _playbackStreamService(new BrainCloudPlaybackStream(this)),
        _playerStateService(new BrainCloudPlayerState(this)),
        _playerStatisticsService(new BrainCloudPlayerStatistics(this)),
        _playerStatisticsEventService(new BrainCloudPlayerStatisticsEvent(this)),
        _presenceService(new BrainCloudPresence(this)),
        _productService(new BrainCloudProduct(this)),
        _virtualCurrencyService(new BrainCloudVirtualCurrency(this)),
        _appStoreService(new BrainCloudAppStore(this)),
        _profanityService(new BrainCloudProfanity(this)),
        _pushNotificationService(new BrainCloudPushNotification(this)),
        _redemptionCodeService(new BrainCloudRedemptionCode(this)),
        _s3HandlingService(new BrainCloudS3Handling(this)),
        _scriptService(new BrainCloudScript(this)),
        _socialLeaderboardService(new BrainCloudSocialLeaderboard(this)),
        _steamService(new BrainCloudSteam(this)),
        _timeService(new BrainCloudTime(this)),
        _tournamentService(new BrainCloudTournament(this)),
        _releasePlatform(""),
        _appVersion(""),
        _timezoneOffset(0.0)
    {
        //needed this here otherwise out of scope compiler error
        _rttService = new BrainCloudRTT(_rttComms, this);
    }

    BrainCloudClient::~BrainCloudClient()
    {
        delete _rttService;
        delete _tournamentService;
        delete _timeService;
        delete _steamService;
        delete _socialLeaderboardService;
        delete _scriptService;
        delete _s3HandlingService;
        delete _redemptionCodeService;
        delete _pushNotificationService;
        delete _profanityService;
        delete _appStoreService;
        delete _virtualCurrencyService;
        delete _productService;
        delete _presenceService;
        delete _playerStatisticsEventService;
        delete _playerStatisticsService;
        delete _playerStateService;
        delete _playbackStreamService;
        delete _oneWayMatchService;
        delete _messagingService;
        delete _matchmakingService;
        delete _mailService;
        delete _lobbyService;
        delete _identityService;
        delete _groupService;
        delete _globalStatisticsService;
        delete _globalEntityService;
        delete _globalAppService;
        delete _gamificationService;
        delete _friendService;
        delete _fileService;
        delete _eventService;
        delete _entityService;
        delete _dataStreamService;
        delete _chatService;
        delete _authenticationService;
        delete _asyncMatchService;
        delete _rttComms;
        delete _brainCloudComms;
    }

    ////////////////////////////////////////////////////
    // Public Methods
    ////////////////////////////////////////////////////

    const char * BrainCloudClient::getSessionId() const {
        return(_brainCloudComms->getSessionId().c_str());
    }

    const char * BrainCloudClient::getRttConnectionId() const{
        return(_rttComms->getConnectionId().c_str());
    }

    void BrainCloudClient::initializeComms(const char * in_serverURL, const char * in_appId, const std::map<std::string, std::string>& in_secretMap)
    {
        if (_brainCloudComms)
        {
            // automatically upgrade any older clients using "dispatcher" url
            // to "dispatcherv2" endpoint. Comms supports this now and otherwise
            // the change is transparent to the client.
            const char * urlToUse = in_serverURL;
            std::string url = in_serverURL;
            if (url.find("dispatcherv2") == std::string::npos)
            {
                size_t index = url.find("dispatcher");
                if (index != std::string::npos)
                {
                    url = url.substr(0, index);
                    url += "dispatcherv2";
                    urlToUse = url.c_str();
                }
            }
            _brainCloudComms->initializeWithApps(urlToUse, in_appId, in_secretMap);
        }

        if (_rttComms)
        {
            _rttComms->initialize();
        }
    }

    void BrainCloudClient::initialize(const char * in_serverURL, const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_secretKey == NULL || strlen(in_secretKey) <= 0)
            error = "secretKey was null or empty";
        else if (in_appId == NULL || strlen(in_appId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        std::map<std::string, std::string> secretMap;
        secretMap[in_appId] = in_secretKey;

        initializeComms(in_serverURL, in_appId, secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initialize(const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        initialize(BC_SERVER_URL, in_secretKey, in_appId, in_appVersion);
    }

    void BrainCloudClient::initializeWithApps(const char * in_serverURL, const char * in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_defaultAppId == NULL || strlen(in_defaultAppId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";
        else if (in_secretMap.find(in_defaultAppId) == in_secretMap.end())
            error = "not secretKey match for appid";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        initializeComms(in_serverURL, in_defaultAppId, in_secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initializeWithApps(const char* in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char* in_appVersion)
    {
        initializeWithApps(BC_SERVER_URL, in_defaultAppId, in_secretMap, in_appVersion);
    }

    void BrainCloudClient::initializeIdentity(const char * in_profileId, const char * in_anonymousId)
    {
        _authenticationService->initialize(in_profileId, in_anonymousId);
    }

    void BrainCloudClient::runCallbacks()
    {
        _brainCloudComms->runCallbacks();
        _rttComms->runCallbacks();
    }

    void BrainCloudClient::registerEventCallback(IEventCallback *in_eventCallback)
    {
        _brainCloudComms->registerEventCallback(in_eventCallback);
    }

    void BrainCloudClient::deregisterEventCallback()
    {
        _brainCloudComms->deregisterEventCallback();
    }

    void BrainCloudClient::registerRewardCallback(IRewardCallback *in_rewardCallback)
    {
        _brainCloudComms->registerRewardCallback(in_rewardCallback);
    }

    void BrainCloudClient::deregisterRewardCallback()
    {
        _brainCloudComms->deregisterRewardCallback();
    }

    void BrainCloudClient::registerFileUploadCallback(IFileUploadCallback * in_fileUploadCallback)
    {
        _brainCloudComms->registerFileUploadCallback(in_fileUploadCallback);
    }

    void BrainCloudClient::deregisterFileUploadCallback()
    {
        _brainCloudComms->deregisterFileUploadCallback();
    }

    void BrainCloudClient::registerGlobalErrorCallback(IGlobalErrorCallback * in_globalErrorCallback)
    {
        _brainCloudComms->registerGlobalErrorCallback(in_globalErrorCallback);
    }

    void BrainCloudClient::deregisterGlobalErrorCallback()
    {
        _brainCloudComms->deregisterGlobalErrorCallback();
    }

    void BrainCloudClient::registerNetworkErrorCallback(INetworkErrorCallback * in_networkErrorCallback)
    {
        _brainCloudComms->registerNetworkErrorCallback(in_networkErrorCallback);
    }

    void BrainCloudClient::deregisterNetworkErrorCallback()
    {
        _brainCloudComms->deregisterNetworkErrorCallback();
    }

    void BrainCloudClient::enableLogging(bool shouldEnable)
    {
        _brainCloudComms->enableLogging(shouldEnable);
        _rttComms->enableLogging(shouldEnable);
    }

    /**
     * Heart beat to keep session(s) current, and retrieve any pending events...
     */
    void BrainCloudClient::heartbeat()
    {
        _brainCloudComms->sendHeartbeat();
    }

    void BrainCloudClient::sendRequest(ServerCall * in_serviceMessage)
    {
        _brainCloudComms->addToQueue(in_serviceMessage);
    }

    void BrainCloudClient::resetCommunication()
    {
        _rttComms->resetCommunication();
        _brainCloudComms->resetCommunication();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    void BrainCloudClient::shutdown()
    {
        _rttComms->shutdown();
        _brainCloudComms->shutdown();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    bool BrainCloudClient::isAuthenticated()
    {
        return _brainCloudComms->isAuthenticated();
    }

    bool BrainCloudClient::isInitialized()
    {
        return _brainCloudComms->isInitialized() && _rttComms->isInitialized();
    }

    void BrainCloudClient::setImmediateRetryOnError(bool value)
    {
        _brainCloudComms->setImmediateRetryOnError(value);
    }

    /**
     * Retrieve the pointer to the singleton BrainCloudClient instance.
     */
    BrainCloudClient * BrainCloudClient::getInstance()
    {
        if(EnableSingletonMode == false) {
            throw std::invalid_argument(SingletonUseErrorMessage);
        }

        if (_instance == NULL) {
            _instance = new BrainCloudClient();
        }
        return _instance;
    }

    void BrainCloudClient::setHeartbeatInterval(int in_intervalInMilliseconds) {
        _brainCloudComms->setHeartbeatInterval(in_intervalInMilliseconds);
    }

    const std::vector<int> & BrainCloudClient::getPacketTimeouts()
    {
        return _brainCloudComms->getPacketTimeouts();
    }

    void BrainCloudClient::setPacketTimeouts(const std::vector<int> & in_packetTimeouts)
    {
        _brainCloudComms->setPacketTimeouts(in_packetTimeouts);
    }

    void BrainCloudClient::setPacketTimeoutsToDefault()
    {
        _brainCloudComms->setPacketTimeoutsToDefault();
    }

    void BrainCloudClient::setAuthenticationPacketTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setAuthenticationPacketTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getAuthenticationPacketTimeout()
    {
        return _brainCloudComms->getAuthenticationPacketTimeout();
    }

    void BrainCloudClient::setOldStyleStatusMessageErrorCallback(bool in_enabled)
    {
        _brainCloudComms->setOldStyleStatusMessageErrorCallback(in_enabled);
    }

    void BrainCloudClient::setErrorCallbackOn202Status(bool in_isError)
    {
        _brainCloudComms->setErrorCallbackOn202Status(in_isError);
    }

    int BrainCloudClient::getUploadLowTransferRateTimeout()
    {
        return _brainCloudComms->getUploadLowTransferRateTimeout();
    }

    void BrainCloudClient::setUploadLowTransferRateTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setUploadLowTransferRateTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getUploadLowTransferRateThreshold()
    {
        return _brainCloudComms->getUploadLowTransferRateThreshold();
    }

    void BrainCloudClient::setUploadLowTransferRateThreshold(int in_bytesPerSec)
    {
        _brainCloudComms->setUploadLowTransferRateThreshold(in_bytesPerSec);
    }

    void BrainCloudClient::enableNetworkErrorMessageCaching(bool in_enabled)
    {
        _brainCloudComms->enableNetworkErrorMessageCaching(in_enabled);
    }

    void BrainCloudClient::retryCachedMessages()
    {
        _brainCloudComms->retryCachedMessages();
    }

    void BrainCloudClient::flushCachedMessages(bool in_sendApiErrorCallbacks)
    {
        _brainCloudComms->flushCachedMessages(in_sendApiErrorCallbacks);
    }

    void BrainCloudClient::insertEndOfMessageBundleMarker()
    {
        _brainCloudComms->insertEndOfMessageBundleMarker();
    }

    ////////////////////////////////////////////////////
    // Private Methods
    ////////////////////////////////////////////////////
    void BrainCloudClient::setupOSLocaleData()
    {
        Device::getLocale(&_timezoneOffset, &_languageCode, &_countryCode);
    }
}  // end namespace
<commit_msg>updating versions of lib for release<commit_after>// BrainCloudClient.cpp
// BrainCloudLib
// Copyright 2016 bitHeads, Inc. All Rights Reserved.

#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

#include "braincloud/BrainCloudClient.h"

#include "braincloud/internal/Device.h"
#include "braincloud/internal/JsonUtil.h"
#include "braincloud/internal/URLRequestMethod.h"

namespace BrainCloud
{
    // Define all static member variables.
    bool BrainCloudClient::EnableSingletonMode = false;
    const char * BrainCloudClient::SingletonUseErrorMessage =
            "Singleton usage is disabled. If called by mistake, use your own variable that holds an instance of the bcWrapper/bcClient.";

    BrainCloudClient * BrainCloudClient::_instance = NULL;
    std::string BrainCloudClient::s_brainCloudClientVersion = "4.0.0";
    const char* BC_SERVER_URL = "https://sharedprod.braincloudservers.com/dispatcherv2";

    /**
     * Constructor
     */
    BrainCloudClient::BrainCloudClient() :
        _brainCloudComms(IBrainCloudComms::create(this)),
        _rttComms(new RTTComms(this)),
        _asyncMatchService(new BrainCloudAsyncMatch(this)),
        _authenticationService(new BrainCloudAuthentication(this)),
        _chatService(new BrainCloudChat(this)),
        _dataStreamService(new BrainCloudDataStream(this)),
        _entityService(new BrainCloudEntity(this)),
        _eventService(new BrainCloudEvent(this)),
        _fileService(new BrainCloudFile(this)),
        _friendService(new BrainCloudFriend(this)),
        _gamificationService(new BrainCloudGamification(this)),
        _globalAppService(new BrainCloudGlobalApp(this)),
        _globalEntityService(new BrainCloudGlobalEntity(this)),
        _globalStatisticsService(new BrainCloudGlobalStatistics(this)),
        _groupService(new BrainCloudGroup(this)),
        _identityService(new BrainCloudIdentity(this)),
        _lobbyService(new BrainCloudLobby(this)),
        _mailService(new BrainCloudMail(this)),
        _matchmakingService(new BrainCloudMatchmaking(this)),
        _messagingService(new BrainCloudMessaging(this)),
        _oneWayMatchService(new BrainCloudOneWayMatch(this)),
        _playbackStreamService(new BrainCloudPlaybackStream(this)),
        _playerStateService(new BrainCloudPlayerState(this)),
        _playerStatisticsService(new BrainCloudPlayerStatistics(this)),
        _playerStatisticsEventService(new BrainCloudPlayerStatisticsEvent(this)),
        _presenceService(new BrainCloudPresence(this)),
        _productService(new BrainCloudProduct(this)),
        _virtualCurrencyService(new BrainCloudVirtualCurrency(this)),
        _appStoreService(new BrainCloudAppStore(this)),
        _profanityService(new BrainCloudProfanity(this)),
        _pushNotificationService(new BrainCloudPushNotification(this)),
        _redemptionCodeService(new BrainCloudRedemptionCode(this)),
        _s3HandlingService(new BrainCloudS3Handling(this)),
        _scriptService(new BrainCloudScript(this)),
        _socialLeaderboardService(new BrainCloudSocialLeaderboard(this)),
        _steamService(new BrainCloudSteam(this)),
        _timeService(new BrainCloudTime(this)),
        _tournamentService(new BrainCloudTournament(this)),
        _releasePlatform(""),
        _appVersion(""),
        _timezoneOffset(0.0)
    {
        //needed this here otherwise out of scope compiler error
        _rttService = new BrainCloudRTT(_rttComms, this);
    }

    BrainCloudClient::~BrainCloudClient()
    {
        delete _rttService;
        delete _tournamentService;
        delete _timeService;
        delete _steamService;
        delete _socialLeaderboardService;
        delete _scriptService;
        delete _s3HandlingService;
        delete _redemptionCodeService;
        delete _pushNotificationService;
        delete _profanityService;
        delete _appStoreService;
        delete _virtualCurrencyService;
        delete _productService;
        delete _presenceService;
        delete _playerStatisticsEventService;
        delete _playerStatisticsService;
        delete _playerStateService;
        delete _playbackStreamService;
        delete _oneWayMatchService;
        delete _messagingService;
        delete _matchmakingService;
        delete _mailService;
        delete _lobbyService;
        delete _identityService;
        delete _groupService;
        delete _globalStatisticsService;
        delete _globalEntityService;
        delete _globalAppService;
        delete _gamificationService;
        delete _friendService;
        delete _fileService;
        delete _eventService;
        delete _entityService;
        delete _dataStreamService;
        delete _chatService;
        delete _authenticationService;
        delete _asyncMatchService;
        delete _rttComms;
        delete _brainCloudComms;
    }

    ////////////////////////////////////////////////////
    // Public Methods
    ////////////////////////////////////////////////////

    const char * BrainCloudClient::getSessionId() const {
        return(_brainCloudComms->getSessionId().c_str());
    }

    const char * BrainCloudClient::getRttConnectionId() const{
        return(_rttComms->getConnectionId().c_str());
    }

    void BrainCloudClient::initializeComms(const char * in_serverURL, const char * in_appId, const std::map<std::string, std::string>& in_secretMap)
    {
        if (_brainCloudComms)
        {
            // automatically upgrade any older clients using "dispatcher" url
            // to "dispatcherv2" endpoint. Comms supports this now and otherwise
            // the change is transparent to the client.
            const char * urlToUse = in_serverURL;
            std::string url = in_serverURL;
            if (url.find("dispatcherv2") == std::string::npos)
            {
                size_t index = url.find("dispatcher");
                if (index != std::string::npos)
                {
                    url = url.substr(0, index);
                    url += "dispatcherv2";
                    urlToUse = url.c_str();
                }
            }
            _brainCloudComms->initializeWithApps(urlToUse, in_appId, in_secretMap);
        }

        if (_rttComms)
        {
            _rttComms->initialize();
        }
    }

    void BrainCloudClient::initialize(const char * in_serverURL, const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_secretKey == NULL || strlen(in_secretKey) <= 0)
            error = "secretKey was null or empty";
        else if (in_appId == NULL || strlen(in_appId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        std::map<std::string, std::string> secretMap;
        secretMap[in_appId] = in_secretKey;

        initializeComms(in_serverURL, in_appId, secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initialize(const char * in_secretKey, const char * in_appId, const char * in_appVersion)
    {
        initialize(BC_SERVER_URL, in_secretKey, in_appId, in_appVersion);
    }

    void BrainCloudClient::initializeWithApps(const char * in_serverURL, const char * in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char * in_appVersion)
    {
        std::string error = "";
        if (in_serverURL == NULL || strlen(in_serverURL) <= 0)
            error = "serverURL was null or empty";
        else if (in_defaultAppId == NULL || strlen(in_defaultAppId) <= 0)
            error = "appId was null or empty";
        else if (in_appVersion == NULL || strlen(in_appVersion) <= 0)
            error = "appVersion was null or empty";
        else if (in_secretMap.find(in_defaultAppId) == in_secretMap.end())
            error = "not secretKey match for appid";

        if (error.length() > 0)
        {
            std::cout << "ERROR | Failed to initialize brainCloud - " << error;
            return;
        }

        initializeComms(in_serverURL, in_defaultAppId, in_secretMap);
        setupOSLocaleData();

        _releasePlatform = Device::getPlatformName();
        _appVersion = in_appVersion;
    }

    void BrainCloudClient::initializeWithApps(const char* in_defaultAppId, const std::map<std::string, std::string>& in_secretMap, const char* in_appVersion)
    {
        initializeWithApps(BC_SERVER_URL, in_defaultAppId, in_secretMap, in_appVersion);
    }

    void BrainCloudClient::initializeIdentity(const char * in_profileId, const char * in_anonymousId)
    {
        _authenticationService->initialize(in_profileId, in_anonymousId);
    }

    void BrainCloudClient::runCallbacks()
    {
        _brainCloudComms->runCallbacks();
        _rttComms->runCallbacks();
    }

    void BrainCloudClient::registerEventCallback(IEventCallback *in_eventCallback)
    {
        _brainCloudComms->registerEventCallback(in_eventCallback);
    }

    void BrainCloudClient::deregisterEventCallback()
    {
        _brainCloudComms->deregisterEventCallback();
    }

    void BrainCloudClient::registerRewardCallback(IRewardCallback *in_rewardCallback)
    {
        _brainCloudComms->registerRewardCallback(in_rewardCallback);
    }

    void BrainCloudClient::deregisterRewardCallback()
    {
        _brainCloudComms->deregisterRewardCallback();
    }

    void BrainCloudClient::registerFileUploadCallback(IFileUploadCallback * in_fileUploadCallback)
    {
        _brainCloudComms->registerFileUploadCallback(in_fileUploadCallback);
    }

    void BrainCloudClient::deregisterFileUploadCallback()
    {
        _brainCloudComms->deregisterFileUploadCallback();
    }

    void BrainCloudClient::registerGlobalErrorCallback(IGlobalErrorCallback * in_globalErrorCallback)
    {
        _brainCloudComms->registerGlobalErrorCallback(in_globalErrorCallback);
    }

    void BrainCloudClient::deregisterGlobalErrorCallback()
    {
        _brainCloudComms->deregisterGlobalErrorCallback();
    }

    void BrainCloudClient::registerNetworkErrorCallback(INetworkErrorCallback * in_networkErrorCallback)
    {
        _brainCloudComms->registerNetworkErrorCallback(in_networkErrorCallback);
    }

    void BrainCloudClient::deregisterNetworkErrorCallback()
    {
        _brainCloudComms->deregisterNetworkErrorCallback();
    }

    void BrainCloudClient::enableLogging(bool shouldEnable)
    {
        _brainCloudComms->enableLogging(shouldEnable);
        _rttComms->enableLogging(shouldEnable);
    }

    /**
     * Heart beat to keep session(s) current, and retrieve any pending events...
     */
    void BrainCloudClient::heartbeat()
    {
        _brainCloudComms->sendHeartbeat();
    }

    void BrainCloudClient::sendRequest(ServerCall * in_serviceMessage)
    {
        _brainCloudComms->addToQueue(in_serviceMessage);
    }

    void BrainCloudClient::resetCommunication()
    {
        _rttComms->resetCommunication();
        _brainCloudComms->resetCommunication();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    void BrainCloudClient::shutdown()
    {
        _rttComms->shutdown();
        _brainCloudComms->shutdown();
        _brainCloudComms->setSessionId("");
        _authenticationService->setProfileId("");
    }

    bool BrainCloudClient::isAuthenticated()
    {
        return _brainCloudComms->isAuthenticated();
    }

    bool BrainCloudClient::isInitialized()
    {
        return _brainCloudComms->isInitialized() && _rttComms->isInitialized();
    }

    void BrainCloudClient::setImmediateRetryOnError(bool value)
    {
        _brainCloudComms->setImmediateRetryOnError(value);
    }

    /**
     * Retrieve the pointer to the singleton BrainCloudClient instance.
     */
    BrainCloudClient * BrainCloudClient::getInstance()
    {
        if(EnableSingletonMode == false) {
            throw std::invalid_argument(SingletonUseErrorMessage);
        }

        if (_instance == NULL) {
            _instance = new BrainCloudClient();
        }
        return _instance;
    }

    void BrainCloudClient::setHeartbeatInterval(int in_intervalInMilliseconds) {
        _brainCloudComms->setHeartbeatInterval(in_intervalInMilliseconds);
    }

    const std::vector<int> & BrainCloudClient::getPacketTimeouts()
    {
        return _brainCloudComms->getPacketTimeouts();
    }

    void BrainCloudClient::setPacketTimeouts(const std::vector<int> & in_packetTimeouts)
    {
        _brainCloudComms->setPacketTimeouts(in_packetTimeouts);
    }

    void BrainCloudClient::setPacketTimeoutsToDefault()
    {
        _brainCloudComms->setPacketTimeoutsToDefault();
    }

    void BrainCloudClient::setAuthenticationPacketTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setAuthenticationPacketTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getAuthenticationPacketTimeout()
    {
        return _brainCloudComms->getAuthenticationPacketTimeout();
    }

    void BrainCloudClient::setOldStyleStatusMessageErrorCallback(bool in_enabled)
    {
        _brainCloudComms->setOldStyleStatusMessageErrorCallback(in_enabled);
    }

    void BrainCloudClient::setErrorCallbackOn202Status(bool in_isError)
    {
        _brainCloudComms->setErrorCallbackOn202Status(in_isError);
    }

    int BrainCloudClient::getUploadLowTransferRateTimeout()
    {
        return _brainCloudComms->getUploadLowTransferRateTimeout();
    }

    void BrainCloudClient::setUploadLowTransferRateTimeout(int in_timeoutSecs)
    {
        _brainCloudComms->setUploadLowTransferRateTimeout(in_timeoutSecs);
    }

    int BrainCloudClient::getUploadLowTransferRateThreshold()
    {
        return _brainCloudComms->getUploadLowTransferRateThreshold();
    }

    void BrainCloudClient::setUploadLowTransferRateThreshold(int in_bytesPerSec)
    {
        _brainCloudComms->setUploadLowTransferRateThreshold(in_bytesPerSec);
    }

    void BrainCloudClient::enableNetworkErrorMessageCaching(bool in_enabled)
    {
        _brainCloudComms->enableNetworkErrorMessageCaching(in_enabled);
    }

    void BrainCloudClient::retryCachedMessages()
    {
        _brainCloudComms->retryCachedMessages();
    }

    void BrainCloudClient::flushCachedMessages(bool in_sendApiErrorCallbacks)
    {
        _brainCloudComms->flushCachedMessages(in_sendApiErrorCallbacks);
    }

    void BrainCloudClient::insertEndOfMessageBundleMarker()
    {
        _brainCloudComms->insertEndOfMessageBundleMarker();
    }

    ////////////////////////////////////////////////////
    // Private Methods
    ////////////////////////////////////////////////////
    void BrainCloudClient::setupOSLocaleData()
    {
        Device::getLocale(&_timezoneOffset, &_languageCode, &_countryCode);
    }
}  // end namespace
<|endoftext|>