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

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbReciprocalHAlphaImageFilter.h"
#include "otbSinclairReciprocalImageFilter.h"
#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
#include "otbPerBandVectorImageFilter.h"
#include "itkMeanImageFilter.h"

namespace otb
{
namespace Wrapper
{

class SARDecompositions : public Application
{
public:
  /** Standard class typedefs. */
  typedef SARDecompositions                   Self;
  typedef Application                         Superclass;
  typedef itk::SmartPointer<Self>             Pointer;
  typedef itk::SmartPointer<const Self>       ConstPointer;

  typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexFloatImageType::PixelType,
                                    ComplexFloatImageType::PixelType,
                                    ComplexFloatImageType::PixelType,
                                    ComplexFloatVectorImageType::PixelType>								FunctorType;

  typedef SinclairReciprocalImageFilter<ComplexFloatImageType,
											 ComplexFloatImageType,
											 ComplexFloatImageType,
											 ComplexFloatVectorImageType,
											 FunctorType > 												SRFilterType;

  typedef otb::ReciprocalHAlphaImageFilter<ComplexFloatVectorImageType, FloatVectorImageType> 			HAFilterType;

  typedef itk::MeanImageFilter<ComplexFloatImageType, ComplexFloatImageType>         MeanFilterType;
  typedef otb::PerBandVectorImageFilter<ComplexFloatVectorImageType, ComplexFloatVectorImageType, MeanFilterType> PerBandMeanFilterType;
  //FloatImageType

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(SARDecompositions, otb::Application);

private:
  void DoInit()
  {
    SetName("SARDecompositions");
    SetDescription("From one-band complex images (each one related to an element of the Sinclair matrix), returns the selected decomposition.");

    // Documentation
    SetDocName("SARDecompositions");
    SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
						  "The H-alpha-A decomposition is currently the only one available; it is implemented for the monostatic case (transmitter and receiver are co-located).\n"
						  "User must provide three one-band complex images HH, HV or VH, and VV (monostatic case <=> HV = VH).\n"
						  "The H-alpha-A decomposition consists in averaging 3x3 complex coherency matrices (incoherent analysis); the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize.\n "
						  "The applications returns a float vector image, made up of three channels : H (entropy), Alpha, A (Anisotropy)." );

    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("");

    AddDocTag(Tags::SAR);

    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input Image");
    SetParameterDescription("inhh", "Input image (HH)");

    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input Image");
    SetParameterDescription("inhv", "Input image (HV)");
    MandatoryOff("inhv");

    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input Image");
    SetParameterDescription("invh", "Input image (VH)");
    MandatoryOff("invh");

    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input Image");
    SetParameterDescription("invv", "Input image (VV)");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output image");

    AddParameter(ParameterType_Choice, "decomp", "Decompositions");
    AddChoice("decomp.haa","H-alpha-A decomposition");
    SetParameterDescription("decomp.haa","H-alpha-A decomposition");

    AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
    SetParameterDescription("inco","This group allows to set parameters related to the incoherent decompositions.");

    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging.");
    SetParameterDescription("inco.kernelsize", "Minute (0-59)");
    SetMinimumParameterIntValue("inco.kernelsize", 1);
    SetDefaultParameterInt("inco.kernelsize", 3);
    MandatoryOff("inco.kernelsize");

    AddRAMParameter();

    // Default values
    SetDefaultParameterInt("decomp", 0); // H-alpha-A

    // Doc example parameter settings
    SetDocExampleParameterValue("inhh", "HH.tif");
	SetDocExampleParameterValue("invh", "VH.tif");
	SetDocExampleParameterValue("invv", "VV.tif");
	SetDocExampleParameterValue("decomp", "haa");
    SetDocExampleParameterValue("out", "HaA.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {

	bool inhv = HasUserValue("inhv");
	bool invh = HasUserValue("invh");

	if ( (!inhv) && (!invh) )
	  otbAppLogFATAL( << "Parameter inhv or invh not set. Please provide a HV or a VH complex image.");

    switch (GetParameterInt("decomp"))
      {
		case 0: // H-alpha-A

		m_SRFilter = SRFilterType::New();
		m_HAFilter = HAFilterType::New();
		m_MeanFilter = PerBandMeanFilterType::New();

		if (inhv)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexFloatImage("inhv"));
	    else if (invh)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexFloatImage("invh"));

		m_SRFilter->SetInputHH(GetParameterComplexFloatImage("inhh"));
		m_SRFilter->SetInputVV(GetParameterComplexFloatImage("invv"));

		MeanFilterType::InputSizeType radius;
        radius.Fill( GetParameterInt("inco.kernelsize") );
        m_MeanFilter->GetFilter()->SetRadius(radius);

		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
		SetParameterOutputImage("out", m_HAFilter->GetOutput() );

		break;
	  }

  }

  //MCPSFilterType::Pointer m_MCPSFilter;
  SRFilterType::Pointer m_SRFilter;
  HAFilterType::Pointer m_HAFilter;
  PerBandMeanFilterType::Pointer m_MeanFilter;

};

} //end namespace Wrapper
} //end namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::SARDecompositions)
<commit_msg>ENH: SARDecompositions app, float to double pixels<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbReciprocalHAlphaImageFilter.h"
#include "otbSinclairReciprocalImageFilter.h"
#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
#include "otbPerBandVectorImageFilter.h"
#include "itkMeanImageFilter.h"

namespace otb
{
namespace Wrapper
{

class SARDecompositions : public Application
{
public:
  /** Standard class typedefs. */
  typedef SARDecompositions                   Self;
  typedef Application                         Superclass;
  typedef itk::SmartPointer<Self>             Pointer;
  typedef itk::SmartPointer<const Self>       ConstPointer;

  typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
                                    ComplexDoubleImageType::PixelType,
                                    ComplexDoubleImageType::PixelType,
                                    ComplexDoubleVectorImageType::PixelType>								FunctorType;

  typedef SinclairReciprocalImageFilter<ComplexDoubleImageType,
											 ComplexDoubleImageType,
											 ComplexDoubleImageType,
											 ComplexDoubleVectorImageType,
											 FunctorType > 												SRFilterType;

  typedef otb::ReciprocalHAlphaImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType> 			HAFilterType;

  typedef itk::MeanImageFilter<ComplexDoubleImageType, ComplexDoubleImageType>         MeanFilterType;
  typedef otb::PerBandVectorImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType, MeanFilterType> PerBandMeanFilterType;
  //FloatImageType

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(SARDecompositions, otb::Application);

private:
  void DoInit()
  {
    SetName("SARDecompositions");
    SetDescription("From one-band complex images (each one related to an element of the Sinclair matrix), returns the selected decomposition.");

    // Documentation
    SetDocName("SARDecompositions");
    SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
						  "The H-alpha-A decomposition is currently the only one available; it is implemented for the monostatic case (transmitter and receiver are co-located).\n"
						  "User must provide three one-band complex images HH, HV or VH, and VV (monostatic case <=> HV = VH).\n"
						  "The H-alpha-A decomposition consists in averaging 3x3 complex coherency matrices (incoherent analysis); the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize.\n "
						  "The applications returns a float vector image, made up of three channels : H (entropy), Alpha, A (Anisotropy)." );

    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("");

    AddDocTag(Tags::SAR);

    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input Image");
    SetParameterDescription("inhh", "Input image (HH)");

    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input Image");
    SetParameterDescription("inhv", "Input image (HV)");
    MandatoryOff("inhv");

    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input Image");
    SetParameterDescription("invh", "Input image (VH)");
    MandatoryOff("invh");

    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input Image");
    SetParameterDescription("invv", "Input image (VV)");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output image");

    AddParameter(ParameterType_Choice, "decomp", "Decompositions");
    AddChoice("decomp.haa","H-alpha-A decomposition");
    SetParameterDescription("decomp.haa","H-alpha-A decomposition");

    AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
    SetParameterDescription("inco","This group allows to set parameters related to the incoherent decompositions.");

    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging.");
    SetParameterDescription("inco.kernelsize", "Minute (0-59)");
    SetMinimumParameterIntValue("inco.kernelsize", 1);
    SetDefaultParameterInt("inco.kernelsize", 3);
    MandatoryOff("inco.kernelsize");

    AddRAMParameter();

    // Default values
    SetDefaultParameterInt("decomp", 0); // H-alpha-A

    // Doc example parameter settings
    SetDocExampleParameterValue("inhh", "HH.tif");
	SetDocExampleParameterValue("invh", "VH.tif");
	SetDocExampleParameterValue("invv", "VV.tif");
	SetDocExampleParameterValue("decomp", "haa");
    SetDocExampleParameterValue("out", "HaA.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {

	bool inhv = HasUserValue("inhv");
	bool invh = HasUserValue("invh");

	if ( (!inhv) && (!invh) )
	  otbAppLogFATAL( << "Parameter inhv or invh not set. Please provide a HV or a VH complex image.");

    switch (GetParameterInt("decomp"))
      {
		case 0: // H-alpha-A

		m_SRFilter = SRFilterType::New();
		m_HAFilter = HAFilterType::New();
		m_MeanFilter = PerBandMeanFilterType::New();

		if (inhv)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
	    else if (invh)
		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));

		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));

		MeanFilterType::InputSizeType radius;
        radius.Fill( GetParameterInt("inco.kernelsize") );
        m_MeanFilter->GetFilter()->SetRadius(radius);

		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
		SetParameterOutputImage("out", m_HAFilter->GetOutput() );

		break;
	  }

  }

  //MCPSFilterType::Pointer m_MCPSFilter;
  SRFilterType::Pointer m_SRFilter;
  HAFilterType::Pointer m_HAFilter;
  PerBandMeanFilterType::Pointer m_MeanFilter;

};

} //end namespace Wrapper
} //end namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::SARDecompositions)
<|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)

#ifndef DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH

#include <memory>
#include <sstream>
#include <type_traits>
#include <vector>
#include <array>

#include <boost/numeric/conversion/cast.hpp>

#if HAVE_DUNE_GRID
# include <dune/grid/sgrid.hh>
# include <dune/grid/yaspgrid.hh>
# if HAVE_ALUGRID
#   include <dune/grid/alugrid.hh>
# endif
# if HAVE_DUNE_SPGRID
#   include <dune/grid/spgrid.hh>
# endif
# include <dune/stuff/grid/structuredgridfactory.hh>
#endif

#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/memory.hh>

