<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_LINGUISTIC_SOURCE_LNGOPT_HXX
#define INCLUDED_LINGUISTIC_SOURCE_LNGOPT_HXX

#include <cppuhelper/implbase5.hxx>
#include <cppuhelper/interfacecontainer.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/beans/XPropertyAccess.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/linguistic2/XLinguProperties.hpp>
#include <unotools/lingucfg.hxx>
#include <svl/itemprop.hxx>
#include <unotools/configitem.hxx>
#include <unotools/linguprops.hxx>
#include <com/sun/star/uno/Any.h>
#include <tools/solar.h>

#include "linguistic/misc.hxx"
#include "defs.hxx"

namespace com { namespace sun { namespace star {
    namespace beans {
        struct PropertyChangeEvent;
    }
}}}

// LinguOptions
// This class represents all Linguistik relevant options.

class LinguOptions
{
    static SvtLinguOptions     *pData;
    static oslInterlockedCount  nRefCount;  // number of objects of this class

public:
    LinguOptions();
    LinguOptions(const LinguOptions &rOpt);
    ~LinguOptions();

    static OUString    GetName( sal_Int32 nWID );

    const ::com::sun::star::uno::Sequence< OUString >
            GetActiveDics() const   { return pData->aActiveDics; }

    const ::com::sun::star::uno::Sequence< OUString >
            GetActiveConvDics() const   { return pData->aActiveConvDics; }
};

// uses templates from <cppuhelper/interfacecontainer.h>

// helper function call class
struct PropHashType_Impl
{
    size_t operator()(const sal_Int32 &s) const { return s; }
};

typedef cppu::OMultiTypeInterfaceContainerHelperVar
    <
        sal_Int32,
        PropHashType_Impl
    > OPropertyListenerContainerHelper;

class LinguProps :
    public cppu::WeakImplHelper5
    <
        com::sun::star::linguistic2::XLinguProperties,
        com::sun::star::beans::XFastPropertySet,
        com::sun::star::beans::XPropertyAccess,
        com::sun::star::lang::XComponent,
        com::sun::star::lang::XServiceInfo
    >
{
    ::cppu::OInterfaceContainerHelper           aEvtListeners;
    OPropertyListenerContainerHelper            aPropListeners;

    SfxItemPropertyMap                          aPropertyMap;
    SvtLinguConfig                              aConfig;

    sal_Bool                                        bDisposing;

    // disallow copy-constructor and assignment-operator for now
    LinguProps(const LinguProps &);
    LinguProps & operator = (const LinguProps &);

    void    launchEvent( const ::com::sun::star::beans::PropertyChangeEvent &rEvt ) const;

    sal_Bool getPropertyBool(const OUString& aPropertyName) throw (css::uno::RuntimeException);
    sal_Int16 getPropertyInt16(const OUString& aPropertyName) throw (css::uno::RuntimeException);
    css::lang::Locale getPropertyLocale(const OUString& aPropertyName) throw (css::uno::RuntimeException);
    void setProperty(const OUString& aPropertyName, sal_Bool p1) throw (css::uno::RuntimeException)
        { setPropertyValue( aPropertyName, css::uno::Any(p1) ); }
    void setProperty(const OUString& aPropertyName, sal_Int16 p1) throw (css::uno::RuntimeException)
        { setPropertyValue( aPropertyName, css::uno::Any(p1) ); }
    void setProperty(const OUString& aPropertyName, css::lang::Locale p1) throw (css::uno::RuntimeException)
        { setPropertyValue( aPropertyName, css::uno::Any(p1) ); }

public:
    LinguProps();

    virtual sal_Bool SAL_CALL getIsUseDictionaryList() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_USE_DICTIONARY_LIST); }
    virtual void SAL_CALL setIsUseDictionaryList(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_USE_DICTIONARY_LIST, p1); }
    virtual sal_Bool SAL_CALL getIsIgnoreControlCharacters() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_IGNORE_CONTROL_CHARACTERS); }
    virtual void SAL_CALL setIsIgnoreControlCharacters(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_IGNORE_CONTROL_CHARACTERS, p1); }
    virtual sal_Bool SAL_CALL getIsSpellUpperCase() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_UPPER_CASE); }
    virtual void SAL_CALL setIsSpellUpperCase(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_UPPER_CASE, p1); }
    virtual sal_Bool SAL_CALL getIsSpellWithDigits() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_WITH_DIGITS); }
    virtual void SAL_CALL setIsSpellWithDigits(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_WITH_DIGITS, p1); }
    virtual sal_Bool SAL_CALL getIsSpellCapitalization() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_CAPITALIZATION); }
    virtual void SAL_CALL setIsSpellCapitalization(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_CAPITALIZATION, p1); }
    virtual sal_Int16 SAL_CALL getHyphMinLeading() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_HYPH_MIN_LEADING); }
    virtual void SAL_CALL setHyphMinLeading(sal_Int16 p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_HYPH_MIN_LEADING, p1); }
    virtual sal_Int16 SAL_CALL getHyphMinTrailing() throw (css::uno::RuntimeException)
        { return getPropertyInt16(UPN_HYPH_MIN_TRAILING); }
    virtual void SAL_CALL setHyphMinTrailing(sal_Int16 p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_HYPH_MIN_TRAILING, p1); }
    virtual sal_Int16 SAL_CALL getHyphMinWordLength() throw (css::uno::RuntimeException)
        { return getPropertyInt16(UPN_HYPH_MIN_WORD_LENGTH); }
    virtual void SAL_CALL setHyphMinWordLength(sal_Int16 p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_HYPH_MIN_WORD_LENGTH, p1); }
    virtual com::sun::star::lang::Locale SAL_CALL getDefaultLocale() throw (css::uno::RuntimeException)
        { return getPropertyLocale(UPN_DEFAULT_LOCALE); }
    virtual void SAL_CALL setDefaultLocale(const com::sun::star::lang::Locale& p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_DEFAULT_LOCALE, p1); }
    virtual sal_Bool SAL_CALL getIsHyphAuto() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_HYPH_AUTO); }
    virtual void SAL_CALL setIsHyphAuto(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_HYPH_AUTO, p1); }
    virtual sal_Bool SAL_CALL getIsHyphSpecial() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_HYPH_SPECIAL); }
    virtual void SAL_CALL setIsHyphSpecial(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_HYPH_SPECIAL, p1); }
    virtual sal_Bool SAL_CALL getIsSpellAuto() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_AUTO); }
    virtual void SAL_CALL setIsSpellAuto(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_AUTO, p1); }
    virtual sal_Bool SAL_CALL getIsSpellSpecial() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_SPECIAL); }
    virtual void SAL_CALL setIsSpellSpecial(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_SPECIAL, p1); }
    virtual sal_Bool SAL_CALL getIsWrapReverse() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_WRAP_REVERSE); }
    virtual void SAL_CALL setIsWrapReverse(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_WRAP_REVERSE, p1); }
    virtual com::sun::star::lang::Locale SAL_CALL getDefaultLocale_CJK() throw (css::uno::RuntimeException)
        { return getPropertyLocale(UPN_DEFAULT_LOCALE_CJK); }
    virtual void SAL_CALL setDefaultLocale_CJK(const com::sun::star::lang::Locale& p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_DEFAULT_LOCALE_CJK, p1); }
    virtual css::lang::Locale SAL_CALL getDefaultLocale_CTL() throw (css::uno::RuntimeException)
        { return getPropertyLocale(UPN_DEFAULT_LOCALE_CTL); }
    virtual void SAL_CALL setDefaultLocale_CTL(const com::sun::star::lang::Locale& p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_DEFAULT_LOCALE_CTL, p1); }

    // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XFastPropertySet
    virtual void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( sal_Int32 nHandle ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XPropertyAccess
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XComponent
    virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    static inline OUString getImplementationName_Static() throw();
    static com::sun::star::uno::Sequence< OUString > getSupportedServiceNames_Static() throw();
};

inline OUString LinguProps::getImplementationName_Static() throw()
{
    return OUString( "com.sun.star.lingu2.LinguProps" );
}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Resolves: fdo#72464 Character line break is set to 0 Options/.../Writing Aids<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_LINGUISTIC_SOURCE_LNGOPT_HXX
#define INCLUDED_LINGUISTIC_SOURCE_LNGOPT_HXX

