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

#ifndef _DBAUI_DBADMINIMPL_HXX_
#define _DBAUI_DBADMINIMPL_HXX_

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XNAMINGSERVICE_HPP_
#include <com/sun/star/uno/XNamingService.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDRIVER_HPP_
#include <com/sun/star/sdbc/XDriver.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _DBAUI_DSNTYPES_HXX_
#include "dsntypes.hxx"
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif

class Window;
//.........................................................................
namespace dbaui
{
//.........................................................................
    class IItemSetHelper;
    //========================================================================
    //= ODbDataSourceAdministrationHelper
    //========================================================================
    class ODbDataSourceAdministrationHelper
    {
    public:
        DECLARE_STL_MAP(sal_Int32, ::rtl::OUString, ::std::less< sal_Int32 >, MapInt2String);

    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                            m_xORB;                 /// service factory
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
                                m_xDatabaseContext;     /// database context we're working in
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XNamingService >
                                m_xDynamicContext;      /// just another interface of the context ...
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >   m_xDatasource;
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >         m_xModel;

        ::com::sun::star::uno::Any              m_aDataSourceName;
        typedef ::std::set< ::rtl::OUString >   StringSet;
        typedef StringSet::const_iterator       ConstStringSetIterator;

        MapInt2String           m_aDirectPropTranslator;    /// translating property id's into names (direct properties of a data source)
        MapInt2String           m_aIndirectPropTranslator;  /// translating property id's into names (indirect properties of a data source)
        Window*                 m_pParent;
        IItemSetHelper*         m_pItemSetHelper;
    public:

        ODbDataSourceAdministrationHelper(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
                                        ,Window* _pParent
                                        ,IItemSetHelper* _pItemSetHelper);

        /** translate the current dialog SfxItems into driver relevant PropertyValues
            @see successfullyConnected
        */
        sal_Bool    getCurrentSettings(::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rDriverParams);

        /** to be called if the settings got from getCurrentSettings have been used for successfully connecting
            @see getCurrentSettings
        */
        void        successfullyConnected();

        /// clear the password in the current data source's item set
        void        clearPassword();

        inline ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() const { return m_xORB; }

        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > getDatabaseContext() const { return m_xDatabaseContext; }
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XNamingService > getDynamicContext() const { return m_xDynamicContext; }

        /** creates a new connection. The caller is responsible to dispose it !!!!
        */
        ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >,sal_Bool>      createConnection();

        /** return the corresponding driver for the selected URL
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver >         getDriver();

        /** returns the data source the dialog is currently working with
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >   getCurrentDataSource();

        // returns the Url of a database document
        String              getDocumentUrl(SfxItemSet& _rDest);

        void setCurrentDataSourceName(const ::com::sun::star::uno::Any& _aDataSourceName);

        /** extracts the connection type from the given set

            The connection type is determined by the value of the DSN item, analyzed by the TypeCollection item.
        */
        DATASOURCE_TYPE     getDatasourceType(const SfxItemSet& _rSet) const;

        /** returns the connection URL
            @return
                The connection URL
        */
        String getConnectionURL() const;

        /// fill the nescessary information from the url line
        void convertUrl(SfxItemSet& _rDest);

        const MapInt2String& getIndirectProperties() const { return m_aIndirectPropTranslator; }

        /** translates properties of an UNO data source into SfxItems
            @param  _rxSource
                The data source
            @param  _rDest
                The item set to fill.
        */
        void translateProperties(
                const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxSource,
                SfxItemSet& _rDest);

        /** translate SfxItems into properties of an UNO data source
            @param  _rSource
                The item set to read from.
            @param  _rxDest
                The data source to fill.
        */
        void translateProperties(
                const SfxItemSet& _rSource,
                const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDest);

        sal_Bool saveChanges(const SfxItemSet& _rSource);
    protected:
        /** fill a data source info array with the settings from a given item set
        */
        void fillDatasourceInfo(const SfxItemSet& _rSource, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rInfo);

        /// translate the given value into an SfxPoolItem, put this into the given set under the given id
        void        implTranslateProperty(SfxItemSet& _rSet, sal_Int32  _nId, const ::com::sun::star::uno::Any& _rValue);

        /// translate the given SfxPoolItem into an <type scope="com.sun.star.Any">uno</type>
        ::com::sun::star::uno::Any implTranslateProperty(const SfxPoolItem* _pItem);

        /// translate the given SfxPoolItem into an <type scope="com.sun.star.Any">uno</type>, set it (under the given name) on the given property set
        void        implTranslateProperty(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const SfxPoolItem* _pItem);

        /** check if the data source described by the given set needs authentication

            The return value depends on the data source type only.
        */
        sal_Bool            hasAuthentication(const SfxItemSet& _rSet) const;

#ifdef DBG_UTIL
        ::rtl::OString translatePropertyId( sal_Int32 _nId );
#endif
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif // _DBAUI_DBADMINIMPL_HXX_

<commit_msg>INTEGRATION: CWS wizopendb (1.5.48); FILE MERGED 2005/06/06 10:40:39 fs 1.5.48.1: #i42477# allow the 'New Database' wizard to load existing documents<commit_after>/*************************************************************************
 *
 *  $RCSfile: DbAdminImpl.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2005-06-30 16:30:58 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Ocke Janssen
 *
 *
 ************************************************************************/

#ifndef _DBAUI_DBADMINIMPL_HXX_
#define _DBAUI_DBADMINIMPL_HXX_

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XNAMINGSERVICE_HPP_
#include <com/sun/star/uno/XNamingService.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDRIVER_HPP_
#include <com/sun/star/sdbc/XDriver.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _DBAUI_DSNTYPES_HXX_
#include "dsntypes.hxx"
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif

class Window;
//.........................................................................
namespace dbaui
{
//.........................................................................
    class IItemSetHelper;
    //========================================================================
    //= ODbDataSourceAdministrationHelper
    //========================================================================
    class ODbDataSourceAdministrationHelper
    {
    public:
        DECLARE_STL_MAP(sal_Int32, ::rtl::OUString, ::std::less< sal_Int32 >, MapInt2String);

    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                            m_xORB;                 /// service factory
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
                                m_xDatabaseContext;     /// database context we're working in
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XNamingService >
                                m_xDynamicContext;      /// just another interface of the context ...
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >   m_xDatasource;
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >         m_xModel;

