<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_INTERFACES_HH
#define DUNE_GDT_OPERATORS_INTERFACES_HH

#include <type_traits>

#include <dune/stuff/common/disable_warnings.hh>
#include <dune/common/dynmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/common/configuration.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

#include "../products/interfaces.hh"

namespace Dune {
namespace GDT {

template <class Traits>
class OperatorInterface : public ProductInterface<Traits>
{
  typedef ProductInterface<Traits> BaseType;

public:
  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;

  template <class SourceType, class RangeType>
  void apply(const SourceType& source, RangeType& range) const
  {
    CHECK_CRTP(this->as_imp(*this).apply(source, range));
    return this->as_imp(*this).apply(source, range);
  }

  template <class S, class R>
  FieldType apply2(const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const Stuff::LA::VectorInterface<R, FieldType>& range) const
  {
    auto tmp = range.copy();
    apply(source.as_imp(source), tmp);
    return range.dot(tmp);
  } // ... apply2(...)

  template <class SS, class SV, class RS, class RV>
  FieldType apply2(const ConstDiscreteFunction<SS, SV>& source, const ConstDiscreteFunction<RS, RV>& range) const
  {
    auto tmp_vector = range.copy();
    DiscreteFunction<RS, RV> tmp_function(range.space(), tmp_vector);
    apply(source, tmp_function);
    return range.vector().dot(tmp_vector);
  }
}; // class OperatorInterface

template <class Traits>
class LocalizableOperatorInterface : public Stuff::CRTPInterface<LocalizableOperatorInterface<Traits>, Traits>
{
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::FieldType FieldType;

  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridViewType::dimension;

private:
  static_assert(std::is_base_of<Stuff::IsLocalizableFunction, SourceType>::value,
                "SourceType has to be derived from Stuff::IsLocalizableFunction!");
  static_assert(std::is_base_of<DiscreteFunction<typename RangeType::SpaceType, typename RangeType::VectorType>,
                                RangeType>::value,
                "RangeType has to be derived from DiscreteFunction!");
  static_assert(std::is_same<typename SourceType::EntityType, EntityType>::value,
                "The EntityType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::EntityType, EntityType>::value,
                "The EntityType of RangeType and GridViewType have to match!");
  static_assert(std::is_same<typename SourceType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of RangeType and GridViewType have to match!");
  static_assert(SourceType::dimDomain == dimDomain, "The dimDomain of SourceType and GridViewType have to match!");
  static_assert(RangeType::dimDomain == dimDomain, "The dimDomain of RangeType and GridViewType have to match!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const SourceType& source() const
  {
    CHECK_CRTP(this->as_imp(*this).source());
    return this->as_imp(*this).source();
  }

  const RangeType& range() const
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  RangeType& range()
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  void apply()
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).apply());
  }
}; // class LocalizableOperatorInterface

template <class Traits>
class AssemblableOperatorInterface : public AssemblableProductInterface<Traits>
{
  typedef AssemblableProductInterface<Traits> BaseType;

public:
  typedef typename BaseType::derived_type derived_type;

  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::MatrixType;

  using typename BaseType::EntityType;
  using typename BaseType::DomainFieldType;
  using BaseType::dimDomain;
  using typename BaseType::PatternType;

  template <class S, class R>
  void apply(const Stuff::LA::VectorInterface<S, DomainFieldType>& source,
             Stuff::LA::VectorInterface<R, FieldType>& range)
  {
    CHECK_CRTP(this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range)));
    return this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range));
  }

  template <class S, class R>
  void apply(const ConstDiscreteFunction<SourceSpaceType, S>& source, ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    apply(source.vector(), range.vector());
  }

  static std::vector<std::string> invert_options()
  {
    return derived_type::invert_options();
  }

  static Stuff::Common::Configuration invert_options(const std::string& type)
  {
    return derived_type::invert_options(type);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    apply_inverse(range, source, invert_options()[0]);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const std::string& opt)
  {
    apply_inverse(range, source, invert_options(opt));
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const Stuff::Common::Configuration& opts)
  {
    CHECK_CRTP(this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts));
    return this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source)
  {
    apply_inverse(range.vector(), source.vector());
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const std::string& opt)
  {
    apply_inverse(range.vector(), source.vector(), opt);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const Stuff::Common::Configuration& opts)
  {
    apply_inverse(range.vector(), source.vector(), opts);
  }

  template <class R, class S, class P>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const AssemblableProductInterface<P>& product)
  {
    auto tmp = range.copy();
    apply(source, tmp);
    return product.apply2(tmp, source);
  }

  template <class R, class S>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    this->assemble();
    auto tmp = range.copy();
    this->matrix().mv(source.as_imp(), tmp);
    return range.dot(tmp);
  }

  template <class S, class R>
  FieldType apply2(const ConstDiscreteFunction<SourceSpaceType, S>& source,
                   const ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    return apply2(range.vector(), source.vector());
  }
}; // class AssemblableOperatorInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_INTERFACES_HH
<commit_msg>[operators.interfaces] do not guard dune includes<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_INTERFACES_HH
#define DUNE_GDT_OPERATORS_INTERFACES_HH

#include <type_traits>

#include <dune/common/dynmatrix.hh>
#include <dune/common/fvector.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/common/configuration.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

#include "../products/interfaces.hh"

namespace Dune {
namespace GDT {

template <class Traits>
class OperatorInterface : public ProductInterface<Traits>
{
  typedef ProductInterface<Traits> BaseType;

public:
  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;

  template <class SourceType, class RangeType>
  void apply(const SourceType& source, RangeType& range) const
  {
    CHECK_CRTP(this->as_imp(*this).apply(source, range));
    return this->as_imp(*this).apply(source, range);
  }

  template <class S, class R>
  FieldType apply2(const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const Stuff::LA::VectorInterface<R, FieldType>& range) const
  {
    auto tmp = range.copy();
    apply(source.as_imp(source), tmp);
    return range.dot(tmp);
  } // ... apply2(...)

  template <class SS, class SV, class RS, class RV>
  FieldType apply2(const ConstDiscreteFunction<SS, SV>& source, const ConstDiscreteFunction<RS, RV>& range) const
  {
    auto tmp_vector = range.copy();
    DiscreteFunction<RS, RV> tmp_function(range.space(), tmp_vector);
    apply(source, tmp_function);
    return range.vector().dot(tmp_vector);
  }
}; // class OperatorInterface

template <class Traits>
class LocalizableOperatorInterface : public Stuff::CRTPInterface<LocalizableOperatorInterface<Traits>, Traits>
{
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::FieldType FieldType;

  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridViewType::dimension;

private:
  static_assert(std::is_base_of<Stuff::IsLocalizableFunction, SourceType>::value,
                "SourceType has to be derived from Stuff::IsLocalizableFunction!");
  static_assert(std::is_base_of<DiscreteFunction<typename RangeType::SpaceType, typename RangeType::VectorType>,
                                RangeType>::value,
                "RangeType has to be derived from DiscreteFunction!");
  static_assert(std::is_same<typename SourceType::EntityType, EntityType>::value,
                "The EntityType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::EntityType, EntityType>::value,
                "The EntityType of RangeType and GridViewType have to match!");
  static_assert(std::is_same<typename SourceType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of SourceType and GridViewType have to match!");
  static_assert(std::is_same<typename RangeType::DomainFieldType, DomainFieldType>::value,
                "The DomainFieldType of RangeType and GridViewType have to match!");
  static_assert(SourceType::dimDomain == dimDomain, "The dimDomain of SourceType and GridViewType have to match!");
  static_assert(RangeType::dimDomain == dimDomain, "The dimDomain of RangeType and GridViewType have to match!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const SourceType& source() const
  {
    CHECK_CRTP(this->as_imp(*this).source());
    return this->as_imp(*this).source();
  }

  const RangeType& range() const
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  RangeType& range()
  {
    CHECK_CRTP(this->as_imp(*this).range());
    return this->as_imp(*this).range();
  }

  void apply()
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).apply());
  }
}; // class LocalizableOperatorInterface

template <class Traits>
class AssemblableOperatorInterface : public AssemblableProductInterface<Traits>
{
  typedef AssemblableProductInterface<Traits> BaseType;

public:
  typedef typename BaseType::derived_type derived_type;

  using typename BaseType::GridViewType;
  using typename BaseType::FieldType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::MatrixType;

  using typename BaseType::EntityType;
  using typename BaseType::DomainFieldType;
  using BaseType::dimDomain;
  using typename BaseType::PatternType;

  template <class S, class R>
  void apply(const Stuff::LA::VectorInterface<S, DomainFieldType>& source,
             Stuff::LA::VectorInterface<R, FieldType>& range)
  {
    CHECK_CRTP(this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range)));
    return this->as_imp(*this).apply(source.as_imp(source), range.as_imp(range));
  }

  template <class S, class R>
  void apply(const ConstDiscreteFunction<SourceSpaceType, S>& source, ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    apply(source.vector(), range.vector());
  }

  static std::vector<std::string> invert_options()
  {
    return derived_type::invert_options();
  }

  static Stuff::Common::Configuration invert_options(const std::string& type)
  {
    return derived_type::invert_options(type);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    apply_inverse(range, source, invert_options()[0]);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const std::string& opt)
  {
    apply_inverse(range, source, invert_options(opt));
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R, FieldType>& range,
                     Stuff::LA::VectorInterface<S, FieldType>& source, const Stuff::Common::Configuration& opts)
  {
    CHECK_CRTP(this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts));
    return this->as_imp(*this).apply_inverse(range.as_imp(range), source.as_imp(source), opts);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source)
  {
    apply_inverse(range.vector(), source.vector());
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const std::string& opt)
  {
    apply_inverse(range.vector(), source.vector(), opt);
  }

  template <class R, class S>
  void apply_inverse(const ConstDiscreteFunction<SourceSpaceType, R>& range,
                     ConstDiscreteFunction<RangeSpaceType, S>& source, const Stuff::Common::Configuration& opts)
  {
    apply_inverse(range.vector(), source.vector(), opts);
  }

  template <class R, class S, class P>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source,
                   const AssemblableProductInterface<P>& product)
  {
    auto tmp = range.copy();
    apply(source, tmp);
    return product.apply2(tmp, source);
  }

  template <class R, class S>
  FieldType apply2(const Stuff::LA::VectorInterface<R, FieldType>& range,
                   const Stuff::LA::VectorInterface<S, FieldType>& source)
  {
    this->assemble();
    auto tmp = range.copy();
    this->matrix().mv(source.as_imp(), tmp);
    return range.dot(tmp);
  }

  template <class S, class R>
  FieldType apply2(const ConstDiscreteFunction<SourceSpaceType, S>& source,
                   const ConstDiscreteFunction<RangeSpaceType, R>& range)
  {
    return apply2(range.vector(), source.vector());
  }
}; // class AssemblableOperatorInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_INTERFACES_HH
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_STUFF_FUNCTIONS_CONSTANT_HH
#define DUNE_STUFF_FUNCTIONS_CONSTANT_HH