#include <cppuhelper/implbase5.hxx>
#include <cppuhelper/interfacecontainer.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/beans/XPropertyAccess.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/linguistic2/XLinguProperties.hpp>
#include <unotools/lingucfg.hxx>
#include <svl/itemprop.hxx>
#include <unotools/configitem.hxx>
#include <unotools/linguprops.hxx>
#include <com/sun/star/uno/Any.h>
#include <tools/solar.h>

#include "linguistic/misc.hxx"
#include "defs.hxx"

namespace com { namespace sun { namespace star {
    namespace beans {
        struct PropertyChangeEvent;
    }
}}}

// LinguOptions
// This class represents all Linguistik relevant options.

class LinguOptions
{
    static SvtLinguOptions     *pData;
    static oslInterlockedCount  nRefCount;  // number of objects of this class

public:
    LinguOptions();
    LinguOptions(const LinguOptions &rOpt);
    ~LinguOptions();

    static OUString    GetName( sal_Int32 nWID );

    const ::com::sun::star::uno::Sequence< OUString >
            GetActiveDics() const   { return pData->aActiveDics; }

    const ::com::sun::star::uno::Sequence< OUString >
            GetActiveConvDics() const   { return pData->aActiveConvDics; }
};

// uses templates from <cppuhelper/interfacecontainer.h>

// helper function call class
struct PropHashType_Impl
{
    size_t operator()(const sal_Int32 &s) const { return s; }
};

typedef cppu::OMultiTypeInterfaceContainerHelperVar
    <
        sal_Int32,
        PropHashType_Impl
    > OPropertyListenerContainerHelper;

class LinguProps :
    public cppu::WeakImplHelper5
    <
        com::sun::star::linguistic2::XLinguProperties,
        com::sun::star::beans::XFastPropertySet,
        com::sun::star::beans::XPropertyAccess,
        com::sun::star::lang::XComponent,
        com::sun::star::lang::XServiceInfo
    >
{
    ::cppu::OInterfaceContainerHelper           aEvtListeners;
    OPropertyListenerContainerHelper            aPropListeners;

    SfxItemPropertyMap                          aPropertyMap;
    SvtLinguConfig                              aConfig;

    sal_Bool                                        bDisposing;

    // disallow copy-constructor and assignment-operator for now
    LinguProps(const LinguProps &);
    LinguProps & operator = (const LinguProps &);

    void    launchEvent( const ::com::sun::star::beans::PropertyChangeEvent &rEvt ) const;

    sal_Bool getPropertyBool(const OUString& aPropertyName) throw (css::uno::RuntimeException);
    sal_Int16 getPropertyInt16(const OUString& aPropertyName) throw (css::uno::RuntimeException);
    css::lang::Locale getPropertyLocale(const OUString& aPropertyName) throw (css::uno::RuntimeException);
    void setProperty(const OUString& aPropertyName, sal_Bool p1) throw (css::uno::RuntimeException)
        { setPropertyValue( aPropertyName, css::uno::Any(p1) ); }
    void setProperty(const OUString& aPropertyName, sal_Int16 p1) throw (css::uno::RuntimeException)
        { setPropertyValue( aPropertyName, css::uno::Any(p1) ); }
    void setProperty(const OUString& aPropertyName, css::lang::Locale p1) throw (css::uno::RuntimeException)
        { setPropertyValue( aPropertyName, css::uno::Any(p1) ); }

public:
    LinguProps();

    virtual sal_Bool SAL_CALL getIsUseDictionaryList() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_USE_DICTIONARY_LIST); }
    virtual void SAL_CALL setIsUseDictionaryList(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_USE_DICTIONARY_LIST, p1); }
    virtual sal_Bool SAL_CALL getIsIgnoreControlCharacters() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_IGNORE_CONTROL_CHARACTERS); }
    virtual void SAL_CALL setIsIgnoreControlCharacters(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_IGNORE_CONTROL_CHARACTERS, p1); }
    virtual sal_Bool SAL_CALL getIsSpellUpperCase() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_UPPER_CASE); }
    virtual void SAL_CALL setIsSpellUpperCase(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_UPPER_CASE, p1); }
    virtual sal_Bool SAL_CALL getIsSpellWithDigits() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_WITH_DIGITS); }
    virtual void SAL_CALL setIsSpellWithDigits(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_WITH_DIGITS, p1); }
    virtual sal_Bool SAL_CALL getIsSpellCapitalization() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_CAPITALIZATION); }
    virtual void SAL_CALL setIsSpellCapitalization(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_CAPITALIZATION, p1); }
    virtual sal_Int16 SAL_CALL getHyphMinLeading() throw (css::uno::RuntimeException)
        { return getPropertyInt16(UPN_HYPH_MIN_LEADING); }
    virtual void SAL_CALL setHyphMinLeading(sal_Int16 p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_HYPH_MIN_LEADING, p1); }
    virtual sal_Int16 SAL_CALL getHyphMinTrailing() throw (css::uno::RuntimeException)
        { return getPropertyInt16(UPN_HYPH_MIN_TRAILING); }
    virtual void SAL_CALL setHyphMinTrailing(sal_Int16 p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_HYPH_MIN_TRAILING, p1); }
    virtual sal_Int16 SAL_CALL getHyphMinWordLength() throw (css::uno::RuntimeException)
        { return getPropertyInt16(UPN_HYPH_MIN_WORD_LENGTH); }
    virtual void SAL_CALL setHyphMinWordLength(sal_Int16 p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_HYPH_MIN_WORD_LENGTH, p1); }
    virtual com::sun::star::lang::Locale SAL_CALL getDefaultLocale() throw (css::uno::RuntimeException)
        { return getPropertyLocale(UPN_DEFAULT_LOCALE); }
    virtual void SAL_CALL setDefaultLocale(const com::sun::star::lang::Locale& p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_DEFAULT_LOCALE, p1); }
    virtual sal_Bool SAL_CALL getIsHyphAuto() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_HYPH_AUTO); }
    virtual void SAL_CALL setIsHyphAuto(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_HYPH_AUTO, p1); }
    virtual sal_Bool SAL_CALL getIsHyphSpecial() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_HYPH_SPECIAL); }
    virtual void SAL_CALL setIsHyphSpecial(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_HYPH_SPECIAL, p1); }
    virtual sal_Bool SAL_CALL getIsSpellAuto() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_AUTO); }
    virtual void SAL_CALL setIsSpellAuto(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_AUTO, p1); }
    virtual sal_Bool SAL_CALL getIsSpellSpecial() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_SPELL_SPECIAL); }
    virtual void SAL_CALL setIsSpellSpecial(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_SPELL_SPECIAL, p1); }
    virtual sal_Bool SAL_CALL getIsWrapReverse() throw (css::uno::RuntimeException)
        { return getPropertyBool(UPN_IS_WRAP_REVERSE); }
    virtual void SAL_CALL setIsWrapReverse(sal_Bool p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_IS_WRAP_REVERSE, p1); }
    virtual com::sun::star::lang::Locale SAL_CALL getDefaultLocale_CJK() throw (css::uno::RuntimeException)
        { return getPropertyLocale(UPN_DEFAULT_LOCALE_CJK); }
    virtual void SAL_CALL setDefaultLocale_CJK(const com::sun::star::lang::Locale& p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_DEFAULT_LOCALE_CJK, p1); }
    virtual css::lang::Locale SAL_CALL getDefaultLocale_CTL() throw (css::uno::RuntimeException)
        { return getPropertyLocale(UPN_DEFAULT_LOCALE_CTL); }
    virtual void SAL_CALL setDefaultLocale_CTL(const com::sun::star::lang::Locale& p1) throw (css::uno::RuntimeException)
        { setProperty(UPN_DEFAULT_LOCALE_CTL, p1); }

    // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& rxListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XFastPropertySet
    virtual void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue( sal_Int32 nHandle ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XPropertyAccess
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // XComponent
    virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    static inline OUString getImplementationName_Static() throw();
    static com::sun::star::uno::Sequence< OUString > getSupportedServiceNames_Static() throw();
};

