<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 "otbPipelineMemoryPrintCalculator.h"

#include "otbMath.h"
#include "itkImage.h"
#include "itkVectorImage.h"
#include "itkFixedArray.h"

namespace otb
{
const double PipelineMemoryPrintCalculator::ByteToMegabyte = 1./vcl_pow(2.0, 20);

PipelineMemoryPrintCalculator
::PipelineMemoryPrintCalculator()
  : m_MemoryPrint(0),
    m_AvailableMemory(256),
    m_OptimalNumberOfStreamDivisions(1),
    m_DataToWrite(NULL),
    m_BiasCorrectionFactor(1.)
{}

void
PipelineMemoryPrintCalculator
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  // Call superclass implementation
  Superclass::PrintSelf(os,indent);

  // Display parameters
  os<<indent<<"Data to write:                      "<<m_DataToWrite<<std::endl;
  os<<indent<<"Memory print of whole pipeline:     "<<m_MemoryPrint * ByteToMegabyte <<" Mb"<<std::endl;
  os<<indent<<"Available memory:                   "<<m_AvailableMemory * ByteToMegabyte <<" Mb"<<std::endl;
  os<<indent<<"Optimal number of stream divisions: "<<m_OptimalNumberOfStreamDivisions<<std::endl;
  os<<indent<<"Bias correction factor applied:     "<<m_BiasCorrectionFactor<<std::endl;
}

void
PipelineMemoryPrintCalculator
::Compute()
{
  // Dry run of pipeline synchronisation
  m_DataToWrite->UpdateOutputInformation();
  m_DataToWrite->SetRequestedRegionToLargestPossibleRegion();
  m_DataToWrite->PropagateRequestedRegion();

  // Get the source process object
  ProcessObjectType * source = m_DataToWrite->GetSource();

  // Check if source exists
  if(source)
    {
    // Call the recursive memory print evaluation
    m_MemoryPrint = EvaluateMemoryPrint(source);
    }
  else
    {
    // Get memory print for this data only
    m_MemoryPrint = EvaluateDataObjectPrint(m_DataToWrite);
    }

  // Apply bias correction factor
  m_MemoryPrint *= m_BiasCorrectionFactor;

  // Compute the optimal number of stream division
  m_OptimalNumberOfStreamDivisions = vcl_ceil(m_MemoryPrint
                                              /m_AvailableMemory);
}

PipelineMemoryPrintCalculator::MemoryPrintType
PipelineMemoryPrintCalculator
::EvaluateMemoryPrint(ProcessObjectType * process)
{
  // This variable will store the final print
  MemoryPrintType print = 0;

  // Retrieve the array of inputs
  ProcessObjectType::DataObjectPointerArray inputs = process->GetInputs();
  // First, recurse on each input source
  for(unsigned int i = 0; i < process->GetNumberOfInputs(); ++i)
    {
    // Retrieve the data object
    DataObjectType * input = inputs[i];

    // Retrieve possible source
    ProcessObjectType * source = input->GetSource();

    // If data object has a source
    if(source)
      {
      print += this->EvaluateMemoryPrint(source);
      }
    else
      {
      MemoryPrintType localPrint = this->EvaluateDataObjectPrint(input);
      print += localPrint;
      }
    }
  // Retrieve the output array
  ProcessObjectType::DataObjectPointerArray outputs = process->GetOutputs();

  // Now, evaluate the current object print
  for(unsigned int i = 0; i < process->GetNumberOfOutputs(); ++i)
    {
    MemoryPrintType localPrint = this->EvaluateDataObjectPrint(outputs[0]);
    print += localPrint;
    }

  // Finally, return the total print
  return print;
}

PipelineMemoryPrintCalculator::MemoryPrintType
PipelineMemoryPrintCalculator
::EvaluateDataObjectPrint(DataObjectType * data) const
{

#define OTB_IMAGE_SIZE_BLOCK(type)                                      \
  if(dynamic_cast<itk::Image<type,2> *>(data) != NULL)                  \
    {                                                                   \
    itk::Image<type,2> * image = dynamic_cast<itk::Image<type,2> *>(data); \
    return image->GetRequestedRegion().GetNumberOfPixels()              \
      * image->GetNumberOfComponentsPerPixel() * sizeof(type); \
    }                                                                   \
  if(dynamic_cast<itk::VectorImage<type,2> * >(data) != NULL)           \
    {                                                                   \
    itk::VectorImage<type,2> * image = dynamic_cast<itk::VectorImage<type,2> *>(data); \
    return image->GetRequestedRegion().GetNumberOfPixels()              \
      * image->GetNumberOfComponentsPerPixel() * sizeof(type); \
    }                                                                   \

  // Call the macro for each pixel type
  OTB_IMAGE_SIZE_BLOCK(unsigned char)
  OTB_IMAGE_SIZE_BLOCK(char)
  OTB_IMAGE_SIZE_BLOCK(unsigned short)
  OTB_IMAGE_SIZE_BLOCK(short)
  OTB_IMAGE_SIZE_BLOCK(unsigned int)
  OTB_IMAGE_SIZE_BLOCK(int)
  OTB_IMAGE_SIZE_BLOCK(unsigned long)
  OTB_IMAGE_SIZE_BLOCK(long)
  OTB_IMAGE_SIZE_BLOCK(float)
  OTB_IMAGE_SIZE_BLOCK(double)
  OTB_IMAGE_SIZE_BLOCK(std::complex<float>)
  OTB_IMAGE_SIZE_BLOCK(std::complex<double>)
  typedef itk::FixedArray<float,2> FloatFixedArray2Type;
  typedef itk::FixedArray<float,2> DoubleFixedArray2Type;
  OTB_IMAGE_SIZE_BLOCK(FloatFixedArray2Type)
  OTB_IMAGE_SIZE_BLOCK(DoubleFixedArray2Type)

  // If we are still here, none of the macro call succeed
  return 0;
}

} // End namespace otb
<commit_msg>BUG: fix windows compilation<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 "otbPipelineMemoryPrintCalculator.h"

#include "otbMath.h"
#include "itkImage.h"
#include "itkVectorImage.h"
#include "itkFixedArray.h"

namespace otb
{
const double PipelineMemoryPrintCalculator::ByteToMegabyte = 1./vcl_pow(2.0, 20);

PipelineMemoryPrintCalculator
::PipelineMemoryPrintCalculator()
  : m_MemoryPrint(0),
    m_AvailableMemory(256),
    m_OptimalNumberOfStreamDivisions(1),
    m_DataToWrite(NULL),
    m_BiasCorrectionFactor(1.)
{}

void
PipelineMemoryPrintCalculator
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  // Call superclass implementation
  Superclass::PrintSelf(os,indent);

  // Display parameters
  os<<indent<<"Data to write:                      "<<m_DataToWrite<<std::endl;
  os<<indent<<"Memory print of whole pipeline:     "<<m_MemoryPrint * ByteToMegabyte <<" Mb"<<std::endl;
  os<<indent<<"Available memory:                   "<<m_AvailableMemory * ByteToMegabyte <<" Mb"<<std::endl;
  os<<indent<<"Optimal number of stream divisions: "<<m_OptimalNumberOfStreamDivisions<<std::endl;
  os<<indent<<"Bias correction factor applied:     "<<m_BiasCorrectionFactor<<std::endl;
}

void
PipelineMemoryPrintCalculator
::Compute()
{
  // Dry run of pipeline synchronisation
  m_DataToWrite->UpdateOutputInformation();
  m_DataToWrite->SetRequestedRegionToLargestPossibleRegion();
  m_DataToWrite->PropagateRequestedRegion();

  // Get the source process object
  ProcessObjectType * source = m_DataToWrite->GetSource();

  // Check if source exists
  if(source)
    {
    // Call the recursive memory print evaluation
    m_MemoryPrint = EvaluateMemoryPrint(source);
    }
  else
    {
    // Get memory print for this data only
    m_MemoryPrint = EvaluateDataObjectPrint(m_DataToWrite);
    }

  // Apply bias correction factor
  m_MemoryPrint *= m_BiasCorrectionFactor;

  // Compute the optimal number of stream division
  m_OptimalNumberOfStreamDivisions = vcl_ceil(static_cast<double>(m_MemoryPrint)
                                              /m_AvailableMemory);
}

PipelineMemoryPrintCalculator::MemoryPrintType
PipelineMemoryPrintCalculator
::EvaluateMemoryPrint(ProcessObjectType * process)
{
  // This variable will store the final print
  MemoryPrintType print = 0;

  // Retrieve the array of inputs
  ProcessObjectType::DataObjectPointerArray inputs = process->GetInputs();
  // First, recurse on each input source
  for(unsigned int i = 0; i < process->GetNumberOfInputs(); ++i)
    {
    // Retrieve the data object
    DataObjectType * input = inputs[i];

    // Retrieve possible source
    ProcessObjectType * source = input->GetSource();

    // If data object has a source
    if(source)
      {
      print += this->EvaluateMemoryPrint(source);
      }
    else
      {
      MemoryPrintType localPrint = this->EvaluateDataObjectPrint(input);
      print += localPrint;
      }
    }
  // Retrieve the output array
  ProcessObjectType::DataObjectPointerArray outputs = process->GetOutputs();

  // Now, evaluate the current object print
  for(unsigned int i = 0; i < process->GetNumberOfOutputs(); ++i)
    {
    MemoryPrintType localPrint = this->EvaluateDataObjectPrint(outputs[0]);
    print += localPrint;
    }

  // Finally, return the total print
  return print;
}

PipelineMemoryPrintCalculator::MemoryPrintType
PipelineMemoryPrintCalculator
::EvaluateDataObjectPrint(DataObjectType * data) const
{

#define OTB_IMAGE_SIZE_BLOCK(type)                                      \
  if(dynamic_cast<itk::Image<type,2> *>(data) != NULL)                  \
    {                                                                   \
    itk::Image<type,2> * image = dynamic_cast<itk::Image<type,2> *>(data); \
    return image->GetRequestedRegion().GetNumberOfPixels()              \
      * image->GetNumberOfComponentsPerPixel() * sizeof(type); \
    }                                                                   \
  if(dynamic_cast<itk::VectorImage<type,2> * >(data) != NULL)           \
    {                                                                   \
    itk::VectorImage<type,2> * image = dynamic_cast<itk::VectorImage<type,2> *>(data); \
    return image->GetRequestedRegion().GetNumberOfPixels()              \
      * image->GetNumberOfComponentsPerPixel() * sizeof(type); \
    }                                                                   \

  // Call the macro for each pixel type
  OTB_IMAGE_SIZE_BLOCK(unsigned char)
  OTB_IMAGE_SIZE_BLOCK(char)
  OTB_IMAGE_SIZE_BLOCK(unsigned short)
  OTB_IMAGE_SIZE_BLOCK(short)
  OTB_IMAGE_SIZE_BLOCK(unsigned int)
  OTB_IMAGE_SIZE_BLOCK(int)
  OTB_IMAGE_SIZE_BLOCK(unsigned long)
  OTB_IMAGE_SIZE_BLOCK(long)
  OTB_IMAGE_SIZE_BLOCK(float)
  OTB_IMAGE_SIZE_BLOCK(double)
  OTB_IMAGE_SIZE_BLOCK(std::complex<float>)
  OTB_IMAGE_SIZE_BLOCK(std::complex<double>)
  typedef itk::FixedArray<float,2> FloatFixedArray2Type;
  typedef itk::FixedArray<float,2> DoubleFixedArray2Type;
  OTB_IMAGE_SIZE_BLOCK(FloatFixedArray2Type)
  OTB_IMAGE_SIZE_BLOCK(DoubleFixedArray2Type)

  // If we are still here, none of the macro call succeed
  return 0;
}

} // End namespace otb
<|endoftext|>


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

#include <pdal/pdal_test_main.hpp>

#include <pdal/PDALUtils.hpp>
#include <pdal/StageFactory.hpp>
#include <FauxReader.hpp>
#include <StatsFilter.hpp>

#include "Support.hpp"

using namespace pdal;

TEST(Stats, simple)
{
    BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 1000);
    ops.add("mode", "constant");

    StageFactory f;

    std::unique_ptr<Stage> reader(f.createStage("readers.faux"));
    EXPECT_TRUE(reader.get());
    reader->setOptions(ops);

    StatsFilter filter;
    filter.setInput(*reader);
    EXPECT_EQ(filter.getName(), "filters.stats");

    PointTable table;
    filter.prepare(table);
    filter.execute(table);

    const stats::Summary& statsX = filter.getStats(Dimension::Id::X);
    const stats::Summary& statsY = filter.getStats(Dimension::Id::Y);
    const stats::Summary& statsZ = filter.getStats(Dimension::Id::Z);

    EXPECT_EQ(statsX.count(), 1000u);
    EXPECT_EQ(statsY.count(), 1000u);
    EXPECT_EQ(statsZ.count(), 1000u);

    EXPECT_FLOAT_EQ(statsX.minimum(), 1.0);
    EXPECT_FLOAT_EQ(statsY.minimum(), 2.0);
    EXPECT_FLOAT_EQ(statsZ.minimum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.maximum(), 1.0);
    EXPECT_FLOAT_EQ(statsY.maximum(), 2.0);
    EXPECT_FLOAT_EQ(statsZ.maximum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.average(), 1.0);
    EXPECT_FLOAT_EQ(statsY.average(), 2.0);
    EXPECT_FLOAT_EQ(statsZ.average(), 3.0);
}

TEST(Stats, dimset)
{
    BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 1000);
    ops.add("mode", "constant");

    StageFactory f;
    std::unique_ptr<Stage> reader(f.createStage("readers.faux"));
    EXPECT_TRUE(reader.get());
    reader->setOptions(ops);

    Options filterOps;
    filterOps.add("dimensions", " , X, Z ");
    StatsFilter filter;
    filter.setInput(*reader);
    filter.setOptions(filterOps);
    EXPECT_EQ(filter.getName(), "filters.stats");

    PointTable table;
    filter.prepare(table);
    filter.execute(table);

    const stats::Summary& statsX = filter.getStats(Dimension::Id::X);
    EXPECT_THROW(filter.getStats(Dimension::Id::Y), pdal_error);
    const stats::Summary& statsZ = filter.getStats(Dimension::Id::Z);

    EXPECT_EQ(statsX.count(), 1000u);
    EXPECT_EQ(statsZ.count(), 1000u);

    EXPECT_FLOAT_EQ(statsX.minimum(), 1.0);
    EXPECT_FLOAT_EQ(statsZ.minimum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.maximum(), 1.0);
    EXPECT_FLOAT_EQ(statsZ.maximum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.average(), 1.0);
    EXPECT_FLOAT_EQ(statsZ.average(), 3.0);
}

TEST(Stats, metadata)
{
    BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 1000);
    ops.add("mode", "constant");

    StageFactory f;
    std::unique_ptr<Stage> reader(f.createStage("readers.faux"));
    EXPECT_TRUE(reader.get());
    reader->setOptions(ops);

    Options filterOps;
    filterOps.add("dimensions", " , X, Z ");
    StatsFilter filter;
    filter.setInput(*reader);
    filter.setOptions(filterOps);

    PointTable table;
    filter.prepare(table);
    filter.execute(table);
    MetadataNode m = filter.getMetadata();
    std::vector<MetadataNode> children = m.children("statistic");

    auto findNode = [](MetadataNode m,
        const std::string name, const std::string val)
    {
        auto findNameVal = [name, val](MetadataNode m)
            { return (m.name() == name && m.value() == val); };

        return m.find(findNameVal);
    };

    for (auto mi = children.begin(); mi != children.end(); ++mi)
    {
        if (findNode(*mi, "name", "X").valid())
        {
            EXPECT_EQ(mi->findChild("average").value(), "1");
            EXPECT_EQ(mi->findChild("minimum").value(), "1");
            EXPECT_EQ(mi->findChild("maximum").value(), "1");
            EXPECT_EQ(mi->findChild("count").value(), "1000");
        }
        if (findNode(*mi, "name", "Z").valid())
        {
            EXPECT_EQ(mi->findChild("average").value(), "3");
            EXPECT_EQ(mi->findChild("minimum").value(), "3");
            EXPECT_EQ(mi->findChild("maximum").value(), "3");
            EXPECT_EQ(mi->findChild("count").value(), "1000");
        }
    }
}

TEST(Stats, enum)
{
    BOX3D bounds(1.0, 0.0, 0.0, 10.0, 100.0, 1000.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 10);
    ops.add("mode", "ramp");

    FauxReader reader;
    reader.setOptions(ops);

    Options filterOps;
    filterOps.add("dimensions", "X, Y, Z");
    filterOps.add("enumerate", "X");
    filterOps.add("count", "Y");

    StatsFilter filter;
    filter.setInput(reader);
    filter.setOptions(filterOps);

    PointTable table;
    filter.prepare(table);
    filter.execute(table);

    const stats::Summary& statsX = filter.getStats(Dimension::Id::X);
    const stats::Summary::EnumMap& values = statsX.values();
    EXPECT_EQ(values.size(), 10U);
    double d = 1.0;
    for (auto& v : values)
    {
        EXPECT_DOUBLE_EQ(d, v.first);
        d += 1.0;
    }

    const stats::Summary& statsY = filter.getStats(Dimension::Id::Y);
    const stats::Summary::EnumMap& yValues = statsY.values();
    d = 0.0;
    for (auto& v : yValues)
    {
        EXPECT_DOUBLE_EQ(d, v.first);
        EXPECT_EQ(1u, v.second);
        d += (100.0 / 9);
    }
}
<commit_msg>Fix stats test to handle metadata more flexibly.<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/pdal_test_main.hpp>

#include <pdal/PDALUtils.hpp>
#include <pdal/StageFactory.hpp>
#include <FauxReader.hpp>
#include <StatsFilter.hpp>

#include "Support.hpp"

using namespace pdal;

TEST(Stats, simple)
{
    BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 1000);
    ops.add("mode", "constant");

    StageFactory f;

    std::unique_ptr<Stage> reader(f.createStage("readers.faux"));
    EXPECT_TRUE(reader.get());
    reader->setOptions(ops);

    StatsFilter filter;
    filter.setInput(*reader);
    EXPECT_EQ(filter.getName(), "filters.stats");

    PointTable table;
    filter.prepare(table);
    filter.execute(table);

    const stats::Summary& statsX = filter.getStats(Dimension::Id::X);
    const stats::Summary& statsY = filter.getStats(Dimension::Id::Y);
    const stats::Summary& statsZ = filter.getStats(Dimension::Id::Z);

    EXPECT_EQ(statsX.count(), 1000u);
    EXPECT_EQ(statsY.count(), 1000u);
    EXPECT_EQ(statsZ.count(), 1000u);

    EXPECT_FLOAT_EQ(statsX.minimum(), 1.0);
    EXPECT_FLOAT_EQ(statsY.minimum(), 2.0);
    EXPECT_FLOAT_EQ(statsZ.minimum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.maximum(), 1.0);
    EXPECT_FLOAT_EQ(statsY.maximum(), 2.0);
    EXPECT_FLOAT_EQ(statsZ.maximum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.average(), 1.0);
    EXPECT_FLOAT_EQ(statsY.average(), 2.0);
    EXPECT_FLOAT_EQ(statsZ.average(), 3.0);
}

TEST(Stats, dimset)
{
    BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 1000);
    ops.add("mode", "constant");

    StageFactory f;
    std::unique_ptr<Stage> reader(f.createStage("readers.faux"));
    EXPECT_TRUE(reader.get());
    reader->setOptions(ops);

    Options filterOps;
    filterOps.add("dimensions", " , X, Z ");
    StatsFilter filter;
    filter.setInput(*reader);
    filter.setOptions(filterOps);
    EXPECT_EQ(filter.getName(), "filters.stats");

    PointTable table;
    filter.prepare(table);
    filter.execute(table);

    const stats::Summary& statsX = filter.getStats(Dimension::Id::X);
    EXPECT_THROW(filter.getStats(Dimension::Id::Y), pdal_error);
    const stats::Summary& statsZ = filter.getStats(Dimension::Id::Z);

    EXPECT_EQ(statsX.count(), 1000u);
    EXPECT_EQ(statsZ.count(), 1000u);

    EXPECT_FLOAT_EQ(statsX.minimum(), 1.0);
    EXPECT_FLOAT_EQ(statsZ.minimum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.maximum(), 1.0);
    EXPECT_FLOAT_EQ(statsZ.maximum(), 3.0);

    EXPECT_FLOAT_EQ(statsX.average(), 1.0);
    EXPECT_FLOAT_EQ(statsZ.average(), 3.0);
}

