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

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_
#include <com/sun/star/uno/RuntimeException.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HDL_
#include <com/sun/star/uno/XInterface.hdl>
#endif
#ifndef _COM_SUN_STAR_UNO_GENFUNC_HXX_
#include <com/sun/star/uno/genfunc.hxx>
#endif

namespace com
{
namespace sun
{
namespace star
{
namespace uno
{

//__________________________________________________________________________________________________
inline XInterface * BaseReference::iquery(
    XInterface * pInterface, const Type & rType )
    SAL_THROW( (RuntimeException) )
{
    if (pInterface)
    {
        Any aRet( pInterface->queryInterface( rType ) );
        if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass)
        {
            XInterface * pRet = reinterpret_cast< XInterface * >( aRet.pReserved );
            aRet.pReserved = 0;
            return pRet;
        }
    }
    return 0;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline XInterface * Reference< interface_type >::iquery(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return BaseReference::iquery(pInterface, interface_type::static_type());
}
#ifndef EXCEPTIONS_OFF
extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg(
    typelib_TypeDescriptionReference * pType )
    SAL_THROW_EXTERN_C();
//__________________________________________________________________________________________________
inline XInterface * BaseReference::iquery_throw(
    XInterface * pInterface, const Type & rType )
    SAL_THROW( (RuntimeException) )
{
    XInterface * pQueried = iquery( pInterface, rType );
    if (pQueried)
        return pQueried;
    throw RuntimeException(
        ::rtl::OUString( cppu_unsatisfied_iquery_msg( rType.getTypeLibType() ), SAL_NO_ACQUIRE ),
        Reference< XInterface >( pInterface ) );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline XInterface * Reference< interface_type >::iquery_throw(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return BaseReference::iquery_throw(
        pInterface, interface_type::static_type());
}
#endif

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::~Reference() SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference() SAL_THROW( () )
{
    _pInterface = 0;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    _pInterface = rRef._pInterface;
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface ) SAL_THROW( () )
{
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () )
{
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery( pInterface );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass
                   ? iquery( reinterpret_cast< XInterface * >( rAny.pReserved ) ) : 0);
}
#ifndef EXCEPTIONS_OFF
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery_throw( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery_throw( pInterface );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery_throw( typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass
                                ? reinterpret_cast< XInterface * >( rAny.pReserved ) : 0 );
}
#endif

//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::clear() SAL_THROW( () )
{
    if (_pInterface)
    {
        _pInterface->release();
        _pInterface = 0;
    }
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface ) SAL_THROW( () )
{
    if (pInterface)
        reinterpret_cast< XInterface * >(pInterface)->acquire();
    if (_pInterface)
        _pInterface->release();
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
    return (0 != pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
    return (0 != pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () )
{
    return set( pInterface, SAL_NO_ACQUIRE );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    return set( reinterpret_cast< interface_type * >( rRef._pInterface ) );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set(
        reinterpret_cast< interface_type * >(iquery( pInterface )),
        SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set(
        reinterpret_cast< interface_type * >(iquery( rRef.get() )),
        SAL_NO_ACQUIRE );
}

//______________________________________________________________________________
template< class interface_type >
inline bool Reference< interface_type >::set(
    Any const & rAny, UnoReference_Query )
{
    return set(
        reinterpret_cast< interface_type * >(
            iquery(
                rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE
                ? reinterpret_cast< XInterface * >( rAny.pReserved ) : 0 )),
        SAL_NO_ACQUIRE );
}

#ifndef EXCEPTIONS_OFF
//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::set(
    XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    set( reinterpret_cast< interface_type * >(iquery_throw( pInterface )),
         SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::set(
    const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    set( reinterpret_cast< interface_type * >(iquery_throw( rRef.get() )),
         SAL_NO_ACQUIRE );
}

//______________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::set(
    Any const & rAny, UnoReference_QueryThrow )
{
    set( reinterpret_cast< interface_type * >(
             iquery_throw(
                 rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE
                 ? reinterpret_cast< XInterface * >( rAny.pReserved ) : 0 )),
         SAL_NO_ACQUIRE );
}

#endif

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    interface_type * pInterface ) SAL_THROW( () )
{
    set( pInterface );
    return *this;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    set( reinterpret_cast< interface_type * >( rRef._pInterface ) );
    return *this;
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    const BaseReference & rRef ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >(
        reinterpret_cast< interface_type * >(iquery( rRef.get() )),
        SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >(
        reinterpret_cast< interface_type * >(iquery( pInterface )),
        SAL_NO_ACQUIRE );
}

//##################################################################################################

//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( XInterface * pInterface ) const SAL_THROW( () )
{
    if (_pInterface == pInterface)
        return sal_True;
#ifndef EXCEPTIONS_OFF
    try
    {
#endif
        // only the query to XInterface must return the same pointer if they belong to same objects
        Reference< XInterface > x1( _pInterface, UNO_QUERY );
        Reference< XInterface > x2( pInterface, UNO_QUERY );
        return (x1._pInterface == x2._pInterface);
#ifndef EXCEPTIONS_OFF
    }
    catch (RuntimeException &)
    {
        return sal_False;
    }
#endif
}

//______________________________________________________________________________
inline sal_Bool BaseReference::operator < (
    const BaseReference & rRef ) const SAL_THROW( () )
{
    if (_pInterface == rRef._pInterface)
        return sal_False;
#if ! defined EXCEPTIONS_OFF
    try
    {
#endif
        // only the query to XInterface must return the same pointer:
        Reference< XInterface > x1( _pInterface, UNO_QUERY );
        Reference< XInterface > x2( rRef, UNO_QUERY );
        return (x1._pInterface < x2._pInterface);
#if ! defined EXCEPTIONS_OFF
    }
    catch (RuntimeException &)
    {
        return sal_False;
    }
#endif
}

//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( XInterface * pInterface ) const SAL_THROW( () )
{
    return (! operator == ( pInterface ));
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return operator == ( rRef._pInterface );
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return (! operator == ( rRef._pInterface ));
}

}
}
}
}

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.22.34); FILE MERGED 2005/09/05 13:54:11 rt 1.22.34.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Reference.hxx,v $
 *
 *  $Revision: 1.23 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 08:34:00 $
 *
 *  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 _COM_SUN_STAR_UNO_REFERENCE_HXX_
#define _COM_SUN_STAR_UNO_REFERENCE_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_
#include <com/sun/star/uno/RuntimeException.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HDL_
#include <com/sun/star/uno/XInterface.hdl>
#endif
#ifndef _COM_SUN_STAR_UNO_GENFUNC_HXX_
#include <com/sun/star/uno/genfunc.hxx>
#endif

namespace com
{
namespace sun
{
namespace star
{
namespace uno
{

//__________________________________________________________________________________________________
inline XInterface * BaseReference::iquery(
    XInterface * pInterface, const Type & rType )
    SAL_THROW( (RuntimeException) )
{
    if (pInterface)
    {
        Any aRet( pInterface->queryInterface( rType ) );
        if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass)
        {
            XInterface * pRet = reinterpret_cast< XInterface * >( aRet.pReserved );
            aRet.pReserved = 0;
            return pRet;
        }
    }
    return 0;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline XInterface * Reference< interface_type >::iquery(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return BaseReference::iquery(pInterface, interface_type::static_type());
}
#ifndef EXCEPTIONS_OFF
extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg(
    typelib_TypeDescriptionReference * pType )
    SAL_THROW_EXTERN_C();
//__________________________________________________________________________________________________
inline XInterface * BaseReference::iquery_throw(
    XInterface * pInterface, const Type & rType )
    SAL_THROW( (RuntimeException) )
{
    XInterface * pQueried = iquery( pInterface, rType );
    if (pQueried)
        return pQueried;
    throw RuntimeException(
        ::rtl::OUString( cppu_unsatisfied_iquery_msg( rType.getTypeLibType() ), SAL_NO_ACQUIRE ),
        Reference< XInterface >( pInterface ) );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline XInterface * Reference< interface_type >::iquery_throw(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return BaseReference::iquery_throw(
        pInterface, interface_type::static_type());
}
#endif

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::~Reference() SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference() SAL_THROW( () )
{
    _pInterface = 0;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    _pInterface = rRef._pInterface;
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface ) SAL_THROW( () )
{
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () )
{
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery( pInterface );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass
                   ? iquery( reinterpret_cast< XInterface * >( rAny.pReserved ) ) : 0);
}
#ifndef EXCEPTIONS_OFF
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery_throw( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery_throw( pInterface );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    _pInterface = iquery_throw( typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass
                                ? reinterpret_cast< XInterface * >( rAny.pReserved ) : 0 );
}
#endif

//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::clear() SAL_THROW( () )
{
    if (_pInterface)
    {
        _pInterface->release();
        _pInterface = 0;
    }
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface ) SAL_THROW( () )
{
    if (pInterface)
        reinterpret_cast< XInterface * >(pInterface)->acquire();
    if (_pInterface)
        _pInterface->release();
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
    return (0 != pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
    _pInterface = reinterpret_cast< XInterface * >(pInterface);
    return (0 != pInterface);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, UnoReference_NoAcquire ) SAL_THROW( () )
{
    return set( pInterface, SAL_NO_ACQUIRE );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    return set( reinterpret_cast< interface_type * >( rRef._pInterface ) );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    XInterface * pInterface, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set(
        reinterpret_cast< interface_type * >(iquery( pInterface )),
        SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const BaseReference & rRef, UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set(
        reinterpret_cast< interface_type * >(iquery( rRef.get() )),
        SAL_NO_ACQUIRE );
}

//______________________________________________________________________________
template< class interface_type >
inline bool Reference< interface_type >::set(
    Any const & rAny, UnoReference_Query )
{
    return set(
        reinterpret_cast< interface_type * >(
            iquery(
                rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE
                ? reinterpret_cast< XInterface * >( rAny.pReserved ) : 0 )),
        SAL_NO_ACQUIRE );
}

#ifndef EXCEPTIONS_OFF
//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::set(
    XInterface * pInterface, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    set( reinterpret_cast< interface_type * >(iquery_throw( pInterface )),
         SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::set(
    const BaseReference & rRef, UnoReference_QueryThrow ) SAL_THROW( (RuntimeException) )
{
    set( reinterpret_cast< interface_type * >(iquery_throw( rRef.get() )),
         SAL_NO_ACQUIRE );
}

//______________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::set(
    Any const & rAny, UnoReference_QueryThrow )
{
    set( reinterpret_cast< interface_type * >(
             iquery_throw(
                 rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE
                 ? reinterpret_cast< XInterface * >( rAny.pReserved ) : 0 )),
         SAL_NO_ACQUIRE );
}

#endif

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    interface_type * pInterface ) SAL_THROW( () )
{
    set( pInterface );
    return *this;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    set( reinterpret_cast< interface_type * >( rRef._pInterface ) );
    return *this;
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    const BaseReference & rRef ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >(
        reinterpret_cast< interface_type * >(iquery( rRef.get() )),
        SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >(
        reinterpret_cast< interface_type * >(iquery( pInterface )),
        SAL_NO_ACQUIRE );
}

//##################################################################################################

//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( XInterface * pInterface ) const SAL_THROW( () )
{
    if (_pInterface == pInterface)
        return sal_True;
#ifndef EXCEPTIONS_OFF
    try
    {
#endif
        // only the query to XInterface must return the same pointer if they belong to same objects
        Reference< XInterface > x1( _pInterface, UNO_QUERY );
        Reference< XInterface > x2( pInterface, UNO_QUERY );
        return (x1._pInterface == x2._pInterface);
#ifndef EXCEPTIONS_OFF
    }
    catch (RuntimeException &)
    {
        return sal_False;
    }
#endif
}

//______________________________________________________________________________
inline sal_Bool BaseReference::operator < (
    const BaseReference & rRef ) const SAL_THROW( () )
{
    if (_pInterface == rRef._pInterface)
        return sal_False;
#if ! defined EXCEPTIONS_OFF
    try
    {
#endif
        // only the query to XInterface must return the same pointer:
        Reference< XInterface > x1( _pInterface, UNO_QUERY );
        Reference< XInterface > x2( rRef, UNO_QUERY );
        return (x1._pInterface < x2._pInterface);
#if ! defined EXCEPTIONS_OFF
    }
    catch (RuntimeException &)
    {
        return sal_False;
    }
#endif
}

//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( XInterface * pInterface ) const SAL_THROW( () )
{
    return (! operator == ( pInterface ));
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return operator == ( rRef._pInterface );
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return (! operator == ( rRef._pInterface ));
}

}
}
}
}

#endif
<|endoftext|>


<commit_before>#include "game/skirmish/mapmanager.hpp"

#include <cstdlib>
#include <fstream>
#include <regex>

#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTexture.hpp>

#include "foundation/spritecomponent.hpp"

#include "meta/metamanager.hpp"

#include "engine/board.hpp"
#include "game/constants.hpp"
#include "game/deploymentzone.hpp"
#include "game/skirmish/structure.hpp"
#include "engine/terrain.hpp"

namespace fs = std::experimental::filesystem;

namespace qrw
{

MapManager::MapManager(MetaManager& metaManager)
  : metaManager_(metaManager),
	mapValidator_(new MapValidator())
{
}

MapManager::~MapManager()
{
}

MapDto MapManager::loadMap(
	const std::string& mapName,
	LoadErrors& error)
{
	MapDto mapDto;

	if(!doesMapExist(mapName))
	{
		error = LoadErrors::MAP_NOT_FOUND;
		return mapDto;
	}

	std::vector<YAML::Node> documents = YAML::LoadAllFromFile(getUserMapDir() / convertMapNameToPath(mapName, ".map"));
	if(!mapValidator_->validate(documents))
	{
		error = LoadErrors::MAP_VALIDATION_FAILED;
		return mapDto;
	}

	YAML::Node gameObjectsNode = documents.at(1);

	for(auto node : gameObjectsNode)
	{
		auto gameObject = metaManager_.deserialize(node);

		if(auto zone = dynamic_cast<DeploymentZone*>(gameObject))
		{
			mapDto.deploymentZones.push_back(zone);
		}
		else if(auto board = dynamic_cast<Board*>(gameObject))
		{
			mapDto.board = board;
		}
		else
		{
			std::cerr << "Found unsupported game object in map \'"
					<< mapName << "\': "
				  	<< node[MetaClass::TYPE_NAME_YAML_KEY].as<std::string>() << std::endl << std::flush;
		}
	}

	error = LoadErrors::SUCCESS;
	return mapDto;
}

bool MapManager::doesMapExist(const std::string& mapName)
{
	fs::path mapFilePath = getUserMapDir() / convertMapNameToPath(mapName, ".map");

	return fs::exists(mapFilePath);
}

void MapManager::saveMap(
	const std::string& mapName,
	const MapDto& dto)
{
	const std::string fileName = convertMapNameToPath(mapName, ".map");

	YAML::Emitter yaml;
	yaml << YAML::BeginDoc
		 << YAML::Comment("Description")
		 << YAML::BeginMap
			<< YAML::Key << "name" << YAML::Value << mapName
			<< YAML::Key << "short-description" << YAML::Value << "Here goes the short description"
			<< YAML::Key << "playerCount" << YAML::Value << 2
	    << YAML::EndMap;

	yaml << YAML::BeginDoc
		 << YAML::BeginSeq;
			metaManager_.serialize(dto.board, yaml);
			for(auto& zone : dto.deploymentZones)
				metaManager_.serialize(zone, yaml);
	yaml << YAML::EndSeq;

	std::ofstream mapFile;
	fs::path userMapDir = getUserMapDir();

	if(!fs::exists(userMapDir))
		fs::create_directories(userMapDir);

	mapFile.open(userMapDir / fileName, std::ofstream::out | std::ofstream::trunc);
	mapFile << yaml.c_str() << std::endl;
	mapFile.close();

	createAndSaveMapPreview(mapName, dto);
}

std::vector<std::string> MapManager::getMapList() const
{
	std::vector<std::string> mapNames;

	for(auto& p: fs::directory_iterator(getUserMapDir()))
		mapNames.push_back(convertPathToMapName(p));

	return mapNames;
}

std::string MapManager::convertMapNameToPath(const std::string& mapName, const std::string& extension) const
{
	std::regex whitespaceMatcher("\\s+");
	return std::regex_replace(mapName, whitespaceMatcher, "-") += extension;
}

std::string MapManager::convertPathToMapName(const fs::path& filePath) const
{
	std::regex dashMatcher("-");
	return std::regex_replace(filePath.stem().string(), dashMatcher, " ");
}

void MapManager::createAndSaveMapPreview(const std::string mapName, const MapDto& dto)
{
	sf::RenderTexture renderTexture;
	renderTexture.create(
			static_cast<unsigned int>(dto.board->getWidth() * SQUARE_DIMENSION),
			static_cast<unsigned int>(dto.board->getHeight() * SQUARE_DIMENSION));

	dto.board->getComponent<SpriteComponent>()->render(renderTexture);
	for(auto& structureIter : dto.board->getStructures())
		structureIter.second->getComponent<SpriteComponent>()->render(renderTexture);
	for(auto& terrainIter : dto.board->getTerrains())
		terrainIter.second->getComponent<SpriteComponent>()->render(renderTexture);
	for(auto& deploymentZone : dto.deploymentZones)
		deploymentZone->render(renderTexture);

	renderTexture.display();
	renderTexture.getTexture().copyToImage().saveToFile(getUserMapDir() / (convertMapNameToPath(mapName, ".png")));
}

sf::Texture* MapManager::loadMapPreview(const std::string& mapName)
{
	sf::Texture* image = new sf::Texture();
	fs::path previewPath = getUserMapDir() / (convertMapNameToPath(mapName, ".png"));
	std::cerr << "Loading map preview from '" << previewPath << "'" << std::endl << std::flush;
	if(!image->loadFromFile(previewPath))
		std::cerr << "Failed to load map preview from '" << previewPath << "'" << std::endl << std::flush;

	return image;
}

fs::path MapManager::getUserMapDir() const
{
	return std::string(getenv("HOME")) + "/.qrw/maps";
}

} // namespace qrw
<commit_msg>Only treat files with '.map' extension as maps<commit_after>#include "game/skirmish/mapmanager.hpp"

#include <cstdlib>
#include <fstream>
#include <regex>

#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTexture.hpp>

#include "foundation/spritecomponent.hpp"

#include "meta/metamanager.hpp"

#include "engine/board.hpp"
#include "game/constants.hpp"
#include "game/deploymentzone.hpp"
#include "game/skirmish/structure.hpp"
#include "engine/terrain.hpp"

namespace fs = std::experimental::filesystem;

namespace qrw
{

MapManager::MapManager(MetaManager& metaManager)
  : metaManager_(metaManager),
	mapValidator_(new MapValidator())
{
}

MapManager::~MapManager()
{
}

MapDto MapManager::loadMap(
	const std::string& mapName,
	LoadErrors& error)
{
	MapDto mapDto;

	if(!doesMapExist(mapName))
	{
		error = LoadErrors::MAP_NOT_FOUND;
		return mapDto;
	}

	std::vector<YAML::Node> documents = YAML::LoadAllFromFile(getUserMapDir() / convertMapNameToPath(mapName, ".map"));
	if(!mapValidator_->validate(documents))
	{
		error = LoadErrors::MAP_VALIDATION_FAILED;
		return mapDto;
	}

	YAML::Node gameObjectsNode = documents.at(1);

	for(auto node : gameObjectsNode)
	{
		auto gameObject = metaManager_.deserialize(node);

		if(auto zone = dynamic_cast<DeploymentZone*>(gameObject))
		{
			mapDto.deploymentZones.push_back(zone);
		}
		else if(auto board = dynamic_cast<Board*>(gameObject))
		{
			mapDto.board = board;
		}
		else
		{
			std::cerr << "Found unsupported game object in map \'"
					<< mapName << "\': "
				  	<< node[MetaClass::TYPE_NAME_YAML_KEY].as<std::string>() << std::endl << std::flush;
		}
	}

	error = LoadErrors::SUCCESS;
	return mapDto;
}

bool MapManager::doesMapExist(const std::string& mapName)
{
	fs::path mapFilePath = getUserMapDir() / convertMapNameToPath(mapName, ".map");

	return fs::exists(mapFilePath);
}

void MapManager::saveMap(
	const std::string& mapName,
	const MapDto& dto)
{
	const std::string fileName = convertMapNameToPath(mapName, ".map");

	YAML::Emitter yaml;
	yaml << YAML::BeginDoc
		 << YAML::Comment("Description")
		 << YAML::BeginMap
			<< YAML::Key << "name" << YAML::Value << mapName
			<< YAML::Key << "short-description" << YAML::Value << "Here goes the short description"
			<< YAML::Key << "playerCount" << YAML::Value << 2
	    << YAML::EndMap;

	yaml << YAML::BeginDoc
		 << YAML::BeginSeq;
			metaManager_.serialize(dto.board, yaml);
			for(auto& zone : dto.deploymentZones)
				metaManager_.serialize(zone, yaml);
	yaml << YAML::EndSeq;

	std::ofstream mapFile;
	fs::path userMapDir = getUserMapDir();

	if(!fs::exists(userMapDir))
		fs::create_directories(userMapDir);

	mapFile.open(userMapDir / fileName, std::ofstream::out | std::ofstream::trunc);
	mapFile << yaml.c_str() << std::endl;
	mapFile.close();

	createAndSaveMapPreview(mapName, dto);
}

std::vector<std::string> MapManager::getMapList() const
{
	std::vector<std::string> mapNames;

	for(auto& p : fs::directory_iterator(getUserMapDir()))
	{
		if(p.path().extension().compare(".map") == 0)
			mapNames.push_back(convertPathToMapName(p));
	}

	return mapNames;
}

std::string MapManager::convertMapNameToPath(const std::string& mapName, const std::string& extension) const
{
	std::regex whitespaceMatcher("\\s+");
	return std::regex_replace(mapName, whitespaceMatcher, "-") += extension;
}

std::string MapManager::convertPathToMapName(const fs::path& filePath) const
{
	std::regex dashMatcher("-");
	return std::regex_replace(filePath.stem().string(), dashMatcher, " ");
}

void MapManager::createAndSaveMapPreview(const std::string mapName, const MapDto& dto)
{
	sf::RenderTexture renderTexture;
	renderTexture.create(
			static_cast<unsigned int>(dto.board->getWidth() * SQUARE_DIMENSION),
			static_cast<unsigned int>(dto.board->getHeight() * SQUARE_DIMENSION));

	dto.board->getComponent<SpriteComponent>()->render(renderTexture);
	for(auto& structureIter : dto.board->getStructures())
		structureIter.second->getComponent<SpriteComponent>()->render(renderTexture);
	for(auto& terrainIter : dto.board->getTerrains())
		terrainIter.second->getComponent<SpriteComponent>()->render(renderTexture);
	for(auto& deploymentZone : dto.deploymentZones)
		deploymentZone->render(renderTexture);

	renderTexture.display();
	renderTexture.getTexture().copyToImage().saveToFile(getUserMapDir() / (convertMapNameToPath(mapName, ".png")));
}

sf::Texture* MapManager::loadMapPreview(const std::string& mapName)
{
	sf::Texture* image = new sf::Texture();
	fs::path previewPath = getUserMapDir() / (convertMapNameToPath(mapName, ".png"));
	std::cerr << "Loading map preview from '" << previewPath << "'" << std::endl << std::flush;
	if(!image->loadFromFile(previewPath))
		std::cerr << "Failed to load map preview from '" << previewPath << "'" << std::endl << std::flush;

	return image;
}

fs::path MapManager::getUserMapDir() const
{
	return std::string(getenv("HOME")) + "/.qrw/maps";
}

} // namespace qrw
<|endoftext|>


<commit_before>/*
Copyright (c) 2013, Regents of the University of Alaska

All rights reserved.

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

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of the Geographic Information Network of Alaska nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

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

This code was developed by Dan Stahlke for the Geographic Information Network of Alaska.
*/

#include "common.h"
#include "polygon.h"
#include "debugplot.h"

using namespace dangdal;

void plot_points(const Ring &pl, const std::string &fn);

struct PointStats {
	PointStats() :
		total(0),
		proj_ok(0),
		contained(0)
	{ }

