<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sqlerror.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: ihi $ $Date: 2008-02-04 13:28:22 $
 *
 *  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_connectivity.hxx"

#include "connectivity/sqlerror.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/sdbc/SQLException.hpp>
/** === end UNO includes === **/

#include <comphelper/officeresourcebundle.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <rtl/ustrbuf.hxx>

#include <string.h>

//........................................................................
namespace connectivity
{
//........................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::sdbc::SQLException;
    using ::com::sun::star::uno::Type;
    /** === end UNO using === **/

    //using SQLError::ParamValue; // GCC (unxlngi6) does not like this
    namespace
    {
        typedef SQLError::ParamValue ParamValue;
    }

    //====================================================================
    //= SQLError_Impl - declaration
    //====================================================================
    class SQLError_Impl
    {
    public:
        SQLError_Impl( const ::comphelper::ComponentContext& _rContext );
        ~SQLError_Impl();

        // versions of the public SQLError methods which are just delegated to this impl-class
        static const ::rtl::OUString& getMessagePrefix();
        ::rtl::OUString     getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        ::rtl::OUString     getSQLState( const ErrorCondition _eCondition );
        static ErrorCode    getErrorCode( const ErrorCondition _eCondition );
        void                raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        void                raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        void                raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        SQLException        getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );

    private:
        /// returns the basic error message associated with the given error condition, without any parameter replacements
        ::rtl::OUString
                impl_getErrorMessage( const ErrorCondition& _eCondition );

        /// returns the SQLState associated with the given error condition
        ::rtl::OUString
                impl_getSQLState( const ErrorCondition& _eCondition );