        ::com::sun::star::uno::Any              m_aDataSourceOrName;
        typedef ::std::set< ::rtl::OUString >   StringSet;
        typedef StringSet::const_iterator       ConstStringSetIterator;

        MapInt2String           m_aDirectPropTranslator;    /// translating property id's into names (direct properties of a data source)
        MapInt2String           m_aIndirectPropTranslator;  /// translating property id's into names (indirect properties of a data source)
        Window*                 m_pParent;
        IItemSetHelper*         m_pItemSetHelper;
    public:

        ODbDataSourceAdministrationHelper(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
                                        ,Window* _pParent
                                        ,IItemSetHelper* _pItemSetHelper);

        /** translate the current dialog SfxItems into driver relevant PropertyValues
            @see successfullyConnected
        */
        sal_Bool    getCurrentSettings(::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rDriverParams);

        /** to be called if the settings got from getCurrentSettings have been used for successfully connecting
            @see getCurrentSettings
        */
        void        successfullyConnected();

        /// clear the password in the current data source's item set
        void        clearPassword();

        inline ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() const { return m_xORB; }

        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > getDatabaseContext() const { return m_xDatabaseContext; }
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XNamingService > getDynamicContext() const { return m_xDynamicContext; }

        /** creates a new connection. The caller is responsible to dispose it !!!!
        */
        ::std::pair< ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >,sal_Bool>      createConnection();

        /** return the corresponding driver for the selected URL
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver >         getDriver();

        /** returns the data source the dialog is currently working with
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >   getCurrentDataSource();
        /** returs the model we're currently working with
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >         getCurrentModel();

        // returns the Url of a database document
        String              getDocumentUrl(SfxItemSet& _rDest);

        void setDataSourceOrName( const ::com::sun::star::uno::Any& _rDataSourceOrName );

        /** extracts the connection type from the given set

            The connection type is determined by the value of the DSN item, analyzed by the TypeCollection item.
        */
        DATASOURCE_TYPE     getDatasourceType(const SfxItemSet& _rSet) const;

        /** returns the connection URL
            @return
                The connection URL
        */
        String getConnectionURL() const;

        /// fill the nescessary information from the url line
        void convertUrl(SfxItemSet& _rDest);

        const MapInt2String& getIndirectProperties() const { return m_aIndirectPropTranslator; }

        /** translates properties of an UNO data source into SfxItems
            @param  _rxSource
                The data source
            @param  _rDest
                The item set to fill.
        */
        void translateProperties(
                const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxSource,
                SfxItemSet& _rDest);

        /** translate SfxItems into properties of an UNO data source
            @param  _rSource
                The item set to read from.
            @param  _rxDest
                The data source to fill.
        */
        void translateProperties(
                const SfxItemSet& _rSource,
                const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDest);

        sal_Bool saveChanges(const SfxItemSet& _rSource);
    protected:
        /** fill a data source info array with the settings from a given item set
        */
        void fillDatasourceInfo(const SfxItemSet& _rSource, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rInfo);

        /// translate the given value into an SfxPoolItem, put this into the given set under the given id
        void        implTranslateProperty(SfxItemSet& _rSet, sal_Int32  _nId, const ::com::sun::star::uno::Any& _rValue);

        /// translate the given SfxPoolItem into an <type scope="com.sun.star.Any">uno</type>
        ::com::sun::star::uno::Any implTranslateProperty(const SfxPoolItem* _pItem);

        /// translate the given SfxPoolItem into an <type scope="com.sun.star.Any">uno</type>, set it (under the given name) on the given property set
        void        implTranslateProperty(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const SfxPoolItem* _pItem);

        /** check if the data source described by the given set needs authentication

            The return value depends on the data source type only.
        */
        sal_Bool            hasAuthentication(const SfxItemSet& _rSet) const;

#ifdef DBG_UTIL
        ::rtl::OString translatePropertyId( sal_Int32 _nId );
#endif
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif // _DBAUI_DBADMINIMPL_HXX_

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: GeneralUndo.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-06 08:22:49 $
 *
 *  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 DBAUI_GENERALUNDO_HXX
#define DBAUI_GENERALUNDO_HXX

#ifndef _UNDO_HXX
#include <svtools/undo.hxx>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif

namespace dbaui
{
    // ================================================================================================
    // SbaCommentUndoAction - Undo-Basisklasse fuer Aktionen, deren GetComment einen aus einer Sba-Ressource
    // geladenen String liefert

    class OCommentUndoAction : public SfxUndoAction
    {
        OModuleClient    m_aModuleClient;

    protected:
        String                  m_strComment; // undo, redo comment

    public:
        TYPEINFO();
        OCommentUndoAction(USHORT nCommentID) { m_strComment = String(ModuleRes(nCommentID)); }

        virtual UniString   GetComment() const { return m_strComment; }
    };
}
#endif // DBAUI_GENERALUNDO_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.5.162); FILE MERGED 2008/03/31 13:27:42 rt 1.5.162.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: GeneralUndo.hxx,v $
 * $Revision: 1.6 $
 *
 * 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.
 *
 ************************************************************************/
#ifndef DBAUI_GENERALUNDO_HXX
#define DBAUI_GENERALUNDO_HXX

#ifndef _UNDO_HXX
#include <svtools/undo.hxx>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif

namespace dbaui
{
    // ================================================================================================
    // SbaCommentUndoAction - Undo-Basisklasse fuer Aktionen, deren GetComment einen aus einer Sba-Ressource
    // geladenen String liefert

    class OCommentUndoAction : public SfxUndoAction
    {
        OModuleClient    m_aModuleClient;