TEST(Stats, metadata)
{
    BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 1000);
    ops.add("mode", "constant");

    StageFactory f;
    std::unique_ptr<Stage> reader(f.createStage("readers.faux"));
    EXPECT_TRUE(reader.get());
    reader->setOptions(ops);

    Options filterOps;
    filterOps.add("dimensions", " , X, Z ");
    StatsFilter filter;
    filter.setInput(*reader);
    filter.setOptions(filterOps);

    PointTable table;
    filter.prepare(table);
    filter.execute(table);
    MetadataNode m = filter.getMetadata();
    std::vector<MetadataNode> children = m.children("statistic");

    auto findNode = [](MetadataNode m,
        const std::string name, const std::string val)
    {
        auto findNameVal = [name, val](MetadataNode m)
            { return (m.name() == name && m.value() == val); };

        return m.find(findNameVal);
    };

    for (auto mi = children.begin(); mi != children.end(); ++mi)
    {
        if (findNode(*mi, "name", "X").valid())
        {
            EXPECT_DOUBLE_EQ(mi->findChild("average").value<double>(), 1.0);
            EXPECT_EQ(mi->findChild("minimum").value<double>(), 1.0);
            EXPECT_EQ(mi->findChild("maximum").value<double>(), 1.0);
            EXPECT_EQ(mi->findChild("count").value<double>(), 1000.0);
        }
        if (findNode(*mi, "name", "Z").valid())
        {
            EXPECT_EQ(mi->findChild("average").value<double>(), 3.0);
            EXPECT_EQ(mi->findChild("minimum").value<double>(), 3.0);
            EXPECT_EQ(mi->findChild("maximum").value<double>(), 3.0);
            EXPECT_EQ(mi->findChild("count").value<double>(), 1000.0);
        }
    }
}

TEST(Stats, enum)
{
    BOX3D bounds(1.0, 0.0, 0.0, 10.0, 100.0, 1000.0);
    Options ops;
    ops.add("bounds", bounds);
    ops.add("count", 10);
    ops.add("mode", "ramp");

    FauxReader reader;
    reader.setOptions(ops);

    Options filterOps;
    filterOps.add("dimensions", "X, Y, Z");
    filterOps.add("enumerate", "X");
    filterOps.add("count", "Y");

    StatsFilter filter;
    filter.setInput(reader);
    filter.setOptions(filterOps);

    PointTable table;
    filter.prepare(table);
    filter.execute(table);

    const stats::Summary& statsX = filter.getStats(Dimension::Id::X);
    const stats::Summary::EnumMap& values = statsX.values();
    EXPECT_EQ(values.size(), 10U);
    double d = 1.0;
    for (auto& v : values)
    {
        EXPECT_DOUBLE_EQ(d, v.first);
        d += 1.0;
    }

    const stats::Summary& statsY = filter.getStats(Dimension::Id::Y);
    const stats::Summary::EnumMap& yValues = statsY.values();
    d = 0.0;
    for (auto& v : yValues)
    {
        EXPECT_DOUBLE_EQ(d, v.first);
        EXPECT_EQ(1u, v.second);
        d += (100.0 / 9);
    }
}
<|endoftext|>


<commit_before>#include <opencp.hpp>
#include <fstream>
using namespace std;
using namespace cv;
using namespace cp;

static enum class DENOISE_METHOD
{
	BILATERAL,
	GUIDED,
	UNNORMALIZED_BF,

	NONLOCAL,
	JOINTNONLOCAL,
	NONLOCAL_L1,
	JOINTNONLOCAL_L1,
	PATCHBF,
	PATCHBF_L1,
	JOINTPATCHBF,
	JOINTPATCHBF_L1,
	REC_BF,
	BM3D,

	SIZE
};

string getDenoiseMethodName(DENOISE_METHOD method)
{
	string ret = "";
	switch (method)
	{
	case DENOISE_METHOD::BILATERAL:			ret = "BILATERAL"; break;
	case DENOISE_METHOD::GUIDED:			ret = "GUIDED"; break;
	case DENOISE_METHOD::UNNORMALIZED_BF:	ret = "UNNORMALIZED_BF"; break;
	case DENOISE_METHOD::NONLOCAL:			ret = "NONLOCAL"; break;
	case DENOISE_METHOD::NONLOCAL_L1:		ret = "NONLOCAL_L1"; break;
	case DENOISE_METHOD::PATCHBF:			ret = "PATCHBF"; break;
	case DENOISE_METHOD::PATCHBF_L1:		ret = "PATCHBF_L1"; break;
	case DENOISE_METHOD::JOINTNONLOCAL:		ret = "JOINTNONLOCAL"; break;
	case DENOISE_METHOD::JOINTNONLOCAL_L1:	ret = "JOINTNONLOCAL_L1"; break;
	case DENOISE_METHOD::JOINTPATCHBF:		ret = "JOINTPATCHBF"; break;
	case DENOISE_METHOD::JOINTPATCHBF_L1:	ret = "JOINTPATCHBF_L1"; break;
	case DENOISE_METHOD::REC_BF:			ret = "REC_BF"; break;
	case DENOISE_METHOD::BM3D:				ret = "BM3D"; break;
	default:
		break;
	}
	return ret;
}

void guiDenoiseTest(Mat& src)
{
	Mat dest, dest2;

	string wname = "denoise";
	namedWindow(wname);

	int a = 0; createTrackbar("a", wname, &a, 100);
	int type = 0; createTrackbar("type:8u/32f", wname, &type, 1);
	int color = 1; createTrackbar("color", wname, &color, 1);
	int sw = (int)DENOISE_METHOD::NONLOCAL; createTrackbar("switch", wname, &sw, (int)DENOISE_METHOD::SIZE - 1);
	int sigma_color10 = 850; createTrackbar("sigma_color", wname, &sigma_color10, 5000);
	int sigma_space10 = 100; createTrackbar("sigma_space", wname, &sigma_space10, 200);
	int r = 4; createTrackbar("r", wname, &r, 100);
	int powexp = 2; createTrackbar("powexp", wname, &powexp, 100);
	int powexp_space = 2; createTrackbar("powexp_space", wname, &powexp_space, 100);
	int tr = 1; createTrackbar("tr", wname, &tr, 20);
	int isSep = 1; createTrackbar("sep", wname, &isSep, 1);

	int noise_s10 = 200; createTrackbar("noise", wname, &noise_s10, 2550);
	int key = 0;
	Mat show;

	RecursiveBilateralFilter recbf(src.size());
	cp::ConsoleImage ci;
	cp::UpdateCheck uc_filter(sw, r, tr, isSep);
	cp::UpdateCheck uc_noise(noise_s10, type, color);
	Timer t("time", TIME_MSEC, false);
	Mat noise;
	Mat srcf; src.convertTo(srcf, CV_32F);
	bool isFourceUpdateNoise = false;
	Mat ref;
	while (key != 'q')
	{
		float sigma_color = sigma_color10 / 10.f;
		float sigma_space = sigma_space10 / 10.f;
		int d = 2 * r + 1;
		int td = 2 * tr + 1;

		const bool noiseUpdate = uc_noise.isUpdate(noise_s10, type, color);
		if (noiseUpdate || isFourceUpdateNoise)
		{
			if (color == 0) cvtColor(src, ref, COLOR_BGR2GRAY);
			else src.copyTo(ref);
			if (type == 1) ref.convertTo(ref, CV_32F);
			addNoise(ref, noise, noise_s10 / 10.0);
		}
		if (uc_filter.isUpdate(sw, r, tr, isSep) || key == 'r' || noiseUpdate)
		{
			t.clearStat();
		}

		DENOISE_METHOD method= DENOISE_METHOD(sw);
		t.start();
		switch (method)
		{
		case DENOISE_METHOD::BILATERAL:
			cv::bilateralFilter(noise, dest, d, sigma_color, sigma_space, BORDER_DEFAULT); break;
		case DENOISE_METHOD::GUIDED:
			cp::guidedImageFilter(noise, noise, dest, r, sigma_color * 10.f);break;
		case DENOISE_METHOD::UNNORMALIZED_BF:
			cp::unnormalizedBilateralFilterCenterBlur(noise, dest, r, sigma_color, sigma_space, 1, false); break;
			//cp::unnormalizedBilateralFilter(noise, dest, r, sigma_color, sigma_space, false); break;
		case DENOISE_METHOD::NONLOCAL:
			if(isSep) nonLocalMeansFilterSeparable(noise, dest, td, d, sigma_color, powexp);
			else nonLocalMeansFilter(noise, dest, td, d, sigma_color, powexp); break;
		case DENOISE_METHOD::JOINTNONLOCAL:
			if (isSep) jointNonLocalMeansFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 2);
			else jointNonLocalMeansFilter(noise, ref, dest, td, d, sigma_color, powexp, 2); break;
		case DENOISE_METHOD::NONLOCAL_L1:
			if (isSep) nonLocalMeansFilterSeparable(noise, dest, td, d, sigma_color, powexp, 1);
			else nonLocalMeansFilter(noise, dest, td, d, sigma_color, powexp, 1); break;
		case DENOISE_METHOD::JOINTNONLOCAL_L1:
			if (isSep) jointNonLocalMeansFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 1);
			else jointNonLocalMeansFilter(noise, ref, dest, td, d, sigma_color, powexp, 1); break;
		case DENOISE_METHOD::PATCHBF:
			if (isSep) patchBilateralFilterSeparable(noise, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space);
			else patchBilateralFilter(noise, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space); break;
		case DENOISE_METHOD::PATCHBF_L1:
			if (isSep) patchBilateralFilterSeparable(noise, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space);
			else patchBilateralFilter(noise, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space); break;
		case DENOISE_METHOD::JOINTPATCHBF:
			if (isSep) jointPatchBilateralFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space);
			else jointPatchBilateralFilter(noise, ref, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space); break;
		case DENOISE_METHOD::JOINTPATCHBF_L1:
			if (isSep) jointPatchBilateralFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space);
			else jointPatchBilateralFilter(noise, ref, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space); break;
		case DENOISE_METHOD::REC_BF:
			recbf(noise, dest, sigma_color, sigma_space); break;
		case DENOISE_METHOD::BM3D:
			xphoto::bm3dDenoising(noise, dest, sigma_color, 8, 16, 2500, 400, 16, 1, 2.f, 4, 1, cv::xphoto::HAAR); break;
		default:
			xphoto::dctDenoising(noise, dest, sigma_color, 16);
			break;
		}
		t.getpushLapTime();

		ci(getDenoiseMethodName(DENOISE_METHOD(sw)));
		if (isFourceUpdateNoise) ci("noise  %6.3f dB, update (swich 'n' key)", PSNR(ref, noise));
		else ci("noise  %6.3f dB, const (swich 'n' key)", PSNR(ref, noise));

		ci("filter %6.3f dB", PSNR(ref, dest));
		ci("time   %f ms %d", t.getLapTimeMedian(), t.getStatSize());
		if (key == 'p')ci.push();
		ci.show();

		cp::dissolveSlideBlend(noise, dest, dest);
		cp::alphaBlend(src, dest, a / 100.0, show);
		cp::imshowScale(wname, show);
		key = waitKey(1);
		if (key == 'n')isFourceUpdateNoise = isFourceUpdateNoise ? false : true;

	}
}
<commit_msg>Update guiDenoiseTest.cpp<commit_after>#include <opencp.hpp>
#include <fstream>
using namespace std;
using namespace cv;
using namespace cp;

