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

#include "helpinterceptor.hxx"
#include "helpdispatch.hxx"
#include "newhelp.hxx"
#include "sfxuno.hxx"

#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XNOTIFYINGDISPATCH_HPP_
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#include <vcl/window.hxx>
#include <limits.h>

using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;

extern void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ); // sfxhelp.cxx

// class HelpInterceptor_Impl --------------------------------------------

HelpInterceptor_Impl::HelpInterceptor_Impl() :

    m_pHistory  ( NULL ),
    m_nCurPos   ( 0 )

{
}

// -----------------------------------------------------------------------

HelpInterceptor_Impl::~HelpInterceptor_Impl()
{
    for ( USHORT i = 0; m_pHistory && i < m_pHistory->Count(); ++i )
        delete m_pHistory->GetObject(i);
    delete m_pHistory;

    if ( m_xIntercepted.is() )
        m_xIntercepted->releaseDispatchProviderInterceptor( (XDispatchProviderInterceptor*)this );
}

// -----------------------------------------------------------------------

Reference< XController > HelpInterceptor_Impl::getController() const throw( RuntimeException )
{
    Reference< XController > xRet;
    if( m_pWindow )
    {
        Reference< XFrame > xFrame = m_pWindow->getTextFrame();
        if( xFrame.is() )
            xRet = xFrame->getController();
    }

    return xRet;
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::addURL( const String& rURL )
{
    if ( !m_pHistory )
        m_pHistory = new HelpHistoryList_Impl;
    ULONG nCount = m_pHistory->Count();
    if ( nCount && m_nCurPos < ( nCount - 1 ) )
    {
        for ( ULONG i = nCount - 1; i > m_nCurPos; i-- )
            delete m_pHistory->Remove(i);
    }
    Reference<XFrame> xFrame(m_xIntercepted, UNO_QUERY);
    Reference<XController> xController = xFrame.is() ? xFrame->getController() : 0;
    Any aViewData;
    if(xController.is() && m_pHistory->Count())
    {
        m_pHistory->GetObject(m_nCurPos)->aViewData = xController->getViewData();
    }

    m_aCurrentURL = rURL;
    m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL ), LIST_APPEND );
    m_nCurPos = m_pHistory->Count() - 1;

    if ( m_xListener.is() )
    {
        ::com::sun::star::frame::FeatureStateEvent aEvent;
        URL aURL;
        aURL.Complete = rURL;
        aEvent.FeatureURL = aURL;
        aEvent.Source = (::com::sun::star::frame::XDispatch*)this;
        m_xListener->statusChanged( aEvent );
    }

    m_pWindow->UpdateToolbox();
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::LeavePage()
{
    if( m_pHistory && m_pHistory->Count() > m_nCurPos)
    {
        // get view position of _current_ URL
        HelpHistoryEntry_Impl* pCurEntry = m_pHistory->GetObject( m_nCurPos );
        try
        {
            Reference< XController > xContr( getController() );
            if( xContr.is() )
                pCurEntry->aViewData = xContr->getViewData();
        }
        catch( const Exception& ) {}
    }
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::setInterception( Reference< XFrame > xFrame )
{
    m_xIntercepted = Reference< XDispatchProviderInterception>( xFrame, UNO_QUERY );

    if ( m_xIntercepted.is() )
        m_xIntercepted->registerDispatchProviderInterceptor( (XDispatchProviderInterceptor*)this );
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::SetStartURL( const String& rURL )
{
    DBG_ASSERT( !m_pHistory, "invalid history" );
    if ( !m_pHistory )
    {
        m_pHistory = new HelpHistoryList_Impl;
        m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL ), ((ULONG)0x0) );
        m_nCurPos = m_pHistory->Count() - 1;

        m_pWindow->UpdateToolbox();
    }
    m_aCurrentURL = rURL;
}

// -----------------------------------------------------------------------

sal_Bool HelpInterceptor_Impl::HasHistoryPred() const
{
    return m_pHistory && ( m_nCurPos > 0 );
}

// -----------------------------------------------------------------------

sal_Bool HelpInterceptor_Impl::HasHistorySucc() const
{
    return m_pHistory && ( m_nCurPos < ( m_pHistory->Count() - 1 ) );
}

// -----------------------------------------------------------------------
// XDispatchProvider

Reference< XDispatch > SAL_CALL HelpInterceptor_Impl::queryDispatch(

    const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags )

    throw( RuntimeException )

{
    Reference< XDispatch > xResult;
    if ( m_xSlaveDispatcher.is() )
        xResult = m_xSlaveDispatcher->queryDispatch( aURL, aTargetFrameName, nSearchFlags );

    INetURLObject aObj( aURL.Complete );
    sal_Bool bHelpURL = ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP );
    if ( bHelpURL )
    {
        DBG_ASSERT( xResult.is(), "invalid dispatch" );
        HelpDispatch_Impl* pHelpDispatch = new HelpDispatch_Impl( *this, xResult );
        xResult = Reference< XDispatch >( static_cast< ::cppu::OWeakObject* >(pHelpDispatch), UNO_QUERY );
    }

    return xResult;
}

// -----------------------------------------------------------------------

Sequence < Reference < XDispatch > > SAL_CALL HelpInterceptor_Impl::queryDispatches(

    const Sequence< DispatchDescriptor >& aDescripts )

    throw( RuntimeException )

{
    Sequence< Reference< XDispatch > > aReturn( aDescripts.getLength() );
    Reference< XDispatch >* pReturn = aReturn.getArray();
    const DispatchDescriptor* pDescripts = aDescripts.getConstArray();
    for ( sal_Int16 i = 0; i < aDescripts.getLength(); ++i, ++pReturn, ++pDescripts )
    {
        *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
    }
    return aReturn;
}

// -----------------------------------------------------------------------
// XDispatchProviderInterceptor

Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getSlaveDispatchProvider()

    throw( RuntimeException )

