<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbOGRDataSourceWrapper.h"
#include "otbOGRFeatureWrapper.h"
#include "otbStatisticsXMLFileWriter.h"
#include "itkVariableLengthVector.h"

#include <time.h>

namespace otb
{
namespace Wrapper
{
class ComputeOGRLayersFeaturesStatistics : public Application
{
public:
  typedef ComputeOGRLayersFeaturesStatistics Self;
  typedef Application Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro(Self)
;

  itkTypeMacro(ComputeOGRLayersFeaturesStatistics, otb::Application)
;

private:
  void DoInit() ITK_OVERRIDE
  {
    SetName("ComputeOGRLayersFeaturesStatistics");
    SetDescription("Compute statistics of the features in a set of OGR Layers");

    SetDocName("ComputeOGRLayersFeaturesStatistics");
    SetDocLongDescription("Compute statistics (mean and standard deviation) of the features in a set of OGR Layers, and write them in an XML file. This XML file can then be used by the training application.");
    SetDocLimitations("Experimental. For now only shapefiles are supported.");
    SetDocAuthors("David Youssefi during internship at CNES");
    SetDocSeeAlso("OGRLayerClassifier,TrainOGRLayersClassifier");
    AddDocTag(Tags::Segmentation);

    AddParameter(ParameterType_InputVectorData, "inshp", "Name of the input shapefile");
    SetParameterDescription("inshp","Name of the input shapefile");

    AddParameter(ParameterType_OutputFilename, "outstats", "XML file containing mean and variance of each feature.");
    SetParameterDescription("outstats", "XML file containing mean and variance of each feature.");

    AddParameter(ParameterType_ListView,  "feat", "List of features to consider for statistics.");
    SetParameterDescription("feat","List of features to consider for statistics.");

    // Doc example parameter settings
    SetDocExampleParameterValue("inshp", "vectorData.shp");
    SetDocExampleParameterValue("outstats", "results.xml");
    SetDocExampleParameterValue("feat", "perimeter");

  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    if ( HasValue("inshp") )
      {
      std::string shapefile = GetParameterString("inshp");

       otb::ogr::DataSource::Pointer ogrDS;
       otb::ogr::Layer layer(ITK_NULLPTR, false);

       OGRSpatialReference oSRS("");
       std::vector<std::string> options;

       ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read);
       std::string layername = itksys::SystemTools::GetFilenameName(shapefile);
       layername = layername.substr(0,layername.size()-4);
       layer = ogrDS->GetLayer(0);

       otb::ogr::Feature feature = layer.ogr().GetNextFeature();
       ClearChoices("feat");
       for(int iField=0; iField<feature.ogr().GetFieldCount(); iField++)
         {
           std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
           key = item;
           key.erase(std::remove(key.begin(), key.end(), ' '), key.end());
           std::transform(key.begin(), key.end(), key.begin(), tolower);
           key="feat."+key;
           AddChoice(key,item);
         }
      }
  }

  void DoExecute() ITK_OVERRIDE
  {
      clock_t tic = clock();

      std::string shapefile = GetParameterString("inshp");
      std::string XMLfile = GetParameterString("outstats");

      otb::ogr::DataSource::Pointer source = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read);

      otb::ogr::Layer layer = source->GetLayer(0);
      bool goesOn = true;
      otb::ogr::Feature feature = layer.ogr().GetNextFeature();

      typedef double ValueType;
      typedef itk::VariableLengthVector<ValueType> MeasurementType;
      std::vector<MeasurementType> featValue;

      const std::vector<int>::size_type nbFeatures = GetSelectedItems("feat").size();

      if(feature.addr())
       while(goesOn)
         {
           MeasurementType mv; mv.SetSize(nbFeatures);

           for(unsigned int idx=0; idx < nbFeatures; ++idx)
             mv[idx] = feature.ogr().GetFieldAsDouble(GetSelectedItems("feat")[idx]);

           featValue.push_back(mv);
           feature = layer.ogr().GetNextFeature();
           goesOn = feature.addr() != ITK_NULLPTR;
         }

      MeasurementType mean; mean.SetSize(nbFeatures);
      MeasurementType stddev; stddev.SetSize(nbFeatures);

      for(unsigned int featIt=0; featIt<nbFeatures; featIt++){
       double sum = 0.0; for(unsigned add=0; add<featValue.size(); add++)  sum += featValue[add][featIt];
       mean[featIt] =  sum / featValue.size();
       double accum = 0.0; for(unsigned add=0; add<featValue.size(); add++) accum += (featValue[add][featIt] - mean[featIt]) * (featValue[add][featIt] - mean[featIt]);
       stddev[featIt] = sqrt(accum / (featValue.size()-1)); }

      typedef otb::StatisticsXMLFileWriter<MeasurementType> StatisticsWriter;
      StatisticsWriter::Pointer writer = StatisticsWriter::New();
      writer->SetFileName(XMLfile);
      writer->AddInput("mean", mean);
      writer->AddInput("stddev", stddev);
      writer->Update();

      clock_t toc = clock();
      otbAppLogINFO( "Elapsed: "<< ((double)(toc - tic) / CLOCKS_PER_SEC)<<" seconds.");
  }

};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeOGRLayersFeaturesStatistics)

<commit_msg>DOC: change description of parameter name in ComputeOGRLayersFeaturesStatistics<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbOGRDataSourceWrapper.h"
#include "otbOGRFeatureWrapper.h"
#include "otbStatisticsXMLFileWriter.h"
#include "itkVariableLengthVector.h"

#include <time.h>

namespace otb
{
namespace Wrapper
{
class ComputeOGRLayersFeaturesStatistics : public Application
{
public:
  typedef ComputeOGRLayersFeaturesStatistics Self;
  typedef Application Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro(Self)
;

  itkTypeMacro(ComputeOGRLayersFeaturesStatistics, otb::Application)
;

private:
  void DoInit() ITK_OVERRIDE
  {
    SetName("ComputeOGRLayersFeaturesStatistics");
    SetDescription("Compute statistics of the features in a set of OGR Layers");

    SetDocName("ComputeOGRLayersFeaturesStatistics");
    SetDocLongDescription("Compute statistics (mean and standard deviation) of the features in a set of OGR Layers, and write them in an XML file. This XML file can then be used by the training application.");
    SetDocLimitations("Experimental. For now only shapefiles are supported.");
    SetDocAuthors("David Youssefi during internship at CNES");
    SetDocSeeAlso("OGRLayerClassifier,TrainOGRLayersClassifier");
    AddDocTag(Tags::Segmentation);

    AddParameter(ParameterType_InputVectorData, "inshp", "Vector Data");
    SetParameterDescription("inshp","Name of the input shapefile");

    AddParameter(ParameterType_OutputFilename, "outstats", "Output XML file");
    SetParameterDescription("outstats", "XML file containing mean and variance of each feature.");

    AddParameter(ParameterType_ListView,  "feat", "Feature");
    SetParameterDescription("feat","List of features to consider for statistics.");

    // Doc example parameter settings
    SetDocExampleParameterValue("inshp", "vectorData.shp");
    SetDocExampleParameterValue("outstats", "results.xml");
    SetDocExampleParameterValue("feat", "perimeter");

  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
    if ( HasValue("inshp") )
      {
      std::string shapefile = GetParameterString("inshp");

       otb::ogr::DataSource::Pointer ogrDS;
       otb::ogr::Layer layer(ITK_NULLPTR, false);

       OGRSpatialReference oSRS("");
       std::vector<std::string> options;

       ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read);
       std::string layername = itksys::SystemTools::GetFilenameName(shapefile);
       layername = layername.substr(0,layername.size()-4);
       layer = ogrDS->GetLayer(0);

       otb::ogr::Feature feature = layer.ogr().GetNextFeature();
       ClearChoices("feat");
       for(int iField=0; iField<feature.ogr().GetFieldCount(); iField++)
         {
           std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
           key = item;
           key.erase(std::remove(key.begin(), key.end(), ' '), key.end());
           std::transform(key.begin(), key.end(), key.begin(), tolower);
           key="feat."+key;
           AddChoice(key,item);
         }
      }
  }

  void DoExecute() ITK_OVERRIDE
  {
      clock_t tic = clock();

      std::string shapefile = GetParameterString("inshp");
      std::string XMLfile = GetParameterString("outstats");

      otb::ogr::DataSource::Pointer source = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read);

      otb::ogr::Layer layer = source->GetLayer(0);
      bool goesOn = true;
      otb::ogr::Feature feature = layer.ogr().GetNextFeature();

      typedef double ValueType;
      typedef itk::VariableLengthVector<ValueType> MeasurementType;
      std::vector<MeasurementType> featValue;

      const std::vector<int>::size_type nbFeatures = GetSelectedItems("feat").size();

      if(feature.addr())
       while(goesOn)
         {
           MeasurementType mv; mv.SetSize(nbFeatures);

           for(unsigned int idx=0; idx < nbFeatures; ++idx)
             mv[idx] = feature.ogr().GetFieldAsDouble(GetSelectedItems("feat")[idx]);

           featValue.push_back(mv);
           feature = layer.ogr().GetNextFeature();
           goesOn = feature.addr() != ITK_NULLPTR;
         }