inline OUString LinguProps::getImplementationName_Static() throw()
{
    return OUString( "com.sun.star.lingu2.LinguProps" );
}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdint.h>

#include <vector>

#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>

#include <process/collect.hpp>
#include <process/defer.hpp>
#include <process/delay.hpp>
#include <process/io.hpp>
#include <process/pid.hpp>
#include <process/reap.hpp>
#include <process/subprocess.hpp>

#include <stout/bytes.hpp>
#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/hashset.hpp>
#include <stout/lambda.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/stringify.hpp>
#include <stout/try.hpp>

#include "linux/cgroups.hpp"
#include "linux/perf.hpp"

#include "slave/containerizer/isolators/cgroups/perf_event.hpp"

using mesos::slave::ContainerLimitation;
using mesos::slave::ContainerPrepareInfo;
using mesos::slave::ContainerState;
using mesos::slave::Isolator;

using std::list;
using std::set;
using std::string;
using std::vector;

using process::Clock;
using process::Failure;
using process::Future;
using process::PID;
using process::Time;

namespace mesos {
namespace internal {
namespace slave {

Try<Isolator*> CgroupsPerfEventIsolatorProcess::create(const Flags& flags)
{
  LOG(INFO) << "Creating PerfEvent isolator";

  if (!perf::supported()) {
    return Error("Perf is not supported");
  }

  if (flags.perf_duration > flags.perf_interval) {
    return Error("Sampling perf for duration (" +
                 stringify(flags.perf_duration) +
                 ") > interval (" +
                 stringify(flags.perf_interval) +
                 ") is not supported.");
  }

  if (!flags.perf_events.isSome()) {
    return Error("No perf events specified.");
  }

  set<string> events;
  foreach (const string& event,
           strings::tokenize(flags.perf_events.get(), ",")) {
    events.insert(event);
  }

  if (!perf::valid(events)) {
    return Error("Failed to create PerfEvent isolator, invalid events: " +
                 stringify(events));
  }

  Try<string> hierarchy = cgroups::prepare(
      flags.cgroups_hierarchy,
      "perf_event",
      flags.cgroups_root);

  if (hierarchy.isError()) {
    return Error("Failed to create perf_event cgroup: " + hierarchy.error());
  }

  LOG(INFO) << "PerfEvent isolator will profile for " << flags.perf_duration
            << " every " << flags.perf_interval
            << " for events: " << stringify(events);

  process::Owned<MesosIsolatorProcess> process(
      new CgroupsPerfEventIsolatorProcess(flags, hierarchy.get(), events));

  return new MesosIsolator(process);
}

CgroupsPerfEventIsolatorProcess::~CgroupsPerfEventIsolatorProcess() {}

void CgroupsPerfEventIsolatorProcess::initialize()
{
  // Start sampling.
  sample();
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::recover(
    const list<ContainerState>& states,
    const hashset<ContainerID>& orphans)
{
  foreach (const ContainerState& state, states) {
    const ContainerID& containerId = state.container_id();
    const string cgroup = path::join(flags.cgroups_root, containerId.value());

    Try<bool> exists = cgroups::exists(hierarchy, cgroup);
    if (exists.isError()) {
      foreachvalue (Info* info, infos) {
        delete info;
      }

      infos.clear();
      return Failure("Failed to check cgroup " + cgroup +
                     " for container '" + stringify(containerId) + "'");
    }

    if (!exists.get()) {
      // This may occur if the executor is exiting and the isolator has
      // destroyed the cgroup but the slave dies before noticing this. This
      // will be detected when the containerizer tries to monitor the
      // executor's pid.
      // NOTE: This could also occur if this isolator is now enabled for a
      // container that was started without this isolator. For this
      // particular isolator it is acceptable to continue running this
      // container without a perf_event cgroup because we don't ever
      // query it and the destroy will succeed immediately.
      VLOG(1) << "Couldn't find perf event cgroup for container " << containerId
              << ", perf statistics will not be available";
      continue;
    }

    infos[containerId] = new Info(containerId, cgroup);
  }

  // Remove orphan cgroups.
  Try<vector<string>> cgroups = cgroups::get(hierarchy, flags.cgroups_root);
  if (cgroups.isError()) {
    foreachvalue (Info* info, infos) {
      delete info;
    }
    infos.clear();
    return Failure(cgroups.error());
  }

  foreach (const string& cgroup, cgroups.get()) {
    // Ignore the slave cgroup (see the --slave_subsystems flag).
    // TODO(idownes): Remove this when the cgroups layout is updated,
    // see MESOS-1185.
    if (cgroup == path::join(flags.cgroups_root, "slave")) {
      continue;
    }

    ContainerID containerId;
    containerId.set_value(Path(cgroup).basename());

    if (infos.contains(containerId)) {
      continue;
    }

    // Known orphan cgroups will be destroyed by the containerizer
    // using the normal cleanup path. See details in MESOS-2367.
    if (orphans.contains(containerId)) {
      infos[containerId] = new Info(containerId, cgroup);
      continue;
    }

    LOG(INFO) << "Removing unknown orphaned cgroup '" << cgroup << "'";

    // We don't wait on the destroy as we don't want to block recovery.
    cgroups::destroy(hierarchy, cgroup, cgroups::DESTROY_TIMEOUT);
  }

  return Nothing();
}

Future<Option<ContainerPrepareInfo>> CgroupsPerfEventIsolatorProcess::prepare(
    const ContainerID& containerId,
    const ExecutorInfo& executorInfo,
    const string& directory,
    const Option<string>& user)
{
  if (infos.contains(containerId)) {
    return Failure("Container has already been prepared");
  }

  LOG(INFO) << "Preparing perf event cgroup for " << containerId;

  Info* info = new Info(
      containerId,
      path::join(flags.cgroups_root, containerId.value()));

  infos[containerId] = CHECK_NOTNULL(info);

  // Create a cgroup for this container.
  Try<bool> exists = cgroups::exists(hierarchy, info->cgroup);

  if (exists.isError()) {
    return Failure("Failed to prepare isolator: " + exists.error());
  }

  if (exists.get()) {
    return Failure("Failed to prepare isolator: cgroup already exists");
  }

  if (!exists.get()) {
    Try<Nothing> create = cgroups::create(hierarchy, info->cgroup);
    if (create.isError()) {
      return Failure("Failed to prepare isolator: " + create.error());
    }
  }

  // Chown the cgroup so the executor can create nested cgroups. Do
  // not recurse so the control files are still owned by the slave
  // user and thus cannot be changed by the executor.
  if (user.isSome()) {
    Try<Nothing> chown = os::chown(
        user.get(),
        path::join(hierarchy, info->cgroup),
        false);
    if (chown.isError()) {
      return Failure("Failed to prepare isolator: " + chown.error());
    }
  }

  return None();
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::isolate(
    const ContainerID& containerId,
    pid_t pid)
{
  if (!infos.contains(containerId)) {
    return Failure("Unknown container");
  }

  Info* info = CHECK_NOTNULL(infos[containerId]);

  Try<Nothing> assign = cgroups::assign(hierarchy, info->cgroup, pid);
  if (assign.isError()) {
    return Failure("Failed to assign container '" +
                   stringify(info->containerId) + "' to its own cgroup '" +
                   path::join(hierarchy, info->cgroup) +
                   "' : " + assign.error());
  }

  return Nothing();
}

Future<ContainerLimitation> CgroupsPerfEventIsolatorProcess::watch(
    const ContainerID& containerId)
{
  // No resources are limited.
  return Future<ContainerLimitation>();
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::update(
    const ContainerID& containerId,
    const Resources& resources)
{
  // Nothing to update.
  return Nothing();
}

Future<ResourceStatistics> CgroupsPerfEventIsolatorProcess::usage(
    const ContainerID& containerId)
{
  if (!infos.contains(containerId)) {
    // Return an empty ResourceStatistics, i.e., without
    // PerfStatistics, if we don't know about this container.
    return ResourceStatistics();
  }

  CHECK_NOTNULL(infos[containerId]);

  ResourceStatistics statistics;
  statistics.mutable_perf()->CopyFrom(infos[containerId]->statistics);

  return statistics;
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::cleanup(
    const ContainerID& containerId)
{
  // Tolerate clean up attempts for unknown containers which may arise from
  // repeated clean up attempts (during test cleanup).
  if (!infos.contains(containerId)) {
    VLOG(1) << "Ignoring cleanup request for unknown container: "
            << containerId;
    return Nothing();
  }

  Info* info = CHECK_NOTNULL(infos[containerId]);

  info->destroying = true;

  return cgroups::destroy(hierarchy, info->cgroup)
    .then(defer(PID<CgroupsPerfEventIsolatorProcess>(this),
                &CgroupsPerfEventIsolatorProcess::_cleanup,
                containerId));
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::_cleanup(
    const ContainerID& containerId)
{
  if (!infos.contains(containerId)) {
    return Nothing();
  }

  delete infos[containerId];
  infos.erase(containerId);

  return Nothing();
}

Future<hashmap<string, PerfStatistics>> discardSample(
    Future<hashmap<string, PerfStatistics>> future,
    const Duration& duration,
    const Duration& timeout)
{
  LOG(ERROR) << "Perf sample of " << stringify(duration)
             << " failed to complete within " << stringify(timeout)
             << "; sampling will be halted";

  future.discard();

  return future;
}

void CgroupsPerfEventIsolatorProcess::sample()
{
  // Collect a perf sample for all cgroups that are not being
  // destroyed. Since destroyal is asynchronous, 'perf stat' may
  // fail if the cgroup is destroyed before running perf.
  set<string> cgroups;

  foreachvalue (Info* info, infos) {
    CHECK_NOTNULL(info);

    if (!info->destroying) {
      cgroups.insert(info->cgroup);
    }
  }

  // The timeout includes an allowance of twice the process::reap
  // interval to ensure we see the perf process exit. If the sample
  // is not ready after the timeout something very unexpected has
  // occurred so we discard it and halt all sampling.
  Duration timeout = flags.perf_duration + process::MAX_REAP_INTERVAL() * 2;

  perf::sample(events, cgroups, flags.perf_duration)
    .after(timeout,
           lambda::bind(&discardSample,
                        lambda::_1,
                        flags.perf_duration,
                        timeout))
    .onAny(defer(PID<CgroupsPerfEventIsolatorProcess>(this),
                 &CgroupsPerfEventIsolatorProcess::_sample,
                 Clock::now() + flags.perf_interval,
                 lambda::_1));
}

void CgroupsPerfEventIsolatorProcess::_sample(
    const Time& next,
    const Future<hashmap<string, PerfStatistics>>& statistics)
{
  if (!statistics.isReady()) {
    // Failure can occur for many reasons but all are unexpected and
    // indicate something is not right so we'll stop sampling.
    LOG(ERROR) << "Failed to get perf sample, sampling will be halted: "
               << (statistics.isFailed()
                   ? statistics.failure()
                   : "discarded due to timeout");
    return;
  }

  // Store the latest statistics, note that cgroups added in the
  // interim will be picked up by the next sample.
  foreachvalue (Info* info, infos) {
    CHECK_NOTNULL(info);

    if (statistics->contains(info->cgroup)) {
      info->statistics = statistics->get(info->cgroup).get();
    }
  }

  // Schedule sample for the next time.
  delay(next - Clock::now(),
        PID<CgroupsPerfEventIsolatorProcess>(this),
        &CgroupsPerfEventIsolatorProcess::sample);
}

} // namespace slave {
} // namespace internal {
} // namespace mesos {
<commit_msg>Fixed the perf event isolator to continue sampling in the presence of failures.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdint.h>

#include <vector>

#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>

#include <process/collect.hpp>
#include <process/defer.hpp>
#include <process/delay.hpp>
#include <process/io.hpp>
#include <process/pid.hpp>
#include <process/reap.hpp>
#include <process/subprocess.hpp>

#include <stout/bytes.hpp>
#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/hashset.hpp>
#include <stout/lambda.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/stringify.hpp>
#include <stout/try.hpp>

#include "linux/cgroups.hpp"
#include "linux/perf.hpp"

#include "slave/containerizer/isolators/cgroups/perf_event.hpp"

using mesos::slave::ContainerLimitation;
using mesos::slave::ContainerPrepareInfo;
using mesos::slave::ContainerState;
using mesos::slave::Isolator;

using std::list;
using std::set;
using std::string;
using std::vector;

using process::Clock;
using process::Failure;
using process::Future;
using process::PID;
using process::Time;

namespace mesos {
namespace internal {
namespace slave {

Try<Isolator*> CgroupsPerfEventIsolatorProcess::create(const Flags& flags)
{
  LOG(INFO) << "Creating PerfEvent isolator";

  if (!perf::supported()) {
    return Error("Perf is not supported");
  }

  if (flags.perf_duration > flags.perf_interval) {
    return Error("Sampling perf for duration (" +
                 stringify(flags.perf_duration) +
                 ") > interval (" +
                 stringify(flags.perf_interval) +
                 ") is not supported.");
  }

  if (!flags.perf_events.isSome()) {
    return Error("No perf events specified.");
  }

  set<string> events;
  foreach (const string& event,
           strings::tokenize(flags.perf_events.get(), ",")) {
    events.insert(event);
  }

  if (!perf::valid(events)) {
    return Error("Failed to create PerfEvent isolator, invalid events: " +
                 stringify(events));
  }

  Try<string> hierarchy = cgroups::prepare(
      flags.cgroups_hierarchy,
      "perf_event",
      flags.cgroups_root);

  if (hierarchy.isError()) {
    return Error("Failed to create perf_event cgroup: " + hierarchy.error());
  }

  LOG(INFO) << "PerfEvent isolator will profile for " << flags.perf_duration
            << " every " << flags.perf_interval
            << " for events: " << stringify(events);

  process::Owned<MesosIsolatorProcess> process(
      new CgroupsPerfEventIsolatorProcess(flags, hierarchy.get(), events));

  return new MesosIsolator(process);
}

CgroupsPerfEventIsolatorProcess::~CgroupsPerfEventIsolatorProcess() {}

void CgroupsPerfEventIsolatorProcess::initialize()
{
  // Start sampling.
  sample();
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::recover(
    const list<ContainerState>& states,
    const hashset<ContainerID>& orphans)
{
  foreach (const ContainerState& state, states) {
    const ContainerID& containerId = state.container_id();
    const string cgroup = path::join(flags.cgroups_root, containerId.value());

    Try<bool> exists = cgroups::exists(hierarchy, cgroup);
    if (exists.isError()) {
      foreachvalue (Info* info, infos) {
        delete info;
      }

      infos.clear();
      return Failure("Failed to check cgroup " + cgroup +
                     " for container '" + stringify(containerId) + "'");
    }

    if (!exists.get()) {
      // This may occur if the executor is exiting and the isolator has
      // destroyed the cgroup but the slave dies before noticing this. This
      // will be detected when the containerizer tries to monitor the
      // executor's pid.
      // NOTE: This could also occur if this isolator is now enabled for a
      // container that was started without this isolator. For this
      // particular isolator it is acceptable to continue running this
      // container without a perf_event cgroup because we don't ever
      // query it and the destroy will succeed immediately.
      VLOG(1) << "Couldn't find perf event cgroup for container " << containerId
              << ", perf statistics will not be available";
      continue;
    }

    infos[containerId] = new Info(containerId, cgroup);
  }

  // Remove orphan cgroups.
  Try<vector<string>> cgroups = cgroups::get(hierarchy, flags.cgroups_root);
  if (cgroups.isError()) {
    foreachvalue (Info* info, infos) {
      delete info;
    }
    infos.clear();
    return Failure(cgroups.error());
  }

  foreach (const string& cgroup, cgroups.get()) {
    // Ignore the slave cgroup (see the --slave_subsystems flag).
    // TODO(idownes): Remove this when the cgroups layout is updated,
    // see MESOS-1185.
    if (cgroup == path::join(flags.cgroups_root, "slave")) {
      continue;
    }

    ContainerID containerId;
    containerId.set_value(Path(cgroup).basename());

    if (infos.contains(containerId)) {
      continue;
    }

    // Known orphan cgroups will be destroyed by the containerizer
    // using the normal cleanup path. See details in MESOS-2367.
    if (orphans.contains(containerId)) {
      infos[containerId] = new Info(containerId, cgroup);
      continue;
    }

    LOG(INFO) << "Removing unknown orphaned cgroup '" << cgroup << "'";

    // We don't wait on the destroy as we don't want to block recovery.
    cgroups::destroy(hierarchy, cgroup, cgroups::DESTROY_TIMEOUT);
  }

  return Nothing();
}

Future<Option<ContainerPrepareInfo>> CgroupsPerfEventIsolatorProcess::prepare(
    const ContainerID& containerId,
    const ExecutorInfo& executorInfo,
    const string& directory,
    const Option<string>& user)
{
  if (infos.contains(containerId)) {
    return Failure("Container has already been prepared");
  }

  LOG(INFO) << "Preparing perf event cgroup for " << containerId;

  Info* info = new Info(
      containerId,
      path::join(flags.cgroups_root, containerId.value()));

  infos[containerId] = CHECK_NOTNULL(info);

  // Create a cgroup for this container.
  Try<bool> exists = cgroups::exists(hierarchy, info->cgroup);

  if (exists.isError()) {
    return Failure("Failed to prepare isolator: " + exists.error());
  }

  if (exists.get()) {
    return Failure("Failed to prepare isolator: cgroup already exists");
  }

  if (!exists.get()) {
    Try<Nothing> create = cgroups::create(hierarchy, info->cgroup);
    if (create.isError()) {
      return Failure("Failed to prepare isolator: " + create.error());
    }
  }

  // Chown the cgroup so the executor can create nested cgroups. Do
  // not recurse so the control files are still owned by the slave
  // user and thus cannot be changed by the executor.
  if (user.isSome()) {
    Try<Nothing> chown = os::chown(
        user.get(),
        path::join(hierarchy, info->cgroup),
        false);
    if (chown.isError()) {
      return Failure("Failed to prepare isolator: " + chown.error());
    }
  }

  return None();
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::isolate(
    const ContainerID& containerId,
    pid_t pid)
{
  if (!infos.contains(containerId)) {
    return Failure("Unknown container");
  }

  Info* info = CHECK_NOTNULL(infos[containerId]);

  Try<Nothing> assign = cgroups::assign(hierarchy, info->cgroup, pid);
  if (assign.isError()) {
    return Failure("Failed to assign container '" +
                   stringify(info->containerId) + "' to its own cgroup '" +
                   path::join(hierarchy, info->cgroup) +
                   "' : " + assign.error());
  }

  return Nothing();
}

Future<ContainerLimitation> CgroupsPerfEventIsolatorProcess::watch(
    const ContainerID& containerId)
{
  // No resources are limited.
  return Future<ContainerLimitation>();
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::update(
    const ContainerID& containerId,
    const Resources& resources)
{
  // Nothing to update.
  return Nothing();
}

Future<ResourceStatistics> CgroupsPerfEventIsolatorProcess::usage(
    const ContainerID& containerId)
{
  if (!infos.contains(containerId)) {
    // Return an empty ResourceStatistics, i.e., without
    // PerfStatistics, if we don't know about this container.
    return ResourceStatistics();
  }

  CHECK_NOTNULL(infos[containerId]);

  ResourceStatistics statistics;
  statistics.mutable_perf()->CopyFrom(infos[containerId]->statistics);

  return statistics;
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::cleanup(
    const ContainerID& containerId)
{
  // Tolerate clean up attempts for unknown containers which may arise from
  // repeated clean up attempts (during test cleanup).
  if (!infos.contains(containerId)) {
    VLOG(1) << "Ignoring cleanup request for unknown container: "
            << containerId;
    return Nothing();
  }

  Info* info = CHECK_NOTNULL(infos[containerId]);

  info->destroying = true;

  return cgroups::destroy(hierarchy, info->cgroup)
    .then(defer(PID<CgroupsPerfEventIsolatorProcess>(this),
                &CgroupsPerfEventIsolatorProcess::_cleanup,
                containerId));
}

Future<Nothing> CgroupsPerfEventIsolatorProcess::_cleanup(
    const ContainerID& containerId)
{
  if (!infos.contains(containerId)) {
    return Nothing();
  }

  delete infos[containerId];
  infos.erase(containerId);

  return Nothing();
}

Future<hashmap<string, PerfStatistics>> discardSample(
    Future<hashmap<string, PerfStatistics>> future,
    const Duration& duration,
    const Duration& timeout)
{
  LOG(ERROR) << "Perf sample of " << stringify(duration)
             << " failed to complete within " << stringify(timeout)
             << "; sampling will be halted";

  future.discard();

  return future;
}

void CgroupsPerfEventIsolatorProcess::sample()
{
  // Collect a perf sample for all cgroups that are not being
  // destroyed. Since destroyal is asynchronous, 'perf stat' may
  // fail if the cgroup is destroyed before running perf.
  set<string> cgroups;

  foreachvalue (Info* info, infos) {
    CHECK_NOTNULL(info);

    if (!info->destroying) {
      cgroups.insert(info->cgroup);
    }
  }

  // The discard timeout includes an allowance of twice the
  // reaper interval to ensure we see the perf process exit.
  Duration timeout = flags.perf_duration + process::MAX_REAP_INTERVAL() * 2;

  perf::sample(events, cgroups, flags.perf_duration)
    .after(timeout,
           lambda::bind(&discardSample,
                        lambda::_1,
                        flags.perf_duration,
                        timeout))
    .onAny(defer(PID<CgroupsPerfEventIsolatorProcess>(this),
                 &CgroupsPerfEventIsolatorProcess::_sample,
                 Clock::now() + flags.perf_interval,
                 lambda::_1));
}

void CgroupsPerfEventIsolatorProcess::_sample(
    const Time& next,
    const Future<hashmap<string, PerfStatistics>>& statistics)
{
  if (!statistics.isReady()) {
    // In case the failure is transient or this is due to a timeout,
    // we continue sampling. Note that since sampling is done on an
    // interval, it should be ok if this is a non-transient failure.
    LOG(ERROR) << "Failed to get perf sample: "
               << (statistics.isFailed()
                   ? statistics.failure()
                   : "discarded due to timeout");
  } else {
    // Store the latest statistics, note that cgroups added in the
    // interim will be picked up by the next sample.
    foreachvalue (Info* info, infos) {
      CHECK_NOTNULL(info);

      if (statistics->contains(info->cgroup)) {
        info->statistics = statistics->get(info->cgroup).get();
      }
    }
  }

  // Schedule sample for the next time.
  delay(next - Clock::now(),
        PID<CgroupsPerfEventIsolatorProcess>(this),
        &CgroupsPerfEventIsolatorProcess::sample);
}

} // namespace slave {
} // namespace internal {
} // namespace mesos {
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"
#include <tools/stream.hxx>
#include <rsc/rscsfx.hxx>

// wg. pSlotPool
#include "appdata.hxx"
#include <sfx2/msgpool.hxx>
#include <sfx2/minarray.hxx>
#include <sfx2/msg.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include "sfxtypes.hxx"
#include <sfx2/macrconf.hxx>
#include "sfxresid.hxx"
#include "arrdecl.hxx"
#include <sfx2/module.hxx>

#include <sfx2/sfx.hrc>

//====================================================================

struct SfxSIDRegistration_Impl
{
    String          _aGroup;
    String          _aName;
    USHORT          _nSID;
};

struct SfxSlotType_Impl
{
    USHORT  nId;
    TypeId  nType;

    SfxSlotType_Impl( USHORT nTheId, TypeId nTheType ):
        nId(nTheId), nType(nTheType)
    {}
};

DECL_2BYTEARRAY(SfxSlotGroupArr_Impl, USHORT, 6, 4)
DECL_PTRARRAY(SfxInterfaceArr_Impl, SfxInterface*, 6, 3)
DECL_PTRARRAY(SfxSlotTypeArr_Impl, SfxSlotType_Impl*, 8, 8)

//====================================================================

SfxSlotPool::SfxSlotPool( SfxSlotPool *pParent, ResMgr* pResManager )
 : _pGroups(0)
 , _pTypes(0)
 , _pParentPool( pParent )
 , _pResMgr( pResManager )
 , _pInterfaces(0)
 , _nCurGroup(0)
 , _nCurInterface(0)
 , _nCurMsg(0)
 , _pUnoSlots( 0 )
{
    if ( !_pResMgr )
        _pResMgr = SfxApplication::GetOrCreate()->GetOffResManager_Impl();
}

//====================================================================

SfxSlotPool::~SfxSlotPool()
{
    _pParentPool = 0;
    for ( SfxInterface *pIF = FirstInterface(); pIF; pIF = FirstInterface() )
        delete pIF;
    delete _pInterfaces;
    delete _pGroups;
    if ( _pTypes )
    {
        for ( USHORT n =_pTypes->Count(); n--; )
            delete _pTypes->GetObject(n);
        delete _pTypes;
    }
}

//====================================================================

// registers the availability of the Interface of functions

void SfxSlotPool::RegisterInterface( SfxInterface& rInterface )
{
    DBG_MEMTEST();

    // add to the list of SfxObjectInterface instances
    if ( _pInterfaces == 0 )
        _pInterfaces = new SfxInterfaceArr_Impl;
    _pInterfaces->Append(&rInterface);

    // bei einem (einzelnen) Null-Slot abbrechen (aus syntaktischen Gr"unden
    // enthalten interfaces immer mindestens einen Slot)
    if ( rInterface.Count() == 1 && !rInterface[0]->nSlotId )
        return;

    // possibly add Interface-id and group-ids of funcs to the list of groups
    if ( !_pGroups )
    {
        _pGroups = new SfxSlotGroupArr_Impl;

        if ( _pParentPool )
        {
            // Die Groups im parent Slotpool sind auch hier bekannt
            SfxSlotGroupArr_Impl& rGroups = *_pParentPool->_pGroups;
            for ( USHORT n=0; n<rGroups.Count(); n++ )
                _pGroups->Append( rGroups[n] );
        }
    }

    if ( !_pTypes )
        _pTypes = new SfxSlotTypeArr_Impl;
    for ( USHORT nFunc = 0; nFunc < rInterface.Count(); ++nFunc )
    {
        SfxSlot *pDef = rInterface[nFunc];
        if ( pDef->GetGroupId() && /* pDef->GetGroupId() != GID_INTERN && */
             !_pGroups->Contains(pDef->GetGroupId()) )
        {
            if (pDef->GetGroupId() == GID_INTERN)
                _pGroups->Insert(0, pDef->GetGroupId());
            else
                _pGroups->Append(pDef->GetGroupId());
        }
    }
}

//====================================================================

TypeId SfxSlotPool::GetSlotType( USHORT nId ) const
{
    const SfxSlot* pSlot = (const_cast <SfxSlotPool*> (this))->GetSlot( nId );
    return pSlot ? pSlot->GetType()->Type() : 0;
/*
    for ( USHORT nPos = 0; nPos < _pTypes->Count(); ++nPos )
    {
        if ( _pTypes->GetObject(nPos)->nId == nId )
            return _pTypes->GetObject(nPos)->nType;
    }
    return _pParentPool ? _pParentPool->GetSlotType( nId ) : 0;
 */
}

//====================================================================

// unregisters the availability of the Interface of functions

void SfxSlotPool::ReleaseInterface( SfxInterface& rInterface )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces, "releasing SfxInterface, but there are none" );
    // remove from the list of SfxInterface instances
    _pInterfaces->Remove(&rInterface);
}

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

// get the first SfxMessage for a special Id (e.g. for getting check-mode)

const SfxSlot* SfxSlotPool::GetSlot( USHORT nId )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // Zun"achst die eigenen Interfaces absuchen
    for ( USHORT nInterf = 0; nInterf < _pInterfaces->Count(); ++nInterf )
    {
        const SfxSlot *pDef = _pInterfaces->GetObject(nInterf)->GetSlot(nId);
        if ( pDef )
            return pDef;
    }

    // Dann beim eventuell vorhandenen parent versuchen
    return _pParentPool ? _pParentPool->GetSlot( nId ) : 0;
}

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

// skips to the next group

String SfxSlotPool::SeekGroup( USHORT nNo )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // if the group exists, use it
    if ( _pGroups && nNo < _pGroups->Count() )
    {
        _nCurGroup = nNo;
        if ( _pParentPool )
        {
            // Meistens stimmt die Reihenfolge der Ids "uberein
            USHORT nParentCount = _pParentPool->_pGroups->Count();
            if ( nNo < nParentCount && (*_pGroups)[nNo] == (*_pParentPool->_pGroups)[nNo] )
                _pParentPool->_nCurGroup = nNo;
            else
            {
                // Ansonsten mu\s gesucht werden
                // Wenn die Gruppe im parent pool nicht gefunden wird, wird
                // _nCurGroup au\serhalb des g"ultigen Bereiches gesetzt
                USHORT i;
                for ( i=1; i<nParentCount; i++ )
                    if ( (*_pGroups)[nNo] == (*_pParentPool->_pGroups)[i] )
                        break;
                _pParentPool->_nCurGroup = i;
            }
        }

        SfxResId aResId( (*_pGroups)[_nCurGroup] );
        aResId.SetRT(RSC_STRING);
        if ( !aResId.GetResMgr()->IsAvailable(aResId) )
        {
            DBG_ERROR( "GroupId-Name nicht im SFX definiert!" );
            return String();
        }

        return String( aResId );
    }

    return String();
}

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

USHORT SfxSlotPool::GetGroupCount()
{
    return _pGroups->Count();
}

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

// internal search loop

const SfxSlot* SfxSlotPool::SeekSlot( USHORT nStartInterface )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // Die Numerierung der interfaces startet beim parent pool
    USHORT nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0;

    // sind wir am Ende des Parent-Pools angekommen?
    if ( nStartInterface < nFirstInterface &&
         _pParentPool->_nCurGroup >= _pParentPool->_pGroups->Count() )
        nStartInterface = nFirstInterface;

    // liegt das Interface noch im Parent-Pool?
    if ( nStartInterface < nFirstInterface )
    {
        DBG_ASSERT( _pParentPool, "Kein parent pool!" );
        _nCurInterface = nStartInterface;
        return _pParentPool->SeekSlot( nStartInterface );
    }

    // find the first func-def with the current group id
    USHORT nCount = _pInterfaces->Count() + nFirstInterface;
    for ( _nCurInterface = nStartInterface;
            _nCurInterface < nCount;
          ++_nCurInterface )
    {
        SfxInterface* pInterface = (*_pInterfaces)[_nCurInterface-nFirstInterface];
        for ( _nCurMsg = 0;
              _nCurMsg < pInterface->Count();
              ++_nCurMsg )
        {
            const SfxSlot* pMsg = (*pInterface)[_nCurMsg];
            if ( pMsg->GetGroupId() == _pGroups->GetObject(_nCurGroup) )
                return pMsg;
        }
    }

    return 0;
}

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

// skips to the next func in the current group

const SfxSlot* SfxSlotPool::NextSlot()
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // Die Numerierung der interfaces startet beim parent pool
    USHORT nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0;

    if ( _nCurInterface < nFirstInterface && _nCurGroup >= _pParentPool->_pGroups->Count() )
        _nCurInterface = nFirstInterface;

    if ( _nCurInterface < nFirstInterface )
    {
        DBG_ASSERT( _pParentPool, "Kein parent pool!" );
        const SfxSlot *pSlot = _pParentPool->NextSlot();
        _nCurInterface = _pParentPool->_nCurInterface;
        if ( pSlot )
            return pSlot;
        if ( _nCurInterface == nFirstInterface )
            // parent pool ist fertig
            return SeekSlot( nFirstInterface );
    }

    USHORT nInterface = _nCurInterface - nFirstInterface;
    // possibly we are already at the end
    if ( nInterface >= _pInterfaces->Count() )
        return 0;

    // look for further matching func-defs within the same Interface
    SfxInterface* pInterface = (*_pInterfaces)[nInterface];
    while ( ++_nCurMsg < pInterface->Count() )
    {
        SfxSlot* pMsg = (*pInterface)[_nCurMsg];
        if ( pMsg->GetGroupId() == _pGroups->GetObject(_nCurGroup) )
            return pMsg;
    }

    return SeekSlot(++_nCurInterface );
}

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

// SlotName erfragen, gfs. mit HilfeText

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

SfxInterface* SfxSlotPool::FirstInterface()
{
    _nCurInterface = 0;
    if ( !_pInterfaces || !_pInterfaces->Count() )
        return 0;
    return _pParentPool ? _pParentPool->FirstInterface() : (*_pInterfaces)[0];
}

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

SfxInterface* SfxSlotPool::NextInterface()
{
    _nCurInterface++;
    USHORT nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0;
    if ( _nCurInterface < nFirstInterface )
        return (*_pParentPool->_pInterfaces)[_nCurInterface];
    USHORT nInterface = _nCurInterface - nFirstInterface;
    return nInterface < _pInterfaces->Count() ? (*_pInterfaces)[nInterface] : 0;
}

const SfxSlot* SfxSlotPool::GetUnoSlot( const String& rName )
{
    const SfxSlot *pSlot = NULL;
    for ( USHORT nInterface=0; nInterface<_pInterfaces->Count(); nInterface++ )
    {
        pSlot = (*_pInterfaces)[nInterface]->GetSlot( rName );
        if ( pSlot )
            break;
    }

    if ( !pSlot && _pParentPool )
        pSlot = _pParentPool->GetUnoSlot( rName );

    return pSlot;
}

SfxSlotPool& SfxSlotPool::GetSlotPool( SfxViewFrame *pFrame )
{
    SfxModule *pMod = SfxModule::GetActiveModule( pFrame );
    if ( pMod && pMod->GetSlotPool() )
        return *pMod->GetSlotPool();
    else
        return *SFX_APP()->Get_Impl()->pSlotPool;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cppcheck reports unused struct<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"
#include <tools/stream.hxx>
#include <rsc/rscsfx.hxx>

// wg. pSlotPool
#include "appdata.hxx"
#include <sfx2/msgpool.hxx>
#include <sfx2/minarray.hxx>
#include <sfx2/msg.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include "sfxtypes.hxx"
#include <sfx2/macrconf.hxx>
#include "sfxresid.hxx"
#include "arrdecl.hxx"
#include <sfx2/module.hxx>

#include <sfx2/sfx.hrc>

//====================================================================

struct SfxSlotType_Impl
{
    USHORT  nId;
    TypeId  nType;

    SfxSlotType_Impl( USHORT nTheId, TypeId nTheType ):
        nId(nTheId), nType(nTheType)
    {}
};

DECL_2BYTEARRAY(SfxSlotGroupArr_Impl, USHORT, 6, 4)
DECL_PTRARRAY(SfxInterfaceArr_Impl, SfxInterface*, 6, 3)
DECL_PTRARRAY(SfxSlotTypeArr_Impl, SfxSlotType_Impl*, 8, 8)

//====================================================================

SfxSlotPool::SfxSlotPool( SfxSlotPool *pParent, ResMgr* pResManager )
 : _pGroups(0)
 , _pTypes(0)
 , _pParentPool( pParent )
 , _pResMgr( pResManager )
 , _pInterfaces(0)
 , _nCurGroup(0)
 , _nCurInterface(0)
 , _nCurMsg(0)
 , _pUnoSlots( 0 )
{
    if ( !_pResMgr )
        _pResMgr = SfxApplication::GetOrCreate()->GetOffResManager_Impl();
}

//====================================================================

SfxSlotPool::~SfxSlotPool()
{
    _pParentPool = 0;
    for ( SfxInterface *pIF = FirstInterface(); pIF; pIF = FirstInterface() )
        delete pIF;
    delete _pInterfaces;
    delete _pGroups;
    if ( _pTypes )
    {
        for ( USHORT n =_pTypes->Count(); n--; )
            delete _pTypes->GetObject(n);
        delete _pTypes;
    }
}

//====================================================================

// registers the availability of the Interface of functions

void SfxSlotPool::RegisterInterface( SfxInterface& rInterface )
{
    DBG_MEMTEST();

    // add to the list of SfxObjectInterface instances
    if ( _pInterfaces == 0 )
        _pInterfaces = new SfxInterfaceArr_Impl;
    _pInterfaces->Append(&rInterface);

    // bei einem (einzelnen) Null-Slot abbrechen (aus syntaktischen Gr"unden
    // enthalten interfaces immer mindestens einen Slot)
    if ( rInterface.Count() == 1 && !rInterface[0]->nSlotId )
        return;

    // possibly add Interface-id and group-ids of funcs to the list of groups
    if ( !_pGroups )
    {
        _pGroups = new SfxSlotGroupArr_Impl;

        if ( _pParentPool )
        {
            // Die Groups im parent Slotpool sind auch hier bekannt
            SfxSlotGroupArr_Impl& rGroups = *_pParentPool->_pGroups;
            for ( USHORT n=0; n<rGroups.Count(); n++ )
                _pGroups->Append( rGroups[n] );
        }
    }

    if ( !_pTypes )
        _pTypes = new SfxSlotTypeArr_Impl;
    for ( USHORT nFunc = 0; nFunc < rInterface.Count(); ++nFunc )
    {
        SfxSlot *pDef = rInterface[nFunc];
        if ( pDef->GetGroupId() && /* pDef->GetGroupId() != GID_INTERN && */
             !_pGroups->Contains(pDef->GetGroupId()) )
        {
            if (pDef->GetGroupId() == GID_INTERN)
                _pGroups->Insert(0, pDef->GetGroupId());
            else
                _pGroups->Append(pDef->GetGroupId());
        }
    }
}

//====================================================================

TypeId SfxSlotPool::GetSlotType( USHORT nId ) const
{
    const SfxSlot* pSlot = (const_cast <SfxSlotPool*> (this))->GetSlot( nId );
    return pSlot ? pSlot->GetType()->Type() : 0;
/*
    for ( USHORT nPos = 0; nPos < _pTypes->Count(); ++nPos )
    {
        if ( _pTypes->GetObject(nPos)->nId == nId )
            return _pTypes->GetObject(nPos)->nType;
    }
    return _pParentPool ? _pParentPool->GetSlotType( nId ) : 0;
 */
}

//====================================================================

// unregisters the availability of the Interface of functions

void SfxSlotPool::ReleaseInterface( SfxInterface& rInterface )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces, "releasing SfxInterface, but there are none" );
    // remove from the list of SfxInterface instances
    _pInterfaces->Remove(&rInterface);
}

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

// get the first SfxMessage for a special Id (e.g. for getting check-mode)

const SfxSlot* SfxSlotPool::GetSlot( USHORT nId )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // Zun"achst die eigenen Interfaces absuchen
    for ( USHORT nInterf = 0; nInterf < _pInterfaces->Count(); ++nInterf )
    {
        const SfxSlot *pDef = _pInterfaces->GetObject(nInterf)->GetSlot(nId);
        if ( pDef )
            return pDef;
    }

