<commit_before>/*************************************************************************
 *
 *  $RCSfile: customshapeitem.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-04-02 14:07:39 $
 *
 *  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 _SDASITM_HXX
#include "sdasitm.hxx"
#endif
#include "svdattr.hxx"

using namespace ::std;
using namespace com::sun::star;

SdrCustomShapeEngineItem::SdrCustomShapeEngineItem()
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_ENGINE, String() )
{}
SdrCustomShapeEngineItem::SdrCustomShapeEngineItem( const String& rVal )
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_ENGINE, rVal )
{}

SdrCustomShapeDataItem::SdrCustomShapeDataItem()
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_DATA, String() )
{}
SdrCustomShapeDataItem::SdrCustomShapeDataItem( const String& rVal )
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_DATA, rVal )
{}

bool SdrCustomShapeGeometryItem::PropertyEq::operator()( const rtl::OUString& r1, const rtl::OUString& r2 ) const
{
    return r1.equals( r2 );
}
bool SdrCustomShapeGeometryItem::PropertyPairEq::operator()( const SdrCustomShapeGeometryItem::PropertyPair& r1, const SdrCustomShapeGeometryItem::PropertyPair& r2 ) const
{
    return ( r1.first.equals( r2.first ) ) && ( r1.second.equals( r2.second ) );
}
size_t SdrCustomShapeGeometryItem::PropertyPairHash::operator()( const SdrCustomShapeGeometryItem::PropertyPair &r1 ) const
{
    return (size_t)r1.first.hashCode() + r1.second.hashCode();
};

TYPEINIT1_AUTOFACTORY( SdrCustomShapeGeometryItem, SfxPoolItem );
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem()
:   SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{}
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem( const uno::Sequence< beans::PropertyValue >& rVal )
:   SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{
    sal_Int32 i, j;
    aPropSeq = rVal;

    // hashing property values
    beans::PropertyValue* pPropValues = aPropSeq.getArray();
    const rtl::OUString* pPtr = NULL;
    for ( i = 0; i < aPropSeq.getLength(); i++ )
    {
        beans::PropertyValue& rPropVal = aPropSeq[ i ];
        aPropHashMap[ rPropVal.Name ] = i;
        if ( rPropVal.Value.getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {
            uno::Sequence< beans::PropertyValue >& rPropSeq = *( uno::Sequence< beans::PropertyValue >*)rPropVal.Value.getValue();
            for ( j = 0; j < rPropSeq.getLength(); j++ )
            {
                beans::PropertyValue& rPropVal2 = rPropSeq[ j ];
                aPropPairHashMap[ PropertyPair( rPropVal.Name, rPropVal2.Name ) ] = j;
            }
        }
    }
}

com::sun::star::uno::Any* SdrCustomShapeGeometryItem::GetPropertyValueByName( const rtl::OUString& rPropName )
{
    com::sun::star::uno::Any* pRet = NULL;
    PropertyHashMap::iterator aHashIter( aPropHashMap.find( rPropName ) );
    if ( aHashIter != aPropHashMap.end() )
        pRet = &aPropSeq[ (*aHashIter).second ].Value;
    return pRet;
}

com::sun::star::uno::Any* SdrCustomShapeGeometryItem::GetPropertyValueByName( const rtl::OUString& rSequenceName, const rtl::OUString& rPropName )
{
    com::sun::star::uno::Any* pRet = NULL;
    com::sun::star::uno::Any* pSeqAny = GetPropertyValueByName( rSequenceName );
    if ( pSeqAny )
    {
        if ( pSeqAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {
            PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rSequenceName, rPropName ) ) );
            if ( aHashIter != aPropPairHashMap.end() )
            {
                ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                    *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());
                pRet = &rSecSequence[ (*aHashIter).second ].Value;
            }
        }
    }
    return pRet;
}

void SdrCustomShapeGeometryItem::SetPropertyValue( const com::sun::star::beans::PropertyValue& rPropVal )
{
    com::sun::star::uno::Any* pAny = GetPropertyValueByName( rPropVal.Name );
    if ( pAny )
        *pAny = rPropVal.Value;
    else
    {
        sal_uInt32 nIndex = aPropSeq.getLength();
        aPropSeq.realloc( nIndex + 1 );
        aPropSeq[ nIndex ] = rPropVal ;

        aPropHashMap[ rPropVal.Name ] = nIndex;
    }
}

void SdrCustomShapeGeometryItem::SetPropertyValue( const rtl::OUString& rSequenceName, const com::sun::star::beans::PropertyValue& rPropVal )
{
    com::sun::star::uno::Any* pAny = GetPropertyValueByName( rSequenceName, rPropVal.Name );
    if ( pAny )
        *pAny = rPropVal.Value;
    else
    {
        com::sun::star::uno::Any* pSeqAny = GetPropertyValueByName( rSequenceName );
        if( pSeqAny == NULL )
        {
            ::com::sun::star::uno::Sequence < beans::PropertyValue > aSeq;
            beans::PropertyValue aValue;
            aValue.Name = rSequenceName;
            aValue.Value = ::com::sun::star::uno::makeAny( aSeq );
            SetPropertyValue( aValue );

            pSeqAny = GetPropertyValueByName( rSequenceName );
        }

        DBG_ASSERT( pSeqAny, "SdrCustomShapeGeometryItem::SetPropertyValue() - No Value??" );

        if( pSeqAny )
        {
            if ( pSeqAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
            {
                PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rSequenceName, rPropVal.Name ) ) );
                if ( aHashIter != aPropPairHashMap.end() )
                {
                    ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                        *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());
                    rSecSequence[ (*aHashIter).second ].Value = rPropVal.Value;
                }
                else
                {
                    ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                        *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());

                    sal_Int32 nCount = rSecSequence.getLength();
                    rSecSequence.realloc( nCount + 1 );
                    rSecSequence[ nCount ] = rPropVal;

                    aPropPairHashMap[ PropertyPair( rSequenceName, rPropVal.Name ) ] = nCount;
                }
            }
        }
    }
}

SdrCustomShapeGeometryItem::~SdrCustomShapeGeometryItem()
{
}
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem( SvStream& rIn, sal_uInt16 nVersion ):
    SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{
    if ( nVersion )
    {

    }
}
int __EXPORT SdrCustomShapeGeometryItem::operator==( const SfxPoolItem& rCmp ) const
{
    int bRet = SfxPoolItem::operator==( rCmp );
    if ( bRet )
        bRet = ((SdrCustomShapeGeometryItem&)rCmp).aPropSeq == aPropSeq;
    return bRet;
}

SfxItemPresentation __EXPORT SdrCustomShapeGeometryItem::GetPresentation(
    SfxItemPresentation ePresentation, SfxMapUnit eCoreMetric,
    SfxMapUnit ePresentationMetric, XubString &rText, const IntlWrapper *) const
{
    rText += sal_Unicode( ' ' );
    if ( ePresentation == SFX_ITEM_PRESENTATION_COMPLETE )
    {
        XubString aStr;
//      SdrItemPool::TakeItemName( Which(), aStr );
        aStr += sal_Unicode( ' ' );
        rText.Insert( aStr, 0 );
    }
    return ePresentation;
}

SfxPoolItem* __EXPORT SdrCustomShapeGeometryItem::Create( SvStream& rIn, sal_uInt16 nItemVersion ) const
{
    return new SdrCustomShapeGeometryItem( rIn, nItemVersion );
}

SvStream& __EXPORT SdrCustomShapeGeometryItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
{
    if ( nItemVersion )
    {

    }
    return rOut;
}

SfxPoolItem* __EXPORT SdrCustomShapeGeometryItem::Clone( SfxItemPool *pPool ) const
{
    SdrCustomShapeGeometryItem* pItem = new SdrCustomShapeGeometryItem( GetGeometry() );
//  SdrCustomShapeGeometryItem* pItem = new SdrCustomShapeGeometryItem( *this );

/*
    for ( i = 0; i < GetCount(); i++ )
    {
        const SdrCustomShapeAdjustmentValue& rVal = GetValue( i );
        pItem->SetValue( i, rVal );
    }
*/
    return pItem;
}

#ifdef SDR_ISPOOLABLE
int __EXPORT SdrCustomShapeGeometryItem::IsPoolable() const
{
    USHORT nId=Which();
    return nId < SDRATTR_NOTPERSIST_FIRST || nId > SDRATTR_NOTPERSIST_LAST;
}
#endif
sal_uInt16 SdrCustomShapeGeometryItem::GetVersion( sal_uInt16 nFileFormatVersion ) const
{
    return 1;
}
sal_Bool SdrCustomShapeGeometryItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
{
    rVal <<= aPropSeq;
    return sal_True;
}
sal_Bool SdrCustomShapeGeometryItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
{
    if ( ! ( rVal >>= aPropSeq ) )
        return sal_False;
    else
        return sal_True;
}
const uno::Sequence< beans::PropertyValue >& SdrCustomShapeGeometryItem::GetGeometry() const
{
    return aPropSeq;
}
/*
const uno::Any* GetValueByName( const rtl::OUString& rProperty ) const
{

}
*/
SdrCustomShapeReplacementURLItem::SdrCustomShapeReplacementURLItem()
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_REPLACEMENT_URL, String() )
{}
SdrCustomShapeReplacementURLItem::SdrCustomShapeReplacementURLItem( const String& rVal )
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_REPLACEMENT_URL, rVal )
{}

