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

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

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

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

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

#include "otbWrapperChoiceParameter.h"
#include "otbWrapperDirectoryParameter.h"
#include "otbWrapperEmptyParameter.h"
#include "otbWrapperFilenameParameter.h"
#include "otbWrapperInputComplexImageParameter.h"
#include "otbWrapperInputImageParameter.h"
#include "otbWrapperInputVectorDataParameter.h"
#include "otbWrapperNumericalParameter.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperOutputVectorDataParameter.h"
#include "otbWrapperRadiusParameter.h"
#include "otbWrapperStringParameter.h"

#include "otbWrapperParameterGroup.h"

namespace otb
{
namespace Wrapper
{

Application::Application()
 : m_Name(""),
   m_Description("")
{
  // Don't call Init from the constructor, since it calls a virtual method !
}

Application::~Application()
{
}

std::vector<std::string>
Application::GetParametersKeys(bool recursive)
{
  return GetParameterList()->GetParametersKeys(recursive);
}

ParameterGroup* Application::GetParameterList()
{
  if (!m_ParameterList)
    {
    Init();
    }

  return m_ParameterList;
}

Parameter* Application::GetParameterByKey(std::string name)
{
  return GetParameterList()->GetParameterByKey(name);
}

const Parameter* Application::GetParameterByKey(std::string name) const
{
  // GetParameterList is non const...
  Application* _this = const_cast<Application*>(this);
  return _this->GetParameterByKey(name);
}

void Application::Init()
{
  m_ParameterList = ParameterGroup::New();
  this->DoCreateParameters();
}

void Application::UpdateParameters()
{
  this->DoUpdateParameters();
}

void Application::Execute()
{
  this->DoExecute();
}

void Application::ExecuteAndWriteOutput()
{
  this->Execute();

  std::vector<std::string> paramList = GetParametersKeys(true);
  for (std::vector<std::string>::const_iterator it = paramList.begin();
      it != paramList.end();
      ++it)
    {
    if (GetParameterType(*it) == ParameterType_OutputImage)
      {
      Parameter* param = GetParameterByKey(*it);
      OutputImageParameter* outputParam = dynamic_cast<OutputImageParameter*>(param);
      outputParam->Write();
      }
    }
}

/* Enable the use of an optional parameter. Returns the previous state */
void Application::EnableParameter(std::string paramKey)
{
  Parameter* param = GetParameterByKey(paramKey);
  param->SetActive(true);
}

/* Disable the use of an optional parameter. Returns the previous state  */
void Application::DisableParameter(std::string paramKey)
{
  GetParameterByKey(paramKey)->SetActive(false);
}

/* Return the enable state of an optional parameter  */
bool Application::IsParameterEnabled(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->GetActive();
}

/* Return true if the specified parameter is mandatory */
bool Application::IsMandatory(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->GetMandatory();
}

/* Returns true if the parameter has an associated value provided externally
 *  (not automatically computed by the application) */
bool Application::HasUserValue(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->HasUserValue();
}

/* If a user value was provided clear it and update the other parameters */
void Application::ClearValue(std::string paramKey)
{
  GetParameterByKey(paramKey)->ClearValue();
}

/* Returns true if the parameter has an associated value.
 * This value can be an automatically computed value or default value,
 * or a value set externally by user */
bool Application::HasValue(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->HasValue();
}

/* Return the user level of access to a parameter */
UserLevel Application::GetParameterUserLevel(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->GetUserLevel();
}

/* Get the parameter type from its name */
ParameterType Application::GetParameterType(std::string paramKey) const
{
  const Parameter* param = GetParameterByKey(paramKey);
  ParameterType type;

  if (dynamic_cast<const ChoiceParameter*>(param))
    {
    type = ParameterType_Choice;
    }
  else if (dynamic_cast<const RadiusParameter*>(param))
    {
    type = ParameterType_Radius;
    }
  else if (dynamic_cast<const EmptyParameter*>(param))
    {
    std::cout << "GetParameterType Empty" << std::endl;
    type = ParameterType_Empty;
    }
 else if (dynamic_cast<const IntParameter*>(param))
    {
    type = ParameterType_Int;
    }
  else if (dynamic_cast<const FloatParameter*>(param))
    {
    type = ParameterType_Float;
    }
  else if (dynamic_cast<const FilenameParameter*>(param))
    {
    type = ParameterType_Filename;
    }
  else if (dynamic_cast<const DirectoryParameter*>(param))
    {
    type = ParameterType_Directory;
    }
  else if (dynamic_cast<const InputImageParameter*>(param))
    {
    type = ParameterType_InputImage;
    }
  else if (dynamic_cast<const InputComplexImageParameter*>(param))
    {
    type = ParameterType_InputComplexImage;
    }
  else if (dynamic_cast<const InputVectorDataParameter*>(param))
    {
    type = ParameterType_InputVectorData;
    }
  else if (dynamic_cast<const OutputImageParameter*>(param))
    {
    type = ParameterType_OutputImage;
    }
  else if (dynamic_cast<const OutputVectorDataParameter*>(param))
    {
    type = ParameterType_OutputVectorData;
    }
  else if (dynamic_cast<const StringParameter*>(param))
    {
    type = ParameterType_String;
    }
  else if (dynamic_cast<const ParameterGroup*>(param))
    {
    type = ParameterType_Group;
    }
  else
    {
    itkExceptionMacro(<< "Unknown parameter : " << paramKey);
    }

  return type;
}

void Application::SetParameterInt(std::string parameter, int value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<IntParameter*>(param))
    {
    IntParameter* paramInt = dynamic_cast<IntParameter*>(param);
    paramInt->SetValue(value);
    }
  else if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    paramFloat->SetValue(static_cast<float>(value));
    }
  else if (dynamic_cast<RadiusParameter*>(param))
    {
    RadiusParameter* paramRadius = dynamic_cast<RadiusParameter*>(param);
    paramRadius->SetValue(value);
    }
  else if (dynamic_cast<ChoiceParameter*>(param))
    {
    ChoiceParameter* paramChoice = dynamic_cast<ChoiceParameter*>(param);
    paramChoice->SetValue(value);
    }
}

void Application::SetParameterFloat(std::string parameter, float value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    paramFloat->SetValue(value);
    }
}

void Application::SetParameterString(std::string parameter, std::string value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<ChoiceParameter*>(param))
    {
    ChoiceParameter* paramDown = dynamic_cast<ChoiceParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<StringParameter*>(param))
    {
    StringParameter* paramDown = dynamic_cast<StringParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<FilenameParameter*>(param))
    {
    FilenameParameter* paramDown = dynamic_cast<FilenameParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<DirectoryParameter*>(param))
    {
    DirectoryParameter* paramDown = dynamic_cast<DirectoryParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<InputImageParameter*>(param))
    {
    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param);
    paramDown->SetFromFileName(value);
    }
  else if (dynamic_cast<InputComplexImageParameter*>(param))
    {
    InputComplexImageParameter* paramDown = dynamic_cast<InputComplexImageParameter*>(param);
    paramDown->SetFromFileName(value);
    }
  else if (dynamic_cast<InputVectorDataParameter*>(param))
    {
    InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
    paramDown->SetFromFileName(value);
    }
  else if (dynamic_cast<OutputImageParameter*>(param))
    {
    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
    paramDown->SetFileName(value);
    }
  else if (dynamic_cast<OutputVectorDataParameter*>(param))
    {
    OutputVectorDataParameter* paramDown = dynamic_cast<OutputVectorDataParameter*>(param);
    paramDown->SetFileName(value);
    }
}

void Application::SetParameterOutputImage(std::string parameter, VectorImageType* value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<OutputImageParameter*>(param))
    {
    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
    paramDown->SetValue(value);
    }
}

void Application::SetParameterOutputVectorData(std::string parameter, VectorDataType* value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<OutputVectorDataParameter*>(param))
    {
    OutputVectorDataParameter* paramDown = dynamic_cast<OutputVectorDataParameter*>(param);
    paramDown->SetValue(value);
    }
}

std::string Application::GetParameterName(std::string parameter)
{
  Parameter* param = GetParameterByKey(parameter);
  return param->GetName();
}

std::string Application::GetParameterDescription(std::string parameter)
{
  Parameter* param = GetParameterByKey(parameter);
  return param->GetDescription();
}

int Application::GetParameterInt(std::string parameter)
{
  int ret = 0;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<IntParameter*>(param))
    {
    IntParameter* paramInt = dynamic_cast<IntParameter*>(param);
    ret = paramInt->GetValue();
    }
  else if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    ret = static_cast<int>(paramFloat->GetValue());
    }
  else if (dynamic_cast<RadiusParameter*>(param))
    {
    RadiusParameter* paramRadius = dynamic_cast<RadiusParameter*>(param);
    ret = paramRadius->GetValue();
    }
  else if (dynamic_cast<ChoiceParameter*>(param))
    {
    ChoiceParameter* paramChoice = dynamic_cast<ChoiceParameter*>(param);
    ret = paramChoice->GetValue();
    }

  //TODO: exception if not found ?
  return ret;
}

float Application::GetParameterFloat(std::string parameter)
{
  float ret = 0;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    ret = paramFloat->GetValue();
    }

  //TODO: exception if not found ?
  return ret;
}

std::string Application::GetParameterString(std::string parameter)
{
  std::string ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<FilenameParameter*>(param))
    {
    FilenameParameter* paramDown = dynamic_cast<FilenameParameter*>(param);
    ret = paramDown->GetValue();
    }
  else if (dynamic_cast<DirectoryParameter*>(param))
    {
    DirectoryParameter* paramDown = dynamic_cast<DirectoryParameter*>(param);
    ret = paramDown->GetValue();
    }
  else if (dynamic_cast<InputImageParameter*>(param))
    {
    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<InputComplexImageParameter*>(param))
    {
    InputComplexImageParameter* paramDown = dynamic_cast<InputComplexImageParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<InputVectorDataParameter*>(param))
    {
    InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<OutputImageParameter*>(param))
    {
    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<OutputVectorDataParameter*>(param))
    {
    OutputVectorDataParameter* paramDown = dynamic_cast<OutputVectorDataParameter*>(param);
    ret = paramDown->GetFileName();
    }

  //TODO: exception if not found ?
  return ret;
}

VectorImageType* Application::GetParameterImage(std::string parameter)
{
  VectorImageType::Pointer ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<InputImageParameter*>(param))
    {
    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param);
    ret = paramDown->GetImage();
    }

  //TODO: exception if not found ?
  return ret;
}

