tdf#117066 Saving ODT document with ~1500 bookmarks is slow, part 2

Individually, these don't make much difference, but they add up
to a halving the time to save on my machine.

OTempFileService was spending a lot of time in PropertySetMixin doing
UNO reflection.
Re-implement the required property interfaces directly..

Change-Id: I9b6ef439d4c56eb40c1f5d636e3e5cb888d5d4ff
Reviewed-on: https://gerrit.libreoffice.org/70310
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/unotools/source/ucbhelper/XTempFile.hxx b/unotools/source/ucbhelper/XTempFile.hxx
index 43150b6..8a3d9fd 100644
--- a/unotools/source/ucbhelper/XTempFile.hxx
+++ b/unotools/source/ucbhelper/XTempFile.hxx
@@ -39,10 +39,12 @@
typedef ::cppu::WeakImplHelper< css::io::XTempFile
    , css::io::XInputStream
    , css::io::XOutputStream
    , css::io::XTruncate > OTempFileBase;
    , css::io::XTruncate
    , css::beans::XPropertySet
    , css::beans::XFastPropertySet
    , css::beans::XPropertyAccess > OTempFileBase;

class OTempFileService : public OTempFileBase
    , public ::cppu::PropertySetMixin< css::io::XTempFile >
{
protected:
    std::unique_ptr<utl::TempFile> mpTempFile;
@@ -62,12 +64,6 @@
    explicit OTempFileService (css::uno::Reference< css::uno::XComponentContext > const & context);

    //Methods
    //  XInterface
    virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
    virtual void SAL_CALL acquire(  )
        throw () override;
    virtual void SAL_CALL release(  )
        throw () override;
    //  XTypeProvider
    virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes(  ) override;

@@ -97,6 +93,22 @@
    // XTruncate
    virtual void SAL_CALL truncate() override;

    // XPropertySet
    virtual ::css::uno::Reference< ::css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::css::uno::Any& aValue ) override;
    virtual ::css::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) override;
    virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::css::uno::Reference< ::css::beans::XPropertyChangeListener >& xListener ) override;
    virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::css::uno::Reference< ::css::beans::XPropertyChangeListener >& aListener ) override;
    virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::css::uno::Reference< ::css::beans::XVetoableChangeListener >& aListener ) override;
    virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::css::uno::Reference< ::css::beans::XVetoableChangeListener >& aListener ) override;
    // XFastPropertySet
    virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const ::css::uno::Any& aValue ) override;
    virtual ::css::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) override;
    // XPropertyAccess
    virtual ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL getPropertyValues() override;
    virtual void SAL_CALL setPropertyValues( const ::css::uno::Sequence< ::css::beans::PropertyValue >& aProps ) override;


    virtual ~OTempFileService () override;
};
#endif
diff --git a/unotools/source/ucbhelper/xtempfile.cxx b/unotools/source/ucbhelper/xtempfile.cxx
index a8e0771..dc05e41 100644
--- a/unotools/source/ucbhelper/xtempfile.cxx
+++ b/unotools/source/ucbhelper/xtempfile.cxx
@@ -21,6 +21,7 @@
#include <unotoolsservices.hxx>
#include <com/sun/star/io/BufferSizeExceededException.hpp>
#include <com/sun/star/io/NotConnectedException.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <cppuhelper/factory.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/typeprovider.hxx>
@@ -28,13 +29,10 @@
#include <osl/file.hxx>
#include <unotools/configmgr.hxx>
#include <unotools/tempfile.hxx>
#include <cppuhelper/propshlp.hxx>

OTempFileService::OTempFileService(css::uno::Reference< css::uno::XComponentContext > const & context)
: ::cppu::PropertySetMixin< css::io::XTempFile >(
    context
    , static_cast< Implements >( IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET | IMPLEMENTS_PROPERTY_ACCESS )
    , css::uno::Sequence< OUString >() )
, mpStream( nullptr )
OTempFileService::OTempFileService(css::uno::Reference< css::uno::XComponentContext > const &)
: mpStream( nullptr )
, mbRemoveFile( true )
, mbInClosed( false )
, mbOutClosed( false )
@@ -50,26 +48,6 @@
{
}

// XInterface

css::uno::Any SAL_CALL OTempFileService::queryInterface( css::uno::Type const & aType )
{
    css::uno::Any aResult( OTempFileBase::queryInterface( aType ) );
    if (!aResult.hasValue())
        aResult = cppu::PropertySetMixin< css::io::XTempFile >::queryInterface( aType );
    return aResult;
};
void SAL_CALL OTempFileService::acquire(  )
throw ()
{
    OTempFileBase::acquire();
}
void SAL_CALL OTempFileService::release(  )
throw ()
{
    OTempFileBase::release();
}

//  XTypeProvider