#include <memory>

#include <dune/stuff/common/configtree.hh>

#include "interfaces.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class Constant
  : public GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols>
{

public:
  typedef GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > BaseType;
  typedef Constant < EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >  ThisType;
  typedef typename BaseType::RangeType  RangeType;
  typedef typename BaseType::DomainType DomainType;
  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  using typename BaseType::LocalfunctionType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".constant";
  }

  static Common::ConfigTree default_config(const std::string sub_name = "")
  {
    Common::ConfigTree config;
    config["value"] = "1.0";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::ConfigTree config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::ConfigTree default_cfg = default_config();
    //create
    return Common::make_unique< ThisType >(
          cfg.get("value",  default_cfg.get< RangeType >("value")),
          cfg.get("name",   default_cfg.get< std::string >("name")));
  } // ... create(...)

  explicit Constant(const RangeType& constant, const std::string name = static_id())
    : constant_(constant)
    , name_(name)
  {}

  explicit Constant(const RangeFieldImp& constant, const std::string name = static_id())
    : constant_(constant)
    , name_(name)
  {}

  Constant(const ThisType& other)
    : constant_(other.constant_)
    , name_(other.name_)
  {}

  virtual std::string type() const DS_OVERRIDE
  {
    return BaseType::static_id() + ".constant";
  }

  virtual size_t order() const DS_OVERRIDE DS_FINAL
  {
    return 0;
  }

  virtual void evaluate(const DomainType& /*x*/, RangeType& ret) const DS_OVERRIDE DS_FINAL
  {
    ret = constant_;
  }

  virtual void jacobian(const DomainType& /*x*/, JacobianRangeType& ret) const DS_OVERRIDE DS_FINAL
  {
    ret *= 0.0;
  }

  virtual std::string name() const DS_OVERRIDE DS_FINAL
  {
    return name_;
  }

private:
  const RangeType constant_;
  const std::string name_;
};

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#ifdef DUNE_STUFF_FUNCTIONS_TO_LIB
# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(etype, ddim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, 1) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, 2) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, 3)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, rdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 1) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 2) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 3)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_RANGEFIELDTYPES(etype, double, ddim, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_RANGEFIELDTYPES(etype, dftype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION(etype, dftype, ddim, double, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION(etype, dftype, ddim, long double, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION(etype, dftype, ddim, rftype, rdim, rcdim) \
  extern template class Dune::Stuff::Functions::Constant< etype, dftype, ddim, rftype, rdim, rcdim >;

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesFake1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesFake2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesFake3dEntityType, 3)

# if HAVE_DUNE_GRID

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid3dEntityType, 3)

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid3dEntityType, 3)

#   if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid3dEntityType, 3)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluCubeGrid3dEntityType, 3)

#   endif // HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
# endif // HAVE_DUNE_GRID

# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_RANGEFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE
# endif // DUNE_STUFF_FUNCTIONS_TO_LIB

#endif // DUNE_STUFF_FUNCTIONS_CONSTANT_HH
<commit_msg>[functions.constant] implement default_config() for all dimensions<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_STUFF_FUNCTIONS_CONSTANT_HH
#define DUNE_STUFF_FUNCTIONS_CONSTANT_HH

#include <memory>

#include <dune/stuff/common/configtree.hh>

#include "interfaces.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class Constant
  : public GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols>
{
  typedef GlobalFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > BaseType;
  typedef Constant < EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >  ThisType;

  template< class R, int r, int rC >
  struct Get{ static std::string value_str()
  {
    std::string str = "[";
    for (size_t rr = 0; rr < r; ++rr) {
      if (rr > 0)
        str += "; ";
      str += "[";
      for (size_t cc = 0; cc < rC; ++cc) {
        if (cc > 0)
          str += " ";
        if (cc == rr)
          str += "1";
        else
          str += "0";
      }
      str += "]";
    }
    str += "]";
    return str;
  } };

  template< class R, int rC >
  struct Get< R, 1, rC >{ static std::string value_str()
  {
    std::string str = "[";
    for (size_t cc = 0; cc < rC; ++cc) {
      if (cc > 0)
        str += "; ";
      str += "1";
    }
    str += "]";
    return str;
  } };

  template< class R, int r >
  struct Get< R, r, 1 >{ static std::string value_str()
  {
    std::string str = "[";
    for (size_t rr = 0; rr < r; ++rr) {
      if (rr > 0)
        str += " ";
      str += "1";
    }
    str += "]";
    return str;
  } };

  template< class R >
  struct Get< R, 1, 1 >{ static std::string value_str()
  {
    return "1";
  } };

public:
  typedef typename BaseType::DomainType DomainType;
  typedef typename BaseType::RangeType  RangeFieldType;
  typedef typename BaseType::RangeType  RangeType;
  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  using typename BaseType::LocalfunctionType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".constant";
  }

  static Common::ConfigTree default_config(const std::string sub_name = "")
  {
    Common::ConfigTree config;
    config["value"] = Get< RangeFieldImp, rangeDim, rangeDimCols >::value_str();
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::ConfigTree config = default_config(),
                                            const std::string sub_name = static_id())
  {
    // get correct config
    const Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::ConfigTree default_cfg = default_config();
    //create
    RangeType value;
    try {
      value = cfg.get("value", default_cfg.get< RangeType >("value"));
    } catch (Stuff::Exceptions::configuration_error) {
      value = RangeType(cfg.get("value", RangeFieldType(1)));
    }
    return Common::make_unique< ThisType >(
          cfg.get("value",  default_cfg.get< RangeType >("value")),
          cfg.get("name",   default_cfg.get< std::string >("name")));
  } // ... create(...)

  explicit Constant(const RangeType& constant, const std::string name = static_id())
    : constant_(constant)
    , name_(name)
  {}

  explicit Constant(const RangeFieldImp& constant, const std::string name = static_id())
    : constant_(constant)
    , name_(name)
  {}

  Constant(const ThisType& other)
    : constant_(other.constant_)
    , name_(other.name_)
  {}

  virtual std::string type() const DS_OVERRIDE DS_FINAL
  {
    return BaseType::static_id() + ".constant";
  }

  virtual size_t order() const DS_OVERRIDE DS_FINAL
  {
    return 0;
  }

  virtual void evaluate(const DomainType& /*x*/, RangeType& ret) const DS_OVERRIDE DS_FINAL
  {
    ret = constant_;
  }

  virtual void jacobian(const DomainType& /*x*/, JacobianRangeType& ret) const DS_OVERRIDE DS_FINAL
  {
    ret *= 0.0;
  }

  virtual std::string name() const DS_OVERRIDE DS_FINAL
  {
    return name_;
  }

private:
  const RangeType constant_;
  const std::string name_;
};

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#ifdef DUNE_STUFF_FUNCTIONS_TO_LIB
# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(etype, ddim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, 1) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, 2) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, 3)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS(etype, ddim, rdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 1) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 2) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 3)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_RANGEFIELDTYPES(etype, double, ddim, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_RANGEFIELDTYPES(etype, dftype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION(etype, dftype, ddim, double, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION(etype, dftype, ddim, long double, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION(etype, dftype, ddim, rftype, rdim, rcdim) \
  extern template class Dune::Stuff::Functions::Constant< etype, dftype, ddim, rftype, rdim, rcdim >;

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesFake1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesFake2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesFake3dEntityType, 3)

# if HAVE_DUNE_GRID

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid3dEntityType, 3)

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid3dEntityType, 3)

#   if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H

DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid3dEntityType, 3)
DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluCubeGrid3dEntityType, 3)

#   endif // HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
# endif // HAVE_DUNE_GRID

# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LAST_EXPANSION
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_RANGEFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DOMAINFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGECOLS
# undef DUNE_STUFF_FUNCTIONS_CONSTANT_LIST_DIMRANGE
# endif // DUNE_STUFF_FUNCTIONS_TO_LIB

#endif // DUNE_STUFF_FUNCTIONS_CONSTANT_HH
<|endoftext|>


<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"

// dune-stuff
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/logstreams.hh>

namespace DSC = Dune::Stuff::Common;

void balh(std::ostream& out) {
  static int c = 0;
  out << "balh " << c << "\n";
  c++;
}

void do_something_that_takes_long(std::ostream& out)
{
  out << "  there should appear five dots, but not too fast:" << std::flush;
  for (unsigned int i = 0; i < 5; ++i){
    busywait(666);
    out << "." << std::flush;
  }
  out << std::endl;
} // void do_something_that_takes_long()

