<commit_before>/*************************************************************************
 *
 *  $RCSfile: txtdrope.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: dvo $ $Date: 2001-10-19 18:43:58 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER 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 _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

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

#ifndef _COM_SUN_STAR_STYLE_DROPCAPFORMAT_HPP_
#include <com/sun/star/style/DropCapFormat.hpp>
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_TXTDROPE_HXX
#include "txtdrope.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::uno;
using namespace ::rtl;
using namespace ::xmloff::token;

XMLTextDropCapExport::XMLTextDropCapExport( SvXMLExport& rExp ) :
    rExport(rExp)
{
}

XMLTextDropCapExport::~XMLTextDropCapExport()
{
}

void XMLTextDropCapExport::exportXML( const Any& rAny,
                                      sal_Bool bWholeWord,
                                      const OUString& rStyleName )
{
    DropCapFormat aFormat;
    rAny >>= aFormat;
    OUString sValue;
    OUStringBuffer sBuffer;
    if( aFormat.Lines > 1 )
    {
        SvXMLUnitConverter& rUnitConv = rExport.GetMM100UnitConverter();

        // style:lines
        rUnitConv.convertNumber( sBuffer, (sal_Int32)aFormat.Lines );
        rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LINES,
                              sBuffer.makeStringAndClear() );

        // style:length
        if( bWholeWord )
        {
            sValue = GetXMLToken(XML_WORD);
        }
        else if( aFormat.Count > 1 )
        {
            rUnitConv.convertNumber( sBuffer, (sal_Int32)aFormat.Count );
            sValue = sBuffer.makeStringAndClear();
        }
        if( sValue.getLength() )
            rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LENGTH, sValue );

        // style:distance
        if( aFormat.Distance > 0 )
        {
            rUnitConv.convertMeasure( sBuffer, aFormat.Distance );
            rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_DISTANCE,
                                  sBuffer.makeStringAndClear() );
        }

        // style:style-name
        if( rStyleName.getLength() )
            rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_STYLE_NAME,
                                  rStyleName );
    }

    SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, XML_DROP_CAP,
                              sal_False, sal_False );
}

<commit_msg>INTEGRATION: CWS oasis (1.3.270); FILE MERGED 2004/05/07 12:00:06 mib 1.3.270.1: - #i20153#: encode/decode style names (ooo2oasis missing)<commit_after>/*************************************************************************
 *
 *  $RCSfile: txtdrope.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 08:39:41 $
 *
 *  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 _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

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

#ifndef _COM_SUN_STAR_STYLE_DROPCAPFORMAT_HPP_
#include <com/sun/star/style/DropCapFormat.hpp>
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_TXTDROPE_HXX
#include "txtdrope.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::uno;
using namespace ::rtl;
using namespace ::xmloff::token;

XMLTextDropCapExport::XMLTextDropCapExport( SvXMLExport& rExp ) :
    rExport(rExp)
{
}

XMLTextDropCapExport::~XMLTextDropCapExport()
{
}

void XMLTextDropCapExport::exportXML( const Any& rAny,
                                      sal_Bool bWholeWord,
                                      const OUString& rStyleName )
{
    DropCapFormat aFormat;
    rAny >>= aFormat;
    OUString sValue;
    OUStringBuffer sBuffer;
    if( aFormat.Lines > 1 )
    {
        SvXMLUnitConverter& rUnitConv = rExport.GetMM100UnitConverter();

        // style:lines
        rUnitConv.convertNumber( sBuffer, (sal_Int32)aFormat.Lines );
        rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LINES,
                              sBuffer.makeStringAndClear() );

        // style:length
        if( bWholeWord )
        {
            sValue = GetXMLToken(XML_WORD);
        }
        else if( aFormat.Count > 1 )
        {
            rUnitConv.convertNumber( sBuffer, (sal_Int32)aFormat.Count );
            sValue = sBuffer.makeStringAndClear();
        }
        if( sValue.getLength() )
            rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_LENGTH, sValue );

        // style:distance
        if( aFormat.Distance > 0 )
        {
            rUnitConv.convertMeasure( sBuffer, aFormat.Distance );
            rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_DISTANCE,
                                  sBuffer.makeStringAndClear() );
        }

        // style:style-name
        if( rStyleName.getLength() )
            rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_STYLE_NAME,
                                  rExport.EncodeStyleName( rStyleName ) );
    }

    SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, XML_DROP_CAP,
                              sal_False, sal_False );
}

<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include "cyclic_array.hpp"

namespace gt = testing;

namespace pk
{
namespace testing
{

struct cyclic_array_tester : public gt::Test
{
    cyclic_array_tester() : elem1(11), elem2(22), elem3(33)
    {
        ca[0] = elem1;
        ca[1] = elem2;
        ca[2] = elem3;
    }

    static const int SIZE = 3;

    const int elem1;
    const int elem2;
    const int elem3;

    // tested class:
    cyclic_array<int, SIZE> ca;
};

TEST_F(cyclic_array_tester, tests_shift_Left_by_zero)
{
    // when
    ca.shift_left(0);

    // then
    EXPECT_EQ(elem1, ca[0]);
    EXPECT_EQ(elem2, ca[1]);
    EXPECT_EQ(elem3, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_small_value)
{
    // when
    ca.shift_left(1);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_small_negative_value)
{
    // when
    ca.shift_left(-1);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_bigger_value)
{
    // when
    ca.shift_left(5);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_bigger_negative_value)
{
    // when
    ca.shift_left(-5);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_zero)
{
    // when
    ca.shift_right(0);

    // then
    EXPECT_EQ(elem1, ca[0]);
    EXPECT_EQ(elem2, ca[1]);
    EXPECT_EQ(elem3, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_small_value)
{
    // when
    ca.shift_right(1);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_small_negative_value)
{
    // when
    ca.shift_right(-1);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_bigger_value)
{
    // when
    ca.shift_right(5);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_bigger_negative_value)
{
    // when
    ca.shift_right(-5);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

} // namespace testing
} // namespace pk
<commit_msg>Typo fix<commit_after>#include <gtest/gtest.h>

#include "cyclic_array.hpp"

namespace gt = testing;

namespace pk
{
namespace testing
{

struct cyclic_array_tester : public gt::Test
{
    cyclic_array_tester() : elem1(11), elem2(22), elem3(33)
    {
        ca[0] = elem1;
        ca[1] = elem2;
        ca[2] = elem3;
    }

    static const int SIZE = 3;

    const int elem1;
    const int elem2;
    const int elem3;

    // tested class:
    cyclic_array<int, SIZE> ca;
};

TEST_F(cyclic_array_tester, tests_shift_left_by_zero)
{
    // when
    ca.shift_left(0);

    // then
    EXPECT_EQ(elem1, ca[0]);
    EXPECT_EQ(elem2, ca[1]);
    EXPECT_EQ(elem3, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_small_value)
{
    // when
    ca.shift_left(1);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_small_negative_value)
{
    // when
    ca.shift_left(-1);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_bigger_value)
{
    // when
    ca.shift_left(5);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_left_by_bigger_negative_value)
{
    // when
    ca.shift_left(-5);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_zero)
{
    // when
    ca.shift_right(0);

    // then
    EXPECT_EQ(elem1, ca[0]);
    EXPECT_EQ(elem2, ca[1]);
    EXPECT_EQ(elem3, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_small_value)
{
    // when
    ca.shift_right(1);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_small_negative_value)
{
    // when
    ca.shift_right(-1);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_bigger_value)
{
    // when
    ca.shift_right(5);

    // then
    EXPECT_EQ(elem2, ca[0]);
    EXPECT_EQ(elem3, ca[1]);
    EXPECT_EQ(elem1, ca[2]);
}

TEST_F(cyclic_array_tester, tests_shift_right_by_bigger_negative_value)
{
    // when
    ca.shift_right(-5);

    // then
    EXPECT_EQ(elem3, ca[0]);
    EXPECT_EQ(elem1, ca[1]);
    EXPECT_EQ(elem2, ca[2]);
}

} // namespace testing
} // namespace pk
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_TXTPARAE_HXX
#include "txtparae.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

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

#include <vector>

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XINDEXREPLACE_HPP_
#include <com/sun/star/container/XIndexReplace.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
#include <com/sun/star/beans/PropertyValues.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_XTEXTSECTION_HPP_
#include <com/sun/star/text/XTextSection.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_SECTIONFILELINK_HPP_
#include <com/sun/star/text/SectionFileLink.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_XDOCUMENTINDEX_HPP_
#include <com/sun/star/text/XDocumentIndex.hpp>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_FAMILIES_HXX_
#include "families.hxx"
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif

#ifndef _XMLOFF_XMLTKMAP_HXX
#include "xmltkmap.hxx"
#endif

#ifndef _XMLOFF_XMLTEXTNUMRULEINFO_HXX
#include "XMLTextNumRuleInfo.hxx"
#endif

#ifndef _XMLOFF_XMLSECTIONEXPORT_HXX_
#include "XMLSectionExport.hxx"
#endif

#ifndef _XMLOFF_XMLREDLINEEXPORT_HXX
#include "XMLRedlineExport.hxx"
#endif
#ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX
#include "MultiPropertySetHelper.hxx"
#endif

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

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::beans::PropertyValues;
using ::com::sun::star::beans::PropertyState;
using ::com::sun::star::container::XIndexReplace;
using ::com::sun::star::container::XNamed;
using ::com::sun::star::lang::XServiceInfo;

Reference<XText> lcl_findXText(const Reference<XTextSection>& rSect)
{
    Reference<XText> xText;

    Reference<XTextContent> xTextContent(rSect, UNO_QUERY);
    if (xTextContent.is())
    {
        xText.set(xTextContent->getAnchor()->getText());
    }

    return xText;
}

void XMLTextParagraphExport::exportListAndSectionChange(
    Reference<XTextSection> & rPrevSection,
    const Reference<XTextContent> & rNextSectionContent,
    const XMLTextNumRuleInfo& rPrevRule,
    const XMLTextNumRuleInfo& rNextRule,
    sal_Bool bAutoStyles)
{
    Reference<XTextSection> xNextSection;

    // first: get current XTextSection
    Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY);
    if (xPropSet.is())
    {
        if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
        {
            xPropSet->getPropertyValue(sTextSection) >>= xNextSection;
        }
        // else: no current section
    }

    exportListAndSectionChange(rPrevSection, xNextSection,
                               rPrevRule, rNextRule, bAutoStyles);
}

void XMLTextParagraphExport::exportListAndSectionChange(
    Reference<XTextSection> & rPrevSection,
    MultiPropertySetHelper& rPropSetHelper,
    sal_Int16 nTextSectionId,
    const Reference<XTextContent> & rNextSectionContent,
    const XMLTextNumRuleInfo& rPrevRule,
    const XMLTextNumRuleInfo& rNextRule,
    sal_Bool bAutoStyles)
{
    Reference<XTextSection> xNextSection;

    // first: get current XTextSection
    Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY);
    if (xPropSet.is())
    {
        if( !rPropSetHelper.checkedProperties() )
            rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() );
        if( rPropSetHelper.hasProperty( nTextSectionId ))
        {
            xNextSection.set(rPropSetHelper.getValue( nTextSectionId , xPropSet,
                sal_True ), uno::UNO_QUERY);
        }
        // else: no current section
    }

    exportListAndSectionChange(rPrevSection, xNextSection,
                               rPrevRule, rNextRule, bAutoStyles);
}

void XMLTextParagraphExport::exportListAndSectionChange(
    Reference<XTextSection> & rPrevSection,
    const Reference<XTextSection> & rNextSection,
    const XMLTextNumRuleInfo& rPrevRule,
    const XMLTextNumRuleInfo& rNextRule,
    sal_Bool bAutoStyles)
{
    // old != new? -> maybe we have to start or end a new section
    if (rPrevSection != rNextSection)
    {
        // a new section started, or an old one gets closed!

        // close old list
        XMLTextNumRuleInfo aEmptyNumRule;
        if ( !bAutoStyles )
            exportListChange(rPrevRule, aEmptyNumRule);

        // Build stacks of old and new sections
        // Sections on top of mute sections should not be on the stack
        vector<Reference<XTextSection> > aOldStack;
        Reference<XTextSection> aCurrent(rPrevSection);
        while(aCurrent.is())
        {
            // if we have a mute section, ignore all its children
            // (all previous ones)
            if (pSectionExport->IsMuteSection(aCurrent))
                aOldStack.clear();

            aOldStack.push_back(aCurrent);
            aCurrent.set(aCurrent->getParentSection());
        }

        vector<Reference<XTextSection> > aNewStack;
        aCurrent.set(rNextSection);
        sal_Bool bMute = sal_False;
        while(aCurrent.is())
        {
            // if we have a mute section, ignore all its children
            // (all previous ones)
            if (pSectionExport->IsMuteSection(aCurrent))
            {
                aNewStack.clear();
                bMute = sal_True;
            }

            aNewStack.push_back(aCurrent);
            aCurrent.set(aCurrent->getParentSection());
        }

        // compare the two stacks
        vector<Reference<XTextSection> > ::reverse_iterator aOld =
            aOldStack.rbegin();
        vector<Reference<XTextSection> > ::reverse_iterator aNew =
            aNewStack.rbegin();
        // compare bottom sections and skip equal section
        while ( (aOld != aOldStack.rend()) &&
                (aNew != aNewStack.rend()) &&
                (*aOld) == (*aNew) )
        {
            ++aOld;
            ++aNew;
        }

        // close all elements of aOld ...
        // (order: newest to oldest)
        if (aOld != aOldStack.rend())
        {
            vector<Reference<XTextSection> > ::iterator aOldForward(
                aOldStack.begin());
            while ((aOldForward != aOldStack.end()) &&
                   (*aOldForward != *aOld))
            {
                if ( !bAutoStyles && (NULL != pRedlineExport) )
                    pRedlineExport->ExportStartOrEndRedline(*aOldForward,
                                                                sal_False);
                pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles);
                ++aOldForward;
            }
            if (aOldForward != aOldStack.end())
            {
                if ( !bAutoStyles && (NULL != pRedlineExport) )
                    pRedlineExport->ExportStartOrEndRedline(*aOldForward,
                                                            sal_False);
                pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles);
            }
        }

        // ...then open all of aNew
        // (order: oldest to newest)
        while (aNew != aNewStack.rend())
        {
            if ( !bAutoStyles && (NULL != pRedlineExport) )
                pRedlineExport->ExportStartOrEndRedline(*aNew, sal_True);
            pSectionExport->ExportSectionStart(*aNew, bAutoStyles);
            ++aNew;
        }

        // start new list
        if ( !bAutoStyles && !bMute )
            exportListChange(aEmptyNumRule, rNextRule);
    }
    else
    {
        // list change, if sections have not changed
        if ( !bAutoStyles )
            exportListChange(rPrevRule, rNextRule);
    }

    // save old section (old numRule gets saved in calling method)
    rPrevSection.set(rNextSection);
}

<commit_msg>INTEGRATION: CWS vgbugs07 (1.16.124); FILE MERGED 2007/06/04 13:23:42 vg 1.16.124.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: txtsecte.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:17:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_TXTPARAE_HXX
#include <xmloff/txtparae.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

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

#include <vector>

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XINDEXREPLACE_HPP_
#include <com/sun/star/container/XIndexReplace.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
#include <com/sun/star/beans/PropertyValues.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_XTEXTSECTION_HPP_
#include <com/sun/star/text/XTextSection.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_SECTIONFILELINK_HPP_
#include <com/sun/star/text/SectionFileLink.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif

#ifndef _COM_SUN_STAR_TEXT_XDOCUMENTINDEX_HPP_
#include <com/sun/star/text/XDocumentIndex.hpp>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_FAMILIES_HXX_
#include <xmloff/families.hxx>
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include <xmloff/xmlexp.hxx>
#endif

#ifndef _XMLOFF_XMLTKMAP_HXX
#include <xmloff/xmltkmap.hxx>
#endif

#ifndef _XMLOFF_XMLTEXTNUMRULEINFO_HXX
#include "XMLTextNumRuleInfo.hxx"
#endif

#ifndef _XMLOFF_XMLSECTIONEXPORT_HXX_
#include "XMLSectionExport.hxx"
#endif

#ifndef _XMLOFF_XMLREDLINEEXPORT_HXX
#include "XMLRedlineExport.hxx"
#endif
#ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX
#include "MultiPropertySetHelper.hxx"
#endif

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

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::beans::PropertyValues;
using ::com::sun::star::beans::PropertyState;
using ::com::sun::star::container::XIndexReplace;
using ::com::sun::star::container::XNamed;
using ::com::sun::star::lang::XServiceInfo;

Reference<XText> lcl_findXText(const Reference<XTextSection>& rSect)
{
    Reference<XText> xText;

    Reference<XTextContent> xTextContent(rSect, UNO_QUERY);
    if (xTextContent.is())
    {
        xText.set(xTextContent->getAnchor()->getText());
    }

    return xText;
}

void XMLTextParagraphExport::exportListAndSectionChange(
    Reference<XTextSection> & rPrevSection,
    const Reference<XTextContent> & rNextSectionContent,
    const XMLTextNumRuleInfo& rPrevRule,
    const XMLTextNumRuleInfo& rNextRule,
    sal_Bool bAutoStyles)
{
    Reference<XTextSection> xNextSection;

    // first: get current XTextSection
    Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY);
    if (xPropSet.is())
    {
        if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
        {
            xPropSet->getPropertyValue(sTextSection) >>= xNextSection;
        }
        // else: no current section
    }

    exportListAndSectionChange(rPrevSection, xNextSection,
                               rPrevRule, rNextRule, bAutoStyles);
}

void XMLTextParagraphExport::exportListAndSectionChange(
    Reference<XTextSection> & rPrevSection,
    MultiPropertySetHelper& rPropSetHelper,
    sal_Int16 nTextSectionId,
    const Reference<XTextContent> & rNextSectionContent,
    const XMLTextNumRuleInfo& rPrevRule,
    const XMLTextNumRuleInfo& rNextRule,
    sal_Bool bAutoStyles)
{
    Reference<XTextSection> xNextSection;

    // first: get current XTextSection
    Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY);
    if (xPropSet.is())
    {
        if( !rPropSetHelper.checkedProperties() )
            rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() );
        if( rPropSetHelper.hasProperty( nTextSectionId ))
        {
            xNextSection.set(rPropSetHelper.getValue( nTextSectionId , xPropSet,
                sal_True ), uno::UNO_QUERY);
        }
        // else: no current section
    }

    exportListAndSectionChange(rPrevSection, xNextSection,
                               rPrevRule, rNextRule, bAutoStyles);
}

void XMLTextParagraphExport::exportListAndSectionChange(
    Reference<XTextSection> & rPrevSection,
    const Reference<XTextSection> & rNextSection,
    const XMLTextNumRuleInfo& rPrevRule,
    const XMLTextNumRuleInfo& rNextRule,
    sal_Bool bAutoStyles)
{
    // old != new? -> maybe we have to start or end a new section
    if (rPrevSection != rNextSection)
    {
        // a new section started, or an old one gets closed!

        // close old list
        XMLTextNumRuleInfo aEmptyNumRule;
        if ( !bAutoStyles )
            exportListChange(rPrevRule, aEmptyNumRule);

        // Build stacks of old and new sections
        // Sections on top of mute sections should not be on the stack
        vector<Reference<XTextSection> > aOldStack;
        Reference<XTextSection> aCurrent(rPrevSection);
        while(aCurrent.is())
        {
            // if we have a mute section, ignore all its children
            // (all previous ones)
            if (pSectionExport->IsMuteSection(aCurrent))
                aOldStack.clear();

            aOldStack.push_back(aCurrent);
            aCurrent.set(aCurrent->getParentSection());
        }

        vector<Reference<XTextSection> > aNewStack;
        aCurrent.set(rNextSection);
        sal_Bool bMute = sal_False;
        while(aCurrent.is())
        {
            // if we have a mute section, ignore all its children
            // (all previous ones)
            if (pSectionExport->IsMuteSection(aCurrent))
            {
                aNewStack.clear();
                bMute = sal_True;
            }

            aNewStack.push_back(aCurrent);
            aCurrent.set(aCurrent->getParentSection());
        }

        // compare the two stacks
        vector<Reference<XTextSection> > ::reverse_iterator aOld =
            aOldStack.rbegin();
        vector<Reference<XTextSection> > ::reverse_iterator aNew =
            aNewStack.rbegin();
        // compare bottom sections and skip equal section
        while ( (aOld != aOldStack.rend()) &&
                (aNew != aNewStack.rend()) &&
                (*aOld) == (*aNew) )
        {
            ++aOld;
            ++aNew;
        }

        // close all elements of aOld ...
        // (order: newest to oldest)
        if (aOld != aOldStack.rend())
        {
            vector<Reference<XTextSection> > ::iterator aOldForward(
                aOldStack.begin());
            while ((aOldForward != aOldStack.end()) &&
                   (*aOldForward != *aOld))
            {
                if ( !bAutoStyles && (NULL != pRedlineExport) )
                    pRedlineExport->ExportStartOrEndRedline(*aOldForward,
                                                                sal_False);
                pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles);
                ++aOldForward;
            }
            if (aOldForward != aOldStack.end())
            {
                if ( !bAutoStyles && (NULL != pRedlineExport) )
                    pRedlineExport->ExportStartOrEndRedline(*aOldForward,
                                                            sal_False);
                pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles);
            }
        }

        // ...then open all of aNew
        // (order: oldest to newest)
        while (aNew != aNewStack.rend())
        {
            if ( !bAutoStyles && (NULL != pRedlineExport) )
                pRedlineExport->ExportStartOrEndRedline(*aNew, sal_True);
            pSectionExport->ExportSectionStart(*aNew, bAutoStyles);
            ++aNew;
        }

        // start new list
        if ( !bAutoStyles && !bMute )
            exportListChange(aEmptyNumRule, rNextRule);
    }
    else
    {
        // list change, if sections have not changed
        if ( !bAutoStyles )
            exportListChange(rPrevRule, rNextRule);
    }

    // save old section (old numRule gets saved in calling method)
    rPrevSection.set(rNextSection);
}

<|endoftext|>


<commit_before>/************************************************************************/
/*                                                                      */
/*                 Copyright 2009 by Ullrich Koethe                     */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#define PY_ARRAY_UNIQUE_SYMBOL vigranumpytest_PyArray_API
#include <Python.h>
#include <boost/python.hpp>
#include <vigra/numpy_array.hxx>
#include <vigra/numpy_array_converters.hxx>
#include <vigra/fftw3.hxx>
#include <iostream>

