<commit_before>#include "itkCommandLineArgumentParser.h"
#include "CommandLineArgumentHelper.h"

#include "itkImageFileReader.h"
#include "itkSmoothingRecursiveGaussianImageFilter2.h"
#include "itkImageToVectorImageFilter.h"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkImageFileWriter.h"

//-------------------------------------------------------------------------------------

/** run: A macro to call a function. */
#define run( function, type, dim ) \
if ( componentType == #type && Dimension == dim ) \
{ \
  typedef itk::Image< type, dim >  OutputImageType; \
  if ( retmag == false ) \
  { \
    function< OutputImageType >( inputFileName, outputFileName, sigma, order ); \
  } \
  else \
  { \
  function##Magnitude< OutputImageType >( inputFileName, outputFileName, sigma, order ); \
  } \
  supported = true; \
}

//-------------------------------------------------------------------------------------

/** Declare GaussianImageFilter. */
template< class OutputImageType >
void GaussianImageFilter(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order );

/** Declare GaussianImageFilter. */
template< class OutputImageType >
void GaussianImageFilterMagnitude(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order );

/** Declare PrintHelp. */
void PrintHelp( void );

//-------------------------------------------------------------------------------------

int main( int argc, char ** argv )
{
 	/** Check arguments for help. */
	if ( argc < 3 || argc > 15 )
	{
		PrintHelp();
		return 1;
	}

	/** Create a command line argument parser. */
	itk::CommandLineArgumentParser::Pointer parser = itk::CommandLineArgumentParser::New();
	parser->SetCommandLineArguments( argc, argv );

	/** Get arguments. */
  std::string inputFileName = "";
	bool retin = parser->GetCommandLineArgument( "-in", inputFileName );

  std::vector<float> sigma;
  sigma.push_back(1.0); // default 1.0 for each resolution
  bool retstd = parser->GetCommandLineArgument( "-std", sigma );

  std::vector<unsigned int> order;
  bool retord = parser->GetCommandLineArgument( "-ord", order );

  std::string	outputFileName = inputFileName.substr( 0, inputFileName.rfind( "." ) );
	outputFileName += "BLURRED.mhd";
	bool retout = parser->GetCommandLineArgument( "-out", outputFileName );

	bool retmag = parser->ArgumentExists( "-mag" );

  std::string componentType = "";
	bool retpt = parser->GetCommandLineArgument( "-pt", componentType );

 	/** Check if the required arguments are given. */
	if ( !retin )
	{
		std::cerr << "ERROR: You should specify \"-in\"." << std::endl;
		return 1;
	}

  /** Check options. */
  for ( unsigned int i = 0; i < order.size(); ++i )
  {
    if ( order[ i ] > 2 )
    {
      std::cerr << "ERROR: The order should not be higher than 2." << std::endl;
      std::cerr << "Only zeroth, first and second order derivatives are supported." << std::endl;
      return 1;
    }
  }

  /** Determine image properties. */
  std::string ComponentTypeIn = "short";
  std::string	PixelType; //we don't use this
  unsigned int Dimension = 3;
  unsigned int NumberOfComponents = 1;
  std::vector<unsigned int> imagesize( Dimension, 0 );
  int retgip = GetImageProperties(
    inputFileName,
    PixelType,
    ComponentTypeIn,
    Dimension,
    NumberOfComponents,
    imagesize );
  if ( retgip != 0 )
  {
    return 1;
  }

  /** The default output is equal to the input, but can be overridden by
   * specifying -pt in the command line.
   */
  if ( !retpt ) componentType = ComponentTypeIn;

  /** Check for vector images. */
  if ( NumberOfComponents > 1 )
  {
    std::cerr << "ERROR: The NumberOfComponents is larger than 1!" << std::endl;
    std::cerr << "Cannot make vector of vector images." << std::endl;
    return 1;
  }

	/** Get rid of the possible "_" in ComponentType. */
  ReplaceUnderscoreWithSpace( ComponentTypeIn );

  /** Check order. */
  if ( order.size() != Dimension )
  {
    std::cerr << "ERROR: the # of orders should be equal to the image dimension!" << std::endl;
    return 1;
  }

  /** Check sigma. */
  if ( sigma.size() != 1 && sigma.size() != Dimension )
  {
    std::cerr << "ERROR: the # of sigmas should be equal to 1 or the image dimension!" << std::endl;
    return 1;
  }

  /** Run the program. */
  bool supported = false;
	try
	{
    run( GaussianImageFilter, char, 2 );
		run( GaussianImageFilter, unsigned char, 2 );
    run( GaussianImageFilter, short, 2 );
		run( GaussianImageFilter, unsigned short, 2 );
    run( GaussianImageFilter, int, 2 );
		run( GaussianImageFilter, unsigned int, 2 );
    run( GaussianImageFilter, long, 2 );
		run( GaussianImageFilter, unsigned long, 2 );
    run( GaussianImageFilter, float, 2 );
		run( GaussianImageFilter, double, 2 );

    run( GaussianImageFilter, char, 3 );
		run( GaussianImageFilter, unsigned char, 3 );
    run( GaussianImageFilter, short, 3 );
		run( GaussianImageFilter, unsigned short, 3 );
    run( GaussianImageFilter, int, 3 );
		run( GaussianImageFilter, unsigned int, 3 );
    run( GaussianImageFilter, long, 3 );
		run( GaussianImageFilter, unsigned long, 3 );
    run( GaussianImageFilter, float, 3 );
		run( GaussianImageFilter, double, 3 );

	}
	catch( itk::ExceptionObject &e )
	{
		std::cerr << "Caught ITK exception: " << e << std::endl;
		return 1;
	}
  if ( !supported )
  {
    std::cerr << "ERROR: this combination of pixeltype and dimension is not supported!" << std::endl;
    std::cerr <<
      "pixel (component) type = " << ComponentTypeIn <<
      " ; dimension = " << Dimension
      << std::endl;
    return 1;
  }

	/** End program. */
	return 0;

} // end main

	/**
	 * ******************* GaussianImageFilter *******************
	 */

template< class OutputImageType >
void GaussianImageFilter(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order )
{
  /** Typedef's. */
  const unsigned int Dimension = OutputImageType::ImageDimension;
  typedef float                                           InputPixelType;
  typedef itk::Image< InputPixelType, Dimension >         InputImageType;
	typedef itk::ImageFileReader< InputImageType >			    ReaderType;
	typedef itk::SmoothingRecursiveGaussianImageFilter2<
    InputImageType, OutputImageType >                     FilterType;
  typedef typename FilterType::OrderType                  OrderType;
  typedef typename FilterType::SigmaType                  SigmaType;
	typedef itk::ImageFileWriter< OutputImageType >			    WriterType;

	/**	Read in the input image. */
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputFileName );

  /** Setup the order and sigma. */
  OrderType orderFA;
  SigmaType sigmaFA;
  sigmaFA.Fill( sigma[ 0 ] );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    orderFA[ i ] = order[ i ];
    if ( sigma.size() == Dimension ) sigmaFA[ i ] = sigma[ i ];
  }

  /** Setup the smoothing filter. */
  typename FilterType::Pointer filter = FilterType::New();
  filter->SetNormalizeAcrossScale( false );
  filter->SetInput( reader->GetOutput() );
  filter->SetSigma( sigmaFA );
  filter->SetOrder( orderFA );

  /** Write image. */
  typename WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( outputFileName );
	writer->SetInput( filter->GetOutput() );
  writer->Update();

} // end GaussianImageFilter()

  /**
	 * ******************* GaussianImageFilterMagnitude *******************
	 */

template< class OutputImageType >
void GaussianImageFilterMagnitude(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order )
{
  /** Typedef's. */
  const unsigned int Dimension = OutputImageType::ImageDimension;
  typedef float                                           InputPixelType;
  typedef itk::Image< InputPixelType, Dimension >         InputImageType;
	typedef itk::ImageFileReader< InputImageType >			    ReaderType;
	typedef itk::SmoothingRecursiveGaussianImageFilter2<
    InputImageType, InputImageType >                      SmoothingFilterType;
  typedef typename SmoothingFilterType::Pointer           SmoothingFilterPointer;
  typedef typename SmoothingFilterType::OrderType         OrderType;
  typedef typename SmoothingFilterType::SigmaType         SigmaType;
  typedef itk::ImageToVectorImageFilter<
    InputImageType >                                      ImageToVectorImageFilterType;
  typedef typename ImageToVectorImageFilterType
    ::OutputImageType                                     VectorImageType;
  typedef itk::GradientToMagnitudeImageFilter<
    VectorImageType, OutputImageType >                    MagnitudeFilterType;
	typedef itk::ImageFileWriter< OutputImageType >			    WriterType;

	/**	Read in the input image. */
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputFileName );

  /** Setup the order and sigma. */
  OrderType orderFA;
  SigmaType sigmaFA;
  sigmaFA.Fill( sigma[ 0 ] );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    orderFA[ i ] = order[ i ];
    if ( sigma.size() == Dimension ) sigmaFA[ i ] = sigma[ i ];
  }

  /** Setup filters. */
  typename ImageToVectorImageFilterType::Pointer imageToVectorImageFilter
    = ImageToVectorImageFilterType::New();
  typename MagnitudeFilterType::Pointer magnitudeFilter = MagnitudeFilterType::New();

  /** Setup and run the smoothing filters. */
  std::vector< SmoothingFilterPointer > filter( Dimension );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    filter[ i ] = SmoothingFilterType::New();
    filter[ i ]->SetNormalizeAcrossScale( false );
    filter[ i ]->SetInput( reader->GetOutput() );
    SigmaType sigma2; sigma2.Fill( 0.0 ); sigma2[ i ] = sigmaFA[ i ];
    OrderType order2; order2.Fill( 0.0 ); order2[ i ] = orderFA[ i ];
    filter[ i ]->SetSigma( sigma2 );
    filter[ i ]->SetOrder( order2 );
    filter[ i ]->Update();

    /** Setup composition filter. */
    imageToVectorImageFilter->SetNthInput( i, filter[ i ]->GetOutput() );
  }

  /** Compose vector image and compute magnitude. */
  magnitudeFilter->SetInput( imageToVectorImageFilter->GetOutput() );
  magnitudeFilter->Update();

  /** Write image. */
  typename WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( outputFileName );
	writer->SetInput( magnitudeFilter->GetOutput() );
  writer->Update();

} // end GaussianImageFilterMagnitude()

	/**
	 * ******************* PrintHelp *******************
	 */
void PrintHelp()
{
	std::cout << "Usage:" << std::endl << "pxgaussianimagefilter" << std::endl;
	std::cout << "  -in      inputFilename" << std::endl;
	std::cout << "  [-out]   outputFilename, default in + BLURRED.mhd" << std::endl;
  std::cout << "  [-std]   sigma, for each dimension, default 1.0" << std::endl;
  std::cout << "  [-ord]   order, for each dimension, default zero\n";
  std::cout << "             0: zero order = blurring\n";
  std::cout << "             1: first order = gradient\n";
  std::cout << "             2: second order derivative" << std::endl;
  std::cout << "  [-mag]   compute the magnitude of the separate blurrings, default false" << std::endl;
  std::cout << "  [-pt]    output pixel type, default equal to input" << std::endl;
	std::cout << "Supported: 2D, 3D, (unsigned) char, (unsigned) short, (unsigned) int, (unsigned) long, float, double." << std::endl;
} // end PrintHelp()