        /// returns an SQLException describing the given error condition
        SQLException
                impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
                    const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );

        /// initializes our resource bundle
        bool    impl_initResources();

    private:
        ::osl::Mutex                                            m_aMutex;
        ::comphelper::ComponentContext                          m_aContext;
        ::std::auto_ptr< ::comphelper::OfficeResourceBundle >   m_pResources;
        bool                                                    m_bAttemptedInit;
    };

    //====================================================================
    //= SQLError_Impl - implementation
    //====================================================================
    //--------------------------------------------------------------------
    SQLError_Impl::SQLError_Impl( const ::comphelper::ComponentContext& _rContext )
        :m_aContext( _rContext )
        ,m_pResources( )
        ,m_bAttemptedInit( false )
    {
    }

    //--------------------------------------------------------------------
    SQLError_Impl::~SQLError_Impl()
    {
    }

    //--------------------------------------------------------------------
    const ::rtl::OUString& SQLError_Impl::getMessagePrefix()
    {
        static ::rtl::OUString s_sMessagePrefix( RTL_CONSTASCII_USTRINGPARAM( "[OOoBase]" ) );
        return s_sMessagePrefix;
    }

    //--------------------------------------------------------------------
    namespace
    {
        //................................................................
        /** substitutes a given placeholder in the given message with the given value
        */
        void    lcl_substitutePlaceholder( ::rtl::OUString& _rMessage, const sal_Char* _pPlaceholder, ParamValue _rParamValue )
        {
            size_t nPlaceholderLen( strlen( _pPlaceholder ) );
            sal_Int32 nIndex = _rMessage.indexOfAsciiL( _pPlaceholder, nPlaceholderLen );

            bool bHasPlaceholder = ( nIndex != -1 );
            bool bWantsPlaceholder = _rParamValue.is();
            OSL_ENSURE( bHasPlaceholder == bWantsPlaceholder, "lcl_substitutePlaceholder: placeholder where none is expected, or no placeholder where one is needed!" );

            if ( bHasPlaceholder && bWantsPlaceholder )
                _rMessage = _rMessage.replaceAt( nIndex, nPlaceholderLen, *_rParamValue );
        }

        //................................................................
        sal_Int32   lcl_getResourceID( const ErrorCondition _eCondition, bool _bSQLState )
        {
            return  256
                +   2 * ::sal::static_int_cast< sal_Int32, ErrorCondition >( _eCondition )
                +   ( _bSQLState ? 1 : 0 );
        }
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        ::rtl::OUString sErrorMessage( impl_getErrorMessage( _eCondition ) );

        lcl_substitutePlaceholder( sErrorMessage, "$1$", _rParamValue1 );
        lcl_substitutePlaceholder( sErrorMessage, "$2$", _rParamValue2 );
        lcl_substitutePlaceholder( sErrorMessage, "$3$", _rParamValue3 );

        return sErrorMessage;
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::getSQLState( const ErrorCondition _eCondition )
    {
        return impl_getSQLState( _eCondition );
    }

    //--------------------------------------------------------------------
    ErrorCode SQLError_Impl::getErrorCode( const ErrorCondition _eCondition )
    {
        return 0 - ::sal::static_int_cast< ErrorCode, ErrorCondition >( _eCondition );
    }

    //--------------------------------------------------------------------
    void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        raiseTypedException(
            _eCondition,
            _rxContext,
            ::cppu::UnoType< SQLException >::get(),
            _rParamValue1,
            _rParamValue2,
            _rParamValue3
        );
    }

    //--------------------------------------------------------------------
    void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        raiseTypedException(
            _eCondition,
            NULL,
            ::cppu::UnoType< SQLException >::get(),
            _rParamValue1,
            _rParamValue2,
            _rParamValue3
        );
    }

    //--------------------------------------------------------------------
    void SQLError_Impl::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        if ( !::cppu::UnoType< SQLException >::get().isAssignableFrom( _rExceptionType ) )
            throw ::std::bad_cast();

        // default-construct an exception of the desired type
        Any aException( NULL, _rExceptionType );

        // fill it
        SQLException* pException = static_cast< SQLException* >( aException.pData );
        *pException = impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );

        // throw it
        ::cppu::throwException( aException );
    }

    //--------------------------------------------------------------------
    SQLException SQLError_Impl::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        return impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    SQLException SQLError_Impl::impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        return SQLException(
            getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 ),
            _rxContext,
            getSQLState( _eCondition ),
            getErrorCode( _eCondition ),
            Any()
        );
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::impl_getErrorMessage( const ErrorCondition& _eCondition )
    {
        ::rtl::OUStringBuffer aMessage;

        if ( impl_initResources() )
        {
            ::rtl::OUString sResMessage( m_pResources->loadString( lcl_getResourceID( _eCondition, false ) ) );
            OSL_ENSURE( sResMessage.getLength(), "SQLError_Impl::impl_getErrorMessage: illegal error condition, or invalid resource!" );
            aMessage.append( getMessagePrefix() ).appendAscii( " " ).append( sResMessage );
        }

        return aMessage.makeStringAndClear();
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::impl_getSQLState( const ErrorCondition& _eCondition )
    {
        ::rtl::OUString sState;

        if ( impl_initResources() )
        {
            sal_Int32 nResourceId( lcl_getResourceID( _eCondition, true ) );
            if ( m_pResources->hasString( nResourceId ) )
                sState = m_pResources->loadString( nResourceId );
        }

        if ( !sState.getLength() )
            sState = ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "S1000" ), RTL_TEXTENCODING_ASCII_US );

        return sState;
    }

    //--------------------------------------------------------------------
    bool SQLError_Impl::impl_initResources()
    {
        if ( m_pResources.get() )
            return true;
        if ( m_bAttemptedInit )
            return false;

        ::osl::MutexGuard aGuard( m_aMutex );
        m_bAttemptedInit = true;

        m_pResources.reset( new ::comphelper::OfficeResourceBundle( m_aContext.getUNOContext(), "sdberr" ) );
        return m_pResources.get() != NULL;
    }

    //====================================================================
    //= SQLError
    //====================================================================
    //--------------------------------------------------------------------
    SQLError::SQLError( const ::comphelper::ComponentContext& _rContext )
        :m_pImpl( new SQLError_Impl( _rContext ) )
    {
    }

    //--------------------------------------------------------------------
    SQLError::~SQLError()
    {
    }

    //--------------------------------------------------------------------
    const ::rtl::OUString& SQLError::getMessagePrefix()
    {
        return SQLError_Impl::getMessagePrefix();
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        return m_pImpl->getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError::getSQLState( const ErrorCondition _eCondition ) const
    {
        return m_pImpl->getSQLState( _eCondition );
    }

    //--------------------------------------------------------------------
    ErrorCode SQLError::getErrorCode( const ErrorCondition _eCondition )
    {
        return SQLError_Impl::getErrorCode( _eCondition );
    }

    //--------------------------------------------------------------------
    void SQLError::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        m_pImpl->raiseException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    void SQLError::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        m_pImpl->raiseException( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    void SQLError::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        m_pImpl->raiseTypedException( _eCondition, _rxContext, _rExceptionType, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    SQLException SQLError::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        return m_pImpl->getSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

//........................................................................
} // namespace connectivity
//........................................................................
<commit_msg>INTEGRATION: CWS changefileheader (1.3.22); FILE MERGED 2008/03/28 15:23:21 rt 1.3.22.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sqlerror.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#include "connectivity/sqlerror.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/sdbc/SQLException.hpp>
/** === end UNO includes === **/

#include <comphelper/officeresourcebundle.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <rtl/ustrbuf.hxx>

#include <string.h>

//........................................................................
namespace connectivity
{
//........................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::sdbc::SQLException;
    using ::com::sun::star::uno::Type;
    /** === end UNO using === **/

    //using SQLError::ParamValue; // GCC (unxlngi6) does not like this
    namespace
    {
        typedef SQLError::ParamValue ParamValue;
    }

    //====================================================================
    //= SQLError_Impl - declaration
    //====================================================================
    class SQLError_Impl
    {
    public:
        SQLError_Impl( const ::comphelper::ComponentContext& _rContext );
        ~SQLError_Impl();

        // versions of the public SQLError methods which are just delegated to this impl-class
        static const ::rtl::OUString& getMessagePrefix();
        ::rtl::OUString     getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        ::rtl::OUString     getSQLState( const ErrorCondition _eCondition );
        static ErrorCode    getErrorCode( const ErrorCondition _eCondition );
        void                raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        void                raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        void                raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
        SQLException        getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );

    private:
        /// returns the basic error message associated with the given error condition, without any parameter replacements
        ::rtl::OUString
                impl_getErrorMessage( const ErrorCondition& _eCondition );

        /// returns the SQLState associated with the given error condition
        ::rtl::OUString
                impl_getSQLState( const ErrorCondition& _eCondition );

        /// returns an SQLException describing the given error condition
        SQLException
                impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
                    const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );

        /// initializes our resource bundle
        bool    impl_initResources();

    private:
        ::osl::Mutex                                            m_aMutex;
        ::comphelper::ComponentContext                          m_aContext;
        ::std::auto_ptr< ::comphelper::OfficeResourceBundle >   m_pResources;
        bool                                                    m_bAttemptedInit;
    };

    //====================================================================
    //= SQLError_Impl - implementation
    //====================================================================
    //--------------------------------------------------------------------
    SQLError_Impl::SQLError_Impl( const ::comphelper::ComponentContext& _rContext )
        :m_aContext( _rContext )
        ,m_pResources( )
        ,m_bAttemptedInit( false )
    {
    }

    //--------------------------------------------------------------------
    SQLError_Impl::~SQLError_Impl()
    {
    }

    //--------------------------------------------------------------------
    const ::rtl::OUString& SQLError_Impl::getMessagePrefix()
    {
        static ::rtl::OUString s_sMessagePrefix( RTL_CONSTASCII_USTRINGPARAM( "[OOoBase]" ) );
        return s_sMessagePrefix;
    }

    //--------------------------------------------------------------------
    namespace
    {
        //................................................................
        /** substitutes a given placeholder in the given message with the given value
        */
        void    lcl_substitutePlaceholder( ::rtl::OUString& _rMessage, const sal_Char* _pPlaceholder, ParamValue _rParamValue )
        {
            size_t nPlaceholderLen( strlen( _pPlaceholder ) );
            sal_Int32 nIndex = _rMessage.indexOfAsciiL( _pPlaceholder, nPlaceholderLen );

            bool bHasPlaceholder = ( nIndex != -1 );
            bool bWantsPlaceholder = _rParamValue.is();
            OSL_ENSURE( bHasPlaceholder == bWantsPlaceholder, "lcl_substitutePlaceholder: placeholder where none is expected, or no placeholder where one is needed!" );

            if ( bHasPlaceholder && bWantsPlaceholder )
                _rMessage = _rMessage.replaceAt( nIndex, nPlaceholderLen, *_rParamValue );
        }

        //................................................................
        sal_Int32   lcl_getResourceID( const ErrorCondition _eCondition, bool _bSQLState )
        {
            return  256
                +   2 * ::sal::static_int_cast< sal_Int32, ErrorCondition >( _eCondition )
                +   ( _bSQLState ? 1 : 0 );
        }
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        ::rtl::OUString sErrorMessage( impl_getErrorMessage( _eCondition ) );

        lcl_substitutePlaceholder( sErrorMessage, "$1$", _rParamValue1 );
        lcl_substitutePlaceholder( sErrorMessage, "$2$", _rParamValue2 );
        lcl_substitutePlaceholder( sErrorMessage, "$3$", _rParamValue3 );

        return sErrorMessage;
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::getSQLState( const ErrorCondition _eCondition )
    {
        return impl_getSQLState( _eCondition );
    }

    //--------------------------------------------------------------------
    ErrorCode SQLError_Impl::getErrorCode( const ErrorCondition _eCondition )
    {
        return 0 - ::sal::static_int_cast< ErrorCode, ErrorCondition >( _eCondition );
    }

    //--------------------------------------------------------------------
    void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        raiseTypedException(
            _eCondition,
            _rxContext,
            ::cppu::UnoType< SQLException >::get(),
            _rParamValue1,
            _rParamValue2,
            _rParamValue3
        );
    }

    //--------------------------------------------------------------------
    void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        raiseTypedException(
            _eCondition,
            NULL,
            ::cppu::UnoType< SQLException >::get(),
            _rParamValue1,
            _rParamValue2,
            _rParamValue3
        );
    }

    //--------------------------------------------------------------------
    void SQLError_Impl::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        if ( !::cppu::UnoType< SQLException >::get().isAssignableFrom( _rExceptionType ) )
            throw ::std::bad_cast();

        // default-construct an exception of the desired type
        Any aException( NULL, _rExceptionType );

        // fill it
        SQLException* pException = static_cast< SQLException* >( aException.pData );
        *pException = impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );

        // throw it
        ::cppu::throwException( aException );
    }

    //--------------------------------------------------------------------
    SQLException SQLError_Impl::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        return impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    SQLException SQLError_Impl::impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
    {
        return SQLException(
            getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 ),
            _rxContext,
            getSQLState( _eCondition ),
            getErrorCode( _eCondition ),
            Any()
        );
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::impl_getErrorMessage( const ErrorCondition& _eCondition )
    {
        ::rtl::OUStringBuffer aMessage;

        if ( impl_initResources() )
        {
            ::rtl::OUString sResMessage( m_pResources->loadString( lcl_getResourceID( _eCondition, false ) ) );
            OSL_ENSURE( sResMessage.getLength(), "SQLError_Impl::impl_getErrorMessage: illegal error condition, or invalid resource!" );
            aMessage.append( getMessagePrefix() ).appendAscii( " " ).append( sResMessage );
        }

        return aMessage.makeStringAndClear();
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError_Impl::impl_getSQLState( const ErrorCondition& _eCondition )
    {
        ::rtl::OUString sState;

        if ( impl_initResources() )
        {
            sal_Int32 nResourceId( lcl_getResourceID( _eCondition, true ) );
            if ( m_pResources->hasString( nResourceId ) )
                sState = m_pResources->loadString( nResourceId );
        }

        if ( !sState.getLength() )
            sState = ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "S1000" ), RTL_TEXTENCODING_ASCII_US );

        return sState;
    }

    //--------------------------------------------------------------------
    bool SQLError_Impl::impl_initResources()
    {
        if ( m_pResources.get() )
            return true;
        if ( m_bAttemptedInit )
            return false;

        ::osl::MutexGuard aGuard( m_aMutex );
        m_bAttemptedInit = true;

        m_pResources.reset( new ::comphelper::OfficeResourceBundle( m_aContext.getUNOContext(), "sdberr" ) );
        return m_pResources.get() != NULL;
    }

    //====================================================================
    //= SQLError
    //====================================================================
    //--------------------------------------------------------------------
    SQLError::SQLError( const ::comphelper::ComponentContext& _rContext )
        :m_pImpl( new SQLError_Impl( _rContext ) )
    {
    }

    //--------------------------------------------------------------------
    SQLError::~SQLError()
    {
    }

    //--------------------------------------------------------------------
    const ::rtl::OUString& SQLError::getMessagePrefix()
    {
        return SQLError_Impl::getMessagePrefix();
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        return m_pImpl->getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SQLError::getSQLState( const ErrorCondition _eCondition ) const
    {
        return m_pImpl->getSQLState( _eCondition );
    }

    //--------------------------------------------------------------------
    ErrorCode SQLError::getErrorCode( const ErrorCondition _eCondition )
    {
        return SQLError_Impl::getErrorCode( _eCondition );
    }

    //--------------------------------------------------------------------
    void SQLError::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        m_pImpl->raiseException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    void SQLError::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        m_pImpl->raiseException( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    void SQLError::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        m_pImpl->raiseTypedException( _eCondition, _rxContext, _rExceptionType, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

    //--------------------------------------------------------------------
    SQLException SQLError::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
        const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
    {
        return m_pImpl->getSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
    }

//........................................................................
} // namespace connectivity
//........................................................................
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TResultSetHelper.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 06:39:58 $
 *
 *  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 CONNECTIVITY_TRESULTSETHELPER_HXX
#define CONNECTIVITY_TRESULTSETHELPER_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace connectivity
{
    class SAL_NO_VTABLE IResultSetHelper
    {
    public:
        enum Movement
        {
            NEXT        = 0,
            PRIOR,
            FIRST,
            LAST,
            RELATIVE,
            ABSOLUTE,
            BOOKMARK
        };
    public:
        virtual sal_Bool move(Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData) = 0;
        virtual sal_Int32 getDriverPos() const = 0;
        virtual sal_Bool deletedVisible() const = 0;
        virtual sal_Bool isRowDeleted() const = 0;
    };
}

#endif // CONNECTIVITY_TRESULTSETHELPER_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.372); FILE MERGED 2008/04/01 15:09:07 thb 1.2.372.2: #i85898# Stripping all external header guards 2008/03/28 15:24:05 rt 1.2.372.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: TResultSetHelper.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef CONNECTIVITY_TRESULTSETHELPER_HXX
#define CONNECTIVITY_TRESULTSETHELPER_HXX

#include <sal/types.h>

namespace connectivity
{
    class SAL_NO_VTABLE IResultSetHelper
    {
    public:
        enum Movement
        {
            NEXT        = 0,
            PRIOR,
            FIRST,
            LAST,
            RELATIVE,
            ABSOLUTE,
            BOOKMARK
        };
    public:
        virtual sal_Bool move(Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData) = 0;
        virtual sal_Int32 getDriverPos() const = 0;
        virtual sal_Bool deletedVisible() const = 0;
        virtual sal_Bool isRowDeleted() const = 0;
    };
}

#endif // CONNECTIVITY_TRESULTSETHELPER_HXX

<|endoftext|>


<commit_before>//
//  Speaker.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 12/01/2016.
//  Copyright © 2016 Thomas Harte. All rights reserved.
//

#ifndef Speaker_hpp
#define Speaker_hpp

#include <cstdint>
#include <cstdio>
#include <ctime>

#include <memory>
#include <list>
#include <vector>

#include "../SignalProcessing/Stepper.hpp"
#include "../SignalProcessing/FIRFilter.hpp"
#include "../Concurrency/AsyncTaskQueue.hpp"
#include "../ClockReceiver/ClockReceiver.hpp"

namespace Outputs {

/*!
	Provides the base class for an audio output source, with an input rate (the speed at which the source will
	provide data), an output rate (the speed at which the destination will receive data), a delegate to receive
	the output and some help for the output in picking an appropriate rate once the input rate is known.

	Intended to be a parent class, allowing descendants to pick the strategy by which input samples are mapped to
	output samples.
*/
class Speaker {
	public:
		class Delegate {
			public:
				virtual void speaker_did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer) = 0;
		};

		float get_ideal_clock_rate_in_range(float minimum, float maximum) {
			// return twice the cut off, if applicable
			if(high_frequency_cut_off_ > 0.0f && input_cycles_per_second_ >= high_frequency_cut_off_ * 3.0f && input_cycles_per_second_ <= high_frequency_cut_off_ * 3.0f) return high_frequency_cut_off_ * 3.0f;

			// return exactly the input rate if possible
			if(input_cycles_per_second_ >= minimum && input_cycles_per_second_ <= maximum) return input_cycles_per_second_;

			// if the input rate is lower, return the minimum
			if(input_cycles_per_second_ < minimum) return minimum;

			// otherwise, return the maximum
			return maximum;
		}

		void set_output_rate(float cycles_per_second, int buffer_size) {
			output_cycles_per_second_ = cycles_per_second;
			buffer_in_progress_.resize(static_cast<size_t>(buffer_size));
			set_needs_updated_filter_coefficients();
		}

		void set_output_quality(int number_of_taps) {
			requested_number_of_taps_ = static_cast<size_t>(number_of_taps);
			set_needs_updated_filter_coefficients();
		}

		void set_delegate(Delegate *delegate) {
			delegate_ = delegate;
		}

		void set_input_rate(float cycles_per_second) {
			input_cycles_per_second_ = cycles_per_second;
			set_needs_updated_filter_coefficients();
		}

		/*!
			Sets the cut-off frequency for a low-pass filter attached to the output of this speaker; optional.
		*/
		void set_high_frequency_cut_off(float high_frequency) {
			high_frequency_cut_off_ = high_frequency;
			set_needs_updated_filter_coefficients();
		}

		Speaker() : buffer_in_progress_pointer_(0), requested_number_of_taps_(0), high_frequency_cut_off_(-1.0), _queue(new Concurrency::AsyncTaskQueue) {}

		/*!
			Ensures any deferred processing occurs now.
		*/
		void flush() {
			if(!queued_functions_) return;
			std::shared_ptr<std::list<std::function<void(void)>>> queued_functions = queued_functions_;
			queued_functions_.reset();
			_queue->enqueue([queued_functions] {
				for(auto &function : *queued_functions) {
					function();
				}
			});
		}

	protected:
		void enqueue(std::function<void(void)> function) {
			if(!queued_functions_) queued_functions_.reset(new std::list<std::function<void(void)>>);
			queued_functions_->push_back(function);
		}
		std::shared_ptr<std::list<std::function<void(void)>>> queued_functions_;

		std::vector<int16_t> buffer_in_progress_;
		float high_frequency_cut_off_;
		size_t buffer_in_progress_pointer_;
		size_t number_of_taps_, requested_number_of_taps_;
		bool coefficients_are_dirty_;
		Delegate *delegate_;

		float input_cycles_per_second_, output_cycles_per_second_;

		void set_needs_updated_filter_coefficients() {
			coefficients_are_dirty_ = true;
		}

		void get_samples(unsigned int quantity, int16_t *target)	{}
		void skip_samples(unsigned int quantity) {
			int16_t throwaway_samples[quantity];
			get_samples(quantity, throwaway_samples);
		}

		std::unique_ptr<Concurrency::AsyncTaskQueue> _queue;
};

/*!
	A concrete descendant of Speaker that uses a FIR filter to map from input data to output data when scaling
	and a copy-through buffer when input and output rates are the same.

	Audio sources should use @c Filter as both a template and a parent, implementing at least
	`get_samples(unsigned int quantity, int16_t *target)` and ideally also `skip_samples(unsigned int quantity)`
	to provide source data.

	Call `run_for` to request that the next period of input data is collected.
*/
template <class T> class Filter: public Speaker {
	public:
		~Filter() {
			_queue->flush();
		}

		void run_for(const Cycles cycles) {
			enqueue([=]() {
				unsigned int cycles_remaining = static_cast<unsigned int>(cycles.as_int());
				if(coefficients_are_dirty_) update_filter_coefficients();

				// if input and output rates exactly match, just accumulate results and pass on
				if(input_cycles_per_second_ == output_cycles_per_second_ && high_frequency_cut_off_ < 0.0) {
					while(cycles_remaining) {
						unsigned int cycles_to_read = static_cast<unsigned int>(buffer_in_progress_.size() - static_cast<size_t>(buffer_in_progress_pointer_));
						if(cycles_to_read > cycles_remaining) cycles_to_read = cycles_remaining;

						static_cast<T *>(this)->get_samples(cycles_to_read, &buffer_in_progress_[static_cast<size_t>(buffer_in_progress_pointer_)]);
						buffer_in_progress_pointer_ += cycles_to_read;

						// announce to delegate if full
						if(buffer_in_progress_pointer_ == buffer_in_progress_.size()) {
							buffer_in_progress_pointer_ = 0;
							if(delegate_) {
								delegate_->speaker_did_complete_samples(this, buffer_in_progress_);
							}
						}

						cycles_remaining -= cycles_to_read;
					}

					return;
				}

				// if the output rate is less than the input rate, use the filter
				if(input_cycles_per_second_ > output_cycles_per_second_ || (input_cycles_per_second_ == output_cycles_per_second_ && high_frequency_cut_off_ >= 0.0)) {
					while(cycles_remaining) {
						unsigned int cycles_to_read = static_cast<unsigned int>(std::min(static_cast<size_t>(cycles_remaining), number_of_taps_ - input_buffer_depth_));
						static_cast<T *>(this)->get_samples(cycles_to_read, &input_buffer_[static_cast<size_t>(input_buffer_depth_)]);
						cycles_remaining -= cycles_to_read;
						input_buffer_depth_ += cycles_to_read;

						if(input_buffer_depth_ == number_of_taps_) {
							buffer_in_progress_[static_cast<size_t>(buffer_in_progress_pointer_)] = filter_->apply(input_buffer_.data());
							buffer_in_progress_pointer_++;

							// announce to delegate if full
							if(buffer_in_progress_pointer_ == buffer_in_progress_.size()) {
								buffer_in_progress_pointer_ = 0;
								if(delegate_) {
									delegate_->speaker_did_complete_samples(this, buffer_in_progress_);
								}
							}

							// If the next loop around is going to reuse some of the samples just collected, use a memmove to
							// preserve them in the correct locations (TODO: use a longer buffer to fix that) and don't skip
							// anything. Otherwise skip as required to get to the next sample batch and don't expect to reuse.
							uint64_t steps = stepper_->step();
							if(steps < number_of_taps_) {
								int16_t *input_buffer = input_buffer_.data();
								memmove(input_buffer, &input_buffer[steps], sizeof(int16_t) * (static_cast<size_t>(number_of_taps_) - static_cast<size_t>(steps)));
								input_buffer_depth_ -= steps;
							} else {
								if(steps > number_of_taps_)
									static_cast<T *>(this)->skip_samples(static_cast<unsigned int>(steps) - static_cast<unsigned int>(number_of_taps_));
								input_buffer_depth_ = 0;
							}
						}
					}

					return;
				}

			// TODO: input rate is less than output rate
			});
		}

	private:
		std::unique_ptr<SignalProcessing::Stepper> stepper_;
		std::unique_ptr<SignalProcessing::FIRFilter> filter_;

		std::vector<int16_t> input_buffer_;
		size_t input_buffer_depth_;

		void update_filter_coefficients() {
			// make a guess at a good number of taps if this hasn't been provided explicitly
			if(requested_number_of_taps_) {
				number_of_taps_ = requested_number_of_taps_;
			} else {
				number_of_taps_ = static_cast<size_t>(ceilf((input_cycles_per_second_ + output_cycles_per_second_) / output_cycles_per_second_));
				number_of_taps_ *= 2;
				number_of_taps_ |= 1;
			}

			coefficients_are_dirty_ = false;
			buffer_in_progress_pointer_ = 0;

			stepper_.reset(new SignalProcessing::Stepper((uint64_t)input_cycles_per_second_, (uint64_t)output_cycles_per_second_));

			float high_pass_frequency;
			if(high_frequency_cut_off_ > 0.0) {
				high_pass_frequency = std::min(output_cycles_per_second_ / 2.0f, high_frequency_cut_off_);
			} else {
				high_pass_frequency = output_cycles_per_second_ / 2.0f;
			}
			filter_.reset(new SignalProcessing::FIRFilter(static_cast<unsigned int>(number_of_taps_), static_cast<float>(input_cycles_per_second_), 0.0, high_pass_frequency, SignalProcessing::FIRFilter::DefaultAttenuation));

			input_buffer_.resize(static_cast<size_t>(number_of_taps_));
			input_buffer_depth_ = 0;
		}
};

}

#endif /* Speaker_hpp */
<commit_msg>Ensures proper initialisation of the delegate pointer.<commit_after>//
//  Speaker.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 12/01/2016.
//  Copyright © 2016 Thomas Harte. All rights reserved.
//

#ifndef Speaker_hpp
#define Speaker_hpp

#include <cstdint>
#include <cstdio>
#include <ctime>

#include <memory>
#include <list>
#include <vector>

#include "../SignalProcessing/Stepper.hpp"
#include "../SignalProcessing/FIRFilter.hpp"
#include "../Concurrency/AsyncTaskQueue.hpp"
#include "../ClockReceiver/ClockReceiver.hpp"

namespace Outputs {

/*!
	Provides the base class for an audio output source, with an input rate (the speed at which the source will
	provide data), an output rate (the speed at which the destination will receive data), a delegate to receive
	the output and some help for the output in picking an appropriate rate once the input rate is known.

	Intended to be a parent class, allowing descendants to pick the strategy by which input samples are mapped to
	output samples.
*/
class Speaker {
	public:
		class Delegate {
			public:
				virtual void speaker_did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer) = 0;
		};

		float get_ideal_clock_rate_in_range(float minimum, float maximum) {
			// return twice the cut off, if applicable
			if(high_frequency_cut_off_ > 0.0f && input_cycles_per_second_ >= high_frequency_cut_off_ * 3.0f && input_cycles_per_second_ <= high_frequency_cut_off_ * 3.0f) return high_frequency_cut_off_ * 3.0f;

			// return exactly the input rate if possible
			if(input_cycles_per_second_ >= minimum && input_cycles_per_second_ <= maximum) return input_cycles_per_second_;

			// if the input rate is lower, return the minimum
			if(input_cycles_per_second_ < minimum) return minimum;

			// otherwise, return the maximum
			return maximum;
		}

		void set_output_rate(float cycles_per_second, int buffer_size) {
			output_cycles_per_second_ = cycles_per_second;
			buffer_in_progress_.resize(static_cast<size_t>(buffer_size));
			set_needs_updated_filter_coefficients();
		}

		void set_output_quality(int number_of_taps) {
			requested_number_of_taps_ = static_cast<size_t>(number_of_taps);
			set_needs_updated_filter_coefficients();
		}

		void set_delegate(Delegate *delegate) {
			delegate_ = delegate;
		}

		void set_input_rate(float cycles_per_second) {
			input_cycles_per_second_ = cycles_per_second;
			set_needs_updated_filter_coefficients();
		}

		/*!
			Sets the cut-off frequency for a low-pass filter attached to the output of this speaker; optional.
		*/
		void set_high_frequency_cut_off(float high_frequency) {
			high_frequency_cut_off_ = high_frequency;
			set_needs_updated_filter_coefficients();
		}

		Speaker() : buffer_in_progress_pointer_(0), requested_number_of_taps_(0), high_frequency_cut_off_(-1.0), _queue(new Concurrency::AsyncTaskQueue) {}

		/*!
			Ensures any deferred processing occurs now.
		*/
		void flush() {
			if(!queued_functions_) return;
			std::shared_ptr<std::list<std::function<void(void)>>> queued_functions = queued_functions_;
			queued_functions_.reset();
			_queue->enqueue([queued_functions] {
				for(auto &function : *queued_functions) {
					function();
				}
			});
		}

	protected:
		void enqueue(std::function<void(void)> function) {
			if(!queued_functions_) queued_functions_.reset(new std::list<std::function<void(void)>>);
			queued_functions_->push_back(function);
		}
		std::shared_ptr<std::list<std::function<void(void)>>> queued_functions_;

		std::vector<int16_t> buffer_in_progress_;
		float high_frequency_cut_off_;
		size_t buffer_in_progress_pointer_;
		size_t number_of_taps_, requested_number_of_taps_;
		bool coefficients_are_dirty_;
		Delegate *delegate_ = nullptr;

		float input_cycles_per_second_, output_cycles_per_second_;

		void set_needs_updated_filter_coefficients() {
			coefficients_are_dirty_ = true;
		}

		void get_samples(unsigned int quantity, int16_t *target)	{}
		void skip_samples(unsigned int quantity) {
			int16_t throwaway_samples[quantity];
			get_samples(quantity, throwaway_samples);
		}

		std::unique_ptr<Concurrency::AsyncTaskQueue> _queue;
};

/*!
	A concrete descendant of Speaker that uses a FIR filter to map from input data to output data when scaling
	and a copy-through buffer when input and output rates are the same.

	Audio sources should use @c Filter as both a template and a parent, implementing at least
	`get_samples(unsigned int quantity, int16_t *target)` and ideally also `skip_samples(unsigned int quantity)`
	to provide source data.

	Call `run_for` to request that the next period of input data is collected.
*/
template <class T> class Filter: public Speaker {
	public:
		~Filter() {
			_queue->flush();
		}

		void run_for(const Cycles cycles) {
			enqueue([=]() {
				unsigned int cycles_remaining = static_cast<unsigned int>(cycles.as_int());
				if(coefficients_are_dirty_) update_filter_coefficients();

				// if input and output rates exactly match, just accumulate results and pass on
				if(input_cycles_per_second_ == output_cycles_per_second_ && high_frequency_cut_off_ < 0.0) {
					while(cycles_remaining) {
						unsigned int cycles_to_read = static_cast<unsigned int>(buffer_in_progress_.size() - static_cast<size_t>(buffer_in_progress_pointer_));
						if(cycles_to_read > cycles_remaining) cycles_to_read = cycles_remaining;

						static_cast<T *>(this)->get_samples(cycles_to_read, &buffer_in_progress_[static_cast<size_t>(buffer_in_progress_pointer_)]);
						buffer_in_progress_pointer_ += cycles_to_read;

						// announce to delegate if full
						if(buffer_in_progress_pointer_ == buffer_in_progress_.size()) {
							buffer_in_progress_pointer_ = 0;
							if(delegate_) {
								delegate_->speaker_did_complete_samples(this, buffer_in_progress_);
							}
						}

						cycles_remaining -= cycles_to_read;
					}

					return;
				}

				// if the output rate is less than the input rate, use the filter
				if(input_cycles_per_second_ > output_cycles_per_second_ || (input_cycles_per_second_ == output_cycles_per_second_ && high_frequency_cut_off_ >= 0.0)) {
					while(cycles_remaining) {
						unsigned int cycles_to_read = static_cast<unsigned int>(std::min(static_cast<size_t>(cycles_remaining), number_of_taps_ - input_buffer_depth_));
						static_cast<T *>(this)->get_samples(cycles_to_read, &input_buffer_[static_cast<size_t>(input_buffer_depth_)]);
						cycles_remaining -= cycles_to_read;
						input_buffer_depth_ += cycles_to_read;

						if(input_buffer_depth_ == number_of_taps_) {
							buffer_in_progress_[static_cast<size_t>(buffer_in_progress_pointer_)] = filter_->apply(input_buffer_.data());
							buffer_in_progress_pointer_++;

							// announce to delegate if full
							if(buffer_in_progress_pointer_ == buffer_in_progress_.size()) {
								buffer_in_progress_pointer_ = 0;
								if(delegate_) {
									delegate_->speaker_did_complete_samples(this, buffer_in_progress_);
								}
							}

							// If the next loop around is going to reuse some of the samples just collected, use a memmove to
							// preserve them in the correct locations (TODO: use a longer buffer to fix that) and don't skip
							// anything. Otherwise skip as required to get to the next sample batch and don't expect to reuse.
							uint64_t steps = stepper_->step();
							if(steps < number_of_taps_) {
								int16_t *input_buffer = input_buffer_.data();
								memmove(input_buffer, &input_buffer[steps], sizeof(int16_t) * (static_cast<size_t>(number_of_taps_) - static_cast<size_t>(steps)));
								input_buffer_depth_ -= steps;
							} else {
								if(steps > number_of_taps_)
									static_cast<T *>(this)->skip_samples(static_cast<unsigned int>(steps) - static_cast<unsigned int>(number_of_taps_));
								input_buffer_depth_ = 0;
							}
						}
					}

					return;
				}

			// TODO: input rate is less than output rate
			});
		}

	private:
		std::unique_ptr<SignalProcessing::Stepper> stepper_;
		std::unique_ptr<SignalProcessing::FIRFilter> filter_;

		std::vector<int16_t> input_buffer_;
		size_t input_buffer_depth_;

		void update_filter_coefficients() {
			// make a guess at a good number of taps if this hasn't been provided explicitly
			if(requested_number_of_taps_) {
				number_of_taps_ = requested_number_of_taps_;
			} else {
				number_of_taps_ = static_cast<size_t>(ceilf((input_cycles_per_second_ + output_cycles_per_second_) / output_cycles_per_second_));
				number_of_taps_ *= 2;
				number_of_taps_ |= 1;
			}

			coefficients_are_dirty_ = false;
			buffer_in_progress_pointer_ = 0;

			stepper_.reset(new SignalProcessing::Stepper((uint64_t)input_cycles_per_second_, (uint64_t)output_cycles_per_second_));

			float high_pass_frequency;
			if(high_frequency_cut_off_ > 0.0) {
				high_pass_frequency = std::min(output_cycles_per_second_ / 2.0f, high_frequency_cut_off_);
			} else {
				high_pass_frequency = output_cycles_per_second_ / 2.0f;
			}
			filter_.reset(new SignalProcessing::FIRFilter(static_cast<unsigned int>(number_of_taps_), static_cast<float>(input_cycles_per_second_), 0.0, high_pass_frequency, SignalProcessing::FIRFilter::DefaultAttenuation));

			input_buffer_.resize(static_cast<size_t>(number_of_taps_));
			input_buffer_depth_ = 0;
		}
};

}

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


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <thrift/lib/cpp2/frozen/schema/MemorySchema.h>