css::uno::Sequence< css::uno::Type > SAL_CALL OTempFileService::getTypes(  )
@@ -365,6 +343,105 @@
    checkError();
}

#define PROPERTY_HANDLE_URI 1
#define PROPERTY_HANDLE_REMOVE_FILE 2
#define PROPERTY_HANDLE_RESOURCE_NAME 3

// XPropertySet
::css::uno::Reference< ::css::beans::XPropertySetInfo > OTempFileService::getPropertySetInfo()
{
    // Create a table that map names to index values.
    // attention: properties need to be sorted by name!
    static cppu::OPropertyArrayHelper ourPropertyInfo(
        {
            css::beans::Property( "Uri", PROPERTY_HANDLE_URI, cppu::UnoType<OUString>::get(),
                css::beans::PropertyAttribute::READONLY ),
            css::beans::Property( "RemoveFile", PROPERTY_HANDLE_REMOVE_FILE, cppu::UnoType<bool>::get(),
                0 ),
            css::beans::Property( "ResourceName", PROPERTY_HANDLE_RESOURCE_NAME, cppu::UnoType<OUString>::get(),
                css::beans::PropertyAttribute::READONLY )
        },
        true );
    static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( 
        ::cppu::OPropertySetHelper::createPropertySetInfo( ourPropertyInfo ) );
    return xInfo;
}
void OTempFileService::setPropertyValue( const ::rtl::OUString& aPropertyName, const ::css::uno::Any& aValue )
{
    if ( aPropertyName == "RemoveFile" )
        setRemoveFile( aValue.get<bool>() );
    else
    {
        assert(false);
        throw css::beans::UnknownPropertyException(aPropertyName);
    }
}
::css::uno::Any OTempFileService::getPropertyValue( const ::rtl::OUString& aPropertyName )
{
    if ( aPropertyName == "RemoveFile" )
        return css::uno::Any(getRemoveFile());
    else if ( aPropertyName == "ResourceName" )
        return css::uno::Any(getResourceName());
    else if ( aPropertyName == "Uri" )
        return css::uno::Any(getUri());
    else
    {
        assert(false);
        throw css::beans::UnknownPropertyException(aPropertyName);
    }
}
void OTempFileService::addPropertyChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XPropertyChangeListener >& /*xListener*/ )
{
    assert(false);
}
void OTempFileService::removePropertyChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XPropertyChangeListener >& /*xListener*/ )
{
    assert(false);
}
void OTempFileService::addVetoableChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XVetoableChangeListener >& /*xListener*/ )
{
    assert(false);
}
void OTempFileService::removeVetoableChangeListener( const ::rtl::OUString& /*aPropertyName*/, const ::css::uno::Reference< ::css::beans::XVetoableChangeListener >& /*xListener*/ )
{
    assert(false);
}
// XFastPropertySet
void OTempFileService::setFastPropertyValue( ::sal_Int32 nHandle, const ::css::uno::Any& aValue )
{
    switch (nHandle)
    {
        case PROPERTY_HANDLE_REMOVE_FILE: setRemoveFile( aValue.get<bool>() ); return;
    }
    assert(false);
    throw css::beans::UnknownPropertyException(OUString::number(nHandle));
}
::css::uno::Any OTempFileService::getFastPropertyValue( ::sal_Int32 nHandle )
{
    switch (nHandle)
    {
        case PROPERTY_HANDLE_REMOVE_FILE: return css::uno::Any(getRemoveFile());
        case PROPERTY_HANDLE_RESOURCE_NAME: return css::uno::Any(getResourceName());
        case PROPERTY_HANDLE_URI: return css::uno::Any(getUri());
    }
    assert(false);
    throw css::beans::UnknownPropertyException(OUString::number(nHandle));
}
// XPropertyAccess
::css::uno::Sequence< ::css::beans::PropertyValue > OTempFileService::getPropertyValues()
{
    return {
        css::beans::PropertyValue("Uri", PROPERTY_HANDLE_URI, css::uno::Any(getUri()), css::beans::PropertyState_DEFAULT_VALUE),
        css::beans::PropertyValue("RemoveFile", PROPERTY_HANDLE_REMOVE_FILE, css::uno::Any(getRemoveFile()), css::beans::PropertyState_DEFAULT_VALUE),
        css::beans::PropertyValue("ResourceName", PROPERTY_HANDLE_RESOURCE_NAME, css::uno::Any(getResourceName()), css::beans::PropertyState_DEFAULT_VALUE)
    };
}
void OTempFileService::setPropertyValues( const ::css::uno::Sequence< ::css::beans::PropertyValue >& aProps )
{
    for ( auto const & rPropVal : aProps )
        setPropertyValue( rPropVal.Name, rPropVal.Value );
}

namespace sdecl = ::comphelper::service_decl;
sdecl::class_< OTempFileService> const OTempFileServiceImpl;
const sdecl::ServiceDecl OTempFileServiceDecl(