static enum class DENOISE_METHOD
{
	BILATERAL,
	GUIDED,
	UNNORMALIZED_BF,

	NONLOCAL,
	JOINTNONLOCAL,
	NONLOCAL_L1,
	JOINTNONLOCAL_L1,
	PATCHBF,
	PATCHBF_L1,
	JOINTPATCHBF,
	JOINTPATCHBF_L1,
	REC_BF,
	BM3D,

	SIZE
};

string getDenoiseMethodName(DENOISE_METHOD method)
{
	string ret = "";
	switch (method)
	{
	case DENOISE_METHOD::BILATERAL:			ret = "BILATERAL"; break;
	case DENOISE_METHOD::GUIDED:			ret = "GUIDED"; break;
	case DENOISE_METHOD::UNNORMALIZED_BF:	ret = "UNNORMALIZED_BF"; break;
	case DENOISE_METHOD::NONLOCAL:			ret = "NONLOCAL"; break;
	case DENOISE_METHOD::NONLOCAL_L1:		ret = "NONLOCAL_L1"; break;
	case DENOISE_METHOD::PATCHBF:			ret = "PATCHBF"; break;
	case DENOISE_METHOD::PATCHBF_L1:		ret = "PATCHBF_L1"; break;
	case DENOISE_METHOD::JOINTNONLOCAL:		ret = "JOINTNONLOCAL"; break;
	case DENOISE_METHOD::JOINTNONLOCAL_L1:	ret = "JOINTNONLOCAL_L1"; break;
	case DENOISE_METHOD::JOINTPATCHBF:		ret = "JOINTPATCHBF"; break;
	case DENOISE_METHOD::JOINTPATCHBF_L1:	ret = "JOINTPATCHBF_L1"; break;
	case DENOISE_METHOD::REC_BF:			ret = "REC_BF"; break;
	case DENOISE_METHOD::BM3D:				ret = "BM3D"; break;
	default:
		break;
	}
	return ret;
}

void guiDenoiseTest(Mat& src)
{
	Mat dest, dest2;

	string wname = "denoise";
	namedWindow(wname);

	int a = 0; createTrackbar("a", wname, &a, 100);
	int type = 0; createTrackbar("type:8u/32f", wname, &type, 1);
	int color = 1; createTrackbar("color", wname, &color, 1);
	int sw = (int)DENOISE_METHOD::NONLOCAL; createTrackbar("switch", wname, &sw, (int)DENOISE_METHOD::SIZE - 1);
	int sigma_color10 = 850; createTrackbar("sigma_color", wname, &sigma_color10, 5000);
	int sigma_space10 = 100; createTrackbar("sigma_space", wname, &sigma_space10, 200);
	int r = 4; createTrackbar("r", wname, &r, 100);
	int powexp = 2; createTrackbar("powexp", wname, &powexp, 100);
	int powexp_space = 2; createTrackbar("powexp_space", wname, &powexp_space, 100);
	int tr = 1; createTrackbar("tr", wname, &tr, 20);
	int isSep = 1; createTrackbar("sep", wname, &isSep, 1);

	int noise_s10 = 200; createTrackbar("noise", wname, &noise_s10, 2550);
	int sigma_space2_ = 100; createTrackbar("sigma_space2", wname, &sigma_space2_, 200);
	int key = 0;
	Mat show;

	RecursiveBilateralFilter recbf(src.size());
	cp::ConsoleImage ci;
	cp::UpdateCheck uc_filter(sw, r, tr, isSep);
	cp::UpdateCheck uc_noise(noise_s10, type, color);
	Timer t("time", TIME_MSEC, false);
	Mat noise;
	Mat srcf; src.convertTo(srcf, CV_32F);
	bool isFourceUpdateNoise = false;
	Mat ref;
	while (key != 'q')
	{
		float sigma_color = sigma_color10 / 10.f;
		float sigma_space = sigma_space10 / 10.f;
		float sigma_space2 = sigma_space2_ / 10.f;
		int d = 2 * r + 1;
		int td = 2 * tr + 1;

		const bool noiseUpdate = uc_noise.isUpdate(noise_s10, type, color);
		if (noiseUpdate || isFourceUpdateNoise)
		{
			if (color == 0) cvtColor(src, ref, COLOR_BGR2GRAY);
			else src.copyTo(ref);
			if (type == 1) ref.convertTo(ref, CV_32F);
			addNoise(ref, noise, noise_s10 / 10.0);
		}
		if (uc_filter.isUpdate(sw, r, tr, isSep) || key == 'r' || noiseUpdate)
		{
			t.clearStat();
		}

		DENOISE_METHOD method= DENOISE_METHOD(sw);
		t.start();
		switch (method)
		{
		case DENOISE_METHOD::BILATERAL:
			cv::bilateralFilter(noise, dest, d, sigma_color, sigma_space, BORDER_DEFAULT); break;
		case DENOISE_METHOD::GUIDED:
			cp::guidedImageFilter(noise, noise, dest, r, sigma_color * 10.f);break;
		case DENOISE_METHOD::UNNORMALIZED_BF:
			cp::unnormalizedBilateralFilterCenterBlur(noise, dest, r, sigma_color, sigma_space, sigma_space2, false); break;
			//cp::unnormalizedBilateralFilter(noise, dest, r, sigma_color, sigma_space, false); break;
		case DENOISE_METHOD::NONLOCAL:
			if(isSep) nonLocalMeansFilterSeparable(noise, dest, td, d, sigma_color, powexp);
			else nonLocalMeansFilter(noise, dest, td, d, sigma_color, powexp); break;
		case DENOISE_METHOD::JOINTNONLOCAL:
			if (isSep) jointNonLocalMeansFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 2);
			else jointNonLocalMeansFilter(noise, ref, dest, td, d, sigma_color, powexp, 2); break;
		case DENOISE_METHOD::NONLOCAL_L1:
			if (isSep) nonLocalMeansFilterSeparable(noise, dest, td, d, sigma_color, powexp, 1);
			else nonLocalMeansFilter(noise, dest, td, d, sigma_color, powexp, 1); break;
		case DENOISE_METHOD::JOINTNONLOCAL_L1:
			if (isSep) jointNonLocalMeansFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 1);
			else jointNonLocalMeansFilter(noise, ref, dest, td, d, sigma_color, powexp, 1); break;
		case DENOISE_METHOD::PATCHBF:
			if (isSep) patchBilateralFilterSeparable(noise, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space);
			else patchBilateralFilter(noise, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space); break;
		case DENOISE_METHOD::PATCHBF_L1:
			if (isSep) patchBilateralFilterSeparable(noise, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space);
			else patchBilateralFilter(noise, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space); break;
		case DENOISE_METHOD::JOINTPATCHBF:
			if (isSep) jointPatchBilateralFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space);
			else jointPatchBilateralFilter(noise, ref, dest, td, d, sigma_color, powexp, 2, sigma_space, powexp_space); break;
		case DENOISE_METHOD::JOINTPATCHBF_L1:
			if (isSep) jointPatchBilateralFilterSeparable(noise, ref, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space);
			else jointPatchBilateralFilter(noise, ref, dest, td, d, sigma_color, powexp, 1, sigma_space, powexp_space); break;
		case DENOISE_METHOD::REC_BF:
			recbf(noise, dest, sigma_color, sigma_space); break;
		case DENOISE_METHOD::BM3D:
			xphoto::bm3dDenoising(noise, dest, sigma_color, 8, 16, 2500, 400, 16, 1, 2.f, 4, 1, cv::xphoto::HAAR); break;
		default:
			xphoto::dctDenoising(noise, dest, sigma_color, 16);
			break;
		}
		t.getpushLapTime();

		ci(getDenoiseMethodName(DENOISE_METHOD(sw)));
		if (isFourceUpdateNoise) ci("noise  %6.3f dB, update (swich 'n' key)", PSNR(ref, noise));
		else ci("noise  %6.3f dB, const (swich 'n' key)", PSNR(ref, noise));

		ci("filter %6.3f dB", PSNR(ref, dest));
		ci("time   %f ms %d", t.getLapTimeMedian(), t.getStatSize());
		if (key == 'p')ci.push();
		ci.show();

		cp::dissolveSlideBlend(noise, dest, dest);
		cp::alphaBlend(src, dest, a / 100.0, show);
		cp::imshowScale(wname, show);
		key = waitKey(1);
		if (key == 'n')isFourceUpdateNoise = isFourceUpdateNoise ? false : true;

	}
}
<|endoftext|>


<commit_before>#include "wm.hpp"
#include "output.hpp"
#include "view.hpp"
#include "debug.hpp"
#include "core.hpp"
#include "workspace-manager.hpp"

#include "../view/xdg-shell.hpp"
#include "../output/output-impl.hpp"
#include "signal-definitions.hpp"

void wayfire_exit::init(wayfire_config*)
{
    key = [](uint32_t key)
    {
        auto output_impl =
            static_cast<wf::output_impl_t*> (wf::get_core().get_active_output());
        if (output_impl->is_inhibited())
            return;

        wf::get_core().emit_signal("shutdown", nullptr);
        wl_display_terminate(wf::get_core().display);
    };

    output->add_key(new_static_option("<ctrl> <alt> KEY_BACKSPACE"), &key);
}

void wayfire_exit::fini()
{
    output->rem_binding(&key);
}

void wayfire_close::init(wayfire_config *config)
{
    grab_interface->capabilities = wf::CAPABILITY_GRAB_INPUT;
    auto key = config->get_section("core")
        ->get_option("close_top_view", "<super> KEY_Q | <alt> KEY_FN_F4");

    callback = [=] (wf_activator_source, uint32_t)
    {
        if (!output->activate_plugin(grab_interface))
            return;

        output->deactivate_plugin(grab_interface);
        auto view = output->get_active_view();
        if (view && view->role == wf::VIEW_ROLE_TOPLEVEL) view->close();
    };

    output->add_activator(key, &callback);
}

void wayfire_close::fini()
{
    output->rem_binding(&callback);
}

void wayfire_focus::init(wayfire_config *)
{
    grab_interface->name = "_wf_focus";
    grab_interface->capabilities = wf::CAPABILITY_MANAGE_DESKTOP;

    on_wm_focus_request = [=] (wf::signal_data_t *data) {
        auto ev = static_cast<wm_focus_request*> (data);
        check_focus_surface(ev->surface);
    };
    output->connect_signal("wm-focus-request", &on_wm_focus_request);

    on_button = [=] (uint32_t button, int x, int y) {
        this->check_focus_surface(wf::get_core().get_cursor_focus());
    };
    output->add_button(new_static_option("BTN_LEFT"), &on_button);

    on_touch = [=] (int x, int y) {
        this->check_focus_surface(wf::get_core().get_touch_focus());
    };
    output->add_touch(new_static_option(""), &on_touch);

    on_view_disappear = [=] (wf::signal_data_t *data) {
        set_last_focus(nullptr);
    };

    on_view_output_change = [=] (wf::signal_data_t *data)
    {
        if (get_signaled_output(data) != this->output)
            send_done(last_focus); // will also reset last_focus
    };
}