      MeasurementType mean; mean.SetSize(nbFeatures);
      MeasurementType stddev; stddev.SetSize(nbFeatures);

      for(unsigned int featIt=0; featIt<nbFeatures; featIt++){
       double sum = 0.0; for(unsigned add=0; add<featValue.size(); add++)  sum += featValue[add][featIt];
       mean[featIt] =  sum / featValue.size();
       double accum = 0.0; for(unsigned add=0; add<featValue.size(); add++) accum += (featValue[add][featIt] - mean[featIt]) * (featValue[add][featIt] - mean[featIt]);
       stddev[featIt] = sqrt(accum / (featValue.size()-1)); }

      typedef otb::StatisticsXMLFileWriter<MeasurementType> StatisticsWriter;
      StatisticsWriter::Pointer writer = StatisticsWriter::New();
      writer->SetFileName(XMLfile);
      writer->AddInput("mean", mean);
      writer->AddInput("stddev", stddev);
      writer->Update();

      clock_t toc = clock();
      otbAppLogINFO( "Elapsed: "<< ((double)(toc - tic) / CLOCKS_PER_SEC)<<" seconds.");
  }

};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeOGRLayersFeaturesStatistics)

<|endoftext|>


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

#ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX
#define SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX

#include "ViewShell.hxx"
#include "SlideSorterViewShell.hxx"
#include "glob.hxx"
#ifndef _SFX_SHELL_HXX
#include <sfx2/shell.hxx>
#endif
#ifndef _VIEWFAC_HXX
#include <sfx2/viewfac.hxx>
#endif

class ScrollBarBox;
class TabBar;
class Window;

namespace sd { namespace slidesorter { namespace model {
class SlideSorterModel;
} } }

namespace sd { namespace slidesorter { namespace view {
class SlideSorterView;
} } }

namespace sd { namespace slidesorter { namespace controller {
class Listener;
class SlideSorterController;
class SlotManager;
} } }

namespace sd { namespace slidesorter {

class SlideSorterViewShell
    : public ViewShell
{
    friend class controller::SlotManager;
public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SD_IF_SDSLIDESORTERVIEWSHELL);

    enum TabBarEntry
    {
        TBE_SWITCH = 0,
        TBE_SLIDES = 1,
        TBE_MASTER_PAGES = 2
    };

    static SfxShell* CreateInstance (
        sal_Int32 nId,
        SfxShell* pParent,
        void* pUserData,
        ViewShellBase& rBase);

    SlideSorterViewShell (
        SfxViewFrame* pFrame,
        ViewShellBase& rViewShellBase,
        ::Window* pParentWindow,
        FrameView* pFrameView);

    virtual ~SlideSorterViewShell (void);

    /** Late initialization that has to be called after a new instance has
        completed its construction.
    */
    virtual void Init (void);

    /** Return a slide sorter that is currently displayed in one of the
        panes that belong to the given ViewShellBase object.
        When there is only one slide sorter visible then that one is
        returned.  When two (or more) are visible then the one in the center
        pane is returned.  When no slidesorter is visible then NULL is
        returned.
    */
    static SlideSorterViewShell* GetSlideSorter (ViewShellBase& rBase);

    virtual void GetFocus (void);
    virtual void LoseFocus (void);
    virtual SdPage* GetActualPage (void);

    /// inherited from sd::ViewShell
    virtual SdPage* getCurrentPage() const;

    void ExecCtrl (SfxRequest& rRequest);
    virtual void GetCtrlState (SfxItemSet &rSet);
    virtual void FuSupport (SfxRequest& rRequest);
    virtual void FuTemporary (SfxRequest& rRequest);
    virtual void GetStatusBarState (SfxItemSet& rSet);
    virtual void FuPermanent (SfxRequest& rRequest);
    void GetAttrState (SfxItemSet& rSet);
    void ExecStatusBar (SfxRequest& rRequest);
    virtual void Command (const CommandEvent& rEvent, ::sd::Window* pWindow);
    virtual void GetMenuState (SfxItemSet &rSet);

    virtual void ReadFrameViewData (FrameView* pView);
    virtual void WriteFrameViewData (void);

    /** The UI features are used for selective display of tool bars
        depending on whether the slide sorter is the main view or not.
        @param nFeature
            Valid values are defined (and used) in the implementation file.
    */
    virtual BOOL HasUIFeature (ULONG nFeature);

    /** Set the zoom factor.  The given value is clipped against an upper
        bound.
        @param nZoom
            An integer percent value, i.e. nZoom/100 is the actual zoom
            factor.
        */
    virtual void SetZoom (long int nZoom);
    virtual void SetZoomRect (const Rectangle& rZoomRect);

    /** This is a callback method used by the active window to delegate its
        Paint() call to.  This view shell itself delegates it to the view.
    */
    virtual void Paint(const Rectangle& rRect, ::sd::Window* pWin);

    /** Place and size the controls and windows.  You may want to call this
        method when something has changed that for instance affects the
        visibility state of the scroll bars.
    */
    virtual void ArrangeGUIElements (void);

    /** Return the control of the vertical scroll bar.
    */
    ScrollBar* GetVerticalScrollBar (void) const;

    /** Return the control of the horizontal scroll bar.
    */
    ScrollBar* GetHorizontalScrollBar (void) const;

    /** Return the scroll bar filler that paints the little square that is
        enclosed by the two scroll bars.
    */
    ScrollBarBox* GetScrollBarFiller (void) const;

    /** Set the tab bar to the given mode.
        @param eEntry
            When TBE_SWITCH is given, then switch between the two tabs.
    */
    TabBarEntry SwitchTabBar (TabBarEntry eEntry);

    controller::SlideSorterController& GetSlideSorterController (void);

    //===== Drag and Drop =====================================================

    virtual void StartDrag (
        const Point& rDragPt,
        ::Window* pWindow );
    virtual void DragFinished (
        sal_Int8 nDropAction);
    virtual sal_Int8 AcceptDrop (
        const AcceptDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND );
    virtual sal_Int8 ExecuteDrop (
        const ExecuteDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND);

    /** Return the selected pages by putting them into the given container.
        The container does not have to be empty.  It is not cleared.
    */
    void GetSelectedPages (::std::vector<SdPage*>& pPageContainer);

    /** Add a listener that is called when the selection of the slide sorter
        changes.
        @param rListener
            When this method is called multiple times for the same listener
            the second and all following calls are ignored.  Each listener
            is added only once.
    */
    void AddSelectionChangeListener (const Link& rListener);

    /** Remove a listener that was called when the selection of the slide
        sorter changes.
        @param rListener
            It is save to pass a listener that was not added are has been
            removed previously.  Such calls are ignored.
    */
    void RemoveSelectionChangeListener (const Link& rListener);

    virtual DrawController* GetController (void);

    /** Create an accessible object representing the specified window.
        @param pWindow
            The returned object makes the document displayed in this window
            accessible.
        @return
            Returns an <type>AccessibleSlideSorterView</type> object.
   */
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible>
        CreateAccessibleDocumentView (::sd::Window* pWindow);

protected:
    ::std::auto_ptr<controller::SlideSorterController> mpSlideSorterController;
    ::std::auto_ptr<model::SlideSorterModel> mpSlideSorterModel;
    ::std::auto_ptr<view::SlideSorterView> mpSlideSorterView;

    virtual SvBorder GetBorder (bool bOuterResize);

    /** This virtual method makes it possible to create a specialization of
        the slide sorter view shell that works with its own implementation
        of model, view, and controller.  The default implementation simply
        calls the CreateModel(), CreateView(), and CreateController()
        methods in this order.
    */
    virtual void CreateModelViewController (void);

    /** Create the model for the view shell.  When called from the default
        implementation of CreateModelViewController() then neither view nor
        controller do exist.  Test their pointers when in doubt.
    */
    virtual model::SlideSorterModel* CreateModel (void);

    /** Create the view for the view shell.  When called from the default
        implementation of CreateModelViewController() then the model but not
        the controller does exist.  Test their pointers when in doubt.
    */
    virtual view::SlideSorterView* CreateView (void);

    /** Create the controller for the view shell.  When called from the default
        implementation of CreateModelViewController() then both the view and
        the controller do exist.  Test their pointers when in doubt.
    */
    virtual controller::SlideSorterController* CreateController (void);

    /** This method is overloaded to handle a missing tool bar correctly.
        This is the case when the slide sorter is not the main view shell.
    */
    virtual SfxUndoManager* ImpGetUndoManager (void) const;

private:
    ::std::auto_ptr<TabBar> mpTabBar;

    /** Set this flag to <TRUE/> to force a layout before the next paint.
    */
    bool mbLayoutPending;

    /** Create the controls for the slide sorter.  This are the tab bar
       for switching the edit mode, the scroll bar, and the actual
       slide sorter view window.
       This method is usually called exactly one time from the
       constructor.
    */
    void SetupControls (::Window* pParentWindow);

    /** This method is usually called exactly one time from the
        constructor.
    */
    void SetupListeners (void);

    /** Release the listeners that have been installed in SetupListeners().
    */
    void ReleaseListeners (void);

    /** This method overwrites the one from our base class:  We do our own
        scroll bar and the base class call is thus unnecessary.  It simply
        calls UpdateScrollBars(false).
    */
    virtual void UpdateScrollBars (void);
};

} } // end of namespace ::sd::slidesorter