	void printYaml(const char *label) {
		printf("%s:\n", label);
		printf("  total: %zd\n", total);
		printf("  proj_ok: %zd\n", proj_ok);
		printf("  contained: %zd\n", contained);
	}

	size_t total;
	size_t proj_ok;
	size_t contained;
};

void usage(const std::string &cmdname) {
	printf("Usage: %s [options] \n", cmdname.c_str());
	printf("  -s_wkt <fn>           File containing WKT of source region\n");
	printf("  -t_bounds_wkt <fn>    File containing WKT for valid region of target SRS (optional)\n");
	printf("  -s_srs <srs_def>      Source SRS\n");
	printf("  -t_srs <srs_def>      Target SRS\n");
	printf("  -report <out.ppm>     Ouput a graphical report (optional)\n");
	printf("\nOutput is the envelope of the source region projected into the target SRS.\n");
	printf("If the -t_bounds_wkt option is given it will be used as a clip mask in the\n");
	printf("projected space.\n");
	printf("\n");

	exit(1);
}

// This function transforms a point, and then as a check transforms it back to
// see if it comes back to the same place.  This allows us to detect cases
// where OCTTransform reports success when really it just returned some
// meaningless result.
bool picky_transform(
	OGRCoordinateTransformationH fwd_xform,
	OGRCoordinateTransformationH inv_xform,
	Vertex *v_in
) {
	// tolerance in meters, could probably be much smaller
	const double toler = 1.0;

	Vertex v_out = *v_in;
	if(!OCTTransform(fwd_xform, 1, &v_out.x, &v_out.y, NULL)) {
		return 0;
	}

	Vertex v_back = v_out;
	if(!OCTTransform(inv_xform, 1, &v_back.x, &v_back.y, NULL)) {
		return 0;
	}

	double err = hypot(v_in->x - v_back.x, v_in->y - v_back.y);
	//fprintf(stderr, "err=%g\n", err);
	if(err > toler) {
		return 0;
	}

	*v_in = v_out;
	return 1;
}

int main(int argc, char **argv) {
	const std::string cmdname = argv[0];
	if(argc == 1) usage(cmdname);
	std::vector<std::string> arg_list = argv_to_list(argc, argv);

	std::string src_wkt_fn;
	std::string t_bounds_wkt_fn;
	std::string s_srs;
	std::string t_srs;
	std::string report_fn;

	size_t argp = 1;
	while(argp < arg_list.size()) {
		const std::string &arg = arg_list[argp++];
		// FIXME - check duplicate values
		if(arg[0] == '-') {
			if(arg == "-v") {
				VERBOSE++;
			} else if(arg == "-s_wkt") {
				if(argp == arg_list.size()) usage(cmdname);
				src_wkt_fn = arg_list[argp++];
			} else if(arg == "-t_bounds_wkt") {
				if(argp == arg_list.size()) usage(cmdname);
				t_bounds_wkt_fn = arg_list[argp++];
			} else if(arg == "-s_srs") {
				if(argp == arg_list.size()) usage(cmdname);
				s_srs = arg_list[argp++];
			} else if(arg == "-t_srs") {
				if(argp == arg_list.size()) usage(cmdname);
				t_srs = arg_list[argp++];
			} else if(arg == "-report") {
				if(argp == arg_list.size()) usage(cmdname);
				report_fn = arg_list[argp++];
			} else {
				usage(cmdname);
			}
		} else {
			usage(cmdname);
		}
	}

	if(src_wkt_fn.empty() || s_srs.empty() || t_srs.empty()) usage(cmdname);

	GDALAllRegister();

	CPLPushErrorHandler(CPLQuietErrorHandler);

	///////////////////////

	OGRSpatialReferenceH s_sref = OSRNewSpatialReference(NULL);
	if(OSRImportFromProj4(s_sref, s_srs.c_str()) != OGRERR_NONE)
		fatal_error("cannot parse proj4 definition for -s_srs");

	OGRSpatialReferenceH t_sref = OSRNewSpatialReference(NULL);
	if(OSRImportFromProj4(t_sref, t_srs.c_str()) != OGRERR_NONE)
		fatal_error("cannot parse proj4 definition for -t_srs");

	OGRCoordinateTransformationH fwd_xform =
		OCTNewCoordinateTransformation(s_sref, t_sref);
	OGRCoordinateTransformationH inv_xform =
		OCTNewCoordinateTransformation(t_sref, s_sref);

	Mpoly src_mp = mpoly_from_wktfile(src_wkt_fn);
	Bbox src_bbox = src_mp.getBbox();

	Mpoly t_bounds_mp;
	bool use_t_bounds;
	Bbox t_bounds_bbox;
	if(t_bounds_wkt_fn.size()) {
		use_t_bounds = 1;
		t_bounds_mp = mpoly_from_wktfile(t_bounds_wkt_fn);
		t_bounds_bbox = t_bounds_mp.getBbox();
	} else {
		use_t_bounds = 0;
	}

	Ring pl;

	PointStats ps_border;
	PointStats ps_interior;
	PointStats ps_bounds;

	// Sample a regular grid of points, take the ones within the source region,
	// and project them to the target projection.  This is done to handle the
	// cases where the projected border does not necessarily encircle the
	// source region (such as would be the case for a source region that
	// encircles the pole with a target lonlat projection).
	int num_grid_steps = 100;
	for(int grid_xi=0; grid_xi<=num_grid_steps; grid_xi++) {
		Vertex src_pt;
		double alpha_x = (double)grid_xi / (double)num_grid_steps;
		src_pt.x = src_bbox.min_x + (src_bbox.max_x - src_bbox.min_x) * alpha_x;
		for(int grid_yi=0; grid_yi<=num_grid_steps; grid_yi++) {
			double alpha_y = (double)grid_yi / (double)num_grid_steps;
			src_pt.y = src_bbox.min_y + (src_bbox.max_y - src_bbox.min_y) * alpha_y;
			if(!src_mp.contains(src_pt)) continue;

			ps_interior.total++;

			Vertex tgt_pt = src_pt;
			if(!picky_transform(fwd_xform, inv_xform, &tgt_pt)) {
				continue;
			}

			ps_interior.proj_ok++;

			if(!use_t_bounds || t_bounds_mp.contains(tgt_pt)) {
				ps_interior.contained++;
				pl.pts.push_back(tgt_pt);
			}
		}
	}

	// Project points along the source region border to the target projection.
	double max_step_len = std::max(
		src_bbox.max_x - src_bbox.min_x,
		src_bbox.max_y - src_bbox.min_y) / 1000.0;
	for(size_t r_idx=0; r_idx<src_mp.rings.size(); r_idx++) {
		const Ring &ring = src_mp.rings[r_idx];
		for(size_t v_idx=0; v_idx<ring.pts.size(); v_idx++) {
			Vertex v1 = ring.pts[v_idx];
			Vertex v2 = ring.pts[(v_idx+1) % ring.pts.size()];
			double dx = v2.x - v1.x;
			double dy = v2.y - v1.y;
			double len = sqrt(dx*dx + dy*dy);
			int num_steps = 1 + (int)(len / max_step_len);
			for(int step=0; step<=num_steps; step++) {
				double alpha = (double)step / (double)num_steps;
				Vertex src_pt;
				src_pt.x = v1.x + dx * alpha;
				src_pt.y = v1.y + dy * alpha;

				ps_border.total++;

				Vertex tgt_pt = src_pt;
				if(!picky_transform(fwd_xform, inv_xform, &tgt_pt)) {
					continue;
				}

				ps_border.proj_ok++;

				if(!use_t_bounds || t_bounds_mp.contains(tgt_pt)) {
					ps_border.contained++;
					pl.pts.push_back(tgt_pt);
				}
			}
		}
	}

	// Take points along the border of the t_bounds clip shape that lie within the
	// source region.
	if(use_t_bounds) {
		double max_step_len = std::max(
			t_bounds_bbox.max_x - t_bounds_bbox.min_x,
			t_bounds_bbox.max_y - t_bounds_bbox.min_y) / 1000.0;
		for(size_t r_idx=0; r_idx<t_bounds_mp.rings.size(); r_idx++) {
			const Ring &ring = t_bounds_mp.rings[r_idx];
			for(size_t v_idx=0; v_idx<ring.pts.size(); v_idx++) {
				Vertex v1 = ring.pts[v_idx];
				Vertex v2 = ring.pts[(v_idx+1) % ring.pts.size()];
				double dx = v2.x - v1.x;
				double dy = v2.y - v1.y;
				double len = sqrt(dx*dx + dy*dy);
				int num_steps = 1 + (int)(len / max_step_len);
				for(int step=0; step<=num_steps; step++) {
					double alpha = (double)step / (double)num_steps;
					Vertex tgt_pt;
					tgt_pt.x = v1.x + dx * alpha;
					tgt_pt.y = v1.y + dy * alpha;

					ps_bounds.total++;

					Vertex src_pt = tgt_pt;
					if(!picky_transform(inv_xform, fwd_xform, &src_pt)) {
						continue;
					}

					ps_bounds.proj_ok++;

					if(src_mp.contains(src_pt)) {
						ps_bounds.contained++;
						pl.pts.push_back(tgt_pt);
					}
				}
			}
		}
	}

	//bool debug = 1;
	//if(debug) {
	//	ps_border.printYaml("stats_border");
	//	ps_interior.printYaml("stats_interior");
	//	ps_bounds.printYaml("stats_bounds");
	//}

	//fprintf(stderr, "got %zd points\n", pl.npts);
	Bbox bbox = pl.getBbox();
	printf("bounds:\n");
	printf("  min_e: %.15f\n", bbox.min_x);
	printf("  min_n: %.15f\n", bbox.min_y);
	printf("  max_e: %.15f\n", bbox.max_x);
	printf("  max_n: %.15f\n", bbox.max_y);

	if(report_fn.size()) plot_points(pl, report_fn);

	return 0;
}

void plot_points(const Ring &pl, const std::string &fn) {
	Bbox bbox = pl.getBbox();
	bbox.min_x -= (bbox.max_x - bbox.min_x) * .05;
	bbox.max_x += (bbox.max_x - bbox.min_x) * .05;
	bbox.min_y -= (bbox.max_y - bbox.min_y) * .05;
	bbox.max_y += (bbox.max_y - bbox.min_y) * .05;
	double W = bbox.max_x - bbox.min_x;
	double H = bbox.max_y - bbox.min_y;
	DebugPlot dbuf(W, H, PLOT_NORMAL);
	for(size_t i=0; i<pl.pts.size(); i++) {
		Vertex v = pl.pts[i];
		double x = v.x - bbox.min_x;
		double y = bbox.max_y - v.y;
		dbuf.plotPoint(x, y, 255, 255, 255);
	}
	dbuf.writePlot(fn);
}
<commit_msg>Fix 'Ouput' typo, replace with 'Output'.<commit_after>/*
Copyright (c) 2013, Regents of the University of Alaska

All rights reserved.

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

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of the Geographic Information Network of Alaska nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

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

This code was developed by Dan Stahlke for the Geographic Information Network of Alaska.
*/

#include "common.h"
#include "polygon.h"
#include "debugplot.h"

using namespace dangdal;

void plot_points(const Ring &pl, const std::string &fn);

struct PointStats {
	PointStats() :
		total(0),
		proj_ok(0),
		contained(0)
	{ }

