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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkGDCMSeriesFileNames.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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.

=========================================================================*/
#ifndef _itkGDCMSeriesFileNames_h
#define _itkGDCMSeriesFileNames_h

#include "itkGDCMSeriesFileNames.h"
#include "gdcm/src/gdcmSerieHelper.h"
#include "gdcm/src/gdcmFile.h"
#include "gdcm/src/gdcmUtil.h"
#include <itksys/SystemTools.hxx>

#include <vector>
#include <string>

namespace itk
{

GDCMSeriesFileNames::GDCMSeriesFileNames()
{
  m_SerieHelper = new gdcm::SerieHelper();
  m_InputDirectory = "";
  m_OutputDirectory = "";
  m_UseSeriesDetails = true;
}

GDCMSeriesFileNames::~GDCMSeriesFileNames()
{
  delete m_SerieHelper;
}

void GDCMSeriesFileNames::SetInputDirectory (std::string const &name)
{
  if ( name == "" )
    {
    itkWarningMacro( << "You need to specify a directory where "
      "the DICOM files are located");
    return;
    }
  m_InputDirectory = name;
  m_SerieHelper->SetUseSeriesDetails( m_UseSeriesDetails );
  m_SerieHelper->SetDirectory( name ); //as a side effect it also execute
  this->Modified();
}

const SerieUIDContainer &GDCMSeriesFileNames::GetSeriesUIDs()
{
  m_SeriesUIDs.clear();
  // Accessing the first serie found (assume there is at least one)
  gdcm::GdcmFileList *flist = m_SerieHelper->GetFirstCoherentFileList();
  while(flist)
    {
    if( flist->size() ) //make sure we have at leat one serie
      {
      gdcm::File *file = (*flist)[0]; //for example take the first one

      // Create its unique series ID
      std::string id = m_SerieHelper->
                       CreateUniqueSeriesIdentifier( file ).c_str();

      m_SeriesUIDs.push_back( id.c_str() );
      }
    flist = m_SerieHelper->GetNextCoherentFileList();
    }
  if( !m_SeriesUIDs.size() )
    {
    itkWarningMacro(<<"No Series were found");
    }
  return m_SeriesUIDs;
}

const FilenamesContainer &GDCMSeriesFileNames::GetFileNames(const std::string serie)
{
  m_InputFileNames.clear();
  // Accessing the first serie found (assume there is at least one)
  gdcm::GdcmFileList *flist = m_SerieHelper->GetFirstCoherentFileList();
  bool found = false;
  if( serie != "" ) // user did not specify any sub selcection based on UID
    {
    while(flist && !found)
      {
      if( flist->size() ) //make sure we have at leat one serie
        {
        gdcm::File *file = (*flist)[0]; //for example take the first one
        std::string id = m_SerieHelper->
          CreateUniqueSeriesIdentifier( file ).c_str();

        if( id == serie )
          {
          found = true; // we found a match
          break;
          }
        }
      flist = m_SerieHelper->GetNextCoherentFileList();
      }
    if( !found)
      {
      itkWarningMacro(<<"No Series were found");
      return m_InputFileNames;
      }
    }
  m_SerieHelper->OrderGdcmFileList(flist);

  gdcm::GdcmFileList::iterator it;
  if( flist->size() )
    {
    for(it = flist->begin();
        it != flist->end(); ++it )
      {
        gdcm::File * header = *it;
        if( !header )
          {
          itkWarningMacro( << "GDCMSeriesFileNames got NULL header, "
            "this is a serious bug" );
          continue;
          }
        if( !header->IsReadable() )
          {
          itkWarningMacro( << "GDCMSeriesFileNames got a non DICOM file:"
            << header->GetFileName() );
          continue;
          }
        m_InputFileNames.push_back( header->GetFileName() );
      }
    }
  else
    {
    itkDebugMacro(<<"No files were found");
    }

  return m_InputFileNames;
}

const FilenamesContainer &GDCMSeriesFileNames::GetInputFileNames()
{
  // Do not specify any UID
  return GetFileNames("");
}

const FilenamesContainer &GDCMSeriesFileNames::GetOutputFileNames()
{
  // We are trying to extract the original filename and compose it with a path:

  //There are two different approachs if directory does not exist:
  // 1. Exit
  // 2. Mkdir
  //bool SystemTools::FileExists(const char* filename)
  //bool SystemTools::FileIsDirectory(const char* name)
  m_OutputFileNames.clear();

  if( m_OutputDirectory.empty() )
    {
    itkDebugMacro(<<"No output directory was specified");
    return m_OutputFileNames;
    }

  itksys::SystemTools::ConvertToUnixSlashes( m_OutputDirectory );
  if(m_OutputDirectory[m_OutputDirectory.size()-1] != '/')
    {
    m_OutputDirectory += '/';
    }

  if( m_InputFileNames.size() )
    {
    bool hasExtension = false;
    for(std::vector<std::string>::const_iterator it = m_InputFileNames.begin();
      it != m_InputFileNames.end(); ++it )
      {
      // look for extension ".dcm" and ".DCM"
      std::string::size_type dcmPos = (*it).rfind(".dcm");
      if ( (dcmPos != std::string::npos)
           && (dcmPos == (*it).length() - 4) )
        {
        hasExtension = true;
        }
      else
        {
        dcmPos = (*it).rfind(".DCM");
        if ( (dcmPos != std::string::npos)
             && (dcmPos == (*it).length() - 4) )
          {
          hasExtension = true;
          }
        }

      // look for extension ".dicom" and ".DICOM"
      std::string::size_type dicomPos = (*it).rfind(".dicom");
      if ( (dicomPos != std::string::npos)
           && (dicomPos == (*it).length() - 6) )
        {
        hasExtension = true;
        }
      else
        {
        dicomPos = (*it).rfind(".DICOM");
        if ( (dicomPos != std::string::npos)
             && (dicomPos == (*it).length() - 6) )
          {
          hasExtension = true;
          }
        }

      // construct a filename, adding an extension if necessary
      std::string filename;
      if (hasExtension)
        {
        filename =
          m_OutputDirectory + itksys::SystemTools::GetFilenameName( *it );
        }
      else
        {
        // input filename has no extension, add a ".dcm"
        filename =
          m_OutputDirectory + itksys::SystemTools::GetFilenameName( *it )
          + ".dcm";
        }

      // Add the file name to the output list
      m_OutputFileNames.push_back( filename );
      }
    }
  else
    {
    itkDebugMacro(<<"No files were found.");
    }

  return m_OutputFileNames;
}

void GDCMSeriesFileNames::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  unsigned int i;
  os << indent << "InputDirectory: " << m_InputDirectory << std::endl;
  for (i = 0; i < m_InputFileNames.size(); i++)
    {
    os << indent << "InputFilenames[" << i << "]: " << m_InputFileNames[i] << std::endl;
    }

  os << indent << "OutputDirectory: " << m_OutputDirectory << std::endl;
  for (i = 0; i < m_OutputFileNames.size(); i++)
    {
    os << indent << "OutputFilenames[" << i << "]: " << m_OutputFileNames[i] << std::endl;
    }
}
} //namespace ITK

#endif
<commit_msg>BUG: If too many restrictions we could not even be able to construct one single serie<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkGDCMSeriesFileNames.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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.

=========================================================================*/
#ifndef _itkGDCMSeriesFileNames_h
#define _itkGDCMSeriesFileNames_h

#include "itkGDCMSeriesFileNames.h"
#include "gdcm/src/gdcmSerieHelper.h"
#include "gdcm/src/gdcmFile.h"
#include "gdcm/src/gdcmUtil.h"
#include <itksys/SystemTools.hxx>

#include <vector>
#include <string>