#include "default.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace Providers {
namespace Configs {

static Common::Configuration Cube_default(const std::string sub_name = "")
{
  Common::Configuration config;
  config["lower_left"] = "[0 0 0 0]";
  config["upper_right"] = "[1 1 1 1]";
  config["num_elements"] = "[8 8 8 8]";
  config["num_refinements"] = "0";
  if (sub_name.empty())
    return config;
  else {
    Common::Configuration tmp;
    tmp.add(config, sub_name);
    return tmp;
  }
} // ... Cube_default(...)

} // namespace Configs
namespace internal {

template< typename GridType >
struct ElementVariant;

template< typename GridType >
struct ElementVariant
{
  static const int id = 2;
};

#if HAVE_DUNE_GRID
template< int dim >
struct ElementVariant< Dune::YaspGrid< dim > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::SGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

#if HAVE_DUNE_SPGRID
template< class ct, int dim, SPRefinementStrategy strategy, class Comm >
struct ElementVariant< Dune::SPGrid< ct, dim, strategy, Comm > >
{
  static const int id = 1;
};
#endif

#endif // HAVE_DUNE_GRID

#if HAVE_ALUGRID

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUCubeGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld, class MpiCommImp >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::conforming, MpiCommImp > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld, class MpiCommImp >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::nonconforming, MpiCommImp > >
{
  static const int id = 1;
};

#endif // HAVE_ALUGRID

} // namespace internal

#if HAVE_DUNE_GRID

/**
 *  \brief  Creates a grid of a cube in various dimensions.
 *
 *          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
 *          dimensions. Tested with
 *

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c SGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,
 *
 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and
 *
 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

 *  \tparam GridImp
 *          Type of the underlying grid.
 *  \tparam variant
 *          Type of the codim 0 elements:
 *

\c 1: cubes
 *
2: simplices

 **/
template< typename GridImp, int variant = internal::ElementVariant< GridImp >::id >
class Cube
  : public ProviderInterface< GridImp >
{
  typedef ProviderInterface< GridImp > BaseType;
  typedef Cube< GridImp, variant > ThisType;
public:
  using typename BaseType::GridType;
  static const size_t dimDomain = BaseType::dimDomain;
  using typename BaseType::DomainFieldType;
  using typename BaseType::DomainType;

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

  static Common::Configuration default_config(const std::string sub_name = "")
  {
    return Configs::Cube_default(sub_name);
  }

  static std::unique_ptr< ThisType > create(const Common::Configuration config = default_config(),
                                            const std::string sub_name = static_id())
  {
    // get correct config
    const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::Configuration default_cfg = default_config();
    return Common::make_unique< ThisType >(
          cfg.get("lower_left", default_cfg.get< DomainType >("lower_left")),
          cfg.get("upper_right", default_cfg.get< DomainType >("upper_right")),
          cfg.get("num_elements", default_cfg.get< std::vector< unsigned int > >("num_elements"), dimDomain),
          cfg.get("num_refinements", default_cfg.get< size_t >("num_refinements")));
  } // ... create(...)

  /**
   *  \brief      Creates a cube.
   *  \param[in]  lower_left
   *              Used as a lower left corner (in each dimension, if scalar).
   *  \param[in]  upper_right
   *              Used as an upper right corner (in each dimension, if scalar).
   *  \param[in]  num_elements (optional)
   *              Number of elements.
   **/
  explicit Cube(const DomainFieldType lower_left = default_config().get< DomainFieldType >("lower_left"),
       const DomainFieldType upper_right = default_config().get< DomainFieldType >("upper_right"),
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(DomainType(lower_left),
                            DomainType(upper_right),
                            parse_array(num_elements),
                            num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const std::vector< unsigned int > num_elements
          = default_config().get< std::vector< unsigned int > >("num_elements"),
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  virtual GridType& grid() override
  {
    return *grid_ptr_;
  }

  virtual const GridType& grid() const override
  {
    return *grid_ptr_;
  }

  std::shared_ptr< GridType > grid_ptr()
  {
    return grid_ptr_;
  }

  const std::shared_ptr< const GridType >& grid_ptr() const
  {
    return grid_ptr_;
  }

private:
  static std::array< unsigned int, dimDomain > parse_array(const unsigned int in)
  {
    std::array< unsigned int, dimDomain > ret;
    std::fill(ret.begin(), ret.end(), in);
    return ret;
  } // ... parse_array(...)

  static std::array< unsigned int, dimDomain > parse_array(const std::vector< unsigned int >& in)
  {
    if (in.size() < dimDomain)
      DUNE_THROW(Exceptions::wrong_input_given,
                 "Given vector is too short: should be " << dimDomain << ", is " << in.size() << "!");
    std::array< unsigned int, dimDomain > ret;
    for (size_t ii = 0; ii < dimDomain; ++ii)
      ret[ii] = in[ii];
    return ret;
  } // ... parse_array(...)

  static std::shared_ptr< GridType > create_grid(DomainType lower_left,
                                                 DomainType upper_right,
                                                 const std::array< unsigned int, dimDomain >& num_elements,
                                                 const size_t num_refinements)
  {
    static_assert(variant == 1 || variant == 2, "variant has to be 1 or 2!");
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      if (!(lower_left[dd] < upper_right[dd]))
        DUNE_THROW(Exceptions::wrong_input_given,
                   "lower_left has to be elementwise smaller than upper_right!\n\n"
                   << lower_left[dd] << " vs. " << upper_right[dd]);
    }
    std::shared_ptr< GridType > grd_ptr(nullptr);
    switch (variant) {
      case 1:
        grd_ptr = DSG::StructuredGridFactory< GridType >::createCubeGrid(lower_left, upper_right, num_elements);
        break;
      case 2:
    default:
        grd_ptr = DSG::StructuredGridFactory< GridType >::createSimplexGrid(lower_left, upper_right, num_elements);
        break;
    }
    grd_ptr->loadBalance();
    grd_ptr->preAdapt();
    grd_ptr->globalRefine(boost::numeric_cast< int >(num_refinements));
    grd_ptr->postAdapt();
    grd_ptr->loadBalance();
    return grd_ptr;
  } // ... create_grid(...)

  std::shared_ptr< GridType > grid_ptr_;
}; // class Cube

#else // HAVE_DUNE_GRID

template< typename GridImp, int variant = 1 >
class Cube
{
  static_assert(AlwaysFalse< GridImp >::value, "You are missing dune-grid!");
};

#endif // HAVE_DUNE_GRID

} // namespace Providers
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
<commit_msg>[provider.cube] makes overlap settable<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)

#ifndef DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH

#include <memory>
#include <sstream>
#include <type_traits>
#include <vector>
#include <array>

#include <boost/numeric/conversion/cast.hpp>

#if HAVE_DUNE_GRID
# include <dune/grid/sgrid.hh>
# include <dune/grid/yaspgrid.hh>
# if HAVE_ALUGRID
#   include <dune/grid/alugrid.hh>
# endif
# if HAVE_DUNE_SPGRID
#   include <dune/grid/spgrid.hh>
# endif
# include <dune/stuff/grid/structuredgridfactory.hh>
#endif

#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/memory.hh>

#include "default.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace Providers {
namespace Configs {

static Common::Configuration Cube_default(const std::string sub_name = "")
{
  Common::Configuration config;
  config["lower_left"] = "[0 0 0 0]";
  config["upper_right"] = "[1 1 1 1]";
  config["num_elements"] = "[8 8 8 8]";
  config["num_refinements"] = "0";
  config["overlap"] = "1";
  if (sub_name.empty())
    return config;
  else {
    Common::Configuration tmp;
    tmp.add(config, sub_name);
    return tmp;
  }
} // ... Cube_default(...)

} // namespace Configs
namespace internal {

template< typename GridType >
struct ElementVariant;

template< typename GridType >
struct ElementVariant
{
  static const int id = 2;
};

#if HAVE_DUNE_GRID
template< int dim >
struct ElementVariant< Dune::YaspGrid< dim > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::SGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

#if HAVE_DUNE_SPGRID
template< class ct, int dim, SPRefinementStrategy strategy, class Comm >
struct ElementVariant< Dune::SPGrid< ct, dim, strategy, Comm > >
{
  static const int id = 1;
};
#endif

#endif // HAVE_DUNE_GRID

#if HAVE_ALUGRID

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUCubeGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld, class MpiCommImp >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::conforming, MpiCommImp > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld, class MpiCommImp >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::nonconforming, MpiCommImp > >
{
  static const int id = 1;
};

#endif // HAVE_ALUGRID

} // namespace internal

#if HAVE_DUNE_GRID

/**
 *  \brief  Creates a grid of a cube in various dimensions.
 *
 *          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
 *          dimensions. Tested with
 *

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c SGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,
 *
 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and
 *
 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

 *  \tparam GridImp
 *          Type of the underlying grid.
 *  \tparam variant
 *          Type of the codim 0 elements:
 *

\c 1: cubes
 *
2: simplices

 **/
template< typename GridImp, int variant = internal::ElementVariant< GridImp >::id >
class Cube
  : public ProviderInterface< GridImp >
{
  typedef ProviderInterface< GridImp > BaseType;
  typedef Cube< GridImp, variant > ThisType;
public:
  using typename BaseType::GridType;
  static const size_t dimDomain = BaseType::dimDomain;
  using typename BaseType::DomainFieldType;
  using typename BaseType::DomainType;

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

  static Common::Configuration default_config(const std::string sub_name = "")
  {
    return Configs::Cube_default(sub_name);
  }

  static std::unique_ptr< ThisType > create(const Common::Configuration config = default_config(),
                                            const std::string sub_name = static_id())
  {
    // get correct config
    const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const auto overlap = cfg.get("overlap", default_config().get< unsigned int >("overlap"));
    const auto overlap_array = DSC::make_array< unsigned int, dimDomain >(overlap);
    return Common::make_unique< ThisType >(
          cfg.get("lower_left", default_config().get< DomainType >("lower_left")),
          cfg.get("upper_right", default_config().get< DomainType >("upper_right")),
          cfg.get("num_elements", default_config().get< std::vector< unsigned int > >("num_elements"), dimDomain),
          cfg.get("num_refinements", default_config().get< size_t >("num_refinements")),
          overlap_array);
  } // ... create(...)

  /**
   *  \brief      Creates a cube.
   *  \param[in]  lower_left
   *              Used as a lower left corner (in each dimension, if scalar).
   *  \param[in]  upper_right
   *              Used as an upper right corner (in each dimension, if scalar).
   *  \param[in]  num_elements (optional)
   *              Number of elements.
   **/
  explicit Cube(const DomainFieldType lower_left = default_config().get< DomainFieldType >("lower_left"),
       const DomainFieldType upper_right = default_config().get< DomainFieldType >("upper_right"),
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"),
                const std::array< unsigned int, dimDomain > overlap
                = DSC::make_array< unsigned int, dimDomain >(default_config().get< unsigned int >("overlap")))
    : grid_ptr_(create_grid(DomainType(lower_left),
                            DomainType(upper_right),
                            parse_array(num_elements),
                            num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"),
       const std::array< unsigned int, dimDomain > overlap
       = DSC::make_array< unsigned int, dimDomain >(default_config().get< unsigned int >("overlap")))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const std::vector< unsigned int > num_elements
          = default_config().get< std::vector< unsigned int > >("num_elements"),
       const size_t num_refinements = default_config().get< size_t >("num_refinements"),
       const std::array< unsigned int, dimDomain > overlap
       = DSC::make_array< unsigned int, dimDomain >(default_config().get< unsigned int >("overlap")))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  virtual GridType& grid() override
  {
    return *grid_ptr_;
  }

  virtual const GridType& grid() const override
  {
    return *grid_ptr_;
  }

  std::shared_ptr< GridType > grid_ptr()
  {
    return grid_ptr_;
  }

  const std::shared_ptr< const GridType >& grid_ptr() const
  {
    return grid_ptr_;
  }

private:
  static std::array< unsigned int, dimDomain > parse_array(const unsigned int in)
  {
    std::array< unsigned int, dimDomain > ret;
    std::fill(ret.begin(), ret.end(), in);
    return ret;
  } // ... parse_array(...)

  static std::array< unsigned int, dimDomain > parse_array(const std::vector< unsigned int >& in)
  {
    if (in.size() < dimDomain)
      DUNE_THROW(Exceptions::wrong_input_given,
                 "Given vector is too short: should be " << dimDomain << ", is " << in.size() << "!");
    std::array< unsigned int, dimDomain > ret;
    for (size_t ii = 0; ii < dimDomain; ++ii)
      ret[ii] = in[ii];
    return ret;
  } // ... parse_array(...)

  ///TODO simplex grid overlap
  static std::shared_ptr< GridType > create_grid(DomainType lower_left,
                                                 DomainType upper_right,
                                                 const std::array< unsigned int, dimDomain >& num_elements,
                                                 const size_t num_refinements,
                                                 const std::array< unsigned int, dimDomain > overlap
                                                 = DSC::make_array< unsigned int, dimDomain >(default_config().get< size_t >("overlap")))
  {
    static_assert(variant == 1 || variant == 2, "variant has to be 1 or 2!");
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      if (!(lower_left[dd] < upper_right[dd]))
        DUNE_THROW(Exceptions::wrong_input_given,
                   "lower_left has to be elementwise smaller than upper_right!\n\n"
                   << lower_left[dd] << " vs. " << upper_right[dd]);
    }
    std::shared_ptr< GridType > grd_ptr(nullptr);
    switch (variant) {
      case 1:
        grd_ptr = DSG::StructuredGridFactory< GridType >::createCubeGrid(lower_left, upper_right, num_elements, overlap);
        break;
      case 2:
    default:
        grd_ptr = DSG::StructuredGridFactory< GridType >::createSimplexGrid(lower_left, upper_right, num_elements);
        break;
    }
    grd_ptr->loadBalance();
    grd_ptr->preAdapt();
    grd_ptr->globalRefine(boost::numeric_cast< int >(num_refinements));
    grd_ptr->postAdapt();
    grd_ptr->loadBalance();
    return grd_ptr;
  } // ... create_grid(...)

  std::shared_ptr< GridType > grid_ptr_;
}; // class Cube

#else // HAVE_DUNE_GRID

template< typename GridImp, int variant = 1 >
class Cube
{
  static_assert(AlwaysFalse< GridImp >::value, "You are missing dune-grid!");
};

#endif // HAVE_DUNE_GRID

} // namespace Providers
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
<|endoftext|>


<commit_before>#include "NFCMasterNet_WebServerModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include <thread>

extern "C" int uhStats(UrlHandlerParam* param);
UrlHandler urlHandlerList[] = {
	{ "stats", uhStats, NULL },
	{ NULL },
};

AuthHandler authHandlerList[] = {
	{ "stats", "user", "pass", "group=admin", "" },
	{ NULL }
};

bool NFCMasterNet_WebServerModule::Init()
{
	return true;
}
bool NFCMasterNet_WebServerModule::BeforeShut()
{
	return true;
}
bool NFCMasterNet_WebServerModule::Shut()
{
	// cleanup
	_mwCloseAllConnections(hp);
	SYSLOG(LOG_INFO, "Cleaning up...\n");
	for (i = 0; i < hp->maxClients; i++) {
		if (hp->hsSocketQueue[i].buffer) free(hp->hsSocketQueue[i].buffer);
	}
	for (i = 0; hp->pxUrlHandler[i].pchUrlPrefix; i++) {
		if (hp->pxUrlHandler[i].pfnUrlHandler && hp->pxUrlHandler[i].pfnEventHandler)
			hp->pxUrlHandler[i].pfnEventHandler(MW_UNINIT, &hp->pxUrlHandler[i], hp);
	}
	free(hp->hsSocketQueue);
	hp->hsSocketQueue = 0;

	// clear state vars
	hp->bKillWebserver = FALSE;
	hp->bWebserverRunning = FALSE;
	mwServerShutdown(&httpParam);
	UninitSocket();
	return true;
}

char * NFCMasterNet_WebServerModule::GetLocalAddrString()
{
	return "127.0.0.1";
}

void NFCMasterNet_WebServerModule::GetFullPath(char * buffer, const char * path)
{
	strcpy(buffer, path);
}

bool NFCMasterNet_WebServerModule::AfterInit()
{
	mKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pLogicClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();

	NF_SHARE_PTR<NFIClass> xLogicClass = m_pLogicClassModule->GetElement(NFrame::HttpServer::ThisName());
	if (xLogicClass)
	{
		NFList<std::string>& strIdList = xLogicClass->GetIdList();
		std::string strId;
		for (bool bRet = strIdList.First(strId); bRet; bRet = strIdList.Next(strId))
		{
			nWebPort = m_pElementModule->GetPropertyInt(strId, NFrame::HttpServer::WebPort());
			strWebRootPath = m_pElementModule->GetPropertyString(strId, NFrame::HttpServer::WebRootPath());
		}
	}
	//fill in default settings
	mwInitParam(&httpParam);
	httpParam.maxClients = 50;
	GetFullPath(httpParam.pchWebPath, strWebRootPath.c_str());
	httpParam.httpPort = nWebPort;

	httpParam.pxAuthHandler = authHandlerList;
	httpParam.pxUrlHandler = urlHandlerList;
	httpParam.flags = FLAG_DIR_LISTING;
	httpParam.tmSocketExpireTime = 15;
	{
		int i;
		int error = 0;
		for (i = 0; urlHandlerList[i].pchUrlPrefix; i++) {
			if (urlHandlerList[i].pfnEventHandler) {
				if (urlHandlerList[i].pfnEventHandler(MW_PARSE_ARGS, urlHandlerList[i].pfnEventHandler, &httpParam))
					error++;
			}
		}
		if (error > 0) {
			printf("Error parsing command line options\n");
			return -1;
		}
	}

	InitSocket();

	{
		int n;
		printf("Host: %s:%d\n", GetLocalAddrString(), httpParam.httpPort);
		printf("Web root: %s\n", httpParam.pchWebPath);
		printf("Max clients (per IP): %d (%d)\n", httpParam.maxClients, httpParam.maxClientsPerIP);
		for (n = 0;urlHandlerList[n].pchUrlPrefix;n++);
		printf("URL handlers: %d\n", n);
		if (httpParam.flags & FLAG_DIR_LISTING) printf("Dir listing enabled\n");
		if (httpParam.flags & FLAG_DISABLE_RANGE) printf("Byte-range disabled\n");

		//register page variable substitution callback
		//httpParam[i].pfnSubst=DefaultWebSubstCallback;
		//start server
		if (mwServerStart(&httpParam)) {
			printf("Error starting HTTP server\n");
		}
	}
	return true;
}

bool NFCMasterNet_WebServerModule::Execute()
{
		// main processing loop
		if (!hp->bKillWebserver) {
			time_t tmCurrentTime;
			SOCKET iSelectMaxFds;
			fd_set fdsSelectRead;
			fd_set fdsSelectWrite;

			// clear descriptor sets
			FD_ZERO(&fdsSelectRead);
			FD_ZERO(&fdsSelectWrite);
			FD_SET(hp->listenSocket, &fdsSelectRead);
			iSelectMaxFds = hp->listenSocket;

			// get current time
#ifndef WINCE
			tmCurrentTime = time(NULL);
#else
			tmCurrentTime = GetTickCount() >> 10;
#endif
			// build descriptor sets and close timed out sockets
			for (int i = 0; i < hp->maxClients; i++) {
				phsSocketCur = hp->hsSocketQueue + i;

				// get socket fd
				socket = phsSocketCur->socket;
				if (!socket) continue;

				{
					int iError = 0;
					int iOptSize = sizeof(int);
					if (getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&iError, &iOptSize)) {
						// if a socket contains a error, close it
						SYSLOG(LOG_INFO, "[%d] Socket no longer vaild.\n", socket);
						phsSocketCur->flags = FLAG_CONN_CLOSE;
						_mwCloseSocket(hp, phsSocketCur);
						continue;
					}
				}
				// check expiration timer (for non-listening, in-use sockets)
				if (tmCurrentTime > phsSocketCur->tmExpirationTime) {
					SYSLOG(LOG_INFO, "[%d] Http socket expired\n", phsSocketCur->socket);
					hp->stats.timeOutCount++;
					// close connection
					phsSocketCur->flags = FLAG_CONN_CLOSE;
					_mwCloseSocket(hp, phsSocketCur);
				}
				else {
					if (phsSocketCur->dwResumeTick) {
						// suspended
						if (phsSocketCur->dwResumeTick > GetTickCount())
							continue;
						else
							phsSocketCur->dwResumeTick = 0;
					}
					if (ISFLAGSET(phsSocketCur, FLAG_RECEIVING)) {
						// add to read descriptor set
						FD_SET(socket, &fdsSelectRead);
					}
					if (ISFLAGSET(phsSocketCur, FLAG_SENDING)) {
						// add to write descriptor set
						FD_SET(socket, &fdsSelectWrite);
					}
					// check if new max socket
					if (socket > iSelectMaxFds) {
						iSelectMaxFds = socket;
					}
				}
			}

			{
				struct timeval tvSelectWait;
				// initialize select delay
				tvSelectWait.tv_sec = 1;
				tvSelectWait.tv_usec = 0; // note: using timeval here -> usec not nsec

										  // and check sockets (may take a while!)
				iRc = select(iSelectMaxFds + 1, &fdsSelectRead, &fdsSelectWrite,
					NULL, &tvSelectWait);
			}
			if (iRc < 0) {
				msleep(1000);
				return true;
			}
			if (iRc > 0) {
				// check which sockets are read/write able
				for (i = 0; i < hp->maxClients; i++) {
					BOOL bRead;
					BOOL bWrite;

					phsSocketCur = hp->hsSocketQueue + i;

					// get socket fd
					socket = phsSocketCur->socket;
					if (!socket) continue;

					// get read/write status for socket
					bRead = FD_ISSET(socket, &fdsSelectRead);
					bWrite = FD_ISSET(socket, &fdsSelectWrite);

					if ((bRead | bWrite) != 0) {
						//DBG("socket %d bWrite=%d, bRead=%d\n",phsSocketCur->socket,bWrite,bRead);
						// if readable or writeable then process
						if (bWrite && ISFLAGSET(phsSocketCur, FLAG_SENDING)) {
							iRc = _mwProcessWriteSocket(hp, phsSocketCur);
						}
						else if (bRead && ISFLAGSET(phsSocketCur, FLAG_RECEIVING)) {
							iRc = _mwProcessReadSocket(hp, phsSocketCur);
						}
						else {
							iRc = -1;
							DBG("Invalid socket state (flag: %08x)\n", phsSocketCur->flags);
						}
						if (!iRc) {
							// and reset expiration timer
#ifndef WINCE
							phsSocketCur->tmExpirationTime = time(NULL) + hp->tmSocketExpireTime;
#else
							phsSocketCur->tmExpirationTime = (GetTickCount() >> 10) + hp->tmSocketExpireTime;
#endif
						}
						else {
							SETFLAG(phsSocketCur, FLAG_CONN_CLOSE);
							_mwCloseSocket(hp, phsSocketCur);
						}
					}
				}

				// check if any socket to accept and accept the socket
				if (FD_ISSET(hp->listenSocket, &fdsSelectRead)) {
					// find empty slot
					phsSocketCur = 0;
					for (i = 0; i < hp->maxClients; i++) {
						if (hp->hsSocketQueue[i].socket == 0) {
							phsSocketCur = hp->hsSocketQueue + i;
							break;
						}
					}

					if (!phsSocketCur) {
						DBG("WARNING: clientCount:%d > maxClients:%d\n", hp->stats.clientCount, hp->maxClients);
						_mwDenySocket(hp, &sinaddr);
						return true;
					}

					phsSocketCur->socket = _mwAcceptSocket(hp, &sinaddr);
					if (phsSocketCur->socket == 0) return true;
					phsSocketCur->ipAddr.laddr = ntohl(sinaddr.sin_addr.s_addr);
					SYSLOG(LOG_INFO, "[%d] IP: %d.%d.%d.%d\n",
						phsSocketCur->socket,
						phsSocketCur->ipAddr.caddr[3],
						phsSocketCur->ipAddr.caddr[2],
						phsSocketCur->ipAddr.caddr[1],
						phsSocketCur->ipAddr.caddr[0]);

					hp->stats.clientCount++;

					//fill structure with data
					_mwInitSocketData(phsSocketCur);
					phsSocketCur->request.pucPayload = 0;
#ifndef WINCE
					phsSocketCur->tmAcceptTime = time(NULL);
#else
					phsSocketCur->tmAcceptTime = GetTickCount() >> 10;
#endif
					phsSocketCur->tmExpirationTime = phsSocketCur->tmAcceptTime + hp->tmSocketExpireTime;
					phsSocketCur->iRequestCount = 0;
					DBG("Connected clients: %d\n", hp->stats.clientCount);

					//update max client count
					if (hp->stats.clientCount > hp->stats.clientCountMax) hp->stats.clientCountMax = hp->stats.clientCount;
				}
			}
			else {
				//DBG("Select Timeout\n");
				// select timeout
				// call idle event
				if (hp->pfnIdleCallback) {
					(*hp->pfnIdleCallback)(hp);
				}
			}
		}

	return true;
}
<commit_msg>fixed for compile<commit_after>#include "NFCMasterNet_WebServerModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include <thread>

extern "C" int uhStats(UrlHandlerParam* param);
UrlHandler urlHandlerList[] = {
	{ "stats", uhStats, NULL },
	{ NULL },
};

AuthHandler authHandlerList[] = {
	{ "stats", "user", "pass", "group=admin", "" },
	{ NULL }
};

bool NFCMasterNet_WebServerModule::Init()
{
	return true;
}
bool NFCMasterNet_WebServerModule::BeforeShut()
{
	return true;
}
bool NFCMasterNet_WebServerModule::Shut()
{
	// cleanup
	_mwCloseAllConnections(hp);
	SYSLOG(LOG_INFO, "Cleaning up...\n");
	for (i = 0; i < hp->maxClients; i++) {
		if (hp->hsSocketQueue[i].buffer) free(hp->hsSocketQueue[i].buffer);
	}
	for (i = 0; hp->pxUrlHandler[i].pchUrlPrefix; i++) {
		if (hp->pxUrlHandler[i].pfnUrlHandler && hp->pxUrlHandler[i].pfnEventHandler)
			hp->pxUrlHandler[i].pfnEventHandler(MW_UNINIT, &hp->pxUrlHandler[i], hp);
	}
	free(hp->hsSocketQueue);
	hp->hsSocketQueue = 0;

	// clear state vars
	hp->bKillWebserver = FALSE;
	hp->bWebserverRunning = FALSE;
	mwServerShutdown(&httpParam);
	UninitSocket();
	return true;
}

char * NFCMasterNet_WebServerModule::GetLocalAddrString()
{
	return "127.0.0.1";
}

void NFCMasterNet_WebServerModule::GetFullPath(char * buffer, const char * path)
{
	strcpy(buffer, path);
}

bool NFCMasterNet_WebServerModule::AfterInit()
{
	mKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pLogicClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();

	NF_SHARE_PTR<NFIClass> xLogicClass = m_pLogicClassModule->GetElement(NFrame::HttpServer::ThisName());
	if (xLogicClass)
	{
		NFList<std::string>& strIdList = xLogicClass->GetIdList();
		std::string strId;
		for (bool bRet = strIdList.First(strId); bRet; bRet = strIdList.Next(strId))
		{
			nWebPort = m_pElementModule->GetPropertyInt(strId, NFrame::HttpServer::WebPort());
			strWebRootPath = m_pElementModule->GetPropertyString(strId, NFrame::HttpServer::WebRootPath());
		}
	}
	//fill in default settings
	mwInitParam(&httpParam);
	httpParam.maxClients = 50;
	GetFullPath(httpParam.pchWebPath, strWebRootPath.c_str());
	httpParam.httpPort = nWebPort;

	httpParam.pxAuthHandler = authHandlerList;
	httpParam.pxUrlHandler = urlHandlerList;
	httpParam.flags = FLAG_DIR_LISTING;
	httpParam.tmSocketExpireTime = 15;
	{
		int i;
		int error = 0;
		for (i = 0; urlHandlerList[i].pchUrlPrefix; i++) {
			if (urlHandlerList[i].pfnEventHandler) {
				if (urlHandlerList[i].pfnEventHandler(MW_PARSE_ARGS, (void*)urlHandlerList[i].pfnEventHandler, &httpParam))
					error++;
			}
		}
		if (error > 0) {
			printf("Error parsing command line options\n");
			return -1;
		}
	}

	InitSocket();

	{
		int n;
		printf("Host: %s:%d\n", GetLocalAddrString(), httpParam.httpPort);
		printf("Web root: %s\n", httpParam.pchWebPath);
		printf("Max clients (per IP): %d (%d)\n", httpParam.maxClients, httpParam.maxClientsPerIP);
		for (n = 0;urlHandlerList[n].pchUrlPrefix;n++);
		printf("URL handlers: %d\n", n);
		if (httpParam.flags & FLAG_DIR_LISTING) printf("Dir listing enabled\n");
		if (httpParam.flags & FLAG_DISABLE_RANGE) printf("Byte-range disabled\n");

		//register page variable substitution callback
		//httpParam[i].pfnSubst=DefaultWebSubstCallback;
		//start server
		if (mwServerStart(&httpParam)) {
			printf("Error starting HTTP server\n");
		}
	}
	return true;
}