VectorImageType* Application::GetParameterComplexImage(std::string parameter)
{
  VectorImageType::Pointer ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<InputComplexImageParameter*>(param))
    {
    InputComplexImageParameter* paramDown = dynamic_cast<InputComplexImageParameter*>(param);
    ret = paramDown->GetImage();
    }

  //TODO: exception if not found ?
  return ret;

}

VectorDataType* Application::GetParameterVectorData(std::string parameter)
{
  VectorDataType::Pointer ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<InputVectorDataParameter*>(param))
    {
    InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
    ret = paramDown->GetVectorData();
    }

  //TODO: exception if not found ?
  return ret;
}

void
Application::AddChoice(std::string paramKey, std::string paramName)
{
  GetParameterList()->AddChoice(paramKey, paramName);
}

void
Application::AddParameter(ParameterType type, std::string paramKey, std::string paramName)
{
  GetParameterList()->AddParameter(type, paramKey, paramName);
}

}
}

<commit_msg>ENH: remove cout<commit_after>/*=========================================================================

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

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

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

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

#include "otbWrapperChoiceParameter.h"
#include "otbWrapperDirectoryParameter.h"
#include "otbWrapperEmptyParameter.h"
#include "otbWrapperFilenameParameter.h"
#include "otbWrapperInputComplexImageParameter.h"
#include "otbWrapperInputImageParameter.h"
#include "otbWrapperInputVectorDataParameter.h"
#include "otbWrapperNumericalParameter.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperOutputVectorDataParameter.h"
#include "otbWrapperRadiusParameter.h"
#include "otbWrapperStringParameter.h"

#include "otbWrapperParameterGroup.h"

namespace otb
{
namespace Wrapper
{

Application::Application()
 : m_Name(""),
   m_Description("")
{
  // Don't call Init from the constructor, since it calls a virtual method !
}

Application::~Application()
{
}

std::vector<std::string>
Application::GetParametersKeys(bool recursive)
{
  return GetParameterList()->GetParametersKeys(recursive);
}

ParameterGroup* Application::GetParameterList()
{
  if (!m_ParameterList)
    {
    Init();
    }

  return m_ParameterList;
}

Parameter* Application::GetParameterByKey(std::string name)
{
  return GetParameterList()->GetParameterByKey(name);
}

const Parameter* Application::GetParameterByKey(std::string name) const
{
  // GetParameterList is non const...
  Application* _this = const_cast<Application*>(this);
  return _this->GetParameterByKey(name);
}

void Application::Init()
{
  m_ParameterList = ParameterGroup::New();
  this->DoCreateParameters();
}

void Application::UpdateParameters()
{
  this->DoUpdateParameters();
}

void Application::Execute()
{
  this->DoExecute();
}

void Application::ExecuteAndWriteOutput()
{
  this->Execute();

  std::vector<std::string> paramList = GetParametersKeys(true);
  for (std::vector<std::string>::const_iterator it = paramList.begin();
      it != paramList.end();
      ++it)
    {
    if (GetParameterType(*it) == ParameterType_OutputImage)
      {
      Parameter* param = GetParameterByKey(*it);
      OutputImageParameter* outputParam = dynamic_cast<OutputImageParameter*>(param);
      outputParam->Write();
      }
    }
}

/* Enable the use of an optional parameter. Returns the previous state */
void Application::EnableParameter(std::string paramKey)
{
  Parameter* param = GetParameterByKey(paramKey);
  param->SetActive(true);
}

/* Disable the use of an optional parameter. Returns the previous state  */
void Application::DisableParameter(std::string paramKey)
{
  GetParameterByKey(paramKey)->SetActive(false);
}

/* Return the enable state of an optional parameter  */
bool Application::IsParameterEnabled(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->GetActive();
}

/* Return true if the specified parameter is mandatory */
bool Application::IsMandatory(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->GetMandatory();
}

/* Returns true if the parameter has an associated value provided externally
 *  (not automatically computed by the application) */
bool Application::HasUserValue(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->HasUserValue();
}

/* If a user value was provided clear it and update the other parameters */
void Application::ClearValue(std::string paramKey)
{
  GetParameterByKey(paramKey)->ClearValue();
}

/* Returns true if the parameter has an associated value.
 * This value can be an automatically computed value or default value,
 * or a value set externally by user */
bool Application::HasValue(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->HasValue();
}

/* Return the user level of access to a parameter */
UserLevel Application::GetParameterUserLevel(std::string paramKey) const
{
  return GetParameterByKey(paramKey)->GetUserLevel();
}

/* Get the parameter type from its name */
ParameterType Application::GetParameterType(std::string paramKey) const
{
  const Parameter* param = GetParameterByKey(paramKey);
  ParameterType type;

  if (dynamic_cast<const ChoiceParameter*>(param))
    {
    type = ParameterType_Choice;
    }
  else if (dynamic_cast<const RadiusParameter*>(param))
    {
    type = ParameterType_Radius;
    }
  else if (dynamic_cast<const EmptyParameter*>(param))
    {
    type = ParameterType_Empty;
    }
 else if (dynamic_cast<const IntParameter*>(param))
    {
    type = ParameterType_Int;
    }
  else if (dynamic_cast<const FloatParameter*>(param))
    {
    type = ParameterType_Float;
    }
  else if (dynamic_cast<const FilenameParameter*>(param))
    {
    type = ParameterType_Filename;
    }
  else if (dynamic_cast<const DirectoryParameter*>(param))
    {
    type = ParameterType_Directory;
    }
  else if (dynamic_cast<const InputImageParameter*>(param))
    {
    type = ParameterType_InputImage;
    }
  else if (dynamic_cast<const InputComplexImageParameter*>(param))
    {
    type = ParameterType_InputComplexImage;
    }
  else if (dynamic_cast<const InputVectorDataParameter*>(param))
    {
    type = ParameterType_InputVectorData;
    }
  else if (dynamic_cast<const OutputImageParameter*>(param))
    {
    type = ParameterType_OutputImage;
    }
  else if (dynamic_cast<const OutputVectorDataParameter*>(param))
    {
    type = ParameterType_OutputVectorData;
    }
  else if (dynamic_cast<const StringParameter*>(param))
    {
    type = ParameterType_String;
    }
  else if (dynamic_cast<const ParameterGroup*>(param))
    {
    type = ParameterType_Group;
    }
  else
    {
    itkExceptionMacro(<< "Unknown parameter : " << paramKey);
    }

  return type;
}

void Application::SetParameterInt(std::string parameter, int value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<IntParameter*>(param))
    {
    IntParameter* paramInt = dynamic_cast<IntParameter*>(param);
    paramInt->SetValue(value);
    }
  else if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    paramFloat->SetValue(static_cast<float>(value));
    }
  else if (dynamic_cast<RadiusParameter*>(param))
    {
    RadiusParameter* paramRadius = dynamic_cast<RadiusParameter*>(param);
    paramRadius->SetValue(value);
    }
  else if (dynamic_cast<ChoiceParameter*>(param))
    {
    ChoiceParameter* paramChoice = dynamic_cast<ChoiceParameter*>(param);
    paramChoice->SetValue(value);
    }
}

void Application::SetParameterFloat(std::string parameter, float value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    paramFloat->SetValue(value);
    }
}

void Application::SetParameterString(std::string parameter, std::string value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<ChoiceParameter*>(param))
    {
    ChoiceParameter* paramDown = dynamic_cast<ChoiceParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<StringParameter*>(param))
    {
    StringParameter* paramDown = dynamic_cast<StringParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<FilenameParameter*>(param))
    {
    FilenameParameter* paramDown = dynamic_cast<FilenameParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<DirectoryParameter*>(param))
    {
    DirectoryParameter* paramDown = dynamic_cast<DirectoryParameter*>(param);
    paramDown->SetValue(value);
    }
  else if (dynamic_cast<InputImageParameter*>(param))
    {
    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param);
    paramDown->SetFromFileName(value);
    }
  else if (dynamic_cast<InputComplexImageParameter*>(param))
    {
    InputComplexImageParameter* paramDown = dynamic_cast<InputComplexImageParameter*>(param);
    paramDown->SetFromFileName(value);
    }
  else if (dynamic_cast<InputVectorDataParameter*>(param))
    {
    InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
    paramDown->SetFromFileName(value);
    }
  else if (dynamic_cast<OutputImageParameter*>(param))
    {
    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
    paramDown->SetFileName(value);
    }
  else if (dynamic_cast<OutputVectorDataParameter*>(param))
    {
    OutputVectorDataParameter* paramDown = dynamic_cast<OutputVectorDataParameter*>(param);
    paramDown->SetFileName(value);
    }
}

void Application::SetParameterOutputImage(std::string parameter, VectorImageType* value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<OutputImageParameter*>(param))
    {
    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
    paramDown->SetValue(value);
    }
}

void Application::SetParameterOutputVectorData(std::string parameter, VectorDataType* value)
{
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<OutputVectorDataParameter*>(param))
    {
    OutputVectorDataParameter* paramDown = dynamic_cast<OutputVectorDataParameter*>(param);
    paramDown->SetValue(value);
    }
}

std::string Application::GetParameterName(std::string parameter)
{
  Parameter* param = GetParameterByKey(parameter);
  return param->GetName();
}

std::string Application::GetParameterDescription(std::string parameter)
{
  Parameter* param = GetParameterByKey(parameter);
  return param->GetDescription();
}

int Application::GetParameterInt(std::string parameter)
{
  int ret = 0;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<IntParameter*>(param))
    {
    IntParameter* paramInt = dynamic_cast<IntParameter*>(param);
    ret = paramInt->GetValue();
    }
  else if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    ret = static_cast<int>(paramFloat->GetValue());
    }
  else if (dynamic_cast<RadiusParameter*>(param))
    {
    RadiusParameter* paramRadius = dynamic_cast<RadiusParameter*>(param);
    ret = paramRadius->GetValue();
    }
  else if (dynamic_cast<ChoiceParameter*>(param))
    {
    ChoiceParameter* paramChoice = dynamic_cast<ChoiceParameter*>(param);
    ret = paramChoice->GetValue();
    }

  //TODO: exception if not found ?
  return ret;
}

float Application::GetParameterFloat(std::string parameter)
{
  float ret = 0;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<FloatParameter*>(param))
    {
    FloatParameter* paramFloat = dynamic_cast<FloatParameter*>(param);
    ret = paramFloat->GetValue();
    }

  //TODO: exception if not found ?
  return ret;
}