#include <limits>

THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemoryField)
THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemoryLayoutBase)
THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemoryLayout)
THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemorySchema)

namespace apache {
namespace thrift {
namespace frozen {
namespace schema {

int16_t MemorySchema::Helper::add(MemoryLayout&& layout) {
  // Add distinct layout, bounds check layoutId
  size_t layoutId = layoutTable_.add(std::move(layout));
  CHECK_LE(layoutId, std::numeric_limits<int16_t>::max()) << "Layout overflow";
  return static_cast<int16_t>(layoutId);
}

void MemorySchema::initFromSchema(Schema&& schema) {
  if (!schema.layouts.empty()) {
    layouts.resize(schema.layouts.size());

    for (const auto& layoutKvp : schema.layouts) {
      const auto id = layoutKvp.first;
      const auto& layout = layoutKvp.second;

      // Note: This will throw if there are any id >=
      // schema.layouts.size().
      auto& memLayout = layouts.at(id);

      memLayout.setSize(layout.size);
      memLayout.setBits(layout.bits);

      for (const auto& fieldKvp : layout.fields) {
        MemoryField memField;
        const auto& fieldId = fieldKvp.first;
        const auto& field = fieldKvp.second;

        memField.setId(fieldId);
        memField.setLayoutId(field.layoutId);
        memField.setOffset(field.offset);
        memLayout.addField(std::move(memField));
      }
    }
  }
  setRootLayoutId(schema.rootLayout);
}

void convert(Schema&& schema, MemorySchema& memSchema) {
  memSchema.initFromSchema(std::move(schema));
}

void convert(const MemorySchema& memSchema, Schema& schema) {
  std::size_t i = 0;
  for (const auto& memLayout : memSchema.getLayouts()) {
    auto& newLayout = schema.layouts[i];

    newLayout.size = memLayout.getSize();
    newLayout.bits = memLayout.getBits();

    for (const auto& field : memLayout.getFields()) {
      auto& newField = newLayout.fields[field.getId()];

      newField.layoutId = field.getLayoutId();
      newField.offset = field.getOffset();
    }
    ++i;
  }

  //
  // Type information is discarded when transforming from memSchema to
  // schema, so force this bit to true.
  //
  schema.relaxTypeChecks = true;
  schema.rootLayout = memSchema.getRootLayoutId();
}

} // namespace schema
} // namespace frozen
} // namespace thrift
} // namespace apache
<commit_msg>fix violation of -Werror=sign-compare in MemorySchema<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <thrift/lib/cpp2/frozen/schema/MemorySchema.h>

#include <limits>

#include <folly/Utility.h>

THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemoryField)
THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemoryLayoutBase)
THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemoryLayout)
THRIFT_IMPL_HASH(apache::thrift::frozen::schema::MemorySchema)

namespace apache {
namespace thrift {
namespace frozen {
namespace schema {

int16_t MemorySchema::Helper::add(MemoryLayout&& layout) {
  // Add distinct layout, bounds check layoutId
  size_t layoutId = layoutTable_.add(std::move(layout));
  CHECK_LE(layoutId, folly::to_unsigned(std::numeric_limits<int16_t>::max()))
      << "Layout overflow";
  return static_cast<int16_t>(layoutId);
}

void MemorySchema::initFromSchema(Schema&& schema) {
  if (!schema.layouts.empty()) {
    layouts.resize(schema.layouts.size());

    for (const auto& layoutKvp : schema.layouts) {
      const auto id = layoutKvp.first;
      const auto& layout = layoutKvp.second;

      // Note: This will throw if there are any id >=
      // schema.layouts.size().
      auto& memLayout = layouts.at(id);

      memLayout.setSize(layout.size);
      memLayout.setBits(layout.bits);

      for (const auto& fieldKvp : layout.fields) {
        MemoryField memField;
        const auto& fieldId = fieldKvp.first;
        const auto& field = fieldKvp.second;

        memField.setId(fieldId);
        memField.setLayoutId(field.layoutId);
        memField.setOffset(field.offset);
        memLayout.addField(std::move(memField));
      }
    }
  }
  setRootLayoutId(schema.rootLayout);
}

void convert(Schema&& schema, MemorySchema& memSchema) {
  memSchema.initFromSchema(std::move(schema));
}

void convert(const MemorySchema& memSchema, Schema& schema) {
  std::size_t i = 0;
  for (const auto& memLayout : memSchema.getLayouts()) {
    auto& newLayout = schema.layouts[i];

    newLayout.size = memLayout.getSize();
    newLayout.bits = memLayout.getBits();

    for (const auto& field : memLayout.getFields()) {
      auto& newField = newLayout.fields[field.getId()];

      newField.layoutId = field.getLayoutId();
      newField.offset = field.getOffset();
    }
    ++i;
  }

  //
  // Type information is discarded when transforming from memSchema to
  // schema, so force this bit to true.
  //
  schema.relaxTypeChecks = true;
  schema.rootLayout = memSchema.getRootLayoutId();
}

} // namespace schema
} // namespace frozen
} // namespace thrift
} // namespace apache
<|endoftext|>


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

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "vtkChartHistogramColorOpacityEditor.h"