<commit_msg>MS:<commit_after>#include "itkCommandLineArgumentParser.h"
#include "CommandLineArgumentHelper.h"

#include "itkImageFileReader.h"
#include "itkSmoothingRecursiveGaussianImageFilter2.h"
#include "itkImageToVectorImageFilter.h"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkImageRegionConstIterator.h"
#include "itkImageRegionIterator.h"
#include "itkImageFileWriter.h"

//-------------------------------------------------------------------------------------

/** run: A macro to call a function. */
#define run( function, type, dim ) \
if ( componentType == #type && Dimension == dim ) \
{ \
  typedef itk::Image< type, dim >  OutputImageType; \
  if ( retmag ) \
  { \
    function##Magnitude< OutputImageType >( inputFileName, outputFileName, sigma, order ); \
  } \
  if ( retlap ) \
  { \
    function##Laplacian< OutputImageType >( inputFileName, outputFileName, sigma ); \
  } \
  if ( !retmag && !retlap ) \
  { \
    function< OutputImageType >( inputFileName, outputFileName, sigma, order ); \
  } \
  supported = true; \
}

//-------------------------------------------------------------------------------------

/** Declare GaussianImageFilter. */
template< class OutputImageType >
void GaussianImageFilter(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order );

template< class OutputImageType >
void GaussianImageFilterMagnitude(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order );

template< class OutputImageType >
void GaussianImageFilterLaplacian(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma );

/** Declare PrintHelp. */
void PrintHelp( void );

//-------------------------------------------------------------------------------------

int main( int argc, char ** argv )
{
 	/** Check arguments for help. */
	if ( argc < 3 || argc > 15 )
	{
		PrintHelp();
		return 1;
	}

	/** Create a command line argument parser. */
	itk::CommandLineArgumentParser::Pointer parser = itk::CommandLineArgumentParser::New();
	parser->SetCommandLineArguments( argc, argv );

	/** Get arguments. */
  std::string inputFileName = "";
	bool retin = parser->GetCommandLineArgument( "-in", inputFileName );

  std::vector<float> sigma;
  sigma.push_back(1.0); // default 1.0 for each resolution
  bool retstd = parser->GetCommandLineArgument( "-std", sigma );

  std::vector<unsigned int> order;
  bool retord = parser->GetCommandLineArgument( "-ord", order );

  std::string	outputFileName = inputFileName.substr( 0, inputFileName.rfind( "." ) );
	outputFileName += "BLURRED.mhd";
	bool retout = parser->GetCommandLineArgument( "-out", outputFileName );

	bool retmag = parser->ArgumentExists( "-mag" );
  bool retlap = parser->ArgumentExists( "-lap" );

  std::string componentType = "";
	bool retpt = parser->GetCommandLineArgument( "-pt", componentType );

 	/** Check if the required arguments are given. */
	if ( !retin )
	{
		std::cerr << "ERROR: You should specify \"-in\"." << std::endl;
		return 1;
	}

  /** Check options. */
  for ( unsigned int i = 0; i < order.size(); ++i )
  {
    if ( order[ i ] > 2 )
    {
      std::cerr << "ERROR: The order should not be higher than 2." << std::endl;
      std::cerr << "Only zeroth, first and second order derivatives are supported." << std::endl;
      return 1;
    }
  }

  /** Check that not both mag and lap are given. */
  if ( retmag && retlap )
  {
    std::cerr << "ERROR: only one of \"-mag\" and \"-lap\" should be given!" << std::endl;
    return 1;
  }

  /** Determine image properties. */
  std::string ComponentTypeIn = "short";
  std::string	PixelType; //we don't use this
  unsigned int Dimension = 3;
  unsigned int NumberOfComponents = 1;
  std::vector<unsigned int> imagesize( Dimension, 0 );
  int retgip = GetImageProperties(
    inputFileName,
    PixelType,
    ComponentTypeIn,
    Dimension,
    NumberOfComponents,
    imagesize );
  if ( retgip != 0 )
  {
    return 1;
  }

  /** The default output is equal to the input, but can be overridden by
   * specifying -pt in the command line.
   */
  if ( !retpt ) componentType = ComponentTypeIn;

  /** Check for vector images. */
  if ( NumberOfComponents > 1 )
  {
    std::cerr << "ERROR: The NumberOfComponents is larger than 1!" << std::endl;
    std::cerr << "Cannot make vector of vector images." << std::endl;
    return 1;
  }

	/** Get rid of the possible "_" in ComponentType. */
  ReplaceUnderscoreWithSpace( ComponentTypeIn );

  /** Check order. */
  if ( order.size() != Dimension )
  {
    std::cerr << "ERROR: the # of orders should be equal to the image dimension!" << std::endl;
    return 1;
  }

  /** Check sigma. */
  if ( sigma.size() != 1 && sigma.size() != Dimension )
  {
    std::cerr << "ERROR: the # of sigmas should be equal to 1 or the image dimension!" << std::endl;
    return 1;
  }

  /** Run the program. */
  bool supported = false;
	try
	{
    run( GaussianImageFilter, char, 2 );
		run( GaussianImageFilter, unsigned char, 2 );
    run( GaussianImageFilter, short, 2 );
		run( GaussianImageFilter, unsigned short, 2 );
    run( GaussianImageFilter, int, 2 );
		run( GaussianImageFilter, unsigned int, 2 );
    run( GaussianImageFilter, long, 2 );
		run( GaussianImageFilter, unsigned long, 2 );
    run( GaussianImageFilter, float, 2 );
		run( GaussianImageFilter, double, 2 );

    run( GaussianImageFilter, char, 3 );
		run( GaussianImageFilter, unsigned char, 3 );
    run( GaussianImageFilter, short, 3 );
		run( GaussianImageFilter, unsigned short, 3 );
    run( GaussianImageFilter, int, 3 );
		run( GaussianImageFilter, unsigned int, 3 );
    run( GaussianImageFilter, long, 3 );
		run( GaussianImageFilter, unsigned long, 3 );
    run( GaussianImageFilter, float, 3 );
		run( GaussianImageFilter, double, 3 );

	}
	catch( itk::ExceptionObject &e )
	{
		std::cerr << "Caught ITK exception: " << e << std::endl;
		return 1;
	}
  if ( !supported )
  {
    std::cerr << "ERROR: this combination of pixeltype and dimension is not supported!" << std::endl;
    std::cerr <<
      "pixel (component) type = " << ComponentTypeIn <<
      " ; dimension = " << Dimension
      << std::endl;
    return 1;
  }

	/** End program. */
	return 0;

} // end main

	/**
	 * ******************* GaussianImageFilter *******************
	 */

template< class OutputImageType >
void GaussianImageFilter(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order )
{
  /** Typedef's. */
  const unsigned int Dimension = OutputImageType::ImageDimension;
  typedef float                                           InputPixelType;
  typedef itk::Image< InputPixelType, Dimension >         InputImageType;
	typedef itk::ImageFileReader< InputImageType >			    ReaderType;
	typedef itk::SmoothingRecursiveGaussianImageFilter2<
    InputImageType, OutputImageType >                     FilterType;
  typedef typename FilterType::OrderType                  OrderType;
  typedef typename FilterType::SigmaType                  SigmaType;
	typedef itk::ImageFileWriter< OutputImageType >			    WriterType;

	/**	Read in the input image. */
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputFileName );

  /** Setup the order and sigma. */
  OrderType orderFA;
  SigmaType sigmaFA;
  sigmaFA.Fill( sigma[ 0 ] );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    orderFA[ i ] = order[ i ];
    if ( sigma.size() == Dimension ) sigmaFA[ i ] = sigma[ i ];
  }

  /** Setup the smoothing filter. */
  typename FilterType::Pointer filter = FilterType::New();
  filter->SetNormalizeAcrossScale( false );
  filter->SetInput( reader->GetOutput() );
  filter->SetSigma( sigmaFA );
  filter->SetOrder( orderFA );

  /** Write image. */
  typename WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( outputFileName );
	writer->SetInput( filter->GetOutput() );
  writer->Update();

} // end GaussianImageFilter()

  /**
	 * ******************* GaussianImageFilterMagnitude *******************
	 */

template< class OutputImageType >
void GaussianImageFilterMagnitude(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma,
  const std::vector<unsigned int> & order )
{
  /** Typedef's. */
  const unsigned int Dimension = OutputImageType::ImageDimension;
  typedef float                                           InputPixelType;
  typedef itk::Image< InputPixelType, Dimension >         InputImageType;
	typedef itk::ImageFileReader< InputImageType >			    ReaderType;
	typedef itk::SmoothingRecursiveGaussianImageFilter2<
    InputImageType, InputImageType >                      SmoothingFilterType;
  typedef typename SmoothingFilterType::Pointer           SmoothingFilterPointer;
  typedef typename SmoothingFilterType::OrderType         OrderType;
  typedef typename SmoothingFilterType::SigmaType         SigmaType;
  typedef itk::ImageToVectorImageFilter<
    InputImageType >                                      ImageToVectorImageFilterType;
  typedef typename ImageToVectorImageFilterType
    ::OutputImageType                                     VectorImageType;
  typedef itk::GradientToMagnitudeImageFilter<
    VectorImageType, OutputImageType >                    MagnitudeFilterType;
	typedef itk::ImageFileWriter< OutputImageType >			    WriterType;

	/**	Read in the input image. */
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputFileName );

  /** Setup the order and sigma. */
  OrderType orderFA;
  SigmaType sigmaFA;
  sigmaFA.Fill( sigma[ 0 ] );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    orderFA[ i ] = order[ i ];
    if ( sigma.size() == Dimension ) sigmaFA[ i ] = sigma[ i ];
  }

  /** Setup filters. */
  std::vector< SmoothingFilterPointer > smoothingFilter( Dimension );
  typename ImageToVectorImageFilterType::Pointer composeFilter
    = ImageToVectorImageFilterType::New();
  typename MagnitudeFilterType::Pointer magnitudeFilter = MagnitudeFilterType::New();
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    /** Setup smoothing filter. */
    smoothingFilter[ i ] = SmoothingFilterType::New();
    smoothingFilter[ i ]->SetInput( reader->GetOutput() );
    smoothingFilter[ i ]->SetNormalizeAcrossScale( false );
    OrderType order2; order2.Fill( 0 ); order2[ i ] = orderFA[ i ];
    smoothingFilter[ i ]->SetSigma( sigmaFA );
    smoothingFilter[ i ]->SetOrder( order2 );
    smoothingFilter[ i ]->Update();

    /** Setup composition filter. */
    composeFilter->SetNthInput( i, smoothingFilter[ i ]->GetOutput() );
  }

  /** Compose vector image and compute magnitude. */
  magnitudeFilter->SetInput( composeFilter->GetOutput() );
  magnitudeFilter->Update();

  /** Write image. */
  typename WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( outputFileName );
	writer->SetInput( magnitudeFilter->GetOutput() );
  writer->Update();

} // end GaussianImageFilterMagnitude()

  /**
	 * ******************* GaussianImageFilterLaplacian *******************
	 */

