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

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

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

#include <vector>

#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
#include <ucbhelper/contentidentifier.hxx>
#endif
#ifndef _UCBHELPER_PROVIDERHELPER_HXX
#include <ucbhelper/providerhelper.hxx>
#endif

#ifndef DBA_DATASUPPLIER_HXX
#include "myucp_datasupplier.hxx"
#endif
#ifndef DBA_CONTENTHELPER_HXX
#include "ContentHelper.hxx"
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::container;

// @@@ Adjust namespace name.
using namespace dbaccess;

// @@@ Adjust namespace name.
namespace dbaccess
{

//=========================================================================
//
// struct ResultListEntry.
//
//=========================================================================

struct ResultListEntry
{
    rtl::OUString                       aId;
    Reference< XContentIdentifier >     xId;
    ::rtl::Reference< OContentHelper >  xContent;
    Reference< XRow >                   xRow;
    const ContentProperties&            rData;

    ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
};

//=========================================================================
//
// ResultList.
//
//=========================================================================

typedef std::vector< ResultListEntry* > ResultList;

//=========================================================================
//
// struct DataSupplier_Impl.
//
//=========================================================================

struct DataSupplier_Impl
{
    osl::Mutex                                   m_aMutex;
    ResultList                                   m_aResults;
    rtl::Reference< ODocumentContainer >             m_xContent;
    Reference< XMultiServiceFactory >            m_xSMgr;
      sal_Int32                                  m_nOpenMode;
      sal_Bool                                   m_bCountFinal;

    DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
                        const rtl::Reference< ODocumentContainer >& rContent,
                       sal_Int32 nOpenMode )
    : m_xContent(rContent)
    , m_xSMgr( rxSMgr )
    , m_nOpenMode( nOpenMode )
    , m_bCountFinal( sal_False ) {}
    ~DataSupplier_Impl();
};

//=========================================================================
DataSupplier_Impl::~DataSupplier_Impl()
{
    ResultList::const_iterator it  = m_aResults.begin();
    ResultList::const_iterator end = m_aResults.end();

    while ( it != end )
    {
        delete (*it);
        it++;
    }
}

}

//=========================================================================
//=========================================================================
//
// DataSupplier Implementation.
//
//=========================================================================
//=========================================================================
DBG_NAME(DataSupplier)

DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr,
                           const rtl::Reference< ODocumentContainer >& rContent,
                            sal_Int32 nOpenMode )
: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) )
{
    DBG_CTOR(DataSupplier,NULL);

}

//=========================================================================
// virtual
DataSupplier::~DataSupplier()
{

    DBG_DTOR(DataSupplier,NULL);
}

//=========================================================================
// virtual
rtl::OUString DataSupplier::queryContentIdentifierString( sal_Int32 nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
        if ( aId.getLength() )
        {
            // Already cached.
            return aId;
        }
    }

    if ( getResult( nIndex ) )
    {
        rtl::OUString aId
            = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();

        if ( aId.getLength() )
            aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));

        aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;

        m_pImpl->m_aResults[ nIndex ]->aId = aId;
        return aId;
    }
    return rtl::OUString();
}

//=========================================================================
// virtual
Reference< XContentIdentifier >
DataSupplier::queryContentIdentifier( sal_Int32 nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId;
        if ( xId.is() )
        {
            // Already cached.
            return xId;
        }
    }

    rtl::OUString aId = queryContentIdentifierString( nIndex );
    if ( aId.getLength() )
    {
        Reference< XContentIdentifier > xId = new ::ucb::ContentIdentifier( aId );
        m_pImpl->m_aResults[ nIndex ]->xId = xId;
        return xId;
    }
    return Reference< XContentIdentifier >();
}

//=========================================================================
// virtual
Reference< XContent >
DataSupplier::queryContent( sal_Int32 _nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)_nIndex < m_pImpl->m_aResults.size() )
    {
        Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
        if ( xContent.is() )
        {
            // Already cached.
            return xContent;
        }
    }

    Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex );
    if ( xId.is() )
    {
        try
        {
            Reference< XContent > xContent;
            ::rtl::OUString sName = xId->getContentIdentifier();
            sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
            sName = sName.getToken(0,'/',nIndex);

            m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName);

            xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
            return xContent;

        }
        catch ( IllegalIdentifierException& )
        {
        }
    }
    return Reference< XContent >();
}

//=========================================================================
// virtual
sal_Bool DataSupplier::getResult( sal_Int32 nIndex )
{
    osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        // Result already present.
        return sal_True;
    }

    // Result not (yet) present.

    if ( m_pImpl->m_bCountFinal )
        return sal_False;

    // Try to obtain result...

    sal_Int32 nOldCount = m_pImpl->m_aResults.size();
    sal_Bool bFound = sal_False;
    sal_Int32 nPos = nOldCount;

    // @@@ Obtain data and put it into result list...
    Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
    if ( nIndex < aSeq.getLength() )
    {
        const ::rtl::OUString* pIter = aSeq.getConstArray();
        const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
        for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos)
        {
            m_pImpl->m_aResults.push_back(
                            new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );

            if ( nPos == nIndex )
            {
                // Result obtained.
                bFound = sal_True;
                break;
            }
        }
    }

    if ( !bFound )
        m_pImpl->m_bCountFinal = sal_True;

    rtl::Reference< ::ucb::ResultSet > xResultSet = getResultSet().getBodyPtr();
    if ( xResultSet.is() )
    {
        // Callbacks follow!
        aGuard.clear();

        if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
            xResultSet->rowCountChanged(
                                    nOldCount, m_pImpl->m_aResults.size() );

        if ( m_pImpl->m_bCountFinal )
            xResultSet->rowCountFinal();
    }

    return bFound;
}

//=========================================================================
// virtual
sal_Int32 DataSupplier::totalCount()
{
    osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( m_pImpl->m_bCountFinal )
        return m_pImpl->m_aResults.size();

    sal_Int32 nOldCount = m_pImpl->m_aResults.size();

    // @@@ Obtain data and put it into result list...
    Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
    const ::rtl::OUString* pIter = aSeq.getConstArray();
    const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
    for(;pIter != pEnd;++pIter)
        m_pImpl->m_aResults.push_back(
                        new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );

    m_pImpl->m_bCountFinal = sal_True;

    rtl::Reference< ::ucb::ResultSet > xResultSet = getResultSet().getBodyPtr();
    if ( xResultSet.is() )
    {
        // Callbacks follow!
        aGuard.clear();

        if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
            xResultSet->rowCountChanged(
                                    nOldCount, m_pImpl->m_aResults.size() );

        xResultSet->rowCountFinal();
    }

    return m_pImpl->m_aResults.size();
}

//=========================================================================
// virtual
sal_Int32 DataSupplier::currentCount()
{
    return m_pImpl->m_aResults.size();
}

//=========================================================================
// virtual
sal_Bool DataSupplier::isCountFinal()
{
    return m_pImpl->m_bCountFinal;
}

//=========================================================================
// virtual
Reference< XRow >
DataSupplier::queryPropertyValues( sal_Int32 nIndex  )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
        if ( xRow.is() )
        {
            // Already cached.
            return xRow;
        }
    }

    if ( getResult( nIndex ) )
    {
        if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() )
            queryContent(nIndex);

        Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties());
        m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
        return xRow;
    }

    return Reference< XRow >();
}

//=========================================================================
// virtual
void DataSupplier::releasePropertyValues( sal_Int32 nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
        m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
}

//=========================================================================
// virtual
void DataSupplier::close()
{
}

//=========================================================================
// virtual
void DataSupplier::validate()
    throw( ResultSetException )
{
}

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

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

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

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

#include <vector>

#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
#include <ucbhelper/contentidentifier.hxx>
#endif
#ifndef _UCBHELPER_PROVIDERHELPER_HXX
#include <ucbhelper/providerhelper.hxx>
#endif

#ifndef DBA_DATASUPPLIER_HXX
#include "myucp_datasupplier.hxx"
#endif
#ifndef DBA_CONTENTHELPER_HXX
#include "ContentHelper.hxx"
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::container;

// @@@ Adjust namespace name.
using namespace dbaccess;