std::string Application::GetParameterString(std::string parameter)
{
  std::string ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<FilenameParameter*>(param))
    {
    FilenameParameter* paramDown = dynamic_cast<FilenameParameter*>(param);
    ret = paramDown->GetValue();
    }
  else if (dynamic_cast<DirectoryParameter*>(param))
    {
    DirectoryParameter* paramDown = dynamic_cast<DirectoryParameter*>(param);
    ret = paramDown->GetValue();
    }
  else if (dynamic_cast<InputImageParameter*>(param))
    {
    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<InputComplexImageParameter*>(param))
    {
    InputComplexImageParameter* paramDown = dynamic_cast<InputComplexImageParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<InputVectorDataParameter*>(param))
    {
    InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<OutputImageParameter*>(param))
    {
    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
    ret = paramDown->GetFileName();
    }
  else if (dynamic_cast<OutputVectorDataParameter*>(param))
    {
    OutputVectorDataParameter* paramDown = dynamic_cast<OutputVectorDataParameter*>(param);
    ret = paramDown->GetFileName();
    }

  //TODO: exception if not found ?
  return ret;
}

VectorImageType* Application::GetParameterImage(std::string parameter)
{
  VectorImageType::Pointer ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<InputImageParameter*>(param))
    {
    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param);
    ret = paramDown->GetImage();
    }

  //TODO: exception if not found ?
  return ret;
}

VectorImageType* Application::GetParameterComplexImage(std::string parameter)
{
  VectorImageType::Pointer ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<InputComplexImageParameter*>(param))
    {
    InputComplexImageParameter* paramDown = dynamic_cast<InputComplexImageParameter*>(param);
    ret = paramDown->GetImage();
    }

  //TODO: exception if not found ?
  return ret;

}

VectorDataType* Application::GetParameterVectorData(std::string parameter)
{
  VectorDataType::Pointer ret;
  Parameter* param = GetParameterByKey(parameter);

  if (dynamic_cast<InputVectorDataParameter*>(param))
    {
    InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
    ret = paramDown->GetVectorData();
    }

  //TODO: exception if not found ?
  return ret;
}

void
Application::AddChoice(std::string paramKey, std::string paramName)
{
  GetParameterList()->AddChoice(paramKey, paramName);
}

void
Application::AddParameter(ParameterType type, std::string paramKey, std::string paramName)
{
  GetParameterList()->AddParameter(type, paramKey, paramName);
}

}
}

<|endoftext|>


<commit_before>#include "RenderTarget.h"

#include <unirender/RenderContext.h>
#include <unirender/RenderTarget.h>
#include <unirender/Texture.h>
#include <shaderlab/ShaderMgr.h>
#include <dtex2/DebugDraw.h>

namespace gum
{

SINGLETON_DEFINITION(RenderTarget);

RenderTarget::RenderTarget()
	: m_screen0(NULL)
	, m_screen1(NULL)
{
}

void RenderTarget::OnSize(ur::RenderContext* rc, int w, int h)
{
	if (m_screen0 &&
		m_screen0->GetTexture()->Width() == w &&
		m_screen0->GetTexture()->Height() == h) {
		return;
	}

	delete m_screen0;
	delete m_screen1;

	m_screen0 = new ur::RenderTarget(rc, w, h);
	m_screen1 = new ur::RenderTarget(rc, w, h);
}

void RenderTarget::DebugDraw() const
{
	dtex::DebugDraw::Draw(m_screen0->GetTexture()->ID(), 1);
}

}<commit_msg>fix rt on size<commit_after>#include "RenderTarget.h"

#include <unirender/RenderContext.h>
#include <unirender/RenderTarget.h>
#include <unirender/Texture.h>
#include <shaderlab/ShaderMgr.h>
#include <dtex2/DebugDraw.h>

namespace gum
{

SINGLETON_DEFINITION(RenderTarget);

RenderTarget::RenderTarget()
	: m_screen0(NULL)
	, m_screen1(NULL)
{
}

void RenderTarget::OnSize(ur::RenderContext* rc, int w, int h)
{
	if (w == 0 || h == 0) {
		return;
	}
	if (m_screen0 &&
		m_screen0->GetTexture()->Width() == w &&
		m_screen0->GetTexture()->Height() == h) {
		return;
	}

	delete m_screen0;
	delete m_screen1;

	m_screen0 = new ur::RenderTarget(rc, w, h);
	m_screen1 = new ur::RenderTarget(rc, w, h);
}

void RenderTarget::DebugDraw() const
{
	dtex::DebugDraw::Draw(m_screen0->GetTexture()->ID(), 1);
}

}<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <fstream>
#include <vector>
#include <stdexcept>
#include "api-spec.h"
#include "api.h"

using namespace std;

class AJpegAsm : public ::testing::Test {
public:
  static const unsigned int rgb_width = 32;
  static const unsigned int rgb_height = 32;

  unsigned char rgb_buffer[rgb_width * rgb_height * 3];

public:
  AJpegAsm() {
    init_rgb_image();
  }

protected:
  void init_rgb_image() {
    unsigned int ptr;
    for(unsigned int y = 0; y != rgb_height; ++y) {
      for(unsigned int x = 0; x != rgb_width * 3; x += 3) {
        ptr = y * rgb_width * 3 + x;
        rgb_buffer[ptr + 0] = 0x00; // R
        rgb_buffer[ptr + 1] = 0x00; // G
        rgb_buffer[ptr + 2] = 0xFF; // B
      }
    }
  }

  void save_buffer(const std::string& filepath, unsigned char* buffer, unsigned long buffer_size) {
    std::ofstream ofs(filepath.c_str(), std::ios_base::out | std::ios_base::binary);
    if(ofs) {
      ofs.write(reinterpret_cast<char*>(buffer), buffer_size);
      ofs.close();
    } else {
      throw std::runtime_error("Cannot open the file for writing");
    }
  }

  std::vector<unsigned char> load_buffer(const std::string& filepath) {
    std::vector<unsigned char> result;
    std::ifstream ifs(filepath.c_str(), std::ios_base::in | std::ios_base::binary);
    if (ifs) {
      ifs.seekg(0, std::ios_base::end);
      size_t length = static_cast<size_t>(ifs.tellg());
      ifs.seekg(0, std::ios_base::beg);

      result.resize(length);

      ifs.read(reinterpret_cast<char*>(&result[0]), length);
      ifs.close();
    } else {
      throw std::runtime_error("Cannot open the file for reading");
    }
    return result;
  }
};

TEST_F(AJpegAsm, EncodesJpeg) {
  int quality = 80;
  unsigned char* jpeg_buffer = nullptr;
  unsigned long jpeg_buffer_size = 0;

  char* out_msg = nullptr;

  int result = encode_jpeg(rgb_buffer, rgb_width, rgb_height, quality, &jpeg_buffer, &jpeg_buffer_size, &out_msg);

  ASSERT_EQ(0, result);
  ASSERT_TRUE(out_msg == nullptr);
  ASSERT_TRUE(jpeg_buffer != nullptr);
  ASSERT_GT(jpeg_buffer_size, 0);

  save_buffer(std::string(TEST_DIR) + "/out/encoded-by-cpp.jpg", jpeg_buffer, jpeg_buffer_size);

  free(jpeg_buffer);
  free(out_msg);
}

TEST_F(AJpegAsm, DecodesJpeg) {

  std::vector<unsigned char> jpeg_buffer = load_buffer(std::string(TEST_DIR) + "/data/sample.jpg");

  unsigned char* new_buffer = nullptr;
  unsigned int new_width = 0;
  unsigned int new_height = 0;

  char* out_msg = nullptr;

  int result = decode_jpeg(&jpeg_buffer[0], jpeg_buffer.size(), &new_buffer, &new_width, &new_height, &out_msg);

  ASSERT_EQ(0, result);
  ASSERT_TRUE(out_msg == nullptr);
  ASSERT_TRUE(new_buffer != nullptr);
  ASSERT_EQ(32, new_width);
  ASSERT_EQ(32, new_height);

  free(new_buffer);
  free(out_msg);
}

TEST_F(AJpegAsm, CannotEncodeImageWithInvalidDimensions) {
  unsigned char* in_buffer = rgb_buffer;
  unsigned int in_width = 0;
  unsigned int in_height = 0;

  int quality = 80;

  unsigned char* jpeg_buffer = nullptr;
  unsigned long jpeg_buffer_size = 0;

  char* out_msg = nullptr;

  int result = encode_jpeg(in_buffer, in_width, in_height, quality, &jpeg_buffer, &jpeg_buffer_size, &out_msg);

  ASSERT_EQ(33, result);
  ASSERT_TRUE(out_msg != nullptr);
  ASSERT_TRUE(jpeg_buffer != nullptr);
  ASSERT_GT(jpeg_buffer_size, 0);

  free(jpeg_buffer);
  free(out_msg);
}<commit_msg>added a test to handle corrupted JPEGs<commit_after>#include <gtest/gtest.h>
#include <fstream>
#include <vector>
#include <stdexcept>
#include "api-spec.h"
#include "api.h"

using namespace std;

class AJpegAsm : public ::testing::Test {
public:
  static const unsigned int rgb_width = 32;
  static const unsigned int rgb_height = 32;

  unsigned char rgb_buffer[rgb_width * rgb_height * 3];

public:
  AJpegAsm() {
    init_rgb_image();
  }

protected:
  void init_rgb_image() {
    unsigned int ptr;
    for(unsigned int y = 0; y != rgb_height; ++y) {
      for(unsigned int x = 0; x != rgb_width * 3; x += 3) {
        ptr = y * rgb_width * 3 + x;
        rgb_buffer[ptr + 0] = 0x00; // R
        rgb_buffer[ptr + 1] = 0x00; // G
        rgb_buffer[ptr + 2] = 0xFF; // B
      }
    }
  }

  void save_buffer(const std::string& filepath, unsigned char* buffer, unsigned long buffer_size) {
    std::ofstream ofs(filepath.c_str(), std::ios_base::out | std::ios_base::binary);
    if(ofs) {
      ofs.write(reinterpret_cast<char*>(buffer), buffer_size);
      ofs.close();
    } else {
      throw std::runtime_error("Cannot open the file for writing");
    }
  }

  std::vector<unsigned char> load_buffer(const std::string& filepath) {
    std::vector<unsigned char> result;
    std::ifstream ifs(filepath.c_str(), std::ios_base::in | std::ios_base::binary);
    if (ifs) {
      ifs.seekg(0, std::ios_base::end);
      size_t length = static_cast<size_t>(ifs.tellg());
      ifs.seekg(0, std::ios_base::beg);

      result.resize(length);

      ifs.read(reinterpret_cast<char*>(&result[0]), length);
      ifs.close();
    } else {
      throw std::runtime_error("Cannot open the file for reading");
    }
    return result;
  }
};