    // Dann beim eventuell vorhandenen parent versuchen
    return _pParentPool ? _pParentPool->GetSlot( nId ) : 0;
}

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

// skips to the next group

String SfxSlotPool::SeekGroup( USHORT nNo )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // if the group exists, use it
    if ( _pGroups && nNo < _pGroups->Count() )
    {
        _nCurGroup = nNo;
        if ( _pParentPool )
        {
            // Meistens stimmt die Reihenfolge der Ids "uberein
            USHORT nParentCount = _pParentPool->_pGroups->Count();
            if ( nNo < nParentCount && (*_pGroups)[nNo] == (*_pParentPool->_pGroups)[nNo] )
                _pParentPool->_nCurGroup = nNo;
            else
            {
                // Ansonsten mu\s gesucht werden
                // Wenn die Gruppe im parent pool nicht gefunden wird, wird
                // _nCurGroup au\serhalb des g"ultigen Bereiches gesetzt
                USHORT i;
                for ( i=1; i<nParentCount; i++ )
                    if ( (*_pGroups)[nNo] == (*_pParentPool->_pGroups)[i] )
                        break;
                _pParentPool->_nCurGroup = i;
            }
        }

        SfxResId aResId( (*_pGroups)[_nCurGroup] );
        aResId.SetRT(RSC_STRING);
        if ( !aResId.GetResMgr()->IsAvailable(aResId) )
        {
            DBG_ERROR( "GroupId-Name nicht im SFX definiert!" );
            return String();
        }

        return String( aResId );
    }

    return String();
}

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

USHORT SfxSlotPool::GetGroupCount()
{
    return _pGroups->Count();
}

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

// internal search loop

const SfxSlot* SfxSlotPool::SeekSlot( USHORT nStartInterface )
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // Die Numerierung der interfaces startet beim parent pool
    USHORT nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0;

    // sind wir am Ende des Parent-Pools angekommen?
    if ( nStartInterface < nFirstInterface &&
         _pParentPool->_nCurGroup >= _pParentPool->_pGroups->Count() )
        nStartInterface = nFirstInterface;

    // liegt das Interface noch im Parent-Pool?
    if ( nStartInterface < nFirstInterface )
    {
        DBG_ASSERT( _pParentPool, "Kein parent pool!" );
        _nCurInterface = nStartInterface;
        return _pParentPool->SeekSlot( nStartInterface );
    }

    // find the first func-def with the current group id
    USHORT nCount = _pInterfaces->Count() + nFirstInterface;
    for ( _nCurInterface = nStartInterface;
            _nCurInterface < nCount;
          ++_nCurInterface )
    {
        SfxInterface* pInterface = (*_pInterfaces)[_nCurInterface-nFirstInterface];
        for ( _nCurMsg = 0;
              _nCurMsg < pInterface->Count();
              ++_nCurMsg )
        {
            const SfxSlot* pMsg = (*pInterface)[_nCurMsg];
            if ( pMsg->GetGroupId() == _pGroups->GetObject(_nCurGroup) )
                return pMsg;
        }
    }

    return 0;
}

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