bool NFCMasterNet_WebServerModule::Execute()
{
		// main processing loop
		if (!hp->bKillWebserver) {
			time_t tmCurrentTime;
			SOCKET iSelectMaxFds;
			fd_set fdsSelectRead;
			fd_set fdsSelectWrite;

			// clear descriptor sets
			FD_ZERO(&fdsSelectRead);
			FD_ZERO(&fdsSelectWrite);
			FD_SET(hp->listenSocket, &fdsSelectRead);
			iSelectMaxFds = hp->listenSocket;

			// get current time
#ifndef WINCE
			tmCurrentTime = time(NULL);
#else
			tmCurrentTime = GetTickCount() >> 10;
#endif
			// build descriptor sets and close timed out sockets
			for (int i = 0; i < hp->maxClients; i++) {
				phsSocketCur = hp->hsSocketQueue + i;

				// get socket fd
				socket = phsSocketCur->socket;
				if (!socket) continue;

				{
					int iError = 0;
					int iOptSize = sizeof(int);
					if (getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&iError, (socklen_t*)&iOptSize)) {
						// if a socket contains a error, close it
						SYSLOG(LOG_INFO, "[%d] Socket no longer vaild.\n", socket);
						phsSocketCur->flags = FLAG_CONN_CLOSE;
						_mwCloseSocket(hp, phsSocketCur);
						continue;
					}
				}
				// check expiration timer (for non-listening, in-use sockets)
				if (tmCurrentTime > phsSocketCur->tmExpirationTime) {
					SYSLOG(LOG_INFO, "[%d] Http socket expired\n", phsSocketCur->socket);
					hp->stats.timeOutCount++;
					// close connection
					phsSocketCur->flags = FLAG_CONN_CLOSE;
					_mwCloseSocket(hp, phsSocketCur);
				}
				else {
					if (phsSocketCur->dwResumeTick) {
						// suspended
						if (phsSocketCur->dwResumeTick > GetTickCount())
							continue;
						else
							phsSocketCur->dwResumeTick = 0;
					}
					if (ISFLAGSET(phsSocketCur, FLAG_RECEIVING)) {
						// add to read descriptor set
						FD_SET(socket, &fdsSelectRead);
					}
					if (ISFLAGSET(phsSocketCur, FLAG_SENDING)) {
						// add to write descriptor set
						FD_SET(socket, &fdsSelectWrite);
					}
					// check if new max socket
					if (socket > iSelectMaxFds) {
						iSelectMaxFds = socket;
					}
				}
			}

			{
				struct timeval tvSelectWait;
				// initialize select delay
				tvSelectWait.tv_sec = 1;
				tvSelectWait.tv_usec = 0; // note: using timeval here -> usec not nsec

										  // and check sockets (may take a while!)
				iRc = select(iSelectMaxFds + 1, &fdsSelectRead, &fdsSelectWrite,
					NULL, &tvSelectWait);
			}
			if (iRc < 0) {
				msleep(1000);
				return true;
			}
			if (iRc > 0) {
				// check which sockets are read/write able
				for (i = 0; i < hp->maxClients; i++) {
					BOOL bRead;
					BOOL bWrite;

					phsSocketCur = hp->hsSocketQueue + i;

					// get socket fd
					socket = phsSocketCur->socket;
					if (!socket) continue;

					// get read/write status for socket
					bRead = FD_ISSET(socket, &fdsSelectRead);
					bWrite = FD_ISSET(socket, &fdsSelectWrite);

					if ((bRead | bWrite) != 0) {
						//DBG("socket %d bWrite=%d, bRead=%d\n",phsSocketCur->socket,bWrite,bRead);
						// if readable or writeable then process
						if (bWrite && ISFLAGSET(phsSocketCur, FLAG_SENDING)) {
							iRc = _mwProcessWriteSocket(hp, phsSocketCur);
						}
						else if (bRead && ISFLAGSET(phsSocketCur, FLAG_RECEIVING)) {
							iRc = _mwProcessReadSocket(hp, phsSocketCur);
						}
						else {
							iRc = -1;
							DBG("Invalid socket state (flag: %08x)\n", phsSocketCur->flags);
						}
						if (!iRc) {
							// and reset expiration timer
#ifndef WINCE
							phsSocketCur->tmExpirationTime = time(NULL) + hp->tmSocketExpireTime;
#else
							phsSocketCur->tmExpirationTime = (GetTickCount() >> 10) + hp->tmSocketExpireTime;
#endif
						}
						else {
							SETFLAG(phsSocketCur, FLAG_CONN_CLOSE);
							_mwCloseSocket(hp, phsSocketCur);
						}
					}
				}

				// check if any socket to accept and accept the socket
				if (FD_ISSET(hp->listenSocket, &fdsSelectRead)) {
					// find empty slot
					phsSocketCur = 0;
					for (i = 0; i < hp->maxClients; i++) {
						if (hp->hsSocketQueue[i].socket == 0) {
							phsSocketCur = hp->hsSocketQueue + i;
							break;
						}
					}

					if (!phsSocketCur) {
						DBG("WARNING: clientCount:%d > maxClients:%d\n", hp->stats.clientCount, hp->maxClients);
						_mwDenySocket(hp, &sinaddr);
						return true;
					}

					phsSocketCur->socket = _mwAcceptSocket(hp, &sinaddr);
					if (phsSocketCur->socket == 0) return true;
					phsSocketCur->ipAddr.laddr = ntohl(sinaddr.sin_addr.s_addr);
					SYSLOG(LOG_INFO, "[%d] IP: %d.%d.%d.%d\n",
						phsSocketCur->socket,
						phsSocketCur->ipAddr.caddr[3],
						phsSocketCur->ipAddr.caddr[2],
						phsSocketCur->ipAddr.caddr[1],
						phsSocketCur->ipAddr.caddr[0]);

					hp->stats.clientCount++;

					//fill structure with data
					_mwInitSocketData(phsSocketCur);
					phsSocketCur->request.pucPayload = 0;
#ifndef WINCE
					phsSocketCur->tmAcceptTime = time(NULL);
#else
					phsSocketCur->tmAcceptTime = GetTickCount() >> 10;
#endif
					phsSocketCur->tmExpirationTime = phsSocketCur->tmAcceptTime + hp->tmSocketExpireTime;
					phsSocketCur->iRequestCount = 0;
					DBG("Connected clients: %d\n", hp->stats.clientCount);

					//update max client count
					if (hp->stats.clientCount > hp->stats.clientCountMax) hp->stats.clientCountMax = hp->stats.clientCount;
				}
			}
			else {
				//DBG("Select Timeout\n");
				// select timeout
				// call idle event
				if (hp->pfnIdleCallback) {
					(*hp->pfnIdleCallback)(hp);
				}
			}
		}

	return true;
}
<|endoftext|>


<commit_before>#include "Common.h"
#include "DarunGrim.h"
#include "LogOperation.h"

LogOperation Logger;

DarunGrim::DarunGrim():
	pStorageDB(NULL),
	pOneIDAClientManagerTheSource(NULL),
	pOneIDAClientManagerTheTarget(NULL),
	pDiffMachine(NULL),
	pIDAClientManager(NULL),
	SourceFilename(NULL),
	TargetFilename(NULL),
	IsLoadedSourceFile( FALSE )
{
	Logger.SetLogOutputType( LogToStdout );
	Logger.SetDebugLevel( 100 );
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	pIDAClientManager = new IDAClientManager();
}

DarunGrim::~DarunGrim()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	if( pStorageDB )
	{
		pStorageDB->CloseDatabase();
		delete pStorageDB;
	}

	if( pDiffMachine )
		delete pDiffMachine;

	if( pIDAClientManager )
		delete pIDAClientManager;

	if( pOneIDAClientManagerTheSource )
		delete pOneIDAClientManagerTheSource;

	if( pOneIDAClientManagerTheTarget )
		delete pOneIDAClientManagerTheTarget;
}

void DarunGrim::SetLogParameters( int ParamLogOutputType, int ParamDebugLevel, const char *LogFile )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	Logger.SetLogOutputType( ParamLogOutputType );
	if( LogFile )
		Logger.SetLogFilename( LogFile );
	Logger.SetDebugLevel( ParamDebugLevel );
}

void DarunGrim::SetIDAPath( const char *path )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	if( path )
		pIDAClientManager->SetIDAPath( path );
}

bool DarunGrim::GenerateDB(
	char *ParamStorageFilename,
	char *LogFilename,
	DWORD start_address_for_source, DWORD end_address_for_source,
	DWORD start_address_for_target, DWORD end_address_for_target )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	StorageFilename = ParamStorageFilename;

	pIDAClientManager->SetOutputFilename(StorageFilename);
	pIDAClientManager->SetLogFilename(LogFilename);
	pIDAClientManager->RunIDAToGenerateDB( SourceFilename, start_address_for_source, end_address_for_source );
	pIDAClientManager->RunIDAToGenerateDB( TargetFilename, start_address_for_target, end_address_for_target );
	return OpenDatabase();
}

DWORD WINAPI ConnectToDarunGrim2Thread( LPVOID lpParameter )
{
	DarunGrim *pDarunGrim=( DarunGrim * )lpParameter;
	IDAClientManager *pIDAClientManager;

	if( pDarunGrim && (pIDAClientManager = pDarunGrim->GetIDAClientManager()) )
	{
		if( !pDarunGrim->LoadedSourceFile() )
		{
			pIDAClientManager->ConnectToDarunGrim2( pDarunGrim->GetSourceFilename() );
		}
		else
		{
			pIDAClientManager->ConnectToDarunGrim2( pDarunGrim->GetTargetFilename() );
		}
	}
	return 1;
}

char *DarunGrim::GetSourceFilename()
{
	return SourceFilename;
}

void DarunGrim::SetSourceFilename( char *source_filename )
{
	SourceFilename = source_filename;
}

char *DarunGrim::GetTargetFilename()
{
	return TargetFilename;
}

void DarunGrim::SetTargetFilename( char *target_filename )
{
	TargetFilename = target_filename;
}

bool DarunGrim::LoadedSourceFile()
{
	return IsLoadedSourceFile;
}

void DarunGrim::SetLoadedSourceFile( bool is_loaded )
{
	IsLoadedSourceFile = is_loaded;
}

bool DarunGrim::AcceptIDAClientsFromSocket( const char *storage_filename )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );

	if( storage_filename )
	{
		if( pStorageDB )
			delete pStorageDB;

		pStorageDB = new DBWrapper( (char *) storage_filename );
	}

	if( pStorageDB )
	{
		pIDAClientManager->SetDatabase( pStorageDB );
	}
	pIDAClientManager->StartIDAListener( DARUNGRIM2_PORT );

	pOneIDAClientManagerTheSource=new OneIDAClientManager( pStorageDB );
	pOneIDAClientManagerTheTarget=new OneIDAClientManager( pStorageDB );

	//Create a thread that will call ConnectToDarunGrim2 one by one
	DWORD dwThreadId;
	CreateThread( NULL, 0, ConnectToDarunGrim2Thread, ( PVOID )this, 0, &dwThreadId );
	pIDAClientManager->AcceptIDAClient( pOneIDAClientManagerTheSource, pDiffMachine? FALSE:pStorageDB?TRUE:FALSE );
	SetLoadedSourceFile( TRUE );

	CreateThread( NULL, 0, ConnectToDarunGrim2Thread, ( PVOID )this, 0, &dwThreadId );
	pIDAClientManager->AcceptIDAClient( pOneIDAClientManagerTheTarget, pDiffMachine? FALSE:pStorageDB?TRUE:FALSE );

	if( !pDiffMachine )
	{
		Analyze();
	}

	pIDAClientManager->SetMembers( pOneIDAClientManagerTheSource, pOneIDAClientManagerTheTarget, pDiffMachine );
	pIDAClientManager->CreateIDACommandProcessorThread();
	pIDAClientManager->StopIDAListener();

	return TRUE;
}

bool DarunGrim::OpenDatabase()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );

	if( pStorageDB )
		delete pStorageDB;

	pStorageDB = new DBWrapper( StorageFilename );

	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_ONE_LOCATION_INFO_TABLE_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_ONE_LOCATION_INFO_TABLE_START_ADDRESS_INDEX_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_ONE_LOCATION_INFO_TABLE_END_ADDRESS_INDEX_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_MAP_INFO_TABLE_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_MAP_INFO_TABLE_INDEX_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_FILE_INFO_TABLE_STATEMENT);
	return TRUE;
}

bool DarunGrim::LoadDiffResults( const char *storage_filename )
{
	pStorageDB = new DBWrapper( (char *) storage_filename );
	if( pStorageDB )
	{
		pDiffMachine = new DiffMachine();

		if( pDiffMachine )
		{
			pDiffMachine->Retrieve( *pStorageDB,TRUE, 1 , 2 );
			return TRUE;
		}
	}
	return FALSE;
}

