/* -*- 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 . */ #include #include #include #include #include #include #include #include #include #include using namespace ::cppu; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; namespace svx { namespace { /** implements a component to export namespaces of all SvXMLAttrContainerItem inside one or two pools with a variable count of which ids. */ class NamespaceMap : public WeakImplHelper< XNameAccess, XServiceInfo > { private: sal_uInt16* mpWhichIds; SfxItemPool* mpPool; public: NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool ); // XNameAccess virtual Any SAL_CALL getByName( const OUString& aName ) override; virtual Sequence< OUString > SAL_CALL getElementNames( ) override; virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; // XElementAccess virtual Type SAL_CALL getElementType( ) override; virtual sal_Bool SAL_CALL hasElements( ) override; // XServiceInfo virtual OUString SAL_CALL getImplementationName( ) override; virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; }; } Reference< XInterface > NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool ) { return getXWeak(new NamespaceMap( pWhichIds, pPool )); } static Sequence< OUString > NamespaceMap_getSupportedServiceNames() noexcept { Sequence aSupportedServiceNames { u"com.sun.star.xml.NamespaceMap"_ustr }; return aSupportedServiceNames; } static OUString NamespaceMap_getImplementationName() noexcept { return u"com.sun.star.comp.Svx.NamespaceMap"_ustr; } namespace { class NamespaceIteratorImpl { private: SfxItemPool* mpPool; sal_uInt16* mpWhichId; std::vector mvItems; sal_Int32 mnItem; const SvXMLAttrContainerItem* mpCurrentAttr; sal_uInt16 mnCurrentAttr; public: NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool ); bool next( OUString& rPrefix, OUString& rURL ); }; } } using namespace ::svx; NamespaceIteratorImpl::NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool ) { mpPool = pPool; mpCurrentAttr = nullptr; mnCurrentAttr = 0; mpWhichId = pWhichIds; mnItem = -1; if (mpWhichId && (0 != *mpWhichId) && mpPool) { ItemSurrogates aSurrogates; mpPool->GetItemSurrogates(aSurrogates, *mpWhichId); mvItems.reserve(aSurrogates.size()); for (const SfxPoolItem* pItem : aSurrogates) mvItems.push_back(static_cast(pItem)); } } bool NamespaceIteratorImpl::next( OUString& rPrefix, OUString& rURL ) { // we still need to process the current attribute if( mpCurrentAttr && (mnCurrentAttr != USHRT_MAX) ) { rPrefix = mpCurrentAttr->GetPrefix( mnCurrentAttr ); rURL = mpCurrentAttr->GetNamespace( mnCurrentAttr ); mnCurrentAttr = mpCurrentAttr->GetNextNamespaceIndex( mnCurrentAttr ); return true; } // we need the next namespace item mpCurrentAttr = nullptr; mnItem++; // are we finished with the current whichid? if( mnItem == static_cast(mvItems.size()) ) { mpWhichId++; // are we finished with the current pool? if( 0 == *mpWhichId ) return false; mnItem = -1; mvItems.clear(); if (mpPool) { ItemSurrogates aSurrogates; mpPool->GetItemSurrogates(aSurrogates, *mpWhichId); mvItems.reserve(aSurrogates.size()); for (const SfxPoolItem* pItem2 : aSurrogates) mvItems.push_back(static_cast(pItem2)); } return next( rPrefix, rURL ); } auto pItem = mvItems[mnItem]; // get that item and see if there namespaces inside if( pItem->GetAttrCount() > 0 ) { mpCurrentAttr = pItem; mnCurrentAttr = pItem->GetFirstNamespaceIndex(); } return next( rPrefix, rURL ); } NamespaceMap::NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool ) : mpWhichIds( pWhichIds ), mpPool( pPool ) { } // XNameAccess Any SAL_CALL NamespaceMap::getByName( const OUString& aName ) { NamespaceIteratorImpl aIter( mpWhichIds, mpPool ); OUString aPrefix; OUString aURL; bool bFound; do { bFound = aIter.next( aPrefix, aURL ); } while( bFound && (aPrefix != aName ) ); if( !bFound ) throw NoSuchElementException(); return Any( aURL ); } Sequence< OUString > SAL_CALL NamespaceMap::getElementNames() { NamespaceIteratorImpl aIter( mpWhichIds, mpPool ); OUString aPrefix; OUString aURL; std::set< OUString > aPrefixSet; while( aIter.next( aPrefix, aURL ) ) aPrefixSet.insert( aPrefix ); return comphelper::containerToSequence(aPrefixSet); } sal_Bool SAL_CALL NamespaceMap::hasByName( const OUString& aName ) { NamespaceIteratorImpl aIter( mpWhichIds, mpPool ); OUString aPrefix; OUString aURL; bool bFound; do { bFound = aIter.next( aPrefix, aURL ); } while( bFound && (aPrefix != aName ) ); return bFound; } // XElementAccess Type SAL_CALL NamespaceMap::getElementType() { return ::cppu::UnoType::get(); } sal_Bool SAL_CALL NamespaceMap::hasElements() { NamespaceIteratorImpl aIter( mpWhichIds, mpPool ); OUString aPrefix; OUString aURL; return aIter.next( aPrefix, aURL ); } // XServiceInfo OUString SAL_CALL NamespaceMap::getImplementationName( ) { return NamespaceMap_getImplementationName(); } sal_Bool SAL_CALL NamespaceMap::supportsService( const OUString& serviceName ) { return cppu::supportsService( this, serviceName ); } Sequence< OUString > SAL_CALL NamespaceMap::getSupportedServiceNames( ) { return NamespaceMap_getSupportedServiceNames(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */