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

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

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

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

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

//#include "otbWrapperTypes.h"

#include "itkVariableLengthVector.h"
#include "otbChangeLabelImageFilter.h"
#include "otbStandardWriterWatcher.h"
#include "otbStatisticsXMLFileReader.h"
#include "otbShiftScaleVectorImageFilter.h"
#include "otbSVMImageClassificationFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbImageToVectorImageCastFilter.h"

namespace otb
{
namespace Wrapper
{

class ImageSVMClassifier : public Application
{
public:
  /** Standard class typedefs. */
  typedef ImageSVMClassifier            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ImageSVMClassifier, otb::Application);

  /** Filters typedef */
  // Statistic XML file Reader
  typedef itk::VariableLengthVector<FloatVectorImageType::InternalPixelType>            MeasurementType;
  typedef otb::StatisticsXMLFileReader<MeasurementType>                                 StatisticsReader;
  typedef otb::ShiftScaleVectorImageFilter<FloatVectorImageType, FloatVectorImageType>  RescalerType;

  /// Classification typedefs
  typedef otb::SVMImageClassificationFilter<FloatVectorImageType, UInt8ImageType>   ClassificationFilterType;
  typedef ClassificationFilterType::Pointer                                      ClassificationFilterPointerType;
  typedef ClassificationFilterType::ModelType                                    ModelType;
  typedef ModelType::Pointer                                                     ModelPointerType;

  // Cast filter
  // TODO: supress that !!
  typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,
                                       UInt8ImageType::PixelType>               ExtractImageFilterType;
  typedef ImageToVectorImageCastFilter<UInt8ImageType, FloatVectorImageType>    CastImageFilterType;

private:
  ImageSVMClassifier()
  {
    SetName("ImageSVMClassifier");
    SetDescription("Perform SVM classification based a previous computed SVM model");
  }

  virtual ~ImageSVMClassifier()
  {
  }

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage, "in",  "Input Image to classify");
    SetParameterDescription( "in", "Input Image to classify");

    AddParameter(ParameterType_InputImage,  "mask",   "Input Mask to classify");
    SetParameterDescription( "mask", "A mask associated with the new image to classify");
    MandatoryOff("mask");

    AddParameter(ParameterType_Filename, "imstat", "Image statistics file.");
    SetParameterDescription("imstat", "a XML file containing mean and standard deviation of input images used to train svm model.");
    MandatoryOff("imstat");

    AddParameter(ParameterType_Filename, "svm", "SVM Model.");
    SetParameterDescription("svm", "An estimated SVM model previously computed");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription( "out", "Output labeled image");
    SetParameterOutputImagePixelType( "out", ImagePixelType_uint8);
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    // Load input image
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    inImage->UpdateOutputInformation();

    // Load svm model
    otbAppLogINFO("Loading SVM model");
    m_ModelSVM = ModelType::New();
    m_ModelSVM->LoadModel(GetParameterString("svm").c_str());
    otbAppLogINFO("SVM model loaded");

    // Normalize input image (optional)
    StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
    MeasurementType  meanMeasurementVector;
    MeasurementType  stddevMeasurementVector;
    m_Rescaler = RescalerType::New();

    // Classify
    m_ClassificationFilter = ClassificationFilterType::New();
    m_ClassificationFilter->SetModel(m_ModelSVM);

    // Normalize input image if asked
    if( HasValue("imstat")  )
      {
      otbAppLogINFO("Input image normalization activated.");
      // Load input image statistics
      statisticsReader->SetFileName(GetParameterString("imstat"));
      meanMeasurementVector   = statisticsReader->GetStatisticVectorByName("mean");
      stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev");
      otbAppLogINFO( "mean used: " << meanMeasurementVector );
      otbAppLogINFO( "standard deviation used: " << stddevMeasurementVector );
      // Rescale vector image
      m_Rescaler->SetScale(stddevMeasurementVector);
      m_Rescaler->SetShift(meanMeasurementVector);
      m_Rescaler->SetInput(inImage);

      m_ClassificationFilter->SetInput(m_Rescaler->GetOutput());
      }
    else
      {
      otbAppLogINFO("Input image normalization deactivated.");
      m_ClassificationFilter->SetInput(inImage);
      }

    if( HasValue("mask")  )
      {
      otbAppLogINFO("Using input mask");
      // Load mask image and cast into LabeledImageType
      FloatVectorImageType::Pointer inMask = GetParameterImage("mask");
      m_Extract = ExtractImageFilterType::New();
      m_Extract->SetInput( inMask );
      m_Extract->SetChannel(0);
      m_Extract->UpdateOutputInformation();

      m_ClassificationFilter->SetInputMask(m_Extract->GetOutput());
      }

    SetParameterOutputImage<UInt8ImageType>("out", m_ClassificationFilter->GetOutput());
  }

  ClassificationFilterType::Pointer m_ClassificationFilter;
  ModelPointerType m_ModelSVM;
  RescalerType::Pointer m_Rescaler;
  ExtractImageFilterType::Pointer m_Extract;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ImageSVMClassifier)
<commit_msg>BUG: first channel of ROIextractor is 1.<commit_after>/*=========================================================================

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

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

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

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

//#include "otbWrapperTypes.h"

#include "itkVariableLengthVector.h"
#include "otbChangeLabelImageFilter.h"
#include "otbStandardWriterWatcher.h"
#include "otbStatisticsXMLFileReader.h"
#include "otbShiftScaleVectorImageFilter.h"
#include "otbSVMImageClassificationFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbImageToVectorImageCastFilter.h"

namespace otb
{
namespace Wrapper
{

class ImageSVMClassifier : public Application
{
public:
  /** Standard class typedefs. */
  typedef ImageSVMClassifier            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ImageSVMClassifier, otb::Application);

  /** Filters typedef */
  // Statistic XML file Reader
  typedef itk::VariableLengthVector<FloatVectorImageType::InternalPixelType>            MeasurementType;
  typedef otb::StatisticsXMLFileReader<MeasurementType>                                 StatisticsReader;
  typedef otb::ShiftScaleVectorImageFilter<FloatVectorImageType, FloatVectorImageType>  RescalerType;

  /// Classification typedefs
  typedef otb::SVMImageClassificationFilter<FloatVectorImageType, UInt8ImageType>   ClassificationFilterType;
  typedef ClassificationFilterType::Pointer                                      ClassificationFilterPointerType;
  typedef ClassificationFilterType::ModelType                                    ModelType;
  typedef ModelType::Pointer                                                     ModelPointerType;

  // Cast filter
  // TODO: supress that !!
  typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,
                                       UInt8ImageType::PixelType>               ExtractImageFilterType;
  typedef ImageToVectorImageCastFilter<UInt8ImageType, FloatVectorImageType>    CastImageFilterType;

private:
  ImageSVMClassifier()
  {
    SetName("ImageSVMClassifier");
    SetDescription("Perform SVM classification based a previous computed SVM model");
  }

  virtual ~ImageSVMClassifier()
  {
  }

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage, "in",  "Input Image to classify");
    SetParameterDescription( "in", "Input Image to classify");

    AddParameter(ParameterType_InputImage,  "mask",   "Input Mask to classify");
    SetParameterDescription( "mask", "A mask associated with the new image to classify");
    MandatoryOff("mask");

    AddParameter(ParameterType_Filename, "imstat", "Image statistics file.");
    SetParameterDescription("imstat", "a XML file containing mean and standard deviation of input images used to train svm model.");
    MandatoryOff("imstat");

    AddParameter(ParameterType_Filename, "svm", "SVM Model.");
    SetParameterDescription("svm", "An estimated SVM model previously computed");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription( "out", "Output labeled image");
    SetParameterOutputImagePixelType( "out", ImagePixelType_uint8);
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    // Load input image
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    inImage->UpdateOutputInformation();

    // Load svm model
    otbAppLogINFO("Loading SVM model");
    m_ModelSVM = ModelType::New();
    m_ModelSVM->LoadModel(GetParameterString("svm").c_str());
    otbAppLogINFO("SVM model loaded");

    // Normalize input image (optional)
    StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
    MeasurementType  meanMeasurementVector;
    MeasurementType  stddevMeasurementVector;
    m_Rescaler = RescalerType::New();

    // Classify
    m_ClassificationFilter = ClassificationFilterType::New();
    m_ClassificationFilter->SetModel(m_ModelSVM);

    // Normalize input image if asked
    if( HasValue("imstat")  )
      {
      otbAppLogINFO("Input image normalization activated.");
      // Load input image statistics
      statisticsReader->SetFileName(GetParameterString("imstat"));
      meanMeasurementVector   = statisticsReader->GetStatisticVectorByName("mean");
      stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev");
      otbAppLogINFO( "mean used: " << meanMeasurementVector );
      otbAppLogINFO( "standard deviation used: " << stddevMeasurementVector );
      // Rescale vector image
      m_Rescaler->SetScale(stddevMeasurementVector);
      m_Rescaler->SetShift(meanMeasurementVector);
      m_Rescaler->SetInput(inImage);

      m_ClassificationFilter->SetInput(m_Rescaler->GetOutput());
      }
    else
      {
      otbAppLogINFO("Input image normalization deactivated.");
      m_ClassificationFilter->SetInput(inImage);
      }

    if( HasValue("mask")  )
      {
      otbAppLogINFO("Using input mask");
      // Load mask image and cast into LabeledImageType
      FloatVectorImageType::Pointer inMask = GetParameterImage("mask");
      m_Extract = ExtractImageFilterType::New();
      m_Extract->SetInput( inMask );
      m_Extract->SetChannel(1);
      m_Extract->UpdateOutputInformation();

      m_ClassificationFilter->SetInputMask(m_Extract->GetOutput());
      }

    SetParameterOutputImage<UInt8ImageType>("out", m_ClassificationFilter->GetOutput());
  }

  ClassificationFilterType::Pointer m_ClassificationFilter;
  ModelPointerType m_ModelSVM;
  RescalerType::Pointer m_Rescaler;
  ExtractImageFilterType::Pointer m_Extract;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ImageSVMClassifier)
<|endoftext|>


<commit_before><commit_msg>[cling] Only add NullPtrChk if enabled.<commit_after><|endoftext|>


<commit_before>//     Copyright 2016, Kay Hayen, mailto:kay.hayen@gmail.com
//
//     Part of "Nuitka", an optimizing Python compiler that is compatible and
//     integrates with CPython, but also works on its own.
//
//     Licensed under the Apache License, Version 2.0 (the "License");
//     you may not use this file except in compliance with the License.
//     You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//     Unless required by applicable law or agreed to in writing, software
//     distributed under the License is distributed on an "AS IS" BASIS,
//     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//     See the License for the specific language governing permissions and
//     limitations under the License.
//

