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

  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 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_;
  }

  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
    Common::ConfigTree cfg;
    if (config.has_sub(sub_name))
      cfg = config.sub(sub_name);
    else
      cfg = config;
    //extract data
      auto value = cfg.get< RangeFieldImp >("value");
      auto nm = cfg.get< std::string >("name", static_id());
      return Common::make_unique< ThisType >(value, nm);
  } // ... create(...)

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::Function::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] move static methods to the top<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>
{

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
    Common::ConfigTree cfg;
    if (config.has_sub(sub_name))
      cfg = config.sub(sub_name);
    else
      cfg = config;
    //extract data
      auto value = cfg.get< RangeFieldImp >("value");
      auto nm = cfg.get< std::string >("name", static_id());
      return Common::make_unique< ThisType >(value, nm);
  } // ... 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 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::Function::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>/*=========================================================================

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

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

  Some parts of this code are derived from ITK. See ITKCopyright.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 "otbWriterWatcherBase.h"

namespace otb
{

WriterWatcherBase
::WriterWatcherBase()
{
  // Initialize state
  m_Comment = "Not watching any object";
  m_Process = 0;
}

WriterWatcherBase
::WriterWatcherBase(itk::ProcessObject* process,
                    const char *comment)
{
  // Initialize state
  m_Process = process;
  m_Comment = comment;

  // Create a series of commands
  m_StartWriterCommand = CommandType::New();
  m_EndWriterCommand = CommandType::New();
  m_ProgressWriterCommand = CommandType::New();
  m_StartFilterCommand = CommandType::New();
  m_EndFilterCommand = CommandType::New();
  m_ProgressFilterCommand = CommandType::New();

  // Assign the callbacks
  m_StartFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartFilter);
  m_EndFilterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndFilter);
  m_ProgressFilterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowFilterProgress);
  m_StartWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartWriter);
  m_EndWriterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndWriter);
  m_ProgressWriterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowWriterProgress);

  // Add the commands as observers
  m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(),
                                            m_StartWriterCommand);

  m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(),
                                          m_EndWriterCommand);

  m_ProgressWriterTag = m_Process->AddObserver(itk::ProgressEvent(),
                                               m_ProgressWriterCommand);

  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;

 // Try to get the filter that is wired to m_Process.
  if (m_Process->GetInputs()[0]->GetSource())
    {
    m_SourceProcess = m_Process->GetInputs()[0]->GetSource();

    // Add the commands as observers
    m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(),
                                                    m_StartFilterCommand);

    m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(),
                                                  m_EndFilterCommand);

    m_ProgressFilterTag = m_SourceProcess->AddObserver(itk::ProgressEvent(),
                                                       m_ProgressFilterCommand);
    }
}

WriterWatcherBase
::WriterWatcherBase(itk::ProcessObject* process, itk::ProcessObject * source,
                    const char *comment)
{
  // Initialize state
  m_Process = process;
  m_Comment = comment;

  // Create a series of commands
  m_StartWriterCommand = CommandType::New();
  m_EndWriterCommand = CommandType::New();
  m_ProgressWriterCommand = CommandType::New();
  m_StartFilterCommand = CommandType::New();
  m_EndFilterCommand = CommandType::New();
  m_ProgressFilterCommand = CommandType::New();

  // Assign the callbacks
  m_StartFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartFilter);
  m_EndFilterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndFilter);
  m_ProgressFilterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowFilterProgress);
  m_StartWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartWriter);
  m_EndWriterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndWriter);
  m_ProgressWriterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowWriterProgress);

  // Add the commands as observers
  m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(),
                                            m_StartWriterCommand);

  m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(),
                                          m_EndWriterCommand);

  m_ProgressWriterTag = m_Process->AddObserver(itk::ProgressEvent(),
                                               m_ProgressWriterCommand);

  m_SourceProcess = source;

  // Add the commands as observers
  m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(),
                                                  m_StartFilterCommand);

  m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(),
                                                m_EndFilterCommand);

  m_ProgressFilterTag = m_SourceProcess->AddObserver(itk::ProgressEvent(),
                                                     m_ProgressFilterCommand);
}

WriterWatcherBase
::WriterWatcherBase(const WriterWatcherBase& watch)
{
  // Remove any observers we have on the old process object
  if (m_Process)
    {
    if (m_StartWriterCommand)
      {
      m_Process->RemoveObserver(m_StartWriterTag);
      }
    if (m_EndWriterCommand)
      {
      m_Process->RemoveObserver(m_EndWriterTag);
      }
    if (m_ProgressWriterCommand)
      {
      m_Process->RemoveObserver(m_ProgressWriterTag);
      }
    }
  if (m_SourceProcess)
    {
    if (m_StartFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_StartFilterTag);
      }
    if (m_EndFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_EndFilterTag);
      }
    if (m_ProgressFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_ProgressFilterTag);
      }
    }

  // Initialize state
  m_TimeProbe = watch.m_TimeProbe;
  m_Process = watch.m_Process;
  m_SourceProcess = watch.m_SourceProcess;
  m_Comment = watch.m_Comment;

  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;
  m_StartWriterTag = 0;
  m_EndWriterTag = 0;
  m_ProgressWriterTag = 0;

  // Create a series of commands
  if (m_Process)
    {
    m_StartWriterCommand = CommandType::New();
    m_EndWriterCommand = CommandType::New();
    m_ProgressWriterCommand = CommandType::New();

    // Assign the callbacks
    m_StartWriterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartWriter);
    m_EndWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndWriter);
    m_ProgressWriterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowWriterProgress);

    // Add the commands as observers
    m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(), m_StartWriterCommand);
    m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(), m_EndWriterCommand);
    m_ProgressWriterTag
      = m_Process->AddObserver(itk::ProgressEvent(), m_ProgressWriterCommand);
    }

  if (m_SourceProcess)
    {
    m_StartFilterCommand = CommandType::New();
    m_EndFilterCommand = CommandType::New();
    m_ProgressFilterCommand = CommandType::New();

    // Assign the callbacks
    m_StartFilterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartFilter);
    m_EndFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndFilter);
    m_ProgressFilterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowFilterProgress);

    // Add the commands as observers
    m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(), m_StartFilterCommand);
    m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(), m_EndFilterCommand);
    m_ProgressFilterTag
      = m_SourceProcess->AddObserver(itk::ProgressEvent(), m_ProgressFilterCommand);
    }
}

void
WriterWatcherBase
::operator =(const WriterWatcherBase& watch)
{
// Remove any observers we have on the old process object
  if (m_Process)
    {
    if (m_StartWriterCommand)
      {
      m_Process->RemoveObserver(m_StartWriterTag);
      }
    if (m_EndWriterCommand)
      {
      m_Process->RemoveObserver(m_EndWriterTag);
      }
    if (m_ProgressWriterCommand)
      {
      m_Process->RemoveObserver(m_ProgressWriterTag);
      }
    }
  if (m_SourceProcess)
    {
    if (m_StartFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_StartFilterTag);
      }
    if (m_EndFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_EndFilterTag);
      }
    if (m_ProgressFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_ProgressFilterTag);
      }
    }

  // Initialize state
  m_TimeProbe = watch.m_TimeProbe;
  m_Process = watch.m_Process;
  m_SourceProcess = watch.m_SourceProcess;
  m_Comment = watch.m_Comment;

  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;
  m_StartWriterTag = 0;
  m_EndWriterTag = 0;
  m_ProgressWriterTag = 0;

  // Create a series of commands
  if (m_Process)
    {
    m_StartWriterCommand = CommandType::New();
    m_EndWriterCommand = CommandType::New();
    m_ProgressWriterCommand = CommandType::New();

    // Assign the callbacks
    m_StartWriterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartWriter);
    m_EndWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndWriter);
    m_ProgressWriterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowWriterProgress);

    // Add the commands as observers
    m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(), m_StartWriterCommand);
    m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(), m_EndWriterCommand);
    m_ProgressWriterTag
      = m_Process->AddObserver(itk::ProgressEvent(), m_ProgressWriterCommand);
    }
  if (m_SourceProcess)
    {
    m_StartFilterCommand = CommandType::New();
    m_EndFilterCommand = CommandType::New();
    m_ProgressFilterCommand = CommandType::New();

    // Assign the callbacks
    m_StartFilterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartFilter);
    m_EndFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndFilter);
    m_ProgressFilterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowFilterProgress);

    // Add the commands as observers
    m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(), m_StartFilterCommand);
    m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(), m_EndFilterCommand);
    m_ProgressFilterTag
      = m_SourceProcess->AddObserver(itk::ProgressEvent(), m_ProgressFilterCommand);
    }
}

WriterWatcherBase
::~WriterWatcherBase()
{
  // Remove any observers we have on the old process object
  if (m_Process)
    {
    if (m_StartWriterCommand)
      {
      m_Process->RemoveObserver(m_StartWriterTag);
      }
    if (m_EndWriterCommand)
      {
      m_Process->RemoveObserver(m_EndWriterTag);
      }
    if (m_ProgressWriterCommand)
      {
      m_Process->RemoveObserver(m_ProgressWriterTag);
      }
    }
  if (m_SourceProcess)
    {
    if (m_StartFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_StartFilterTag);
      }
    if (m_EndFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_EndFilterTag);
      }
    if (m_ProgressFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_ProgressFilterTag);
      }
    }
}

} // end namespace otb
<commit_msg>COV: Fixing coverty issue 1221890 (Unintialized scalar field)<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.

  Some parts of this code are derived from ITK. See ITKCopyright.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 "otbWriterWatcherBase.h"

namespace otb
{

WriterWatcherBase
::WriterWatcherBase()
{
  // Initialize state
  m_Comment = "Not watching any object";
  m_Process = 0;
  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;
  m_StartWriterTag = 0;
  m_EndWriterTag = 0;
  m_ProgressWriterTag = 0;
}

WriterWatcherBase
::WriterWatcherBase(itk::ProcessObject* process,
                    const char *comment)
{
  // Initialize state
  m_Process = process;
  m_Comment = comment;

  // Create a series of commands
  m_StartWriterCommand = CommandType::New();
  m_EndWriterCommand = CommandType::New();
  m_ProgressWriterCommand = CommandType::New();
  m_StartFilterCommand = CommandType::New();
  m_EndFilterCommand = CommandType::New();
  m_ProgressFilterCommand = CommandType::New();

  // Assign the callbacks
  m_StartFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartFilter);
  m_EndFilterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndFilter);
  m_ProgressFilterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowFilterProgress);
  m_StartWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartWriter);
  m_EndWriterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndWriter);
  m_ProgressWriterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowWriterProgress);

  // Add the commands as observers
  m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(),
                                            m_StartWriterCommand);

  m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(),
                                          m_EndWriterCommand);

  m_ProgressWriterTag = m_Process->AddObserver(itk::ProgressEvent(),
                                               m_ProgressWriterCommand);

  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;

 // Try to get the filter that is wired to m_Process.
  if (m_Process->GetInputs()[0]->GetSource())
    {
    m_SourceProcess = m_Process->GetInputs()[0]->GetSource();

    // Add the commands as observers
    m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(),
                                                    m_StartFilterCommand);

    m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(),
                                                  m_EndFilterCommand);

    m_ProgressFilterTag = m_SourceProcess->AddObserver(itk::ProgressEvent(),
                                                       m_ProgressFilterCommand);
    }
}

WriterWatcherBase
::WriterWatcherBase(itk::ProcessObject* process, itk::ProcessObject * source,
                    const char *comment)
{
  // Initialize state
  m_Process = process;
  m_Comment = comment;

  // Create a series of commands
  m_StartWriterCommand = CommandType::New();
  m_EndWriterCommand = CommandType::New();
  m_ProgressWriterCommand = CommandType::New();
  m_StartFilterCommand = CommandType::New();
  m_EndFilterCommand = CommandType::New();
  m_ProgressFilterCommand = CommandType::New();

  // Assign the callbacks
  m_StartFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartFilter);
  m_EndFilterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndFilter);
  m_ProgressFilterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowFilterProgress);
  m_StartWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::StartWriter);
  m_EndWriterCommand->SetCallbackFunction(this,
                                          &WriterWatcherBase::EndWriter);
  m_ProgressWriterCommand->SetCallbackFunction(this,
                                               &WriterWatcherBase::ShowWriterProgress);

  // Add the commands as observers
  m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(),
                                            m_StartWriterCommand);

  m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(),
                                          m_EndWriterCommand);

  m_ProgressWriterTag = m_Process->AddObserver(itk::ProgressEvent(),
                                               m_ProgressWriterCommand);

  m_SourceProcess = source;

  // Add the commands as observers
  m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(),
                                                  m_StartFilterCommand);

  m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(),
                                                m_EndFilterCommand);

  m_ProgressFilterTag = m_SourceProcess->AddObserver(itk::ProgressEvent(),
                                                     m_ProgressFilterCommand);
}

WriterWatcherBase
::WriterWatcherBase(const WriterWatcherBase& watch)
{
  // Remove any observers we have on the old process object
  if (m_Process)
    {
    if (m_StartWriterCommand)
      {
      m_Process->RemoveObserver(m_StartWriterTag);
      }
    if (m_EndWriterCommand)
      {
      m_Process->RemoveObserver(m_EndWriterTag);
      }
    if (m_ProgressWriterCommand)
      {
      m_Process->RemoveObserver(m_ProgressWriterTag);
      }
    }
  if (m_SourceProcess)
    {
    if (m_StartFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_StartFilterTag);
      }
    if (m_EndFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_EndFilterTag);
      }
    if (m_ProgressFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_ProgressFilterTag);
      }
    }

  // Initialize state
  m_TimeProbe = watch.m_TimeProbe;
  m_Process = watch.m_Process;
  m_SourceProcess = watch.m_SourceProcess;
  m_Comment = watch.m_Comment;

  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;
  m_StartWriterTag = 0;
  m_EndWriterTag = 0;
  m_ProgressWriterTag = 0;

  // Create a series of commands
  if (m_Process)
    {
    m_StartWriterCommand = CommandType::New();
    m_EndWriterCommand = CommandType::New();
    m_ProgressWriterCommand = CommandType::New();

    // Assign the callbacks
    m_StartWriterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartWriter);
    m_EndWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndWriter);
    m_ProgressWriterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowWriterProgress);

    // Add the commands as observers
    m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(), m_StartWriterCommand);
    m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(), m_EndWriterCommand);
    m_ProgressWriterTag
      = m_Process->AddObserver(itk::ProgressEvent(), m_ProgressWriterCommand);
    }

  if (m_SourceProcess)
    {
    m_StartFilterCommand = CommandType::New();
    m_EndFilterCommand = CommandType::New();
    m_ProgressFilterCommand = CommandType::New();

    // Assign the callbacks
    m_StartFilterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartFilter);
    m_EndFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndFilter);
    m_ProgressFilterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowFilterProgress);

    // Add the commands as observers
    m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(), m_StartFilterCommand);
    m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(), m_EndFilterCommand);
    m_ProgressFilterTag
      = m_SourceProcess->AddObserver(itk::ProgressEvent(), m_ProgressFilterCommand);
    }
}

void
WriterWatcherBase
::operator =(const WriterWatcherBase& watch)
{
// Remove any observers we have on the old process object
  if (m_Process)
    {
    if (m_StartWriterCommand)
      {
      m_Process->RemoveObserver(m_StartWriterTag);
      }
    if (m_EndWriterCommand)
      {
      m_Process->RemoveObserver(m_EndWriterTag);
      }
    if (m_ProgressWriterCommand)
      {
      m_Process->RemoveObserver(m_ProgressWriterTag);
      }
    }
  if (m_SourceProcess)
    {
    if (m_StartFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_StartFilterTag);
      }
    if (m_EndFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_EndFilterTag);
      }
    if (m_ProgressFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_ProgressFilterTag);
      }
    }

  // Initialize state
  m_TimeProbe = watch.m_TimeProbe;
  m_Process = watch.m_Process;
  m_SourceProcess = watch.m_SourceProcess;
  m_Comment = watch.m_Comment;

  m_StartFilterTag = 0;
  m_EndFilterTag = 0;
  m_ProgressFilterTag = 0;
  m_StartWriterTag = 0;
  m_EndWriterTag = 0;
  m_ProgressWriterTag = 0;

  // Create a series of commands
  if (m_Process)
    {
    m_StartWriterCommand = CommandType::New();
    m_EndWriterCommand = CommandType::New();
    m_ProgressWriterCommand = CommandType::New();

    // Assign the callbacks
    m_StartWriterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartWriter);
    m_EndWriterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndWriter);
    m_ProgressWriterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowWriterProgress);

    // Add the commands as observers
    m_StartWriterTag = m_Process->AddObserver(itk::StartEvent(), m_StartWriterCommand);
    m_EndWriterTag = m_Process->AddObserver(itk::EndEvent(), m_EndWriterCommand);
    m_ProgressWriterTag
      = m_Process->AddObserver(itk::ProgressEvent(), m_ProgressWriterCommand);
    }
  if (m_SourceProcess)
    {
    m_StartFilterCommand = CommandType::New();
    m_EndFilterCommand = CommandType::New();
    m_ProgressFilterCommand = CommandType::New();

    // Assign the callbacks
    m_StartFilterCommand->SetCallbackFunction(this,
                                              &WriterWatcherBase::StartFilter);
    m_EndFilterCommand->SetCallbackFunction(this,
                                            &WriterWatcherBase::EndFilter);
    m_ProgressFilterCommand->SetCallbackFunction(this,
                                                 &WriterWatcherBase::ShowFilterProgress);

    // Add the commands as observers
    m_StartFilterTag = m_SourceProcess->AddObserver(itk::StartEvent(), m_StartFilterCommand);
    m_EndFilterTag = m_SourceProcess->AddObserver(itk::EndEvent(), m_EndFilterCommand);
    m_ProgressFilterTag
      = m_SourceProcess->AddObserver(itk::ProgressEvent(), m_ProgressFilterCommand);
    }
}

WriterWatcherBase
::~WriterWatcherBase()
{
  // Remove any observers we have on the old process object
  if (m_Process)
    {
    if (m_StartWriterCommand)
      {
      m_Process->RemoveObserver(m_StartWriterTag);
      }
    if (m_EndWriterCommand)
      {
      m_Process->RemoveObserver(m_EndWriterTag);
      }
    if (m_ProgressWriterCommand)
      {
      m_Process->RemoveObserver(m_ProgressWriterTag);
      }
    }
  if (m_SourceProcess)
    {
    if (m_StartFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_StartFilterTag);
      }
    if (m_EndFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_EndFilterTag);
      }
    if (m_ProgressFilterCommand)
      {
      m_SourceProcess->RemoveObserver(m_ProgressFilterTag);
      }
    }
}

} // end namespace otb
<|endoftext|>


<commit_before>/*
 *  Copyright 2019-2020 Diligent Graphics LLC
 *  Copyright 2015-2019 Egor Yusov
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  In no event and under no legal theory, whether in tort (including negligence),
 *  contract, or otherwise, unless required by applicable law (such as deliberate
 *  and grossly negligent acts) or agreed to in writing, shall any Contributor be
 *  liable for any damages, including any direct, indirect, special, incidental,
 *  or consequential damages of any character arising as a result of this License or
 *  out of the use or inability to use the software (including but not limited to damages
 *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and
 *  all other commercial damages or losses), even if such Contributor has been advised
 *  of the possibility of such damages.
 */

#pragma once

/// \file
/// Defines Diligent::LinearAllocator class

#include <vector>

#include "../../Primitives/interface/BasicTypes.h"
#include "../../Primitives/interface/MemoryAllocator.h"
#include "../../Platforms/Basic/interface/DebugUtilities.hpp"
#include "Align.hpp"

namespace Diligent
{

/// Implementation of a linear allocator on a fixed-size memory page
class LinearAllocator
{
public:
    // clang-format off
    LinearAllocator           (const LinearAllocator&) = delete;
    LinearAllocator& operator=(const LinearAllocator&) = delete;
    LinearAllocator& operator=(LinearAllocator&&)      = delete;
    // clang-format on

    LinearAllocator(IMemoryAllocator& Allocator) :
        m_pAllocator{&Allocator}
    {}

    LinearAllocator(LinearAllocator&& Other) :
        // clang-format off
        m_pDataStart {Other.m_pDataStart},
        m_pCurrPtr   {Other.m_pCurrPtr  },
        m_pDataEnd   {Other.m_pDataEnd  },
        m_pAllocator {Other.m_pAllocator}
    // clang-format on
    {
        Other.m_pDataStart = nullptr;
        Other.m_pCurrPtr   = nullptr;
        Other.m_pDataEnd   = nullptr;
        Other.m_pAllocator = nullptr;
    }

    ~LinearAllocator()
    {
        Free();
    }

    void Free()
    {
        if (m_pDataStart != nullptr && m_pDataStart != GetDummyMemory() && m_pAllocator != nullptr)
        {
            m_pAllocator->Free(m_pDataStart);
        }

        m_pDataStart = nullptr;
        m_pCurrPtr   = nullptr;
        m_pDataEnd   = nullptr;
        m_pAllocator = nullptr;
    }

    void* Release()
    {
        void* Ptr    = m_pDataStart;
        m_pDataStart = nullptr;
        m_pCurrPtr   = nullptr;
        m_pDataEnd   = nullptr;
        m_pAllocator = nullptr;
        return Ptr;
    }

    void AddSpace(size_t size, size_t align)
    {
        VERIFY(m_pDataStart == nullptr || m_pDataStart == GetDummyMemory(), "Memory has already been allocated");
        AllocateInternal(size, align);
    }

    template <typename T>
    void AddSpace(size_t count = 1)
    {
        AddSpace(sizeof(T) * count, alignof(T));
    }

    void AddSpaceForString(const Char* str)
    {
        VERIFY_EXPR(str != nullptr);
        AddSpace(strlen(str) + 1, 1);
    }

    void AddSpaceForString(const String& str)
    {
        AddSpaceForString(str.c_str());
    }

    void Reserve(size_t size)
    {
        VERIFY(m_pDataStart == nullptr || m_pDataStart == GetDummyMemory(), "Memory has already been allocated");
        VERIFY(m_pCurrPtr == nullptr, "Space has been added to the allocator and will be overriden");
        m_pCurrPtr = m_pDataStart + size;
        Reserve();
    }

    void Reserve()
    {
        VERIFY(m_pDataStart == nullptr || m_pDataStart == GetDummyMemory(), "Memory has already been allocated");
        VERIFY(m_pAllocator != nullptr, "Allocator must not be null");
        // Make sure the data size is at least sizeof(void*)-aligned
        auto DataSize = Align(static_cast<size_t>(m_pCurrPtr - m_pDataStart), sizeof(void*));
        if (DataSize > 0)
        {
            m_pDataStart = reinterpret_cast<uint8_t*>(m_pAllocator->Allocate(DataSize, "Raw memory for linear allocator", __FILE__, __LINE__));
            VERIFY(m_pDataStart == Align(m_pDataStart, sizeof(void*)), "Memory pointer must be at least sizeof(void*)-aligned");

            m_pCurrPtr = m_pDataStart;
            m_pDataEnd = m_pDataStart + DataSize;
        }
    }

    void* Allocate(size_t size, size_t align)
    {
        if (size == 0)
            return nullptr;

        VERIFY(m_pDataStart != nullptr && m_pDataStart != GetDummyMemory(), "Memory has not been allocated");
        return AllocateInternal(size, align);
    }

    template <typename T>
    T* Allocate(size_t count = 1)
    {
        return reinterpret_cast<T*>(Allocate(sizeof(T) * count, alignof(T)));
    }

    template <typename T, typename... Args>
    T* Construct(Args&&... args)
    {
        T* Ptr = Allocate<T>();
        new (Ptr) T{std::forward<Args>(args)...};
        return Ptr;
    }

    template <typename T, typename... Args>
    T* ConstructArray(size_t count, const Args&... args)
    {
        T* Ptr = Allocate<T>(count);
        for (size_t i = 0; i < count; ++i)
        {
            new (Ptr + i) T{args...};
        }
        return Ptr;
    }

    template <typename T>
    T* Copy(const T& Src)
    {
        return Construct<T>(Src);
    }

    template <typename T>
    T* CopyArray(const T* Src, size_t count)
    {
        T* Dst = Allocate<T>(count);
        for (size_t i = 0; i < count; ++i)
        {
            new (Dst + i) T{Src[i]};
        }
        return Dst;
    }

    Char* CopyString(const char* Str)
    {
        if (Str == nullptr)
            return nullptr;

        auto* Ptr = reinterpret_cast<Char*>(AllocateInternal(strlen(Str) + 1, 1));
        Char* Dst = Ptr;
        while (*Str != 0 && Dst < reinterpret_cast<Char*>(m_pDataEnd))
        {
            *(Dst++) = *(Str++);
        }
        if (Dst < reinterpret_cast<Char*>(m_pDataEnd))
            *(Dst++) = 0;
        else
            UNEXPECTED("Not enough space reserved for the string");
        VERIFY_EXPR(reinterpret_cast<Char*>(m_pCurrPtr) == Dst);
        return Ptr;
    }

    Char* CopyString(const std::string& Str)
    {
        return CopyString(Str.c_str());
    }

    size_t GetCurrentSize() const
    {
        return static_cast<size_t>(m_pCurrPtr - m_pDataStart);
    }

    size_t GetReservedSize() const
    {
        return static_cast<size_t>(m_pDataEnd - m_pDataStart);
    }

private:
    void* AllocateInternal(size_t size, size_t align)
    {
        VERIFY(IsPowerOfTwo(align), "Alignment is not a power of two!");
        if (size == 0)
            return m_pCurrPtr;

        if (m_pCurrPtr == nullptr)
        {
            VERIFY_EXPR(m_pDataStart == nullptr);
            m_pDataStart = m_pCurrPtr = GetDummyMemory();
        }

        m_pCurrPtr = Align(m_pCurrPtr, align);
        auto* ptr  = m_pCurrPtr;

#if DILIGENT_DEBUG
        if (m_pDataStart == GetDummyMemory())
        {
            m_DbgAllocations.emplace_back(size, align, m_pCurrPtr - m_pDataStart);
        }
        else
        {
            VERIFY(m_DbgCurrAllocation < m_DbgAllocations.size(), "Allocation number exceed the number of allocations that were originally reserved.");
            const auto& CurrAllocation = m_DbgAllocations[m_DbgCurrAllocation++];
            VERIFY(CurrAllocation.size == size, "Allocation size (", size, ") does not match the initially requested size (", CurrAllocation.size, ")");
            VERIFY(CurrAllocation.alignment == align, "Allocation alignment (", align, ") does not match initially requested alignment (", CurrAllocation.alignment, ")");

            auto CurrOffset = m_pCurrPtr - m_pDataStart;
            VERIFY(CurrOffset <= CurrAllocation.offset,
                   "Allocation offset exceed the offset that was initially computed. "
                   "This should never happen as long as the allocated memory is sizeof(void*)-aligned.");
        }
#endif

        m_pCurrPtr += size;

        VERIFY(m_pDataEnd == nullptr || m_pCurrPtr <= m_pDataEnd, "Allocation size exceeds the reserved space");

        return ptr;
    }

    static uint8_t* GetDummyMemory()
    {
        // Simulate that allocated memory is only sizeof(void*)-aligned
        auto* DummyMemory = reinterpret_cast<uint8_t*>(sizeof(void*));
        VERIFY_EXPR(DummyMemory != nullptr);
        return DummyMemory;
    }

    uint8_t*          m_pDataStart = nullptr;
    uint8_t*          m_pCurrPtr   = nullptr;
    uint8_t*          m_pDataEnd   = nullptr;
    IMemoryAllocator* m_pAllocator = nullptr;

#if DILIGENT_DEBUG
    size_t m_DbgCurrAllocation = 0;
    struct DbgAllocationInfo
    {
        const size_t    size;
        const size_t    alignment;
        const ptrdiff_t offset;

        DbgAllocationInfo(size_t _size, size_t _alignment, ptrdiff_t _offset) :
            size{_size},
            alignment{_alignment},
            offset{_offset}
        {
        }
    };
    std::vector<DbgAllocationInfo> m_DbgAllocations;
#endif
};

} // namespace Diligent
<commit_msg>Fixed Codacy issue<commit_after>/*
 *  Copyright 2019-2020 Diligent Graphics LLC
 *  Copyright 2015-2019 Egor Yusov
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  In no event and under no legal theory, whether in tort (including negligence),
 *  contract, or otherwise, unless required by applicable law (such as deliberate
 *  and grossly negligent acts) or agreed to in writing, shall any Contributor be
 *  liable for any damages, including any direct, indirect, special, incidental,
 *  or consequential damages of any character arising as a result of this License or
 *  out of the use or inability to use the software (including but not limited to damages
 *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and
 *  all other commercial damages or losses), even if such Contributor has been advised
 *  of the possibility of such damages.
 */

#pragma once

/// \file
/// Defines Diligent::LinearAllocator class

#include <vector>

#include "../../Primitives/interface/BasicTypes.h"
#include "../../Primitives/interface/MemoryAllocator.h"
#include "../../Platforms/Basic/interface/DebugUtilities.hpp"
#include "Align.hpp"

namespace Diligent
{

/// Implementation of a linear allocator on a fixed-size memory page
class LinearAllocator
{
public:
    // clang-format off
    LinearAllocator           (const LinearAllocator&) = delete;
    LinearAllocator& operator=(const LinearAllocator&) = delete;
    LinearAllocator& operator=(LinearAllocator&&)      = delete;
    // clang-format on

    explicit LinearAllocator(IMemoryAllocator& Allocator) :
        m_pAllocator{&Allocator}
    {}

    LinearAllocator(LinearAllocator&& Other) :
        // clang-format off
        m_pDataStart {Other.m_pDataStart},
        m_pCurrPtr   {Other.m_pCurrPtr  },
        m_pDataEnd   {Other.m_pDataEnd  },
        m_pAllocator {Other.m_pAllocator}
    // clang-format on
    {
        Other.m_pDataStart = nullptr;
        Other.m_pCurrPtr   = nullptr;
        Other.m_pDataEnd   = nullptr;
        Other.m_pAllocator = nullptr;
    }

    ~LinearAllocator()
    {
        Free();
    }

    void Free()
    {
        if (m_pDataStart != nullptr && m_pDataStart != GetDummyMemory() && m_pAllocator != nullptr)
        {
            m_pAllocator->Free(m_pDataStart);
        }

        m_pDataStart = nullptr;
        m_pCurrPtr   = nullptr;
        m_pDataEnd   = nullptr;
        m_pAllocator = nullptr;
    }

    void* Release()
    {
        void* Ptr    = m_pDataStart;
        m_pDataStart = nullptr;
        m_pCurrPtr   = nullptr;
        m_pDataEnd   = nullptr;
        m_pAllocator = nullptr;
        return Ptr;
    }

    void AddSpace(size_t size, size_t align)
    {
        VERIFY(m_pDataStart == nullptr || m_pDataStart == GetDummyMemory(), "Memory has already been allocated");
        AllocateInternal(size, align);
    }

    template <typename T>
    void AddSpace(size_t count = 1)
    {
        AddSpace(sizeof(T) * count, alignof(T));
    }

    void AddSpaceForString(const Char* str)
    {
        VERIFY_EXPR(str != nullptr);
        AddSpace(strlen(str) + 1, 1);
    }

    void AddSpaceForString(const String& str)
    {
        AddSpaceForString(str.c_str());
    }

    void Reserve(size_t size)
    {
        VERIFY(m_pDataStart == nullptr || m_pDataStart == GetDummyMemory(), "Memory has already been allocated");
        VERIFY(m_pCurrPtr == nullptr, "Space has been added to the allocator and will be overriden");
        m_pCurrPtr = m_pDataStart + size;
        Reserve();
    }

    void Reserve()
    {
        VERIFY(m_pDataStart == nullptr || m_pDataStart == GetDummyMemory(), "Memory has already been allocated");
        VERIFY(m_pAllocator != nullptr, "Allocator must not be null");
        // Make sure the data size is at least sizeof(void*)-aligned
        auto DataSize = Align(static_cast<size_t>(m_pCurrPtr - m_pDataStart), sizeof(void*));
        if (DataSize > 0)
        {
            m_pDataStart = reinterpret_cast<uint8_t*>(m_pAllocator->Allocate(DataSize, "Raw memory for linear allocator", __FILE__, __LINE__));
            VERIFY(m_pDataStart == Align(m_pDataStart, sizeof(void*)), "Memory pointer must be at least sizeof(void*)-aligned");

            m_pCurrPtr = m_pDataStart;
            m_pDataEnd = m_pDataStart + DataSize;
        }
    }

    void* Allocate(size_t size, size_t align)
    {
        if (size == 0)
            return nullptr;

        VERIFY(m_pDataStart != nullptr && m_pDataStart != GetDummyMemory(), "Memory has not been allocated");
        return AllocateInternal(size, align);
    }

    template <typename T>
    T* Allocate(size_t count = 1)
    {
        return reinterpret_cast<T*>(Allocate(sizeof(T) * count, alignof(T)));
    }

    template <typename T, typename... Args>
    T* Construct(Args&&... args)
    {
        T* Ptr = Allocate<T>();
        new (Ptr) T{std::forward<Args>(args)...};
        return Ptr;
    }

    template <typename T, typename... Args>
    T* ConstructArray(size_t count, const Args&... args)
    {
        T* Ptr = Allocate<T>(count);
        for (size_t i = 0; i < count; ++i)
        {
            new (Ptr + i) T{args...};
        }
        return Ptr;
    }

    template <typename T>
    T* Copy(const T& Src)
    {
        return Construct<T>(Src);
    }

    template <typename T>
    T* CopyArray(const T* Src, size_t count)
    {
        T* Dst = Allocate<T>(count);
        for (size_t i = 0; i < count; ++i)
        {
            new (Dst + i) T{Src[i]};
        }
        return Dst;
    }

    Char* CopyString(const char* Str)
    {
        if (Str == nullptr)
            return nullptr;

        auto* Ptr = reinterpret_cast<Char*>(AllocateInternal(strlen(Str) + 1, 1));
        Char* Dst = Ptr;
        while (*Str != 0 && Dst < reinterpret_cast<Char*>(m_pDataEnd))
        {
            *(Dst++) = *(Str++);
        }
        if (Dst < reinterpret_cast<Char*>(m_pDataEnd))
            *(Dst++) = 0;
        else
            UNEXPECTED("Not enough space reserved for the string");
        VERIFY_EXPR(reinterpret_cast<Char*>(m_pCurrPtr) == Dst);
        return Ptr;
    }

    Char* CopyString(const std::string& Str)
    {
        return CopyString(Str.c_str());
    }

    size_t GetCurrentSize() const
    {
        return static_cast<size_t>(m_pCurrPtr - m_pDataStart);
    }

    size_t GetReservedSize() const
    {
        return static_cast<size_t>(m_pDataEnd - m_pDataStart);
    }

private:
    void* AllocateInternal(size_t size, size_t align)
    {
        VERIFY(IsPowerOfTwo(align), "Alignment is not a power of two!");
        if (size == 0)
            return m_pCurrPtr;

        if (m_pCurrPtr == nullptr)
        {
            VERIFY_EXPR(m_pDataStart == nullptr);
            m_pDataStart = m_pCurrPtr = GetDummyMemory();
        }

        m_pCurrPtr = Align(m_pCurrPtr, align);
        auto* ptr  = m_pCurrPtr;

#if DILIGENT_DEBUG
        if (m_pDataStart == GetDummyMemory())
        {
            m_DbgAllocations.emplace_back(size, align, m_pCurrPtr - m_pDataStart);
        }
        else
        {
            VERIFY(m_DbgCurrAllocation < m_DbgAllocations.size(), "Allocation number exceed the number of allocations that were originally reserved.");
            const auto& CurrAllocation = m_DbgAllocations[m_DbgCurrAllocation++];
            VERIFY(CurrAllocation.size == size, "Allocation size (", size, ") does not match the initially requested size (", CurrAllocation.size, ")");
            VERIFY(CurrAllocation.alignment == align, "Allocation alignment (", align, ") does not match initially requested alignment (", CurrAllocation.alignment, ")");

            auto CurrOffset = m_pCurrPtr - m_pDataStart;
            VERIFY(CurrOffset <= CurrAllocation.offset,
                   "Allocation offset exceed the offset that was initially computed. "
                   "This should never happen as long as the allocated memory is sizeof(void*)-aligned.");
        }
#endif

        m_pCurrPtr += size;

        VERIFY(m_pDataEnd == nullptr || m_pCurrPtr <= m_pDataEnd, "Allocation size exceeds the reserved space");

        return ptr;
    }

    static uint8_t* GetDummyMemory()
    {
        // Simulate that allocated memory is only sizeof(void*)-aligned
        auto* DummyMemory = reinterpret_cast<uint8_t*>(sizeof(void*));
        VERIFY_EXPR(DummyMemory != nullptr);
        return DummyMemory;
    }

    uint8_t*          m_pDataStart = nullptr;
    uint8_t*          m_pCurrPtr   = nullptr;
    uint8_t*          m_pDataEnd   = nullptr;
    IMemoryAllocator* m_pAllocator = nullptr;

#if DILIGENT_DEBUG
    size_t m_DbgCurrAllocation = 0;
    struct DbgAllocationInfo
    {
        const size_t    size;
        const size_t    alignment;
        const ptrdiff_t offset;

        DbgAllocationInfo(size_t _size, size_t _alignment, ptrdiff_t _offset) :
            size{_size},
            alignment{_alignment},
            offset{_offset}
        {
        }
    };
    std::vector<DbgAllocationInfo> m_DbgAllocations;
#endif
};

} // namespace Diligent
<|endoftext|>


<commit_before>/**
 * @file offboard_velocity.cpp
 * @brief Example that demonstrates offboard velocity control in local NED and body coordinates
 *
 * @authors Author: Julian Oes <julian@oes.ch>,
 *                  Shakthi Prashanth <shakthi.prashanth.m@intel.com>
 * @date 2017-10-17
 */

#include <iostream>
#include <cmath>
#include <thread>
#include <chrono>
#include <dronecore/dronecore.h>

using namespace dronecore;
using std::this_thread::sleep_for;
using std::chrono::milliseconds;
using std::chrono::seconds;

#define ERROR_CONSOLE_TEXT "\033[31m" //Turn text on console red
#define TELEMETRY_CONSOLE_TEXT "\033[34m" //Turn text on console blue
#define NORMAL_CONSOLE_TEXT "\033[0m"  //Restore normal console colour

// Handles Action's result
inline void action_error_exit(Action::Result result, const std::string &message)
{
    if (result != Action::Result::SUCCESS) {
        std::cerr << ERROR_CONSOLE_TEXT << message << Action::result_str(
                      result) << NORMAL_CONSOLE_TEXT << std::endl;
        exit(EXIT_FAILURE);
    }
}

// Handles Offboard's result
inline void offboard_error_exit(Offboard::Result result, const std::string &message)
{
    if (result != Offboard::Result::SUCCESS) {
        std::cerr << ERROR_CONSOLE_TEXT << message << Offboard::result_str(
                      result) << NORMAL_CONSOLE_TEXT << std::endl;
        exit(EXIT_FAILURE);
    }
}

