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
32using namespace ::com::sun::star;
33
34// Interface implementation
35
36uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
37{
38 return *(new SvUnoAttributeContainer);
39}
40
41SvUnoAttributeContainer::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
59sal_uInt16 SvUnoAttributeContainer::getIndexByName(std::u16string_view aName ) const
60{
61 const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
62
63 size_t nPos = aName.find( ':' );
64 if( nPos == std::u16string_view::npos )
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 std::u16string_view aPrefix( aName.substr( 0L, nPos ) );
76 const std::u16string_view aLName( aName.substr( 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// container::XNameAccess
90uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName)
91{
92 sal_uInt16 nAttr = getIndexByName(aName );
93
94 if( nAttr == USHRT_MAX )
95 throw container::NoSuchElementException();
96
97 xml::AttributeData aData;
98 aData.Namespace = mpContainer->GetAttrNamespace(nAttr);
99 aData.Type = "CDATA";
100 aData.Value = mpContainer->GetAttrValue(nAttr);
101
102 return uno::Any(aData);
103}
104
105uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames()
106{
107 const sal_uInt16 nAttrCount = mpContainer->GetAttrCount();
108
109 uno::Sequence< OUString > aElementNames( static_cast<sal_Int32>(nAttrCount) );
110 OUString *pNames = aElementNames.getArray();
111
112 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ )
113 {
114 OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) );
115 if( !sBuffer.isEmpty() )
116 sBuffer.append( ':' );
117 sBuffer.append( mpContainer->GetAttrLName(nAttr) );
118 *pNames++ = sBuffer.makeStringAndClear();
119 }
120
121 return aElementNames;
122}
123
124sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName)
125{
126 return getIndexByName(aName ) != USHRT_MAX;
127}
128
129// container::XNameReplace
130void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement)
131{
132 if( auto pData = o3tl::tryAccess<xml::AttributeData>(aElement) )
133 {
134 sal_uInt16 nAttr = getIndexByName(aName );
135 if( nAttr == USHRT_MAX )
136 throw container::NoSuchElementException();
137
138 sal_Int32 nPos = aName.indexOf( ':' );
139 if( nPos != -1 )
140 {
141 const OUString aPrefix( aName.copy( 0L, nPos ));
142 const OUString aLName( aName.copy( nPos+1 ));
143
144 if( pData->Namespace.isEmpty() )
145 {
146 if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) )
147 return;
148 }
149 else
150 {
151 if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) )
152 return;
153 }
154 }
155 else
156 {
157 if( pData->Namespace.isEmpty() )
158 {
159 if( mpContainer->SetAt( nAttr, aName, pData->Value ) )
160 return;
161 }
162 }
163 }
164
165 throw lang::IllegalArgumentException();
166}
167
168// container::XNameContainer
169void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement)
170{
171 auto pData = o3tl::tryAccess<xml::AttributeData>(aElement);
172 if( !pData )
173 throw lang::IllegalArgumentException();
174
175 sal_uInt16 nAttr = getIndexByName(aName );
176 if( nAttr != USHRT_MAX )
177 throw container::ElementExistException();
178
179 sal_Int32 nPos = aName.indexOf( ':' );
180 if( nPos != -1 )
181 {
182 const OUString aPrefix( aName.copy( 0L, nPos ));
183 const OUString aLName( aName.copy( nPos+1 ));
184
185 if( pData->Namespace.isEmpty() )
186 {
187 if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) )
188 return;
189 }
190 else
191 {
192 if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) )
193 return;
194 }
195 }
196 else
197 {
198 if( pData->Namespace.isEmpty() )
199 {
200 if( mpContainer->AddAttr( aName, pData->Value ) )
201 return;
202 }
203 }
204}
205
206void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name)
207{
208 sal_uInt16 nAttr = getIndexByName(Name);
209 if( nAttr == USHRT_MAX )
210 throw container::NoSuchElementException();
211
212 mpContainer->Remove( nAttr );
213}
214
215//XServiceInfo
217{
218 return "SvUnoAttributeContainer";
219}
220
222{
223 return { "com.sun.star.xml.AttributeContainer" };
224}
225
227{
229}
230
231/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: unoatrcn.cxx:105
SAL_DLLPRIVATE sal_uInt16 getIndexByName(std::u16string_view aName) const
Definition: unoatrcn.cxx:59
SvUnoAttributeContainer(std::unique_ptr< SvXMLAttrContainerData > pContainer=nullptr)
Definition: unoatrcn.cxx:41
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: unoatrcn.cxx:124
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unoatrcn.cxx:221
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: unoatrcn.cxx:226
virtual OUString SAL_CALL getImplementationName() override
Definition: unoatrcn.cxx:216
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unoatrcn.cxx:49
virtual void SAL_CALL removeByName(const OUString &Name) override
Definition: unoatrcn.cxx:206
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unoatrcn.cxx:130
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: unoatrcn.cxx:90
std::unique_ptr< SvXMLAttrContainerData > mpContainer
Definition: unoatrcn.hxx:44
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unoatrcn.cxx:169
virtual sal_Bool SAL_CALL hasElements() override
Definition: unoatrcn.cxx:54
css::uno::Type const & get()
OUString aName
sal_uInt16 nPos
std::unique_ptr< sal_Int32[]> pData
constexpr OUStringLiteral aData
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
OUString Name
unsigned char sal_Bool
uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
Definition: unoatrcn.cxx:36