#include "nuitka/prelude.h"

#include "nuitka/compiled_method.h"

#include "structmember.h"

static PyObject *Nuitka_Method_get__doc__( struct Nuitka_MethodObject *method, void *closure )
{
    return INCREASE_REFCOUNT( method->m_function->m_doc );
}

static PyGetSetDef Nuitka_Method_getsets[] =
{
    { (char *)"__doc__", (getter)Nuitka_Method_get__doc__, NULL, NULL },
    { NULL }
};

#define OFF( x ) offsetof( struct Nuitka_MethodObject, x )

static PyMemberDef Nuitka_Method_members[] =
{
    { (char *)"im_class", T_OBJECT, OFF( m_class ), READONLY | RESTRICTED, (char *)"the class associated with a method"},
    { (char *)"im_func", T_OBJECT, OFF( m_function ), READONLY | RESTRICTED, (char *)"the function (or other callable) implementing a method" },
    { (char *)"__func__", T_OBJECT, OFF( m_function ), READONLY | RESTRICTED, (char *)"the function (or other callable) implementing a method" },
    { (char *)"im_self",  T_OBJECT, OFF( m_object ), READONLY | RESTRICTED, (char *)"the instance to which a method is bound; None for unbound method" },
    { (char *)"__self__", T_OBJECT, OFF( m_object ), READONLY | RESTRICTED, (char *)"the instance to which a method is bound; None for unbound method" },
    { NULL }
};

static PyObject *Nuitka_Method_reduce( struct Nuitka_MethodObject *method )
{
    PyErr_Format(
        PyExc_TypeError,
        "Can't pickle instancemethod objects"
    );

    return NULL;
}

static PyObject *Nuitka_Method_reduce_ex( struct Nuitka_MethodObject *method, PyObject *args )
{
    int proto;

    if ( !PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto) )
    {
        return NULL;
    }

    PyErr_Format(
        PyExc_TypeError,
        "Can't pickle instancemethod objects"
    );

    return NULL;
}

static PyObject *Nuitka_Method_deepcopy( struct Nuitka_MethodObject *method, PyObject *memo )
{
    assert( Nuitka_Method_Check( (PyObject *)method ));

    static PyObject *module_copy = NULL;
    static PyObject *deepcopy_function = NULL;

    if ( module_copy == NULL  )
    {
        module_copy = PyImport_ImportModule( "copy" );
        CHECK_OBJECT( module_copy );

        deepcopy_function = PyObject_GetAttrString( module_copy, "deepcopy" );
        CHECK_OBJECT( deepcopy_function );
    }

    PyObject *object = PyObject_CallFunctionObjArgs( deepcopy_function, method->m_object, memo, NULL );

    if (unlikely( object == NULL ))
    {
        return NULL;
    }

    return Nuitka_Method_New( method->m_function, object, method->m_class );
}

static PyMethodDef Nuitka_Method_methods[] =
{
    { "__reduce__",    (PyCFunction)Nuitka_Method_reduce,    METH_NOARGS,  NULL },
    { "__reduce_ex__", (PyCFunction)Nuitka_Method_reduce_ex, METH_VARARGS, NULL },
    { "__deepcopy__",  (PyCFunction)Nuitka_Method_deepcopy,  METH_O,       NULL },
    { NULL }
};

extern PyObject *const_str_plain___name__;

static char const *GET_CLASS_NAME( PyObject *klass )
{
    if ( klass == NULL )
    {
        return "?";
    }
    else
    {
#if PYTHON_VERSION < 300
        if ( PyClass_Check( klass ) )
        {
            return Nuitka_String_AsString( ((PyClassObject *)klass)->cl_name );
        }
#endif

        if ( !PyType_Check( klass ) )
        {
            klass = (PyObject *)Py_TYPE( klass );
        }

        return ((PyTypeObject *)klass)->tp_name;
    }
}

static char const *GET_INSTANCE_CLASS_NAME( PyObject *instance )
{
    // TODO: We have a constant for that already.
    PyObject *klass = PyObject_GetAttrString( instance, "__class__" );

    // Fallback to type as this cannot fail.
    if ( klass == NULL )
    {
        CLEAR_ERROR_OCCURRED();
        klass = INCREASE_REFCOUNT( (PyObject *)Py_TYPE( instance ) );
    }

    char const *result = GET_CLASS_NAME( klass );

    Py_DECREF( klass );

    return result;
}

static char const *GET_CALLABLE_DESC( PyObject *object )
{
    if ( Nuitka_Function_Check( object ) || Nuitka_Generator_Check( object ) || PyMethod_Check( object ) || PyFunction_Check( object ) || PyCFunction_Check( object ) )
    {
        return "()";
    }
#if PYTHON_VERSION < 300
    else if ( PyClass_Check( object ) )
    {
        return " constructor";
    }
    else if ( PyInstance_Check( object ))
    {
        return " instance";
    }
#endif
    else
    {
        return " object";
    }
}

static char const *GET_CALLABLE_NAME( PyObject *object )
{
    if ( Nuitka_Function_Check( object ) )
    {
        return Nuitka_String_AsString( Nuitka_Function_GetName( object ) );
    }
    else if ( Nuitka_Generator_Check( object ) )
    {
        return Nuitka_String_AsString( Nuitka_Generator_GetName( object ) );
    }
    else if ( PyMethod_Check( object ) )
    {
        return PyEval_GetFuncName( PyMethod_GET_FUNCTION( object ) );
    }
    else if ( PyFunction_Check( object ) )
    {
        return Nuitka_String_AsString( ((PyFunctionObject*)object)->func_name );
    }
#if PYTHON_VERSION < 300
    else if ( PyInstance_Check( object ) )
    {
        return Nuitka_String_AsString( ((PyInstanceObject*)object)->in_class->cl_name );
    }
    else if ( PyClass_Check( object ) )
    {
        return Nuitka_String_AsString( ((PyClassObject*)object)->cl_name );
    }
#endif
    else if ( PyCFunction_Check( object ) )
    {
        return ((PyCFunctionObject*)object)->m_ml->ml_name;
    }
    else
    {
        return Py_TYPE( object )->tp_name;
    }
}

static PyObject *Nuitka_Method_tp_call( struct Nuitka_MethodObject *method, PyObject *args, PyObject *kw )
{
    Py_ssize_t arg_count = PyTuple_Size( args );

    if ( method->m_object == NULL )
    {
        if (unlikely( arg_count < 1 ))
        {
            PyErr_Format(
                PyExc_TypeError,
                "unbound compiled_method %s%s must be called with %s instance as first argument (got nothing instead)",
                GET_CALLABLE_NAME( (PyObject *)method->m_function ),
                GET_CALLABLE_DESC( (PyObject *)method->m_function ),
                GET_CLASS_NAME( method->m_class )
            );
            return NULL;
        }
        else
        {
            PyObject *self = PyTuple_GET_ITEM( args, 0 );
            CHECK_OBJECT( self );

            int result = PyObject_IsInstance( self, method->m_class );

            if (unlikely( result < 0 ))
            {
                return NULL;
            }
            else if (unlikely( result == 0 ))
            {
                PyErr_Format(
                    PyExc_TypeError,
                    "unbound compiled_method %s%s must be called with %s instance as first argument (got %s instance instead)",
                    GET_CALLABLE_NAME( (PyObject *)method->m_function ),
                    GET_CALLABLE_DESC( (PyObject *)method->m_function ),
                    GET_CLASS_NAME( method->m_class ),
                    GET_INSTANCE_CLASS_NAME( (PyObject *)self )
                );

                return NULL;
            }
        }

        return Py_TYPE( method->m_function )->tp_call(
            (PyObject *)method->m_function, args, kw
        );
    }
    else
    {
        return Nuitka_CallMethodFunctionPosArgsKwArgs(
            method->m_function,
            method->m_object,
            &PyTuple_GET_ITEM( args, 0 ),
            arg_count,
            kw
        );
    }
}

static PyObject *Nuitka_Method_tp_descr_get( struct Nuitka_MethodObject *method, PyObject *object, PyObject *klass )
{
    // Don't rebind already bound methods.
    if ( method->m_object != NULL )
    {
        return INCREASE_REFCOUNT( (PyObject *)method );
    }

    if ( method->m_class != NULL && klass != NULL )
    {
        // Quick subclass test, bound methods remain the same if the class is a sub class
        int result = PyObject_IsSubclass( klass, method->m_class );

        if (unlikely( result < 0 ))
        {
            return NULL;
        }
        else if ( result == 0 )
        {
            return INCREASE_REFCOUNT( (PyObject *)method );
        }
    }

    return Nuitka_Method_New( method->m_function, object, klass );
}

static PyObject *Nuitka_Method_tp_getattro( struct Nuitka_MethodObject *method, PyObject *name )
{
    PyObject *descr = _PyType_Lookup( &Nuitka_Method_Type, name );

    if ( descr != NULL )
    {
        if (
#if PYTHON_VERSION < 300
            PyType_HasFeature( Py_TYPE( descr ), Py_TPFLAGS_HAVE_CLASS ) &&
#endif
            ( Py_TYPE( descr )->tp_descr_get != NULL )
           )
        {
            return Py_TYPE( descr )->tp_descr_get(
                descr,
                (PyObject *)method,
                (PyObject *)Py_TYPE( method )
            );
        }
        else
        {
            return INCREASE_REFCOUNT( descr );
        }
    }

    return PyObject_GetAttr( (PyObject *)method->m_function, name );
}

static long Nuitka_Method_tp_traverse( struct Nuitka_MethodObject *method, visitproc visit, void *arg )
{
    Py_VISIT( method->m_function );
    Py_VISIT( method->m_object );
    Py_VISIT( method->m_class );

    return 0;
}

 // tp_repr slot, decide how a function shall be output