<commit_msg>INTEGRATION: CWS sj09 (1.2.8); FILE MERGED 2004/08/04 18:43:58 sj 1.2.8.1: added methods to remove property values<commit_after>/*************************************************************************
 *
 *  $RCSfile: customshapeitem.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-10-12 14:14:49 $
 *
 *  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 _SDASITM_HXX
#include "sdasitm.hxx"
#endif
#include "svdattr.hxx"

using namespace ::std;
using namespace com::sun::star;

SdrCustomShapeEngineItem::SdrCustomShapeEngineItem()
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_ENGINE, String() )
{}
SdrCustomShapeEngineItem::SdrCustomShapeEngineItem( const String& rVal )
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_ENGINE, rVal )
{}

SdrCustomShapeDataItem::SdrCustomShapeDataItem()
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_DATA, String() )
{}
SdrCustomShapeDataItem::SdrCustomShapeDataItem( const String& rVal )
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_DATA, rVal )
{}

bool SdrCustomShapeGeometryItem::PropertyEq::operator()( const rtl::OUString& r1, const rtl::OUString& r2 ) const
{
    return r1.equals( r2 );
}
bool SdrCustomShapeGeometryItem::PropertyPairEq::operator()( const SdrCustomShapeGeometryItem::PropertyPair& r1, const SdrCustomShapeGeometryItem::PropertyPair& r2 ) const
{
    return ( r1.first.equals( r2.first ) ) && ( r1.second.equals( r2.second ) );
}
size_t SdrCustomShapeGeometryItem::PropertyPairHash::operator()( const SdrCustomShapeGeometryItem::PropertyPair &r1 ) const
{
    return (size_t)r1.first.hashCode() + r1.second.hashCode();
};

TYPEINIT1_AUTOFACTORY( SdrCustomShapeGeometryItem, SfxPoolItem );
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem()
:   SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{}
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem( const uno::Sequence< beans::PropertyValue >& rVal )
:   SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{
    sal_Int32 i, j;
    aPropSeq = rVal;

    // hashing property values
    beans::PropertyValue* pPropValues = aPropSeq.getArray();
    const rtl::OUString* pPtr = NULL;
    for ( i = 0; i < aPropSeq.getLength(); i++ )
    {
        beans::PropertyValue& rPropVal = aPropSeq[ i ];
        aPropHashMap[ rPropVal.Name ] = i;
        if ( rPropVal.Value.getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {
            uno::Sequence< beans::PropertyValue >& rPropSeq = *( uno::Sequence< beans::PropertyValue >*)rPropVal.Value.getValue();
            for ( j = 0; j < rPropSeq.getLength(); j++ )
            {
                beans::PropertyValue& rPropVal2 = rPropSeq[ j ];
                aPropPairHashMap[ PropertyPair( rPropVal.Name, rPropVal2.Name ) ] = j;
            }
        }
    }
}

com::sun::star::uno::Any* SdrCustomShapeGeometryItem::GetPropertyValueByName( const rtl::OUString& rPropName )
{
    com::sun::star::uno::Any* pRet = NULL;
    PropertyHashMap::iterator aHashIter( aPropHashMap.find( rPropName ) );
    if ( aHashIter != aPropHashMap.end() )
        pRet = &aPropSeq[ (*aHashIter).second ].Value;
    return pRet;
}

com::sun::star::uno::Any* SdrCustomShapeGeometryItem::GetPropertyValueByName( const rtl::OUString& rSequenceName, const rtl::OUString& rPropName )
{
    com::sun::star::uno::Any* pRet = NULL;
    com::sun::star::uno::Any* pSeqAny = GetPropertyValueByName( rSequenceName );
    if ( pSeqAny )
    {
        if ( pSeqAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {
            PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rSequenceName, rPropName ) ) );
            if ( aHashIter != aPropPairHashMap.end() )
            {
                ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                    *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());
                pRet = &rSecSequence[ (*aHashIter).second ].Value;
            }
        }
    }
    return pRet;
}

void SdrCustomShapeGeometryItem::SetPropertyValue( const com::sun::star::beans::PropertyValue& rPropVal )
{
    com::sun::star::uno::Any* pAny = GetPropertyValueByName( rPropVal.Name );
    if ( pAny )
    {   // property is already available
        sal_Int32 i;
        if ( pAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {   // old property is a sequence->each entry has to be removed from the HashPairMap
            ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pAny->getValue());
            for ( i = 0; i < rSecSequence.getLength(); i++ )
            {
                PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rPropVal.Name, rSecSequence[ i ].Name ) ) );
                if ( aHashIter != aPropPairHashMap.end() )
                    aPropPairHashMap.erase( aHashIter );
            }
        }
        *pAny = rPropVal.Value;
        if ( rPropVal.Value.getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {   // the new property is a sequence->each entry has to be inserted into the HashPairMap
            ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pAny->getValue());
            for ( i = 0; i < rSecSequence.getLength(); i++ )
            {
                beans::PropertyValue& rPropVal2 = rSecSequence[ i ];
                aPropPairHashMap[ PropertyPair( rPropVal.Name, rPropVal2.Name ) ] = i;
            }
        }
    }
    else
    {   // its a new property
        sal_uInt32 nIndex = aPropSeq.getLength();
        aPropSeq.realloc( nIndex + 1 );
        aPropSeq[ nIndex ] = rPropVal ;

        aPropHashMap[ rPropVal.Name ] = nIndex;
    }
}

void SdrCustomShapeGeometryItem::SetPropertyValue( const rtl::OUString& rSequenceName, const com::sun::star::beans::PropertyValue& rPropVal )
{
    com::sun::star::uno::Any* pAny = GetPropertyValueByName( rSequenceName, rPropVal.Name );
    if ( pAny ) // just replacing
        *pAny = rPropVal.Value;
    else
    {
        com::sun::star::uno::Any* pSeqAny = GetPropertyValueByName( rSequenceName );
        if( pSeqAny == NULL )
        {
            ::com::sun::star::uno::Sequence < beans::PropertyValue > aSeq;
            beans::PropertyValue aValue;
            aValue.Name = rSequenceName;
            aValue.Value = ::com::sun::star::uno::makeAny( aSeq );

            sal_uInt32 nIndex = aPropSeq.getLength();
            aPropSeq.realloc( nIndex + 1 );
            aPropSeq[ nIndex ] = aValue;
            aPropHashMap[ rSequenceName ] = nIndex;

            pSeqAny = &aPropSeq[ nIndex ].Value;
        }

        DBG_ASSERT( pSeqAny, "SdrCustomShapeGeometryItem::SetPropertyValue() - No Value??" );

        if( pSeqAny )
        {
            if ( pSeqAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
            {
                PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rSequenceName, rPropVal.Name ) ) );
                if ( aHashIter != aPropPairHashMap.end() )
                {
                    ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                        *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());
                    rSecSequence[ (*aHashIter).second ].Value = rPropVal.Value;
                }
                else
                {
                    ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                        *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());

                    sal_Int32 nCount = rSecSequence.getLength();
                    rSecSequence.realloc( nCount + 1 );
                    rSecSequence[ nCount ] = rPropVal;

                    aPropPairHashMap[ PropertyPair( rSequenceName, rPropVal.Name ) ] = nCount;
                }
            }
        }
    }
}

void SdrCustomShapeGeometryItem::ClearPropertyValue( const rtl::OUString& rPropName )
{
    if ( aPropSeq.getLength() )
    {
        PropertyHashMap::iterator aHashIter( aPropHashMap.find( rPropName ) );
        if ( aHashIter != aPropHashMap.end() )
        {
             com::sun::star::uno::Any* pSeqAny = &aPropSeq[ (*aHashIter).second ].Value;
            if ( pSeqAny )
            {
                if ( pSeqAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
                {
                    ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                        *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());

                    sal_Int32 i;
                    for ( i = 0; i < rSecSequence.getLength(); i++ )
                    {
                        PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rPropName, rSecSequence[ i ].Name ) ) );
                        if ( aHashIter != aPropPairHashMap.end() )
                            aPropPairHashMap.erase( aHashIter );        // removing property from pair hashmap
                    }
                }
            }
            sal_Int32 nLength = aPropSeq.getLength();
            if ( nLength )
            {
                sal_Int32 nIndex  = (*aHashIter).second;
                if ( nIndex != ( nLength - 1 ) )                        // resizing sequence
                {
                    PropertyHashMap::iterator aHashIter2( aPropHashMap.find( aPropSeq[ nLength - 1 ].Name ) );
                    (*aHashIter2).second = nIndex;
                    aPropSeq[ (*aHashIter).second ] = aPropSeq[ aPropSeq.getLength() - 1 ];
                }
                aPropSeq.realloc( aPropSeq.getLength() - 1 );
            }
            aPropHashMap.erase( aHashIter );                            // removing property from hashmap
        }
    }
}

void SdrCustomShapeGeometryItem::ClearPropertyValue( const rtl::OUString& rSequenceName, const rtl::OUString& rPropName )
{
    com::sun::star::uno::Any* pSeqAny = GetPropertyValueByName( rSequenceName );
    if ( pSeqAny )
    {
        if ( pSeqAny->getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence < beans::PropertyValue >*)0) )
        {
            PropertyPairHashMap::iterator aHashIter( aPropPairHashMap.find( PropertyPair( rSequenceName, rPropName ) ) );
            if ( aHashIter != aPropPairHashMap.end() )
            {
                ::com::sun::star::uno::Sequence < beans::PropertyValue >& rSecSequence =
                    *((::com::sun::star::uno::Sequence < beans::PropertyValue >*)pSeqAny->getValue());

                sal_Int32 nLength = rSecSequence.getLength();
                if ( nLength )
                {
                    sal_Int32 nIndex  = (*aHashIter).second;
                    if ( nIndex != ( nLength - 1 ) )                            // resizing sequence
                    {
                        PropertyPairHashMap::iterator aHashIter2( aPropPairHashMap.find( PropertyPair( rSequenceName, rSecSequence[ nLength - 1 ].Name ) ) );
                        (*aHashIter2).second = nIndex;
                        rSecSequence[ nIndex ] = rSecSequence[ nLength - 1 ];
                    }
                    rSecSequence.realloc( aPropSeq.getLength() - 1 );
                }
                aPropPairHashMap.erase( aHashIter );
            }
        }
    }
}

SdrCustomShapeGeometryItem::~SdrCustomShapeGeometryItem()
{
}
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem( SvStream& rIn, sal_uInt16 nVersion ):
    SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{
    if ( nVersion )
    {

    }
}
int __EXPORT SdrCustomShapeGeometryItem::operator==( const SfxPoolItem& rCmp ) const
{
    int bRet = SfxPoolItem::operator==( rCmp );
    if ( bRet )
        bRet = ((SdrCustomShapeGeometryItem&)rCmp).aPropSeq == aPropSeq;
    return bRet;
}

SfxItemPresentation __EXPORT SdrCustomShapeGeometryItem::GetPresentation(
    SfxItemPresentation ePresentation, SfxMapUnit eCoreMetric,
    SfxMapUnit ePresentationMetric, XubString &rText, const IntlWrapper *) const
{
    rText += sal_Unicode( ' ' );
    if ( ePresentation == SFX_ITEM_PRESENTATION_COMPLETE )
    {
        XubString aStr;
//      SdrItemPool::TakeItemName( Which(), aStr );
        aStr += sal_Unicode( ' ' );
        rText.Insert( aStr, 0 );
    }
    return ePresentation;
}

SfxPoolItem* __EXPORT SdrCustomShapeGeometryItem::Create( SvStream& rIn, sal_uInt16 nItemVersion ) const
{
    return new SdrCustomShapeGeometryItem( rIn, nItemVersion );
}

SvStream& __EXPORT SdrCustomShapeGeometryItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
{
    if ( nItemVersion )
    {

    }
    return rOut;
}

SfxPoolItem* __EXPORT SdrCustomShapeGeometryItem::Clone( SfxItemPool *pPool ) const
{
    SdrCustomShapeGeometryItem* pItem = new SdrCustomShapeGeometryItem( GetGeometry() );
//  SdrCustomShapeGeometryItem* pItem = new SdrCustomShapeGeometryItem( *this );

/*
    for ( i = 0; i < GetCount(); i++ )
    {
        const SdrCustomShapeAdjustmentValue& rVal = GetValue( i );
        pItem->SetValue( i, rVal );
    }
*/
    return pItem;
}

