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 const css::uno::Sequence< sal_Int8 > & SvUnoAttributeContainer::getUnoTunnelId() noexcept
90 {
91  static const comphelper::UnoIdInit theSvUnoAttributeContainerUnoTunnelId;
92  return theSvUnoAttributeContainerUnoTunnelId.getSeq();
93 }
94 
95 sal_Int64 SAL_CALL SvUnoAttributeContainer::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
96 {
97  return comphelper::getSomethingImpl(rId, this);
98 }
99 
100 // container::XNameAccess
101 uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName)
102 {
103  sal_uInt16 nAttr = getIndexByName(aName );
104 
105  if( nAttr == USHRT_MAX )
106  throw container::NoSuchElementException();
107 
108  xml::AttributeData aData;
109  aData.Namespace = mpContainer->GetAttrNamespace(nAttr);
110  aData.Type = "CDATA";
111  aData.Value = mpContainer->GetAttrValue(nAttr);
112 
113  return uno::Any(aData);
114 }
115 
116 uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames()
117 {
118  const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
119 
120  uno::Sequence< OUString > aElementNames( static_cast<sal_Int32>(nAttrCount) );
121  OUString *pNames = aElementNames.getArray();
122 
123  for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
124  {
125  OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) );
126  if( !sBuffer.isEmpty() )
127  sBuffer.append( ':' );
128  sBuffer.append( mpContainer->GetAttrLName(nAttr) );
129  *pNames++ = sBuffer.makeStringAndClear();
130  }
131 
132  return aElementNames;
133 }
134 
135 sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName)
136 {
137  return getIndexByName(aName ) != USHRT_MAX;
138 }
139 
140 // container::XNameReplace
141 void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement)
142 {
143  if( auto pData = o3tl::tryAccess<xml::AttributeData>(aElement) )
144  {
145  sal_uInt16 nAttr = getIndexByName(aName );
146  if( nAttr == USHRT_MAX )
147  throw container::NoSuchElementException();
148 
149  sal_Int32 nPos = aName.indexOf( ':' );
150  if( nPos != -1 )
151  {
152  const OUString aPrefix( aName.copy( 0L, nPos ));
153  const OUString aLName( aName.copy( nPos+1 ));
154 
155  if( pData->Namespace.isEmpty() )
156  {
157  if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) )
158  return;
159  }
160  else
161  {
162  if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) )
163  return;
164  }
165  }
166  else
167  {
168  if( pData->Namespace.isEmpty() )
169  {
170  if( mpContainer->SetAt( nAttr, aName, pData->Value ) )
171  return;
172  }
173  }
174  }
175 
176  throw lang::IllegalArgumentException();
177 }
178 
179 // container::XNameContainer
180 void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement)
181 {
182  auto pData = o3tl::tryAccess<xml::AttributeData>(aElement);
183  if( !pData )
184  throw lang::IllegalArgumentException();
185 
186  sal_uInt16 nAttr = getIndexByName(aName );
187  if( nAttr != USHRT_MAX )
188  throw container::ElementExistException();
189 
190  sal_Int32 nPos = aName.indexOf( ':' );
191  if( nPos != -1 )
192  {
193  const OUString aPrefix( aName.copy( 0L, nPos ));
194  const OUString aLName( aName.copy( nPos+1 ));
195 
196  if( pData->Namespace.isEmpty() )
197  {
198  if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) )
199  return;
200  }
201  else
202  {
203  if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) )
204  return;
205  }
206  }
207  else
208  {
209  if( pData->Namespace.isEmpty() )
210  {
211  if( mpContainer->AddAttr( aName, pData->Value ) )
212  return;
213  }
214  }
215 }
216 
217 void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name)
218 {
219  sal_uInt16 nAttr = getIndexByName(Name);
220  if( nAttr == USHRT_MAX )
221  throw container::NoSuchElementException();
222 
223  mpContainer->Remove( nAttr );
224 }
225 
226 //XServiceInfo
228 {
229  return "SvUnoAttributeContainer";
230 }
231 
233 {
234  return { "com.sun.star.xml.AttributeContainer" };
235 }
236 
238 {
239  return cppu::supportsService(this, ServiceName);
240 }
241 
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: unoatrcn.cxx:116
std::unique_ptr< ContentProperties > pData
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: unoatrcn.cxx:135
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
Definition: unoatrcn.cxx:95
std::unique_ptr< SvXMLAttrContainerData > mpContainer
Definition: unoatrcn.hxx:46
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId() noexcept
Definition: unoatrcn.cxx:89
virtual void SAL_CALL removeByName(const OUString &Name) override
Definition: unoatrcn.cxx:217
constexpr OUStringLiteral aData
const css::uno::Sequence< sal_Int8 > & getSeq() const
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: unoatrcn.cxx:101
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:180
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: unoatrcn.cxx:237
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:227
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unoatrcn.cxx:141
sal_Int64 getSomethingImpl(const css::uno::Sequence< sal_Int8 > &rId, T *pThis, FallbackToGetSomethingOf< Base >={})
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:232
sal_uInt16 nPos