#include <vtkAxis.h>
#include <vtkChart.h>
#include <vtkColorTransferFunction.h>
#include <vtkColorTransferFunctionItem.h>
#include <vtkColorTransferControlPointsItem.h>
#include <vtkContextItem.h>
#include <vtkContextScene.h>
#include <vtkObjectFactory.h>
#include <vtkPiecewiseFunction.h>
#include <vtkScalarsToColors.h>
#include <vtkSmartPointer.h>
#include <vtkTable.h>
#include <vtkVector.h>

#include "vtkChartHistogram.h"

class vtkChartHistogramColorOpacityEditor::PIMPL
{
public:
  PIMPL() : Geometry(0, 0), NeedsUpdate(true) {}
  ~PIMPL() {}

  void ForwardEvent(vtkObject* vtkNotUsed(object),
                    unsigned long eventId,
                    void * vtkNotUsed(data))
  {
    this->Self->InvokeEvent(eventId);
  }

  // Cached geometry of the chart
  vtkVector2i Geometry;

  // Dirty bit
  bool NeedsUpdate;

  // Reference to owner of the PIMPL
  vtkChartHistogramColorOpacityEditor* Self;
};

vtkStandardNewMacro(vtkChartHistogramColorOpacityEditor)

vtkChartHistogramColorOpacityEditor::vtkChartHistogramColorOpacityEditor()
{
  this->Private = new PIMPL();
  this->Private->Self = this;

  this->Borders[vtkAxis::LEFT] = 8;
  this->Borders[vtkAxis::BOTTOM] = 8;
  this->Borders[vtkAxis::RIGHT] = 8;
  this->Borders[vtkAxis::TOP] = 20;

  this->HistogramChart->SetHiddenAxisBorder(10);
  this->HistogramChart->SetLayoutStrategy(vtkChart::AXES_TO_RECT);

  this->ColorTransferFunctionChart->SetBarWidthFraction(1.0);
  this->ColorTransferFunctionChart->SetHiddenAxisBorder(8);
  this->ColorTransferFunctionChart->SetRenderEmpty(true);
  this->ColorTransferFunctionChart->SetAutoAxes(false);
  this->ColorTransferFunctionChart->ZoomWithMouseWheelOff();
  this->ColorTransferFunctionChart->SetLayoutStrategy(vtkChart::AXES_TO_RECT);

  this->ColorTransferFunctionItem->SelectableOff();

  this->ColorTransferControlPointsItem->SetEndPointsXMovable(false);
  this->ColorTransferControlPointsItem->SetEndPointsYMovable(true);
  this->ColorTransferControlPointsItem->SetEndPointsRemovable(false);
  this->ColorTransferControlPointsItem->SelectableOff();

  this->ColorTransferFunctionChart->AddPlot(this->ColorTransferFunctionItem.Get());
  this->ColorTransferFunctionChart->SetPlotCorner(this->ColorTransferFunctionItem.Get(), 1);
  this->ColorTransferFunctionChart->AddPlot(this->ColorTransferControlPointsItem.Get());
  this->ColorTransferFunctionChart->SetPlotCorner(this->ColorTransferControlPointsItem.Get(), 1);

  vtkAxis* bottomAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::BOTTOM);
  bottomAxis->SetTitle("");
  bottomAxis->SetBehavior(vtkAxis::FIXED);
  bottomAxis->SetVisible(false);
  bottomAxis->SetRange(0, 255);

  vtkAxis* leftAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::LEFT);
  leftAxis->SetTitle("");
  leftAxis->SetBehavior(vtkAxis::FIXED);
  leftAxis->SetVisible(false);

  vtkAxis* topAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::TOP);
  topAxis->SetVisible(false);

  this->AddItem(this->HistogramChart.Get());
  this->AddItem(this->ColorTransferFunctionChart.Get());

  // Forward events from internal charts to observers of this object
  this->HistogramChart->
    AddObserver(vtkCommand::CursorChangedEvent, this->Private, &PIMPL::ForwardEvent);
  this->ColorTransferControlPointsItem->
    AddObserver(vtkCommand::EndEvent, this->Private, &PIMPL::ForwardEvent);
  this->ColorTransferControlPointsItem->
    AddObserver(vtkControlPointsItem::CurrentPointEditEvent,
                this->Private, &PIMPL::ForwardEvent);
}