template< class OutputImageType >
void GaussianImageFilterLaplacian(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const std::vector<float> & sigma )
{
  /** Typedef's. */
  const unsigned int Dimension = OutputImageType::ImageDimension;
  typedef typename OutputImageType::PixelType             OutputPixelType;
  typedef float                                           InputPixelType;
  typedef itk::Image< InputPixelType, Dimension >         InputImageType;
	typedef itk::ImageFileReader< InputImageType >			    ReaderType;
	typedef itk::SmoothingRecursiveGaussianImageFilter2<
    InputImageType, InputImageType >                      SmoothingFilterType;
  typedef typename SmoothingFilterType::Pointer           SmoothingFilterPointer;
  typedef typename SmoothingFilterType::OrderType         OrderType;
  typedef typename SmoothingFilterType::SigmaType         SigmaType;
  typedef itk::ImageRegionConstIterator< InputImageType > ConstIteratorType;
  typedef itk::ImageRegionIterator< OutputImageType >     IteratorType;
	typedef itk::ImageFileWriter< OutputImageType >			    WriterType;

	/**	Read in the input image. */
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputFileName );

  /** Setup sigma. */
  SigmaType sigmaFA; sigmaFA.Fill( sigma[ 0 ] );
  if ( sigma.size() == Dimension )
  {
    for ( unsigned int i = 0; i < Dimension; ++i )
    {
      sigmaFA[ i ] = sigma[ i ];
    }
  }

  /** Setup filters. */
  std::vector< SmoothingFilterPointer > smoothingFilter( Dimension );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    /** Setup smoothing filter. */
    smoothingFilter[ i ] = SmoothingFilterType::New();
    smoothingFilter[ i ]->SetInput( reader->GetOutput() );
    smoothingFilter[ i ]->SetNormalizeAcrossScale( false );
    OrderType order; order.Fill( 0 ); order[ i ] = 2;
    smoothingFilter[ i ]->SetSigma( sigmaFA );
    smoothingFilter[ i ]->SetOrder( order );
    smoothingFilter[ i ]->Update();
  }

  /** Create output image. */
  typename OutputImageType::Pointer outputImage = OutputImageType::New();
  outputImage->CopyInformation( reader->GetOutput() );
  outputImage->SetRegions( reader->GetOutput()->GetLargestPossibleRegion() );
  outputImage->Allocate();

  /** Setup iterators. */
  std::vector< ConstIteratorType > itIn( Dimension );
  for ( unsigned int i = 0; i < Dimension; ++i )
  {
    itIn[ i ] = ConstIteratorType( smoothingFilter[ i ]->GetOutput(),
      smoothingFilter[ i ]->GetOutput()->GetLargestPossibleRegion() );
    itIn[ i ].GoToBegin();
  }
  IteratorType itOut( outputImage, outputImage->GetLargestPossibleRegion() );
  itOut.GoToBegin();

  /** Fill the output image by adding the second order derivatives. */
  while ( !itOut.IsAtEnd() )
  {
    InputPixelType value = itk::NumericTraits<InputPixelType>::Zero;
    for ( unsigned int i = 0; i < Dimension; ++i )
    {
      value += itIn[ i ].Get();
      ++itIn[ i ];
    }
    itOut.Set( static_cast<OutputPixelType>( value ) );
    ++itOut;
  }

  /** Write image. */
  typename WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( outputFileName );
	writer->SetInput( outputImage );
  writer->Update();

} // end GaussianImageFilterLaplacian()

	/**
	 * ******************* PrintHelp *******************
	 */
void PrintHelp()
{
	std::cout << "Usage:" << std::endl << "pxgaussianimagefilter" << std::endl;
	std::cout << "  -in      inputFilename" << std::endl;
	std::cout << "  [-out]   outputFilename, default in + BLURRED.mhd" << std::endl;
  std::cout << "  [-std]   sigma, for each dimension, default 1.0" << std::endl;
  std::cout << "  [-ord]   order, for each dimension, default zero\n";
  std::cout << "             0: zero order = blurring\n";
  std::cout << "             1: first order = gradient\n";
  std::cout << "             2: second order derivative" << std::endl;
  std::cout << "  [-mag]   compute the magnitude of the separate blurrings, default false" << std::endl;
  std::cout << "  [-lap]   compute the laplacian, default false" << std::endl;
  std::cout << "  [-pt]    output pixel type, default equal to input" << std::endl;
	std::cout << "Supported: 2D, 3D, (unsigned) char, (unsigned) short, (unsigned) int, (unsigned) long, float, double." << std::endl;
} // end PrintHelp()

<|endoftext|>


<commit_before>#include <QtTest/QtTest>
#include "shellcontents.h"
#include "helpers.h"

class Test: public QObject
{
	Q_OBJECT

public:
	// Initialize a shell with contents
	//     a b c d e ..
	//     a b c d e ..
	//     ...
	ShellContents initShell(int rows, int cols) {
		ShellContents s(rows,cols);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				s.value(i, j).c = QChar('a'+j);
			}
		}
		return s;
	}
	// Check if the contents are the same as returned
	// by initShell
	void checkInitShell(const ShellContents& s) {
		for (int i=0; i<s.rows(); i++) {
			for (int j=0; j<s.columns(); j++) {
				QCOMPARE(s.constValue(i, j).c, QChar('a'+j));
			}
		}
	}
	// True if the shell is clear
	bool checkClear(const ShellContents& s) {
		for (int i=0; i<s.rows(); i++) {
			for (int j=0; j<s.columns(); j++) {
				QChar c = s.constValue(i, j).c;
				if (c != QChar(' ')) {
					qDebug() << __func__ << i << j << c;
					return false;
				}
			}
		}
		return true;
	}
	// Create a shell with
	//     a a a a
	//     b b b b
	//     ...
	ShellContents initShellScroll(int rows, int cols) {
		ShellContents s(rows,cols);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				s.value(i, j).c = QChar('a'+i);
			}
		}
		return s;
	}
	bool checkScrollShell(const ShellContents& s) {
		for (int i=0; i<s.rows(); i++) {
			for (int j=0; j<s.columns(); j++) {
				QChar c = s.constValue(i, j).c;
				if (c != QChar('a'+i)) {
					qDebug() << __func__ << i << j << c;
					return false;
				}
			}
		}
		return true;
	}

private slots:
	void cellDefault() {
		int rows = 40;
		int cols = 60;
		ShellContents s(rows,cols);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s.value(i, j).c, QChar(' '));
			}
		}

		// invalid cells are initialized as red X
		QCOMPARE(s.value(-1, -1).c, QChar('X'));
		QCOMPARE(s.value(-1, -1).backgroundColor, QColor(Qt::red));

		QBENCHMARK {
			ShellContents s(100,100);
		}
	}

	void resize() {
		int rows = 40;
		int cols = 60;
		ShellContents s = initShell(rows, cols);

		// These should have no effect
		s.resize(-10, -10);
		s.resize(0, 0);

		// resize() changes columns()/rows()
		s.resize(rows-1, cols);
		QCOMPARE(s.rows(), rows-1);
		s.resize(rows-1,cols-1);
		QCOMPARE(s.columns(), cols-1);

		// shrink
		s.resize(20, 20);
		for (int i=0; i<20; i++) {
			for (int j=0; j<20; j++) {
				QCOMPARE(s.value(i, j).c, QChar('a'+j));
			}
		}

		// grow
		s.resize(30, 30);
		for (int i=0; i<20; i++) {
			for (int j=0; j<20; j++) {
				QCOMPARE(s.value(i, j).c, QChar('a'+j));
			}
		}
		for (int i=20; i<30; i++) {
			for (int j=20; j<30; j++) {
				QCOMPARE(s.value(i, j).c, QChar(' '));
			}
		}

	}

	void resizeBench() {
		ShellContents s(100,100);
		QBENCHMARK {
			s.resize(50, 50);
		}
	}

	void clearRow() {
		int rows = 40;
		int cols = 60;
		ShellContents s = initShell(rows, cols);

		s.clearRow(3);
		// These should have no effect
		s.clearRow(-1);
		s.clearRow(55);

		for (int i=0; i<rows; i++) {
			if (i == 3) {
				for (int j=0; j<cols; j++) {
					QCOMPARE(s.value(i, j).c, QChar(' '));
				}
			} else {
				for (int j=0; j<cols; j++) {
					QCOMPARE(s.value(i, j).c, QChar('a'+j));
				}
			}
		}

		ShellContents s1 = initShell(rows, cols);
		// Clear row (starting at col 10)
		s1.clearRow(20, 10);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				if (i == 20 && j >= 10) {
					QCOMPARE(s1.value(i, j).c, QChar(' '));
				} else {
					QCOMPARE(s1.value(i, j).c, QChar('a'+j));
				}
			}
		}
	}

	void clearRowBench() {
		ShellContents s = initShell(100, 100);
		QBENCHMARK {
			s.clearRow(50);
		}
	}

	void clearRegion() {
		int rows = 100;
		int columns = 100;
		ShellContents s = initShell(rows, columns);

		// These should have no effect
		s.clearRegion(200, 0, 10, 10);
		s.clearRegion(0, 200, 10, 10);
		s.clearRegion(0, 0, -10, 10);
		s.clearRegion(0, 0, 10, -10);
		checkInitShell(s);

		s.clearRegion(0, 0, 10, 10);
		for (int i=0; i<10; i++) {
			for (int j=0; j<10; j++) {
				QCOMPARE(s.value(i, j), Cell());
			}
		}
		// Similar to checkInitShell
		for (int i=10; i<rows; i++) {
			for (int j=0; j<columns; j++) {
				Cell c; c.c = 'a'+j;
				QCOMPARE(s.value(i, j), c);
			}
		}

		ShellContents s2 = ShellContents(1, 1);
		QCOMPARE(s2.value(0, 0), Cell());
		// A region with size 0 causes no change
		s2.clearRegion(0, 0, 0, 0, Qt::blue);
		QCOMPARE(s2.value(0, 0), Cell());

		ShellContents s3 = ShellContents(4, 4);
		s3.clearRegion(1, 1, 3, 3, Qt::blue);
		saveShellContents(s3, "clearRegion.jpg");
		QCOMPARE(s3.value(0, 0), Cell());
		QCOMPARE(s3.value(0, 1), Cell());
		QCOMPARE(s3.value(0, 1), Cell());
		QCOMPARE(s3.value(1, 1), Cell::bg(Qt::blue));

		QCOMPARE(s3.value(3, 3), Cell());
	}

	void clearAll() {
		int rows = 26;
		int cols = 100;
		ShellContents s = initShell(rows, cols);

		s.clearAll();
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s.value(i, j), Cell());
			}
		}
	}

	void scrollRegion() {
		int rows = 100;
		int cols = 100;

		ShellContents s0 = initShell(rows, cols);
		// This does nothing
		s0.scroll(0);
		checkInitShell(s0);

		// This is the same as clear
		s0.scroll(100);
		QVERIFY(checkClear(s0));

		ShellContents s1 = initShell(rows, cols);
		// This is the same as clear (scrolls to bottom)
		s1.scroll(-100);
		QVERIFY(checkClear(s1));

		// Scroll 10 lines up
		ShellContents s2 = initShellScroll(rows,cols);
		s2.scroll(10);
		for (int i=0; i<rows-10; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s2.value(i, j).c, QChar('a'+i+10));
			}
		}
		for (int i=rows-10; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				// The bottom region is empty
				QCOMPARE(s2.value(i, j).c, QChar(' '));
			}
		}

		// Scroll 10 lines down
		ShellContents s3 = initShellScroll(rows,cols);
		s3.scroll(-10);
		for (int i=10; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s3.value(i, j).c, QChar('a'+i-10));
			}
		}
		for (int i=0; i<10; i++) {
			for (int j=0; j<cols; j++) {
				// The top region is empty
				QCOMPARE(s3.value(i, j).c, QChar(' '));
			}
		}
	}

	void scrollRegion2() {
		int rows = 100;
		int cols = 100;

		ShellContents s0 = initShell(rows, cols);
		s0.clearRow(0);
		s0.clearRow(99);

		// FIXME: is this inclusive or NOT?
		s0.scrollRegion(1, 99, 0, 100, 1);

		for (int j=0; j<cols; j++) {
			QCOMPARE(s0.value(0, j),  Cell());
			QCOMPARE(s0.value(cols-1, j),  Cell());
		}
		s0.scrollRegion(1, 99, 0, 100, -1);
		for (int j=0; j<cols; j++) {
			QCOMPARE(s0.value(0, j),  Cell());
			QCOMPARE(s0.value(cols-1, j),  Cell());
		}
	}

	void put() {
		int rows = 10;
		int cols = 10;

		ShellContents s0(rows, cols);
		s0.put("HelloWorld", 0, 0);

		QCOMPARE(s0.value(0, 0).c, QChar('H'));
		QCOMPARE(s0.value(0, 1).c, QChar('e'));
		QCOMPARE(s0.value(0, 2).c, QChar('l'));
		QCOMPARE(s0.value(0, 3).c, QChar('l'));
		QCOMPARE(s0.value(0, 4).c, QChar('o'));
		QCOMPARE(s0.value(0, 5).c, QChar('W'));
		QCOMPARE(s0.value(0, 6).c, QChar('o'));
		QCOMPARE(s0.value(0, 7).c, QChar('r'));
		QCOMPARE(s0.value(0, 8).c, QChar('l'));
		QCOMPARE(s0.value(0, 9).c, QChar('d'));

		s0.put("HelloWorld", 5, 5);
		saveShellContents(s0, "shell.jpg");
		QCOMPARE(s0.value(5, 0).c, QChar(' '));
		QCOMPARE(s0.value(5, 1).c, QChar(' '));
		QCOMPARE(s0.value(5, 2).c, QChar(' '));
		QCOMPARE(s0.value(5, 3).c, QChar(' '));
		QCOMPARE(s0.value(5, 4).c, QChar(' '));
		QCOMPARE(s0.value(5, 5).c, QChar('H'));
		QCOMPARE(s0.value(5, 6).c, QChar('e'));
		QCOMPARE(s0.value(5, 7).c, QChar('l'));
		QCOMPARE(s0.value(5, 8).c, QChar('l'));
		QCOMPARE(s0.value(5, 9).c, QChar('o'));
	}

	// Grab test cases from ../test/shellcontents
	void cases() {
		QDir dir("../test/shellcontents/");
		QFileInfoList files = dir.entryInfoList();
		foreach(const QFileInfo &fi, files) {
			if (!fi.isFile() || !fi.fileName().startsWith("shell")
					|| fi.suffix() != "txt") {
				continue;
			}
			ShellContents s(0, 0);
			QCOMPARE(s.fromFile(fi.absoluteFilePath()), true);

			QString out("test/");
			out.append(fi.fileName().append(".out.jpeg"));
			saveShellContents(s, out);

			// Compare file with previous test output

		}
	}
};