    protected:
        String                  m_strComment; // undo, redo comment

    public:
        TYPEINFO();
        OCommentUndoAction(USHORT nCommentID) { m_strComment = String(ModuleRes(nCommentID)); }

        virtual UniString   GetComment() const { return m_strComment; }
    };
}
#endif // DBAUI_GENERALUNDO_HXX

<|endoftext|>


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

#ifndef DBAUI_DATABASEEXPORT_HXX
#include "DExport.hxx"
#endif
#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif
#ifndef _COM_SUN_STAR_AWT_FONTDESCRIPTOR_HPP_
#include <com/sun/star/awt/FontDescriptor.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HPP_
#include <com/sun/star/lang/XEventListener.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
#include <com/sun/star/sdb/CommandType.hpp>
#endif

namespace dbaui
{
    // =========================================================================
    // ODatabaseImportExport Basisklasse f"ur Import/Export
    // =========================================================================
    class ODatabaseExport;
    class ODatabaseImportExport : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener>
    {
        void disposing();
    protected:
        SvStream*                               m_pStream;
        ::com::sun::star::awt::FontDescriptor   m_aFont;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >       m_xObject;      // table/query
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >         m_xConnection;  //
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >          m_xResultSet;   //
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >                m_xRow; //
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData >  m_xResultSetMetaData;   //
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >    m_xFormatter;   // a number formatter working with the connection's NumberFormatsSupplier
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xFactory;

        ::rtl::OUString m_sName;
        ::rtl::OUString m_sDataSourceName;
        sal_Int32       m_nCommandType;
        sal_Bool        m_bDisposeConnection;

#if defined UNX || defined MAC
        static const char __FAR_DATA sNewLine;
#else
        static const char __FAR_DATA sNewLine[];
#endif
        ODatabaseExport*    m_pReader;
        sal_Int32*          m_pRowMarker; // wenn gesetzt, dann nur diese Rows kopieren

        // export data
        ODatabaseImportExport(  const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _aSeq,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                                const String& rExchange = String());

        // import data
        ODatabaseImportExport(  const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
                                :m_xConnection(_rxConnection)
        ,m_pReader(NULL)
        ,m_pRowMarker(NULL)
        ,m_xFormatter(_rxNumberF)
        ,m_xFactory(_rM)
        ,m_nCommandType(::com::sun::star::sdb::CommandType::TABLE)
        ,m_bDisposeConnection(sal_False)
        {}

        virtual ~ODatabaseImportExport();
    public:
        void setStream(SvStream* _pStream){  m_pStream = _pStream; }

        virtual BOOL Write()    = 0; // Export
        virtual BOOL Read()     = 0; // Import

        void initialize();;
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
    };

    // =========================================================================
    // RTF Im- und Export
    // =========================================================================

    class ORTFImportExport : public ODatabaseImportExport
    {

    public:
        // export data
        ORTFImportExport(   const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _aSeq,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const String& rExchange = String())
                            : ODatabaseImportExport(_aSeq,_rM,_rxNumberF,rExchange) {};

        // import data
        ORTFImportExport(   const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
                        : ODatabaseImportExport(_rxConnection,_rxNumberF,_rM)
        {}

        virtual BOOL Write();
        virtual BOOL Read();
    };
    // =========================================================================
    // HTML Im- und Export
    // =========================================================================
    #define SBA_HTML_FONTSIZES 7
    const sal_Int16 nIndentMax = 23;
    class OHTMLImportExport : public ODatabaseImportExport
    {
        // default HtmlFontSz[1-7]
        static const sal_Int16  nDefaultFontSize[SBA_HTML_FONTSIZES];
        // HtmlFontSz[1-7] in s*3.ini [user]
        static sal_Int16        nFontSize[SBA_HTML_FONTSIZES];
        static const sal_Int16  nCellSpacing;
        static const char __FAR_DATA sIndentSource[];
        char                    sIndent[nIndentMax+1];
        sal_Int16               m_nIndent;
    #if DBG_UTIL
        BOOL                    m_bCheckFont;
    #endif

        void WriteHeader();
        void WriteBody();
        void WriteTables();
        void WriteCell( sal_Int32 nFormat,sal_Int32 nWidthPixel,sal_Int32 nHeightPixel,const char* pChar,const String& rValue,const char* pHtmlTag);
        void IncIndent( sal_Int16 nVal );
        const char*         GetIndentStr() { return sIndent; }
        void FontOn();
        inline void FontOff();

    public:
        // export data
        OHTMLImportExport(  const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _aSeq,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const String& rExchange = String());
        // import data
        OHTMLImportExport(  const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
                        : ODatabaseImportExport(_rxConnection,_rxNumberF,_rM)
        {}

        virtual BOOL Write();
        virtual BOOL Read();

    };

}
#endif // DBAUI_TOKENWRITER_HXX

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

#ifndef DBAUI_DATABASEEXPORT_HXX
#include "DExport.hxx"
#endif
#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif
#ifndef _COM_SUN_STAR_AWT_FONTDESCRIPTOR_HPP_
#include <com/sun/star/awt/FontDescriptor.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HPP_
#include <com/sun/star/lang/XEventListener.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
#include <com/sun/star/sdb/CommandType.hpp>
#endif

namespace dbaui
{
    // =========================================================================
    // ODatabaseImportExport Basisklasse f"ur Import/Export
    // =========================================================================
    class ODatabaseExport;
    class ODatabaseImportExport : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener>
    {
        void disposing();
    protected:
        SvStream*                               m_pStream;
        ::com::sun::star::awt::FontDescriptor   m_aFont;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >       m_xObject;      // table/query
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >         m_xConnection;  //
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >          m_xResultSet;   //
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >                m_xRow; //
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData >  m_xResultSetMetaData;   //
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >    m_xFormatter;   // a number formatter working with the connection's NumberFormatsSupplier
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xFactory;