namespace vigra {

template <>
struct NumpyArrayValuetypeTraits<FFTWComplex>
{
    static bool isValuetypeCompatible(PyArrayObject const * obj) /* obj must not be NULL */
    {
        return PyArray_EquivTypenums(NPY_CDOUBLE, PyArray_DESCR((PyObject *)obj)->type_num) &&
               PyArray_ITEMSIZE((PyObject *)obj) == sizeof(FFTWComplex);
    }

    static NPY_TYPES const typeCode = NPY_CDOUBLE;

    static std::string typeName()
    {
        return "complex128";
    }

    static std::string typeNameImpex()
    {
        return "";
    }

    static PyObject * typeObject()
    {
        return PyArray_TypeObjectFromType(NPY_CDOUBLE);
    }
};

template <unsigned int N, int SIGN>
NumpyAnyArray
pythonFourierTransform(NumpyArray<N, Multiband<FFTWComplex> > in, NumpyArray<N, Multiband<FFTWComplex> > res)
{
    res.reshapeIfEmpty(in.shape(), in.strideOrdering(),
        "fourierTransform(): Output array must have the same shape and stride ordering as input array.", true);

    for(MultiArrayIndex k=0; k<in.shape(N-1); ++k)
    {
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bin = in.bindOuter(k).permuteStridesDescending();
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bres = res.bindOuter(k).permuteStridesDescending();

        TinyVector<int, N-1> bshape(bin.shape()), itotal(bin.shape()), ototal(bres.shape());
        double norm = (double)bshape[0];
        for(int j=1; j<N-1; ++j)
        {
            itotal[j] = bin.stride(j-1) / bin.stride(j);
            ototal[j] = bres.stride(j-1) / bres.stride(j);
            norm *= (double)bshape[j];
        }

        fftw_plan plan = fftw_plan_many_dft(N-1, bshape.begin(), 1,
                                            (fftw_complex*)bin.data(), itotal.begin(),
                                            bin.stride(N-2), 0,
                                            (fftw_complex*)bres.data(), ototal.begin(),
                                            bres.stride(N-2), 0,
                                            SIGN, FFTW_ESTIMATE);
        vigra_postcondition(plan != 0, "fourierTransform(): Unable to create plan.");
        fftw_execute(plan);
        fftw_destroy_plan(plan);
        if(SIGN == FFTW_BACKWARD)
        {
            bres *= FFTWComplex(1.0 / norm);
        }
    }
    return res;
}

NumpyAnyArray
pythonFourierTransformR2C(NumpyAnyArray in, NumpyAnyArray res)
{
    switch(in.spatialDimensions())
    {
      case 2:
      {
        NumpyArray<3, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<3, FFTW_FORWARD>(inc, out);
      }
      case 3:
      {
        NumpyArray<4, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<4, FFTW_FORWARD>(inc, out);
      }
      default:
        vigra_fail("fourierTransform(): "
                   "Can only handle 2 or 3 spatial dimensions.");
    }
    return res; // this will never be reached
}

} // namespace vigra