QTEST_MAIN(Test)
#include "test_shellcontents.moc"
<commit_msg>Remove old debug statements<commit_after>#include <QtTest/QtTest>
#include "shellcontents.h"
#include "helpers.h"

class Test: public QObject
{
	Q_OBJECT

public:
	// Initialize a shell with contents
	//     a b c d e ..
	//     a b c d e ..
	//     ...
	ShellContents initShell(int rows, int cols) {
		ShellContents s(rows,cols);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				s.value(i, j).c = QChar('a'+j);
			}
		}
		return s;
	}
	// Check if the contents are the same as returned
	// by initShell
	void checkInitShell(const ShellContents& s) {
		for (int i=0; i<s.rows(); i++) {
			for (int j=0; j<s.columns(); j++) {
				QCOMPARE(s.constValue(i, j).c, QChar('a'+j));
			}
		}
	}
	// True if the shell is clear
	bool checkClear(const ShellContents& s) {
		for (int i=0; i<s.rows(); i++) {
			for (int j=0; j<s.columns(); j++) {
				QChar c = s.constValue(i, j).c;
				if (c != QChar(' ')) {
					return false;
				}
			}
		}
		return true;
	}
	// Create a shell with
	//     a a a a
	//     b b b b
	//     ...
	ShellContents initShellScroll(int rows, int cols) {
		ShellContents s(rows,cols);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				s.value(i, j).c = QChar('a'+i);
			}
		}
		return s;
	}
	bool checkScrollShell(const ShellContents& s) {
		for (int i=0; i<s.rows(); i++) {
			for (int j=0; j<s.columns(); j++) {
				QChar c = s.constValue(i, j).c;
				if (c != QChar('a'+i)) {
					return false;
				}
			}
		}
		return true;
	}

private slots:
	void cellDefault() {
		int rows = 40;
		int cols = 60;
		ShellContents s(rows,cols);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s.value(i, j).c, QChar(' '));
			}
		}

		// invalid cells are initialized as red X
		QCOMPARE(s.value(-1, -1).c, QChar('X'));
		QCOMPARE(s.value(-1, -1).backgroundColor, QColor(Qt::red));

		QBENCHMARK {
			ShellContents s(100,100);
		}
	}

	void resize() {
		int rows = 40;
		int cols = 60;
		ShellContents s = initShell(rows, cols);

		// These should have no effect
		s.resize(-10, -10);
		s.resize(0, 0);

		// resize() changes columns()/rows()
		s.resize(rows-1, cols);
		QCOMPARE(s.rows(), rows-1);
		s.resize(rows-1,cols-1);
		QCOMPARE(s.columns(), cols-1);

		// shrink
		s.resize(20, 20);
		for (int i=0; i<20; i++) {
			for (int j=0; j<20; j++) {
				QCOMPARE(s.value(i, j).c, QChar('a'+j));
			}
		}

		// grow
		s.resize(30, 30);
		for (int i=0; i<20; i++) {
			for (int j=0; j<20; j++) {
				QCOMPARE(s.value(i, j).c, QChar('a'+j));
			}
		}
		for (int i=20; i<30; i++) {
			for (int j=20; j<30; j++) {
				QCOMPARE(s.value(i, j).c, QChar(' '));
			}
		}

	}

	void resizeBench() {
		ShellContents s(100,100);
		QBENCHMARK {
			s.resize(50, 50);
		}
	}

	void clearRow() {
		int rows = 40;
		int cols = 60;
		ShellContents s = initShell(rows, cols);

		s.clearRow(3);
		// These should have no effect
		s.clearRow(-1);
		s.clearRow(55);

		for (int i=0; i<rows; i++) {
			if (i == 3) {
				for (int j=0; j<cols; j++) {
					QCOMPARE(s.value(i, j).c, QChar(' '));
				}
			} else {
				for (int j=0; j<cols; j++) {
					QCOMPARE(s.value(i, j).c, QChar('a'+j));
				}
			}
		}

		ShellContents s1 = initShell(rows, cols);
		// Clear row (starting at col 10)
		s1.clearRow(20, 10);
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				if (i == 20 && j >= 10) {
					QCOMPARE(s1.value(i, j).c, QChar(' '));
				} else {
					QCOMPARE(s1.value(i, j).c, QChar('a'+j));
				}
			}
		}
	}

	void clearRowBench() {
		ShellContents s = initShell(100, 100);
		QBENCHMARK {
			s.clearRow(50);
		}
	}

	void clearRegion() {
		int rows = 100;
		int columns = 100;
		ShellContents s = initShell(rows, columns);

		// These should have no effect
		s.clearRegion(200, 0, 10, 10);
		s.clearRegion(0, 200, 10, 10);
		s.clearRegion(0, 0, -10, 10);
		s.clearRegion(0, 0, 10, -10);
		checkInitShell(s);

		s.clearRegion(0, 0, 10, 10);
		for (int i=0; i<10; i++) {
			for (int j=0; j<10; j++) {
				QCOMPARE(s.value(i, j), Cell());
			}
		}
		// Similar to checkInitShell
		for (int i=10; i<rows; i++) {
			for (int j=0; j<columns; j++) {
				Cell c; c.c = 'a'+j;
				QCOMPARE(s.value(i, j), c);
			}
		}

		ShellContents s2 = ShellContents(1, 1);
		QCOMPARE(s2.value(0, 0), Cell());
		// A region with size 0 causes no change
		s2.clearRegion(0, 0, 0, 0, Qt::blue);
		QCOMPARE(s2.value(0, 0), Cell());

		ShellContents s3 = ShellContents(4, 4);
		s3.clearRegion(1, 1, 3, 3, Qt::blue);
		saveShellContents(s3, "clearRegion.jpg");
		QCOMPARE(s3.value(0, 0), Cell());
		QCOMPARE(s3.value(0, 1), Cell());
		QCOMPARE(s3.value(0, 1), Cell());
		QCOMPARE(s3.value(1, 1), Cell::bg(Qt::blue));

		QCOMPARE(s3.value(3, 3), Cell());
	}

	void clearAll() {
		int rows = 26;
		int cols = 100;
		ShellContents s = initShell(rows, cols);

		s.clearAll();
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s.value(i, j), Cell());
			}
		}
	}

	void scrollRegion() {
		int rows = 100;
		int cols = 100;

		ShellContents s0 = initShell(rows, cols);
		// This does nothing
		s0.scroll(0);
		checkInitShell(s0);

		// This is the same as clear
		s0.scroll(100);
		QVERIFY(checkClear(s0));

		ShellContents s1 = initShell(rows, cols);
		// This is the same as clear (scrolls to bottom)
		s1.scroll(-100);
		QVERIFY(checkClear(s1));

		// Scroll 10 lines up
		ShellContents s2 = initShellScroll(rows,cols);
		s2.scroll(10);
		for (int i=0; i<rows-10; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s2.value(i, j).c, QChar('a'+i+10));
			}
		}
		for (int i=rows-10; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				// The bottom region is empty
				QCOMPARE(s2.value(i, j).c, QChar(' '));
			}
		}

		// Scroll 10 lines down
		ShellContents s3 = initShellScroll(rows,cols);
		s3.scroll(-10);
		for (int i=10; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				QCOMPARE(s3.value(i, j).c, QChar('a'+i-10));
			}
		}
		for (int i=0; i<10; i++) {
			for (int j=0; j<cols; j++) {
				// The top region is empty
				QCOMPARE(s3.value(i, j).c, QChar(' '));
			}
		}
	}

	void scrollRegion2() {
		int rows = 100;
		int cols = 100;

		ShellContents s0 = initShell(rows, cols);
		s0.clearRow(0);
		s0.clearRow(99);

		// FIXME: is this inclusive or NOT?
		s0.scrollRegion(1, 99, 0, 100, 1);

		for (int j=0; j<cols; j++) {
			QCOMPARE(s0.value(0, j),  Cell());
			QCOMPARE(s0.value(cols-1, j),  Cell());
		}
		s0.scrollRegion(1, 99, 0, 100, -1);
		for (int j=0; j<cols; j++) {
			QCOMPARE(s0.value(0, j),  Cell());
			QCOMPARE(s0.value(cols-1, j),  Cell());
		}
	}

	void put() {
		int rows = 10;
		int cols = 10;

		ShellContents s0(rows, cols);
		s0.put("HelloWorld", 0, 0);

		QCOMPARE(s0.value(0, 0).c, QChar('H'));
		QCOMPARE(s0.value(0, 1).c, QChar('e'));
		QCOMPARE(s0.value(0, 2).c, QChar('l'));
		QCOMPARE(s0.value(0, 3).c, QChar('l'));
		QCOMPARE(s0.value(0, 4).c, QChar('o'));
		QCOMPARE(s0.value(0, 5).c, QChar('W'));
		QCOMPARE(s0.value(0, 6).c, QChar('o'));
		QCOMPARE(s0.value(0, 7).c, QChar('r'));
		QCOMPARE(s0.value(0, 8).c, QChar('l'));
		QCOMPARE(s0.value(0, 9).c, QChar('d'));

		s0.put("HelloWorld", 5, 5);
		saveShellContents(s0, "shell.jpg");
		QCOMPARE(s0.value(5, 0).c, QChar(' '));
		QCOMPARE(s0.value(5, 1).c, QChar(' '));
		QCOMPARE(s0.value(5, 2).c, QChar(' '));
		QCOMPARE(s0.value(5, 3).c, QChar(' '));
		QCOMPARE(s0.value(5, 4).c, QChar(' '));
		QCOMPARE(s0.value(5, 5).c, QChar('H'));
		QCOMPARE(s0.value(5, 6).c, QChar('e'));
		QCOMPARE(s0.value(5, 7).c, QChar('l'));
		QCOMPARE(s0.value(5, 8).c, QChar('l'));
		QCOMPARE(s0.value(5, 9).c, QChar('o'));
	}

	// Grab test cases from ../test/shellcontents
	void cases() {
		QDir dir("../test/shellcontents/");
		QFileInfoList files = dir.entryInfoList();
		foreach(const QFileInfo &fi, files) {
			if (!fi.isFile() || !fi.fileName().startsWith("shell")
					|| fi.suffix() != "txt") {
				continue;
			}
			ShellContents s(0, 0);
			QCOMPARE(s.fromFile(fi.absoluteFilePath()), true);

			QString out("test/");
			out.append(fi.fileName().append(".out.jpeg"));
			saveShellContents(s, out);

			// Compare file with previous test output

		}
	}
};

