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