void wayfire_focus::check_focus_surface(wf::surface_interface_t* focus)
{
    /* Find the main view */
    auto main_surface = focus ? focus->get_main_surface() : nullptr;
    auto view = dynamic_cast<wf::view_interface_t*> (main_surface);

    /* Close popups from the lastly focused view */
    if (last_focus.get() != view)
        send_done(last_focus);

    if (!view || !view->is_mapped() || !view->get_keyboard_focus_surface()
        || !output->activate_plugin(grab_interface))
    {
        return;
    }

    output->deactivate_plugin(grab_interface);

    /* Raise the base view. Modal views will be raised to the top by
     * wayfire_handle_focus_parent */
    while (view->parent)
        view = view->parent.get();

    view->get_output()->focus_view(view->self(), true);
    set_last_focus(view->self());
}

void wayfire_focus::send_done(wayfire_view view)
{
    if (!last_focus)
        return;

    /* Do not send done while running */
    auto surfaces = view->enumerate_surfaces();
    for (auto& child : surfaces)
    {
        auto popup =
            dynamic_cast<wayfire_xdg_popup<wlr_xdg_popup>*> (child.surface);
        auto popup_v6 =
            dynamic_cast<wayfire_xdg_popup<wlr_xdg_popup_v6>*> (child.surface);

        if (popup)
            popup->send_done();
        if (popup_v6)
            popup->send_done();
    }

    set_last_focus(nullptr);
}

void wayfire_focus::set_last_focus(wayfire_view view)
{
    if (last_focus)
    {
        last_focus->disconnect_signal("disappeared", &on_view_disappear);
        last_focus->disconnect_signal("set-output", &on_view_output_change);
    }

    last_focus = view;
    if (last_focus)
    {
        last_focus->connect_signal("disappeared", &on_view_disappear);
        last_focus->connect_signal("set-output", &on_view_output_change);
    }
}

void wayfire_focus::fini()
{
    output->rem_binding(&on_button);
    output->rem_binding(&on_touch);
    output->disconnect_signal("wm-focus-request", &on_wm_focus_request);

    set_last_focus(nullptr);
}

/* Enumerate view's in @root's view tree, from top to bottom */
static std::vector<wayfire_view> enumerate_views(wayfire_view root)
{
    if (!root->is_mapped())
        return {};

    std::vector<wayfire_view> views;
    for (auto& child : root->children)
    {
        auto child_views = enumerate_views(child);
        views.insert(views.end(), child_views.begin(), child_views.end());
    }

    views.push_back(root);
    return views;
}

void wayfire_handle_focus_parent::init(wayfire_config*)
{
    focus_event = [&] (wf::signal_data_t *data) mutable
    {
        auto view = get_signaled_view(data);
        if (!view)
            return;

        auto root = view;
        while(root->parent)
            root = root->parent;

        auto views = enumerate_views(root);
        /* Already focused the view, no need to restack */
        if (views.front() == view)
            return;

        log_info("frontmost is %s want %s", views.front()->get_title().c_str(), view->get_title().c_str());

        /* Delay focus a bit because we do not want to mess with other output
         * focus handlers. However, we need to be careful, because the view
         * might get unmapped while waiting. */
        pending_focus_unmap = [=] (wf::signal_data_t*) {
            this->idle_focus.disconnect();
            view->disconnect_signal("unmap", &pending_focus_unmap);
        };
        view->connect_signal("unmap", &pending_focus_unmap);

        idle_focus.run_once([view, this] () {
            auto views = enumerate_views(view);
            for (auto& child : views)
                output->workspace->restack_above(child, view);

            /* Prevent getting called again */
            output->disconnect_signal("focus-view", &focus_event);
            output->focus_view(views.front());
            output->connect_signal("focus-view", &focus_event);

            view->disconnect_signal("unmap", &pending_focus_unmap);
        });
    };

    output->connect_signal("focus-view", &focus_event);
}

void wayfire_handle_focus_parent::fini()
{
    output->disconnect_signal("focus-view", &focus_event);
}
<commit_msg>wm: do not go to unmapped parents when searching for parent view<commit_after>#include "wm.hpp"
#include "output.hpp"
#include "view.hpp"
#include "debug.hpp"
#include "core.hpp"
#include "workspace-manager.hpp"

#include "../view/xdg-shell.hpp"
#include "../output/output-impl.hpp"
#include "signal-definitions.hpp"

void wayfire_exit::init(wayfire_config*)
{
    key = [](uint32_t key)
    {
        auto output_impl =
            static_cast<wf::output_impl_t*> (wf::get_core().get_active_output());
        if (output_impl->is_inhibited())
            return;

        wf::get_core().emit_signal("shutdown", nullptr);
        wl_display_terminate(wf::get_core().display);
    };

    output->add_key(new_static_option("<ctrl> <alt> KEY_BACKSPACE"), &key);
}

void wayfire_exit::fini()
{
    output->rem_binding(&key);
}

void wayfire_close::init(wayfire_config *config)
{
    grab_interface->capabilities = wf::CAPABILITY_GRAB_INPUT;
    auto key = config->get_section("core")
        ->get_option("close_top_view", "<super> KEY_Q | <alt> KEY_FN_F4");

    callback = [=] (wf_activator_source, uint32_t)
    {
        if (!output->activate_plugin(grab_interface))
            return;

        output->deactivate_plugin(grab_interface);
        auto view = output->get_active_view();
        if (view && view->role == wf::VIEW_ROLE_TOPLEVEL) view->close();
    };

    output->add_activator(key, &callback);
}

void wayfire_close::fini()
{
    output->rem_binding(&callback);
}

void wayfire_focus::init(wayfire_config *)
{
    grab_interface->name = "_wf_focus";
    grab_interface->capabilities = wf::CAPABILITY_MANAGE_DESKTOP;

    on_wm_focus_request = [=] (wf::signal_data_t *data) {
        auto ev = static_cast<wm_focus_request*> (data);
        check_focus_surface(ev->surface);
    };
    output->connect_signal("wm-focus-request", &on_wm_focus_request);

    on_button = [=] (uint32_t button, int x, int y) {
        this->check_focus_surface(wf::get_core().get_cursor_focus());
    };
    output->add_button(new_static_option("BTN_LEFT"), &on_button);

    on_touch = [=] (int x, int y) {
        this->check_focus_surface(wf::get_core().get_touch_focus());
    };
    output->add_touch(new_static_option(""), &on_touch);

    on_view_disappear = [=] (wf::signal_data_t *data) {
        set_last_focus(nullptr);
    };

    on_view_output_change = [=] (wf::signal_data_t *data)
    {
        if (get_signaled_output(data) != this->output)
            send_done(last_focus); // will also reset last_focus
    };
}

void wayfire_focus::check_focus_surface(wf::surface_interface_t* focus)
{
    /* Find the main view */
    auto main_surface = focus ? focus->get_main_surface() : nullptr;
    auto view = dynamic_cast<wf::view_interface_t*> (main_surface);

    /* Close popups from the lastly focused view */
    if (last_focus.get() != view)
        send_done(last_focus);

    if (!view || !view->is_mapped() || !view->get_keyboard_focus_surface()
        || !output->activate_plugin(grab_interface))
    {
        return;
    }

    output->deactivate_plugin(grab_interface);

    /* Raise the base view. Modal views will be raised to the top by
     * wayfire_handle_focus_parent */
    while (view->parent)
        view = view->parent.get();

    view->get_output()->focus_view(view->self(), true);
    set_last_focus(view->self());
}

void wayfire_focus::send_done(wayfire_view view)
{
    if (!last_focus)
        return;

    /* Do not send done while running */
    auto surfaces = view->enumerate_surfaces();
    for (auto& child : surfaces)
    {
        auto popup =
            dynamic_cast<wayfire_xdg_popup<wlr_xdg_popup>*> (child.surface);
        auto popup_v6 =
            dynamic_cast<wayfire_xdg_popup<wlr_xdg_popup_v6>*> (child.surface);

        if (popup)
            popup->send_done();
        if (popup_v6)
            popup->send_done();
    }

    set_last_focus(nullptr);
}

void wayfire_focus::set_last_focus(wayfire_view view)
{
    if (last_focus)
    {
        last_focus->disconnect_signal("disappeared", &on_view_disappear);
        last_focus->disconnect_signal("set-output", &on_view_output_change);
    }

    last_focus = view;
    if (last_focus)
    {
        last_focus->connect_signal("disappeared", &on_view_disappear);
        last_focus->connect_signal("set-output", &on_view_output_change);
    }
}

void wayfire_focus::fini()
{
    output->rem_binding(&on_button);
    output->rem_binding(&on_touch);
    output->disconnect_signal("wm-focus-request", &on_wm_focus_request);

    set_last_focus(nullptr);
}

/* Enumerate view's in @root's view tree, from top to bottom */
static std::vector<wayfire_view> enumerate_views(wayfire_view root)
{
    if (!root->is_mapped())
        return {};

    std::vector<wayfire_view> views;
    for (auto& child : root->children)
    {
        auto child_views = enumerate_views(child);
        views.insert(views.end(), child_views.begin(), child_views.end());
    }

    views.push_back(root);
    return views;
}

void wayfire_handle_focus_parent::init(wayfire_config*)
{
    focus_event = [&] (wf::signal_data_t *data) mutable
    {
        auto view = get_signaled_view(data);
        if (!view)
            return;

        auto root = view;
        while(root->parent && root->parent->is_mapped())
            root = root->parent;

        auto views = enumerate_views(root);
        /* Already focused the view, no need to restack */
        if (views.front() == view)
            return;

        log_info("frontmost is %s want %s", views.front()->get_title().c_str(), view->get_title().c_str());

        /* Delay focus a bit because we do not want to mess with other output
         * focus handlers. However, we need to be careful, because the view
         * might get unmapped while waiting. */
        pending_focus_unmap = [=] (wf::signal_data_t*) {
            this->idle_focus.disconnect();
            view->disconnect_signal("unmap", &pending_focus_unmap);
        };
        view->connect_signal("unmap", &pending_focus_unmap);

        idle_focus.run_once([view, this] () {
            auto views = enumerate_views(view);
            for (auto& child : views)
                output->workspace->restack_above(child, view);

            /* Prevent getting called again */
            output->disconnect_signal("focus-view", &focus_event);
            output->focus_view(views.front());
            output->connect_signal("focus-view", &focus_event);

            view->disconnect_signal("unmap", &pending_focus_unmap);
        });
    };

    output->connect_signal("focus-view", &focus_event);
}