#endif
<commit_msg>INTEGRATION: CWS viewswitch (1.8.62); FILE MERGED 2005/11/29 14:21:41 af 1.8.62.2: #i57552# Added CreateSubController() method. 2005/11/17 14:49:39 af 1.8.62.1: #i57551# Removed HasUIFeature() method.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlideSorterViewShell.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2006-03-21 17:27:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX
#define SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX

#include "ViewShell.hxx"
#include "SlideSorterViewShell.hxx"
#include "glob.hxx"
#ifndef _SFX_SHELL_HXX
#include <sfx2/shell.hxx>
#endif
#ifndef _VIEWFAC_HXX
#include <sfx2/viewfac.hxx>
#endif

class ScrollBarBox;
class TabBar;
class Window;

namespace sd { namespace slidesorter { namespace model {
class SlideSorterModel;
} } }

namespace sd { namespace slidesorter { namespace view {
class SlideSorterView;
} } }

namespace sd { namespace slidesorter { namespace controller {
class Listener;
class SlideSorterController;
class SlotManager;
} } }

namespace sd { namespace slidesorter {

class SlideSorterViewShell
    : public ViewShell
{
    friend class controller::SlotManager;
public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SD_IF_SDSLIDESORTERVIEWSHELL);

    enum TabBarEntry
    {
        TBE_SWITCH = 0,
        TBE_SLIDES = 1,
        TBE_MASTER_PAGES = 2
    };

    static SfxShell* CreateInstance (
        sal_Int32 nId,
        SfxShell* pParent,
        void* pUserData,
        ViewShellBase& rBase);

    SlideSorterViewShell (
        SfxViewFrame* pFrame,
        ViewShellBase& rViewShellBase,
        ::Window* pParentWindow,
        FrameView* pFrameView);

    virtual ~SlideSorterViewShell (void);

    /** Late initialization that has to be called after a new instance has
        completed its construction.
    */
    virtual void Init (bool bIsMainViewShell);

    /** Return a slide sorter that is currently displayed in one of the
        panes that belong to the given ViewShellBase object.
        When there is only one slide sorter visible then that one is
        returned.  When two (or more) are visible then the one in the center
        pane is returned.  When no slidesorter is visible then NULL is
        returned.
    */
    static SlideSorterViewShell* GetSlideSorter (ViewShellBase& rBase);

    virtual void GetFocus (void);
    virtual void LoseFocus (void);
    virtual SdPage* GetActualPage (void);

    /// inherited from sd::ViewShell
    virtual SdPage* getCurrentPage() const;

    void ExecCtrl (SfxRequest& rRequest);
    virtual void GetCtrlState (SfxItemSet &rSet);
    virtual void FuSupport (SfxRequest& rRequest);
    virtual void FuTemporary (SfxRequest& rRequest);
    virtual void GetStatusBarState (SfxItemSet& rSet);
    virtual void FuPermanent (SfxRequest& rRequest);
    void GetAttrState (SfxItemSet& rSet);
    void ExecStatusBar (SfxRequest& rRequest);
    virtual void Command (const CommandEvent& rEvent, ::sd::Window* pWindow);
    virtual void GetMenuState (SfxItemSet &rSet);

    virtual void ReadFrameViewData (FrameView* pView);
    virtual void WriteFrameViewData (void);

    /** Set the zoom factor.  The given value is clipped against an upper
        bound.
        @param nZoom
            An integer percent value, i.e. nZoom/100 is the actual zoom
            factor.
        */
    virtual void SetZoom (long int nZoom);
    virtual void SetZoomRect (const Rectangle& rZoomRect);

    /** This is a callback method used by the active window to delegate its
        Paint() call to.  This view shell itself delegates it to the view.
    */
    virtual void Paint(const Rectangle& rRect, ::sd::Window* pWin);

    /** Place and size the controls and windows.  You may want to call this
        method when something has changed that for instance affects the
        visibility state of the scroll bars.
    */
    virtual void ArrangeGUIElements (void);

    /** Return the control of the vertical scroll bar.
    */
    ScrollBar* GetVerticalScrollBar (void) const;

    /** Return the control of the horizontal scroll bar.
    */
    ScrollBar* GetHorizontalScrollBar (void) const;

    /** Return the scroll bar filler that paints the little square that is
        enclosed by the two scroll bars.
    */
    ScrollBarBox* GetScrollBarFiller (void) const;

    /** Set the tab bar to the given mode.
        @param eEntry
            When TBE_SWITCH is given, then switch between the two tabs.
    */
    TabBarEntry SwitchTabBar (TabBarEntry eEntry);

    controller::SlideSorterController& GetSlideSorterController (void);

    //===== Drag and Drop =====================================================

    virtual void StartDrag (
        const Point& rDragPt,
        ::Window* pWindow );
    virtual void DragFinished (
        sal_Int8 nDropAction);
    virtual sal_Int8 AcceptDrop (
        const AcceptDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND );
    virtual sal_Int8 ExecuteDrop (
        const ExecuteDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND);

    /** Return the selected pages by putting them into the given container.
        The container does not have to be empty.  It is not cleared.
    */
    void GetSelectedPages (::std::vector<SdPage*>& pPageContainer);

    /** Add a listener that is called when the selection of the slide sorter
        changes.
        @param rListener
            When this method is called multiple times for the same listener
            the second and all following calls are ignored.  Each listener
            is added only once.
    */
    void AddSelectionChangeListener (const Link& rListener);

    /** Remove a listener that was called when the selection of the slide
        sorter changes.
        @param rListener
            It is save to pass a listener that was not added are has been
            removed previously.  Such calls are ignored.
    */
    void RemoveSelectionChangeListener (const Link& rListener);

    virtual ::std::auto_ptr<DrawSubController> CreateSubController (void);

    /** Create an accessible object representing the specified window.
        @param pWindow
            The returned object makes the document displayed in this window
            accessible.
        @return
            Returns an <type>AccessibleSlideSorterView</type> object.
   */
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible>
        CreateAccessibleDocumentView (::sd::Window* pWindow);

protected:
    ::std::auto_ptr<controller::SlideSorterController> mpSlideSorterController;
    ::std::auto_ptr<model::SlideSorterModel> mpSlideSorterModel;
    ::std::auto_ptr<view::SlideSorterView> mpSlideSorterView;

    virtual SvBorder GetBorder (bool bOuterResize);

    /** This virtual method makes it possible to create a specialization of
        the slide sorter view shell that works with its own implementation
        of model, view, and controller.  The default implementation simply
        calls the CreateModel(), CreateView(), and CreateController()
        methods in this order.
    */
    virtual void CreateModelViewController (void);

    /** Create the model for the view shell.  When called from the default
        implementation of CreateModelViewController() then neither view nor
        controller do exist.  Test their pointers when in doubt.
    */
    virtual model::SlideSorterModel* CreateModel (void);

    /** Create the view for the view shell.  When called from the default
        implementation of CreateModelViewController() then the model but not
        the controller does exist.  Test their pointers when in doubt.
    */
    virtual view::SlideSorterView* CreateView (void);

    /** Create the controller for the view shell.  When called from the default
        implementation of CreateModelViewController() then both the view and
        the controller do exist.  Test their pointers when in doubt.
    */
    virtual controller::SlideSorterController* CreateController (void);

    /** This method is overloaded to handle a missing tool bar correctly.
        This is the case when the slide sorter is not the main view shell.
    */
    virtual SfxUndoManager* ImpGetUndoManager (void) const;

private:
    ::std::auto_ptr<TabBar> mpTabBar;

    /** Set this flag to <TRUE/> to force a layout before the next paint.
    */
    bool mbLayoutPending;

    /** Create the controls for the slide sorter.  This are the tab bar
       for switching the edit mode, the scroll bar, and the actual
       slide sorter view window.
       This method is usually called exactly one time from the
       constructor.
    */
    void SetupControls (::Window* pParentWindow);

    /** This method is usually called exactly one time from the
        constructor.
    */
    void SetupListeners (void);

    /** Release the listeners that have been installed in SetupListeners().
    */
    void ReleaseListeners (void);

    /** This method overwrites the one from our base class:  We do our own
        scroll bar and the base class call is thus unnecessary.  It simply
        calls UpdateScrollBars(false).
    */
    virtual void UpdateScrollBars (void);
};

} } // end of namespace ::sd::slidesorter

#endif
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/texture/texture.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>

//////////////////////////////////////////////////////////////////////////////