// skips to the next func in the current group

const SfxSlot* SfxSlotPool::NextSlot()
{
    DBG_MEMTEST();
    DBG_ASSERT( _pInterfaces != 0, "no Interfaces registered" );

    // Die Numerierung der interfaces startet beim parent pool
    USHORT nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0;

    if ( _nCurInterface < nFirstInterface && _nCurGroup >= _pParentPool->_pGroups->Count() )
        _nCurInterface = nFirstInterface;

    if ( _nCurInterface < nFirstInterface )
    {
        DBG_ASSERT( _pParentPool, "Kein parent pool!" );
        const SfxSlot *pSlot = _pParentPool->NextSlot();
        _nCurInterface = _pParentPool->_nCurInterface;
        if ( pSlot )
            return pSlot;
        if ( _nCurInterface == nFirstInterface )
            // parent pool ist fertig
            return SeekSlot( nFirstInterface );
    }

    USHORT nInterface = _nCurInterface - nFirstInterface;
    // possibly we are already at the end
    if ( nInterface >= _pInterfaces->Count() )
        return 0;

    // look for further matching func-defs within the same Interface
    SfxInterface* pInterface = (*_pInterfaces)[nInterface];
    while ( ++_nCurMsg < pInterface->Count() )
    {
        SfxSlot* pMsg = (*pInterface)[_nCurMsg];
        if ( pMsg->GetGroupId() == _pGroups->GetObject(_nCurGroup) )
            return pMsg;
    }

    return SeekSlot(++_nCurInterface );
}

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

