<commit_before>/*************************************************************************
 *
 *  $RCSfile: provider.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: abi $ $Date: 2001-10-31 13:08:14 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

/**************************************************************************
                                TODO
 **************************************************************************

 *************************************************************************/

#include <stdio.h>

#ifndef _VOS_DIAGNOSE_HXX_
#include <vos/diagnose.hxx>
#endif
#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
#include <ucbhelper/contentidentifier.hxx>
#endif
#ifndef _DATABASES_HXX_
#include <provider/databases.hxx>
#endif
#ifndef _PROVIDER_HXX
#include <provider/provider.hxx>
#endif
#ifndef _CONTENT_HXX
#include <provider/content.hxx>
#endif
#ifndef _DATABASES_HXX_
#include <provider/databases.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XCONFIGMANAGER_HPP_
#include <com/sun/star/frame/XConfigManager.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif

using namespace com::sun::star::frame;
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
using namespace com::sun::star::lang;
using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;
using namespace rtl;

using namespace chelp;

//=========================================================================
//=========================================================================
//
// ContentProvider Implementation.
//
//=========================================================================
//=========================================================================

ContentProvider::ContentProvider( const Reference< XMultiServiceFactory >& rSMgr )
    : ::ucb::ContentProviderImplHelper( rSMgr ),
        isInitialized( false ),
        m_aScheme( OUString::createFromAscii( MYUCP_URL_SCHEME ) ),
        m_pDatabases( 0 )
{
}

//=========================================================================
// virtual
ContentProvider::~ContentProvider()
{
    delete m_pDatabases;
}

//=========================================================================
//
// XInterface methods.
//
//=========================================================================

XINTERFACE_IMPL_3( ContentProvider,
                   XTypeProvider,
                   XServiceInfo,
                   XContentProvider );

//=========================================================================
//
// XTypeProvider methods.
//
//=========================================================================

XTYPEPROVIDER_IMPL_3( ContentProvider,
                         XTypeProvider,
                         XServiceInfo,
                         XContentProvider );

//=========================================================================
//
// XServiceInfo methods.
//
//=========================================================================

XSERVICEINFO_IMPL_1( ContentProvider,
                     OUString::createFromAscii(
                             "CHelpContentProvider" ),
                     OUString::createFromAscii(
                             MYUCP_CONTENT_PROVIDER_SERVICE_NAME ) );

//=========================================================================
//
// Service factory implementation.
//
//=========================================================================

ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );

//=========================================================================
//
// XContentProvider methods.
//
//=========================================================================

// virtual
Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& xCanonicId )
    throw( IllegalIdentifierException, RuntimeException )
{
    if ( ! xCanonicId->getContentProviderScheme().equalsIgnoreAsciiCase( m_aScheme ) )
    {   // Wrong URL-scheme
        throw IllegalIdentifierException();
    }

    {
        osl::MutexGuard aGuard( m_aMutex );
        if( ! isInitialized )
            init();
    }

    if( ! m_pDatabases )
        throw RuntimeException();

    rtl::OUString aOUString( m_pDatabases->getInstallPathAsURL() );
    rtl::OString aOString( aOUString.getStr(),
                           aOUString.getLength(),
                           RTL_TEXTENCODING_UTF8 );

    // Check, if a content with given id already exists...
    Reference< XContent > xContent
        = queryExistingContent( xCanonicId ).getBodyPtr();
    if ( xContent.is() )
        return xContent;

    xContent = new Content( m_xSMgr,this,xCanonicId,m_pDatabases );

    // Further checks

    if ( !xContent->getIdentifier().is() )
        throw IllegalIdentifierException();

    return xContent;
}

void ContentProvider::init()
{
    osl::MutexGuard aGuard( m_aMutex );

    isInitialized = true;
    Reference< XMultiServiceFactory >  sProvider( getConfiguration() );
    Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider,
                                                                     "org.openoffice.Office.Common" ) );

    rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
    if( ! instPath.getLength() )
        // try to determine path from default
        instPath = rtl::OUString::createFromAscii( "$(instpath)/help" );

    // replace anything like $(instpath);
    subst( instPath );

    /**
     *  now determing
     *  productname,
     *  productversion,
     *  vendorname,
     *  vendorversion,
     *  vendorshort
     */

    xHierAccess = getHierAccess( sProvider,
                                 "org.openoffice.Setup" );
    rtl::OUString productname( getKey(  xHierAccess,"Product/ooName" ) );

    rtl::OUString setupversion( getKey(  xHierAccess,"Product/ooSetupVersion" ) );
    rtl::OUString setupextension( getKey(  xHierAccess,"Product/ooSetupExtension") );
    rtl::OUString productversion( setupversion +
                                  rtl::OUString::createFromAscii( " " ) +
                                  setupextension );

    xHierAccess = getHierAccess( sProvider,
                                 "org.openoffice.Webtop.Common" );
    rtl::OUString vendorname( getKey(  xHierAccess,"Product/ooName" ) );

    setupversion = rtl::OUString( getKey(  xHierAccess,"Product/ooSetupVersion" ) );
    setupextension = rtl::OUString ( getKey(  xHierAccess,"Product/ooSetupExtension") );
    rtl::OUString vendorversion( setupversion +
                                 rtl::OUString::createFromAscii( " " ) +
                                 setupextension );
    rtl::OUString vendorshort = vendorname;

    m_pDatabases = new Databases( instPath,
                                  productname,
                                  productversion,
                                  vendorname,
                                  vendorversion,
                                  vendorshort,
                                  m_xSMgr );
}

Reference< XMultiServiceFactory > ContentProvider::getConfiguration() const
{
    Reference< XMultiServiceFactory > sProvider;
    if( m_xSMgr.is() )
    {
        Any aAny;
        aAny <<= rtl::OUString::createFromAscii( "plugin" );
        PropertyValue aProp( rtl::OUString::createFromAscii( "servertype" ),
                             -1,
                             aAny,
                             PropertyState_DIRECT_VALUE );

        Sequence< Any > seq(1);
        seq[0] <<= aProp;

        try
        {
            rtl::OUString sProviderService =
                rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" );
            sProvider =
                Reference< XMultiServiceFactory >(
                    m_xSMgr->createInstanceWithArguments( sProviderService,seq ),
                    UNO_QUERY );
        }
        catch( const com::sun::star::uno::Exception& )
        {
            OSL_ENSURE( sProvider.is(),"cant instantiate configuration" );
        }
    }

    return sProvider;
}

Reference< XHierarchicalNameAccess >
ContentProvider::getHierAccess( const Reference< XMultiServiceFactory >& sProvider,
                                const char* file ) const
{
    Reference< XHierarchicalNameAccess > xHierAccess;

    if( sProvider.is() )
    {
        Sequence< Any > seq(1);
        rtl::OUString sReaderService =
            rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" );

        seq[0] <<= rtl::OUString::createFromAscii( file );

        try
        {
            xHierAccess =
                Reference< XHierarchicalNameAccess >
                ( sProvider->createInstanceWithArguments( sReaderService,seq ),
                  UNO_QUERY );
        }
        catch( const com::sun::star::uno::Exception& )
        {
        }
    }

    return xHierAccess;
}

rtl::OUString
ContentProvider::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess,
                         const char* key ) const
{
    rtl::OUString instPath;
    if( xHierAccess.is() )
    {
        Any aAny;
        try
        {
            aAny =
                xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) );
        }
        catch( const com::sun::star::container::NoSuchElementException& )
        {
        }
        aAny >>= instPath;
    }
    return instPath;
}

void ContentProvider::subst( rtl::OUString& instpath ) const
{
    Reference< XConfigManager >  xCfgMgr;
    if( m_xSMgr.is() )
    {
        try
        {
            xCfgMgr =
                Reference< XConfigManager >(
                    m_xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ),
                    UNO_QUERY );
        }
        catch( const com::sun::star::uno::Exception& e )
        {
            OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " );
        }
    }

    OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" );

    if( xCfgMgr.is() )
        instpath = xCfgMgr->substituteVariables( instpath );
}
<commit_msg>#99496# accessibility<commit_after>/*************************************************************************
 *
 *  $RCSfile: provider.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: abi $ $Date: 2002-05-31 10:31:38 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

/**************************************************************************
                                TODO
 **************************************************************************

 *************************************************************************/

#include <stdio.h>

#ifndef _VOS_DIAGNOSE_HXX_
#include <vos/diagnose.hxx>
#endif
#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
#include <ucbhelper/contentidentifier.hxx>
#endif
#ifndef _DATABASES_HXX_
#include <provider/databases.hxx>
#endif
#ifndef _PROVIDER_HXX
#include <provider/provider.hxx>
#endif
#ifndef _CONTENT_HXX
#include <provider/content.hxx>
#endif
#ifndef _DATABASES_HXX_
#include <provider/databases.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XCONFIGMANAGER_HPP_
#include <com/sun/star/frame/XConfigManager.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_
#include <com/sun/star/container/XContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEREPLACE_HPP_
#include <com/sun/star/container/XNameReplace.hpp>
#endif

using namespace com::sun::star::frame;
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
using namespace com::sun::star::lang;
using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;
using namespace rtl;

using namespace chelp;

//=========================================================================
//=========================================================================
//
// ContentProvider Implementation.
//
//=========================================================================
//=========================================================================

ContentProvider::ContentProvider( const Reference< XMultiServiceFactory >& rSMgr )
    : ::ucb::ContentProviderImplHelper( rSMgr ),
        isInitialized( false ),
        m_aScheme( OUString::createFromAscii( MYUCP_URL_SCHEME ) ),
        m_pDatabases( 0 )
{
}

//=========================================================================
// virtual
ContentProvider::~ContentProvider()
{
    delete m_pDatabases;
}

//=========================================================================
//
// XInterface methods.
//
//=========================================================================

XINTERFACE_IMPL_5( ContentProvider,
                   XTypeProvider,
                   XServiceInfo,
                   XContentProvider,
                   XComponent,
                   XContainerListener);

//=========================================================================
//
// XTypeProvider methods.
//
//=========================================================================

XTYPEPROVIDER_IMPL_5( ContentProvider,
                         XTypeProvider,
                         XServiceInfo,
                         XContentProvider,
                      XComponent,
                      XContainerListener);

//=========================================================================
//
// XServiceInfo methods.
//
//=========================================================================

XSERVICEINFO_IMPL_1( ContentProvider,
                     OUString::createFromAscii(
                             "CHelpContentProvider" ),
                     OUString::createFromAscii(
                             MYUCP_CONTENT_PROVIDER_SERVICE_NAME ) );

//=========================================================================
//
// Service factory implementation.
//
//=========================================================================

ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );

//=========================================================================
//
// XContentProvider methods.
//
//=========================================================================

