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