using namespace com::sun::star;

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
    namespace primitive2d
    {
        void FillGradientPrimitive2D::generateMatricesAndColors(
            std::vector< basegfx::B2DHomMatrix >& rMatrices,
            std::vector< basegfx::BColor >& rColors) const
        {
            rMatrices.clear();
            rColors.clear();

            // make sure steps is not too high/low
            const basegfx::BColor aStart(getFillGradient().getStartColor());
            const basegfx::BColor aEnd(getFillGradient().getEndColor());
            const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
            sal_uInt32 nSteps(getFillGradient().getSteps());

            if(nSteps == 0)
            {
                nSteps = nMaxSteps;
            }

            if(nSteps < 2)
            {
                nSteps = 2;
            }

            if(nSteps > nMaxSteps)
            {
                nSteps = nMaxSteps;
            }

            switch(getFillGradient().getStyle())
            {
                case attribute::GRADIENTSTYLE_LINEAR:
                {
                    texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_AXIAL:
                {
                    texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_RADIAL:
                {
                    texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_ELLIPTICAL:
                {
                    texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_SQUARE:
                {
                    texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_RECT:
                {
                    texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
            }
        }

        Primitive2DSequence FillGradientPrimitive2D::createOverlappingFill(
            const std::vector< basegfx::B2DHomMatrix >& rMatrices,
            const std::vector< basegfx::BColor >& rColors,
            const basegfx::B2DPolygon& rUnitPolygon) const
        {
            // prepare return value
            Primitive2DSequence aRetval(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());

            // create solid fill with start color
            if(!rColors.empty())
            {
                // create primitive
                const Primitive2DReference xRef(
                    new PolyPolygonColorPrimitive2D(
                        basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())),
                        rColors[0]));
                aRetval[0] = xRef;
            }

            // create solid fill steps
            for(sal_uInt32 a(0); a < rMatrices.size(); a++)
            {
                // create part polygon
                basegfx::B2DPolygon aNewPoly(rUnitPolygon);
                aNewPoly.transform(rMatrices[a]);

                // create solid fill
                const Primitive2DReference xRef(
                    new PolyPolygonColorPrimitive2D(
                        basegfx::B2DPolyPolygon(aNewPoly),
                        rColors[a + 1]));
                aRetval[a + 1] = xRef;
            }

            return aRetval;
        }

        Primitive2DSequence FillGradientPrimitive2D::createNonOverlappingFill(
            const std::vector< basegfx::B2DHomMatrix >& rMatrices,
            const std::vector< basegfx::BColor >& rColors,
            const basegfx::B2DPolygon& rUnitPolygon) const
        {
            // prepare return value
            Primitive2DSequence aRetval;
            const sal_uInt32 nMatricesSize(rMatrices.size());

            if(nMatricesSize)
            {
                basegfx::B2DPolygon aOuterPoly(rUnitPolygon);
                aOuterPoly.transform(rMatrices[0]);
                basegfx::B2DPolyPolygon aCombinedPolyPoly(aOuterPoly);
                const sal_uInt32 nEntryCount(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());
                sal_uInt32 nIndex(0);

                aRetval.realloc(nEntryCount);

                if(!rColors.empty())
                {
                    basegfx::B2DRange aOuterPolyRange(aOuterPoly.getB2DRange());
                    aOuterPolyRange.expand(getObjectRange());
                    aCombinedPolyPoly.append(basegfx::tools::createPolygonFromRect(aOuterPolyRange));
                    aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[0]));
                    aCombinedPolyPoly = basegfx::B2DPolyPolygon(aOuterPoly);
                }

                for(sal_uInt32 a(1); a < nMatricesSize - 1; a++)
                {
                    basegfx::B2DPolygon aInnerPoly(rUnitPolygon);
                    aInnerPoly.transform(rMatrices[a]);
                    aCombinedPolyPoly.append(aInnerPoly);
                    aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[a]));
                    aCombinedPolyPoly = basegfx::B2DPolyPolygon(aInnerPoly);
                }

                if(!rColors.empty())
                {
                    aRetval[nIndex] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
                        aCombinedPolyPoly, rColors[rColors.size() - 1]));
                }
            }

            return aRetval;
        }

        Primitive2DSequence FillGradientPrimitive2D::createFill(bool bOverlapping) const
        {
            // prepare shape of the Unit Polygon
            basegfx::B2DPolygon aUnitPolygon;

            if(attribute::GRADIENTSTYLE_RADIAL == getFillGradient().getStyle()
                || attribute::GRADIENTSTYLE_ELLIPTICAL == getFillGradient().getStyle())
            {
                aUnitPolygon = basegfx::tools::createPolygonFromCircle(
                    basegfx::B2DPoint(0,0), 1);
            }
            else if(attribute::GRADIENTSTYLE_LINEAR == maFillGradient.getStyle())
            {
                aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0, 0, 1, 1));
            }
            else
            {
                aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
            }

            // get the transform matrices and colors (where colors
            // will have one more entry that matrices)
            std::vector< basegfx::B2DHomMatrix > aMatrices;
            std::vector< basegfx::BColor > aColors;
            generateMatricesAndColors(aMatrices, aColors);

            if(bOverlapping)
            {
                return createOverlappingFill(aMatrices, aColors, aUnitPolygon);
            }
            else
            {
                return createNonOverlappingFill(aMatrices, aColors, aUnitPolygon);
            }
        }

        Primitive2DSequence FillGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
        {
            // default creates overlapping fill which works with AntiAliasing and without.
            // The non-overlapping version does not create single filled polygons, but
            // PolyPolygons where each one describes a 'ring' for the gradient such
            // that the rings will not overlap. This is useful fir the old XOR-paint
            // 'trick' of VCL which is recorded in Metafiles; so this version may be
            // used from the MetafilePrimitive2D in it's decomposition.

            if(!getFillGradient().isDefault())
            {
                return createFill(true);
            }
            else
            {
                return Primitive2DSequence();
            }
        }

        FillGradientPrimitive2D::FillGradientPrimitive2D(
            const basegfx::B2DRange& rObjectRange,
            const attribute::FillGradientAttribute& rFillGradient)
        :   BufferedDecompositionPrimitive2D(),
            maObjectRange(rObjectRange),
            maFillGradient(rFillGradient)
        {
        }

        bool FillGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
        {
            if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
            {
                const FillGradientPrimitive2D& rCompare = (FillGradientPrimitive2D&)rPrimitive;

                return (getObjectRange() == rCompare.getObjectRange()
                    && getFillGradient() == rCompare.getFillGradient());
            }

            return false;
        }

        basegfx::B2DRange FillGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
        {
            // return ObjectRange
            return getObjectRange();
        }

        // provide unique ID
        ImplPrimitrive2DIDBlock(FillGradientPrimitive2D, PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D)

    } // end of namespace primitive2d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////
// eof

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Fix fdo#33591 - edge-case trans gradients came out empty<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/texture/texture.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>

//////////////////////////////////////////////////////////////////////////////