// virtual
Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& xCanonicId )
    throw( IllegalIdentifierException, RuntimeException )
{
    if ( ! xCanonicId->getContentProviderScheme().equalsIgnoreAsciiCase( m_aScheme ) )
    {   // Wrong URL-scheme
        throw IllegalIdentifierException();
    }

    {
        osl::MutexGuard aGuard( m_aMutex );
        if( ! isInitialized )
            init();
    }

    if( ! m_pDatabases )
        throw RuntimeException();

    rtl::OUString aOUString( m_pDatabases->getInstallPathAsURL() );
    rtl::OString aOString( aOUString.getStr(),
                           aOUString.getLength(),
                           RTL_TEXTENCODING_UTF8 );

    // Check, if a content with given id already exists...
    Reference< XContent > xContent
        = queryExistingContent( xCanonicId ).getBodyPtr();
    if ( xContent.is() )
        return xContent;

    xContent = new Content( m_xSMgr,this,xCanonicId,m_pDatabases );

    // Further checks

    if ( !xContent->getIdentifier().is() )
        throw IllegalIdentifierException();

    return xContent;
}

void SAL_CALL
ContentProvider::dispose()
{
    if(m_xContainer.is())
    {
        m_xContainer->removeContainerListener(this);
        m_xContainer = Reference<XContainer>(0);
    }
}

#include <provider/debughelper.hxx>

void SAL_CALL
ContentProvider::elementReplaced(const ContainerEvent& Event)
    throw (::com::sun::star::uno::RuntimeException)
{
    if(!m_pDatabases)
        return;

    rtl::OUString accessor;
    Event.Accessor >>= accessor;
    if(accessor.compareToAscii("HelpStyleSheet"))
        return;

    rtl::OUString replacedElement,element;
    Event.ReplacedElement >>= replacedElement;
    Event.Element >>= element;

    if(replacedElement == element)
        return;

    m_pDatabases->changeCSS(element);
}

void ContentProvider::init()
{
    osl::MutexGuard aGuard( m_aMutex );

    isInitialized = true;
    Reference< XMultiServiceFactory >  sProvider( getConfiguration() );
    Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider,
                                                                     "org.openoffice.Office.Common" ) );

    rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
    if( ! instPath.getLength() )
        // try to determine path from default
        instPath = rtl::OUString::createFromAscii( "$(instpath)/help" );
    // replace anything like $(instpath);
    subst( instPath );

    rtl::OUString stylesheet(getKey(xHierAccess,"Help/HelpStyleSheet"));
    try {
        // now adding as configuration change listener for the stylesheet
        Reference<XNameAccess> xAccess(xHierAccess,UNO_QUERY);
        Any aAny =
            xAccess->getByName(rtl::OUString::createFromAscii("Help"));
        aAny >>= m_xContainer;
        if(m_xContainer.is())
            m_xContainer->addContainerListener(this);
    } catch(const com::sun::star::uno::Exception& e) {
    }

    /**
     *  now determing
     *  productname,
     *  productversion,
     *  vendorname,
     *  vendorversion,
     *  vendorshort
     */

    xHierAccess = getHierAccess( sProvider,
                                 "org.openoffice.Setup" );
    rtl::OUString productname( getKey(  xHierAccess,"Product/ooName" ) );

    rtl::OUString setupversion( getKey(  xHierAccess,"Product/ooSetupVersion" ) );
    rtl::OUString setupextension( getKey(  xHierAccess,"Product/ooSetupExtension") );
    rtl::OUString productversion( setupversion +
                                  rtl::OUString::createFromAscii( " " ) +
                                  setupextension );

    xHierAccess = getHierAccess( sProvider,
                                 "org.openoffice.Webtop.Common" );
    rtl::OUString vendorname( getKey(  xHierAccess,"Product/ooName" ) );

    setupversion = rtl::OUString( getKey(  xHierAccess,"Product/ooSetupVersion" ) );
    setupextension = rtl::OUString ( getKey(  xHierAccess,"Product/ooSetupExtension") );
    rtl::OUString vendorversion( setupversion +
                                 rtl::OUString::createFromAscii( " " ) +
                                 setupextension );
    rtl::OUString vendorshort = vendorname;

    m_pDatabases = new Databases( instPath,
                                  productname,
                                  productversion,
                                  vendorname,
                                  vendorversion,
                                  vendorshort,
                                  stylesheet,
                                  m_xSMgr );

//      rtl::OUString newVal = rtl::OUString::createFromAscii("high_contrast");
//      Any bla;
//      bla <<= newVal;
//      Reference<XNameReplace> rep(m_xContainer,UNO_QUERY);
//      rep->replaceByName(rtl::OUString::createFromAscii("HelpStyleSheet"),
//                         bla);
}

Reference< XMultiServiceFactory > ContentProvider::getConfiguration() const
{
    Reference< XMultiServiceFactory > sProvider;
    if( m_xSMgr.is() )
    {
        Any aAny;
        aAny <<= rtl::OUString::createFromAscii( "plugin" );
        PropertyValue aProp( rtl::OUString::createFromAscii( "servertype" ),
                             -1,
                             aAny,
                             PropertyState_DIRECT_VALUE );

        Sequence< Any > seq(1);
        seq[0] <<= aProp;

        try
        {
            rtl::OUString sProviderService =
                rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" );
            sProvider =
                Reference< XMultiServiceFactory >(
                    m_xSMgr->createInstanceWithArguments( sProviderService,seq ),
                    UNO_QUERY );
        }
        catch( const com::sun::star::uno::Exception& )
        {
            OSL_ENSURE( sProvider.is(),"cant instantiate configuration" );
        }
    }

    return sProvider;
}

Reference< XHierarchicalNameAccess >
ContentProvider::getHierAccess( const Reference< XMultiServiceFactory >& sProvider,
                                const char* file ) const
{
    Reference< XHierarchicalNameAccess > xHierAccess;

    if( sProvider.is() )
    {
        Sequence< Any > seq(1);
        rtl::OUString sReaderService =
            rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" );

        seq[0] <<= rtl::OUString::createFromAscii( file );

        try
        {
            xHierAccess =
                Reference< XHierarchicalNameAccess >
                ( sProvider->createInstanceWithArguments( sReaderService,seq ),
                  UNO_QUERY );
        }
        catch( const com::sun::star::uno::Exception& )
        {
        }
    }

    return xHierAccess;
}

rtl::OUString
ContentProvider::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess,
                         const char* key ) const
{
    rtl::OUString instPath;
    if( xHierAccess.is() )
    {
        Any aAny;
        try
        {
            aAny =
                xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) );
        }
        catch( const com::sun::star::container::NoSuchElementException& )
        {
        }
        aAny >>= instPath;
    }
    return instPath;
}

void ContentProvider::subst( rtl::OUString& instpath ) const
{
    Reference< XConfigManager >  xCfgMgr;
    if( m_xSMgr.is() )
    {
        try
        {
            xCfgMgr =
                Reference< XConfigManager >(
                    m_xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ),
                    UNO_QUERY );
        }
        catch( const com::sun::star::uno::Exception& e )
        {
            OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " );
        }
    }

    OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" );

    if( xCfgMgr.is() )
        instpath = xCfgMgr->substituteVariables( instpath );
}
<|endoftext|>


<commit_before>#pragma once

#include <Communicator.hpp>
#include <Addressing.hpp>
#include <Collective.hpp>
#include <ParallelLoop.hpp>
#include <GlobalAllocator.hpp>
#include <Delegate.hpp>
#include <AsyncDelegate.hpp>
#include <Array.hpp>

#include <algorithm>

#include "common.h"

// #define USE_MPI3_COLLECTIVES
#undef USE_MPI3_COLLECTIVES
#ifdef USE_MPI3_COLLECTIVES
#include <mpi.h>
#endif

using namespace Grappa;

struct Vertex {
  int64_t * local_adj; // adjacencies that are local
  int64_t nadj;        // number of adjacencies
  int64_t local_sz;    // size of local allocation (regardless of how full it is)
  // int64_t parent;
  void * vertex_data;

  Vertex(): local_adj(nullptr), nadj(0), local_sz(0) {}
  ~Vertex() {}

  template< typename F >
  void forall_adj(F body) {
    for (int64_t i=0; i<nadj; i++) {
      body(local_adj[i]);
    }
  }

  auto adj_iter() -> decltype(util::iterate(local_adj)) { return util::iterate(local_adj, nadj); }
};

// vertex with parent
struct VertexP : public Vertex {
  VertexP(): Vertex() { parent(-1); }
  int64_t parent() { return (int64_t)vertex_data; }
  void parent(int64_t parent) { vertex_data = (void*)parent; }
};

template< class V = Vertex >
struct Graph {
  static_assert(block_size % sizeof(V) == 0, "V size not evenly divisible into blocks!");

  // // Helpers (for if we go with custom cyclic distribution)
  // inline Core    vertex_owner (int64_t v) { return v % cores(); }
  // inline int64_t vertex_offset(int64_t v) { return v / cores(); }

  // Fields
  GlobalAddress<V> vs;
  int64_t nv, nadj, nadj_local;

  // Internal fields
  int64_t * adj_buf;
  int64_t * scratch;

  GlobalAddress<Graph> self;

  Graph(GlobalAddress<Graph> self, GlobalAddress<V> vs, int64_t nv)
    : self(self)
    , vs(vs)
    , nv(nv)
    , nadj(0)
    , nadj_local(0)
    , adj_buf(nullptr)
    , scratch(nullptr)
  { }

  ~Graph() {
    for (V& v : iterate_local(vs, nv)) { v.~V(); }
    if (adj_buf) locale_free(adj_buf);
  }

  void destroy() {
    auto self = this->self;
    global_free(this->vs);
    call_on_all_cores([self]{ self->~Graph(); });
    global_free(self);
  }

  template< int LEVEL = 0 >
  static void dump(GlobalAddress<Graph> g) {
    for (int64_t i=0; i<g->nv; i++) {
      delegate::call(g->vs+i, [i](V * v){
        std::stringstream ss;
        ss << "<" << i << ">";
        for (int64_t i=0; i<v->nadj; i++) ss << " " << v->local_adj[i];
        VLOG(LEVEL) << ss.str();
      });
    }
  }

  /// Cast graph to new type, and allow user to re-initialize each V by providing a
  /// functor (the body of a forall_localized() over the vertices)
  template< typename VNew, typename VOld, typename InitFunc = decltype(nullptr) >
  static GlobalAddress<Graph<VNew>> transform_vertices(GlobalAddress<Graph<VOld>> o, InitFunc init) {
    static_assert(sizeof(VNew) == sizeof(V), "transformed vertex size must be the unchanged.");
    auto g = static_cast<GlobalAddress<Graph<VNew>>>(o);
    forall_localized(g->vs, g->nv, init);
    return g;
  }

