1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmloff.hxx" 26 27 #include <vector> 28 #include <osl/mutex.hxx> 29 #include <xmloff/xmltoken.hxx> 30 #include <rtl/uuid.h> 31 #include <rtl/memory.h> 32 33 #include <xmloff/attrlist.hxx> 34 35 using ::rtl::OUString; 36 37 using namespace ::osl; 38 using namespace ::com::sun::star; 39 using namespace ::xmloff::token; 40 41 struct SvXMLTagAttribute_Impl 42 { 43 SvXMLTagAttribute_Impl(){} 44 SvXMLTagAttribute_Impl( const OUString &rName, 45 const OUString &rValue ) 46 : sName(rName), 47 sValue(rValue) 48 { 49 } 50 51 SvXMLTagAttribute_Impl( const SvXMLTagAttribute_Impl& r ) : 52 sName(r.sName), 53 sValue(r.sValue) 54 { 55 } 56 57 OUString sName; 58 OUString sValue; 59 }; 60 61 struct SvXMLAttributeList_Impl 62 { 63 SvXMLAttributeList_Impl() 64 { 65 // performance improvement during adding 66 vecAttribute.reserve(20); 67 } 68 69 SvXMLAttributeList_Impl( const SvXMLAttributeList_Impl& r ) : 70 vecAttribute( r.vecAttribute ) 71 { 72 } 73 74 ::std::vector<struct SvXMLTagAttribute_Impl> vecAttribute; 75 typedef ::std::vector<struct SvXMLTagAttribute_Impl>::size_type size_type; 76 }; 77 78 79 80 sal_Int16 SAL_CALL SvXMLAttributeList::getLength(void) throw( ::com::sun::star::uno::RuntimeException ) 81 { 82 return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size()); 83 } 84 85 86 SvXMLAttributeList::SvXMLAttributeList( const SvXMLAttributeList &r ) : 87 cppu::WeakImplHelper3<com::sun::star::xml::sax::XAttributeList, com::sun::star::util::XCloneable, com::sun::star::lang::XUnoTunnel>(r), 88 m_pImpl( new SvXMLAttributeList_Impl( *r.m_pImpl ) ) 89 { 90 } 91 92 SvXMLAttributeList::SvXMLAttributeList( const uno::Reference< 93 xml::sax::XAttributeList> & rAttrList ) 94 : sType( GetXMLToken(XML_CDATA) ) 95 { 96 m_pImpl = new SvXMLAttributeList_Impl; 97 98 SvXMLAttributeList* pImpl = 99 SvXMLAttributeList::getImplementation( rAttrList ); 100 101 if( pImpl ) 102 *m_pImpl = *(pImpl->m_pImpl); 103 else 104 AppendAttributeList( rAttrList ); 105 } 106 107 OUString SAL_CALL SvXMLAttributeList::getNameByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException ) 108 { 109 return ( static_cast< SvXMLAttributeList_Impl::size_type >( i ) < m_pImpl->vecAttribute.size() ) ? m_pImpl->vecAttribute[i].sName : OUString(); 110 } 111 112 113 OUString SAL_CALL SvXMLAttributeList::getTypeByIndex(sal_Int16) throw( ::com::sun::star::uno::RuntimeException ) 114 { 115 return sType; 116 } 117 118 OUString SAL_CALL SvXMLAttributeList::getValueByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException ) 119 { 120 return ( static_cast< SvXMLAttributeList_Impl::size_type >( i ) < m_pImpl->vecAttribute.size() ) ? m_pImpl->vecAttribute[i].sValue : OUString(); 121 } 122 123 OUString SAL_CALL SvXMLAttributeList::getTypeByName( const OUString& ) throw( ::com::sun::star::uno::RuntimeException ) 124 { 125 return sType; 126 } 127 128 OUString SAL_CALL SvXMLAttributeList::getValueByName(const OUString& sName) throw( ::com::sun::star::uno::RuntimeException ) 129 { 130 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin(); 131 132 for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) { 133 if( (*ii).sName == sName ) { 134 return (*ii).sValue; 135 } 136 } 137 return OUString(); 138 } 139 140 141 uno::Reference< ::com::sun::star::util::XCloneable > SvXMLAttributeList::createClone() throw( ::com::sun::star::uno::RuntimeException ) 142 { 143 uno::Reference< ::com::sun::star::util::XCloneable > r = new SvXMLAttributeList( *this ); 144 return r; 145 } 146 147 148 SvXMLAttributeList::SvXMLAttributeList() 149 : sType( GetXMLToken(XML_CDATA) ) 150 { 151 m_pImpl = new SvXMLAttributeList_Impl; 152 } 153 154 155 156 SvXMLAttributeList::~SvXMLAttributeList() 157 { 158 delete m_pImpl; 159 } 160 161 162 void SvXMLAttributeList::AddAttribute( const OUString &sName , 163 const OUString &sValue ) 164 { 165 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) ); 166 } 167 168 void SvXMLAttributeList::Clear() 169 { 170 m_pImpl->vecAttribute.clear(); 171 172 OSL_ASSERT( ! getLength() ); 173 } 174 175 void SvXMLAttributeList::RemoveAttribute( const OUString sName ) 176 { 177 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin(); 178 179 for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) { 180 if( (*ii).sName == sName ) { 181 m_pImpl->vecAttribute.erase( ii ); 182 break; 183 } 184 } 185 } 186 187 188 void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r ) 189 { 190 Clear(); 191 AppendAttributeList( r ); 192 } 193 194 void SvXMLAttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r ) 195 { 196 OSL_ASSERT( r.is() ); 197 198 sal_Int16 nMax = r->getLength(); 199 SvXMLAttributeList_Impl::size_type nTotalSize = 200 m_pImpl->vecAttribute.size() + nMax; 201 m_pImpl->vecAttribute.reserve( nTotalSize ); 202 203 for( sal_Int16 i = 0 ; i < nMax ; ++i ) { 204 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( 205 r->getNameByIndex( i ) , 206 r->getValueByIndex( i ))); 207 } 208 209 OSL_ASSERT( nTotalSize == (SvXMLAttributeList_Impl::size_type)getLength()); 210 } 211 212 void SvXMLAttributeList::SetValueByIndex( sal_Int16 i, 213 const ::rtl::OUString& rValue ) 214 { 215 if( static_cast< SvXMLAttributeList_Impl::size_type >( i ) 216 < m_pImpl->vecAttribute.size() ) 217 { 218 m_pImpl->vecAttribute[i].sValue = rValue; 219 } 220 } 221 222 void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i ) 223 { 224 if( static_cast< SvXMLAttributeList_Impl::size_type >( i ) 225 < m_pImpl->vecAttribute.size() ) 226 m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i ); 227 } 228 229 void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i, 230 const OUString& rNewName ) 231 { 232 if( static_cast< SvXMLAttributeList_Impl::size_type >( i ) 233 < m_pImpl->vecAttribute.size() ) 234 { 235 m_pImpl->vecAttribute[i].sName = rNewName; 236 } 237 } 238 239 sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const 240 { 241 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = 242 m_pImpl->vecAttribute.begin(); 243 244 for( sal_Int16 nIndex=0; ii!=m_pImpl->vecAttribute.end(); ++ii, ++nIndex ) 245 { 246 if( (*ii).sName == rName ) 247 { 248 return nIndex; 249 } 250 } 251 return -1; 252 } 253 254 // XUnoTunnel & co 255 const uno::Sequence< sal_Int8 > & SvXMLAttributeList::getUnoTunnelId() throw() 256 { 257 static uno::Sequence< sal_Int8 > * pSeq = 0; 258 if( !pSeq ) 259 { 260 Guard< Mutex > aGuard( Mutex::getGlobalMutex() ); 261 if( !pSeq ) 262 { 263 static uno::Sequence< sal_Int8 > aSeq( 16 ); 264 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 265 pSeq = &aSeq; 266 } 267 } 268 return *pSeq; 269 } 270 271 SvXMLAttributeList* SvXMLAttributeList::getImplementation( uno::Reference< uno::XInterface > xInt ) throw() 272 { 273 uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY ); 274 if( xUT.is() ) 275 { 276 return 277 reinterpret_cast<SvXMLAttributeList*>( 278 sal::static_int_cast<sal_IntPtr>( 279 xUT->getSomething( SvXMLAttributeList::getUnoTunnelId()))); 280 } 281 else 282 return NULL; 283 } 284 285 // XUnoTunnel 286 sal_Int64 SAL_CALL SvXMLAttributeList::getSomething( const uno::Sequence< sal_Int8 >& rId ) 287 throw( uno::RuntimeException ) 288 { 289 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 290 rId.getConstArray(), 16 ) ) 291 { 292 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); 293 } 294 return 0; 295 } 296 297 298