	void printYaml(const char *label) {
		printf("%s:\n", label);
		printf("  total: %zd\n", total);
		printf("  proj_ok: %zd\n", proj_ok);
		printf("  contained: %zd\n", contained);
	}

	size_t total;
	size_t proj_ok;
	size_t contained;
};

void usage(const std::string &cmdname) {
	printf("Usage: %s [options] \n", cmdname.c_str());
	printf("  -s_wkt <fn>           File containing WKT of source region\n");
	printf("  -t_bounds_wkt <fn>    File containing WKT for valid region of target SRS (optional)\n");
	printf("  -s_srs <srs_def>      Source SRS\n");
	printf("  -t_srs <srs_def>      Target SRS\n");
	printf("  -report <out.ppm>     Output a graphical report (optional)\n");
	printf("\nOutput is the envelope of the source region projected into the target SRS.\n");
	printf("If the -t_bounds_wkt option is given it will be used as a clip mask in the\n");
	printf("projected space.\n");
	printf("\n");

	exit(1);
}

// This function transforms a point, and then as a check transforms it back to
// see if it comes back to the same place.  This allows us to detect cases
// where OCTTransform reports success when really it just returned some
// meaningless result.
bool picky_transform(
	OGRCoordinateTransformationH fwd_xform,
	OGRCoordinateTransformationH inv_xform,
	Vertex *v_in
) {
	// tolerance in meters, could probably be much smaller
	const double toler = 1.0;

	Vertex v_out = *v_in;
	if(!OCTTransform(fwd_xform, 1, &v_out.x, &v_out.y, NULL)) {
		return 0;
	}

	Vertex v_back = v_out;
	if(!OCTTransform(inv_xform, 1, &v_back.x, &v_back.y, NULL)) {
		return 0;
	}

	double err = hypot(v_in->x - v_back.x, v_in->y - v_back.y);
	//fprintf(stderr, "err=%g\n", err);
	if(err > toler) {
		return 0;
	}

	*v_in = v_out;
	return 1;
}

int main(int argc, char **argv) {
	const std::string cmdname = argv[0];
	if(argc == 1) usage(cmdname);
	std::vector<std::string> arg_list = argv_to_list(argc, argv);

	std::string src_wkt_fn;
	std::string t_bounds_wkt_fn;
	std::string s_srs;
	std::string t_srs;
	std::string report_fn;

	size_t argp = 1;
	while(argp < arg_list.size()) {
		const std::string &arg = arg_list[argp++];
		// FIXME - check duplicate values
		if(arg[0] == '-') {
			if(arg == "-v") {
				VERBOSE++;
			} else if(arg == "-s_wkt") {
				if(argp == arg_list.size()) usage(cmdname);
				src_wkt_fn = arg_list[argp++];
			} else if(arg == "-t_bounds_wkt") {
				if(argp == arg_list.size()) usage(cmdname);
				t_bounds_wkt_fn = arg_list[argp++];
			} else if(arg == "-s_srs") {
				if(argp == arg_list.size()) usage(cmdname);
				s_srs = arg_list[argp++];
			} else if(arg == "-t_srs") {
				if(argp == arg_list.size()) usage(cmdname);
				t_srs = arg_list[argp++];
			} else if(arg == "-report") {
				if(argp == arg_list.size()) usage(cmdname);
				report_fn = arg_list[argp++];
			} else {
				usage(cmdname);
			}
		} else {
			usage(cmdname);
		}
	}

	if(src_wkt_fn.empty() || s_srs.empty() || t_srs.empty()) usage(cmdname);

	GDALAllRegister();

	CPLPushErrorHandler(CPLQuietErrorHandler);

	///////////////////////

	OGRSpatialReferenceH s_sref = OSRNewSpatialReference(NULL);
	if(OSRImportFromProj4(s_sref, s_srs.c_str()) != OGRERR_NONE)
		fatal_error("cannot parse proj4 definition for -s_srs");

	OGRSpatialReferenceH t_sref = OSRNewSpatialReference(NULL);
	if(OSRImportFromProj4(t_sref, t_srs.c_str()) != OGRERR_NONE)
		fatal_error("cannot parse proj4 definition for -t_srs");

	OGRCoordinateTransformationH fwd_xform =
		OCTNewCoordinateTransformation(s_sref, t_sref);
	OGRCoordinateTransformationH inv_xform =
		OCTNewCoordinateTransformation(t_sref, s_sref);

	Mpoly src_mp = mpoly_from_wktfile(src_wkt_fn);
	Bbox src_bbox = src_mp.getBbox();

	Mpoly t_bounds_mp;
	bool use_t_bounds;
	Bbox t_bounds_bbox;
	if(t_bounds_wkt_fn.size()) {
		use_t_bounds = 1;
		t_bounds_mp = mpoly_from_wktfile(t_bounds_wkt_fn);
		t_bounds_bbox = t_bounds_mp.getBbox();
	} else {
		use_t_bounds = 0;
	}

	Ring pl;

	PointStats ps_border;
	PointStats ps_interior;
	PointStats ps_bounds;

	// Sample a regular grid of points, take the ones within the source region,
	// and project them to the target projection.  This is done to handle the
	// cases where the projected border does not necessarily encircle the
	// source region (such as would be the case for a source region that
	// encircles the pole with a target lonlat projection).
	int num_grid_steps = 100;
	for(int grid_xi=0; grid_xi<=num_grid_steps; grid_xi++) {
		Vertex src_pt;
		double alpha_x = (double)grid_xi / (double)num_grid_steps;
		src_pt.x = src_bbox.min_x + (src_bbox.max_x - src_bbox.min_x) * alpha_x;
		for(int grid_yi=0; grid_yi<=num_grid_steps; grid_yi++) {
			double alpha_y = (double)grid_yi / (double)num_grid_steps;
			src_pt.y = src_bbox.min_y + (src_bbox.max_y - src_bbox.min_y) * alpha_y;
			if(!src_mp.contains(src_pt)) continue;

			ps_interior.total++;

			Vertex tgt_pt = src_pt;
			if(!picky_transform(fwd_xform, inv_xform, &tgt_pt)) {
				continue;
			}

			ps_interior.proj_ok++;

			if(!use_t_bounds || t_bounds_mp.contains(tgt_pt)) {
				ps_interior.contained++;
				pl.pts.push_back(tgt_pt);
			}
		}
	}

	// Project points along the source region border to the target projection.
	double max_step_len = std::max(
		src_bbox.max_x - src_bbox.min_x,
		src_bbox.max_y - src_bbox.min_y) / 1000.0;
	for(size_t r_idx=0; r_idx<src_mp.rings.size(); r_idx++) {
		const Ring &ring = src_mp.rings[r_idx];
		for(size_t v_idx=0; v_idx<ring.pts.size(); v_idx++) {
			Vertex v1 = ring.pts[v_idx];
			Vertex v2 = ring.pts[(v_idx+1) % ring.pts.size()];
			double dx = v2.x - v1.x;
			double dy = v2.y - v1.y;
			double len = sqrt(dx*dx + dy*dy);
			int num_steps = 1 + (int)(len / max_step_len);
			for(int step=0; step<=num_steps; step++) {
				double alpha = (double)step / (double)num_steps;
				Vertex src_pt;
				src_pt.x = v1.x + dx * alpha;
				src_pt.y = v1.y + dy * alpha;

				ps_border.total++;

				Vertex tgt_pt = src_pt;
				if(!picky_transform(fwd_xform, inv_xform, &tgt_pt)) {
					continue;
				}

				ps_border.proj_ok++;

				if(!use_t_bounds || t_bounds_mp.contains(tgt_pt)) {
					ps_border.contained++;
					pl.pts.push_back(tgt_pt);
				}
			}
		}
	}

	// Take points along the border of the t_bounds clip shape that lie within the
	// source region.
	if(use_t_bounds) {
		double max_step_len = std::max(
			t_bounds_bbox.max_x - t_bounds_bbox.min_x,
			t_bounds_bbox.max_y - t_bounds_bbox.min_y) / 1000.0;
		for(size_t r_idx=0; r_idx<t_bounds_mp.rings.size(); r_idx++) {
			const Ring &ring = t_bounds_mp.rings[r_idx];
			for(size_t v_idx=0; v_idx<ring.pts.size(); v_idx++) {
				Vertex v1 = ring.pts[v_idx];
				Vertex v2 = ring.pts[(v_idx+1) % ring.pts.size()];
				double dx = v2.x - v1.x;
				double dy = v2.y - v1.y;
				double len = sqrt(dx*dx + dy*dy);
				int num_steps = 1 + (int)(len / max_step_len);
				for(int step=0; step<=num_steps; step++) {
					double alpha = (double)step / (double)num_steps;
					Vertex tgt_pt;
					tgt_pt.x = v1.x + dx * alpha;
					tgt_pt.y = v1.y + dy * alpha;

					ps_bounds.total++;

					Vertex src_pt = tgt_pt;
					if(!picky_transform(inv_xform, fwd_xform, &src_pt)) {
						continue;
					}

					ps_bounds.proj_ok++;

					if(src_mp.contains(src_pt)) {
						ps_bounds.contained++;
						pl.pts.push_back(tgt_pt);
					}
				}
			}
		}
	}

	//bool debug = 1;
	//if(debug) {
	//	ps_border.printYaml("stats_border");
	//	ps_interior.printYaml("stats_interior");
	//	ps_bounds.printYaml("stats_bounds");
	//}

	//fprintf(stderr, "got %zd points\n", pl.npts);
	Bbox bbox = pl.getBbox();
	printf("bounds:\n");
	printf("  min_e: %.15f\n", bbox.min_x);
	printf("  min_n: %.15f\n", bbox.min_y);
	printf("  max_e: %.15f\n", bbox.max_x);
	printf("  max_n: %.15f\n", bbox.max_y);

	if(report_fn.size()) plot_points(pl, report_fn);

	return 0;
}

void plot_points(const Ring &pl, const std::string &fn) {
	Bbox bbox = pl.getBbox();
	bbox.min_x -= (bbox.max_x - bbox.min_x) * .05;
	bbox.max_x += (bbox.max_x - bbox.min_x) * .05;
	bbox.min_y -= (bbox.max_y - bbox.min_y) * .05;
	bbox.max_y += (bbox.max_y - bbox.min_y) * .05;
	double W = bbox.max_x - bbox.min_x;
	double H = bbox.max_y - bbox.min_y;
	DebugPlot dbuf(W, H, PLOT_NORMAL);
	for(size_t i=0; i<pl.pts.size(); i++) {
		Vertex v = pl.pts[i];
		double x = v.x - bbox.min_x;
		double y = bbox.max_y - v.y;
		dbuf.plotPoint(x, y, 255, 255, 255);
	}
	dbuf.writePlot(fn);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: proxy.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: svesik $ $Date: 2004-04-21 13:43:44 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/
#if OSL_DEBUG_LEVEL == 0
#  ifndef NDEBUG
#    define NDEBUG
#  endif
#endif
#include <assert.h>
#include <sal/alloca.h>
#include <bridges/remote/proxy.hxx>
#include <bridges/remote/context.h>

#include <uno/data.h>
#include <uno/mapping.hxx>
#include <uno/environment.h>

#include <com/sun/star/uno/Any.hxx>

#include <bridges/remote/bridgeimpl.hxx>

#include "remote_types.hxx"

#if OSL_DEBUG_LEVEL > 1
#include <bridges/remote/counter.hxx>
static MyCounter thisCounter( "DEBUG : Remote2UnoProxy");
#endif

using namespace ::bridges_remote;
using namespace ::com::sun::star::uno;

namespace bridges_remote {

void Remote2UnoProxy::thisFree( uno_ExtEnvironment *pEnvUno , void *pThis )
{
    delete (Remote2UnoProxy*) pThis;
}

void Remote2UnoProxy::thisAcquire( uno_Interface *pThis )
{
    Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
    if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
    {
        p->m_pEnvUno->pExtEnv->registerProxyInterface(
            p->m_pEnvUno->pExtEnv,
            (void**)&pThis,
            Remote2UnoProxy::thisFree,
            p->m_sOid.pData,
            p->m_pType );
        assert( (uno_Interface *)p == pThis );
    }
}

void Remote2UnoProxy::thisRelease( uno_Interface *pThis )
{
    Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
    if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) ))
    {
        p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p );
    }
}

void SAL_CALL remote_release( void *pRemoteI )
{
    ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI );
}

void Remote2UnoProxy::thisDispatch(
    uno_Interface * pUnoI,
    typelib_TypeDescription * pType,
    void * pReturn,
    void * ppArgs[],
    uno_Any ** ppException )
{
    Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI;
    RemoteThreadCounter counter( p->m_pEnvRemote );

    typelib_InterfaceMethodTypeDescription *pMethodType = 0;
    typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
    typelib_TypeDescription *pReturnType = 0;
    typelib_TypeDescription **ppArgType = 0;
    sal_Int32 nArgCount = 0;
    sal_Bool *pbIsIn = 0;
    sal_Bool *pbIsOut = 0;
    sal_Bool *pbConversionNeeded = 0;
    sal_Bool bConversionNeededForReturn = 0;

    //--------------------------------
    // Collect all needed types !
    //--------------------------------
    if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
    {
        pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
        if( pReturn )
        {
            TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
            bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
        }
        else
        {
            nArgCount = 1;
            ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
            pbIsIn  = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
            pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
            pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) );

            pbIsIn[0]  = sal_True;
            pbIsOut[0] = sal_False;
            ppArgType[0] = 0;
            TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
            pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );

        }
    }
    if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
    {
        pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
        TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
        bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
        nArgCount = pMethodType->nParams;
        ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
        pbIsIn  = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
        pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
        pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount );
        sal_Int32 i;
        for( i = 0 ; i < nArgCount ; i ++ )
        {
            ppArgType[i] = 0;
            TYPELIB_DANGER_GET( & (ppArgType[i]) ,  pMethodType->pParams[i].pTypeRef );
            pbIsIn[i]  = pMethodType->pParams[i].bIn;
            pbIsOut[i] = pMethodType->pParams[i].bOut;
            pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
        }
    }

    void *pRemoteReturn = 0;
    if( pReturnType )
    {
        if( bConversionNeededForReturn )
        {
            pRemoteReturn = alloca( pReturnType->nSize );
        }
        else
        {
            pRemoteReturn = pReturn;
        }
    }

    void ** ppRemoteArgs = 0;
    if( nArgCount )
    {
        ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount );
    }

    sal_Int32 i;
    for( i = 0 ; i < nArgCount ; i ++ )
    {
        if( pbConversionNeeded[i] )
        {
            ppRemoteArgs[i] = alloca( ppArgType[i]->nSize );

            if( pbIsIn[i] ) {
                uno_copyAndConvertData(
                    ppRemoteArgs[i],
                    ppArgs[i],
                    ppArgType[i],
                    p->m_mapUno2Remote.get() );
            }
        }
        else
        {
            ppRemoteArgs[i] = ppArgs[i];
        }
    }

    uno_Any any;
    uno_Any *pAny = &any;

    p->m_pRemoteI->pDispatcher( p->m_pRemoteI,
                                pType,
                                pRemoteReturn,
                                ppRemoteArgs,
                                &pAny );

    if( ! pAny )
    {
        if( pReturn && bConversionNeededForReturn )
        {
            uno_copyAndConvertData(
                pReturn ,
                pRemoteReturn,
                pReturnType,
                p->m_mapRemote2Uno.get() );
            uno_destructData( pRemoteReturn , pReturnType , remote_release );
        }

        sal_Int32 i;
        for( i = 0 ; i < nArgCount ; i ++ )
        {
            if( pbConversionNeeded[i] )
            {
                if( pbIsIn[i] ) {
                    if( pbIsOut[i] ) {
                        uno_destructData( ppArgs[i] ,
                                          ppArgType[i] ,
                                          0 );
                        uno_copyAndConvertData( ppArgs[i] ,
                                                ppRemoteArgs[i],
                                                ppArgType[i],
                                                p->m_mapRemote2Uno.get()  );
                    }
                }
                else // pure out
                {
                    uno_copyAndConvertData( ppArgs[i] ,
                                            ppRemoteArgs[i],
                                            ppArgType[i],
                                            p->m_mapRemote2Uno.get() );
                }
                uno_destructData( ppRemoteArgs[i],
                                  ppArgType[i],
                                  remote_release );
            }
        }
        *ppException = 0;
    }
    else
    {
        // -----------------------
        // an exception occured
        // -----------------------
        typelib_TypeDescription *pAnyType = 0;
        getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType );
        uno_copyAndConvertData( *ppException ,
                                pAny ,
                                pAnyType,
                                p->m_mapRemote2Uno.get() );
        uno_destructData( pAny , pAnyType , remote_release );
        typelib_typedescription_release( pAnyType );

        // destruct remote in parameters ( out parameters have not been constructed )
        for( i = 0 ; i < nArgCount ; i ++ )
        {
            if( pbConversionNeeded[i] &&  pbIsIn[i] )
            {
                uno_destructData( ppRemoteArgs[i],
                                  ppArgType[i],
                                  remote_release );
            }
        }
    }

    //--------------------------
    // release all acquired types
    //--------------------------
    if( pReturnType )
    {
        TYPELIB_DANGER_RELEASE( pReturnType );
    }
    for( i = 0 ; i < nArgCount ; i ++ )
    {
        TYPELIB_DANGER_RELEASE( ppArgType[ i] );
    }

}

Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI,
                                  rtl_uString *pOid,
                                  typelib_InterfaceTypeDescription *pType,
                                  uno_Environment *pEnvUno,
                                  uno_Environment *pEnvRemote ) :
    m_sOid( pOid ),
    m_pType( pType ),
    m_pRemoteI( pRemoteI ),
    m_pEnvUno( pEnvUno ),
    m_pEnvRemote( pEnvRemote ),
    m_mapRemote2Uno( pEnvRemote, pEnvUno ),
    m_mapUno2Remote( pEnvUno , pEnvRemote ),
    m_nRef( 1 )
{
    typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType );
    m_pEnvUno->acquire( m_pEnvUno );
    m_pEnvRemote->acquire( m_pEnvRemote );

    acquire = thisAcquire;
    release = thisRelease;
    pDispatcher = ( uno_DispatchMethod ) thisDispatch;

    m_pEnvRemote->pExtEnv->registerInterface(
        m_pEnvRemote->pExtEnv,
        (void**)&m_pRemoteI,
        m_sOid.pData,
        m_pType );
    m_pRemoteI->acquire( m_pRemoteI );

