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 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) );
166 }
167
Clear()168 void SvXMLAttributeList::Clear()
169 {
170 m_pImpl->vecAttribute.clear();
171
172 OSL_ASSERT( ! getLength() );
173 }
174
RemoveAttribute(const OUString sName)175 void SvXMLAttributeList::RemoveAttribute( const OUString sName )
176 {
177 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin();
178
179 for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
180 if( (*ii).sName == sName ) {
181 m_pImpl->vecAttribute.erase( ii );
182 break;
183 }
184 }
185 }
186
187
SetAttributeList(const uno::Reference<::com::sun::star::xml::sax::XAttributeList> & r)188 void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r )
189 {
190 Clear();
191 AppendAttributeList( r );
192 }
193
AppendAttributeList(const uno::Reference<::com::sun::star::xml::sax::XAttributeList> & r)194 void SvXMLAttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r )
195 {
196 OSL_ASSERT( r.is() );
197
198 sal_Int16 nMax = r->getLength();
199 SvXMLAttributeList_Impl::size_type nTotalSize =
200 m_pImpl->vecAttribute.size() + nMax;
201 m_pImpl->vecAttribute.reserve( nTotalSize );
202
203 for( sal_Int16 i = 0 ; i < nMax ; ++i ) {
204 m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl(
205 r->getNameByIndex( i ) ,
206 r->getValueByIndex( i )));
207 }
208
209 OSL_ASSERT( nTotalSize == (SvXMLAttributeList_Impl::size_type)getLength());
210 }
211
SetValueByIndex(sal_Int16 i,const::rtl::OUString & rValue)212 void SvXMLAttributeList::SetValueByIndex( sal_Int16 i,
213 const ::rtl::OUString& rValue )
214 {
215 if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
216 < m_pImpl->vecAttribute.size() )
217 {
218 m_pImpl->vecAttribute[i].sValue = rValue;
219 }
220 }
221
RemoveAttributeByIndex(sal_Int16 i)222 void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i )
223 {
224 if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
225 < m_pImpl->vecAttribute.size() )
226 m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i );
227 }
228
RenameAttributeByIndex(sal_Int16 i,const OUString & rNewName)229 void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i,
230 const OUString& rNewName )
231 {
232 if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
233 < m_pImpl->vecAttribute.size() )
234 {
235 m_pImpl->vecAttribute[i].sName = rNewName;
236 }
237 }
238
GetIndexByName(const OUString & rName) const239 sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const
240 {
241 ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii =
242 m_pImpl->vecAttribute.begin();
243
244 for( sal_Int16 nIndex=0; ii!=m_pImpl->vecAttribute.end(); ++ii, ++nIndex )
245 {
246 if( (*ii).sName == rName )
247 {
248 return nIndex;
249 }
250 }
251 return -1;
252 }
253
254 // XUnoTunnel & co
getUnoTunnelId()255 const uno::Sequence< sal_Int8 > & SvXMLAttributeList::getUnoTunnelId() throw()
256 {
257 static uno::Sequence< sal_Int8 > * pSeq = 0;
258 if( !pSeq )
259 {
260 Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
261 if( !pSeq )
262 {
263 static uno::Sequence< sal_Int8 > aSeq( 16 );
264 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
265 pSeq = &aSeq;
266 }
267 }
268 return *pSeq;
269 }
270
getImplementation(uno::Reference<uno::XInterface> xInt)271 SvXMLAttributeList* SvXMLAttributeList::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
272 {
273 uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
274 if( xUT.is() )
275 {
276 return
277 reinterpret_cast<SvXMLAttributeList*>(
278 sal::static_int_cast<sal_IntPtr>(
279 xUT->getSomething( SvXMLAttributeList::getUnoTunnelId())));
280 }
281 else
282 return NULL;
283 }
284
285 // XUnoTunnel
getSomething(const uno::Sequence<sal_Int8> & rId)286 sal_Int64 SAL_CALL SvXMLAttributeList::getSomething( const uno::Sequence< sal_Int8 >& rId )
287 throw( uno::RuntimeException )
288 {
289 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
290 rId.getConstArray(), 16 ) )
291 {
292 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
293 }
294 return 0;
295 }
296
297
298