#ifdef SDR_ISPOOLABLE
int __EXPORT SdrCustomShapeGeometryItem::IsPoolable() const
{
    USHORT nId=Which();
    return nId < SDRATTR_NOTPERSIST_FIRST || nId > SDRATTR_NOTPERSIST_LAST;
}
#endif
sal_uInt16 SdrCustomShapeGeometryItem::GetVersion( sal_uInt16 nFileFormatVersion ) const
{
    return 1;
}
sal_Bool SdrCustomShapeGeometryItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
{
    rVal <<= aPropSeq;
    return sal_True;
}
sal_Bool SdrCustomShapeGeometryItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
{
    if ( ! ( rVal >>= aPropSeq ) )
        return sal_False;
    else
        return sal_True;
}
const uno::Sequence< beans::PropertyValue >& SdrCustomShapeGeometryItem::GetGeometry() const
{
    return aPropSeq;
}
/*
const uno::Any* GetValueByName( const rtl::OUString& rProperty ) const
{

}
*/
SdrCustomShapeReplacementURLItem::SdrCustomShapeReplacementURLItem()
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_REPLACEMENT_URL, String() )
{}
SdrCustomShapeReplacementURLItem::SdrCustomShapeReplacementURLItem( const String& rVal )
:   SfxStringItem( SDRATTR_CUSTOMSHAPE_REPLACEMENT_URL, rVal )
{}

<|endoftext|>


<commit_before>#include "potholedetector.h"
#include <opencv2/video/video.hpp>
#include <sensor_msgs/image_encodings.h>
#include <pcl_ros/point_cloud.h>
#include <camera_info_manager/camera_info_manager.h>
#include <math.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

using namespace std;
using namespace cv;
using namespace pcl;

cv_bridge::CvImagePtr cv_ptr;
typedef pcl::PointCloud<pcl::PointXYZ> PCLCloud;
//Used to threshold the sum of a 60x60 matrix whose values are between 0-255
//Want mostly (>50%) white pixels (values around >200) in the matrix
//60x60x200ish = 720,000/2 = ~400000
const int sumThreshold = 400000;
const int sizeThreshold = 200;

constexpr double radians(double degrees)
{
    return degrees / 180.0 * M_PI;
}

constexpr int getDiff(int a, int b) {
    return abs(a - b);
}