using namespace boost::python;
using namespace vigra;

BOOST_PYTHON_MODULE_INIT(fourier)
{
    import_vigranumpy();

    docstring_options doc_options(true, true, false);

    def("fourierTransform", registerConverters(&pythonFourierTransformR2C),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional or 3-dimensional Fourier transformation of a scalar float64 array."
        "If the input array has multiple channels, each channel is transformed separately.\n"
        );

    def("fourierTransform", registerConverters(&pythonFourierTransform<3, FFTW_FORWARD>),
        (arg("image"), arg("out") = object()),
        "Likewise for a 2D complex128 image.\n");

    def("fourierTransform", registerConverters(&pythonFourierTransform<4, FFTW_FORWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<3, FFTW_BACKWARD>),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional inverse Fourier transformation of a complex array."
        "If the input array has multiple channels, each channel is transformed separately.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<4, FFTW_BACKWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");
}
<commit_msg>vigranumpy.fourier: added support for Gabor filtering (patch by Jens Barthel)<commit_after>/************************************************************************/
/*                                                                      */
/*                 Copyright 2009 by Ullrich Koethe                     */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#define PY_ARRAY_UNIQUE_SYMBOL vigranumpytest_PyArray_API
#include <Python.h>
#include <boost/python.hpp>
#include <vigra/numpy_array.hxx>
#include <vigra/multi_array.hxx>
#include <vigra/numpy_array_converters.hxx>
#include <vigra/fftw3.hxx>
#include <vigra/gaborfilter.hxx>
#include <iostream>