static PyObject *Nuitka_Method_tp_repr( struct Nuitka_MethodObject *method )
{
    if ( method->m_object == NULL )
    {
#if PYTHON_VERSION < 300
        return PyString_FromFormat(
            "<unbound compiled_method %s.%s>",
            GET_CLASS_NAME( method->m_class ),
            Nuitka_String_AsString( method->m_function->m_name )
        );
#else
        return PyUnicode_FromFormat(
            "<compiled_function %s at %p>",
            Nuitka_String_AsString( method->m_function->m_name ),
            method->m_function
        );
#endif
    }
    else
    {
        // Note: CPython uses repr ob the object, although a comment despises
        // it, we do it for compatibility.
        PyObject *object_repr = PyObject_Repr( method->m_object );

        if ( object_repr == NULL )
        {
            return NULL;
        }
#if PYTHON_VERSION < 300
        else if ( !PyString_Check( object_repr ) )
        {
            Py_DECREF( object_repr );
            return NULL;
        }
#else
        else if ( !PyUnicode_Check( object_repr ) )
        {
            Py_DECREF( object_repr );
            return NULL;
        }
#endif

#if PYTHON_VERSION < 300
        PyObject *result = PyString_FromFormat(
            "<bound compiled_method %s.%s of %s>",
            GET_CLASS_NAME( method->m_class ),
            Nuitka_String_AsString( method->m_function->m_name ),
            Nuitka_String_AsString_Unchecked( object_repr )
        );
#elif PYTHON_VERSION < 350
        PyObject *result = PyUnicode_FromFormat(
            "<bound compiled_method %s.%s of %s>",
            GET_CLASS_NAME( method->m_class ),
            Nuitka_String_AsString( method->m_function->m_name ),
            Nuitka_String_AsString_Unchecked( object_repr )
        );
#else
        PyObject *result = PyUnicode_FromFormat(
            "<bound compiled_method %s of %s>",
            Nuitka_String_AsString( method->m_function->m_qualname ),
            Nuitka_String_AsString_Unchecked( object_repr )
        );
#endif

        Py_DECREF( object_repr );

        return result;
    }
}

#if PYTHON_VERSION < 300
static int Nuitka_Method_tp_compare( struct Nuitka_MethodObject *a, struct Nuitka_MethodObject *b )
{
    if ( a->m_function->m_counter < b->m_function->m_counter )
    {
        return -1;
    }
    else if ( a->m_function->m_counter > b->m_function->m_counter )
    {
        return 1;
    }
    else if ( a->m_object == b->m_object )
    {
        return 0;
    }
    else if ( a->m_object == NULL )
    {
        return -1;
    }
    else if ( b->m_object == NULL )
    {
        return 1;
    }
    else
    {
        return PyObject_Compare( a->m_object, b->m_object );
    }
}
#endif

static PyObject *Nuitka_Method_tp_richcompare( struct Nuitka_MethodObject *a, struct Nuitka_MethodObject *b, int op )
{
    if ( op != Py_EQ && op != Py_NE )
    {
        return INCREASE_REFCOUNT( Py_NotImplemented );
    }

    if ( Nuitka_Method_Check( (PyObject *)a ) == false || Nuitka_Method_Check( (PyObject *)b ) == false )
    {
        return INCREASE_REFCOUNT( Py_NotImplemented );
    }

    bool result = a->m_function->m_counter == b->m_function->m_counter;

    // If the underlying function objects are the same, check the objects, which
    // may be NULL in case of unbound methods, which would be the same again.
    if ( result )
    {
        if ( a->m_object == NULL )
        {
            result = b->m_object == NULL;
        }
        else if ( b->m_object == NULL )
        {
            result = 0;
        }
        else
        {
            int res = PyObject_RichCompareBool(
                a->m_object,
                b->m_object,
                Py_EQ
            );

            result = res != 0;
        }
    }

    if ( op == Py_EQ )
    {
        return INCREASE_REFCOUNT( BOOL_FROM( result ) );
    }
    else
    {
        return INCREASE_REFCOUNT( BOOL_FROM( !result ) );
    }
}

static long Nuitka_Method_tp_hash( struct Nuitka_MethodObject *method )
{
    // Just give the hash of the method function, that ought to be good enough.
    return method->m_function->m_counter;
}

// Cache for method object, try to avoid malloc overhead.
static struct Nuitka_MethodObject *method_cache_head = NULL;
static int method_cache_size = 0;
static const int max_method_cache_size = 4096;

static void Nuitka_Method_tp_dealloc( struct Nuitka_MethodObject *method )
{
#ifndef __NUITKA_NO_ASSERT__
    // Save the current exception, if any, we must to not corrupt it.
    PyObject *save_exception_type, *save_exception_value;
    PyTracebackObject *save_exception_tb;
    FETCH_ERROR_OCCURRED( &save_exception_type, &save_exception_value, &save_exception_tb );
    RESTORE_ERROR_OCCURRED( save_exception_type, save_exception_value, save_exception_tb );
#endif

    Nuitka_GC_UnTrack( method );

    if ( method->m_weakrefs != NULL )
    {
        PyObject_ClearWeakRefs( (PyObject *)method );
    }

    Py_XDECREF( method->m_object );
    Py_XDECREF( method->m_class );

    Py_DECREF( (PyObject *)method->m_function );

    if (likely( method_cache_size < max_method_cache_size ))
    {
        method->m_object = (PyObject *)method_cache_head;
        method_cache_head = method;
        method_cache_size += 1;
    }
    else {
        PyObject_GC_Del( method );
    }

#ifndef __NUITKA_NO_ASSERT__
    PyThreadState *tstate = PyThreadState_GET();

    assert( tstate->curexc_type == save_exception_type );
    assert( tstate->curexc_value == save_exception_value );
    assert( (PyTracebackObject *)tstate->curexc_traceback == save_exception_tb );
#endif
}

static PyObject *Nuitka_Method_tp_new( PyTypeObject* type, PyObject* args, PyObject *kw )
{
    PyObject *func;
    PyObject *self;
    PyObject *klass = NULL;

    if ( !_PyArg_NoKeywords( "instancemethod", kw ) )
    {
        return NULL;
    }
    else if ( !PyArg_UnpackTuple( args, "compiled_method", 2, 3, &func, &self, &klass ) )
    {
        return NULL;
    }
    else if ( !PyCallable_Check( func ) )
    {
        PyErr_Format( PyExc_TypeError, "first argument must be callable" );
        return NULL;
    }
    else
    {
        if ( self == Py_None )
        {
            self = NULL;
        }

        if ( self == NULL && klass == NULL )
        {
            PyErr_Format( PyExc_TypeError, "unbound methods must have non-NULL im_class" );
            return NULL;
        }
    }

    assert( Nuitka_Function_Check( func ) );

    return Nuitka_Method_New( (struct Nuitka_FunctionObject *)func, self, klass );
}

PyTypeObject Nuitka_Method_Type =
{
    PyVarObject_HEAD_INIT(NULL, 0)
    "compiled_method",
    sizeof(struct Nuitka_MethodObject),
    0,
    (destructor)Nuitka_Method_tp_dealloc,        // tp_dealloc
    0,                                           /* tp_print */
    0,                                           /* tp_getattr */
    0,                                           /* tp_setattr */
#if PYTHON_VERSION < 300
    (cmpfunc)Nuitka_Method_tp_compare,           /* tp_compare */
#else
    0,
#endif
    (reprfunc)Nuitka_Method_tp_repr,             /* tp_repr */
    0,                                           /* tp_as_number */
    0,                                           /* tp_as_sequence */
    0,                                           /* tp_as_mapping */
    (hashfunc)Nuitka_Method_tp_hash,             /* tp_hash */
    (ternaryfunc)Nuitka_Method_tp_call,          /* tp_call */
    0,                                           /* tp_str */
    (getattrofunc)Nuitka_Method_tp_getattro,     /* tp_getattro */
    PyObject_GenericSetAttr,                     /* tp_setattro */
    0,                                           /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT       |
#if PYTHON_VERSION < 300
    Py_TPFLAGS_HAVE_WEAKREFS |
#endif
    Py_TPFLAGS_HAVE_GC,                          /* tp_flags */
    0,                                           /* tp_doc */
    (traverseproc)Nuitka_Method_tp_traverse,     /* tp_traverse */
    0,                                           /* tp_clear */
    (richcmpfunc)Nuitka_Method_tp_richcompare,   /* tp_richcompare */
    offsetof(struct Nuitka_MethodObject, m_weakrefs), /* tp_weaklistoffset */
    0,                                           /* tp_iter */
    0,                                           /* tp_iternext */
    Nuitka_Method_methods,                       /* tp_methods */
    Nuitka_Method_members,                       /* tp_members */
    Nuitka_Method_getsets,                       /* tp_getset */
    0,                                           /* tp_base */
    0,                                           /* tp_dict */
    (descrgetfunc)Nuitka_Method_tp_descr_get,    /* tp_descr_get */
    0,                                           /* tp_descr_set */
    0,                                           /* tp_dictoffset */
    0,                                           /* tp_init */
    0,                                           /* tp_alloc */
    Nuitka_Method_tp_new,                        /* tp_new */
    0,                                           /* tp_free */
    0,                                           /* tp_is_gc */
    0,                                           /* tp_bases */
    0,                                           /* tp_mro */
    0,                                           /* tp_cache */
    0,                                           /* tp_subclasses */
    0,                                           /* tp_weaklist */
    0,                                           /* tp_del */
    0                                            /* tp_version_tag */
#if PYTHON_VERSION >= 340
    ,0                                           /* tp_finalizer */
#endif
};

void _initCompiledMethodType( void )
{
    PyType_Ready( &Nuitka_Method_Type );
}

PyObject *Nuitka_Method_New( struct Nuitka_FunctionObject *function, PyObject *object, PyObject *klass )
{
    struct Nuitka_MethodObject *result = method_cache_head;

    if ( result != NULL )
    {
        method_cache_head = (struct Nuitka_MethodObject *)method_cache_head->m_object;
        method_cache_size -= 1;

        Py_TYPE( result ) = &Nuitka_Method_Type;
        _Py_NewReference( (PyObject *)result );
    }
    else
    {
        result = PyObject_GC_New(struct Nuitka_MethodObject, &Nuitka_Method_Type);
    }

    if (unlikely( result == NULL ))
    {
        PyErr_Format(
            PyExc_RuntimeError,
            "cannot create method %s",
            Nuitka_String_AsString( function->m_name )
        );

        return NULL;
    }

    result->m_function = (struct Nuitka_FunctionObject *)INCREASE_REFCOUNT( (PyObject *)function );

    result->m_object = object;
    Py_XINCREF( object );
    result->m_class = klass;
    Py_XINCREF( klass );

    result->m_weakrefs = NULL;

    Nuitka_GC_Track( result );
    return (PyObject *)result;
}
<commit_msg>Delete CompiledMethodType.cpp<commit_after><|endoftext|>


<commit_before>/******************************************************************
*
* Copyright 2014 Samsung Electronics All Rights Reserved.
*
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************/
#include "QueryEngine.h"
#include "DataReader.h"

SSMRESULT CQueryEngine::finalConstruct()
{
    SSMRESULT res = SSM_E_FAIL;

    m_cqid = 0;

    m_pQueryEngineEvent = NULL;

    SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, (IBase **)&m_pTasker));

    SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IPropagationEngine, (IBase **)&m_pPropagationEngine));