vtkChartHistogramColorOpacityEditor::~vtkChartHistogramColorOpacityEditor()
{
  delete this->Private;
}

void vtkChartHistogramColorOpacityEditor::SetHistogramInputData(vtkTable* table,
                                                                const char* xAxisColumn,
                                                                const char* yAxisColumn)
{
  this->HistogramChart->SetHistogramInputData(table, xAxisColumn, yAxisColumn);

  // The data range may change and cause the labels to change. Hence, update
  // the geometry.
  this->Private->NeedsUpdate = true;
}

void vtkChartHistogramColorOpacityEditor::SetColorTransferFunction(vtkColorTransferFunction* ctf)
{
  this->HistogramChart->SetLookupTable(ctf);
  this->ColorTransferFunctionItem->SetColorTransferFunction(ctf);
  this->ColorTransferControlPointsItem->SetColorTransferFunction(ctf);
}

void vtkChartHistogramColorOpacityEditor::SetScalarVisibility(bool visible)
{
  this->HistogramChart->SetScalarVisibility(visible);
}

void vtkChartHistogramColorOpacityEditor::ScalarVisibilityOn()
{
  this->HistogramChart->SetScalarVisibility(true);
}

void vtkChartHistogramColorOpacityEditor::ScalarVisibilityOff()
{
  this->HistogramChart->SetScalarVisibility(false);
}

void vtkChartHistogramColorOpacityEditor::SelectColorArray(const char* arrayName)
{
  this->HistogramChart->SelectColorArray(arrayName);
}

void vtkChartHistogramColorOpacityEditor::SetOpacityFunction(vtkPiecewiseFunction* opacityFunction)
{
  this->HistogramChart->SetOpacityFunction(opacityFunction);
}

vtkAxis* vtkChartHistogramColorOpacityEditor::GetHistogramAxis(int axis)
{
  return this->HistogramChart->GetAxis(axis);
}

bool vtkChartHistogramColorOpacityEditor::GetCurrentControlPointColor(double rgb[3])
{
  vtkColorTransferFunction* ctf =
    this->ColorTransferControlPointsItem->GetColorTransferFunction();
  if (!ctf)
  {
    return false;
  }

  vtkIdType currentIdx = this->ColorTransferControlPointsItem->GetCurrentPoint();
  if (currentIdx < 0)
  {
    return false;
  }

  double xrgbms[6];
  ctf->GetNodeValue(currentIdx, xrgbms);
  rgb[0] = xrgbms[1];
  rgb[1] = xrgbms[2];
  rgb[2] = xrgbms[3];

  return true;
}

void vtkChartHistogramColorOpacityEditor::SetCurrentControlPointColor(const double rgb[3])
{
  vtkColorTransferFunction* ctf =
    this->ColorTransferControlPointsItem->GetColorTransferFunction();
  if (!ctf)
  {
    return;
  }

  vtkIdType currentIdx = this->ColorTransferControlPointsItem->GetCurrentPoint();
  if (currentIdx < 0)
  {
    return;
  }

  double xrgbms[6];
  ctf->GetNodeValue(currentIdx, xrgbms);
  xrgbms[1] = rgb[0];
  xrgbms[2] = rgb[1];
  xrgbms[3] = rgb[2];
  ctf->SetNodeValue(currentIdx, xrgbms);
}