QTEST_MAIN(Test)
#include "test_shellcontents.moc"
<|endoftext|>


<commit_before>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#include "jitpch.h"
#ifdef _MSC_VER
#pragma hdrstop
#endif

#include "inlinepolicy.h"

//------------------------------------------------------------------------
// getPolicy: Factory method for getting an InlinePolicy
//
// Arguments:
//    compiler     - the compiler instance that will evaluate inlines
//    isPrejitRoot - true if this policy is evaluating a prejit root
//
// Return Value:
//    InlinePolicy to use in evaluating the inlines
//
// Notes:
//    Determines which of the various policies should apply,
//    and creates (or reuses) a policy instance to use.

InlinePolicy* InlinePolicy::getPolicy(Compiler* compiler, bool isPrejitRoot)
{
    // For now, always create a Legacy policy.
    InlinePolicy* policy = new (compiler, CMK_Inlining) LegacyPolicy(compiler, isPrejitRoot);

    return policy;
}

//------------------------------------------------------------------------
// noteSuccess: handle finishing all the inlining checks successfully

void LegacyPolicy::noteSuccess()
{
    assert(inlDecisionIsCandidate(inlDecision));
    inlDecision = InlineDecision::SUCCESS;
}

//------------------------------------------------------------------------
// note: handle an observation with non-fatal impact
//
// Arguments:
//    obs      - the current obsevation
//    value    - the value of the observation

void LegacyPolicy::noteBool(InlineObservation obs, bool value)
{
    // Check the impact
    InlineImpact impact = inlGetImpact(obs);

    // As a safeguard, all fatal impact must be
    // reported via noteFatal.
    assert(impact != InlineImpact::FATAL);

    // Handle most information here
    bool isInformation = (impact == InlineImpact::INFORMATION);
    bool propagate = !isInformation;

    if (isInformation)
    {
        switch (obs)
        {
        case InlineObservation::CALLEE_IS_FORCE_INLINE:
            // We may make the force-inline observation more than
            // once.  All observations should agree.
            assert(!inlIsForceInlineKnown || (inlIsForceInline == value));
            inlIsForceInline = value;
            inlIsForceInlineKnown = true;
            break;
        case InlineObservation::CALLEE_IS_INSTANCE_CTOR:
            inlIsInstanceCtor = value;
            break;
        case InlineObservation::CALLEE_CLASS_PROMOTABLE:
            inlIsFromPromotableValueClass = value;
            break;
        case InlineObservation::CALLEE_HAS_SIMD:
            inlHasSimd = value;
            break;
        case InlineObservation::CALLEE_LOOKS_LIKE_WRAPPER:
            inlLooksLikeWrapperMethod = value;
            break;
        case InlineObservation::CALLEE_ARG_FEEDS_CONSTANT_TEST:
            inlArgFeedsConstantTest = value;
            break;
        case InlineObservation::CALLEE_ARG_FEEDS_RANGE_CHECK:
            inlArgFeedsRangeCheck = value;
            break;
        case InlineObservation::CALLEE_IS_MOSTLY_LOAD_STORE:
            inlMethodIsMostlyLoadStore = value;
            break;
        case InlineObservation::CALLEE_HAS_SWITCH:
            // Pass this one on, it should cause inlining to fail.
            propagate = true;
            break;
        case InlineObservation::CALLSITE_CONSTANT_ARG_FEEDS_TEST:
            inlConstantFeedsConstantTest = value;
            break;
        case InlineObservation::CALLSITE_NATIVE_SIZE_ESTIMATE_OK:
            // Passed the profitability screen. Update candidacy.
            setCandidate(obs);
            break;
        default:
            // Ignore the remainder for now
            break;
        }
    }

    if (propagate)
    {
        noteInternal(obs);
    }
}

//------------------------------------------------------------------------
// noteFatal: handle an observation with fatal impact
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::noteFatal(InlineObservation obs)
{
    // As a safeguard, all fatal impact must be
    // reported via noteFatal.
    assert(inlGetImpact(obs) == InlineImpact::FATAL);
    noteInternal(obs);
    assert(inlDecisionIsFailure(inlDecision));
}

//------------------------------------------------------------------------
// noteInt: handle an observed integer value
//
// Arguments:
//    obs      - the current obsevation
//    value    - the value being observed

void LegacyPolicy::noteInt(InlineObservation obs, int value)
{
    switch (obs)
    {
    case InlineObservation::CALLEE_MAXSTACK:
        {
            assert(inlIsForceInlineKnown);

            unsigned calleeMaxStack = static_cast<unsigned>(value);

            if (!inlIsForceInline && (calleeMaxStack > SMALL_STACK_SIZE))
            {
                setNever(InlineObservation::CALLEE_MAXSTACK_TOO_BIG);
            }

            break;
        }

    case InlineObservation::CALLEE_NUMBER_OF_BASIC_BLOCKS:
        {
            assert(inlIsForceInlineKnown);
            assert(value != 0);

            unsigned basicBlockCount = static_cast<unsigned>(value);

            if (!inlIsForceInline && (basicBlockCount > MAX_BASIC_BLOCKS))
            {
                setNever(InlineObservation::CALLEE_TOO_MANY_BASIC_BLOCKS);
            }

            break;
        }

    case InlineObservation::CALLEE_IL_CODE_SIZE:
        {
            assert(inlIsForceInlineKnown);
            assert(value != 0);
            unsigned ilByteSize = static_cast<unsigned>(value);

            // Now that we know size and forceinline state,
            // update candidacy.
            if (ilByteSize <= ALWAYS_INLINE_SIZE)
            {
                // Candidate based on small size
                setCandidate(InlineObservation::CALLEE_BELOW_ALWAYS_INLINE_SIZE);
            }
            else if (inlIsForceInline)
            {
                // Candidate based on force inline
                setCandidate(InlineObservation::CALLEE_IS_FORCE_INLINE);
            }
            else if (ilByteSize <= inlCompiler->getImpInlineSize())
            {
                // Candidate, pending profitability evaluation
                setCandidate(InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE);
            }
            else
            {
                // Callee too big, not a candidate
                setNever(InlineObservation::CALLEE_TOO_MUCH_IL);
            }

            break;
        }

    default:
        // Ignore all other information
        break;
    }
}

//------------------------------------------------------------------------
// noteDouble: handle an observed double value
//
// Arguments:
//    obs      - the current obsevation
//    value    - the value being observed

void LegacyPolicy::noteDouble(InlineObservation obs, double value)
{
    // Ignore for now...
    (void) value;
    (void) obs;
}

//------------------------------------------------------------------------
// noteInternal: helper for handling an observation
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::noteInternal(InlineObservation obs)
{
    // Note any INFORMATION that reaches here will now cause failure.
    // Non-fatal INFORMATION observations must be handled higher up.
    InlineTarget target = inlGetTarget(obs);

    if (target == InlineTarget::CALLEE)
    {
        this->setNever(obs);
    }
    else
    {
        this->setFailure(obs);
    }
}

//------------------------------------------------------------------------
// setFailure: helper for setting a failing decision
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::setFailure(InlineObservation obs)
{
    // Expect a valid observation
    assert(inlIsValidObservation(obs));

    switch (inlDecision)
    {
    case InlineDecision::FAILURE:
        // Repeated failure only ok if evaluating a prejit root
        assert(inlIsPrejitRoot);
        break;
    case InlineDecision::UNDECIDED:
    case InlineDecision::CANDIDATE:
        inlDecision = InlineDecision::FAILURE;
        inlObservation = obs;
        break;
    default:
        // SUCCESS, NEVER, or ??
        assert(!"Unexpected inlDecision");
        unreached();
    }
}