TEST(LoggerTest, all) {
  DSC::Logger().create(DSC::LOG_CONSOLE | DSC::LOG_ERROR);
  DSC::Logger().error() << "This should be in output\n";
  DSC::Logger().info() << "This should NOT be in output\n";
  DSC::Logger().debug() << "dito\n";
  DSC::Logger().flush();
  for (int i: {DSC::LOG_INFO, DSC::LOG_DEBUG, DSC::LOG_ERROR}) {
    const int id = DSC::Logger().addStream(DSC::LOG_CONSOLE | i);
    DSC::Logger().getStream(id) << "Create a new stream with id: " << id << std::endl;
  }
  DSC_LOG_ERROR.suspend();
  DSC_LOG_ERROR << "not in output\n";
  balh(DSC_LOG_ERROR);
  DSC_LOG_ERROR.resume();
  DSC_LOG_ERROR << "in output\n";
  balh(DSC_LOG_ERROR);

    //this should do nothing whatsoever
    balh(DSC::dev_null);
    DSC::Logger().flush();

    // this is the desired result:
    DSC::LogStream& err = DSC::Logger().error();
    std::cout << "begin std::cout test" << std::endl;
    do_something_that_takes_long(std::cout);
    std::cout << "end   std::cout test" << std::endl;
    std::cout << "begin Logger().error() test" << std::endl;
    do_something_that_takes_long(err);
    std::cout << "end   Logger().error() test" << std::endl;
}
<commit_msg>[test.common_logger] added "test" for file logging.<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"

// dune-stuff
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/logstreams.hh>

namespace DSC = Dune::Stuff::Common;

void balh(std::ostream& out) {
  static int c = 0;
  out << "balh " << c << "\n";
  c++;
}

void do_something_that_takes_long(std::ostream& out)
{
  out << "  there should appear five dots, but not too fast:" << std::flush;
  for (unsigned int i = 0; i < 5; ++i){
    busywait(666);
    out << "." << std::flush;
  }
  out << std::endl;
} // void do_something_that_takes_long()

TEST(LoggerTest, all) {
  DSC::Logger().create(DSC::LOG_CONSOLE | DSC::LOG_ERROR);
  DSC::Logger().error() << "This should be in output\n";
  DSC::Logger().info() << "This should NOT be in output\n";
  DSC::Logger().debug() << "dito\n";
  DSC::Logger().flush();
  for (int i: {DSC::LOG_INFO, DSC::LOG_DEBUG, DSC::LOG_ERROR}) {
    const int id = DSC::Logger().addStream(DSC::LOG_CONSOLE | i);
    DSC::Logger().getStream(id) << "Create a new stream with id: " << id << std::endl;
  }
  DSC_LOG_ERROR.suspend();
  DSC_LOG_ERROR << "not in output\n";
  balh(DSC_LOG_ERROR);
  DSC_LOG_ERROR.resume();
  DSC_LOG_ERROR << "in output\n";
  balh(DSC_LOG_ERROR);

  //this should do nothing whatsoever
  balh(DSC::dev_null);
  DSC::Logger().flush();

  // this is the desired result:
  DSC::LogStream& err = DSC::Logger().error();
  std::cout << "begin std::cout test" << std::endl;
  do_something_that_takes_long(std::cout);
  std::cout << "end   std::cout test" << std::endl;
  std::cout << "begin Logger().error() test" << std::endl;
  do_something_that_takes_long(err);
  std::cout << "end   Logger().error() test" << std::endl;
}

TEST(LoggerTest, file) {
  DSC::Logger().create(DSC::LOG_INFO | DSC::LOG_CONSOLE | DSC::LOG_FILE, "test_common_logger", "", "");
  DSC::Logger().info() << "This output should be in 'test_common_logger.log'" << std::endl;
}
<|endoftext|>


<commit_before>#include "client.h"
#include "../utils/exception.h"
#include "../utils/locker.h"
#include "../utils/logger.h"
#include "async_connection.h"
#include "net_common.h"

#include <json/json.hpp>
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <boost/asio.hpp>
#include <functional>
#include <thread>

using namespace std::placeholders;
using namespace boost::asio;

using namespace dariadb;
using namespace dariadb::net;

typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;

class Client::Private : public AsyncConnection {
public:
  Private(const Client::Param &p) : _params(p) {
    _query_num = 1;
    _state = ClientState::CONNECT;
    _pings_answers = 0;
  }

  ~Private() noexcept(false) {
    try {
      if (_state != ClientState::DISCONNECTED && _socket != nullptr) {
        this->disconnect();
      }
      if (_socket->is_open()) {
        boost::system::error_code err;
        _socket->cancel(err);
        if (err) {
          logger("client: #", id(), " on socket::cancel - ", err.message());
        }
      }
      _service.stop();
      _thread_handler.join();
    } catch (std::exception &ex) {
      THROW_EXCEPTION_SS("client: #" << id() << ex.what());
    }
  }

  void connect() {
    logger_info("client: connecting to ", _params.host, ':', _params.port);

    _state = ClientState::CONNECT;
    _thread_handler = std::move(std::thread{&Client::Private::client_thread, this});

    while (this->_state != ClientState::WORK) {
      std::this_thread::sleep_for(std::chrono::milliseconds(300));
    }
  }