#if OSL_DEBUG_LEVEL > 1
    thisCounter.acquire();
#endif
}

Remote2UnoProxy::~Remote2UnoProxy()
{
    // revoke external ref (oid)
    m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI );

    typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
    m_pRemoteI->release( m_pRemoteI );
    m_pEnvUno->release( m_pEnvUno );
    m_pEnvRemote->release( m_pEnvRemote );
#if OSL_DEBUG_LEVEL > 1
    thisCounter.release();
#endif
}

} // end namespace bridge_remote
<commit_msg>INTEGRATION: CWS ooo19126 (1.9.86); FILE MERGED 2005/09/05 17:07:50 rt 1.9.86.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: proxy.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 22:43:14 $
 *
 *  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
 *
 ************************************************************************/
#if OSL_DEBUG_LEVEL == 0
#  ifndef NDEBUG
#    define NDEBUG
#  endif
#endif
#include <assert.h>
#include <sal/alloca.h>
#include <bridges/remote/proxy.hxx>
#include <bridges/remote/context.h>

#include <uno/data.h>
#include <uno/mapping.hxx>
#include <uno/environment.h>

#include <com/sun/star/uno/Any.hxx>

#include <bridges/remote/bridgeimpl.hxx>

#include "remote_types.hxx"

#if OSL_DEBUG_LEVEL > 1
#include <bridges/remote/counter.hxx>
static MyCounter thisCounter( "DEBUG : Remote2UnoProxy");
#endif