using namespace com::sun::star;

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
    namespace primitive2d
    {
        void FillGradientPrimitive2D::generateMatricesAndColors(
            std::vector< basegfx::B2DHomMatrix >& rMatrices,
            std::vector< basegfx::BColor >& rColors) const
        {
            rMatrices.clear();
            rColors.clear();

            // make sure steps is not too high/low
            const basegfx::BColor aStart(getFillGradient().getStartColor());
            const basegfx::BColor aEnd(getFillGradient().getEndColor());
            const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
            sal_uInt32 nSteps(getFillGradient().getSteps());

            if(nSteps == 0)
            {
                nSteps = nMaxSteps;
            }

            if(nSteps < 2)
            {
                nSteps = 2;
            }

            if(nSteps > nMaxSteps)
            {
                nSteps = nMaxSteps;
            }

            nSteps = std::max(sal_uInt32(1), nSteps);

            switch(getFillGradient().getStyle())
            {
                case attribute::GRADIENTSTYLE_LINEAR:
                {
                    texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_AXIAL:
                {
                    texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_RADIAL:
                {
                    texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_ELLIPTICAL:
                {
                    texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_SQUARE:
                {
                    texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
                case attribute::GRADIENTSTYLE_RECT:
                {
                    texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
                    aGradient.appendTransformations(rMatrices);
                    aGradient.appendColors(rColors);
                    break;
                }
            }
        }

        Primitive2DSequence FillGradientPrimitive2D::createOverlappingFill(
            const std::vector< basegfx::B2DHomMatrix >& rMatrices,
            const std::vector< basegfx::BColor >& rColors,
            const basegfx::B2DPolygon& rUnitPolygon) const
        {
            // prepare return value
            Primitive2DSequence aRetval(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());

            // create solid fill with start color
            if(!rColors.empty())
            {
                // create primitive
                const Primitive2DReference xRef(
                    new PolyPolygonColorPrimitive2D(
                        basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())),
                        rColors[0]));
                aRetval[0] = xRef;
            }

            // create solid fill steps
            for(sal_uInt32 a(0); a < rMatrices.size(); a++)
            {
                // create part polygon
                basegfx::B2DPolygon aNewPoly(rUnitPolygon);
                aNewPoly.transform(rMatrices[a]);

                // create solid fill
                const Primitive2DReference xRef(
                    new PolyPolygonColorPrimitive2D(
                        basegfx::B2DPolyPolygon(aNewPoly),
                        rColors[a + 1]));
                aRetval[a + 1] = xRef;
            }

            return aRetval;
        }

        Primitive2DSequence FillGradientPrimitive2D::createNonOverlappingFill(
            const std::vector< basegfx::B2DHomMatrix >& rMatrices,
            const std::vector< basegfx::BColor >& rColors,
            const basegfx::B2DPolygon& rUnitPolygon) const
        {
            // prepare return value
            Primitive2DSequence aRetval;
            const sal_uInt32 nMatricesSize(rMatrices.size());

            if(nMatricesSize)
            {
                basegfx::B2DPolygon aOuterPoly(rUnitPolygon);
                aOuterPoly.transform(rMatrices[0]);
                basegfx::B2DPolyPolygon aCombinedPolyPoly(aOuterPoly);
                const sal_uInt32 nEntryCount(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());
                sal_uInt32 nIndex(0);

                aRetval.realloc(nEntryCount);

                if(!rColors.empty())
                {
                    basegfx::B2DRange aOuterPolyRange(aOuterPoly.getB2DRange());
                    aOuterPolyRange.expand(getObjectRange());
                    aCombinedPolyPoly.append(basegfx::tools::createPolygonFromRect(aOuterPolyRange));
                    aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[0]));
                    aCombinedPolyPoly = basegfx::B2DPolyPolygon(aOuterPoly);
                }

                for(sal_uInt32 a(1); a < nMatricesSize - 1; a++)
                {
                    basegfx::B2DPolygon aInnerPoly(rUnitPolygon);
                    aInnerPoly.transform(rMatrices[a]);
                    aCombinedPolyPoly.append(aInnerPoly);
                    aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[a]));
                    aCombinedPolyPoly = basegfx::B2DPolyPolygon(aInnerPoly);
                }

                if(!rColors.empty())
                {
                    aRetval[nIndex] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
                        aCombinedPolyPoly, rColors[rColors.size() - 1]));
                }
            }

            return aRetval;
        }

        Primitive2DSequence FillGradientPrimitive2D::createFill(bool bOverlapping) const
        {
            // prepare shape of the Unit Polygon
            basegfx::B2DPolygon aUnitPolygon;

            if(attribute::GRADIENTSTYLE_RADIAL == getFillGradient().getStyle()
                || attribute::GRADIENTSTYLE_ELLIPTICAL == getFillGradient().getStyle())
            {
                aUnitPolygon = basegfx::tools::createPolygonFromCircle(
                    basegfx::B2DPoint(0,0), 1);
            }
            else if(attribute::GRADIENTSTYLE_LINEAR == maFillGradient.getStyle())
            {
                aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0, 0, 1, 1));
            }
            else
            {
                aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
            }

            // get the transform matrices and colors (where colors
            // will have one more entry that matrices)
            std::vector< basegfx::B2DHomMatrix > aMatrices;
            std::vector< basegfx::BColor > aColors;
            generateMatricesAndColors(aMatrices, aColors);

            if(bOverlapping)
            {
                return createOverlappingFill(aMatrices, aColors, aUnitPolygon);
            }
            else
            {
                return createNonOverlappingFill(aMatrices, aColors, aUnitPolygon);
            }
        }

        Primitive2DSequence FillGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
        {
            // default creates overlapping fill which works with AntiAliasing and without.
            // The non-overlapping version does not create single filled polygons, but
            // PolyPolygons where each one describes a 'ring' for the gradient such
            // that the rings will not overlap. This is useful fir the old XOR-paint
            // 'trick' of VCL which is recorded in Metafiles; so this version may be
            // used from the MetafilePrimitive2D in it's decomposition.

            if(!getFillGradient().isDefault())
            {
                return createFill(true);
            }
            else
            {
                return Primitive2DSequence();
            }
        }

        FillGradientPrimitive2D::FillGradientPrimitive2D(
            const basegfx::B2DRange& rObjectRange,
            const attribute::FillGradientAttribute& rFillGradient)
        :   BufferedDecompositionPrimitive2D(),
            maObjectRange(rObjectRange),
            maFillGradient(rFillGradient)
        {
        }

        bool FillGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
        {
            if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
            {
                const FillGradientPrimitive2D& rCompare = (FillGradientPrimitive2D&)rPrimitive;

                return (getObjectRange() == rCompare.getObjectRange()
                    && getFillGradient() == rCompare.getFillGradient());
            }

            return false;
        }

        basegfx::B2DRange FillGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
        {
            // return ObjectRange
            return getObjectRange();
        }

        // provide unique ID
        ImplPrimitrive2DIDBlock(FillGradientPrimitive2D, PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D)

    } // end of namespace primitive2d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////
// eof

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <cstdint>
#include <cassert>
#include <chrono>

#include <gtest/gtest.h>

#include "joynr/SingleThreadedDelayedScheduler.h"
#include "joynr/SingleThreadedIOService.h"

#include "tests/mock/MockRunnable.h"
#include "tests/utils/TestRunnable.h"
#include "tests/mock/MockRunnableWithAccuracy.h"

using namespace ::testing;
using namespace joynr;

using ::testing::StrictMock;

class SingleThreadedDelayedSchedulerTest : public testing::Test
{
public:
    SingleThreadedDelayedSchedulerTest() : singleThreadedIOService(std::make_shared<SingleThreadedIOService>())
    {
        singleThreadedIOService->start();
    }
protected:
    std::shared_ptr<SingleThreadedIOService> singleThreadedIOService;
};

TEST_F(SingleThreadedDelayedSchedulerTest, startAndShutdownWithoutWork)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    scheduler->shutdown();
}

TEST_F(SingleThreadedDelayedSchedulerTest, startAndShutdownWithPendingWork_callDtorOfRunnablesCorrect)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    // Dtor should be called
    auto runnable1 = std::make_shared<StrictMock<MockRunnable>>();
    scheduler->schedule(runnable1, std::chrono::milliseconds(100));

    // Dtor called after scheduler was cleaned
    auto runnable2 = std::make_shared<StrictMock<MockRunnable>>();
    scheduler->schedule(runnable2, std::chrono::milliseconds(100));

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    EXPECT_CALL(*runnable2, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, testAccuracyOfDelayedScheduler)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(5);

    scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    EXPECT_CALL(*runnable1, runCalled()).Times(1);
    EXPECT_CALL(*runnable1, runCalledInTime()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, callDtorOfRunnablesAfterSchedulerHasExpired)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnable>>();

    scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    EXPECT_CALL(*runnable1, run()).Times(1);
    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();
}

TEST_F(SingleThreadedDelayedSchedulerTest, scheduleAndUnscheduleRunnable)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(5);

    DelayedScheduler::RunnableHandle handle = scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    std::this_thread::sleep_for(std::chrono::milliseconds(1));

    scheduler->unschedule(handle);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, scheduleAndUnscheduleRunnable_CallDtorOnUnschedule)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(5u);

    DelayedScheduler::RunnableHandle handle = scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    std::this_thread::sleep_for(std::chrono::milliseconds(1));

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);

    scheduler->unschedule(handle);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();
}

TEST_F(SingleThreadedDelayedSchedulerTest, useDefaultDelay)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds(10));

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(10u);

    scheduler->schedule(runnable1);

    EXPECT_CALL(*runnable1, runCalled()).Times(1);
    EXPECT_CALL(*runnable1, runCalledInTime()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(20));

    scheduler->shutdown();

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, schedule_deletingRunnablesCorrectly)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThread", singleThreadedIOService->getIOService());
    auto runnable = std::make_shared<TestRunnable>();
    scheduler->schedule(runnable, std::chrono::milliseconds(1));
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    scheduler->shutdown();
}
<commit_msg>[C++] Stop SingleThreadedIOService in SingleThreadedDelayedSchedulerTest<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <cstdint>
#include <cassert>
#include <chrono>

#include <gtest/gtest.h>

#include "joynr/SingleThreadedDelayedScheduler.h"
#include "joynr/SingleThreadedIOService.h"

#include "tests/mock/MockRunnable.h"
#include "tests/utils/TestRunnable.h"
#include "tests/mock/MockRunnableWithAccuracy.h"

using namespace ::testing;
using namespace joynr;

using ::testing::StrictMock;

class SingleThreadedDelayedSchedulerTest : public testing::Test
{
public:
    SingleThreadedDelayedSchedulerTest() : singleThreadedIOService(std::make_shared<SingleThreadedIOService>())
    {
        singleThreadedIOService->start();
    }

    ~SingleThreadedDelayedSchedulerTest() {
        singleThreadedIOService->stop();
    }
protected:
    std::shared_ptr<SingleThreadedIOService> singleThreadedIOService;
};

TEST_F(SingleThreadedDelayedSchedulerTest, startAndShutdownWithoutWork)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    scheduler->shutdown();
}

TEST_F(SingleThreadedDelayedSchedulerTest, startAndShutdownWithPendingWork_callDtorOfRunnablesCorrect)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    // Dtor should be called
    auto runnable1 = std::make_shared<StrictMock<MockRunnable>>();
    scheduler->schedule(runnable1, std::chrono::milliseconds(100));

    // Dtor called after scheduler was cleaned
    auto runnable2 = std::make_shared<StrictMock<MockRunnable>>();
    scheduler->schedule(runnable2, std::chrono::milliseconds(100));

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    EXPECT_CALL(*runnable2, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, testAccuracyOfDelayedScheduler)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(5);

    scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    EXPECT_CALL(*runnable1, runCalled()).Times(1);
    EXPECT_CALL(*runnable1, runCalledInTime()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, callDtorOfRunnablesAfterSchedulerHasExpired)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnable>>();

    scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    EXPECT_CALL(*runnable1, run()).Times(1);
    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();
}