namespace itk
{

GDCMSeriesFileNames::GDCMSeriesFileNames()
{
  m_SerieHelper = new gdcm::SerieHelper();
  m_InputDirectory = "";
  m_OutputDirectory = "";
  m_UseSeriesDetails = true;
}

GDCMSeriesFileNames::~GDCMSeriesFileNames()
{
  delete m_SerieHelper;
}

void GDCMSeriesFileNames::SetInputDirectory (std::string const &name)
{
  if ( name == "" )
    {
    itkWarningMacro( << "You need to specify a directory where "
      "the DICOM files are located");
    return;
    }
  m_InputDirectory = name;
  m_SerieHelper->SetUseSeriesDetails( m_UseSeriesDetails );
  m_SerieHelper->SetDirectory( name ); //as a side effect it also execute
  this->Modified();
}

const SerieUIDContainer &GDCMSeriesFileNames::GetSeriesUIDs()
{
  m_SeriesUIDs.clear();
  // Accessing the first serie found (assume there is at least one)
  gdcm::GdcmFileList *flist = m_SerieHelper->GetFirstCoherentFileList();
  while(flist)
    {
    if( flist->size() ) //make sure we have at leat one serie
      {
      gdcm::File *file = (*flist)[0]; //for example take the first one

      // Create its unique series ID
      std::string id = m_SerieHelper->
                       CreateUniqueSeriesIdentifier( file ).c_str();

      m_SeriesUIDs.push_back( id.c_str() );
      }
    flist = m_SerieHelper->GetNextCoherentFileList();
    }
  if( !m_SeriesUIDs.size() )
    {
    itkWarningMacro(<<"No Series were found");
    }
  return m_SeriesUIDs;
}

const FilenamesContainer &GDCMSeriesFileNames::GetFileNames(const std::string serie)
{
  m_InputFileNames.clear();
  // Accessing the first serie found (assume there is at least one)
  gdcm::GdcmFileList *flist = m_SerieHelper->GetFirstCoherentFileList();
  if( !flist )
    {
    itkWarningMacro(<<"No Series can be found, make sure you restiction are not too strong");
    return m_InputFileNames;
    }
  if( serie != "" ) // user did not specify any sub selcection based on UID
    {
    bool found = false;
    while(flist && !found)
      {
      if( flist->size() ) //make sure we have at leat one serie
        {
        gdcm::File *file = (*flist)[0]; //for example take the first one
        std::string id = m_SerieHelper->
          CreateUniqueSeriesIdentifier( file ).c_str();

        if( id == serie )
          {
          found = true; // we found a match
          break;
          }
        }
      flist = m_SerieHelper->GetNextCoherentFileList();
      }
    if( !found)
      {
      itkWarningMacro(<<"No Series were found");
      return m_InputFileNames;
      }
    }
  m_SerieHelper->OrderGdcmFileList(flist);

  gdcm::GdcmFileList::iterator it;
  if( flist->size() )
    {
    for(it = flist->begin();
        it != flist->end(); ++it )
      {
        gdcm::File * header = *it;
        if( !header )
          {
          itkWarningMacro( << "GDCMSeriesFileNames got NULL header, "
            "this is a serious bug" );
          continue;
          }
        if( !header->IsReadable() )
          {
          itkWarningMacro( << "GDCMSeriesFileNames got a non DICOM file:"
            << header->GetFileName() );
          continue;
          }
        m_InputFileNames.push_back( header->GetFileName() );
      }
    }
  else
    {
    itkDebugMacro(<<"No files were found");
    }

  return m_InputFileNames;
}

const FilenamesContainer &GDCMSeriesFileNames::GetInputFileNames()
{
  // Do not specify any UID
  return GetFileNames("");
}

const FilenamesContainer &GDCMSeriesFileNames::GetOutputFileNames()
{
  // We are trying to extract the original filename and compose it with a path:

  //There are two different approachs if directory does not exist:
  // 1. Exit
  // 2. Mkdir
  //bool SystemTools::FileExists(const char* filename)
  //bool SystemTools::FileIsDirectory(const char* name)
  m_OutputFileNames.clear();

  if( m_OutputDirectory.empty() )
    {
    itkDebugMacro(<<"No output directory was specified");
    return m_OutputFileNames;
    }

  itksys::SystemTools::ConvertToUnixSlashes( m_OutputDirectory );
  if(m_OutputDirectory[m_OutputDirectory.size()-1] != '/')
    {
    m_OutputDirectory += '/';
    }

  if( m_InputFileNames.size() )
    {
    bool hasExtension = false;
    for(std::vector<std::string>::const_iterator it = m_InputFileNames.begin();
      it != m_InputFileNames.end(); ++it )
      {
      // look for extension ".dcm" and ".DCM"
      std::string::size_type dcmPos = (*it).rfind(".dcm");
      if ( (dcmPos != std::string::npos)
           && (dcmPos == (*it).length() - 4) )
        {
        hasExtension = true;
        }
      else
        {
        dcmPos = (*it).rfind(".DCM");
        if ( (dcmPos != std::string::npos)
             && (dcmPos == (*it).length() - 4) )
          {
          hasExtension = true;
          }
        }

      // look for extension ".dicom" and ".DICOM"
      std::string::size_type dicomPos = (*it).rfind(".dicom");
      if ( (dicomPos != std::string::npos)
           && (dicomPos == (*it).length() - 6) )
        {
        hasExtension = true;
        }
      else
        {
        dicomPos = (*it).rfind(".DICOM");
        if ( (dicomPos != std::string::npos)
             && (dicomPos == (*it).length() - 6) )
          {
          hasExtension = true;
          }
        }

      // construct a filename, adding an extension if necessary
      std::string filename;
      if (hasExtension)
        {
        filename =
          m_OutputDirectory + itksys::SystemTools::GetFilenameName( *it );
        }
      else
        {
        // input filename has no extension, add a ".dcm"
        filename =
          m_OutputDirectory + itksys::SystemTools::GetFilenameName( *it )
          + ".dcm";
        }

      // Add the file name to the output list
      m_OutputFileNames.push_back( filename );
      }
    }
  else
    {
    itkDebugMacro(<<"No files were found.");
    }

  return m_OutputFileNames;
}

void GDCMSeriesFileNames::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  unsigned int i;
  os << indent << "InputDirectory: " << m_InputDirectory << std::endl;
  for (i = 0; i < m_InputFileNames.size(); i++)
    {
    os << indent << "InputFilenames[" << i << "]: " << m_InputFileNames[i] << std::endl;
    }

  os << indent << "OutputDirectory: " << m_OutputDirectory << std::endl;
  for (i = 0; i < m_OutputFileNames.size(); i++)
    {
    os << indent << "OutputFilenames[" << i << "]: " << m_OutputFileNames[i] << std::endl;
    }
}
} //namespace ITK

#endif
<|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.

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.

=========================================================================*/
#ifndef __otbGlWidget_cxx
#define __otbGlWidget_cxx

#include "otbGlWidget.h"

namespace otb
{

GlWidget
::GlWidget() : Fl_Gl_Window(0,0,0,0), m_Identifier(), m_UseGlAcceleration(false),
               m_BackgroundColor()
{
  m_Identifier = "Default";

  #ifdef OTB_GL_USE_ACCEL
  m_UseGlAcceleration = true;
  #endif
  // Default background color
  m_BackgroundColor.Fill(0);
}

GlWidget::~GlWidget()
{}

void GlWidget::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  // Call the superclass implementation
  Superclass::PrintSelf(os,indent);
  // Display information about the widget
  os<<indent<<"Widget "<<m_Identifier<<": "<<std::endl;
  #ifndef OTB_GL_USE_ACCEL
  os<<indent<<indent<<"OpenGl acceleration is not allowed."<<std::endl;
  #else
  if(m_UseGlAcceleration)
    {
    os<<indent<<indent<<"OpenGl acceleration is allowed and enabled."<<std::endl;
    }
  else
    {
    os<<indent<<indent<<"OpenGl acceleration is allowed but disabled."<<std::endl;
    }
  #endif
}

void GlWidget::draw()
{
  // Check if Gl acceleration mode is correct
  #ifndef OTB_GL_USE_ACCEL
  if(m_UseGlAcceleration)
    {
    itkWarningMacro(<<"Gl acceleration enabled but not allowed. Consider rebuilding with OTB_USE_GL_ACCEL to ON. For now, disabling Gl acceleration.");
    m_UseGlAcceleration=false;
    }
  #endif

  // Set up Gl environement
  if (!this->valid())
  {
    valid(1);
    glLoadIdentity();
    glViewport(0,0,w(),h());
    glClearColor(m_BackgroundColor[0],m_BackgroundColor[1], m_BackgroundColor[2],m_BackgroundColor[3]);
    glShadeModel(GL_FLAT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  }
  glClear(GL_COLOR_BUFFER_BIT);    //this clears and paints to black
  glMatrixMode(GL_MODELVIEW);      //clear previous 3D draw params
  glLoadIdentity();
  glMatrixMode(GL_PROJECTION);
  this->ortho();
  glDisable(GL_BLEND);
}

void GlWidget::resize(int x, int y, int w, int h)
{
  // Distinguish between resize, move and not changed events
  // (The system window manager may generate multiple resizing events,
  // so we'd rather avoid event flooding here)
  bool reportMove   = false;
  bool reportResize = false;
  if(this->x() != x || this->y() != y)
    {
    reportMove = true;
    }

  if(this->w() != w || this->h() != h)
    {
    reportResize = true;
    }

  // First call the superclass implementation
  Fl_Gl_Window::resize(x,y,w,h);
  // If There is a controller
  if(m_Controller.IsNotNull())
    {
    if(reportMove)
      {
      m_Controller->HandleWidgetMove(m_Identifier,x,y);
      }
    if(reportResize)
      {
      m_Controller->HandleWidgetResize(m_Identifier,w,h);
      }
    }
}

int GlWidget::handle(int event)
{
  // If there is a controller
  if(m_Controller.IsNotNull())
    {
    return m_Controller->HandleWidgetEvent(m_Identifier,event);
    }
  else
    {
    return 0;
    }
}

GlWidget::PointType GlWidget::GetMousePosition()
{
  // Get the cursor position
  PointType index;
  index[0] = Fl::event_x();
  index[1] = Fl::event_y();
  // Flip the y axis
  index[1]= this->h()-index[1];
  return index;
}
}
#endif
<commit_msg>BUG: Fl_Widget destructor generates one last FL_HIDE event which causes segmentation fault (maybe because the object is already in its desctruction process). Therefore we should avoid to process FL_HIDE events.<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.

=========================================================================*/
#ifndef __otbGlWidget_cxx
#define __otbGlWidget_cxx

#include "otbGlWidget.h"

namespace otb
{

GlWidget
::GlWidget() : Fl_Gl_Window(0,0,0,0), m_Identifier(), m_UseGlAcceleration(false),
               m_BackgroundColor()
{
  m_Identifier = "Default";

  #ifdef OTB_GL_USE_ACCEL
  m_UseGlAcceleration = true;
  #endif
  // Default background color
  m_BackgroundColor.Fill(0);
}

GlWidget::~GlWidget()
{
  // Clear registered controller
  m_Controller = NULL;
}

void GlWidget::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  // Call the superclass implementation
  Superclass::PrintSelf(os,indent);
  // Display information about the widget
  os<<indent<<"Widget "<<m_Identifier<<": "<<std::endl;
  #ifndef OTB_GL_USE_ACCEL
  os<<indent<<indent<<"OpenGl acceleration is not allowed."<<std::endl;
  #else
  if(m_UseGlAcceleration)
    {
    os<<indent<<indent<<"OpenGl acceleration is allowed and enabled."<<std::endl;
    }
  else
    {
    os<<indent<<indent<<"OpenGl acceleration is allowed but disabled."<<std::endl;
    }
  #endif
}