        ::rtl::OUString m_sName;
        ::rtl::OUString m_sDataSourceName;
        sal_Int32       m_nCommandType;
        sal_Bool        m_bDisposeConnection;

#if defined UNX || defined MAC
        static const char __FAR_DATA sNewLine;
#else
        static const char __FAR_DATA sNewLine[];
#endif
        ODatabaseExport*    m_pReader;
        sal_Int32*          m_pRowMarker; // wenn gesetzt, dann nur diese Rows kopieren

        // export data
        ODatabaseImportExport(  const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _aSeq,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                                const String& rExchange = String());

        // import data
        ODatabaseImportExport(  const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
                                :m_xConnection(_rxConnection)
        ,m_pReader(NULL)
        ,m_pRowMarker(NULL)
        ,m_xFormatter(_rxNumberF)
        ,m_xFactory(_rM)
        ,m_nCommandType(::com::sun::star::sdb::CommandType::TABLE)
        ,m_bDisposeConnection(sal_False)
        {}

        virtual ~ODatabaseImportExport();
    public:
        void setStream(SvStream* _pStream){  m_pStream = _pStream; }

        virtual BOOL Write()    = 0; // Export
        virtual BOOL Read()     = 0; // Import

        void initialize();
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
    };

    // =========================================================================
    // RTF Im- und Export
    // =========================================================================

    class ORTFImportExport : public ODatabaseImportExport
    {

    public:
        // export data
        ORTFImportExport(   const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _aSeq,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const String& rExchange = String())
                            : ODatabaseImportExport(_aSeq,_rM,_rxNumberF,rExchange) {};

        // import data
        ORTFImportExport(   const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
                        : ODatabaseImportExport(_rxConnection,_rxNumberF,_rM)
        {}

        virtual BOOL Write();
        virtual BOOL Read();
    };
    // =========================================================================
    // HTML Im- und Export
    // =========================================================================
    #define SBA_HTML_FONTSIZES 7
    const sal_Int16 nIndentMax = 23;
    class OHTMLImportExport : public ODatabaseImportExport
    {
        // default HtmlFontSz[1-7]
        static const sal_Int16  nDefaultFontSize[SBA_HTML_FONTSIZES];
        // HtmlFontSz[1-7] in s*3.ini [user]
        static sal_Int16        nFontSize[SBA_HTML_FONTSIZES];
        static const sal_Int16  nCellSpacing;
        static const char __FAR_DATA sIndentSource[];
        char                    sIndent[nIndentMax+1];
        sal_Int16               m_nIndent;
    #if DBG_UTIL
        BOOL                    m_bCheckFont;
    #endif

        void WriteHeader();
        void WriteBody();
        void WriteTables();
        void WriteCell( sal_Int32 nFormat,sal_Int32 nWidthPixel,sal_Int32 nHeightPixel,const char* pChar,const String& rValue,const char* pHtmlTag);
        void IncIndent( sal_Int16 nVal );
        const char*         GetIndentStr() { return sIndent; }
        void FontOn();
        inline void FontOff();

    public:
        // export data
        OHTMLImportExport(  const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _aSeq,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const String& rExchange = String());
        // import data
        OHTMLImportExport(  const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
                        : ODatabaseImportExport(_rxConnection,_rxNumberF,_rM)
        {}

        virtual BOOL Write();
        virtual BOOL Read();

    };

}
#endif // DBAUI_TOKENWRITER_HXX

<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by ApexAI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_utils/cxx/deadline_timer.hpp"
#include "iceoryx_utils/internal/posix_wrapper/mutex.hpp"
#include "test.hpp"

#include <atomic>
#include <thread>

using namespace ::testing;
using namespace iox::units::duration_literals;

class Mutex_test : public Test
{
  public:
    void SetUp() override
    {
        internal::CaptureStderr();
    }

    void TearDown() override
    {
        std::string output = internal::GetCapturedStderr();
        if (Test::HasFailure())
        {
            std::cout << output << std::endl;
        }
    }

    iox::posix::mutex sutNonRecursive{false};
    iox::posix::mutex sutRecursive{true};
};

TEST_F(Mutex_test, TryLockWithNoLock)
{
    EXPECT_THAT(sutNonRecursive.try_lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}

#ifndef _WIN32
TEST_F(Mutex_test, TryLockWithNonRecursiveLock)
{
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.try_lock(), Eq(false));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}
#endif

TEST_F(Mutex_test, LockAndUnlock)
{
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}

TEST_F(Mutex_test, LockAndUnlockRepeatedly)
{
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}

#if !defined(_WIN32) || !defined(QNX) || !defined(QNX__) || !defined(__QNX__)
// in qnx you can destroy a locked mutex, without error if the thread holding the lock is destructing it.
TEST_F(Mutex_test, DestructorFailsOnLockedMutex)
{
    std::string output = internal::GetCapturedStderr();
    std::set_terminate([]() { std::cout << "", std::abort(); });

    EXPECT_DEATH(
        {
            iox::posix::mutex mtx{false};
            mtx.lock();
        },
        ".*");

    internal::CaptureStderr();
}
#endif

TEST_F(Mutex_test, LockedMutexBlocks)
{
    std::atomic_bool isLockFinished{false};
    sutNonRecursive.lock();

    std::thread lockThread([&] {
        sutNonRecursive.lock();
        isLockFinished.store(true);
        sutNonRecursive.unlock();
    });

    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    EXPECT_THAT(isLockFinished.load(), Eq(false));

    sutNonRecursive.unlock();
    lockThread.join();

    EXPECT_THAT(isLockFinished.load(), Eq(true));
}

TEST_F(Mutex_test, TryLockWithRecursiveMutexWhenMutexLocked)
{
    std::atomic_bool isTryLockSuccessful{true};
    sutRecursive.lock();

    std::thread lockThread([&] { isTryLockSuccessful = sutRecursive.try_lock(); });

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

    EXPECT_THAT(isTryLockSuccessful.load(), Eq(false));

    sutRecursive.unlock();
    lockThread.join();
}
<commit_msg>iox-#495 add watchdog to mutext_test<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by ApexAI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_utils/cxx/deadline_timer.hpp"
#include "iceoryx_utils/internal/posix_wrapper/mutex.hpp"
#include "test.hpp"
#include "testutils/watch_dog.hpp"

#include <atomic>
#include <thread>

using namespace ::testing;
using namespace iox::units::duration_literals;

class Mutex_test : public Test
{
  public:
    void SetUp() override
    {
        internal::CaptureStderr();
        m_deadlockWatchdog.watchAndActOnFailure([] { std::terminate(); });
    }