using namespace ::bridges_remote;
using namespace ::com::sun::star::uno;

namespace bridges_remote {

void Remote2UnoProxy::thisFree( uno_ExtEnvironment *pEnvUno , void *pThis )
{
    delete (Remote2UnoProxy*) pThis;
}

void Remote2UnoProxy::thisAcquire( uno_Interface *pThis )
{
    Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
    if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
    {
        p->m_pEnvUno->pExtEnv->registerProxyInterface(
            p->m_pEnvUno->pExtEnv,
            (void**)&pThis,
            Remote2UnoProxy::thisFree,
            p->m_sOid.pData,
            p->m_pType );
        assert( (uno_Interface *)p == pThis );
    }
}

void Remote2UnoProxy::thisRelease( uno_Interface *pThis )
{
    Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
    if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) ))
    {
        p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p );
    }
}

void SAL_CALL remote_release( void *pRemoteI )
{
    ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI );
}

void Remote2UnoProxy::thisDispatch(
    uno_Interface * pUnoI,
    typelib_TypeDescription * pType,
    void * pReturn,
    void * ppArgs[],
    uno_Any ** ppException )
{
    Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI;
    RemoteThreadCounter counter( p->m_pEnvRemote );

    typelib_InterfaceMethodTypeDescription *pMethodType = 0;
    typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
    typelib_TypeDescription *pReturnType = 0;
    typelib_TypeDescription **ppArgType = 0;
    sal_Int32 nArgCount = 0;
    sal_Bool *pbIsIn = 0;
    sal_Bool *pbIsOut = 0;
    sal_Bool *pbConversionNeeded = 0;
    sal_Bool bConversionNeededForReturn = 0;

    //--------------------------------
    // Collect all needed types !
    //--------------------------------
    if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
    {
        pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
        if( pReturn )
        {
            TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
            bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
        }
        else
        {
            nArgCount = 1;
            ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
            pbIsIn  = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
            pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
            pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) );

            pbIsIn[0]  = sal_True;
            pbIsOut[0] = sal_False;
            ppArgType[0] = 0;
            TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
            pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );

        }
    }
    if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
    {
        pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
        TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
        bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
        nArgCount = pMethodType->nParams;
        ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
        pbIsIn  = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
        pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
        pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount );
        sal_Int32 i;
        for( i = 0 ; i < nArgCount ; i ++ )
        {
            ppArgType[i] = 0;
            TYPELIB_DANGER_GET( & (ppArgType[i]) ,  pMethodType->pParams[i].pTypeRef );
            pbIsIn[i]  = pMethodType->pParams[i].bIn;
            pbIsOut[i] = pMethodType->pParams[i].bOut;
            pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
        }
    }

    void *pRemoteReturn = 0;
    if( pReturnType )
    {
        if( bConversionNeededForReturn )
        {
            pRemoteReturn = alloca( pReturnType->nSize );
        }
        else
        {
            pRemoteReturn = pReturn;
        }
    }

    void ** ppRemoteArgs = 0;
    if( nArgCount )
    {
        ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount );
    }

    sal_Int32 i;
    for( i = 0 ; i < nArgCount ; i ++ )
    {
        if( pbConversionNeeded[i] )
        {
            ppRemoteArgs[i] = alloca( ppArgType[i]->nSize );

            if( pbIsIn[i] ) {
                uno_copyAndConvertData(
                    ppRemoteArgs[i],
                    ppArgs[i],
                    ppArgType[i],
                    p->m_mapUno2Remote.get() );
            }
        }
        else
        {
            ppRemoteArgs[i] = ppArgs[i];
        }
    }

    uno_Any any;
    uno_Any *pAny = &any;

    p->m_pRemoteI->pDispatcher( p->m_pRemoteI,
                                pType,
                                pRemoteReturn,
                                ppRemoteArgs,
                                &pAny );

    if( ! pAny )
    {
        if( pReturn && bConversionNeededForReturn )
        {
            uno_copyAndConvertData(
                pReturn ,
                pRemoteReturn,
                pReturnType,
                p->m_mapRemote2Uno.get() );
            uno_destructData( pRemoteReturn , pReturnType , remote_release );
        }

        sal_Int32 i;
        for( i = 0 ; i < nArgCount ; i ++ )
        {
            if( pbConversionNeeded[i] )
            {
                if( pbIsIn[i] ) {
                    if( pbIsOut[i] ) {
                        uno_destructData( ppArgs[i] ,
                                          ppArgType[i] ,
                                          0 );
                        uno_copyAndConvertData( ppArgs[i] ,
                                                ppRemoteArgs[i],
                                                ppArgType[i],
                                                p->m_mapRemote2Uno.get()  );
                    }
                }
                else // pure out
                {
                    uno_copyAndConvertData( ppArgs[i] ,
                                            ppRemoteArgs[i],
                                            ppArgType[i],
                                            p->m_mapRemote2Uno.get() );
                }
                uno_destructData( ppRemoteArgs[i],
                                  ppArgType[i],
                                  remote_release );
            }
        }
        *ppException = 0;
    }
    else
    {
        // -----------------------
        // an exception occured
        // -----------------------
        typelib_TypeDescription *pAnyType = 0;
        getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType );
        uno_copyAndConvertData( *ppException ,
                                pAny ,
                                pAnyType,
                                p->m_mapRemote2Uno.get() );
        uno_destructData( pAny , pAnyType , remote_release );
        typelib_typedescription_release( pAnyType );

        // destruct remote in parameters ( out parameters have not been constructed )
        for( i = 0 ; i < nArgCount ; i ++ )
        {
            if( pbConversionNeeded[i] &&  pbIsIn[i] )
            {
                uno_destructData( ppRemoteArgs[i],
                                  ppArgType[i],
                                  remote_release );
            }
        }
    }

    //--------------------------
    // release all acquired types
    //--------------------------
    if( pReturnType )
    {
        TYPELIB_DANGER_RELEASE( pReturnType );
    }
    for( i = 0 ; i < nArgCount ; i ++ )
    {
        TYPELIB_DANGER_RELEASE( ppArgType[ i] );
    }

}

Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI,
                                  rtl_uString *pOid,
                                  typelib_InterfaceTypeDescription *pType,
                                  uno_Environment *pEnvUno,
                                  uno_Environment *pEnvRemote ) :
    m_sOid( pOid ),
    m_pType( pType ),
    m_pRemoteI( pRemoteI ),
    m_pEnvUno( pEnvUno ),
    m_pEnvRemote( pEnvRemote ),
    m_mapRemote2Uno( pEnvRemote, pEnvUno ),
    m_mapUno2Remote( pEnvUno , pEnvRemote ),
    m_nRef( 1 )
{
    typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType );
    m_pEnvUno->acquire( m_pEnvUno );
    m_pEnvRemote->acquire( m_pEnvRemote );

    acquire = thisAcquire;
    release = thisRelease;
    pDispatcher = ( uno_DispatchMethod ) thisDispatch;

    m_pEnvRemote->pExtEnv->registerInterface(
        m_pEnvRemote->pExtEnv,
        (void**)&m_pRemoteI,
        m_sOid.pData,
        m_pType );
    m_pRemoteI->acquire( m_pRemoteI );