CLEANUP:
    return res;
}

void CQueryEngine::finalRelease()
{
    m_pQueryEngineEvent = NULL;

    m_mtxQueries.lock();

    for (std::map<int, IConditionedQuery *>::iterator itor = m_conditionedQueries.begin();
         itor != m_conditionedQueries.end(); ++itor)
    {
        itor->second->deactivateTriggers();
        SAFE_RELEASE(itor->second);
    }

    for (std::map<int, CContextQuery *>::iterator itor = m_contextQueries.begin();
         itor != m_contextQueries.end(); ++itor)
    {
        //Token *root = itor->second->getRoot();
        //SAFE_DELETE(root);
        SAFE_DELETE(itor->second);
    }

    m_mtxQueries.unlock();
}

SSMRESULT CQueryEngine::processQueryResult(int userTriggerId,
        std::vector<result_model> *result)
{
    SSMRESULT           res = SSM_E_FAIL;
    ModelPropertyVec    modelData;
    std::vector<result_model> result_model_data_id;
    IntVec                  modelID;
    std::vector<std::string> contextName;
    IContextModel           *temp_contextmodel = NULL;
    IContextModel           *temp_contextmodel2 = NULL;

    intptr_t             *pData = NULL;

    CDataReader *pDataReader = NULL;

    m_mtxQueries.lock();

    if (m_contextQueries.find(userTriggerId) == m_contextQueries.end())
    {
        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
    }

    m_contextQueries[userTriggerId]->check_result_model();
    m_contextQueries[userTriggerId]->return_contextName(&contextName);
    m_contextQueries[userTriggerId]->return_modelID(&modelID);

    for (unsigned int i = 0; i < modelID.size(); i++)
    {
        SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel(contextName.at(i), &temp_contextmodel2));

        for (unsigned int j = 0 ; j < result->size() ; j++)
        {
            int data;
            if (result->at(j).dataId.size() <= 0)
            {
                continue;
            }

            int modelid = modelID.at(i);
            std::vector<int> dataid;
            for (unsigned int k = 0 ; k < result->at(j).dataId.size() ; k++)
            {
                SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel(result->at(j).modelName,
                                   &temp_contextmodel));
                data = result->at(j).dataId.at(k);

                if (modelID.at(i) < result->at(j).modelID )
                {
                    SSM_CLEANUP_ASSERT(temp_contextmodel->getParentDataId(data, temp_contextmodel2, &data));
                    dataid.push_back(data);
                }
                else if (modelID.at(i) > result->at(j).modelID )
                {
                    SSM_CLEANUP_ASSERT(temp_contextmodel->getChildDataId(data, temp_contextmodel2, &dataid));
                }
                else
                {
                    dataid.push_back(data);
                }
                SAFE_RELEASE(temp_contextmodel);
            }

            m_contextQueries[userTriggerId]->integrate_result(&result_model_data_id, modelid, &dataid,
                    temp_contextmodel2->getModelName());
        }

        SAFE_RELEASE(temp_contextmodel2);
    }

    pDataReader = new CDataReader();

    for (unsigned int i = 0; i < result_model_data_id.size(); i++)
    {
        std::vector<CModelData *>    modelDataSet;

        for (unsigned int j = 0; j < (result_model_data_id)[i].dataId.size(); j++)
        {
            CModelData *pModelData = new CModelData();
            IContextModel       *pCM = NULL;
            ModelPropertyVec    modelPropertyVec;

            SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel((result_model_data_id)[i].modelName,
                               &pCM));
            SSM_CLEANUP_ASSERT(pCM->getModelData((result_model_data_id)[i].dataId[j], &modelPropertyVec));
            pModelData->setDataId((result_model_data_id)[i].dataId[j]);
            for (ModelPropertyVec::iterator itor = modelPropertyVec.begin();
                 itor != modelPropertyVec.end(); ++itor)
            {
                pModelData->addModelData(itor->propertyName, itor->propertyValue);
            }

            modelDataSet.push_back(pModelData);

            SAFE_RELEASE(pCM);
        }

        SSM_CLEANUP_ASSERT(pDataReader->addModelData((result_model_data_id)[i].modelName, &modelDataSet));
    }
    pData = new intptr_t [3];
    pData[0] = EVENT_TYPE_OUTER;
    pData[1] = userTriggerId;
    pData[2] = reinterpret_cast<intptr_t>(pDataReader);

    m_pTasker->addTask(this, (void *)pData);

    res = SSM_S_OK;

CLEANUP:
    m_mtxQueries.unlock();
    SAFE_RELEASE(temp_contextmodel);
    SAFE_RELEASE(temp_contextmodel2);
    return res;
}

SSMRESULT CQueryEngine::validateQueryResult(IConditionedQueryResult *pConditionedQueryResult,
        std::vector<result_model> *resultData)
{
    SSMRESULT               res = SSM_E_FAIL;
    IContextModel           *pContextModel = NULL;
    IConditionedModel       *pConditionedModel = NULL;

    for (unsigned int i = 0 ; i < pConditionedQueryResult->getConditionedModelCount() ; i++)
    {
        std::vector<int>    temp_dataID;
        result_model        temp_result;
        SSM_CLEANUP_ASSERT(pConditionedQueryResult->getConditionedContextModel(i, &pConditionedModel));
        SSM_CLEANUP_ASSERT(pConditionedModel->getAffectedData(&temp_dataID));

        if (temp_dataID.size() == 0)
        {
            break;
        }

        SSM_CLEANUP_ASSERT(pConditionedModel->getBaseContextModel(&pContextModel));
        temp_result.modelID = pContextModel->getModelId();
        temp_result.dataId = temp_dataID;
        temp_result.modelName = pContextModel->getModelName();
        resultData->push_back(temp_result);
        SAFE_RELEASE(pConditionedModel);
        SAFE_RELEASE(pContextModel);
    }

    if (resultData->size() == pConditionedQueryResult->getConditionedModelCount())
    {
        res = SSM_S_OK;
    }
    else
    {
        res = SSM_S_FALSE;
    }

CLEANUP:
    SAFE_RELEASE(pConditionedModel);
    SAFE_RELEASE(pContextModel);
    return res;
}

SSMRESULT CQueryEngine::onConditionedQueryEvent(int userTriggerId,
        IConditionedQueryResult *pConditionedQueryResult)
{
    SSMRESULT                   res = SSM_E_FAIL;
    std::vector<result_model>   result;

    SSM_CLEANUP_ASSERT(validateQueryResult(pConditionedQueryResult, &result));
    SSM_CLEANUP_ASSERT(processQueryResult(userTriggerId, &result));

CLEANUP:
    return res;
}

void CQueryEngine::onExecute(void *pArg)
{
    intptr_t *pData = (intptr_t *)pArg;

    switch (pData[0])
    {
        case EVENT_TYPE_INNER:
            processQueryResult(pData[1], (std::vector<result_model> *)pData[2]);
            break;

        case EVENT_TYPE_OUTER:
            if (m_pQueryEngineEvent != NULL)
            {
                m_pQueryEngineEvent->onQueryEngineEvent(pData[1], (IDataReader *)pData[2]);
            }
            break;

        default:
            break;
    }
}

void CQueryEngine::onTerminate(void *pArg)
{
    intptr_t *pData = (intptr_t *)pArg;
    std::vector<result_model>   *pResult = NULL;
    CDataReader                 *pDataReader = NULL;

    switch (pData[0])
    {
        case EVENT_TYPE_INNER:
            pResult = (std::vector<result_model> *)pData[2];
            SAFE_DELETE(pResult);
            break;

        case EVENT_TYPE_OUTER:
            pDataReader = (CDataReader *)pData[2];
            SAFE_DELETE(pDataReader);
            break;

        default:
            break;
    }
    SAFE_ARRAY_DELETE(pData);
}

SSMRESULT CQueryEngine::executeContextQuery(std::string contextQuery, int *cqid)
{
    SSMRESULT               res = SSM_E_FAIL;
    IConditionedQuery       *pConditionedQuery = NULL;
    IConditionedQueryResult *pConditionedQueryResult = NULL;
    QueryCondition          queryConditions;
    CContextQuery           *clsContextQuery = NULL;
    Token                   token;
    CCQLParser              cqlParser;
    IContextModel::ActivationType   queryCommandType;

    if (!cqlParser.parse(contextQuery, &token))
    {
        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
    }

    if (!cqlParser.check_grammer(&token))
    {
        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
    }

    clsContextQuery = new CContextQuery();
    SSM_CLEANUP_NULL_ASSERT(clsContextQuery);
    SSM_CLEANUP_ASSERT(clsContextQuery->initialize(token));
    clsContextQuery->make_QueryCondition(&queryConditions);

    if (CCQLParser::tolower(token.child_token[0].name) == "subscribe")
    {
        queryCommandType = IContextModel::ACTIVATION_TYPE_SUBSCRIBE;
    }
    else
    {
        queryCommandType = IContextModel::ACTIVATION_TYPE_GET;
    }

    SSM_CLEANUP_ASSERT(m_pPropagationEngine->createConditionedQuery(queryCommandType,
                       &queryConditions, this, &pConditionedQuery));

    m_mtxQueries.lock();
    pConditionedQuery->addRef();
    m_conditionedQueries[m_cqid] = pConditionedQuery;
    m_contextQueries[m_cqid] = clsContextQuery;
    m_mtxQueries.unlock();

    if (pConditionedQuery->hasAllConditionedModels() == true)
    {
        std::vector<result_model>   *pResult = NULL;

        SSM_CLEANUP_ASSERT(pConditionedQuery->getConditionedQueryResult(&pConditionedQueryResult));
        pResult = new std::vector<result_model>();
        if (validateQueryResult(pConditionedQueryResult, pResult) == SSM_S_OK)
        {
            //We have valid data, let's deliver to application.
            intptr_t  *pData = new intptr_t [3];
            pData[0] = EVENT_TYPE_INNER;
            pData[1] = m_cqid;
            pData[2] = reinterpret_cast<intptr_t>(pResult);

            m_pTasker->addTask(this, (void *)pData);
        }
        else
        {
            SAFE_DELETE(pResult);
            if (queryCommandType == IContextModel::ACTIVATION_TYPE_GET)
            {
                //There is no valid data. let's request new one
                SSM_CLEANUP_ASSERT(pConditionedQuery->activateTriggers(m_cqid));
            }
        }
    }
    else
    {
        if (queryCommandType == IContextModel::ACTIVATION_TYPE_GET)
        {
            //There is no models such name
            SSM_CLEANUP_ASSERT(SSM_E_FAIL);
        }
    }

    //Every subscribe command must request new data to models
    if (queryCommandType == IContextModel::ACTIVATION_TYPE_SUBSCRIBE)
    {
        SSM_CLEANUP_ASSERT(pConditionedQuery->activateTriggers(m_cqid));
    }

    *cqid = m_cqid++;

CLEANUP:
    SAFE_RELEASE(pConditionedQuery);
    SAFE_RELEASE(pConditionedQueryResult);
    return res;
}