void PotholeDetector::img_callback(const sensor_msgs::ImageConstPtr& msg)
{
    cv_ptr = cv_bridge::toCvCopy(msg, "");
    Mat orig = cv_ptr->image.clone();
    src = cv_ptr->image.clone();

    //Crops the image (removes sky)
    cv::Rect myROI(0, src.rows/2 - 100, src.cols, src.rows/2 - 50);
    src = src(myROI);

    cvtColor(src, src_gray, CV_BGR2GRAY);

    //Find the mean and stddev of the grayscale image in order to do adaptive thresholding
    Mat mean;
    Mat stddev;
    meanStdDev(src_gray, mean, stddev);

    double thresh = mean.at<double>(0,0) + (stddev.at<double>(0,0) * 2);
    if(thresh > 254)
    {
        thresh = 254;
    }

    threshold(src_gray, src_gray, thresh, 255, THRESH_BINARY);

    GaussianBlur(src_gray, src_gray, Size(gaussian_size, gaussian_size), 100, 100);

    vector<vector<Point>> contours;
    findContours(src_gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

    // Filter smaller contours
    for (unsigned int i = 0; i < contours.size(); i++) {
        vector<Point> curCont = contours[i];
        if (curCont.size() <= sizeThreshold) {
            contours.erase(contours.begin() + i);
            i--;
        }
    }

    // Get min / max Y and X
    int minY = 10000;
    int minX;
    int maxY = 0;
    int maxX;
    for (unsigned int i = 0; i < contours.size(); i++) {
        for (Point p : contours[i]) {
            int y = p.y;
            if (y > maxY) {
                maxY = y;
                maxX = p.x;
            } else if (y < minY) {
                minY = y;
                minX = p.x;
            }
        }

        // Delete if there is orange below or above
        Vec3b intensityAbove = orig.at<Vec3b>(minX, minY - 5);
        uchar greenAbove = intensityAbove.val[1];
        uchar redAbove = intensityAbove.val[2];
        Vec3b intensityBelow = orig.at<Vec3b>(maxX, maxY + 5);
        uchar greenBelow = intensityBelow.val[1];
        uchar redBelow = intensityBelow.val[2];
        if (getDiff(greenAbove, 125) > 50 && getDiff(redAbove, 240) > 50 && getDiff(greenBelow, 125) > 50 && getDiff(redBelow, 240) > 50) {    // Play with these thresholds
            contours.erase(contours.begin() + i);
            i--;
        }

        // Delete if the contour itself is orange
        Vec3b intensity = orig.at<Vec3b>((minX + maxX) / 2, (minY + maxY) / 2);
        uchar green = intensity.val[1];
        uchar red = intensity.val[2];
        if (getDiff(green, 125) > 50 && getDiff(red, 240) > 50) {    // Play with these thresholds
            contours.erase(contours.begin() + i);
            i--;
        }
    }

    /// Draw contours
    drawContours(src, contours, -1, Scalar(255), 2, 8);

    Mat cloudMat = Mat::zeros(orig.rows, orig.cols, CV_32F);
    cvtColor(src_gray, src_gray, CV_GRAY2BGR);

    cv_bridge::CvImage out_msg;
    out_msg.header   = msg->header;
    out_msg.encoding = msg->encoding;
    out_msg.image    = src_gray;

    cv_ptr->image = src;
    _pothole_filt_img.publish(cv_ptr->toImageMsg());
    _pothole_thres.publish(out_msg.toImageMsg());
    cloud = toPointCloud(cloudMat);
    _pothole_cloud.publish(cloud);
}

PotholeDetector::PotholeDetector(ros::NodeHandle &handle)
    : gaussian_size(7),
      _it(handle),
      tf_listener(handle)
{
    _src_img = _it.subscribe("/left/image_rect_color", 1, &PotholeDetector::img_callback, this);
    _pothole_filt_img = _it.advertise("/pothole_filt_img", 1);
    _pothole_thres = _it.advertise("/pothole_thres", 1);
    _pothole_cloud = handle.advertise<PCLCloud>("/pothole_cloud", 100);
}

PointCloud<PointXYZ>::Ptr PotholeDetector::toPointCloud(Mat src)
{
    PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
    for(int r = 0; r < src.rows; r++)
    {
        float *row = src.ptr<float>(r);
        for(int c = 0; c < src.cols; c++)
        {
            if(row[c] > 0)
            {
                cloud->points.push_back(PointXYZ(r, c, 0));
            }
        }
    }
	cloud->header.frame_id = "base_footprint";
	return cloud;
}<commit_msg>Pothole detector semi-working<commit_after>#include "potholedetector.h"
#include <opencv2/video/video.hpp>
#include <sensor_msgs/image_encodings.h>
#include <pcl_ros/point_cloud.h>
#include <camera_info_manager/camera_info_manager.h>
#include <math.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

using namespace std;
using namespace cv;
using namespace pcl;

cv_bridge::CvImagePtr cv_ptr;
typedef pcl::PointCloud<pcl::PointXYZ> PCLCloud;
//Used to threshold the sum of a 60x60 matrix whose values are between 0-255
//Want mostly (>50%) white pixels (values around >200) in the matrix
//60x60x200ish = 720,000/2 = ~400000
const int sumThreshold = 400000;
const int sizeThreshold = 200;
const int rOrange = 190;
const int gOrange = 60;
const int bOrange = 35;

double radians(double degrees)
{
    return degrees / 180.0 * M_PI;
}

int getDiff(int a, int b) {
    return abs(a - b);
}

void PotholeDetector::img_callback(const sensor_msgs::ImageConstPtr& msg)
{
    cv_ptr = cv_bridge::toCvCopy(msg, "");
    src = cv_ptr->image.clone();

    //Crops the image (removes sky)
    cv::Rect myROI(0, src.rows/2 - 100, src.cols, src.rows/2 - 50);
    src = src(myROI);
    Mat orig = src.clone();

    cvtColor(src, src_gray, CV_BGR2GRAY);

    //Find the mean and stddev of the grayscale image in order to do adaptive thresholding
    Mat mean;
    Mat stddev;
    meanStdDev(src_gray, mean, stddev);

    double thresh = mean.at<double>(0,0) + (stddev.at<double>(0,0) * 2);
    if(thresh > 254)
    {
        thresh = 254;
    }

    threshold(src_gray, src_gray, thresh, 255, THRESH_BINARY);

    GaussianBlur(src_gray, src_gray, Size(gaussian_size, gaussian_size),
            100, 100);

    vector<vector<Point>> contours;
    findContours(src_gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

    // Filter smaller contours
    for (vector<vector<Point>>::iterator it = contours.begin();
            it != contours.end(); ++it) {
        vector<Point> curCont = *it;
        if (curCont.size() <= sizeThreshold) {
            contours.erase(it);
            --it;
        }
    }
    for (vector<vector<Point>>::iterator it = contours.begin();
            it != contours.end(); ++it) {
        // Get min / max Y and X
        int minY = 10000;
        int minX = 10000;
        int maxY = 0;
        int maxX = 0;
        for (Point p : *it) {
            int x = p.x;
            if (x > maxX) {
                maxX = x;
            }
            if (x < minX) {
                minX = x;
            }
        }

        int centerX = (minX + maxX) / 2;

        for (Point p : *it) {
            int x = p.x;
            int y = p.y;
            if (x == centerX && y > maxY) {
                maxY = y;
            }
            if (x == centerX && y < minY) {
                minY = y;
            }
        }

        if (minY - 35 >= 0) {
            // Delete if there is orange below or above
            int blueAbove = 0;
            int greenAbove = 0;
            int redAbove = 0;
            int blueBelow = 0;
            int greenBelow = 0;
            int redBelow = 0;
            for (int j = 5; j < 36; j++) {
                blueAbove += orig.at<Vec3b>(minY - j, centerX)[0];
                greenAbove += orig.at<Vec3b>(minY - j, centerX)[1];
                redAbove += orig.at<Vec3b>(minY - j, centerX)[2];
                blueBelow += orig.at<Vec3b>(maxY + j, centerX)[0];
                greenBelow += orig.at<Vec3b>(maxY + j, centerX)[1];
                redBelow += orig.at<Vec3b>(maxY + j, centerX)[2];
            }
            blueAbove /= 30;
            greenAbove /= 30;
            redAbove /= 30;
            blueBelow /= 30;
            greenBelow /= 30;
            redBelow /= 30;
            if (getDiff(redAbove, rOrange) < 50
                    && getDiff(greenAbove, gOrange) < 50
                    && getDiff(blueAbove, bOrange) < 50
                    && getDiff(redBelow, rOrange) < 50
                    && getDiff(greenBelow, gOrange) < 50
                    && getDiff(blueBelow, bOrange) < 50) {
                contours.erase(it);
                --it;
            }

            // Delete if the contour itself is orange
            Vec3b intensity = orig.at<Vec3b>((minY + maxY) / 2, centerX);
            uchar blue = intensity.val[0];
            uchar green = intensity.val[1];
            uchar red = intensity.val[2];
            if (getDiff(red, rOrange) < 50 && getDiff(green, gOrange) < 50
                    && getDiff(blue, bOrange) < 50) {
                contours.erase(it);
                --it;
            }
        } else {
            contours.erase(it);
            --it;
        }
    }
    /// Draw contours
    drawContours(src, contours, -1, Scalar(255), 2, 8);

    Mat cloudMat = Mat::zeros(orig.rows, orig.cols, CV_32F);
    cvtColor(src_gray, src_gray, CV_GRAY2BGR);

    cv_bridge::CvImage out_msg;
    out_msg.header   = msg->header;
    out_msg.encoding = msg->encoding;
    out_msg.image    = src_gray;

    cv_ptr->image = src;
    _pothole_filt_img.publish(cv_ptr->toImageMsg());
    _pothole_thres.publish(out_msg.toImageMsg());
    cloud = toPointCloud(cloudMat);
    _pothole_cloud.publish(cloud);
}

PotholeDetector::PotholeDetector(ros::NodeHandle &handle)
    : gaussian_size(7),
      _it(handle),
      tf_listener(handle)
{
    _src_img = _it.subscribe("/left/image_rect_color", 1, &PotholeDetector::img_callback, this);
    _pothole_filt_img = _it.advertise("/pothole_filt_img", 1);
    _pothole_thres = _it.advertise("/pothole_thres", 1);
    _pothole_cloud = handle.advertise<PCLCloud>("/pothole_cloud", 100);
}

PointCloud<PointXYZ>::Ptr PotholeDetector::toPointCloud(Mat src)
{
    PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
    for(int r = 0; r < src.rows; r++)
    {
        float *row = src.ptr<float>(r);
        for(int c = 0; c < src.cols; c++)
        {
            if(row[c] > 0)
            {
                cloud->points.push_back(PointXYZ(r, c, 0));
            }
        }
    }
	cloud->header.frame_id = "base_footprint";
	return cloud;
}
<|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 2008 by Sun Microsystems, Inc.
 *
 * 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 <AnnotationWin.hxx>

#include <AnnotationMenuButton.hxx>
#include <PostItMgr.hxx>

#include <annotation.hrc>
#include <popup.hrc>
#include <cmdid.h>

#include <vcl/menu.hxx>

#include <svl/undo.hxx>
#include <unotools/syslocale.hxx>
#include <svl/languageoptions.hxx>

#include <editeng/postitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/langitem.hxx>

#include <editeng/editview.hxx>
#include <editeng/outliner.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editobj.hxx>

#include <docufld.hxx> // SwPostItField
#include <txtfld.hxx>
#include <ndtxt.hxx>
#include <view.hxx>
#include <wrtsh.hxx>
#include <docsh.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <SwUndoField.hxx>

#include <boost/scoped_ptr.hpp>

namespace sw { namespace annotation {

SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin,
                                  WinBits nBits,
                                  SwPostItMgr& aMgr,
                                  SwPostItBits aBits,
                                  SwSidebarItem& rSidebarItem,
                                  SwFmtFld* aField )
    : SwSidebarWin( rEditWin, nBits, aMgr, aBits, rSidebarItem )
    , mpFmtFld(aField)
    , mpFld( static_cast<SwPostItField*>(aField->GetFld()))
    , mpButtonPopup(0)
{
}

SwAnnotationWin::~SwAnnotationWin()
{
    delete mpButtonPopup;
}

void SwAnnotationWin::SetPostItText()
{
    // get text from SwPostItField and insert into our textview
    Engine()->SetModifyHdl( Link() );
    Engine()->EnableUndo( sal_False );
    mpFld = static_cast<SwPostItField*>(mpFmtFld->GetFld());
    if( mpFld->GetTextObject() )
        Engine()->SetText( *mpFld->GetTextObject() );
    else
    {
        Engine()->Clear();
        GetOutlinerView()->SetAttribs(DefaultItem());
        GetOutlinerView()->InsertText(mpFld->GetPar2(),false);
    }

    Engine()->ClearModifyFlag();
    Engine()->GetUndoManager().Clear();
    Engine()->EnableUndo( sal_True );
    Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
    Invalidate();
}

void SwAnnotationWin::UpdateData()
{
    if ( Engine()->IsModified() )
    {
        IDocumentUndoRedo & rUndoRedo(
            DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
        boost::scoped_ptr<SwField> pOldField;
        if (rUndoRedo.DoesUndo())
        {
            pOldField.reset(mpFld->Copy());
        }
        mpFld->SetPar2(Engine()->GetEditEngine().GetText());
        mpFld->SetTextObject(Engine()->CreateParaObject());
        if (rUndoRedo.DoesUndo())
        {
            SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
            SwPosition aPosition( pTxtFld->GetTxtNode() );
            aPosition.nContent = *pTxtFld->GetStart();
            rUndoRedo.AppendUndo(
                new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
        }
        // so we get a new layout of notes (anchor position is still the same and we would otherwise not get one)
        Mgr().SetLayout();
        // #i98686# if we have several views, all notes should update their text
        mpFmtFld->Broadcast(SwFmtFldHint( 0, SWFMTFLD_CHANGED));
        DocView().GetDocShell()->SetModified();
    }
    Engine()->ClearModifyFlag();
    Engine()->GetUndoManager().Clear();
}

void SwAnnotationWin::Delete()
{
    SwSidebarWin::Delete();
    // we delete the field directly, the Mgr cleans up the PostIt by listening
    DocView().GetWrtShellPtr()->GotoField(*mpFmtFld);
    GrabFocusToDocument();
    DocView().GetWrtShellPtr()->DelRight();
}

void SwAnnotationWin::GotoPos()
{
    DocView().GetDocShell()->GetWrtShell()->GotoField(*mpFmtFld);
}

sal_uInt32 SwAnnotationWin::MoveCaret()
{
    // if this is an answer, do not skip over all following ones, but insert directly behind the current one
    // but when just leaving a note, skip all following ones as well to continue typing
    return Mgr().IsAnswer()
           ? 1
           : 1 + CountFollowing();
}

//returns true, if there is another note right before this note
bool SwAnnotationWin::CalcFollow()
{
    SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
    SwPosition aPosition( pTxtFld->GetTxtNode() );
    aPosition.nContent = *pTxtFld->GetStart();
    SwTxtAttr * const pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
                    aPosition.nContent.GetIndex() - 1, RES_TXTATR_FIELD );
    const SwField* pFld = pTxtAttr ? pTxtAttr->GetFld().GetFld() : 0;
    return pFld && (pFld->Which()== RES_POSTITFLD);
}

// counts how many SwPostItField we have right after the current one
sal_uInt32 SwAnnotationWin::CountFollowing()
{
    sal_uInt32 aCount = 1;  // we start with 1, so we have to subtract one at the end again
    SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
    SwPosition aPosition( pTxtFld->GetTxtNode() );
    aPosition.nContent = *pTxtFld->GetStart();

    SwTxtAttr * pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
                                        aPosition.nContent.GetIndex() + 1,
                                        RES_TXTATR_FIELD );
    SwField* pFld = pTxtAttr
                    ? const_cast<SwField*>(pTxtAttr->GetFld().GetFld())
                    : 0;
    while ( pFld && ( pFld->Which()== RES_POSTITFLD ) )
    {
        aCount++;
        pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
                                        aPosition.nContent.GetIndex() + aCount,
                                        RES_TXTATR_FIELD );
        pFld = pTxtAttr
               ? const_cast<SwField*>(pTxtAttr->GetFld().GetFld())
               : 0;
    }
    return aCount - 1;
}

MenuButton* SwAnnotationWin::CreateMenuButton()
{
    mpButtonPopup = new PopupMenu(SW_RES(MN_ANNOTATION_BUTTON));
    XubString aText = mpButtonPopup->GetItemText( FN_DELETE_NOTE_AUTHOR );
    SwRewriter aRewriter;
    aRewriter.AddRule(UndoArg1,GetAuthor());
    aText = aRewriter.Apply(aText);
    mpButtonPopup->SetItemText(FN_DELETE_NOTE_AUTHOR,aText);
    MenuButton* pMenuButton = new AnnotationMenuButton( *this );
    pMenuButton->SetPopupMenu( mpButtonPopup );
    pMenuButton->Show();
    return pMenuButton;
}

void SwAnnotationWin::InitAnswer(OutlinerParaObject* pText)
{
    //collect our old meta data
    SwSidebarWin* pWin = Mgr().GetNextPostIt(KEY_PAGEUP, this);
    const SvtSysLocale aSysLocale;
    const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
    String aText = String(SW_RES(STR_REPLY));
        SwRewriter aRewriter;
        aRewriter.AddRule(UndoArg1, pWin->GetAuthor());
        aText = aRewriter.Apply(aText);
        aText.Append(String(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (")) +
        String(rLocalData.getDate( pWin->GetDate())) + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(", ")) +
        String(rLocalData.getTime( pWin->GetTime(),false)) + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("): \""))));
    GetOutlinerView()->InsertText(aText,false);

    // insert old, selected text or "..."
    // TOOD: iterate over all paragraphs, not only first one to find out if it is empty
    if (pText->GetTextObject().GetText(0).Len())
        GetOutlinerView()->GetEditView().InsertText(pText->GetTextObject());
    else
        GetOutlinerView()->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("...")),false);
    GetOutlinerView()->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"\n")),false);

    GetOutlinerView()->SetSelection(ESelection(0x0,0x0,0xFFFF,0xFFFF));
    SfxItemSet aAnswerSet( DocView().GetDocShell()->GetPool() );
    aAnswerSet.Put(SvxFontHeightItem(200,80,EE_CHAR_FONTHEIGHT));
    aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
    GetOutlinerView()->SetAttribs(aAnswerSet);
    GetOutlinerView()->SetSelection(ESelection(0xFFFF,0xFFFF,0xFFFF,0xFFFF));

    //remove all attributes and reset our standard ones
    GetOutlinerView()->GetEditView().RemoveAttribsKeepLanguages(true);
    GetOutlinerView()->SetAttribs(DefaultItem());
    // lets insert an undo step so the initial text can be easily deleted
    // but do not use UpdateData() directly, would set modified state again and reentrance into Mgr
    Engine()->SetModifyHdl( Link() );
    IDocumentUndoRedo & rUndoRedo(
        DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
    boost::scoped_ptr<SwField> pOldField;
    if (rUndoRedo.DoesUndo())
    {
        pOldField.reset(mpFld->Copy());
    }
    mpFld->SetPar2(Engine()->GetEditEngine().GetText());
    mpFld->SetTextObject(Engine()->CreateParaObject());
    if (rUndoRedo.DoesUndo())
    {
        SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
        SwPosition aPosition( pTxtFld->GetTxtNode() );
        aPosition.nContent = *pTxtFld->GetStart();
        rUndoRedo.AppendUndo(
            new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
    }
    Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
    Engine()->ClearModifyFlag();
    Engine()->GetUndoManager().Clear();
}

SvxLanguageItem SwAnnotationWin::GetLanguage(void)
{
    // set initial language for outliner
    sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( mpFld->GetLanguage() );
    sal_uInt16 nLangWhichId = 0;
    switch (nScriptType)
    {
        case SCRIPTTYPE_LATIN :    nLangWhichId = EE_CHAR_LANGUAGE ; break;
        case SCRIPTTYPE_ASIAN :    nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
        case SCRIPTTYPE_COMPLEX :  nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
        default: OSL_FAIL("GetLanguage: wrong script type");
    }
    return SvxLanguageItem(mpFld->GetLanguage(),nLangWhichId);
}

bool SwAnnotationWin::IsProtected()
{
    return SwSidebarWin::IsProtected() ||
           GetLayoutStatus() == SwPostItHelper::DELETED ||
           ( mpFmtFld ? mpFmtFld->IsProtect() : false );
}

String SwAnnotationWin::GetAuthor()
{
    return mpFld->GetPar1();
}

Date SwAnnotationWin::GetDate()
{
    return mpFld->GetDate();
}

Time SwAnnotationWin::GetTime()
{
    return mpFld->GetTime();
}

} } // end of namespace sw::annotation

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Resolves: fdo#33599 cursor in notes is reset to start on focus out/focus in<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 2008 by Sun Microsystems, Inc.
 *
 * 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 <AnnotationWin.hxx>