    void TearDown() override
    {
        std::string output = internal::GetCapturedStderr();
        if (Test::HasFailure())
        {
            std::cout << output << std::endl;
        }
    }

    iox::posix::mutex sutNonRecursive{false};
    iox::posix::mutex sutRecursive{true};
    iox::units::Duration m_watchdogTimeout = 5_s;
    Watchdog m_deadlockWatchdog{m_watchdogTimeout};
};

TEST_F(Mutex_test, TryLockWithNoLock)
{
    EXPECT_THAT(sutNonRecursive.try_lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}

#ifndef _WIN32
TEST_F(Mutex_test, TryLockWithNonRecursiveLock)
{
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.try_lock(), Eq(false));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}
#endif

TEST_F(Mutex_test, LockAndUnlock)
{
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}

TEST_F(Mutex_test, LockAndUnlockRepeatedly)
{
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.lock(), Eq(true));
    EXPECT_THAT(sutNonRecursive.unlock(), Eq(true));
}

#if !defined(_WIN32) || !defined(QNX) || !defined(QNX__) || !defined(__QNX__)
// in qnx you can destroy a locked mutex, without error if the thread holding the lock is destructing it.
TEST_F(Mutex_test, DestructorFailsOnLockedMutex)
{
    std::string output = internal::GetCapturedStderr();
    std::set_terminate([]() { std::cout << "", std::abort(); });

    EXPECT_DEATH(
        {
            iox::posix::mutex mtx{false};
            mtx.lock();
        },
        ".*");

    internal::CaptureStderr();
}
#endif

TEST_F(Mutex_test, LockedMutexBlocks)
{
    std::atomic_bool isLockFinished{false};
    sutNonRecursive.lock();

    std::thread lockThread([&] {
        sutNonRecursive.lock();
        isLockFinished.store(true);
        sutNonRecursive.unlock();
    });

    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    EXPECT_THAT(isLockFinished.load(), Eq(false));

    sutNonRecursive.unlock();
    lockThread.join();

    EXPECT_THAT(isLockFinished.load(), Eq(true));
}

TEST_F(Mutex_test, TryLockWithRecursiveMutexWhenMutexLocked)
{
    std::atomic_bool isTryLockSuccessful{true};
    sutRecursive.lock();

    std::thread lockThread([&] { isTryLockSuccessful = sutRecursive.try_lock(); });

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

    EXPECT_THAT(isTryLockSuccessful.load(), Eq(false));

    sutRecursive.unlock();
    lockThread.join();
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include <ox/std/trace.hpp>

#include "ptr.hpp"

namespace ox::ptrarith {

template<typename size_t, typename Item>
class __attribute__((packed)) NodeBuffer {

	public:
		struct __attribute__((packed)) Header {
			ox::LittleEndian<size_t> size = sizeof(Header); // capacity
			ox::LittleEndian<size_t> bytesUsed = sizeof(Header);
			ox::LittleEndian<size_t> firstItem = 0;
		};

		using ItemPtr = Ptr<Item, size_t, sizeof(Header)>;

		class Iterator {
			private:
				NodeBuffer *m_buffer = nullptr;
				ItemPtr m_current;
				size_t m_it = 0;

			public:
				Iterator(NodeBuffer *buffer, ItemPtr current) {
					m_buffer = buffer;
					m_current = current;
					oxTrace("ox::ptrarith::Iterator::start") << current.offset();
				}

				operator const Item*() const {
					return m_current;
				}

				ItemPtr ptr() {
					return m_current;
				}

				Item *get() {
					return m_current;
				}

				operator ItemPtr() {
					return m_current;
				}

				operator Item*() {
					return m_current;
				}

				const Item *operator->() const {
					return m_current;
				}

				Item *operator->() {
					return m_current;
				}

				[[nodiscard]] bool valid() const noexcept {
					return m_current.valid();
				}

				bool hasNext() {
					if (m_current.valid()) {
						oxTrace("ox::ptrarith::NodeBuffer::Iterator::hasNext::current") << m_current.offset();
						auto next = m_buffer->next(m_current);
						return next.valid() && m_buffer->firstItem() != next;
					}
					return false;
				}

				void next() {
					oxTrace("ox::ptrarith::NodeBuffer::Iterator::next") << m_it++;
					if (hasNext()) {
						m_current = m_buffer->next(m_current);
					} else {
						m_current = nullptr;
					}
				}
		};

		Header m_header;

	public:
		NodeBuffer() = default;

		NodeBuffer(const NodeBuffer &other);

		explicit NodeBuffer(size_t size);

		const Iterator iterator() const;

		Iterator iterator();

		ItemPtr firstItem();

		ItemPtr lastItem();

		/**
		 * @return the data section of the given item
		 */
		template<typename T>
		Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr);

		[[nodiscard]] ItemPtr prev(Item *item);

		[[nodiscard]] ItemPtr next(Item *item);

		[[nodiscard]] ItemPtr ptr(size_t offset);

		[[nodiscard]] ItemPtr ptr(void *item);

		[[nodiscard]] ItemPtr malloc(size_t size);

		[[nodiscard]] ox::Error free(ItemPtr item);

		[[nodiscard]] bool valid(size_t maxSize);

		/**
		 * Set size, capacity.
		 */
		[[nodiscard]] ox::Error setSize(size_t size);

		/**
		 * Get size, capacity.
		 * @return capacity
		 */
		size_t size();

		/**
		 * @return the bytes still available in this NodeBuffer
		 */
		size_t available();

		/**
		 * @return the actual number a bytes need to store the given number of
		 * bytes
		 */
		size_t spaceNeeded(size_t size);

		template<typename F>
		void compact(F cb = [](uint64_t, ItemPtr) {});

		void truncate();

	private:
		uint8_t *data();

};

template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(size_t size) {
	m_header.size = size;
}

template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other) {
	ox_memcpy(this, &other, other.size());
}

template<typename size_t, typename Item>
const typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() const {
	return Iterator(this, firstItem());
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() {
	oxTrace("ox::ptrarith::NodeBuffer::iterator::size") << m_header.size;
	return Iterator(this, firstItem());
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::firstItem() {
	//oxTrace("ox::ptrarith::NodeBuffer::firstItem") << m_header.firstItem;
	return ptr(m_header.firstItem);
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem() {
	auto first = ptr(m_header.firstItem);
	if (first.valid()) {
		return prev(first);
	}
	return nullptr;
}

template<typename size_t, typename Item>
template<typename T>
Ptr<T, size_t, sizeof(Item)> NodeBuffer<size_t, Item>::dataOf(ItemPtr ip) {
	auto out = ip.template subPtr<T>(sizeof(Item));
	oxAssert(out.size() == ip.size() - sizeof(Item), "Sub Ptr has invalid size.");
	return out;
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) {
	return ptr(item->prev);
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *item) {
	return ptr(item->next);
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) {
	// make sure this can be read as an Item, and then use Item::size for the size
	std::size_t itemSpace = m_header.size - itemOffset;
	auto item = reinterpret_cast<Item*>(reinterpret_cast<uint8_t*>(this) + itemOffset);
	if (itemOffset >= sizeof(Header) &&
	    itemOffset + itemSpace <= size() &&
	    itemSpace >= sizeof(Item) &&
	    itemSpace >= item->fullSize()) {
		return ItemPtr(this, m_header.size, itemOffset, item->fullSize());
	} else {
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemOffset:" << itemOffset;
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemOffset >= sizeof(Header):" << (itemOffset >= sizeof(Header));
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemSpace >= sizeof(Item):" << (itemSpace >= sizeof(Item));
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemSpace >= item->fullSize():" << (itemSpace >= item->fullSize());
		return ItemPtr(this, m_header.size, 0, 0);
	}
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size_t size) {
	oxTrace("ox::ptrarith::NodeBuffer::malloc") << "Size:" << size;
	size_t fullSize = size + sizeof(Item);
	if (m_header.size - m_header.bytesUsed >= fullSize) {
		auto last = lastItem();
		size_t addr = 0;
		if (last.valid()) {
			addr = last.offset() + last.size();
		} else {
			// there is no first item, so this must be the first item
			if (!m_header.firstItem) {
				oxTrace("ox::ptrarith::NodeBuffer::malloc") << "No first item, initializing.";
				m_header.firstItem = sizeof(m_header);
				addr = m_header.firstItem;
			}
		}
		auto out = ItemPtr(this, m_header.size, addr, fullSize);
		if (out.valid()) {
			new (out) Item;
			out->setSize(size);

			auto first = firstItem();
			auto oldLast = last;
			out->next = first.offset();
			if (first.valid()) {
				first->prev = out.offset();
			} else {
				oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid first element pointer.";
				return nullptr;
			}

			if (oldLast.valid()) {
				out->prev = oldLast.offset();
				oldLast->next = out.offset();
			} else { // check to see if this is the first allocation
				if (out.offset() != first.offset()) {
					// if this is not the first allocation, there should be an oldLast
					oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid last element pointer.";
					return nullptr;
				}
				out->prev = out.offset();
			}
			m_header.bytesUsed += out.size();
		} else {
			oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "Unknown";
			return nullptr;
		}
		oxTrace("ox::ptrarith::NodeBuffer::malloc") << "Offset:" << out.offset();
		return out;
	}
	oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "Insufficient space:" << fullSize << "needed," << available() << "available";
	return nullptr;
}

template<typename size_t, typename Item>
Error NodeBuffer<size_t, Item>::free(ItemPtr item) {
	oxTrace("ox::ptrarith::NodeBuffer::free") << "offset:" << item.offset();
	auto prev = this->prev(item);
	auto next = this->next(item);
	if (prev.valid() && next.valid()) {
		if (next != item) {
			prev->next = next;
			next->prev = prev;
			if (item.offset() == m_header.firstItem) {
				m_header.firstItem = next;
			}
		} else {
			// only one item, null out first
			oxTrace("ox::ptrarith::NodeBuffer::free") << "Nulling out firstItem.";
			m_header.firstItem = 0;
		}
	} else {
		if (!prev.valid()) {
			oxTrace("ox::ptrarith::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer:" << prev.offset();
			return OxError(1);
		}
		if (!next.valid()) {
			oxTrace("ox::ptrarith::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer:" << next.offset();
			return OxError(1);
		}
	}
	m_header.bytesUsed -= item.size();
	return OxError(0);
}

template<typename size_t, typename Item>
Error NodeBuffer<size_t, Item>::setSize(size_t size) {
	oxTrace("ox::ptrarith::NodeBuffer::setSize") << size;
	auto last = lastItem();
	auto end = last.valid() ? last.end() : sizeof(m_header);
	oxTrace("ox::ptrarith::NodeBuffer::setSize") << "end:" << end;
	if (end > size) {
		return OxError(1);
	} else {
		m_header.size = size;
		return OxError(0);
	}
}

template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::size() {
	return m_header.size;
}

template<typename size_t, typename Item>
bool NodeBuffer<size_t, Item>::valid(size_t maxSize) {
	return m_header.size <= maxSize;
}

template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::available() {
	return m_header.size - m_header.bytesUsed;
}

template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::spaceNeeded(size_t size) {
	return sizeof(Item) + size;
}

template<typename size_t, typename Item>
template<typename F>
void NodeBuffer<size_t, Item>::compact(F cb) {
	auto src = firstItem();
	auto dest = ptr(sizeof(*this));
	while (src.valid() && dest.valid() && dest.offset() < src.offset()) {
		// move node
		ox_memcpy(dest, src, src.size());
		cb(src, dest);
		// update surrounding nodes
		auto prev = ptr(dest->prev);
		if (prev.valid()) {
			prev->next = dest;
		}
		auto next = ptr(dest->next);
		if (next.valid()) {
			next->prev = dest;
		}
		// update iterators
		src = ptr(dest->next);
		dest = ptr(dest.offset() + dest.size());
	}
}

template<typename size_t, typename Item>
void NodeBuffer<size_t, Item>::truncate() {
	m_header.size = m_header.bytesUsed;
}

template<typename size_t, typename Item>
uint8_t *NodeBuffer<size_t, Item>::data() {
	return reinterpret_cast<uint8_t*>(ptr(sizeof(*this)).get());
}

template<typename size_t>
struct __attribute__((packed)) Item {
	public:
		ox::LittleEndian<size_t> prev = 0;
		ox::LittleEndian<size_t> next = 0;

	private:
		ox::LittleEndian<size_t> m_size = sizeof(Item);

	public:
		size_t size() const {
			return m_size;
		}

		void setSize(size_t size) {
			m_size = size;
		}
};

}
<commit_msg>[ox/ptrarith] Fix NodeBuffer::compact to iterate over items when item already in correct location<commit_after>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include <ox/std/trace.hpp>

#include "ptr.hpp"

namespace ox::ptrarith {

template<typename size_t, typename Item>
class __attribute__((packed)) NodeBuffer {

	public:
		struct __attribute__((packed)) Header {
			ox::LittleEndian<size_t> size = sizeof(Header); // capacity
			ox::LittleEndian<size_t> bytesUsed = sizeof(Header);
			ox::LittleEndian<size_t> firstItem = 0;
		};

		using ItemPtr = Ptr<Item, size_t, sizeof(Header)>;

		class Iterator {
			private:
				NodeBuffer *m_buffer = nullptr;
				ItemPtr m_current;
				size_t m_it = 0;

			public:
				Iterator(NodeBuffer *buffer, ItemPtr current) {
					m_buffer = buffer;
					m_current = current;
					oxTrace("ox::ptrarith::Iterator::start") << current.offset();
				}

				operator const Item*() const {
					return m_current;
				}

				ItemPtr ptr() {
					return m_current;
				}

				Item *get() {
					return m_current;
				}

				operator ItemPtr() {
					return m_current;
				}

				operator Item*() {
					return m_current;
				}

				const Item *operator->() const {
					return m_current;
				}

				Item *operator->() {
					return m_current;
				}

				[[nodiscard]] bool valid() const noexcept {
					return m_current.valid();
				}

				bool hasNext() {
					if (m_current.valid()) {
						oxTrace("ox::ptrarith::NodeBuffer::Iterator::hasNext::current") << m_current.offset();
						auto next = m_buffer->next(m_current);
						return next.valid() && m_buffer->firstItem() != next;
					}
					return false;
				}

				void next() {
					oxTrace("ox::ptrarith::NodeBuffer::Iterator::next") << m_it++;
					if (hasNext()) {
						m_current = m_buffer->next(m_current);
					} else {
						m_current = nullptr;
					}
				}
		};

		Header m_header;

	public:
		NodeBuffer() = default;

		NodeBuffer(const NodeBuffer &other);

		explicit NodeBuffer(size_t size);

		const Iterator iterator() const;

		Iterator iterator();

		ItemPtr firstItem();

		ItemPtr lastItem();

		/**
		 * @return the data section of the given item
		 */
		template<typename T>
		Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr);

		[[nodiscard]] ItemPtr prev(Item *item);

		[[nodiscard]] ItemPtr next(Item *item);

		[[nodiscard]] ItemPtr ptr(size_t offset);

		[[nodiscard]] ItemPtr ptr(void *item);

		[[nodiscard]] ItemPtr malloc(size_t size);

		[[nodiscard]] ox::Error free(ItemPtr item);

		[[nodiscard]] bool valid(size_t maxSize);

		/**
		 * Set size, capacity.
		 */
		[[nodiscard]] ox::Error setSize(size_t size);

		/**
		 * Get size, capacity.
		 * @return capacity
		 */
		size_t size();

		/**
		 * @return the bytes still available in this NodeBuffer
		 */
		size_t available();

		/**
		 * @return the actual number a bytes need to store the given number of
		 * bytes
		 */
		size_t spaceNeeded(size_t size);

		template<typename F>
		void compact(F cb = [](uint64_t, ItemPtr) {});

		void truncate();

	private:
		uint8_t *data();

};

template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(size_t size) {
	m_header.size = size;
}

template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other) {
	ox_memcpy(this, &other, other.size());
}

template<typename size_t, typename Item>
const typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() const {
	return Iterator(this, firstItem());
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() {
	oxTrace("ox::ptrarith::NodeBuffer::iterator::size") << m_header.size;
	return Iterator(this, firstItem());
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::firstItem() {
	//oxTrace("ox::ptrarith::NodeBuffer::firstItem") << m_header.firstItem;
	return ptr(m_header.firstItem);
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem() {
	auto first = ptr(m_header.firstItem);
	if (first.valid()) {
		return prev(first);
	}
	return nullptr;
}

template<typename size_t, typename Item>
template<typename T>
Ptr<T, size_t, sizeof(Item)> NodeBuffer<size_t, Item>::dataOf(ItemPtr ip) {
	auto out = ip.template subPtr<T>(sizeof(Item));
	oxAssert(out.size() == ip.size() - sizeof(Item), "Sub Ptr has invalid size.");
	return out;
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) {
	return ptr(item->prev);
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *item) {
	return ptr(item->next);
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) {
	// make sure this can be read as an Item, and then use Item::size for the size
	std::size_t itemSpace = m_header.size - itemOffset;
	auto item = reinterpret_cast<Item*>(reinterpret_cast<uint8_t*>(this) + itemOffset);
	if (itemOffset >= sizeof(Header) &&
	    itemOffset + itemSpace <= size() &&
	    itemSpace >= sizeof(Item) &&
	    itemSpace >= item->fullSize()) {
		return ItemPtr(this, m_header.size, itemOffset, item->fullSize());
	} else {
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemOffset:" << itemOffset;
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemOffset >= sizeof(Header):" << (itemOffset >= sizeof(Header));
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemSpace >= sizeof(Item):" << (itemSpace >= sizeof(Item));
		//oxTrace("ox::ptrarith::NodeBuffer::ptr::null") << "itemSpace >= item->fullSize():" << (itemSpace >= item->fullSize());
		return ItemPtr(this, m_header.size, 0, 0);
	}
}

template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size_t size) {
	oxTrace("ox::ptrarith::NodeBuffer::malloc") << "Size:" << size;
	size_t fullSize = size + sizeof(Item);
	if (m_header.size - m_header.bytesUsed >= fullSize) {
		auto last = lastItem();
		size_t addr = 0;
		if (last.valid()) {
			addr = last.offset() + last.size();
		} else {
			// there is no first item, so this must be the first item
			if (!m_header.firstItem) {
				oxTrace("ox::ptrarith::NodeBuffer::malloc") << "No first item, initializing.";
				m_header.firstItem = sizeof(m_header);
				addr = m_header.firstItem;
			}
		}
		auto out = ItemPtr(this, m_header.size, addr, fullSize);
		if (out.valid()) {
			new (out) Item;
			out->setSize(size);

			auto first = firstItem();
			auto oldLast = last;
			out->next = first.offset();
			if (first.valid()) {
				first->prev = out.offset();
			} else {
				oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid first element pointer.";
				return nullptr;
			}

			if (oldLast.valid()) {
				out->prev = oldLast.offset();
				oldLast->next = out.offset();
			} else { // check to see if this is the first allocation
				if (out.offset() != first.offset()) {
					// if this is not the first allocation, there should be an oldLast
					oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid last element pointer.";
					return nullptr;
				}
				out->prev = out.offset();
			}
			m_header.bytesUsed += out.size();
		} else {
			oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "Unknown";
			return nullptr;
		}
		oxTrace("ox::ptrarith::NodeBuffer::malloc") << "Offset:" << out.offset();
		return out;
	}
	oxTrace("ox::ptrarith::NodeBuffer::malloc::fail") << "Insufficient space:" << fullSize << "needed," << available() << "available";
	return nullptr;
}

template<typename size_t, typename Item>
Error NodeBuffer<size_t, Item>::free(ItemPtr item) {
	oxTrace("ox::ptrarith::NodeBuffer::free") << "offset:" << item.offset();
	auto prev = this->prev(item);
	auto next = this->next(item);
	if (prev.valid() && next.valid()) {
		if (next != item) {
			prev->next = next;
			next->prev = prev;
			if (item.offset() == m_header.firstItem) {
				m_header.firstItem = next;
			}
		} else {
			// only one item, null out first
			oxTrace("ox::ptrarith::NodeBuffer::free") << "Nulling out firstItem.";
			m_header.firstItem = 0;
		}
	} else {
		if (!prev.valid()) {
			oxTrace("ox::ptrarith::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer:" << prev.offset();
			return OxError(1);
		}
		if (!next.valid()) {
			oxTrace("ox::ptrarith::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer:" << next.offset();
			return OxError(1);
		}
	}
	m_header.bytesUsed -= item.size();
	return OxError(0);
}

template<typename size_t, typename Item>
Error NodeBuffer<size_t, Item>::setSize(size_t size) {
	oxTrace("ox::ptrarith::NodeBuffer::setSize") << size;
	auto last = lastItem();
	auto end = last.valid() ? last.end() : sizeof(m_header);
	oxTrace("ox::ptrarith::NodeBuffer::setSize") << "end:" << end;
	if (end > size) {
		return OxError(1);
	} else {
		m_header.size = size;
		return OxError(0);
	}
}

template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::size() {
	return m_header.size;
}

template<typename size_t, typename Item>
bool NodeBuffer<size_t, Item>::valid(size_t maxSize) {
	return m_header.size <= maxSize;
}

template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::available() {
	return m_header.size - m_header.bytesUsed;
}

template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::spaceNeeded(size_t size) {
	return sizeof(Item) + size;
}

template<typename size_t, typename Item>
template<typename F>
void NodeBuffer<size_t, Item>::compact(F cb) {
	auto src = firstItem();
	auto dest = ptr(sizeof(*this));
	while (src.valid() && dest.valid() && dest.offset() <= src.offset()) {
		// move node
		ox_memcpy(dest, src, src.size());
		cb(src, dest);
		// update surrounding nodes
		auto prev = ptr(dest->prev);
		if (prev.valid()) {
			prev->next = dest;
		}
		auto next = ptr(dest->next);
		if (next.valid()) {
			next->prev = dest;
		}
		// update iterators
		src = ptr(dest->next);
		dest = ptr(dest.offset() + dest.size());
	}
}

template<typename size_t, typename Item>
void NodeBuffer<size_t, Item>::truncate() {
	m_header.size = m_header.bytesUsed;
}

template<typename size_t, typename Item>
uint8_t *NodeBuffer<size_t, Item>::data() {
	return reinterpret_cast<uint8_t*>(ptr(sizeof(*this)).get());
}

template<typename size_t>
struct __attribute__((packed)) Item {
	public:
		ox::LittleEndian<size_t> prev = 0;
		ox::LittleEndian<size_t> next = 0;

	private:
		ox::LittleEndian<size_t> m_size = sizeof(Item);

	public:
		size_t size() const {
			return m_size;
		}

		void setSize(size_t size) {
			m_size = size;
		}
};

}
<|endoftext|>