//------------------------------------------------------------------------
// setNever: helper for setting a never decision
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::setNever(InlineObservation obs)
{
    // Expect a valid observation
    assert(inlIsValidObservation(obs));

    switch (inlDecision)
    {
    case InlineDecision::NEVER:
        // Repeated never only ok if evaluating a prejit root
        assert(inlIsPrejitRoot);
        break;
    case InlineDecision::UNDECIDED:
    case InlineDecision::CANDIDATE:
        inlDecision = InlineDecision::NEVER;
        inlObservation = obs;
        break;
    default:
        // SUCCESS, FAILURE or ??
        assert(!"Unexpected inlDecision");
        unreached();
    }
}

//------------------------------------------------------------------------
// setCandidate: helper updating candidacy
//
// Arguments:
//    obs      - the current obsevation
//
// Note:
//    Candidate observations are handled here. If the inline has already
//    failed, they're ignored. If there's already a candidate reason,
//    this new reason trumps it.

void LegacyPolicy::setCandidate(InlineObservation obs)
{
    // Ignore if this inline is going to fail.
    if (inlDecisionIsFailure(inlDecision))
    {
        return;
    }

    // We should not have declared success yet.
    assert(!inlDecisionIsSuccess(inlDecision));

    // Update, overriding any previous candidacy.
    inlDecision = InlineDecision::CANDIDATE;
    inlObservation = obs;
}

//------------------------------------------------------------------------
// determineMultiplier: determine benefit multiplier for this inline
//
// Notes: uses the accumulated set of observations to compute a
// profitability boost for the inline candidate.

double LegacyPolicy::determineMultiplier()
{
    double multiplier = 0;

    // Bump up the multiplier for instance constructors

    if (inlIsInstanceCtor)
    {
        multiplier += 1.5;
        JITDUMP("\nmultiplier in instance constructors increased to %g.", multiplier);
    }

    // Bump up the multiplier for methods in promotable struct

    if (inlIsFromPromotableValueClass)
    {
        multiplier += 3;
        JITDUMP("\nmultiplier in methods of promotable struct increased to %g.", multiplier);
    }

#ifdef FEATURE_SIMD

    if (inlHasSimd)
    {
        multiplier += JitConfig.JitInlineSIMDMultiplier();
        JITDUMP("\nInline candidate has SIMD type args, locals or return value.  Multiplier increased to %g.", multiplier);
    }

#endif // FEATURE_SIMD

    if (inlLooksLikeWrapperMethod)
    {
        multiplier += 1.0;
        JITDUMP("\nInline candidate looks like a wrapper method.  Multiplier increased to %g.", multiplier);
    }

    if (inlArgFeedsConstantTest)
    {
        multiplier += 1.0;
        JITDUMP("\nInline candidate has an arg that feeds a constant test.  Multiplier increased to %g.", multiplier);
    }

    if (inlMethodIsMostlyLoadStore)
    {
        multiplier += 3.0;
        JITDUMP("\nInline candidate is mostly loads and stores.  Multiplier increased to %g.", multiplier);
    }

    if (inlArgFeedsRangeCheck)
    {
        multiplier += 0.5;
        JITDUMP("\nInline candidate has arg that feeds range check.  Multiplier increased to %g.", multiplier);
    }

    if (inlConstantFeedsConstantTest)
    {
        multiplier += 3.0;
        JITDUMP("\nInline candidate has const arg that feeds a conditional.  Multiplier increased to %g.", multiplier);
    }

    return multiplier;
}
<commit_msg>Inliner: fix assert about repeated failing observations<commit_after>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#include "jitpch.h"
#ifdef _MSC_VER
#pragma hdrstop
#endif

#include "inlinepolicy.h"

//------------------------------------------------------------------------
// getPolicy: Factory method for getting an InlinePolicy
//
// Arguments:
//    compiler     - the compiler instance that will evaluate inlines
//    isPrejitRoot - true if this policy is evaluating a prejit root
//
// Return Value:
//    InlinePolicy to use in evaluating the inlines
//
// Notes:
//    Determines which of the various policies should apply,
//    and creates (or reuses) a policy instance to use.

InlinePolicy* InlinePolicy::getPolicy(Compiler* compiler, bool isPrejitRoot)
{
    // For now, always create a Legacy policy.
    InlinePolicy* policy = new (compiler, CMK_Inlining) LegacyPolicy(compiler, isPrejitRoot);

    return policy;
}

//------------------------------------------------------------------------
// noteSuccess: handle finishing all the inlining checks successfully

void LegacyPolicy::noteSuccess()
{
    assert(inlDecisionIsCandidate(inlDecision));
    inlDecision = InlineDecision::SUCCESS;
}

//------------------------------------------------------------------------
// note: handle an observation with non-fatal impact
//
// Arguments:
//    obs      - the current obsevation
//    value    - the value of the observation

void LegacyPolicy::noteBool(InlineObservation obs, bool value)
{
    // Check the impact
    InlineImpact impact = inlGetImpact(obs);

    // As a safeguard, all fatal impact must be
    // reported via noteFatal.
    assert(impact != InlineImpact::FATAL);

    // Handle most information here
    bool isInformation = (impact == InlineImpact::INFORMATION);
    bool propagate = !isInformation;

    if (isInformation)
    {
        switch (obs)
        {
        case InlineObservation::CALLEE_IS_FORCE_INLINE:
            // We may make the force-inline observation more than
            // once.  All observations should agree.
            assert(!inlIsForceInlineKnown || (inlIsForceInline == value));
            inlIsForceInline = value;
            inlIsForceInlineKnown = true;
            break;
        case InlineObservation::CALLEE_IS_INSTANCE_CTOR:
            inlIsInstanceCtor = value;
            break;
        case InlineObservation::CALLEE_CLASS_PROMOTABLE:
            inlIsFromPromotableValueClass = value;
            break;
        case InlineObservation::CALLEE_HAS_SIMD:
            inlHasSimd = value;
            break;
        case InlineObservation::CALLEE_LOOKS_LIKE_WRAPPER:
            inlLooksLikeWrapperMethod = value;
            break;
        case InlineObservation::CALLEE_ARG_FEEDS_CONSTANT_TEST:
            inlArgFeedsConstantTest = value;
            break;
        case InlineObservation::CALLEE_ARG_FEEDS_RANGE_CHECK:
            inlArgFeedsRangeCheck = value;
            break;
        case InlineObservation::CALLEE_IS_MOSTLY_LOAD_STORE:
            inlMethodIsMostlyLoadStore = value;
            break;
        case InlineObservation::CALLEE_HAS_SWITCH:
            // Pass this one on, it should cause inlining to fail.
            propagate = true;
            break;
        case InlineObservation::CALLSITE_CONSTANT_ARG_FEEDS_TEST:
            inlConstantFeedsConstantTest = value;
            break;
        case InlineObservation::CALLSITE_NATIVE_SIZE_ESTIMATE_OK:
            // Passed the profitability screen. Update candidacy.
            setCandidate(obs);
            break;
        default:
            // Ignore the remainder for now
            break;
        }
    }

    if (propagate)
    {
        noteInternal(obs);
    }
}

//------------------------------------------------------------------------
// noteFatal: handle an observation with fatal impact
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::noteFatal(InlineObservation obs)
{
    // As a safeguard, all fatal impact must be
    // reported via noteFatal.
    assert(inlGetImpact(obs) == InlineImpact::FATAL);
    noteInternal(obs);
    assert(inlDecisionIsFailure(inlDecision));
}

//------------------------------------------------------------------------
// noteInt: handle an observed integer value
//
// Arguments:
//    obs      - the current obsevation
//    value    - the value being observed

void LegacyPolicy::noteInt(InlineObservation obs, int value)
{
    switch (obs)
    {
    case InlineObservation::CALLEE_MAXSTACK:
        {
            assert(inlIsForceInlineKnown);

            unsigned calleeMaxStack = static_cast<unsigned>(value);

            if (!inlIsForceInline && (calleeMaxStack > SMALL_STACK_SIZE))
            {
                setNever(InlineObservation::CALLEE_MAXSTACK_TOO_BIG);
            }

            break;
        }

    case InlineObservation::CALLEE_NUMBER_OF_BASIC_BLOCKS:
        {
            assert(inlIsForceInlineKnown);
            assert(value != 0);

            unsigned basicBlockCount = static_cast<unsigned>(value);

            if (!inlIsForceInline && (basicBlockCount > MAX_BASIC_BLOCKS))
            {
                setNever(InlineObservation::CALLEE_TOO_MANY_BASIC_BLOCKS);
            }

            break;
        }

    case InlineObservation::CALLEE_IL_CODE_SIZE:
        {
            assert(inlIsForceInlineKnown);
            assert(value != 0);
            unsigned ilByteSize = static_cast<unsigned>(value);

            // Now that we know size and forceinline state,
            // update candidacy.
            if (ilByteSize <= ALWAYS_INLINE_SIZE)
            {
                // Candidate based on small size
                setCandidate(InlineObservation::CALLEE_BELOW_ALWAYS_INLINE_SIZE);
            }
            else if (inlIsForceInline)
            {
                // Candidate based on force inline
                setCandidate(InlineObservation::CALLEE_IS_FORCE_INLINE);
            }
            else if (ilByteSize <= inlCompiler->getImpInlineSize())
            {
                // Candidate, pending profitability evaluation
                setCandidate(InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE);
            }
            else
            {
                // Callee too big, not a candidate
                setNever(InlineObservation::CALLEE_TOO_MUCH_IL);
            }

            break;
        }

    default:
        // Ignore all other information
        break;
    }
}

//------------------------------------------------------------------------
// noteDouble: handle an observed double value
//
// Arguments:
//    obs      - the current obsevation
//    value    - the value being observed

void LegacyPolicy::noteDouble(InlineObservation obs, double value)
{
    // Ignore for now...
    (void) value;
    (void) obs;
}

//------------------------------------------------------------------------
// noteInternal: helper for handling an observation
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::noteInternal(InlineObservation obs)
{
    // Note any INFORMATION that reaches here will now cause failure.
    // Non-fatal INFORMATION observations must be handled higher up.
    InlineTarget target = inlGetTarget(obs);

    if (target == InlineTarget::CALLEE)
    {
        this->setNever(obs);
    }
    else
    {
        this->setFailure(obs);
    }
}

//------------------------------------------------------------------------
// setFailure: helper for setting a failing decision
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::setFailure(InlineObservation obs)
{
    // Expect a valid observation
    assert(inlIsValidObservation(obs));

    switch (inlDecision)
    {
    case InlineDecision::FAILURE:
        // Repeated failure only ok if evaluating a prejit root
        // (since we can't fail fast because we're not inlining)
        // or if inlining and the observation is CALLSITE_TOO_MANY_LOCALS
        // (since we can't fail fast from lvaGrabTemp).
        assert(inlIsPrejitRoot ||
               (obs == InlineObservation::CALLSITE_TOO_MANY_LOCALS));
        break;
    case InlineDecision::UNDECIDED:
    case InlineDecision::CANDIDATE:
        inlDecision = InlineDecision::FAILURE;
        inlObservation = obs;
        break;
    default:
        // SUCCESS, NEVER, or ??
        assert(!"Unexpected inlDecision");
        unreached();
    }
}