  // Constructor
  static GlobalAddress<Graph> create(tuple_graph& tg) {
    double t;
    auto g = symmetric_global_alloc<Graph<V>>();

    // find nv
        t = walltime();
    forall_localized(tg.edges, tg.nedge, [g](packed_edge& e){
      if (e.v0 > g->nv) { g->nv = e.v0; }
      else if (e.v1 > g->nv) { g->nv = e.v1; }
    });
    on_all_cores([g]{
      g->nv = Grappa::allreduce<int64_t,collective_max>(g->nv) + 1;
    });
        VLOG(1) << "find_nv_time: " << walltime() - t;

    auto vs = global_alloc<V>(g->nv);
    auto self = g;
    on_all_cores([g,vs]{
      new (g.localize()) Graph(g, vs, g->nv);
      for (V& v : iterate_local(g->vs, g->nv)) {
        new (&v) V();
      }

  #ifdef SMALL_GRAPH
      // g->scratch = locale_alloc<int64_t>(g->nv);
      if (locale_mycore() == 0) g->scratch = locale_alloc<int64_t>(g->nv);
      barrier();
      if (locale_mycore() == 0) {
        memset(g->scratch, 0, sizeof(int64_t)*g->nv);
      } else {
        g->scratch = delegate::call(mylocale()*locale_cores(), [g]{ return g->scratch; });
      }
      VLOG(0) << "locale = " << mylocale() << ", scratch = " << g->scratch;
  #endif
    });
                                                              t = walltime();
    forall_localized(tg.edges, tg.nedge, [g](packed_edge& e){
      CHECK_LT(e.v0, g->nv); CHECK_LT(e.v1, g->nv);
  #ifdef SMALL_GRAPH
      // g->scratch[e.v0]++;
      // g->scratch[e.v1]++;
      __sync_fetch_and_add(g->scratch+e.v0, 1);
      __sync_fetch_and_add(g->scratch+e.v1, 1);
  #else
      auto count = [](GlobalAddress<V> v){
        delegate::call_async(v.core(), [v]{ v->local_sz++; });
      };
      count(g->vs+e.v0);
      count(g->vs+e.v1);
  #endif
    });
    VLOG(1) << "count_time: " << walltime() - t;

  #ifdef SMALL_GRAPH
    t = walltime();
  #ifdef USE_MPI3_COLLECTIVES
    on_all_cores([g]{
      MPI_Request r; int done;
      MPI_Iallreduce(MPI_IN_PLACE, g->scratch, g->nv, MPI_INT64_T, MPI_SUM, MPI_COMM_WORLD, &r);
      do {
        MPI_Test( &r, &done, MPI_STATUS_IGNORE );
        if(!done) { Grappa_yield(); }
      } while(!done);
    });
  #else
    on_all_cores([g]{ allreduce_inplace<int64_t,collective_add>(g->scratch, g->nv); });
  #endif // USE_MPI3_COLLECTIVES
    VLOG(1) << "allreduce_inplace_time: " << walltime() - t;
    // on_all_cores([g]{ VLOG(5) << util::array_str("scratch", g->scratch, g->nv, 25); });
  #endif // SMALL_GRAPH

    // allocate space for each vertex's adjacencies (+ duplicates)
    forall_localized(g->vs, g->nv, [g](int64_t i, V& v) {
  #ifdef SMALL_GRAPH
      // adjust b/c allreduce didn't account for having 1 instance per locale
      v.local_sz = g->scratch[i] / locale_cores();
  #endif

      v.nadj = 0;
      if (v.local_sz > 0) v.local_adj = new int64_t[v.local_sz];
    });
    VLOG(3) << "after adj allocs";

    // scatter
    forall_localized(tg.edges, tg.nedge, [g](packed_edge& e){
      auto scatter = [g](int64_t vi, int64_t adj) {
        auto vaddr = g->vs+vi;
        delegate::call_async(vaddr.core(), [vaddr,adj]{
          auto& v = *vaddr.pointer();
          v.local_adj[v.nadj++] = adj;
        });
      };
      scatter(e.v0, e.v1);
      scatter(e.v1, e.v0);
    });
    VLOG(3) << "after scatter, nv = " << g->nv;

    // sort & de-dup
    forall_localized(g->vs, g->nv, [g](int64_t vi, V& v){
      CHECK_EQ(v.nadj, v.local_sz);
      std::sort(v.local_adj, v.local_adj+v.nadj);

      int64_t tail = 0;
      for (int64_t i=0; i<v.nadj; i++, tail++) {
        v.local_adj[tail] = v.local_adj[i];
        while (v.local_adj[tail] == v.local_adj[i+1]) i++;
      }
      v.nadj = tail;
      // VLOG(0) << "<" << vi << ">" << util::array_str("", v.local_adj, v.nadj);
      g->nadj_local += v.nadj;
    });
    VLOG(3) << "after sort";

    // compact
    on_all_cores([g]{
  #ifdef SMALL_GRAPH
      if (locale_mycore() == 0) locale_free(g->scratch);
  #endif

      VLOG(2) << "nadj_local = " << g->nadj_local;

      // allocate storage for local vertices' adjacencies
      g->adj_buf = locale_alloc<int64_t>(g->nadj_local);
      // compute total nadj
      g->nadj = allreduce<int64_t,collective_add>(g->nadj_local);

      int64_t * adj = g->adj_buf;
      for (V& v : iterate_local(g->vs, g->nv)) {
        Grappa::memcpy(adj, v.local_adj, v.nadj);
        if (v.local_sz > 0) delete[] v.local_adj;
        v.local_sz = v.nadj;
        v.local_adj = adj;
        adj += v.nadj;
      }
      CHECK_EQ(adj - g->adj_buf, g->nadj_local);
    });

    return g;
  }

} GRAPPA_BLOCK_ALIGNED;
<commit_msg>Graph::Create reference can be const<commit_after>#pragma once

#include <Communicator.hpp>
#include <Addressing.hpp>
#include <Collective.hpp>
#include <ParallelLoop.hpp>
#include <GlobalAllocator.hpp>
#include <Delegate.hpp>
#include <AsyncDelegate.hpp>
#include <Array.hpp>

#include <algorithm>

#include "common.h"

// #define USE_MPI3_COLLECTIVES
#undef USE_MPI3_COLLECTIVES
#ifdef USE_MPI3_COLLECTIVES
#include <mpi.h>
#endif

using namespace Grappa;

struct Vertex {
  int64_t * local_adj; // adjacencies that are local
  int64_t nadj;        // number of adjacencies
  int64_t local_sz;    // size of local allocation (regardless of how full it is)
  // int64_t parent;
  void * vertex_data;

  Vertex(): local_adj(nullptr), nadj(0), local_sz(0) {}
  ~Vertex() {}

  template< typename F >
  void forall_adj(F body) {
    for (int64_t i=0; i<nadj; i++) {
      body(local_adj[i]);
    }
  }

  auto adj_iter() -> decltype(util::iterate(local_adj)) { return util::iterate(local_adj, nadj); }
};

// vertex with parent
struct VertexP : public Vertex {
  VertexP(): Vertex() { parent(-1); }
  int64_t parent() { return (int64_t)vertex_data; }
  void parent(int64_t parent) { vertex_data = (void*)parent; }
};

template< class V = Vertex >
struct Graph {
  static_assert(block_size % sizeof(V) == 0, "V size not evenly divisible into blocks!");

  // // Helpers (for if we go with custom cyclic distribution)
  // inline Core    vertex_owner (int64_t v) { return v % cores(); }
  // inline int64_t vertex_offset(int64_t v) { return v / cores(); }

  // Fields
  GlobalAddress<V> vs;
  int64_t nv, nadj, nadj_local;

  // Internal fields
  int64_t * adj_buf;
  int64_t * scratch;

  GlobalAddress<Graph> self;

  Graph(GlobalAddress<Graph> self, GlobalAddress<V> vs, int64_t nv)
    : self(self)
    , vs(vs)
    , nv(nv)
    , nadj(0)
    , nadj_local(0)
    , adj_buf(nullptr)
    , scratch(nullptr)
  { }

  ~Graph() {
    for (V& v : iterate_local(vs, nv)) { v.~V(); }
    if (adj_buf) locale_free(adj_buf);
  }

  void destroy() {
    auto self = this->self;
    global_free(this->vs);
    call_on_all_cores([self]{ self->~Graph(); });
    global_free(self);
  }

  template< int LEVEL = 0 >
  static void dump(GlobalAddress<Graph> g) {
    for (int64_t i=0; i<g->nv; i++) {
      delegate::call(g->vs+i, [i](V * v){
        std::stringstream ss;
        ss << "<" << i << ">";
        for (int64_t i=0; i<v->nadj; i++) ss << " " << v->local_adj[i];
        VLOG(LEVEL) << ss.str();
      });
    }
  }

  /// Cast graph to new type, and allow user to re-initialize each V by providing a
  /// functor (the body of a forall_localized() over the vertices)
  template< typename VNew, typename VOld, typename InitFunc = decltype(nullptr) >
  static GlobalAddress<Graph<VNew>> transform_vertices(GlobalAddress<Graph<VOld>> o, InitFunc init) {
    static_assert(sizeof(VNew) == sizeof(V), "transformed vertex size must be the unchanged.");
    auto g = static_cast<GlobalAddress<Graph<VNew>>>(o);
    forall_localized(g->vs, g->nv, init);
    return g;
  }