double vtkChartHistogramColorOpacityEditor::GetContourValue()
{
  return this->HistogramChart->GetContourValue();
}

bool vtkChartHistogramColorOpacityEditor::Paint(vtkContext2D* painter)
{
  vtkContextScene* scene = this->GetScene();
  int sceneWidth = scene->GetSceneWidth();
  int sceneHeight = scene->GetSceneHeight();
  if (this->Private->NeedsUpdate ||
      sceneWidth != this->Private->Geometry.GetX() ||
      sceneHeight != this->Private->Geometry.GetY())
  {
    this->Private->NeedsUpdate = false;

    // Update the geometry size cache
    this->Private->Geometry.Set(sceneWidth, sceneHeight);

    // Upper chart (histogram) expands, lower chart (color bar) is fixed height.
    float x = this->Borders[vtkAxis::LEFT];
    float y = this->Borders[vtkAxis::BOTTOM];

    // Add the width of the left axis to x to make room for y labels
    this->GetHistogramAxis(vtkAxis::LEFT)->Update();
    float leftAxisWidth = this->GetHistogramAxis(vtkAxis::LEFT)->
      GetBoundingRect(painter).GetWidth();
    x += leftAxisWidth;

    float colorBarThickness = 20;
    float plotWidth = sceneWidth - x - this->Borders[vtkAxis::RIGHT];

    vtkRectf colorTransferFunctionChartSize(x, y, plotWidth, colorBarThickness);
    this->ColorTransferFunctionChart->SetSize(colorTransferFunctionChartSize);

    float bottomAxisHeight = this->GetHistogramAxis(vtkAxis::BOTTOM)->
      GetBoundingRect(painter).GetHeight();
    float verticalMargin = bottomAxisHeight;
    y += colorBarThickness + verticalMargin - 5;
    vtkRectf histogramChart(x, y, plotWidth, sceneHeight - y - this->Borders[vtkAxis::TOP]);
    this->HistogramChart->SetSize(histogramChart);
  }

  return this->Superclass::Paint(painter);
}
<commit_msg>Synchronize color bar x-range with histogram x-range<commit_after>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/
#include "vtkChartHistogramColorOpacityEditor.h"

#include <vtkAxis.h>
#include <vtkChart.h>
#include <vtkColorTransferFunction.h>
#include <vtkColorTransferFunctionItem.h>
#include <vtkColorTransferControlPointsItem.h>
#include <vtkContextItem.h>
#include <vtkContextScene.h>
#include <vtkObjectFactory.h>
#include <vtkPiecewiseFunction.h>
#include <vtkScalarsToColors.h>
#include <vtkSmartPointer.h>
#include <vtkTable.h>
#include <vtkVector.h>

#include "vtkChartHistogram.h"

class vtkChartHistogramColorOpacityEditor::PIMPL
{
public:
  PIMPL() : Geometry(0, 0), NeedsUpdate(true) {}
  ~PIMPL() {}

  void ForwardEvent(vtkObject* vtkNotUsed(object),
                    unsigned long eventId,
                    void * vtkNotUsed(data))
  {
    this->Self->InvokeEvent(eventId);
  }

  // Cached geometry of the chart
  vtkVector2i Geometry;

  // Dirty bit
  bool NeedsUpdate;

  // Reference to owner of the PIMPL
  vtkChartHistogramColorOpacityEditor* Self;
};

vtkStandardNewMacro(vtkChartHistogramColorOpacityEditor)

vtkChartHistogramColorOpacityEditor::vtkChartHistogramColorOpacityEditor()
{
  this->Private = new PIMPL();
  this->Private->Self = this;

  this->Borders[vtkAxis::LEFT] = 8;
  this->Borders[vtkAxis::BOTTOM] = 8;
  this->Borders[vtkAxis::RIGHT] = 8;
  this->Borders[vtkAxis::TOP] = 20;

  this->HistogramChart->SetHiddenAxisBorder(10);
  this->HistogramChart->SetLayoutStrategy(vtkChart::AXES_TO_RECT);

  this->ColorTransferFunctionChart->SetBarWidthFraction(1.0);
  this->ColorTransferFunctionChart->SetHiddenAxisBorder(8);
  this->ColorTransferFunctionChart->SetRenderEmpty(true);
  this->ColorTransferFunctionChart->SetAutoAxes(false);
  this->ColorTransferFunctionChart->ZoomWithMouseWheelOff();
  this->ColorTransferFunctionChart->SetLayoutStrategy(vtkChart::AXES_TO_RECT);

  this->ColorTransferFunctionItem->SelectableOff();

  this->ColorTransferControlPointsItem->SetEndPointsXMovable(false);
  this->ColorTransferControlPointsItem->SetEndPointsYMovable(true);
  this->ColorTransferControlPointsItem->SetEndPointsRemovable(false);
  this->ColorTransferControlPointsItem->SelectableOff();

  this->ColorTransferFunctionChart->AddPlot(this->ColorTransferFunctionItem.Get());
  this->ColorTransferFunctionChart->SetPlotCorner(this->ColorTransferFunctionItem.Get(), 1);
  this->ColorTransferFunctionChart->AddPlot(this->ColorTransferControlPointsItem.Get());
  this->ColorTransferFunctionChart->SetPlotCorner(this->ColorTransferControlPointsItem.Get(), 1);

  vtkAxis* bottomAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::BOTTOM);
  bottomAxis->SetTitle("");
  bottomAxis->SetBehavior(vtkAxis::FIXED);
  bottomAxis->SetVisible(false);
  bottomAxis->SetRange(0, 255);

  vtkAxis* leftAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::LEFT);
  leftAxis->SetTitle("");
  leftAxis->SetBehavior(vtkAxis::FIXED);
  leftAxis->SetVisible(false);

  vtkAxis* topAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::TOP);
  topAxis->SetVisible(false);

  this->AddItem(this->HistogramChart.Get());
  this->AddItem(this->ColorTransferFunctionChart.Get());

  // Forward events from internal charts to observers of this object
  this->HistogramChart->
    AddObserver(vtkCommand::CursorChangedEvent, this->Private, &PIMPL::ForwardEvent);
  this->ColorTransferControlPointsItem->
    AddObserver(vtkCommand::EndEvent, this->Private, &PIMPL::ForwardEvent);
  this->ColorTransferControlPointsItem->
    AddObserver(vtkControlPointsItem::CurrentPointEditEvent,
                this->Private, &PIMPL::ForwardEvent);
}

vtkChartHistogramColorOpacityEditor::~vtkChartHistogramColorOpacityEditor()
{
  delete this->Private;
}

void vtkChartHistogramColorOpacityEditor::SetHistogramInputData(vtkTable* table,
                                                                const char* xAxisColumn,
                                                                const char* yAxisColumn)
{
  this->HistogramChart->SetHistogramInputData(table, xAxisColumn, yAxisColumn);

  // The histogram chart bottom axis range was updated in the call above.
  // Set the same range for the color bar bottom axis here.
  vtkAxis* histogramBottomAxis = this->HistogramChart->GetAxis(vtkAxis::BOTTOM);
  double axisRange[2];
  histogramBottomAxis->GetRange(axisRange);

  vtkAxis* bottomAxis = this->ColorTransferFunctionChart->GetAxis(vtkAxis::BOTTOM);
  bottomAxis->SetRange(axisRange);

  // The data range may change and cause the labels to change. Hence, update
  // the geometry.
  this->Private->NeedsUpdate = true;
}

void vtkChartHistogramColorOpacityEditor::SetColorTransferFunction(vtkColorTransferFunction* ctf)
{
  this->HistogramChart->SetLookupTable(ctf);
  this->ColorTransferFunctionItem->SetColorTransferFunction(ctf);
  this->ColorTransferControlPointsItem->SetColorTransferFunction(ctf);
}

void vtkChartHistogramColorOpacityEditor::SetScalarVisibility(bool visible)
{
  this->HistogramChart->SetScalarVisibility(visible);
}

void vtkChartHistogramColorOpacityEditor::ScalarVisibilityOn()
{
  this->HistogramChart->SetScalarVisibility(true);
}

void vtkChartHistogramColorOpacityEditor::ScalarVisibilityOff()
{
  this->HistogramChart->SetScalarVisibility(false);
}

void vtkChartHistogramColorOpacityEditor::SelectColorArray(const char* arrayName)
{
  this->HistogramChart->SelectColorArray(arrayName);
}

void vtkChartHistogramColorOpacityEditor::SetOpacityFunction(vtkPiecewiseFunction* opacityFunction)
{
  this->HistogramChart->SetOpacityFunction(opacityFunction);
}

vtkAxis* vtkChartHistogramColorOpacityEditor::GetHistogramAxis(int axis)
{
  return this->HistogramChart->GetAxis(axis);
}

bool vtkChartHistogramColorOpacityEditor::GetCurrentControlPointColor(double rgb[3])
{
  vtkColorTransferFunction* ctf =
    this->ColorTransferControlPointsItem->GetColorTransferFunction();
  if (!ctf)
  {
    return false;
  }

  vtkIdType currentIdx = this->ColorTransferControlPointsItem->GetCurrentPoint();
  if (currentIdx < 0)
  {
    return false;
  }

  double xrgbms[6];
  ctf->GetNodeValue(currentIdx, xrgbms);
  rgb[0] = xrgbms[1];
  rgb[1] = xrgbms[2];
  rgb[2] = xrgbms[3];

  return true;
}

void vtkChartHistogramColorOpacityEditor::SetCurrentControlPointColor(const double rgb[3])
{
  vtkColorTransferFunction* ctf =
    this->ColorTransferControlPointsItem->GetColorTransferFunction();
  if (!ctf)
  {
    return;
  }

  vtkIdType currentIdx = this->ColorTransferControlPointsItem->GetCurrentPoint();
  if (currentIdx < 0)
  {
    return;
  }

  double xrgbms[6];
  ctf->GetNodeValue(currentIdx, xrgbms);
  xrgbms[1] = rgb[0];
  xrgbms[2] = rgb[1];
  xrgbms[3] = rgb[2];
  ctf->SetNodeValue(currentIdx, xrgbms);
}

double vtkChartHistogramColorOpacityEditor::GetContourValue()
{
  return this->HistogramChart->GetContourValue();
}

bool vtkChartHistogramColorOpacityEditor::Paint(vtkContext2D* painter)
{
  vtkContextScene* scene = this->GetScene();
  int sceneWidth = scene->GetSceneWidth();
  int sceneHeight = scene->GetSceneHeight();
  if (this->Private->NeedsUpdate ||
      sceneWidth != this->Private->Geometry.GetX() ||
      sceneHeight != this->Private->Geometry.GetY())
  {
    this->Private->NeedsUpdate = false;

    // Update the geometry size cache
    this->Private->Geometry.Set(sceneWidth, sceneHeight);

    // Upper chart (histogram) expands, lower chart (color bar) is fixed height.
    float x = this->Borders[vtkAxis::LEFT];
    float y = this->Borders[vtkAxis::BOTTOM];

    // Add the width of the left axis to x to make room for y labels
    this->GetHistogramAxis(vtkAxis::LEFT)->Update();
    float leftAxisWidth = this->GetHistogramAxis(vtkAxis::LEFT)->
      GetBoundingRect(painter).GetWidth();
    x += leftAxisWidth;

    float colorBarThickness = 20;
    float plotWidth = sceneWidth - x - this->Borders[vtkAxis::RIGHT];

    vtkRectf colorTransferFunctionChartSize(x, y, plotWidth, colorBarThickness);
    this->ColorTransferFunctionChart->SetSize(colorTransferFunctionChartSize);

    float bottomAxisHeight = this->GetHistogramAxis(vtkAxis::BOTTOM)->
      GetBoundingRect(painter).GetHeight();
    float verticalMargin = bottomAxisHeight;
    y += colorBarThickness + verticalMargin - 5;
    vtkRectf histogramChart(x, y, plotWidth, sceneHeight - y - this->Borders[vtkAxis::TOP]);
    this->HistogramChart->SetSize(histogramChart);
  }

  return this->Superclass::Paint(painter);
}
<|endoftext|>


<commit_before>// Copyright 2013-2015 Eric Schkufza, Rahul Sharma, Berkeley Churchill, Stefan Heule
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cassert>

#include "src/solver/z3solver.h"
#include "src/verifier/verifier.h"
#include "src/validator/validator.h"

using namespace std;

namespace stoke {

bool Verifier::verify(const Cfg& target, const Cfg& rewrite) {
  switch (strategy_) {
  case Strategy::NONE:
    counter_example_available_ = false;
    return true;
  case Strategy::HOLD_OUT:
    return hold_out_verify(target, rewrite);
  case Strategy::FORMAL:
    return formal_verify(target, rewrite);
  case Strategy::EXTENSION:
    return extension_verify(target, rewrite);
  default:
    assert(false);
    return false;
  }
}

bool Verifier::hold_out_verify(const Cfg& target, const Cfg& rewrite) {
  // Don't set a max value here; we're okay with performance costs
  error_ = "";
  const auto res = fxn_(rewrite);
  if (!res.first) {
    counter_example_available_ = next_counter_example_ < fxn_.num_testcases();
    counter_example_ = fxn_.get_testcase(next_counter_example_);
    next_counter_example_++;
    return false;
  }
  return true;
}

bool Verifier::formal_verify(const Cfg& target, const Cfg& rewrite) {

  error_ = "";
  CpuState ceg;

  bool success = validator_.validate(target, rewrite, ceg);

  if(validator_.has_error()) {
    error_ = validator_.get_error();
    counter_example_available_ = false;
    return false;
  }

  bool has_ceg = validator_.is_counterexample_valid();
  if (has_ceg) {
    counter_example_available_ = true;
    counter_example_ = ceg;
  } else {
    counter_example_available_ = false;
  }

  return success;
}

bool Verifier::extension_verify(const Cfg& target, const Cfg& rewrite) {
  // Add user-defined implementation here ...

  // Invariant 1. If this method returns false and is able to produce a
  // counter example explaining why, counter_example_available_ should be
  // set to true.

  // Invariant 2. If this method returns false, and it is able (see above),
  // counter_example_ should be set to a CpuState that will cause target and
  // rewrite to produce different values.

  // Invariant 3.  If this method encounters an error, it should set the
  // error_ member variable to a non-empty string; otherwise the error_
  // member should be empty.

  return true;
}

} // namespace stoke

<commit_msg>Don't let stoke_search succeed with no testcases<commit_after>// Copyright 2013-2015 Eric Schkufza, Rahul Sharma, Berkeley Churchill, Stefan Heule
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cassert>

#include "src/solver/z3solver.h"
#include "src/verifier/verifier.h"
#include "src/validator/validator.h"

using namespace std;

namespace stoke {

bool Verifier::verify(const Cfg& target, const Cfg& rewrite) {
  switch (strategy_) {
  case Strategy::NONE:
    counter_example_available_ = false;
    return true;
  case Strategy::HOLD_OUT:
    return hold_out_verify(target, rewrite);
  case Strategy::FORMAL:
    return formal_verify(target, rewrite);
  case Strategy::EXTENSION:
    return extension_verify(target, rewrite);
  default:
    assert(false);
    return false;
  }
}

bool Verifier::hold_out_verify(const Cfg& target, const Cfg& rewrite) {
  if (fxn_.num_testcases() == 0) {
    error_ = "No testcases provided; cannot perform hold-out verification.";
    counter_example_available_ = false;
    return false;
  }
  // Don't set a max value here; we're okay with performance costs
  error_ = "";
  const auto res = fxn_(rewrite);
  if (!res.first) {
    counter_example_available_ = next_counter_example_ < fxn_.num_testcases();
    counter_example_ = fxn_.get_testcase(next_counter_example_);
    next_counter_example_++;
    return false;
  }
  return true;
}

bool Verifier::formal_verify(const Cfg& target, const Cfg& rewrite) {

  error_ = "";
  CpuState ceg;

  bool success = validator_.validate(target, rewrite, ceg);

  if(validator_.has_error()) {
    error_ = validator_.get_error();
    counter_example_available_ = false;
    return false;
  }

  bool has_ceg = validator_.is_counterexample_valid();
  if (has_ceg) {
    counter_example_available_ = true;
    counter_example_ = ceg;
  } else {
    counter_example_available_ = false;
  }

  return success;
}

bool Verifier::extension_verify(const Cfg& target, const Cfg& rewrite) {
  // Add user-defined implementation here ...

  // Invariant 1. If this method returns false and is able to produce a
  // counter example explaining why, counter_example_available_ should be
  // set to true.

  // Invariant 2. If this method returns false, and it is able (see above),
  // counter_example_ should be set to a CpuState that will cause target and
  // rewrite to produce different values.

  // Invariant 3.  If this method encounters an error, it should set the
  // error_ member variable to a non-empty string; otherwise the error_
  // member should be empty.

  return true;
}

} // namespace stoke

<|endoftext|>