bool DarunGrim::Analyze()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	int source_file_id=1;
	int target_file_id=2;

	if( pStorageDB )
	{
		pDiffMachine = new DiffMachine();
		pDiffMachine->Retrieve( *pStorageDB,TRUE,source_file_id,target_file_id);
	}
	else if( pOneIDAClientManagerTheSource && pOneIDAClientManagerTheTarget )
	{
		pDiffMachine = new DiffMachine( pOneIDAClientManagerTheSource, pOneIDAClientManagerTheTarget );
	}

	if( pDiffMachine )
	{
		pDiffMachine->Analyze();
		pDiffMachine->Save( *pStorageDB );
	}
	return TRUE;
}

bool DarunGrim::ShowOnIDA()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	//pDiffMachine->PrintMatchMapInfo();
	if( pIDAClientManager )
	{
		pIDAClientManager->SetMembers(
			pOneIDAClientManagerTheSource,
			pOneIDAClientManagerTheTarget,
			pDiffMachine
		);
		pIDAClientManager->ShowResultsOnIDA();
		pIDAClientManager->IDACommandProcessor();
		return TRUE;
	}
	return FALSE;
}

void DarunGrim::ShowAddresses( unsigned long source_address, unsigned long target_address )
{
	pOneIDAClientManagerTheSource->ShowAddress( source_address );
	pOneIDAClientManagerTheTarget->ShowAddress( target_address );
}

void DarunGrim::ColorAddress( int index, unsigned long start_address, unsigned long end_address,unsigned long color )
{
	if( index == 0 )
	{
		pOneIDAClientManagerTheSource->ColorAddress( start_address, end_address, color );
	}
	else
	{
		pOneIDAClientManagerTheTarget->ColorAddress( start_address, end_address, color );
	}
}

IDAClientManager *DarunGrim::GetIDAClientManager()
{
	return pIDAClientManager;
}
<commit_msg>Support address coloring<commit_after>#include "Common.h"
#include "DarunGrim.h"
#include "LogOperation.h"

LogOperation Logger;

DarunGrim::DarunGrim():
	pStorageDB(NULL),
	pOneIDAClientManagerTheSource(NULL),
	pOneIDAClientManagerTheTarget(NULL),
	pDiffMachine(NULL),
	pIDAClientManager(NULL),
	SourceFilename(NULL),
	TargetFilename(NULL),
	IsLoadedSourceFile( FALSE )
{
	Logger.SetLogOutputType( LogToStdout );
	Logger.SetDebugLevel( 100 );
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	pIDAClientManager = new IDAClientManager();
}

DarunGrim::~DarunGrim()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	if( pStorageDB )
	{
		pStorageDB->CloseDatabase();
		delete pStorageDB;
	}

	if( pDiffMachine )
		delete pDiffMachine;

	if( pIDAClientManager )
		delete pIDAClientManager;

	if( pOneIDAClientManagerTheSource )
		delete pOneIDAClientManagerTheSource;

	if( pOneIDAClientManagerTheTarget )
		delete pOneIDAClientManagerTheTarget;
}

void DarunGrim::SetLogParameters( int ParamLogOutputType, int ParamDebugLevel, const char *LogFile )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	Logger.SetLogOutputType( ParamLogOutputType );
	if( LogFile )
		Logger.SetLogFilename( LogFile );
	Logger.SetDebugLevel( ParamDebugLevel );
}

void DarunGrim::SetIDAPath( const char *path )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	if( path )
		pIDAClientManager->SetIDAPath( path );
}

bool DarunGrim::GenerateDB(
	char *ParamStorageFilename,
	char *LogFilename,
	DWORD start_address_for_source, DWORD end_address_for_source,
	DWORD start_address_for_target, DWORD end_address_for_target )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	StorageFilename = ParamStorageFilename;

	pIDAClientManager->SetOutputFilename(StorageFilename);
	pIDAClientManager->SetLogFilename(LogFilename);
	pIDAClientManager->RunIDAToGenerateDB( SourceFilename, start_address_for_source, end_address_for_source );
	pIDAClientManager->RunIDAToGenerateDB( TargetFilename, start_address_for_target, end_address_for_target );
	return OpenDatabase();
}

DWORD WINAPI ConnectToDarunGrim2Thread( LPVOID lpParameter )
{
	DarunGrim *pDarunGrim=( DarunGrim * )lpParameter;
	IDAClientManager *pIDAClientManager;

	if( pDarunGrim && (pIDAClientManager = pDarunGrim->GetIDAClientManager()) )
	{
		if( !pDarunGrim->LoadedSourceFile() )
		{
			pIDAClientManager->ConnectToDarunGrim2( pDarunGrim->GetSourceFilename() );
		}
		else
		{
			pIDAClientManager->ConnectToDarunGrim2( pDarunGrim->GetTargetFilename() );
		}
	}
	return 1;
}

char *DarunGrim::GetSourceFilename()
{
	return SourceFilename;
}

void DarunGrim::SetSourceFilename( char *source_filename )
{
	SourceFilename = source_filename;
}

char *DarunGrim::GetTargetFilename()
{
	return TargetFilename;
}

void DarunGrim::SetTargetFilename( char *target_filename )
{
	TargetFilename = target_filename;
}

bool DarunGrim::LoadedSourceFile()
{
	return IsLoadedSourceFile;
}

void DarunGrim::SetLoadedSourceFile( bool is_loaded )
{
	IsLoadedSourceFile = is_loaded;
}

bool DarunGrim::AcceptIDAClientsFromSocket( const char *storage_filename )
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );

	if( storage_filename )
	{
		if( pStorageDB )
			delete pStorageDB;

		pStorageDB = new DBWrapper( (char *) storage_filename );
	}

	if( pStorageDB )
	{
		pIDAClientManager->SetDatabase( pStorageDB );
	}
	pIDAClientManager->StartIDAListener( DARUNGRIM2_PORT );

	pOneIDAClientManagerTheSource=new OneIDAClientManager( pStorageDB );
	pOneIDAClientManagerTheTarget=new OneIDAClientManager( pStorageDB );

	//Create a thread that will call ConnectToDarunGrim2 one by one
	DWORD dwThreadId;
	CreateThread( NULL, 0, ConnectToDarunGrim2Thread, ( PVOID )this, 0, &dwThreadId );
	pIDAClientManager->AcceptIDAClient( pOneIDAClientManagerTheSource, pDiffMachine? FALSE:pStorageDB?TRUE:FALSE );
	SetLoadedSourceFile( TRUE );

	CreateThread( NULL, 0, ConnectToDarunGrim2Thread, ( PVOID )this, 0, &dwThreadId );
	pIDAClientManager->AcceptIDAClient( pOneIDAClientManagerTheTarget, pDiffMachine? FALSE:pStorageDB?TRUE:FALSE );

	if( !pDiffMachine )
	{
		Analyze();
	}

	pIDAClientManager->SetMembers( pOneIDAClientManagerTheSource, pOneIDAClientManagerTheTarget, pDiffMachine );
	pIDAClientManager->CreateIDACommandProcessorThread();
	pIDAClientManager->StopIDAListener();

	return TRUE;
}

bool DarunGrim::OpenDatabase()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );

	if( pStorageDB )
		delete pStorageDB;

	pStorageDB = new DBWrapper( StorageFilename );

	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_ONE_LOCATION_INFO_TABLE_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_ONE_LOCATION_INFO_TABLE_START_ADDRESS_INDEX_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_ONE_LOCATION_INFO_TABLE_END_ADDRESS_INDEX_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_MAP_INFO_TABLE_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_MAP_INFO_TABLE_INDEX_STATEMENT);
	pStorageDB->ExecuteStatement(NULL,NULL,CREATE_FILE_INFO_TABLE_STATEMENT);
	return TRUE;
}

bool DarunGrim::LoadDiffResults( const char *storage_filename )
{
	pStorageDB = new DBWrapper( (char *) storage_filename );
	if( pStorageDB )
	{
		pDiffMachine = new DiffMachine();

		if( pDiffMachine )
		{
			pDiffMachine->Retrieve( *pStorageDB,TRUE, 1 , 2 );
			return TRUE;
		}
	}
	return FALSE;
}

bool DarunGrim::Analyze()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	int source_file_id=1;
	int target_file_id=2;

	if( pStorageDB )
	{
		pDiffMachine = new DiffMachine();
		pDiffMachine->Retrieve( *pStorageDB,TRUE,source_file_id,target_file_id);
	}
	else if( pOneIDAClientManagerTheSource && pOneIDAClientManagerTheTarget )
	{
		pDiffMachine = new DiffMachine( pOneIDAClientManagerTheSource, pOneIDAClientManagerTheTarget );
	}

	if( pDiffMachine )
	{
		pDiffMachine->Analyze();
		pDiffMachine->Save( *pStorageDB );
	}
	return TRUE;
}

bool DarunGrim::ShowOnIDA()
{
	Logger.Log(10, "%s: entry\n", __FUNCTION__ );
	//pDiffMachine->PrintMatchMapInfo();
	if( pIDAClientManager )
	{
		pIDAClientManager->SetMembers(
			pOneIDAClientManagerTheSource,
			pOneIDAClientManagerTheTarget,
			pDiffMachine
		);
		pIDAClientManager->ShowResultsOnIDA();
		pIDAClientManager->IDACommandProcessor();
		return TRUE;
	}
	return FALSE;
}

void DarunGrim::ShowAddresses( unsigned long source_address, unsigned long target_address )
{
	if( pOneIDAClientManagerTheSource )
		pOneIDAClientManagerTheSource->ShowAddress( source_address );
	if( pOneIDAClientManagerTheTarget )
		pOneIDAClientManagerTheTarget->ShowAddress( target_address );
}

void DarunGrim::ColorAddress( int index, unsigned long start_address, unsigned long end_address,unsigned long color )
{
	if( index == 0 )
	{
		if( pOneIDAClientManagerTheSource )
			pOneIDAClientManagerTheSource->ColorAddress( start_address, end_address, color );
	}
	else
	{
		if( pOneIDAClientManagerTheTarget )
			pOneIDAClientManagerTheTarget->ColorAddress( start_address, end_address, color );
	}
}

IDAClientManager *DarunGrim::GetIDAClientManager()
{
	return pIDAClientManager;
}
<|endoftext|>


<commit_before>#include <ocean/displacement_map.h>

#include <util/error.h>
#include <util/util.h>

namespace ocean {

#define N_FFT_BATCHES 5

displacement_map::displacement_map(gpu::compute::command_queue queue, const surface_params& params)
  : queue(queue),
    wave_spectrum(queue.getInfo<CL_QUEUE_CONTEXT>(), params),
    fft_algorithm(queue, params.grid_size, N_FFT_BATCHES),
    displacement_map(queue.getInfo<CL_QUEUE_CONTEXT>(), params.grid_size, texture_format::TEXTURE_FORMAT_RGBA8),
    height_gradient_map(queue.getInfo<CL_QUEUE_CONTEXT>(), params.grid_size, texture_format::TEXTURE_FORMAT_RG16F)
{
    int N = wave_spectrum.get_N();
    int M = wave_spectrum.get_M();
    auto context = queue.getInfo<CL_QUEUE_CONTEXT>();
    size_t buf_size_bytes = N_FFT_BATCHES * (N + 2) * M * sizeof(float);
    fft_buffer = gpu::compute::buffer(context, CL_MEM_READ_WRITE, buf_size_bytes);

    load_export_kernel();
}

displacement_map::shared_texture::shared_texture(gpu::compute::context& context, math::ivec2 size, texture_format format)
{
    tex.init(size.x, size.y, format);
    tex.set_max_anisotropy(2);
    img = gpu::compute::graphics_image(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, tex.get_api_texture());
    tex.generate_mipmap();
}

void displacement_map::enqueue_generate(math::real time, const gpu::compute::event_vector *wait_events)
{
    gpu::compute::event event;
    event = wave_spectrum.enqueue_generate(queue, time, fft_buffer, wait_events);
    event = fft_algorithm.enqueue_transform(queue, fft_buffer, &gpu::compute::event_vector({ event }));
    event = enqueue_export_kernel(&gpu::compute::event_vector({ event }));
    event.wait();

    displacement_map.tex.generate_mipmap();
    height_gradient_map.tex.generate_mipmap();
}

void displacement_map::load_export_kernel()
{
    auto program = gpu::compute::create_program_from_file(queue.getInfo<CL_QUEUE_CONTEXT>(), "kernels/export_to_texture.cl");
    export_kernel = gpu::compute::kernel(program, "export_to_texture");

    export_kernel.setArg(0, fft_buffer);
    export_kernel.setArg(1, wave_spectrum.get_N());
    export_kernel.setArg(2, wave_spectrum.get_M());
    export_kernel.setArg(3, displacement_map.img);
    export_kernel.setArg(4, height_gradient_map.img);
}

gpu::compute::event displacement_map::enqueue_export_kernel(const gpu::compute::event_vector *wait_events)
{
    gpu::compute::event event;
    std::vector<gpu::compute::memory_object> gl_objects = { displacement_map.img, height_gradient_map.img };

    queue.enqueueAcquireGLObjects(&gl_objects, wait_events, &event);
    gpu::compute::nd_range offset = { 0, 0 }, local_size = { 1, 1 };
    gpu::compute::nd_range global_size = { static_cast<size_t>(wave_spectrum.get_N()), static_cast<size_t>(wave_spectrum.get_M()) };
    queue.enqueueNDRangeKernel(export_kernel, offset, global_size, local_size, &gpu::compute::event_vector({ event }), &event);
    queue.enqueueReleaseGLObjects(&gl_objects, &gpu::compute::event_vector({ event }), &event);
    return event;
}

} // namespace ocean
<commit_msg>move fft_buffer init to initializer list<commit_after>#include <ocean/displacement_map.h>

#include <util/error.h>
#include <util/util.h>

namespace ocean {

#define N_FFT_BATCHES 5

displacement_map::displacement_map(gpu::compute::command_queue queue, const surface_params& params)
  : queue(queue),
    wave_spectrum(queue.getInfo<CL_QUEUE_CONTEXT>(), params),
    fft_algorithm(queue, params.grid_size, N_FFT_BATCHES),
    fft_buffer(queue.getInfo<CL_QUEUE_CONTEXT>(), CL_MEM_READ_ONLY, N_FFT_BATCHES * (params.grid_size.x + 2) * params.grid_size.y * sizeof(float)),
    displacement_map(queue.getInfo<CL_QUEUE_CONTEXT>(), params.grid_size, texture_format::TEXTURE_FORMAT_RGBA8),
    height_gradient_map(queue.getInfo<CL_QUEUE_CONTEXT>(), params.grid_size, texture_format::TEXTURE_FORMAT_RG16F)
{
    load_export_kernel();
}

displacement_map::shared_texture::shared_texture(gpu::compute::context& context, math::ivec2 size, texture_format format)
{
    tex.init(size.x, size.y, format);
    tex.set_max_anisotropy(2);
    img = gpu::compute::graphics_image(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, tex.get_api_texture());
    tex.generate_mipmap();
}

void displacement_map::enqueue_generate(math::real time, const gpu::compute::event_vector *wait_events)
{
    gpu::compute::event event;
    event = wave_spectrum.enqueue_generate(queue, time, fft_buffer, wait_events);
    event = fft_algorithm.enqueue_transform(queue, fft_buffer, &gpu::compute::event_vector({ event }));
    event = enqueue_export_kernel(&gpu::compute::event_vector({ event }));
    event.wait();

    displacement_map.tex.generate_mipmap();
    height_gradient_map.tex.generate_mipmap();
}

void displacement_map::load_export_kernel()
{
    auto program = gpu::compute::create_program_from_file(queue.getInfo<CL_QUEUE_CONTEXT>(), "kernels/export_to_texture.cl");
    export_kernel = gpu::compute::kernel(program, "export_to_texture");

    export_kernel.setArg(0, fft_buffer);
    export_kernel.setArg(1, wave_spectrum.get_N());
    export_kernel.setArg(2, wave_spectrum.get_M());
    export_kernel.setArg(3, displacement_map.img);
    export_kernel.setArg(4, height_gradient_map.img);
}

gpu::compute::event displacement_map::enqueue_export_kernel(const gpu::compute::event_vector *wait_events)
{
    gpu::compute::event event;
    std::vector<gpu::compute::memory_object> gl_objects = { displacement_map.img, height_gradient_map.img };

    queue.enqueueAcquireGLObjects(&gl_objects, wait_events, &event);
    gpu::compute::nd_range offset = { 0, 0 }, local_size = { 1, 1 };
    gpu::compute::nd_range global_size = { static_cast<size_t>(wave_spectrum.get_N()), static_cast<size_t>(wave_spectrum.get_M()) };
    queue.enqueueNDRangeKernel(export_kernel, offset, global_size, local_size, &gpu::compute::event_vector({ event }), &event);
    queue.enqueueReleaseGLObjects(&gl_objects, &gpu::compute::event_vector({ event }), &event);
    return event;
}

} // namespace ocean
<|endoftext|>


<commit_before>#include <cassert>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <iostream>

#include <set>
#include <unordered_set>
#include "clause.h"
#include "config.h"

using namespace satsolver;

Clause::Clause(int nb_var, std::shared_ptr<std::vector<int>> literals) {
    this->literals = std::unordered_set<int>() ;
    this->nb_variables = nb_var;
    for(std::vector<int>::iterator it = literals->begin(); it != literals->end(); ++it) {
        assert(*it != 0 && abs(*it) <= nb_var);
        this->literals.insert(*it) ;
    }
    if (WITH_WL)
        this->watched = std::pair<int,int>(0,0) ;
    this->aff = NULL ;
}
Clause::Clause(int nb_var, std::vector<int> literals) {
    this->literals = std::unordered_set<int>() ;
    this->nb_variables = nb_var;
    for(std::vector<int>::iterator it = literals.begin(); it != literals.end(); ++it) {
        assert(*it != 0 && abs(*it) <= nb_var);
        this->literals.insert(*it) ;
    }
    if (WITH_WL)
        this->watched = std::pair<int,int>(0,0) ;
    this->aff = NULL ;
}

Clause::Clause(const Clause &c){
    this->literals = std::unordered_set<int>(c.literals) ;
    this->nb_variables = c.nb_variables ;
    if (WITH_WL)
        this->watched = std::pair<int,int>(c.watched) ;
    this->aff = c.aff ;
}

Clause& Clause::operator=(const Clause &that) {
    this->literals = that.literals;
    this->nb_variables = that.nb_variables;
    if (WITH_WL)
        this->watched = that.watched ;
    return *this;
    this->aff = that.aff ;
}

Clause::~Clause() {

}

int Clause::get_size() const {
    return (int) this->literals.size() ;
}

bool Clause::is_empty() const {
    return this->get_size() == 0 ;
}

bool Clause::contains_literal(int literal) const {
    assert(abs(literal)<=this->nb_variables && literal != 0);
    return this->literals.find(literal) != this->literals.end() ;
}

void Clause::add(int literal) {
    assert(abs(literal)<=this->nb_variables && literal != 0);
    this->literals.insert(literal) ;
}

void Clause::remove(int literal) {
    assert(abs(literal)<=this->nb_variables && literal != 0);
    this->literals.erase(literal) ;
}

bool Clause::is_tautology() const {
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(this->contains_literal(i) && this->contains_literal(-i))
            return true ;
    }
    return false ;
}

std::string Clause::to_string()  {
    std::ostringstream oss;
    bool flag = false ;
    oss << "{" ;
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(this->contains_literal(-i)) {
            if(flag)
                oss << "," ;
            flag = true ;
            oss << -i ;
        }
        if(this->contains_literal(i)) {
            if(flag)
                oss << "," ;
            flag = true ;
            oss << i ;
        }
    }
    oss << "}" ;
    if(WITH_WL) oss << " WL : " << this->fst_WL() << " & " << this->snd_WL()  ;
    return oss.str() ;
}

std::string Clause::to_string2()  {
    std::ostringstream oss;
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(this->contains_literal(-i)) {
            oss << -i << " ";
        }
        if(this->contains_literal(i)) {
            oss << i << " ";
        }
    }
    oss << "0" ;
    return oss.str() ;
}

std::set<int> Clause::to_set() const {
    std::set<int> s = std::set<int>() ;
    for(auto l : this->literals) {
        if(!this->aff->is_false(l)) {
            s.insert(l) ;
        }
    }
    return s ;
}

bool Clause::contains_clause(satsolver::Clause &c) const {
    if(this->get_size() < c.get_size()) {
        return false ;
    }
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(!this->contains_literal(i) && c.contains_literal(i))
            return false ;
        if(!this->contains_literal(-i) && c.contains_literal(-i))
            return false ;
    }
    return true ;
}

void Clause::init_WL() {
    assert(WITH_WL);
    assert(this->get_size() >= 2) ;
    std::unordered_set<int>::iterator it = this->literals.begin() ;
    this->watched.first = *it ;
    ++it ;
    this->watched.second = *it ;
}

