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 OSL_ASSERT(GetIndexByName(sName) == -1); // TODO raise an exception 166 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) ); 167 } 168 169 void SvXMLAttributeList::Clear() 170 { 171 m_pImpl->vecAttribute.clear(); 172 173 OSL_ASSERT( ! getLength() ); 174 } 175 176 void SvXMLAttributeList::RemoveAttribute( const OUString sName ) 177 { 178 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin(); 179 180 for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) { 181 if( (*ii).sName == sName ) { 182 m_pImpl->vecAttribute.erase( ii ); 183 break; 184 } 185 } 186 } 187 188 189 void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r ) 190 { 191 Clear(); 192 AppendAttributeList( r ); 193 } 194 195 void SvXMLAttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r ) 196 { 197 OSL_ASSERT( r.is() ); 198 199 sal_Int16 nMax = r->getLength(); 200 SvXMLAttributeList_Impl::size_type nTotalSize = 201 m_pImpl->vecAttribute.size() + nMax; 202 m_pImpl->vecAttribute.reserve( nTotalSize ); 203 204 OUString sName; 205 for( sal_Int16 i = 0 ; i < nMax ; ++i ) { 206 sName = r->getNameByIndex(i); 207 OSL_ASSERT(GetIndexByName(sName) == -1); // TODO raise an exception 208 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( 209 sName , 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