xref: /trunk/main/xmloff/source/core/attrlist.cxx (revision ebd28ad3)
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 {
SvXMLTagAttribute_ImplSvXMLTagAttribute_Impl43 	SvXMLTagAttribute_Impl(){}
SvXMLTagAttribute_ImplSvXMLTagAttribute_Impl44 	SvXMLTagAttribute_Impl( const OUString &rName,
45 						 const OUString &rValue )
46 		: sName(rName),
47 		sValue(rValue)
48 	{
49 	}
50 
SvXMLTagAttribute_ImplSvXMLTagAttribute_Impl51 	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 {
SvXMLAttributeList_ImplSvXMLAttributeList_Impl63 	SvXMLAttributeList_Impl()
64 	{
65 		// performance improvement during adding
66 		vecAttribute.reserve(20);
67 	}
68 
SvXMLAttributeList_ImplSvXMLAttributeList_Impl69 	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 
getLength(void)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 
SvXMLAttributeList(const SvXMLAttributeList & r)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 
SvXMLAttributeList(const uno::Reference<xml::sax::XAttributeList> & rAttrList)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 
getNameByIndex(sal_Int16 i)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 
getTypeByIndex(sal_Int16)113 OUString SAL_CALL SvXMLAttributeList::getTypeByIndex(sal_Int16) throw( ::com::sun::star::uno::RuntimeException )
114 {
115     return sType;
116 }
117 
getValueByIndex(sal_Int16 i)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 
getTypeByName(const OUString &)123 OUString SAL_CALL SvXMLAttributeList::getTypeByName( const OUString& ) throw( ::com::sun::star::uno::RuntimeException )
124 {
125     return sType;
126 }
127 
getValueByName(const OUString & sName)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 
createClone()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 
SvXMLAttributeList()148 SvXMLAttributeList::SvXMLAttributeList()
149     : sType( GetXMLToken(XML_CDATA) )
150 {
151 	m_pImpl = new SvXMLAttributeList_Impl;
152 }
153 
154 
155 
~SvXMLAttributeList()156 SvXMLAttributeList::~SvXMLAttributeList()
157 {
158 	delete m_pImpl;
159 }
160 
161 
AddAttribute(const OUString & sName,const OUString & sValue)162 void SvXMLAttributeList::AddAttribute( 	const OUString &sName ,
163 										const OUString &sValue )
164 {
165     if (GetIndexByName(sName) == -1) {
166 		m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) );
167     } else {
168         throw com::sun::star::uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("attempt to insert duplicate XML tag attribute: ")) + sName, NULL);
169     }
170 }
171 
Clear()172 void SvXMLAttributeList::Clear()
173 {
174 	m_pImpl->vecAttribute.clear();
175 
176 	OSL_ASSERT( ! getLength() );
177 }
178 
RemoveAttribute(const OUString sName)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 
SetAttributeList(const uno::Reference<::com::sun::star::xml::sax::XAttributeList> & r)192 void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
193 {
194 	Clear();
195 	AppendAttributeList( r );
196 }
197 
AppendAttributeList(const uno::Reference<::com::sun::star::xml::sax::XAttributeList> & r)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     OUString sName;
208 	for( sal_Int16 i = 0 ; i < nMax ; ++i ) {
209         sName = r->getNameByIndex(i);
210         if (GetIndexByName(sName) == -1) {
211             m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl(
212                 sName ,
213 			    r->getValueByIndex( i )));
214         } else {
215             throw com::sun::star::uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("attempt to insert duplicate XML tag attribute: ")) + sName, NULL);
216         }
217 	}
218 
219 	OSL_ASSERT( nTotalSize == (SvXMLAttributeList_Impl::size_type)getLength());
220 }
221 
SetValueByIndex(sal_Int16 i,const::rtl::OUString & rValue)222 void SvXMLAttributeList::SetValueByIndex( sal_Int16 i,
223 		const ::rtl::OUString& rValue )
224 {
225 	if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
226 			< m_pImpl->vecAttribute.size() )
227 	{
228 		m_pImpl->vecAttribute[i].sValue = rValue;
229 	}
230 }
231 
RemoveAttributeByIndex(sal_Int16 i)232 void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i )
233 {
234     if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
235 			< m_pImpl->vecAttribute.size() )
236 		m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i );
237 }
238 
RenameAttributeByIndex(sal_Int16 i,const OUString & rNewName)239 void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i,
240 												 const OUString& rNewName )
241 {
242 	if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
243 			< m_pImpl->vecAttribute.size() )
244 	{
245 		m_pImpl->vecAttribute[i].sName = rNewName;
246 	}
247 }
248 
GetIndexByName(const OUString & rName) const249 sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const
250 {
251 	::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii =
252 		m_pImpl->vecAttribute.begin();
253 
254 	for( sal_Int16 nIndex=0; ii!=m_pImpl->vecAttribute.end(); ++ii, ++nIndex )
255 	{
256 		if( (*ii).sName == rName )
257 		{
258 			return nIndex;
259 		}
260 	}
261 	return -1;
262 }
263 
264 // XUnoTunnel & co
getUnoTunnelId()265 const uno::Sequence< sal_Int8 > & SvXMLAttributeList::getUnoTunnelId() throw()
266 {
267 	static uno::Sequence< sal_Int8 > * pSeq = 0;
268 	if( !pSeq )
269 	{
270 		Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
271 		if( !pSeq )
272 		{
273 			static uno::Sequence< sal_Int8 > aSeq( 16 );
274 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
275 			pSeq = &aSeq;
276 		}
277 	}
278 	return *pSeq;
279 }
280 
getImplementation(uno::Reference<uno::XInterface> xInt)281 SvXMLAttributeList* SvXMLAttributeList::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
282 {
283 	uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
284 	if( xUT.is() )
285 	{
286 		return
287 			reinterpret_cast<SvXMLAttributeList*>(
288 				sal::static_int_cast<sal_IntPtr>(
289 					xUT->getSomething( SvXMLAttributeList::getUnoTunnelId())));
290 	}
291 	else
292 		return NULL;
293 }
294 
295 // XUnoTunnel
getSomething(const uno::Sequence<sal_Int8> & rId)296 sal_Int64 SAL_CALL SvXMLAttributeList::getSomething( const uno::Sequence< sal_Int8 >& rId )
297 	throw( uno::RuntimeException )
298 {
299 	if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
300 														 rId.getConstArray(), 16 ) )
301 	{
302 		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
303 	}
304 	return 0;
305 }
306 
307 
308