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

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

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/

//  Software Guide : BeginLatex
//
//  This example illustrates the use of the confidence connected concept
//  applied to images with vector pixel types. The confidence connected
//  algorithm is implemented for vector images in the class
//  \doxygen{VectorConfidenceConnected}. The basic difference between the
//  scalar and vector version is that the vector version uses the covariance
//  matrix instead of a variance, and a vector mean instead of a scalar mean.
//  The membership of a vector pixel value to the region is measured using the
//  Mahalanobis distance as implemented in the class
//  \subdoxygen{Statistics}{MahalanobisDistanceThresholdImageFunction}.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkVectorConfidenceConnectedImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRGBPixel.h"

int main( int argc, char *argv[] )
{
  if( argc < 7 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " inputImage  outputImage seedX seedY multiplier iterations" << std::endl;
    return 1;
    }

  //  Software Guide : BeginLatex
  //
  //  We now define the image type using a particular pixel type and
  //  dimension. In this case the \code{float} type is used for the pixels
  //  due to the requirements of the smoothing filter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   unsigned char                         PixelComponentType;
  typedef   itk::RGBPixel< PixelComponentType >   InputPixelType;
  const     unsigned int    Dimension = 2;
  typedef itk::Image< InputPixelType, Dimension >  InputImageType;
  // Software Guide : EndCodeSnippet

  typedef unsigned char OutputPixelType;
  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  // We instantiate reader and writer types
  //
  typedef  itk::ImageFileReader<  InputImageType   > ReaderType;
  typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( argv[1] );
  writer->SetFileName( argv[2] );

  //  Software Guide : BeginLatex
  //
  //  We now declare the type of the region growing filter. In this case it
  //  is the \doxygen{VectorConfidenceConnectedImageFilter}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef  itk::VectorConfidenceConnectedImageFilter< InputImageType,
                                    OutputImageType > ConnectedFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Then, we construct one filter of this class using the \code{New()}
  //  method.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ConnectedFilterType::Pointer confidenceConnected = ConnectedFilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Next we create a simple, linear data processing pipeline.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetInput( reader->GetOutput() );
  writer->SetInput( confidenceConnected->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The VectorConfidenceConnectedImageFilter requires specifying two
  //  parameters.  First, the multiplier factor $f$ defines how large the
  //  range of intensities will be. Small values of the multiplier will
  //  restrict the inclusion of pixels to those having similar intensities to
  //  those already in the current region. Larger values of the multiplier
  //  relax the accepting condition and result in more generous growth of the
  //  region. Values that are too large will cause the region to grow into
  //  neighboring regions that may actually belong to separate anatomical
  //  structures.
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetMultiplier()}
  //
  //  Software Guide : EndLatex

  const double multiplier = atof( argv[5] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetMultiplier( multiplier );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The number of iterations is typically determined based on the
  //  homogeneity of the image intensity representing the anatomical
  //  structure to be segmented. Highly homogeneous regions may only require
  //  a couple of iterations. Regions with ramp effects, like MRI images with
  //  inhomogenous fields, may require more iterations. In practice, it seems
  //  to be more relevant to carefully select the multiplier factor than the
  //  number of iterations.  However, keep in mind that there is no reason to
  //  assume that this algorithm should converge to a stable region. It is
  //  possible that by letting the algorithm run for more iterations the
  //  region will end up engulfing the entire image.
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetNumberOfIterations()}
  //
  //  Software Guide : EndLatex

  const unsigned int iterations = atoi( argv[6] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetNumberOfIterations( iterations );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The output of this filter is a binary image with zero-value pixels
  //  everywhere except on the extracted region. The intensity value to be
  //  put inside the region is selected with the method
  //  \code{SetReplaceValue()}
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetReplaceValue()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetReplaceValue( 255 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The initialization of the algorithm requires the user to provide a seed
  //  point. This point should be placed in a \emph{typical} region of the
  //  anatomical structure to be segmented. A small neighborhood around the
  //  seed point will be used to compute the initial mean and standard
  //  deviation for the inclusion criterion. The seed is passed in the form
  //  of a \doxygen{Index} to the \code{SetSeed()} method.
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetSeed()}
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetInitialNeighborhoodRadius()}
  //
  //  Software Guide : EndLatex

  InputImageType::IndexType  index;

  index[0] = atoi( argv[3] );
  index[1] = atoi( argv[4] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetSeed( index );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The size of the initial neighborhood around the seed is defined with the
  //  method \code{SetInitialNeighborhoodRadius()}. The neighborhood will be
  //  defined as an $N$-Dimensional rectangular region with $2r+1$ pixels on
  //  the side, where $r$ is the value passed as initial neighborhood radius.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetInitialNeighborhoodRadius( 3 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The invocation of the \code{Update()} method on the writer triggers the
  //  execution of the pipeline.  It is usually wise to put update calls in a
  //  \code{try/catch} block in case errors occur and exceptions are thrown.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now let's run this example using as input the image
  //  \code{VisibleWomanEyeSlice.png} provided in the directory
  //  \code{Examples/Data}. We can easily segment the major anatomical
  //  structures by providing seeds in the appropriate locations. For example,
  //
  //  \begin{center}
  //  \begin{tabular}{|l|c|c|c|c|}
  //  \hline
  //  Structure & Seed Index & Multiplier & Iterations & Output Image \\ \hline
  //  Rectum & $(70,120)$ & 7 & 1 & Second from left in Figure \ref{fig:VectorConfidenceConnectedOutput} \\ \hline
  //  Rectum & $(23, 93)$ & 7 & 1 & Third  from left in Figure \ref{fig:VectorConfidenceConnectedOutput} \\ \hline
  //  Vitreo & $(66, 66)$ & 3 & 1 & Fourth from left in Figure \ref{fig:VectorConfidenceConnectedOutput} \\ \hline
  //  \end{tabular}
  //  \end{center}
  //
  // \begin{figure} \center
  // \includegraphics[width=0.24\textwidth]{VisibleWomanEyeSlice.eps}
  // \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput1.eps}
  // \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput2.eps}
  // \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput3.eps}
  // \itkcaption[VectorConfidenceConnected segmentation results]{Segmentation results of
  // the VectorConfidenceConnected filter for various seed points.}
  // \label{fig:VectorConfidenceConnectedOutput}
  // \end{figure}
  //
  // The coloration of muscular tissue makes it easy to distinguish them from
  // the surrounding anatomical strucures. The optic vitrea on the other hand
  // has a coloration that is not very homogeneous inside the eyeball and
  // does not allow to generate a full segmentation based only on color.
  //
  //  Software Guide : EndLatex

  return 0;
}

<commit_msg>ENH: Print out of the mean vector and covariance matrix added.<commit_after>/*=========================================================================

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

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/

//  Software Guide : BeginLatex
//
//  This example illustrates the use of the confidence connected concept
//  applied to images with vector pixel types. The confidence connected
//  algorithm is implemented for vector images in the class
//  \doxygen{VectorConfidenceConnected}. The basic difference between the
//  scalar and vector version is that the vector version uses the covariance
//  matrix instead of a variance, and a vector mean instead of a scalar mean.
//  The membership of a vector pixel value to the region is measured using the
//  Mahalanobis distance as implemented in the class
//  \subdoxygen{Statistics}{MahalanobisDistanceThresholdImageFunction}.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkVectorConfidenceConnectedImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRGBPixel.h"

int main( int argc, char *argv[] )
{
  if( argc < 7 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " inputImage  outputImage seedX seedY multiplier iterations" << std::endl;
    return 1;
    }

  //  Software Guide : BeginLatex
  //
  //  We now define the image type using a particular pixel type and
  //  dimension. In this case the \code{float} type is used for the pixels
  //  due to the requirements of the smoothing filter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   unsigned char                         PixelComponentType;
  typedef   itk::RGBPixel< PixelComponentType >   InputPixelType;
  const     unsigned int    Dimension = 2;
  typedef itk::Image< InputPixelType, Dimension >  InputImageType;
  // Software Guide : EndCodeSnippet

  typedef unsigned char OutputPixelType;
  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  // We instantiate reader and writer types
  //
  typedef  itk::ImageFileReader<  InputImageType   > ReaderType;
  typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( argv[1] );
  writer->SetFileName( argv[2] );

  //  Software Guide : BeginLatex
  //
  //  We now declare the type of the region growing filter. In this case it
  //  is the \doxygen{VectorConfidenceConnectedImageFilter}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef  itk::VectorConfidenceConnectedImageFilter< InputImageType,
                                    OutputImageType > ConnectedFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Then, we construct one filter of this class using the \code{New()}
  //  method.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ConnectedFilterType::Pointer confidenceConnected = ConnectedFilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Next we create a simple, linear data processing pipeline.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetInput( reader->GetOutput() );
  writer->SetInput( confidenceConnected->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The VectorConfidenceConnectedImageFilter requires specifying two
  //  parameters.  First, the multiplier factor $f$ defines how large the
  //  range of intensities will be. Small values of the multiplier will
  //  restrict the inclusion of pixels to those having similar intensities to
  //  those already in the current region. Larger values of the multiplier
  //  relax the accepting condition and result in more generous growth of the
  //  region. Values that are too large will cause the region to grow into
  //  neighboring regions that may actually belong to separate anatomical
  //  structures.
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetMultiplier()}
  //
  //  Software Guide : EndLatex

  const double multiplier = atof( argv[5] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetMultiplier( multiplier );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The number of iterations is typically determined based on the
  //  homogeneity of the image intensity representing the anatomical
  //  structure to be segmented. Highly homogeneous regions may only require
  //  a couple of iterations. Regions with ramp effects, like MRI images with
  //  inhomogenous fields, may require more iterations. In practice, it seems
  //  to be more relevant to carefully select the multiplier factor than the
  //  number of iterations.  However, keep in mind that there is no reason to
  //  assume that this algorithm should converge to a stable region. It is
  //  possible that by letting the algorithm run for more iterations the
  //  region will end up engulfing the entire image.
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetNumberOfIterations()}
  //
  //  Software Guide : EndLatex

  const unsigned int iterations = atoi( argv[6] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetNumberOfIterations( iterations );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The output of this filter is a binary image with zero-value pixels
  //  everywhere except on the extracted region. The intensity value to be
  //  put inside the region is selected with the method
  //  \code{SetReplaceValue()}
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetReplaceValue()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetReplaceValue( 255 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The initialization of the algorithm requires the user to provide a seed
  //  point. This point should be placed in a \emph{typical} region of the
  //  anatomical structure to be segmented. A small neighborhood around the
  //  seed point will be used to compute the initial mean and standard
  //  deviation for the inclusion criterion. The seed is passed in the form
  //  of a \doxygen{Index} to the \code{SetSeed()} method.
  //
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetSeed()}
  //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetInitialNeighborhoodRadius()}
  //
  //  Software Guide : EndLatex

  InputImageType::IndexType  index;

  index[0] = atoi( argv[3] );
  index[1] = atoi( argv[4] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetSeed( index );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The size of the initial neighborhood around the seed is defined with the
  //  method \code{SetInitialNeighborhoodRadius()}. The neighborhood will be
  //  defined as an $N$-Dimensional rectangular region with $2r+1$ pixels on
  //  the side, where $r$ is the value passed as initial neighborhood radius.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetInitialNeighborhoodRadius( 3 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The invocation of the \code{Update()} method on the writer triggers the
  //  execution of the pipeline.  It is usually wise to put update calls in a
  //  \code{try/catch} block in case errors occur and exceptions are thrown.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now let's run this example using as input the image
  //  \code{VisibleWomanEyeSlice.png} provided in the directory
  //  \code{Examples/Data}. We can easily segment the major anatomical
  //  structures by providing seeds in the appropriate locations. For example,
  //
  //  \begin{center}
  //  \begin{tabular}{|l|c|c|c|c|}
  //  \hline
  //  Structure & Seed Index & Multiplier & Iterations & Output Image \\ \hline
  //  Rectum & $(70,120)$ & 7 & 1 & Second from left in Figure \ref{fig:VectorConfidenceConnectedOutput} \\ \hline
  //  Rectum & $(23, 93)$ & 7 & 1 & Third  from left in Figure \ref{fig:VectorConfidenceConnectedOutput} \\ \hline
  //  Vitreo & $(66, 66)$ & 3 & 1 & Fourth from left in Figure \ref{fig:VectorConfidenceConnectedOutput} \\ \hline
  //  \end{tabular}
  //  \end{center}
  //
  // \begin{figure} \center
  // \includegraphics[width=0.24\textwidth]{VisibleWomanEyeSlice.eps}
  // \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput1.eps}
  // \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput2.eps}
  // \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput3.eps}
  // \itkcaption[VectorConfidenceConnected segmentation results]{Segmentation results of
  // the VectorConfidenceConnected filter for various seed points.}
  // \label{fig:VectorConfidenceConnectedOutput}
  // \end{figure}
  //
  // The coloration of muscular tissue makes it easy to distinguish them from
  // the surrounding anatomical strucures. The optic vitrea on the other hand
  // has a coloration that is not very homogeneous inside the eyeball and
  // does not allow to generate a full segmentation based only on color.
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginLatex
  //
  //  The values of the final mean vector and covariance matrix used for the
  //  last iteration can be queried using the methods \code{GetMean()} and
  //  \code{GetCovariance()}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef ConnectedFilterType::MeanVectorType   MeanVectorType;

  const MeanVectorType & mean = confidenceConnected->GetMean();

  std::cout << "Mean vector = " << std::endl;
  std::cout << mean << std::endl;

  typedef ConnectedFilterType::CovarianceMatrixType   CovarianceMatrixType;

  const CovarianceMatrixType & covariance = confidenceConnected->GetCovariance();

  std::cout << "Covariance matrix = " << std::endl;
  std::cout << covariance << std::endl;
  // Software Guide : EndCodeSnippet

  return 0;
}

<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning(4:4786)
#endif

// interface header
#include "Bundle.h"

// system headers
#include <fstream>
#include <stdio.h>

// local implementation headers
#include "StateDatabase.h"
#include "AnsiCodes.h"

Bundle::Bundle(const Bundle *pBundle)
{
  if (pBundle == NULL)
    return;

  mappings = pBundle->mappings;
}

void Bundle::load(const std::string &path)
{
  std::string untranslated;
  std::string translated;
  char buffer[1024];

  std::ifstream poStrm(path.c_str());
  if (!poStrm.good())
    return;

  poStrm.getline(buffer,1024);
  while (poStrm.good()) {
    std::string line = buffer;
    std::string data;
    TLineType type = parseLine(line, data);
    if (type == tMSGID) {
      if (untranslated.length() > 0) {
	mappings.erase(untranslated);
	ensureNormalText(translated);
	mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
      }
      untranslated = data;
      translated.resize(0);
    }
    else if (type == tMSGSTR) {
      if (untranslated.length() > 0)
	translated = data;
    }
    else if (type == tAPPEND) {
      if (untranslated.length() > 0)
	translated += data;
    }
    else if (type == tERROR) {

    }

    poStrm.getline(buffer,1024);
  }

  if ((untranslated.length() > 0) && (translated.length() > 0)) {
    mappings.erase(untranslated);
    ensureNormalText(translated);
    mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
  }
}

Bundle::TLineType Bundle::parseLine(const std::string &line, std::string &data) const
{
  int startPos, endPos;
  TLineType type;

  data.resize(0);
  startPos = line.find_first_not_of("\t \r\n");

  if ((startPos < 0) || (line.at(startPos) == '#'))
    return tCOMMENT;

  else if (line.at(startPos) == '"') {
    endPos = line.find_first_of('"', startPos+1);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr(startPos+1, endPos-startPos-1);
    return tAPPEND;
  }

  endPos = line.find_first_of("\t \r\n\"");
  if (endPos < 0)
    endPos = line.length();
  std::string key = line.substr(startPos, endPos-startPos);
  if (key == "msgid")
    type = tMSGID;
  else if (key == "msgstr")
    type = tMSGSTR;
  else
    return tERROR;

  startPos = line.find_first_of('"', endPos + 1);
  if (startPos >= 0) {
    startPos++;
    endPos = line.find_first_of('"', startPos);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr( startPos, endPos-startPos);
  }
  return type;
}

#include <set>
static std::set<std::string> unmapped;

std::string Bundle::getLocalString(const std::string &key) const
{
  if (key == "") return key;
  BundleStringMap::const_iterator it = mappings.find(key);
  if (it != mappings.end()) {
    return it->second;
  } else {
    if (BZDB.getDebug()) {
      if (unmapped.find( key ) == unmapped.end( )) {
	unmapped.insert( key );
    std::string stripped = stripAnsiCodes (key);
	std::string debugStr = "Unmapped Locale String: " + stripped + "\n";
	DEBUG1("%s", debugStr.c_str());
      }
    }
    return key;
  }
}

void Bundle::ensureNormalText(std::string &msg)
{
// This is an ugly hack. If you don't like it fix it.
// BZFlag's font bitmaps don't contain letters with accents, so strip them here
// Would be nice if some kind sole added them.

  for (std::string::size_type i = 0; i < msg.length(); i++) {
    char c = msg.at(i);
    switch (c) {
      case '':
      case '':
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'a';
      break;
      case '':
	msg[i] = 'a';
	i++;
	msg.insert(i, 1, 'a');
      break;
      case '':
      case '':
	msg[i] = 'a';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
      case '':
      case '':
	msg[i] = 'A';
      break;
      case '':
      case '':
	msg[i] = 'A';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'A';
	i++;
	msg.insert(i, 1, 'a');
      break;
      case '':
	msg[i] = 'c';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'e';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'i';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'o';
      break;
      case '':
      case '':
	msg[i] = 'o';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'O';
      break;
      case '':
      case '':
	msg[i] = 'O';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
      case '':
      case '':
	msg[i] = 'u';
      break;
      case '':
	msg[i] = 'u';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'U';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'n';
      break;
      case '':
	msg[i] = 'Y';
      break;
      case '':
	msg[i] = 's';
	i++;
	msg.insert(i, 1, 's');
      break;
      case '':
      case '':
	msg[i] = ' ';
      break;

      default: // A temporary patch, to catch untranslated chars.. To be removed eventually
	if (((c >= 'A') && (c <= 'Z'))
	    || ((c >= 'a') && (c <= 'z'))
	    || ((c >= '0') && (c <= '9'))
	    || (c == '}') || (c == '{') || (c == ' ')
	    || (c == ':') || (c == '/') || (c == '-')
	    || (c == ',') || (c == '&') || (c == '?')
	    || (c == '<') || (c == '>') || (c == '.')
	    || (c == '(') || (c == ')') || (c == '%')
	    || (c == '!') || (c == '+') || (c == '-')
	    || (c == '$') || (c == ';') || (c == '@')
	    || (c == '[') || (c == ']')
	    || (c == '=') || (c == '\''))
	;
	else {
		msg = std::string("unsupported char:") + c;
		return;
	}
      break;

    }
  }
}

std::string Bundle::formatMessage(const std::string &key, const std::vector<std::string> *parms) const
{
  std::string messageIn = getLocalString(key);
  std::string messageOut;

  if (!parms || (parms->size() == 0))
    return messageIn;

  int parmCnt = parms->size();
  int startPos = 0;
  int lCurlyPos = messageIn.find_first_of("{");

  while (lCurlyPos >= 0) {
    messageOut += messageIn.substr( startPos, lCurlyPos - startPos);
    int rCurlyPos = messageIn.find_first_of("}", lCurlyPos++);
    if (rCurlyPos < 0) {
      messageOut += messageIn.substr(lCurlyPos);
      return messageOut;
    }
    std::string numStr = messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    int num;
    if (sscanf(numStr.c_str(), "%d", &num) != 1)
      messageOut += messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    else {
      num--;
      if ((num >= 0) && (num < parmCnt))
	messageOut += (*parms)[num];
    }
    startPos = rCurlyPos+1;
    lCurlyPos = messageIn.find_first_of("{", startPos);
  }
  messageOut += messageIn.substr(startPos);
  return messageOut;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>utf8<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning(4:4786)
#endif

// interface header
#include "Bundle.h"

// system headers
#include <fstream>
#include <stdio.h>

// local implementation headers
#include "StateDatabase.h"
#include "AnsiCodes.h"

Bundle::Bundle(const Bundle *pBundle)
{
  if (pBundle == NULL)
    return;

  mappings = pBundle->mappings;
}

void Bundle::load(const std::string &path)
{
  std::string untranslated;
  std::string translated;
  char buffer[1024];

  std::ifstream poStrm(path.c_str());
  if (!poStrm.good())
    return;

  poStrm.getline(buffer,1024);
  while (poStrm.good()) {
    std::string line = buffer;
    std::string data;
    TLineType type = parseLine(line, data);
    if (type == tMSGID) {
      if (untranslated.length() > 0) {
	mappings.erase(untranslated);
	ensureNormalText(translated);
	mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
      }
      untranslated = data;
      translated.resize(0);
    }
    else if (type == tMSGSTR) {
      if (untranslated.length() > 0)
	translated = data;
    }
    else if (type == tAPPEND) {
      if (untranslated.length() > 0)
	translated += data;
    }
    else if (type == tERROR) {

    }

    poStrm.getline(buffer,1024);
  }

  if ((untranslated.length() > 0) && (translated.length() > 0)) {
    mappings.erase(untranslated);
    ensureNormalText(translated);
    mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
  }
}

Bundle::TLineType Bundle::parseLine(const std::string &line, std::string &data) const
{
  int startPos, endPos;
  TLineType type;

  data.resize(0);
  startPos = line.find_first_not_of("\t \r\n");

  if ((startPos < 0) || (line.at(startPos) == '#'))
    return tCOMMENT;

  else if (line.at(startPos) == '"') {
    endPos = line.find_first_of('"', startPos+1);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr(startPos+1, endPos-startPos-1);
    return tAPPEND;
  }

  endPos = line.find_first_of("\t \r\n\"");
  if (endPos < 0)
    endPos = line.length();
  std::string key = line.substr(startPos, endPos-startPos);
  if (key == "msgid")
    type = tMSGID;
  else if (key == "msgstr")
    type = tMSGSTR;
  else
    return tERROR;

  startPos = line.find_first_of('"', endPos + 1);
  if (startPos >= 0) {
    startPos++;
    endPos = line.find_first_of('"', startPos);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr( startPos, endPos-startPos);
  }
  return type;
}

#include <set>
static std::set<std::string> unmapped;

std::string Bundle::getLocalString(const std::string &key) const
{
  if (key == "") return key;
  BundleStringMap::const_iterator it = mappings.find(key);
  if (it != mappings.end()) {
    return it->second;
  } else {
    if (BZDB.getDebug()) {
      if (unmapped.find( key ) == unmapped.end( )) {
	unmapped.insert( key );
    std::string stripped = stripAnsiCodes (key);
	std::string debugStr = "Unmapped Locale String: " + stripped + "\n";
	DEBUG1("%s", debugStr.c_str());
      }
    }
    return key;
  }
}

const char utf8bytes[256] = {
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6
};

#if 0
    // TODO: find the utf-8 values for these
    switch (c) {
      case '':
      case '':
	msg[i] = 'a';
      break;
      case '':
      case '':
	msg[i] = 'A';
      break;
      case '':
	msg[i] = 'i';
      break;
      case '':
	msg[i] = 'o';
      break;
      case '':
	msg[i] = 'O';
      break;
      case '':
	msg[i] = 'Y';
      break;
    }
#endif

// TODO: sort this and bsearch it. perhaps divided by utf8 length
const char *translationTable[][2] = {
  {"â", "a"}, {"à", "a"}, {"á", "a"}, {"ã", "a"},
  {"å", "aa"},
  {"ä", "ae"}, {"æ", "ae"},
  {"Â", "A"},
  {"Ä", "AE"}, {"Æ", "AE"},
  {"Å", "AA"},
  {"ç", "c"},
  {"é", "e"}, {"è", "e"}, {"ê", "e"}, {"ë", "e"},
  {"î", "i"}, {"ï", "i"}, {"í", "i"},
  {"ô", "o"}, {"ó", "o"}, {"õ", "o"},
  {"ö", "oe"}, {"ø", "oe"},
  {"Ö", "OE"}, {"Ø", "OE"},
  {"û", "u"}, {"ù", "u"}, {"ú", "u"},
  {"ü", "ue"},
  {"Ü", "UE"},
  {"ñ", "n"},
  {"ß", "ss"},
  {"¿", "?"},
  {"¡", "!"},
};

void Bundle::ensureNormalText(std::string &msg)
{
  // BZFlag's font system only supports ascii
  // convert msg to ascii
  // If you don't like it fix it.

  for (std::string::size_type i = 0; i < msg.length(); i++) {
    unsigned char c = msg.at(i);
    if (((c >= 'A') && (c <= 'Z'))
	|| ((c >= 'a') && (c <= 'z'))
	|| ((c >= '0') && (c <= '9'))
	|| (c == '}') || (c == '{') || (c == ' ')
	|| (c == ':') || (c == '/') || (c == '-')
	|| (c == ',') || (c == '&') || (c == '?')
	|| (c == '<') || (c == '>') || (c == '.')
	|| (c == '(') || (c == ')') || (c == '%')
	|| (c == '!') || (c == '+') || (c == '-')
	|| (c == '$') || (c == ';') || (c == '@')
	|| (c == '[') || (c == ']')
	|| (c == '=') || (c == '\'')) {
      ; // this char's ok by me
    } else {
      std::string replacement = "0x";
      unsigned int trans;
      // TODO: optimize this
      for (trans = 0; trans < sizeof(translationTable) / sizeof (char *) / 2; trans++) {
	if (!strncmp(translationTable[trans][0],&(msg.c_str()[i]),utf8bytes[(int)c])) {
	  replacement = translationTable[trans][1];
	  break;
	}
      }
      if (trans == sizeof(translationTable) / sizeof (char *) / 2) {
	// didn't find a match
	for (int j = 0; j < utf8bytes[(int)c]; j++) {
	//for (int j = 0; j < 1; j++) {
	  char hexchar[30];
	  sprintf(hexchar, "%2X", (unsigned char)msg.at(i+j));
	  replacement += hexchar;
	}
      }
      msg.replace(i,utf8bytes[(int)c],replacement);
      i += replacement.length() - 1;
    }
  }
  //std::cout << "\"" + msg + "\"\n";
}

std::string Bundle::formatMessage(const std::string &key, const std::vector<std::string> *parms) const
{
  std::string messageIn = getLocalString(key);
  std::string messageOut;

  if (!parms || (parms->size() == 0))
    return messageIn;

  int parmCnt = parms->size();
  int startPos = 0;
  int lCurlyPos = messageIn.find_first_of("{");

  while (lCurlyPos >= 0) {
    messageOut += messageIn.substr( startPos, lCurlyPos - startPos);
    int rCurlyPos = messageIn.find_first_of("}", lCurlyPos++);
    if (rCurlyPos < 0) {
      messageOut += messageIn.substr(lCurlyPos);
      return messageOut;
    }
    std::string numStr = messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    int num;
    if (sscanf(numStr.c_str(), "%d", &num) != 1)
      messageOut += messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    else {
      num--;
      if ((num >= 0) && (num < parmCnt))
	messageOut += (*parms)[num];
    }
    startPos = rCurlyPos+1;
    lCurlyPos = messageIn.find_first_of("{", startPos);
  }
  messageOut += messageIn.substr(startPos);
  return messageOut;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>#ifndef PIXELBOOST_DISABLE_GRAPHICS

#include <algorithm>
#include <set>

#include "pixelboost/graphics/camera/camera.h"
#include "pixelboost/graphics/camera/viewport.h"
#include "pixelboost/graphics/device/device.h"
#include "pixelboost/graphics/effect/effect.h"
#include "pixelboost/graphics/effect/manager.h"
#include "pixelboost/graphics/renderer/common/irenderer.h"
#include "pixelboost/graphics/renderer/common/renderable.h"
#include "pixelboost/graphics/renderer/common/renderer.h"

using namespace pb;

Renderer* Renderer::Renderer::_Instance = 0;

Renderer::Renderer()
{
    _Instance = this;

    _EffectManager = new EffectManager();
}

Renderer::~Renderer()
{
    _Instance = 0;
}

Renderer* Renderer::Instance()
{
    return _Instance;
}

void Renderer::Render()
{
    for (ViewportList::iterator it = _Viewports.begin(); it != _Viewports.end(); ++it)
    {
        (*it)->Render();

        FlushBuffer(*it);
    }
}

EffectManager* Renderer::GetEffectManager()
{
    return _EffectManager;
}

void Renderer::AttachRenderable(Renderable* renderable)
{
    _Renderables[renderable->GetLayer()].push_back(renderable);
}

void Renderer::AddViewport(Viewport* viewport)
{
    _Viewports.push_back(viewport);
}

void Renderer::RemoveViewport(Viewport* viewport)
{
    for (ViewportList::iterator it = _Viewports.begin(); it != _Viewports.end(); ++it)
    {
        if (*it == viewport)
        {
            _Viewports.erase(it);
            return;
        }
    }
}

void Renderer::SetHandler(int renderableType, IRenderer* renderer)
{
    _RenderableHandlers[renderableType] = renderer;
}

bool RenderableSorter(const Renderable* a, const Renderable* b)
{
    return a->GetMVP()[3][2] < b->GetMVP()[3][2];
}

void Renderer::FlushBuffer(Viewport* viewport)
{
    for (int i=0; i<16; i++)
    {
        RenderableList& renderables = _Renderables[i];

        if (!renderables.size())
            continue;

        for (RenderableList::iterator it = renderables.begin(); it != renderables.end(); ++it)
        {
            (*it)->CalculateMVP(viewport);
        }

        std::stable_sort(renderables.begin(), renderables.end(), &RenderableSorter);

        Uid type = renderables[0]->GetRenderableType();
        Effect* effect = renderables[0]->GetEffect();
        int start = 0;
        int count = 0;

        for (int i=0; i < renderables.size(); i++)
        {
            Uid newType = renderables[i]->GetRenderableType();
            Effect* newEffect = renderables[i]->GetEffect();

            if (type == newType && effect == newEffect)
            {
                count++;
            } else {
                RenderBatch(viewport, count, &renderables[start], effect);
                start = i;
                count = 1;
                type = newType;
                effect = newEffect;
            }
        }

        if (count > 0)
        {
            RenderBatch(viewport, count, &renderables[start], effect);
        }
    }

    _Renderables.clear();
}

void Renderer::RenderBatch(Viewport* viewport, int count, Renderable** renderable, Effect* effect)
{
    if (!effect)
        return;

    RenderableHandlerMap::iterator it = _RenderableHandlers.find(renderable[0]->GetRenderableType());

    if (it != _RenderableHandlers.end())
    {
        EffectTechnique* technique = effect->GetTechnique(viewport->GetRenderScheme());

        if (!technique)
        {
            for (int i=0; i < count; i++)
            {
                technique = viewport->GetTechnique(renderable[i], effect);

                if (technique)
                {
                    for (int j=0; j<technique->GetNumPasses(); j++)
                    {
                        EffectPass* pass = technique->GetPass(j);
                        pass->Bind();
                        it->second->Render(1, &renderable[i], viewport, pass);
                    }
                }
            }
        } else
        {
            for (int i=0; i<technique->GetNumPasses(); i++)
            {
                EffectPass* pass = technique->GetPass(i);
                pass->Bind();
                it->second->Render(count, renderable, viewport, pass);
            }
        }
    }
}

#endif
<commit_msg>Reverse depth sort<commit_after>#ifndef PIXELBOOST_DISABLE_GRAPHICS

#include <algorithm>
#include <set>

#include "pixelboost/graphics/camera/camera.h"
#include "pixelboost/graphics/camera/viewport.h"
#include "pixelboost/graphics/device/device.h"
#include "pixelboost/graphics/effect/effect.h"
#include "pixelboost/graphics/effect/manager.h"
#include "pixelboost/graphics/renderer/common/irenderer.h"
#include "pixelboost/graphics/renderer/common/renderable.h"
#include "pixelboost/graphics/renderer/common/renderer.h"

using namespace pb;

Renderer* Renderer::Renderer::_Instance = 0;

Renderer::Renderer()
{
    _Instance = this;

    _EffectManager = new EffectManager();
}

Renderer::~Renderer()
{
    _Instance = 0;
}

Renderer* Renderer::Instance()
{
    return _Instance;
}

void Renderer::Render()
{
    for (ViewportList::iterator it = _Viewports.begin(); it != _Viewports.end(); ++it)
    {
        (*it)->Render();

        FlushBuffer(*it);
    }
}

EffectManager* Renderer::GetEffectManager()
{
    return _EffectManager;
}

void Renderer::AttachRenderable(Renderable* renderable)
{
    _Renderables[renderable->GetLayer()].push_back(renderable);
}

void Renderer::AddViewport(Viewport* viewport)
{
    _Viewports.push_back(viewport);
}

void Renderer::RemoveViewport(Viewport* viewport)
{
    for (ViewportList::iterator it = _Viewports.begin(); it != _Viewports.end(); ++it)
    {
        if (*it == viewport)
        {
            _Viewports.erase(it);
            return;
        }
    }
}

void Renderer::SetHandler(int renderableType, IRenderer* renderer)
{
    _RenderableHandlers[renderableType] = renderer;
}

bool RenderableBackToFrontSorter(const Renderable* a, const Renderable* b)
{
    return a->GetMVP()[3][2] > b->GetMVP()[3][2];
}

void Renderer::FlushBuffer(Viewport* viewport)
{
    for (int i=0; i<16; i++)
    {
        RenderableList& renderables = _Renderables[i];

        if (!renderables.size())
            continue;

        for (RenderableList::iterator it = renderables.begin(); it != renderables.end(); ++it)
        {
            (*it)->CalculateMVP(viewport);
        }

        std::stable_sort(renderables.begin(), renderables.end(), &RenderableBackToFrontSorter);

        Uid type = renderables[0]->GetRenderableType();
        Effect* effect = renderables[0]->GetEffect();
        int start = 0;
        int count = 0;

        for (int i=0; i < renderables.size(); i++)
        {
            Uid newType = renderables[i]->GetRenderableType();
            Effect* newEffect = renderables[i]->GetEffect();

            if (type == newType && effect == newEffect)
            {
                count++;
            } else {
                RenderBatch(viewport, count, &renderables[start], effect);
                start = i;
                count = 1;
                type = newType;
                effect = newEffect;
            }
        }

        if (count > 0)
        {
            RenderBatch(viewport, count, &renderables[start], effect);
        }
    }

    _Renderables.clear();
}

void Renderer::RenderBatch(Viewport* viewport, int count, Renderable** renderable, Effect* effect)
{
    if (!effect)
        return;

    RenderableHandlerMap::iterator it = _RenderableHandlers.find(renderable[0]->GetRenderableType());

    if (it != _RenderableHandlers.end())
    {
        EffectTechnique* technique = effect->GetTechnique(viewport->GetRenderScheme());

        if (!technique)
        {
            for (int i=0; i < count; i++)
            {
                technique = viewport->GetTechnique(renderable[i], effect);

                if (technique)
                {
                    for (int j=0; j<technique->GetNumPasses(); j++)
                    {
                        EffectPass* pass = technique->GetPass(j);
                        pass->Bind();
                        it->second->Render(1, &renderable[i], viewport, pass);
                    }
                }
            }
        } else
        {
            for (int i=0; i<technique->GetNumPasses(); i++)
            {
                EffectPass* pass = technique->GetPass(i);
                pass->Bind();
                it->second->Render(count, renderable, viewport, pass);
            }
        }
    }
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/notifications/notification_ui_manager.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"

// A class which represents a notification waiting to be shown.
class QueuedNotification {
 public:
  QueuedNotification(const Notification& notification, Profile* profile)
      : notification_(notification),
        profile_(profile) {
  }

  const Notification& notification() const { return notification_; }
  Profile* profile() const { return profile_; }

  void Replace(const Notification& new_notification) {
    notification_ = new_notification;
  }

 private:
  // The notification to be shown.
  Notification notification_;

  // Non owned pointer to the user's profile.
  Profile* profile_;

  DISALLOW_COPY_AND_ASSIGN(QueuedNotification);
};

NotificationUIManager::NotificationUIManager()
    : balloon_collection_(NULL) {
  registrar_.Add(this, NotificationType::APP_TERMINATING,
                 NotificationService::AllSources());
}

NotificationUIManager::~NotificationUIManager() {
  STLDeleteElements(&show_queue_);
}

// static
NotificationUIManager* NotificationUIManager::Create() {
  BalloonCollection* balloons = BalloonCollection::Create();
  NotificationUIManager* instance = new NotificationUIManager();
  instance->Initialize(balloons);
  balloons->set_space_change_listener(instance);
  return instance;
}

void NotificationUIManager::Add(const Notification& notification,
                                Profile* profile) {
  if (TryReplacement(notification)) {
    return;
  }

  VLOG(1) << "Added notification. URL: "
          << notification.content_url().spec();
  show_queue_.push_back(
      new QueuedNotification(notification, profile));
  CheckAndShowNotifications();
}

bool NotificationUIManager::CancelById(const std::string& id) {
  // See if this ID hasn't been shown yet.
  NotificationDeque::iterator iter;
  for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) {
    if ((*iter)->notification().notification_id() == id) {
      show_queue_.erase(iter);
      return true;
    }
  }
  // If it has been shown, remove it from the balloon collections.
  return balloon_collection_->RemoveById(id);
}

bool NotificationUIManager::CancelAllBySourceOrigin(const GURL& source) {
  // Same pattern as CancelById, but more complicated than the above
  // because there may be multiple notifications from the same source.
  bool removed = false;
  NotificationDeque::iterator iter;
  for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) {
    if ((*iter)->notification().origin_url() == source) {
      iter = show_queue_.erase(iter);
      removed = true;
    } else {
      ++iter;
    }
  }

  return balloon_collection_->RemoveBySourceOrigin(source) || removed;
}

void NotificationUIManager::CancelAll() {
  STLDeleteElements(&show_queue_);
  balloon_collection_->RemoveAll();
}

void NotificationUIManager::CheckAndShowNotifications() {
  // TODO(johnnyg): http://crbug.com/25061 - Check for user idle/presentation.
  ShowNotifications();
}

void NotificationUIManager::ShowNotifications() {
  while (!show_queue_.empty() && balloon_collection_->HasSpace()) {
    scoped_ptr<QueuedNotification> queued_notification(show_queue_.front());
    show_queue_.pop_front();
    balloon_collection_->Add(queued_notification->notification(),
                             queued_notification->profile());
  }
}

void NotificationUIManager::OnBalloonSpaceChanged() {
  CheckAndShowNotifications();
}

bool NotificationUIManager::TryReplacement(const Notification& notification) {
  const GURL& origin = notification.origin_url();
  const string16& replace_id = notification.replace_id();

  if (replace_id.empty())
    return false;

  // First check the queue of pending notifications for replacement.
  // Then check the list of notifications already being shown.
  NotificationDeque::iterator iter;
  for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) {
    if (origin == (*iter)->notification().origin_url() &&
        replace_id == (*iter)->notification().replace_id()) {
      (*iter)->Replace(notification);
      return true;
    }
  }

  BalloonCollection::Balloons::iterator balloon_iter;
  BalloonCollection::Balloons balloons =
      balloon_collection_->GetActiveBalloons();
  for (balloon_iter = balloons.begin();
       balloon_iter != balloons.end();
       ++balloon_iter) {
    if (origin == (*balloon_iter)->notification().origin_url() &&
        replace_id == (*balloon_iter)->notification().replace_id()) {
      (*balloon_iter)->Update(notification);
      return true;
    }
  }

  return false;
}

void NotificationUIManager::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) {
  if (type == NotificationType::APP_TERMINATING)
    CancelAll();
  else
    NOTREACHED();
}
<commit_msg>Stray ++ causes crashes.  Don't walk off the end of the array.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/notifications/notification_ui_manager.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"

// A class which represents a notification waiting to be shown.
class QueuedNotification {
 public:
  QueuedNotification(const Notification& notification, Profile* profile)
      : notification_(notification),
        profile_(profile) {
  }

  const Notification& notification() const { return notification_; }
  Profile* profile() const { return profile_; }

  void Replace(const Notification& new_notification) {
    notification_ = new_notification;
  }

 private:
  // The notification to be shown.
  Notification notification_;

  // Non owned pointer to the user's profile.
  Profile* profile_;

  DISALLOW_COPY_AND_ASSIGN(QueuedNotification);
};

NotificationUIManager::NotificationUIManager()
    : balloon_collection_(NULL) {
  registrar_.Add(this, NotificationType::APP_TERMINATING,
                 NotificationService::AllSources());
}

NotificationUIManager::~NotificationUIManager() {
  STLDeleteElements(&show_queue_);
}

// static
NotificationUIManager* NotificationUIManager::Create() {
  BalloonCollection* balloons = BalloonCollection::Create();
  NotificationUIManager* instance = new NotificationUIManager();
  instance->Initialize(balloons);
  balloons->set_space_change_listener(instance);
  return instance;
}

void NotificationUIManager::Add(const Notification& notification,
                                Profile* profile) {
  if (TryReplacement(notification)) {
    return;
  }

  VLOG(1) << "Added notification. URL: "
          << notification.content_url().spec();
  show_queue_.push_back(
      new QueuedNotification(notification, profile));
  CheckAndShowNotifications();
}

bool NotificationUIManager::CancelById(const std::string& id) {
  // See if this ID hasn't been shown yet.
  NotificationDeque::iterator iter;
  for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) {
    if ((*iter)->notification().notification_id() == id) {
      show_queue_.erase(iter);
      return true;
    }
  }
  // If it has been shown, remove it from the balloon collections.
  return balloon_collection_->RemoveById(id);
}

bool NotificationUIManager::CancelAllBySourceOrigin(const GURL& source) {
  // Same pattern as CancelById, but more complicated than the above
  // because there may be multiple notifications from the same source.
  bool removed = false;
  NotificationDeque::iterator iter;
  for (iter = show_queue_.begin(); iter != show_queue_.end();) {
    if ((*iter)->notification().origin_url() == source) {
      iter = show_queue_.erase(iter);
      removed = true;
    } else {
      ++iter;
    }
  }

  return balloon_collection_->RemoveBySourceOrigin(source) || removed;
}

void NotificationUIManager::CancelAll() {
  STLDeleteElements(&show_queue_);
  balloon_collection_->RemoveAll();
}

void NotificationUIManager::CheckAndShowNotifications() {
  // TODO(johnnyg): http://crbug.com/25061 - Check for user idle/presentation.
  ShowNotifications();
}

void NotificationUIManager::ShowNotifications() {
  while (!show_queue_.empty() && balloon_collection_->HasSpace()) {
    scoped_ptr<QueuedNotification> queued_notification(show_queue_.front());
    show_queue_.pop_front();
    balloon_collection_->Add(queued_notification->notification(),
                             queued_notification->profile());
  }
}

void NotificationUIManager::OnBalloonSpaceChanged() {
  CheckAndShowNotifications();
}

bool NotificationUIManager::TryReplacement(const Notification& notification) {
  const GURL& origin = notification.origin_url();
  const string16& replace_id = notification.replace_id();

  if (replace_id.empty())
    return false;

  // First check the queue of pending notifications for replacement.
  // Then check the list of notifications already being shown.
  NotificationDeque::iterator iter;
  for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) {
    if (origin == (*iter)->notification().origin_url() &&
        replace_id == (*iter)->notification().replace_id()) {
      (*iter)->Replace(notification);
      return true;
    }
  }

  BalloonCollection::Balloons::iterator balloon_iter;
  BalloonCollection::Balloons balloons =
      balloon_collection_->GetActiveBalloons();
  for (balloon_iter = balloons.begin();
       balloon_iter != balloons.end();
       ++balloon_iter) {
    if (origin == (*balloon_iter)->notification().origin_url() &&
        replace_id == (*balloon_iter)->notification().replace_id()) {
      (*balloon_iter)->Update(notification);
      return true;
    }
  }

  return false;
}

void NotificationUIManager::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) {
  if (type == NotificationType::APP_TERMINATING)
    CancelAll();
  else
    NOTREACHED();
}
<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "Copyright (c) 2012-2013 Tokutek Inc.  All rights reserved."
#ident "$Id$"

// Test to make sure nothing crashes if the backup source directory has unreadable permissions.

#include <errno.h>

#include "backup_test_helpers.h"

volatile bool saw_error = false;

static void expect_eacces_error_fun(int error_number, const char *error_string, void *backup_extra __attribute__((unused))) {
    fprintf(stderr, "EXPECT ERROR %d: %d (%s)\n", EACCES, error_number, error_string);
    check(error_number==EACCES);
    saw_error = true;
}

int test_main(int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
    char *src = get_src();
    char *dst = get_dst();
    {
        int r = systemf("chmod ugo+rwx %s", src);
        check(r==0);
    }
    setup_source();
    setup_destination();
    setup_dirs();
    {
        int r = systemf("chmod ugo-r %s", src);
        check(r==0);
    }
    {
        const char *srcs[1] = {src};
        const char *dsts[1] = {dst};
        int r = tokubackup_create_backup(srcs, dsts, 1,
                                         simple_poll_fun, NULL,
                                         expect_eacces_error_fun, NULL);
        check(r==EACCES);
        check(saw_error);
    }
    {
        int r = systemf("chmod ugo+rwx %s", src);
        check(r==0);
    }
    cleanup_dirs();
    free(src);
    free(dst);
    return 0;
}

<commit_msg>#19 still messing with permissions<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "Copyright (c) 2012-2013 Tokutek Inc.  All rights reserved."
#ident "$Id$"

// Test to make sure nothing crashes if the backup source directory has unreadable permissions.

#include <errno.h>

#include "backup_test_helpers.h"

volatile bool saw_error = false;

static void expect_eacces_error_fun(int error_number, const char *error_string, void *backup_extra __attribute__((unused))) {
    fprintf(stderr, "EXPECT ERROR %d: %d (%s)\n", EACCES, error_number, error_string);
    check(error_number==EACCES);
    saw_error = true;
}

int test_main(int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
    char *src = get_src();
    char *dst = get_dst();
    {
        int r = systemf("chmod ugo+rwx %s 2> /dev/null", src);
        ignore(r);
    }
    setup_source();
    setup_destination();
    setup_dirs();
    {
        int r = systemf("chmod ugo-r %s", src);
        check(r==0);
    }
    {
        const char *srcs[1] = {src};
        const char *dsts[1] = {dst};
        int r = tokubackup_create_backup(srcs, dsts, 1,
                                         simple_poll_fun, NULL,
                                         expect_eacces_error_fun, NULL);
        check(r==EACCES);
        check(saw_error);
    }
    {
        int r = systemf("chmod ugo+rwx %s", src);
        check(r==0);
    }
    cleanup_dirs();
    free(src);
    free(dst);
    return 0;
}

<|endoftext|>


<commit_before>#include <QtTest>

#include <timing/calendartiming.h>

class TestCalendarTiming : public QObject
{
    Q_OBJECT

private slots:
    void constructors()
    {
        CalendarTiming timing;

        QCOMPARE(timing.type(), QLatin1String("calendar"));
    }
};

QTEST_MAIN(TestCalendarTiming)

#include "tst_calendartiming.moc"
<commit_msg>Unittests for calendarTiming<commit_after>#include <QtTest>

#include <timing/calendartiming.h>

class TestCalendarTiming : public QObject
{
    Q_OBJECT

private slots:
    void constructors()
    {
        CalendarTiming timing;

        QCOMPARE(timing.type(), QLatin1String("calendar"));
    }

    void nextRuns()
    {
        QTime time = QTime::currentTime();
        time = QTime(time.hour(), time.minute(), time.second());
        QDateTime now = QDateTime::currentDateTime();
        now.setTime(time);

        QDateTime start = QDateTime::currentDateTime();
        QDateTime end;
        QList<quint8> months = QList<quint8>()<<1<<2<<3<<4<<5<<6<<7<<8<<9<<10<<11<<12;
        QList<quint8> daysOfWeek = QList<quint8>()<<1<<2<<3<<4<<5<<6<<7;
        QList<quint8> daysOfMonth;
        QList<quint8> hours;
        QList<quint8> minutes;
        QList<quint8> seconds;

        for(int i=1; i<32; i++)
        {
            daysOfMonth<<i;
        }

        for(int i=0; i<24; i++)
        {
            hours<<i;
        }

        for(int i=0; i<60; i++)
        {
            minutes<<i;
            seconds<<i;
        }

        // start now
        CalendarTiming nowTiming(start, end, months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("start time now");
        QCOMPARE(nowTiming.nextRun(), now);

        // start time in the future
        CalendarTiming futureTiming(start.addDays(1), end, months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("start time one day in the future");
        QCOMPARE(futureTiming.nextRun(), now.addDays(1));

        // end time already reached
        CalendarTiming pastTiming(start.addDays(1), start.addDays(-1), months, daysOfWeek, daysOfMonth, hours, minutes, seconds);
        qDebug("end time already reached");
        QCOMPARE(pastTiming.nextRun(), QDateTime());

        // start tomorrow because hour already passed today (not true before 4 am)
        CalendarTiming tomorrowTiming(start, end, months, daysOfWeek, daysOfMonth, QList<quint8>()<<4, minutes, seconds);
        qDebug("nextRun tomorrow because hour already passed today (4 am)");
        QDateTime tomorrowTime = now.addDays(1);
        tomorrowTime.setTime(QTime(4,0,0));
        QCOMPARE(tomorrowTiming.nextRun(), tomorrowTime);

        // start tomorrow because hour already passed today (not true before 4 am [2])
        CalendarTiming tomorrowTiming2(start, end, months, daysOfWeek, daysOfMonth, QList<quint8>()<<4<<5, minutes, seconds);
        qDebug("nextRun tomorrow because hour already passed today (4 and 5 am)");
        QCOMPARE(tomorrowTiming2.nextRun(), tomorrowTime);

        // start next month because day already passed this month (not true on 1st of month)
        CalendarTiming nextMonthTiming(start, end, months, daysOfWeek, QList<quint8>()<<1, hours, minutes, seconds);
        qDebug("nextRun next month because day already passed this month (1st)");
        QDateTime nextMonthTime = now.addMonths(1);
        nextMonthTime.setTime(QTime(0,0,0));
        nextMonthTime.setDate(QDate(nextMonthTime.date().year(), nextMonthTime.date().month(), 1));
        QCOMPARE(nextMonthTiming.nextRun(), nextMonthTime);

        // start next month because day already passed this month (not true on 1st or 2nd of month)
        CalendarTiming nextMonthTiming2(start, end, months, daysOfWeek, QList<quint8>()<<1<<2, hours, minutes, seconds);
        qDebug("nextRun next month because day already passed this month (1st and 2nd)");
        QCOMPARE(nextMonthTiming2.nextRun(), nextMonthTime);

        // no nextRun because of invalid Timing (February 30th)
        CalendarTiming februaryTiming(start, end,  QList<quint8>()<<2, daysOfWeek, QList<quint8>()<<30, hours, minutes, seconds);
        qDebug("no nextRun because invalid Timing (30.02)");
        QCOMPARE(februaryTiming.nextRun(), QDateTime());

        // start next year because day already passed this year (not true on January 1st)
        CalendarTiming yearTiming(start, end,  QList<quint8>()<<1, daysOfWeek, QList<quint8>()<<1, hours, minutes, seconds);
        qDebug("nextRun on January 1st");
        QCOMPARE(yearTiming.nextRun(), QDateTime(QDate(now.date().year()+1, 1, 1), QTime(0,0,0)));
    }
};

QTEST_MAIN(TestCalendarTiming)

#include "tst_calendartiming.moc"
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 midnightBITS
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifdef _WIN32
#include <sdkddkver.h>
#endif

#include <dom.hpp>
#include <http/http.hpp>
#include <http/server.hpp>
#include <ssdp/ssdp.hpp>
#include <boost/filesystem.hpp>
#include <iostream>

namespace fs = boost::filesystem;

inline void push() {}

template <typename T, typename... Args>
inline void push(T && arg, Args && ... rest)
{
	std::cerr << arg;
	push(std::forward<Args>(rest)...);
}

template <typename... Args>
void help(Args&& ... args)
{
	std::cerr << "svcc 1.0 -- SSDP service compiler.\n";

	push(std::forward<Args>(args)...);
	if (sizeof...(args) > 0)
		std::cerr << "\n";

	std::cerr <<
		"\nusage:\n"
		"	ssvc INFILE OUTFILE\n"
		"e.g.\n"
		"	ssvc service.xml service.idl\n"
		"	ssvc service.idl service.hpp\n"
		;
}

inline bool is_file(const fs::path& p) { return fs::is_regular_file(p) || fs::is_symlink(p); }

int main(int argc, char* argv [])
{
	try
	{
		std::cout << fs::current_path().string() << std::endl;

		if (argc != 3)
		{
			help("File name missing.");
			return 1;
		}
		fs::path in(argv[1]);
		fs::path out(argv[2]);

		if (is_file(in) && is_file(out) && fs::last_write_time(in) < fs::last_write_time(out))
			return 0;

		fs::ifstream in_f(in);

		if (!in_f)
		{
			help("File `", in, "` could not be read.");
			return 1;
		}

		std::cout << in.filename().string() << std::endl;

		auto doc = dom::XmlDocument::fromDataSource([&](void* buffer, size_t size) { return (size_t)in_f.read((char*)buffer, size).gcount(); });
		if (doc)
		{
			// try XML -> IDL
		}
		else
		{
			// try IDL -> HPP
		}
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\n";
	}
	return 0;
}
<commit_msg>Crude IDL printing<commit_after>/*
 * Copyright (C) 2013 midnightBITS
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifdef _WIN32
#include <sdkddkver.h>
#endif

#include <dom.hpp>
#include <http/http.hpp>
#include <http/server.hpp>
#include <ssdp/ssdp.hpp>
#include <boost/filesystem.hpp>
#include <iostream>

namespace fs = boost::filesystem;

inline void push() {}

template <typename T, typename... Args>
inline void push(T && arg, Args && ... rest)
{
	std::cerr << arg;
	push(std::forward<Args>(rest)...);
}

template <typename... Args>
void help(Args&& ... args)
{
	std::cerr << "svcc 1.0 -- SSDP service compiler.\n";

	push(std::forward<Args>(args)...);
	if (sizeof...(args) > 0)
		std::cerr << "\n";

	std::cerr <<
		"\nusage:\n"
		"	ssvc INFILE OUTFILE\n"
		"e.g.\n"
		"	ssvc service.xml service.idl\n"
		"	ssvc service.idl service.hpp\n"
		;
}

inline bool is_file(const fs::path& p) { return fs::is_regular_file(p) || fs::is_symlink(p); }

struct state_variable
{
	bool m_event;
	std::string m_name;
	std::string m_type;
	std::vector<std::string> m_values;

	std::string getType() const { return m_values.empty() ? m_type : m_event ? m_name + "_Values" : m_name; }
};

struct action_arg
{
	bool m_input;
	std::string m_name;
	std::string m_type_ref;
	std::string getType(const std::vector<state_variable>& refs) const
	{
		for (auto&& ref : refs)
		{
			if (m_type_ref == ref.m_name)
				return ref.getType();
		}
		return m_type_ref;
	}
};

struct action
{
	std::string m_name;
	std::vector<action_arg> m_args;
};

inline std::string find_string(const dom::XmlNodePtr& node, const std::string& xpath)
{
	auto tmp = node->find(xpath);
	if (tmp) return tmp->stringValue();
	return std::string();
}

inline std::string find_string(const dom::XmlNodePtr& node, const std::string& xpath, dom::Namespaces ns)
{
	auto tmp = node->find(xpath, ns);
	if (tmp) return tmp->stringValue();
	return std::string();
}

int main(int argc, char* argv [])
{
	try
	{
		std::cout << fs::current_path().string() << std::endl;

		if (argc != 3)
		{
			help("File name missing.");
			return 1;
		}
		fs::path in(argv[1]);
		fs::path out(argv[2]);

		if (is_file(in) && is_file(out) && fs::last_write_time(in) < fs::last_write_time(out))
			return 0;

		fs::ifstream in_f(in);

		if (!in_f)
		{
			help("File `", in, "` could not be read.");
			return 1;
		}

		std::cout << in.filename().string() << std::endl;

		auto doc = dom::XmlDocument::fromDataSource([&](void* buffer, size_t size) { return (size_t)in_f.read((char*)buffer, size).gcount(); });
		if (doc)
		{
			std::vector<state_variable> types_variables;
			std::vector<action> actions;
			int spec_major = 0, spec_minor = 0;

			// try XML -> IDL
			dom::NSData ns[] = { {"svc", "urn:schemas-upnp-org:service-1-0"} };
			auto version = doc->find("/svc:scpd/svc:specVersion", ns);
			if (version)
			{
				auto major = find_string(version, "svc:major", ns);
				auto minor = find_string(version, "svc:minor", ns);
				{
					std::istringstream i(major);
					i >> spec_major;
				}
				{
					std::istringstream i(minor);
					i >> spec_minor;
				}
			}

			auto action_list = doc->findall("/svc:scpd/svc:actionList/svc:action", ns);
			for (auto&& act : action_list)
			{
				action action;
				action.m_name = find_string(act, "svc:name", ns);

				auto args = act->findall("svc:argumentList/svc:argument", ns);
				for (auto&& arg : args)
				{
					action_arg action_arg;
					action_arg.m_input = find_string(arg, "svc:direction", ns) == "out";
					action_arg.m_name = find_string(arg, "svc:name", ns);
					action_arg.m_type_ref = find_string(arg, "svc:relatedStateVariable", ns);
					action.m_args.push_back(action_arg);
				}
				actions.push_back(action);
			}

			auto variables = doc->findall("/svc:scpd/svc:serviceStateTable/svc:stateVariable", ns);
			for (auto&& variable : variables)
			{
				auto sendEvent = find_string(variable, "@sendEvents");

				state_variable var;
				var.m_event = sendEvent == "1" || sendEvent == "yes";
				var.m_name = find_string(variable, "svc:name", ns);
				var.m_type = find_string(variable, "svc:dataType", ns);

				auto allowedValues = variable->findall("svc:allowedValueList/svc:allowedValue", ns);
				for (auto&& value : allowedValues)
					var.m_values.push_back(value->stringValue());

				types_variables.push_back(var);
			}

			size_t events = 0;
			for (auto&& var : types_variables)
			{
				if (var.m_values.empty())
				{
					++events;
					continue;
				}

				std::cout << "enum " << var.getType() << " { // " << var.m_type << "\n";
				for (auto&& val : var.m_values)
				{
					std::cout << "    " << val << ";\n";
				}
				std::cout << "};\n\n";
			}

			std::cout << "[version(" << spec_major << "." << spec_minor << ")] interface <name missing> {\n";

			for (auto&& action : actions)
			{
				bool first = true;
				std::cout << "    void " << action.m_name << "(";

				size_t  out_count = 0;
				for (auto&& arg : action.m_args)
				{
					if (!arg.m_input)
						++out_count;
				}

				for (auto&& arg : action.m_args)
				{
					if (first) first = false;
					else std::cout << ", ";
					std::cout << (arg.m_input ? "[in] " : out_count == 1 ? "[retval] " : "[out] ") << arg.getType(types_variables) << " " << arg.m_name;
				}
				std::cout << ");\n";
			}

			if (!types_variables.empty() && events > 0)
				std::cout << "\n";

			for (auto && var : types_variables)
			{
				if (!var.m_event)
					continue;

				std::cout << "    ";
				std::cout << var.getType() << " " << var.m_name << ";\n";
			}

			std::cout << "};\n";
		}
		else
		{
			// try IDL -> HPP
		}
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\n";
	}
	return 0;
}
<|endoftext|>


<commit_before>#include "remote_control/resource_allocation_manager_impl.h"
#include "application_manager/application.h"
#include "application_manager/message_helper.h"
#include "remote_control/rc_module_constants.h"
#include "json/json.h"
#include "utils/helpers.h"
#include "utils/make_shared.h"
#include "remote_control/message_helper.h"

namespace remote_control {

CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule")

ResourceAllocationManagerImpl::ResourceAllocationManagerImpl(
    RemotePluginInterface& rc_plugin)
    : current_access_mode_(hmi_apis::Common_RCAccessMode::AUTO_ALLOW)
    , rc_plugin_(rc_plugin) {}

ResourceAllocationManagerImpl::~ResourceAllocationManagerImpl() {}

AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  const application_manager::ApplicationSharedPtr acquiring_app =
      rc_plugin_.service()->GetApplication(app_id);
  if (!acquiring_app) {
    LOG4CXX_WARN(logger_, "App with app_id: " << app_id << "does not exist!");
    return AcquireResult::IN_USE;
  }

  const AllocatedResources::const_iterator allocated_it =
      allocated_resources_.find(module_type);
  if (allocated_resources_.end() == allocated_it) {
    allocated_resources_[module_type] = app_id;
    LOG4CXX_DEBUG(logger_,
                  "Resource is not acquired yet. "
                      << "App: " << app_id << " is allowed to acquire "
                      << module_type);
    return AcquireResult::ALLOWED;
  }

  if (app_id == allocated_resources_[module_type]) {
    LOG4CXX_DEBUG(logger_,
                  "App: " << app_id << " is already acquired resource "
                          << module_type);
    return AcquireResult::ALLOWED;
  }

  if (IsModuleTypeRejected(module_type, app_id)) {
    LOG4CXX_DEBUG(logger_,
                  "Driver disallowed app: " << app_id << " to acquire "
                                            << module_type);
    return AcquireResult::REJECTED;
  }

  const mobile_apis::HMILevel::eType acquiring_app_hmi_level =
      acquiring_app->hmi_level();

  if (mobile_apis::HMILevel::HMI_FULL != acquiring_app_hmi_level) {
    LOG4CXX_DEBUG(
        logger_,
        "Aquiring resources is not allowed in HMI level: "
            << application_manager::MessageHelper::StringifiedHMILevel(
                   acquiring_app_hmi_level) << ". App: " << app_id
            << " is disallowed to acquire " << module_type);
    return AcquireResult::REJECTED;
  }

  switch (current_access_mode_) {
    case hmi_apis::Common_RCAccessMode::AUTO_DENY: {
      LOG4CXX_DEBUG(logger_,
                    "Current access_mode is AUTO_DENY. "
                        << "App: " << app_id << " is disallowed to acquire "
                        << module_type);
      return AcquireResult::IN_USE;
    }
    case hmi_apis::Common_RCAccessMode::ASK_DRIVER: {
      LOG4CXX_DEBUG(logger_,
                    "Current access_mode is ASK_DRIVER. "
                    "Driver confirmation is required for app: "
                        << app_id << " to acquire " << module_type);
      return AcquireResult::ASK_DRIVER;
    }
    case hmi_apis::Common_RCAccessMode::AUTO_ALLOW: {
      LOG4CXX_DEBUG(logger_,
                    "Current access_mode is AUTO_ALLOW. "
                        << "App: " << app_id << " is allowed to acquire "
                        << module_type);

      allocated_resources_[module_type] = app_id;
      return AcquireResult::ALLOWED;
    }
    default: { DCHECK_OR_RETURN(false, AcquireResult::IN_USE); }
  }
}

void ResourceAllocationManagerImpl::SetResourceState(
    const std::string& module_type,
    const uint32_t app_id,
    const ResourceState::eType state) {
  LOG4CXX_AUTO_TRACE(logger_);
  LOG4CXX_DEBUG(logger_,
                "Setting state for " << module_type << " by app_id " << app_id
                                     << " to state " << state);
  const AllocatedResources::const_iterator allocated_it =
      allocated_resources_.find(module_type);

  const std::string status = allocated_resources_.end() != allocated_it
                                 ? " acquired "
                                 : " not acquired ";
  LOG4CXX_DEBUG(logger_,
                "Resource " << module_type << " is " << status
                            << " Owner application id is "
                            << allocated_it->second
                            << " Changing application id is " << app_id);

  resources_state_[module_type] = state;
  LOG4CXX_DEBUG(logger_, "Resource " << module_type << " got state " << state);
}

bool ResourceAllocationManagerImpl::IsResourceFree(
    const std::string& module_type) const {
  LOG4CXX_AUTO_TRACE(logger_);
  const ResourcesState::const_iterator resource =
      resources_state_.find(module_type);

  if (resources_state_.end() == resource) {
    LOG4CXX_DEBUG(logger_, "Resource " << module_type << " is free.");
    return true;
  }

  LOG4CXX_DEBUG(logger_,
                "Resource " << module_type << " state is " << resource->second);

  return ResourceState::FREE == resource->second;
}

void ResourceAllocationManagerImpl::SetAccessMode(
    const hmi_apis::Common_RCAccessMode::eType access_mode) {
  if (hmi_apis::Common_RCAccessMode::ASK_DRIVER != access_mode) {
    rejected_resources_for_application_.clear();
  }
  current_access_mode_ = access_mode;
}

void ResourceAllocationManagerImpl::ForceAcquireResource(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_DEBUG(logger_, "Force " << app_id << " acquiring " << module_type);
  allocated_resources_[module_type] = app_id;
}

bool ResourceAllocationManagerImpl::IsModuleTypeRejected(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  RejectedResources::iterator it =
      rejected_resources_for_application_.find(app_id);

  if (rejected_resources_for_application_.end() == it) {
    return false;
  }

  const std::vector<std::string>& list_of_rejected_resources =
      rejected_resources_for_application_[app_id];

  return helpers::in_range(list_of_rejected_resources, module_type);
}

void ResourceAllocationManagerImpl::OnDriverDisallowed(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  RejectedResources::iterator it =
      rejected_resources_for_application_.find(app_id);

  if (rejected_resources_for_application_.end() == it) {
    rejected_resources_for_application_[app_id] = std::vector<std::string>();
  }
  std::vector<std::string>& list_of_rejected_resources =
      rejected_resources_for_application_[app_id];
  list_of_rejected_resources.push_back(module_type);
}

void ResourceAllocationManagerImpl::OnUnregisterApplication(
    const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);

  rejected_resources_for_application_.erase(app_id);
  for (AllocatedResources::const_iterator it = allocated_resources_.begin();
       it != allocated_resources_.end();) {
    if (app_id == it->second) {
      LOG4CXX_INFO(logger_,
                   "Application " << app_id
                                  << " is unregistered. Releasing resource "
                                  << it->first);
      resources_state_.erase(it->first);
      it = allocated_resources_.erase(it);
    } else {
      ++it;
    }
  }
}

void ResourceAllocationManagerImpl::ResetAllAllocations() {
  LOG4CXX_AUTO_TRACE(logger_);
  allocated_resources_.clear();
  rejected_resources_for_application_.clear();
  resources_state_.clear();
}

}  // namespace remote_control
<commit_msg>Mark variable as unused to avoid build fail without logs<commit_after>#include "remote_control/resource_allocation_manager_impl.h"
#include "application_manager/application.h"
#include "application_manager/message_helper.h"
#include "remote_control/rc_module_constants.h"
#include "json/json.h"
#include "utils/helpers.h"
#include "utils/make_shared.h"
#include "remote_control/message_helper.h"

namespace remote_control {

CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule")

ResourceAllocationManagerImpl::ResourceAllocationManagerImpl(
    RemotePluginInterface& rc_plugin)
    : current_access_mode_(hmi_apis::Common_RCAccessMode::AUTO_ALLOW)
    , rc_plugin_(rc_plugin) {}

ResourceAllocationManagerImpl::~ResourceAllocationManagerImpl() {}

AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  const application_manager::ApplicationSharedPtr acquiring_app =
      rc_plugin_.service()->GetApplication(app_id);
  if (!acquiring_app) {
    LOG4CXX_WARN(logger_, "App with app_id: " << app_id << "does not exist!");
    return AcquireResult::IN_USE;
  }

  const AllocatedResources::const_iterator allocated_it =
      allocated_resources_.find(module_type);
  if (allocated_resources_.end() == allocated_it) {
    allocated_resources_[module_type] = app_id;
    LOG4CXX_DEBUG(logger_,
                  "Resource is not acquired yet. "
                      << "App: " << app_id << " is allowed to acquire "
                      << module_type);
    return AcquireResult::ALLOWED;
  }

  if (app_id == allocated_resources_[module_type]) {
    LOG4CXX_DEBUG(logger_,
                  "App: " << app_id << " is already acquired resource "
                          << module_type);
    return AcquireResult::ALLOWED;
  }

  if (IsModuleTypeRejected(module_type, app_id)) {
    LOG4CXX_DEBUG(logger_,
                  "Driver disallowed app: " << app_id << " to acquire "
                                            << module_type);
    return AcquireResult::REJECTED;
  }

  const mobile_apis::HMILevel::eType acquiring_app_hmi_level =
      acquiring_app->hmi_level();

  if (mobile_apis::HMILevel::HMI_FULL != acquiring_app_hmi_level) {
    LOG4CXX_DEBUG(
        logger_,
        "Aquiring resources is not allowed in HMI level: "
            << application_manager::MessageHelper::StringifiedHMILevel(
                   acquiring_app_hmi_level) << ". App: " << app_id
            << " is disallowed to acquire " << module_type);
    return AcquireResult::REJECTED;
  }

  switch (current_access_mode_) {
    case hmi_apis::Common_RCAccessMode::AUTO_DENY: {
      LOG4CXX_DEBUG(logger_,
                    "Current access_mode is AUTO_DENY. "
                        << "App: " << app_id << " is disallowed to acquire "
                        << module_type);
      return AcquireResult::IN_USE;
    }
    case hmi_apis::Common_RCAccessMode::ASK_DRIVER: {
      LOG4CXX_DEBUG(logger_,
                    "Current access_mode is ASK_DRIVER. "
                    "Driver confirmation is required for app: "
                        << app_id << " to acquire " << module_type);
      return AcquireResult::ASK_DRIVER;
    }
    case hmi_apis::Common_RCAccessMode::AUTO_ALLOW: {
      LOG4CXX_DEBUG(logger_,
                    "Current access_mode is AUTO_ALLOW. "
                        << "App: " << app_id << " is allowed to acquire "
                        << module_type);

      allocated_resources_[module_type] = app_id;
      return AcquireResult::ALLOWED;
    }
    default: { DCHECK_OR_RETURN(false, AcquireResult::IN_USE); }
  }
}

void ResourceAllocationManagerImpl::SetResourceState(
    const std::string& module_type,
    const uint32_t app_id,
    const ResourceState::eType state) {
  LOG4CXX_AUTO_TRACE(logger_);
  LOG4CXX_DEBUG(logger_,
                "Setting state for " << module_type << " by app_id " << app_id
                                     << " to state " << state);
  const AllocatedResources::const_iterator allocated_it =
      allocated_resources_.find(module_type);

  const std::string status = allocated_resources_.end() != allocated_it
                                 ? " acquired "
                                 : " not acquired ";
  UNUSED(status);
  LOG4CXX_DEBUG(logger_,
                "Resource " << module_type << " is " << status
                            << " Owner application id is "
                            << allocated_it->second
                            << " Changing application id is " << app_id);

  resources_state_[module_type] = state;
  LOG4CXX_DEBUG(logger_, "Resource " << module_type << " got state " << state);
}

bool ResourceAllocationManagerImpl::IsResourceFree(
    const std::string& module_type) const {
  LOG4CXX_AUTO_TRACE(logger_);
  const ResourcesState::const_iterator resource =
      resources_state_.find(module_type);

  if (resources_state_.end() == resource) {
    LOG4CXX_DEBUG(logger_, "Resource " << module_type << " is free.");
    return true;
  }

  LOG4CXX_DEBUG(logger_,
                "Resource " << module_type << " state is " << resource->second);

  return ResourceState::FREE == resource->second;
}

void ResourceAllocationManagerImpl::SetAccessMode(
    const hmi_apis::Common_RCAccessMode::eType access_mode) {
  if (hmi_apis::Common_RCAccessMode::ASK_DRIVER != access_mode) {
    rejected_resources_for_application_.clear();
  }
  current_access_mode_ = access_mode;
}

void ResourceAllocationManagerImpl::ForceAcquireResource(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_DEBUG(logger_, "Force " << app_id << " acquiring " << module_type);
  allocated_resources_[module_type] = app_id;
}

bool ResourceAllocationManagerImpl::IsModuleTypeRejected(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  RejectedResources::iterator it =
      rejected_resources_for_application_.find(app_id);

  if (rejected_resources_for_application_.end() == it) {
    return false;
  }

  const std::vector<std::string>& list_of_rejected_resources =
      rejected_resources_for_application_[app_id];

  return helpers::in_range(list_of_rejected_resources, module_type);
}

void ResourceAllocationManagerImpl::OnDriverDisallowed(
    const std::string& module_type, const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);
  RejectedResources::iterator it =
      rejected_resources_for_application_.find(app_id);

  if (rejected_resources_for_application_.end() == it) {
    rejected_resources_for_application_[app_id] = std::vector<std::string>();
  }
  std::vector<std::string>& list_of_rejected_resources =
      rejected_resources_for_application_[app_id];
  list_of_rejected_resources.push_back(module_type);
}

void ResourceAllocationManagerImpl::OnUnregisterApplication(
    const uint32_t app_id) {
  LOG4CXX_AUTO_TRACE(logger_);

  rejected_resources_for_application_.erase(app_id);
  for (AllocatedResources::const_iterator it = allocated_resources_.begin();
       it != allocated_resources_.end();) {
    if (app_id == it->second) {
      LOG4CXX_INFO(logger_,
                   "Application " << app_id
                                  << " is unregistered. Releasing resource "
                                  << it->first);
      resources_state_.erase(it->first);
      it = allocated_resources_.erase(it);
    } else {
      ++it;
    }
  }
}

void ResourceAllocationManagerImpl::ResetAllAllocations() {
  LOG4CXX_AUTO_TRACE(logger_);
  allocated_resources_.clear();
  rejected_resources_for_application_.clear();
  resources_state_.clear();
}

}  // namespace remote_control
<|endoftext|>