// Handles connection result
inline void connection_error_exit(DroneCore::ConnectionResult result, const std::string &message)
{
    if (result != DroneCore::ConnectionResult::SUCCESS) {
        std::cerr << ERROR_CONSOLE_TEXT << message
                  << DroneCore::connection_result_str(result)
                  << NORMAL_CONSOLE_TEXT << std::endl;
        exit(EXIT_FAILURE);
    }
}

// Logs during Offboard control
inline void offboard_log(const std::string &offb_mode, const std::string msg)
{
    std::cout << "[" << offb_mode << "] " << msg << std::endl;
}

/**
 * Does Offboard control using NED co-ordinates.
 *
 * returns true if everything went well in Offboard control, exits with a log otherwise.
 */
bool offb_ctrl_ned(Device &device)
{
    const std::string offb_mode = "NED";
    // Send it once before starting offboard, otherwise it will be rejected.
    device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 0.0f});

    Offboard::Result offboard_result = device.offboard().start();
    offboard_error_exit(offboard_result, "Offboard start failed");
    offboard_log(offb_mode, "Offboard started");

    offboard_log(offb_mode,  "Turn to face East");
    device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 90.0f});
    sleep_for(seconds(1)); // Let yaw settle.

    {
        const float step_size = 0.01f;
        const float one_cycle = 2.0f * (float)M_PI;
        const unsigned steps = 2 * unsigned(one_cycle / step_size);

        offboard_log(offb_mode,  "Go North and back South");
        for (unsigned i = 0; i < steps; ++i) {
            float vx = 5.0f * sinf(i * step_size);
            device.offboard().set_velocity_ned({vx, 0.0f, 0.0f, 90.0f});
            sleep_for(milliseconds(10));
        }
    }

    offboard_log(offb_mode,  "Turn to face West");
    device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 270.0f});
    sleep_for(seconds(2));

    offboard_log(offb_mode, "Go up 2 m/s, turn to face South");
    device.offboard().set_velocity_ned({0.0f, 0.0f, -2.0f, 180.0f});
    sleep_for(seconds(4));

    offboard_log(offb_mode,  "Go down 1 m/s, turn to face North");
    device.offboard().set_velocity_ned({0.0f, 0.0f, 1.0f, 0.0f});
    sleep_for(seconds(4));

    // Now, stop offboard mode.
    offboard_result = device.offboard().stop();
    offboard_error_exit(offboard_result, "Offboard stop failed: ");
    offboard_log(offb_mode, "Offboard stopped");

    return true;
}

/**
 * Does Offboard control using body co-ordinates.
 *
 * returns true if everything went well in Offboard control, exits with a log otherwise.
 */
bool offb_ctrl_body(Device &device)
{
    const std::string offb_mode = "BODY";

    // Send it once before starting offboard, otherwise it will be rejected.
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});

    Offboard::Result offboard_result = device.offboard().start();
    offboard_error_exit(offboard_result, "Offboard start failed: ");
    offboard_log(offb_mode, "Offboard started");

    offboard_log(offb_mode, "Turn clock-wise and climb");
    device.offboard().set_velocity_body({0.0f, 0.0f, -1.0f, 60.0f});
    sleep_for(seconds(5));

    offboard_log(offb_mode, "Turn back anti-clockwise");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, -60.0f});
    sleep_for(seconds(5));

    offboard_log(offb_mode, "Wait for a bit");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});
    sleep_for(seconds(2));

    offboard_log(offb_mode, "Fly a circle");
    device.offboard().set_velocity_body({5.0f, 0.0f, 0.0f, 30.0f});
    sleep_for(seconds(15));

    offboard_log(offb_mode, "Wait for a bit");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});
    sleep_for(seconds(5));

    offboard_log(offb_mode, "Fly a circle sideways");
    device.offboard().set_velocity_body({0.0f, -5.0f, 0.0f, 30.0f});
    sleep_for(seconds(15));

    offboard_log(offb_mode, "Wait for a bit");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});
    sleep_for(seconds(8));

    offboard_result = device.offboard().stop();
    offboard_error_exit(offboard_result, "Offboard stop failed: ");
    offboard_log(offb_mode, "Offboard stopped");

    return true;
}

int main(int, char **)
{
    DroneCore dc;

    DroneCore::ConnectionResult conn_result = dc.add_udp_connection();
    connection_error_exit(conn_result, "Connection failed");

    // Wait for the device to connect via heartbeat
    while (!dc.is_connected()) {
        std::cout << "Wait for device to connect via heartbeat" << std::endl;
        sleep_for(seconds(1));
    }

    // Device got discovered.
    Device &device = dc.device();

    while (!device.telemetry().health_all_ok()) {
        std::cout << "Waiting for device to be ready" << std::endl;
        sleep_for(seconds(1));
    }
    std::cout << "Device is ready" << std::endl;

    Action::Result arm_result = device.action().arm();
    action_error_exit(arm_result, "Arming failed");
    std::cout << "Armed" << std::endl;

    Action::Result takeoff_result = device.action().takeoff();
    action_error_exit(takeoff_result, "Takeoff failed");
    std::cout << "In Air..." << std::endl;
    sleep_for(seconds(5));

    //  using local NED co-ordinates
    bool ret = offb_ctrl_ned(device);
    if (ret == false) {
        return EXIT_FAILURE;
    }

    //  using body co-ordinates
    ret = offb_ctrl_body(device);
    if (ret == false) {
        return EXIT_FAILURE;
    }

    const Action::Result land_result = device.action().land();
    action_error_exit(land_result, "Landing failed");

    // We are relying on auto-disarming but let's keep watching the telemetry for a bit longer.
    sleep_for(seconds(10));
    std::cout << "Landed" << std::endl;

    return EXIT_SUCCESS;
}
<commit_msg>example: fix Pi on Windows<commit_after>/**
 * @file offboard_velocity.cpp
 * @brief Example that demonstrates offboard velocity control in local NED and body coordinates
 *
 * @authors Author: Julian Oes <julian@oes.ch>,
 *                  Shakthi Prashanth <shakthi.prashanth.m@intel.com>
 * @date 2017-10-17
 */

#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>
#include <thread>
#include <chrono>
#include <dronecore/dronecore.h>

using namespace dronecore;
using std::this_thread::sleep_for;
using std::chrono::milliseconds;
using std::chrono::seconds;

#define ERROR_CONSOLE_TEXT "\033[31m" //Turn text on console red
#define TELEMETRY_CONSOLE_TEXT "\033[34m" //Turn text on console blue
#define NORMAL_CONSOLE_TEXT "\033[0m"  //Restore normal console colour

// Handles Action's result
inline void action_error_exit(Action::Result result, const std::string &message)
{
    if (result != Action::Result::SUCCESS) {
        std::cerr << ERROR_CONSOLE_TEXT << message << Action::result_str(
                      result) << NORMAL_CONSOLE_TEXT << std::endl;
        exit(EXIT_FAILURE);
    }
}

// Handles Offboard's result
inline void offboard_error_exit(Offboard::Result result, const std::string &message)
{
    if (result != Offboard::Result::SUCCESS) {
        std::cerr << ERROR_CONSOLE_TEXT << message << Offboard::result_str(
                      result) << NORMAL_CONSOLE_TEXT << std::endl;
        exit(EXIT_FAILURE);
    }
}

// Handles connection result
inline void connection_error_exit(DroneCore::ConnectionResult result, const std::string &message)
{
    if (result != DroneCore::ConnectionResult::SUCCESS) {
        std::cerr << ERROR_CONSOLE_TEXT << message
                  << DroneCore::connection_result_str(result)
                  << NORMAL_CONSOLE_TEXT << std::endl;
        exit(EXIT_FAILURE);
    }
}

// Logs during Offboard control
inline void offboard_log(const std::string &offb_mode, const std::string msg)
{
    std::cout << "[" << offb_mode << "] " << msg << std::endl;
}

/**
 * Does Offboard control using NED co-ordinates.
 *
 * returns true if everything went well in Offboard control, exits with a log otherwise.
 */
bool offb_ctrl_ned(Device &device)
{
    const std::string offb_mode = "NED";
    // Send it once before starting offboard, otherwise it will be rejected.
    device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 0.0f});

    Offboard::Result offboard_result = device.offboard().start();
    offboard_error_exit(offboard_result, "Offboard start failed");
    offboard_log(offb_mode, "Offboard started");

    offboard_log(offb_mode,  "Turn to face East");
    device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 90.0f});
    sleep_for(seconds(1)); // Let yaw settle.

    {
        const float step_size = 0.01f;
        const float one_cycle = 2.0f * (float)M_PI;
        const unsigned steps = 2 * unsigned(one_cycle / step_size);

        offboard_log(offb_mode,  "Go North and back South");
        for (unsigned i = 0; i < steps; ++i) {
            float vx = 5.0f * sinf(i * step_size);
            device.offboard().set_velocity_ned({vx, 0.0f, 0.0f, 90.0f});
            sleep_for(milliseconds(10));
        }
    }

    offboard_log(offb_mode,  "Turn to face West");
    device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 270.0f});
    sleep_for(seconds(2));

    offboard_log(offb_mode, "Go up 2 m/s, turn to face South");
    device.offboard().set_velocity_ned({0.0f, 0.0f, -2.0f, 180.0f});
    sleep_for(seconds(4));

    offboard_log(offb_mode,  "Go down 1 m/s, turn to face North");
    device.offboard().set_velocity_ned({0.0f, 0.0f, 1.0f, 0.0f});
    sleep_for(seconds(4));

    // Now, stop offboard mode.
    offboard_result = device.offboard().stop();
    offboard_error_exit(offboard_result, "Offboard stop failed: ");
    offboard_log(offb_mode, "Offboard stopped");

    return true;
}

/**
 * Does Offboard control using body co-ordinates.
 *
 * returns true if everything went well in Offboard control, exits with a log otherwise.
 */