  // Constructor
  static GlobalAddress<Graph> create(const tuple_graph& tg) {
    double t;
    auto g = symmetric_global_alloc<Graph<V>>();

    // find nv
        t = walltime();
    forall_localized(tg.edges, tg.nedge, [g](packed_edge& e){
      if (e.v0 > g->nv) { g->nv = e.v0; }
      else if (e.v1 > g->nv) { g->nv = e.v1; }
    });
    on_all_cores([g]{
      g->nv = Grappa::allreduce<int64_t,collective_max>(g->nv) + 1;
    });
        VLOG(1) << "find_nv_time: " << walltime() - t;

    auto vs = global_alloc<V>(g->nv);
    auto self = g;
    on_all_cores([g,vs]{
      new (g.localize()) Graph(g, vs, g->nv);
      for (V& v : iterate_local(g->vs, g->nv)) {
        new (&v) V();
      }

  #ifdef SMALL_GRAPH
      // g->scratch = locale_alloc<int64_t>(g->nv);
      if (locale_mycore() == 0) g->scratch = locale_alloc<int64_t>(g->nv);
      barrier();
      if (locale_mycore() == 0) {
        memset(g->scratch, 0, sizeof(int64_t)*g->nv);
      } else {
        g->scratch = delegate::call(mylocale()*locale_cores(), [g]{ return g->scratch; });
      }
      VLOG(0) << "locale = " << mylocale() << ", scratch = " << g->scratch;
  #endif
    });
                                                              t = walltime();
    forall_localized(tg.edges, tg.nedge, [g](packed_edge& e){
      CHECK_LT(e.v0, g->nv); CHECK_LT(e.v1, g->nv);
  #ifdef SMALL_GRAPH
      // g->scratch[e.v0]++;
      // g->scratch[e.v1]++;
      __sync_fetch_and_add(g->scratch+e.v0, 1);
      __sync_fetch_and_add(g->scratch+e.v1, 1);
  #else
      auto count = [](GlobalAddress<V> v){
        delegate::call_async(v.core(), [v]{ v->local_sz++; });
      };
      count(g->vs+e.v0);
      count(g->vs+e.v1);
  #endif
    });
    VLOG(1) << "count_time: " << walltime() - t;

  #ifdef SMALL_GRAPH
    t = walltime();
  #ifdef USE_MPI3_COLLECTIVES
    on_all_cores([g]{
      MPI_Request r; int done;
      MPI_Iallreduce(MPI_IN_PLACE, g->scratch, g->nv, MPI_INT64_T, MPI_SUM, MPI_COMM_WORLD, &r);
      do {
        MPI_Test( &r, &done, MPI_STATUS_IGNORE );
        if(!done) { Grappa_yield(); }
      } while(!done);
    });
  #else
    on_all_cores([g]{ allreduce_inplace<int64_t,collective_add>(g->scratch, g->nv); });
  #endif // USE_MPI3_COLLECTIVES
    VLOG(1) << "allreduce_inplace_time: " << walltime() - t;
    // on_all_cores([g]{ VLOG(5) << util::array_str("scratch", g->scratch, g->nv, 25); });
  #endif // SMALL_GRAPH

    // allocate space for each vertex's adjacencies (+ duplicates)
    forall_localized(g->vs, g->nv, [g](int64_t i, V& v) {
  #ifdef SMALL_GRAPH
      // adjust b/c allreduce didn't account for having 1 instance per locale
      v.local_sz = g->scratch[i] / locale_cores();
  #endif

      v.nadj = 0;
      if (v.local_sz > 0) v.local_adj = new int64_t[v.local_sz];
    });
    VLOG(3) << "after adj allocs";

    // scatter
    forall_localized(tg.edges, tg.nedge, [g](packed_edge& e){
      auto scatter = [g](int64_t vi, int64_t adj) {
        auto vaddr = g->vs+vi;
        delegate::call_async(vaddr.core(), [vaddr,adj]{
          auto& v = *vaddr.pointer();
          v.local_adj[v.nadj++] = adj;
        });
      };
      scatter(e.v0, e.v1);
      scatter(e.v1, e.v0);
    });
    VLOG(3) << "after scatter, nv = " << g->nv;

    // sort & de-dup
    forall_localized(g->vs, g->nv, [g](int64_t vi, V& v){
      CHECK_EQ(v.nadj, v.local_sz);
      std::sort(v.local_adj, v.local_adj+v.nadj);

      int64_t tail = 0;
      for (int64_t i=0; i<v.nadj; i++, tail++) {
        v.local_adj[tail] = v.local_adj[i];
        while (v.local_adj[tail] == v.local_adj[i+1]) i++;
      }
      v.nadj = tail;
      // VLOG(0) << "<" << vi << ">" << util::array_str("", v.local_adj, v.nadj);
      g->nadj_local += v.nadj;
    });
    VLOG(3) << "after sort";

    // compact
    on_all_cores([g]{
  #ifdef SMALL_GRAPH
      if (locale_mycore() == 0) locale_free(g->scratch);
  #endif

      VLOG(2) << "nadj_local = " << g->nadj_local;

      // allocate storage for local vertices' adjacencies
      g->adj_buf = locale_alloc<int64_t>(g->nadj_local);
      // compute total nadj
      g->nadj = allreduce<int64_t,collective_add>(g->nadj_local);

      int64_t * adj = g->adj_buf;
      for (V& v : iterate_local(g->vs, g->nv)) {
        Grappa::memcpy(adj, v.local_adj, v.nadj);
        if (v.local_sz > 0) delete[] v.local_adj;
        v.local_sz = v.nadj;
        v.local_adj = adj;
        adj += v.nadj;
      }
      CHECK_EQ(adj - g->adj_buf, g->nadj_local);
    });

    return g;
  }

} GRAPPA_BLOCK_ALIGNED;
<|endoftext|>


<commit_before>/*
  Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <fc2d_clawpack46.H>
#include <fclaw_base.h>
#include <fclaw2d_map.h>
#include <p4est_connectivity.h>
#include <fclaw2d_map_query.h>

#include <amr_forestclaw.H>
#include <amr_utils.H>
#include <fclaw_options.h>

typedef struct user_options
{
    int example;

    const char* frames_string;
    int *frames;
    const char* density_string;
    double *density;

    amr_options_t* gparms;

    int is_registered;

} user_options_t;

static void *
options_register_user (fclaw_app_t * app, void *package, sc_options_t * opt)
{
    user_options_t* user = (user_options_t*) package;

    /* [user] User options */
    /* [user] User options */
    sc_options_add_int (opt, 0, "example", &user->example, 0,
                        "[user] 0 (simple); 1 (simulation)");

    fclaw_options_add_int_array(opt,0,"frames",&user->frames_string,
                                NULL, &user->frames,0,
                                "[user] Frames these frames [NULL]");

    fclaw_options_add_double_array(opt,0,"density",&user->density_string,
                                   NULL,&user->density, 0,
                                   "[user] Density [NULL]");

    user->is_registered = 1;
    return NULL;
}

static fclaw_exit_type_t
options_postprocess_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;

    if (user->example == 2)
    {
        fclaw_options_convert_int_array (user->frames_string, &user->frames,
                                         user->gparms->nout);

        fclaw_options_convert_double_array (user->density_string, &user->density,
                                            user->gparms->nout);
    }
    return FCLAW_NOEXIT;
}

static fclaw_exit_type_t
options_check_user (fclaw_app_t * app, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    if (user->example < 1 || user->example > 2) {
        fclaw_global_essentialf ("Option --user:example must be 1 or 2\n");
        return FCLAW_EXIT_QUIET;
    }
    return FCLAW_NOEXIT;
}

static void
options_destroy_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    /* Destroy arrays used in options  */

    if (user->example == 2)
    {
        fclaw_options_destroy_array((void*) user->frames);
        fclaw_options_destroy_array((void*) user->density);
    }
}

static const fclaw_app_options_vtable_t options_vtable_user =
{
    options_register_user,
    options_postprocess_user,
    options_check_user,
    options_destroy_user
};

static
void register_user_options (fclaw_app_t * app,
                            const char *configfile,
                            user_options_t* user)
{
    FCLAW_ASSERT (app != NULL);

    fclaw_app_options_register (app,"user", configfile, &options_vtable_user,
                                user);
}

void run_program(fclaw_app_t* app, amr_options_t* gparms,
                 fc2d_clawpack46_options_t* clawpack_options,
                 user_options_t* user)
{
    sc_MPI_Comm            mpicomm;

    /* Local variables */
    double test_fpe;
    int i;

    mpicomm = fclaw_app_get_mpi_size_rank (app, NULL, NULL);

    switch (user->example)
    {
    case 1:
        fclaw_global_infof("Running example 1 ... Done\n");
        break;
    case 2:
        fclaw_global_infof("Running example 2 ... \n");
        for(i = 0; i < gparms->nout; i++)
        {
            fclaw_global_productionf("Density in frame %2d : %12.4f\n",
                                     user->frames[i],user->density[i]);
        }
        fclaw_global_productionf("Trap a floating point error ... sqrt(-1.0) \n");
        test_fpe = sqrt(-1.0);
        fclaw_global_productionf(" ... Done!\n");
        break;
    default:
        SC_ABORT_NOT_REACHED (); /* must be checked in torus_checkparms */
    }
}

int main (int argc, char **argv)
{
    fclaw_app_t *app;
    int first_arg;
    fclaw_exit_type_t vexit;

    /* Options */
    sc_options_t                  *options;
    amr_options_t                 samr_options, *gparms = &samr_options;
    fc2d_clawpack46_options_t     sclawpack_options, *clawpack_options = &sclawpack_options;
    user_options_t                suser_options, *user = &suser_options;

    int retval;

    /* Initialize application */
    app = fclaw_app_new (&argc, &argv, user);
    options = fclaw_app_get_options (app);

    fclaw_options_register_general (app, "fclaw_options.ini", gparms);
    fc2d_clawpack46_options_register(app,NULL,clawpack_options);

    /* User defined options (defined above) */
    user->gparms = gparms;
    register_user_options (app, "fclaw_options.ini", user);

    /* Read configuration file(s) */
    retval = fclaw_options_read_from_file(options);
    vexit =  fclaw_app_options_parse (app, &first_arg,"fclaw_options.ini.used");

    /* -------------------------------------------------------------
       - Run program
       ------------------------------------------------------------- */
    if (!retval & !vexit)
    {
        run_program(app, gparms, clawpack_options,user);
    }

    fclaw_app_destroy (app);

    return 0;
}
<commit_msg>(test_parms) Cleaner package handling<commit_after>/*
  Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <fc2d_clawpack46.H>
#include <fclaw_base.h>
#include <fclaw2d_map.h>
#include <p4est_connectivity.h>
#include <fclaw2d_map_query.h>

#include <amr_forestclaw.H>
#include <amr_utils.H>
#include <fclaw_options.h>

typedef struct user_options
{
    int example;

    const char* frames_string;
    int *frames;
    const char* density_string;
    double *density;

    amr_options_t* gparms;

    int is_registered;

} user_options_t;

static void *
options_register_user (fclaw_app_t * app, void *package, sc_options_t * opt)
{
    user_options_t* user = (user_options_t*) package;

    /* [user] User options */
    /* [user] User options */
    sc_options_add_int (opt, 0, "example", &user->example, 0,
                        "[user] 0 (simple); 1 (simulation)");

    fclaw_options_add_int_array(opt,0,"frames",&user->frames_string,
                                NULL, &user->frames,0,
                                "[user] Frames these frames [NULL]");

    fclaw_options_add_double_array(opt,0,"density",&user->density_string,
                                   NULL,&user->density, 0,
                                   "[user] Density [NULL]");

    user->is_registered = 1;
    return NULL;
}

static fclaw_exit_type_t
options_postprocess_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;

    if (user->example == 2)
    {
        fclaw_options_convert_int_array (user->frames_string, &user->frames,
                                         user->gparms->nout);

        fclaw_options_convert_double_array (user->density_string, &user->density,
                                            user->gparms->nout);
    }
    return FCLAW_NOEXIT;
}

static fclaw_exit_type_t
options_check_user (fclaw_app_t * app, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    if (user->example < 1 || user->example > 2) {
        fclaw_global_essentialf ("Option --user:example must be 1 or 2\n");
        return FCLAW_EXIT_QUIET;
    }
    return FCLAW_NOEXIT;
}

static void
options_destroy_user (fclaw_app_t * a, void *package, void *registered)
{
    user_options_t* user = (user_options_t*) package;
    /* Destroy arrays used in options  */

    if (user->example == 2)
    {
        fclaw_options_destroy_array((void*) user->frames);
        fclaw_options_destroy_array((void*) user->density);
    }
}