#if OSL_DEBUG_LEVEL > 1
    thisCounter.acquire();
#endif
}

Remote2UnoProxy::~Remote2UnoProxy()
{
    // revoke external ref (oid)
    m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI );

    typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
    m_pRemoteI->release( m_pRemoteI );
    m_pEnvUno->release( m_pEnvUno );
    m_pEnvRemote->release( m_pEnvRemote );
#if OSL_DEBUG_LEVEL > 1
    thisCounter.release();
#endif
}

} // end namespace bridge_remote
<|endoftext|>


<commit_before>/*
    This file is part of Kung.

    Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include <kfiledialog.h>
#include <kio/netaccess.h>
#include <kcodecs.h>
#include <kmessagebox.h>
#include <kmimemagic.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kparts/componentfactory.h>
#include <ktemporaryfile.h>

#include <QFile>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
#include <QWidget>

#include <schema/simpletype.h>

#include "binaryinputfield.h"

BinaryInputField::BinaryInputField( const QString &name, const QString &typeName, const XSD::SimpleType *type )
  : SimpleInputField( name, type ),
    mValue( 0 ), mTypeName( typeName )
{
}

void BinaryInputField::setXMLData( const QDomElement &element )
{
  if ( mName != element.tagName() ) {
    qDebug( "BinaryInputField: Wrong dom element passed: expected %s, got %s", qPrintable( mName ), qPrintable( element.tagName() ) );
    return;
  }

  setData( element.text() );
}

void BinaryInputField::xmlData( QDomDocument &document, QDomElement &parent )
{
  QDomElement element = document.createElement( mName );
  element.setAttribute( "xsi:type", "xsd:" + mTypeName );
  QDomText text = document.createTextNode( data() );
  element.appendChild( text );

  parent.appendChild( element );
}

void BinaryInputField::setData( const QString &data )
{
  KCodecs::base64Decode( data.toUtf8(), mValue );
}

QString BinaryInputField::data() const
{
  QByteArray data = KCodecs::base64Encode( mValue, false );
  return QString::fromUtf8( data.data(), data.size() );
}

QWidget *BinaryInputField::createWidget( QWidget *parent )
{
  mInputWidget = new BinaryWidget( parent );

  if ( !mValue.isEmpty() )
    mInputWidget->setData( mValue );

  return mInputWidget;
}

void BinaryInputField::valueChanged( const QByteArray &value )
{
  mValue = value;

  emit modified();
}

BinaryWidget::BinaryWidget( QWidget *parent )
  : QWidget( parent ),
    mMainWidget( 0 )
{
  setObjectName( "BinaryWidget" );

  mLayout = new QGridLayout( this );
  mLayout->setSpacing( 6 );
  mLayout->setMargin( 11 );

  mLoadButton = new QPushButton( i18n( "Load..." ), this );
  mSaveButton = new QPushButton( i18n( "Save..." ), this );
  mSaveButton->setEnabled( false );

  mLayout->addWidget( mLoadButton, 0, 1 );
  mLayout->addWidget( mSaveButton, 1, 1 );

  connect( mLoadButton, SIGNAL( clicked() ), SLOT( load() ) );
  connect( mSaveButton, SIGNAL( clicked() ), SLOT( save() ) );
}

void BinaryWidget::setData( const QByteArray &data )
{
  KMimeMagic magic;
  QString mimetype;

  delete mMainWidget;

  KMimeMagicResult *result = magic.findBufferType( data );
  if ( result->isValid() )
    mimetype = result->mimeType();

  if ( !mimetype.isEmpty() ) {
    KParts::ReadOnlyPart *part = 0;
    //KParts::ReadOnlyPart *part = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>( mimetype, QString::null, this, 0, this, 0 ); // FIXME: doesn't work
    if ( part ) {
      KTemporaryFile file;
      file.setAutoRemove(false);
      file.open();
      file.write( data );
      file.flush();
      part->openUrl( KUrl( file.fileName() ) );
      mMainWidget = part->widget();
    } else {
      mMainWidget = new QLabel( i18n( "No part found for visualization of mimetype %1", mimetype ), this );
    }

    mData = data;
    mSaveButton->setEnabled( true );
  } else {
    mMainWidget = new QLabel( i18n( "Got data of unknown mimetype" ), this );
  }

  mLayout->addWidget( mMainWidget, 0, 0, 3, 1);
  mMainWidget->show();
}

void BinaryWidget::load()
{
  KUrl url = KFileDialog::getOpenUrl( QString(), QString(), this );
  if ( url.isEmpty() )
    return;

  QString tempFile;
  if ( KIO::NetAccess::download( url, tempFile, this ) ) {
    QFile file( tempFile );
    if ( !file.open( QIODevice::ReadOnly ) ) {
      KMessageBox::error( this, i18n( "Unable to open file %1", url.url() ) );
      return;
    }

    QByteArray data = file.readAll();
    setData( data );

    file.close();
    KIO::NetAccess::removeTempFile( tempFile );

    emit valueChanged( data );
  } else
    KMessageBox::error( this, KIO::NetAccess::lastErrorString() );
}

void BinaryWidget::save()
{
  KUrl url = KFileDialog::getSaveUrl( QString(), QString(), this );
  if ( url.isEmpty() )
    return;

  KTemporaryFile tempFile;
  tempFile.open();
  tempFile.write( mData );
  tempFile.flush();

  if ( !KIO::NetAccess::upload( tempFile.fileName(), url, this ) )
    KMessageBox::error( this, KIO::NetAccess::lastErrorString() );
}

#include "binaryinputfield.moc"
<commit_msg>KMimeMagic -> KMimeType and port the ComponentFactory call.<commit_after>/*
    This file is part of Kung.

    Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include <kfiledialog.h>
#include <kio/netaccess.h>
#include <kcodecs.h>
#include <kmessagebox.h>
#include <kmimetype.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kparts/componentfactory.h>
#include <ktemporaryfile.h>

#include <QFile>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
#include <QWidget>

#include <schema/simpletype.h>

#include "binaryinputfield.h"

BinaryInputField::BinaryInputField( const QString &name, const QString &typeName, const XSD::SimpleType *type )
  : SimpleInputField( name, type ),
    mValue( 0 ), mTypeName( typeName )
{
}

void BinaryInputField::setXMLData( const QDomElement &element )
{
  if ( mName != element.tagName() ) {
    qDebug( "BinaryInputField: Wrong dom element passed: expected %s, got %s", qPrintable( mName ), qPrintable( element.tagName() ) );
    return;
  }

  setData( element.text() );
}

void BinaryInputField::xmlData( QDomDocument &document, QDomElement &parent )
{
  QDomElement element = document.createElement( mName );
  element.setAttribute( "xsi:type", "xsd:" + mTypeName );
  QDomText text = document.createTextNode( data() );
  element.appendChild( text );

  parent.appendChild( element );
}

void BinaryInputField::setData( const QString &data )
{
  KCodecs::base64Decode( data.toUtf8(), mValue );
}

QString BinaryInputField::data() const
{
  QByteArray data = KCodecs::base64Encode( mValue, false );
  return QString::fromUtf8( data.data(), data.size() );
}

QWidget *BinaryInputField::createWidget( QWidget *parent )
{
  mInputWidget = new BinaryWidget( parent );

  if ( !mValue.isEmpty() )
    mInputWidget->setData( mValue );

  return mInputWidget;
}

void BinaryInputField::valueChanged( const QByteArray &value )
{
  mValue = value;

  emit modified();
}

BinaryWidget::BinaryWidget( QWidget *parent )
  : QWidget( parent ),
    mMainWidget( 0 )
{
  setObjectName( "BinaryWidget" );

  mLayout = new QGridLayout( this );
  mLayout->setSpacing( 6 );
  mLayout->setMargin( 11 );

  mLoadButton = new QPushButton( i18n( "Load..." ), this );
  mSaveButton = new QPushButton( i18n( "Save..." ), this );
  mSaveButton->setEnabled( false );

  mLayout->addWidget( mLoadButton, 0, 1 );
  mLayout->addWidget( mSaveButton, 1, 1 );

  connect( mLoadButton, SIGNAL( clicked() ), SLOT( load() ) );
  connect( mSaveButton, SIGNAL( clicked() ), SLOT( save() ) );
}

void BinaryWidget::setData( const QByteArray &data )
{
  delete mMainWidget;

  QString mimetype;
  KMimeType::Ptr mime = KMimeType::findByContent( data );
  if ( mime && !mime->isDefault() )
    mimetype = mime->name();

  if ( !mimetype.isEmpty() ) {
    KParts::ReadOnlyPart *part = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>( mimetype, QString(), this, this );
    if ( part ) {
      KTemporaryFile file;
      file.setAutoRemove(false);
      file.open();
      file.write( data );
      file.flush();
      part->openUrl( KUrl( file.fileName() ) );
      mMainWidget = part->widget();
    } else {
      mMainWidget = new QLabel( i18n( "No part found for visualization of mimetype %1", mimetype ), this );
    }

    mData = data;
    mSaveButton->setEnabled( true );
  } else {
    mMainWidget = new QLabel( i18n( "Got data of unknown mimetype" ), this );
  }

  mLayout->addWidget( mMainWidget, 0, 0, 3, 1);
  mMainWidget->show();
}

void BinaryWidget::load()
{
  KUrl url = KFileDialog::getOpenUrl( QString(), QString(), this );
  if ( url.isEmpty() )
    return;

  QString tempFile;
  if ( KIO::NetAccess::download( url, tempFile, this ) ) {
    QFile file( tempFile );
    if ( !file.open( QIODevice::ReadOnly ) ) {
      KMessageBox::error( this, i18n( "Unable to open file %1", url.url() ) );
      return;
    }

    QByteArray data = file.readAll();
    setData( data );

    file.close();
    KIO::NetAccess::removeTempFile( tempFile );

    emit valueChanged( data );
  } else
    KMessageBox::error( this, KIO::NetAccess::lastErrorString() );
}

void BinaryWidget::save()
{
  KUrl url = KFileDialog::getSaveUrl( QString(), QString(), this );
  if ( url.isEmpty() )
    return;

  KTemporaryFile tempFile;
  tempFile.open();
  tempFile.write( mData );
  tempFile.flush();

  if ( !KIO::NetAccess::upload( tempFile.fileName(), url, this ) )
    KMessageBox::error( this, KIO::NetAccess::lastErrorString() );
}

#include "binaryinputfield.moc"
<|endoftext|>