namespace vigra {

template <>
struct NumpyArrayValuetypeTraits<FFTWComplex>
{
    static bool isValuetypeCompatible(PyArrayObject const * obj) /* obj must not be NULL */
    {
        return PyArray_EquivTypenums(NPY_CDOUBLE, PyArray_DESCR((PyObject *)obj)->type_num) &&
               PyArray_ITEMSIZE((PyObject *)obj) == sizeof(FFTWComplex);
    }

    static NPY_TYPES const typeCode = NPY_CDOUBLE;

    static std::string typeName()
    {
        return "complex128";
    }

    static std::string typeNameImpex()
    {
        return "";
    }

    static PyObject * typeObject()
    {
        return PyArray_TypeObjectFromType(NPY_CDOUBLE);
    }
};

template <class T>
NumpyAnyArray
pythonCreateGaborFilter(typename MultiArrayView<2,T>::difference_type shape,
                        double orientation, double centerFrequency,
                        double angularSigma, double radialSigma, NumpyArray<2,Singleband<T> > res)
{
    res.reshapeIfEmpty(shape, "createGaborFilter(): Output array has wrong shape.");

    createGaborFilter(destImageRange(res),
                      orientation, centerFrequency, angularSigma, radialSigma);
    return res;
}

template <unsigned int N, int SIGN>
NumpyAnyArray
pythonFourierTransform(NumpyArray<N, Multiband<FFTWComplex> > in, NumpyArray<N, Multiband<FFTWComplex> > res)
{
    res.reshapeIfEmpty(in.shape(), in.strideOrdering(),
        "fourierTransform(): Output array must have the same shape and stride ordering as input array.", true);

    for(MultiArrayIndex k=0; k<in.shape(N-1); ++k)
    {
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bin = in.bindOuter(k).permuteStridesDescending();
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bres = res.bindOuter(k).permuteStridesDescending();

        TinyVector<int, N-1> bshape(bin.shape()), itotal(bin.shape()), ototal(bres.shape());
        double norm = (double)bshape[0];
        for(int j=1; j<N-1; ++j)
        {
            itotal[j] = bin.stride(j-1) / bin.stride(j);
            ototal[j] = bres.stride(j-1) / bres.stride(j);
            norm *= (double)bshape[j];
        }

        fftw_plan plan = fftw_plan_many_dft(N-1, bshape.begin(), 1,
                                            (fftw_complex*)bin.data(), itotal.begin(),
                                            bin.stride(N-2), 0,
                                            (fftw_complex*)bres.data(), ototal.begin(),
                                            bres.stride(N-2), 0,
                                            SIGN, FFTW_ESTIMATE);
        vigra_postcondition(plan != 0, "fourierTransform(): Unable to create plan.");
        fftw_execute(plan);
        fftw_destroy_plan(plan);
        if(SIGN == FFTW_BACKWARD)
        {
            bres *= FFTWComplex(1.0 / norm);
        }
    }
    return res;
}

NumpyAnyArray
pythonFourierTransformR2C(NumpyAnyArray in, NumpyAnyArray res)
{
    switch(in.spatialDimensions())
    {
      case 2:
      {
        NumpyArray<3, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<3, FFTW_FORWARD>(inc, out);
      }
      case 3:
      {
        NumpyArray<4, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<4, FFTW_FORWARD>(inc, out);
      }
      default:
        vigra_fail("fourierTransform(): "
                   "Can only handle 2 or 3 spatial dimensions.");
    }
    return res; // this will never be reached
}

} // namespace vigra

