1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include "attriblistmerge.hxx" 21 22 #include <osl/diagnose.h> 23 24 #include <numeric> 25 26 namespace xmloff 27 { 28 29 using namespace ::com::sun::star::uno; 30 using namespace ::com::sun::star; 31 32 //= OAttribListMerger addList(const Reference<xml::sax::XAttributeList> & _rxList)33 void OAttribListMerger::addList(const Reference< xml::sax::XAttributeList >& _rxList) 34 { 35 OSL_ENSURE(_rxList.is(), "OAttribListMerger::addList: invalid list!"); 36 if (_rxList.is()) 37 m_aLists.push_back(_rxList); 38 } 39 seekToIndex(sal_Int16 _nGlobalIndex,Reference<xml::sax::XAttributeList> & _rSubList,sal_Int16 & _rLocalIndex)40 bool OAttribListMerger::seekToIndex(sal_Int16 _nGlobalIndex, Reference< xml::sax::XAttributeList >& _rSubList, sal_Int16& _rLocalIndex) 41 { 42 sal_Int16 nLeftOver = _nGlobalIndex; 43 AttributeListArray::const_iterator aLookupSublist = m_aLists.begin(); 44 45 for ( ; (aLookupSublist != m_aLists.end()) && (nLeftOver >= (*aLookupSublist)->getLength()); 46 ++aLookupSublist 47 ) 48 nLeftOver = nLeftOver - (*aLookupSublist)->getLength(); 49 50 if (aLookupSublist == m_aLists.end()) 51 { 52 OSL_FAIL("OAttribListMerger::seekToIndex: invalid index!"); 53 return false; 54 } 55 _rSubList = *aLookupSublist; 56 _rLocalIndex = nLeftOver; 57 return true; 58 } 59 seekToName(const OUString & _rName,Reference<xml::sax::XAttributeList> & _rSubList,sal_Int16 & _rLocalIndex)60 bool OAttribListMerger::seekToName(const OUString& _rName, Reference< xml::sax::XAttributeList >& _rSubList, sal_Int16& _rLocalIndex) 61 { 62 for ( const auto& rLookupSublist : m_aLists ) 63 for (sal_Int16 i=0; i<rLookupSublist->getLength(); ++i) 64 if (rLookupSublist->getNameByIndex(i) == _rName) 65 { 66 _rSubList = rLookupSublist; 67 _rLocalIndex = i; 68 return true; 69 } 70 71 OSL_FAIL("OAttribListMerger::seekToName: did not find the name!"); 72 return false; 73 } 74 getLength()75 sal_Int16 SAL_CALL OAttribListMerger::getLength( ) 76 { 77 return std::accumulate(m_aLists.begin(), m_aLists.end(), static_cast<sal_Int16>(0), 78 [](sal_Int16 sum, AttributeListArray::value_type& rAccumulate) { return sum + rAccumulate->getLength(); }); 79 } 80 getNameByIndex(sal_Int16 i)81 OUString SAL_CALL OAttribListMerger::getNameByIndex( sal_Int16 i ) 82 { 83 Reference< xml::sax::XAttributeList > xSubList; 84 sal_Int16 nLocalIndex; 85 86 if (!seekToIndex(i, xSubList, nLocalIndex)) 87 return OUString(); 88 89 return xSubList->getNameByIndex(nLocalIndex); 90 } 91 getTypeByIndex(sal_Int16 i)92 OUString SAL_CALL OAttribListMerger::getTypeByIndex( sal_Int16 i ) 93 { 94 Reference< xml::sax::XAttributeList > xSubList; 95 sal_Int16 nLocalIndex; 96 97 if (!seekToIndex(i, xSubList, nLocalIndex)) 98 return OUString(); 99 100 return xSubList->getTypeByIndex(nLocalIndex); 101 } 102 getTypeByName(const OUString & _rName)103 OUString SAL_CALL OAttribListMerger::getTypeByName( const OUString& _rName ) 104 { 105 Reference< xml::sax::XAttributeList > xSubList; 106 sal_Int16 nLocalIndex; 107 108 if (!seekToName(_rName, xSubList, nLocalIndex)) 109 return OUString(); 110 111 // though we're in getTypeByName here, we reroute this to the getTypeByIndex of the sub list, 112 // assuming that this is faster 113 return xSubList->getTypeByIndex(nLocalIndex); 114 } 115 getValueByIndex(sal_Int16 i)116 OUString SAL_CALL OAttribListMerger::getValueByIndex( sal_Int16 i ) 117 { 118 Reference< xml::sax::XAttributeList > xSubList; 119 sal_Int16 nLocalIndex; 120 121 if (!seekToIndex(i, xSubList, nLocalIndex)) 122 return OUString(); 123 124 return xSubList->getValueByIndex(nLocalIndex); 125 } 126 getValueByName(const OUString & _rName)127 OUString SAL_CALL OAttribListMerger::getValueByName( const OUString& _rName ) 128 { 129 Reference< xml::sax::XAttributeList > xSubList; 130 sal_Int16 nLocalIndex; 131 132 if (!seekToName(_rName, xSubList, nLocalIndex)) 133 return OUString(); 134 135 // though we're in getValueByName here, we reroute this to the getValueByIndex of the sub list, 136 // assuming that this is faster 137 return xSubList->getValueByIndex(nLocalIndex); 138 } 139 140 } // namespace xmloff 141 142 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 143