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