void GlWidget::draw()
{
  // Check if Gl acceleration mode is correct
  #ifndef OTB_GL_USE_ACCEL
  if(m_UseGlAcceleration)
    {
    itkWarningMacro(<<"Gl acceleration enabled but not allowed. Consider rebuilding with OTB_USE_GL_ACCEL to ON. For now, disabling Gl acceleration.");
    m_UseGlAcceleration=false;
    }
  #endif

  // Set up Gl environement
  if (!this->valid())
  {
    valid(1);
    glLoadIdentity();
    glViewport(0,0,w(),h());
    glClearColor(m_BackgroundColor[0],m_BackgroundColor[1], m_BackgroundColor[2],m_BackgroundColor[3]);
    glShadeModel(GL_FLAT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  }
  glClear(GL_COLOR_BUFFER_BIT);    //this clears and paints to black
  glMatrixMode(GL_MODELVIEW);      //clear previous 3D draw params
  glLoadIdentity();
  glMatrixMode(GL_PROJECTION);
  this->ortho();
  glDisable(GL_BLEND);
}

void GlWidget::resize(int x, int y, int w, int h)
{
  // Distinguish between resize, move and not changed events
  // (The system window manager may generate multiple resizing events,
  // so we'd rather avoid event flooding here)
  bool reportMove   = false;
  bool reportResize = false;
  if(this->x() != x || this->y() != y)
    {
    reportMove = true;
    }

  if(this->w() != w || this->h() != h)
    {
    reportResize = true;
    }

  // First call the superclass implementation
  Fl_Gl_Window::resize(x,y,w,h);
  // If There is a controller
  if(m_Controller.IsNotNull())
    {
    if(reportMove)
      {
      m_Controller->HandleWidgetMove(m_Identifier,x,y);
      }
    if(reportResize)
      {
      m_Controller->HandleWidgetResize(m_Identifier,w,h);
      }
    }
}

int GlWidget::handle(int event)
{
  // Call superclass implementation
  int resp = Fl_Widget::handle(event);

  // Check if there is a controller
  // Avoid processing hide events, since it causes segfault (the
  // destructor of the Fl class generates hide events).
  if(m_Controller.IsNotNull() && event != FL_HIDE)
    {
    resp = m_Controller->HandleWidgetEvent(m_Identifier,event);
    }
  return resp;
}

GlWidget::PointType GlWidget::GetMousePosition()
{
  // Get the cursor position
  PointType index;
  index[0] = Fl::event_x();
  index[1] = Fl::event_y();
  // Flip the y axis
  index[1]= this->h()-index[1];
  return index;
}
}
#endif
<|endoftext|>


<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2016 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
** disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
** following disclaimer in the documentation and/or other materials provided with the distribution.
** * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "CFocus.h"

#include "../nodes/NodeReviews.h"
#include "../nodes/ReviewComment.h"

#include "ModelBase/src/model/TreeManager.h"
#include "ModelBase/src/model/AllTreeManagers.h"

#include "VisualizationBase/src/items/Item.h"
#include "VisualizationBase/src/items/ViewItem.h"
#include "VisualizationBase/src/views/MainView.h"
#include "VisualizationBase/src/VisualizationManager.h"
#include "VisualizationBase/src/overlays/HighlightOverlay.h"

#include "../CodeReviewManager.h"

#include "../overlays/CodeReviewCommentOverlay.h"

using namespace Visualization;

namespace CodeReview {

int CFocus::currentStep_{0};

CFocus::CFocus() : Command{"focus"} {}

QHash<int, CFocus::FocusInformation> CFocus::focusList_;

bool CFocus::canInterpret(Visualization::Item*, Visualization::Item*,
		const QStringList& commandTokens, const std::unique_ptr<Visualization::Cursor>& )
{
	if (commandTokens.size() > 0)
		return name() == commandTokens.first();
	return false;
}

Interaction::CommandResult* CFocus::execute(Visualization::Item*, Visualization::Item*,
				const QStringList&, const std::unique_ptr<Visualization::Cursor>&)
{
	focusStep({}, {}, {});
	return new Interaction::CommandResult{};
}

bool CFocus::focusStep(Visualization::Item *, QKeySequence, Interaction::ActionRegistry::InputState)
{
	Visualization::VisualizationManager::instance().mainScene()->removeOverlayGroup("focusOverlay");

	auto focusInformations = focusList_.values(currentStep_);

	if (focusInformations.isEmpty()){
		currentStep_ = 0;
		focusInformations = focusList_.values(currentStep_);
	}

	if (focusInformations.isEmpty())
		return false;

	for (auto focusInformation : focusInformations)
	{

		auto focusItem = CodeReviewManager::instance().overlayForNodeReviews(focusInformation.node_);

		if (focusInformation.type_.testFlag(FocusInformation::Center))
		{
			Visualization::VisualizationManager::instance().mainView()->centerOn(focusItem);
		}

		if (focusInformation.type_.testFlag(FocusInformation::Highlight))
		{
			auto overlay = new Visualization::HighlightOverlay{focusItem,
					Visualization::HighlightOverlay::itemStyles().get("focus")};
			focusItem->addOverlay(overlay, "focusOverlay");
		}
	}

	currentStep_++;
	return true;
}

QList<Interaction::CommandSuggestion*> CFocus::suggest(Visualization::Item*, Visualization::Item*,
		const QString& textSoFar, const std::unique_ptr<Visualization::Cursor>&)
{
	if (name().startsWith(textSoFar))
		return {new Interaction::CommandSuggestion{name()}};
	return {};
}

CFocus::FocusInformation CFocus::extractFocusInformation(QString line)
{
	QStringList commandTokens = line.split(" ");

	FocusInformation focusInformation;

	while (!commandTokens.isEmpty())
	{
		auto token = commandTokens.takeFirst();

		if (QString{"highlight"}.startsWith(token))
			focusInformation.type_ |= FocusInformation::FocusType::Highlight;
		else if (QString{"center"}.startsWith(token))
			focusInformation.type_ |= FocusInformation::FocusType::Center;
		else
		{
			bool isNumber;
			auto step = token.toInt(&isNumber);

			if (isNumber)
			{
				focusInformation.step_ = step;
				break;
			}
		}

	}

	return focusInformation;
}

void CFocus::loadFocusInformation()
{
	for (NodeReviews* nodeReviews : *CodeReviewManager::instance().nodeReviewsList())
	{
		auto focusInformation = extractFocusInformation(nodeReviews->focusInformation());

		if (!focusInformation.type_.testFlag(FocusInformation::None))
		{
			focusInformation.node_ = nodeReviews;
			focusList_.insertMulti(focusInformation.step_, focusInformation);
		}
	}
}

}
<commit_msg>Use target in focusStep to get the scene<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2016 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
** disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
** following disclaimer in the documentation and/or other materials provided with the distribution.
** * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "CFocus.h"

#include "../nodes/NodeReviews.h"
#include "../nodes/ReviewComment.h"

#include "ModelBase/src/model/TreeManager.h"
#include "ModelBase/src/model/AllTreeManagers.h"

#include "VisualizationBase/src/items/Item.h"
#include "VisualizationBase/src/items/ViewItem.h"
#include "VisualizationBase/src/views/MainView.h"
#include "VisualizationBase/src/VisualizationManager.h"
#include "VisualizationBase/src/overlays/HighlightOverlay.h"

#include "../CodeReviewManager.h"

#include "../overlays/CodeReviewCommentOverlay.h"

using namespace Visualization;

namespace CodeReview {

int CFocus::currentStep_{0};

CFocus::CFocus() : Command{"focus"} {}

QHash<int, CFocus::FocusInformation> CFocus::focusList_;

bool CFocus::canInterpret(Visualization::Item*, Visualization::Item*,
		const QStringList& commandTokens, const std::unique_ptr<Visualization::Cursor>& )
{
	if (commandTokens.size() > 0)
		return name() == commandTokens.first();
	return false;
}

Interaction::CommandResult* CFocus::execute(Visualization::Item* source, Visualization::Item*,
				const QStringList&, const std::unique_ptr<Visualization::Cursor>&)
{
	focusStep(source, {}, {});
	return new Interaction::CommandResult{};
}

bool CFocus::focusStep(Visualization::Item* target, QKeySequence, Interaction::ActionRegistry::InputState)
{
	target->scene()->removeOverlayGroup("focusOverlay");

	auto focusInformations = focusList_.values(currentStep_);

	if (focusInformations.isEmpty()){
		currentStep_ = 0;
		focusInformations = focusList_.values(currentStep_);
	}

	if (focusInformations.isEmpty())
		return false;

	for (auto focusInformation : focusInformations)
	{

		auto focusItem = CodeReviewManager::instance().overlayForNodeReviews(focusInformation.node_);

		if (focusInformation.type_.testFlag(FocusInformation::Center))
		{
			Visualization::VisualizationManager::instance().mainView()->centerOn(focusItem);
		}

		if (focusInformation.type_.testFlag(FocusInformation::Highlight))
		{
			auto overlay = new Visualization::HighlightOverlay{focusItem,
					Visualization::HighlightOverlay::itemStyles().get("focus")};
			focusItem->addOverlay(overlay, "focusOverlay");
		}
	}

	currentStep_++;
	return true;
}

QList<Interaction::CommandSuggestion*> CFocus::suggest(Visualization::Item*, Visualization::Item*,
		const QString& textSoFar, const std::unique_ptr<Visualization::Cursor>&)
{
	if (name().startsWith(textSoFar))
		return {new Interaction::CommandSuggestion{name()}};
	return {};
}

CFocus::FocusInformation CFocus::extractFocusInformation(QString line)
{
	QStringList commandTokens = line.split(" ");

	FocusInformation focusInformation;

	while (!commandTokens.isEmpty())
	{
		auto token = commandTokens.takeFirst();

		if (QString{"highlight"}.startsWith(token))
			focusInformation.type_ |= FocusInformation::FocusType::Highlight;
		else if (QString{"center"}.startsWith(token))
			focusInformation.type_ |= FocusInformation::FocusType::Center;
		else
		{
			bool isNumber;
			auto step = token.toInt(&isNumber);

			if (isNumber)
			{
				focusInformation.step_ = step;
				break;
			}
		}

	}

	return focusInformation;
}

void CFocus::loadFocusInformation()
{
	for (NodeReviews* nodeReviews : *CodeReviewManager::instance().nodeReviewsList())
	{
		auto focusInformation = extractFocusInformation(nodeReviews->focusInformation());

		if (!focusInformation.type_.testFlag(FocusInformation::None))
		{
			focusInformation.node_ = nodeReviews;
			focusList_.insertMulti(focusInformation.step_, focusInformation);
		}
	}
}

}
<|endoftext|>


<commit_before>
#include "CommonSingleFileTesting.hpp"
#include "UseUnaryOperator/UseUnaryOperator.h"
#include "UseUnaryOperator/UseUnaryOperatorActions.h"
#include "UseUnaryOperator/UseUnaryOperatorMatchers.h"

namespace {
class MatcherProvider {
    protected:
	auto makeMatcher(){
	    return makeUseUnaryOperatorMatcher();
	}
};

typedef Fixture<UseUnaryOperatorFixer,UseUnaryOperatorTransform,MatcherProvider> LocalFixture;
}

TEST( UseUnaryOperatorTest, PlusEqualToPrefixPlusPlus ) {
    // input for the transformation
    std::string cpp_input =
	"void fun() {\n"
        "  a += 1;\n"
	"}\n"
    ;
    // the text that i expect to get after the transformation
    std::string cpp_output =
	"void fun() {\n"
	"  ++a;\n"
	"}\n"
    ;
    LocalFixture Test(cpp_input,cpp_output);
}