{
    return m_xSlaveDispatcher;
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::setSlaveDispatchProvider( const Reference< XDispatchProvider >& xNewSlave )

    throw( RuntimeException )

{
    m_xSlaveDispatcher = xNewSlave;
}

// -----------------------------------------------------------------------

Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getMasterDispatchProvider()

    throw( RuntimeException )

{
    return m_xMasterDispatcher;
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::setMasterDispatchProvider( const Reference< XDispatchProvider >& xNewMaster )

    throw( RuntimeException )

{
    m_xMasterDispatcher = xNewMaster;
}

// -----------------------------------------------------------------------
// XInterceptorInfo

Sequence< ::rtl::OUString > SAL_CALL HelpInterceptor_Impl::getInterceptedURLs()

    throw( RuntimeException )

{
    Sequence< ::rtl::OUString > aURLList( 1 );
    aURLList[0] = DEFINE_CONST_UNICODE("vnd.sun.star.help://*");
    return aURLList;
}

// -----------------------------------------------------------------------
// XDispatch

void SAL_CALL HelpInterceptor_Impl::dispatch(

    const URL& aURL, const Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw( RuntimeException )

{
    sal_Bool bBack = ( String( DEFINE_CONST_UNICODE(".uno:Backward") ) == String( aURL.Complete ) );
    if ( bBack || String( DEFINE_CONST_UNICODE(".uno:Forward") ) == String( aURL.Complete ) )
    {
        if ( m_pHistory )
        {
            LeavePage();       // save current position

            ULONG nPos = ( bBack && m_nCurPos > 0 ) ? --m_nCurPos
                                                    : ( !bBack && m_nCurPos < m_pHistory->Count() - 1 )
                                                    ? ++m_nCurPos
                                                    : ULONG_MAX;

            if ( nPos < ULONG_MAX )
            {
                HelpHistoryEntry_Impl* pEntry = m_pHistory->GetObject( nPos );
                if ( pEntry )
                {
                    URL aURL;
                    aURL.Complete = pEntry->aURL;
                    Reference < XDispatch > xDisp = m_xSlaveDispatcher->queryDispatch( aURL, String(), 0 );
                    if ( xDisp.is() )
                    {
                        if ( m_pOpenListener && m_pWindow )
                        {
                            if ( !m_pWindow->IsWait() )
                                m_pWindow->EnterWait();
                        }
                        m_aCurrentURL = aURL.Complete;
                        m_aViewData = pEntry->aViewData;

                        Reference < XNotifyingDispatch > xNotifyingDisp( xDisp, UNO_QUERY );
                        if ( xNotifyingDisp.is() )
                        {
                            OpenStatusListener_Impl* pListener = (OpenStatusListener_Impl*)m_pWindow->getOpenListener().get();
                            DBG_ASSERT( pListener, "invalid XDispatchResultListener" );
                            pListener->SetURL( aURL.Complete );
                            xNotifyingDisp->dispatchWithNotification( aURL, Sequence < PropertyValue >(), pListener );
                        }
                    }
                }
            }

            m_pWindow->UpdateToolbox();
        }
    }
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::addStatusListener(

    const Reference< XStatusListener >& xControl, const URL& aURL ) throw( RuntimeException )

{
    DBG_ASSERT( !m_xListener.is(), "listener already exists" );
    m_xListener = xControl;
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::removeStatusListener(

    const Reference< XStatusListener >& xControl, const URL& aURL ) throw( RuntimeException )

{
    m_xListener = 0;
}

// HelpListener_Impl -----------------------------------------------------

HelpListener_Impl::HelpListener_Impl( HelpInterceptor_Impl* pInter )
{
    pInterceptor = pInter;
    pInterceptor->addStatusListener( this, ::com::sun::star::util::URL() );
}

// -----------------------------------------------------------------------

void SAL_CALL HelpListener_Impl::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event )

    throw( ::com::sun::star::uno::RuntimeException )

{
    INetURLObject aObj( Event.FeatureURL.Complete );
    aFactory = aObj.GetHost();
    aChangeLink.Call( this );
}

// -----------------------------------------------------------------------

void SAL_CALL HelpListener_Impl::disposing( const ::com::sun::star::lang::EventObject& obj )

    throw( ::com::sun::star::uno::RuntimeException )

{
    pInterceptor->removeStatusListener( this, ::com::sun::star::util::URL() );
    pInterceptor = NULL;
}
/*-- 05.09.2002 12:17:59---------------------------------------------------

  -----------------------------------------------------------------------*/
HelpStatusListener_Impl::HelpStatusListener_Impl(
        Reference < XDispatch > xDispatch, URL& rURL)
{
    xDispatch->addStatusListener(this, rURL);
}
/*-- 05.09.2002 12:17:59---------------------------------------------------

  -----------------------------------------------------------------------*/
HelpStatusListener_Impl::~HelpStatusListener_Impl()
{
    if(xDispatch.is())
        xDispatch->removeStatusListener(this, com::sun::star::util::URL());
}
/*-- 05.09.2002 12:17:59---------------------------------------------------

  -----------------------------------------------------------------------*/
void HelpStatusListener_Impl::statusChanged(
    const FeatureStateEvent& rEvent ) throw( RuntimeException )
{
    aStateEvent = rEvent;
}
/*-- 05.09.2002 12:18:00---------------------------------------------------

  -----------------------------------------------------------------------*/
void HelpStatusListener_Impl::disposing( const EventObject& obj ) throw( RuntimeException )
{
    xDispatch->removeStatusListener(this, com::sun::star::util::URL());
    xDispatch = 0;
}
<commit_msg>#93478# syntax error Solaris corrected<commit_after>/*************************************************************************
 *
 *  $RCSfile: helpinterceptor.cxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: os $ $Date: 2002-10-29 12:15:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "helpinterceptor.hxx"
#include "helpdispatch.hxx"
#include "newhelp.hxx"
#include "sfxuno.hxx"

#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XNOTIFYINGDISPATCH_HPP_
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#include <vcl/window.hxx>
#include <limits.h>

using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;

extern void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ); // sfxhelp.cxx

// class HelpInterceptor_Impl --------------------------------------------

HelpInterceptor_Impl::HelpInterceptor_Impl() :

    m_pHistory  ( NULL ),
    m_nCurPos   ( 0 )

{
}

// -----------------------------------------------------------------------

HelpInterceptor_Impl::~HelpInterceptor_Impl()
{
    for ( USHORT i = 0; m_pHistory && i < m_pHistory->Count(); ++i )
        delete m_pHistory->GetObject(i);
    delete m_pHistory;

    if ( m_xIntercepted.is() )
        m_xIntercepted->releaseDispatchProviderInterceptor( (XDispatchProviderInterceptor*)this );
}

// -----------------------------------------------------------------------

Reference< XController > HelpInterceptor_Impl::getController() const throw( RuntimeException )
{
    Reference< XController > xRet;
    if( m_pWindow )
    {
        Reference< XFrame > xFrame = m_pWindow->getTextFrame();
        if( xFrame.is() )
            xRet = xFrame->getController();
    }

    return xRet;
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::addURL( const String& rURL )
{
    if ( !m_pHistory )
        m_pHistory = new HelpHistoryList_Impl;
    ULONG nCount = m_pHistory->Count();
    if ( nCount && m_nCurPos < ( nCount - 1 ) )
    {
        for ( ULONG i = nCount - 1; i > m_nCurPos; i-- )
            delete m_pHistory->Remove(i);
    }
    Reference<XFrame> xFrame(m_xIntercepted, UNO_QUERY);
    Reference<XController> xController;
    if(xFrame.is())
        xController = xFrame->getController();
    Any aViewData;
    if(xController.is() && m_pHistory->Count())
    {
        m_pHistory->GetObject(m_nCurPos)->aViewData = xController->getViewData();
    }

    m_aCurrentURL = rURL;
    m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL ), LIST_APPEND );
    m_nCurPos = m_pHistory->Count() - 1;

    if ( m_xListener.is() )
    {
        ::com::sun::star::frame::FeatureStateEvent aEvent;
        URL aURL;
        aURL.Complete = rURL;
        aEvent.FeatureURL = aURL;
        aEvent.Source = (::com::sun::star::frame::XDispatch*)this;
        m_xListener->statusChanged( aEvent );
    }

    m_pWindow->UpdateToolbox();
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::LeavePage()
{
    if( m_pHistory && m_pHistory->Count() > m_nCurPos)
    {
        // get view position of _current_ URL
        HelpHistoryEntry_Impl* pCurEntry = m_pHistory->GetObject( m_nCurPos );
        try
        {
            Reference< XController > xContr( getController() );
            if( xContr.is() )
                pCurEntry->aViewData = xContr->getViewData();
        }
        catch( const Exception& ) {}
    }
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::setInterception( Reference< XFrame > xFrame )
{
    m_xIntercepted = Reference< XDispatchProviderInterception>( xFrame, UNO_QUERY );

    if ( m_xIntercepted.is() )
        m_xIntercepted->registerDispatchProviderInterceptor( (XDispatchProviderInterceptor*)this );
}

// -----------------------------------------------------------------------

void HelpInterceptor_Impl::SetStartURL( const String& rURL )
{
    DBG_ASSERT( !m_pHistory, "invalid history" );
    if ( !m_pHistory )
    {
        m_pHistory = new HelpHistoryList_Impl;
        m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL ), ((ULONG)0x0) );
        m_nCurPos = m_pHistory->Count() - 1;

        m_pWindow->UpdateToolbox();
    }
    m_aCurrentURL = rURL;
}

// -----------------------------------------------------------------------

sal_Bool HelpInterceptor_Impl::HasHistoryPred() const
{
    return m_pHistory && ( m_nCurPos > 0 );
}

// -----------------------------------------------------------------------

sal_Bool HelpInterceptor_Impl::HasHistorySucc() const
{
    return m_pHistory && ( m_nCurPos < ( m_pHistory->Count() - 1 ) );
}

// -----------------------------------------------------------------------
// XDispatchProvider

Reference< XDispatch > SAL_CALL HelpInterceptor_Impl::queryDispatch(

    const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags )

    throw( RuntimeException )

{
    Reference< XDispatch > xResult;
    if ( m_xSlaveDispatcher.is() )
        xResult = m_xSlaveDispatcher->queryDispatch( aURL, aTargetFrameName, nSearchFlags );

    INetURLObject aObj( aURL.Complete );
    sal_Bool bHelpURL = ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP );
    if ( bHelpURL )
    {
        DBG_ASSERT( xResult.is(), "invalid dispatch" );
        HelpDispatch_Impl* pHelpDispatch = new HelpDispatch_Impl( *this, xResult );
        xResult = Reference< XDispatch >( static_cast< ::cppu::OWeakObject* >(pHelpDispatch), UNO_QUERY );
    }

    return xResult;
}

// -----------------------------------------------------------------------

Sequence < Reference < XDispatch > > SAL_CALL HelpInterceptor_Impl::queryDispatches(

    const Sequence< DispatchDescriptor >& aDescripts )

    throw( RuntimeException )

{
    Sequence< Reference< XDispatch > > aReturn( aDescripts.getLength() );
    Reference< XDispatch >* pReturn = aReturn.getArray();
    const DispatchDescriptor* pDescripts = aDescripts.getConstArray();
    for ( sal_Int16 i = 0; i < aDescripts.getLength(); ++i, ++pReturn, ++pDescripts )
    {
        *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
    }
    return aReturn;
}

// -----------------------------------------------------------------------
// XDispatchProviderInterceptor

Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getSlaveDispatchProvider()

    throw( RuntimeException )

{
    return m_xSlaveDispatcher;
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::setSlaveDispatchProvider( const Reference< XDispatchProvider >& xNewSlave )

    throw( RuntimeException )

{
    m_xSlaveDispatcher = xNewSlave;
}

// -----------------------------------------------------------------------

Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getMasterDispatchProvider()

    throw( RuntimeException )

{
    return m_xMasterDispatcher;
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::setMasterDispatchProvider( const Reference< XDispatchProvider >& xNewMaster )

    throw( RuntimeException )

{
    m_xMasterDispatcher = xNewMaster;
}

// -----------------------------------------------------------------------
// XInterceptorInfo

Sequence< ::rtl::OUString > SAL_CALL HelpInterceptor_Impl::getInterceptedURLs()

    throw( RuntimeException )

{
    Sequence< ::rtl::OUString > aURLList( 1 );
    aURLList[0] = DEFINE_CONST_UNICODE("vnd.sun.star.help://*");
    return aURLList;
}

// -----------------------------------------------------------------------
// XDispatch

void SAL_CALL HelpInterceptor_Impl::dispatch(

    const URL& aURL, const Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) throw( RuntimeException )

{
    sal_Bool bBack = ( String( DEFINE_CONST_UNICODE(".uno:Backward") ) == String( aURL.Complete ) );
    if ( bBack || String( DEFINE_CONST_UNICODE(".uno:Forward") ) == String( aURL.Complete ) )
    {
        if ( m_pHistory )
        {
            LeavePage();       // save current position

            ULONG nPos = ( bBack && m_nCurPos > 0 ) ? --m_nCurPos
                                                    : ( !bBack && m_nCurPos < m_pHistory->Count() - 1 )
                                                    ? ++m_nCurPos
                                                    : ULONG_MAX;

            if ( nPos < ULONG_MAX )
            {
                HelpHistoryEntry_Impl* pEntry = m_pHistory->GetObject( nPos );
                if ( pEntry )
                {
                    URL aURL;
                    aURL.Complete = pEntry->aURL;
                    Reference < XDispatch > xDisp = m_xSlaveDispatcher->queryDispatch( aURL, String(), 0 );
                    if ( xDisp.is() )
                    {
                        if ( m_pOpenListener && m_pWindow )
                        {
                            if ( !m_pWindow->IsWait() )
                                m_pWindow->EnterWait();
                        }
                        m_aCurrentURL = aURL.Complete;
                        m_aViewData = pEntry->aViewData;

                        Reference < XNotifyingDispatch > xNotifyingDisp( xDisp, UNO_QUERY );
                        if ( xNotifyingDisp.is() )
                        {
                            OpenStatusListener_Impl* pListener = (OpenStatusListener_Impl*)m_pWindow->getOpenListener().get();
                            DBG_ASSERT( pListener, "invalid XDispatchResultListener" );
                            pListener->SetURL( aURL.Complete );
                            xNotifyingDisp->dispatchWithNotification( aURL, Sequence < PropertyValue >(), pListener );
                        }
                    }
                }
            }

            m_pWindow->UpdateToolbox();
        }
    }
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::addStatusListener(

    const Reference< XStatusListener >& xControl, const URL& aURL ) throw( RuntimeException )

{
    DBG_ASSERT( !m_xListener.is(), "listener already exists" );
    m_xListener = xControl;
}

// -----------------------------------------------------------------------

void SAL_CALL HelpInterceptor_Impl::removeStatusListener(

    const Reference< XStatusListener >& xControl, const URL& aURL ) throw( RuntimeException )

{
    m_xListener = 0;
}

// HelpListener_Impl -----------------------------------------------------

HelpListener_Impl::HelpListener_Impl( HelpInterceptor_Impl* pInter )
{
    pInterceptor = pInter;
    pInterceptor->addStatusListener( this, ::com::sun::star::util::URL() );
}

// -----------------------------------------------------------------------

void SAL_CALL HelpListener_Impl::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event )

    throw( ::com::sun::star::uno::RuntimeException )

{
    INetURLObject aObj( Event.FeatureURL.Complete );
    aFactory = aObj.GetHost();
    aChangeLink.Call( this );
}

// -----------------------------------------------------------------------

void SAL_CALL HelpListener_Impl::disposing( const ::com::sun::star::lang::EventObject& obj )

    throw( ::com::sun::star::uno::RuntimeException )

{
    pInterceptor->removeStatusListener( this, ::com::sun::star::util::URL() );
    pInterceptor = NULL;
}
/*-- 05.09.2002 12:17:59---------------------------------------------------

  -----------------------------------------------------------------------*/
HelpStatusListener_Impl::HelpStatusListener_Impl(
        Reference < XDispatch > xDispatch, URL& rURL)
{
    xDispatch->addStatusListener(this, rURL);
}
/*-- 05.09.2002 12:17:59---------------------------------------------------

  -----------------------------------------------------------------------*/
HelpStatusListener_Impl::~HelpStatusListener_Impl()
{
    if(xDispatch.is())
        xDispatch->removeStatusListener(this, com::sun::star::util::URL());
}
/*-- 05.09.2002 12:17:59---------------------------------------------------

  -----------------------------------------------------------------------*/
void HelpStatusListener_Impl::statusChanged(
    const FeatureStateEvent& rEvent ) throw( RuntimeException )
{
    aStateEvent = rEvent;
}
/*-- 05.09.2002 12:18:00---------------------------------------------------

  -----------------------------------------------------------------------*/
void HelpStatusListener_Impl::disposing( const EventObject& obj ) throw( RuntimeException )
{
    xDispatch->removeStatusListener(this, com::sun::star::util::URL());
    xDispatch = 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010-2011 Dmitry Marakasov
 *
 * This file is part of glosm.
 *
 * glosm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glosm 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glosm.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <err.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#if defined(__APPLE__)
#	include <OpenGL/gl.h>
#	include <GLUT/glut.h>
#else
#	include <GL/gl.h>
#	include <GL/glut.h>
#endif

#include <vector>
#include <map>

#include <glosm/Math.hh>

#include <glosm/MercatorProjection.hh>
#include <glosm/PreloadedXmlDatasource.hh>
#include <glosm/DefaultGeometryGenerator.hh>
#include <glosm/FirstPersonViewer.hh>
#include <glosm/GeometryLayer.hh>

/* as glut has no OO concept and no feature like setUserData,
 * please forgive me using global variables pointing to
 * stack data for now */
FirstPersonViewer viewer;
GeometryLayer* layer_p = NULL;

int screenw = 1;
int screenh = 1;
int movementflags = 0;
float speed = 200.0f;
int lockheight = 0;

struct timeval prevtime, curtime, fpstime;
int nframes = 0;

void Display(void) {
	/* update scene */
	gettimeofday(&curtime, NULL);
	float dt = (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f;

	/* render frame */
	glClearColor(0.5, 0.5, 0.5, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (layer_p) {
		int radius = 100000;
		layer_p->RequestVisible(BBoxi(viewer.GetPos(MercatorProjection()) - Vector2i(radius, radius), viewer.GetPos(MercatorProjection()) + Vector2i(radius, radius)), true);
		layer_p->GarbageCollect();
		layer_p->Render(viewer);
	}

	glFlush();
	glutSwapBuffers();

	/* movement */
	if (movementflags) {
		float myspeed = speed;
		float height = viewer.MutablePos().z / 1000.0;

		if (height > 100.0 && height < 100000.0)
			myspeed *= height / 100.0;
		else if (height >= 100000.0)
			myspeed *= 1000.0;

		viewer.Move(movementflags, myspeed, dt);
	}
	if (lockheight != 0)
		viewer.MutablePos().z = lockheight;

	/* update FPS */
	float fpst = (float)(curtime.tv_sec - fpstime.tv_sec) + (float)(curtime.tv_usec - fpstime.tv_usec)/1000000.0f;

	if (fpst > 10.0) {
		fprintf(stderr, "FPS: %.3f\n", (float)nframes/fpst);
		fpstime = curtime;
		nframes = 0;
	}

	prevtime = curtime;
	nframes++;

	/* frame limiter */
	usleep(10000);
}

void Reshape(int w, int h) {
	if (w <= 0)
		w = 1;
	if (h <= 0)
		h = 1;

	screenw = w;
	screenh = h;

	float wanted_fov = 70.0f/180.0f*M_PI;
	float wanted_aspect = 4.0f/3.0f;

	float fov, aspect;

	if ((float)w/(float)h > wanted_aspect) { // wider than wanted
		fov = wanted_fov;
	} else { // narrower than wanted
		float wanted_h = (float)w/wanted_aspect;
		fov = 2.0f*atanf((float)h / wanted_h * tanf(wanted_fov/2.0f));
	}
	fov = wanted_fov;
	aspect = (float)w/(float)h;

	glViewport(0, 0, w, h);

	viewer.SetFov(fov);
	viewer.SetAspect(aspect);

	glutWarpPointer(screenw/2, screenh/2);
}

void Mouse(int x, int y) {
	int dx = x - screenw/2;
	int dy = y - screenh/2;

	float YawDelta = (float)dx / 500.0;
	float PitchDelta = -(float)dy / 500.0;

	viewer.HardRotate(YawDelta, PitchDelta);

	if (dx != 0 || dy != 0)
		glutWarpPointer(screenw/2, screenh/2);
}

void SpecialDown(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags |= FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags |= FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags |= FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags |= FirstPersonViewer::RIGHT; break;
	default:
		  break;
	}
}

void SpecialUp(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags &= ~FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags &= ~FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags &= ~FirstPersonViewer::RIGHT; break;
	default:
		  break;
	}
}

void KeyDown(unsigned char key, int, int) {
	switch (key) {
	case 27: case 'q': exit(0); break;
	case 'w': movementflags |= FirstPersonViewer::FORWARD; break;
	case 's': movementflags |= FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags |= FirstPersonViewer::LEFT; break;
	case 'd': movementflags |= FirstPersonViewer::RIGHT; break;
	case 'c': movementflags |= FirstPersonViewer::LOWER; break;
	case ' ': movementflags |= FirstPersonViewer::HIGHER; break;
	case 'l': lockheight = (lockheight == 0 ? viewer.MutablePos().z : 0); break;
	case 'h': lockheight = (lockheight == 0 ? 1750 : 0); break;
	case '+': speed *= 5.0f; break;
	case '-': speed /= 5.0f; break;
	default:
		  break;
	}
}

void KeyUp(unsigned char key, int, int) {
	switch (key) {
	case 'w': movementflags &= ~FirstPersonViewer::FORWARD; break;
	case 's': movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags &= ~FirstPersonViewer::LEFT; break;
	case 'd': movementflags &= ~FirstPersonViewer::RIGHT; break;
	case 'c': movementflags &= ~FirstPersonViewer::LOWER; break;
	case ' ': movementflags &= ~FirstPersonViewer::HIGHER; break;
	default:
		  break;
	}
}

int real_main(int argc, char** argv) {
	glutInit(&argc, argv);

	if (argc != 2)
		errx(1, "Usage: %s file.osm", argv[0]);

	/* load data */
	fprintf(stderr, "Loading...\n");
	PreloadedXmlDatasource osm_datasource;
	gettimeofday(&prevtime, NULL);
	osm_datasource.Load(argv[1]);
	gettimeofday(&curtime, NULL);
	fprintf(stderr, "Loaded XML in %.3f seconds\n", (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f);
	prevtime = curtime;
	fpstime = curtime;

	/* glut init */
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
	glutInitWindowSize(800, 600);
	glutCreateWindow("glosm viewer");

	glutIgnoreKeyRepeat(1);
	glutSetCursor(GLUT_CURSOR_NONE);

	glutDisplayFunc(Display);
	glutIdleFunc(Display);
	glutReshapeFunc(Reshape);
	glutPassiveMotionFunc(Mouse);
	glutKeyboardFunc(KeyDown);
	glutKeyboardUpFunc(KeyUp);
	glutSpecialFunc(SpecialDown);
	glutSpecialUpFunc(SpecialUp);

	/* glosm init */
	DefaultGeometryGenerator geometry_generator(osm_datasource);
	GeometryLayer layer(MercatorProjection(), geometry_generator);
	layer_p = &layer;

	int height = fabs((float)geometry_generator.GetBBox().top -  (float)geometry_generator.GetBBox().bottom)/3600000000.0*40000000.0/10.0*1000.0;
	viewer.SetPos(Vector3i(geometry_generator.GetCenter(), height));

	/* main loop */
	/* note that this never returns and objects created above
	 * are never properly destroyed; should dump GLUT ASAP */
	glutMainLoop();

	return 0;
}

int main(int argc, char** argv) {
	try {
		return real_main(argc, argv);
	} catch (std::exception &e) {
		fprintf(stderr, "Exception: %s\n", e.what());
	} catch (...) {
		fprintf(stderr, "Unknown exception\n");
	}

	return 1;
}
<commit_msg>Expand view radius, enable async loading<commit_after>/*
 * Copyright (C) 2010-2011 Dmitry Marakasov
 *
 * This file is part of glosm.
 *
 * glosm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glosm 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glosm.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <err.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#if defined(__APPLE__)
#	include <OpenGL/gl.h>
#	include <GLUT/glut.h>
#else
#	include <GL/gl.h>
#	include <GL/glut.h>
#endif

#include <vector>
#include <map>

#include <glosm/Math.hh>

#include <glosm/MercatorProjection.hh>
#include <glosm/PreloadedXmlDatasource.hh>
#include <glosm/DefaultGeometryGenerator.hh>
#include <glosm/FirstPersonViewer.hh>
#include <glosm/GeometryLayer.hh>

/* as glut has no OO concept and no feature like setUserData,
 * please forgive me using global variables pointing to
 * stack data for now */
FirstPersonViewer viewer;
GeometryLayer* layer_p = NULL;

int screenw = 1;
int screenh = 1;
int movementflags = 0;
float speed = 200.0f;
int lockheight = 0;

struct timeval prevtime, curtime, fpstime;
int nframes = 0;

void Display(void) {
	/* update scene */
	gettimeofday(&curtime, NULL);
	float dt = (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f;

	/* render frame */
	glClearColor(0.5, 0.5, 0.5, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (layer_p) {
		int radius = 50000000;
		layer_p->RequestVisible(BBoxi(viewer.GetPos(MercatorProjection()) - Vector2i(radius, radius), viewer.GetPos(MercatorProjection()) + Vector2i(radius, radius)), false);
		layer_p->GarbageCollect();
		layer_p->Render(viewer);
	}

	glFlush();
	glutSwapBuffers();

	/* movement */
	if (movementflags) {
		float myspeed = speed;
		float height = viewer.MutablePos().z / 1000.0;

		if (height > 100.0 && height < 100000.0)
			myspeed *= height / 100.0;
		else if (height >= 100000.0)
			myspeed *= 1000.0;

		viewer.Move(movementflags, myspeed, dt);
	}
	if (lockheight != 0)
		viewer.MutablePos().z = lockheight;

	/* update FPS */
	float fpst = (float)(curtime.tv_sec - fpstime.tv_sec) + (float)(curtime.tv_usec - fpstime.tv_usec)/1000000.0f;

	if (fpst > 10.0) {
		fprintf(stderr, "FPS: %.3f\n", (float)nframes/fpst);
		fpstime = curtime;
		nframes = 0;
	}

	prevtime = curtime;
	nframes++;

	/* frame limiter */
	usleep(10000);
}

void Reshape(int w, int h) {
	if (w <= 0)
		w = 1;
	if (h <= 0)
		h = 1;

	screenw = w;
	screenh = h;

	float wanted_fov = 70.0f/180.0f*M_PI;
	float wanted_aspect = 4.0f/3.0f;

	float fov, aspect;

	if ((float)w/(float)h > wanted_aspect) { // wider than wanted
		fov = wanted_fov;
	} else { // narrower than wanted
		float wanted_h = (float)w/wanted_aspect;
		fov = 2.0f*atanf((float)h / wanted_h * tanf(wanted_fov/2.0f));
	}
	fov = wanted_fov;
	aspect = (float)w/(float)h;

	glViewport(0, 0, w, h);

	viewer.SetFov(fov);
	viewer.SetAspect(aspect);

	glutWarpPointer(screenw/2, screenh/2);
}

void Mouse(int x, int y) {
	int dx = x - screenw/2;
	int dy = y - screenh/2;

	float YawDelta = (float)dx / 500.0;
	float PitchDelta = -(float)dy / 500.0;

	viewer.HardRotate(YawDelta, PitchDelta);

	if (dx != 0 || dy != 0)
		glutWarpPointer(screenw/2, screenh/2);
}

void SpecialDown(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags |= FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags |= FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags |= FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags |= FirstPersonViewer::RIGHT; break;
	default:
		  break;
	}
}

void SpecialUp(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags &= ~FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags &= ~FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags &= ~FirstPersonViewer::RIGHT; break;
	default:
		  break;
	}
}

void KeyDown(unsigned char key, int, int) {
	switch (key) {
	case 27: case 'q': exit(0); break;
	case 'w': movementflags |= FirstPersonViewer::FORWARD; break;
	case 's': movementflags |= FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags |= FirstPersonViewer::LEFT; break;
	case 'd': movementflags |= FirstPersonViewer::RIGHT; break;
	case 'c': movementflags |= FirstPersonViewer::LOWER; break;
	case ' ': movementflags |= FirstPersonViewer::HIGHER; break;
	case 'l': lockheight = (lockheight == 0 ? viewer.MutablePos().z : 0); break;
	case 'h': lockheight = (lockheight == 0 ? 1750 : 0); break;
	case '+': speed *= 5.0f; break;
	case '-': speed /= 5.0f; break;
	default:
		  break;
	}
}

void KeyUp(unsigned char key, int, int) {
	switch (key) {
	case 'w': movementflags &= ~FirstPersonViewer::FORWARD; break;
	case 's': movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags &= ~FirstPersonViewer::LEFT; break;
	case 'd': movementflags &= ~FirstPersonViewer::RIGHT; break;
	case 'c': movementflags &= ~FirstPersonViewer::LOWER; break;
	case ' ': movementflags &= ~FirstPersonViewer::HIGHER; break;
	default:
		  break;
	}
}

int real_main(int argc, char** argv) {
	glutInit(&argc, argv);

	if (argc != 2)
		errx(1, "Usage: %s file.osm", argv[0]);

	/* load data */
	fprintf(stderr, "Loading...\n");
	PreloadedXmlDatasource osm_datasource;
	gettimeofday(&prevtime, NULL);
	osm_datasource.Load(argv[1]);
	gettimeofday(&curtime, NULL);
	fprintf(stderr, "Loaded XML in %.3f seconds\n", (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f);
	prevtime = curtime;
	fpstime = curtime;

	/* glut init */
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
	glutInitWindowSize(800, 600);
	glutCreateWindow("glosm viewer");

	glutIgnoreKeyRepeat(1);
	glutSetCursor(GLUT_CURSOR_NONE);

	glutDisplayFunc(Display);
	glutIdleFunc(Display);
	glutReshapeFunc(Reshape);
	glutPassiveMotionFunc(Mouse);
	glutKeyboardFunc(KeyDown);
	glutKeyboardUpFunc(KeyUp);
	glutSpecialFunc(SpecialDown);
	glutSpecialUpFunc(SpecialUp);

	/* glosm init */
	DefaultGeometryGenerator geometry_generator(osm_datasource);
	GeometryLayer layer(MercatorProjection(), geometry_generator);
	layer_p = &layer;

	int height = fabs((float)geometry_generator.GetBBox().top -  (float)geometry_generator.GetBBox().bottom)/3600000000.0*40000000.0/10.0*1000.0;
	viewer.SetPos(Vector3i(geometry_generator.GetCenter(), height));

	/* main loop */
	/* note that this never returns and objects created above
	 * are never properly destroyed; should dump GLUT ASAP */
	glutMainLoop();

	return 0;
}

int main(int argc, char** argv) {
	try {
		return real_main(argc, argv);
	} catch (std::exception &e) {
		fprintf(stderr, "Exception: %s\n", e.what());
	} catch (...) {
		fprintf(stderr, "Unknown exception\n");
	}

	return 1;
}
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2019, Mike Dunston
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Can.hxx
 *
 * ESP32 adapter code using the WiFiClient provided by the WiFiServer code
 * for interfacing with the OpenMRN stack.
 *
 * @author Mike Dunston
 * @date 13 January 2019
 */

// This include is exclusive against freertos_drivers/common/Can.hxx
#ifndef _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_
#define _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_

#include <Arduino.h>
#include <WiFi.h>

class Esp32WiFiClientAdapter {
public:
    WiFiClientAdapter(WiFiClient client) : client_(client){
        client_.setNoDelay(true);
    }
    // on the ESP32 there is no TX limit method
    size_t availableForWrite() {
        return client_.connected();
    }
    size_t write(const char *buffer, size_t len) {
        if(client_.connected()) {
            return client_.write(buffer, len);
        }
        return 0;
    }
    size_t available() {
        if(client_.connected()) {
            return client_.available();
        }
        return 0;
    }
    size_t read(const char *buffer, size_t len) {
        size_t bytesRead = 0;
        if(client_.connected()) {
            bytesRead = client_.read((uint8_t *)buffer, len);
        }
        return bytesRead;
    }
private:
    WiFiClient client_;
};

#endif /* _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_ */<commit_msg>fix comment<commit_after>/** \copyright
 * Copyright (c) 2019, Mike Dunston
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Can.hxx
 *
 * ESP32 adapter code using the WiFiClient provided by the WiFiServer code
 * for interfacing with the OpenMRN stack.
 *
 * @author Mike Dunston
 * @date 13 January 2019
 */

// This include is exclusive against freertos_drivers/arduino/Esp32WiFiClientAdapter.hxx
#ifndef _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_
#define _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_

#include <Arduino.h>
#include <WiFi.h>

class Esp32WiFiClientAdapter {
public:
    WiFiClientAdapter(WiFiClient client) : client_(client){
        client_.setNoDelay(true);
    }
    // on the ESP32 there is no TX limit method
    size_t availableForWrite() {
        return client_.connected();
    }
    size_t write(const char *buffer, size_t len) {
        if(client_.connected()) {
            return client_.write(buffer, len);
        }
        return 0;
    }
    size_t available() {
        if(client_.connected()) {
            return client_.available();
        }
        return 0;
    }
    size_t read(const char *buffer, size_t len) {
        size_t bytesRead = 0;
        if(client_.connected()) {
            bytesRead = client_.read((uint8_t *)buffer, len);
        }
        return bytesRead;
    }
private:
    WiFiClient client_;
};

#endif /* _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_ */<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2019, Mike Dunston
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Esp32WiFiClientAdapter.hxx
 *
 * ESP32 adapter code using the WiFiClient provided by the WiFiServer code
 * for interfacing with the OpenMRN stack.
 *
 * @author Mike Dunston
 * @date 13 January 2019
 */

#ifndef _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_
#define _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_

#include <Arduino.h>
#include <WiFi.h>

class Esp32WiFiClientAdapter {
public:
    Esp32WiFiClientAdapter(WiFiClient client) : client_(client){
        client_.setNoDelay(true);
    }

    /// This is how many bytes we return as writeable when select says the
    /// socket is write active.
    static constexpr unsigned WRITE_PACKET_SIZE = 512;

    // on the ESP32 there is no TX limit method
    size_t availableForWrite()
    {
        if (!client_.connected())
        {
            return 0;
        }
        int fd = client_.fd();
        fd_set set;
        struct timeval tv;
        FD_ZERO(&set);    // empties the set
        FD_SET(fd, &set); // adds FD to the set
        tv.tv_sec = 0;
        tv.tv_usec = 0;

        if (select(fd + 1, NULL, &set, NULL, &tv) < 0)
        {
            return 0;
        }

        if (FD_ISSET(fd, &set))
        {
            return 500;
        }
        else
        {
            return 0;
        }
    }

    size_t write(const char *buffer, size_t len)
    {
        if(client_.connected()) {
            size_t r = client_.write(buffer, len);
            LOG(INFO, "w%u", len, r);
            return r;
        }
        return 0;
    }
    size_t available() {
        if(client_.connected()) {
            return client_.available();
        }
        return 0;
    }
    size_t read(const char *buffer, size_t len) {
        size_t bytesRead = 0;
        if(client_.connected()) {
            bytesRead = client_.read((uint8_t *)buffer, len);
        }
        return bytesRead;
    }
private:
    WiFiClient client_;
};

#endif /* _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_ */
<commit_msg>remove unnecessary log.<commit_after>/** \copyright
 * Copyright (c) 2019, Mike Dunston
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Esp32WiFiClientAdapter.hxx
 *
 * ESP32 adapter code using the WiFiClient provided by the WiFiServer code
 * for interfacing with the OpenMRN stack.
 *
 * @author Mike Dunston
 * @date 13 January 2019
 */

#ifndef _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_
#define _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_

#include <Arduino.h>
#include <WiFi.h>

class Esp32WiFiClientAdapter {
public:
    Esp32WiFiClientAdapter(WiFiClient client) : client_(client){
        client_.setNoDelay(true);
    }

    /// This is how many bytes we return as writeable when select says the
    /// socket is write active.
    static constexpr unsigned WRITE_PACKET_SIZE = 512;

    // on the ESP32 there is no TX limit method
    size_t availableForWrite()
    {
        if (!client_.connected())
        {
            return 0;
        }
        int fd = client_.fd();
        fd_set set;
        struct timeval tv;
        FD_ZERO(&set);    // empties the set
        FD_SET(fd, &set); // adds FD to the set
        tv.tv_sec = 0;
        tv.tv_usec = 0;

        if (select(fd + 1, NULL, &set, NULL, &tv) < 0)
        {
            return 0;
        }

        if (FD_ISSET(fd, &set))
        {
            return 500;
        }
        else
        {
            return 0;
        }
    }

    size_t write(const char *buffer, size_t len)
    {
        if(client_.connected()) {
            return client_.write(buffer, len);
        }
        return 0;
    }
    size_t available() {
        if(client_.connected()) {
            return client_.available();
        }
        return 0;
    }
    size_t read(const char *buffer, size_t len) {
        size_t bytesRead = 0;
        if(client_.connected()) {
            bytesRead = client_.read((uint8_t *)buffer, len);
        }
        return bytesRead;
    }
private:
    WiFiClient client_;
};

#endif /* _FREERTOS_DRIVERS_ARDUINO_ESP32WIFI_HXX_ */
<|endoftext|>


<commit_before>/*
 * Copyright 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "alternator/error.hh"
#include "log.hh"
#include <string>
#include <string_view>
#include <gnutls/crypto.h>
#include <seastar/util/defer.hh>
#include "hashers.hh"
#include "bytes.hh"
#include "alternator/auth.hh"
#include <fmt/format.h>
#include "auth/common.hh"
#include "auth/password_authenticator.hh"
#include "auth/roles-metadata.hh"
#include "cql3/query_processor.hh"
#include "cql3/untyped_result_set.hh"

namespace alternator {

static logging::logger alogger("alternator-auth");

static hmac_sha256_digest hmac_sha256(std::string_view key, std::string_view msg) {
    hmac_sha256_digest digest;
    int ret = gnutls_hmac_fast(GNUTLS_MAC_SHA256, key.data(), key.size(), msg.data(), msg.size(), digest.data());
    if (ret) {
        throw std::runtime_error(fmt::format("Computing HMAC failed ({}): {}", ret, gnutls_strerror(ret)));
    }
    return digest;
}

static hmac_sha256_digest get_signature_key(std::string_view key, std::string_view date_stamp, std::string_view region_name, std::string_view service_name) {
    auto date = hmac_sha256("AWS4" + std::string(key), date_stamp);
    auto region = hmac_sha256(std::string_view(date.data(), date.size()), region_name);
    auto service = hmac_sha256(std::string_view(region.data(), region.size()), service_name);
    auto signing = hmac_sha256(std::string_view(service.data(), service.size()), "aws4_request");
    return signing;
}

static std::string apply_sha256(std::string_view msg) {
    sha256_hasher hasher;
    hasher.update(msg.data(), msg.size());
    return to_hex(hasher.finalize());
}

static std::string format_time_point(db_clock::time_point tp) {
    time_t time_point_repr = db_clock::to_time_t(tp);
    std::string time_point_str;
    time_point_str.resize(17);
    ::tm time_buf;
    // strftime prints the terminating null character as well
    std::strftime(time_point_str.data(), time_point_str.size(), "%Y%m%dT%H%M%SZ", ::gmtime_r(&time_point_repr, &time_buf));
    time_point_str.resize(16);
    return time_point_str;
}

void check_expiry(std::string_view signature_date) {
    //FIXME: The default 15min can be changed with X-Amz-Expires header - we should honor it
    std::string expiration_str = format_time_point(db_clock::now() - 15min);
    std::string validity_str = format_time_point(db_clock::now() + 15min);
    if (signature_date < expiration_str) {
        throw api_error("InvalidSignatureException",
                fmt::format("Signature expired: {} is now earlier than {} (current time - 15 min.)",
                signature_date, expiration_str));
    }
    if (signature_date > validity_str) {
        throw api_error("InvalidSignatureException",
                fmt::format("Signature not yet current: {} is still later than {} (current time + 15 min.)",
                signature_date, validity_str));
    }
}

std::string get_signature(std::string_view access_key_id, std::string_view secret_access_key, std::string_view host, std::string_view method,
        std::string_view orig_datestamp, std::string_view signed_headers_str, const std::map<std::string_view, std::string_view>& signed_headers_map,
        std::string_view body_content, std::string_view region, std::string_view service, std::string_view query_string) {
    auto amz_date_it = signed_headers_map.find("x-amz-date");
    if (amz_date_it == signed_headers_map.end()) {
        throw api_error("InvalidSignatureException", "X-Amz-Date header is mandatory for signature verification");
    }
    std::string_view amz_date = amz_date_it->second;
    check_expiry(amz_date);
    std::string_view datestamp = amz_date.substr(0, 8);
    if (datestamp != orig_datestamp) {
        throw api_error("InvalidSignatureException",
                format("X-Amz-Date date does not match the provided datestamp. Expected {}, got {}",
                        orig_datestamp, datestamp));
    }
    std::string_view canonical_uri = "/";

    std::stringstream canonical_headers;
    for (const auto& header : signed_headers_map) {
        canonical_headers << fmt::format("{}:{}", header.first, header.second) << '\n';
    }

    std::string payload_hash = apply_sha256(body_content);
    std::string canonical_request = fmt::format("{}\n{}\n{}\n{}\n{}\n{}", method, canonical_uri, query_string, canonical_headers.str(), signed_headers_str, payload_hash);

    std::string_view algorithm = "AWS4-HMAC-SHA256";
    std::string credential_scope = fmt::format("{}/{}/{}/aws4_request", datestamp, region, service);
    std::string string_to_sign = fmt::format("{}\n{}\n{}\n{}", algorithm, amz_date, credential_scope,  apply_sha256(canonical_request));

    hmac_sha256_digest signing_key = get_signature_key(secret_access_key, datestamp, region, service);
    hmac_sha256_digest signature = hmac_sha256(std::string_view(signing_key.data(), signing_key.size()), string_to_sign);

    return to_hex(bytes_view(reinterpret_cast<const int8_t*>(signature.data()), signature.size()));
}

future<std::string> get_key_from_roles(cql3::query_processor& qp, std::string username) {
    static const sstring query = format("SELECT salted_hash FROM {} WHERE {} = ?",
            auth::meta::roles_table::qualified_name(), auth::meta::roles_table::role_col_name);

    auto cl = auth::password_authenticator::consistency_for_user(username);
    auto& timeout = auth::internal_distributed_timeout_config();
    return qp.execute_internal(query, cl, timeout, {sstring(username)}, true).then_wrapped([username = std::move(username)] (future<::shared_ptr<cql3::untyped_result_set>> f) {
        auto res = f.get0();
        auto salted_hash = std::optional<sstring>();
        if (res->empty()) {
            throw api_error("UnrecognizedClientException", fmt::format("User not found: {}", username));
        }
        salted_hash = res->one().get_opt<sstring>("salted_hash");
        if (!salted_hash) {
            throw api_error("UnrecognizedClientException", fmt::format("No password found for user: {}", username));
        }
        return make_ready_future<std::string>(*salted_hash);
    });
}

}
<commit_msg>alternator: use api_error factory functions in auth.cc<commit_after>/*
 * Copyright 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "alternator/error.hh"
#include "log.hh"
#include <string>
#include <string_view>
#include <gnutls/crypto.h>
#include <seastar/util/defer.hh>
#include "hashers.hh"
#include "bytes.hh"
#include "alternator/auth.hh"
#include <fmt/format.h>
#include "auth/common.hh"
#include "auth/password_authenticator.hh"
#include "auth/roles-metadata.hh"
#include "cql3/query_processor.hh"
#include "cql3/untyped_result_set.hh"

namespace alternator {

static logging::logger alogger("alternator-auth");

static hmac_sha256_digest hmac_sha256(std::string_view key, std::string_view msg) {
    hmac_sha256_digest digest;
    int ret = gnutls_hmac_fast(GNUTLS_MAC_SHA256, key.data(), key.size(), msg.data(), msg.size(), digest.data());
    if (ret) {
        throw std::runtime_error(fmt::format("Computing HMAC failed ({}): {}", ret, gnutls_strerror(ret)));
    }
    return digest;
}

static hmac_sha256_digest get_signature_key(std::string_view key, std::string_view date_stamp, std::string_view region_name, std::string_view service_name) {
    auto date = hmac_sha256("AWS4" + std::string(key), date_stamp);
    auto region = hmac_sha256(std::string_view(date.data(), date.size()), region_name);
    auto service = hmac_sha256(std::string_view(region.data(), region.size()), service_name);
    auto signing = hmac_sha256(std::string_view(service.data(), service.size()), "aws4_request");
    return signing;
}

static std::string apply_sha256(std::string_view msg) {
    sha256_hasher hasher;
    hasher.update(msg.data(), msg.size());
    return to_hex(hasher.finalize());
}

static std::string format_time_point(db_clock::time_point tp) {
    time_t time_point_repr = db_clock::to_time_t(tp);
    std::string time_point_str;
    time_point_str.resize(17);
    ::tm time_buf;
    // strftime prints the terminating null character as well
    std::strftime(time_point_str.data(), time_point_str.size(), "%Y%m%dT%H%M%SZ", ::gmtime_r(&time_point_repr, &time_buf));
    time_point_str.resize(16);
    return time_point_str;
}

void check_expiry(std::string_view signature_date) {
    //FIXME: The default 15min can be changed with X-Amz-Expires header - we should honor it
    std::string expiration_str = format_time_point(db_clock::now() - 15min);
    std::string validity_str = format_time_point(db_clock::now() + 15min);
    if (signature_date < expiration_str) {
        throw api_error::invalid_signature(
                fmt::format("Signature expired: {} is now earlier than {} (current time - 15 min.)",
                signature_date, expiration_str));
    }
    if (signature_date > validity_str) {
        throw api_error::invalid_signature(
                fmt::format("Signature not yet current: {} is still later than {} (current time + 15 min.)",
                signature_date, validity_str));
    }
}

std::string get_signature(std::string_view access_key_id, std::string_view secret_access_key, std::string_view host, std::string_view method,
        std::string_view orig_datestamp, std::string_view signed_headers_str, const std::map<std::string_view, std::string_view>& signed_headers_map,
        std::string_view body_content, std::string_view region, std::string_view service, std::string_view query_string) {
    auto amz_date_it = signed_headers_map.find("x-amz-date");
    if (amz_date_it == signed_headers_map.end()) {
        throw api_error::invalid_signature("X-Amz-Date header is mandatory for signature verification");
    }
    std::string_view amz_date = amz_date_it->second;
    check_expiry(amz_date);
    std::string_view datestamp = amz_date.substr(0, 8);
    if (datestamp != orig_datestamp) {
        throw api_error::invalid_signature(
                format("X-Amz-Date date does not match the provided datestamp. Expected {}, got {}",
                        orig_datestamp, datestamp));
    }
    std::string_view canonical_uri = "/";

    std::stringstream canonical_headers;
    for (const auto& header : signed_headers_map) {
        canonical_headers << fmt::format("{}:{}", header.first, header.second) << '\n';
    }

    std::string payload_hash = apply_sha256(body_content);
    std::string canonical_request = fmt::format("{}\n{}\n{}\n{}\n{}\n{}", method, canonical_uri, query_string, canonical_headers.str(), signed_headers_str, payload_hash);

    std::string_view algorithm = "AWS4-HMAC-SHA256";
    std::string credential_scope = fmt::format("{}/{}/{}/aws4_request", datestamp, region, service);
    std::string string_to_sign = fmt::format("{}\n{}\n{}\n{}", algorithm, amz_date, credential_scope,  apply_sha256(canonical_request));

    hmac_sha256_digest signing_key = get_signature_key(secret_access_key, datestamp, region, service);
    hmac_sha256_digest signature = hmac_sha256(std::string_view(signing_key.data(), signing_key.size()), string_to_sign);

    return to_hex(bytes_view(reinterpret_cast<const int8_t*>(signature.data()), signature.size()));
}

future<std::string> get_key_from_roles(cql3::query_processor& qp, std::string username) {
    static const sstring query = format("SELECT salted_hash FROM {} WHERE {} = ?",
            auth::meta::roles_table::qualified_name(), auth::meta::roles_table::role_col_name);

    auto cl = auth::password_authenticator::consistency_for_user(username);
    auto& timeout = auth::internal_distributed_timeout_config();
    return qp.execute_internal(query, cl, timeout, {sstring(username)}, true).then_wrapped([username = std::move(username)] (future<::shared_ptr<cql3::untyped_result_set>> f) {
        auto res = f.get0();
        auto salted_hash = std::optional<sstring>();
        if (res->empty()) {
            throw api_error::unrecognized_client(fmt::format("User not found: {}", username));
        }
        salted_hash = res->one().get_opt<sstring>("salted_hash");
        if (!salted_hash) {
            throw api_error::unrecognized_client(fmt::format("No password found for user: {}", username));
        }
        return make_ready_future<std::string>(*salted_hash);
    });
}

}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 metaverse developers (see AUTHORS)
 *
 * This file is part of mvs-node.
 *
 * metaverse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/bitcoin/chain/attachment/asset/asset_detail.hpp>

#include <sstream>
#include <boost/iostreams/stream.hpp>
#include <metaverse/bitcoin/utility/container_sink.hpp>
#include <metaverse/bitcoin/utility/container_source.hpp>
#include <metaverse/bitcoin/utility/istream_reader.hpp>
#include <metaverse/bitcoin/utility/ostream_writer.hpp>
#include <json/minijson_writer.hpp>

namespace libbitcoin {
namespace chain {

asset_detail::asset_detail()
{
    reset();
}

asset_detail::asset_detail(
    std::string symbol, uint64_t maximum_supply,
    uint8_t decimal_number, uint8_t threshold, std::string issuer,
    std::string address, std::string description):
    symbol(symbol), maximum_supply(maximum_supply),
    decimal_number(decimal_number),
    secondaryissue_threshold(threshold),
    unused2(0), unused3(0),
    issuer(issuer), address(address), description(description)
{
}

asset_detail asset_detail::factory_from_data(const data_chunk& data)
{
    asset_detail instance;
    instance.from_data(data);
    return instance;
}

asset_detail asset_detail::factory_from_data(std::istream& stream)
{
    asset_detail instance;
    instance.from_data(stream);
    return instance;
}

asset_detail asset_detail::factory_from_data(reader& source)
{
    asset_detail instance;
    instance.from_data(source);
    return instance;
}

bool asset_detail::is_valid() const
{
    return !(symbol.empty()
            || (maximum_supply==0)
            || (symbol.size() + 8 + 4 + issuer.size() + address.size() + description.size() + 4)>ASSET_DETAIL_FIX_SIZE);
}

void asset_detail::reset()
{
    symbol = "";
    maximum_supply = 0;
    decimal_number = 0;
    secondaryissue_threshold = 0;
    unused2 = 0;
    unused3 = 0;
    issuer = "";
    address = "";
    description = "";
}

bool asset_detail::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}

bool asset_detail::from_data(std::istream& stream)
{
    istream_reader source(stream);
    return from_data(source);
}

bool asset_detail::from_data(reader& source)
{
    reset();

    symbol = source.read_string();
    maximum_supply = source.read_8_bytes_little_endian();
    decimal_number = source.read_byte();
    secondaryissue_threshold = source.read_byte();
    uint8_t byte_num = source.read_byte();
    unused2 = source.read_byte();
    unused3 = source.read_byte();
    issuer = source.read_string();
    address =  source.read_string();
    description =  source.read_string();

    auto result = static_cast<bool>(source);
    if (!result)
        reset();

    return result;
}

data_chunk asset_detail::to_data() const
{
    data_chunk data;
    data_sink ostream(data);
    to_data(ostream);
    ostream.flush();
    return data;
}

void asset_detail::to_data(std::ostream& stream) const
{
    ostream_writer sink(stream);
    to_data(sink);
}

void asset_detail::to_data(writer& sink) const
{
    sink.write_string(symbol);
    sink.write_8_bytes_little_endian(maximum_supply);
    sink.write_byte(decimal_number);
    sink.write_byte(secondaryissue_threshold);
    sink.write_byte(unused2);
    sink.write_byte(unused3);
    sink.write_string(issuer);
    sink.write_string(address);
    sink.write_string(description);
}

uint64_t asset_detail::serialized_size() const
{
    size_t len = symbol.size() + 8 + 4 + issuer.size() + address.size() + description.size() + 4;
    return std::min(ASSET_DETAIL_FIX_SIZE, len);
}

std::string asset_detail::to_string() const
{
    std::ostringstream ss;

    ss << "\t symbol = " << symbol << "\n"
        << "\t maximum_supply = " << std::to_string(maximum_supply) << "\n"
        << "\t decimal_number = " << std::to_string(decimal_number) << "\n"
        << "\t is_asset_secondaryissue = " << (is_asset_secondaryissue() ? "true" : "false") << "\n"
        << "\t secondaryissue_threshold = " << std::to_string(get_secondaryissue_threshold()) << "\n"
        << "\t issuer = " << issuer << "\n"
        << "\t address = " << address << "\n"
        << "\t description = " << description << "\n";

    return ss.str();
}

const std::string& asset_detail::get_symbol() const
{
    return symbol;
}
void asset_detail::set_symbol(const std::string& symbol)
{
    size_t len = symbol.size()+1 < (ASSET_DETAIL_SYMBOL_FIX_SIZE) ?symbol.size()+1:ASSET_DETAIL_SYMBOL_FIX_SIZE;
    this->symbol = symbol.substr(0, len);
}

uint64_t asset_detail::get_maximum_supply() const
{
    return maximum_supply;
}
void asset_detail::set_maximum_supply(uint64_t maximum_supply)
{
     this->maximum_supply = maximum_supply;
}

uint8_t asset_detail::get_decimal_number() const
{
    return decimal_number;
}
void asset_detail::set_decimal_number(uint8_t decimal_number)
{
     this->decimal_number = decimal_number;
}

const std::string& asset_detail::get_issuer() const
{
    return issuer;
}
void asset_detail::set_issuer(const std::string& issuer)
{
     size_t len = issuer.size()+1 < (ASSET_DETAIL_ISSUER_FIX_SIZE) ?issuer.size()+1:ASSET_DETAIL_ISSUER_FIX_SIZE;
     this->issuer = issuer.substr(0, len);
}

const std::string& asset_detail::get_address() const
{
    return address;
}
void asset_detail::set_address(const std::string& address)
{
     size_t len = address.size()+1 < (ASSET_DETAIL_ADDRESS_FIX_SIZE) ?address.size()+1:ASSET_DETAIL_ADDRESS_FIX_SIZE;
     this->address = address.substr(0, len);
}

const std::string& asset_detail::get_description() const
{
    return description;
}
void asset_detail::set_description(const std::string& description)
{
     size_t len = description.size()+1 < (ASSET_DETAIL_DESCRIPTION_FIX_SIZE) ?description.size()+1:ASSET_DETAIL_DESCRIPTION_FIX_SIZE;
     this->description = description.substr(0, len);
}

asset_cert_type asset_detail::get_asset_cert_mask() const
{
    auto certs = asset_cert_ns::none;
    if (is_secondaryissue_legal()) {
        certs |= asset_cert_ns::issue;
    }
    return certs;
}

bool asset_detail::is_asset_secondaryissue() const
{
    return secondaryissue_threshold >= 128;
}

void asset_detail::set_asset_secondaryissue()
{
    if (!is_asset_secondaryissue()) {
        secondaryissue_threshold += 128;
    }
}

uint8_t asset_detail::get_secondaryissue_threshold() const
{
    if (is_asset_secondaryissue())
        return secondaryissue_threshold - 128;
    else
        return secondaryissue_threshold;
}

void asset_detail::set_secondaryissue_threshold(uint8_t share)
{
    BITCOIN_ASSERT(share < 128);
    secondaryissue_threshold = share;
}

bool asset_detail::is_secondaryissue_threshold_value_ok() const
{
    return is_secondaryissue_threshold_value_ok(get_secondaryissue_threshold());
}

bool asset_detail::is_secondaryissue_legal() const
{
    return is_secondaryissue_legal(get_secondaryissue_threshold());
}

bool asset_detail::is_secondaryissue_forbidden(uint8_t threshold)
{
    return threshold == forbidden_secondaryissue_threshold;
}

bool asset_detail::is_secondaryissue_freely(uint8_t threshold)
{
    return threshold == freely_secondaryissue_threshold;
}

bool asset_detail::is_secondaryissue_threshold_value_ok(uint8_t threshold)
{
    return is_secondaryissue_forbidden(threshold) || is_secondaryissue_legal(threshold);
}

bool asset_detail::is_secondaryissue_legal(uint8_t threshold)
{
    return is_secondaryissue_freely(threshold) || ((threshold >= 1) && (threshold <= 100));
}

bool asset_detail::is_secondaryissue_owns_enough(uint64_t own, uint64_t total, uint8_t threshold)
{
    if (is_secondaryissue_freely(threshold))
        return true;
    if (!is_secondaryissue_legal(threshold))
        return false;
    return own >= (uint64_t)(((double)total) / 100 * threshold);
}

} // namspace chain
} // namspace libbitcoin
<commit_msg>fix an hand error of remove attenuation model type from asset_detail<commit_after>/**
 * Copyright (c) 2011-2015 metaverse developers (see AUTHORS)
 *
 * This file is part of mvs-node.
 *
 * metaverse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/bitcoin/chain/attachment/asset/asset_detail.hpp>

#include <sstream>
#include <boost/iostreams/stream.hpp>
#include <metaverse/bitcoin/utility/container_sink.hpp>
#include <metaverse/bitcoin/utility/container_source.hpp>
#include <metaverse/bitcoin/utility/istream_reader.hpp>
#include <metaverse/bitcoin/utility/ostream_writer.hpp>
#include <json/minijson_writer.hpp>

namespace libbitcoin {
namespace chain {

asset_detail::asset_detail()
{
    reset();
}

asset_detail::asset_detail(
    std::string symbol, uint64_t maximum_supply,
    uint8_t decimal_number, uint8_t threshold, std::string issuer,
    std::string address, std::string description):
    symbol(symbol), maximum_supply(maximum_supply),
    decimal_number(decimal_number),
    secondaryissue_threshold(threshold),
    unused2(0), unused3(0),
    issuer(issuer), address(address), description(description)
{
}

asset_detail asset_detail::factory_from_data(const data_chunk& data)
{
    asset_detail instance;
    instance.from_data(data);
    return instance;
}

asset_detail asset_detail::factory_from_data(std::istream& stream)
{
    asset_detail instance;
    instance.from_data(stream);
    return instance;
}

asset_detail asset_detail::factory_from_data(reader& source)
{
    asset_detail instance;
    instance.from_data(source);
    return instance;
}

bool asset_detail::is_valid() const
{
    return !(symbol.empty()
            || (maximum_supply==0)
            || (symbol.size() + 8 + 4 + issuer.size() + address.size() + description.size() + 4)>ASSET_DETAIL_FIX_SIZE);
}

void asset_detail::reset()
{
    symbol = "";
    maximum_supply = 0;
    decimal_number = 0;
    secondaryissue_threshold = 0;
    unused2 = 0;
    unused3 = 0;
    issuer = "";
    address = "";
    description = "";
}

bool asset_detail::from_data(const data_chunk& data)
{
    data_source istream(data);
    return from_data(istream);
}

bool asset_detail::from_data(std::istream& stream)
{
    istream_reader source(stream);
    return from_data(source);
}

bool asset_detail::from_data(reader& source)
{
    reset();

    symbol = source.read_string();
    maximum_supply = source.read_8_bytes_little_endian();
    decimal_number = source.read_byte();
    secondaryissue_threshold = source.read_byte();
    unused2 = source.read_byte();
    unused3 = source.read_byte();
    issuer = source.read_string();
    address =  source.read_string();
    description =  source.read_string();

    auto result = static_cast<bool>(source);
    if (!result)
        reset();

    return result;
}

data_chunk asset_detail::to_data() const
{
    data_chunk data;
    data_sink ostream(data);
    to_data(ostream);
    ostream.flush();
    return data;
}

void asset_detail::to_data(std::ostream& stream) const
{
    ostream_writer sink(stream);
    to_data(sink);
}

void asset_detail::to_data(writer& sink) const
{
    sink.write_string(symbol);
    sink.write_8_bytes_little_endian(maximum_supply);
    sink.write_byte(decimal_number);
    sink.write_byte(secondaryissue_threshold);
    sink.write_byte(unused2);
    sink.write_byte(unused3);
    sink.write_string(issuer);
    sink.write_string(address);
    sink.write_string(description);
}

uint64_t asset_detail::serialized_size() const
{
    size_t len = symbol.size() + 8 + 4 + issuer.size() + address.size() + description.size() + 4;
    return std::min(ASSET_DETAIL_FIX_SIZE, len);
}

std::string asset_detail::to_string() const
{
    std::ostringstream ss;

    ss << "\t symbol = " << symbol << "\n"
        << "\t maximum_supply = " << std::to_string(maximum_supply) << "\n"
        << "\t decimal_number = " << std::to_string(decimal_number) << "\n"
        << "\t is_asset_secondaryissue = " << (is_asset_secondaryissue() ? "true" : "false") << "\n"
        << "\t secondaryissue_threshold = " << std::to_string(get_secondaryissue_threshold()) << "\n"
        << "\t issuer = " << issuer << "\n"
        << "\t address = " << address << "\n"
        << "\t description = " << description << "\n";

    return ss.str();
}

const std::string& asset_detail::get_symbol() const
{
    return symbol;
}
void asset_detail::set_symbol(const std::string& symbol)
{
    size_t len = symbol.size()+1 < (ASSET_DETAIL_SYMBOL_FIX_SIZE) ?symbol.size()+1:ASSET_DETAIL_SYMBOL_FIX_SIZE;
    this->symbol = symbol.substr(0, len);
}

uint64_t asset_detail::get_maximum_supply() const
{
    return maximum_supply;
}
void asset_detail::set_maximum_supply(uint64_t maximum_supply)
{
     this->maximum_supply = maximum_supply;
}

uint8_t asset_detail::get_decimal_number() const
{
    return decimal_number;
}
void asset_detail::set_decimal_number(uint8_t decimal_number)
{
     this->decimal_number = decimal_number;
}

const std::string& asset_detail::get_issuer() const
{
    return issuer;
}
void asset_detail::set_issuer(const std::string& issuer)
{
     size_t len = issuer.size()+1 < (ASSET_DETAIL_ISSUER_FIX_SIZE) ?issuer.size()+1:ASSET_DETAIL_ISSUER_FIX_SIZE;
     this->issuer = issuer.substr(0, len);
}

const std::string& asset_detail::get_address() const
{
    return address;
}
void asset_detail::set_address(const std::string& address)
{
     size_t len = address.size()+1 < (ASSET_DETAIL_ADDRESS_FIX_SIZE) ?address.size()+1:ASSET_DETAIL_ADDRESS_FIX_SIZE;
     this->address = address.substr(0, len);
}

const std::string& asset_detail::get_description() const
{
    return description;
}
void asset_detail::set_description(const std::string& description)
{
     size_t len = description.size()+1 < (ASSET_DETAIL_DESCRIPTION_FIX_SIZE) ?description.size()+1:ASSET_DETAIL_DESCRIPTION_FIX_SIZE;
     this->description = description.substr(0, len);
}

asset_cert_type asset_detail::get_asset_cert_mask() const
{
    auto certs = asset_cert_ns::none;
    if (is_secondaryissue_legal()) {
        certs |= asset_cert_ns::issue;
    }
    return certs;
}

bool asset_detail::is_asset_secondaryissue() const
{
    return secondaryissue_threshold >= 128;
}

void asset_detail::set_asset_secondaryissue()
{
    if (!is_asset_secondaryissue()) {
        secondaryissue_threshold += 128;
    }
}

uint8_t asset_detail::get_secondaryissue_threshold() const
{
    if (is_asset_secondaryissue())
        return secondaryissue_threshold - 128;
    else
        return secondaryissue_threshold;
}

void asset_detail::set_secondaryissue_threshold(uint8_t share)
{
    BITCOIN_ASSERT(share < 128);
    secondaryissue_threshold = share;
}

bool asset_detail::is_secondaryissue_threshold_value_ok() const
{
    return is_secondaryissue_threshold_value_ok(get_secondaryissue_threshold());
}

bool asset_detail::is_secondaryissue_legal() const
{
    return is_secondaryissue_legal(get_secondaryissue_threshold());
}

bool asset_detail::is_secondaryissue_forbidden(uint8_t threshold)
{
    return threshold == forbidden_secondaryissue_threshold;
}

bool asset_detail::is_secondaryissue_freely(uint8_t threshold)
{
    return threshold == freely_secondaryissue_threshold;
}

bool asset_detail::is_secondaryissue_threshold_value_ok(uint8_t threshold)
{
    return is_secondaryissue_forbidden(threshold) || is_secondaryissue_legal(threshold);
}

bool asset_detail::is_secondaryissue_legal(uint8_t threshold)
{
    return is_secondaryissue_freely(threshold) || ((threshold >= 1) && (threshold <= 100));
}

bool asset_detail::is_secondaryissue_owns_enough(uint64_t own, uint64_t total, uint8_t threshold)
{
    if (is_secondaryissue_freely(threshold))
        return true;
    if (!is_secondaryissue_legal(threshold))
        return false;
    return own >= (uint64_t)(((double)total) / 100 * threshold);
}

} // namspace chain
} // namspace libbitcoin
<|endoftext|>


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

#ifndef _SVX_ACCESSIBILITY_DG_COLOR_NAME_LOOK_UP_HXX
#include "DGColorNameLookUp.hxx"
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

using ::rtl::OUString;
using namespace ::com::sun::star;

namespace accessibility {

// Initialize the class instance with NULL.  A true instance is created only
// when the static <member>Instance</member> is called for the first time.
DGColorNameLookUp* DGColorNameLookUp::mpInstance = NULL;

DGColorNameLookUp& DGColorNameLookUp::Instance (void)
{
    // Using double check pattern to make sure that exactly one instance of
    // the shape type handler is instantiated.
    if (mpInstance == NULL)
    {
        ::vos::OGuard aGuard (::Application::GetSolarMutex());
        if (mpInstance == NULL)
        {
            // Create the single instance of the color name look up.
            mpInstance = new DGColorNameLookUp();
        }
    }

    return *mpInstance;
}

OUString DGColorNameLookUp::LookUpColor (long int nColor) const
{
    OUString sColorName;
    tColorValueToNameMap::const_iterator I;
    I = maColorValueToNameMap.find (nColor);
    if (I != maColorValueToNameMap.end())
        // Found the color value.  Return the associated name.
        sColorName = I->second;
    else
    {
        // Did not find the given color.  Append its rgb tuple to the
        // description.
        ::rtl::OUStringBuffer sNameBuffer;
        sNameBuffer.append (sal_Unicode('#'));
        sNameBuffer.append (nColor, 16);
        sColorName = sNameBuffer.makeStringAndClear();
    }
    return sColorName;
}

DGColorNameLookUp::DGColorNameLookUp (void)
{
    uno::Sequence<OUString> aNames;
    uno::Reference<container::XNameAccess> xNA;

    try
    {
        // Create color table in which to look up the given color.
        uno::Reference<container::XNameContainer> xColorTable (
            ::comphelper::getProcessServiceFactory()->createInstance(
                OUString::createFromAscii("com.sun.star.drawing.ColorTable")),
            uno::UNO_QUERY);

        // Get list of color names in order to iterate over the color table.
        xNA = uno::Reference<container::XNameAccess>(xColorTable, uno::UNO_QUERY);
        if (xNA.is())
        {
            // Look the solar mutex here as workarround for missing lock in
            // called function.
            ::vos::OGuard aGuard (::Application::GetSolarMutex());
            aNames = xNA->getElementNames();
        }
    }
    catch (uno::RuntimeException e)
    {
        // When an excpetion occured then whe have an empty name sequence
        // and the loop below is not entered.
    }

    // Fill the map to convert from numerical color values to names.
    if (xNA.is())
        for (long int i=0; i<aNames.getLength(); i++)
        {
            // Get the numerical value for the i-th color name.
            try
            {
                uno::Any aColor (xNA->getByName (aNames[i]));
                long nColor;
                aColor >>= nColor;
                maColorValueToNameMap[nColor] = aNames[i];
            }
            catch (uno::RuntimeException e)
            {
                // Ignore the exception: the color who lead to the excpetion
                // is not included into the map.
            }
        }
}

DGColorNameLookUp::~DGColorNameLookUp (void)
{
    maColorValueToNameMap.clear();
}

} // end of namespace accessibility
<commit_msg>INTEGRATION: CWS pchfix02 (1.3.536); FILE MERGED 2006/09/01 17:46:00 kaib 1.3.536.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DGColorNameLookUp.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 04:04:29 $
 *
 *  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_svx.hxx"

#ifndef _SVX_ACCESSIBILITY_DG_COLOR_NAME_LOOK_UP_HXX
#include "DGColorNameLookUp.hxx"
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

using ::rtl::OUString;
using namespace ::com::sun::star;

namespace accessibility {

// Initialize the class instance with NULL.  A true instance is created only
// when the static <member>Instance</member> is called for the first time.
DGColorNameLookUp* DGColorNameLookUp::mpInstance = NULL;

DGColorNameLookUp& DGColorNameLookUp::Instance (void)
{
    // Using double check pattern to make sure that exactly one instance of
    // the shape type handler is instantiated.
    if (mpInstance == NULL)
    {
        ::vos::OGuard aGuard (::Application::GetSolarMutex());
        if (mpInstance == NULL)
        {
            // Create the single instance of the color name look up.
            mpInstance = new DGColorNameLookUp();
        }
    }

    return *mpInstance;
}

OUString DGColorNameLookUp::LookUpColor (long int nColor) const
{
    OUString sColorName;
    tColorValueToNameMap::const_iterator I;
    I = maColorValueToNameMap.find (nColor);
    if (I != maColorValueToNameMap.end())
        // Found the color value.  Return the associated name.
        sColorName = I->second;
    else
    {
        // Did not find the given color.  Append its rgb tuple to the
        // description.
        ::rtl::OUStringBuffer sNameBuffer;
        sNameBuffer.append (sal_Unicode('#'));
        sNameBuffer.append (nColor, 16);
        sColorName = sNameBuffer.makeStringAndClear();
    }
    return sColorName;
}

DGColorNameLookUp::DGColorNameLookUp (void)
{
    uno::Sequence<OUString> aNames;
    uno::Reference<container::XNameAccess> xNA;

    try
    {
        // Create color table in which to look up the given color.
        uno::Reference<container::XNameContainer> xColorTable (
            ::comphelper::getProcessServiceFactory()->createInstance(
                OUString::createFromAscii("com.sun.star.drawing.ColorTable")),
            uno::UNO_QUERY);

        // Get list of color names in order to iterate over the color table.
        xNA = uno::Reference<container::XNameAccess>(xColorTable, uno::UNO_QUERY);
        if (xNA.is())
        {
            // Look the solar mutex here as workarround for missing lock in
            // called function.
            ::vos::OGuard aGuard (::Application::GetSolarMutex());
            aNames = xNA->getElementNames();
        }
    }
    catch (uno::RuntimeException e)
    {
        // When an excpetion occured then whe have an empty name sequence
        // and the loop below is not entered.
    }

    // Fill the map to convert from numerical color values to names.
    if (xNA.is())
        for (long int i=0; i<aNames.getLength(); i++)
        {
            // Get the numerical value for the i-th color name.
            try
            {
                uno::Any aColor (xNA->getByName (aNames[i]));
                long nColor;
                aColor >>= nColor;
                maColorValueToNameMap[nColor] = aNames[i];
            }
            catch (uno::RuntimeException e)
            {
                // Ignore the exception: the color who lead to the excpetion
                // is not included into the map.
            }
        }
}

DGColorNameLookUp::~DGColorNameLookUp (void)
{
    maColorValueToNameMap.clear();
}

} // end of namespace accessibility
<|endoftext|>