void wayfire_handle_focus_parent::fini()
{
    output->disconnect_signal("focus-view", &focus_event);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: localfilelayer.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: jb $ $Date: 2002-11-28 09:05:16 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_
#include "localfilelayer.hxx"
#endif // CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_

#ifndef CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_
#include "localoutputstream.hxx"
#endif // CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_

#ifndef _CONFIGMGR_OSLSTREAM_HXX_
#include "oslstream.hxx"
#endif // _CONFIGMGR_OSLSTREAM_HXX_

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif // _RTL_USTRBUF_HXX_

#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
#include <com/sun/star/io/XActiveDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif

namespace configmgr { namespace localbe {

//==============================================================================

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

BasicLocalFileLayer::BasicLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aComponentFile)
: mFactory(xFactory)
, mFileUrl(aComponentFile)
{
    static const rtl::OUString kXMLLayerParser(RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.backend.xml.LayerParser")) ;

    mLayerReader = uno::Reference<backend::XLayer>::query(
                                    mFactory->createInstance(kXMLLayerParser)) ;

}
//------------------------------------------------------------------------------

SimpleLocalFileLayer::SimpleLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aComponentFile)
: BasicLocalFileLayer(xFactory,aComponentFile)
{
}
//------------------------------------------------------------------------------

SimpleLocalFileLayer::SimpleLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aBaseDir,
        const rtl::OUString& aComponent)
: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
{
}
//------------------------------------------------------------------------------

LocalFileLayer::LocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aBaseDir,
        const rtl::OUString& aComponent,
        const rtl::OUString& aResDir)
: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
{
    static const rtl::OUString kXMLLayerWriter(RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.backend.xml.LayerWriter")) ;

    mLayerWriter = uno::Reference<backend::XLayerHandler>::query(
                                    mFactory->createInstance(kXMLLayerWriter)) ;
    if (aResDir.getLength() != 0) {
        fillSubLayerList(aResDir, aComponent) ;
    }
}
//------------------------------------------------------------------------------

BasicLocalFileLayer::~BasicLocalFileLayer() {}
//------------------------------------------------------------------------------

SimpleLocalFileLayer::~SimpleLocalFileLayer() {}
//------------------------------------------------------------------------------

LocalFileLayer::~LocalFileLayer() {}
//------------------------------------------------------------------------------

void SAL_CALL SimpleLocalFileLayer::readData(
        const uno::Reference<backend::XLayerHandler>& xHandler)
    throw (lang::WrappedTargetException, uno::RuntimeException)
{
    BasicLocalFileLayer::readData(this,xHandler, mFileUrl) ;
}
//------------------------------------------------------------------------------

void SAL_CALL LocalFileLayer::readData(
        const uno::Reference<backend::XLayerHandler>& xHandler)
    throw (lang::WrappedTargetException, uno::RuntimeException)
{
    BasicLocalFileLayer::readData(static_cast<backend::XCompositeLayer*>(this),xHandler, mFileUrl) ;
}
//------------------------------------------------------------------------------

void SAL_CALL LocalFileLayer::replaceWith(
        const uno::Reference<backend::XLayer>& aNewLayer)
    throw (lang::WrappedTargetException, uno::RuntimeException)
{
    uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY);
    if (!xAS.is())
    {
        rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("LocalFileLayer - Missing interface: XActiveDataSource not supported by LayerWriter"));

        throw uno::RuntimeException(sMsg,*this);
    }

    LocalOutputStream * pStream = new LocalOutputStream(mFileUrl);
    uno::Reference<io::XOutputStream> xStream( pStream );

    xAS->setOutputStream(xStream);

    aNewLayer->readData(mLayerWriter) ;

    pStream->finishOutput();

    // clear the output stream
    xStream.clear();
    xAS->setOutputStream(xStream);
}
//------------------------------------------------------------------------------

uno::Reference<backend::XLayerHandler> LocalFileLayer::createLayerWriter(void)
{
    OSL_ENSURE(false, "Creating a LayerWriter is not supported. This function should be removed");

    /* or else we need a wrapper for a kXMLLayerWriter,
        that properly calls LocalOutputStream::finishOutput at the end
    */

    rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("LocalFileLayer - Deprecated functionality: createLayerWriter is not supported any more"));

    throw uno::RuntimeException(sMsg,*this);

    return NULL;
}
//------------------------------------------------------------------------------

void SAL_CALL LocalFileLayer::readSubLayerData(
        const uno::Reference<backend::XLayerHandler>& xHandler,
        const rtl::OUString& aSubLayerId)
    throw (lang::IllegalArgumentException, lang::WrappedTargetException,
            uno::RuntimeException)
{
    sal_Int32 i ;

    for (i = 0 ; i < mSubLayers.getLength() ; ++ i) {
        if (mSubLayers [i].equals(aSubLayerId)) { break ; }
    }
    if (i == mSubLayers.getLength()) {
        rtl::OUStringBuffer message ;

        message.appendAscii("Sublayer Id '").append(aSubLayerId) ;
        message.appendAscii("' is unknown") ;
        throw lang::IllegalArgumentException(message.makeStringAndClear(),
                                             *this, 1) ;
    }
    BasicLocalFileLayer::readData(static_cast<backend::XCompositeLayer*>(this),xHandler, mSubLayerFiles [i]) ;
}
//------------------------------------------------------------------------------

rtl::OUString LocalFileLayer::getTimestamp()
    throw (uno::RuntimeException)
{
    rtl::OUString sStamp = getTimestamp(mFileUrl);
#if 0
    for (SubLayerFiles::const_iterator it = mSubLayerFiles.begin();
         it != mSubLayerFiles.end();
         ++it)
    {
        rtl::OUString sSublayerTime = getTimestamp(*it);
        if (sStamp < sSublayerTime)
            sStamp = sSublayerTime;
    }
#endif
    return sStamp;
}
//------------------------------------------------------------------------------

rtl::OUString LocalFileLayer::getTimestamp(const rtl::OUString& aFileUrl) {
    TimeValue timevalue = FileHelper::getModifyTime(aFileUrl) ;
    oslDateTime fileStamp ;
    rtl::OUString retCode ;

    if (osl_getDateTimeFromTimeValue(&timevalue, &fileStamp)) {
        sal_Char asciiStamp [16] ;

        sprintf(asciiStamp, "%04d%02d%02d%02d%02d%02dZ",
                fileStamp.Year, fileStamp.Month, fileStamp.Day,
                fileStamp.Hours, fileStamp.Minutes, fileStamp.Seconds) ;
        retCode = rtl::OUString::createFromAscii(asciiStamp) ;
    }
    return retCode ;
}
//------------------------------------------------------------------------------

void LocalFileLayer::fillSubLayerList(const rtl::OUString& aResDir,
                                      const rtl::OUString& aComponent) {
    // Extract the directory where the file is located
    osl::Directory directory(aResDir) ;

    if (directory.open() != osl_File_E_None) { return ; }
    osl::DirectoryItem item ;
    osl::FileStatus status(osl_FileStatus_Mask_Type |
                           osl_FileStatus_Mask_FileURL) ;
    SubLayerFiles subLayerDirs ;

    while (directory.getNextItem(item) == osl_File_E_None) {
        if (item.getFileStatus(status) == osl_File_E_None) {
            if (status.getFileType() == osl::FileStatus::Directory) {
                // Let's check whether the sublayer exists for the
                // particular component.
                rtl::OUString subLayerFile(status.getFileURL() + aComponent) ;

                if (FileHelper::fileExists(subLayerFile)) {
                    mSubLayerFiles.push_back(subLayerFile) ;
                    subLayerDirs.push_back(
                            FileHelper::getFileName(status.getFileURL())) ;
                }
            }
        }
    }
    if (subLayerDirs.size() > 0) {
        mSubLayers.realloc(subLayerDirs.size()) ;
        SubLayerFiles::const_iterator subLayer ;
        sal_Int32 i = 0 ;

        for (subLayer = subLayerDirs.begin() ;
                subLayer != subLayerDirs.end() ; ++ subLayer) {
            mSubLayers [i ++] = *subLayer ;
        }
    }
}
//------------------------------------------------------------------------------

void BasicLocalFileLayer::readData(
        backend::XLayer * pContext,
        const uno::Reference<backend::XLayerHandler>& xHandler,
        const rtl::OUString& aFileUrl)
    throw (lang::WrappedTargetException, uno::RuntimeException)
{
    if (!xHandler.is())
    {
        // throw IllegalArgumentException ??
        return;
    }

    osl::File blobFile(aFileUrl) ;
    osl::File::RC errorCode = blobFile.open(OpenFlag_Read) ;

    switch (errorCode)
    {
    case osl::File::E_None: // got it
        {
            uno::Reference<io::XActiveDataSink> xAS(mLayerReader, uno::UNO_QUERY);
            if (!xAS.is())
            {
                rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("LocalFileLayer - Missing interface: XActiveDataSink not supported by LayerReader"));

                throw uno::RuntimeException(sMsg,pContext);
            }

            uno::Reference<io::XInputStream> xStream( new OSLInputStreamWrapper(blobFile) );

            xAS->setInputStream(xStream);

            mLayerReader->readData(xHandler) ;
        }
        break;

    case osl::File::E_NOENT: // no layer => empty layer
        xHandler->startLayer();
        xHandler->endLayer();
        break;

    default:
        {
            rtl::OUStringBuffer sMsg;
            sMsg.appendAscii("Cannot open output file \"");
            sMsg.append(aFileUrl);
            sMsg.appendAscii("\" : ");
            sMsg.append(FileHelper::createOSLErrorString(errorCode));

            io::IOException ioe(sMsg.makeStringAndClear(),pContext);

            sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(ioe.Message);
            throw lang::WrappedTargetException(sMsg.makeStringAndClear(),pContext,uno::makeAny(ioe));
        }
        break;

    }
}
//------------------------------------------------------------------------------

} } // configmgr.localbe

<commit_msg>INTEGRATION: CWS configapi01 (1.7.26); FILE MERGED 2003/04/11 13:42:06 jb 1.7.26.2: #1077715# Repair broken exception specifications 2003/04/10 15:47:22 jb 1.7.26.1: #1077715# Move configuration backend API out of drafts; adjust to API changes<commit_after>/*************************************************************************
 *
 *  $RCSfile: localfilelayer.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2003-04-17 13:29:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_
#include "localfilelayer.hxx"
#endif // CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_

#ifndef CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_
#include "localoutputstream.hxx"
#endif // CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_

#ifndef _CONFIGMGR_OSLSTREAM_HXX_
#include "oslstream.hxx"
#endif // _CONFIGMGR_OSLSTREAM_HXX_

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif // _RTL_USTRBUF_HXX_