static const fclaw_app_options_vtable_t options_vtable_user =
{
    options_register_user,
    options_postprocess_user,
    options_check_user,
    options_destroy_user
};

static
void user_options_register (fclaw_app_t * app,
                            const char *configfile,
                            user_options_t* user)
{
    FCLAW_ASSERT (app != NULL);

    fclaw_app_options_register (app,"user", configfile, &options_vtable_user,
                                user);
}

void run_program(fclaw_app_t* app, amr_options_t* gparms,
                 fc2d_clawpack46_options_t* clawpack_options,
                 user_options_t* user)
{
    sc_MPI_Comm            mpicomm;

    /* Local variables */
    double test_fpe;
    int i;

    mpicomm = fclaw_app_get_mpi_size_rank (app, NULL, NULL);

    switch (user->example)
    {
    case 1:
        fclaw_global_infof("Running example 1 ... Done\n");
        break;
    case 2:
        fclaw_global_infof("Running example 2 ... \n");
        for(i = 0; i < gparms->nout; i++)
        {
            fclaw_global_productionf("Density in frame %2d : %12.4f\n",
                                     user->frames[i],user->density[i]);
        }
        fclaw_global_productionf("Trap a floating point error ... sqrt(-1.0) \n");
        test_fpe = sqrt(-1.0);
        fclaw_global_productionf(" ... Done!\n");
        break;
    default:
        SC_ABORT_NOT_REACHED (); /* must be checked in torus_checkparms */
    }
}

