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 if (GetIndexByName(sName) == -1) { 166 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) ); 167 } else { 168 throw com::sun::star::uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("attempt to insert duplicate XML tag attribute: ")) + sName, NULL); 169 } 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 OUString sName; 208 for( sal_Int16 i = 0 ; i < nMax ; ++i ) { 209 sName = r->getNameByIndex(i); 210 if (GetIndexByName(sName) == -1) { 211 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( 212 sName , 213 r->getValueByIndex( i ))); 214 } else { 215 throw com::sun::star::uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("attempt to insert duplicate XML tag attribute: ")) + sName, NULL); 216 } 217 } 218 219 OSL_ASSERT( nTotalSize == (SvXMLAttributeList_Impl::size_type)getLength()); 220 } 221 222 void SvXMLAttributeList::SetValueByIndex( sal_Int16 i, 223 const ::rtl::OUString& rValue ) 224 { 225 if( static_cast< SvXMLAttributeList_Impl::size_type >( i ) 226 < m_pImpl->vecAttribute.size() ) 227 { 228 m_pImpl->vecAttribute[i].sValue = rValue; 229 } 230 } 231 232 void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i ) 233 { 234 if( static_cast< SvXMLAttributeList_Impl::size_type >( i ) 235 < m_pImpl->vecAttribute.size() ) 236 m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i ); 237 } 238 239 void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i, 240 const OUString& rNewName ) 241 { 242 if( static_cast< SvXMLAttributeList_Impl::size_type >( i ) 243 < m_pImpl->vecAttribute.size() ) 244 { 245 m_pImpl->vecAttribute[i].sName = rNewName; 246 } 247 } 248 249 sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const 250 { 251 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = 252 m_pImpl->vecAttribute.begin(); 253 254 for( sal_Int16 nIndex=0; ii!=m_pImpl->vecAttribute.end(); ++ii, ++nIndex ) 255 { 256 if( (*ii).sName == rName ) 257 { 258 return nIndex; 259 } 260 } 261 return -1; 262 } 263 264 // XUnoTunnel & co 265 const uno::Sequence< sal_Int8 > & SvXMLAttributeList::getUnoTunnelId() throw() 266 { 267 static uno::Sequence< sal_Int8 > * pSeq = 0; 268 if( !pSeq ) 269 { 270 Guard< Mutex > aGuard( Mutex::getGlobalMutex() ); 271 if( !pSeq ) 272 { 273 static uno::Sequence< sal_Int8 > aSeq( 16 ); 274 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 275 pSeq = &aSeq; 276 } 277 } 278 return *pSeq; 279 } 280 281 SvXMLAttributeList* SvXMLAttributeList::getImplementation( uno::Reference< uno::XInterface > xInt ) throw() 282 { 283 uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY ); 284 if( xUT.is() ) 285 { 286 return 287 reinterpret_cast<SvXMLAttributeList*>( 288 sal::static_int_cast<sal_IntPtr>( 289 xUT->getSomething( SvXMLAttributeList::getUnoTunnelId()))); 290 } 291 else 292 return NULL; 293 } 294 295 // XUnoTunnel 296 sal_Int64 SAL_CALL SvXMLAttributeList::getSomething( const uno::Sequence< sal_Int8 >& rId ) 297 throw( uno::RuntimeException ) 298 { 299 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 300 rId.getConstArray(), 16 ) ) 301 { 302 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); 303 } 304 return 0; 305 } 306