TEST_F(AJpegAsm, EncodesJpeg) {
  int quality = 80;
  unsigned char* jpeg_buffer = nullptr;
  unsigned long jpeg_buffer_size = 0;

  char* out_msg = nullptr;

  int result = encode_jpeg(rgb_buffer, rgb_width, rgb_height, quality, &jpeg_buffer, &jpeg_buffer_size, &out_msg);

  ASSERT_EQ(0, result);
  ASSERT_TRUE(out_msg == nullptr);
  ASSERT_TRUE(jpeg_buffer != nullptr);
  ASSERT_GT(jpeg_buffer_size, 0);

  save_buffer(std::string(TEST_DIR) + "/out/encoded-by-cpp.jpg", jpeg_buffer, jpeg_buffer_size);

  free(jpeg_buffer);
  free(out_msg);
}

TEST_F(AJpegAsm, DecodesJpeg) {
  std::vector<unsigned char> jpeg_buffer = load_buffer(std::string(TEST_DIR) + "/data/sample.jpg");

  unsigned char* new_buffer = nullptr;
  unsigned int new_width = 0;
  unsigned int new_height = 0;

  char* out_msg = nullptr;

  int result = decode_jpeg(&jpeg_buffer[0], jpeg_buffer.size(), &new_buffer, &new_width, &new_height, &out_msg);

  ASSERT_EQ(0, result);
  ASSERT_TRUE(out_msg == nullptr);
  ASSERT_TRUE(new_buffer != nullptr);
  ASSERT_EQ(32, new_width);
  ASSERT_EQ(32, new_height);

  free(new_buffer);
  free(out_msg);
}

TEST_F(AJpegAsm, CannotEncodeImageWithInvalidDimensions) {
  unsigned char* in_buffer = rgb_buffer;
  unsigned int in_width = 0;
  unsigned int in_height = 0;

  int quality = 80;

  unsigned char* jpeg_buffer = nullptr;
  unsigned long jpeg_buffer_size = 0;

  char* out_msg = nullptr;

  int result = encode_jpeg(in_buffer, in_width, in_height, quality, &jpeg_buffer, &jpeg_buffer_size, &out_msg);

  ASSERT_EQ(33, result);
  ASSERT_TRUE(out_msg != nullptr);
  ASSERT_TRUE(jpeg_buffer != nullptr);
  ASSERT_GT(jpeg_buffer_size, 0);

  free(jpeg_buffer);
  free(out_msg);
}

TEST_F(AJpegAsm, CannotDecodeCorruptedImage) {
  std::vector<unsigned char> jpeg_buffer{ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };

  unsigned char* new_buffer = nullptr;
  unsigned int new_width = 0;
  unsigned int new_height = 0;

  char* out_msg = nullptr;

  int result = decode_jpeg(&jpeg_buffer[0], jpeg_buffer.size(), &new_buffer, &new_width, &new_height, &out_msg);

  ASSERT_EQ(55, result);
  ASSERT_TRUE(out_msg != nullptr);
  ASSERT_TRUE(new_buffer == nullptr);

  free(new_buffer);
  free(out_msg);
}<|endoftext|>


<commit_before>#include <QtCore/QDir>
#include <QtGui/QPainter>
#include "window.hpp"

#define CONVERT_X(x) (x1 + ((x * scale + 1) / 2) * (x2 - x1))
#define CONVERT_Y(y) (y1 + ((y * scale + 1) / 2) * (y2 - y1))
#define CONVERT(point) CONVERT_X(point.x()), CONVERT_Y(point.y())
#define CONVERTBACK_X(x) ((qreal(x - x1) * 2 / (x2 - x1) - 1) / scale)
#define CONVERTBACK_Y(y) ((qreal(y - y1) * 2 / (y2 - y1) - 1) / scale)
#define DEFINE_RECT QRect rectangle = rect(); \
	int x1 = rectangle.topLeft().x(); \
	int x2 = rectangle.topRight().x(); \
	int y1 = rectangle.bottomLeft().y(); \
	int y2 = rectangle.topLeft().y()
#define POINTS 5

MyMainWindow::MyMainWindow(PolynomSystem *system):
	drawArea(system, this),
	toolBar("Toolbar", this),
	drawMeshAction(tr("Draw Mesh"), this),
	fileActionGroup(this),
	paramSlider(Qt::Horizontal, this)
{
	resize(1000, 800);
	setCentralWidget(&drawArea);
	addToolBar(&toolBar);
	setWindowTitle(tr("Differential equations"));

	QStringList nameFilters, files;
	nameFilters << "sys*.txt";
	files = QDir().entryList(nameFilters,
		QDir::Files | QDir::Readable);
	for (int i = 0; i < files.size(); ++i) {
		QAction *action = fileActionGroup.addAction(files.at(i));
		action->setCheckable(true);
		toolBar.addAction(action);
		if (!i) {
			action->setChecked(true);
			drawArea.loadFile(action);
		}
	}
	connect(&fileActionGroup, SIGNAL(triggered(QAction*)),
		&drawArea, SLOT(loadFile(QAction*)));
	paramSlider.setTickInterval(50);
	paramSlider.setTickPosition(QSlider::TicksBothSides);
	paramSlider.setRange(0, 300);
	paramSlider.setValue(150);
	connect(&paramSlider, SIGNAL(valueChanged(int)),
		&drawArea, SLOT(updateParam(int)));
	precisionBox.addItem("0.1", 0.1);
	precisionBox.addItem("0.05", 0.05);
	precisionBox.addItem("0.01", 0.01);
	precisionBox.addItem("0.005", 0.005);
	precisionBox.addItem("0.001", 0.001);
	precisionBox.setCurrentIndex(1); // 0.05
	connect(&precisionBox, SIGNAL(currentIndexChanged(int)),
		&drawArea, SLOT(updatePrecision(int)));

	drawMeshAction.setCheckable(true);
	toolBar.addSeparator();
	toolBar.addAction(&drawMeshAction);
	connect(&drawMeshAction, SIGNAL(triggered(bool)),
		&drawArea, SLOT(drawMesh(bool)));
	toolBar.addSeparator();
	toolBar.addWidget(&paramSlider);
	toolBar.addSeparator();
	toolBar.addWidget(&precisionBox);
}

DrawArea::DrawArea(PolynomSystem *system, QWidget *parent):
	QWidget(parent),
	scale(.2),
	param(1),
	precision(0.05),
	stPoint(0),
	period(0),
	doDrawMesh(false),
	startPoint(2, 0),
	system(system)
{}

void DrawArea::loadFile(QAction *action) {
	fileName = action->text();
	updateSystem();
}

void DrawArea::updateParam(int sliderParam) {
	param = sliderParam * .02 - 2;
	updateSystem();
}

void DrawArea::updatePrecision(int index) {
	QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
	precision = comboBox->itemData(index).toDouble();
	stPoint = system->findPoincareStaticPoint(.1, 5, precision);
	repaint();
}

void DrawArea::updateSystem() {
	fillSystem(fileName, *system, param);
	PointType pointType = system->getPointType();
	pointTypeName = getPointTypeName(pointType);
	stPoint = system->findPoincareStaticPoint(.1, 5, precision);
	period = stPoint ? system->getPeriod(stPoint, precision) : 0;
	repaint();
}

QString DrawArea::getPointTypeName(PointType type) {
	switch(type) {
		case PointCenter:        return tr("Center");
		case PointFocusStable:   return tr("Stable focus");
		case PointFocusUnstable: return tr("Unstable focus");
		case PointKnotStable:    return tr("Stable knot");
		case PointKnotUnstable:  return tr("Unstable knot");
		case PointKnotSingularStable:   return tr("Stable singular knot");
		case PointKnotSingularUnstable: return tr("Unstable singular knot");
		case PointSaddle:        return tr("Saddle");
	}
	return QString();
}

void DrawArea::drawMesh(bool yes) {
	doDrawMesh = yes;
	repaint();
}

void DrawArea::paintEvent(QPaintEvent *event) {
	QWidget::paintEvent(event);
	drawAxes(5);
	if (qAbs(stPoint) > precision) {
		drawPath(QPointF(stPoint, 0), stPoint);
	}
	if (doDrawMesh) {
		for (int i = 0; i <= POINTS; ++i) {
			qreal newx = (1 - 2. * i / POINTS) / scale;
			drawPath(QPointF(newx, -1. / scale), stPoint);
			drawPath(QPointF(newx, -1. / scale), stPoint, Qt::black, true);
			drawPath(QPointF(newx, 1. / scale), stPoint);
			drawPath(QPointF(newx, 1. / scale), stPoint, Qt::black, true);
		}
	} else {
		drawPath(startPoint, stPoint, Qt::lightGray, true);
		drawPath(startPoint, stPoint);
	}
	QString statusText = tr("Parameter: %1;  Point type: %2;  Scale: %3").arg(
		QString::number(param, 'f', 2),
		pointTypeName, QString::number(scale * 5, 'g', 3));
	QPainter(this).drawText(10, height() - 10, statusText);
	if (period) {
		QPainter(this).drawText(10, height() - 25,
			tr("Period: %1").arg(period));
	}
}

void DrawArea::wheelEvent(QWheelEvent *event) {
	int delta = event->delta();
	qreal newScale = scale * qExp(qreal(delta) / 2048);
	if (newScale > 0.08 && newScale < 30) {
		scale = newScale;
		repaint();
	}
}

void DrawArea::mouseMoveEvent(QMouseEvent *event) {
	DEFINE_RECT;
	qreal x = CONVERTBACK_X(event->x());
	qreal y = CONVERTBACK_Y(event->y());
	startPoint = QPointF(x, y);
	repaint();
}

void DrawArea::mouseReleaseEvent(QMouseEvent *event) {
	mouseMoveEvent(event);
}

void DrawArea::drawAxes(qreal ticksize) {
	DEFINE_RECT;
	QPainter painter(this);
	painter.setPen(Qt::lightGray);
	qreal newx = 0, startx = (x1 + x2) / 2, starty = (y1 + y2) / 2;
	painter.drawLine(startx, y1, startx, y2);
	painter.drawLine(x1, starty, x2, starty);
	for (int x = 0; startx+newx < x2; ++x) {
		newx = x * scale * (x2 - x1) / 2;
		painter.drawLine(startx+newx, starty-ticksize, startx+newx, starty+ticksize);
		painter.drawLine(startx-newx, starty-ticksize, startx-newx, starty+ticksize);
	}
	qreal newy = 0;
	for (int y = 0; starty+newy < y1; ++y) {
		newy = y * scale * (y1 - y2) / 2;
		painter.drawLine(startx-ticksize, starty+newy, startx+ticksize, starty+newy);
		painter.drawLine(startx-ticksize, starty-newy, startx+ticksize, starty-newy);
	}
}