// @@@ Adjust namespace name.
namespace dbaccess
{

//=========================================================================
//
// struct ResultListEntry.
//
//=========================================================================

struct ResultListEntry
{
    rtl::OUString                       aId;
    Reference< XContentIdentifier >     xId;
    ::rtl::Reference< OContentHelper >  xContent;
    Reference< XRow >                   xRow;
    const ContentProperties&            rData;

    ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
};

//=========================================================================
//
// ResultList.
//
//=========================================================================

typedef std::vector< ResultListEntry* > ResultList;

//=========================================================================
//
// struct DataSupplier_Impl.
//
//=========================================================================

struct DataSupplier_Impl
{
    osl::Mutex                                   m_aMutex;
    ResultList                                   m_aResults;
    rtl::Reference< ODocumentContainer >             m_xContent;
    Reference< XMultiServiceFactory >            m_xSMgr;
      sal_Int32                                  m_nOpenMode;
      sal_Bool                                   m_bCountFinal;

    DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
                        const rtl::Reference< ODocumentContainer >& rContent,
                       sal_Int32 nOpenMode )
    : m_xContent(rContent)
    , m_xSMgr( rxSMgr )
    , m_nOpenMode( nOpenMode )
    , m_bCountFinal( sal_False ) {}
    ~DataSupplier_Impl();
};

//=========================================================================
DataSupplier_Impl::~DataSupplier_Impl()
{
    ResultList::const_iterator it  = m_aResults.begin();
    ResultList::const_iterator end = m_aResults.end();

    while ( it != end )
    {
        delete (*it);
        it++;
    }
}

}

//=========================================================================
//=========================================================================
//
// DataSupplier Implementation.
//
//=========================================================================
//=========================================================================
DBG_NAME(DataSupplier)

DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr,
                           const rtl::Reference< ODocumentContainer >& rContent,
                            sal_Int32 nOpenMode )
: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) )
{
    DBG_CTOR(DataSupplier,NULL);

}

//=========================================================================
// virtual
DataSupplier::~DataSupplier()
{

    DBG_DTOR(DataSupplier,NULL);
}

//=========================================================================
// virtual
rtl::OUString DataSupplier::queryContentIdentifierString( sal_Int32 nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
        if ( aId.getLength() )
        {
            // Already cached.
            return aId;
        }
    }

    if ( getResult( nIndex ) )
    {
        rtl::OUString aId
            = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();

        if ( aId.getLength() )
            aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));

        aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;

        m_pImpl->m_aResults[ nIndex ]->aId = aId;
        return aId;
    }
    return rtl::OUString();
}

//=========================================================================
// virtual
Reference< XContentIdentifier >
DataSupplier::queryContentIdentifier( sal_Int32 nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId;
        if ( xId.is() )
        {
            // Already cached.
            return xId;
        }
    }

    rtl::OUString aId = queryContentIdentifierString( nIndex );
    if ( aId.getLength() )
    {
        Reference< XContentIdentifier > xId = new ::ucb::ContentIdentifier( aId );
        m_pImpl->m_aResults[ nIndex ]->xId = xId;
        return xId;
    }
    return Reference< XContentIdentifier >();
}

//=========================================================================
// virtual
Reference< XContent >
DataSupplier::queryContent( sal_Int32 _nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)_nIndex < m_pImpl->m_aResults.size() )
    {
        Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
        if ( xContent.is() )
        {
            // Already cached.
            return xContent;
        }
    }

    Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex );
    if ( xId.is() )
    {
        try
        {
            Reference< XContent > xContent;
            ::rtl::OUString sName = xId->getContentIdentifier();
            sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
            sName = sName.getToken(0,'/',nIndex);

            m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName);

            xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
            return xContent;

        }
        catch ( IllegalIdentifierException& )
        {
        }
    }
    return Reference< XContent >();
}

//=========================================================================
// virtual
sal_Bool DataSupplier::getResult( sal_Int32 nIndex )
{
    osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        // Result already present.
        return sal_True;
    }

    // Result not (yet) present.

    if ( m_pImpl->m_bCountFinal )
        return sal_False;

    // Try to obtain result...

    sal_Int32 nOldCount = m_pImpl->m_aResults.size();
    sal_Bool bFound = sal_False;
    sal_Int32 nPos = nOldCount;

    // @@@ Obtain data and put it into result list...
    Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
    if ( nIndex < aSeq.getLength() )
    {
        const ::rtl::OUString* pIter = aSeq.getConstArray();
        const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
        for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos)
        {
            m_pImpl->m_aResults.push_back(
                            new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );

            if ( nPos == nIndex )
            {
                // Result obtained.
                bFound = sal_True;
                break;
            }
        }
    }

    if ( !bFound )
        m_pImpl->m_bCountFinal = sal_True;

    rtl::Reference< ::ucb::ResultSet > xResultSet = getResultSet().getBodyPtr();
    if ( xResultSet.is() )
    {
        // Callbacks follow!
        aGuard.clear();

        if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
            xResultSet->rowCountChanged(
                                    nOldCount, m_pImpl->m_aResults.size() );

        if ( m_pImpl->m_bCountFinal )
            xResultSet->rowCountFinal();
    }

    return bFound;
}

//=========================================================================
// virtual
sal_Int32 DataSupplier::totalCount()
{
    osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( m_pImpl->m_bCountFinal )
        return m_pImpl->m_aResults.size();

    sal_Int32 nOldCount = m_pImpl->m_aResults.size();

    // @@@ Obtain data and put it into result list...
    Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
    const ::rtl::OUString* pIter = aSeq.getConstArray();
    const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
    for(;pIter != pEnd;++pIter)
        m_pImpl->m_aResults.push_back(
                        new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );

    m_pImpl->m_bCountFinal = sal_True;

    rtl::Reference< ::ucb::ResultSet > xResultSet = getResultSet().getBodyPtr();
    if ( xResultSet.is() )
    {
        // Callbacks follow!
        aGuard.clear();

        if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
            xResultSet->rowCountChanged(
                                    nOldCount, m_pImpl->m_aResults.size() );

        xResultSet->rowCountFinal();
    }

    return m_pImpl->m_aResults.size();
}

//=========================================================================
// virtual
sal_Int32 DataSupplier::currentCount()
{
    return m_pImpl->m_aResults.size();
}

//=========================================================================
// virtual
sal_Bool DataSupplier::isCountFinal()
{
    return m_pImpl->m_bCountFinal;
}

//=========================================================================
// virtual
Reference< XRow >
DataSupplier::queryPropertyValues( sal_Int32 nIndex  )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
    {
        Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
        if ( xRow.is() )
        {
            // Already cached.
            return xRow;
        }
    }

    if ( getResult( nIndex ) )
    {
        if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() )
            queryContent(nIndex);

        Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties());
        m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
        return xRow;
    }

    return Reference< XRow >();
}

//=========================================================================
// virtual
void DataSupplier::releasePropertyValues( sal_Int32 nIndex )
{
    osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );

    if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
        m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
}

//=========================================================================
// virtual
void DataSupplier::close()
{
}

//=========================================================================
// virtual
void DataSupplier::validate()
    throw( ResultSetException )
{
}

<|endoftext|>


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

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

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

#include "mvdDatasetDescriptor.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdVectorImageModel.h"
#include "mvdSystemError.h"

/** \brief Indent space when writing XML DOM documents. */
#define XML_INDENT 2

namespace mvd
{
/*
  TRANSLATOR mvd::DatasetDescriptor

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
DatasetDescriptor
::DatasetDescriptor( QObject* parent ) :
  AbstractModel( parent ),
  m_DomDocument( QString( "%1 Dataset" ).arg( PROJECT_NAME ) ),
  m_ImagesElement()
{
}

/*******************************************************************************/
DatasetDescriptor
::~DatasetDescriptor()
{
}

/*******************************************************************************/
void
DatasetDescriptor
::InsertImageModel( const QString& imageFilename,
		    void* imageSettings,
		    const QString& quicklookFilename )
{
  //
  // Image node.
  QDomNode imageNode( m_DomDocument.createElement( "image" ) );
  QDomElement imageElement( imageNode.toElement() );

  imageElement.setAttribute(
    "filename",
    imageFilename
  );

  imageElement.setAttribute(
    "quicklook",
    quicklookFilename
  );

  //
  // Settings node.
  QDomNode settingsNode( m_DomDocument.createElement( "settings" ) );
  QDomElement settingsElement( settingsNode.toElement() );

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  //
  // RGB node
  QDomNode rgbNode( m_DomDocument.createElement( "rgb" ) );
  QDomElement rgbElement( rgbNode.toElement() );

  //
  // Dynamics node.
  QDomNode dynamicsNode( m_DomDocument.createElement( "dynamics" ) );
  QDomElement dynamicsElement( dynamicsNode.toElement() );

  // TODO: Create XML elements and set attribute for settings.
  }
}