#include <AnnotationMenuButton.hxx>
#include <PostItMgr.hxx>

#include <annotation.hrc>
#include <popup.hrc>
#include <cmdid.h>

#include <vcl/menu.hxx>

#include <svl/undo.hxx>
#include <unotools/syslocale.hxx>
#include <svl/languageoptions.hxx>

#include <editeng/postitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/langitem.hxx>

#include <editeng/editview.hxx>
#include <editeng/outliner.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editobj.hxx>

#include <docufld.hxx> // SwPostItField
#include <txtfld.hxx>
#include <ndtxt.hxx>
#include <view.hxx>
#include <wrtsh.hxx>
#include <docsh.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <SwUndoField.hxx>

#include <boost/scoped_ptr.hpp>

namespace sw { namespace annotation {

SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin,
                                  WinBits nBits,
                                  SwPostItMgr& aMgr,
                                  SwPostItBits aBits,
                                  SwSidebarItem& rSidebarItem,
                                  SwFmtFld* aField )
    : SwSidebarWin( rEditWin, nBits, aMgr, aBits, rSidebarItem )
    , mpFmtFld(aField)
    , mpFld( static_cast<SwPostItField*>(aField->GetFld()))
    , mpButtonPopup(0)
{
}

SwAnnotationWin::~SwAnnotationWin()
{
    delete mpButtonPopup;
}

void SwAnnotationWin::SetPostItText()
{
    //If the cursor was visible, then make it visible again after
    //changing text, e.g. fdo#33599
    Cursor *pCursor = GetOutlinerView()->GetEditView().GetCursor();
    bool bCursorVisible = pCursor ? pCursor->IsVisible() : false;

    //If the new text is the same as the old text, keep the same insertion
    //point .e.g. fdo#33599
    mpFld = static_cast<SwPostItField*>(mpFmtFld->GetFld());
    rtl::OUString sNewText = mpFld->GetPar2();
    bool bTextUnchanged = sNewText.equals(Engine()->GetEditEngine().GetText());
    ESelection aOrigSelection(GetOutlinerView()->GetEditView().GetSelection());

    // get text from SwPostItField and insert into our textview
    Engine()->SetModifyHdl( Link() );
    Engine()->EnableUndo( sal_False );
    if( mpFld->GetTextObject() )
        Engine()->SetText( *mpFld->GetTextObject() );
    else
    {
        Engine()->Clear();
        GetOutlinerView()->SetAttribs(DefaultItem());
        GetOutlinerView()->InsertText(sNewText,false);
    }

    Engine()->ClearModifyFlag();
    Engine()->GetUndoManager().Clear();
    Engine()->EnableUndo( sal_True );
    Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
    if (bTextUnchanged)
        GetOutlinerView()->GetEditView().SetSelection(aOrigSelection);
    if (bCursorVisible)
        GetOutlinerView()->ShowCursor();
    Invalidate();
}

void SwAnnotationWin::UpdateData()
{
    if ( Engine()->IsModified() )
    {
        IDocumentUndoRedo & rUndoRedo(
            DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
        boost::scoped_ptr<SwField> pOldField;
        if (rUndoRedo.DoesUndo())
        {
            pOldField.reset(mpFld->Copy());
        }
        mpFld->SetPar2(Engine()->GetEditEngine().GetText());
        mpFld->SetTextObject(Engine()->CreateParaObject());
        if (rUndoRedo.DoesUndo())
        {
            SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
            SwPosition aPosition( pTxtFld->GetTxtNode() );
            aPosition.nContent = *pTxtFld->GetStart();
            rUndoRedo.AppendUndo(
                new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
        }
        // so we get a new layout of notes (anchor position is still the same and we would otherwise not get one)
        Mgr().SetLayout();
        // #i98686# if we have several views, all notes should update their text
        mpFmtFld->Broadcast(SwFmtFldHint( 0, SWFMTFLD_CHANGED));
        DocView().GetDocShell()->SetModified();
    }
    Engine()->ClearModifyFlag();
    Engine()->GetUndoManager().Clear();
}

void SwAnnotationWin::Delete()
{
    SwSidebarWin::Delete();
    // we delete the field directly, the Mgr cleans up the PostIt by listening
    DocView().GetWrtShellPtr()->GotoField(*mpFmtFld);
    GrabFocusToDocument();
    DocView().GetWrtShellPtr()->DelRight();
}

void SwAnnotationWin::GotoPos()
{
    DocView().GetDocShell()->GetWrtShell()->GotoField(*mpFmtFld);
}

sal_uInt32 SwAnnotationWin::MoveCaret()
{
    // if this is an answer, do not skip over all following ones, but insert directly behind the current one
    // but when just leaving a note, skip all following ones as well to continue typing
    return Mgr().IsAnswer()
           ? 1
           : 1 + CountFollowing();
}

//returns true, if there is another note right before this note
bool SwAnnotationWin::CalcFollow()
{
    SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
    SwPosition aPosition( pTxtFld->GetTxtNode() );
    aPosition.nContent = *pTxtFld->GetStart();
    SwTxtAttr * const pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
                    aPosition.nContent.GetIndex() - 1, RES_TXTATR_FIELD );
    const SwField* pFld = pTxtAttr ? pTxtAttr->GetFld().GetFld() : 0;
    return pFld && (pFld->Which()== RES_POSTITFLD);
}

// counts how many SwPostItField we have right after the current one
sal_uInt32 SwAnnotationWin::CountFollowing()
{
    sal_uInt32 aCount = 1;  // we start with 1, so we have to subtract one at the end again
    SwTxtFld* pTxtFld = mpFmtFld->GetTxtFld();
    SwPosition aPosition( pTxtFld->GetTxtNode() );
    aPosition.nContent = *pTxtFld->GetStart();

    SwTxtAttr * pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
                                        aPosition.nContent.GetIndex() + 1,
                                        RES_TXTATR_FIELD );
    SwField* pFld = pTxtAttr
                    ? const_cast<SwField*>(pTxtAttr->GetFld().GetFld())
                    : 0;
    while ( pFld && ( pFld->Which()== RES_POSTITFLD ) )
    {
        aCount++;
        pTxtAttr = pTxtFld->GetTxtNode().GetTxtAttrForCharAt(
                                        aPosition.nContent.GetIndex() + aCount,
                                        RES_TXTATR_FIELD );
        pFld = pTxtAttr
               ? const_cast<SwField*>(pTxtAttr->GetFld().GetFld())
               : 0;
    }
    return aCount - 1;
}

MenuButton* SwAnnotationWin::CreateMenuButton()
{
    mpButtonPopup = new PopupMenu(SW_RES(MN_ANNOTATION_BUTTON));
    XubString aText = mpButtonPopup->GetItemText( FN_DELETE_NOTE_AUTHOR );
    SwRewriter aRewriter;
    aRewriter.AddRule(UndoArg1,GetAuthor());
    aText = aRewriter.Apply(aText);
    mpButtonPopup->SetItemText(FN_DELETE_NOTE_AUTHOR,aText);
    MenuButton* pMenuButton = new AnnotationMenuButton( *this );
    pMenuButton->SetPopupMenu( mpButtonPopup );
    pMenuButton->Show();
    return pMenuButton;
}

void SwAnnotationWin::InitAnswer(OutlinerParaObject* pText)
{
    //collect our old meta data
    SwSidebarWin* pWin = Mgr().GetNextPostIt(KEY_PAGEUP, this);
    const SvtSysLocale aSysLocale;
    const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
    String aText = String(SW_RES(STR_REPLY));
        SwRewriter aRewriter;
        aRewriter.AddRule(UndoArg1, pWin->GetAuthor());
        aText = aRewriter.Apply(aText);
        aText.Append(String(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (")) +
        String(rLocalData.getDate( pWin->GetDate())) + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(", ")) +
        String(rLocalData.getTime( pWin->GetTime(),false)) + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("): \""))));
    GetOutlinerView()->InsertText(aText,false);

    // insert old, selected text or "..."
    // TOOD: iterate over all paragraphs, not only first one to find out if it is empty
    if (pText->GetTextObject().GetText(0).Len())
        GetOutlinerView()->GetEditView().InsertText(pText->GetTextObject());
    else
        GetOutlinerView()->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("...")),false);
    GetOutlinerView()->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"\n")),false);

    GetOutlinerView()->SetSelection(ESelection(0x0,0x0,0xFFFF,0xFFFF));
    SfxItemSet aAnswerSet( DocView().GetDocShell()->GetPool() );
    aAnswerSet.Put(SvxFontHeightItem(200,80,EE_CHAR_FONTHEIGHT));
    aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
    GetOutlinerView()->SetAttribs(aAnswerSet);
    GetOutlinerView()->SetSelection(ESelection(0xFFFF,0xFFFF,0xFFFF,0xFFFF));

    //remove all attributes and reset our standard ones
    GetOutlinerView()->GetEditView().RemoveAttribsKeepLanguages(true);
    GetOutlinerView()->SetAttribs(DefaultItem());
    // lets insert an undo step so the initial text can be easily deleted
    // but do not use UpdateData() directly, would set modified state again and reentrance into Mgr
    Engine()->SetModifyHdl( Link() );
    IDocumentUndoRedo & rUndoRedo(
        DocView().GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
    boost::scoped_ptr<SwField> pOldField;
    if (rUndoRedo.DoesUndo())
    {
        pOldField.reset(mpFld->Copy());
    }
    mpFld->SetPar2(Engine()->GetEditEngine().GetText());
    mpFld->SetTextObject(Engine()->CreateParaObject());
    if (rUndoRedo.DoesUndo())
    {
        SwTxtFld *const pTxtFld = mpFmtFld->GetTxtFld();
        SwPosition aPosition( pTxtFld->GetTxtNode() );
        aPosition.nContent = *pTxtFld->GetStart();
        rUndoRedo.AppendUndo(
            new SwUndoFieldFromDoc(aPosition, *pOldField, *mpFld, 0, true));
    }
    Engine()->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
    Engine()->ClearModifyFlag();
    Engine()->GetUndoManager().Clear();
}