//TODO: Registration with multiple instance support
SSMRESULT CQueryEngine::registerQueryEvent(IQueryEngineEvent *pQueryEngineEvent)
{
    m_pQueryEngineEvent = pQueryEngineEvent;
    return SSM_S_OK;
}

SSMRESULT CQueryEngine::unregisterQueryEvent(IQueryEngineEvent *pQueryEngineEvent)
{
    if (m_pQueryEngineEvent == pQueryEngineEvent)
    {
        m_pQueryEngineEvent = NULL;
        return SSM_S_OK;
    }

    return SSM_E_FAIL;
}

SSMRESULT CQueryEngine::killContextQuery(int cqid)
{
    SSMRESULT res = SSM_E_FAIL;

    std::map<int, IConditionedQuery *>::iterator itorConditionedQueries;
    std::map<int, CContextQuery *>::iterator itorContextQuries;

    m_mtxQueries.lock();
    itorConditionedQueries = m_conditionedQueries.find(cqid);
    itorContextQuries = m_contextQueries.find(cqid);

    if (itorConditionedQueries != m_conditionedQueries.end())
    {
        SSM_CLEANUP_ASSERT(itorConditionedQueries->second->deactivateTriggers());
        itorConditionedQueries->second->release();
        m_conditionedQueries.erase(itorConditionedQueries);
    }

    if (itorContextQuries != m_contextQueries.end())
    {
        SAFE_DELETE(itorContextQuries->second);
        m_contextQueries.erase(itorContextQuries);
    }

CLEANUP:
    m_mtxQueries.unlock();
    return res;
}
<commit_msg>Fix memory leak in SSM QueryEngine<commit_after>/******************************************************************
*
* Copyright 2014 Samsung Electronics All Rights Reserved.
*
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************/
#include "QueryEngine.h"
#include "DataReader.h"

SSMRESULT CQueryEngine::finalConstruct()
{
    SSMRESULT res = SSM_E_FAIL;

    m_cqid = 0;

    m_pQueryEngineEvent = NULL;

    SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, (IBase **)&m_pTasker));

    SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IPropagationEngine, (IBase **)&m_pPropagationEngine));

CLEANUP:
    return res;
}

void CQueryEngine::finalRelease()
{
    m_pQueryEngineEvent = NULL;

    m_mtxQueries.lock();

    for (std::map<int, IConditionedQuery *>::iterator itor = m_conditionedQueries.begin();
         itor != m_conditionedQueries.end(); ++itor)
    {
        itor->second->deactivateTriggers();
        SAFE_RELEASE(itor->second);
    }

    for (std::map<int, CContextQuery *>::iterator itor = m_contextQueries.begin();
         itor != m_contextQueries.end(); ++itor)
    {
        //Token *root = itor->second->getRoot();
        //SAFE_DELETE(root);
        SAFE_DELETE(itor->second);
    }

    m_mtxQueries.unlock();
}

SSMRESULT CQueryEngine::processQueryResult(int userTriggerId,
        std::vector<result_model> *result)
{
    SSMRESULT           res = SSM_E_FAIL;
    ModelPropertyVec    modelData;
    std::vector<result_model> result_model_data_id;
    IntVec                  modelID;
    std::vector<std::string> contextName;
    IContextModel           *temp_contextmodel = NULL;
    IContextModel           *temp_contextmodel2 = NULL;

    intptr_t             *pData = NULL;

    CDataReader *pDataReader = NULL;

    m_mtxQueries.lock();

    if (m_contextQueries.find(userTriggerId) == m_contextQueries.end())
    {
        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
    }

    m_contextQueries[userTriggerId]->check_result_model();
    m_contextQueries[userTriggerId]->return_contextName(&contextName);
    m_contextQueries[userTriggerId]->return_modelID(&modelID);

    for (unsigned int i = 0; i < modelID.size(); i++)
    {
        SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel(contextName.at(i), &temp_contextmodel2));

        for (unsigned int j = 0 ; j < result->size() ; j++)
        {
            int data;
            if (result->at(j).dataId.size() <= 0)
            {
                continue;
            }

            int modelid = modelID.at(i);
            std::vector<int> dataid;
            for (unsigned int k = 0 ; k < result->at(j).dataId.size() ; k++)
            {
                SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel(result->at(j).modelName,
                                   &temp_contextmodel));
                data = result->at(j).dataId.at(k);

                if (modelID.at(i) < result->at(j).modelID )
                {
                    SSM_CLEANUP_ASSERT(temp_contextmodel->getParentDataId(data, temp_contextmodel2, &data));
                    dataid.push_back(data);
                }
                else if (modelID.at(i) > result->at(j).modelID )
                {
                    SSM_CLEANUP_ASSERT(temp_contextmodel->getChildDataId(data, temp_contextmodel2, &dataid));
                }
                else
                {
                    dataid.push_back(data);
                }
                SAFE_RELEASE(temp_contextmodel);
            }

            m_contextQueries[userTriggerId]->integrate_result(&result_model_data_id, modelid, &dataid,
                    temp_contextmodel2->getModelName());
        }

        SAFE_RELEASE(temp_contextmodel2);
    }

    pDataReader = new CDataReader();

    for (unsigned int i = 0; i < result_model_data_id.size(); i++)
    {
        std::vector<CModelData *>    modelDataSet;

        for (unsigned int j = 0; j < (result_model_data_id)[i].dataId.size(); j++)
        {
            CModelData *pModelData = NULL;
            IContextModel       *pCM = NULL;
            ModelPropertyVec    modelPropertyVec;

            SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel((result_model_data_id)[i].modelName,
                               &pCM));
            SSM_CLEANUP_ASSERT(pCM->getModelData((result_model_data_id)[i].dataId[j], &modelPropertyVec));
            pModelData = new CModelData();
            pModelData->setDataId((result_model_data_id)[i].dataId[j]);
            for (ModelPropertyVec::iterator itor = modelPropertyVec.begin();
                 itor != modelPropertyVec.end(); ++itor)
            {
                pModelData->addModelData(itor->propertyName, itor->propertyValue);
            }

            modelDataSet.push_back(pModelData);

            SAFE_RELEASE(pCM);
        }

        SSM_CLEANUP_ASSERT(pDataReader->addModelData((result_model_data_id)[i].modelName, &modelDataSet));
    }
    pData = new intptr_t [3];
    pData[0] = EVENT_TYPE_OUTER;
    pData[1] = userTriggerId;
    pData[2] = reinterpret_cast<intptr_t>(pDataReader);

    m_pTasker->addTask(this, (void *)pData);

    res = SSM_S_OK;

CLEANUP:
    m_mtxQueries.unlock();
    SAFE_RELEASE(temp_contextmodel);
    SAFE_RELEASE(temp_contextmodel2);
    return res;
}

SSMRESULT CQueryEngine::validateQueryResult(IConditionedQueryResult *pConditionedQueryResult,
        std::vector<result_model> *resultData)
{
    SSMRESULT               res = SSM_E_FAIL;
    IContextModel           *pContextModel = NULL;
    IConditionedModel       *pConditionedModel = NULL;

    for (unsigned int i = 0 ; i < pConditionedQueryResult->getConditionedModelCount() ; i++)
    {
        std::vector<int>    temp_dataID;
        result_model        temp_result;
        SSM_CLEANUP_ASSERT(pConditionedQueryResult->getConditionedContextModel(i, &pConditionedModel));
        SSM_CLEANUP_ASSERT(pConditionedModel->getAffectedData(&temp_dataID));

        if (temp_dataID.size() == 0)
        {
            break;
        }

        SSM_CLEANUP_ASSERT(pConditionedModel->getBaseContextModel(&pContextModel));
        temp_result.modelID = pContextModel->getModelId();
        temp_result.dataId = temp_dataID;
        temp_result.modelName = pContextModel->getModelName();
        resultData->push_back(temp_result);
        SAFE_RELEASE(pConditionedModel);
        SAFE_RELEASE(pContextModel);
    }

    if (resultData->size() == pConditionedQueryResult->getConditionedModelCount())
    {
        res = SSM_S_OK;
    }
    else
    {
        res = SSM_S_FALSE;
    }

CLEANUP:
    SAFE_RELEASE(pConditionedModel);
    SAFE_RELEASE(pContextModel);
    return res;
}

SSMRESULT CQueryEngine::onConditionedQueryEvent(int userTriggerId,
        IConditionedQueryResult *pConditionedQueryResult)
{
    SSMRESULT                   res = SSM_E_FAIL;
    std::vector<result_model>   result;

    SSM_CLEANUP_ASSERT(validateQueryResult(pConditionedQueryResult, &result));
    SSM_CLEANUP_ASSERT(processQueryResult(userTriggerId, &result));

CLEANUP:
    return res;
}

void CQueryEngine::onExecute(void *pArg)
{
    intptr_t *pData = (intptr_t *)pArg;

    switch (pData[0])
    {
        case EVENT_TYPE_INNER:
            processQueryResult(pData[1], (std::vector<result_model> *)pData[2]);
            break;

        case EVENT_TYPE_OUTER:
            if (m_pQueryEngineEvent != NULL)
            {
                m_pQueryEngineEvent->onQueryEngineEvent(pData[1], (IDataReader *)pData[2]);
            }
            break;

        default:
            break;
    }
}

void CQueryEngine::onTerminate(void *pArg)
{
    intptr_t *pData = (intptr_t *)pArg;
    std::vector<result_model>   *pResult = NULL;
    CDataReader                 *pDataReader = NULL;

    switch (pData[0])
    {
        case EVENT_TYPE_INNER:
            pResult = (std::vector<result_model> *)pData[2];
            SAFE_DELETE(pResult);
            break;

        case EVENT_TYPE_OUTER:
            pDataReader = (CDataReader *)pData[2];
            SAFE_DELETE(pDataReader);
            break;

        default:
            break;
    }
    SAFE_ARRAY_DELETE(pData);
}

SSMRESULT CQueryEngine::executeContextQuery(std::string contextQuery, int *cqid)
{
    SSMRESULT               res = SSM_E_FAIL;
    IConditionedQuery       *pConditionedQuery = NULL;
    IConditionedQueryResult *pConditionedQueryResult = NULL;
    QueryCondition          queryConditions;
    CContextQuery           *clsContextQuery = NULL;
    Token                   token;
    CCQLParser              cqlParser;
    IContextModel::ActivationType   queryCommandType;

    if (!cqlParser.parse(contextQuery, &token))
    {
        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
    }

    if (!cqlParser.check_grammer(&token))
    {
        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
    }

    clsContextQuery = new CContextQuery();
    SSM_CLEANUP_NULL_ASSERT(clsContextQuery);
    SSM_CLEANUP_ASSERT(clsContextQuery->initialize(token));
    clsContextQuery->make_QueryCondition(&queryConditions);

    if (CCQLParser::tolower(token.child_token[0].name) == "subscribe")
    {
        queryCommandType = IContextModel::ACTIVATION_TYPE_SUBSCRIBE;
    }
    else
    {
        queryCommandType = IContextModel::ACTIVATION_TYPE_GET;
    }

    SSM_CLEANUP_ASSERT(m_pPropagationEngine->createConditionedQuery(queryCommandType,
                       &queryConditions, this, &pConditionedQuery));

    m_mtxQueries.lock();
    pConditionedQuery->addRef();
    m_conditionedQueries[m_cqid] = pConditionedQuery;
    m_contextQueries[m_cqid] = clsContextQuery;
    m_mtxQueries.unlock();

    if (pConditionedQuery->hasAllConditionedModels() == true)
    {
        std::vector<result_model>   *pResult = NULL;

        SSM_CLEANUP_ASSERT(pConditionedQuery->getConditionedQueryResult(&pConditionedQueryResult));
        pResult = new std::vector<result_model>();
        if (validateQueryResult(pConditionedQueryResult, pResult) == SSM_S_OK)
        {
            //We have valid data, let's deliver to application.
            intptr_t  *pData = new intptr_t [3];
            pData[0] = EVENT_TYPE_INNER;
            pData[1] = m_cqid;
            pData[2] = reinterpret_cast<intptr_t>(pResult);

            m_pTasker->addTask(this, (void *)pData);
        }
        else
        {
            SAFE_DELETE(pResult);
            if (queryCommandType == IContextModel::ACTIVATION_TYPE_GET)
            {
                //There is no valid data. let's request new one
                SSM_CLEANUP_ASSERT(pConditionedQuery->activateTriggers(m_cqid));
            }
        }
    }
    else
    {
        if (queryCommandType == IContextModel::ACTIVATION_TYPE_GET)
        {
            //There is no models such name
            SSM_CLEANUP_ASSERT(SSM_E_FAIL);
        }
    }

    //Every subscribe command must request new data to models
    if (queryCommandType == IContextModel::ACTIVATION_TYPE_SUBSCRIBE)
    {
        SSM_CLEANUP_ASSERT(pConditionedQuery->activateTriggers(m_cqid));
    }

    *cqid = m_cqid++;

CLEANUP:
    SAFE_RELEASE(pConditionedQuery);
    SAFE_RELEASE(pConditionedQueryResult);
    return res;
}

//TODO: Registration with multiple instance support
SSMRESULT CQueryEngine::registerQueryEvent(IQueryEngineEvent *pQueryEngineEvent)
{
    m_pQueryEngineEvent = pQueryEngineEvent;
    return SSM_S_OK;
}

SSMRESULT CQueryEngine::unregisterQueryEvent(IQueryEngineEvent *pQueryEngineEvent)
{
    if (m_pQueryEngineEvent == pQueryEngineEvent)
    {
        m_pQueryEngineEvent = NULL;
        return SSM_S_OK;
    }

    return SSM_E_FAIL;
}

SSMRESULT CQueryEngine::killContextQuery(int cqid)
{
    SSMRESULT res = SSM_E_FAIL;

    std::map<int, IConditionedQuery *>::iterator itorConditionedQueries;
    std::map<int, CContextQuery *>::iterator itorContextQuries;

    m_mtxQueries.lock();
    itorConditionedQueries = m_conditionedQueries.find(cqid);
    itorContextQuries = m_contextQueries.find(cqid);

    if (itorConditionedQueries != m_conditionedQueries.end())
    {
        SSM_CLEANUP_ASSERT(itorConditionedQueries->second->deactivateTriggers());
        itorConditionedQueries->second->release();
        m_conditionedQueries.erase(itorConditionedQueries);
    }

    if (itorContextQuries != m_contextQueries.end())
    {
        SAFE_DELETE(itorContextQuries->second);
        m_contextQueries.erase(itorContextQuries);
    }

CLEANUP:
    m_mtxQueries.unlock();
    return res;
}
<|endoftext|>


<commit_before>//  tinygettext - A gettext replacement that works directly on .po files
//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program 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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

extern "C"
{
#include "../../engine/qcommon/q_shared.h"
#include "../../engine/qcommon/qcommon.h"
}

#include <iostream>
#include "log.hpp"

namespace tinygettext {

Log::log_callback_t Log::log_info_callback    = &Log::default_log_callback;
Log::log_callback_t Log::log_warning_callback = &Log::default_log_callback;
Log::log_callback_t Log::log_error_callback   = &Log::default_log_callback;

void
Log::default_log_callback(const std::string& str)
{
  if( Cvar_VariableIntegerValue( "language_debug" ) )
  {
	std::cerr << "tinygettext: " << str;
  }
}

void
Log::set_log_info_callback(log_callback_t callback)
{
  log_info_callback = callback;
}

void
Log::set_log_warning_callback(log_callback_t callback)
{
  log_warning_callback = callback;
}

void
Log::set_log_error_callback(log_callback_t callback)
{
  log_error_callback = callback;
}

Log::Log(log_callback_t callback_) :
  callback(callback_),
  out()
{
}

Log::~Log()
{
  callback(out.str());
}

std::ostream&
Log::get()
{
  return out;
}

} // namespace tinygettext

/* EOF */
<commit_msg>Remove qshared and qcommon from log.cpp includes<commit_after>//  tinygettext - A gettext replacement that works directly on .po files
//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program 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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

extern "C"
{
extern int Cvar_VariableIntegerValue( const char* str );
}

#include <iostream>
#include "log.hpp"

namespace tinygettext {

Log::log_callback_t Log::log_info_callback    = &Log::default_log_callback;
Log::log_callback_t Log::log_warning_callback = &Log::default_log_callback;
Log::log_callback_t Log::log_error_callback   = &Log::default_log_callback;

void
Log::default_log_callback(const std::string& str)
{
  if( Cvar_VariableIntegerValue( "language_debug" ) )
  {
	std::cerr << "tinygettext: " << str;
  }
}

void
Log::set_log_info_callback(log_callback_t callback)
{
  log_info_callback = callback;
}

void
Log::set_log_warning_callback(log_callback_t callback)
{
  log_warning_callback = callback;
}

void
Log::set_log_error_callback(log_callback_t callback)
{
  log_error_callback = callback;
}

Log::Log(log_callback_t callback_) :
  callback(callback_),
  out()
{
}

Log::~Log()
{
  callback(out.str());
}

std::ostream&
Log::get()
{
  return out;
}

} // namespace tinygettext

/* EOF */
<|endoftext|>


<commit_before>#include "Thread/Win/MutexImpl.hh"
#include "Thread/ThreadException.hh"

namespace LilWrapper
{
  MutexImpl::MutexImpl()
  {
    InitializeCriticalSection(&this->_mutex);
  }

  MutexImpl::~MutexImpl()
  {
    DeleteCriticalSection(&this->_mutex);
  }

  void MutexImpl::lock()
  {
    EnterCriticalSection(&this->_mutex);
  }

  void MutexImpl::unlock()
  {
    LeaveCriticalSection(&this->_mutex);
  }

  bool MutexImpl::trylock()
  {

  }
}
<commit_msg>Add trylock in Windows implementation of mutex.<commit_after>#include "Thread/Win/MutexImpl.hh"
#include "Thread/ThreadException.hh"

namespace LilWrapper
{
  MutexImpl::MutexImpl()
  {
    InitializeCriticalSection(&this->_mutex);
  }

  MutexImpl::~MutexImpl()
  {
    DeleteCriticalSection(&this->_mutex);
  }

  void MutexImpl::lock()
  {
    EnterCriticalSection(&this->_mutex);
  }

  void MutexImpl::unlock()
  {
    LeaveCriticalSection(&this->_mutex);
  }

  bool MutexImpl::trylock()
  {
    return (TryEnterCriticalSection(&this->_mutex) != 0);
  }
}
<|endoftext|>


<commit_before>
/*!
	\file
	\brief Compound file.

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2011-2017 Igor Mironchik

	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.
*/

#ifndef COMPOUNDFILE__COMPOUNDFILE_HPP__INCLUDED
#define COMPOUNDFILE__COMPOUNDFILE_HPP__INCLUDED

// CompoundFile include.
#include "compoundfile_stream_and_dir.hpp"
#include "header.hpp"
#include "sat.hpp"
#include "msat.hpp"
#include "utils.hpp"
#include "compoundfile_exceptions.hpp"

// Excel include.
#include "../stream.hpp"

// C++ include.
#include <string>
#include <vector>
#include <fstream>
#include <memory>

namespace CompoundFile {

//
// File
//

//! Compound file.
class File {
public:
	explicit File( std::istream & stream, const std::string & fileName = "<custom-stream>" );
	explicit File( const std::string & fileName );
	~File();

	//! \return Directory entry by its name.
	Directory directory( const std::wstring & name ) const;

	//! \return is Directory entry exist by its name.
	bool hasDirectory(const std::wstring & name ) const;