<commit_msg>forgot to declare a variable in the tests<commit_after>
#include "CommonSingleFileTesting.hpp"
#include "UseUnaryOperator/UseUnaryOperator.h"
#include "UseUnaryOperator/UseUnaryOperatorActions.h"
#include "UseUnaryOperator/UseUnaryOperatorMatchers.h"

namespace {
class MatcherProvider {
    protected:
	auto makeMatcher(){
	    return makeUseUnaryOperatorMatcher();
	}
};

typedef Fixture<UseUnaryOperatorFixer,UseUnaryOperatorTransform,MatcherProvider> LocalFixture;
}

TEST( UseUnaryOperatorTest, PlusEqualToPrefixPlusPlus ) {
    // input for the transformation
    std::string cpp_input =
	"void fun() {\n"
	"  int a = 0;\n"
        "  a += 1;\n"
	"}\n"
    ;
    // the text that i expect to get after the transformation
    std::string cpp_output =
	"void fun() {\n"
	"  int a = 0;\n"
	"  ++a;\n"
	"}\n"
    ;
    LocalFixture Test(cpp_input,cpp_output);
}

<|endoftext|>


<commit_before>#include "xalt_obfuscate.h"
#include "xalt_syshost.h"
#include "xalt_config.h"
#include "xalt_regex.h"
#include "xalt_version.h"
#include <iostream>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "epoch.h"
#include "Json.h"

const int dateSZ=100;

void displayArray(const char *name, int n, const char **A)
{
  std::cout << "*----------------------*\n";
  std::cout << " Array: " << name << "\n";
  std::cout << "*----------------------*\n";

  for (int i = 0; i < n; ++i)
    std::cout << std::setw(4) << i << ": " << A[i] << "\n";
  std::cout << "\n";
}

int main(int argc, char* argv[])
{
  std::string syshost(xalt_syshost());
  std::string syslog_tag("XALT_LOGGING_");
  syslog_tag.append(syshost);

  char    dateStr[dateSZ];
  time_t  now = (time_t) epoch();
  strftime(dateStr,dateSZ, "%c", localtime(&now));

  const char* transmission = getenv("XALT_TRANSMISSION_STYLE");
  if (transmission == NULL)
    transmission = TRANSMISSION;

  const char* computeSHA1 = getenv("XALT_COMPUTE_SHA1");
  if (computeSHA1 == NULL)
    computeSHA1 = XALT_COMPUTE_SHA1;

  const char* enable_backgrounding = getenv("XALT_ENABLE_BACKGROUNDING");
  if (enable_backgrounding == NULL)
    enable_backgrounding = XALT_ENABLE_BACKGROUNDING;

  const char* xalt_etc_dir = getenv("XALT_ETC_DIR");
  if (xalt_etc_dir == NULL)
    xalt_etc_dir = XALT_ETC_DIR;

  const char* xalt_tracking_mpi_only = getenv("XALT_TRACKING_MPI_ONLY");
  if (xalt_tracking_mpi_only == NULL)
    xalt_tracking_mpi_only = XALT_TRACKING_MPI_ONLY;

  if (argc == 2 && strcmp(argv[1],"--json") == 0)
    {
      Json json;
      json.add("DATE",                        dateStr);
      json.add("XALT_SYSHOST",                syshost);
      json.add("XALT_VERSION",                XALT_VERSION);
      json.add("XALT_GIT_VERSION",            XALT_GIT_VERSION);
      json.add("XALT_VERSION_STR",            XALT_VERSION_STR);
      json.add("XALT_FILE_PREFIX",            XALT_FILE_PREFIX);
      json.add("XALT_ENABLE_BACKGROUNDING",   enable_backgrounding);
      json.add("XALT_TRANSMISSION_STYLE",     transmission);
      if (strcmp(transmission,"syslog") == 0)
        json.add("XALT_LOGGING_TAG",          syslog_tag);
      json.add("XALT_COMPUTE_SHA1",           computeSHA1);
      json.add("XALT_ETC_DIR",                xalt_etc_dir);
      json.add("XALT_CONFIG_PY",              XALT_CONFIG_PY);
      json.add("XALT_SYSTEM_PATH",            XALT_SYSTEM_PATH);
      json.add("XALT_SYSHOST_CONFIG",         SYSHOST_CONFIG);
      json.add("XALT_TRACKING_MPI_ONLY",      xalt_tracking_mpi_only);
      json.add("XALT_SYSLOG_MSG_SZ",          SYSLOG_MSG_SZ);
      json.add("HAVE_32BIT",                  HAVE_32BIT);
      json.add("USING_LIBUUID",               HAVE_WORKING_LIBUUID);
      json.add("BUILT_W_MySQL",               BUILT_W_MySQL);

      json.add("hostnameA",    hostnameSz,    hostnameA);
      json.add("pathPatternA", pathPatternSz, pathPatternA);
      json.add("envPatternA",  envPatternSz,  envPatternA);
      json.fini();

      std::string jsonStr = json.result();
      std::cout << jsonStr << std::endl;
      return 0;
    }

  std::cout << "*------------------------------------------------------------------------------*\n";
  std::cout << "                      XALT Configuration Report\n";
  std::cout << "*------------------------------------------------------------------------------*\n\n";
  std::cout << "Today's DATE:              " << dateStr                << "\n";
  std::cout << "XALT_VERSION:              " << XALT_VERSION           << "\n";
  std::cout << "XALT_GIT_VERSION:          " << XALT_GIT_VERSION       << "\n";
  std::cout << "XALT_VERSION_STR:          " << XALT_VERSION_STR       << "\n";
  std::cout << "*------------------------------------------------------------------------------*\n";
  std::cout << "XALT_SYSHOST:              " << syshost                << "\n";
  std::cout << "XALT_FILE_PREFIX:          " << XALT_FILE_PREFIX       << "\n";
  std::cout << "XALT_TRANSMISSION_STYLE:   " << transmission           << "\n";
  if (strcmp(transmission,"syslog") == 0)
    std::cout << "XALT_LOGGING_TAG:        " << syslog_tag             << "\n";
  std::cout << "XALT_COMPUTE_SHA1:         " << computeSHA1            << "\n";
  std::cout << "XALT_ENABLE_BACKGROUNDING: " << enable_backgrounding   << "\n";
  std::cout << "XALT_ETC_DIR:              " << xalt_etc_dir           << "\n";
  std::cout << "XALT_CONFIG_PY:            " << XALT_CONFIG_PY         << "\n";
  std::cout << "XALT_TRACKING_MPI_ONLY:    " << xalt_tracking_mpi_only << "\n";
  std::cout << "XALT_SYSTEM_PATH:          " << XALT_SYSTEM_PATH       << "\n";
  std::cout << "XALT_SYSHOST_CONFIG:       " << SYSHOST_CONFIG         << "\n";
  std::cout << "XALT_SYSLOG_MSG_SZ:        " << SYSLOG_MSG_SZ          << "\n";
  std::cout << "HAVE_32BIT:                " << HAVE_32BIT             << "\n";
  std::cout << "Using libuuid:             " << HAVE_WORKING_LIBUUID   << "\n";
  std::cout << "Built with MySQL:          " << BUILT_W_MySQL          << "\n";
  std::cout << "*------------------------------------------------------------------------------*\n\n";

  displayArray("hostnameA",    hostnameSz,    hostnameA);
  std::cout << "\nRemember that \"SPSR\" means a scalar program that creates a start record\n";
  displayArray("pathPatternA", pathPatternSz, pathPatternA);
  displayArray("envPatternA",  envPatternSz,  envPatternA);

  return 0;
}
<commit_msg>better alignment for xalt_configuration report<commit_after>#include "xalt_obfuscate.h"
#include "xalt_syshost.h"
#include "xalt_config.h"
#include "xalt_regex.h"
#include "xalt_version.h"
#include <iostream>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "epoch.h"
#include "Json.h"

const int dateSZ=100;

void displayArray(const char *name, int n, const char **A)
{
  std::cout << "*----------------------*\n";
  std::cout << " Array: " << name << "\n";
  std::cout << "*----------------------*\n";

  for (int i = 0; i < n; ++i)
    std::cout << std::setw(4) << i << ": " << A[i] << "\n";
  std::cout << "\n";
}