using namespace boost::python;
using namespace vigra;

BOOST_PYTHON_MODULE_INIT(fourier)
{
    import_vigranumpy();

    docstring_options doc_options(true, true, false);

    def("fourierTransform", registerConverters(&pythonFourierTransformR2C),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional or 3-dimensional Fourier transformation of a scalar float64 array."
        "If the input array has multiple channels, each channel is transformed separately.\n"
        );

    def("fourierTransform", registerConverters(&pythonFourierTransform<3, FFTW_FORWARD>),
        (arg("image"), arg("out") = object()),
        "Likewise for a 2D complex128 image.\n");

    def("fourierTransform", registerConverters(&pythonFourierTransform<4, FFTW_FORWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<3, FFTW_BACKWARD>),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional inverse Fourier transformation of a complex array."
        "If the input array has multiple channels, each channel is transformed separately.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<4, FFTW_BACKWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("createGaborFilter", registerConverters(&pythonCreateGaborFilter<float>),
        (arg("shape"),arg("orientation"),arg("centerFrequency"),arg("angularSigma"),arg("radialSigma"), arg("out") = object()),
        "Create a 2-dimensional gabor filter in frequency space.");

    def("radialGaborSigma", &radialGaborSigma,
        "Calculate sensible radial sigma for given parameters.");

    def("angularGaborSigma", &angularGaborSigma,
        "Calculate sensible angular sigma for given parameters.");
}
<|endoftext|>