//------------------------------------------------------------------------
// setNever: helper for setting a never decision
//
// Arguments:
//    obs      - the current obsevation

void LegacyPolicy::setNever(InlineObservation obs)
{
    // Expect a valid observation
    assert(inlIsValidObservation(obs));

    switch (inlDecision)
    {
    case InlineDecision::NEVER:
        // Repeated never only ok if evaluating a prejit root
        assert(inlIsPrejitRoot);
        break;
    case InlineDecision::UNDECIDED:
    case InlineDecision::CANDIDATE:
        inlDecision = InlineDecision::NEVER;
        inlObservation = obs;
        break;
    default:
        // SUCCESS, FAILURE or ??
        assert(!"Unexpected inlDecision");
        unreached();
    }
}

//------------------------------------------------------------------------
// setCandidate: helper updating candidacy
//
// Arguments:
//    obs      - the current obsevation
//
// Note:
//    Candidate observations are handled here. If the inline has already
//    failed, they're ignored. If there's already a candidate reason,
//    this new reason trumps it.

void LegacyPolicy::setCandidate(InlineObservation obs)
{
    // Ignore if this inline is going to fail.
    if (inlDecisionIsFailure(inlDecision))
    {
        return;
    }

    // We should not have declared success yet.
    assert(!inlDecisionIsSuccess(inlDecision));

    // Update, overriding any previous candidacy.
    inlDecision = InlineDecision::CANDIDATE;
    inlObservation = obs;
}

//------------------------------------------------------------------------
// determineMultiplier: determine benefit multiplier for this inline
//
// Notes: uses the accumulated set of observations to compute a
// profitability boost for the inline candidate.