// SlotName erfragen, gfs. mit HilfeText

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

SfxInterface* SfxSlotPool::FirstInterface()
{
    _nCurInterface = 0;
    if ( !_pInterfaces || !_pInterfaces->Count() )
        return 0;
    return _pParentPool ? _pParentPool->FirstInterface() : (*_pInterfaces)[0];
}

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

SfxInterface* SfxSlotPool::NextInterface()
{
    _nCurInterface++;
    USHORT nFirstInterface = _pParentPool ? _pParentPool->_pInterfaces->Count() : 0;
    if ( _nCurInterface < nFirstInterface )
        return (*_pParentPool->_pInterfaces)[_nCurInterface];
    USHORT nInterface = _nCurInterface - nFirstInterface;
    return nInterface < _pInterfaces->Count() ? (*_pInterfaces)[nInterface] : 0;
}

const SfxSlot* SfxSlotPool::GetUnoSlot( const String& rName )
{
    const SfxSlot *pSlot = NULL;
    for ( USHORT nInterface=0; nInterface<_pInterfaces->Count(); nInterface++ )
    {
        pSlot = (*_pInterfaces)[nInterface]->GetSlot( rName );
        if ( pSlot )
            break;
    }

    if ( !pSlot && _pParentPool )
        pSlot = _pParentPool->GetUnoSlot( rName );

    return pSlot;
}