int Clause::fst_WL() const{
    assert(WITH_WL);
    return this->watched.first ;
}
int Clause::snd_WL() const{
    assert(WITH_WL);
    return this->watched.second ;
}

bool Clause::is_WL(int x) {
    assert(WITH_WL);
    return this->watched.first == x || this->watched.second == x ;
}

void Clause::set_affectation(Affectation *a) {
    this->aff = a ;
}

int Clause::set_true(int x) {
    if (!WITH_WL)
        return 0;

    if(this->contains_literal(x) && !this->is_WL(x)) { // on installe x comme littéral surveillé
        if(this->aff->is_unknown(this->fst_WL()))  // priorité aux littéraux vrais
            this->watched.first = x ;
        else
            this->watched.second = x ;
        return 0 ;
    }
    else if(this->contains_literal(x)) { // rien
        return 0 ;
    }
    else if(this->is_WL(-x)) { // on surveille un littéral qui a été mis à faux
        if(this->aff->is_true(this->fst_WL()) || this->aff->is_true(this->snd_WL()))
            return 0 ; // rien à faire, la clause est satisfaite
        for(auto literal : this->literals) {
            if(!this->aff->is_false(literal) && !this->is_WL(literal)) { // nouveau literal surveillé
                if(this->fst_WL() == -x)
                    this->watched.first = literal ;
                else
                    this->watched.second = literal ;
                return 0 ; // pas de propagation unitaire, on a trouvé un remplaçant
            }
        }
        // On n'a pas trouvé de remplaçant, il ne reste donc qu'un literal non faux
        if(this->fst_WL() != -x)
            return this->fst_WL() ;
        else
            return this->snd_WL() ;
    }
    return 0 ;
}

int Clause::set_false(int x) {
    return this->set_true(-x) ;
}

bool Clause::is_true() {
    for(auto l : this->literals) {
        if(this->aff->is_true(l))
            return true ;
    }
    return false ;
}

int Clause::monome_begin() {
    if(this->literals.size() == 1)
        return *(this->literals.begin()) ;
    return 0 ;
}

int Clause::monome() {
    assert(!WITH_WL) ;
    int literal = 0, count = 0;
    for(auto l : literals) {
        if(this->aff->is_true(l))
            return 0 ;
        else if(this->aff->is_unknown(l)) {
            if(count > 0)
                return 0 ;
            literal = l ;
            count ++ ;
        }
    }
    return literal ;
}

bool Clause::is_evaluated_to_false() const {
		if(WITH_WL)
			return (this->aff->is_false(this->fst_WL()) && this->aff->is_false(this->snd_WL())) ;
    for (auto literal : this->literals)
        if (!this->aff->is_false(literal))
            return false;
    return true;
}

bool Clause::is_evaluated_to_true() const {
		if(WITH_WL)
			return (this->aff->is_true(this->fst_WL()) || this->aff->is_true(this->snd_WL())) ;
    for (auto literal : this->literals)
        if (this->aff->is_true(literal))
            return true;
    return false;
}

void Clause::add_literals_to_vector(std::vector<int> &v) const {
	if(this->is_evaluated_to_true())
		return ;
	for(auto l : this->literals) { // clause insatisfaite, on ajoute tous les littéraux non faux
		if(this->aff->is_unknown(l))
			v.push_back(l) ;
	}
}
<commit_msg>Small update of true clauses detection.<commit_after>#include <cassert>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <iostream>

#include <set>
#include <unordered_set>
#include "clause.h"
#include "config.h"

using namespace satsolver;

Clause::Clause(int nb_var, std::shared_ptr<std::vector<int>> literals) {
    this->literals = std::unordered_set<int>() ;
    this->nb_variables = nb_var;
    for(std::vector<int>::iterator it = literals->begin(); it != literals->end(); ++it) {
        assert(*it != 0 && abs(*it) <= nb_var);
        this->literals.insert(*it) ;
    }
    if (WITH_WL)
        this->watched = std::pair<int,int>(0,0) ;
    this->aff = NULL ;
}
Clause::Clause(int nb_var, std::vector<int> literals) {
    this->literals = std::unordered_set<int>() ;
    this->nb_variables = nb_var;
    for(std::vector<int>::iterator it = literals.begin(); it != literals.end(); ++it) {
        assert(*it != 0 && abs(*it) <= nb_var);
        this->literals.insert(*it) ;
    }
    if (WITH_WL)
        this->watched = std::pair<int,int>(0,0) ;
    this->aff = NULL ;
}

Clause::Clause(const Clause &c){
    this->literals = std::unordered_set<int>(c.literals) ;
    this->nb_variables = c.nb_variables ;
    if (WITH_WL)
        this->watched = std::pair<int,int>(c.watched) ;
    this->aff = c.aff ;
}

Clause& Clause::operator=(const Clause &that) {
    this->literals = that.literals;
    this->nb_variables = that.nb_variables;
    if (WITH_WL)
        this->watched = that.watched ;
    return *this;
    this->aff = that.aff ;
}

Clause::~Clause() {

}

int Clause::get_size() const {
    return (int) this->literals.size() ;
}

bool Clause::is_empty() const {
    return this->get_size() == 0 ;
}

bool Clause::contains_literal(int literal) const {
    assert(abs(literal)<=this->nb_variables && literal != 0);
    return this->literals.find(literal) != this->literals.end() ;
}

void Clause::add(int literal) {
    assert(abs(literal)<=this->nb_variables && literal != 0);
    this->literals.insert(literal) ;
}

void Clause::remove(int literal) {
    assert(abs(literal)<=this->nb_variables && literal != 0);
    this->literals.erase(literal) ;
}

bool Clause::is_tautology() const {
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(this->contains_literal(i) && this->contains_literal(-i))
            return true ;
    }
    return false ;
}

std::string Clause::to_string()  {
    std::ostringstream oss;
    bool flag = false ;
    oss << "{" ;
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(this->contains_literal(-i)) {
            if(flag)
                oss << "," ;
            flag = true ;
            oss << -i ;
        }
        if(this->contains_literal(i)) {
            if(flag)
                oss << "," ;
            flag = true ;
            oss << i ;
        }
    }
    oss << "}" ;
    if(WITH_WL) oss << " WL : " << this->fst_WL() << " & " << this->snd_WL()  ;
    return oss.str() ;
}

std::string Clause::to_string2()  {
    std::ostringstream oss;
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(this->contains_literal(-i)) {
            oss << -i << " ";
        }
        if(this->contains_literal(i)) {
            oss << i << " ";
        }
    }
    oss << "0" ;
    return oss.str() ;
}

std::set<int> Clause::to_set() const {
    std::set<int> s = std::set<int>() ;
    for(auto l : this->literals) {
        if(!this->aff->is_false(l)) {
            s.insert(l) ;
        }
    }
    return s ;
}

bool Clause::contains_clause(satsolver::Clause &c) const {
    if(this->get_size() < c.get_size()) {
        return false ;
    }
    for(int i = 1 ; i <= this->nb_variables ; i++) {
        if(!this->contains_literal(i) && c.contains_literal(i))
            return false ;
        if(!this->contains_literal(-i) && c.contains_literal(-i))
            return false ;
    }
    return true ;
}

void Clause::init_WL() {
    assert(WITH_WL);
    assert(this->get_size() >= 2) ;
    std::unordered_set<int>::iterator it = this->literals.begin() ;
    this->watched.first = *it ;
    ++it ;
    this->watched.second = *it ;
}

int Clause::fst_WL() const{
    assert(WITH_WL);
    return this->watched.first ;
}
int Clause::snd_WL() const{
    assert(WITH_WL);
    return this->watched.second ;
}

bool Clause::is_WL(int x) {
    assert(WITH_WL);
    return this->watched.first == x || this->watched.second == x ;
}

void Clause::set_affectation(Affectation *a) {
    this->aff = a ;
}

int Clause::set_true(int x) {
    if (!WITH_WL)
        return 0;

    if(this->contains_literal(x) && !this->is_WL(x)) { // on installe x comme littéral surveillé
        if(this->aff->is_unknown(this->fst_WL()))  // priorité aux littéraux vrais
            this->watched.first = x ;
        else
            this->watched.second = x ;
        return 0 ;
    }
    else if(this->contains_literal(x)) { // rien
        return 0 ;
    }
    else if(this->is_WL(-x)) { // on surveille un littéral qui a été mis à faux
        if(this->aff->is_true(this->fst_WL()) || this->aff->is_true(this->snd_WL()))
            return 0 ; // rien à faire, la clause est satisfaite
        for(auto literal : this->literals) {
            if(!this->aff->is_false(literal) && !this->is_WL(literal)) { // nouveau literal surveillé
                if(this->fst_WL() == -x)
                    this->watched.first = literal ;
                else
                    this->watched.second = literal ;
                return 0 ; // pas de propagation unitaire, on a trouvé un remplaçant
            }
        }
        // On n'a pas trouvé de remplaçant, il ne reste donc qu'un literal non faux
        if(this->fst_WL() != -x)
            return this->fst_WL() ;
        else
            return this->snd_WL() ;
    }
    return 0 ;
}

int Clause::set_false(int x) {
    return this->set_true(-x) ;
}

bool Clause::is_true() {
    for(auto l : this->literals) {
        if(this->aff->is_true(l))
            return true ;
    }
    return false ;
}

int Clause::monome_begin() {
    if(this->literals.size() == 1)
        return *(this->literals.begin()) ;
    return 0 ;
}

int Clause::monome() {
    assert(!WITH_WL) ;
    int literal = 0, count = 0;
    for(auto l : literals) {
        if(this->aff->is_true(l))
            return 0 ;
        else if(this->aff->is_unknown(l)) {
            if(count > 0)
                return 0 ;
            literal = l ;
            count ++ ;
        }
    }
    return literal ;
}

bool Clause::is_evaluated_to_false() const {
		if(WITH_WL)
			return (this->aff->is_false(this->fst_WL()) && this->aff->is_false(this->snd_WL())) ;
    for (auto literal : this->literals)
        if (!this->aff->is_false(literal))
            return false;
    return true;
}

bool Clause::is_evaluated_to_true() const {
		if(WITH_WL && (this->aff->is_true(this->fst_WL()) || this->aff->is_true(this->snd_WL())))
			return true ;
    for (auto literal : this->literals)
        if (this->aff->is_true(literal))
            return true;
    return false;
}

void Clause::add_literals_to_vector(std::vector<int> &v) const {
	if(this->is_evaluated_to_true())
		return ;
	for(auto l : this->literals) { // clause insatisfaite, on ajoute tous les littéraux non faux
		if(this->aff->is_unknown(l))
			v.push_back(l) ;
	}
}
<|endoftext|>