int main (int argc, char **argv)
{
    fclaw_app_t *app;
    int first_arg;
    fclaw_exit_type_t vexit;

    /* Options */
    sc_options_t                  *options;
    amr_options_t                 samr_options, *gparms = &samr_options;
    fc2d_clawpack46_options_t     sclawpack_options, *clawpack_options = &sclawpack_options;
    user_options_t                suser_options, *user = &suser_options;

    int retval;

    /* Initialize application */
    app = fclaw_app_new (&argc, &argv, user);
    options = fclaw_app_get_options (app);

    fclaw_options_register_general (app, "fclaw_options.ini", gparms);
    fc2d_clawpack46_options_register(app,NULL,clawpack_options);

    /* User defined options (defined above) */
    user->gparms = gparms;
    user_options_register (app, "fclaw_options.ini", user);

    /* Read configuration file(s) */
    retval = fclaw_options_read_from_file(options);
    vexit =  fclaw_app_options_parse (app, &first_arg,"fclaw_options.ini.used");

    /* -------------------------------------------------------------
       - Run program
       ------------------------------------------------------------- */
    if (!retval & !vexit)
    {
        run_program(app, gparms, clawpack_options,user);
    }

    fclaw_app_destroy (app);

    return 0;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLandmarkTransform.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Tim Hutton and David G. Gobbi who developed this class.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include "vtkGeneralTransformInverse.h"
#include "vtkLandmarkTransform.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"

//----------------------------------------------------------------------------
vtkLandmarkTransform* vtkLandmarkTransform::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkLandmarkTransform");
  if(ret)
    {
    return (vtkLandmarkTransform*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkLandmarkTransform;
}

//----------------------------------------------------------------------------
vtkLandmarkTransform::vtkLandmarkTransform()
{
  this->Mode = VTK_LANDMARK_SIMILARITY;
  this->SourceLandmarks=NULL;
  this->TargetLandmarks=NULL;

  this->MatrixNeedsUpdate = 0;
  this->UpdateMutex = vtkMutexLock::New();
}

//----------------------------------------------------------------------------
vtkLandmarkTransform::~vtkLandmarkTransform()
{
  if(this->SourceLandmarks)
    {
    this->SourceLandmarks->Delete();
    }
  if(this->TargetLandmarks)
    {
    this->TargetLandmarks->Delete();
    }
  this->UpdateMutex->Delete();
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkLinearTransform::PrintSelf(os, indent);
  os << "Mode: " << this->GetModeAsString() << "\n";
  os << "SourceLandmarks: " << this->SourceLandmarks << "\n";
  if(this->SourceLandmarks)
    {
    this->SourceLandmarks->PrintSelf(os,indent.GetNextIndent());
    }
  os << "TargetLandmarks: " << this->TargetLandmarks << "\n";
  if(this->TargetLandmarks)
    {
    this->TargetLandmarks->PrintSelf(os,indent.GetNextIndent());
    }
}

//----------------------------------------------------------------------------
// Update the 4x4 matrix. Updates are only done as necessary.

void vtkLandmarkTransform::Update()
{
  // Lock so that threads don't collide.  The first thread will succeed
  // in the update, the other threads will wait until the lock is released
  // and then find that the update has already been done.
  this->UpdateMutex->Lock();

  if (this->SourceLandmarks == NULL || this->TargetLandmarks == NULL)
    {
    this->UpdateMutex->Unlock();
    return;
    }

  if (this->UpdateTime.GetMTime() > this->GetMTime() &&
      !this->MatrixNeedsUpdate)
    {
    // already up-to-date!
    this->UpdateMutex->Unlock();
    return;
    }

  // --- compute the necessary transform to match the two sets of landmarks ---

  /*
    The solution is based on
    Berthold K. P. Horn (1987),
    "Closed-form solution of absolute orientation using unit quaternions,"
    Journal of the Optical Society of America A, 4:629-642
  */

  // Original python implementation by David G. Gobbi

  const int N_PTS = this->SourceLandmarks->GetNumberOfPoints();
  if(N_PTS != this->TargetLandmarks->GetNumberOfPoints())
    {
    vtkErrorMacro("Update: Source and Target Landmarks contain a different number of points");
    return;
    }

  int i;

  // -- find the centroid of each set --

  float source_centroid[3]={0,0,0};
  float target_centroid[3]={0,0,0};
  float *p;
  for(i=0;i<N_PTS;i++)
    {
    p = this->SourceLandmarks->GetPoint(i);
    source_centroid[0] += p[0];
    source_centroid[1] += p[1];
    source_centroid[2] += p[2];
    p = this->TargetLandmarks->GetPoint(i);
    target_centroid[0] += p[0];
    target_centroid[1] += p[1];
    target_centroid[2] += p[2];
    }
  source_centroid[0] /= N_PTS;
  source_centroid[1] /= N_PTS;
  source_centroid[2] /= N_PTS;
  target_centroid[0] /= N_PTS;
  target_centroid[1] /= N_PTS;
  target_centroid[2] /= N_PTS;

  // -- build the 3x3 matrix M --

  float M[3][3];
  for(i=0;i<3;i++)
    {
    M[i][0]=0.0F; // fill M with zeros
    M[i][1]=0.0F;
    M[i][2]=0.0F;
    }
  int pt;
  float a[3],b[3];
  float sa=0.0F,sb=0.0F;
  for(pt=0;pt<N_PTS;pt++)
    {
    // get the origin-centred point (a) in the source set
    this->SourceLandmarks->GetPoint(pt,a);
    a[0] -= source_centroid[0];
    a[1] -= source_centroid[1];
    a[2] -= source_centroid[2];
    // get the origin-centred point (b) in the target set
    this->TargetLandmarks->GetPoint(pt,b);
    b[0] -= target_centroid[0];
    b[1] -= target_centroid[1];
    b[2] -= target_centroid[2];
    // accumulate the products a*T(b) into the matrix M
    for(i=0;i<3;i++)
      {
      M[i][0] += a[i]*b[0];
      M[i][1] += a[i]*b[1];
      M[i][2] += a[i]*b[2];
      }
    // accumulate scale factors (if desired)
    sa += a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
    sb += b[0]*b[0]+b[1]*b[1]+b[2]*b[2];
    }
  // compute required scaling factor (if desired)
  float scale = (float)sqrt(sb/sa);

  // -- build the 4x4 matrix N --

  float Ndata[4][4];
  float *N[4];
  for(i=0;i<4;i++)
    {
    N[i] = Ndata[i];
    N[i][0]=0.0F; // fill N with zeros
    N[i][1]=0.0F;
    N[i][2]=0.0F;
    N[i][3]=0.0F;
    }
  // on-diagonal elements
  N[0][0] = M[0][0]+M[1][1]+M[2][2];
  N[1][1] = M[0][0]-M[1][1]-M[2][2];
  N[2][2] = -M[0][0]+M[1][1]-M[2][2];
  N[3][3] = -M[0][0]-M[1][1]+M[2][2];
  // off-diagonal elements
  N[0][1] = N[1][0] = M[1][2]-M[2][1];
  N[0][2] = N[2][0] = M[2][0]-M[0][2];
  N[0][3] = N[3][0] = M[0][1]-M[1][0];

  N[1][2] = N[2][1] = M[0][1]+M[1][0];
  N[1][3] = N[3][1] = M[2][0]+M[0][2];
  N[2][3] = N[3][2] = M[1][2]+M[2][1];

  // -- eigen-decompose N (is symmetric) --

  float eigenvectorData[4][4];
  float *eigenvectors[4],eigenvalues[4];

  eigenvectors[0] = eigenvectorData[0];
  eigenvectors[1] = eigenvectorData[1];
  eigenvectors[2] = eigenvectorData[2];
  eigenvectors[3] = eigenvectorData[3];

  vtkMath::JacobiN(N,4,eigenvalues,eigenvectors);

  // the eigenvector with the largest eigenvalue is the quaternion we want
  // (they are sorted in decreasing order for us by JacobiN)
  float quat[4];
  quat[0] = eigenvectors[0][0];
  quat[1] = eigenvectors[1][0];
  quat[2] = eigenvectors[2][0];
  quat[3] = eigenvectors[3][0];

  // convert it to a rotation matrix
  double w = quat[0];
  double x = quat[1];
  double y = quat[2];
  double z = quat[3];

  double ww = w*w;
  double wx = w*x;
  double wy = w*y;
  double wz = w*z;

  double xx = x*x;
  double yy = y*y;
  double zz = z*z;

  double xy = x*y;
  double xz = x*z;
  double yz = y*z;

  this->Matrix->Element[0][0] = ww + xx - yy - zz;
  this->Matrix->Element[1][0] = 2.0*(wz + xy);
  this->Matrix->Element[2][0] = 2.0*(-wy + xz);

  this->Matrix->Element[0][1] = 2.0*(-wz + xy);
  this->Matrix->Element[1][1] = ww - xx + yy - zz;
  this->Matrix->Element[2][1] = 2.0*(wx + yz);

  this->Matrix->Element[0][2] = 2.0*(wy + xz);
  this->Matrix->Element[1][2] = 2.0*(-wx + yz);
  this->Matrix->Element[2][2] = ww - xx - yy + zz;

  if (this->Mode != VTK_LANDMARK_RIGIDBODY)
    { // add in the scale factor (if desired)
    for(i=0;i<3;i++)
      {
      this->Matrix->Element[i][0] *= scale;
      this->Matrix->Element[i][1] *= scale;
      this->Matrix->Element[i][2] *= scale;
      }
    }

  // the translation is given by the difference in the centroids
  this->Matrix->Element[0][3] = target_centroid[0]-source_centroid[0];
  this->Matrix->Element[1][3] = target_centroid[1]-source_centroid[1];
  this->Matrix->Element[2][3] = target_centroid[2]-source_centroid[2];

  // fill the bottom row of the 4x4 matrix
  this->Matrix->Element[3][0] = 0.0;
  this->Matrix->Element[3][1] = 0.0;
  this->Matrix->Element[3][2] = 0.0;
  this->Matrix->Element[3][3] = 1.0;

  this->Matrix->Modified();
  this->MatrixNeedsUpdate = 0;

  this->UpdateTime.Modified();
  this->UpdateMutex->Unlock();
}

//------------------------------------------------------------------------
unsigned long vtkLandmarkTransform::GetMTime()
{
  unsigned long result = this->vtkLinearTransform::GetMTime();
  unsigned long mtime;

  if (this->SourceLandmarks)
    {
    mtime = this->SourceLandmarks->GetMTime();
    if (mtime > result)
      {
      result = mtime;
      }
    }
  if (this->TargetLandmarks)
    {
    mtime = this->TargetLandmarks->GetMTime();
    if (mtime > result)
      {
      result = mtime;
      }
    }
  return result;
}
//------------------------------------------------------------------------
void vtkLandmarkTransform::SetSourceLandmarks(vtkPoints *source)
{
  if (this->SourceLandmarks == source)
    {
    return;
    }

  if (this->SourceLandmarks)
    {
    this->SourceLandmarks->Delete();
    }

  source->Register(this);
  this->SourceLandmarks = source;

  this->Modified();

  this->MatrixNeedsUpdate = 1;
}

//------------------------------------------------------------------------
void vtkLandmarkTransform::SetTargetLandmarks(vtkPoints *target)
{
  if (this->TargetLandmarks == target)
    {
    return;
    }

  if (this->TargetLandmarks)
    {
    this->TargetLandmarks->Delete();
    }

  target->Register(this);
  this->TargetLandmarks = target;
  this->Modified();

  this->MatrixNeedsUpdate = 1;
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::Identity()
{
  this->SetSourceLandmarks(NULL);
  this->SetTargetLandmarks(NULL);
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::Inverse()
{
  vtkPoints *tmp1 = this->SourceLandmarks;
  vtkPoints *tmp2 = this->TargetLandmarks;
  this->TargetLandmarks = tmp1;
  this->SourceLandmarks = tmp2;
  this->Modified();
}

//----------------------------------------------------------------------------
vtkGeneralTransform *vtkLandmarkTransform::MakeTransform()
{
  return vtkLandmarkTransform::New();
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::DeepCopy(vtkGeneralTransform *transform)
{
  if (strcmp("vtkGeneralTransformInverse",transform->GetClassName()) == 0)
    {
    transform = ((vtkGeneralTransformInverse *)transform)->GetTransform();
    }
  if (strcmp("vtkLandmarkTransform",transform->GetClassName()) != 0)
    {
    vtkErrorMacro(<< "DeepCopy: trying to copy a transform of different type");
    return;
    }

  vtkLandmarkTransform *t = (vtkLandmarkTransform *)transform;

  if (t == this)
    {
    return;
    }

  this->SetMode(t->Mode);
  this->SetSourceLandmarks(t->SourceLandmarks);
  this->SetTargetLandmarks(t->TargetLandmarks);
}

<commit_msg>ERR: translation component of transform was incorrect.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLandmarkTransform.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Tim Hutton and David G. Gobbi who developed this class.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include "vtkGeneralTransformInverse.h"
#include "vtkLandmarkTransform.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"

//----------------------------------------------------------------------------
vtkLandmarkTransform* vtkLandmarkTransform::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkLandmarkTransform");
  if(ret)
    {
    return (vtkLandmarkTransform*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkLandmarkTransform;
}

//----------------------------------------------------------------------------
vtkLandmarkTransform::vtkLandmarkTransform()
{
  this->Mode = VTK_LANDMARK_SIMILARITY;
  this->SourceLandmarks=NULL;
  this->TargetLandmarks=NULL;

  this->MatrixNeedsUpdate = 0;
  this->UpdateMutex = vtkMutexLock::New();
}

//----------------------------------------------------------------------------
vtkLandmarkTransform::~vtkLandmarkTransform()
{
  if(this->SourceLandmarks)
    {
    this->SourceLandmarks->Delete();
    }
  if(this->TargetLandmarks)
    {
    this->TargetLandmarks->Delete();
    }
  this->UpdateMutex->Delete();
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkLinearTransform::PrintSelf(os, indent);
  os << "Mode: " << this->GetModeAsString() << "\n";
  os << "SourceLandmarks: " << this->SourceLandmarks << "\n";
  if(this->SourceLandmarks)
    {
    this->SourceLandmarks->PrintSelf(os,indent.GetNextIndent());
    }
  os << "TargetLandmarks: " << this->TargetLandmarks << "\n";
  if(this->TargetLandmarks)
    {
    this->TargetLandmarks->PrintSelf(os,indent.GetNextIndent());
    }
}

//----------------------------------------------------------------------------
// Update the 4x4 matrix. Updates are only done as necessary.

void vtkLandmarkTransform::Update()
{
  // Lock so that threads don't collide.  The first thread will succeed
  // in the update, the other threads will wait until the lock is released
  // and then find that the update has already been done.
  this->UpdateMutex->Lock();

  if (this->SourceLandmarks == NULL || this->TargetLandmarks == NULL)
    {
    this->UpdateMutex->Unlock();
    return;
    }

  if (this->UpdateTime.GetMTime() > this->GetMTime() &&
      !this->MatrixNeedsUpdate)
    {
    // already up-to-date!
    this->UpdateMutex->Unlock();
    return;
    }

  // --- compute the necessary transform to match the two sets of landmarks ---

  /*
    The solution is based on
    Berthold K. P. Horn (1987),
    "Closed-form solution of absolute orientation using unit quaternions,"
    Journal of the Optical Society of America A, 4:629-642
  */

  // Original python implementation by David G. Gobbi

  const int N_PTS = this->SourceLandmarks->GetNumberOfPoints();
  if(N_PTS != this->TargetLandmarks->GetNumberOfPoints())
    {
    vtkErrorMacro("Update: Source and Target Landmarks contain a different number of points");
    return;
    }

  int i;

  // -- find the centroid of each set --

  float source_centroid[3]={0,0,0};
  float target_centroid[3]={0,0,0};
  float *p;
  for(i=0;i<N_PTS;i++)
    {
    p = this->SourceLandmarks->GetPoint(i);
    source_centroid[0] += p[0];
    source_centroid[1] += p[1];
    source_centroid[2] += p[2];
    p = this->TargetLandmarks->GetPoint(i);
    target_centroid[0] += p[0];
    target_centroid[1] += p[1];
    target_centroid[2] += p[2];
    }
  source_centroid[0] /= N_PTS;
  source_centroid[1] /= N_PTS;
  source_centroid[2] /= N_PTS;
  target_centroid[0] /= N_PTS;
  target_centroid[1] /= N_PTS;
  target_centroid[2] /= N_PTS;

  // -- build the 3x3 matrix M --

  float M[3][3];
  for(i=0;i<3;i++)
    {
    M[i][0]=0.0F; // fill M with zeros
    M[i][1]=0.0F;
    M[i][2]=0.0F;
    }
  int pt;
  float a[3],b[3];
  float sa=0.0F,sb=0.0F;
  for(pt=0;pt<N_PTS;pt++)
    {
    // get the origin-centred point (a) in the source set
    this->SourceLandmarks->GetPoint(pt,a);
    a[0] -= source_centroid[0];
    a[1] -= source_centroid[1];
    a[2] -= source_centroid[2];
    // get the origin-centred point (b) in the target set
    this->TargetLandmarks->GetPoint(pt,b);
    b[0] -= target_centroid[0];
    b[1] -= target_centroid[1];
    b[2] -= target_centroid[2];
    // accumulate the products a*T(b) into the matrix M
    for(i=0;i<3;i++)
      {
      M[i][0] += a[i]*b[0];
      M[i][1] += a[i]*b[1];
      M[i][2] += a[i]*b[2];
      }
    // accumulate scale factors (if desired)
    sa += a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
    sb += b[0]*b[0]+b[1]*b[1]+b[2]*b[2];
    }
  // compute required scaling factor (if desired)
  float scale = (float)sqrt(sb/sa);

  // -- build the 4x4 matrix N --

  float Ndata[4][4];
  float *N[4];
  for(i=0;i<4;i++)
    {
    N[i] = Ndata[i];
    N[i][0]=0.0F; // fill N with zeros
    N[i][1]=0.0F;
    N[i][2]=0.0F;
    N[i][3]=0.0F;
    }
  // on-diagonal elements
  N[0][0] = M[0][0]+M[1][1]+M[2][2];
  N[1][1] = M[0][0]-M[1][1]-M[2][2];
  N[2][2] = -M[0][0]+M[1][1]-M[2][2];
  N[3][3] = -M[0][0]-M[1][1]+M[2][2];
  // off-diagonal elements
  N[0][1] = N[1][0] = M[1][2]-M[2][1];
  N[0][2] = N[2][0] = M[2][0]-M[0][2];
  N[0][3] = N[3][0] = M[0][1]-M[1][0];

  N[1][2] = N[2][1] = M[0][1]+M[1][0];
  N[1][3] = N[3][1] = M[2][0]+M[0][2];
  N[2][3] = N[3][2] = M[1][2]+M[2][1];

  // -- eigen-decompose N (is symmetric) --

  float eigenvectorData[4][4];
  float *eigenvectors[4],eigenvalues[4];

  eigenvectors[0] = eigenvectorData[0];
  eigenvectors[1] = eigenvectorData[1];
  eigenvectors[2] = eigenvectorData[2];
  eigenvectors[3] = eigenvectorData[3];

  vtkMath::JacobiN(N,4,eigenvalues,eigenvectors);

  // the eigenvector with the largest eigenvalue is the quaternion we want
  // (they are sorted in decreasing order for us by JacobiN)
  float quat[4];
  quat[0] = eigenvectors[0][0];
  quat[1] = eigenvectors[1][0];
  quat[2] = eigenvectors[2][0];
  quat[3] = eigenvectors[3][0];

  // convert it to a rotation matrix
  double w = quat[0];
  double x = quat[1];
  double y = quat[2];
  double z = quat[3];

  double ww = w*w;
  double wx = w*x;
  double wy = w*y;
  double wz = w*z;

  double xx = x*x;
  double yy = y*y;
  double zz = z*z;

  double xy = x*y;
  double xz = x*z;
  double yz = y*z;

  this->Matrix->Element[0][0] = ww + xx - yy - zz;
  this->Matrix->Element[1][0] = 2.0*(wz + xy);
  this->Matrix->Element[2][0] = 2.0*(-wy + xz);

  this->Matrix->Element[0][1] = 2.0*(-wz + xy);
  this->Matrix->Element[1][1] = ww - xx + yy - zz;
  this->Matrix->Element[2][1] = 2.0*(wx + yz);

  this->Matrix->Element[0][2] = 2.0*(wy + xz);
  this->Matrix->Element[1][2] = 2.0*(-wx + yz);
  this->Matrix->Element[2][2] = ww - xx - yy + zz;

  if (this->Mode != VTK_LANDMARK_RIGIDBODY)
    { // add in the scale factor (if desired)
    for(i=0;i<3;i++)
      {
      this->Matrix->Element[i][0] *= scale;
      this->Matrix->Element[i][1] *= scale;
      this->Matrix->Element[i][2] *= scale;
      }
    }

  // the translation is given by the difference in the transformed source
  // centroid and the target centroid
  double sx, sy, sz;

  sx = this->Matrix->Element[0][0] * source_centroid[0] +
       this->Matrix->Element[0][1] * source_centroid[1] +
       this->Matrix->Element[0][2] * source_centroid[2];
  sy = this->Matrix->Element[1][0] * source_centroid[0] +
       this->Matrix->Element[1][1] * source_centroid[1] +
       this->Matrix->Element[1][2] * source_centroid[2];
  sz = this->Matrix->Element[2][0] * source_centroid[0] +
       this->Matrix->Element[2][1] * source_centroid[1] +
       this->Matrix->Element[2][2] * source_centroid[2];

  this->Matrix->Element[0][3] = target_centroid[0] - sx;
  this->Matrix->Element[1][3] = target_centroid[1] - sy;
  this->Matrix->Element[2][3] = target_centroid[2] - sz;

  // fill the bottom row of the 4x4 matrix
  this->Matrix->Element[3][0] = 0.0;
  this->Matrix->Element[3][1] = 0.0;
  this->Matrix->Element[3][2] = 0.0;
  this->Matrix->Element[3][3] = 1.0;

  this->Matrix->Modified();
  this->MatrixNeedsUpdate = 0;

  this->UpdateTime.Modified();
  this->UpdateMutex->Unlock();
}

//------------------------------------------------------------------------
unsigned long vtkLandmarkTransform::GetMTime()
{
  unsigned long result = this->vtkLinearTransform::GetMTime();
  unsigned long mtime;

  if (this->SourceLandmarks)
    {
    mtime = this->SourceLandmarks->GetMTime();
    if (mtime > result)
      {
      result = mtime;
      }
    }
  if (this->TargetLandmarks)
    {
    mtime = this->TargetLandmarks->GetMTime();
    if (mtime > result)
      {
      result = mtime;
      }
    }
  return result;
}
//------------------------------------------------------------------------
void vtkLandmarkTransform::SetSourceLandmarks(vtkPoints *source)
{
  if (this->SourceLandmarks == source)
    {
    return;
    }

  if (this->SourceLandmarks)
    {
    this->SourceLandmarks->Delete();
    }

  source->Register(this);
  this->SourceLandmarks = source;

  this->Modified();

  this->MatrixNeedsUpdate = 1;
}

//------------------------------------------------------------------------
void vtkLandmarkTransform::SetTargetLandmarks(vtkPoints *target)
{
  if (this->TargetLandmarks == target)
    {
    return;
    }

  if (this->TargetLandmarks)
    {
    this->TargetLandmarks->Delete();
    }

  target->Register(this);
  this->TargetLandmarks = target;
  this->Modified();

  this->MatrixNeedsUpdate = 1;
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::Identity()
{
  this->SetSourceLandmarks(NULL);
  this->SetTargetLandmarks(NULL);
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::Inverse()
{
  vtkPoints *tmp1 = this->SourceLandmarks;
  vtkPoints *tmp2 = this->TargetLandmarks;
  this->TargetLandmarks = tmp1;
  this->SourceLandmarks = tmp2;
  this->Modified();
}

//----------------------------------------------------------------------------
vtkGeneralTransform *vtkLandmarkTransform::MakeTransform()
{
  return vtkLandmarkTransform::New();
}

//----------------------------------------------------------------------------
void vtkLandmarkTransform::DeepCopy(vtkGeneralTransform *transform)
{
  if (strcmp("vtkGeneralTransformInverse",transform->GetClassName()) == 0)
    {
    transform = ((vtkGeneralTransformInverse *)transform)->GetTransform();
    }
  if (strcmp("vtkLandmarkTransform",transform->GetClassName()) != 0)
    {
    vtkErrorMacro(<< "DeepCopy: trying to copy a transform of different type");
    return;
    }

  vtkLandmarkTransform *t = (vtkLandmarkTransform *)transform;

  if (t == this)
    {
    return;
    }

  this->SetMode(t->Mode);
  this->SetSourceLandmarks(t->SourceLandmarks);
  this->SetTargetLandmarks(t->TargetLandmarks);
}

<|endoftext|>


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

#include <iostream>
#include <string>
#include <vector>

#include <cpr/cprtypes.h>
#include <cpr/ssl_options.h>

#include "httpsServer.hpp"

using namespace cpr;

static HttpsServer* server;

TEST(SslTests, HelloWorldTestSimpel) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

    Url url{server->GetBaseUrl() + "/hello.html"};
    std::string baseDirPath = server->getBaseDirPath();
    SslOptions sslOpts =
            Ssl(ssl::CaPath{baseDirPath + "ca.cer"}, ssl::CertFile{baseDirPath + "client.cer"},
                ssl::KeyFile{baseDirPath + "client.key"}, ssl::VerifyPeer{false},
                ssl::PinnedPublicKey{baseDirPath + "server.pubkey"},
                ssl::VerifyHost{false}, ssl::VerifyStatus{false});
    Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
    std::string expected_text = "Hello world!";
    EXPECT_EQ(expected_text, response.text);
    EXPECT_EQ(url, response.url);
    EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
    EXPECT_EQ(200, response.status_code);
    EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}

TEST(SslTests, HelloWorldTestFull) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

    Url url{server->GetBaseUrl() + "/hello.html"};
    std::string baseDirPath = server->getBaseDirPath();
    SslOptions sslOpts = Ssl(
            ssl::TLSv1{}, ssl::ALPN{false}, ssl::NPN{false}, ssl::CaPath{baseDirPath + "ca.cer"},
            ssl::CertFile{baseDirPath + "client.cer"}, ssl::KeyFile{baseDirPath + "client.key"},
            ssl::PinnedPublicKey{baseDirPath + "server.pubkey"},
            ssl::VerifyPeer{false}, ssl::VerifyHost{false}, ssl::VerifyStatus{false});
    Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
    std::string expected_text = "Hello world!";
    EXPECT_EQ(expected_text, response.text);
    EXPECT_EQ(url, response.url);
    EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
    EXPECT_EQ(200, response.status_code);
    EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}

TEST(SslTests, GetCertInfo) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

    Url url{server->GetBaseUrl() + "/hello.html"};
    std::string baseDirPath = server->getBaseDirPath();
    SslOptions sslOpts =
            Ssl(ssl::CaPath{baseDirPath + "ca.cer"}, ssl::CertFile{baseDirPath + "client.cer"},
                ssl::KeyFile{baseDirPath + "client.key"}, ssl::VerifyPeer{false},
                ssl::VerifyHost{false}, ssl::VerifyStatus{false});
    Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
    std::string expected_text = "Hello world!";
    EXPECT_EQ(expected_text, response.text);
    EXPECT_EQ(url, response.url);
    EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
    EXPECT_EQ(200, response.status_code);
    EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;

    std::vector<std::string> certInfo = response.GetCertInfo();
    EXPECT_EQ(certInfo.size(), 1);
    std::string expected_certInfo = "Subject:C = XX, L = Default City, O = Default Company Ltd";
    EXPECT_EQ(certInfo[0], expected_certInfo);
}

/**
 * We should replace this with a C++17 filesystem call,
 * once we have updated to >= C++17.
 **/
std::string getBasePath(const std::string& execPath) {
    std::string path = execPath.substr(0, execPath.find_last_of("\\/") + 1);

    // If Windows convert paths from "D:/cpr/build/bin/Release/client.cer" to
    // "D:\cpr\build\bin\Release\client.cer":
#ifdef _WIN32
    std::cout << "Converting Unix path to Windows path...\n";
    std::replace(path.begin(), path.end(), '\\', '/');
    std::cout << "Result path: " << path << '\n';
#endif
    return path;
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);

    std::string baseDirPath = getBasePath(argv[0]);
    std::string serverCertPath = baseDirPath + "server.cer";
    std::string serverKeyPath = baseDirPath + "server.key";
    server = new HttpsServer(std::move(baseDirPath), std::move(serverCertPath),
                             std::move(serverKeyPath));
    ::testing::AddGlobalTestEnvironment(server);

    return RUN_ALL_TESTS();
}
<commit_msg>Missing include thread and chrono in clang<commit_after>#include <gtest/gtest.h>

#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

#include <cpr/cprtypes.h>
#include <cpr/ssl_options.h>

#include "httpsServer.hpp"

using namespace cpr;

static HttpsServer* server;

TEST(SslTests, HelloWorldTestSimpel) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

    Url url{server->GetBaseUrl() + "/hello.html"};
    std::string baseDirPath = server->getBaseDirPath();
    SslOptions sslOpts =
            Ssl(ssl::CaPath{baseDirPath + "ca.cer"}, ssl::CertFile{baseDirPath + "client.cer"},
                ssl::KeyFile{baseDirPath + "client.key"}, ssl::VerifyPeer{false},
                ssl::PinnedPublicKey{baseDirPath + "server.pubkey"},
                ssl::VerifyHost{false}, ssl::VerifyStatus{false});
    Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
    std::string expected_text = "Hello world!";
    EXPECT_EQ(expected_text, response.text);
    EXPECT_EQ(url, response.url);
    EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
    EXPECT_EQ(200, response.status_code);
    EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}

TEST(SslTests, HelloWorldTestFull) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

    Url url{server->GetBaseUrl() + "/hello.html"};
    std::string baseDirPath = server->getBaseDirPath();
    SslOptions sslOpts = Ssl(
            ssl::TLSv1{}, ssl::ALPN{false}, ssl::NPN{false}, ssl::CaPath{baseDirPath + "ca.cer"},
            ssl::CertFile{baseDirPath + "client.cer"}, ssl::KeyFile{baseDirPath + "client.key"},
            ssl::PinnedPublicKey{baseDirPath + "server.pubkey"},
            ssl::VerifyPeer{false}, ssl::VerifyHost{false}, ssl::VerifyStatus{false});
    Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
    std::string expected_text = "Hello world!";
    EXPECT_EQ(expected_text, response.text);
    EXPECT_EQ(url, response.url);
    EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
    EXPECT_EQ(200, response.status_code);
    EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;
}

TEST(SslTests, GetCertInfo) {
    std::this_thread::sleep_for(std::chrono::seconds(1));

    Url url{server->GetBaseUrl() + "/hello.html"};
    std::string baseDirPath = server->getBaseDirPath();
    SslOptions sslOpts =
            Ssl(ssl::CaPath{baseDirPath + "ca.cer"}, ssl::CertFile{baseDirPath + "client.cer"},
                ssl::KeyFile{baseDirPath + "client.key"}, ssl::VerifyPeer{false},
                ssl::VerifyHost{false}, ssl::VerifyStatus{false});
    Response response = cpr::Get(url, sslOpts, Timeout{5000}, Verbose{});
    std::string expected_text = "Hello world!";
    EXPECT_EQ(expected_text, response.text);
    EXPECT_EQ(url, response.url);
    EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]);
    EXPECT_EQ(200, response.status_code);
    EXPECT_EQ(ErrorCode::OK, response.error.code) << response.error.message;

    std::vector<std::string> certInfo = response.GetCertInfo();
    EXPECT_EQ(certInfo.size(), 1);
    std::string expected_certInfo = "Subject:C = XX, L = Default City, O = Default Company Ltd";
    EXPECT_EQ(certInfo[0], expected_certInfo);
}