double LegacyPolicy::determineMultiplier()
{
    double multiplier = 0;

    // Bump up the multiplier for instance constructors

    if (inlIsInstanceCtor)
    {
        multiplier += 1.5;
        JITDUMP("\nmultiplier in instance constructors increased to %g.", multiplier);
    }

    // Bump up the multiplier for methods in promotable struct

    if (inlIsFromPromotableValueClass)
    {
        multiplier += 3;
        JITDUMP("\nmultiplier in methods of promotable struct increased to %g.", multiplier);
    }

#ifdef FEATURE_SIMD

    if (inlHasSimd)
    {
        multiplier += JitConfig.JitInlineSIMDMultiplier();
        JITDUMP("\nInline candidate has SIMD type args, locals or return value.  Multiplier increased to %g.", multiplier);
    }

#endif // FEATURE_SIMD

    if (inlLooksLikeWrapperMethod)
    {
        multiplier += 1.0;
        JITDUMP("\nInline candidate looks like a wrapper method.  Multiplier increased to %g.", multiplier);
    }

    if (inlArgFeedsConstantTest)
    {
        multiplier += 1.0;
        JITDUMP("\nInline candidate has an arg that feeds a constant test.  Multiplier increased to %g.", multiplier);
    }

    if (inlMethodIsMostlyLoadStore)
    {
        multiplier += 3.0;
        JITDUMP("\nInline candidate is mostly loads and stores.  Multiplier increased to %g.", multiplier);
    }

    if (inlArgFeedsRangeCheck)
    {
        multiplier += 0.5;
        JITDUMP("\nInline candidate has arg that feeds range check.  Multiplier increased to %g.", multiplier);
    }

    if (inlConstantFeedsConstantTest)
    {
        multiplier += 3.0;
        JITDUMP("\nInline candidate has const arg that feeds a conditional.  Multiplier increased to %g.", multiplier);
    }

    return multiplier;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: treeactions.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 23:30:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <stdio.h>

#include "treeactions.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

//..........................................................................
namespace configmgr
{
// -------------------------------------------------------------------------
namespace
{
    struct ForceWritable : NodeModification
    {
        void handle(ValueNode& _rValue)     { implForceWritable(_rValue); }
        void handle(ISubtree& _rSubtree)    { implForceWritable(_rSubtree); applyToChildren(_rSubtree); }

        void implForceWritable(INode& _rNode) { _rNode.forceReadonlyToFinalized(); }
    };
}

// -------------------------------------------------------------------------
void forceWritable(INode& _rNode)
{
    ForceWritable aVisitor;

    aVisitor.applyToNode(_rNode);
}

//==========================================================================
//= OChangeActionCounter
//==========================================================================

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(ValueChange const& /*aValueNode*/){ ++nValues; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(AddNode const& /*aAddNode*/){ ++nAdds; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(RemoveNode const& /*aRemoveNode*/){ ++nRemoves; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(SubtreeChange const& aSubtree)
{
    applyToChildren(aSubtree);
}

//..........................................................................
}   // namespace configmgr
//..........................................................................

<commit_msg>INTEGRATION: CWS pchfix02 (1.21.18); FILE MERGED 2006/09/01 17:20:43 kaib 1.21.18.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: treeactions.cxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 15:22:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <stdio.h>

#include "treeactions.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

//..........................................................................
namespace configmgr
{
// -------------------------------------------------------------------------
namespace
{
    struct ForceWritable : NodeModification
    {
        void handle(ValueNode& _rValue)     { implForceWritable(_rValue); }
        void handle(ISubtree& _rSubtree)    { implForceWritable(_rSubtree); applyToChildren(_rSubtree); }

        void implForceWritable(INode& _rNode) { _rNode.forceReadonlyToFinalized(); }
    };
}

// -------------------------------------------------------------------------
void forceWritable(INode& _rNode)
{
    ForceWritable aVisitor;

    aVisitor.applyToNode(_rNode);
}

//==========================================================================
//= OChangeActionCounter
//==========================================================================

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(ValueChange const& /*aValueNode*/){ ++nValues; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(AddNode const& /*aAddNode*/){ ++nAdds; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(RemoveNode const& /*aRemoveNode*/){ ++nRemoves; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(SubtreeChange const& aSubtree)
{
    applyToChildren(aSubtree);
}

//..........................................................................
}   // namespace configmgr
//..........................................................................

<|endoftext|>


<commit_before>#include <unistd.h>
#include <cstdio>

#include "libaktualizr/packagemanagerfactory.h"

#include "debianmanager.h"
#include "logging/logging.h"
#include "utilities/utils.h"
#include "storage/invstorage.h"

AUTO_REGISTER_PACKAGE_MANAGER(PACKAGE_MANAGER_DEBIAN, DebianManager);

Json::Value DebianManager::getInstalledPackages() const {
  // Currently not implemented
  return Json::Value(Json::arrayValue);
}

data::InstallationResult DebianManager::install(const Uptane::Target &target) const {
  std::lock_guard<std::mutex> guard(mutex_);
  LOG_INFO << "Installing " << target.filename() << " as Debian package...";
  std::string cmd = "dpkg -i ";
  std::string output;
  TemporaryDirectory package_dir("deb_dir");
  auto target_file = openTargetFile(target);

  boost::filesystem::path deb_path = package_dir / target.filename();
  std::ofstream deb_file(deb_path.string(), std::ios::binary);
  deb_file << target_file.rdbuf();
  target_file.close();
  deb_file.close();

  int status = Utils::shell(cmd + deb_path.string(), &output, true);
  if (status == 0) {
    LOG_INFO << "... Installation of Debian package successful";
    storage_->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kCurrent);
    return data::InstallationResult(data::ResultCode::Numeric::kOk, "Installing debian package was successful");
  }
  LOG_ERROR << "... Installation of Debian package failed";
  return data::InstallationResult(data::ResultCode::Numeric::kInstallFailed, output);
}

Uptane::Target DebianManager::getCurrent() const {
  boost::optional<Uptane::Target> current_version;
  storage_->loadPrimaryInstalledVersions(&current_version, nullptr);

  if (!!current_version) {
    return *current_version;
  }

  return Uptane::Target::Unknown();
}
<commit_msg>fix formating<commit_after>#include <unistd.h>
#include <cstdio>

#include "libaktualizr/packagemanagerfactory.h"

#include "debianmanager.h"
#include "logging/logging.h"
#include "storage/invstorage.h"
#include "utilities/utils.h"

AUTO_REGISTER_PACKAGE_MANAGER(PACKAGE_MANAGER_DEBIAN, DebianManager);

Json::Value DebianManager::getInstalledPackages() const {
  // Currently not implemented
  return Json::Value(Json::arrayValue);
}

data::InstallationResult DebianManager::install(const Uptane::Target &target) const {
  std::lock_guard<std::mutex> guard(mutex_);
  LOG_INFO << "Installing " << target.filename() << " as Debian package...";
  std::string cmd = "dpkg -i ";
  std::string output;
  TemporaryDirectory package_dir("deb_dir");
  auto target_file = openTargetFile(target);

  boost::filesystem::path deb_path = package_dir / target.filename();
  std::ofstream deb_file(deb_path.string(), std::ios::binary);
  deb_file << target_file.rdbuf();
  target_file.close();
  deb_file.close();

  int status = Utils::shell(cmd + deb_path.string(), &output, true);
  if (status == 0) {
    LOG_INFO << "... Installation of Debian package successful";
    storage_->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kCurrent);
    return data::InstallationResult(data::ResultCode::Numeric::kOk, "Installing debian package was successful");
  }
  LOG_ERROR << "... Installation of Debian package failed";
  return data::InstallationResult(data::ResultCode::Numeric::kInstallFailed, output);
}

Uptane::Target DebianManager::getCurrent() const {
  boost::optional<Uptane::Target> current_version;
  storage_->loadPrimaryInstalledVersions(&current_version, nullptr);

  if (!!current_version) {
    return *current_version;
  }

  return Uptane::Target::Unknown();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: treeactions.cxx,v $
 *
 *  $Revision: 1.20 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 04:19:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <stdio.h>

#include "treeactions.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

//..........................................................................
namespace configmgr
{
// -------------------------------------------------------------------------
namespace
{
    struct ForceWritable : NodeModification
    {
        void handle(ValueNode& _rValue)     { implForceWritable(_rValue); }
        void handle(ISubtree& _rSubtree)    { implForceWritable(_rSubtree); applyToChildren(_rSubtree); }

        void implForceWritable(INode& _rNode) { _rNode.forceReadonlyToFinalized(); }
    };
}

// -------------------------------------------------------------------------
void forceWritable(INode& _rNode)
{
    ForceWritable aVisitor;

    aVisitor.applyToNode(_rNode);
}

//==========================================================================
//= OChangeActionCounter
//==========================================================================

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(ValueChange const& aValueNode){ ++nValues; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(AddNode const& aAddNode){ ++nAdds; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(RemoveNode const& aRemoveNode){ ++nRemoves; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(SubtreeChange const& aSubtree)
{
    applyToChildren(aSubtree);
}

//..........................................................................
}   // namespace configmgr
//..........................................................................

<commit_msg>INTEGRATION: CWS warnings01 (1.20.4); FILE MERGED 2005/11/01 12:47:33 cd 1.20.4.1: #i53898# Warning free code for sun solaris compiler<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: treeactions.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 23:30:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <stdio.h>

#include "treeactions.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

//..........................................................................
namespace configmgr
{
// -------------------------------------------------------------------------
namespace
{
    struct ForceWritable : NodeModification
    {
        void handle(ValueNode& _rValue)     { implForceWritable(_rValue); }
        void handle(ISubtree& _rSubtree)    { implForceWritable(_rSubtree); applyToChildren(_rSubtree); }

        void implForceWritable(INode& _rNode) { _rNode.forceReadonlyToFinalized(); }
    };
}

// -------------------------------------------------------------------------
void forceWritable(INode& _rNode)
{
    ForceWritable aVisitor;

    aVisitor.applyToNode(_rNode);
}

//==========================================================================
//= OChangeActionCounter
//==========================================================================

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(ValueChange const& /*aValueNode*/){ ++nValues; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(AddNode const& /*aAddNode*/){ ++nAdds; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(RemoveNode const& /*aRemoveNode*/){ ++nRemoves; }

//--------------------------------------------------------------------------
void OChangeActionCounter::handle(SubtreeChange const& aSubtree)
{
    applyToChildren(aSubtree);
}

//..........................................................................
}   // namespace configmgr
//..........................................................................

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: roottree.cxx,v $
 * $Revision: 1.20 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_configmgr.hxx"
#include <stdio.h>

#include "roottree.hxx"
#include "roottreeimpl.hxx"
#include "viewaccess.hxx"
#include "nodeaccess.hxx"
#include "viewfactory.hxx"
#include "noderef.hxx"
#include "nodechangeinfo.hxx"
#include "treechangelist.hxx"

namespace configmgr
{
    namespace configuration
    {
//-----------------------------------------------------------------------------
// factory methods
//-----------------------------------------------------------------------------

RootTree createReadOnlyTree(    AbsolutePath const& aRootPath,
                                data::NodeAccess const& _aCacheNode,
                                TreeDepth nDepth,
                TemplateProvider const& aTemplateProvider)
{
    return RootTree( new RootTreeImpl(view::createReadOnlyStrategy(),
                      aRootPath, _aCacheNode, nDepth,
                      aTemplateProvider
                      ));
}
//-----------------------------------------------------------------------------

RootTree createUpdatableTree(   AbsolutePath const& aRootPath,
                                data::NodeAccess const& _aCacheNode,
                                TreeDepth nDepth,
                                TemplateProvider const& aTemplateProvider)
{
    return RootTree(new RootTreeImpl(view::createDeferredChangeStrategy(),
                      aRootPath, _aCacheNode, nDepth,
                      aTemplateProvider
                      ));
}

//-----------------------------------------------------------------------------
// update on notify method
//-----------------------------------------------------------------------------
bool adjustToChanges(   NodeChangesInformation& rLocalChanges,
                        Tree const& aBaseTree, NodeRef const& aBaseNode,
                        SubtreeChange const& aExternalChange)
{
    OSL_PRECOND( !aBaseTree.isEmpty(), "ERROR: Configuration: Tree operation requires a valid Tree");
    OSL_PRECOND(  aBaseTree.isValidNode(aBaseNode), "ERROR: Configuration: NodeRef does not match Tree");

    if (!aBaseTree.isEmpty())
    {
        OSL_ENSURE(rLocalChanges.empty(), "Should pass empty container to adjustToChanges(...)");

        aBaseTree.getView().adjustToChanges(rLocalChanges, aBaseNode, aExternalChange);

        return !rLocalChanges.empty();
    }
    else
        return false;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// class CommitHelper
//-----------------------------------------------------------------------------
struct CommitHelper::Data
{
    ElementList m_aRemovedElements; // filled to keep the elements alive 'till after notification
};

//-----------------------------------------------------------------------------
CommitHelper::CommitHelper(TreeRef const& aTree)
: m_pData(  )
, m_pTree( TreeImplHelper::impl(aTree) )
{
    OSL_ENSURE(m_pTree, "INTERNAL ERROR: Unexpected NULL tree in commit helper");
}
//-----------------------------------------------------------------------------
CommitHelper::~CommitHelper()
{
}

//-----------------------------------------------------------------------------
void CommitHelper::reset()
{
    m_pData.reset();
}

//-----------------------------------------------------------------------------
bool CommitHelper::prepareCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"ERROR: CommitHelper: Cannot commit without a tree");
    if (m_pTree == NULL)
        return false;

    OSL_ENSURE(m_pData.get() == NULL,"ERROR: CommitHelper: Need to reset before reusing");
    m_pData.reset( new Data() );

    // get and check the changes
    std::auto_ptr<SubtreeChange> pTreeChange(view::ViewTreeAccess(*m_pTree).preCommitChanges(m_pData->m_aRemovedElements));
    if (pTreeChange.get() == NULL)
        return false;

    // find the name and path of the change
    OSL_ENSURE(m_pTree->getSimpleRootName().toString() == pTreeChange->getNodeName(), "ERROR in Commit: Change Name Mismatch");

    // now fill the TreeChangeList
    rChangeList.setRootPath( m_pTree->getRootPath() );
    rChangeList.root.swap( *pTreeChange );

    return true;
}
//-----------------------------------------------------------------------------

void CommitHelper::finishCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");

    // find the name and path of the change
    AbsolutePath aPath = m_pTree->getRootPath();

    OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
    if ( !matches(rChangeList.getRootNodePath(), aPath) )
        throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");

    view::ViewTreeAccess(*m_pTree).finishCommit(rChangeList.root);
}
//-----------------------------------------------------------------------------

void CommitHelper::revertCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");

    AbsolutePath aPath = m_pTree->getRootPath();

    OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
    if ( !matches(rChangeList.getRootNodePath(), aPath) )
        throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");

    view::ViewTreeAccess(*m_pTree).revertCommit(rChangeList.root);
}
//-----------------------------------------------------------------------------

void CommitHelper::failedCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");

    AbsolutePath aPath = m_pTree->getRootPath();

    OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
    if ( !matches(rChangeList.getRootNodePath(), aPath) )
        throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");

    view::ViewTreeAccess(*m_pTree).recoverFailedCommit(rChangeList.root);
}
//-----------------------------------------------------------------------------

    }
}

<commit_msg>INTEGRATION: CWS sb88 (1.20.10); FILE MERGED 2008/06/03 15:29:54 sb 1.20.10.1: #i89553 applied patch by cmc<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: roottree.cxx,v $
 * $Revision: 1.21 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_configmgr.hxx"
#include <stdio.h>

#include "roottree.hxx"
#include "roottreeimpl.hxx"
#include "viewaccess.hxx"
#include "nodeaccess.hxx"
#include "viewfactory.hxx"
#include "noderef.hxx"
#include "nodechangeinfo.hxx"
#include "treechangelist.hxx"

namespace configmgr
{
    namespace configuration
    {
//-----------------------------------------------------------------------------
// factory methods
//-----------------------------------------------------------------------------

RootTree createReadOnlyTree(    AbsolutePath const& aRootPath,
                                data::NodeAccess const& _aCacheNode,
                                TreeDepth nDepth,
                TemplateProvider const& aTemplateProvider)
{
    return RootTree( new RootTreeImpl(view::createReadOnlyStrategy(),
                      aRootPath, _aCacheNode, nDepth,
                      aTemplateProvider
                      ));
}
//-----------------------------------------------------------------------------

RootTree createUpdatableTree(   AbsolutePath const& aRootPath,
                                data::NodeAccess const& _aCacheNode,
                                TreeDepth nDepth,
                                TemplateProvider const& aTemplateProvider)
{
    return RootTree(new RootTreeImpl(view::createDeferredChangeStrategy(),
                      aRootPath, _aCacheNode, nDepth,
                      aTemplateProvider
                      ));
}

//-----------------------------------------------------------------------------
// update on notify method
//-----------------------------------------------------------------------------
bool adjustToChanges(   NodeChangesInformation& rLocalChanges,
                        Tree const& aBaseTree, NodeRef const& aBaseNode,
                        SubtreeChange const& aExternalChange)
{
    OSL_PRECOND( !aBaseTree.isEmpty(), "ERROR: Configuration: Tree operation requires a valid Tree");
    OSL_PRECOND(  aBaseTree.isValidNode(aBaseNode), "ERROR: Configuration: NodeRef does not match Tree");

    if (!aBaseTree.isEmpty())
    {
        OSL_ENSURE(rLocalChanges.empty(), "Should pass empty container to adjustToChanges(...)");

        aBaseTree.getView().adjustToChanges(rLocalChanges, aBaseNode, aExternalChange);

        return !rLocalChanges.empty();
    }
    else
        return false;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// class CommitHelper
//-----------------------------------------------------------------------------
struct CommitHelper::Data
{
    ElementList m_aRemovedElements; // filled to keep the elements alive 'till after notification
};

//-----------------------------------------------------------------------------
CommitHelper::CommitHelper(TreeRef const& aTree)
: m_pData(  )
, m_pTree( TreeImplHelper::impl(aTree) )
{
    OSL_ENSURE(m_pTree, "INTERNAL ERROR: Unexpected NULL tree in commit helper");
}
//-----------------------------------------------------------------------------
CommitHelper::~CommitHelper()
{
}

//-----------------------------------------------------------------------------
bool CommitHelper::prepareCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"ERROR: CommitHelper: Cannot commit without a tree");
    if (m_pTree == NULL)
        return false;

    OSL_ENSURE(m_pData.get() == NULL,"ERROR: CommitHelper: Need to reset before reusing");
    m_pData.reset( new Data() );

    // get and check the changes
    std::auto_ptr<SubtreeChange> pTreeChange(view::ViewTreeAccess(*m_pTree).preCommitChanges(m_pData->m_aRemovedElements));
    if (pTreeChange.get() == NULL)
        return false;

    // find the name and path of the change
    OSL_ENSURE(m_pTree->getSimpleRootName().toString() == pTreeChange->getNodeName(), "ERROR in Commit: Change Name Mismatch");

    // now fill the TreeChangeList
    rChangeList.setRootPath( m_pTree->getRootPath() );
    rChangeList.root.swap( *pTreeChange );

    return true;
}
//-----------------------------------------------------------------------------

void CommitHelper::finishCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");

    // find the name and path of the change
    AbsolutePath aPath = m_pTree->getRootPath();

    OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
    if ( !matches(rChangeList.getRootNodePath(), aPath) )
        throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");

    view::ViewTreeAccess(*m_pTree).finishCommit(rChangeList.root);
}
//-----------------------------------------------------------------------------

void CommitHelper::failedCommit(TreeChangeList& rChangeList)
{
    OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");

    AbsolutePath aPath = m_pTree->getRootPath();

    OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
    if ( !matches(rChangeList.getRootNodePath(), aPath) )
        throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");

    view::ViewTreeAccess(*m_pTree).recoverFailedCommit(rChangeList.root);
}
//-----------------------------------------------------------------------------

    }
}

<|endoftext|>