bool offb_ctrl_body(Device &device)
{
    const std::string offb_mode = "BODY";

    // Send it once before starting offboard, otherwise it will be rejected.
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});

    Offboard::Result offboard_result = device.offboard().start();
    offboard_error_exit(offboard_result, "Offboard start failed: ");
    offboard_log(offb_mode, "Offboard started");

    offboard_log(offb_mode, "Turn clock-wise and climb");
    device.offboard().set_velocity_body({0.0f, 0.0f, -1.0f, 60.0f});
    sleep_for(seconds(5));

    offboard_log(offb_mode, "Turn back anti-clockwise");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, -60.0f});
    sleep_for(seconds(5));

    offboard_log(offb_mode, "Wait for a bit");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});
    sleep_for(seconds(2));

    offboard_log(offb_mode, "Fly a circle");
    device.offboard().set_velocity_body({5.0f, 0.0f, 0.0f, 30.0f});
    sleep_for(seconds(15));

    offboard_log(offb_mode, "Wait for a bit");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});
    sleep_for(seconds(5));

    offboard_log(offb_mode, "Fly a circle sideways");
    device.offboard().set_velocity_body({0.0f, -5.0f, 0.0f, 30.0f});
    sleep_for(seconds(15));

    offboard_log(offb_mode, "Wait for a bit");
    device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f});
    sleep_for(seconds(8));

    offboard_result = device.offboard().stop();
    offboard_error_exit(offboard_result, "Offboard stop failed: ");
    offboard_log(offb_mode, "Offboard stopped");

    return true;
}

int main(int, char **)
{
    DroneCore dc;

    DroneCore::ConnectionResult conn_result = dc.add_udp_connection();
    connection_error_exit(conn_result, "Connection failed");

    // Wait for the device to connect via heartbeat
    while (!dc.is_connected()) {
        std::cout << "Wait for device to connect via heartbeat" << std::endl;
        sleep_for(seconds(1));
    }

    // Device got discovered.
    Device &device = dc.device();

    while (!device.telemetry().health_all_ok()) {
        std::cout << "Waiting for device to be ready" << std::endl;
        sleep_for(seconds(1));
    }
    std::cout << "Device is ready" << std::endl;

    Action::Result arm_result = device.action().arm();
    action_error_exit(arm_result, "Arming failed");
    std::cout << "Armed" << std::endl;

    Action::Result takeoff_result = device.action().takeoff();
    action_error_exit(takeoff_result, "Takeoff failed");
    std::cout << "In Air..." << std::endl;
    sleep_for(seconds(5));

    //  using local NED co-ordinates
    bool ret = offb_ctrl_ned(device);
    if (ret == false) {
        return EXIT_FAILURE;
    }

    //  using body co-ordinates
    ret = offb_ctrl_body(device);
    if (ret == false) {
        return EXIT_FAILURE;
    }

    const Action::Result land_result = device.action().land();
    action_error_exit(land_result, "Landing failed");

    // We are relying on auto-disarming but let's keep watching the telemetry for a bit longer.
    sleep_for(seconds(10));
    std::cout << "Landed" << std::endl;

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fwkutil.cxx,v $
 *
 *  $Revision: 1.25 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 17:48:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_jvmfwk.hxx"

#if defined WNT
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#endif

#include <string>
#include "osl/mutex.hxx"
#include "osl/module.hxx"
#include "osl/thread.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"
#include "rtl/bootstrap.hxx"
#include "osl/file.hxx"
#include "osl/process.h"
#include "rtl/instance.hxx"
#include "rtl/uri.hxx"
#include "osl/getglobalmutex.hxx"

#include "framework.hxx"
#include "fwkutil.hxx"

using namespace rtl;
using namespace osl;

namespace jfw
{

struct Init
{
    osl::Mutex * operator()()
        {
            static osl::Mutex aInstance;
            return &aInstance;
        }
};
osl::Mutex * getFwkMutex()
{
    return rtl_Instance< osl::Mutex, Init, ::osl::MutexGuard,
        ::osl::GetGlobalMutex >::create(
            Init(), ::osl::GetGlobalMutex());
}

bool isAccessibilitySupportDesired()
{
    bool retVal = false;
#ifdef WNT
    HKEY    hKey = 0;
    if (RegOpenKeyEx(HKEY_CURRENT_USER,
                     "Software\\OpenOffice.org\\Accessibility\\AtToolSupport",
                     0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD   dwType = 0;
        DWORD   dwLen = 16;
        unsigned char arData[16];
        if( RegQueryValueEx(hKey, "SupportAssistiveTechnology", NULL, &dwType, arData,
                            & dwLen)== ERROR_SUCCESS)
        {
            if (dwType == REG_SZ)
            {
                if (strcmp((char*) arData, "true") == 0
                    || strcmp((char*) arData, "1") == 0)
                    retVal = true;
                else if (strcmp((char*) arData, "false") == 0
                         || strcmp((char*) arData, "0") == 0)
                    retVal = false;
#if OSL_DEBUG_LEVEL > 1
                else
                    OSL_ASSERT(0);
#endif
            }
            else if (dwType == REG_DWORD)
            {
                if (arData[0] == 1)
                    retVal = true;
                else if (arData[0] == 0)
                    retVal = false;
#if OSL_DEBUG_LEVEL > 1
                else
                    OSL_ASSERT(0);
#endif
            }
        }
    }
    RegCloseKey(hKey);

#elif UNX
    char buf[16];
    // use 2 shells to suppress the eventual "gcontool-2 not found" message
    // of the shell trying to execute the command
    FILE* fp = popen( "/bin/sh 2>/dev/null -c \"gconftool-2 -g /desktop/gnome/interface/accessibility\"", "r" );
    if( fp )
    {
        if( fgets( buf, sizeof(buf), fp ) )
        {
            int nCompare = strncasecmp( buf, "true", 4 );
            retVal = (nCompare == 0 ? true : false);
        }
        pclose( fp );
    }
#endif
    return retVal;
}

rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData)
{
    static char EncodingTable[] =
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    sal_Int32 lenRaw = rawData.getLength();
    char* pBuf = new char[lenRaw * 2];
    const sal_Int8* arRaw = rawData.getConstArray();

    char* pCurBuf = pBuf;
    for (int i = 0; i < lenRaw; i++)
    {
        unsigned char curChar = arRaw[i];
        curChar >>= 4;

        *pCurBuf = EncodingTable[curChar];
        pCurBuf++;

        curChar = arRaw[i];
        curChar &= 0x0F;

        *pCurBuf = EncodingTable[curChar];
        pCurBuf++;
    }

    rtl::ByteSequence ret((sal_Int8*) pBuf, lenRaw * 2);
    delete [] pBuf;
    return ret;
}

rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data)
{
    static char decodingTable[] =
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    sal_Int32 lenData = data.getLength();
    sal_Int32 lenBuf = lenData / 2; //always divisable by two
    unsigned char* pBuf = new unsigned char[lenBuf];
    const sal_Int8* pData = data.getConstArray();
    for (sal_Int32 i = 0; i < lenBuf; i++)
    {
        sal_Int8 curChar = *pData++;
        //find the index of the first 4bits
        //  TODO  What happens if text is not valid Hex characters?
        unsigned char nibble = 0;
        for (unsigned char j = 0; j < 16; j++)
        {
            if (curChar == decodingTable[j])
            {
                nibble = j;
                break;
            }
        }
        nibble <<= 4;
        curChar = *pData++;
        //find the index for the next 4bits
        for (unsigned char j = 0; j < 16; j++)
        {
            if (curChar == decodingTable[j])
            {
                nibble |= j;
                break;
            }
        }
        pBuf[i] = nibble;
    }
    rtl::ByteSequence ret((sal_Int8*) pBuf, lenBuf );
    delete [] pBuf;
    return ret;
}

rtl::OUString getDirFromFile(const rtl::OUString& usFilePath)
{
    sal_Int32 index= usFilePath.lastIndexOf('/');
    return rtl::OUString(usFilePath.getStr(), index);
}

rtl::OUString getFileFromURL(const rtl::OUString& sFileURL)
{
    sal_Int32 index= sFileURL.lastIndexOf('/');
    if (index == -1)
        return sFileURL;
    return sFileURL.copy(index + 1);
}

rtl::OUString getExecutableDirectory()
{
    rtl_uString* sExe = NULL;
    if (osl_getExecutableFile( & sExe) != osl_Process_E_None)
        throw FrameworkException(
            JFW_E_ERROR,
            "[Java framework] Error in function getApplicationBase (fwkutil.cxx)");

    rtl::OUString ouExe(sExe, SAL_NO_ACQUIRE);
    return getDirFromFile(ouExe);
}

rtl::OUString findPlugin(
    const rtl::OUString & baseUrl, const rtl::OUString & plugin)
{
    rtl::OUString sUrl;
    try
    {
        sUrl = rtl::Uri::convertRelToAbs(baseUrl, plugin);
    }
    catch (rtl::MalformedUriException & e)
    {
        throw FrameworkException(
            JFW_E_ERROR,
            (rtl::OString(
                RTL_CONSTASCII_STRINGPARAM(
                    "[Java framework] rtl::MalformedUriException in"
                    " findPlugin: "))
             + rtl::OUStringToOString(
                 e.getMessage(), osl_getThreadTextEncoding())));
    }
    if (checkFileURL(sUrl) == jfw::FILE_OK)
    {
        return sUrl;
    }
    rtl::OUString retVal;
    rtl::OUString sProgDir = getExecutableDirectory();
    sUrl = sProgDir + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"))
        + plugin;
    jfw::FileStatus s = checkFileURL(sUrl);
    if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST)
    {
        //If only the name of the library is given, then
        //use PATH, LD_LIBRARY_PATH etc. to locate the plugin
        if (plugin.indexOf('/') == -1)
        {
            rtl::OUString url;
#ifdef UNX
#ifdef MACOSX
            rtl::OUString path = rtl::OUString::createFromAscii("DYLD_LIBRARY_PATH");
#else
            rtl::OUString path = rtl::OUString::createFromAscii("LD_LIBRARY_PATH");
#endif
            rtl::OUString env_path;
            oslProcessError err = osl_getEnvironment(path.pData, &env_path.pData);
            if (err != osl_Process_E_None && err != osl_Process_E_NotFound)
                throw FrameworkException(
                    JFW_E_ERROR,
                    "[Java framework] Error in function findPlugin (fwkutil.cxx).");
            if (err == osl_Process_E_NotFound)
                return retVal;
            if (osl_searchFileURL(plugin.pData, env_path.pData, &url.pData)
                                == osl_File_E_None)
#else
            if (osl_searchFileURL(plugin.pData, NULL, &url.pData)
                == osl_File_E_None)
#endif
                retVal = url;
            else
                throw FrameworkException(
                    JFW_E_ERROR,
                    "[Java framework] Error in function findPlugin (fwkutil.cxx).");
        }
    }
    else
    {
        retVal = sUrl;
    }
    return retVal;
}