TEST_F(SingleThreadedDelayedSchedulerTest, scheduleAndUnscheduleRunnable)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(5);

    DelayedScheduler::RunnableHandle handle = scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    std::this_thread::sleep_for(std::chrono::milliseconds(1));

    scheduler->unschedule(handle);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, scheduleAndUnscheduleRunnable_CallDtorOnUnschedule)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds::zero());

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(5u);

    DelayedScheduler::RunnableHandle handle = scheduler->schedule(runnable1, std::chrono::milliseconds(5));

    std::this_thread::sleep_for(std::chrono::milliseconds(1));

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);

    scheduler->unschedule(handle);

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    scheduler->shutdown();
}

TEST_F(SingleThreadedDelayedSchedulerTest, useDefaultDelay)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThreadedDelayedScheduler", singleThreadedIOService->getIOService(), std::chrono::milliseconds(10));

    auto runnable1 = std::make_shared<StrictMock<MockRunnableWithAccuracy>>(10u);

    scheduler->schedule(runnable1);

    EXPECT_CALL(*runnable1, runCalled()).Times(1);
    EXPECT_CALL(*runnable1, runCalledInTime()).Times(1);

    std::this_thread::sleep_for(std::chrono::milliseconds(20));

    scheduler->shutdown();

    EXPECT_CALL(*runnable1, dtorCalled()).Times(1);
}

TEST_F(SingleThreadedDelayedSchedulerTest, schedule_deletingRunnablesCorrectly)
{
    auto scheduler = std::make_shared<SingleThreadedDelayedScheduler>("SingleThread", singleThreadedIOService->getIOService());
    auto runnable = std::make_shared<TestRunnable>();
    scheduler->schedule(runnable, std::chrono::milliseconds(1));
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    scheduler->shutdown();
}
<|endoftext|>


<commit_before>#include "db-sqlite3.h"
#include <stdexcept>

DBSQLite3::DBSQLite3(const std::string &mapdir) {

	std::string db_name = mapdir + "map.sqlite";
	if (sqlite3_open_v2(db_name.c_str(), &m_db, SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE, 0) != SQLITE_OK) {
		throw std::runtime_error(std::string(sqlite3_errmsg(m_db)) + ", Database file: " + db_name);
	}
}

DBSQLite3::~DBSQLite3() {
	sqlite3_close_v2(m_db);
}

std::vector<int64_t> DBSQLite3::getBlockPos() {
	std::vector<int64_t> vec;
	sqlite3_stmt *statement;
	std::string sql = "SELECT pos FROM blocks";
	if (sqlite3_prepare_v2(m_db, sql.c_str(), sql.length(), &statement, 0) == SQLITE_OK) {
		int result = 0;
		while (true) {
			result = sqlite3_step(statement);
			if(result == SQLITE_ROW) {
				sqlite3_int64 blocknum = sqlite3_column_int64(statement, 0);
				vec.push_back(blocknum);
			}
			else
				break;
		}
	} else {
		throw std::runtime_error("Failed to get list of MapBlocks");
	}
	return vec;
}

DBBlockList DBSQLite3::getBlocksOnZ(int zPos)
{
	sqlite3_stmt *statement;
	std::string sql = "SELECT pos, data FROM blocks WHERE (pos >= ? AND pos <= ?)";
	if (sqlite3_prepare_v2(m_db, sql.c_str(), sql.length(), &statement, 0) != SQLITE_OK) {
		throw std::runtime_error("Failed to prepare statement");
	}
	DBBlockList blocks;

	sqlite3_int64 psMin;
	sqlite3_int64 psMax;

	psMin = (static_cast<sqlite3_int64>(zPos) * 16777216l) - 0x800000;
	psMax = (static_cast<sqlite3_int64>(zPos) * 16777216l) + 0x7fffff;
	sqlite3_bind_int64(statement, 1, psMin);
	sqlite3_bind_int64(statement, 2, psMax);

	int result = 0;
	while (true) {
		result = sqlite3_step(statement);
		if(result == SQLITE_ROW) {
			sqlite3_int64 blocknum = sqlite3_column_int64(statement, 0);
			const unsigned char *data = reinterpret_cast<const unsigned char *>(sqlite3_column_blob(statement, 1));
			int size = sqlite3_column_bytes(statement, 1);
			blocks.push_back(DBBlock(blocknum, std::basic_string<unsigned char>(data, size)));
		}
		else {
			break;
		}
	}
	sqlite3_reset(statement);

	return blocks;
}

<commit_msg>Catch SQLITE_BUSY and try again<commit_after>#include "db-sqlite3.h"
#include <stdexcept>
#include <unistd.h> // for usleep

DBSQLite3::DBSQLite3(const std::string &mapdir) {

	std::string db_name = mapdir + "map.sqlite";
	if (sqlite3_open_v2(db_name.c_str(), &m_db, SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE, 0) != SQLITE_OK) {
		throw std::runtime_error(std::string(sqlite3_errmsg(m_db)) + ", Database file: " + db_name);
	}
}

DBSQLite3::~DBSQLite3() {
	sqlite3_close_v2(m_db);
}

std::vector<int64_t> DBSQLite3::getBlockPos() {
	std::vector<int64_t> vec;
	sqlite3_stmt *statement;
	std::string sql = "SELECT pos FROM blocks";
	if (sqlite3_prepare_v2(m_db, sql.c_str(), sql.length(), &statement, 0) == SQLITE_OK) {
		int result = 0;
		while (true) {
			result = sqlite3_step(statement);
			if(result == SQLITE_ROW) {
				sqlite3_int64 blocknum = sqlite3_column_int64(statement, 0);
				vec.push_back(blocknum);
			} else if (result == SQLITE_BUSY) // Wait some time and try again
				usleep(10000);
			else
				break;
		}
	} else {
		throw std::runtime_error("Failed to get list of MapBlocks");
	}
	return vec;
}

DBBlockList DBSQLite3::getBlocksOnZ(int zPos)
{
	sqlite3_stmt *statement;
	std::string sql = "SELECT pos, data FROM blocks WHERE (pos >= ? AND pos <= ?)";
	if (sqlite3_prepare_v2(m_db, sql.c_str(), sql.length(), &statement, 0) != SQLITE_OK) {
		throw std::runtime_error("Failed to prepare statement");
	}
	DBBlockList blocks;

	sqlite3_int64 psMin;
	sqlite3_int64 psMax;

	psMin = (static_cast<sqlite3_int64>(zPos) * 16777216l) - 0x800000;
	psMax = (static_cast<sqlite3_int64>(zPos) * 16777216l) + 0x7fffff;
	sqlite3_bind_int64(statement, 1, psMin);
	sqlite3_bind_int64(statement, 2, psMax);

	int result = 0;
	while (true) {
		result = sqlite3_step(statement);
		if(result == SQLITE_ROW) {
			sqlite3_int64 blocknum = sqlite3_column_int64(statement, 0);
			const unsigned char *data = reinterpret_cast<const unsigned char *>(sqlite3_column_blob(statement, 1));
			int size = sqlite3_column_bytes(statement, 1);
			blocks.push_back(DBBlock(blocknum, std::basic_string<unsigned char>(data, size)));
		} else if (result == SQLITE_BUSY) { // Wait some time and try again
			usleep(10000);
		} else {
			break;
		}
	}
	sqlite3_reset(statement);

	return blocks;
}

<|endoftext|>


<commit_before>//===-- TarWriter.cpp - Tar archive file creator --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// TarWriter class provides a feature to create a tar archive file.
//
// I put emphasis on simplicity over comprehensiveness when implementing this
// class because we don't need a full-fledged archive file generator in LLVM
// at the moment.
//
// The filename field in the Unix V7 tar header is 100 bytes. Longer filenames
// are stored using the PAX extension. The PAX header is standardized in
// POSIX.1-2001.
//
// The struct definition of UstarHeader is copied from
// https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/TarWriter.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MathExtras.h"

using namespace llvm;

// Each file in an archive must be aligned to this block size.
static const int BlockSize = 512;

struct UstarHeader {
  char Name[100];
  char Mode[8];
  char Uid[8];
  char Gid[8];
  char Size[12];
  char Mtime[12];
  char Checksum[8];
  char TypeFlag;
  char Linkname[100];
  char Magic[6];
  char Version[2];
  char Uname[32];
  char Gname[32];
  char DevMajor[8];
  char DevMinor[8];
  char Prefix[155];
  char Pad[12];
};
static_assert(sizeof(UstarHeader) == BlockSize, "invalid Ustar header");

// A PAX attribute is in the form of "<length> <key>=<value>\n"
// where <length> is the length of the entire string including
// the length field itself. An example string is this.
//
//   25 ctime=1084839148.1212\n
//
// This function create such string.
static std::string formatPax(StringRef Key, StringRef Val) {
  int Len = Key.size() + Val.size() + 3; // +3 for " ", "=" and "\n"

  // We need to compute total size twice because appending
  // a length field could change total size by one.
  int Total = Len + Twine(Len).str().size();
  Total = Len + Twine(Total).str().size();
  return (Twine(Total) + " " + Key + "=" + Val + "\n").str();
}