#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
#include <com/sun/star/io/XActiveDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif
#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_BACKENDACCESSEXCEPTION_HPP_
#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
#endif

namespace configmgr { namespace localbe {

//==============================================================================

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

BasicLocalFileLayer::BasicLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aComponentFile)
: mFactory(xFactory)
, mFileUrl(aComponentFile)
{
    static const rtl::OUString kXMLLayerParser(RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.backend.xml.LayerParser")) ;

    mLayerReader = uno::Reference<backend::XLayer>::query(
                                    mFactory->createInstance(kXMLLayerParser)) ;

}
//------------------------------------------------------------------------------

SimpleLocalFileLayer::SimpleLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aComponentFile)
: BasicLocalFileLayer(xFactory,aComponentFile)
{
}
//------------------------------------------------------------------------------

SimpleLocalFileLayer::SimpleLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aBaseDir,
        const rtl::OUString& aComponent)
: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
{
}
//------------------------------------------------------------------------------

FlatLocalFileLayer::FlatLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aBaseDir,
        const rtl::OUString& aComponent)
: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
, mLayerWriter( createLayerWriter() )
{
}
//------------------------------------------------------------------------------

CompositeLocalFileLayer::CompositeLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aBaseDir,
        const rtl::OUString& aComponent,
        const SubLayerFiles& aSublayerDirectories)
: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
, mLayerWriter( createLayerWriter() )
{
    fillSubLayerLists(aSublayerDirectories, aComponent) ;
}
//------------------------------------------------------------------------------

BasicLocalFileLayer::~BasicLocalFileLayer() {}
//------------------------------------------------------------------------------

SimpleLocalFileLayer::~SimpleLocalFileLayer() {}
//------------------------------------------------------------------------------

FlatLocalFileLayer::~FlatLocalFileLayer() {}
//------------------------------------------------------------------------------

CompositeLocalFileLayer::~CompositeLocalFileLayer() {}
//------------------------------------------------------------------------------

uno::Reference<backend::XLayerHandler> BasicLocalFileLayer::createLayerWriter()
{
    static const rtl::OUString kXMLLayerWriter(RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.backend.xml.LayerWriter")) ;

    uno::Reference< uno::XInterface > xWriter = mFactory->createInstance(kXMLLayerWriter);

    return uno::Reference<backend::XLayerHandler>(xWriter,uno::UNO_REF_QUERY_THROW) ;
}
//------------------------------------------------------------------------------

static inline void readEmptyLayer(const uno::Reference<backend::XLayerHandler>& xHandler)
{
    OSL_ASSERT(xHandler.is());
    xHandler->startLayer();
    xHandler->endLayer();
}
//------------------------------------------------------------------------------

void BasicLocalFileLayer::readData(
        backend::XLayer * pContext,
        const uno::Reference<backend::XLayerHandler>& xHandler,
        const rtl::OUString& aFileUrl)
    throw ( backend::MalformedDataException,
            lang::NullPointerException,
            lang::WrappedTargetException,
            uno::RuntimeException)
{
    if (!xHandler.is())
    {
        rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
            "LocalFileLayer - Cannot readData: Handler is NULL."));

        throw  lang::NullPointerException(sMessage,pContext);
    }

    osl::File blobFile(aFileUrl) ;
    osl::File::RC errorCode = blobFile.open(OpenFlag_Read) ;

    switch (errorCode)
    {
    case osl::File::E_None: // got it
        {
            uno::Reference<io::XActiveDataSink> xAS(mLayerReader, uno::UNO_QUERY_THROW);

            uno::Reference<io::XInputStream> xStream( new OSLInputStreamWrapper(blobFile) );

            xAS->setInputStream(xStream);

            mLayerReader->readData(xHandler) ;
        }
        break;

    case osl::File::E_NOENT: // no layer => empty layer
        readEmptyLayer(xHandler);
        break;

    default:
        {
            rtl::OUStringBuffer sMsg;
            sMsg.appendAscii("LocalFile Layer: Cannot open input file \"");
            sMsg.append(aFileUrl);
            sMsg.appendAscii("\" : ");
            sMsg.append(FileHelper::createOSLErrorString(errorCode));

            io::IOException ioe(sMsg.makeStringAndClear(),pContext);

            sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(ioe.Message);
            throw backend::BackendAccessException(sMsg.makeStringAndClear(),pContext,uno::makeAny(ioe));
        }
        break;

    }
}
//------------------------------------------------------------------------------

void SAL_CALL SimpleLocalFileLayer::readData(
        const uno::Reference<backend::XLayerHandler>& xHandler)
    throw ( backend::MalformedDataException,
            lang::NullPointerException,
            lang::WrappedTargetException,
            uno::RuntimeException)
{
    BasicLocalFileLayer::readData(this,xHandler, getFileUrl()) ;
}
//------------------------------------------------------------------------------

void SAL_CALL FlatLocalFileLayer::readData(
        const uno::Reference<backend::XLayerHandler>& xHandler)
    throw ( backend::MalformedDataException,
            lang::NullPointerException,
            lang::WrappedTargetException,
            uno::RuntimeException)
{
    BasicLocalFileLayer::readData(this,xHandler, getFileUrl() ) ;
}
//------------------------------------------------------------------------------

void SAL_CALL CompositeLocalFileLayer::readData(
        const uno::Reference<backend::XLayerHandler>& xHandler)
    throw ( backend::MalformedDataException,
            lang::NullPointerException,
            lang::WrappedTargetException,
            uno::RuntimeException)
{
    BasicLocalFileLayer::readData(static_cast<backend::XCompositeLayer*>(this),xHandler, getFileUrl() ) ;
}
//------------------------------------------------------------------------------

void SAL_CALL CompositeLocalFileLayer::readSubLayerData(
        const uno::Reference<backend::XLayerHandler>& xHandler,
        const rtl::OUString& aSubLayerId)
    throw ( backend::MalformedDataException,
            lang::IllegalArgumentException,
            lang::NullPointerException,
            lang::WrappedTargetException,
            uno::RuntimeException)
{
    sal_Int32 i ;

    for (i = 0 ; i < mSubLayers.getLength() ; ++ i) {
        if (mSubLayers [i].equals(aSubLayerId)) { break ; }
    }
    if (i == mSubLayers.getLength())
    {
        rtl::OUStringBuffer message ;

        message.appendAscii("Sublayer Id '").append(aSubLayerId) ;
        message.appendAscii("' is unknown") ;
        throw lang::IllegalArgumentException(message.makeStringAndClear(),
                                             *this, 2) ;
    }
    if (mSubLayerFiles[i].getLength() != 0)
        BasicLocalFileLayer::readData(static_cast<backend::XCompositeLayer*>(this),xHandler, mSubLayerFiles [i]) ;
    else
        readEmptyLayer(xHandler);
}
//------------------------------------------------------------------------------

void SAL_CALL FlatLocalFileLayer::replaceWith(
        const uno::Reference<backend::XLayer>& aNewLayer)
    throw ( backend::MalformedDataException,
            lang::NullPointerException,
            lang::WrappedTargetException,
            uno::RuntimeException)
{
    if (!aNewLayer.is())
    {
        rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
            "LocalFileLayer - Cannot replaceWith: Replacement layer is NULL."));

        throw  lang::NullPointerException(sMessage,*this);
    }
    OSL_ENSURE( !uno::Reference<backend::XCompositeLayer>::query(aNewLayer).is(),
                "Warning: correct updates with composite layers are not implemented");

    uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY_THROW);

    LocalOutputStream * pStream = new LocalOutputStream(getFileUrl());
    uno::Reference<io::XOutputStream> xStream( pStream );

    xAS->setOutputStream(xStream);

    aNewLayer->readData(mLayerWriter) ;

    pStream->finishOutput();

    // clear the output stream
    xStream.clear();
    xAS->setOutputStream(xStream);
}
//------------------------------------------------------------------------------

void SAL_CALL CompositeLocalFileLayer::replaceWith(
        const uno::Reference<backend::XLayer>& aNewLayer)
    throw (backend::MalformedDataException, lang::NullPointerException,
            lang::WrappedTargetException, uno::RuntimeException)
{
    if (!aNewLayer.is())
    {
        rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
            "LocalFileLayer - Cannot replaceWith: Replacement layer is NULL."));

        throw  lang::NullPointerException(sMessage,*this);
    }
    OSL_ENSURE( !uno::Reference<backend::XCompositeLayer>::query(aNewLayer).is(),
                "Warning: correct updates with composite layers are not implemented");

    uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY_THROW);

    LocalOutputStream * pStream = new LocalOutputStream(getFileUrl());
    uno::Reference<io::XOutputStream> xStream( pStream );

    xAS->setOutputStream(xStream);

    aNewLayer->readData(mLayerWriter) ;

    pStream->finishOutput();

    // clear the output stream
    xStream.clear();
    xAS->setOutputStream(xStream);
}
//------------------------------------------------------------------------------

rtl::OUString BasicLocalFileLayer::getTimestamp(const rtl::OUString& aFileUrl)
{
    TimeValue timevalue = FileHelper::getModifyTime(aFileUrl) ;
    oslDateTime fileStamp ;
    rtl::OUString retCode ;

    if (osl_getDateTimeFromTimeValue(&timevalue, &fileStamp)) {
        sal_Char asciiStamp [20] ;

        sprintf(asciiStamp, "%04d%02d%02d%02d%02d%02dZ",
                fileStamp.Year, fileStamp.Month, fileStamp.Day,
                fileStamp.Hours, fileStamp.Minutes, fileStamp.Seconds) ;
        retCode = rtl::OUString::createFromAscii(asciiStamp) ;
    }
    return retCode ;
}
//------------------------------------------------------------------------------

rtl::OUString FlatLocalFileLayer::getTimestamp()
    throw (uno::RuntimeException)
{
    rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());

    return sStamp;
}
//------------------------------------------------------------------------------

rtl::OUString CompositeLocalFileLayer::getTimestamp()
    throw (uno::RuntimeException)
{
    rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
#if 0 // thus far composite layers are only manipulated via the main layer
    for (SubLayerFiles::const_iterator it = mSubLayerFiles.begin();
         it != mSubLayerFiles.end();
         ++it)
    {
        rtl::OUString sSublayerTime = BasicLocalFileLayer::getTimestamp(*it);
        if (sStamp < sSublayerTime)
            sStamp = sSublayerTime;
    }
#endif
    return sStamp;
}
//------------------------------------------------------------------------------