rtl::OUString getLibraryLocation()
{
    rtl::OString sExcMsg("[Java framework] Error in function getLibraryLocation "
                         "(fwkutil.cxx).");
    rtl::OUString libraryFileUrl;

    if (!osl::Module::getUrlFromAddress(
            reinterpret_cast< oslGenericFunction >(getLibraryLocation),
            libraryFileUrl))
        throw FrameworkException(JFW_E_ERROR, sExcMsg);

    return getDirFromFile(libraryFileUrl);
}

//Todo is this still needed?
rtl::OUString searchFileNextToThisLib(const rtl::OUString & sFile)
{
    rtl::OUString ret;
    rtl::OUString sLib;
    if (osl::Module::getUrlFromAddress(
            reinterpret_cast< oslGenericFunction >(searchFileNextToThisLib),
            sLib))
    {
        sLib = getDirFromFile(sLib);
        rtl::OUStringBuffer sBufVendor(256);
        sBufVendor.append(sLib);
        sBufVendor.appendAscii("/");
        sBufVendor.append(sFile);
        sLib =  sBufVendor.makeStringAndClear();
        //check if the file exists
        osl::DirectoryItem item;
        osl::File::RC fileError = osl::DirectoryItem::get(sLib, item);
        if (fileError == osl::FileBase::E_None)
            ret = sLib;
    }
    return ret;
}

jfw::FileStatus checkFileURL(const rtl::OUString & path)
{
    rtl::OString sExcMsg("[Java framework] Error in function "
                         "resolveFileURL (fwkutil.cxx).");
    OUString sResolved = path;
    jfw::FileStatus ret = jfw::FILE_OK;
    while (1)
    {
        DirectoryItem item;
        File::RC fileErr =
            DirectoryItem::get(sResolved, item);
        if (fileErr == File::E_None)
        {
            osl::FileStatus status(FileStatusMask_Type |
                              FileStatusMask_LinkTargetURL |
                              FileStatusMask_FileURL);

            if (item.getFileStatus(status) == File::E_None)
            {
                osl::FileStatus::Type t = status.getFileType();
                if (t == osl::FileStatus::Regular)
                {
                    ret = jfw::FILE_OK;
                    break;
                }
                else if ( t == osl::FileStatus::Link )
                {
                    sResolved = status.getLinkTargetURL();
                }
                else
                {
                    ret = FILE_INVALID;
                    break;
                }
            }
            else
            {
                throw FrameworkException(JFW_E_ERROR, sExcMsg);
            }
        }
        else if(fileErr == File::E_NOENT)
        {
            ret = FILE_DOES_NOT_EXIST;
            break;
        }
        else
        {
            ret = FILE_INVALID;
            break;
        }
    }
    return ret;
}
const rtl::Bootstrap& getBootstrap()
{
    static rtl::Bootstrap *pBootstrap = 0;
    rtl::OUString sIni;
    if( !pBootstrap )
    {
        rtl::OUStringBuffer buf( 255);
        buf.append( getLibraryLocation());
        buf.appendAscii( SAL_CONFIGFILE("/jvmfwk3") );
        sIni = buf.makeStringAndClear();
        static rtl::Bootstrap  bootstrap(sIni);
        pBootstrap = &bootstrap;
#if OSL_DEBUG_LEVEL >=2
        rtl::OString o = rtl::OUStringToOString( sIni , osl_getThreadTextEncoding() );
        fprintf(stderr, "[Java framework] Using configuration file %s\n" , o.getStr() );
#endif
    }

    return *pBootstrap;

}

}
<commit_msg>INTEGRATION: CWS jl64 (1.25.24); FILE MERGED 2007/06/07 07:52:58 jl 1.25.24.2: #i76390# support of new bootstrap variable UNO_JAVA_JFW_INSTALL_DATA and UNO_JAVA_JFW_INSTALL_EXPIRE 2007/06/04 08:05:45 jl 1.25.24.1: #i76390 do not create user installation when installing java extensions during setup<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fwkutil.cxx,v $
 *
 *  $Revision: 1.26 $
 *
 *  last change: $Author: obo $ $Date: 2007-06-13 07:58:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_jvmfwk.hxx"

#if defined WNT
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#endif

#include <string>
#include "osl/mutex.hxx"
#include "osl/module.hxx"
#include "osl/thread.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"
#include "rtl/bootstrap.hxx"
#include "osl/file.hxx"
#include "osl/process.h"
#include "rtl/instance.hxx"
#include "rtl/uri.hxx"
#include "osl/getglobalmutex.hxx"

#include "framework.hxx"
#include "fwkutil.hxx"

using namespace rtl;
using namespace osl;

namespace jfw
{

bool isAccessibilitySupportDesired()
{
    bool retVal = false;
#ifdef WNT
    HKEY    hKey = 0;
    if (RegOpenKeyEx(HKEY_CURRENT_USER,
                     "Software\\OpenOffice.org\\Accessibility\\AtToolSupport",
                     0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD   dwType = 0;
        DWORD   dwLen = 16;
        unsigned char arData[16];
        if( RegQueryValueEx(hKey, "SupportAssistiveTechnology", NULL, &dwType, arData,
                            & dwLen)== ERROR_SUCCESS)
        {
            if (dwType == REG_SZ)
            {
                if (strcmp((char*) arData, "true") == 0
                    || strcmp((char*) arData, "1") == 0)
                    retVal = true;
                else if (strcmp((char*) arData, "false") == 0
                         || strcmp((char*) arData, "0") == 0)
                    retVal = false;
#if OSL_DEBUG_LEVEL > 1
                else
                    OSL_ASSERT(0);
#endif
            }
            else if (dwType == REG_DWORD)
            {
                if (arData[0] == 1)
                    retVal = true;
                else if (arData[0] == 0)
                    retVal = false;
#if OSL_DEBUG_LEVEL > 1
                else
                    OSL_ASSERT(0);
#endif
            }
        }
    }
    RegCloseKey(hKey);

#elif UNX
    char buf[16];
    // use 2 shells to suppress the eventual "gcontool-2 not found" message
    // of the shell trying to execute the command
    FILE* fp = popen( "/bin/sh 2>/dev/null -c \"gconftool-2 -g /desktop/gnome/interface/accessibility\"", "r" );
    if( fp )
    {
        if( fgets( buf, sizeof(buf), fp ) )
        {
            int nCompare = strncasecmp( buf, "true", 4 );
            retVal = (nCompare == 0 ? true : false);
        }
        pclose( fp );
    }
#endif
    return retVal;
}

rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData)
{
    static char EncodingTable[] =
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    sal_Int32 lenRaw = rawData.getLength();
    char* pBuf = new char[lenRaw * 2];
    const sal_Int8* arRaw = rawData.getConstArray();

    char* pCurBuf = pBuf;
    for (int i = 0; i < lenRaw; i++)
    {
        unsigned char curChar = arRaw[i];
        curChar >>= 4;

        *pCurBuf = EncodingTable[curChar];
        pCurBuf++;

        curChar = arRaw[i];
        curChar &= 0x0F;

        *pCurBuf = EncodingTable[curChar];
        pCurBuf++;
    }

    rtl::ByteSequence ret((sal_Int8*) pBuf, lenRaw * 2);
    delete [] pBuf;
    return ret;
}

rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data)
{
    static char decodingTable[] =
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    sal_Int32 lenData = data.getLength();
    sal_Int32 lenBuf = lenData / 2; //always divisable by two
    unsigned char* pBuf = new unsigned char[lenBuf];
    const sal_Int8* pData = data.getConstArray();
    for (sal_Int32 i = 0; i < lenBuf; i++)
    {
        sal_Int8 curChar = *pData++;
        //find the index of the first 4bits
        //  TODO  What happens if text is not valid Hex characters?
        unsigned char nibble = 0;
        for (unsigned char j = 0; j < 16; j++)
        {
            if (curChar == decodingTable[j])
            {
                nibble = j;
                break;
            }
        }
        nibble <<= 4;
        curChar = *pData++;
        //find the index for the next 4bits
        for (unsigned char j = 0; j < 16; j++)
        {
            if (curChar == decodingTable[j])
            {
                nibble |= j;
                break;
            }
        }
        pBuf[i] = nibble;
    }
    rtl::ByteSequence ret((sal_Int8*) pBuf, lenBuf );
    delete [] pBuf;
    return ret;
}

rtl::OUString getDirFromFile(const rtl::OUString& usFilePath)
{
    sal_Int32 index= usFilePath.lastIndexOf('/');
    return rtl::OUString(usFilePath.getStr(), index);
}

rtl::OUString getFileFromURL(const rtl::OUString& sFileURL)
{
    sal_Int32 index= sFileURL.lastIndexOf('/');
    if (index == -1)
        return sFileURL;
    return sFileURL.copy(index + 1);
}