int main(int argc, char* argv[])
{
  std::string syshost(xalt_syshost());
  std::string syslog_tag("XALT_LOGGING_");
  syslog_tag.append(syshost);

  char    dateStr[dateSZ];
  time_t  now = (time_t) epoch();
  strftime(dateStr,dateSZ, "%c", localtime(&now));

  const char* transmission = getenv("XALT_TRANSMISSION_STYLE");
  if (transmission == NULL)
    transmission = TRANSMISSION;

  const char* computeSHA1 = getenv("XALT_COMPUTE_SHA1");
  if (computeSHA1 == NULL)
    computeSHA1 = XALT_COMPUTE_SHA1;

  const char* enable_backgrounding = getenv("XALT_ENABLE_BACKGROUNDING");
  if (enable_backgrounding == NULL)
    enable_backgrounding = XALT_ENABLE_BACKGROUNDING;

  const char* xalt_etc_dir = getenv("XALT_ETC_DIR");
  if (xalt_etc_dir == NULL)
    xalt_etc_dir = XALT_ETC_DIR;

  const char* xalt_tracking_mpi_only = getenv("XALT_TRACKING_MPI_ONLY");
  if (xalt_tracking_mpi_only == NULL)
    xalt_tracking_mpi_only = XALT_TRACKING_MPI_ONLY;

  if (argc == 2 && strcmp(argv[1],"--json") == 0)
    {
      Json json;
      json.add("DATE",                        dateStr);
      json.add("XALT_SYSHOST",                syshost);
      json.add("XALT_VERSION",                XALT_VERSION);
      json.add("XALT_GIT_VERSION",            XALT_GIT_VERSION);
      json.add("XALT_VERSION_STR",            XALT_VERSION_STR);
      json.add("XALT_FILE_PREFIX",            XALT_FILE_PREFIX);
      json.add("XALT_ENABLE_BACKGROUNDING",   enable_backgrounding);
      json.add("XALT_TRANSMISSION_STYLE",     transmission);
      if (strcmp(transmission,"syslog") == 0)
        json.add("XALT_LOGGING_TAG",            syslog_tag);
      json.add("XALT_COMPUTE_SHA1",           computeSHA1);
      json.add("XALT_ETC_DIR",                xalt_etc_dir);
      json.add("XALT_CONFIG_PY",              XALT_CONFIG_PY);
      json.add("XALT_SYSTEM_PATH",            XALT_SYSTEM_PATH);
      json.add("XALT_SYSHOST_CONFIG",         SYSHOST_CONFIG);
      json.add("XALT_TRACKING_MPI_ONLY",      xalt_tracking_mpi_only);
      json.add("XALT_SYSLOG_MSG_SZ",          SYSLOG_MSG_SZ);
      json.add("HAVE_32BIT",                  HAVE_32BIT);
      json.add("USING_LIBUUID",               HAVE_WORKING_LIBUUID);
      json.add("BUILT_W_MySQL",               BUILT_W_MySQL);

      json.add("hostnameA",    hostnameSz,    hostnameA);
      json.add("pathPatternA", pathPatternSz, pathPatternA);
      json.add("envPatternA",  envPatternSz,  envPatternA);
      json.fini();

      std::string jsonStr = json.result();
      std::cout << jsonStr << std::endl;
      return 0;
    }

  std::cout << "*------------------------------------------------------------------------------*\n";
  std::cout << "                      XALT Configuration Report\n";
  std::cout << "*------------------------------------------------------------------------------*\n\n";
  std::cout << "Today's DATE:              " << dateStr                << "\n";
  std::cout << "XALT_VERSION:              " << XALT_VERSION           << "\n";
  std::cout << "XALT_GIT_VERSION:          " << XALT_GIT_VERSION       << "\n";
  std::cout << "XALT_VERSION_STR:          " << XALT_VERSION_STR       << "\n";
  std::cout << "*------------------------------------------------------------------------------*\n";
  std::cout << "XALT_SYSHOST:              " << syshost                << "\n";
  std::cout << "XALT_FILE_PREFIX:          " << XALT_FILE_PREFIX       << "\n";
  std::cout << "XALT_TRANSMISSION_STYLE:   " << transmission           << "\n";
  if (strcmp(transmission,"syslog") == 0)
    std::cout << "XALT_LOGGING_TAG:        " << syslog_tag             << "\n";
  std::cout << "XALT_COMPUTE_SHA1:         " << computeSHA1            << "\n";
  std::cout << "XALT_ENABLE_BACKGROUNDING: " << enable_backgrounding   << "\n";
  std::cout << "XALT_ETC_DIR:              " << xalt_etc_dir           << "\n";
  std::cout << "XALT_CONFIG_PY:            " << XALT_CONFIG_PY         << "\n";
  std::cout << "XALT_TRACKING_MPI_ONLY:    " << xalt_tracking_mpi_only << "\n";
  std::cout << "XALT_SYSTEM_PATH:          " << XALT_SYSTEM_PATH       << "\n";
  std::cout << "XALT_SYSHOST_CONFIG:       " << SYSHOST_CONFIG         << "\n";
  std::cout << "XALT_SYSLOG_MSG_SZ:        " << SYSLOG_MSG_SZ          << "\n";
  std::cout << "HAVE_32BIT:                " << HAVE_32BIT             << "\n";
  std::cout << "Using libuuid:             " << HAVE_WORKING_LIBUUID   << "\n";
  std::cout << "Built with MySQL:          " << BUILT_W_MySQL          << "\n";
  std::cout << "*------------------------------------------------------------------------------*\n\n";

  displayArray("hostnameA",    hostnameSz,    hostnameA);
  std::cout << "\nRemember that \"SPSR\" means a scalar program that creates a start record\n";
  displayArray("pathPatternA", pathPatternSz, pathPatternA);
  displayArray("envPatternA",  envPatternSz,  envPatternA);

  return 0;
}
<|endoftext|>