// Headers in tar files must be aligned to 512 byte boundaries.
// This function forwards the current file position to the next boundary.
static void pad(raw_fd_ostream &OS) {
  uint64_t Pos = OS.tell();
  OS.seek(alignTo(Pos, BlockSize));
}

// Computes a checksum for a tar header.
static void computeChecksum(UstarHeader &Hdr) {
  // Before computing a checksum, checksum field must be
  // filled with space characters.
  memset(Hdr.Checksum, ' ', sizeof(Hdr.Checksum));

  // Compute a checksum and set it to the checksum field.
  unsigned Chksum = 0;
  for (size_t I = 0; I < sizeof(Hdr); ++I)
    Chksum += reinterpret_cast<uint8_t *>(&Hdr)[I];
  snprintf(Hdr.Checksum, sizeof(Hdr.Checksum), "%06o", Chksum);
}

// Create a tar header and write it to a given output stream.
static void writePaxHeader(raw_fd_ostream &OS, StringRef Path) {
  // A PAX header consists of a 512-byte header followed
  // by key-value strings. First, create key-value strings.
  std::string PaxAttr = formatPax("path", Path);

  // Create a 512-byte header.
  UstarHeader Hdr = {};
  snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", PaxAttr.size());
  Hdr.TypeFlag = 'x';            // PAX magic
  memcpy(Hdr.Magic, "ustar", 6); // Ustar magic
  computeChecksum(Hdr);

  // Write them down.
  OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));
  OS << PaxAttr;
  pad(OS);
}

// The PAX header is an extended format, so a PAX header needs
// to be followed by a "real" header.
static void writeUstarHeader(raw_fd_ostream &OS, StringRef Path, size_t Size) {
  UstarHeader Hdr = {};
  memcpy(Hdr.Name, Path.data(), Path.size());
  memcpy(Hdr.Mode, "0000664", 8);
  snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", Size);
  memcpy(Hdr.Magic, "ustar", 6);
  computeChecksum(Hdr);
  OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));
}

// We want to use '/' as a path separator even on Windows.
// This function canonicalizes a given path.
static std::string canonicalize(std::string S) {
#ifdef LLVM_ON_WIN32
  std::replace(S.begin(), S.end(), '\\', '/');
#endif
  return S;
}

// Creates a TarWriter instance and returns it.
Expected<std::unique_ptr<TarWriter>> TarWriter::create(StringRef OutputPath,
                                                       StringRef BaseDir) {
  int FD;
  if (std::error_code EC = openFileForWrite(OutputPath, FD, sys::fs::F_None))
    return make_error<StringError>("cannot open " + OutputPath, EC);
  return std::unique_ptr<TarWriter>(new TarWriter(FD, BaseDir));
}

TarWriter::TarWriter(int FD, StringRef BaseDir)
    : OS(FD, /*shouldClose=*/true, /*unbuffered=*/false), BaseDir(BaseDir) {}

// Append a given file to an archive.
void TarWriter::append(StringRef Path, StringRef Data) {
  // Write Path and Data.
  std::string S = BaseDir + "/" + canonicalize(Path) + "\0";
  if (S.size() <= sizeof(UstarHeader::Name)) {
    writeUstarHeader(OS, S, Data.size());
  } else {
    writePaxHeader(OS, S);
    writeUstarHeader(OS, "", Data.size());
  }

  OS << Data;
  pad(OS);

  // POSIX requires tar archives end with two null blocks.
  // Here, we write the terminator and then seek back, so that
  // the file being output is terminated correctly at any moment.
  uint64_t Pos = OS.tell();
  OS << std::string(BlockSize * 2, '\0');
  OS.seek(Pos);
  OS.flush();
}
<commit_msg>TarWriter: Use Ustar header's "prefix" field to store long filenames.<commit_after>//===-- TarWriter.cpp - Tar archive file creator --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// TarWriter class provides a feature to create a tar archive file.
//
// I put emphasis on simplicity over comprehensiveness when implementing this
// class because we don't need a full-fledged archive file generator in LLVM
// at the moment.
//
// The filename field in the Unix V7 tar header is 100 bytes. Longer filenames
// are stored using the PAX extension. The PAX header is standardized in
// POSIX.1-2001.
//
// The struct definition of UstarHeader is copied from
// https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/TarWriter.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MathExtras.h"

using namespace llvm;

// Each file in an archive must be aligned to this block size.
static const int BlockSize = 512;

struct UstarHeader {
  char Name[100];
  char Mode[8];
  char Uid[8];
  char Gid[8];
  char Size[12];
  char Mtime[12];
  char Checksum[8];
  char TypeFlag;
  char Linkname[100];
  char Magic[6];
  char Version[2];
  char Uname[32];
  char Gname[32];
  char DevMajor[8];
  char DevMinor[8];
  char Prefix[155];
  char Pad[12];
};
static_assert(sizeof(UstarHeader) == BlockSize, "invalid Ustar header");

// A PAX attribute is in the form of "<length> <key>=<value>\n"
// where <length> is the length of the entire string including
// the length field itself. An example string is this.
//
//   25 ctime=1084839148.1212\n
//
// This function create such string.
static std::string formatPax(StringRef Key, StringRef Val) {
  int Len = Key.size() + Val.size() + 3; // +3 for " ", "=" and "\n"

  // We need to compute total size twice because appending
  // a length field could change total size by one.
  int Total = Len + Twine(Len).str().size();
  Total = Len + Twine(Total).str().size();
  return (Twine(Total) + " " + Key + "=" + Val + "\n").str();
}

// Headers in tar files must be aligned to 512 byte boundaries.
// This function forwards the current file position to the next boundary.
static void pad(raw_fd_ostream &OS) {
  uint64_t Pos = OS.tell();
  OS.seek(alignTo(Pos, BlockSize));
}

// Computes a checksum for a tar header.
static void computeChecksum(UstarHeader &Hdr) {
  // Before computing a checksum, checksum field must be
  // filled with space characters.
  memset(Hdr.Checksum, ' ', sizeof(Hdr.Checksum));

  // Compute a checksum and set it to the checksum field.
  unsigned Chksum = 0;
  for (size_t I = 0; I < sizeof(Hdr); ++I)
    Chksum += reinterpret_cast<uint8_t *>(&Hdr)[I];
  snprintf(Hdr.Checksum, sizeof(Hdr.Checksum), "%06o", Chksum);
}

// Create a tar header and write it to a given output stream.
static void writePaxHeader(raw_fd_ostream &OS, StringRef Path) {
  // A PAX header consists of a 512-byte header followed
  // by key-value strings. First, create key-value strings.
  std::string PaxAttr = formatPax("path", Path);

  // Create a 512-byte header.
  UstarHeader Hdr = {};
  snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", PaxAttr.size());
  Hdr.TypeFlag = 'x';            // PAX magic
  memcpy(Hdr.Magic, "ustar", 6); // Ustar magic
  computeChecksum(Hdr);

  // Write them down.
  OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));
  OS << PaxAttr;
  pad(OS);
}

// In the Ustar header, a path can be split at any '/' to store
// a path into UstarHeader::Name and UstarHeader::Prefix. This
// function splits a given path for that purpose.
static std::pair<StringRef, StringRef> splitPath(StringRef Path) {
  if (Path.size() <= sizeof(UstarHeader::Name))
    return {"", Path};
  size_t Sep = Path.rfind('/', sizeof(UstarHeader::Name) + 1);
  if (Sep == StringRef::npos)
    return {"", Path};
  return {Path.substr(0, Sep), Path.substr(Sep + 1)};
}

// Returns true if a given path can be stored to a Ustar header
// without the PAX extension.
static bool fitInUstar(StringRef Path) {
  StringRef Prefix;
  StringRef Name;
  std::tie(Prefix, Name) = splitPath(Path);
  return Name.size() <= sizeof(UstarHeader::Name);
}

// The PAX header is an extended format, so a PAX header needs
// to be followed by a "real" header.
static void writeUstarHeader(raw_fd_ostream &OS, StringRef Path, size_t Size) {
  StringRef Prefix;
  StringRef Name;
  std::tie(Prefix, Name) = splitPath(Path);

  UstarHeader Hdr = {};
  memcpy(Hdr.Name, Name.data(), Name.size());
  memcpy(Hdr.Mode, "0000664", 8);
  snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", Size);
  memcpy(Hdr.Magic, "ustar", 6);
  memcpy(Hdr.Prefix, Prefix.data(), Prefix.size());
  computeChecksum(Hdr);
  OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));
}

// We want to use '/' as a path separator even on Windows.
// This function canonicalizes a given path.
static std::string canonicalize(std::string S) {
#ifdef LLVM_ON_WIN32
  std::replace(S.begin(), S.end(), '\\', '/');
#endif
  return S;
}

// Creates a TarWriter instance and returns it.
Expected<std::unique_ptr<TarWriter>> TarWriter::create(StringRef OutputPath,
                                                       StringRef BaseDir) {
  int FD;
  if (std::error_code EC = openFileForWrite(OutputPath, FD, sys::fs::F_None))
    return make_error<StringError>("cannot open " + OutputPath, EC);
  return std::unique_ptr<TarWriter>(new TarWriter(FD, BaseDir));
}

TarWriter::TarWriter(int FD, StringRef BaseDir)
    : OS(FD, /*shouldClose=*/true, /*unbuffered=*/false), BaseDir(BaseDir) {}