	//! \return Stream in the directory.
	std::unique_ptr< Excel::Stream > stream( const Directory & dir );

private:
	//! Read stream and initialize m_dirs.
    void initialize( const std::string& fileName );

private:
	//! Inner file stream.
	std::ifstream m_fileStream;
	//! Stream.
	std::istream & m_stream;
	//! Header of the compound file.
	Header m_header;
	//! SAT.
	SAT m_sat;
	//! SSAT.
	SAT m_ssat;
	//! SecID of the first sector of the short-sector stream.
	SecID m_shortStreamFirstSector;
	//! All directories defined in the compound file.
	std::vector< Directory > m_dirs;
}; // class File

//
// loadSSAT
//

inline SAT
loadSSAT( const Header & header, std::istream & stream,
	const SAT & sat )
{
	std::vector< SecID > ssat;

	if( header.ssatFirstSecID() != SecID::EndOfChain )
	{
		std::vector< SecID > chain = sat.sectors( header.ssatFirstSecID() );

		for( std::vector< SecID >::const_iterator it = chain.begin(),
			last = chain.end(); it != last; ++it )
		{
			stream.seekg( calcFileOffset( *it, header.sectorSize() ) );

			loadSATSector( stream, ssat, header.sectorSize() );
		}
	}

	return SAT( ssat );
} // loadSSAT

//! Size of the dir record.
static const int32_t dirRecordSize = 128;

//
// loadChildDir
//

inline bool
loadChildDir( std::vector< Directory > & dirs,
	int32_t dirID, Stream & stream )
{
	if( dirID != -1 )
	{
		stream.seek( dirID * dirRecordSize, Stream::FromBeginning );

		Directory dir;
		dir.load( stream );

		dirs.push_back( dir );

		return true;
	}

	return false;
} // loadChildDir

//
// loadChildDirectories
//

inline void
loadChildDirectories( std::vector< Directory > & dirs,
	const Directory & parentDir, Stream & stream )
{
	if( loadChildDir( dirs, parentDir.leftChild(), stream ) )
		loadChildDirectories( dirs, dirs.back(), stream );
	if( loadChildDir( dirs, parentDir.rightChild(), stream ) )
		loadChildDirectories( dirs, dirs.back(), stream );
} // loadChildDirectories

//
// File
//

inline
File::File( std::istream & stream, const std::string & fileName )
	: m_stream( stream )
{
	initialize( fileName );
}

inline
File::File( const std::string & fileName )
	: m_fileStream( fileName, std::ios::in | std::ios::binary )
	, m_stream( m_fileStream )

{
	initialize( fileName );
}

inline
File::~File()
{
	m_fileStream.close();
}

inline Directory
File::directory( const std::wstring & name ) const
{
	for( std::vector< Directory >::const_iterator it = m_dirs.begin(),
		last = m_dirs.end(); it != last; ++it )
	{
		if( it->name() == name )
			return *it;
	}

	throw Exception( std::wstring( L"There is no such directory : " ) + name );
}

inline bool
File::hasDirectory( const std::wstring & name ) const
{
	for( std::vector< Directory >::const_iterator it = m_dirs.begin(),
		last = m_dirs.end(); it != last; ++it )
	{
		if ( it->name() == name )
			return true;
	}

	return false;
}

inline std::unique_ptr< Excel::Stream >
File::stream( const Directory & dir )
{
	return std::unique_ptr< Excel::Stream > ( new Stream( m_header,
		m_sat, m_ssat, dir, m_shortStreamFirstSector, m_stream ) );
}

inline void
File::initialize( const std::string & fileName )
{
	if( m_stream.good() )
	{
		m_header.load( m_stream );

		MSAT msat( m_header, m_stream );
		m_sat = msat.buildSAT();

		m_ssat = loadSSAT( m_header, m_stream, m_sat );

		Stream stream( m_header, m_sat, m_header.dirStreamSecID(), m_stream );

		Directory root;
		root.load( stream );

		m_shortStreamFirstSector = root.streamSecID();

		stream.seek( root.rootNode() * dirRecordSize, Stream::FromBeginning );

		Directory rootEntry;
		rootEntry.load( stream );
		m_dirs.push_back( rootEntry );

		loadChildDirectories( m_dirs, rootEntry, stream );
	}
	else
		throw Exception( std::wstring( L"Unable to open file : " ) +
			std::wstring( fileName.cbegin(), fileName.cend() ) );
}

} /* namespace CompoundFile */

#endif // COMPOUNDFILE__COMPOUNDFILE_HPP__INCLUDED
<commit_msg>Update read-excel/compoundfile/compoundfile.hpp<commit_after>
/*!
	\file
	\brief Compound file.

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2011-2017 Igor Mironchik

	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.
*/

#ifndef COMPOUNDFILE__COMPOUNDFILE_HPP__INCLUDED
#define COMPOUNDFILE__COMPOUNDFILE_HPP__INCLUDED

// CompoundFile include.
#include "compoundfile_stream_and_dir.hpp"
#include "header.hpp"
#include "sat.hpp"
#include "msat.hpp"
#include "utils.hpp"
#include "compoundfile_exceptions.hpp"

// Excel include.
#include "../stream.hpp"

// C++ include.
#include <string>
#include <vector>
#include <fstream>
#include <memory>

namespace CompoundFile {

//
// File
//

//! Compound file.
class File {
public:
	explicit File( std::istream & stream, const std::string & fileName = "<custom-stream>" );
	explicit File( const std::string & fileName );
	~File();

	//! \return Directory entry by its name.
	Directory directory( const std::wstring & name ) const;

	//! \return is Directory entry exist by its name.
	bool hasDirectory(const std::wstring & name ) const;

	//! \return Stream in the directory.
	std::unique_ptr< Excel::Stream > stream( const Directory & dir );

private:
	//! Read stream and initialize m_dirs.
    void initialize( const std::string& fileName );

private:
	//! Inner file stream.
	std::ifstream m_fileStream;
	//! Stream.
	std::istream & m_stream;
	//! Header of the compound file.
	Header m_header;
	//! SAT.
	SAT m_sat;
	//! SSAT.
	SAT m_ssat;
	//! SecID of the first sector of the short-sector stream.
	SecID m_shortStreamFirstSector;
	//! All directories defined in the compound file.
	std::vector< Directory > m_dirs;
}; // class File

//
// loadSSAT
//

inline SAT
loadSSAT( const Header & header, std::istream & stream,
	const SAT & sat )
{
	std::vector< SecID > ssat;

	if( header.ssatFirstSecID() != SecID::EndOfChain )
	{
		std::vector< SecID > chain = sat.sectors( header.ssatFirstSecID() );

		for( std::vector< SecID >::const_iterator it = chain.begin(),
			last = chain.end(); it != last; ++it )
		{
			stream.seekg( calcFileOffset( *it, header.sectorSize() ) );

			loadSATSector( stream, ssat, header.sectorSize() );
		}
	}

	return SAT( ssat );
} // loadSSAT

//! Size of the dir record.
static const int32_t dirRecordSize = 128;

//
// loadChildDir
//

inline bool
loadChildDir( std::vector< Directory > & dirs,
	int32_t dirID, Stream & stream )
{
	if( dirID != -1 )
	{
		stream.seek( dirID * dirRecordSize, Stream::FromBeginning );

		Directory dir;
		dir.load( stream );

		dirs.push_back( dir );

		return true;
	}

	return false;
} // loadChildDir

//
// loadChildDirectories
//

inline void
loadChildDirectories( std::vector< Directory > & dirs,
	const Directory & parentDir, Stream & stream )
{
	if( loadChildDir( dirs, parentDir.leftChild(), stream ) )
		loadChildDirectories( dirs, dirs.back(), stream );
	if( loadChildDir( dirs, parentDir.rightChild(), stream ) )
		loadChildDirectories( dirs, dirs.back(), stream );
} // loadChildDirectories

//
// File
//

inline
File::File( std::istream & stream, const std::string & fileName )
	:	m_stream( stream )
{
	initialize( fileName );
}

inline
File::File( const std::string & fileName )
	: m_fileStream( fileName, std::ios::in | std::ios::binary )
	, m_stream( m_fileStream )

{
	initialize( fileName );
}

inline
File::~File()
{
	m_fileStream.close();
}

inline Directory
File::directory( const std::wstring & name ) const
{
	for( std::vector< Directory >::const_iterator it = m_dirs.begin(),
		last = m_dirs.end(); it != last; ++it )
	{
		if( it->name() == name )
			return *it;
	}

	throw Exception( std::wstring( L"There is no such directory : " ) + name );
}

inline bool
File::hasDirectory( const std::wstring & name ) const
{
	for( std::vector< Directory >::const_iterator it = m_dirs.begin(),
		last = m_dirs.end(); it != last; ++it )
	{
		if ( it->name() == name )
			return true;
	}

	return false;
}

inline std::unique_ptr< Excel::Stream >
File::stream( const Directory & dir )
{
	return std::unique_ptr< Excel::Stream > ( new Stream( m_header,
		m_sat, m_ssat, dir, m_shortStreamFirstSector, m_stream ) );
}

inline void
File::initialize( const std::string & fileName )
{
	if( m_stream.good() )
	{
		m_header.load( m_stream );

		MSAT msat( m_header, m_stream );
		m_sat = msat.buildSAT();

		m_ssat = loadSSAT( m_header, m_stream, m_sat );

		Stream stream( m_header, m_sat, m_header.dirStreamSecID(), m_stream );

		Directory root;
		root.load( stream );

		m_shortStreamFirstSector = root.streamSecID();

		stream.seek( root.rootNode() * dirRecordSize, Stream::FromBeginning );

		Directory rootEntry;
		rootEntry.load( stream );
		m_dirs.push_back( rootEntry );

		loadChildDirectories( m_dirs, rootEntry, stream );
	}
	else
		throw Exception( std::wstring( L"Unable to open file : " ) +
			std::wstring( fileName.cbegin(), fileName.cend() ) );
}

} /* namespace CompoundFile */

#endif // COMPOUNDFILE__COMPOUNDFILE_HPP__INCLUDED
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "savefile.h"
#include "qtcassert.h"
#include "fileutils.h"
#ifdef Q_OS_WIN
#  include <windows.h>
#else
#  include <unistd.h>
#  include <sys/stat.h>
#endif