<commit_before>/*
**
** Author(s):
**  - Pierre Roullon <proullon@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <qic/servicedirectory.h>
#include <qic/value.h>
#include "value_p.h"

#include <qimessaging/servicedirectory.hpp>

#ifdef __cplusplus
extern "C"
{
#endif

inline qi::ServiceDirectory *qi_servicedirectory_cpp(qi_servicedirectory_t *value) {
  return reinterpret_cast<qi::ServiceDirectory *>(value);
};

qi_servicedirectory_t *qi_servicedirectory_create()
{
  qi::ServiceDirectory* sd = new qi::ServiceDirectory();
  return (qi_servicedirectory_t *) sd;
}

void              qi_servicedirectory_destroy(qi_servicedirectory_t *servicedirectory)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  delete sd;
}

void              qi_servicedirectory_listen(qi_servicedirectory_t *servicedirectory, const char *url)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  qi::Url ur(url);
  sd->listen(ur);
}

void              qi_servicedirectory_close(qi_servicedirectory_t *servicedirectory)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  sd->close();
}

qi_value_t*       qi_servicedirectory_endpoints(qi_servicedirectory_t *servicedirectory) {
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);

  std::vector<qi::Url> eps = sd->endpoints();
  std::vector<std::string> epss;

  std::vector<qi::Url>::iterator it;
  for (it = eps.begin(); it != eps.end(); ++it) {
    epss.push_back(it->str());
  }
  qi_value_t *val = qi_value_create("");
  qi::AnyValue &gvp = qi_value_cpp(val);
  gvp.destroy();
  gvp = qi::AnyValue::from(epss);
  return val;
}

int qi_servicedirectory_set_identity(qi_servicedirectory_t *servicedirectory, char *key, char *crt)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  return (int)sd->setIdentity(std::string(key), std::string(crt));
}

#ifdef __cplusplus
}
#endif
<commit_msg>c: servicedirectory: do not use AnyValue::destroy<commit_after>/*
**
** Author(s):
**  - Pierre Roullon <proullon@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <qic/servicedirectory.h>
#include <qic/value.h>
#include "value_p.h"

#include <qimessaging/servicedirectory.hpp>

#ifdef __cplusplus
extern "C"
{
#endif

inline qi::ServiceDirectory *qi_servicedirectory_cpp(qi_servicedirectory_t *value) {
  return reinterpret_cast<qi::ServiceDirectory *>(value);
};

qi_servicedirectory_t *qi_servicedirectory_create()
{
  qi::ServiceDirectory* sd = new qi::ServiceDirectory();
  return (qi_servicedirectory_t *) sd;
}

void              qi_servicedirectory_destroy(qi_servicedirectory_t *servicedirectory)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  delete sd;
}

void              qi_servicedirectory_listen(qi_servicedirectory_t *servicedirectory, const char *url)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  qi::Url ur(url);
  sd->listen(ur);
}

void              qi_servicedirectory_close(qi_servicedirectory_t *servicedirectory)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  sd->close();
}

qi_value_t*       qi_servicedirectory_endpoints(qi_servicedirectory_t *servicedirectory) {
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);

  std::vector<qi::Url> eps = sd->endpoints();
  std::vector<std::string> epss;

  std::vector<qi::Url>::iterator it;
  for (it = eps.begin(); it != eps.end(); ++it) {
    epss.push_back(it->str());
  }
  qi_value_t *val = qi_value_create("");
  qi::AnyValue &gvp = qi_value_cpp(val);
  gvp = qi::AnyValue::from(epss);
  return val;
}

int qi_servicedirectory_set_identity(qi_servicedirectory_t *servicedirectory, char *key, char *crt)
{
  qi::ServiceDirectory* sd = qi_servicedirectory_cpp(servicedirectory);
  return (int)sd->setIdentity(std::string(key), std::string(crt));
}

#ifdef __cplusplus
}
#endif
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QEventLoop>
#include <QtTest>

#include <TelepathyQt4/Constants>
#include <TelepathyQt4/Debug>
#include <TelepathyQt4/Types>
#include <TelepathyQt4/Client/StatefulDBusProxy>

using namespace Telepathy;
using namespace Telepathy::Client;

// expose protected functions for testing
class MyStatefulDBusProxy : public StatefulDBusProxy
{
public:
    MyStatefulDBusProxy(const QDBusConnection &dbusConnection,
            const QString &busName, const QString &objectPath,
            QObject *parent = 0)
        : StatefulDBusProxy(dbusConnection, busName, objectPath, parent)
    {
    }

    using StatefulDBusProxy::invalidate;
};

class TestStatefulProxy : public QObject
{
    Q_OBJECT

public:
    TestStatefulProxy(QObject *parent = 0);
    ~TestStatefulProxy();

private Q_SLOTS:
    void initTestCase();
    void init();

    void testBasics();
    void testNameOwnerChanged();

    void cleanup();
    void cleanupTestCase();

protected Q_SLOTS:
    // these would be public, but then QtTest would think they were tests
    void expectInvalidated(Telepathy::Client::DBusProxy *,
            QString, QString);

private:
    QEventLoop *mLoop;
    MyStatefulDBusProxy *mProxy;

    int mInvalidated;
    QString mSignalledInvalidationReason;
    QString mSignalledInvalidationMessage;

    static QString wellKnownName();
    static QString objectPath();
    static QString uniqueName();
};

QString TestStatefulProxy::wellKnownName()
{
    return "org.freedesktop.Telepathy.Qt4.TestStatefulProxy";
}

QString TestStatefulProxy::objectPath()
{
    return "/org/freedesktop/Telepathy/Qt4/TestStatefulProxy/Object";
}

TestStatefulProxy::TestStatefulProxy(QObject *parent)
    : QObject(parent),
      mLoop(new QEventLoop(this)),
      mProxy(0)
{
}

TestStatefulProxy::~TestStatefulProxy()
{
    delete mLoop;
}

QString TestStatefulProxy::uniqueName()
{
    return QDBusConnection::sessionBus().baseService();
}

void TestStatefulProxy::initTestCase()
{
    Telepathy::registerTypes();
    Telepathy::enableDebug(true);
    Telepathy::enableWarnings(true);

    QVERIFY(QDBusConnection::sessionBus().isConnected());
    QVERIFY(QDBusConnection::sessionBus().registerService(wellKnownName()));
}

void TestStatefulProxy::init()
{
    mInvalidated = 0;
}

void TestStatefulProxy::testBasics()
{
    mProxy = new MyStatefulDBusProxy(QDBusConnection::sessionBus(),
            wellKnownName(), objectPath());

    QVERIFY(mProxy);
    QCOMPARE(mProxy->dbusConnection().baseService(), uniqueName());
    QCOMPARE(mProxy->busName(), uniqueName());
    QCOMPARE(mProxy->objectPath(), objectPath());

    QVERIFY(mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(), QString());
    QCOMPARE(mProxy->invalidationMessage(), QString());

    QVERIFY(connect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));
    mProxy->invalidate("com.example.DomainSpecificError",
            "Because I said so");

    QVERIFY(!mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(),
            QString::fromAscii("com.example.DomainSpecificError"));
    QCOMPARE(mProxy->invalidationMessage(),
            QString::fromAscii("Because I said so"));

    // the signal doesn't arrive instantly
    QCOMPARE(mLoop->exec(), 0);
    QVERIFY(disconnect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));

    QCOMPARE(mInvalidated, 1);
    QVERIFY(!mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(),
            QString::fromAscii("com.example.DomainSpecificError"));
    QCOMPARE(mSignalledInvalidationReason,
            QString::fromAscii("com.example.DomainSpecificError"));
    QCOMPARE(mProxy->invalidationMessage(),
            QString::fromAscii("Because I said so"));
    QCOMPARE(mSignalledInvalidationMessage,
            QString::fromAscii("Because I said so"));
}

void TestStatefulProxy::expectInvalidated(DBusProxy *proxy,
        QString reason, QString message)
{
    mInvalidated++;
    mSignalledInvalidationReason = reason;
    mSignalledInvalidationMessage = message;
    mLoop->exit(0);
}

void TestStatefulProxy::testNameOwnerChanged()
{
    QString otherUniqueName = QDBusConnection::connectToBus(
            QDBusConnection::SessionBus,
            "another unique name").baseService();

    mProxy = new MyStatefulDBusProxy(QDBusConnection::sessionBus(),
            otherUniqueName, objectPath());

    QVERIFY(mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(), QString());
    QCOMPARE(mProxy->invalidationMessage(), QString());

    QVERIFY(connect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));
    QDBusConnection::disconnectFromBus("another unique name");
    QCOMPARE(mLoop->exec(), 0);
    QVERIFY(disconnect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));

    QCOMPARE(mInvalidated, 1);
    QVERIFY(!mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(),
            QString::fromAscii(TELEPATHY_DBUS_ERROR_NAME_HAS_NO_OWNER));
    QCOMPARE(mSignalledInvalidationReason,
            QString::fromAscii(TELEPATHY_DBUS_ERROR_NAME_HAS_NO_OWNER));
    QVERIFY(!mProxy->invalidationMessage().isEmpty());
    QCOMPARE(mProxy->invalidationMessage(), mSignalledInvalidationMessage);
}

void TestStatefulProxy::cleanup()
{
    if (mProxy) {
        delete mProxy;
        mProxy = 0;
    }
}

void TestStatefulProxy::cleanupTestCase()
{
}

QTEST_MAIN(TestStatefulProxy)

#include "_gen/stateful-proxy.cpp.moc.hpp"
<commit_msg>Add a test for method calls failing<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QEventLoop>
#include <QtTest>

#include <TelepathyQt4/Constants>
#include <TelepathyQt4/Debug>
#include <TelepathyQt4/Types>
#include <TelepathyQt4/Client/DBus>
#include <TelepathyQt4/Client/StatefulDBusProxy>

#include "tests/lib/test.h"

using namespace Telepathy;
using namespace Telepathy::Client;
using Telepathy::Client::DBus::IntrospectableInterface;

// expose protected functions for testing
class MyStatefulDBusProxy : public StatefulDBusProxy
{
public:
    MyStatefulDBusProxy(const QDBusConnection &dbusConnection,
            const QString &busName, const QString &objectPath,
            QObject *parent = 0)
        : StatefulDBusProxy(dbusConnection, busName, objectPath, parent)
    {
    }

    using StatefulDBusProxy::invalidate;
};

class ObjectAdaptor : public QDBusAbstractAdaptor
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.example.Foo")

public:
    ObjectAdaptor(Test *test)
        : QDBusAbstractAdaptor(test)
    {
    }
};

class TestStatefulProxy : public Test
{
    Q_OBJECT

public:
    TestStatefulProxy(QObject *parent = 0);

private Q_SLOTS:
    void initTestCase();
    void init();

    void testBasics();
    void testNameOwnerChanged();

    void cleanup();
    void cleanupTestCase();

protected Q_SLOTS:
    // these would be public, but then QtTest would think they were tests
    void expectInvalidated(Telepathy::Client::DBusProxy *,
            QString, QString);

    // anything other than 0 or 1 is OK
#   define EXPECT_INVALIDATED_SUCCESS 111

private:
    MyStatefulDBusProxy *mProxy;
    ObjectAdaptor *mAdaptor;

    int mInvalidated;
    QString mSignalledInvalidationReason;
    QString mSignalledInvalidationMessage;

    static QString wellKnownName();
    static QString objectPath();
    static QString uniqueName();
};

QString TestStatefulProxy::wellKnownName()
{
    return "org.freedesktop.Telepathy.Qt4.TestStatefulProxy";
}

QString TestStatefulProxy::objectPath()
{
    return "/org/freedesktop/Telepathy/Qt4/TestStatefulProxy/Object";
}

TestStatefulProxy::TestStatefulProxy(QObject *parent)
    : Test(parent),
      mProxy(0),
      mAdaptor(new ObjectAdaptor(this))
{
}

QString TestStatefulProxy::uniqueName()
{
    return QDBusConnection::sessionBus().baseService();
}

void TestStatefulProxy::initTestCase()
{
    initTestCaseImpl();

    QVERIFY(QDBusConnection::sessionBus().registerService(wellKnownName()));
    QDBusConnection::sessionBus().registerObject(objectPath(), this);
}

void TestStatefulProxy::init()
{
    initImpl();

    mInvalidated = 0;
}

void TestStatefulProxy::testBasics()
{
    mProxy = new MyStatefulDBusProxy(QDBusConnection::sessionBus(),
            wellKnownName(), objectPath());
    IntrospectableInterface ifaceFromProxy(mProxy);
    IntrospectableInterface ifaceFromWellKnown(wellKnownName(), objectPath());
    IntrospectableInterface ifaceFromUnique(uniqueName(), objectPath());

    QVERIFY(mProxy);
    QCOMPARE(mProxy->dbusConnection().baseService(), uniqueName());
    QCOMPARE(mProxy->busName(), uniqueName());
    QCOMPARE(mProxy->objectPath(), objectPath());

    QVERIFY(mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(), QString());
    QCOMPARE(mProxy->invalidationMessage(), QString());

    QDBusPendingReply<QString> reply;
    QDBusPendingCallWatcher *watcher;

    reply = ifaceFromUnique.Introspect();
    if (!reply.isValid()) {
        watcher = new QDBusPendingCallWatcher(reply);
        QVERIFY(connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
                this, SLOT(expectSuccessfulCall(QDBusPendingCallWatcher *))));
        QCOMPARE(mLoop->exec(), 0);
        delete watcher;
    }

    reply = ifaceFromWellKnown.Introspect();
    if (!reply.isValid()) {
        watcher = new QDBusPendingCallWatcher(reply);
        QVERIFY(connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
                this, SLOT(expectSuccessfulCall(QDBusPendingCallWatcher *))));
        QCOMPARE(mLoop->exec(), 0);
        delete watcher;
    }

    reply = ifaceFromProxy.Introspect();
    if (!reply.isValid()) {
        watcher = new QDBusPendingCallWatcher(reply);
        QVERIFY(connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
                this, SLOT(expectSuccessfulCall(QDBusPendingCallWatcher *))));
        QCOMPARE(mLoop->exec(), 0);
        delete watcher;
    }

    QVERIFY(connect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));
    mProxy->invalidate("com.example.DomainSpecificError",
            "Because I said so");

    QVERIFY(!mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(),
            QString::fromAscii("com.example.DomainSpecificError"));
    QCOMPARE(mProxy->invalidationMessage(),
            QString::fromAscii("Because I said so"));

    // FIXME: ideally, the method call would already fail synchronously at
    // this point - after all, the proxy already knows it's dead
    reply = ifaceFromProxy.Introspect();
    if (reply.isValid()) {
        qWarning() << "reply is valid";
    } else if (reply.isError()) {
        qDebug() << "reply is error" << reply.error().name()
            << reply.error().message();
    } else {
        qWarning() << "no reply yet";
    }

    // the signal doesn't arrive instantly
    QCOMPARE(mLoop->exec(), EXPECT_INVALIDATED_SUCCESS);
    QVERIFY(disconnect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));

    QCOMPARE(mInvalidated, 1);
    QCOMPARE(mSignalledInvalidationReason,
            QString::fromAscii("com.example.DomainSpecificError"));
    QCOMPARE(mSignalledInvalidationMessage,
            QString::fromAscii("Because I said so"));

    // the low-level proxy made from the high-level proxy now returns an
    // error, synchronously
    reply = ifaceFromProxy.Introspect();
    QVERIFY(reply.isError());

    // low-level proxies with no knowledge of the high-level DBusProxy are
    // unaffected

    reply = ifaceFromUnique.Introspect();
    if (!reply.isValid()) {
        watcher = new QDBusPendingCallWatcher(reply);
        QVERIFY(connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
                this, SLOT(expectSuccessfulCall(QDBusPendingCallWatcher *))));
        QCOMPARE(mLoop->exec(), 0);
        delete watcher;
    }

    reply = ifaceFromWellKnown.Introspect();
    if (!reply.isValid()) {
        watcher = new QDBusPendingCallWatcher(reply);
        QVERIFY(connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
                this, SLOT(expectSuccessfulCall(QDBusPendingCallWatcher *))));
        QCOMPARE(mLoop->exec(), 0);
        delete watcher;
    }
}

void TestStatefulProxy::expectInvalidated(DBusProxy *proxy,
        QString reason, QString message)
{
    mInvalidated++;
    mSignalledInvalidationReason = reason;
    mSignalledInvalidationMessage = message;
    mLoop->exit(EXPECT_INVALIDATED_SUCCESS);
}

void TestStatefulProxy::testNameOwnerChanged()
{
    QString otherUniqueName = QDBusConnection::connectToBus(
            QDBusConnection::SessionBus,
            "another unique name").baseService();

    mProxy = new MyStatefulDBusProxy(QDBusConnection::sessionBus(),
            otherUniqueName, objectPath());

    QVERIFY(mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(), QString());
    QCOMPARE(mProxy->invalidationMessage(), QString());

    QVERIFY(connect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));
    QDBusConnection::disconnectFromBus("another unique name");
    QCOMPARE(mLoop->exec(), EXPECT_INVALIDATED_SUCCESS);
    QVERIFY(disconnect(mProxy, SIGNAL(invalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString)),
                this, SLOT(expectInvalidated(
                        Telepathy::Client::DBusProxy *,
                        QString, QString))));

    QCOMPARE(mInvalidated, 1);
    QVERIFY(!mProxy->isValid());
    QCOMPARE(mProxy->invalidationReason(),
            QString::fromAscii(TELEPATHY_DBUS_ERROR_NAME_HAS_NO_OWNER));
    QCOMPARE(mSignalledInvalidationReason,
            QString::fromAscii(TELEPATHY_DBUS_ERROR_NAME_HAS_NO_OWNER));
    QVERIFY(!mProxy->invalidationMessage().isEmpty());
    QCOMPARE(mProxy->invalidationMessage(), mSignalledInvalidationMessage);
}

void TestStatefulProxy::cleanup()
{
    if (mProxy) {
        delete mProxy;
        mProxy = 0;
    }

    cleanupImpl();
}

void TestStatefulProxy::cleanupTestCase()
{
    cleanupTestCaseImpl();
}

QTEST_MAIN(TestStatefulProxy)

#include "_gen/stateful-proxy.cpp.moc.hpp"
<|endoftext|>