SvxLanguageItem SwAnnotationWin::GetLanguage(void)
{
    // set initial language for outliner
    sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( mpFld->GetLanguage() );
    sal_uInt16 nLangWhichId = 0;
    switch (nScriptType)
    {
        case SCRIPTTYPE_LATIN :    nLangWhichId = EE_CHAR_LANGUAGE ; break;
        case SCRIPTTYPE_ASIAN :    nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
        case SCRIPTTYPE_COMPLEX :  nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
        default: OSL_FAIL("GetLanguage: wrong script type");
    }
    return SvxLanguageItem(mpFld->GetLanguage(),nLangWhichId);
}

bool SwAnnotationWin::IsProtected()
{
    return SwSidebarWin::IsProtected() ||
           GetLayoutStatus() == SwPostItHelper::DELETED ||
           ( mpFmtFld ? mpFmtFld->IsProtect() : false );
}

String SwAnnotationWin::GetAuthor()
{
    return mpFld->GetPar1();
}

Date SwAnnotationWin::GetDate()
{
    return mpFld->GetDate();
}

Time SwAnnotationWin::GetTime()
{
    return mpFld->GetTime();
}

} } // end of namespace sw::annotation

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


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License 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. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/parsed_interior_qoi.h"

// GRINS
#include "grins/multiphysics_sys.h"
#include "grins/assembly_context.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/fem_system.h"
#include "libmesh/quadrature.h"
#include "libmesh/fe_base.h"
#include "libmesh/parsed_fem_function.h"

namespace GRINS
{
  ParsedInteriorQoI::ParsedInteriorQoI( const std::string& qoi_name )
    : QoIBase(qoi_name) {}

  ParsedInteriorQoI::ParsedInteriorQoI( const ParsedInteriorQoI& original )
    : QoIBase(original.name())
  {
    this->qoi_functional = original.qoi_functional->clone();
  }

  ParsedInteriorQoI::~ParsedInteriorQoI() {}

  QoIBase* ParsedInteriorQoI::clone() const
  {
    return new ParsedInteriorQoI( *this );
  }

  void ParsedInteriorQoI::init( const GetPot& input, const MultiphysicsSystem& system )
  {
    std::string qoi_functional_string =
      input("QoI/ParsedInterior/", std::string("0"));

    if (qoi_functional_string == "0")
      libmesh_error_msg("Error! Zero ParsedInteriorQoI specified!" <<
                        std::endl);

    this->qoi_functional.reset
      (new libMesh::ParsedFEMFunction<libMesh::Number>
       (system, qoi_functional_string));
  }

  void ParsedInteriorQoI::init_context( AssemblyContext& context )
  {
    libMesh::FEBase* element_fe;
    context.get_element_fe<libMesh::Real>(0, element_fe);
    element_fe->get_JxW();
    element_fe->get_xyz();

    qoi_functional->init_context(context);
  }

  void ParsedInteriorQoI::element_qoi( AssemblyContext& context,
                                       const unsigned int qoi_index )
  {
    libMesh::FEBase* element_fe;
    context.get_element_fe<libMesh::Real>(0, element_fe);
    const std::vector<libMesh::Real> &JxW = element_fe->get_JxW();

    const std::vector<libMesh::Point>& x_qp = element_fe->get_xyz();

    unsigned int n_qpoints = context.get_element_qrule().n_points();

    /*! \todo Need to generalize this to the multiple QoI case */
    libMesh::Number& qoi = context.get_qois()[qoi_index];

    for( unsigned int qp = 0; qp != n_qpoints; qp++ )
      {
        const libMesh::Number func_val =
          (*qoi_functional)(context, x_qp[qp], context.get_time());

        qoi += func_val;
      }
  }

  void ParsedInteriorQoI::element_qoi_derivative( AssemblyContext& context,
                                                  const unsigned int qoi_index )
  {
    libMesh::FEBase* element_fe;
    context.get_element_fe<libMesh::Real>(0, element_fe);
    const std::vector<libMesh::Real> &JxW = element_fe->get_JxW();

    const std::vector<libMesh::Point>& x_qp = element_fe->get_xyz();

    // Local DOF count and quadrature point count
    const unsigned int n_u_dofs = context.get_dof_indices().size();

    unsigned int n_qpoints = context.get_element_qrule().n_points();

    // Local solution vector - non-const version for finite
    // differenting purposes
    libMesh::DenseVector<libMesh::Number>& elem_solution =
      const_cast<libMesh::DenseVector<libMesh::Number>&>
        (context.get_elem_solution());

    /*! \todo Need to generalize this to the multiple QoI case */
    libMesh::DenseVector<libMesh::Number> &Qu =
      context.get_qoi_derivatives()[qoi_index];

    for( unsigned int qp = 0; qp != n_qpoints; qp++ )
      {
        // Central finite differencing to approximate derivatives.
        // FIXME - we should hook the FParserAD stuff into
        // ParsedFEMFunction

        for( unsigned int i = 0; i != n_u_dofs; ++i )
          {
            libMesh::Number &current_solution = elem_solution(i);
            const libMesh::Number original_solution = current_solution;

            current_solution = original_solution + libMesh::TOLERANCE;

            const libMesh::Number plus_val =
              (*qoi_functional)(context, x_qp[qp], context.get_time());

            current_solution = original_solution - libMesh::TOLERANCE;

            const libMesh::Number minus_val =
              (*qoi_functional)(context, x_qp[qp], context.get_time());

            Qu(i) += (plus_val - minus_val) * (0.5 / libMesh::TOLERANCE);

            // Don't forget to restore the correct solution...
            current_solution = original_solution;
          }
      }
  }

} //namespace GRINS
<commit_msg>Fix ParsedInteriorQoI input variable name<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License 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. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/parsed_interior_qoi.h"

// GRINS
#include "grins/multiphysics_sys.h"
#include "grins/assembly_context.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/fem_system.h"
#include "libmesh/quadrature.h"
#include "libmesh/fe_base.h"
#include "libmesh/parsed_fem_function.h"

namespace GRINS
{
  ParsedInteriorQoI::ParsedInteriorQoI( const std::string& qoi_name )
    : QoIBase(qoi_name) {}

  ParsedInteriorQoI::ParsedInteriorQoI( const ParsedInteriorQoI& original )
    : QoIBase(original.name())
  {
    this->qoi_functional = original.qoi_functional->clone();
  }

  ParsedInteriorQoI::~ParsedInteriorQoI() {}

  QoIBase* ParsedInteriorQoI::clone() const
  {
    return new ParsedInteriorQoI( *this );
  }

  void ParsedInteriorQoI::init( const GetPot& input, const MultiphysicsSystem& system )
  {
    std::string qoi_functional_string =
      input("QoI/ParsedInterior/qoi_functional", std::string("0"));

    if (qoi_functional_string == "0")
      libmesh_error_msg("Error! Zero ParsedInteriorQoI specified!" <<
                        std::endl);

    this->qoi_functional.reset
      (new libMesh::ParsedFEMFunction<libMesh::Number>
       (system, qoi_functional_string));
  }

  void ParsedInteriorQoI::init_context( AssemblyContext& context )
  {
    libMesh::FEBase* element_fe;
    context.get_element_fe<libMesh::Real>(0, element_fe);
    element_fe->get_JxW();
    element_fe->get_xyz();

    qoi_functional->init_context(context);
  }

  void ParsedInteriorQoI::element_qoi( AssemblyContext& context,
                                       const unsigned int qoi_index )
  {
    libMesh::FEBase* element_fe;
    context.get_element_fe<libMesh::Real>(0, element_fe);
    const std::vector<libMesh::Real> &JxW = element_fe->get_JxW();

    const std::vector<libMesh::Point>& x_qp = element_fe->get_xyz();

    unsigned int n_qpoints = context.get_element_qrule().n_points();

    /*! \todo Need to generalize this to the multiple QoI case */
    libMesh::Number& qoi = context.get_qois()[qoi_index];

    for( unsigned int qp = 0; qp != n_qpoints; qp++ )
      {
        const libMesh::Number func_val =
          (*qoi_functional)(context, x_qp[qp], context.get_time());

        qoi += func_val;
      }
  }

  void ParsedInteriorQoI::element_qoi_derivative( AssemblyContext& context,
                                                  const unsigned int qoi_index )
  {
    libMesh::FEBase* element_fe;
    context.get_element_fe<libMesh::Real>(0, element_fe);
    const std::vector<libMesh::Real> &JxW = element_fe->get_JxW();

    const std::vector<libMesh::Point>& x_qp = element_fe->get_xyz();

    // Local DOF count and quadrature point count
    const unsigned int n_u_dofs = context.get_dof_indices().size();

    unsigned int n_qpoints = context.get_element_qrule().n_points();

    // Local solution vector - non-const version for finite
    // differenting purposes
    libMesh::DenseVector<libMesh::Number>& elem_solution =
      const_cast<libMesh::DenseVector<libMesh::Number>&>
        (context.get_elem_solution());

    /*! \todo Need to generalize this to the multiple QoI case */
    libMesh::DenseVector<libMesh::Number> &Qu =
      context.get_qoi_derivatives()[qoi_index];

    for( unsigned int qp = 0; qp != n_qpoints; qp++ )
      {
        // Central finite differencing to approximate derivatives.
        // FIXME - we should hook the FParserAD stuff into
        // ParsedFEMFunction

        for( unsigned int i = 0; i != n_u_dofs; ++i )
          {
            libMesh::Number &current_solution = elem_solution(i);
            const libMesh::Number original_solution = current_solution;

            current_solution = original_solution + libMesh::TOLERANCE;

            const libMesh::Number plus_val =
              (*qoi_functional)(context, x_qp[qp], context.get_time());

            current_solution = original_solution - libMesh::TOLERANCE;

            const libMesh::Number minus_val =
              (*qoi_functional)(context, x_qp[qp], context.get_time());

            Qu(i) += (plus_val - minus_val) * (0.5 / libMesh::TOLERANCE);

            // Don't forget to restore the correct solution...
            current_solution = original_solution;
          }
      }
  }

} //namespace GRINS
<|endoftext|>


<commit_before><commit_msg>Deleted unnecessary files<commit_after><|endoftext|>


<commit_before>
<commit_msg>Delete 1.cpp<commit_after><|endoftext|>


<commit_before>#ifndef AIKIDO_CONTROL_TRAJECTORYEXECUTOR_HPP_
#define AIKIDO_CONTROL_TRAJECTORYEXECUTOR_HPP_

#include <chrono>
#include <future>
#include <set>
#include "aikido/common/pointers.hpp"
#include "aikido/trajectory/Trajectory.hpp"

namespace aikido {
namespace control {

AIKIDO_DECLARE_POINTERS(TrajectoryExecutor)

/// Abstract class for executing trajectories.
class TrajectoryExecutor
{
public:
  virtual ~TrajectoryExecutor() = default;

  /// Validate the traj in preparation for execution.
  ///
  /// \param traj Trajectory to be validated
  virtual void validate(const trajectory::Trajectory* traj) = 0;