/*******************************************************************************/
void
DatasetDescriptor
::GetImageModel( const QDomElement& imageSibling,
		 QString& imageFilename,
		 void* imageSettings,
		 QString& quicklookFilename )
{
  imageFilename = imageSibling.attribute( "filename" );

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  // Settings
  QDomElement settingsElement( imageSibling.firstChildElement( "settings" ) );

  // RGB
  QDomElement rgbElement( settingsElement.firstChildElement( "rgb" ) );

  // Dynamics
  QDomElement dynamicsElement( settingsElement.firstChildElement( "dynamics" ) );

  // Ensure there is only one '<settings>...</settings>' child.
  settingsElement = settingsElement.nextSiblingElement( "settings" );
  assert( settingsElement.isNull() );
  }

  quicklookFilename = imageSibling.attribute( "quicklook" );
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( const QString& filename )
{
  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  // Read file context.
  Read( &file );

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( QIODevice* device )
{
  // Temporary DOM document.
  QDomDocument domDoc;

  // Error information.
  QString error;
  int line;
  int column;

  // Link to content and manages error.
  if( !domDoc.setContent( device, true, &error, &line, &column ) )
    throw /* XmlError( error, line, column ) */;

  // If Ok, remember DOM document data (otherwise, forget temporary
  // DOM document and leave class state unchanged).
  m_DomDocument = domDoc;
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( const QString& filename ) const
{
  qDebug() << filename;

  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  try
    {
    // Read file context.
    Write( file );
    }
  catch( SystemError& syserr )
    {
    // Catch any SystemError thrown by DatasetDescriptor::Write() and
    // morph it into the same SystemError containing filename
    // information.
    syserr = SystemError(
      syserr.GetErrorCode(),
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

    // Throw morphed SystemError.
    throw syserr;
    }

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( QIODevice& device ) const
{
  qDebug() << "descriptor.xml: " << m_DomDocument.toByteArray( XML_INDENT );
  qDebug() << "descriptor.xml: " << m_DomDocument.toString( XML_INDENT );

  // TODO: Check IO device is formatted to UTF-8 data.
  if( device.write( m_DomDocument.toByteArray( XML_INDENT ) )==-1 )
    throw SystemError();
}

/*******************************************************************************/
void
DatasetDescriptor
::virtual_BuildModel( void* context )
{
  qDebug() << "DatasetDescriptor::virtual_BuildModel()";

#if 0
  // Get build-context.
  assert( context!=NULL );
  BuildContext* buildContext = static_cast< BuildContext* >( context );
#endif

  const DatasetModel* model = GetParentModel< DatasetModel >();
  assert( model );

  // Root document element: '<dataset>...</dataset>'.
  QDomElement docElt( m_DomDocument.documentElement() );
  docElt.setTagName( "dataset" );
  docElt.setAttribute(
    "directory",
    QDir::cleanPath( model->GetDirectory().path() )
  );

  // Images group element: '<dataset><images>...</images></dataset>'.
  QDomNode imagesNode(
    docElt.appendChild(
      m_DomDocument.createElement( "images" )
    )
  );

  m_ImagesElement = imagesNode.toElement();
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/

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

} // end namespace 'mvd'
<commit_msg>ENH: add root element to enable writing<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

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

#include "mvdDatasetDescriptor.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdVectorImageModel.h"
#include "mvdSystemError.h"

/** \brief Indent space when writing XML DOM documents. */
#define XML_INDENT 2

namespace mvd
{
/*
  TRANSLATOR mvd::DatasetDescriptor

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
DatasetDescriptor
::DatasetDescriptor( QObject* parent ) :
  AbstractModel( parent ),
  m_DomDocument(QString(PROJECT_NAME).append("_Dataset") ),
  m_ImagesElement()
{
}

/*******************************************************************************/
DatasetDescriptor
::~DatasetDescriptor()
{
}

/*******************************************************************************/
void
DatasetDescriptor
::InsertImageModel( const QString& imageFilename,
		    void* imageSettings,
		    const QString& quicklookFilename )
{

  //
  // Image node.
  QDomNode imageNode( m_DomDocument.createElement( "image" ) );
  QDomElement imageElement( imageNode.toElement() );
  //QDomElement imageElement = m_DomDocument.createElement("image");

  imageElement.setAttribute(
    "filename",
    imageFilename
  );

  imageElement.setAttribute(
    "quicklook",
    quicklookFilename
  );

  //m_DomDocument.appendChild(imageElement);

  //
  // Settings node.
  QDomNode settingsNode( m_DomDocument.createElement( "settings" ) );
  QDomElement settingsElement( settingsNode.toElement() );

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  //
  // RGB node
  QDomNode rgbNode( m_DomDocument.createElement( "rgb" ) );
  QDomElement rgbElement( rgbNode.toElement() );

  //
  // Dynamics node.
  QDomNode dynamicsNode( m_DomDocument.createElement( "dynamics" ) );
  QDomElement dynamicsElement( dynamicsNode.toElement() );

  // TODO: Create XML elements and set attribute for settings.
  }

}

/*******************************************************************************/
void
DatasetDescriptor
::GetImageModel( const QDomElement& imageSibling,
		 QString& imageFilename,
		 void* imageSettings,
		 QString& quicklookFilename )
{
  imageFilename = imageSibling.attribute( "filename" );

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  // Settings
  QDomElement settingsElement( imageSibling.firstChildElement( "settings" ) );

  // RGB
  QDomElement rgbElement( settingsElement.firstChildElement( "rgb" ) );

  // Dynamics
  QDomElement dynamicsElement( settingsElement.firstChildElement( "dynamics" ) );

  // Ensure there is only one '<settings>...</settings>' child.
  settingsElement = settingsElement.nextSiblingElement( "settings" );
  assert( settingsElement.isNull() );
  }

  quicklookFilename = imageSibling.attribute( "quicklook" );
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( const QString& filename )
{
  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  // Read file context.
  Read( &file );

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( QIODevice* device )
{
  // Temporary DOM document.
  QDomDocument domDoc;

  // Error information.
  QString error;
  int line;
  int column;

  // Link to content and manages error.
  if( !domDoc.setContent( device, true, &error, &line, &column ) )
    throw /* XmlError( error, line, column ) */;

  // If Ok, remember DOM document data (otherwise, forget temporary
  // DOM document and leave class state unchanged).
  m_DomDocument = domDoc;
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( const QString& filename ) const
{
  qDebug() << filename;

  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  try
    {
    // Read file context.
    Write( file );
    }
  catch( SystemError& syserr )
    {
    // Catch any SystemError thrown by DatasetDescriptor::Write() and
    // morph it into the same SystemError containing filename
    // information.
    syserr = SystemError(
      syserr.GetErrorCode(),
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

    // Throw morphed SystemError.
    throw syserr;
    }

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( QIODevice& device ) const
{
  qDebug() << "descriptor.xml: " << m_DomDocument.toByteArray( XML_INDENT );
  qDebug() << "descriptor.xml: " << m_DomDocument.toString( XML_INDENT );

  // TODO: Check IO device is formatted to UTF-8 data.
  if( device.write( m_DomDocument.toByteArray( XML_INDENT ) )==-1 )
    throw SystemError();
}

/*******************************************************************************/
void
DatasetDescriptor
::virtual_BuildModel( void* context )
{
  qDebug() << "DatasetDescriptor::virtual_BuildModel()";

#if 0
  // Get build-context.
  assert( context!=NULL );
  BuildContext* buildContext = static_cast< BuildContext* >( context );
#endif

  const DatasetModel* model = GetParentModel< DatasetModel >();
  assert( model );

  // Add the root element
  QDomElement root = m_DomDocument.createElement(QString(PROJECT_NAME).append("_Dataset"));
  m_DomDocument.appendChild(root);

  // Root document element: '<dataset>...</dataset>'.
  QDomElement docElt( m_DomDocument.documentElement() );
  docElt.setTagName( "dataset" );
  docElt.setAttribute(
    "directory",
    QDir::cleanPath( model->GetDirectory().path() )
  );

  QDomNode noeud = m_DomDocument.createProcessingInstruction("xml","version=\"1.0\"");
  m_DomDocument.insertBefore(noeud, m_DomDocument);

  // Images group element: '<dataset><images>...</images></dataset>'.
  QDomNode imagesNode(
    docElt.appendChild(
      m_DomDocument.createElement( "images" )
    )
  );

  m_ImagesElement = imagesNode.toElement();
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/

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

} // end namespace 'mvd'
<|endoftext|>


<commit_before>#include <limits>

#include <Bull/Core/Log/Log.hpp>

#include <Bull/Render/Context/Wgl/WglContext.hpp>
#include <Bull/Render/Context/Wgl/WglContextNoError.hpp>
#include <Bull/Render/Context/Wgl/WglCreateContextARB.hpp>
#include <Bull/Render/Context/Wgl/WglMultisampleARB.hpp>
#include <Bull/Render/Context/Wgl/WglPbufferARB.hpp>
#include <Bull/Render/Context/Wgl/WglPixelFormatARB.hpp>
#include <Bull/Render/Context/Wgl/WglSwapControlEXT.hpp>

namespace Bull
{
    namespace prv
    {
        void* WglContext::getFunction(const String& function)
        {
            void* functionProc = reinterpret_cast<void*>(wglGetProcAddress(function.getBuffer()));

            if(functionProc)
            {
                return functionProc;
            }

            static HMODULE module = LoadLibrary("opengl32.dll");

            if(!module)
            {
                return nullptr;
            }

            return reinterpret_cast<void*>(GetProcAddress(module, function.getBuffer()));
        }

        void WglContext::requireExtensions(const ExtensionsLoader::Instance& loader)
        {
            loader->require(WglCreateContext);
            loader->require(WglPixelFormat);
            loader->require(WglSwapControl);
            loader->require(WglPbuffer);
        }

        int WglContext::getBestPixelFormat(HDC device, Uint8 bitsPerPixel, const ContextSettings& settings, bool usePbuffer)
        {
            int bestPixelFormat = 0;

            if(isLoaded(WglPixelFormat))
            {
                static const int attribs[] =
                {
                    WGL_DRAW_TO_WINDOW_ARB, 1,
                    WGL_SUPPORT_OPENGL_ARB, 1,
                    WGL_DOUBLE_BUFFER_ARB,  1,
                    WGL_PIXEL_TYPE_ARB,     WGL_TYPE_RGBA_ARB,
                    0
                };

                int formats[512];
                UINT count = 0;
                bool isValid = wglChoosePixelFormat(device, attribs, nullptr, 512, formats, &count) != 0;

                if(isValid && count > 0)
                {
                    int bestScore = std::numeric_limits<int>::max();

                    for(UINT i = 0; i < count; i++)
                    {
                        int format[7]  = {0};
                        int sample[2]  = {0};
                        static const int formatAttribs[] =
                        {
                            WGL_RED_BITS_ARB,
                            WGL_GREEN_BITS_ARB,
                            WGL_BLUE_BITS_ARB,
                            WGL_ALPHA_BITS_ARB,
                            WGL_DEPTH_BITS_ARB,
                            WGL_STENCIL_BITS_ARB,
                            WGL_ACCELERATION_ARB
                        };

                        if(!wglGetPixelFormatAttribiv(device, formats[i], PFD_MAIN_PLANE, 7, formatAttribs, format))
                        {
                            break;
                        }

                        if(isSupported(WglMultisample))
                        {
                            static const int sampleAttribs[] =
                            {
                                WGL_SAMPLE_BUFFERS_ARB,
                                WGL_SAMPLES_ARB
                            };

                            if(!wglGetPixelFormatAttribiv(device, formats[i], PFD_MAIN_PLANE, 2, sampleAttribs, sample))
                            {
                                break;
                            }
                        }

                        if(usePbuffer)
                        {
                            int pbuffer;
                            static const int pbufferAttribs[] =
                            {
                                WGL_DRAW_TO_PBUFFER_ARB
                            };

                            if(!wglGetPixelFormatAttribiv(device, formats[i], PFD_MAIN_PLANE, 1, pbufferAttribs, &pbuffer))
                            {
                                break;
                            }
                            else if(pbuffer != 1)
                            {
                                continue;
                            }
                        }

                        /// We don't care about non hardware accelerated pixel format
                        if(format[6])
                        {
                            int colors = format[0] + format[1] + format[2] + format[3];
                            int score  = evaluatePixelFormat(colors, format[4], format[5], sample[0] ? sample[1] : 0, bitsPerPixel, settings);

                            if(bestScore > score)
                            {
                                bestScore       = score;
                                bestPixelFormat = formats[i];
                            }
                        }
                    }
                }
            }

            if(usePbuffer)
            {
                return bestPixelFormat;
            }

            if(!bestPixelFormat)
            {
                PIXELFORMATDESCRIPTOR descriptor;
                ZeroMemory(&descriptor, sizeof(descriptor));
                descriptor.nSize        = sizeof(descriptor);
                descriptor.nVersion     = 1;
                descriptor.iLayerType   = PFD_MAIN_PLANE;
                descriptor.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
                descriptor.iPixelType   = PFD_TYPE_RGBA;
                descriptor.cColorBits   = static_cast<BYTE>(bitsPerPixel);
                descriptor.cDepthBits   = static_cast<BYTE>(settings.depths);
                descriptor.cStencilBits = static_cast<BYTE>(settings.stencil);
                descriptor.cAlphaBits   = bitsPerPixel == 32 ? 8 : 0;

                bestPixelFormat = ChoosePixelFormat(device, &descriptor);
            }

            return bestPixelFormat;
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared) :
            WglContext(shared, VideoMode(1, 1), ContextSettings())
        {
            /// Nothing
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared, const VideoMode& mode, const ContextSettings& settings) :
            GlContext(settings),
            m_device(nullptr),
            m_render(nullptr),
            m_pbuffer(nullptr),
            m_ownWindow(false)
        {
            createSurface(shared, mode.width, mode.height, mode.bitsPerPixel);

            if(m_device)
            {
                setPixelFormat(mode.bitsPerPixel);

                createContext(shared);
            }
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared, Uint8 bitsPerPixel, const ContextSettings& settings) :
            WglContext(shared, VideoMode(1, 1, bitsPerPixel), settings)
        {
            /// Nothing
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared, const std::unique_ptr<WindowImpl>& window, Uint8 bitsPerPixel, const ContextSettings& settings) :
            GlContext(settings),
            m_device(nullptr),
            m_render(nullptr),
            m_pbuffer(nullptr),
            m_ownWindow(false)
        {
            createSurface(window);

            if(m_device)
            {
                setPixelFormat(bitsPerPixel);

                createContext(shared);
            }
        }

        WglContext::~WglContext()
        {
            if(m_render)
            {
                if(wglGetCurrentContext() == m_render)
                {
                    wglMakeCurrent(nullptr, nullptr);
                }

                wglDeleteContext(m_render);
            }

            if(m_device)
            {
                if(m_pbuffer)
                {
                    wglReleasePbufferDC(m_pbuffer, m_device);
                    wglDestroyPbuffer(m_pbuffer);
                }
                else
                {
                    ReleaseDC(m_window, m_device);
                }
            }

            if(m_window && m_ownWindow)
            {
                DestroyWindow(m_window);
            }
        }

        SurfaceHandler WglContext::getSurfaceHandler() const
        {
            return m_device;
        }

        void WglContext::display()
        {
            if(m_device && m_render)
            {
                SwapBuffers(m_device);
            }
        }

        void WglContext::enableVsync(bool active)
        {
            if(isLoaded(WglSwapControl))
            {
                wglSwapInterval(active ? 1 : 0);
            }
        }

        bool WglContext::makeCurrent()
        {
            return wglMakeCurrent(m_device, m_render) == TRUE;
        }

        void WglContext::createSurface(const std::unique_ptr<WindowImpl>& window)
        {
            m_window = window->getSystemHandler();

            m_device = GetDC(m_window);
        }

        void WglContext::createSurface(const std::shared_ptr<WglContext>& shared, unsigned int width, unsigned int height, Uint8 bitsPerPixel)
        {
            if(isLoaded(WglPbuffer) && shared)
            {
                int format = getBestPixelFormat(shared->m_device, bitsPerPixel, m_settings, true);

                if(format)
                {
                    m_pbuffer = wglCreatePbuffer(shared->m_device, format, width, height, nullptr);

                    if(m_pbuffer)
                    {
                        m_device = wglGetPbufferDC(m_pbuffer);

                        if(!m_device)
                        {
                            wglDestroyPbuffer(m_pbuffer);
                        }
                    }
                }
            }

            if(!m_device)
            {
                m_window = CreateWindow("STATIC", nullptr,
                                         WS_DISABLED | WS_POPUP,
                                         0, 0,
                                         width, height,
                                         nullptr,
                                         nullptr,
                                         GetModuleHandle(nullptr),
                                         nullptr);

                m_device = GetDC(m_window);

                m_ownWindow = true;
            }
        }

        void WglContext::setPixelFormat(Uint8 bitsPerPixel)
        {
            PIXELFORMATDESCRIPTOR descriptor;
            int bestFormat = getBestPixelFormat(m_device, bitsPerPixel, m_settings);

            descriptor.nSize    = sizeof(PIXELFORMATDESCRIPTOR);
            descriptor.nVersion = 1;
            DescribePixelFormat(m_device, bestFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor);

            SetPixelFormat(m_device, bestFormat, &descriptor);
        }

        void WglContext::createContext(const std::shared_ptr<WglContext>& shared)
        {
            HGLRC sharedHandler = shared ? shared->m_render : nullptr;

            if(isLoaded(WglCreateContext))
            {
                do
                {
                    std::vector<int> attribs;

                    attribs.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
                    attribs.push_back(m_settings.major);
                    attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
                    attribs.push_back(m_settings.minor);

                    if(isSupported("WGL_ARB_create_context_profile"))
                    {
                        int flags   = 0;
                        int profile = (m_settings.profile == ContextSettings::Compatibility) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;

                        if(m_settings.type == ContextSettings::Debug)
                        {
                            flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
                        }

                        if(m_settings.type == ContextSettings::ForwardCompatible)
                        {
                            flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
                        }

                        attribs.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
                        attribs.push_back(profile);
                        attribs.push_back(WGL_CONTEXT_FLAGS_ARB);
                        attribs.push_back(flags);
                    }

                    if(m_settings.type == ContextSettings::NoError)
                    {
                        if(isSupported("WGL_ARB_create_context_no_error"))
                        {
                            attribs.push_back(WGL_CONTEXT_OPENGL_NO_ERROR_ARB);
                            attribs.push_back(1);
                        }
                        else
                        {   m_settings.type = ContextSettings::Default;
                            Log::get()->write("WGL_CONTEXT_OPENGL_NO_ERROR_ARB is not available", Log::Level::Warning);
                        }
                    }

                    attribs.push_back(0);
                    attribs.push_back(0);

                    m_render = wglCreateContextAttribs(m_device, sharedHandler, &attribs[0]);

                    if(!m_render)
                    {
                        Log::get()->write("Failed to create WglContext with version " + String::number(m_settings.major) + "." + String::number(m_settings.minor), Log::Level::Warning);

                        if(m_settings.minor == 0)
                        {
                            m_settings.major -= 1;
                            m_settings.minor  = 9;
                        }
                        else
                        {
                            m_settings.minor -= 1;
                        }
                    }
                }while(!m_render && m_settings.major >= 1);
            }

            if(m_render == nullptr)
            {
                m_render = wglCreateContext(m_device);

                if(m_render && shared)
                {
                    static Mutex mutex;
                    Lock lock(mutex);

                    wglShareLists(sharedHandler, m_render);
                }
            }

            updateSettings();
        }

        void WglContext::updateSettings()
        {
            int pixelFormat = GetPixelFormat(m_device);
            PIXELFORMATDESCRIPTOR pfd;
            pfd.nVersion = 1;
            pfd.nSize    = sizeof(PIXELFORMATDESCRIPTOR);

            DescribePixelFormat(m_device, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

            if(isLoaded(WglPixelFormat))
            {
                int format[2] = {0};

                static const int formatAttribs[] =
                {
                    WGL_DEPTH_BITS_ARB,
                    WGL_STENCIL_BITS_ARB
                };

                if(wglGetPixelFormatAttribiv(m_device, pixelFormat, PFD_MAIN_PLANE, 2, formatAttribs, format))
                {
                    m_settings.depths  = static_cast<Uint8>(format[0]);
                    m_settings.stencil = static_cast<Uint8>(format[1]);
                }
                else
                {
                    m_settings.depths  = pfd.cDepthBits;
                    m_settings.stencil = pfd.cStencilBits;
                }

                if(isSupported(WglMultisample))
                {
                    int sample[2] = {0};
                    static const int sampleAttribs[] =
                    {
                        WGL_SAMPLE_BUFFERS_ARB,
                        WGL_SAMPLES_ARB
                    };

                    if(wglGetPixelFormatAttribiv(m_device, pixelFormat, PFD_MAIN_PLANE, 2, sampleAttribs, sample))
                    {
                        m_settings.antialiasing = sample[0] ? sample[1] : 0;
                    }
                    else
                    {
                        m_settings.antialiasing = 0;
                    }
                }
                else
                {
                    m_settings.antialiasing = 0;
                }
            }
            else
            {
                m_settings.depths       = pfd.cDepthBits;
                m_settings.stencil      = pfd.cStencilBits;
                m_settings.antialiasing = 0;
            }
        }
    }
}
<commit_msg>[Render/WglContext] Disable pbuffer extension<commit_after>#include <limits>

#include <Bull/Core/Log/Log.hpp>

#include <Bull/Render/Context/Wgl/WglContext.hpp>
#include <Bull/Render/Context/Wgl/WglContextNoError.hpp>
#include <Bull/Render/Context/Wgl/WglCreateContextARB.hpp>
#include <Bull/Render/Context/Wgl/WglMultisampleARB.hpp>
#include <Bull/Render/Context/Wgl/WglPbufferARB.hpp>
#include <Bull/Render/Context/Wgl/WglPixelFormatARB.hpp>
#include <Bull/Render/Context/Wgl/WglSwapControlEXT.hpp>

namespace Bull
{
    namespace prv
    {
        void* WglContext::getFunction(const String& function)
        {
            void* functionProc = reinterpret_cast<void*>(wglGetProcAddress(function.getBuffer()));

            if(functionProc)
            {
                return functionProc;
            }

            static HMODULE module = LoadLibrary("opengl32.dll");

            if(!module)
            {
                return nullptr;
            }

            return reinterpret_cast<void*>(GetProcAddress(module, function.getBuffer()));
        }

        void WglContext::requireExtensions(const ExtensionsLoader::Instance& loader)
        {
            loader->require(WglCreateContext);
            loader->require(WglPixelFormat);
            loader->require(WglSwapControl);
        }

        int WglContext::getBestPixelFormat(HDC device, Uint8 bitsPerPixel, const ContextSettings& settings, bool usePbuffer)
        {
            int bestPixelFormat = 0;

            if(isLoaded(WglPixelFormat))
            {
                static const int attribs[] =
                {
                    WGL_DRAW_TO_WINDOW_ARB, 1,
                    WGL_SUPPORT_OPENGL_ARB, 1,
                    WGL_DOUBLE_BUFFER_ARB,  1,
                    WGL_PIXEL_TYPE_ARB,     WGL_TYPE_RGBA_ARB,
                    0
                };

                int formats[512];
                UINT count = 0;
                bool isValid = wglChoosePixelFormat(device, attribs, nullptr, 512, formats, &count) != 0;

                if(isValid && count > 0)
                {
                    int bestScore = std::numeric_limits<int>::max();

                    for(UINT i = 0; i < count; i++)
                    {
                        int format[7] = {0};
                        int sample[2] = {0};
                        static const int formatAttribs[] =
                        {
                            WGL_RED_BITS_ARB,
                            WGL_GREEN_BITS_ARB,
                            WGL_BLUE_BITS_ARB,
                            WGL_ALPHA_BITS_ARB,
                            WGL_DEPTH_BITS_ARB,
                            WGL_STENCIL_BITS_ARB,
                            WGL_ACCELERATION_ARB
                        };

                        if(!wglGetPixelFormatAttribiv(device, formats[i], PFD_MAIN_PLANE, 7, formatAttribs, format))
                        {
                            break;
                        }

                        if(isSupported(WglMultisample))
                        {
                            static const int sampleAttribs[] =
                            {
                                WGL_SAMPLE_BUFFERS_ARB,
                                WGL_SAMPLES_ARB
                            };

                            if(!wglGetPixelFormatAttribiv(device, formats[i], PFD_MAIN_PLANE, 2, sampleAttribs, sample))
                            {
                                break;
                            }
                        }

                        if(usePbuffer)
                        {
                            int pbuffer;
                            static const int pbufferAttribs[] =
                            {
                                WGL_DRAW_TO_PBUFFER_ARB
                            };

                            if(!wglGetPixelFormatAttribiv(device, formats[i], PFD_MAIN_PLANE, 1, pbufferAttribs, &pbuffer))
                            {
                                break;
                            }
                            else if(pbuffer != 1)
                            {
                                continue;
                            }
                        }

                        /// We don't care about non hardware accelerated pixel format
                        if(format[6])
                        {
                            int colors = format[0] + format[1] + format[2] + format[3];
                            int score  = evaluatePixelFormat(colors, format[4], format[5], sample[0] ? sample[1] : 0, bitsPerPixel, settings);

                            if(bestScore > score)
                            {
                                bestScore       = score;
                                bestPixelFormat = formats[i];
                            }
                        }
                    }
                }
            }

            if(usePbuffer)
            {
                return bestPixelFormat;
            }

            if(!bestPixelFormat)
            {
                PIXELFORMATDESCRIPTOR descriptor;
                ZeroMemory(&descriptor, sizeof(descriptor));
                descriptor.nSize        = sizeof(descriptor);
                descriptor.nVersion     = 1;
                descriptor.iLayerType   = PFD_MAIN_PLANE;
                descriptor.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
                descriptor.iPixelType   = PFD_TYPE_RGBA;
                descriptor.cColorBits   = static_cast<BYTE>(bitsPerPixel);
                descriptor.cDepthBits   = static_cast<BYTE>(settings.depths);
                descriptor.cStencilBits = static_cast<BYTE>(settings.stencil);
                descriptor.cAlphaBits   = bitsPerPixel == 32 ? 8 : 0;

                bestPixelFormat = ChoosePixelFormat(device, &descriptor);
            }

            return bestPixelFormat;
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared) :
            WglContext(shared, VideoMode(1, 1), ContextSettings())
        {
            /// Nothing
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared, const VideoMode& mode, const ContextSettings& settings) :
            GlContext(settings),
            m_device(nullptr),
            m_render(nullptr),
            m_pbuffer(nullptr),
            m_ownWindow(false)
        {
            createSurface(shared, mode.width, mode.height, mode.bitsPerPixel);

            if(m_device)
            {
                setPixelFormat(mode.bitsPerPixel);

                createContext(shared);
            }
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared, Uint8 bitsPerPixel, const ContextSettings& settings) :
            WglContext(shared, VideoMode(1, 1, bitsPerPixel), settings)
        {
            /// Nothing
        }

        WglContext::WglContext(const std::shared_ptr<WglContext>& shared, const std::unique_ptr<WindowImpl>& window, Uint8 bitsPerPixel, const ContextSettings& settings) :
            GlContext(settings),
            m_device(nullptr),
            m_render(nullptr),
            m_pbuffer(nullptr),
            m_ownWindow(false)
        {
            createSurface(window);

            if(m_device)
            {
                setPixelFormat(bitsPerPixel);

                createContext(shared);
            }
        }

        WglContext::~WglContext()
        {
            if(m_render)
            {
                if(wglGetCurrentContext() == m_render)
                {
                    wglMakeCurrent(nullptr, nullptr);
                }

                wglDeleteContext(m_render);
            }

            if(m_device)
            {
                if(m_pbuffer)
                {
                    wglReleasePbufferDC(m_pbuffer, m_device);
                    wglDestroyPbuffer(m_pbuffer);
                }
                else
                {
                    ReleaseDC(m_window, m_device);
                }
            }

            if(m_window && m_ownWindow)
            {
                DestroyWindow(m_window);
            }
        }

        SurfaceHandler WglContext::getSurfaceHandler() const
        {
            return m_device;
        }

        void WglContext::display()
        {
            if(m_device && m_render)
            {
                SwapBuffers(m_device);
            }
        }

        void WglContext::enableVsync(bool active)
        {
            if(isLoaded(WglSwapControl))
            {
                wglSwapInterval(active ? 1 : 0);
            }
        }

        bool WglContext::makeCurrent()
        {
            return wglMakeCurrent(m_device, m_render) == TRUE;
        }

        void WglContext::createSurface(const std::unique_ptr<WindowImpl>& window)
        {
            m_window = window->getSystemHandler();

            m_device = GetDC(m_window);
        }

        void WglContext::createSurface(const std::shared_ptr<WglContext>& shared, unsigned int width, unsigned int height, Uint8 bitsPerPixel)
        {
            if(isLoaded(WglPbuffer) && shared)
            {
                int format = getBestPixelFormat(shared->m_device, bitsPerPixel, m_settings, true);

                if(format)
                {
                    m_pbuffer = wglCreatePbuffer(shared->m_device, format, width, height, nullptr);

                    if(m_pbuffer)
                    {
                        m_device = wglGetPbufferDC(m_pbuffer);

                        if(!m_device)
                        {
                            wglDestroyPbuffer(m_pbuffer);
                        }
                    }
                }
            }

            if(!m_device)
            {
                m_window = CreateWindow("STATIC", nullptr,
                                         WS_DISABLED | WS_POPUP,
                                         0, 0,
                                         width, height,
                                         nullptr,
                                         nullptr,
                                         GetModuleHandle(nullptr),
                                         nullptr);

                m_device = GetDC(m_window);

                m_ownWindow = true;
            }
        }

        void WglContext::setPixelFormat(Uint8 bitsPerPixel)
        {
            PIXELFORMATDESCRIPTOR descriptor;
            int bestFormat = getBestPixelFormat(m_device, bitsPerPixel, m_settings);

            descriptor.nSize    = sizeof(PIXELFORMATDESCRIPTOR);
            descriptor.nVersion = 1;
            DescribePixelFormat(m_device, bestFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor);

            SetPixelFormat(m_device, bestFormat, &descriptor);
        }

        void WglContext::createContext(const std::shared_ptr<WglContext>& shared)
        {
            HGLRC sharedHandler = shared ? shared->m_render : nullptr;

            if(isLoaded(WglCreateContext))
            {
                do
                {
                    std::vector<int> attribs;

                    attribs.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
                    attribs.push_back(m_settings.major);
                    attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
                    attribs.push_back(m_settings.minor);

                    if(isSupported("WGL_ARB_create_context_profile"))
                    {
                        int flags   = 0;
                        int profile = (m_settings.profile == ContextSettings::Compatibility) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;

                        if(m_settings.type == ContextSettings::Debug)
                        {
                            flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
                        }

                        if(m_settings.type == ContextSettings::ForwardCompatible)
                        {
                            flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
                        }

                        attribs.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
                        attribs.push_back(profile);
                        attribs.push_back(WGL_CONTEXT_FLAGS_ARB);
                        attribs.push_back(flags);
                    }

                    if(m_settings.type == ContextSettings::NoError)
                    {
                        if(isSupported("WGL_ARB_create_context_no_error"))
                        {
                            attribs.push_back(WGL_CONTEXT_OPENGL_NO_ERROR_ARB);
                            attribs.push_back(1);
                        }
                        else
                        {   m_settings.type = ContextSettings::Default;
                            Log::get()->write("WGL_CONTEXT_OPENGL_NO_ERROR_ARB is not available", Log::Level::Warning);
                        }
                    }

                    attribs.push_back(0);
                    attribs.push_back(0);

                    m_render = wglCreateContextAttribs(m_device, sharedHandler, &attribs[0]);

                    if(!m_render)
                    {
                        Log::get()->write("Failed to create WglContext with version " + String::number(m_settings.major) + "." + String::number(m_settings.minor), Log::Level::Warning);

                        if(m_settings.minor == 0)
                        {
                            m_settings.major -= 1;
                            m_settings.minor  = 9;
                        }
                        else
                        {
                            m_settings.minor -= 1;
                        }
                    }
                }while(!m_render && m_settings.major >= 1);
            }

            if(m_render == nullptr)
            {
                m_render = wglCreateContext(m_device);

                if(m_render && shared)
                {
                    static Mutex mutex;
                    Lock lock(mutex);

                    wglShareLists(sharedHandler, m_render);
                }
            }

            updateSettings();
        }

        void WglContext::updateSettings()
        {
            PIXELFORMATDESCRIPTOR pfd;
            pfd.nVersion = 1;
            pfd.nSize    = sizeof(PIXELFORMATDESCRIPTOR);

            int pixelFormat = GetPixelFormat(m_device);
            DescribePixelFormat(m_device, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

            if(isLoaded(WglPixelFormat))
            {
                int format[2] = {0};

                static const int formatAttribs[] =
                {
                    WGL_DEPTH_BITS_ARB,
                    WGL_STENCIL_BITS_ARB
                };

                if(wglGetPixelFormatAttribiv(m_device, pixelFormat, PFD_MAIN_PLANE, 2, formatAttribs, format))
                {
                    m_settings.depths  = static_cast<Uint8>(format[0]);
                    m_settings.stencil = static_cast<Uint8>(format[1]);
                }
                else
                {
                    m_settings.depths  = pfd.cDepthBits;
                    m_settings.stencil = pfd.cStencilBits;
                }

                if(isSupported(WglMultisample))
                {
                    int sample[2] = {0};
                    static const int sampleAttribs[] =
                    {
                        WGL_SAMPLE_BUFFERS_ARB,
                        WGL_SAMPLES_ARB
                    };

                    if(wglGetPixelFormatAttribiv(m_device, pixelFormat, PFD_MAIN_PLANE, 2, sampleAttribs, sample))
                    {
                        m_settings.antialiasing = sample[0] ? sample[1] : 0;
                    }
                    else
                    {
                        m_settings.antialiasing = 0;
                    }
                }
                else
                {
                    m_settings.antialiasing = 0;
                }
            }
            else
            {
                m_settings.depths       = pfd.cDepthBits;
                m_settings.stencil      = pfd.cStencilBits;
                m_settings.antialiasing = 0;
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <gtest/gtest.h>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <Dataflow/Network/Network.h>
#include <Dataflow/Network/Connection.h>
#include <Dataflow/Network/ModuleDescription.h>
#include <Dataflow/Network/Tests/MockModule.h>
#include <Dataflow/Network/Tests/MockPorts.h>
#include <Dataflow/Network/Tests/MockModuleState.h>

using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Dataflow::Networks::Mocks;
using namespace boost::assign;
using ::testing::DefaultValue;
using ::testing::NiceMock;

class NetworkTests : public ::testing::Test
{
protected:
  virtual void SetUp()
  {
    DefaultValue<InputPortHandle>::Set(InputPortHandle(new NiceMock<MockInputPort>));
    DefaultValue<OutputPortHandle>::Set(OutputPortHandle(new NiceMock<MockOutputPort>));
    DefaultValue<boost::signals2::connection>::Set(boost::signals2::connection());
    moduleFactory_.reset(new MockModuleFactory);
  }

  virtual void TearDown()
  {
    moduleFactory_.reset();
    sf_.reset();
  }

  ModuleFactoryHandle moduleFactory_;
  static ModuleStateFactoryHandle sf_;
};

ModuleStateFactoryHandle NetworkTests::sf_;

TEST_F(NetworkTests, CanAddAndRemoveModules)
{
  Network network(moduleFactory_, sf_);

  EXPECT_EQ(0, network.nmodules());

  ModuleLookupInfo mli;
  mli.module_name_ = "Module1";
  ModuleHandle m = network.add_module(mli);
  EXPECT_EQ(mli.module_name_, m->get_module_name());
  EXPECT_EQ(1, network.nmodules());
  EXPECT_EQ(m, network.module(0));
  EXPECT_TRUE(network.remove_module(ModuleId(m->get_id())));
  EXPECT_EQ(0, network.nmodules());
  EXPECT_FALSE(network.remove_module(ModuleId("not in the network4")));
}

TEST_F(NetworkTests, CanAddAndRemoveConnections)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  EXPECT_EQ(2, network.nmodules());
  EXPECT_EQ(m1, network.module(0));
  EXPECT_EQ(m2, network.module(1));

  ConnectionId connId = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  EXPECT_EQ("module1_p#0_@to@_module2_p#1", connId.id_);

  EXPECT_TRUE(network.disconnect(connId));
  EXPECT_EQ(0, network.nconnections());
}

TEST_F(NetworkTests, CannotMakeSameConnectionTwice)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  ConnectionId connId = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  EXPECT_EQ("module1_p#0_@to@_module2_p#1", connId.id_);

  ConnectionId connIdEmpty = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  //not sure what to return here.
  EXPECT_EQ("", connIdEmpty.id_);

  EXPECT_TRUE(network.disconnect(connId));
  EXPECT_EQ(0, network.nconnections());

  connId = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  EXPECT_EQ("module1_p#0_@to@_module2_p#1", connId.id_);
}

//TODO: this verification pushed up to higher layer.
TEST_F(NetworkTests, DISABLED_ConnectionsMustHaveMatchingPortTypes)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  EXPECT_THROW(network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 2)), SCIRun::Core::InvalidArgumentException);
}

TEST_F(NetworkTests, CannotConnectNonExistentPorts)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  ConnectionId connId = network.connect(ConnectionOutputPort(m1, 3), ConnectionInputPort(m2, 2));
  EXPECT_EQ("", connId.id_);
}<commit_msg>Fix unit test.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#include <gtest/gtest.h>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <Dataflow/Network/Network.h>
#include <Dataflow/Network/Connection.h>
#include <Dataflow/Network/ModuleDescription.h>
#include <Dataflow/Network/Tests/MockModule.h>
#include <Dataflow/Network/Tests/MockPorts.h>
#include <Dataflow/Network/Tests/MockModuleState.h>

using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Dataflow::Networks::Mocks;
using namespace boost::assign;
using ::testing::DefaultValue;
using ::testing::NiceMock;

class NetworkTests : public ::testing::Test
{
protected:
  virtual void SetUp()
  {
    DefaultValue<InputPortHandle>::Set(InputPortHandle(new NiceMock<MockInputPort>));
    DefaultValue<OutputPortHandle>::Set(OutputPortHandle(new NiceMock<MockOutputPort>));
    DefaultValue<boost::signals2::connection>::Set(boost::signals2::connection());
    moduleFactory_.reset(new MockModuleFactory);
  }

  virtual void TearDown()
  {
    moduleFactory_.reset();
    sf_.reset();
  }

  ModuleFactoryHandle moduleFactory_;
  static ModuleStateFactoryHandle sf_;
};

ModuleStateFactoryHandle NetworkTests::sf_;

TEST_F(NetworkTests, CanAddAndRemoveModules)
{
  Network network(moduleFactory_, sf_);

  EXPECT_EQ(0, network.nmodules());

  ModuleLookupInfo mli;
  mli.module_name_ = "Module1";
  ModuleHandle m = network.add_module(mli);
  EXPECT_EQ(mli.module_name_, m->get_module_name());
  EXPECT_EQ(1, network.nmodules());
  EXPECT_EQ(m, network.module(0));
  EXPECT_TRUE(network.remove_module(ModuleId(m->get_id())));
  EXPECT_EQ(0, network.nmodules());
  EXPECT_FALSE(network.remove_module(ModuleId("not in the network4")));
}

TEST_F(NetworkTests, CanAddAndRemoveConnections)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  EXPECT_EQ(2, network.nmodules());
  EXPECT_EQ(m1, network.module(0));
  EXPECT_EQ(m2, network.module(1));

  ConnectionId connId = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  EXPECT_EQ("module:1_p#0_@to@_module:2_p#1", connId.id_);

  EXPECT_TRUE(network.disconnect(connId));
  EXPECT_EQ(0, network.nconnections());
}

TEST_F(NetworkTests, CannotMakeSameConnectionTwice)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  ConnectionId connId = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  EXPECT_EQ("module:1_p#0_@to@_module:2_p#1", connId.id_);

  ConnectionId connIdEmpty = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  //not sure what to return here.
  EXPECT_EQ("", connIdEmpty.id_);

  EXPECT_TRUE(network.disconnect(connId));
  EXPECT_EQ(0, network.nconnections());

  connId = network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 1));
  EXPECT_EQ(1, network.nconnections());
  EXPECT_EQ("module:1_p#0_@to@_module:2_p#1", connId.id_);
}

//TODO: this verification pushed up to higher layer.
TEST_F(NetworkTests, DISABLED_ConnectionsMustHaveMatchingPortTypes)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  EXPECT_THROW(network.connect(ConnectionOutputPort(m1, 0), ConnectionInputPort(m2, 2)), SCIRun::Core::InvalidArgumentException);
}

TEST_F(NetworkTests, CannotConnectNonExistentPorts)
{
  Network network(moduleFactory_, sf_);

  ModuleLookupInfo mli1;
  mli1.module_name_ = "Module1";
  ModuleHandle m1 = network.add_module(mli1);
  ModuleLookupInfo mli2;
  mli2.module_name_ = "Module2";
  ModuleHandle m2 = network.add_module(mli2);

  ConnectionId connId = network.connect(ConnectionOutputPort(m1, 3), ConnectionInputPort(m2, 2));
  EXPECT_EQ("", connId.id_);
}<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008, Image Engine Design Inc. 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  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 OWNER 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 <boost/python.hpp>
#include <cassert>

#include "boost/static_assert.hpp"

#include "IECore/LineSegment.h"
#include "IECore/bindings/LineSegmentBinding.h"

using namespace boost::python;

namespace IECore
{

template<class L>
static const char *typeName()
{
	BOOST_STATIC_ASSERT( sizeof(L) == 0 );
	return "";
}

template<>
static const char *typeName<LineSegment2f>()
{
	return "LineSegment2f";
}

template<>
static const char *typeName<LineSegment2d>()
{
	return "LineSegment2d";
}

template<>
static const char *typeName<LineSegment3f>()
{
	return "LineSegment3f";
}

template<>
static const char *typeName<LineSegment3d>()
{
	return "LineSegment3d";
}

template<class L>
static std::string repr( L &x )
{
	std::stringstream s;

	s << "IECore." << typeName<L>() << "( ";

	object item0( x.p0 );
	assert( item.attr0( "__repr__" ) != object() );
	s << call_method< std::string >( item0.ptr(), "__repr__" ) << ", ";

	object item1( x.p1 );
	assert( item.attr1( "__repr__" ) != object() );
	s << call_method< std::string >( item1.ptr(), "__repr__" ) << " )";

	return s.str();
}

template<class L>
static tuple closestPoints( const L &l, const L &l2 )
{
	typename L::Point a, b;
	a = l.closestPoints( l2, b );
	return make_tuple( a, b );
}

template<typename Vec>
static void bind3D()
{
	typedef typename Vec::BaseType BaseType;
	typedef LineSegment<Vec> L;
	typedef Imath::Matrix44<BaseType> M;

	class_<L>( IECore::typeName< L >() )
		.def( init<L>() )
		.def( init<Vec, Vec>() )
		.def_readwrite( "p0", &L::p0 )
		.def_readwrite( "p1", &L::p1 )
		.def( "__repr__", &repr<L> )
		.def( "__call__", &L::operator() )
		.def( "direction", &L::direction )
		.def( "normalizedDirection", &L::normalizedDirection )
		.def( "length", &L::length )
		.def( "length2", &L::length2 )
		.def( "closestPointTo", &L::closestPointTo )
		.def( "closestPoints", &closestPoints<L> )
		.def( "distanceTo", (typename L::BaseType (L::*)( const Vec & ) const)&L::distanceTo )
		.def( "distanceTo", (typename L::BaseType (L::*)( const L & ) const)&L::distanceTo )
		.def( "distance2To", (typename L::BaseType (L::*)( const Vec & ) const)&L::distance2To )
		.def( "distance2To", (typename L::BaseType (L::*)( const L & ) const)&L::distance2To )
		.def( self *= M() )
		.def( self * M() )
		.def( self == self )
		.def( self != self )
		/// \todo Bind the intersect methods when we have a binding for ImathPlane
	;

}

template<typename Vec>
static void bind2D()
{
	typedef typename Vec::BaseType BaseType;
	typedef LineSegment<Vec> L;
	typedef Imath::Matrix33<BaseType> M;

	class_<L>( IECore::typeName< L >() )
		.def( init<L>() )
		.def( init<Vec, Vec>() )
		.def_readwrite( "p0", &L::p0 )
		.def_readwrite( "p1", &L::p1 )
		.def( "__repr__", &repr<L> )
		.def( "__call__", &L::operator() )
		.def( "direction", &L::direction )
		.def( "normalizedDirection", &L::normalizedDirection )
		.def( "length", &L::length )
		.def( "length2", &L::length2 )
		.def( "closestPointTo", &L::closestPointTo )
		.def( "distanceTo", (typename L::BaseType (L::*)( const Vec & ) const)&L::distanceTo )
		.def( "distance2To", (typename L::BaseType (L::*)( const Vec & ) const)&L::distance2To )
		.def( self *= M() )
		.def( self * M() )
		.def( self == self )
		.def( self != self )
	;

}

void bindLineSegment()
{
	bind3D<Imath::V3f>();
	bind3D<Imath::V3d>();
	bind2D<Imath::V2f>();
	bind2D<Imath::V2d>();
}

} // namespace IECore
<commit_msg>gcc 3.3.4 workarounds for the changes made for gcc 4.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008, Image Engine Design Inc. 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  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 OWNER 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 <boost/python.hpp>
#include <cassert>

#include "boost/static_assert.hpp"

#include "IECore/LineSegment.h"
#include "IECore/bindings/LineSegmentBinding.h"

using namespace boost::python;

namespace IECore
{

template<class L>
static const char *typeName()
{
	BOOST_STATIC_ASSERT( sizeof(L) == 0 );
	return "";
}

template<>
static const char *typeName<LineSegment2f>()
{
	return "LineSegment2f";
}

template<>
static const char *typeName<LineSegment2d>()
{
	return "LineSegment2d";
}

template<>
static const char *typeName<LineSegment3f>()
{
	return "LineSegment3f";
}

template<>
static const char *typeName<LineSegment3d>()
{
	return "LineSegment3d";
}

template<class L>
static std::string repr( L &x )
{
	std::stringstream s;

	s << "IECore." << typeName<L>() << "( ";

	object item0( x.p0 );
	assert( item.attr0( "__repr__" ) != object() );
	s << call_method< std::string >( item0.ptr(), "__repr__" ) << ", ";

	object item1( x.p1 );
	assert( item.attr1( "__repr__" ) != object() );
	s << call_method< std::string >( item1.ptr(), "__repr__" ) << " )";

	return s.str();
}

template<class L>
static tuple closestPoints( const L &l, const L &l2 )
{
	typename L::Point a, b;
	a = l.closestPoints( l2, b );
	return make_tuple( a, b );
}

template<typename Vec>
static void bind3D()
{
	typedef typename Vec::BaseType BaseType;
	typedef LineSegment<Vec> L;
	typedef Imath::Matrix44<BaseType> M;

	const char *name = typeName< L >();

	class_<L>( name )
		.def( init<L>() )
		.def( init<Vec, Vec>() )
		.def_readwrite( "p0", &L::p0 )
		.def_readwrite( "p1", &L::p1 )
		.def( "__repr__", &repr<L> )
		.def( "__call__", &L::operator() )
		.def( "direction", &L::direction )
		.def( "normalizedDirection", &L::normalizedDirection )
		.def( "length", &L::length )
		.def( "length2", &L::length2 )
		.def( "closestPointTo", &L::closestPointTo )
		.def( "closestPoints", &closestPoints<L> )
		.def( "distanceTo", (typename L::BaseType (L::*)( const Vec & ) const)&L::distanceTo )
		.def( "distanceTo", (typename L::BaseType (L::*)( const L & ) const)&L::distanceTo )
		.def( "distance2To", (typename L::BaseType (L::*)( const Vec & ) const)&L::distance2To )
		.def( "distance2To", (typename L::BaseType (L::*)( const L & ) const)&L::distance2To )
		.def( self *= M() )
		.def( self * M() )
		.def( self == self )
		.def( self != self )
		/// \todo Bind the intersect methods when we have a binding for ImathPlane
	;

}

template<typename Vec>
static void bind2D()
{
	typedef typename Vec::BaseType BaseType;
	typedef LineSegment<Vec> L;
	typedef Imath::Matrix33<BaseType> M;

	const char *name = typeName< L >();

	class_<L>( name )
		.def( init<L>() )
		.def( init<Vec, Vec>() )
		.def_readwrite( "p0", &L::p0 )
		.def_readwrite( "p1", &L::p1 )
		.def( "__repr__", &repr<L> )
		.def( "__call__", &L::operator() )
		.def( "direction", &L::direction )
		.def( "normalizedDirection", &L::normalizedDirection )
		.def( "length", &L::length )
		.def( "length2", &L::length2 )
		.def( "closestPointTo", &L::closestPointTo )
		.def( "distanceTo", (typename L::BaseType (L::*)( const Vec & ) const)&L::distanceTo )
		.def( "distance2To", (typename L::BaseType (L::*)( const Vec & ) const)&L::distance2To )
		.def( self *= M() )
		.def( self * M() )
		.def( self == self )
		.def( self != self )
	;

}

void bindLineSegment()
{
	bind3D<Imath::V3f>();
	bind3D<Imath::V3d>();
	bind2D<Imath::V2f>();
	bind2D<Imath::V2d>();
}

} // namespace IECore
<|endoftext|>