xref: /trunk/main/xmloff/source/core/attrlist.cxx (revision 498c5314b25c4b59dffa5ced0e77ac859c79ac96)
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 {
43     SvXMLTagAttribute_Impl(){}
44     SvXMLTagAttribute_Impl( const OUString &rName,
45                          const OUString &rValue )
46         : sName(rName),
47         sValue(rValue)
48     {
49     }
50 
51     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 {
63     SvXMLAttributeList_Impl()
64     {
65         // performance improvement during adding
66         vecAttribute.reserve(20);
67     }
68 
69     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 
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 
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 
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 
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 
113 OUString SAL_CALL SvXMLAttributeList::getTypeByIndex(sal_Int16) throw( ::com::sun::star::uno::RuntimeException )
114 {
115     return sType;
116 }
117 
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 
123 OUString SAL_CALL SvXMLAttributeList::getTypeByName( const OUString& ) throw( ::com::sun::star::uno::RuntimeException )
124 {
125     return sType;
126 }
127 
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 
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 
148 SvXMLAttributeList::SvXMLAttributeList()
149     : sType( GetXMLToken(XML_CDATA) )
150 {
151     m_pImpl = new SvXMLAttributeList_Impl;
152 }
153 
154 
155 
156 SvXMLAttributeList::~SvXMLAttributeList()
157 {
158     delete m_pImpl;
159 }
160 
161 
162 void SvXMLAttributeList::AddAttribute(  const OUString &sName ,
163                                         const OUString &sValue )
164 {
165     OSL_ASSERT(GetIndexByName(sName) == -1); // TODO raise an exception
166     m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) );
167 }
168 
169 void SvXMLAttributeList::Clear()
170 {
171     m_pImpl->vecAttribute.clear();
172 
173     OSL_ASSERT( ! getLength() );
174 }
175 
176 void SvXMLAttributeList::RemoveAttribute( const OUString sName )
177 {
178     ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin();
179 
180     for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
181         if( (*ii).sName == sName ) {
182             m_pImpl->vecAttribute.erase( ii );
183             break;
184         }
185     }
186 }
187 
188 
189 void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
190 {
191     Clear();
192     AppendAttributeList( r );
193 }
194 
195 void SvXMLAttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
196 {
197     OSL_ASSERT( r.is() );
198 
199     sal_Int16 nMax = r->getLength();
200     SvXMLAttributeList_Impl::size_type nTotalSize =
201         m_pImpl->vecAttribute.size() + nMax;
202     m_pImpl->vecAttribute.reserve( nTotalSize );
203 
204     OUString sName;
205     for( sal_Int16 i = 0 ; i < nMax ; ++i ) {
206         sName = r->getNameByIndex(i);
207         OSL_ASSERT(GetIndexByName(sName) == -1); // TODO raise an exception
208         m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl(
209             sName ,
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