/**
 * We should replace this with a C++17 filesystem call,
 * once we have updated to >= C++17.
 **/
std::string getBasePath(const std::string& execPath) {
    std::string path = execPath.substr(0, execPath.find_last_of("\\/") + 1);

    // If Windows convert paths from "D:/cpr/build/bin/Release/client.cer" to
    // "D:\cpr\build\bin\Release\client.cer":
#ifdef _WIN32
    std::cout << "Converting Unix path to Windows path...\n";
    std::replace(path.begin(), path.end(), '\\', '/');
    std::cout << "Result path: " << path << '\n';
#endif
    return path;
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);

    std::string baseDirPath = getBasePath(argv[0]);
    std::string serverCertPath = baseDirPath + "server.cer";
    std::string serverKeyPath = baseDirPath + "server.key";
    server = new HttpsServer(std::move(baseDirPath), std::move(serverCertPath),
                             std::move(serverKeyPath));
    ::testing::AddGlobalTestEnvironment(server);

    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <iv/detail/array.h>
#include <iv/arith.h>

TEST(ArithCase, FLP2Test) {
  typedef std::array<uint32_t, 64> Samples;
  const Samples expected = { {
    0,
    1,
    2, 2,
    4, 4, 4, 4,
    8, 8, 8, 8, 8, 8, 8, 8,
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
  } };
  uint32_t i = 0;
  for (Samples::const_iterator it = expected.begin(),
       last = expected.end(); it != last; ++it, ++i) {
    EXPECT_EQ(*it, iv::core::FLP2(i)) << i;
  }
}