void DrawArea::drawPath(QPointF start, qreal stPoint, QColor color, bool backwards) {
	DEFINE_RECT;
	QPainter painter(this);
	painter.setPen(color);
	painter.setRenderHint(QPainter::Antialiasing);
	QPointF point;
	qreal eps = backwards ? -precision : precision;
	qreal xdiff = !start.isNull();
	quint32 step = 0;
	while (step < 5 || (qAbs(xdiff) > 1e-4 && step < 50. / precision)) {
		point = system->getNextValue(start, eps);
		painter.drawLine(CONVERT(start), CONVERT(point));
		if (qAbs(point.y()) < qAbs(eps) && point.x() > 0 && stPoint > 0) {
			xdiff = point.x() - stPoint;
		}
		start = point;
		++step;
	}
}
<commit_msg>Set default precision to 0.01<commit_after>#include <QtCore/QDir>
#include <QtGui/QPainter>
#include "window.hpp"

#define CONVERT_X(x) (x1 + ((x * scale + 1) / 2) * (x2 - x1))
#define CONVERT_Y(y) (y1 + ((y * scale + 1) / 2) * (y2 - y1))
#define CONVERT(point) CONVERT_X(point.x()), CONVERT_Y(point.y())
#define CONVERTBACK_X(x) ((qreal(x - x1) * 2 / (x2 - x1) - 1) / scale)
#define CONVERTBACK_Y(y) ((qreal(y - y1) * 2 / (y2 - y1) - 1) / scale)
#define DEFINE_RECT QRect rectangle = rect(); \
	int x1 = rectangle.topLeft().x(); \
	int x2 = rectangle.topRight().x(); \
	int y1 = rectangle.bottomLeft().y(); \
	int y2 = rectangle.topLeft().y()
#define POINTS 5

MyMainWindow::MyMainWindow(PolynomSystem *system):
	drawArea(system, this),
	toolBar("Toolbar", this),
	drawMeshAction(tr("Draw Mesh"), this),
	fileActionGroup(this),
	paramSlider(Qt::Horizontal, this)
{
	resize(1000, 800);
	setCentralWidget(&drawArea);
	addToolBar(&toolBar);
	setWindowTitle(tr("Differential equations"));

	QStringList nameFilters, files;
	nameFilters << "sys*.txt";
	files = QDir().entryList(nameFilters,
		QDir::Files | QDir::Readable);
	for (int i = 0; i < files.size(); ++i) {
		QAction *action = fileActionGroup.addAction(files.at(i));
		action->setCheckable(true);
		toolBar.addAction(action);
		if (!i) {
			action->setChecked(true);
			drawArea.loadFile(action);
		}
	}
	connect(&fileActionGroup, SIGNAL(triggered(QAction*)),
		&drawArea, SLOT(loadFile(QAction*)));
	paramSlider.setTickInterval(50);
	paramSlider.setTickPosition(QSlider::TicksBothSides);
	paramSlider.setRange(0, 300);
	paramSlider.setValue(150);
	connect(&paramSlider, SIGNAL(valueChanged(int)),
		&drawArea, SLOT(updateParam(int)));
	precisionBox.addItem("0.1", 0.1);
	precisionBox.addItem("0.05", 0.05);
	precisionBox.addItem("0.01", 0.01);
	precisionBox.addItem("0.005", 0.005);
	precisionBox.addItem("0.001", 0.001);
	precisionBox.setCurrentIndex(2); // 0.01
	connect(&precisionBox, SIGNAL(currentIndexChanged(int)),
		&drawArea, SLOT(updatePrecision(int)));

	drawMeshAction.setCheckable(true);
	toolBar.addSeparator();
	toolBar.addAction(&drawMeshAction);
	connect(&drawMeshAction, SIGNAL(triggered(bool)),
		&drawArea, SLOT(drawMesh(bool)));
	toolBar.addSeparator();
	toolBar.addWidget(&paramSlider);
	toolBar.addSeparator();
	toolBar.addWidget(&precisionBox);
}

DrawArea::DrawArea(PolynomSystem *system, QWidget *parent):
	QWidget(parent),
	scale(.2),
	param(1),
	precision(0.05),
	stPoint(0),
	period(0),
	doDrawMesh(false),
	startPoint(2, 0),
	system(system)
{}

void DrawArea::loadFile(QAction *action) {
	fileName = action->text();
	updateSystem();
}

void DrawArea::updateParam(int sliderParam) {
	param = sliderParam * .02 - 2;
	updateSystem();
}

void DrawArea::updatePrecision(int index) {
	QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
	precision = comboBox->itemData(index).toDouble();
	stPoint = system->findPoincareStaticPoint(.1, 5, precision);
	repaint();
}

void DrawArea::updateSystem() {
	fillSystem(fileName, *system, param);
	PointType pointType = system->getPointType();
	pointTypeName = getPointTypeName(pointType);
	stPoint = system->findPoincareStaticPoint(.1, 5, precision);
	period = stPoint ? system->getPeriod(stPoint, precision) : 0;
	repaint();
}

QString DrawArea::getPointTypeName(PointType type) {
	switch(type) {
		case PointCenter:        return tr("Center");
		case PointFocusStable:   return tr("Stable focus");
		case PointFocusUnstable: return tr("Unstable focus");
		case PointKnotStable:    return tr("Stable knot");
		case PointKnotUnstable:  return tr("Unstable knot");
		case PointKnotSingularStable:   return tr("Stable singular knot");
		case PointKnotSingularUnstable: return tr("Unstable singular knot");
		case PointSaddle:        return tr("Saddle");
	}
	return QString();
}

void DrawArea::drawMesh(bool yes) {
	doDrawMesh = yes;
	repaint();
}

void DrawArea::paintEvent(QPaintEvent *event) {
	QWidget::paintEvent(event);
	drawAxes(5);
	if (qAbs(stPoint) > precision) {
		drawPath(QPointF(stPoint, 0), stPoint);
	}
	if (doDrawMesh) {
		for (int i = 0; i <= POINTS; ++i) {
			qreal newx = (1 - 2. * i / POINTS) / scale;
			drawPath(QPointF(newx, -1. / scale), stPoint);
			drawPath(QPointF(newx, -1. / scale), stPoint, Qt::black, true);
			drawPath(QPointF(newx, 1. / scale), stPoint);
			drawPath(QPointF(newx, 1. / scale), stPoint, Qt::black, true);
		}
	} else {
		drawPath(startPoint, stPoint, Qt::lightGray, true);
		drawPath(startPoint, stPoint);
	}
	QString statusText = tr("Parameter: %1;  Point type: %2;  Scale: %3").arg(
		QString::number(param, 'f', 2),
		pointTypeName, QString::number(scale * 5, 'g', 3));
	QPainter(this).drawText(10, height() - 10, statusText);
	if (period) {
		QPainter(this).drawText(10, height() - 25,
			tr("Period: %1").arg(period));
	}
}

void DrawArea::wheelEvent(QWheelEvent *event) {
	int delta = event->delta();
	qreal newScale = scale * qExp(qreal(delta) / 2048);
	if (newScale > 0.08 && newScale < 30) {
		scale = newScale;
		repaint();
	}
}

void DrawArea::mouseMoveEvent(QMouseEvent *event) {
	DEFINE_RECT;
	qreal x = CONVERTBACK_X(event->x());
	qreal y = CONVERTBACK_Y(event->y());
	startPoint = QPointF(x, y);
	repaint();
}

void DrawArea::mouseReleaseEvent(QMouseEvent *event) {
	mouseMoveEvent(event);
}

void DrawArea::drawAxes(qreal ticksize) {
	DEFINE_RECT;
	QPainter painter(this);
	painter.setPen(Qt::lightGray);
	qreal newx = 0, startx = (x1 + x2) / 2, starty = (y1 + y2) / 2;
	painter.drawLine(startx, y1, startx, y2);
	painter.drawLine(x1, starty, x2, starty);
	for (int x = 0; startx+newx < x2; ++x) {
		newx = x * scale * (x2 - x1) / 2;
		painter.drawLine(startx+newx, starty-ticksize, startx+newx, starty+ticksize);
		painter.drawLine(startx-newx, starty-ticksize, startx-newx, starty+ticksize);
	}
	qreal newy = 0;
	for (int y = 0; starty+newy < y1; ++y) {
		newy = y * scale * (y1 - y2) / 2;
		painter.drawLine(startx-ticksize, starty+newy, startx+ticksize, starty+newy);
		painter.drawLine(startx-ticksize, starty-newy, startx+ticksize, starty-newy);
	}
}