<commit_before>/*
** Copyright 2011-2015 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include "com/centreon/broker/config/state.hh"
#include "com/centreon/broker/correlation/engine_state.hh"
#include "com/centreon/broker/correlation/factory.hh"
#include "com/centreon/broker/correlation/internal.hh"
#include "com/centreon/broker/correlation/issue.hh"
#include "com/centreon/broker/correlation/issue_parent.hh"
#include "com/centreon/broker/correlation/log_issue.hh"
#include "com/centreon/broker/correlation/state.hh"
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/events.hh"
#include "com/centreon/broker/io/protocols.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/multiplexing/engine.hh"

using namespace com::centreon::broker;

// Load count.
static unsigned int instances(0);

extern "C" {
  /**
   *  Module version symbol. Used to check for version mismatch.
   */
  char const* broker_module_version = CENTREON_BROKER_VERSION;

  /**
   *  Module deinitialization routine.
   */
  void broker_module_deinit() {
    // Decrement instance number.
    if (!--instances) {
      // Unregister correlation layer.
      io::protocols::instance().unreg("correlation");

      // Remove events.
      io::events::instance().unregister_category(io::events::correlation);
    }
    return ;
  }

  /**
   *  Module initialization routine.
   *
   *  @param[in] arg Configuration argument.
   */
  void broker_module_init(void const* arg) {
    (void)arg;

    // Increment instance number.
    if (!instances++) {
      // Correlation module.
      logging::info(logging::high)
        << "correlation: module for Centreon Broker "
        << CENTREON_BROKER_VERSION;

      // Register correlation layer.
      io::protocols::instance().reg(
        "correlation",
        correlation::factory(),
        1,
        7);

      // Register category.
      io::events& e(io::events::instance());
      int correlation_category(e.register_category(
                                   "correlation",
                                   io::events::correlation));
      if (correlation_category != io::events::correlation) {
        e.unregister_category(correlation_category);
        --instances;
        throw (exceptions::msg() << "correlation: category "
               << io::events::correlation
               << " is already registered whereas it should be "
               << "reserved for the correlation module");
      }

      // Register events.
      {
        e.register_event(
            io::events::correlation,
            correlation::de_engine_state,
            io::event_info(
                  "engine_state",
                  &correlation::engine_state::operations,
                  correlation::engine_state::entries));
        e.register_event(
            io::events::correlation,
            correlation::de_state,
            io::event_info(
                  "state",
                  &correlation::state::operations,
                  correlation::state::entries,
                  "rt_servicestateevents"));
        e.register_event(
            io::events::correlation,
            correlation::de_issue,
            io::event_info(
                  "issue",
                  &correlation::issue::operations,
                  correlation::issue::entries,
                  "rt_issues"));
        e.register_event(
            io::events::correlation,
            correlation::de_issue_parent,
            io::event_info(
                  "issue_parent",
                  &correlation::issue_parent::operations,
                  correlation::issue_parent::entries,
                  "rt_issues_issues_parents"));
        e.register_event(
            io::events::correlation,
            correlation::de_log_issue,
            io::event_info(
                  "log_issue",
                  &correlation::log_issue::operations,
                  correlation::log_issue::entries,
                  "log_logs"));
      }
    }
    return ;
  }
}
<commit_msg>correlation: provide 2.x table names to events.<commit_after>/*
** Copyright 2011-2016 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include "com/centreon/broker/config/state.hh"
#include "com/centreon/broker/correlation/engine_state.hh"
#include "com/centreon/broker/correlation/factory.hh"
#include "com/centreon/broker/correlation/internal.hh"
#include "com/centreon/broker/correlation/issue.hh"
#include "com/centreon/broker/correlation/issue_parent.hh"
#include "com/centreon/broker/correlation/log_issue.hh"
#include "com/centreon/broker/correlation/state.hh"
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/io/events.hh"
#include "com/centreon/broker/io/protocols.hh"
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/multiplexing/engine.hh"

using namespace com::centreon::broker;

// Load count.
static unsigned int instances(0);

extern "C" {
  /**
   *  Module version symbol. Used to check for version mismatch.
   */
  char const* broker_module_version = CENTREON_BROKER_VERSION;

  /**
   *  Module deinitialization routine.
   */
  void broker_module_deinit() {
    // Decrement instance number.
    if (!--instances) {
      // Unregister correlation layer.
      io::protocols::instance().unreg("correlation");

      // Remove events.
      io::events::instance().unregister_category(io::events::correlation);
    }
    return ;
  }

  /**
   *  Module initialization routine.
   *
   *  @param[in] arg Configuration argument.
   */
  void broker_module_init(void const* arg) {
    (void)arg;

    // Increment instance number.
    if (!instances++) {
      // Correlation module.
      logging::info(logging::high)
        << "correlation: module for Centreon Broker "
        << CENTREON_BROKER_VERSION;

      // Register correlation layer.
      io::protocols::instance().reg(
        "correlation",
        correlation::factory(),
        1,
        7);

      // Register category.
      io::events& e(io::events::instance());
      int correlation_category(e.register_category(
                                   "correlation",
                                   io::events::correlation));
      if (correlation_category != io::events::correlation) {
        e.unregister_category(correlation_category);
        --instances;
        throw (exceptions::msg() << "correlation: category "
               << io::events::correlation
               << " is already registered whereas it should be "
               << "reserved for the correlation module");
      }

      // Register events.
      {
        e.register_event(
            io::events::correlation,
            correlation::de_engine_state,
            io::event_info(
                  "engine_state",
                  &correlation::engine_state::operations,
                  correlation::engine_state::entries));
        e.register_event(
            io::events::correlation,
            correlation::de_state,
            io::event_info(
                  "state",
                  &correlation::state::operations,
                  correlation::state::entries,
                  "rt_servicestateevents"));
        e.register_event(
            io::events::correlation,
            correlation::de_issue,
            io::event_info(
                  "issue",
                  &correlation::issue::operations,
                  correlation::issue::entries,
                  "rt_issues",
                  "issues"));
        e.register_event(
            io::events::correlation,
            correlation::de_issue_parent,
            io::event_info(
                  "issue_parent",
                  &correlation::issue_parent::operations,
                  correlation::issue_parent::entries,
                  "rt_issues_issues_parents",
                  "issues_issues_parents"));
        e.register_event(
            io::events::correlation,
            correlation::de_log_issue,
            io::event_info(
                  "log_issue",
                  &correlation::log_issue::operations,
                  correlation::log_issue::entries,
                  "log_logs",
                  "logs"));
      }
    }
    return ;
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/net/http/HttpConnectionServicer.h"

#include "db/net/http/HttpRequest.h"
#include "db/net/http/HttpResponse.h"
#include "db/io/ByteArrayInputStream.h"

#include <cstdlib>

using namespace std;
using namespace db::io;
using namespace db::net::http;
using namespace db::rt;

HttpConnectionServicer::HttpConnectionServicer(const char* serverName)
{
   mServerName = strdup(serverName);
}

HttpConnectionServicer::~HttpConnectionServicer()
{
   free(mServerName);
}

HttpRequestServicer* HttpConnectionServicer::findRequestServicer(
   char* path, ServicerMap& servicerMap)
{
   HttpRequestServicer* rval = NULL;

   // strip any query
   if(path != NULL)
   {
      char* end = strrchr(path, '?');
      if(end != NULL)
      {
         end[0] = 0;
      }
   }

   mRequestServicerLock.lockShared();
   {
      // try to find servicer for path
      ServicerMap::iterator i;
      while(rval == NULL && path != NULL)
      {
         i = servicerMap.find(path);
         if(i != servicerMap.end())
         {
            rval = i->second;
         }
         else if(strlen(path) > 1)
         {
            // try to find servicer at parent path
            char* end = strrchr(path, '/');
            if(end != NULL)
            {
               end[0] = 0;
            }
            else
            {
               // no path left to search
               path = NULL;
            }
         }
         else
         {
            // no path left to search
            path = NULL;
         }
      }
   }
   mRequestServicerLock.unlockShared();

   return rval;
}

void HttpConnectionServicer::serviceConnection(Connection* c)
{
   // wrap connection, set default timeouts to 30 seconds
   HttpConnection hc(c, false);
   hc.setReadTimeout(30000);
   hc.setWriteTimeout(30000);

   // create request
   HttpRequest* request = (HttpRequest*)hc.createRequest();
   HttpRequestHeader* reqHeader = request->getHeader();

   // create response
   HttpResponse* response = (HttpResponse*)request->createResponse();
   HttpResponseHeader* resHeader = response->getHeader();

   // handle keep-alive (HTTP/1.1 keep-alive is on by default)
   bool keepAlive = true;
   bool noerror = true;
   while(keepAlive && noerror)
   {
      // set defaults
      resHeader->setVersion("HTTP/1.1");
      resHeader->setDate();
      resHeader->setField("Server", mServerName);

      // receive request header
      if((noerror = request->receiveHeader()))
      {
         // check http version
         bool version10 = (strcmp(reqHeader->getVersion(), "HTTP/1.0") == 0);
         bool version11 = (strcmp(reqHeader->getVersion(), "HTTP/1.1") == 0);

         // only version 1.0 and 1.1 supported
         if(version10 || version11)
         {
            // set response version according to request version
            resHeader->setVersion(reqHeader->getVersion());

            // include host path if one was used
            string host;
            if(reqHeader->getField("Host", host))
            {
               resHeader->setField("Host", host);
            }

            // get connection header
            string connHeader;
            if(reqHeader->getField("Connection", connHeader))
            {
               if(strcasecmp(connHeader.c_str(), "close") == 0)
               {
                  keepAlive = false;
               }
               else if(strcasecmp(connHeader.c_str(), "keep-alive") == 0)
               {
                  keepAlive = true;
               }
            }
            else if(version10)
            {
               // if HTTP/1.0 and no keep-alive header, keep-alive is off
               keepAlive = false;
            }

            // get request path and normalize it
            const char* inPath = reqHeader->getPath();
            char outPath[strlen(inPath) + 2];
            HttpRequestServicer::normalizePath(inPath, outPath);

            // find appropriate request servicer for path
            HttpRequestServicer* hrs = NULL;

            // find secure/non-secure servicer
            hrs = hc.isSecure() ?
               findRequestServicer(outPath, mSecureServicers) :
               findRequestServicer(outPath, mNonSecureServicers);

            if(hrs != NULL)
            {
               // service request
               hrs->serviceRequest(request, response);

               // if servicer closed connection, turn off keep-alive
               if(c->isClosed())
               {
                  keepAlive = false;
               }

               // turn off keep-alive if response has close connection field
               if(keepAlive)
               {
                  if(resHeader->getField("Connection", connHeader) &&
                     strcasecmp(connHeader.c_str(), "close") == 0)
                  {
                     keepAlive = false;
                  }
               }
            }
            else
            {
               // no servicer, so send 404 Not Found
               char html[] = "
404 Not Found
";
               resHeader->setStatus(404, "Not Found");
               resHeader->setField("Content-Type", "text/html");
               resHeader->setField("Content-Length", 35);
               resHeader->setField("Connection", "close");
               if((noerror = response->sendHeader()))
               {
                  ByteArrayInputStream is(html, 35);
                  noerror = response->sendBody(&is);
               }
            }
         }
         else
         {
            // send 505 HTTP Version Not Supported
            char html[] =
               "
505 HTTP Version Not Supported
";
            resHeader->setStatus(505, "HTTP Version Not Supported");
            resHeader->setField("Content-Type", "text/html");
            resHeader->setField("Content-Length", 52);
            resHeader->setField("Connection", "close");
            if((noerror = response->sendHeader()))
            {
               ByteArrayInputStream is(html, 52);
               noerror = response->sendBody(&is);
            }
         }
      }
      else
      {
         // exception occurred while receiving header
         ExceptionRef e = Exception::getLast();
         if(!e.isNull() && strcmp(e->getType(), "db.net.http.BadRequest") == 1)
         {
            // send 400 Bad Request
            char html[] = "
400 Bad Request
";
            response->getHeader()->setStatus(400, "Bad Request");
            response->getHeader()->setField("Content-Type", "text/html");
            response->getHeader()->setField("Content-Length", 38);
            response->getHeader()->setField("Connection", "close");
            if(response->sendHeader())
            {
               ByteArrayInputStream is(html, 38);
               response->sendBody(&is);
            }
         }
         else
         {
            // if the exception was not an interruption or socket error then
            // send an internal server error response
            if(!e.isNull() &&
               strcmp(e->getType(), "db.io.InterruptedException") != 0 &&
               strncmp(e->getType(), "db.net.Socket", 13) != 0)
            {
               // send 500 Internal Server Error
               char html[] = "
500 Internal Server Error
";
               resHeader->setStatus(500, "Internal Server Error");
               resHeader->setField("Content-Type", "text/html");
               resHeader->setField("Content-Length", 47);
               resHeader->setField("Connection", "close");
               if((noerror = response->sendHeader()))
               {
                  ByteArrayInputStream is(html, 47);
                  noerror = response->sendBody(&is);
               }
            }
         }
      }

      if(keepAlive && noerror)
      {
         // clear request and response header fields
         reqHeader->clearFields();
         resHeader->clearFields();
         resHeader->clearStatus();
      }
   }

   // clean up request and response
   delete request;
   delete response;

   // close connection
   hc.close();
}

void HttpConnectionServicer::addRequestServicer(
   HttpRequestServicer* s, bool secure)
{
   mRequestServicerLock.lockExclusive();
   {
      if(secure)
      {
         mSecureServicers[s->getPath()] = s;
      }
      else
      {
         mNonSecureServicers[s->getPath()] = s;
      }
   }
   mRequestServicerLock.unlockExclusive();
}

void HttpConnectionServicer::removeRequestServicer(
   HttpRequestServicer* s, bool secure)
{
   mRequestServicerLock.lockExclusive();
   {
      if(secure)
      {
         mSecureServicers.erase(s->getPath());
      }
      else
      {
         mNonSecureServicers.erase(s->getPath());
      }
   }
   mRequestServicerLock.unlockExclusive();
}

HttpRequestServicer* HttpConnectionServicer::removeRequestServicer(
   const char* path, bool secure)
{
   HttpRequestServicer* rval = NULL;

   mRequestServicerLock.lockExclusive();
   {
      if(secure)
      {
         ServicerMap::iterator i = mSecureServicers.find(path);
         if(i != mSecureServicers.end())
         {
            rval = i->second;
            mSecureServicers.erase(path);
         }
      }
      else
      {
         ServicerMap::iterator i = mNonSecureServicers.find(path);
         if(i != mNonSecureServicers.end())
         {
            rval = i->second;
            mNonSecureServicers.erase(path);
         }
      }
   }
   mRequestServicerLock.unlockExclusive();

   return rval;
}
<commit_msg>Added code to use X-Forwarded-Server for host for proxy'd stuff.<commit_after>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/net/http/HttpConnectionServicer.h"

#include "db/net/http/HttpRequest.h"
#include "db/net/http/HttpResponse.h"
#include "db/io/ByteArrayInputStream.h"

#include <cstdlib>

using namespace std;
using namespace db::io;
using namespace db::net::http;
using namespace db::rt;

HttpConnectionServicer::HttpConnectionServicer(const char* serverName)
{
   mServerName = strdup(serverName);
}

HttpConnectionServicer::~HttpConnectionServicer()
{
   free(mServerName);
}

HttpRequestServicer* HttpConnectionServicer::findRequestServicer(
   char* path, ServicerMap& servicerMap)
{
   HttpRequestServicer* rval = NULL;

   // strip any query
   if(path != NULL)
   {
      char* end = strrchr(path, '?');
      if(end != NULL)
      {
         end[0] = 0;
      }
   }

   mRequestServicerLock.lockShared();
   {
      // try to find servicer for path
      ServicerMap::iterator i;
      while(rval == NULL && path != NULL)
      {
         i = servicerMap.find(path);
         if(i != servicerMap.end())
         {
            rval = i->second;
         }
         else if(strlen(path) > 1)
         {
            // try to find servicer at parent path
            char* end = strrchr(path, '/');
            if(end != NULL)
            {
               end[0] = 0;
            }
            else
            {
               // no path left to search
               path = NULL;
            }
         }
         else
         {
            // no path left to search
            path = NULL;
         }
      }
   }
   mRequestServicerLock.unlockShared();

   return rval;
}

void HttpConnectionServicer::serviceConnection(Connection* c)
{
   // wrap connection, set default timeouts to 30 seconds
   HttpConnection hc(c, false);
   hc.setReadTimeout(30000);
   hc.setWriteTimeout(30000);

   // create request
   HttpRequest* request = (HttpRequest*)hc.createRequest();
   HttpRequestHeader* reqHeader = request->getHeader();

   // create response
   HttpResponse* response = (HttpResponse*)request->createResponse();
   HttpResponseHeader* resHeader = response->getHeader();

   // handle keep-alive (HTTP/1.1 keep-alive is on by default)
   bool keepAlive = true;
   bool noerror = true;
   while(keepAlive && noerror)
   {
      // set defaults
      resHeader->setVersion("HTTP/1.1");
      resHeader->setDate();
      resHeader->setField("Server", mServerName);

      // receive request header
      if((noerror = request->receiveHeader()))
      {
         // check http version
         bool version10 = (strcmp(reqHeader->getVersion(), "HTTP/1.0") == 0);
         bool version11 = (strcmp(reqHeader->getVersion(), "HTTP/1.1") == 0);

         // only version 1.0 and 1.1 supported
         if(version10 || version11)
         {
            // set response version according to request version
            resHeader->setVersion(reqHeader->getVersion());

            // use proxy'd host field if one was used
            // else use host field if one was used
            string host;
            if(reqHeader->getField("X-Forwarded-Server", host) ||
               reqHeader->getField("Host", host))
            {
               resHeader->setField("Host", host);
            }

            // get connection header
            string connHeader;
            if(reqHeader->getField("Connection", connHeader))
            {
               if(strcasecmp(connHeader.c_str(), "close") == 0)
               {
                  keepAlive = false;
               }
               else if(strcasecmp(connHeader.c_str(), "keep-alive") == 0)
               {
                  keepAlive = true;
               }
            }
            else if(version10)
            {
               // if HTTP/1.0 and no keep-alive header, keep-alive is off
               keepAlive = false;
            }

            // get request path and normalize it
            const char* inPath = reqHeader->getPath();
            char outPath[strlen(inPath) + 2];
            HttpRequestServicer::normalizePath(inPath, outPath);

            // find appropriate request servicer for path
            HttpRequestServicer* hrs = NULL;

            // find secure/non-secure servicer
            hrs = hc.isSecure() ?
               findRequestServicer(outPath, mSecureServicers) :
               findRequestServicer(outPath, mNonSecureServicers);

            if(hrs != NULL)
            {
               // service request
               hrs->serviceRequest(request, response);

               // if servicer closed connection, turn off keep-alive
               if(c->isClosed())
               {
                  keepAlive = false;
               }

               // turn off keep-alive if response has close connection field
               if(keepAlive)
               {
                  if(resHeader->getField("Connection", connHeader) &&
                     strcasecmp(connHeader.c_str(), "close") == 0)
                  {
                     keepAlive = false;
                  }
               }
            }
            else
            {
               // no servicer, so send 404 Not Found
               char html[] = "
404 Not Found
";
               resHeader->setStatus(404, "Not Found");
               resHeader->setField("Content-Type", "text/html");
               resHeader->setField("Content-Length", 35);
               resHeader->setField("Connection", "close");
               if((noerror = response->sendHeader()))
               {
                  ByteArrayInputStream is(html, 35);
                  noerror = response->sendBody(&is);
               }
            }
         }
         else
         {
            // send 505 HTTP Version Not Supported
            char html[] =
               "
505 HTTP Version Not Supported
";
            resHeader->setStatus(505, "HTTP Version Not Supported");
            resHeader->setField("Content-Type", "text/html");
            resHeader->setField("Content-Length", 52);
            resHeader->setField("Connection", "close");
            if((noerror = response->sendHeader()))
            {
               ByteArrayInputStream is(html, 52);
               noerror = response->sendBody(&is);
            }
         }
      }
      else
      {
         // exception occurred while receiving header
         ExceptionRef e = Exception::getLast();
         if(!e.isNull() && strcmp(e->getType(), "db.net.http.BadRequest") == 1)
         {
            // send 400 Bad Request
            char html[] = "
400 Bad Request
";
            response->getHeader()->setStatus(400, "Bad Request");
            response->getHeader()->setField("Content-Type", "text/html");
            response->getHeader()->setField("Content-Length", 38);
            response->getHeader()->setField("Connection", "close");
            if(response->sendHeader())
            {
               ByteArrayInputStream is(html, 38);
               response->sendBody(&is);
            }
         }
         else
         {
            // if the exception was not an interruption or socket error then
            // send an internal server error response
            if(!e.isNull() &&
               strcmp(e->getType(), "db.io.InterruptedException") != 0 &&
               strncmp(e->getType(), "db.net.Socket", 13) != 0)
            {
               // send 500 Internal Server Error
               char html[] = "
500 Internal Server Error
";
               resHeader->setStatus(500, "Internal Server Error");
               resHeader->setField("Content-Type", "text/html");
               resHeader->setField("Content-Length", 47);
               resHeader->setField("Connection", "close");
               if((noerror = response->sendHeader()))
               {
                  ByteArrayInputStream is(html, 47);
                  noerror = response->sendBody(&is);
               }
            }
         }
      }

      if(keepAlive && noerror)
      {
         // clear request and response header fields
         reqHeader->clearFields();
         resHeader->clearFields();
         resHeader->clearStatus();
      }
   }

   // clean up request and response
   delete request;
   delete response;

   // close connection
   hc.close();
}

void HttpConnectionServicer::addRequestServicer(
   HttpRequestServicer* s, bool secure)
{
   mRequestServicerLock.lockExclusive();
   {
      if(secure)
      {
         mSecureServicers[s->getPath()] = s;
      }
      else
      {
         mNonSecureServicers[s->getPath()] = s;
      }
   }
   mRequestServicerLock.unlockExclusive();
}

void HttpConnectionServicer::removeRequestServicer(
   HttpRequestServicer* s, bool secure)
{
   mRequestServicerLock.lockExclusive();
   {
      if(secure)
      {
         mSecureServicers.erase(s->getPath());
      }
      else
      {
         mNonSecureServicers.erase(s->getPath());
      }
   }
   mRequestServicerLock.unlockExclusive();
}

HttpRequestServicer* HttpConnectionServicer::removeRequestServicer(
   const char* path, bool secure)
{
   HttpRequestServicer* rval = NULL;

   mRequestServicerLock.lockExclusive();
   {
      if(secure)
      {
         ServicerMap::iterator i = mSecureServicers.find(path);
         if(i != mSecureServicers.end())
         {
            rval = i->second;
            mSecureServicers.erase(path);
         }
      }
      else
      {
         ServicerMap::iterator i = mNonSecureServicers.find(path);
         if(i != mNonSecureServicers.end())
         {
            rval = i->second;
            mNonSecureServicers.erase(path);
         }
      }
   }
   mRequestServicerLock.unlockExclusive();

   return rval;
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/base/algorithm/camerautils.h>

#include <inviwo/core/network/networklock.h>

namespace inviwo {

namespace camerautil {

namespace detail {

vec3 getViewDir(Side side) {
    switch (side) {
        case Side::XNegative:
            return vec3(1, 0, 0);
        case Side::XPositive:
            return vec3(-1, 0, 0);
        case Side::YNegative:
            return vec3(0, 1, 0);
        case Side::YPositive:
            return vec3(0, -1, 0);
        case Side::ZNegative:
            return vec3(0, 0, 1);
        case Side::ZPositive:
            return vec3(0, 0, -1);
        default:
            return vec3(0);
    }
}

vec3 getLookUp(Side side) {
    switch (side) {
        case Side::XNegative:
            return vec3(0, 1, 0);
        case Side::XPositive:
            return vec3(0, 1, 0);
        case Side::YNegative:
            return vec3(1, 0, 0);
        case Side::YPositive:
            return vec3(1, 0, 0);
        case Side::ZNegative:
            return vec3(0, 1, 0);
        case Side::ZPositive:
            return vec3(0, 1, 0);
        default:
            return vec3(0);
    }
}

}  // namespace detail

void setCameraView(CameraProperty &cam, const mat4 &boundingBox, vec3 inViewDir, vec3 inLookUp,
                   float fitRatio, UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    if (auto perspectiveCamera = dynamic_cast<PerspectiveCamera *>(&cam.get())) {
        const auto offset = vec3{.5f};
        const auto lookTo = vec3(boundingBox * vec4(offset, 1.f));

        const auto viewDir = glm::normalize(inViewDir);
        const auto lookUp = glm::normalize(inLookUp);
        const auto sideDir = glm::cross(viewDir, lookUp);

        const float fovy = perspectiveCamera->getFovy() / 2.0f;
        const float fovx =
            glm::degrees(std::atan(cam.getAspectRatio() * std::tan(glm::radians(fovy))));

        const std::array<vec3, 8> corners = {vec3{0, 0, 0}, vec3{1, 0, 0}, vec3{1, 1, 0},
                                             vec3{0, 1, 0}, vec3{0, 0, 1}, vec3{1, 0, 1},
                                             vec3{1, 1, 1}, vec3{0, 1, 1}};

        // Find the needed distance from the camera to lookTo given a field of view such that a
        // corner of the bounding box are within the view
        const auto dist = [&](vec3 corner) {
            const auto point = vec3(boundingBox * vec4(corner, 1.f));

            const auto d0 = glm::dot(point - lookTo, -viewDir);
            const auto height = glm::abs(glm::dot(point - lookTo, lookUp)) * fitRatio;
            const auto width = glm::abs(glm::dot(point - lookTo, sideDir)) * fitRatio;
            const float d1 = height * std::tan(glm::radians(90 - fovy));
            const float d2 = width * std::tan(glm::radians(90 - fovx));
            return d0 + std::max(d1, d2);
        };

        // take the largest needed distance for all corners.
        const auto it = std::max_element(corners.begin(), corners.end(),
                                         [&](vec3 a, vec3 b) { return dist(a) < dist(b); });
        const auto lookFrom = dist(*it) * viewDir;

        NetworkLock lock(&cam);
        if (updateNearFar == UpdateNearFar::Yes) {
            setCameraNearFar(cam, boundingBox);
        }
        if (updateLookRanges == UpdateLookRanges::Yes) {
            setCameraLookRanges(cam, boundingBox);
        }
        cam.setLook(lookFrom, lookTo, lookUp);
    } else {
        LogWarnCustom("camerautil::setCameraView",
                      "setCameraView only supports perspective cameras");
    }
}

void setCameraView(CameraProperty &cam, const mat4 &boundingBox, float fitRatio,
                   UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    setCameraView(cam, boundingBox, cam.getLookFrom() - cam.getLookTo(), cam.getLookUp(), fitRatio,
                  updateNearFar, updateLookRanges);
}

void setCameraView(CameraProperty &cam, const mat4 &boundingBox, Side side, float fitRatio,
                   UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    setCameraView(cam, boundingBox, detail::getViewDir(side), detail::getLookUp(side), fitRatio,
                  updateNearFar, updateLookRanges);
}

void setCameraView(CameraProperty &cam, const std::vector<std::shared_ptr<const Mesh>> &meshes,
                   Side side, float fitRatio, UpdateNearFar updateNearFar,
                   UpdateLookRanges updateLookRanges) {
    auto minMax = meshutil::axisAlignedBoundingBox(meshes);
    auto m = glm::scale(minMax.second - minMax.first);
    m[3] = vec4(minMax.first, 1.0f);
    setCameraView(cam, m, side, fitRatio, updateNearFar, updateLookRanges);
}

void setCameraView(CameraProperty &cam, const Mesh &mesh, Side side, float fitRatio,
                   UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    auto minMax = meshutil::axisAlignedBoundingBox(mesh);
    auto m = glm::scale(minMax.second - minMax.first);
    m[3] = vec4(minMax.first, 1.0f);
    setCameraView(cam, m, side, fitRatio, updateNearFar, updateLookRanges);
}

void setCameraLookRanges(CameraProperty &cam, const mat4 &boundingBox, float zoomRange) {
    NetworkLock lock(&cam);

    vec3 lookTo(boundingBox * vec4(vec3(.5f), 1.f));

    vec3 dx(boundingBox[0]);
    vec3 dy(boundingBox[1]);
    vec3 dz(boundingBox[2]);

    auto p0 = lookTo + (dx + dy + dz) * zoomRange;
    auto p1 = lookTo - (dx + dy + dz) * zoomRange;
    cam.lookFrom_.setMinValue(glm::min(p0, p1));
    cam.lookFrom_.setMaxValue(glm::max(p0, p1));
    p0 = lookTo + (dx + dy + dz);
    p1 = lookTo - (dx + dy + dz);
    cam.lookTo_.setMinValue(glm::min(p0, p1));
    cam.lookTo_.setMaxValue(glm::max(p0, p1));
}

std::pair<float, float> computeCameraNearFar(const mat4 &boundingBox, float zoomRange,
                                             float nearFarRatio) {
    vec3 bx(boundingBox[0]);
    vec3 by(boundingBox[1]);
    vec3 bz(boundingBox[2]);

    float dx = glm::length(bx);
    float dy = glm::length(by);
    float dz = glm::length(bz);

    auto d = std::max({dx, dy, dz});

    auto newFar = d * (zoomRange + 1);
    auto newNear = newFar * nearFarRatio;
    return {newNear, newFar};
}

void setCameraNearFar(CameraProperty &cam, const mat4 &boundingBox, float zoomRange,
                      float nearFarRatio) {

    auto [newNear, newFar] = computeCameraNearFar(boundingBox, zoomRange, nearFarRatio);

    cam.setNearFarPlaneDist(newNear, newFar);
}

}  // namespace camerautil

}  // namespace inviwo
<commit_msg>Base: Camera fitter: Fixes for basis not centered at zero and with rotated basises<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/base/algorithm/camerautils.h>

#include <inviwo/core/network/networklock.h>

namespace inviwo {

namespace camerautil {

namespace detail {

vec3 getViewDir(Side side) {
    switch (side) {
        case Side::XNegative:
            return vec3(1, 0, 0);
        case Side::XPositive:
            return vec3(-1, 0, 0);
        case Side::YNegative:
            return vec3(0, 1, 0);
        case Side::YPositive:
            return vec3(0, -1, 0);
        case Side::ZNegative:
            return vec3(0, 0, 1);
        case Side::ZPositive:
            return vec3(0, 0, -1);
        default:
            return vec3(0);
    }
}

vec3 getLookUp(Side side) {
    switch (side) {
        case Side::XNegative:
            return vec3(0, 1, 0);
        case Side::XPositive:
            return vec3(0, 1, 0);
        case Side::YNegative:
            return vec3(1, 0, 0);
        case Side::YPositive:
            return vec3(1, 0, 0);
        case Side::ZNegative:
            return vec3(0, 1, 0);
        case Side::ZPositive:
            return vec3(0, 1, 0);
        default:
            return vec3(0);
    }
}

}  // namespace detail

void setCameraView(CameraProperty &cam, const mat4 &boundingBox, vec3 inViewDir, vec3 inLookUp,
                   float fitRatio, UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    if (auto perspectiveCamera = dynamic_cast<PerspectiveCamera *>(&cam.get())) {
        const auto offset = vec3{.5f};
        const auto lookTo = vec3(boundingBox * vec4(offset, 1.f));

        const auto viewDir = glm::normalize(inViewDir);
        const auto lookUp = glm::normalize(inLookUp);
        const auto sideDir = glm::cross(viewDir, lookUp);

        const float fovy = perspectiveCamera->getFovy() / 2.0f;
        const float fovx =
            glm::degrees(std::atan(cam.getAspectRatio() * std::tan(glm::radians(fovy))));

        const std::array<vec3, 8> corners = {vec3{0, 0, 0}, vec3{1, 0, 0}, vec3{1, 1, 0},
                                             vec3{0, 1, 0}, vec3{0, 0, 1}, vec3{1, 0, 1},
                                             vec3{1, 1, 1}, vec3{0, 1, 1}};

        // Find the needed distance from the camera to lookTo given a field of view such that a
        // corner of the bounding box are within the view
        const auto dist = [&](vec3 corner) {
            const auto point = vec3(boundingBox * vec4(corner, 1.f));

            const auto d0 = glm::dot(point - lookTo, -viewDir);
            const auto height = glm::abs(glm::dot(point - lookTo, lookUp)) * fitRatio;
            const auto width = glm::abs(glm::dot(point - lookTo, sideDir)) * fitRatio;
            const float d1 = height * std::tan(glm::radians(90 - fovy));
            const float d2 = width * std::tan(glm::radians(90 - fovx));
            return d0 + std::max(d1, d2);
        };

        // take the largest needed distance for all corners.
        const auto it = std::max_element(corners.begin(), corners.end(),
                                         [&](vec3 a, vec3 b) { return dist(a) < dist(b); });
        const auto lookOffset = dist(*it) * viewDir;

        NetworkLock lock(&cam);
        if (updateNearFar == UpdateNearFar::Yes) {
            setCameraNearFar(cam, boundingBox);
        }
        if (updateLookRanges == UpdateLookRanges::Yes) {
            setCameraLookRanges(cam, boundingBox);
        }
        cam.setLook(lookTo + lookOffset, lookTo, lookUp);
    } else {
        LogWarnCustom("camerautil::setCameraView",
                      "setCameraView only supports perspective cameras");
    }
}

void setCameraView(CameraProperty &cam, const mat4 &boundingBox, float fitRatio,
                   UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    setCameraView(cam, boundingBox, cam.getLookFrom() - cam.getLookTo(), cam.getLookUp(), fitRatio,
                  updateNearFar, updateLookRanges);
}

void setCameraView(CameraProperty &cam, const mat4 &boundingBox, Side side, float fitRatio,
                   UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    const auto viewDir = mat3(boundingBox) * detail::getViewDir(side);
    const auto lookUp = mat3(boundingBox) * detail::getLookUp(side);
    setCameraView(cam, boundingBox, viewDir, lookUp, fitRatio,
                  updateNearFar, updateLookRanges);
}

void setCameraView(CameraProperty &cam, const std::vector<std::shared_ptr<const Mesh>> &meshes,
                   Side side, float fitRatio, UpdateNearFar updateNearFar,
                   UpdateLookRanges updateLookRanges) {
    auto minMax = meshutil::axisAlignedBoundingBox(meshes);
    auto m = glm::scale(minMax.second - minMax.first);
    m[3] = vec4(minMax.first, 1.0f);
    setCameraView(cam, m, side, fitRatio, updateNearFar, updateLookRanges);
}

void setCameraView(CameraProperty &cam, const Mesh &mesh, Side side, float fitRatio,
                   UpdateNearFar updateNearFar, UpdateLookRanges updateLookRanges) {
    auto minMax = meshutil::axisAlignedBoundingBox(mesh);
    auto m = glm::scale(minMax.second - minMax.first);
    m[3] = vec4(minMax.first, 1.0f);
    setCameraView(cam, m, side, fitRatio, updateNearFar, updateLookRanges);
}

void setCameraLookRanges(CameraProperty &cam, const mat4 &boundingBox, float zoomRange) {
    NetworkLock lock(&cam);

    vec3 lookTo(boundingBox * vec4(vec3(.5f), 1.f));

    vec3 dx(boundingBox[0]);
    vec3 dy(boundingBox[1]);
    vec3 dz(boundingBox[2]);

    auto p0 = lookTo + (dx + dy + dz) * zoomRange;
    auto p1 = lookTo - (dx + dy + dz) * zoomRange;
    cam.lookFrom_.setMinValue(glm::min(p0, p1));
    cam.lookFrom_.setMaxValue(glm::max(p0, p1));
    p0 = lookTo + (dx + dy + dz);
    p1 = lookTo - (dx + dy + dz);
    cam.lookTo_.setMinValue(glm::min(p0, p1));
    cam.lookTo_.setMaxValue(glm::max(p0, p1));
}

std::pair<float, float> computeCameraNearFar(const mat4 &boundingBox, float zoomRange,
                                             float nearFarRatio) {
    vec3 bx(boundingBox[0]);
    vec3 by(boundingBox[1]);
    vec3 bz(boundingBox[2]);

    float dx = glm::length(bx);
    float dy = glm::length(by);
    float dz = glm::length(bz);

    auto d = std::max({dx, dy, dz});

    auto newFar = d * (zoomRange + 1);
    auto newNear = newFar * nearFarRatio;
    return {newNear, newFar};
}

void setCameraNearFar(CameraProperty &cam, const mat4 &boundingBox, float zoomRange,
                      float nearFarRatio) {

    auto [newNear, newFar] = computeCameraNearFar(boundingBox, zoomRange, nearFarRatio);

    cam.setNearFarPlaneDist(newNear, newFar);
}

}  // namespace camerautil

}  // namespace inviwo
<|endoftext|>