rtl::OUString getExecutableDirectory()
{
    rtl_uString* sExe = NULL;
    if (osl_getExecutableFile( & sExe) != osl_Process_E_None)
        throw FrameworkException(
            JFW_E_ERROR,
            "[Java framework] Error in function getApplicationBase (fwkutil.cxx)");

    rtl::OUString ouExe(sExe, SAL_NO_ACQUIRE);
    return getDirFromFile(ouExe);
}

rtl::OUString findPlugin(
    const rtl::OUString & baseUrl, const rtl::OUString & plugin)
{
    rtl::OUString sUrl;
    try
    {
        sUrl = rtl::Uri::convertRelToAbs(baseUrl, plugin);
    }
    catch (rtl::MalformedUriException & e)
    {
        throw FrameworkException(
            JFW_E_ERROR,
            (rtl::OString(
                RTL_CONSTASCII_STRINGPARAM(
                    "[Java framework] rtl::MalformedUriException in"
                    " findPlugin: "))
             + rtl::OUStringToOString(
                 e.getMessage(), osl_getThreadTextEncoding())));
    }
    if (checkFileURL(sUrl) == jfw::FILE_OK)
    {
        return sUrl;
    }
    rtl::OUString retVal;
    rtl::OUString sProgDir = getExecutableDirectory();
    sUrl = sProgDir + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"))
        + plugin;
    jfw::FileStatus s = checkFileURL(sUrl);
    if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST)
    {
        //If only the name of the library is given, then
        //use PATH, LD_LIBRARY_PATH etc. to locate the plugin
        if (plugin.indexOf('/') == -1)
        {
            rtl::OUString url;
#ifdef UNX
#ifdef MACOSX
            rtl::OUString path = rtl::OUString::createFromAscii("DYLD_LIBRARY_PATH");
#else
            rtl::OUString path = rtl::OUString::createFromAscii("LD_LIBRARY_PATH");
#endif
            rtl::OUString env_path;
            oslProcessError err = osl_getEnvironment(path.pData, &env_path.pData);
            if (err != osl_Process_E_None && err != osl_Process_E_NotFound)
                throw FrameworkException(
                    JFW_E_ERROR,
                    "[Java framework] Error in function findPlugin (fwkutil.cxx).");
            if (err == osl_Process_E_NotFound)
                return retVal;
            if (osl_searchFileURL(plugin.pData, env_path.pData, &url.pData)
                                == osl_File_E_None)
#else
            if (osl_searchFileURL(plugin.pData, NULL, &url.pData)
                == osl_File_E_None)
#endif
                retVal = url;
            else
                throw FrameworkException(
                    JFW_E_ERROR,
                    "[Java framework] Error in function findPlugin (fwkutil.cxx).");
        }
    }
    else
    {
        retVal = sUrl;
    }
    return retVal;
}

rtl::OUString getLibraryLocation()
{
    rtl::OString sExcMsg("[Java framework] Error in function getLibraryLocation "
                         "(fwkutil.cxx).");
    rtl::OUString libraryFileUrl;

    if (!osl::Module::getUrlFromAddress(
            reinterpret_cast< oslGenericFunction >(getLibraryLocation),
            libraryFileUrl))
        throw FrameworkException(JFW_E_ERROR, sExcMsg);

    return getDirFromFile(libraryFileUrl);
}

jfw::FileStatus checkFileURL(const rtl::OUString & sURL)
{
    jfw::FileStatus ret = jfw::FILE_OK;
    DirectoryItem item;
    File::RC rc_item = DirectoryItem::get(sURL, item);
    if (File::E_None == rc_item)
    {
        osl::FileStatus status(FileStatusMask_Validate);

        File::RC rc_stat = item.getFileStatus(status);
        if (File::E_None == rc_stat)
        {
            ret = FILE_OK;
        }
        else if (File::E_NOENT == rc_stat)
        {
            ret = FILE_DOES_NOT_EXIST;
        }
        else
        {
            ret = FILE_INVALID;
        }
    }
    else if (File::E_NOENT == rc_item)
    {
        ret = FILE_DOES_NOT_EXIST;
    }
    else
    {
        ret = FILE_INVALID;
    }
    return ret;
}

}
<|endoftext|>


<commit_before>// Copyright (C) 2010-2014 Joshua Boyce.
// See the file COPYING for copying permission.

#include "character_manager.hpp"

#include <cstdio>

#include <hadesmem/read.hpp>

#include "offsets.hpp"

std::vector<Character*> DumpCharacterArray(hadesmem::Process const& process,
                                           Character** ptr_array,
                                           std::uint16_t* type_id_array,
                                           std::uint32_t array_len)
{
  std::vector<Character*> characters;
  characters.reserve(array_len);

  auto character_ptr_array =
    hadesmem::ReadVector<Character*>(process, ptr_array, array_len);
  auto const character_type_id_array =
    type_id_array
      ? hadesmem::ReadVector<std::uint16_t>(process, type_id_array, array_len)
      : std::vector<std::uint16_t>();
  for (std::size_t i = 0; i < character_ptr_array.size(); ++i)
  {
    auto const character_ptr = character_ptr_array[i];
    if (type_id_array)
    {
      printf("Character %X: %p (Type: %04X)\n",
             i,
             static_cast<void*>(character_ptr),
             character_type_id_array[i]);
    }
    else
    {
      printf("Character %X: %p\n", i, static_cast<void*>(character_ptr));
    }

    if (character_ptr != 0)
    {
      DumpCharacter(process, character_ptr);
      characters.push_back(character_ptr);
    }
    else
    {
      printf("  Empty character slot.\n");
    }

    printf("\n");
  }

  return characters;
}

void DumpCharacterManager(hadesmem::Process const& process, std::uint8_t* base)
{
  auto const character_manager_ptr = hadesmem::Read<CharacterManager*>(
    process, base + Offsets::g_character_manager);
  auto const character_manager =
    hadesmem::Read<CharacterManager>(process, character_manager_ptr);
  printf("CharacterManager::CharacterPtrArray: %p\n",
         static_cast<void*>(character_manager.character_ptr_array_));
  printf("CharacterManager::CharacterPtrArrayLen: %X\n",
         character_manager.character_ptr_array_len_);
  printf("CharacterManager::CharacterTypeIdArray: %p\n",
         static_cast<void*>(character_manager.character_type_id_array_));
  printf("CharacterManager::PartyMemberPtrArray: %p\n",
         static_cast<void*>(
           character_manager.party_manager_.party_member_ptr_array_));
  printf("CharacterManager::PartyMemberPtrArrayLen: %X\n",
         character_manager.party_manager_.party_member_ptr_array_len_);
  printf("\n");

  printf("Dumping character array.\n\n");
  DumpCharacterArray(process,
                     character_manager.character_ptr_array_,
                     character_manager.character_type_id_array_,
                     character_manager.character_ptr_array_len_);

  printf("Dumping party array.\n\n");
  DumpCharacterArray(
    process,
    character_manager.party_manager_.party_member_ptr_array_,
    nullptr,
    character_manager.party_manager_.party_member_ptr_array_len_);
}
<commit_msg>* [Divinity] x64 compile fix.<commit_after>// Copyright (C) 2010-2014 Joshua Boyce.
// See the file COPYING for copying permission.

#include "character_manager.hpp"

#include <cstdio>

#include <hadesmem/read.hpp>

#include "offsets.hpp"

std::vector<Character*> DumpCharacterArray(hadesmem::Process const& process,
                                           Character** ptr_array,
                                           std::uint16_t* type_id_array,
                                           std::uint32_t array_len)
{
  std::vector<Character*> characters;
  characters.reserve(array_len);

  auto character_ptr_array =
    hadesmem::ReadVector<Character*>(process, ptr_array, array_len);
  auto const character_type_id_array =
    type_id_array
      ? hadesmem::ReadVector<std::uint16_t>(process, type_id_array, array_len)
      : std::vector<std::uint16_t>();
  for (std::uint32_t i = 0; i < character_ptr_array.size(); ++i)
  {
    auto const character_ptr = character_ptr_array[i];
    if (type_id_array)
    {
      printf("Character %X: %p (Type: %04X)\n",
             i,
             static_cast<void*>(character_ptr),
             character_type_id_array[i]);
    }
    else
    {
      printf("Character %X: %p\n", i, static_cast<void*>(character_ptr));
    }

    if (character_ptr != 0)
    {
      DumpCharacter(process, character_ptr);
      characters.push_back(character_ptr);
    }
    else
    {
      printf("  Empty character slot.\n");
    }

    printf("\n");
  }

  return characters;
}

void DumpCharacterManager(hadesmem::Process const& process, std::uint8_t* base)
{
  auto const character_manager_ptr = hadesmem::Read<CharacterManager*>(
    process, base + Offsets::g_character_manager);
  auto const character_manager =
    hadesmem::Read<CharacterManager>(process, character_manager_ptr);
  printf("CharacterManager::CharacterPtrArray: %p\n",
         static_cast<void*>(character_manager.character_ptr_array_));
  printf("CharacterManager::CharacterPtrArrayLen: %X\n",
         character_manager.character_ptr_array_len_);
  printf("CharacterManager::CharacterTypeIdArray: %p\n",
         static_cast<void*>(character_manager.character_type_id_array_));
  printf("CharacterManager::PartyMemberPtrArray: %p\n",
         static_cast<void*>(
           character_manager.party_manager_.party_member_ptr_array_));
  printf("CharacterManager::PartyMemberPtrArrayLen: %X\n",
         character_manager.party_manager_.party_member_ptr_array_len_);
  printf("\n");

  printf("Dumping character array.\n\n");
  DumpCharacterArray(process,
                     character_manager.character_ptr_array_,
                     character_manager.character_type_id_array_,
                     character_manager.character_ptr_array_len_);

  printf("Dumping party array.\n\n");
  DumpCharacterArray(
    process,
    character_manager.party_manager_.party_member_ptr_array_,
    nullptr,
    character_manager.party_manager_.party_member_ptr_array_len_);
}
<|endoftext|>