void DrawArea::drawPath(QPointF start, qreal stPoint, QColor color, bool backwards) {
	DEFINE_RECT;
	QPainter painter(this);
	painter.setPen(color);
	painter.setRenderHint(QPainter::Antialiasing);
	QPointF point;
	qreal eps = backwards ? -precision : precision;
	qreal xdiff = !start.isNull();
	quint32 step = 0;
	while (step < 5 || (qAbs(xdiff) > 1e-4 && step < 50. / precision)) {
		point = system->getNextValue(start, eps);
		painter.drawLine(CONVERT(start), CONVERT(point));
		if (qAbs(point.y()) < qAbs(eps) && point.x() > 0 && stPoint > 0) {
			xdiff = point.x() - stPoint;
		}
		start = point;
		++step;
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
/*
 * Note - used PUBLIC DOMAIN http://sourceforge.net/projects/libb64/files/libb64/libb64/libb64-1.2.src.zip/download
 * code as a starting point.
 */
#include    "../StroikaPreComp.h"

#include    <algorithm>
#include    <cstdlib>

#include    "../Containers/Common.h"
#include    "../DataExchangeFormat/BadFormatException.h"
#include    "../Debug/Assertions.h"
#include    "../Execution/Exceptions.h"
#include    "../Memory/BLOB.h"              // ONLY FOR QUICKHACK IMPL OF ENCODE...
#include    "../Memory/SmallStackBuffer.h"

#include    "Base64.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Cryptography;
using   namespace   Stroika::Foundation::Memory;

/*
 *  IMPLEMENTATION NOTES:
 *
 *      The public domain (private) code in this file - is designed to operate in a STREAM mode. I've preserved that
 *  internally, evne though my current API doesnt work that way, because we will soon support a STREAM based API here,
 *  and that will fit perfectly.
 *
 *      See also http://libb64.sourceforge.net/ - which explains the design of the routines, and the queer nested loop / switch
 * construct.
 *
 *      -- LGP 2011-06-21
 */

/*
 ********************************************************************************
 *************************** Encoding::DecodeBase64 *****************************
 ********************************************************************************
 */
namespace   {
    enum base64_decodestep_ {
        step_a, step_b, step_c, step_d
    };
    struct base64_decodestate_ {
        base64_decodestep_  step;
        Byte                plainchar;

        base64_decodestate_ ()
            : step (step_a)
            , plainchar ('\0') {
        }
    };
    int base64_decode_value_ (signed char value_in)
    {
        static const signed char kDecoding[] = {62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
        value_in -= 43;
        if (value_in < 0 || value_in >= NEltsOf (kDecoding)) {
            return -1;
        }
        Assert (0 <= value_in and value_in < NEltsOf (kDecoding));
        return kDecoding[(int)value_in];
    }
    size_t base64_decode_block_ (const char* code_in, size_t length_in, Byte* plaintext_out, base64_decodestate_* state)
    {
        RequireNotNull (code_in);
        RequireNotNull (plaintext_out);

        const char* codechar    =   code_in;
        Byte*       plainchar   =   plaintext_out;
        char        fragment    =   '\0';

        *plainchar = state->plainchar;

        switch (state->step) {
                while (1) {
                case step_a:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_a;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar    = (fragment & 0x03f) << 2;
                case step_b:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_b;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar++ |= (fragment & 0x030) >> 4;
                    *plainchar    = (fragment & 0x00f) << 4;
                case step_c:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_c;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar++ |= (fragment & 0x03c) >> 2;
                    *plainchar    = (fragment & 0x003) << 6;
                case step_d:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_d;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar++   |= (fragment & 0x03f);
                }
        }
        return plainchar - plaintext_out;
    }
}

Memory::BLOB    Cryptography::DecodeBase64 (const string& s)
{
    if (s.empty ()) {
        return Memory::BLOB ();
    }
    size_t dataSize1 = s.length ();
    SmallStackBuffer<Byte>  buf1 (dataSize1);   // MUCH more than big enuf
    base64_decodestate_ state;
    size_t r = base64_decode_block_ (Containers::Start (s), s.length (), buf1.begin (), &state);
    Assert (r <= dataSize1);
    return Memory::BLOB (buf1.begin (), buf1.begin () + r);
}

void    Cryptography::DecodeBase64 (const string& s, Streams::BinaryOutputStream out)
{
    // QUICKIE implementation...
    Memory::BLOB   tmp = DecodeBase64 (s);
    out.Write (tmp.begin (), tmp.end ());
}

/*
 ********************************************************************************
 *********************** Cryptography::EncodeBase64 *****************************
 ********************************************************************************
 */
namespace   {
    enum base64_encodestep {
        step_A, step_B, step_C
    };
    struct base64_encodestate {
        base64_encodestep   step;
        char                result;
        int                 stepcount;
        LineBreak           fLineBreak;

        base64_encodestate  (LineBreak lb)
            : step (step_A)
            , result (0)
            , stepcount (0)
            , fLineBreak (lb) {
        }
    };

    char base64_encode_value_ (char value_in)
    {
        const char  BASE64_CHARS_[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        Assert  (NEltsOf (BASE64_CHARS_) == (2 * 26 + 10 + 2 + 1));
        if (value_in > 63) {
            return '=';
        }
        return BASE64_CHARS_[(int)value_in];
    }

    size_t base64_encode_block_ (const Byte* plaintext_in, size_t length_in, char* code_out, base64_encodestate* state)
    {
        const int CHARS_PER_LINE = 76;

        const Byte*         plainchar       =   plaintext_in;
        const Byte* const   plaintextend    =   plaintext_in + length_in;
        char*               codechar        =   code_out;
        char                result          =   state->result;

        char fragment   =   '\0';
        switch (state->step) {
                while (1) {
                case step_A:
                    if (plainchar == plaintextend) {
                        state->result = result;
                        state->step = step_A;
                        return codechar - code_out;
                    }
                    fragment = *plainchar++;
                    result = (fragment & 0x0fc) >> 2;
                    *codechar++ = base64_encode_value_ (result);
                    result = (fragment & 0x003) << 4;
                case step_B:
                    if (plainchar == plaintextend) {
                        state->result = result;
                        state->step = step_B;
                        return codechar - code_out;
                    }
                    fragment = *plainchar++;
                    result |= (fragment & 0x0f0) >> 4;
                    *codechar++ = base64_encode_value_ (result);
                    result = (fragment & 0x00f) << 2;
                case step_C:
                    if (plainchar == plaintextend) {
                        state->result = result;
                        state->step = step_C;
                        return codechar - code_out;
                    }
                    fragment = *plainchar++;
                    result |= (fragment & 0x0c0) >> 6;
                    *codechar++ = base64_encode_value_ (result);
                    result  = (fragment & 0x03f) >> 0;
                    *codechar++ = base64_encode_value_ (result);

                    ++(state->stepcount);
                    if (state->stepcount == CHARS_PER_LINE / 4) {
                        switch (state->fLineBreak) {
                            case    LineBreak::eLF_LB:
                                *codechar++ = '\n';
                                break;
                            case    LineBreak::eCRLF_LB:
                                *codechar++ = '\r';
                                *codechar++ = '\n';
                                break;
                        }
                        state->stepcount = 0;
                    }
                }
        }
        return codechar - code_out;
    }
    inline  size_t  base64_encode_blockend_ (char* code_out, base64_encodestate* state)
    {
        char* codechar = code_out;
        switch (state->step) {
            case step_B:
                *codechar++ = base64_encode_value_ (state->result);
                *codechar++ = '=';
                *codechar++ = '=';
                break;
            case step_C:
                *codechar++ = base64_encode_value_ (state->result);
                *codechar++ = '=';
                break;
            case step_A:
                break;
        }
        return static_cast<size_t> (codechar - code_out);
    }
}

string  Cryptography::EncodeBase64 (const Streams::BinaryInputStream& from, LineBreak lb)
{
#if 0
    // Use look doing multiple base64_encode_block_() calls!
#elif 1
    // quick hack impl
    Memory::BLOB    bytes = Streams::BinaryInputStream (from).ReadAll ();
    const Byte* start = bytes.begin ();
    const Byte* end = bytes.end ();
    Require (start == end or start != nullptr);
    Require (start == end or end != nullptr);
    base64_encodestate state (lb);
    size_t srcLen = end - start;
    size_t bufSize = 4 * srcLen;
    Assert (bufSize >= srcLen);  // no overflow!
    SmallStackBuffer<char>  data (bufSize);
    size_t mostBytesCopied =     base64_encode_block_ (start, srcLen, data.begin (), &state);
    size_t extraBytes = base64_encode_blockend_ (data.begin () + mostBytesCopied, &state);
    size_t totalBytes = mostBytesCopied + extraBytes;
    Assert (totalBytes <= bufSize);
    return string (data.begin (), data.begin () + totalBytes);
#else
    Require (start == end or start != nullptr);
    Require (start == end or end != nullptr);

    base64_encodestate state (lb);
    size_t srcLen = end - start;
    size_t bufSize = 4 * srcLen;
    Assert (bufSize >= srcLen);  // no overflow!
    SmallStackBuffer<char>  data (bufSize);
    size_t mostBytesCopied =     base64_encode_block_ (start, srcLen, data.begin (), &state);
    size_t extraBytes = base64_encode_blockend_ (data.begin () + mostBytesCopied, &state);
    size_t totalBytes = mostBytesCopied + extraBytes;
    Assert (totalBytes <= bufSize);
    return string (data.begin (), data.begin () + totalBytes);
#endif
}
<commit_msg>more tweaks to base64 encode/decode stuff for explicitly signed char (arm)<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
/*
 * Note - used PUBLIC DOMAIN http://sourceforge.net/projects/libb64/files/libb64/libb64/libb64-1.2.src.zip/download
 * code as a starting point.
 */
#include    "../StroikaPreComp.h"

#include    <algorithm>
#include    <cstdlib>

#include    "../Containers/Common.h"
#include    "../DataExchangeFormat/BadFormatException.h"
#include    "../Debug/Assertions.h"
#include    "../Execution/Exceptions.h"
#include    "../Memory/BLOB.h"              // ONLY FOR QUICKHACK IMPL OF ENCODE...
#include    "../Memory/SmallStackBuffer.h"

#include    "Base64.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::Cryptography;
using   namespace   Stroika::Foundation::Memory;

/*
 *  IMPLEMENTATION NOTES:
 *
 *      The public domain (private) code in this file - is designed to operate in a STREAM mode. I've preserved that
 *  internally, evne though my current API doesnt work that way, because we will soon support a STREAM based API here,
 *  and that will fit perfectly.
 *
 *      See also http://libb64.sourceforge.net/ - which explains the design of the routines, and the queer nested loop / switch
 * construct.
 *
 *      -- LGP 2011-06-21
 */

/*
 ********************************************************************************
 *************************** Encoding::DecodeBase64 *****************************
 ********************************************************************************
 */
namespace   {
    enum base64_decodestep_ {
        step_a, step_b, step_c, step_d
    };
    struct base64_decodestate_ {
        base64_decodestep_  step;
        Byte                plainchar;

        base64_decodestate_ ()
            : step (step_a)
            , plainchar ('\0') {
        }
    };
    int base64_decode_value_ (signed char value_in)
    {
        static const signed char kDecoding[] = {62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
        value_in -= 43;
        if (value_in < 0 || value_in >= NEltsOf (kDecoding)) {
            return -1;
        }
        Assert (0 <= value_in and value_in < NEltsOf (kDecoding));
        return kDecoding[(int)value_in];
    }
    size_t base64_decode_block_ (const signed char* code_in, size_t length_in, Byte* plaintext_out, base64_decodestate_* state)
    {
        RequireNotNull (code_in);
        RequireNotNull (plaintext_out);

        const signed char*  codechar    =   code_in;
        Byte*               plainchar   =   plaintext_out;
        signed char         fragment    =   '\0';

        *plainchar = state->plainchar;

        switch (state->step) {
                while (1) {
                case step_a:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_a;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (signed char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar    = (fragment & 0x03f) << 2;
                case step_b:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_b;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (signed char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar++ |= (fragment & 0x030) >> 4;
                    *plainchar    = (fragment & 0x00f) << 4;
                case step_c:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_c;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (signed char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar++ |= (fragment & 0x03c) >> 2;
                    *plainchar    = (fragment & 0x003) << 6;
                case step_d:
                    do {
                        if (codechar == code_in + length_in) {
                            state->step = step_d;
                            state->plainchar = *plainchar;
                            return plainchar - plaintext_out;
                        }
                        fragment = (signed char)base64_decode_value_ (*codechar++);
                    }
                    while (fragment < 0);
                    *plainchar++   |= (fragment & 0x03f);
                }
        }
        return plainchar - plaintext_out;
    }
}

Memory::BLOB    Cryptography::DecodeBase64 (const string& s)
{
    if (s.empty ()) {
        return Memory::BLOB ();
    }
    size_t dataSize1 = s.length ();
    SmallStackBuffer<Byte>  buf1 (dataSize1);   // MUCH more than big enuf
    base64_decodestate_ state;
    size_t r = base64_decode_block_ (reinterpret_cast<const signed char*> (Containers::Start (s)), s.length (), buf1.begin (), &state);
    Assert (r <= dataSize1);
    return Memory::BLOB (buf1.begin (), buf1.begin () + r);
}

void    Cryptography::DecodeBase64 (const string& s, Streams::BinaryOutputStream out)
{
    // QUICKIE implementation...
    Memory::BLOB   tmp = DecodeBase64 (s);
    out.Write (tmp.begin (), tmp.end ());
}

/*
 ********************************************************************************
 *********************** Cryptography::EncodeBase64 *****************************
 ********************************************************************************
 */
namespace   {
    enum base64_encodestep {
        step_A, step_B, step_C
    };
    struct base64_encodestate {
        base64_encodestep   step;
        signed char         result;
        int                 stepcount;
        LineBreak           fLineBreak;

        base64_encodestate  (LineBreak lb)
            : step (step_A)
            , result (0)
            , stepcount (0)
            , fLineBreak (lb) {
        }
    };

    signed char base64_encode_value_ (signed char value_in)
    {
        const signed char  BASE64_CHARS_[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        Assert  (NEltsOf (BASE64_CHARS_) == (2 * 26 + 10 + 2 + 1));
        if (value_in > 63) {
            return '=';
        }
        return BASE64_CHARS_[(int)value_in];
    }

    size_t base64_encode_block_ (const Byte* plaintext_in, size_t length_in, signed char* code_out, base64_encodestate* state)
    {
        const int CHARS_PER_LINE = 76;

        const Byte*         plainchar       =   plaintext_in;
        const Byte* const   plaintextend    =   plaintext_in + length_in;
        signed char*        codechar        =   code_out;
        signed char         result          =   state->result;

        signed char fragment   =   '\0';
        switch (state->step) {
                while (1) {
                case step_A:
                    if (plainchar == plaintextend) {
                        state->result = result;
                        state->step = step_A;
                        return codechar - code_out;
                    }
                    fragment = *plainchar++;
                    result = (fragment & 0x0fc) >> 2;
                    *codechar++ = base64_encode_value_ (result);
                    result = (fragment & 0x003) << 4;
                case step_B:
                    if (plainchar == plaintextend) {
                        state->result = result;
                        state->step = step_B;
                        return codechar - code_out;
                    }
                    fragment = *plainchar++;
                    result |= (fragment & 0x0f0) >> 4;
                    *codechar++ = base64_encode_value_ (result);
                    result = (fragment & 0x00f) << 2;
                case step_C:
                    if (plainchar == plaintextend) {
                        state->result = result;
                        state->step = step_C;
                        return codechar - code_out;
                    }
                    fragment = *plainchar++;
                    result |= (fragment & 0x0c0) >> 6;
                    *codechar++ = base64_encode_value_ (result);
                    result  = (fragment & 0x03f) >> 0;
                    *codechar++ = base64_encode_value_ (result);

                    ++(state->stepcount);
                    if (state->stepcount == CHARS_PER_LINE / 4) {
                        switch (state->fLineBreak) {
                            case    LineBreak::eLF_LB:
                                *codechar++ = '\n';
                                break;
                            case    LineBreak::eCRLF_LB:
                                *codechar++ = '\r';
                                *codechar++ = '\n';
                                break;
                        }
                        state->stepcount = 0;
                    }
                }
        }
        return codechar - code_out;
    }
    inline  size_t  base64_encode_blockend_ (signed char* code_out, base64_encodestate* state)
    {
        signed char* codechar = code_out;
        switch (state->step) {
            case step_B:
                *codechar++ = base64_encode_value_ (state->result);
                *codechar++ = '=';
                *codechar++ = '=';
                break;
            case step_C:
                *codechar++ = base64_encode_value_ (state->result);
                *codechar++ = '=';
                break;
            case step_A:
                break;
        }
        return static_cast<size_t> (codechar - code_out);
    }
}

string  Cryptography::EncodeBase64 (const Streams::BinaryInputStream& from, LineBreak lb)
{
#if 0
    // Use look doing multiple base64_encode_block_() calls!
#elif 1
    // quick hack impl
    Memory::BLOB    bytes = Streams::BinaryInputStream (from).ReadAll ();
    const Byte* start = bytes.begin ();
    const Byte* end = bytes.end ();
    Require (start == end or start != nullptr);
    Require (start == end or end != nullptr);
    base64_encodestate state (lb);
    size_t srcLen = end - start;
    size_t bufSize = 4 * srcLen;
    Assert (bufSize >= srcLen);  // no overflow!
    SmallStackBuffer<signed char>  data (bufSize);
    size_t mostBytesCopied =     base64_encode_block_ (start, srcLen, data.begin (), &state);
    size_t extraBytes = base64_encode_blockend_ (data.begin () + mostBytesCopied, &state);
    size_t totalBytes = mostBytesCopied + extraBytes;
    Assert (totalBytes <= bufSize);
    return string (data.begin (), data.begin () + totalBytes);
#else
    Require (start == end or start != nullptr);
    Require (start == end or end != nullptr);

    base64_encodestate state (lb);
    size_t srcLen = end - start;
    size_t bufSize = 4 * srcLen;
    Assert (bufSize >= srcLen);  // no overflow!
    SmallStackBuffer<char>  data (bufSize);
    size_t mostBytesCopied =     base64_encode_block_ (start, srcLen, data.begin (), &state);
    size_t extraBytes = base64_encode_blockend_ (data.begin () + mostBytesCopied, &state);
    size_t totalBytes = mostBytesCopied + extraBytes;
    Assert (totalBytes <= bufSize);
    return string (data.begin (), data.begin () + totalBytes);
#endif
}
<|endoftext|>


<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "clustering/administration/issues/name_collision.hpp"
#include "clustering/administration/datum_adapter.hpp"
#include "rdb_protocol/configured_limits.hpp"

const datum_string_t server_name_collision_issue_t::server_name_collision_issue_type =
    datum_string_t("server_name_collision");
const uuid_u server_name_collision_issue_t::base_issue_id =
    str_to_uuid("a8bf71c6-a178-43ea-b25d-73a13619c8f0");

const datum_string_t db_name_collision_issue_t::db_name_collision_issue_type =
    datum_string_t("db_name_collision");
const uuid_u db_name_collision_issue_t::base_issue_id =
    str_to_uuid("a6996d3c-418d-4ab1-85b5-455dcd8721d8");

const datum_string_t table_name_collision_issue_t::table_name_collision_issue_type =
    datum_string_t("table_name_collision");
const uuid_u table_name_collision_issue_t::base_issue_id =
    str_to_uuid("d610286a-a374-49e6-8d92-032794ed578f");

name_collision_issue_t::name_collision_issue_t(const issue_id_t &_issue_id,
                                               const name_string_t &_name,
                                               const std::vector<uuid_u> &_collided_ids) :
    issue_t(_issue_id),
    name(_name),
    collided_ids(_collided_ids) { }

void build_info_and_description(
        const std::string &type,
        const name_string_t &name,
        const std::vector<uuid_u> &ids,
        ql::datum_t *info_out,
        datum_string_t *description_out) {
    ql::datum_object_builder_t builder;
    ql::datum_array_builder_t ids_builder(ql::configured_limits_t::unlimited);
    std::string ids_str;
    for (auto const &id : ids) {
        ids_builder.add(convert_uuid_to_datum(id));
        if (!ids_str.empty()) {
            ids_str += ", ";
        }
        ids_str += uuid_to_str(id);
    }
    builder.overwrite("name", convert_name_to_datum(name));
    builder.overwrite("ids", std::move(ids_builder).to_datum());
    *info_out = std::move(builder).to_datum();
    *description_out = datum_string_t(strprintf(
        "The following %s are all named '%s': %s.",
        type.c_str(), name.c_str(), ids_str.c_str()));
}

server_name_collision_issue_t::server_name_collision_issue_t(
        const name_string_t &_name,
        const std::vector<server_id_t> &_collided_ids) :
    name_collision_issue_t(from_hash(base_issue_id, _name),
                          _name,
                          _collided_ids) { }

bool server_name_collision_issue_t::build_info_and_description(
        UNUSED const metadata_t &metadata,
        UNUSED server_name_client_t *name_client,
        UNUSED admin_identifier_format_t identifier_format,
        ql::datum_t *info_out,
        datum_string_t *description_out) const {
    build_info_and_description(
        "servers", name, collided_ids, info_out, description_out);
    return true;
}

db_name_collision_issue_t::db_name_collision_issue_t(
        const name_string_t &_name,
        const std::vector<database_id_t> &_collided_ids) :
    name_collision_issue_t(from_hash(base_issue_id, _name),
                          _name,
                          _collided_ids) { }

bool db_name_collision_issue_t::build_info_and_description(
        UNUSED const metadata_t &metadata,
        UNUSED server_name_client_t *name_client,
        UNUSED admin_identifier_format_t identifier_format,
        ql::datum_t *info_out,
        datum_string_t *description_out) const {
    build_info_and_description(
        "databases", name, collided_ids, info_out, description_out);
    return true;
}

table_name_collision_issue_t::table_name_collision_issue_t(
        const name_string_t &_name,
        const database_id_t &_db_id,
        const std::vector<namespace_id_t> &_collided_ids) :
    name_collision_issue_t(from_hash(base_issue_id, _db_id, _name),
                           _name,
                           _collided_ids),
    db_id(_db_id) { }

bool table_name_collision_issue_t::build_info_and_description(
        const metadata_t &metadata,
        UNUSED server_name_client_t *name_client,
        admin_identifier_format_t identifier_format,
        ql::datum_t *info_out,
        datum_string_t *description_out) const {
    ql::datum_t db_name_or_uuid;
    name_string_t db_name;
    if (!convert_database_id_to_datum(db_id, identifier_format, metadata,
            &db_name_or_uuid, &db_name)) {
        db_name_or_uuid = ql::datum_t("__deleted_database__");
        db_name = name_string_t::guarantee_valid("__deleted_database__");
    }
    ql::datum_t partial_info;
    build_info_and_description(
        strprintf("tables in database `%s`", db_name.c_str()), name, collided_ids,
        &partial_info, description_out);
    ql::datum_object_builder_t info_rebuilder(partial_info);
    info_rebuilder.overwrite("db", db_name_or_uuid);
    *info_out = std::move(info_rebuilder).to_datum();
    return true;
}

name_collision_issue_tracker_t::name_collision_issue_tracker_t(
            boost::shared_ptr<semilattice_read_view_t<cluster_semilattice_metadata_t> >
                _cluster_sl_view) :
    cluster_sl_view(_cluster_sl_view) { }

name_collision_issue_tracker_t::~name_collision_issue_tracker_t() { }

template <typename issue_type, typename map_t>
void find_duplicates(const map_t &data,
                     std::vector<scoped_ptr_t<issue_t> > *issues_out) {
    std::map<name_string_t, std::vector<uuid_u> > name_counts;
    for (auto const &it : data) {
        if (!it.second.is_deleted()) {
            name_string_t name = it.second.get_ref().name.get_ref();
            name_counts[name].push_back(it.first);
        }
    }

    for (auto const &it : name_counts) {
        if (it.second.size() > 1) {
            issues_out->push_back(scoped_ptr_t<issue_t>(
                new issue_type(it.first, it.second)));
        }
    }
}

void find_table_duplicates(
        const namespaces_semilattice_metadata_t::namespace_map_t &data,
        std::vector<scoped_ptr_t<issue_t> > *issues_out) {
    std::map<std::pair<database_id_t, name_string_t>, std::vector<namespace_id_t> >
        name_counts;
    for (auto const &it : data) {
        if (!it.second.is_deleted()) {
            std::pair<database_id_t, name_string_t> info =
                std::make_pair(it.second.get_ref().database.get_ref(),
                               it.second.get_ref().name.get_ref());
            name_counts[info].push_back(it.first);
        }
    }

    for (auto const &it : name_counts) {
        if (it.second.size() > 1) {
            issues_out->push_back(scoped_ptr_t<issue_t>(
                new table_name_collision_issue_t(it.first.second, // Table name
                                                 it.first.first,  // Database
                                                 it.second)));    // IDs of tables
        }
    }
}

std::vector<scoped_ptr_t<issue_t> > name_collision_issue_tracker_t::get_issues() const {
    cluster_semilattice_metadata_t metadata = cluster_sl_view->get();
    std::vector<scoped_ptr_t<issue_t> > issues;

    find_duplicates<server_name_collision_issue_t>(metadata.servers.servers, &issues);
    find_duplicates<db_name_collision_issue_t>(metadata.databases.databases, &issues);
    find_table_duplicates(metadata.rdb_namespaces->namespaces, &issues);

    return issues;
}
<commit_msg>Fix compilation error caused by name shadowing.<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "clustering/administration/issues/name_collision.hpp"
#include "clustering/administration/datum_adapter.hpp"
#include "rdb_protocol/configured_limits.hpp"

const datum_string_t server_name_collision_issue_t::server_name_collision_issue_type =
    datum_string_t("server_name_collision");
const uuid_u server_name_collision_issue_t::base_issue_id =
    str_to_uuid("a8bf71c6-a178-43ea-b25d-73a13619c8f0");

const datum_string_t db_name_collision_issue_t::db_name_collision_issue_type =
    datum_string_t("db_name_collision");
const uuid_u db_name_collision_issue_t::base_issue_id =
    str_to_uuid("a6996d3c-418d-4ab1-85b5-455dcd8721d8");

const datum_string_t table_name_collision_issue_t::table_name_collision_issue_type =
    datum_string_t("table_name_collision");
const uuid_u table_name_collision_issue_t::base_issue_id =
    str_to_uuid("d610286a-a374-49e6-8d92-032794ed578f");

name_collision_issue_t::name_collision_issue_t(const issue_id_t &_issue_id,
                                               const name_string_t &_name,
                                               const std::vector<uuid_u> &_collided_ids) :
    issue_t(_issue_id),
    name(_name),
    collided_ids(_collided_ids) { }

void generic_build_info_and_description(
        const std::string &type,
        const name_string_t &name,
        const std::vector<uuid_u> &ids,
        ql::datum_t *info_out,
        datum_string_t *description_out) {
    ql::datum_object_builder_t builder;
    ql::datum_array_builder_t ids_builder(ql::configured_limits_t::unlimited);
    std::string ids_str;
    for (auto const &id : ids) {
        ids_builder.add(convert_uuid_to_datum(id));
        if (!ids_str.empty()) {
            ids_str += ", ";
        }
        ids_str += uuid_to_str(id);
    }
    builder.overwrite("name", convert_name_to_datum(name));
    builder.overwrite("ids", std::move(ids_builder).to_datum());
    *info_out = std::move(builder).to_datum();
    *description_out = datum_string_t(strprintf(
        "The following %s are all named '%s': %s.",
        type.c_str(), name.c_str(), ids_str.c_str()));
}

server_name_collision_issue_t::server_name_collision_issue_t(
        const name_string_t &_name,
        const std::vector<server_id_t> &_collided_ids) :
    name_collision_issue_t(from_hash(base_issue_id, _name),
                          _name,
                          _collided_ids) { }

bool server_name_collision_issue_t::build_info_and_description(
        UNUSED const metadata_t &metadata,
        UNUSED server_name_client_t *name_client,
        UNUSED admin_identifier_format_t identifier_format,
        ql::datum_t *info_out,
        datum_string_t *description_out) const {
    generic_build_info_and_description(
        "servers", name, collided_ids, info_out, description_out);
    return true;
}

db_name_collision_issue_t::db_name_collision_issue_t(
        const name_string_t &_name,
        const std::vector<database_id_t> &_collided_ids) :
    name_collision_issue_t(from_hash(base_issue_id, _name),
                          _name,
                          _collided_ids) { }

bool db_name_collision_issue_t::build_info_and_description(
        UNUSED const metadata_t &metadata,
        UNUSED server_name_client_t *name_client,
        UNUSED admin_identifier_format_t identifier_format,
        ql::datum_t *info_out,
        datum_string_t *description_out) const {
    generic_build_info_and_description(
        "databases", name, collided_ids, info_out, description_out);
    return true;
}

table_name_collision_issue_t::table_name_collision_issue_t(
        const name_string_t &_name,
        const database_id_t &_db_id,
        const std::vector<namespace_id_t> &_collided_ids) :
    name_collision_issue_t(from_hash(base_issue_id, _db_id, _name),
                           _name,
                           _collided_ids),
    db_id(_db_id) { }

bool table_name_collision_issue_t::build_info_and_description(
        const metadata_t &metadata,
        UNUSED server_name_client_t *name_client,
        admin_identifier_format_t identifier_format,
        ql::datum_t *info_out,
        datum_string_t *description_out) const {
    ql::datum_t db_name_or_uuid;
    name_string_t db_name;
    if (!convert_database_id_to_datum(db_id, identifier_format, metadata,
            &db_name_or_uuid, &db_name)) {
        db_name_or_uuid = ql::datum_t("__deleted_database__");
        db_name = name_string_t::guarantee_valid("__deleted_database__");
    }
    ql::datum_t partial_info;
    generic_build_info_and_description(
        strprintf("tables in database `%s`", db_name.c_str()), name, collided_ids,
        &partial_info, description_out);
    ql::datum_object_builder_t info_rebuilder(partial_info);
    info_rebuilder.overwrite("db", db_name_or_uuid);
    *info_out = std::move(info_rebuilder).to_datum();
    return true;
}

name_collision_issue_tracker_t::name_collision_issue_tracker_t(
            boost::shared_ptr<semilattice_read_view_t<cluster_semilattice_metadata_t> >
                _cluster_sl_view) :
    cluster_sl_view(_cluster_sl_view) { }

name_collision_issue_tracker_t::~name_collision_issue_tracker_t() { }

template <typename issue_type, typename map_t>
void find_duplicates(const map_t &data,
                     std::vector<scoped_ptr_t<issue_t> > *issues_out) {
    std::map<name_string_t, std::vector<uuid_u> > name_counts;
    for (auto const &it : data) {
        if (!it.second.is_deleted()) {
            name_string_t name = it.second.get_ref().name.get_ref();
            name_counts[name].push_back(it.first);
        }
    }

    for (auto const &it : name_counts) {
        if (it.second.size() > 1) {
            issues_out->push_back(scoped_ptr_t<issue_t>(
                new issue_type(it.first, it.second)));
        }
    }
}

void find_table_duplicates(
        const namespaces_semilattice_metadata_t::namespace_map_t &data,
        std::vector<scoped_ptr_t<issue_t> > *issues_out) {
    std::map<std::pair<database_id_t, name_string_t>, std::vector<namespace_id_t> >
        name_counts;
    for (auto const &it : data) {
        if (!it.second.is_deleted()) {
            std::pair<database_id_t, name_string_t> info =
                std::make_pair(it.second.get_ref().database.get_ref(),
                               it.second.get_ref().name.get_ref());
            name_counts[info].push_back(it.first);
        }
    }

    for (auto const &it : name_counts) {
        if (it.second.size() > 1) {
            issues_out->push_back(scoped_ptr_t<issue_t>(
                new table_name_collision_issue_t(it.first.second, // Table name
                                                 it.first.first,  // Database
                                                 it.second)));    // IDs of tables
        }
    }
}

std::vector<scoped_ptr_t<issue_t> > name_collision_issue_tracker_t::get_issues() const {
    cluster_semilattice_metadata_t metadata = cluster_sl_view->get();
    std::vector<scoped_ptr_t<issue_t> > issues;

    find_duplicates<server_name_collision_issue_t>(metadata.servers.servers, &issues);
    find_duplicates<db_name_collision_issue_t>(metadata.databases.databases, &issues);
    find_table_duplicates(metadata.rdb_namespaces->namespaces, &issues);

    return issues;
}
<|endoftext|>