namespace Utils {

QFile::Permissions SaveFile::m_umask = 0;

SaveFile::SaveFile(const QString &filename) :
    m_finalFileName(filename), m_finalized(true), m_backup(false)
{
}

SaveFile::~SaveFile()
{
    QTC_ASSERT(m_finalized, rollback());
}

bool SaveFile::open(OpenMode flags)
{
    QTC_ASSERT(!m_finalFileName.isEmpty() && fileName().isEmpty(), return false);

    QFile ofi(m_finalFileName);
    // Check whether the existing file is writable
    if (ofi.exists() && !ofi.open(QIODevice::ReadWrite)) {
        setErrorString(ofi.errorString());
        return false;
    }

    setAutoRemove(false);
    setFileTemplate(m_finalFileName);
    if (!QTemporaryFile::open(flags))
        return false;

    m_finalized = false; // needs clean up in the end
    if (ofi.exists()) {
        setPermissions(ofi.permissions()); // Ignore errors
    } else {
        Permissions permAll = QFile::ReadOwner
                | QFile::ReadGroup
                | QFile::ReadOther
                | QFile::WriteOwner
                | QFile::WriteGroup
                | QFile::WriteOther;

        // set permissions with respect to the current umask
        setPermissions(permAll & ~m_umask);
    }

    return true;
}

void SaveFile::rollback()
{
    remove();
    m_finalized = true;
}

bool SaveFile::commit()
{
    QTC_ASSERT(!m_finalized, return false);
    m_finalized = true;

    if (!flush()) {
        remove();
        return false;
    }
#ifdef Q_OS_WIN
    FlushFileBuffers(reinterpret_cast<HANDLE>(handle()));
#elif defined(Q_OS_MAC)
    fsync(handle());
#else
    fdatasync(handle());
#endif
    close();
    if (error() != NoError) {
        remove();
        return false;
    }

    QString finalFileName
            = FileUtils::resolveSymlinks(FileName::fromString(m_finalFileName)).toString();
    QString bakname = finalFileName + QLatin1Char('~');
    QFile::remove(bakname); // Kill old backup
    QFile::rename(finalFileName, bakname); // Backup current file
    if (!rename(finalFileName)) { // Replace current file
        QFile::rename(bakname, finalFileName); // Rollback to current file
        return false;
    }
    if (!m_backup)
        QFile::remove(bakname);

    return true;
}

void SaveFile::initializeUmask()
{
#ifdef Q_OS_WIN
    m_umask = QFile::WriteGroup | QFile::WriteOther;
#else
    // Get the current process' file creation mask (umask)
    // umask() is not thread safe so this has to be done by single threaded
    // application initialization
    mode_t mask = umask(0); // get current umask
    umask(mask); // set it back

    m_umask = ((mask & S_IRUSR) ? QFile::ReadOwner  : QFlags<QFile::Permission>(0))
            | ((mask & S_IWUSR) ? QFile::WriteOwner : QFlags<QFile::Permission>(0))
            | ((mask & S_IXUSR) ? QFile::ExeOwner   : QFlags<QFile::Permission>(0))
            | ((mask & S_IRGRP) ? QFile::ReadGroup  : QFlags<QFile::Permission>(0))
            | ((mask & S_IWGRP) ? QFile::WriteGroup : QFlags<QFile::Permission>(0))
            | ((mask & S_IXGRP) ? QFile::ExeGroup   : QFlags<QFile::Permission>(0))
            | ((mask & S_IROTH) ? QFile::ReadOther  : QFlags<QFile::Permission>(0))
            | ((mask & S_IWOTH) ? QFile::WriteOther : QFlags<QFile::Permission>(0))
            | ((mask & S_IXOTH) ? QFile::ExeOther   : QFlags<QFile::Permission>(0));
#endif
}

} // namespace Utils
<commit_msg>Utils: Make sure we only use fdatasync() on systems that have it.<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "savefile.h"
#include "qtcassert.h"
#include "fileutils.h"
#ifdef Q_OS_WIN
#  include <windows.h>
#else
#  include <unistd.h>
#  include <sys/stat.h>
#endif

namespace Utils {

QFile::Permissions SaveFile::m_umask = 0;

SaveFile::SaveFile(const QString &filename) :
    m_finalFileName(filename), m_finalized(true), m_backup(false)
{
}

SaveFile::~SaveFile()
{
    QTC_ASSERT(m_finalized, rollback());
}

bool SaveFile::open(OpenMode flags)
{
    QTC_ASSERT(!m_finalFileName.isEmpty() && fileName().isEmpty(), return false);

    QFile ofi(m_finalFileName);
    // Check whether the existing file is writable
    if (ofi.exists() && !ofi.open(QIODevice::ReadWrite)) {
        setErrorString(ofi.errorString());
        return false;
    }

    setAutoRemove(false);
    setFileTemplate(m_finalFileName);
    if (!QTemporaryFile::open(flags))
        return false;

    m_finalized = false; // needs clean up in the end
    if (ofi.exists()) {
        setPermissions(ofi.permissions()); // Ignore errors
    } else {
        Permissions permAll = QFile::ReadOwner
                | QFile::ReadGroup
                | QFile::ReadOther
                | QFile::WriteOwner
                | QFile::WriteGroup
                | QFile::WriteOther;

        // set permissions with respect to the current umask
        setPermissions(permAll & ~m_umask);
    }

    return true;
}

void SaveFile::rollback()
{
    remove();
    m_finalized = true;
}

bool SaveFile::commit()
{
    QTC_ASSERT(!m_finalized, return false);
    m_finalized = true;

    if (!flush()) {
        remove();
        return false;
    }
#ifdef Q_OS_WIN
    FlushFileBuffers(reinterpret_cast<HANDLE>(handle()));
#elif _POSIX_SYNCHRONIZED_IO > 0
    fdatasync(handle());
#else
    fsync(handle());
#endif
    close();
    if (error() != NoError) {
        remove();
        return false;
    }

    QString finalFileName
            = FileUtils::resolveSymlinks(FileName::fromString(m_finalFileName)).toString();
    QString bakname = finalFileName + QLatin1Char('~');
    QFile::remove(bakname); // Kill old backup
    QFile::rename(finalFileName, bakname); // Backup current file
    if (!rename(finalFileName)) { // Replace current file
        QFile::rename(bakname, finalFileName); // Rollback to current file
        return false;
    }
    if (!m_backup)
        QFile::remove(bakname);

    return true;
}

void SaveFile::initializeUmask()
{
#ifdef Q_OS_WIN
    m_umask = QFile::WriteGroup | QFile::WriteOther;
#else
    // Get the current process' file creation mask (umask)
    // umask() is not thread safe so this has to be done by single threaded
    // application initialization
    mode_t mask = umask(0); // get current umask
    umask(mask); // set it back

    m_umask = ((mask & S_IRUSR) ? QFile::ReadOwner  : QFlags<QFile::Permission>(0))
            | ((mask & S_IWUSR) ? QFile::WriteOwner : QFlags<QFile::Permission>(0))
            | ((mask & S_IXUSR) ? QFile::ExeOwner   : QFlags<QFile::Permission>(0))
            | ((mask & S_IRGRP) ? QFile::ReadGroup  : QFlags<QFile::Permission>(0))
            | ((mask & S_IWGRP) ? QFile::WriteGroup : QFlags<QFile::Permission>(0))
            | ((mask & S_IXGRP) ? QFile::ExeGroup   : QFlags<QFile::Permission>(0))
            | ((mask & S_IROTH) ? QFile::ReadOther  : QFlags<QFile::Permission>(0))
            | ((mask & S_IWOTH) ? QFile::WriteOther : QFlags<QFile::Permission>(0))
            | ((mask & S_IXOTH) ? QFile::ExeOther   : QFlags<QFile::Permission>(0));
#endif
}

} // namespace Utils
<|endoftext|>


<commit_before>/**
 * MegaMol
 * Copyright (c) 2009, MegaMol Dev Team
 * All rights reserved.
 */

#include "mmstd_gl/renderer/CallGetTransferFunctionGL.h"

using namespace megamol::mmstd_gl;

/*
 * view::CallGetTransferFunctionGL::CallGetTransferFunctionGL
 */
CallGetTransferFunctionGL::CallGetTransferFunctionGL(void) : AbstractCallGetTransferFunction(), texID(0) {
    // intentionally empty
}

/*
 * view::CallGetTransferFunctionGL::~CallGetTransferFunctionGL
 */
CallGetTransferFunctionGL::~CallGetTransferFunctionGL(void) {
    // intentionally empty
}

void CallGetTransferFunctionGL::BindConvenience(
    vislib_gl::graphics::gl::GLSLShader& shader, GLenum activeTexture, int textureUniform) {
    glEnable(GL_TEXTURE_1D);
    glActiveTexture(activeTexture);
    glBindTexture(GL_TEXTURE_1D, this->texID);
    glUniform1i(shader.ParameterLocation("tfTexture"), textureUniform);
    glUniform2fv(shader.ParameterLocation("tfRange"), 1, this->range.data());
}

void CallGetTransferFunctionGL::BindConvenience(
    std::unique_ptr<glowl::GLSLProgram>& shader, GLenum activeTexture, int textureUniform) {
        BindConvenience(*shader, activeTexture, textureUniform);
}

void CallGetTransferFunctionGL::BindConvenience(
    glowl::GLSLProgram& shader, GLenum activeTexture, int textureUniform) {
    glEnable(GL_TEXTURE_1D);
    glActiveTexture(activeTexture);
    glBindTexture(GL_TEXTURE_1D, this->texID);
    shader.setUniform("tfTexture", textureUniform);
    glUniform2fv(shader.getUniformLocation("tfRange"), 1, this->range.data());
}

void CallGetTransferFunctionGL::UnbindConvenience() {
    glDisable(GL_TEXTURE_1D);
    glBindTexture(GL_TEXTURE_1D, 0);
}
<commit_msg>Format fix.<commit_after>/**
 * MegaMol
 * Copyright (c) 2009, MegaMol Dev Team
 * All rights reserved.
 */

#include "mmstd_gl/renderer/CallGetTransferFunctionGL.h"

using namespace megamol::mmstd_gl;

/*
 * view::CallGetTransferFunctionGL::CallGetTransferFunctionGL
 */
CallGetTransferFunctionGL::CallGetTransferFunctionGL(void) : AbstractCallGetTransferFunction(), texID(0) {
    // intentionally empty
}

/*
 * view::CallGetTransferFunctionGL::~CallGetTransferFunctionGL
 */
CallGetTransferFunctionGL::~CallGetTransferFunctionGL(void) {
    // intentionally empty
}

void CallGetTransferFunctionGL::BindConvenience(
    vislib_gl::graphics::gl::GLSLShader& shader, GLenum activeTexture, int textureUniform) {
    glEnable(GL_TEXTURE_1D);
    glActiveTexture(activeTexture);
    glBindTexture(GL_TEXTURE_1D, this->texID);
    glUniform1i(shader.ParameterLocation("tfTexture"), textureUniform);
    glUniform2fv(shader.ParameterLocation("tfRange"), 1, this->range.data());
}

void CallGetTransferFunctionGL::BindConvenience(
    std::unique_ptr<glowl::GLSLProgram>& shader, GLenum activeTexture, int textureUniform) {
    BindConvenience(*shader, activeTexture, textureUniform);
}

void CallGetTransferFunctionGL::BindConvenience(glowl::GLSLProgram& shader, GLenum activeTexture, int textureUniform) {
    glEnable(GL_TEXTURE_1D);
    glActiveTexture(activeTexture);
    glBindTexture(GL_TEXTURE_1D, this->texID);
    shader.setUniform("tfTexture", textureUniform);
    glUniform2fv(shader.getUniformLocation("tfRange"), 1, this->range.data());
}

void CallGetTransferFunctionGL::UnbindConvenience() {
    glDisable(GL_TEXTURE_1D);
    glBindTexture(GL_TEXTURE_1D, 0);
}
<|endoftext|>