void CompositeLocalFileLayer::fillSubLayerLists( const SubLayerFiles& aSublayerDirectories,
                                                const rtl::OUString& aComponent)
{
    SubLayerFiles::size_type const nSublayerCount = aSublayerDirectories.size();
    mSubLayers.realloc(nSublayerCount);
    mSubLayerFiles.resize(nSublayerCount);

    for (SubLayerFiles::size_type i = 0; i < nSublayerCount; ++i)
    {
        mSubLayers[i] = FileHelper::getFileName(aSublayerDirectories[i]);

        // Let's check whether the sublayer exists for the
        // particular component.
        rtl::OUString subLayerFile(aSublayerDirectories[i] + aComponent) ;
        if (FileHelper::fileExists(subLayerFile))
        {
            mSubLayerFiles[i] =  subLayerFile;
        }
        else
            OSL_ASSERT(mSubLayerFiles[i].getLength() == 0);
    }
}
//------------------------------------------------------------------------------

static bool findSubLayers(const rtl::OUString& aResDir,
                          CompositeLocalFileLayer::SubLayerFiles& aSublayerDirectories)
{
    if (aResDir.getLength() == 0) return false;

    // Extract the directory where the file is located
    osl::Directory directory(aResDir) ;
    if (directory.open() != osl_File_E_None) return false;

    osl::DirectoryItem item ;
    osl::FileStatus status(osl_FileStatus_Mask_Type |
                           osl_FileStatus_Mask_FileURL) ;

    while (directory.getNextItem(item) == osl_File_E_None)
    {
        if (item.getFileStatus(status) == osl_File_E_None)
        {
            if (status.getFileType() == osl::FileStatus::Directory)
            {
                aSublayerDirectories.push_back(status.getFileURL()) ;
            }
        }
    }
    return !aSublayerDirectories.empty();
}
//------------------------------------------------------------------------------

uno::Reference<backend::XUpdatableLayer> createLocalFileLayer(
        const uno::Reference<lang::XMultiServiceFactory>& xFactory,
        const rtl::OUString& aBaseDir,
        const rtl::OUString& aComponent,
        const rtl::OUString& aResDir)
{
    uno::Reference<backend::XUpdatableLayer> xResult;

    CompositeLocalFileLayer::SubLayerFiles aSublayers;
    if (findSubLayers(aResDir,aSublayers))
    {
        xResult.set( new CompositeLocalFileLayer(xFactory,aBaseDir,aComponent,aSublayers) );
    }
    else
    {
        xResult.set( new FlatLocalFileLayer(xFactory,aBaseDir,aComponent) );
    }
    return xResult;
}
//------------------------------------------------------------------------------

} } // configmgr.localbe

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: TSkipDeletedSet.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: oj $ $Date: 2002-07-05 07:03:02 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef CONNECTIVITY_SKIPDELETEDSSET_HXX
#define CONNECTIVITY_SKIPDELETEDSSET_HXX

#ifndef CONNECTIVITY_TRESULTSETHELPER_HXX
#include "TResultSetHelper.hxx"
#endif

#ifndef _RTL_ALLOC_H_
#include <rtl/alloc.h>
#endif
#include <map>
#include <vector>

namespace connectivity
{
    /**
        the class OSkipDeletedSet supports a general method to skip deleted rows
    */
    class OSkipDeletedSet
    {
        typedef ::std::map<sal_Int32,sal_Int32> TInt2IntMap;
        TInt2IntMap                             m_aBookmarks;         // map from postion to logical position
        ::std::vector<TInt2IntMap::iterator>    m_aBookmarksPositions;// vector of iterators to position map, the order is the logical position
        IResultSetHelper*                       m_pHelper;            // used for moving in the resultset

        sal_Bool    moveAbsolute(sal_Int32 _nOffset,sal_Bool _bRetrieveData);
    public:
        OSkipDeletedSet(IResultSetHelper* _pHelper);

        inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
            { return ::rtl_allocateMemory( nSize ); }
        inline static void * SAL_CALL operator new( size_t nSize,void* _pHint ) SAL_THROW( () )
            { return _pHint; }
        inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
            { ::rtl_freeMemory( pMem ); }
        inline static void SAL_CALL operator delete( void * pMem,void* _pHint ) SAL_THROW( () )
            {  }

        /**
            skipDeleted moves the resultset to the position defined by the parameters
            it garantees that the row isn't deleted
                @param
                    IResultSetHelper::Movement  _eCursorPosition        in which direction the resultset should be moved
                    sal_Int32                   _nOffset                the position relativ to the movement
                    sal_Bool                    _bRetrieveData          is true when the current row should be filled which data
                @return
                    true when the movement was successful otherwise false
        */
        sal_Bool    skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData);
        /**
            clear the map and the vector used in this class
        */
        void        clear();
        /**
            getMappedPosition returns the mapped position of a logical position
            @param
                sal_Int32 _nPos the logical position

            @return the mapped position
        */
        sal_Int32   getMappedPosition(sal_Int32 _nPos) const;
        /**
            insertNewPosition adds a new position to the map
            @param
                sal_Int32 _nPos the logical position
        */
        void        insertNewPosition(sal_Int32 _nPos);
        /**
            deletePosition deletes this position from the map and decrement all following positions
            @param
                sal_Int32 _nPos the logical position
        */
        void        deletePosition(sal_Int32 _nPos);
        /**
            getLastPosition returns the last position
            @return the last position
        */
        sal_Int32   getLastPosition() const { return m_aBookmarksPositions.size(); }
    };
}
#endif // CONNECTIVITY_SKIPDELETEDSSET_HXX

<commit_msg>INTEGRATION: CWS oj07 (1.3.110); FILE MERGED 2003/08/21 15:32:38 oj 1.3.110.1: #i17363# some refactoring and defense programming<commit_after>/*************************************************************************
 *
 *  $RCSfile: TSkipDeletedSet.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-03-02 12:35:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef CONNECTIVITY_SKIPDELETEDSSET_HXX
#define CONNECTIVITY_SKIPDELETEDSSET_HXX

#ifndef CONNECTIVITY_TRESULTSETHELPER_HXX
#include "TResultSetHelper.hxx"
#endif

#ifndef _RTL_ALLOC_H_
#include <rtl/alloc.h>
#endif
#include <map>
#include <vector>

namespace connectivity
{
    /**
        the class OSkipDeletedSet supports a general method to skip deleted rows
    */
    class OSkipDeletedSet
    {
        typedef ::std::map<sal_Int32,sal_Int32> TInt2IntMap;
        TInt2IntMap                             m_aBookmarks;         // map from postion to logical position
        ::std::vector<TInt2IntMap::iterator>    m_aBookmarksPositions;// vector of iterators to position map, the order is the logical position
        IResultSetHelper*                       m_pHelper;            // used for moving in the resultset

        sal_Bool    moveAbsolute(sal_Int32 _nOffset,sal_Bool _bRetrieveData);
    public:
        OSkipDeletedSet(IResultSetHelper* _pHelper);
        ~OSkipDeletedSet();

        inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
            { return ::rtl_allocateMemory( nSize ); }
        inline static void * SAL_CALL operator new( size_t nSize,void* _pHint ) SAL_THROW( () )
            { return _pHint; }
        inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
            { ::rtl_freeMemory( pMem ); }
        inline static void SAL_CALL operator delete( void * pMem,void* _pHint ) SAL_THROW( () )
            {  }

        /**
            skipDeleted moves the resultset to the position defined by the parameters
            it garantees that the row isn't deleted
                @param
                    IResultSetHelper::Movement  _eCursorPosition        in which direction the resultset should be moved
                    sal_Int32                   _nOffset                the position relativ to the movement
                    sal_Bool                    _bRetrieveData          is true when the current row should be filled which data
                @return
                    true when the movement was successful otherwise false
        */
        sal_Bool    skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData);
        /**
            clear the map and the vector used in this class
        */
        void        clear();
        /**
            getMappedPosition returns the mapped position of a logical position
            @param
                sal_Int32 _nPos the logical position

            @return the mapped position
        */
        sal_Int32   getMappedPosition(sal_Int32 _nPos) const;
        /**
            insertNewPosition adds a new position to the map
            @param
                sal_Int32 _nPos the logical position
        */
        void        insertNewPosition(sal_Int32 _nPos);
        /**
            deletePosition deletes this position from the map and decrement all following positions
            @param
                sal_Int32 _nPos the logical position
        */
        void        deletePosition(sal_Int32 _nPos);
        /**
            getLastPosition returns the last position
            @return the last position
        */
        sal_Int32   getLastPosition() const { return m_aBookmarksPositions.size(); }
    };
}
#endif // CONNECTIVITY_SKIPDELETEDSSET_HXX

<|endoftext|>


<commit_before>#include "df_time.h"

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

static double g_tickInterval = -1.0;
static double g_timeShift = 0.0;

inline double GetLowLevelTime();

static void InitialiseHighResTime()
{
    LARGE_INTEGER count;
    QueryPerformanceFrequency(&count);
    g_tickInterval = 1.0 / (double)count.QuadPart;
	g_timeShift = GetLowLevelTime();
}

inline double GetLowLevelTime()
{
    if (g_tickInterval < 0.0)
        InitialiseHighResTime();

    LARGE_INTEGER count;
    QueryPerformanceCounter(&count);
    return (double)count.QuadPart * g_tickInterval;
}

NOINLINE double GetRealTime()
{
	double timeNow = GetLowLevelTime();
    timeNow -= g_timeShift;
    return timeNow;
}

void SleepMillisec(int milliseconds)
{
	Sleep(milliseconds);
}
<commit_msg>Make the df_time module work on Linux.<commit_after>#include "df_time.h"

static double g_timeShift = 0.0;

#if _MSC_VER

// Windows specific code ******************************************************

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

static double g_tickInterval = -1.0;

inline double GetLowLevelTime()
{
    LARGE_INTEGER count;
    QueryPerformanceCounter(&count);
    return (double)count.QuadPart * g_tickInterval;
}

static void InitialiseHighResTime()
{
    LARGE_INTEGER count;
    QueryPerformanceFrequency(&count);
    g_tickInterval = 1.0 / (double)count.QuadPart;
	g_timeShift = GetLowLevelTime();
}

void SleepMillisec(int milliseconds)
{
	Sleep(milliseconds);
}

#else

// Linux specific code ******************************************************

// POSIX headers
#include <stdint.h>
#include <sys/time.h>
#include <unistd.h>

static double GetLowLevelTime()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
}

static void InitialiseHighResTime()
{
	g_timeShift = GetLowLevelTime();
}

void SleepMillisec(int milliseconds)
{
	usleep(milliseconds * 1000);
}

#endif

// Common code ******************************************************

NOINLINE double GetRealTime()
{
    if (g_timeShift <= 0.0) {
        InitialiseHighResTime();
    }

    double timeNow = GetLowLevelTime();
    timeNow -= g_timeShift;
    return timeNow;
}
<|endoftext|>