xref: /trunk/main/xmloff/source/core/attrlist.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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