// Append a given file to an archive.
void TarWriter::append(StringRef Path, StringRef Data) {
  // Write Path and Data.
  std::string S = BaseDir + "/" + canonicalize(Path) + "\0";
  if (S.size() <= sizeof(UstarHeader::Name)) {
    writeUstarHeader(OS, S, Data.size());
  } else {
    writePaxHeader(OS, S);
    writeUstarHeader(OS, "", Data.size());
  }

  OS << Data;
  pad(OS);

  // POSIX requires tar archives end with two null blocks.
  // Here, we write the terminator and then seek back, so that
  // the file being output is terminated correctly at any moment.
  uint64_t Pos = OS.tell();
  OS << std::string(BlockSize * 2, '\0');
  OS.seek(Pos);
  OS.flush();
}
<|endoftext|>


<commit_before>#ifndef DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
#define DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH

#ifdef HAVE_EIGEN

// eigen
#include <Eigen/Core>
#include <Eigen/Sparse>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune
{

namespace Detailed {

namespace Discretizations
{

namespace LA
{

namespace Backend
{

namespace Container
{

namespace Eigen
{

template< class EntryImp >
class SparseMatrix
{
public:
  typedef EntryImp EntryType;

  typedef SparseMatrix< EntryType > ThisType;

  typedef ::Eigen::SparseMatrix< EntryType > StorageType;

  SparseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows),
      cols_(cols),
      storage_(new StorageType(rows_, cols_))
  {
  }

  SparseMatrix(Dune::shared_ptr< StorageType > storage)
    : rows_(storage->rows()),
      cols_(storage->cols()),
      storage_(storage)
  {
  }

  SparseMatrix(const ThisType& other)
    : rows_(other.rows()),
      cols_(other.cols()),
      storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_ = other.rows();
    cols_ = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr< StorageType > storage()
  {
    return storage_;
  }

  const Dune::shared_ptr< StorageType > storage() const
  {
    return storage_;
  }

  void reserve(unsigned int nnz)
  {
    storage_->reserve(nnz);
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->coeff(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr< StorageType > storage_;
}; // class SparseMatrix

template< class EntryImp >
class DenseMatrix;

template<>
class DenseMatrix< double >
{
public:
  typedef double EntryType;

  typedef DenseMatrix< EntryType > ThisType;

  typedef ::Eigen::MatrixXd StorageType;

  DenseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows),
      cols_(cols),
      storage_(new StorageType(rows_, cols_))
  {
  }

  DenseMatrix(Dune::shared_ptr< StorageType > storage)
    : rows_(storage->rows()),
      cols_(storage->cols()),
      storage_(storage)
  {
  }

  DenseMatrix(const ThisType& other)
    : rows_(other.rows()),
      cols_(other.cols()),
      storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_ = other.rows();
    cols_ = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr< StorageType > storage()
  {
    return storage_;
  }

  const Dune::shared_ptr< StorageType > storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(rows(), cols()));
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->operator()(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr< StorageType > storage_;
}; // class DenseMatrix

template< class EntryImp >
class DenseVector;

template<>
class DenseVector< double >
{
public:
  typedef double EntryType;

  typedef DenseVector< EntryType > ThisType;

  typedef ::Eigen::VectorXd StorageType;

  DenseVector(unsigned int size)
    : size_(size),
      storage_(new StorageType(size_))
  {
  }

  DenseVector(Dune::shared_ptr< StorageType > storage)
    : size_(storage->rows()),
      storage_(storage)
  {
  }

  DenseVector(const ThisType& other)
    : size_(other.size()),
      storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    size_ = other.size();
    storage_ = other.storage();
    return *this;
  }

  unsigned int size() const
  {
    return size_;
  }

  Dune::shared_ptr< StorageType > storage()
  {
    return storage_;
  }

  const Dune::shared_ptr< StorageType > storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(size()));
  }

  void add(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) += val;
  }

  void set(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) = val;
  }

  const EntryType get(unsigned int i) const
  {
    return storage_->operator()(i);
  }

  const EntryType& operator[](unsigned int i) const
  {
    return storage_->coeff(i);
  }

  EntryType& operator[](unsigned int i)
  {
    return storage_->coeffRef(i);
  }

private:
  unsigned int size_;
  Dune::shared_ptr< StorageType > storage_;
}; // class DenseVector

} // namespace Container

} // namespace Eigen

} // namespace Backend

} // namespace LA

} // namespace Discretizations

} // namespace Detailed

} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
<commit_msg>[la.backend.container.eigen] minor change<commit_after>#ifndef DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
#define DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH

#ifdef HAVE_EIGEN

// eigen
#include <Eigen/Core>
#include <Eigen/Sparse>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune
{

namespace Detailed {

namespace Discretizations
{

namespace LA
{

namespace Backend
{

namespace Container
{

namespace Eigen
{

template< class EntryImp >
class SparseMatrix
{
public:
  typedef EntryImp EntryType;

  typedef SparseMatrix< EntryType > ThisType;

  typedef ::Eigen::SparseMatrix< EntryType > StorageType;

  SparseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows),
      cols_(cols),
      storage_(new StorageType(rows_, cols_))
  {
  }

  SparseMatrix(Dune::shared_ptr< StorageType > storage)
    : rows_(storage->rows()),
      cols_(storage->cols()),
      storage_(storage)
  {
  }

  SparseMatrix(const ThisType& other)
    : rows_(other.rows_),
      cols_(other.cols_),
      storage_(other.storage_)
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_ = other.rows();
    cols_ = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr< StorageType > storage()
  {
    return storage_;
  }

  const Dune::shared_ptr< StorageType > storage() const
  {
    return storage_;
  }

  void reserve(unsigned int nnz)
  {
    storage_->reserve(nnz);
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->coeffRef(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->coeff(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr< StorageType > storage_;
}; // class SparseMatrix

template< class EntryImp >
class DenseMatrix;

template<>
class DenseMatrix< double >
{
public:
  typedef double EntryType;

  typedef DenseMatrix< EntryType > ThisType;

  typedef ::Eigen::MatrixXd StorageType;

  DenseMatrix(unsigned int rows, unsigned int cols)
    : rows_(rows),
      cols_(cols),
      storage_(new StorageType(rows_, cols_))
  {
  }

  DenseMatrix(Dune::shared_ptr< StorageType > storage)
    : rows_(storage->rows()),
      cols_(storage->cols()),
      storage_(storage)
  {
  }

  DenseMatrix(const ThisType& other)
    : rows_(other.rows()),
      cols_(other.cols()),
      storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    rows_ = other.rows();
    cols_ = other.cols();
    storage_ = other.storage();
    return *this;
  }

  unsigned int rows() const
  {
    return rows_;
  }

  unsigned int cols() const
  {
    return cols_;
  }

  Dune::shared_ptr< StorageType > storage()
  {
    return storage_;
  }

  const Dune::shared_ptr< StorageType > storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(rows(), cols()));
  }

  void add(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) += val;
  }

  void set(unsigned int i, unsigned int j, const EntryType& val)
  {
    storage_->operator()(i, j) = val;
  }

  const EntryType get(unsigned int i, unsigned int j) const
  {
    return storage_->operator()(i, j);
  }

private:
  unsigned int rows_;
  unsigned int cols_;
  Dune::shared_ptr< StorageType > storage_;
}; // class DenseMatrix

template< class EntryImp >
class DenseVector;

template<>
class DenseVector< double >
{
public:
  typedef double EntryType;

  typedef DenseVector< EntryType > ThisType;

  typedef ::Eigen::VectorXd StorageType;

  DenseVector(unsigned int size)
    : size_(size),
      storage_(new StorageType(size_))
  {
  }

  DenseVector(Dune::shared_ptr< StorageType > storage)
    : size_(storage->rows()),
      storage_(storage)
  {
  }

  DenseVector(const ThisType& other)
    : size_(other.size()),
      storage_(other.storage())
  {
  }

  ThisType& operator=(const ThisType& other)
  {
    size_ = other.size();
    storage_ = other.storage();
    return *this;
  }

  unsigned int size() const
  {
    return size_;
  }

  Dune::shared_ptr< StorageType > storage()
  {
    return storage_;
  }

  const Dune::shared_ptr< StorageType > storage() const
  {
    return storage_;
  }

  void reserve()
  {
    storage_->operator=(StorageType::Zero(size()));
  }

  void add(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) += val;
  }

  void set(unsigned int i, const EntryType& val)
  {
    storage_->operator()(i) = val;
  }

  const EntryType get(unsigned int i) const
  {
    return storage_->operator()(i);
  }

  const EntryType& operator[](unsigned int i) const
  {
    return storage_->coeff(i);
  }

  EntryType& operator[](unsigned int i)
  {
    return storage_->coeffRef(i);
  }

private:
  unsigned int size_;
  Dune::shared_ptr< StorageType > storage_;
}; // class DenseVector

} // namespace Container

} // namespace Eigen

} // namespace Backend

} // namespace LA

} // namespace Discretizations

} // namespace Detailed

} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_DETAILED_DISCRETIZATIONS_LA_BACKEND_EIGEN_HH
<|endoftext|>