LibreOffice Module xmloff (master)  1
unoatrcn.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <com/sun/star/xml/AttributeData.hpp>
22 #include <o3tl/any.hxx>
23 #include <rtl/ustrbuf.hxx>
26 #include <limits.h>
27 
28 #include <xmloff/xmlcnimp.hxx>
29 
30 #include <xmloff/unoatrcn.hxx>
31 
32 using namespace ::com::sun::star;
33 
34 // Interface implementation
35 
36 uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
37 {
38  return *(new SvUnoAttributeContainer);
39 }
40 
41 SvUnoAttributeContainer::SvUnoAttributeContainer( std::unique_ptr<SvXMLAttrContainerData> pContainer)
42 : mpContainer( std::move( pContainer ) )
43 {
44  if( !mpContainer )
45  mpContainer = std::make_unique<SvXMLAttrContainerData>();
46 }
47 
48 // container::XElementAccess
50 {
52 }
53 
55 {
56  return mpContainer->GetAttrCount() != 0;
57 }
58 
59 sal_uInt16 SvUnoAttributeContainer::getIndexByName(const OUString& aName ) const
60 {
61  const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
62 
63  sal_Int32 nPos = aName.indexOf( ':' );
64  if( nPos == -1 )
65  {
66  for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
67  {
68  if( mpContainer->GetAttrLName(nAttr) == aName &&
69  mpContainer->GetAttrPrefix(nAttr).isEmpty() )
70  return nAttr;
71  }
72  }
73  else
74  {
75  const OUString aPrefix( aName.copy( 0L, nPos ) );
76  const OUString aLName( aName.copy( nPos+1 ) );
77 
78  for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
79  {
80  if( mpContainer->GetAttrLName(nAttr) == aLName &&
81  mpContainer->GetAttrPrefix(nAttr) == aPrefix )
82  return nAttr;
83  }
84  }
85 
86  return USHRT_MAX;
87 }
88 
89 namespace
90 {
91  class theSvUnoAttributeContainerUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvUnoAttributeContainerUnoTunnelId> {};
92 }
93 
94 const css::uno::Sequence< sal_Int8 > & SvUnoAttributeContainer::getUnoTunnelId() throw()
95 {
96  return theSvUnoAttributeContainerUnoTunnelId::get().getSeq();
97 }
98 
99 sal_Int64 SAL_CALL SvUnoAttributeContainer::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
100 {
101  if( isUnoTunnelId<SvUnoAttributeContainer>(rId) )
102  {
103  return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
104  }
105  return 0;
106 }
107 
108 // container::XNameAccess
109 uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName)
110 {
111  sal_uInt16 nAttr = getIndexByName(aName );
112 
113  if( nAttr == USHRT_MAX )
114  throw container::NoSuchElementException();
115 
116  xml::AttributeData aData;
117  aData.Namespace = mpContainer->GetAttrNamespace(nAttr);
118  aData.Type = "CDATA";
119  aData.Value = mpContainer->GetAttrValue(nAttr);
120 
121  return uno::Any(aData);
122 }
123 
124 uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames()
125 {
126  const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
127 
128  uno::Sequence< OUString > aElementNames( static_cast<sal_Int32>(nAttrCount) );
129  OUString *pNames = aElementNames.getArray();
130 
131  for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
132  {
133  OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) );
134  if( !sBuffer.isEmpty() )
135  sBuffer.append( ':' );
136  sBuffer.append( mpContainer->GetAttrLName(nAttr) );
137  *pNames++ = sBuffer.makeStringAndClear();
138  }
139 
140  return aElementNames;
141 }
142 
143 sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName)
144 {
145  return getIndexByName(aName ) != USHRT_MAX;
146 }
147 
148 // container::XNameReplace
149 void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement)
150 {
151  if( auto pData = o3tl::tryAccess<xml::AttributeData>(aElement) )
152  {
153  sal_uInt16 nAttr = getIndexByName(aName );
154  if( nAttr == USHRT_MAX )
155  throw container::NoSuchElementException();
156 
157  sal_Int32 nPos = aName.indexOf( ':' );
158  if( nPos != -1 )
159  {
160  const OUString aPrefix( aName.copy( 0L, nPos ));
161  const OUString aLName( aName.copy( nPos+1 ));
162 
163  if( pData->Namespace.isEmpty() )
164  {
165  if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) )
166  return;
167  }
168  else
169  {
170  if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) )
171  return;
172  }
173  }
174  else
175  {
176  if( pData->Namespace.isEmpty() )
177  {
178  if( mpContainer->SetAt( nAttr, aName, pData->Value ) )
179  return;
180  }
181  }
182  }
183 
184  throw lang::IllegalArgumentException();
185 }
186 
187 // container::XNameContainer
188 void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement)
189 {
190  auto pData = o3tl::tryAccess<xml::AttributeData>(aElement);
191  if( !pData )
192  throw lang::IllegalArgumentException();
193 
194  sal_uInt16 nAttr = getIndexByName(aName );
195  if( nAttr != USHRT_MAX )
196  throw container::ElementExistException();
197 
198  sal_Int32 nPos = aName.indexOf( ':' );
199  if( nPos != -1 )
200  {
201  const OUString aPrefix( aName.copy( 0L, nPos ));
202  const OUString aLName( aName.copy( nPos+1 ));
203 
204  if( pData->Namespace.isEmpty() )
205  {
206  if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) )
207  return;
208  }
209  else
210  {
211  if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) )
212  return;
213  }
214  }
215  else
216  {
217  if( pData->Namespace.isEmpty() )
218  {
219  if( mpContainer->AddAttr( aName, pData->Value ) )
220  return;
221  }
222  }
223 }
224 
225 void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name)
226 {
227  sal_uInt16 nAttr = getIndexByName(Name);
228  if( nAttr == USHRT_MAX )
229  throw container::NoSuchElementException();
230 
231  mpContainer->Remove( nAttr );
232 }
233 
234 //XServiceInfo
236 {
237  return "SvUnoAttributeContainer";
238 }
239 
241 {
242  return { "com.sun.star.xml.AttributeContainer" };
243 }
244 
246 {
247  return cppu::supportsService(this, ServiceName);
248 }
249 
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: unoatrcn.cxx:124
std::unique_ptr< ContentProperties > pData
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: unoatrcn.cxx:143
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
Definition: unoatrcn.cxx:99
std::unique_ptr< SvXMLAttrContainerData > mpContainer
Definition: unoatrcn.hxx:46
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual void SAL_CALL removeByName(const OUString &Name) override
Definition: unoatrcn.cxx:225
constexpr OUStringLiteral aData
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: unoatrcn.cxx:94
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: unoatrcn.cxx:109
uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
Definition: unoatrcn.cxx:36
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unoatrcn.cxx:188
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: unoatrcn.cxx:245
SAL_DLLPRIVATE sal_uInt16 getIndexByName(const OUString &aName) const
Definition: unoatrcn.cxx:59
unsigned char sal_Bool
css::uno::Type const & get()
virtual OUString SAL_CALL getImplementationName() override
Definition: unoatrcn.cxx:235
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unoatrcn.cxx:149
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
SvUnoAttributeContainer(std::unique_ptr< SvXMLAttrContainerData > pContainer=nullptr)
Definition: unoatrcn.cxx:41
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unoatrcn.cxx:49
virtual sal_Bool SAL_CALL hasElements() override
Definition: unoatrcn.cxx:54
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unoatrcn.cxx:240
sal_uInt16 nPos