TEST(ArithCase, CLP2Test) {
  typedef std::array<uint32_t, 49> Samples;
  const Samples expected = { {
    0,
    1,
    2,
    4, 4,
    8, 8, 8, 8,
    16, 16, 16, 16, 16, 16, 16, 16,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
  } };
  uint32_t i = 0;
  for (Samples::const_iterator it = expected.begin(),
       last = expected.end(); it != last; ++it, ++i) {
    EXPECT_EQ(*it, iv::core::CLP2(i)) << i;
  }
}
<commit_msg>fix correct namespace<commit_after>#include <gtest/gtest.h>
#include <iv/detail/array.h>
#include <iv/arith.h>

TEST(ArithCase, FLP2Test) {
  typedef std::array<uint32_t, 64> Samples;
  const Samples expected = { {
    0,
    1,
    2, 2,
    4, 4, 4, 4,
    8, 8, 8, 8, 8, 8, 8, 8,
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
  } };
  uint32_t i = 0;
  for (Samples::const_iterator it = expected.begin(),
       last = expected.end(); it != last; ++it, ++i) {
    EXPECT_EQ(*it, iv::core::math::FLP2(i)) << i;
  }
}

TEST(ArithCase, CLP2Test) {
  typedef std::array<uint32_t, 49> Samples;
  const Samples expected = { {
    0,
    1,
    2,
    4, 4,
    8, 8, 8, 8,
    16, 16, 16, 16, 16, 16, 16, 16,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
  } };
  uint32_t i = 0;
  for (Samples::const_iterator it = expected.begin(),
       last = expected.end(); it != last; ++it, ++i) {
    EXPECT_EQ(*it, iv::core::math::CLP2(i)) << i;
  }
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CCopasiTask.cpp,v $
   $Revision: 1.3 $
   $Name:  $
   $Author: shoops $
   $Date: 2003/11/26 21:17:57 $
   End CVS Header */

/**
 *  CCopasiTask class.
 *  This class is used to describe a task in COPASI. This class is
 *  intended to be used as the parent class for all tasks whithin COPASI.
 *
 *  Created for Copasi by Stefan Hoops 2003
 */

#include "copasi.h"

#include "CCopasiTask.h"
#include "CCopasiProblem.h"
#include "CCopasiMethod.h"
#include "report/CReport.h"
#include "report/CKeyFactory.h"

const std::string CCopasiTask::TypeName[] =
  {
    "Stead-State",
    "Time-Course",
    "Scan",
    "Elementary Flux Modes",
    "Optimization",
    "Parameter Fitting",
    ""
  };

const char* CCopasiTask::XMLType[] =
  {
    "SteadyState",
    "TimeCourse",
    "Scan",
    "FluxMode",
    "Optimization",
    "ParameterFitting",
    NULL
  };

CCopasiTask::CCopasiTask():
    CCopasiContainer("NoName", NULL, "Task"),
    mType(CCopasiTask::unset),
    mKey(CKeyFactory::add("Task", this)),
    mScheduled(false),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport()
{}

CCopasiTask::CCopasiTask(const CCopasiTask::Type & taskType,
                         const CCopasiContainer * pParent,
                         const std::string & type):
    CCopasiContainer(CCopasiTask::TypeName[taskType], pParent, type),
    mType(taskType),
    mKey(CKeyFactory::add("Task", this)),
    mScheduled(false),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport()
{}

CCopasiTask::CCopasiTask(const CCopasiTask & src,
                         const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mType(src.mType),
    mKey(CKeyFactory::add("Task", this)),
    mScheduled(src.mScheduled),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(src.mReport)
{}

CCopasiTask::~CCopasiTask()
{
  CKeyFactory::remove(mKey);
  pdelete(mpProblem);
  pdelete(mpMethod);
}

const std::string & CCopasiTask::getName() const
  {return getObjectName();}

bool CCopasiTask::setName(const std::string & name)
{return setObjectName(name);}

CCopasiTask::Type CCopasiTask::getType() const {return mType;}

void CCopasiTask::setType(const CCopasiTask::Type & type) {mType = type;}

std::string CCopasiTask::getKey() const {return mKey;}

void CCopasiTask::setScheduled(const bool & scheduled) {mScheduled = scheduled;}

const bool & CCopasiTask::isScheduled() const {return mScheduled;}

bool CCopasiTask::initialize(std::ostream * C_UNUSED(pOstream)) {return true;}

bool CCopasiTask::process() {return true;}

bool CCopasiTask::restore() {return true;}

CCopasiProblem * CCopasiTask::getProblem() {return mpProblem;}

bool CCopasiTask::setMethodType(const int & C_UNUSED(type))
{return false;}

CCopasiMethod * CCopasiTask::getMethod() {return mpMethod;}

CReport & CCopasiTask::getReport() {return mReport;}
<commit_msg>Added closing of the report to the restore method.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CCopasiTask.cpp,v $
   $Revision: 1.4 $
   $Name:  $
   $Author: shoops $
   $Date: 2003/12/04 17:35:08 $
   End CVS Header */

/**
 *  CCopasiTask class.
 *  This class is used to describe a task in COPASI. This class is
 *  intended to be used as the parent class for all tasks whithin COPASI.
 *
 *  Created for Copasi by Stefan Hoops 2003
 */

#include "copasi.h"

#include "CCopasiTask.h"
#include "CCopasiProblem.h"
#include "CCopasiMethod.h"
#include "report/CReport.h"
#include "report/CKeyFactory.h"

const std::string CCopasiTask::TypeName[] =
  {
    "Stead-State",
    "Time-Course",
    "Scan",
    "Elementary Flux Modes",
    "Optimization",
    "Parameter Fitting",
    ""
  };

const char* CCopasiTask::XMLType[] =
  {
    "SteadyState",
    "TimeCourse",
    "Scan",
    "FluxMode",
    "Optimization",
    "ParameterFitting",
    NULL
  };

CCopasiTask::CCopasiTask():
    CCopasiContainer("NoName", NULL, "Task"),
    mType(CCopasiTask::unset),
    mKey(CKeyFactory::add("Task", this)),
    mScheduled(false),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport()
{}

CCopasiTask::CCopasiTask(const CCopasiTask::Type & taskType,
                         const CCopasiContainer * pParent,
                         const std::string & type):
    CCopasiContainer(CCopasiTask::TypeName[taskType], pParent, type),
    mType(taskType),
    mKey(CKeyFactory::add("Task", this)),
    mScheduled(false),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport()
{}

CCopasiTask::CCopasiTask(const CCopasiTask & src,
                         const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mType(src.mType),
    mKey(CKeyFactory::add("Task", this)),
    mScheduled(src.mScheduled),
    mpProblem(NULL),
    mpMethod(NULL),
    mReport(src.mReport)
{}

CCopasiTask::~CCopasiTask()
{
  CKeyFactory::remove(mKey);
  pdelete(mpProblem);
  pdelete(mpMethod);
}

const std::string & CCopasiTask::getName() const
  {return getObjectName();}

bool CCopasiTask::setName(const std::string & name)
{return setObjectName(name);}

CCopasiTask::Type CCopasiTask::getType() const {return mType;}

void CCopasiTask::setType(const CCopasiTask::Type & type) {mType = type;}

std::string CCopasiTask::getKey() const {return mKey;}

void CCopasiTask::setScheduled(const bool & scheduled) {mScheduled = scheduled;}

const bool & CCopasiTask::isScheduled() const {return mScheduled;}

bool CCopasiTask::initialize(std::ostream * C_UNUSED(pOstream)) {return true;}

bool CCopasiTask::process() {return true;}

bool CCopasiTask::restore()
{
  mReport.close();
  return true;
}

CCopasiProblem * CCopasiTask::getProblem() {return mpProblem;}

bool CCopasiTask::setMethodType(const int & C_UNUSED(type))
{return false;}

CCopasiMethod * CCopasiTask::getMethod() {return mpMethod;}

CReport & CCopasiTask::getReport() {return mReport;}
<|endoftext|>