  /// Validate and execute traj, setting future upon completion. If a trajectory
  /// is already running, raise an exception unless the executor supports
  /// queuing.
  ///
  /// \param _traj Trajectory to be executed.
  /// \return future<void> for trajectory execution. If trajectory terminates
  ///        before completion, future will be set to a runtime_error.
  virtual std::future<void> execute(const trajectory::ConstTrajectoryPtr& traj)
      = 0;

  /// Step to a point in time.
  /// \note \c timepoint can be a time in the future to enable faster than
  /// real-time execution.
  ///
  /// \param timepoint Time to simulate to
  virtual void step(const std::chrono::system_clock::time_point& timepoint) = 0;

  /// Abort the current trajectory.
  /// \note This is currently only supported in simulation.
  virtual void abort() = 0;

protected:
  /// Set of trajectories validated by executor
  std::set<const trajectory::Trajectory*> mValidatedTrajectories;

  /// Time of previous call
  std::chrono::system_clock::time_point mExecutionStartTime;
};

} // namespace control
} // namespace aikido

#endif
<commit_msg>Fix documentation typo. (#406)<commit_after>#ifndef AIKIDO_CONTROL_TRAJECTORYEXECUTOR_HPP_
#define AIKIDO_CONTROL_TRAJECTORYEXECUTOR_HPP_

#include <chrono>
#include <future>
#include <set>
#include "aikido/common/pointers.hpp"
#include "aikido/trajectory/Trajectory.hpp"

namespace aikido {
namespace control {

AIKIDO_DECLARE_POINTERS(TrajectoryExecutor)

/// Abstract class for executing trajectories.
class TrajectoryExecutor
{
public:
  virtual ~TrajectoryExecutor() = default;

  /// Validate the traj in preparation for execution.
  ///
  /// \param traj Trajectory to be validated
  virtual void validate(const trajectory::Trajectory* traj) = 0;

  /// Validate and execute traj, setting future upon completion. If a trajectory
  /// is already running, raise an exception unless the executor supports
  /// queuing.
  ///
  /// \param traj Trajectory to be executed.
  /// \return future<void> for trajectory execution. If trajectory terminates
  ///        before completion, future will be set to a runtime_error.
  virtual std::future<void> execute(const trajectory::ConstTrajectoryPtr& traj)
      = 0;

  /// Step to a point in time.
  /// \note \c timepoint can be a time in the future to enable faster than
  /// real-time execution.
  ///
  /// \param timepoint Time to simulate to
  virtual void step(const std::chrono::system_clock::time_point& timepoint) = 0;

  /// Abort the current trajectory.
  /// \note This is currently only supported in simulation.
  virtual void abort() = 0;

protected:
  /// Set of trajectories validated by executor
  std::set<const trajectory::Trajectory*> mValidatedTrajectories;

  /// Time of previous call
  std::chrono::system_clock::time_point mExecutionStartTime;
};

} // namespace control
} // namespace aikido

#endif
<|endoftext|>


<commit_before>/**
 * These codes are licensed under the Unlicense.
 * http://unlicense.org
 */

#ifndef COMMATA_GUARD_F6071085_9476_4724_95ED_E1DA376E837C
#define COMMATA_GUARD_F6071085_9476_4724_95ED_E1DA376E837C

#include <memory>
#include <type_traits>
#include <utility>

#include "member_like_base.hpp"

namespace commata {
namespace detail {

namespace allocation_only {

template <class A, class = void>
struct reference_forwarded
{
    using type = typename A::value_type&;
};

template <class A>
struct reference_forwarded<A, typename A::reference>
{
    using type = typename A::reference;
};

template <class A, class = void>
struct const_reference_forwarded
{
    using type = const typename A::value_type&;
};

template <class A>
struct const_reference_forwarded<A, typename A::const_reference>
{
    using type = typename A::const_reference;
};

} // end allocation_only

template <class Allocator>
class allocation_only_allocator :
    member_like_base<Allocator>
{
    using base_traits_t = typename std::allocator_traits<Allocator>;

    // To rebind
    template <class OtherAllocator>
    friend class allocation_only_allocator;

public:
    using pointer = typename base_traits_t::pointer;
    using const_pointer = typename base_traits_t::const_pointer;
    using void_pointer = typename base_traits_t::void_pointer;
    using const_void_pointer = typename base_traits_t::const_void_pointer;
    using value_type = typename base_traits_t::value_type;
    using size_type = typename base_traits_t::size_type;
    using difference_type = typename base_traits_t::difference_type;

    // These types are not required by the C++14 standard, but
    // std::basic_string which comes with gcc 7.3.1 seems to do
    using reference =
        typename allocation_only::reference_forwarded<Allocator>::type;
    using const_reference =
        typename allocation_only::const_reference_forwarded<Allocator>::type;

    template <class U>
    struct rebind
    {
        using other = allocation_only_allocator<
            typename base_traits_t::template rebind_alloc<U>>;
    };

    // Default-constructibility of an allocator is not mandated by the C++14
    // standard, but std::basic_string which comes with gcc 7.3.1 requires it
    allocation_only_allocator() = default;

    // To make wrappers
    explicit allocation_only_allocator(const Allocator& other) noexcept :
        member_like_base<Allocator>(other)
    {}

    // ditto
    explicit allocation_only_allocator(Allocator&& other) noexcept :
        member_like_base<Allocator>(std::move(other))
    {}

    // To make rebound copies
    template <class OtherAllocator>
    explicit allocation_only_allocator(
        const allocation_only_allocator<OtherAllocator>& other) noexcept :
        member_like_base<Allocator>(other.base())
    {}

    // ditto
    template <class OtherAllocator>
    explicit allocation_only_allocator(
        allocation_only_allocator<OtherAllocator>&& other) noexcept :
        member_like_base<Allocator>(std::move(other.base()))
    {}

    // copy/move ctor/assignment ops are defaulted

    template <class... Args>
    auto allocate(size_type n, Args&&... args)
    {
        return base_traits_t::allocate(base(),
            n, std::forward<Args>(args)...);
    }

    auto deallocate(pointer p, size_type n) noexcept
    {
        return base_traits_t::deallocate(base(), p, n);
    }

    auto max_size() noexcept(noexcept(
        base_traits_t::max_size(std::declval<const Allocator&>())))
    {
        return base_traits_t::max_size(base());
    }

    template <class T, class... Args>
    void construct(T* p, Args&&... args)
    {
        ::new(p) T(std::forward<Args>(args)...);
    }

    template <class T>
    void destroy(T* p)
    {
        destroy(p, std::is_trivially_destructible<T>());
    }

    auto select_on_container_copy_construction() const noexcept(noexcept(
        base_traits_t::select_on_container_copy_construction(
            std::declval<const Allocator&>())))
    {
        return base_traits_t::select_on_container_copy_construction(base());
    }

    using propagate_on_container_copy_assignment =
        typename base_traits_t::propagate_on_container_copy_assignment;
    using propagate_on_container_move_assignment =
        typename base_traits_t::propagate_on_container_move_assignment;
    using propagate_on_container_swap =
        typename base_traits_t::propagate_on_container_swap;

    decltype(auto) base() noexcept
    {
        return this->get();
    }

    decltype(auto) base() const noexcept
    {
        return this->get();
    }

private:
    template <class T>
    void destroy(T*, std::true_type)
    {}

    template <class T>
    void destroy(T* p, std::false_type)
    {
        p->~T();
    }
};

template <class AllocatorL, class AllocatorR>
bool operator==(
    const allocation_only_allocator<AllocatorL>& left,
    const allocation_only_allocator<AllocatorR>& right) noexcept
{
    return left.base() == right.base();
}

template <class AllocatorL, class AllocatorR>
bool operator!=(
    const allocation_only_allocator<AllocatorL>& left,
    const allocation_only_allocator<AllocatorR>& right) noexcept
{
    return left.base() != right.base();
}

}}

#endif
<commit_msg>Refactor allocation_only_allocator<commit_after>/**
 * These codes are licensed under the Unlicense.
 * http://unlicense.org
 */

#ifndef COMMATA_GUARD_F6071085_9476_4724_95ED_E1DA376E837C
#define COMMATA_GUARD_F6071085_9476_4724_95ED_E1DA376E837C

#include <memory>
#include <type_traits>
#include <utility>

#include "member_like_base.hpp"

namespace commata {
namespace detail {

namespace allocation_only {

template <class A, class = void>
struct reference_forwarded
{
    using type = typename A::value_type&;
};

template <class A>
struct reference_forwarded<A, typename A::reference>
{
    using type = typename A::reference;
};

template <class A, class = void>
struct const_reference_forwarded
{
    using type = const typename A::value_type&;
};

template <class A>
struct const_reference_forwarded<A, typename A::const_reference>
{
    using type = typename A::const_reference;
};

} // end allocation_only

template <class A>
class allocation_only_allocator :
    member_like_base<A>
{
    using base_traits_t = typename std::allocator_traits<A>;

public:
    using pointer = typename base_traits_t::pointer;
    using const_pointer = typename base_traits_t::const_pointer;
    using void_pointer = typename base_traits_t::void_pointer;
    using const_void_pointer = typename base_traits_t::const_void_pointer;
    using value_type = typename base_traits_t::value_type;
    using size_type = typename base_traits_t::size_type;
    using difference_type = typename base_traits_t::difference_type;

    // These types are not required by the C++14 standard, but
    // std::basic_string which comes with gcc 7.3.1 seems to do
    using reference =
        typename allocation_only::reference_forwarded<A>::type;
    using const_reference =
        typename allocation_only::const_reference_forwarded<A>::type;

    template <class U>
    struct rebind
    {
        using other = allocation_only_allocator<
            typename base_traits_t::template rebind_alloc<U>>;
    };

    // Default-constructibility of an allocator is not mandated by the C++14
    // standard, but std::basic_string which comes with gcc 7.3.1 requires it
    allocation_only_allocator() = default;

    // To make wrappers
    explicit allocation_only_allocator(const A& other)
            noexcept(std::is_nothrow_copy_constructible<A>::value):
        member_like_base<A>(other)
    {}

    // ditto
    explicit allocation_only_allocator(A&& other)
            noexcept(std::is_nothrow_move_constructible<A>::value) :
        member_like_base<A>(std::move(other))
    {}

    // To make rebound copies
    template <class B>
    explicit allocation_only_allocator(
        const allocation_only_allocator<B>& other)
            noexcept(std::is_nothrow_constructible<A, const B&>::value) :
        member_like_base<A>(other.base())
    {}

    // ditto
    template <class B>
    explicit allocation_only_allocator(
        allocation_only_allocator<B>&& other)
            noexcept(std::is_nothrow_constructible<A, B&&>::value) :
        member_like_base<A>(std::move(other.base()))
    {}

    // copy/move ctor/assignment ops are defaulted

    template <class... Args>
    auto allocate(size_type n, Args&&... args)
    {
        return base_traits_t::allocate(base(), n, std::forward<Args>(args)...);
    }

    auto deallocate(pointer p, size_type n)
    {
        return base_traits_t::deallocate(base(), p, n);
    }

    size_type max_size() const noexcept
        // this noexceptness is mandated in the spec of
        // std::allocator_traits<A>::max_size
    {
        return base_traits_t::max_size(base());
    }

    template <class T, class... Args>
    void construct(T* p, Args&&... args)
    {
        ::new(p) T(std::forward<Args>(args)...);
    }

    template <class T>
    void destroy(T* p)
    {
        destroy(p, std::is_trivially_destructible<T>());
    }

    allocation_only_allocator select_on_container_copy_construction() const
        noexcept(noexcept(base_traits_t::select_on_container_copy_construction(
                            std::declval<const A&>())))
    {
        return base_traits_t::select_on_container_copy_construction(base());
    }

    using propagate_on_container_copy_assignment =
        typename base_traits_t::propagate_on_container_copy_assignment;
    using propagate_on_container_move_assignment =
        typename base_traits_t::propagate_on_container_move_assignment;
    using propagate_on_container_swap =
        typename base_traits_t::propagate_on_container_swap;

    decltype(auto) base() noexcept
    {
        return this->get();
    }

    decltype(auto) base() const noexcept
    {
        return this->get();
    }

private:
    template <class T>
    void destroy(T*, std::true_type)
    {}

    template <class T>
    void destroy(T* p, std::false_type)
    {
        p->~T();
    }
};

template <class AllocatorL, class AllocatorR>
bool operator==(
    const allocation_only_allocator<AllocatorL>& left,
    const allocation_only_allocator<AllocatorR>& right)
    noexcept(noexcept(std::declval<const AllocatorL&>()
                   == std::declval<const AllocatorR&>()))
{
    return left.base() == right.base();
}

template <class AllocatorL, class AllocatorR>
bool operator==(
    const allocation_only_allocator<AllocatorL>& left,
    const AllocatorR& right)
    noexcept(noexcept(std::declval<const AllocatorL&>()
                   == std::declval<const AllocatorR&>()))
{
    return left.base() == right;
}

template <class AllocatorL, class AllocatorR>
bool operator==(
    const AllocatorL& left,
    const allocation_only_allocator<AllocatorR>& right)
    noexcept(noexcept(std::declval<const AllocatorL&>()
                   == std::declval<const AllocatorR&>()))
{
    return left == right.base();
}

template <class AllocatorL, class AllocatorR>
bool operator!=(
    const allocation_only_allocator<AllocatorL>& left,
    const allocation_only_allocator<AllocatorR>& right)
    noexcept(noexcept(std::declval<const AllocatorL&>()
                   != std::declval<const AllocatorR&>()))
{
    return left.base() != right.base();
}

template <class AllocatorL, class AllocatorR>
bool operator!=(
    const allocation_only_allocator<AllocatorL>& left,
    const AllocatorR& right)
    noexcept(noexcept(std::declval<const AllocatorL&>()
                   != std::declval<const AllocatorR&>()))
{
    return left.base() != right;
}

template <class AllocatorL, class AllocatorR>
bool operator!=(
    const AllocatorL& left,
    const allocation_only_allocator<AllocatorR>& right)
    noexcept(noexcept(std::declval<const AllocatorL&>()
                   != std::declval<const AllocatorR&>()))
{
    return left != right.base();
}
}}

#endif
<|endoftext|>


<commit_before>#ifndef DATATRANSFER_BINARY_SERIALIZATION_HPP
#define DATATRANSFER_BINARY_SERIALIZATION_HPP

#include <Eigen/Core>

namespace datatransfer
{

struct binary_serialization
{
    template <typename output_stream>
    class write_policy
    {
    public:
        using stream_type = output_stream;
        output_stream& os;

        write_policy(output_stream& os) : os(os) {}

        template <typename T>
        write_policy<output_stream>& operator% (T& x)
        {
            operate(x);

            return *this;
        }

        template <typename Scalar, int M, int N>
        void operate(Eigen::Matrix<Scalar, M, N>& matrix)
        {
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < M; i++)
                {
                    operate(matrix(i,j));
                }
            }
        }

        template <typename T, int M=0, int N=0>
        void operate(T& t)
        {
            t.template method<write_policy<output_stream> >(os);
        }

    protected:
        void operate(int& x)			{ write(x); }
        void operate(float& x)			{ write(x); }
        void operate(double& x)			{ write(x); }
        void operate(char& x)			{ write(x); }
        void operate(uint8_t& x)		{ write(x); }
        void operate(bool& x)			{ write(x); }
        void operate(uint64_t& x)		{ write(x); }

    private:
        template <typename T>
        void write(const T& t)
        {
            // Assume little endian encoding
            os.write(reinterpret_cast<const typename output_stream::char_type*>(&t), sizeof(T));
        }
    };

    template <typename input_stream>
    struct read_policy
    {
        using stream_type = input_stream;
        input_stream& is;

        read_policy(input_stream& is) : is(is) {}

        template <typename T>
        read_policy& operator% (T& x)
        {
            operate(x);

            return *this;
        }

    protected:
        template <typename Scalar, int M, int N>
        void operate(Eigen::Matrix<Scalar, M, N>& matrix)
        {
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < M; i++)
                {
                    operate(matrix(i,j));
                }
            }
        }

    public:
        template <typename T, int M=0, int N=0>
        void operate(T& t)
        {
            t.template method<read_policy<input_stream> >(is);
        }

        bool operate(int& x) 		{ return read(x); }
        bool operate(float& x) 		{ return read(x); }
        bool operate(double& x) 	{ return read(x); }
        bool operate(char& x)   	{ return read(x); }
        bool operate(bool& x)   	{ return read(x); }
        bool operate(uint64_t& x)	{ return read(x); }

        template <typename T>
        bool read(T& t)
        {
            // Assume little endian encoding
			const auto n = sizeof(T);
			return is.read(reinterpret_cast<typename input_stream::char_type*>(&t), n) == n;
        }
    };

    class checksum_policy
    {
    private:
        uint8_t& _checksum;

    public:
        using data_type = uint8_t;
        using stream_type = data_type;

        checksum_policy(data_type& checksum)
            : _checksum(checksum)
        {}

        uint8_t checksum() const { return _checksum; }

        template <typename T>
        void operator% (T& x)
        {
            operate(x);
        }

    protected:
        template <typename Scalar, int M, int N>
        void operate(Eigen::Matrix<Scalar, M, N>& matrix)
        {
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < M; i++)
                {
                    operate(matrix(i,j));
                }
            }
        }

        template <typename T, int M=0, int N=0>
        void operate(T& t)
        {
            t.template method<checksum_policy>(_checksum);
        }

        void operate(float& x) 		{ read(x); }
        void operate(double& x) 	{ read(x); }
        void operate(char& x)   	{ read(x); }
        void operate(bool& x)   	{ read(x); }
        void operate(uint8_t& x)    { read(x); }
        void operate(uint64_t& x)	{ read(x); }

        template <typename T>
        void read(T& t)
        {
            // Assume little endian encoding
            auto* buf = reinterpret_cast<const data_type*>(&t);
            for (int i = 0; i < sizeof(T); ++i)
                _checksum ^= buf[i];
        }
    };
};

}

