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