SfxSlotPool& SfxSlotPool::GetSlotPool( SfxViewFrame *pFrame )
{
    SfxModule *pMod = SfxModule::GetActiveModule( pFrame );
    if ( pMod && pMod->GetSlotPool() )
        return *pMod->GetSlotPool();
    else
        return *SFX_APP()->Get_Impl()->pSlotPool;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: storagehelper.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 16:36:28 $
 *
 *  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 _COMPHELPER_STORAGEHELPER_HXX
#define _COMPHELPER_STORAGEHELPER_HXX

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif

namespace comphelper {

class OStorageHelper
{
public:
    static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >
        GetStorageFactory(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSF
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetTemporaryStorage(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetStorageFromURL(
            const ::rtl::OUString& aURL,
            sal_Int32 nStorageMode,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetStorageFromInputStream(
            const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetStorageFromStream(
            const ::com::sun::star::uno::Reference < ::com::sun::star::io::XStream >& xStream,
            sal_Int32 nStorageMode = ::com::sun::star::embed::ElementModes::READWRITE,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static void CopyInputToOutput(
            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInput,
            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
        GetInputStreamFromURL(
            const ::rtl::OUString& aURL,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static void SetCommonStoragePassword(
            const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
            const ::rtl::OUString& aPass )
        throw ( ::com::sun::star::uno::Exception );

    static sal_Int32 GetXStorageFormat(
            const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
        throw ( ::com::sun::star::uno::Exception );
};

}

#endif

<commit_msg>INTEGRATION: CWS visibility02 (1.3.10); FILE MERGED 2005/01/05 05:54:12 mnicel 1.3.10.1: Issue number: 38608 Part of symbol visibility work.<commit_after>/*************************************************************************
 *
 *  $RCSfile: storagehelper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-16 16:02:06 $
 *
 *  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 _COMPHELPER_STORAGEHELPER_HXX
#define _COMPHELPER_STORAGEHELPER_HXX

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif
#ifndef INCLUDED_COMPHELPERDLLAPI_H
#include "comphelper/comphelperdllapi.h"
#endif

namespace comphelper {

class COMPHELPER_DLLPUBLIC OStorageHelper
{
public:
    static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >
        GetStorageFactory(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSF
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetTemporaryStorage(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetStorageFromURL(
            const ::rtl::OUString& aURL,
            sal_Int32 nStorageMode,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetStorageFromInputStream(
            const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
        GetStorageFromStream(
            const ::com::sun::star::uno::Reference < ::com::sun::star::io::XStream >& xStream,
            sal_Int32 nStorageMode = ::com::sun::star::embed::ElementModes::READWRITE,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static void CopyInputToOutput(
            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInput,
            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput )
        throw ( ::com::sun::star::uno::Exception );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
        GetInputStreamFromURL(
            const ::rtl::OUString& aURL,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory
                            = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() )
        throw ( ::com::sun::star::uno::Exception );

    static void SetCommonStoragePassword(
            const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
            const ::rtl::OUString& aPass )
        throw ( ::com::sun::star::uno::Exception );

    static sal_Int32 GetXStorageFormat(
            const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
        throw ( ::com::sun::star::uno::Exception );
};

}

#endif

<|endoftext|>