  void disconnect() {
    if (_socket->is_open()) {
      auto nd = std::make_shared<NetData>(DISCONNECT_PREFIX);
      queue_clear();
      this->send(nd);
    }
    while (this->_state != ClientState::DISCONNECTED) {
      logger("client: #", id(), " disconnect - wait server answer...");
      std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
  }

  void client_thread() {
    ip::tcp::endpoint ep(ip::address::from_string(_params.host), _params.port);
    auto raw_sock_ptr = new ip::tcp::socket(_service);
    _socket = socket_ptr{raw_sock_ptr};
    _socket->async_connect(ep, std::bind(&Client::Private::connect_handler, this, _1));
    _service.run();
  }

  void onNetworkError(const boost::system::error_code &err) override {
    if (this->_state != ClientState::DISCONNECTED) {
      THROW_EXCEPTION_SS("client: #" << id() << err.message());
    }
  }

  void onDataRecv(const NetData_ptr &d) override {
    if (this->_state == ClientState::WORK) {
      logger("client: #", id(), " dataRecv ", d->size, " bytes.");
    } else {
      logger("client: dataRecv ", d->size, " bytes.");
    }

    if (d->size >= OK_ANSWER.size() &&
        memcmp(d->data, OK_ANSWER.data(), OK_ANSWER.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      auto query_num = stoi(msg.substr(3, msg.size()));
      logger("client: #", id(), " query #", query_num, " accepted.");
      if (this->_state != ClientState::WORK) {
        THROW_EXCEPTION_SS("(this->_state != ClientState::WORK)" << this->_state);
      }
      return;
    }

    if (d->size == PING_QUERY.size() &&
        memcmp(d->data, PING_QUERY.data(), PING_QUERY.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      logger("client: #", id(), " ping.");
      auto nd = std::make_shared<NetData>(PONG_ANSWER);
      this->send(nd);
      _pings_answers++;
      return;
    }

    if (d->size == DISCONNECT_ANSWER.size() &&
        memcmp(d->data, DISCONNECT_ANSWER.data(), DISCONNECT_ANSWER.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      logger("client: #", id(), " disconnection.");
      try{
      _state = ClientState::DISCONNECTED;
      this->full_stop();
      this->_socket->close();
      }catch(...){}
      logger("client: #", id(), " disconnected.");
      return;
    }

    // hello id
    if (d->size > HELLO_PREFIX.size() &&
        memcmp(HELLO_PREFIX.data(), d->data, HELLO_PREFIX.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      auto id = stoi(msg.substr(HELLO_PREFIX.size(), msg.size()));
      this->set_id(id);
      this->_state = ClientState::WORK;
      logger("client: #", id, " ready.");
    }
  }

  void connect_handler(const boost::system::error_code &ec) {
    if (ec) {
      THROW_EXCEPTION_SS("dariadb::client: error on connect - " << ec.message());
    }
    this->start(this->_socket);
    std::lock_guard<utils::Locker> lg(_locker);
    std::stringstream ss;
    ss << HELLO_PREFIX << ' ' << ip::host_name();

    auto hello_message = ss.str();
    logger("client: send hello ", hello_message.substr(0, hello_message.size() - 1));

    auto nd = std::make_shared<NetData>(hello_message);

    this->send(nd);
  }

  /* void onRead(const boost::system::error_code &err, size_t read_bytes) {
     logger("client: onRead...");
     if (err) {
           THROW_EXCEPTION_SS("client:  " << err.message());
     }

     std::istream iss(&this->buff);
     std::string msg;
     std::getline(iss, msg);
     logger("client: {", msg, "} readed_bytes: ", read_bytes);

     if (msg.size() > OK_ANSWER.size() && msg.substr(0, OK_ANSWER.size()) == OK_ANSWER) {
           auto query_num = stoi(msg.substr(3, msg.size()));
           logger("client: query #", query_num, " accepted.");
           if (this->_state == ClientState::WORK) {
                   auto query_str = msg.substr(OK_ANSWER.size()+1, msg.size());
                   auto delim_pos = query_str.find_first_of(' ');

                   auto count_str = query_str.substr(delim_pos, query_str.size());
                   auto count = stoi(count_str);

                   in_buffer_values.resize(count);

                   delim_pos = query_str.find_first_of('{');
                   query_str = query_str.substr(delim_pos, query_str.size());
                   auto qjs = nlohmann::json::parse(query_str);
                   auto result_array = qjs["result"];
                   size_t i = 0;
                   for (auto meas_js : result_array) {
                           Meas v;
                           v.id= meas_js["id"];
                           v.flag = meas_js["flag"];
                           v.src=meas_js["src"];
                           v.value=meas_js["value"];
                           this->in_buffer_values[i++] = v;
                   }
                   this->_query_locker->unlock();
           } else {
             this->_state = ClientState::WORK;
           }
     }

     if (msg == DISCONNECT_ANSWER) {
           logger("client: disconnected.");
           _state = ClientState::DISCONNECTED;
           this->_socket->close();
           return;
     }

     if (msg == PING_QUERY) {
           logger("client: ping.");
           async_write(*_socket.get(), buffer(PONG_ANSWER + "\n"),
                                   std::bind(&Client::Private::onPongSended, this, _1,
   _2));
     }

     logger_info("client: onRead - nextQuery");
     readNext();
   }*/

  /* void onPongSended(const boost::system::error_code &err, size_t read_bytes) {
         if (err) {
           THROW_EXCEPTION_SS("client::onPongSended - " << err.message());
         }
         _pings_answers++;
         logger("client: pong");
   }*/

  size_t pings_answers() const { return _pings_answers.load(); }
  ClientState state() const { return _state; }
  /*
  void write(const Meas::MeasArray &ma) {
    std::lock_guard<utils::Locker> lg(this->_locker);
    logger("client: write ", ma.size());
    utils::Locker locker;
    locker.lock();
    std::stringstream ss;
    ss << WRITE_QUERY << ' ' << ma.size() << '\n';
    std::string query = ss.str();
    async_write(*_socket.get(), buffer(query),
                            std::bind(&Client::Private::onWriteQuerySended, this, &locker,
                                                  ma.size(), ma, _1, _2));

    locker.lock();
  }

  void onWriteQuerySended(utils::Locker *locker, size_t to_send, Meas::MeasArray &ma,
                                                           const boost::system::error_code
  &err, size_t read_bytes) {
    if (err) {
          THROW_EXCEPTION_SS("client::onWriteQuerySended - " << err.message());
    }

    if (to_send != 0) {
          logger("client: write next part ", to_send, " values.");
          async_write(*_socket.get(), buffer(ma, to_send * sizeof(Meas)),
                                  std::bind(&Client::Private::onWriteQuerySended, this,
  locker,
                                                    size_t(0), ma, _1, _2));
    } else {
          locker->unlock();
    }
  }

  Meas::MeasList read(const storage::QueryInterval &qi) {
          std::lock_guard<utils::Locker> lg(this->_locker);

          auto qid = this->_query_num.load();
          this->_query_num++;

          std::stringstream ss;
          ss << READ_INTERVAL_QUERY
                  << ' '
                  << qid
                  << ' '
                  << qi.to_string()
                  << '\n';
          std::string query = ss.str();

          utils::Locker q_locker;
          q_locker.lock();
          this->_query_locker = &q_locker;

          async_write(*_socket.get(), buffer(query),
                  std::bind(&Client::Private::onReadQuerySended, this, _1, _2));

          q_locker.lock();
          Meas::MeasList result(in_buffer_values.begin(), in_buffer_values.end());
          in_buffer_values.clear();
          return result;
  }*/

  // void onReadQuerySended(const boost::system::error_code &err, size_t read_bytes) {
  // if (err) {
  //  THROW_EXCEPTION_SS("client::onReadQuerySended - " << err.message());
  // }

  // logger_info("client: onReadQuerySended - nextQuery");
  // /*readNext();*/
  //}

  io_service _service;
  socket_ptr _socket;
  streambuf buff;

  Client::Param _params;
  utils::Locker _locker;
  utils::Locker *_query_locker; // lock current query.
  std::thread _thread_handler;
  ClientState _state;
  std::atomic_size_t _pings_answers;

  std::atomic_int _query_num;
  Meas::MeasArray in_buffer_values;
};

Client::Client(const Param &p) : _Impl(new Client::Private(p)) {}

Client::~Client() {}

int Client::id() const {
  return _Impl->id();
}

void Client::connect() {
  _Impl->connect();
}

void Client::disconnect() {
  _Impl->disconnect();
}

ClientState Client::state() const {
  return _Impl->state();
}

size_t Client::pings_answers() const {
  return _Impl->pings_answers();
}

// void Client::write(const Meas::MeasArray &ma) {
//  _Impl->write(ma);
//}
//
// Meas::MeasList Client::read(const storage::QueryInterval &qi) {
//  return _Impl->read(qi);
//}
<commit_msg>try...catch<commit_after>#include "client.h"
#include "../utils/exception.h"
#include "../utils/locker.h"
#include "../utils/logger.h"
#include "async_connection.h"
#include "net_common.h"

#include <json/json.hpp>
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <boost/asio.hpp>
#include <functional>
#include <thread>

using namespace std::placeholders;
using namespace boost::asio;

using namespace dariadb;
using namespace dariadb::net;

typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;

class Client::Private : public AsyncConnection {
public:
  Private(const Client::Param &p) : _params(p) {
    _query_num = 1;
    _state = ClientState::CONNECT;
    _pings_answers = 0;
  }

  ~Private() noexcept(false) {
    try {
      if (_state != ClientState::DISCONNECTED && _socket != nullptr) {
        this->disconnect();
      }
      if (_socket->is_open()) {
        boost::system::error_code err;
        _socket->cancel(err);
        if (err) {
          logger("client: #", id(), " on socket::cancel - ", err.message());
        }
      }
      _service.stop();
      _thread_handler.join();
    } catch (std::exception &ex) {
      THROW_EXCEPTION_SS("client: #" << id() << ex.what());
    }
  }

  void connect() {
    logger_info("client: connecting to ", _params.host, ':', _params.port);

    _state = ClientState::CONNECT;
    _thread_handler = std::move(std::thread{&Client::Private::client_thread, this});

    while (this->_state != ClientState::WORK) {
      std::this_thread::sleep_for(std::chrono::milliseconds(300));
    }
  }

  void disconnect() {
    if (_socket->is_open()) {
      auto nd = std::make_shared<NetData>(DISCONNECT_PREFIX);
      queue_clear();
      this->send(nd);
    }
    while (this->_state != ClientState::DISCONNECTED) {
      logger("client: #", id(), " disconnect - wait server answer...");
      std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
  }

  void client_thread() {
    ip::tcp::endpoint ep(ip::address::from_string(_params.host), _params.port);
    auto raw_sock_ptr = new ip::tcp::socket(_service);
    _socket = socket_ptr{raw_sock_ptr};
    _socket->async_connect(ep, std::bind(&Client::Private::connect_handler, this, _1));
    _service.run();
  }

  void onNetworkError(const boost::system::error_code &err) override {
    if (this->_state != ClientState::DISCONNECTED) {
      THROW_EXCEPTION_SS("client: #" << id() << err.message());
    }
  }

  void onDataRecv(const NetData_ptr &d) override {
    if (this->_state == ClientState::WORK) {
      logger("client: #", id(), " dataRecv ", d->size, " bytes.");
    } else {
      logger("client: dataRecv ", d->size, " bytes.");
    }

    if (d->size >= OK_ANSWER.size() &&
        memcmp(d->data, OK_ANSWER.data(), OK_ANSWER.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      auto query_num = stoi(msg.substr(3, msg.size()));
      logger("client: #", id(), " query #", query_num, " accepted.");
      if (this->_state != ClientState::WORK) {
        THROW_EXCEPTION_SS("(this->_state != ClientState::WORK)" << this->_state);
      }
      return;
    }

    if (d->size == PING_QUERY.size() &&
        memcmp(d->data, PING_QUERY.data(), PING_QUERY.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      logger("client: #", id(), " ping.");
      auto nd = std::make_shared<NetData>(PONG_ANSWER);
      this->send(nd);
      _pings_answers++;
      return;
    }

    if (d->size == DISCONNECT_ANSWER.size() &&
        memcmp(d->data, DISCONNECT_ANSWER.data(), DISCONNECT_ANSWER.size()) ==
            0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      logger("client: #", id(), " disconnection.");
      try {
        _state = ClientState::DISCONNECTED;
        this->full_stop();
        this->_socket->close();
      } catch (...) {
      }
      logger("client: #", id(), " disconnected.");
      return;
    }

    // hello id
    if (d->size > HELLO_PREFIX.size() &&
        memcmp(HELLO_PREFIX.data(), d->data, HELLO_PREFIX.size()) == 0) {
      std::string msg((char *)d->data, (char *)(d->data + d->size));
      auto id = stoi(msg.substr(HELLO_PREFIX.size(), msg.size()));
      this->set_id(id);
      this->_state = ClientState::WORK;
      logger("client: #", id, " ready.");
    }
  }

  void connect_handler(const boost::system::error_code &ec) {
    if (ec) {
      THROW_EXCEPTION_SS("dariadb::client: error on connect - " << ec.message());
    }
    this->start(this->_socket);
    std::lock_guard<utils::Locker> lg(_locker);
    std::stringstream ss;
    ss << HELLO_PREFIX << ' ' << ip::host_name();

    auto hello_message = ss.str();
    logger("client: send hello ", hello_message.substr(0, hello_message.size() - 1));

    auto nd = std::make_shared<NetData>(hello_message);

    this->send(nd);
  }

  /* void onRead(const boost::system::error_code &err, size_t read_bytes) {
     logger("client: onRead...");
     if (err) {
           THROW_EXCEPTION_SS("client:  " << err.message());
     }

     std::istream iss(&this->buff);
     std::string msg;
     std::getline(iss, msg);
     logger("client: {", msg, "} readed_bytes: ", read_bytes);

     if (msg.size() > OK_ANSWER.size() && msg.substr(0, OK_ANSWER.size()) == OK_ANSWER) {
           auto query_num = stoi(msg.substr(3, msg.size()));
           logger("client: query #", query_num, " accepted.");
           if (this->_state == ClientState::WORK) {
                   auto query_str = msg.substr(OK_ANSWER.size()+1, msg.size());
                   auto delim_pos = query_str.find_first_of(' ');

                   auto count_str = query_str.substr(delim_pos, query_str.size());
                   auto count = stoi(count_str);

                   in_buffer_values.resize(count);

                   delim_pos = query_str.find_first_of('{');
                   query_str = query_str.substr(delim_pos, query_str.size());
                   auto qjs = nlohmann::json::parse(query_str);
                   auto result_array = qjs["result"];
                   size_t i = 0;
                   for (auto meas_js : result_array) {
                           Meas v;
                           v.id= meas_js["id"];
                           v.flag = meas_js["flag"];
                           v.src=meas_js["src"];
                           v.value=meas_js["value"];
                           this->in_buffer_values[i++] = v;
                   }
                   this->_query_locker->unlock();
           } else {
             this->_state = ClientState::WORK;
           }
     }

     if (msg == DISCONNECT_ANSWER) {
           logger("client: disconnected.");
           _state = ClientState::DISCONNECTED;
           this->_socket->close();
           return;
     }

     if (msg == PING_QUERY) {
           logger("client: ping.");
           async_write(*_socket.get(), buffer(PONG_ANSWER + "\n"),
                                   std::bind(&Client::Private::onPongSended, this, _1,
   _2));
     }

     logger_info("client: onRead - nextQuery");
     readNext();
   }*/

  /* void onPongSended(const boost::system::error_code &err, size_t read_bytes) {
         if (err) {
           THROW_EXCEPTION_SS("client::onPongSended - " << err.message());
         }
         _pings_answers++;
         logger("client: pong");
   }*/

  size_t pings_answers() const { return _pings_answers.load(); }
  ClientState state() const { return _state; }
  /*
  void write(const Meas::MeasArray &ma) {
    std::lock_guard<utils::Locker> lg(this->_locker);
    logger("client: write ", ma.size());
    utils::Locker locker;
    locker.lock();
    std::stringstream ss;
    ss << WRITE_QUERY << ' ' << ma.size() << '\n';
    std::string query = ss.str();
    async_write(*_socket.get(), buffer(query),
                            std::bind(&Client::Private::onWriteQuerySended, this, &locker,
                                                  ma.size(), ma, _1, _2));

    locker.lock();
  }

  void onWriteQuerySended(utils::Locker *locker, size_t to_send, Meas::MeasArray &ma,
                                                           const boost::system::error_code
  &err, size_t read_bytes) {
    if (err) {
          THROW_EXCEPTION_SS("client::onWriteQuerySended - " << err.message());
    }

    if (to_send != 0) {
          logger("client: write next part ", to_send, " values.");
          async_write(*_socket.get(), buffer(ma, to_send * sizeof(Meas)),
                                  std::bind(&Client::Private::onWriteQuerySended, this,
  locker,
                                                    size_t(0), ma, _1, _2));
    } else {
          locker->unlock();
    }
  }

  Meas::MeasList read(const storage::QueryInterval &qi) {
          std::lock_guard<utils::Locker> lg(this->_locker);

          auto qid = this->_query_num.load();
          this->_query_num++;

          std::stringstream ss;
          ss << READ_INTERVAL_QUERY
                  << ' '
                  << qid
                  << ' '
                  << qi.to_string()
                  << '\n';
          std::string query = ss.str();

          utils::Locker q_locker;
          q_locker.lock();
          this->_query_locker = &q_locker;

          async_write(*_socket.get(), buffer(query),
                  std::bind(&Client::Private::onReadQuerySended, this, _1, _2));

          q_locker.lock();
          Meas::MeasList result(in_buffer_values.begin(), in_buffer_values.end());
          in_buffer_values.clear();
          return result;
  }*/

  // void onReadQuerySended(const boost::system::error_code &err, size_t read_bytes) {
  // if (err) {
  //  THROW_EXCEPTION_SS("client::onReadQuerySended - " << err.message());
  // }

  // logger_info("client: onReadQuerySended - nextQuery");
  // /*readNext();*/
  //}

  io_service _service;
  socket_ptr _socket;
  streambuf buff;

  Client::Param _params;
  utils::Locker _locker;
  utils::Locker *_query_locker; // lock current query.
  std::thread _thread_handler;
  ClientState _state;
  std::atomic_size_t _pings_answers;

  std::atomic_int _query_num;
  Meas::MeasArray in_buffer_values;
};

Client::Client(const Param &p) : _Impl(new Client::Private(p)) {}

Client::~Client() {}

int Client::id() const {
  return _Impl->id();
}

void Client::connect() {
  _Impl->connect();
}

void Client::disconnect() {
  _Impl->disconnect();
}

ClientState Client::state() const {
  return _Impl->state();
}

size_t Client::pings_answers() const {
  return _Impl->pings_answers();
}

// void Client::write(const Meas::MeasArray &ma) {
//  _Impl->write(ma);
//}
//
// Meas::MeasList Client::read(const storage::QueryInterval &qi) {
//  return _Impl->read(qi);
//}
<|endoftext|>


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

#include "sandbox/win/src/process_mitigations.h"

#include <algorithm>

#include "base/win/windows_version.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_utils.h"
#include "sandbox/win/src/win_utils.h"

namespace {

// Functions for enabling policies.
typedef BOOL (WINAPI *SetProcessDEPPolicyFunction)(DWORD dwFlags);

typedef BOOL (WINAPI *SetProcessMitigationPolicyFunction)(
    PROCESS_MITIGATION_POLICY mitigation_policy,
    PVOID buffer,
    SIZE_T length);

typedef BOOL (WINAPI *SetDefaultDllDirectoriesFunction)(
    DWORD DirectoryFlags);

}  // namespace

namespace sandbox {

bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) {
  if (!CanSetProcessMitigationsPostStartup(flags))
    return false;

  // We can't apply anything before Win XP, so just return cleanly.
  if (!IsXPSP2OrLater())
    return true;

  base::win::Version version = base::win::GetVersion();
  HMODULE module = ::GetModuleHandleA("kernel32.dll");

  if (version >= base::win::VERSION_VISTA &&
      (flags & MITIGATION_DLL_SEARCH_ORDER)) {
    SetDefaultDllDirectoriesFunction set_default_dll_directories =
        reinterpret_cast<SetDefaultDllDirectoriesFunction>(
            ::GetProcAddress(module, "SetDefaultDllDirectories"));

    // Check for SetDefaultDllDirectories since it requires KB2533623.
    if (set_default_dll_directories) {
      if (!set_default_dll_directories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) &&
          ERROR_ACCESS_DENIED != ::GetLastError()) {
        return false;
      }
    }
  }

  // Set the heap to terminate on corruption
  if (version >= base::win::VERSION_VISTA &&
      (flags & MITIGATION_HEAP_TERMINATE)) {
    if (!::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption,
                              NULL, 0) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

#if !defined(_WIN64)  // DEP is always enabled on 64-bit.
  if (flags & MITIGATION_DEP) {
    DWORD dep_flags = PROCESS_DEP_ENABLE;
    // DEP support is quirky on XP, so don't force a failure in that case.
    const bool return_on_fail = version >= base::win::VERSION_VISTA;

    if (flags & MITIGATION_DEP_NO_ATL_THUNK)
      dep_flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION;

    SetProcessDEPPolicyFunction set_process_dep_policy =
        reinterpret_cast<SetProcessDEPPolicyFunction>(
            ::GetProcAddress(module, "SetProcessDEPPolicy"));
    if (set_process_dep_policy) {
      if (!set_process_dep_policy(dep_flags) &&
          ERROR_ACCESS_DENIED != ::GetLastError() && return_on_fail) {
        return false;
      }
    } else {
      // We're on XP sp2, so use the less standard approach.
      // For reference: http://www.uninformed.org/?v=2&a=4
      const int MEM_EXECUTE_OPTION_ENABLE = 1;
      const int MEM_EXECUTE_OPTION_DISABLE = 2;
      const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4;
      const int MEM_EXECUTE_OPTION_PERMANENT = 8;

      NtSetInformationProcessFunction set_information_process = NULL;
      ResolveNTFunctionPtr("NtSetInformationProcess",
                           &set_information_process);
      if (!set_information_process)
        return false;
      ULONG dep = MEM_EXECUTE_OPTION_DISABLE | MEM_EXECUTE_OPTION_PERMANENT;
      if (!(dep_flags & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION))
        dep |= MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION;
      if (!SUCCEEDED(set_information_process(GetCurrentProcess(),
                                             ProcessExecuteFlags,
                                             &dep, sizeof(dep))) &&
          ERROR_ACCESS_DENIED != ::GetLastError() && return_on_fail) {
        return false;
      }
    }
  }
#endif

  // This is all we can do in Win7 and below.
  if (version < base::win::VERSION_WIN8)
    return true;

  SetProcessMitigationPolicyFunction set_process_mitigation_policy =
      reinterpret_cast<SetProcessMitigationPolicyFunction>(
          ::GetProcAddress(module, "SetProcessMitigationPolicy"));
  if (!set_process_mitigation_policy)
    return false;

  // Enable ASLR policies.
  if (flags & MITIGATION_RELOCATE_IMAGE) {
    PROCESS_MITIGATION_ASLR_POLICY policy = { 0 };
    policy.EnableForceRelocateImages = true;
    policy.DisallowStrippedImages = (flags &
        MITIGATION_RELOCATE_IMAGE_REQUIRED) ==
        MITIGATION_RELOCATE_IMAGE_REQUIRED;

    if (!set_process_mitigation_policy(ProcessASLRPolicy, &policy,
                                       sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  // Enable strict handle policies.
  if (flags & MITIGATION_STRICT_HANDLE_CHECKS) {
    PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy = { 0 };
    policy.HandleExceptionsPermanentlyEnabled =
        policy.RaiseExceptionOnInvalidHandleReference = true;

    if (!set_process_mitigation_policy(ProcessStrictHandleCheckPolicy, &policy,
                                       sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  // Enable system call policies.
  if (flags & MITIGATION_WIN32K_DISABLE) {
    PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = { 0 };
    policy.DisallowWin32kSystemCalls = true;

    if (!set_process_mitigation_policy(ProcessSystemCallDisablePolicy, &policy,
                                       sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  // Enable system call policies.
  if (flags & MITIGATION_EXTENSION_DLL_DISABLE) {
    PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = { 0 };
    policy.DisableExtensionPoints = true;

    if (!set_process_mitigation_policy(ProcessExtensionPointDisablePolicy,
                                       &policy, sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  return true;
}

void ConvertProcessMitigationsToPolicy(MitigationFlags flags,
                                       DWORD64* policy_flags, size_t* size) {
  base::win::Version version = base::win::GetVersion();

  *policy_flags = 0;
#if defined(_WIN64)
  *size = sizeof(*policy_flags);
#elif defined(_M_IX86)
  // A 64-bit flags attribute is illegal on 32-bit Win 7 and below.
  if (version < base::win::VERSION_WIN8)
    *size = sizeof(DWORD);
  else
    *size = sizeof(*policy_flags);
#else
#error This platform is not supported.
#endif

  // Nothing for Win XP or Vista.
  if (version <= base::win::VERSION_VISTA)
    return;

  // DEP and SEHOP are not valid for 64-bit Windows
#if !defined(_WIN64)
  if (flags & MITIGATION_DEP) {
    *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE;
    if (!(flags & MITIGATION_DEP_NO_ATL_THUNK))
      *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE;
  }

  if (flags & MITIGATION_SEHOP)
    *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE;
#endif

  // Win 7
  if (version < base::win::VERSION_WIN8)
    return;

  if (flags & MITIGATION_RELOCATE_IMAGE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON;
    if (flags & MITIGATION_RELOCATE_IMAGE_REQUIRED) {
      *policy_flags |=
          PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS;
    }
  }

  if (flags & MITIGATION_HEAP_TERMINATE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON;
  }

  if (flags & MITIGATION_BOTTOM_UP_ASLR) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON;
  }

  if (flags & MITIGATION_HIGH_ENTROPY_ASLR) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON;
  }

  if (flags & MITIGATION_STRICT_HANDLE_CHECKS) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON;
  }

  if (flags & MITIGATION_WIN32K_DISABLE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON;
  }

  if (flags & MITIGATION_EXTENSION_DLL_DISABLE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON;
  }
}

MitigationFlags FilterPostStartupProcessMitigations(MitigationFlags flags) {
  // Anything prior to XP SP2.
  if (!IsXPSP2OrLater())
    return 0;

  base::win::Version version = base::win::GetVersion();

  // Windows XP SP2+.
  if (version < base::win::VERSION_VISTA) {
    return flags & (MITIGATION_DEP |
                    MITIGATION_DEP_NO_ATL_THUNK);

  // Windows Vista
  if (version < base::win::VERSION_WIN7) {
    return flags & (MITIGATION_DEP |
                    MITIGATION_DEP_NO_ATL_THUNK |
                    MITIGATION_BOTTOM_UP_ASLR |
                    MITIGATION_DLL_SEARCH_ORDER |
                    MITIGATION_HEAP_TERMINATE);
  }

  // Windows 7 and Vista.
  } else if (version < base::win::VERSION_WIN8) {
    return flags & (MITIGATION_BOTTOM_UP_ASLR |
                    MITIGATION_DLL_SEARCH_ORDER |
                    MITIGATION_HEAP_TERMINATE);
  }

  // Windows 8 and above.
  return flags & (MITIGATION_BOTTOM_UP_ASLR |
                  MITIGATION_DLL_SEARCH_ORDER);
}

bool ApplyProcessMitigationsToSuspendedProcess(HANDLE process,
                                               MitigationFlags flags) {
// This is a hack to fake a weak bottom-up ASLR on 32-bit Windows.
#if !defined(_WIN64)
  if (flags & MITIGATION_BOTTOM_UP_ASLR) {
    unsigned int limit;
    rand_s(&limit);
    char* ptr = 0;
    const size_t kMask64k = 0xFFFF;
    // Random range (512k-16.5mb) in 64k steps.
    const char* end = ptr + ((((limit % 16384) + 512) * 1024) & ~kMask64k);
    while (ptr < end) {
      MEMORY_BASIC_INFORMATION memory_info;
      if (!::VirtualQueryEx(process, ptr, &memory_info, sizeof(memory_info)))
        break;
      size_t size = std::min((memory_info.RegionSize + kMask64k) & ~kMask64k,
                             static_cast<SIZE_T>(end - ptr));
      if (ptr && memory_info.State == MEM_FREE)
        ::VirtualAllocEx(process, ptr, size, MEM_RESERVE, PAGE_NOACCESS);
      ptr += size;
    }
  }
#endif

  return true;
}

bool CanSetProcessMitigationsPostStartup(MitigationFlags flags) {
  // All of these mitigations can be enabled after startup.
  return !(flags & ~(MITIGATION_HEAP_TERMINATE |
                     MITIGATION_DEP |
                     MITIGATION_DEP_NO_ATL_THUNK |
                     MITIGATION_RELOCATE_IMAGE |
                     MITIGATION_RELOCATE_IMAGE_REQUIRED |
                     MITIGATION_BOTTOM_UP_ASLR |
                     MITIGATION_STRICT_HANDLE_CHECKS |
                     MITIGATION_WIN32K_DISABLE |
                     MITIGATION_EXTENSION_DLL_DISABLE |
                     MITIGATION_DLL_SEARCH_ORDER));
}

bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) {
  // These mitigations cannot be enabled prior to startup.
  return !(flags & (MITIGATION_STRICT_HANDLE_CHECKS |
                    MITIGATION_WIN32K_DISABLE |
                    MITIGATION_DLL_SEARCH_ORDER));
}

}  // namespace sandbox

<commit_msg>Fix unreachable code in sandbox/.  Found with MSVC warning 4702.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/win/src/process_mitigations.h"

#include <algorithm>

#include "base/win/windows_version.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_utils.h"
#include "sandbox/win/src/win_utils.h"

namespace {

// Functions for enabling policies.
typedef BOOL (WINAPI *SetProcessDEPPolicyFunction)(DWORD dwFlags);

typedef BOOL (WINAPI *SetProcessMitigationPolicyFunction)(
    PROCESS_MITIGATION_POLICY mitigation_policy,
    PVOID buffer,
    SIZE_T length);

typedef BOOL (WINAPI *SetDefaultDllDirectoriesFunction)(
    DWORD DirectoryFlags);

}  // namespace

namespace sandbox {

bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) {
  if (!CanSetProcessMitigationsPostStartup(flags))
    return false;

  // We can't apply anything before Win XP, so just return cleanly.
  if (!IsXPSP2OrLater())
    return true;

  base::win::Version version = base::win::GetVersion();
  HMODULE module = ::GetModuleHandleA("kernel32.dll");

  if (version >= base::win::VERSION_VISTA &&
      (flags & MITIGATION_DLL_SEARCH_ORDER)) {
    SetDefaultDllDirectoriesFunction set_default_dll_directories =
        reinterpret_cast<SetDefaultDllDirectoriesFunction>(
            ::GetProcAddress(module, "SetDefaultDllDirectories"));

    // Check for SetDefaultDllDirectories since it requires KB2533623.
    if (set_default_dll_directories) {
      if (!set_default_dll_directories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) &&
          ERROR_ACCESS_DENIED != ::GetLastError()) {
        return false;
      }
    }
  }

  // Set the heap to terminate on corruption
  if (version >= base::win::VERSION_VISTA &&
      (flags & MITIGATION_HEAP_TERMINATE)) {
    if (!::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption,
                              NULL, 0) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

#if !defined(_WIN64)  // DEP is always enabled on 64-bit.
  if (flags & MITIGATION_DEP) {
    DWORD dep_flags = PROCESS_DEP_ENABLE;
    // DEP support is quirky on XP, so don't force a failure in that case.
    const bool return_on_fail = version >= base::win::VERSION_VISTA;

    if (flags & MITIGATION_DEP_NO_ATL_THUNK)
      dep_flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION;

    SetProcessDEPPolicyFunction set_process_dep_policy =
        reinterpret_cast<SetProcessDEPPolicyFunction>(
            ::GetProcAddress(module, "SetProcessDEPPolicy"));
    if (set_process_dep_policy) {
      if (!set_process_dep_policy(dep_flags) &&
          ERROR_ACCESS_DENIED != ::GetLastError() && return_on_fail) {
        return false;
      }
    } else {
      // We're on XP sp2, so use the less standard approach.
      // For reference: http://www.uninformed.org/?v=2&a=4
      const int MEM_EXECUTE_OPTION_ENABLE = 1;
      const int MEM_EXECUTE_OPTION_DISABLE = 2;
      const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4;
      const int MEM_EXECUTE_OPTION_PERMANENT = 8;

      NtSetInformationProcessFunction set_information_process = NULL;
      ResolveNTFunctionPtr("NtSetInformationProcess",
                           &set_information_process);
      if (!set_information_process)
        return false;
      ULONG dep = MEM_EXECUTE_OPTION_DISABLE | MEM_EXECUTE_OPTION_PERMANENT;
      if (!(dep_flags & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION))
        dep |= MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION;
      if (!SUCCEEDED(set_information_process(GetCurrentProcess(),
                                             ProcessExecuteFlags,
                                             &dep, sizeof(dep))) &&
          ERROR_ACCESS_DENIED != ::GetLastError() && return_on_fail) {
        return false;
      }
    }
  }
#endif

  // This is all we can do in Win7 and below.
  if (version < base::win::VERSION_WIN8)
    return true;

  SetProcessMitigationPolicyFunction set_process_mitigation_policy =
      reinterpret_cast<SetProcessMitigationPolicyFunction>(
          ::GetProcAddress(module, "SetProcessMitigationPolicy"));
  if (!set_process_mitigation_policy)
    return false;

  // Enable ASLR policies.
  if (flags & MITIGATION_RELOCATE_IMAGE) {
    PROCESS_MITIGATION_ASLR_POLICY policy = { 0 };
    policy.EnableForceRelocateImages = true;
    policy.DisallowStrippedImages = (flags &
        MITIGATION_RELOCATE_IMAGE_REQUIRED) ==
        MITIGATION_RELOCATE_IMAGE_REQUIRED;

    if (!set_process_mitigation_policy(ProcessASLRPolicy, &policy,
                                       sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  // Enable strict handle policies.
  if (flags & MITIGATION_STRICT_HANDLE_CHECKS) {
    PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy = { 0 };
    policy.HandleExceptionsPermanentlyEnabled =
        policy.RaiseExceptionOnInvalidHandleReference = true;

    if (!set_process_mitigation_policy(ProcessStrictHandleCheckPolicy, &policy,
                                       sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  // Enable system call policies.
  if (flags & MITIGATION_WIN32K_DISABLE) {
    PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = { 0 };
    policy.DisallowWin32kSystemCalls = true;

    if (!set_process_mitigation_policy(ProcessSystemCallDisablePolicy, &policy,
                                       sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  // Enable system call policies.
  if (flags & MITIGATION_EXTENSION_DLL_DISABLE) {
    PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = { 0 };
    policy.DisableExtensionPoints = true;

    if (!set_process_mitigation_policy(ProcessExtensionPointDisablePolicy,
                                       &policy, sizeof(policy)) &&
        ERROR_ACCESS_DENIED != ::GetLastError()) {
      return false;
    }
  }

  return true;
}

void ConvertProcessMitigationsToPolicy(MitigationFlags flags,
                                       DWORD64* policy_flags, size_t* size) {
  base::win::Version version = base::win::GetVersion();

  *policy_flags = 0;
#if defined(_WIN64)
  *size = sizeof(*policy_flags);
#elif defined(_M_IX86)
  // A 64-bit flags attribute is illegal on 32-bit Win 7 and below.
  if (version < base::win::VERSION_WIN8)
    *size = sizeof(DWORD);
  else
    *size = sizeof(*policy_flags);
#else
#error This platform is not supported.
#endif

  // Nothing for Win XP or Vista.
  if (version <= base::win::VERSION_VISTA)
    return;

  // DEP and SEHOP are not valid for 64-bit Windows
#if !defined(_WIN64)
  if (flags & MITIGATION_DEP) {
    *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE;
    if (!(flags & MITIGATION_DEP_NO_ATL_THUNK))
      *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE;
  }

  if (flags & MITIGATION_SEHOP)
    *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE;
#endif

  // Win 7
  if (version < base::win::VERSION_WIN8)
    return;

  if (flags & MITIGATION_RELOCATE_IMAGE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON;
    if (flags & MITIGATION_RELOCATE_IMAGE_REQUIRED) {
      *policy_flags |=
          PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS;
    }
  }

  if (flags & MITIGATION_HEAP_TERMINATE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON;
  }

  if (flags & MITIGATION_BOTTOM_UP_ASLR) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON;
  }

  if (flags & MITIGATION_HIGH_ENTROPY_ASLR) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON;
  }

  if (flags & MITIGATION_STRICT_HANDLE_CHECKS) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON;
  }

  if (flags & MITIGATION_WIN32K_DISABLE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON;
  }

  if (flags & MITIGATION_EXTENSION_DLL_DISABLE) {
    *policy_flags |=
        PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON;
  }
}

MitigationFlags FilterPostStartupProcessMitigations(MitigationFlags flags) {
  // Anything prior to XP SP2.
  if (!IsXPSP2OrLater())
    return 0;

  base::win::Version version = base::win::GetVersion();

  // Windows XP SP2+.
  if (version < base::win::VERSION_VISTA) {
    return flags & (MITIGATION_DEP |
                    MITIGATION_DEP_NO_ATL_THUNK);
  }

  // Windows Vista
  if (version < base::win::VERSION_WIN7) {
    return flags & (MITIGATION_DEP |
                    MITIGATION_DEP_NO_ATL_THUNK |
                    MITIGATION_BOTTOM_UP_ASLR |
                    MITIGATION_DLL_SEARCH_ORDER |
                    MITIGATION_HEAP_TERMINATE);
  }

  // Windows 7.
  if (version < base::win::VERSION_WIN8) {
    return flags & (MITIGATION_BOTTOM_UP_ASLR |
                    MITIGATION_DLL_SEARCH_ORDER |
                    MITIGATION_HEAP_TERMINATE);
  }

  // Windows 8 and above.
  return flags & (MITIGATION_BOTTOM_UP_ASLR |
                  MITIGATION_DLL_SEARCH_ORDER);
}

bool ApplyProcessMitigationsToSuspendedProcess(HANDLE process,
                                               MitigationFlags flags) {
// This is a hack to fake a weak bottom-up ASLR on 32-bit Windows.
#if !defined(_WIN64)
  if (flags & MITIGATION_BOTTOM_UP_ASLR) {
    unsigned int limit;
    rand_s(&limit);
    char* ptr = 0;
    const size_t kMask64k = 0xFFFF;
    // Random range (512k-16.5mb) in 64k steps.
    const char* end = ptr + ((((limit % 16384) + 512) * 1024) & ~kMask64k);
    while (ptr < end) {
      MEMORY_BASIC_INFORMATION memory_info;
      if (!::VirtualQueryEx(process, ptr, &memory_info, sizeof(memory_info)))
        break;
      size_t size = std::min((memory_info.RegionSize + kMask64k) & ~kMask64k,
                             static_cast<SIZE_T>(end - ptr));
      if (ptr && memory_info.State == MEM_FREE)
        ::VirtualAllocEx(process, ptr, size, MEM_RESERVE, PAGE_NOACCESS);
      ptr += size;
    }
  }
#endif

  return true;
}

bool CanSetProcessMitigationsPostStartup(MitigationFlags flags) {
  // All of these mitigations can be enabled after startup.
  return !(flags & ~(MITIGATION_HEAP_TERMINATE |
                     MITIGATION_DEP |
                     MITIGATION_DEP_NO_ATL_THUNK |
                     MITIGATION_RELOCATE_IMAGE |
                     MITIGATION_RELOCATE_IMAGE_REQUIRED |
                     MITIGATION_BOTTOM_UP_ASLR |
                     MITIGATION_STRICT_HANDLE_CHECKS |
                     MITIGATION_WIN32K_DISABLE |
                     MITIGATION_EXTENSION_DLL_DISABLE |
                     MITIGATION_DLL_SEARCH_ORDER));
}

bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) {
  // These mitigations cannot be enabled prior to startup.
  return !(flags & (MITIGATION_STRICT_HANDLE_CHECKS |
                    MITIGATION_WIN32K_DISABLE |
                    MITIGATION_DLL_SEARCH_ORDER));
}

}  // namespace sandbox

<|endoftext|>


<commit_before>/*
    This file is part of libkcal.
    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

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

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

// $Id$

#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>

#include "calformat.h"

#include "incidencebase.h"

using namespace KCal;

IncidenceBase::IncidenceBase() :
  mReadOnly(false), mFloats(true), mDuration(0), mHasDuration(false),
  mPilotId(0), mSyncStatus(SYNCMOD), mObserver(0)
{
  setUid(CalFormat::createUniqueId());
}

IncidenceBase::IncidenceBase(const IncidenceBase &i)
{
  mReadOnly = i.mReadOnly;
  mDtStart = i.mDtStart;
  mDuration = i.mDuration;
  mHasDuration = i.mHasDuration;
  mOrganizer = i.mOrganizer;
  mUid = i.mUid;
  mAttendees = i.attendees();
  mFloats = i.mFloats;
  mLastModified = i.mLastModified;
  mPilotId = i.mPilotId;
  mSyncStatus = i.mSyncStatus;
}

IncidenceBase::~IncidenceBase()
{
}

void IncidenceBase::setUid(const QString &uid)
{
  mUid = uid;
  updated();
}

QString IncidenceBase::uid() const
{
  return mUid;
}

void IncidenceBase::setLastModified(const QDateTime &lm)
{
  // DON'T! updated() because we call this from
  // Calendar::updateEvent().
  mLastModified = lm;
}

QDateTime IncidenceBase::lastModified() const
{
  return mLastModified;
}

void IncidenceBase::setOrganizer(const QString &o)
{
  // we don't check for readonly here, because it is
  // possible that by setting the organizer we are changing
  // the event's readonly status...
  mOrganizer = o;
  if (mOrganizer.left(7).upper() == "MAILTO:")
    mOrganizer = mOrganizer.remove(0,7);

  updated();
}

QString IncidenceBase::organizer() const
{
  return mOrganizer;
}

void IncidenceBase::setReadOnly( bool readOnly )
{
  mReadOnly = readOnly;
}

void IncidenceBase::setDtStart(const QDateTime &dtStart)
{
//  if (mReadOnly) return;
  mDtStart = dtStart;
  updated();
}

QDateTime IncidenceBase::dtStart() const
{
  return mDtStart;
}

QString IncidenceBase::dtStartTimeStr() const
{
  return KGlobal::locale()->formatTime(dtStart().time());
}

QString IncidenceBase::dtStartDateStr(bool shortfmt) const
{
  return KGlobal::locale()->formatDate(dtStart().date(),shortfmt);
}

QString IncidenceBase::dtStartStr() const
{
  return KGlobal::locale()->formatDateTime(dtStart());
}

bool IncidenceBase::doesFloat() const
{
  return mFloats;
}

void IncidenceBase::setFloats(bool f)
{
  if (mReadOnly) return;
  mFloats = f;
  updated();
}

void IncidenceBase::addAttendee(Attendee *a, bool doupdate)
{
//  kdDebug(5800) << "IncidenceBase::addAttendee()" << endl;
  if (mReadOnly) return;
//  kdDebug(5800) << "IncidenceBase::addAttendee() weiter" << endl;
  if (a->name().left(7).upper() == "MAILTO:")
    a->setName(a->name().remove(0,7));

  mAttendees.append(a);
  if (doupdate) updated();
}

#if 0
void IncidenceBase::removeAttendee(Attendee *a)
{
  if (mReadOnly) return;
  mAttendees.removeRef(a);
  updated();
}

void IncidenceBase::removeAttendee(const char *n)
{
  Attendee *a;

  if (mReadOnly) return;
  for (a = mAttendees.first(); a; a = mAttendees.next())
    if (a->getName() == n) {
      mAttendees.remove();
      break;
    }
}
#endif

void IncidenceBase::clearAttendees()
{
  if (mReadOnly) return;
  mAttendees.clear();
}

#if 0
Attendee *IncidenceBase::getAttendee(const char *n) const
{
  QPtrListIterator<Attendee> qli(mAttendees);

  qli.toFirst();
  while (qli) {
    if (qli.current()->getName() == n)
      return qli.current();
    ++qli;
  }
  return 0L;
}
#endif

Attendee *IncidenceBase::attendeeByMail(const QString &email)
{
  QPtrListIterator<Attendee> qli(mAttendees);

  qli.toFirst();
  while (qli) {
    if (qli.current()->email() == email)
      return qli.current();
    ++qli;
  }
  return 0L;
}

Attendee *IncidenceBase::attendeeByMails(const QStringList &emails, QString email)
{
  QPtrListIterator<Attendee> qli(mAttendees);

  QStringList mails = emails;
  if (!email.isEmpty()) {
    mails.append(email);
  }
  qli.toFirst();
  while (qli) {
    for ( QStringList::Iterator it = mails.begin(); it != mails.end(); ++it ) {
      if (qli.current()->email() == *it)
        return qli.current();
     }

    ++qli;
  }
  return 0L;
}

void IncidenceBase::setDuration(int seconds)
{
  mDuration = seconds;
  setHasDuration(true);
}

int IncidenceBase::duration() const
{
  return mDuration;
}

void IncidenceBase::setHasDuration(bool)
{
  mHasDuration = true;
}

bool IncidenceBase::hasDuration() const
{
  return mHasDuration;
}

void IncidenceBase::setSyncStatus(int stat)
{
  if (mReadOnly) return;
  mSyncStatus = stat;
}

int IncidenceBase::syncStatus() const
{
  return mSyncStatus;
}

void IncidenceBase::setPilotId( int id )
{
  if (mReadOnly) return;

  mPilotId = id;
}

int IncidenceBase::pilotId() const
{
  return mPilotId;
}

void IncidenceBase::registerObserver( IncidenceBase::Observer *observer )
{
  mObserver = observer;
}

void IncidenceBase::updated()
{
  if ( mObserver ) {
    mObserver->incidenceUpdated( this );
  }
}
<commit_msg><commit_after>/*
    This file is part of libkcal.
    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

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

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

// $Id$

#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>

#include "calformat.h"

#include "incidencebase.h"

using namespace KCal;

IncidenceBase::IncidenceBase() :
  mReadOnly(false), mFloats(true), mDuration(0), mHasDuration(false),
  mPilotId(0), mSyncStatus(SYNCMOD), mObserver(0)
{
  setUid(CalFormat::createUniqueId());
}

IncidenceBase::IncidenceBase(const IncidenceBase &i)
{
  mReadOnly = i.mReadOnly;
  mDtStart = i.mDtStart;
  mDuration = i.mDuration;
  mHasDuration = i.mHasDuration;
  mOrganizer = i.mOrganizer;
  mUid = i.mUid;
  mAttendees = i.attendees();
  mFloats = i.mFloats;
  mLastModified = i.mLastModified;
  mPilotId = i.mPilotId;
  mSyncStatus = i.mSyncStatus;
  mObserver = i.mObserver;
}

IncidenceBase::~IncidenceBase()
{
}

void IncidenceBase::setUid(const QString &uid)
{
  mUid = uid;
  updated();
}

QString IncidenceBase::uid() const
{
  return mUid;
}

void IncidenceBase::setLastModified(const QDateTime &lm)
{
  // DON'T! updated() because we call this from
  // Calendar::updateEvent().
  mLastModified = lm;
}

QDateTime IncidenceBase::lastModified() const
{
  return mLastModified;
}

void IncidenceBase::setOrganizer(const QString &o)
{
  // we don't check for readonly here, because it is
  // possible that by setting the organizer we are changing
  // the event's readonly status...
  mOrganizer = o;
  if (mOrganizer.left(7).upper() == "MAILTO:")
    mOrganizer = mOrganizer.remove(0,7);

  updated();
}

QString IncidenceBase::organizer() const
{
  return mOrganizer;
}

void IncidenceBase::setReadOnly( bool readOnly )
{
  mReadOnly = readOnly;
}

void IncidenceBase::setDtStart(const QDateTime &dtStart)
{
//  if (mReadOnly) return;
  mDtStart = dtStart;
  updated();
}

QDateTime IncidenceBase::dtStart() const
{
  return mDtStart;
}

QString IncidenceBase::dtStartTimeStr() const
{
  return KGlobal::locale()->formatTime(dtStart().time());
}

QString IncidenceBase::dtStartDateStr(bool shortfmt) const
{
  return KGlobal::locale()->formatDate(dtStart().date(),shortfmt);
}

QString IncidenceBase::dtStartStr() const
{
  return KGlobal::locale()->formatDateTime(dtStart());
}

bool IncidenceBase::doesFloat() const
{
  return mFloats;
}

void IncidenceBase::setFloats(bool f)
{
  if (mReadOnly) return;
  mFloats = f;
  updated();
}

void IncidenceBase::addAttendee(Attendee *a, bool doupdate)
{
//  kdDebug(5800) << "IncidenceBase::addAttendee()" << endl;
  if (mReadOnly) return;
//  kdDebug(5800) << "IncidenceBase::addAttendee() weiter" << endl;
  if (a->name().left(7).upper() == "MAILTO:")
    a->setName(a->name().remove(0,7));

  mAttendees.append(a);
  if (doupdate) updated();
}

#if 0
void IncidenceBase::removeAttendee(Attendee *a)
{
  if (mReadOnly) return;
  mAttendees.removeRef(a);
  updated();
}

void IncidenceBase::removeAttendee(const char *n)
{
  Attendee *a;

  if (mReadOnly) return;
  for (a = mAttendees.first(); a; a = mAttendees.next())
    if (a->getName() == n) {
      mAttendees.remove();
      break;
    }
}
#endif

void IncidenceBase::clearAttendees()
{
  if (mReadOnly) return;
  mAttendees.clear();
}

#if 0
Attendee *IncidenceBase::getAttendee(const char *n) const
{
  QPtrListIterator<Attendee> qli(mAttendees);

  qli.toFirst();
  while (qli) {
    if (qli.current()->getName() == n)
      return qli.current();
    ++qli;
  }
  return 0L;
}
#endif

Attendee *IncidenceBase::attendeeByMail(const QString &email)
{
  QPtrListIterator<Attendee> qli(mAttendees);

  qli.toFirst();
  while (qli) {
    if (qli.current()->email() == email)
      return qli.current();
    ++qli;
  }
  return 0L;
}

Attendee *IncidenceBase::attendeeByMails(const QStringList &emails, QString email)
{
  QPtrListIterator<Attendee> qli(mAttendees);

  QStringList mails = emails;
  if (!email.isEmpty()) {
    mails.append(email);
  }
  qli.toFirst();
  while (qli) {
    for ( QStringList::Iterator it = mails.begin(); it != mails.end(); ++it ) {
      if (qli.current()->email() == *it)
        return qli.current();
     }

    ++qli;
  }
  return 0L;
}

void IncidenceBase::setDuration(int seconds)
{
  mDuration = seconds;
  setHasDuration(true);
}

int IncidenceBase::duration() const
{
  return mDuration;
}

void IncidenceBase::setHasDuration(bool)
{
  mHasDuration = true;
}

bool IncidenceBase::hasDuration() const
{
  return mHasDuration;
}

void IncidenceBase::setSyncStatus(int stat)
{
  if (mReadOnly) return;
  mSyncStatus = stat;
}

int IncidenceBase::syncStatus() const
{
  return mSyncStatus;
}

void IncidenceBase::setPilotId( int id )
{
  if (mReadOnly) return;

  mPilotId = id;
}

int IncidenceBase::pilotId() const
{
  return mPilotId;
}

void IncidenceBase::registerObserver( IncidenceBase::Observer *observer )
{
  mObserver = observer;
}

void IncidenceBase::updated()
{
  if ( mObserver ) {
    mObserver->incidenceUpdated( this );
  }
}
<|endoftext|>


<commit_before>#pragma once

#include "../expr.hpp"

namespace wrd {

    /*class blockExpr : public expr {
        WRD(CLASS(blockExpr, expr))

    public:
    };*/
}
<commit_msg>wrd: feat: add blockExpr<commit_after>#pragma once

#include "../expr.hpp"
#include "../../frame/frameInteractable.hpp"

namespace wrd {

    class blockExpr : public expr, public frameInteractable {
        WRD(CLASS(blockExpr, expr))
        friend class mgdFunc;

    public:
        blockExpr() {}
        blockExpr(std::initializer_list<const expr*> elems): _exprs(elems) {}
        template <typename... Es>
        blockExpr(const Es&... elems): _exprs(elems...) {}

    public:
        const tnarr<expr>& getExprs() const { return _exprs; }
        tnarr<expr>& getExprs() { return _exprs; }

        str run(const containable& args) override {
            // TODO:
            return str();
        }

        const wtype& getEvalType() const override {
            wcnt len = _exprs.len();
            if(len <= 0) return nulOf<wtype>();

            return _exprs[len-1].getEvalType();
        }

    protected:
        wbool _onInFrame(frame& fr, const ncontainer& args) override;
        wbool _onOutFrame(frame& fr, const ncontainer& args) override;

    private:
        tnarr<expr> _exprs;
    };
}
<|endoftext|>