#endif // DATATRANSFER_BINARY_SERIALIZATION_HPP
<commit_msg>Initialise checksum value<commit_after>#ifndef DATATRANSFER_BINARY_SERIALIZATION_HPP
#define DATATRANSFER_BINARY_SERIALIZATION_HPP

#include <Eigen/Core>

namespace datatransfer
{

struct binary_serialization
{
    template <typename output_stream>
    class write_policy
    {
    public:
        using stream_type = output_stream;
        output_stream& os;

        write_policy(output_stream& os) : os(os) {}

        template <typename T>
        write_policy<output_stream>& operator% (T& x)
        {
            operate(x);

            return *this;
        }

        template <typename Scalar, int M, int N>
        void operate(Eigen::Matrix<Scalar, M, N>& matrix)
        {
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < M; i++)
                {
                    operate(matrix(i,j));
                }
            }
        }

        template <typename T, int M=0, int N=0>
        void operate(T& t)
        {
            t.template method<write_policy<output_stream> >(os);
        }

    protected:
        void operate(int& x)			{ write(x); }
        void operate(float& x)			{ write(x); }
        void operate(double& x)			{ write(x); }
        void operate(char& x)			{ write(x); }
        void operate(uint8_t& x)		{ write(x); }
        void operate(bool& x)			{ write(x); }
        void operate(uint64_t& x)		{ write(x); }

    private:
        template <typename T>
        void write(const T& t)
        {
            // Assume little endian encoding
            os.write(reinterpret_cast<const typename output_stream::char_type*>(&t), sizeof(T));
        }
    };

    template <typename input_stream>
    struct read_policy
    {
        using stream_type = input_stream;
        input_stream& is;

        read_policy(input_stream& is) : is(is) {}

        template <typename T>
        read_policy& operator% (T& x)
        {
            operate(x);

            return *this;
        }

    protected:
        template <typename Scalar, int M, int N>
        void operate(Eigen::Matrix<Scalar, M, N>& matrix)
        {
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < M; i++)
                {
                    operate(matrix(i,j));
                }
            }
        }

    public:
        template <typename T, int M=0, int N=0>
        void operate(T& t)
        {
            t.template method<read_policy<input_stream> >(is);
        }

        bool operate(int& x) 		{ return read(x); }
        bool operate(float& x) 		{ return read(x); }
        bool operate(double& x) 	{ return read(x); }
        bool operate(char& x)   	{ return read(x); }
        bool operate(bool& x)   	{ return read(x); }
        bool operate(uint64_t& x)	{ return read(x); }

        template <typename T>
        bool read(T& t)
        {
            // Assume little endian encoding
			const auto n = sizeof(T);
			return is.read(reinterpret_cast<typename input_stream::char_type*>(&t), n) == n;
        }
    };

    class checksum_policy
    {
    private:
        uint8_t& _checksum;

    public:
        using data_type = uint8_t;
        using stream_type = data_type;

        checksum_policy(data_type& checksum)
            : _checksum(checksum)
        {
            _checksum = 0;
        }

        uint8_t checksum() const { return _checksum; }

        template <typename T>
        void operator% (T& x)
        {
            operate(x);
        }

    protected:
        template <typename Scalar, int M, int N>
        void operate(Eigen::Matrix<Scalar, M, N>& matrix)
        {
            for (int j = 0; j < N; j++)
            {
                for (int i = 0; i < M; i++)
                {
                    operate(matrix(i,j));
                }
            }
        }

        template <typename T, int M=0, int N=0>
        void operate(T& t)
        {
            t.template method<checksum_policy>(_checksum);
        }

        void operate(float& x) 		{ read(x); }
        void operate(double& x) 	{ read(x); }
        void operate(char& x)   	{ read(x); }
        void operate(bool& x)   	{ read(x); }
        void operate(uint8_t& x)    { read(x); }
        void operate(uint64_t& x)	{ read(x); }

        template <typename T>
        void read(T& t)
        {
            // Assume little endian encoding
            auto* buf = reinterpret_cast<const data_type*>(&t);
            for (int i = 0; i < sizeof(T); ++i)
                _checksum ^= buf[i];
        }
    };
};

}

#endif // DATATRANSFER_BINARY_SERIALIZATION_HPP
<|endoftext|>