Avoid potential negative array index access to cached text.
[LibreOffice.git] / chart2 / source / tools / UncachedDataSequence.cxx
blob7211daedba6fcb5f8fa4bd1877552555de97b776
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <UncachedDataSequence.hxx>
21 #include <CommonFunctors.hxx>
22 #include <ModifyListenerHelper.hxx>
23 #include <InternalDataProvider.hxx>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <algorithm>
27 #include <strings.hrc>
28 #include <ResId.hxx>
29 #include <utility>
31 using namespace ::com::sun::star;
33 using ::com::sun::star::uno::Sequence;
34 using ::com::sun::star::uno::Reference;
35 using ::com::sun::star::uno::Any;
36 using ::osl::MutexGuard;
38 // necessary for MS compiler
39 using ::comphelper::OPropertyContainer;
40 using ::chart::impl::UncachedDataSequence_Base;
42 namespace
44 constexpr OUString lcl_aServiceName = u"com.sun.star.comp.chart.UncachedDataSequence"_ustr;
46 enum
48 PROP_NUMBERFORMAT_KEY,
49 PROP_PROPOSED_ROLE,
50 PROP_XML_RANGE
52 } // anonymous namespace
54 namespace chart
57 UncachedDataSequence::UncachedDataSequence(
58 rtl::Reference< InternalDataProvider > xIntDataProv,
59 OUString aRangeRepresentation )
60 : OPropertyContainer( GetBroadcastHelper()),
61 UncachedDataSequence_Base( GetMutex()),
62 m_nNumberFormatKey(0),
63 m_xDataProvider(std::move( xIntDataProv )),
64 m_aSourceRepresentation(std::move( aRangeRepresentation )),
65 m_xModifyEventForwarder( new ModifyEventForwarder() )
67 registerProperties();
70 UncachedDataSequence::UncachedDataSequence(
71 rtl::Reference< InternalDataProvider > xIntDataProv,
72 OUString aRangeRepresentation,
73 const OUString & rRole )
74 : OPropertyContainer( GetBroadcastHelper()),
75 UncachedDataSequence_Base( GetMutex()),
76 m_nNumberFormatKey(0),
77 m_xDataProvider(std::move( xIntDataProv )),
78 m_aSourceRepresentation(std::move( aRangeRepresentation )),
79 m_xModifyEventForwarder( new ModifyEventForwarder() )
81 registerProperties();
82 setFastPropertyValue_NoBroadcast( PROP_PROPOSED_ROLE, uno::Any( rRole ));
85 UncachedDataSequence::UncachedDataSequence( const UncachedDataSequence & rSource )
86 : OPropertyContainer( GetBroadcastHelper()),
87 UncachedDataSequence_Base( GetMutex()),
88 m_nNumberFormatKey( rSource.m_nNumberFormatKey ),
89 m_sRole( rSource.m_sRole ),
90 m_xDataProvider( rSource.m_xDataProvider ),
91 m_aSourceRepresentation( rSource.m_aSourceRepresentation ),
92 m_xModifyEventForwarder( new ModifyEventForwarder() )
94 registerProperties();
97 UncachedDataSequence::~UncachedDataSequence()
100 void UncachedDataSequence::registerProperties()
102 registerProperty( "NumberFormatKey",
103 PROP_NUMBERFORMAT_KEY,
104 0, // PropertyAttributes
105 & m_nNumberFormatKey,
106 cppu::UnoType<decltype(m_nNumberFormatKey)>::get() );
108 registerProperty( "Role",
109 PROP_PROPOSED_ROLE,
110 0, // PropertyAttributes
111 & m_sRole,
112 cppu::UnoType<decltype(m_sRole)>::get() );
114 registerProperty( "CachedXMLRange",
115 PROP_XML_RANGE,
116 0, // PropertyAttributes
117 & m_aXMLRange,
118 cppu::UnoType<decltype(m_aXMLRange)>::get() );
121 IMPLEMENT_FORWARD_XINTERFACE2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer )
122 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer )
124 // ____ XPropertySet ____
125 Reference< beans::XPropertySetInfo > SAL_CALL UncachedDataSequence::getPropertySetInfo()
127 return createPropertySetInfo( getInfoHelper() );
130 // ____ ::comphelper::OPropertySetHelper ____
131 ::cppu::IPropertyArrayHelper& UncachedDataSequence::getInfoHelper()
133 return *getArrayHelper();
136 // ____ ::comphelper::OPropertyArrayHelper ____
137 ::cppu::IPropertyArrayHelper* UncachedDataSequence::createArrayHelper() const
139 Sequence< beans::Property > aProps;
140 // describes all properties which have been registered in the ctor
141 describeProperties( aProps );
143 return new ::cppu::OPropertyArrayHelper( aProps );
146 OUString SAL_CALL UncachedDataSequence::getImplementationName()
148 return lcl_aServiceName;
151 sal_Bool SAL_CALL UncachedDataSequence::supportsService( const OUString& rServiceName )
153 return cppu::supportsService(this, rServiceName);
156 css::uno::Sequence< OUString > SAL_CALL UncachedDataSequence::getSupportedServiceNames()
158 return {
159 lcl_aServiceName,
160 "com.sun.star.chart2.data.DataSequence",
161 "com.sun.star.chart2.data.NumericalDataSequence",
162 "com.sun.star.chart2.data.TextualDataSequence"
166 // ________ XNumericalDataSequence ________
167 Sequence< double > SAL_CALL UncachedDataSequence::getNumericalData()
169 Sequence< double > aResult;
170 MutexGuard aGuard( GetMutex() );
171 if( m_xDataProvider.is())
173 const Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ));
174 aResult.realloc( aValues.getLength());
175 std::transform( aValues.begin(), aValues.end(),
176 aResult.getArray(), CommonFunctors::AnyToDouble());
178 return aResult;
181 // ________ XTextualDataSequence ________
182 Sequence< OUString > SAL_CALL UncachedDataSequence::getTextualData()
184 Sequence< OUString > aResult;
185 MutexGuard aGuard( GetMutex() );
186 if( m_xDataProvider.is())
188 const Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ));
189 aResult.realloc( aValues.getLength());
190 std::transform( aValues.begin(), aValues.end(),
191 aResult.getArray(), CommonFunctors::AnyToString());
193 return aResult;
196 // ________ XDataSequence ________
197 Sequence< Any > SAL_CALL UncachedDataSequence::getData()
199 MutexGuard aGuard( GetMutex() );
200 if( m_xDataProvider.is())
201 return m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation );
202 return Sequence< Any >();
205 OUString SAL_CALL UncachedDataSequence::getSourceRangeRepresentation()
207 return getName();
210 Sequence< OUString > SAL_CALL UncachedDataSequence::generateLabel( chart2::data::LabelOrigin )
212 // auto-generated label
213 sal_Int32 nSeries = m_aSourceRepresentation.toInt32() + 1;
214 OUString aResString(::chart::SchResId(STR_DATA_UNNAMED_SERIES_WITH_INDEX));
215 static constexpr OUString aReplacementStr(u"%NUMBER"_ustr);
216 sal_Int32 nIndex = aResString.indexOf(aReplacementStr);
217 OUString aName;
218 if( nIndex != -1 )
219 aName = aResString.replaceAt(nIndex, aReplacementStr.getLength(), OUString::number(nSeries));
220 return Sequence< OUString >( &aName, 1 );
223 ::sal_Int32 SAL_CALL UncachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 )
225 return m_nNumberFormatKey;
228 // ____ XIndexReplace ____
229 void SAL_CALL UncachedDataSequence::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element )
231 MutexGuard aGuard( GetMutex() );
232 Sequence< Any > aData( getData());
233 if( Index < aData.getLength() &&
234 m_xDataProvider.is() )
236 aData.getArray()[Index] = Element;
237 m_xDataProvider->setDataByRangeRepresentation( m_aSourceRepresentation, aData );
238 fireModifyEvent();
242 // ____ XIndexAccess (base of XIndexReplace) ____
243 ::sal_Int32 SAL_CALL UncachedDataSequence::getCount()
245 OSL_FAIL( "Implement!" );
246 return 0;
249 uno::Any SAL_CALL UncachedDataSequence::getByIndex( ::sal_Int32 )
251 OSL_FAIL( "Implement!" );
252 return uno::Any();
255 // ____ XElementAccess (base of XIndexAccess) ____
256 uno::Type SAL_CALL UncachedDataSequence::getElementType()
258 return cppu::UnoType<uno::Any>::get();
261 sal_Bool SAL_CALL UncachedDataSequence::hasElements()
263 if( ! m_xDataProvider.is())
264 return false;
265 return m_xDataProvider->hasDataByRangeRepresentation( m_aSourceRepresentation );
268 // ____ XNamed ____
269 OUString SAL_CALL UncachedDataSequence::getName()
271 return m_aSourceRepresentation;
274 void SAL_CALL UncachedDataSequence::setName( const OUString& aName )
276 m_aSourceRepresentation = aName;
277 fireModifyEvent();
280 Reference< util::XCloneable > SAL_CALL UncachedDataSequence::createClone()
282 return new UncachedDataSequence( *this );
285 // ____ XModifiable ____
286 sal_Bool SAL_CALL UncachedDataSequence::isModified()
288 return false;
291 void SAL_CALL UncachedDataSequence::setModified( sal_Bool bModified )
293 if( bModified )
294 fireModifyEvent();
297 // ____ XModifyBroadcaster (base of XModifiable) ____
298 void SAL_CALL UncachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
300 m_xModifyEventForwarder->addModifyListener( aListener );
303 void SAL_CALL UncachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
305 m_xModifyEventForwarder->removeModifyListener( aListener );
308 void UncachedDataSequence::fireModifyEvent()
310 // @todo: currently never called, as data changes are not yet reported by
311 // the data provider
312 m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
315 } // namespace chart
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */