Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx
Warning:line 706, column 13
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name autofilterbuffer.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D BOOST_ALL_NO_LIB -D BOOST_ALL_NO_LIB -D BOOST_ALL_NO_LIB -D SYSTEM_ZLIB -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/oox/generated -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx

/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx

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 <autofilterbuffer.hxx>
21
22#include <com/sun/star/beans/XPropertySet.hpp>
23#include <com/sun/star/sheet/FilterConnection.hpp>
24#include <com/sun/star/sheet/FilterOperator2.hpp>
25#include <com/sun/star/sheet/TableFilterField3.hpp>
26#include <com/sun/star/sheet/XDatabaseRange.hpp>
27#include <com/sun/star/sheet/XSheetFilterDescriptor3.hpp>
28#include <com/sun/star/table/TableOrientation.hpp>
29#include <com/sun/star/table/CellAddress.hpp>
30#include <rtl/ustrbuf.hxx>
31#include <osl/diagnose.h>
32#include <oox/helper/attributelist.hxx>
33#include <oox/helper/containerhelper.hxx>
34#include <oox/helper/propertyset.hxx>
35#include <oox/helper/binaryinputstream.hxx>
36#include <oox/token/namespaces.hxx>
37#include <oox/token/properties.hxx>
38#include <oox/token/tokens.hxx>
39#include <addressconverter.hxx>
40#include <defnamesbuffer.hxx>
41#include <biffhelper.hxx>
42#include <document.hxx>
43#include <dbdata.hxx>
44#include <sortparam.hxx>
45#include <userlist.hxx>
46
47namespace oox::xls {
48
49using namespace ::com::sun::star::sheet;
50using namespace ::com::sun::star::table;
51using namespace ::com::sun::star::uno;
52
53namespace {
54
55const sal_uInt8 BIFF12_TOP10FILTER_TOP = 0x01;
56const sal_uInt8 BIFF12_TOP10FILTER_PERCENT = 0x02;
57
58const sal_uInt16 BIFF12_FILTERCOLUMN_HIDDENBUTTON = 0x0001;
59const sal_uInt16 BIFF12_FILTERCOLUMN_SHOWBUTTON = 0x0002;
60
61const sal_uInt8 BIFF_FILTER_DATATYPE_NONE = 0;
62const sal_uInt8 BIFF_FILTER_DATATYPE_DOUBLE = 4;
63const sal_uInt8 BIFF_FILTER_DATATYPE_STRING = 6;
64const sal_uInt8 BIFF_FILTER_DATATYPE_BOOLEAN = 8;
65const sal_uInt8 BIFF_FILTER_DATATYPE_EMPTY = 12;
66const sal_uInt8 BIFF_FILTER_DATATYPE_NOTEMPTY = 14;
67
68bool lclGetApiOperatorFromToken( sal_Int32& rnApiOperator, sal_Int32 nToken )
69{
70 switch( nToken )
71 {
72 case XML_lessThan: rnApiOperator = FilterOperator2::NOT_EQUAL; return true;
73 case XML_equal: rnApiOperator = FilterOperator2::EQUAL; return true;
74 case XML_lessThanOrEqual: rnApiOperator = FilterOperator2::LESS_EQUAL; return true;
75 case XML_greaterThan: rnApiOperator = FilterOperator2::GREATER; return true;
76 case XML_notEqual: rnApiOperator = FilterOperator2::NOT_EQUAL; return true;
77 case XML_greaterThanOrEqual: rnApiOperator = FilterOperator2::GREATER_EQUAL; return true;
78 }
79 return false;
80}
81
82/** Removes leading asterisk characters from the passed string.
83 @return True = at least one asterisk character has been removed. */
84bool lclTrimLeadingAsterisks( OUString& rValue )
85{
86 sal_Int32 nLength = rValue.getLength();
87 sal_Int32 nPos = 0;
88 while( (nPos < nLength) && (rValue[ nPos ] == '*') )
89 ++nPos;
90 if( nPos > 0 )
91 {
92 rValue = rValue.copy( nPos );
93 return true;
94 }
95 return false;
96}
97
98/** Removes trailing asterisk characters from the passed string.
99 @return True = at least one asterisk character has been removed. */
100bool lclTrimTrailingAsterisks( OUString& rValue )
101{
102 sal_Int32 nLength = rValue.getLength();
103 sal_Int32 nPos = nLength;
104 while( (nPos > 0) && (rValue[ nPos - 1 ] == '*') )
105 --nPos;
106 if( nPos < nLength )
107 {
108 rValue = rValue.copy( 0, nPos );
109 return true;
110 }
111 return false;
112}
113
114/** Converts wildcard characters '*' and '?' to regular expressions and quotes
115 RE meta characters.
116 @return True = passed string has been changed (RE needs to be enabled). */
117bool lclConvertWildcardsToRegExp( OUString& rValue )
118{
119 // check existence of the wildcard characters '*' and '?'
120 if( !rValue.isEmpty() && ((rValue.indexOf( '*' ) >= 0) || (rValue.indexOf( '?' ) >= 0)) )
121 {
122 OUStringBuffer aBuffer;
123 aBuffer.ensureCapacity( rValue.getLength() + 5 );
124 const sal_Unicode* pcChar = rValue.getStr();
125 const sal_Unicode* pcEnd = pcChar + rValue.getLength();
126 for( ; pcChar < pcEnd; ++pcChar )
127 {
128 switch( *pcChar )
129 {
130 case '?':
131 aBuffer.append( '.' );
132 break;
133 case '*':
134 aBuffer.append( '.' ).append( '*' );
135 break;
136 case '\\': case '.': case '|': case '(': case ')': case '^': case '$':
137 // quote RE meta characters
138 aBuffer.append( '\\' ).append( *pcChar );
139 break;
140 default:
141 aBuffer.append( *pcChar );
142 }
143 }
144 rValue = aBuffer.makeStringAndClear();
145 return true;
146 }
147 return false;
148}
149
150} // namespace
151
152ApiFilterSettings::ApiFilterSettings()
153{
154}
155
156void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, double fValue )
157{
158 maFilterFields.emplace_back();
159 TableFilterField3& rFilterField = maFilterFields.back();
160 rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
161 rFilterField.Operator = nOperator;
162 rFilterField.Values.realloc(1);
163 rFilterField.Values[0].IsNumeric = true;
164 rFilterField.Values[0].NumericValue = fValue;
165}
166
167void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, const OUString& rValue )
168{
169 maFilterFields.emplace_back();
170 TableFilterField3& rFilterField = maFilterFields.back();
171 rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
172 rFilterField.Operator = nOperator;
173 rFilterField.Values.realloc(1);
174 rFilterField.Values[0].IsNumeric = false;
175 rFilterField.Values[0].StringValue = rValue;
176}
177
178void ApiFilterSettings::appendField( bool bAnd, const std::vector<OUString>& rValues )
179{
180 maFilterFields.emplace_back();
181 TableFilterField3& rFilterField = maFilterFields.back();
182 rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
183 rFilterField.Operator = FilterOperator2::EQUAL;
184 size_t n = rValues.size();
185 rFilterField.Values.realloc(n);
186 for (size_t i = 0; i < n; ++i)
187 {
188 rFilterField.Values[i].IsNumeric = false;
189 rFilterField.Values[i].StringValue = rValues[i];
190 }
191}
192
193FilterSettingsBase::FilterSettingsBase( const WorkbookHelper& rHelper ) :
194 WorkbookHelper( rHelper )
195{
196}
197
198void FilterSettingsBase::importAttribs( sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ )
199{
200}
201
202void FilterSettingsBase::importRecord( sal_Int32 /*nRecId*/, SequenceInputStream& /*rStrm*/ )
203{
204}
205
206ApiFilterSettings FilterSettingsBase::finalizeImport( sal_Int32 /*nMaxCount*/ )
207{
208 return ApiFilterSettings();
209}
210
211DiscreteFilter::DiscreteFilter( const WorkbookHelper& rHelper ) :
212 FilterSettingsBase( rHelper ),
213 mnCalendarType( XML_none ),
214 mbShowBlank( false )
215{
216}
217
218void DiscreteFilter::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
219{
220 switch( nElement )
221 {
222 case XLS_TOKEN( filters )(::oox::NMSP_xls | ::oox::XML_filters):
223 mnCalendarType = rAttribs.getToken( XML_calendarType, XML_none );
224 mbShowBlank = rAttribs.getBool( XML_blank, false );
225 break;
226
227 case XLS_TOKEN( filter )(::oox::NMSP_xls | ::oox::XML_filter):
228 {
229 OUString aValue = rAttribs.getXString( XML_val, OUString() );
230 if( !aValue.isEmpty() )
231 maValues.push_back( aValue );
232 }
233 break;
234 }
235}
236
237void DiscreteFilter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
238{
239 switch( nRecId )
240 {
241 case BIFF12_ID_DISCRETEFILTERS:
242 {
243 sal_Int32 nShowBlank, nCalendarType;
244 nShowBlank = rStrm.readInt32();
245 nCalendarType = rStrm.readInt32();
246
247 static const sal_Int32 spnCalendarTypes[] = {
248 XML_none, XML_gregorian, XML_gregorianUs, XML_japan, XML_taiwan, XML_korea, XML_hijri, XML_thai, XML_hebrew,
249 XML_gregorianMeFrench, XML_gregorianArabic, XML_gregorianXlitEnglish, XML_gregorianXlitFrench };
250 mnCalendarType = STATIC_ARRAY_SELECT( spnCalendarTypes, nCalendarType, XML_none )((detail::make_unsigned(nCalendarType) < (sizeof(sal_n_array_size
(spnCalendarTypes)))) ? ((spnCalendarTypes)[static_cast<size_t
>(nCalendarType)]) : (XML_none))
;
251 mbShowBlank = nShowBlank != 0;
252 }
253 break;
254
255 case BIFF12_ID_DISCRETEFILTER:
256 {
257 OUString aValue = BiffHelper::readString( rStrm );
258 if( !aValue.isEmpty() )
259 maValues.push_back( aValue );
260 }
261 break;
262 }
263}
264
265ApiFilterSettings DiscreteFilter::finalizeImport( sal_Int32 nMaxCount )
266{
267 ApiFilterSettings aSettings;
268 if( static_cast< sal_Int32 >( maValues.size() ) <= nMaxCount )
269 {
270 aSettings.maFilterFields.reserve( maValues.size() );
271
272 // insert all filter values
273 aSettings.appendField( true, maValues );
274
275 // extra field for 'show empty'
276 if( mbShowBlank )
277 aSettings.appendField( false, FilterOperator2::EMPTY, OUString() );
278
279 /* Require disabled regular expressions, filter entries may contain
280 any RE meta characters. */
281 if( !maValues.empty() )
282 aSettings.mobNeedsRegExp = false;
283 }
284 return aSettings;
285}
286
287Top10Filter::Top10Filter( const WorkbookHelper& rHelper ) :
288 FilterSettingsBase( rHelper ),
289 mfValue( 0.0 ),
290 mbTop( true ),
291 mbPercent( false )
292{
293}
294
295void Top10Filter::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
296{
297 if( nElement == XLS_TOKEN( top10 )(::oox::NMSP_xls | ::oox::XML_top10) )
298 {
299 mfValue = rAttribs.getDouble( XML_val, 0.0 );
300 mbTop = rAttribs.getBool( XML_top, true );
301 mbPercent = rAttribs.getBool( XML_percent, false );
302 }
303}
304
305void Top10Filter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
306{
307 if( nRecId == BIFF12_ID_TOP10FILTER )
308 {
309 sal_uInt8 nFlags;
310 nFlags = rStrm.readuChar();
311 mfValue = rStrm.readDouble();
312 mbTop = getFlag( nFlags, BIFF12_TOP10FILTER_TOP );
313 mbPercent = getFlag( nFlags, BIFF12_TOP10FILTER_PERCENT );
314 }
315}
316
317ApiFilterSettings Top10Filter::finalizeImport( sal_Int32 /*nMaxCount*/ )
318{
319 sal_Int32 nOperator = mbTop ?
320 (mbPercent ? FilterOperator2::TOP_PERCENT : FilterOperator2::TOP_VALUES) :
321 (mbPercent ? FilterOperator2::BOTTOM_PERCENT : FilterOperator2::BOTTOM_VALUES);
322 ApiFilterSettings aSettings;
323 aSettings.appendField( true, nOperator, mfValue );
324 return aSettings;
325}
326
327FilterCriterionModel::FilterCriterionModel() :
328 mnOperator( XML_equal ),
329 mnDataType( BIFF_FILTER_DATATYPE_NONE )
330{
331}
332
333void FilterCriterionModel::setBiffOperator( sal_uInt8 nOperator )
334{
335 static const sal_Int32 spnOperators[] = { XML_TOKEN_INVALID,
336 XML_lessThan, XML_equal, XML_lessThanOrEqual, XML_greaterThan, XML_notEqual, XML_greaterThanOrEqual };
337 mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID )((detail::make_unsigned(nOperator) < (sizeof(sal_n_array_size
(spnOperators)))) ? ((spnOperators)[static_cast<size_t>
(nOperator)]) : (XML_TOKEN_INVALID))
;
338}
339
340void FilterCriterionModel::readBiffData( SequenceInputStream& rStrm )
341{
342 sal_uInt8 nOperator;
343 mnDataType = rStrm.readuChar();
344 nOperator = rStrm.readuChar();
345 setBiffOperator( nOperator );
346
347 switch( mnDataType )
348 {
349 case BIFF_FILTER_DATATYPE_DOUBLE:
350 maValue <<= rStrm.readDouble();
351 break;
352 case BIFF_FILTER_DATATYPE_STRING:
353 {
354 rStrm.skip( 8 );
355 OUString aValue = BiffHelper::readString( rStrm ).trim();
356 if( !aValue.isEmpty() )
357 maValue <<= aValue;
358 }
359 break;
360 case BIFF_FILTER_DATATYPE_BOOLEAN:
361 maValue <<= (rStrm.readuInt8() != 0);
362 rStrm.skip( 7 );
363 break;
364 case BIFF_FILTER_DATATYPE_EMPTY:
365 rStrm.skip( 8 );
366 if( mnOperator == XML_equal )
367 maValue <<= OUString();
368 break;
369 case BIFF_FILTER_DATATYPE_NOTEMPTY:
370 rStrm.skip( 8 );
371 if( mnOperator == XML_notEqual )
372 maValue <<= OUString();
373 break;
374 default:
375 OSL_ENSURE( false, "FilterCriterionModel::readBiffData - unexpected data type" )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx"
":" "375" ": "), "%s", "FilterCriterionModel::readBiffData - unexpected data type"
); } } while (false)
;
376 rStrm.skip( 8 );
377 }
378}
379
380CustomFilter::CustomFilter( const WorkbookHelper& rHelper ) :
381 FilterSettingsBase( rHelper ),
382 mbAnd( false )
383{
384}
385
386void CustomFilter::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
387{
388 switch( nElement )
389 {
390 case XLS_TOKEN( customFilters )(::oox::NMSP_xls | ::oox::XML_customFilters):
391 mbAnd = rAttribs.getBool( XML_and, false );
392 break;
393
394 case XLS_TOKEN( customFilter )(::oox::NMSP_xls | ::oox::XML_customFilter):
395 {
396 FilterCriterionModel aCriterion;
397 aCriterion.mnOperator = rAttribs.getToken( XML_operator, XML_equal );
398 OUString aValue = rAttribs.getXString( XML_val, OUString() ).trim();
399 if( (aCriterion.mnOperator == XML_equal) || (aCriterion.mnOperator == XML_notEqual) || (!aValue.isEmpty()) )
400 aCriterion.maValue <<= aValue;
401 appendCriterion( aCriterion );
402 }
403 break;
404 }
405}
406
407void CustomFilter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm )
408{
409 switch( nRecId )
410 {
411 case BIFF12_ID_CUSTOMFILTERS:
412 mbAnd = rStrm.readInt32() == 0;
413 break;
414
415 case BIFF12_ID_CUSTOMFILTER:
416 {
417 FilterCriterionModel aCriterion;
418 aCriterion.readBiffData( rStrm );
419 appendCriterion( aCriterion );
420 }
421 break;
422 }
423}
424
425ApiFilterSettings CustomFilter::finalizeImport( sal_Int32 /*nMaxCount*/ )
426{
427 ApiFilterSettings aSettings;
428 OSL_ENSURE( maCriteria.size() <= 2, "CustomFilter::finalizeImport - too many filter criteria" )do { if (true && (!(maCriteria.size() <= 2))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx"
":" "428" ": "), "%s", "CustomFilter::finalizeImport - too many filter criteria"
); } } while (false)
;
429 for( const auto& rCriterion : maCriteria )
430 {
431 // first extract the filter operator
432 sal_Int32 nOperator = 0;
433 bool bValidOperator = lclGetApiOperatorFromToken( nOperator, rCriterion.mnOperator );
434 if( bValidOperator )
435 {
436 if( rCriterion.maValue.has< OUString >() )
437 {
438 // string argument
439 OUString aValue;
440 rCriterion.maValue >>= aValue;
441 // check for 'empty', 'contains', 'begins with', or 'ends with' text filters
442 bool bEqual = nOperator == FilterOperator2::EQUAL;
443 bool bNotEqual = nOperator == FilterOperator2::NOT_EQUAL;
444 if( bEqual || bNotEqual )
445 {
446 if( aValue.isEmpty() )
447 {
448 // empty comparison string: create empty/not empty filters
449 nOperator = bNotEqual ? FilterOperator2::NOT_EMPTY : FilterOperator2::EMPTY;
450 }
451 else
452 {
453 // compare to something: try to find begins/ends/contains
454 bool bHasLeadingAsterisk = lclTrimLeadingAsterisks( aValue );
455 bool bHasTrailingAsterisk = lclTrimTrailingAsterisks( aValue );
456 // just '***' matches everything, do not create a filter field
457 bValidOperator = !aValue.isEmpty();
458 if( bValidOperator )
459 {
460 if( bHasLeadingAsterisk && bHasTrailingAsterisk )
461 nOperator = bNotEqual ? FilterOperator2::DOES_NOT_CONTAIN : FilterOperator2::CONTAINS;
462 else if( bHasLeadingAsterisk )
463 nOperator = bNotEqual ? FilterOperator2::DOES_NOT_END_WITH : FilterOperator2::ENDS_WITH;
464 else if( bHasTrailingAsterisk )
465 nOperator = bNotEqual ? FilterOperator2::DOES_NOT_BEGIN_WITH : FilterOperator2::BEGINS_WITH;
466 // else: no asterisks, stick to equal/not equal
467 }
468 }
469 }
470
471 if( bValidOperator )
472 {
473 // if wildcards are present, require RE mode, otherwise keep don't care state
474 if( lclConvertWildcardsToRegExp( aValue ) )
475 aSettings.mobNeedsRegExp = true;
476 // create a new UNO API filter field
477 aSettings.appendField( mbAnd, nOperator, aValue );
478 }
479 }
480 else if( rCriterion.maValue.has< double >() )
481 {
482 // floating-point argument
483 double fValue = 0.0;
484 rCriterion.maValue >>= fValue;
485 aSettings.appendField( mbAnd, nOperator, fValue );
486 }
487 }
488 }
489 return aSettings;
490}
491
492void CustomFilter::appendCriterion( const FilterCriterionModel& rCriterion )
493{
494 if( (rCriterion.mnOperator != XML_TOKEN_INVALID) && rCriterion.maValue.hasValue() )
495 maCriteria.push_back( rCriterion );
496}
497
498FilterColumn::FilterColumn( const WorkbookHelper& rHelper ) :
499 WorkbookHelper( rHelper ),
500 mnColId( -1 ),
501 mbHiddenButton( false ),
502 mbShowButton( true )
503{
504}
505
506void FilterColumn::importFilterColumn( const AttributeList& rAttribs )
507{
508 mnColId = rAttribs.getInteger( XML_colId, -1 );
509 mbHiddenButton = rAttribs.getBool( XML_hiddenButton, false );
510 mbShowButton = rAttribs.getBool( XML_showButton, true );
511}
512
513void FilterColumn::importFilterColumn( SequenceInputStream& rStrm )
514{
515 sal_uInt16 nFlags;
516 mnColId = rStrm.readInt32();
517 nFlags = rStrm.readuInt16();
518 mbHiddenButton = getFlag( nFlags, BIFF12_FILTERCOLUMN_HIDDENBUTTON );
519 mbShowButton = getFlag( nFlags, BIFF12_FILTERCOLUMN_SHOWBUTTON );
520}
521
522ApiFilterSettings FilterColumn::finalizeImport( sal_Int32 nMaxCount )
523{
524 ApiFilterSettings aSettings;
525 if( (0 <= mnColId) && mxSettings )
526 {
527 // filter settings object creates a sequence of filter fields
528 aSettings = mxSettings->finalizeImport( nMaxCount );
529 // add column index to all filter fields
530 for( auto& rFilterField : aSettings.maFilterFields )
531 rFilterField.Field = mnColId;
532 }
533 return aSettings;
534}
535
536// SortCondition
537
538SortCondition::SortCondition( const WorkbookHelper& rHelper ) :
539 WorkbookHelper( rHelper ),
540 mbDescending( false )
541{
542}
543
544void SortCondition::importSortCondition( const AttributeList& rAttribs, sal_Int16 nSheet )
545{
546 OUString aRangeStr = rAttribs.getString( XML_ref, OUString() );
547 AddressConverter::convertToCellRangeUnchecked( maRange, aRangeStr, nSheet );
548
549 maSortCustomList = rAttribs.getString( XML_customList, OUString() );
550 mbDescending = rAttribs.getBool( XML_descending, false );
551}
552
553// AutoFilter
554
555AutoFilter::AutoFilter( const WorkbookHelper& rHelper ) :
556 WorkbookHelper( rHelper )
557{
558}
559
560void AutoFilter::importAutoFilter( const AttributeList& rAttribs, sal_Int16 nSheet )
561{
562 OUString aRangeStr = rAttribs.getString( XML_ref, OUString() );
563 AddressConverter::convertToCellRangeUnchecked( maRange, aRangeStr, nSheet );
564}
565
566void AutoFilter::importAutoFilter( SequenceInputStream& rStrm, sal_Int16 nSheet )
567{
568 BinRange aBinRange;
569 rStrm >> aBinRange;
570 AddressConverter::convertToCellRangeUnchecked( maRange, aBinRange, nSheet );
571}
572
573void AutoFilter::importSortState( const AttributeList& rAttribs, sal_Int16 nSheet )
574{
575 OUString aRangeStr = rAttribs.getString( XML_ref, OUString() );
576 AddressConverter::convertToCellRangeUnchecked( maSortRange, aRangeStr, nSheet );
577}
578
579FilterColumn& AutoFilter::createFilterColumn()
580{
581 FilterColumnVector::value_type xFilterColumn = std::make_shared<FilterColumn>( *this );
582 maFilterColumns.push_back( xFilterColumn );
583 return *xFilterColumn;
584}
585
586SortCondition& AutoFilter::createSortCondition()
587{
588 SortConditionVector::value_type xSortCondition = std::make_shared<SortCondition>( *this );
589 maSortConditions.push_back( xSortCondition );
590 return *xSortCondition;
591}
592
593void AutoFilter::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange, sal_Int16 nSheet )
594{
595 // convert filter settings using the filter descriptor of the database range
596 const Reference<XSheetFilterDescriptor3> xFilterDesc( rxDatabaseRange->getFilterDescriptor(), UNO_QUERY_THROW );
597 if( !xFilterDesc.is() )
10
Calling 'BaseReference::is'
12
Returning from 'BaseReference::is'
13
Taking false branch
598 return;
599
600 // set some common properties for the auto filter range
601 PropertySet aDescProps( xFilterDesc );
602 aDescProps.setProperty( PROP_IsCaseSensitive, false );
603 aDescProps.setProperty( PROP_SkipDuplicates, false );
604 aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS );
605 aDescProps.setProperty( PROP_ContainsHeader, true );
606 aDescProps.setProperty( PROP_CopyOutputData, false );
607
608 // maximum number of UNO API filter fields
609 sal_Int32 nMaxCount = 0;
610 aDescProps.getProperty( nMaxCount, PROP_MaxFieldCount );
611 OSL_ENSURE( nMaxCount > 0, "AutoFilter::finalizeImport - invalid maximum filter field count" )do { if (true && (!(nMaxCount > 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx"
":" "611" ": "), "%s", "AutoFilter::finalizeImport - invalid maximum filter field count"
); } } while (false)
;
14
Taking true branch
15
Loop condition is false. Exiting loop
612
613 // resulting list of all UNO API filter fields
614 ::std::vector<TableFilterField3> aFilterFields;
615
616 // track if columns require to enable or disable regular expressions
617 OptValue< bool > obNeedsRegExp;
618
619 /* Track whether the filter fields of the first filter column are
620 connected with 'or'. In this case, other filter fields cannot be
621 inserted without altering the result of the entire filter, due to
622 Calc's precedence for the 'and' connection operator. Example:
623 Excel's filter conditions 'A1 and (B1 or B2) and C1' where B1 and
624 B2 belong to filter column B, will be evaluated by Calc as
625 '(A1 and B1) or (B2 and C1)'. */
626 bool bHasOrConnection = false;
627
628 // process all filter column objects, exit when 'or' connection exists
629 for( const auto& rxFilterColumn : maFilterColumns )
630 {
631 // the filter settings object creates a list of filter fields
632 ApiFilterSettings aSettings = rxFilterColumn->finalizeImport( nMaxCount );
633 ApiFilterSettings::FilterFieldVector& rColumnFields = aSettings.maFilterFields;
634
635 // new total number of filter fields
636 sal_Int32 nNewCount = static_cast< sal_Int32 >( aFilterFields.size() + rColumnFields.size() );
637
638 /* Check whether mode for regular expressions is compatible with
639 the global mode in obNeedsRegExp. If either one is still in
640 don't-care state, all is fine. If both are set, they must be
641 equal. */
642 bool bRegExpCompatible = !obNeedsRegExp || !aSettings.mobNeedsRegExp || (obNeedsRegExp.get() == aSettings.mobNeedsRegExp.get());
643
644 // check whether fields are connected by 'or' (see comments above).
645 if( rColumnFields.size() >= 2 )
646 bHasOrConnection = std::any_of(rColumnFields.begin() + 1, rColumnFields.end(),
647 [](const css::sheet::TableFilterField3& rColumnField) { return rColumnField.Connection == FilterConnection_OR; });
648
649 /* Skip the column filter, if no filter fields have been created,
650 if the number of new filter fields would exceed the total limit
651 of filter fields, or if the mode for regular expressions of the
652 filter column does not fit. */
653 if( !rColumnFields.empty() && (nNewCount <= nMaxCount) && bRegExpCompatible )
654 {
655 /* Add 'and' connection to the first filter field to connect
656 it to the existing filter fields of other columns. */
657 rColumnFields[ 0 ].Connection = FilterConnection_AND;
658
659 // insert the new filter fields
660 aFilterFields.insert( aFilterFields.end(), rColumnFields.begin(), rColumnFields.end() );
661
662 // update the regular expressions mode
663 obNeedsRegExp.assignIfUsed( aSettings.mobNeedsRegExp );
664 }
665
666 if( bHasOrConnection )
667 break;
668 }
669
670 // insert all filter fields to the filter descriptor
671 if( !aFilterFields.empty() )
16
Assuming the condition is false
17
Taking false branch
672 xFilterDesc->setFilterFields3( ContainerHelper::vectorToSequence( aFilterFields ) );
673
674 // regular expressions
675 bool bUseRegExp = obNeedsRegExp.get( false );
676 aDescProps.setProperty( PROP_UseRegularExpressions, bUseRegExp );
677
678 // sort
679 if (!maSortConditions.empty())
18
Assuming the condition is true
19
Taking true branch
680 {
681 const SortConditionVector::value_type& xSortConditionPointer = *maSortConditions.begin();
682 const SortCondition& rSorConditionLoaded = *xSortConditionPointer;
683
684 ScSortParam aParam;
685 aParam.bUserDef = false;
686 aParam.nUserIndex = 0;
687 aParam.bByRow = false;
688
689 ScUserList* pUserList = ScGlobal::GetUserList();
20
'pUserList' initialized here
690 if (!rSorConditionLoaded.maSortCustomList.isEmpty())
21
Taking true branch
691 {
692 for (size_t i=0; pUserList && i < pUserList->size(); i++)
22
Assuming 'pUserList' is null
693 {
694 const OUString aEntry((*pUserList)[i].GetString());
695 if (aEntry.equalsIgnoreAsciiCase(rSorConditionLoaded.maSortCustomList))
696 {
697 aParam.bUserDef = true;
698 aParam.nUserIndex = i;
699 break;
700 }
701 }
702 }
703
704 if (!aParam.bUserDef
22.1
Field 'bUserDef' is false
22.1
Field 'bUserDef' is false
)
23
Taking true branch
705 {
706 pUserList->push_back(new ScUserListData(rSorConditionLoaded.maSortCustomList));
24
Called C++ object pointer is null
707 aParam.bUserDef = true;
708 aParam.nUserIndex = pUserList->size()-1;
709 }
710
711 // set sort parameter if we have detected it
712 if (aParam.bUserDef)
713 {
714 SCCOLROW nStartPos = aParam.bByRow ? maRange.aStart.Col() : maRange.aStart.Row();
715 if (rSorConditionLoaded.mbDescending)
716 {
717 // descending sort - need to enable 1st SortParam slot
718 assert(aParam.GetSortKeyCount() == DEFSORT)(static_cast <bool> (aParam.GetSortKeyCount() == 3) ? void
(0) : __assert_fail ("aParam.GetSortKeyCount() == DEFSORT", "/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx"
, 718, __extension__ __PRETTY_FUNCTION__))
;
719
720 aParam.maKeyState[0].bDoSort = true;
721 aParam.maKeyState[0].bAscending = false;
722 aParam.maKeyState[0].nField += nStartPos;
723 }
724
725 ScDocument& rDoc = getScDocument();
726 ScDBData* pDBData = rDoc.GetDBAtArea(
727 nSheet,
728 maRange.aStart.Col(), maRange.aStart.Row(),
729 maRange.aEnd.Col(), maRange.aEnd.Row());
730
731 if (pDBData)
732 pDBData->SetSortParam(aParam);
733 else
734 OSL_FAIL("AutoFilter::finalizeImport(): cannot find matching DBData")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx"
":" "734" ": "), "%s", "AutoFilter::finalizeImport(): cannot find matching DBData"
); } } while (false)
;
735 }
736 }
737}
738
739AutoFilterBuffer::AutoFilterBuffer( const WorkbookHelper& rHelper ) :
740 WorkbookHelper( rHelper )
741{
742}
743
744AutoFilter& AutoFilterBuffer::createAutoFilter()
745{
746 AutoFilterVector::value_type xAutoFilter = std::make_shared<AutoFilter>( *this );
747 maAutoFilters.push_back( xAutoFilter );
748 return *xAutoFilter;
749}
750
751void AutoFilterBuffer::finalizeImport( sal_Int16 nSheet )
752{
753 // rely on existence of the defined name '_FilterDatabase' containing the range address of the filtered area
754 const DefinedName* pFilterDBName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_FILTERDATABASE, nSheet ).get();
755 if(!pFilterDBName)
1
Assuming 'pFilterDBName' is non-null
2
Taking false branch
756 return;
757
758 ScRange aFilterRange;
759 if( !(pFilterDBName->getAbsoluteRange( aFilterRange ) && (aFilterRange.aStart.Tab() == nSheet)) )
3
Assuming the condition is true
4
Assuming the condition is true
5
Taking false branch
760 return;
761
762 // use the same name for the database range as used for the defined name '_FilterDatabase'
763 Reference< XDatabaseRange > xDatabaseRange = createUnnamedDatabaseRangeObject( aFilterRange );
764 // first, try to create an auto filter
765 bool bHasAutoFilter = finalizeImport( xDatabaseRange, nSheet );
6
Calling 'AutoFilterBuffer::finalizeImport'
766 // no success: try to create an advanced filter
767 if( bHasAutoFilter || !xDatabaseRange.is() )
768 return;
769
770 // the built-in defined name 'Criteria' must exist
771 const DefinedName* pCriteriaName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_CRITERIA, nSheet ).get();
772 if( !pCriteriaName )
773 return;
774
775 ScRange aCriteriaRange;
776 if( !pCriteriaName->getAbsoluteRange( aCriteriaRange ) )
777 return;
778
779 // set some common properties for the filter descriptor
780 PropertySet aDescProps( xDatabaseRange->getFilterDescriptor() );
781 aDescProps.setProperty( PROP_IsCaseSensitive, false );
782 aDescProps.setProperty( PROP_SkipDuplicates, false );
783 aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS );
784 aDescProps.setProperty( PROP_ContainsHeader, true );
785 // criteria range may contain wildcards, but these are incompatible with REs
786 aDescProps.setProperty( PROP_UseRegularExpressions, false );
787
788 // position of output data (if built-in defined name 'Extract' exists)
789 DefinedNameRef xExtractName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_EXTRACT, nSheet );
790 ScRange aOutputRange;
791 bool bHasOutputRange = xExtractName && xExtractName->getAbsoluteRange( aOutputRange );
792 aDescProps.setProperty( PROP_CopyOutputData, bHasOutputRange );
793 if( bHasOutputRange )
794 {
795 aDescProps.setProperty( PROP_SaveOutputPosition, true );
796 aDescProps.setProperty( PROP_OutputPosition, CellAddress( aOutputRange.aStart.Tab(), aOutputRange.aStart.Col(), aOutputRange.aStart.Row() ) );
797 }
798
799 /* Properties of the database range (must be set after
800 modifying properties of the filter descriptor,
801 otherwise the 'FilterCriteriaSource' property gets
802 deleted). */
803 PropertySet aRangeProps( xDatabaseRange );
804 aRangeProps.setProperty( PROP_AutoFilter, false );
805 aRangeProps.setProperty( PROP_FilterCriteriaSource,
806 CellRangeAddress( aCriteriaRange.aStart.Tab(),
807 aCriteriaRange.aStart.Col(), aCriteriaRange.aStart.Row(),
808 aCriteriaRange.aEnd.Col(), aCriteriaRange.aEnd.Row() ));
809}
810
811bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange, sal_Int16 nSheet )
812{
813 AutoFilter* pAutoFilter = getActiveAutoFilter();
814 if( pAutoFilter && rxDatabaseRange.is() ) try
7
Assuming 'pAutoFilter' is non-null
8
Taking true branch
815 {
816 // the property 'AutoFilter' enables the drop-down buttons
817 PropertySet aRangeProps( rxDatabaseRange );
818 aRangeProps.setProperty( PROP_AutoFilter, true );
819
820 pAutoFilter->finalizeImport( rxDatabaseRange, nSheet );
9
Calling 'AutoFilter::finalizeImport'
821
822 // return true to indicate enabled autofilter
823 return true;
824 }
825 catch( Exception& )
826 {
827 }
828 return false;
829}
830
831AutoFilter* AutoFilterBuffer::getActiveAutoFilter()
832{
833 // Excel expects not more than one auto filter per sheet or table
834 OSL_ENSURE( maAutoFilters.size() <= 1, "AutoFilterBuffer::getActiveAutoFilter - too many auto filters" )do { if (true && (!(maAutoFilters.size() <= 1))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sc/source/filter/oox/autofilterbuffer.cxx"
":" "834" ": "), "%s", "AutoFilterBuffer::getActiveAutoFilter - too many auto filters"
); } } while (false)
;
835 // stick to the last imported auto filter
836 return maAutoFilters.empty() ? nullptr : maAutoFilters.back().get();
837}
838
839} // namespace oox
840
841/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Reference.h

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#ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
20#define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
21
22#include "sal/config.h"
23
24#include <cassert>
25#include <cstddef>
26
27#if defined LIBO_INTERNAL_ONLY1
28#include <type_traits>
29#endif
30
31#include "rtl/alloc.h"
32
33namespace com
34{
35namespace sun
36{
37namespace star
38{
39namespace uno
40{
41
42class RuntimeException;
43class XInterface;
44class Type;
45class Any;
46
47/** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
48 Deprecated, please use SAL_NO_ACQUIRE.
49 @deprecated
50*/
51enum UnoReference_NoAcquire
52{
53 /** This enum value can be used for creating a reference granting a given interface,
54 i.e. transferring ownership to it.
55 */
56 UNO_REF_NO_ACQUIRE
57};
58
59/** This base class serves as a base class for all template reference classes and
60 has been introduced due to compiler problems with templated operators ==, =!.
61*/
62class BaseReference
63{
64protected:
65 /** the interface pointer
66 */
67 XInterface * _pInterface;
68
69 /** Queries given interface for type rType.
70
71 @param pInterface interface pointer
72 @param rType interface type
73 @return interface of demanded type (may be null)
74 */
75 inline static XInterface * SAL_CALL iquery( XInterface * pInterface, const Type & rType );
76 /** Queries given interface for type rType.
77 Throws a RuntimeException if the demanded interface cannot be queried.
78
79 @param pInterface interface pointer
80 @param rType interface type
81 @return interface of demanded type
82 */
83 inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface, const Type & rType );
84
85public:
86 /** Gets interface pointer. This call does not acquire the interface.
87
88 @return UNacquired interface pointer
89 */
90 XInterface * SAL_CALL get() const
91 { return _pInterface; }
92
93 /** Checks if reference is null.
94
95 @return true if reference acquires an interface, i.e. true if it is not null
96 */
97 bool SAL_CALL is() const
98 { return (NULL__null != _pInterface); }
11
Returning the value 1, which participates in a condition later
99
100#if defined LIBO_INTERNAL_ONLY1
101 /** Checks if reference is null.
102
103 @return true if reference acquires an interface, i.e. true if it is not null
104 */
105 explicit operator bool() const
106 { return is(); }
107#endif
108
109 /** Equality operator: compares two interfaces
110 Checks if both references are null or refer to the same object.
111
112 @param pInterface another interface
113 @return true if both references are null or refer to the same object, false otherwise
114 */
115 inline bool SAL_CALL operator == ( XInterface * pInterface ) const;
116 /** Inequality operator: compares two interfaces
117 Checks if both references are null or refer to the same object.
118
119 @param pInterface another interface
120 @return false if both references are null or refer to the same object, true otherwise
121 */
122 inline bool SAL_CALL operator != ( XInterface * pInterface ) const;
123
124 /** Equality operator: compares two interfaces
125 Checks if both references are null or refer to the same object.
126
127 @param rRef another reference
128 @return true if both references are null or refer to the same object, false otherwise
129 */
130 inline bool SAL_CALL operator == ( const BaseReference & rRef ) const;
131 /** Inequality operator: compares two interfaces
132 Checks if both references are null or refer to the same object.
133
134 @param rRef another reference
135 @return false if both references are null or refer to the same object, true otherwise
136 */
137 inline bool SAL_CALL operator != ( const BaseReference & rRef ) const;
138
139 /** Needed by some STL containers.
140
141 @param rRef another reference
142 @return true, if this reference is less than rRef
143 */
144 inline bool SAL_CALL operator < ( const BaseReference & rRef ) const;
145};
146
147/** Enum defining UNO_QUERY for implicit interface query.
148*/
149enum UnoReference_Query
150{
151 /** This enum value can be used for implicit interface query.
152 */
153 UNO_QUERY
154};
155/** Enum defining UNO_QUERY_THROW for implicit interface query.
156 If the demanded interface is unavailable, then a RuntimeException is thrown.
157*/
158enum UnoReference_QueryThrow
159{
160 /** This enum value can be used for implicit interface query.
161 */
162 UNO_QUERY_THROW
163};
164/** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
165 interface
166
167 @since UDK 3.2.8
168*/
169enum UnoReference_SetThrow
170{
171 UNO_SET_THROW
172};
173
174/** Template reference class for interface type derived from BaseReference.
175 A special constructor given the UNO_QUERY identifier queries interfaces
176 for reference type.
177*/
178template< class interface_type >
179class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) Reference : public BaseReference
180{
181 /** Queries given interface for type interface_type.
182
183 @param pInterface interface pointer
184 @return interface of demanded type (may be null)
185 */
186 inline static XInterface * SAL_CALL iquery( XInterface * pInterface );
187 /** Queries given interface for type interface_type.
188 Throws a RuntimeException if the demanded interface cannot be queried.
189
190 @param pInterface interface pointer
191 @return interface of demanded type
192 */
193 inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface );
194 /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
195
196 @param pInterface interface pointer
197 @return pInterface
198 */
199 inline static interface_type * SAL_CALL iset_throw( interface_type * pInterface );
200
201 /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
202 pointer to this interface_type.
203
204 To work around ambiguities in the case of multiple-inheritance interface
205 types (which inherit XInterface more than once), use reinterpret_cast
206 (resp. a sequence of two static_casts, to avoid warnings about
207 reinterpret_cast used between related classes) to switch from a pointer
208 to XInterface to a pointer to this derived interface_type. In
209 principle, this is not guaranteed to work. In practice, it seems to
210 work on all supported platforms.
211 */
212 static interface_type * castFromXInterface(XInterface * p) {
213 return static_cast< interface_type * >(static_cast< void * >(p));
214 }
215
216 /** Cast from a pointer to this interface_type to an "interface pointer"
217 (e.g., BaseReference::_pInterface).
218
219 To work around ambiguities in the case of multiple-inheritance interface
220 types (which inherit XInterface more than once), use reinterpret_cast
221 (resp. a sequence of two static_casts, to avoid warnings about
222 reinterpret_cast used between related classes) to switch from a pointer
223 to this derived interface_type to a pointer to XInterface. In
224 principle, this is not guaranteed to work. In practice, it seems to
225 work on all supported platforms.
226 */
227 static XInterface * castToXInterface(interface_type * p) {
228 return static_cast< XInterface * >(static_cast< void * >(p));
229 }
230
231public:
232 /// @cond INTERNAL
233 // these are here to force memory de/allocation to sal lib.
234 static void * SAL_CALL operator new ( ::size_t nSize )
235 { return ::rtl_allocateMemory( nSize ); }
236 static void SAL_CALL operator delete ( void * pMem )
237 { ::rtl_freeMemory( pMem ); }
238 static void * SAL_CALL operator new ( ::size_t, void * pMem )
239 { return pMem; }
240 static void SAL_CALL operator delete ( void *, void * )
241 {}
242 /// @endcond
243
244 /** Destructor: Releases interface if set.
245 */
246 inline ~Reference() COVERITY_NOEXCEPT_FALSE;
247
248 /** Default Constructor: Sets null reference.
249 */
250 inline Reference();
251
252 /** Copy constructor: Copies interface reference.
253
254 @param rRef another reference
255 */
256 inline Reference( const Reference< interface_type > & rRef );
257
258#if defined LIBO_INTERNAL_ONLY1
259 /** Move constructor
260
261 @param rRef another reference
262 */
263 inline Reference( Reference< interface_type > && rRef ) noexcept;
264
265 /** Up-casting conversion constructor: Copies interface reference.
266
267 Does not work for up-casts to ambiguous bases. For the special case of
268 up-casting to Reference< XInterface >, see the corresponding conversion
269 operator.
270
271 @param rRef another reference
272 */
273 template< class derived_type >
274 inline Reference(
275 const Reference< derived_type > & rRef,
276 std::enable_if_t<
277 std::is_base_of_v<interface_type, derived_type>
278 && !std::is_same_v<interface_type, XInterface>, void *> = nullptr);
279#endif
280
281 /** Constructor: Sets given interface pointer.
282
283 @param pInterface an interface pointer
284 */
285 inline Reference( interface_type * pInterface );
286
287 /** Constructor: Sets given interface pointer without acquiring it.
288
289 @param pInterface another reference
290 @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
291 */
292 inline Reference( interface_type * pInterface, __sal_NoAcquire dummy);
293 /** Constructor: Sets given interface pointer without acquiring it.
294 Deprecated, please use SAL_NO_ACQUIRE version.
295
296 @deprecated
297 @param pInterface another reference
298 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
299 */
300 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version")__attribute__((deprecated("use SAL_NO_ACQUIRE version"))) Reference( interface_type * pInterface, UnoReference_NoAcquire dummy );
301
302 /** Constructor: Queries given interface for reference interface type (interface_type).
303
304 @param rRef another reference
305 @param dummy UNO_QUERY to force obvious distinction to other constructors
306 */
307 inline Reference( const BaseReference & rRef, UnoReference_Query dummy );
308 /** Constructor: Queries given interface for reference interface type (interface_type).
309
310 @param pInterface an interface pointer
311 @param dummy UNO_QUERY to force obvious distinction to other constructors
312 */
313 inline Reference( XInterface * pInterface, UnoReference_Query dummy);
314 /** Constructor: Queries given any for reference interface type (interface_type).
315
316 @param rAny an any
317 @param dummy UNO_QUERY to force obvious distinction to other constructors
318 */
319 inline Reference( const Any & rAny, UnoReference_Query dummy);
320 /** Constructor: Queries given interface for reference interface type (interface_type).
321 Throws a RuntimeException if the demanded interface cannot be queried.
322
323 @param rRef another reference
324 @param dummy UNO_QUERY_THROW to force obvious distinction
325 to other constructors
326 */
327 inline Reference( const BaseReference & rRef, UnoReference_QueryThrow dummy );
328#ifdef LIBO_INTERNAL_ONLY1
329 /**
330 Prevent code from calling the QUERY_THROW constructor, when they meant to use the SET_THROW constructor.
331 */
332 Reference( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete;
333#endif
334 /** Constructor: Queries given interface for reference interface type (interface_type).
335 Throws a RuntimeException if the demanded interface cannot be queried.
336
337 @param pInterface an interface pointer
338 @param dummy UNO_QUERY_THROW to force obvious distinction
339 to other constructors
340 */
341 inline Reference( XInterface * pInterface, UnoReference_QueryThrow dummy );
342 /** Constructor: Queries given any for reference interface type (interface_type).
343 Throws a RuntimeException if the demanded interface cannot be queried.
344
345 @param rAny an any
346 @param dummy UNO_QUERY_THROW to force obvious distinction
347 to other constructors
348 */
349 inline Reference( const Any & rAny, UnoReference_QueryThrow dummy );
350 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
351 if the source interface is NULL.
352
353 @param rRef another interface reference of the same type
354 @param dummy UNO_SET_THROW to distinguish from default copy constructor
355
356 @since UDK 3.2.8
357 */
358 inline Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy );
359 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
360 if the source interface is NULL.
361
362 @param pInterface an interface pointer
363 @param dummy UNO_SET_THROW to distinguish from default assignment constructor
364
365 @since UDK 3.2.8
366 */
367 inline Reference( interface_type * pInterface, UnoReference_SetThrow dummy );
368
369 /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
370 any interface must be derived from com.sun.star.uno.XInterface.
371 This a useful direct cast possibility.
372 */
373 SAL_CALL operator const Reference< XInterface > & () const
374 { return * reinterpret_cast< const Reference< XInterface > * >( this ); }
375
376 /** Dereference operator: Used to call interface methods.
377
378 @return UNacquired interface pointer
379 */
380 interface_type * SAL_CALL operator -> () const {
381 assert(_pInterface != NULL)(static_cast <bool> (_pInterface != __null) ? void (0) :
__assert_fail ("_pInterface != NULL", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Reference.h"
, 381, __extension__ __PRETTY_FUNCTION__))
;
382 return castFromXInterface(_pInterface);
383 }
384
385 /** Indirection operator.
386
387 @since LibreOffice 6.3
388 @return UNacquired interface reference
389 */
390 interface_type & SAL_CALL operator * () const {
391 assert(_pInterface != NULL)(static_cast <bool> (_pInterface != __null) ? void (0) :
__assert_fail ("_pInterface != NULL", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Reference.h"
, 391, __extension__ __PRETTY_FUNCTION__))
;
392 return *castFromXInterface(_pInterface);
393 }
394
395 /** Gets interface pointer. This call does not acquire the interface.
396
397 @return UNacquired interface pointer
398 */
399 interface_type * SAL_CALL get() const
400 { return castFromXInterface(_pInterface); }
401
402 /** Clears reference, i.e. releases interface. Reference is null after clear() call.
403 */
404 inline void SAL_CALL clear();
405
406 /** Sets the given interface. An interface already set will be released.
407
408 @param rRef another reference
409 @return true, if non-null interface was set
410 */
411 inline bool SAL_CALL set( const Reference< interface_type > & rRef );
412 /** Sets the given interface. An interface already set will be released.
413
414 @param pInterface another interface
415 @return true, if non-null interface was set
416 */
417 inline bool SAL_CALL set( interface_type * pInterface );
418
419 /** Sets interface pointer without acquiring it. An interface already set will be released.
420
421 @param pInterface an interface pointer
422 @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
423 @return true, if non-null interface was set
424 */
425 inline bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire dummy);
426 /** Sets interface pointer without acquiring it. An interface already set will be released.
427 Deprecated, please use SAL_NO_ACQUIRE version.
428
429 @deprecated
430 @param pInterface an interface pointer
431 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
432 @return true, if non-null interface was set
433 */
434 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version")__attribute__((deprecated("use SAL_NO_ACQUIRE version"))) bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire dummy);
435
436 /** Queries given interface for reference interface type (interface_type) and sets it.
437 An interface already set will be released.
438
439 @param pInterface an interface pointer
440 @param dummy UNO_QUERY to force obvious distinction to set methods
441 @return true, if non-null interface was set
442 */
443 inline bool SAL_CALL set( XInterface * pInterface, UnoReference_Query dummy );
444 /** Queries given interface for reference interface type (interface_type) and sets it.
445 An interface already set will be released.
446
447 @param rRef another reference
448 @param dummy UNO_QUERY to force obvious distinction to set methods
449 @return true, if non-null interface was set
450 */
451 inline bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query dummy);
452
453 /** Queries given any for reference interface type (interface_type)
454 and sets it. An interface already set will be released.
455
456 @param rAny
457 an Any containing an interface
458 @param dummy
459 UNO_QUERY to force obvious distinction
460 to set methods
461 @return
462 true, if non-null interface was set
463 */
464 inline bool set( Any const & rAny, UnoReference_Query dummy );
465
466 /** Queries given interface for reference interface type (interface_type) and sets it.
467 An interface already set will be released.
468 Throws a RuntimeException if the demanded interface cannot be set.
469
470 @param pInterface an interface pointer
471 @param dummy UNO_QUERY_THROW to force obvious distinction
472 to set methods
473 */
474 inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow dummy );
475 /** Queries given interface for reference interface type (interface_type) and sets it.
476 An interface already set will be released.
477 Throws a RuntimeException if the demanded interface cannot be set.
478
479 @param rRef another reference
480 @param dummy UNO_QUERY_THROW to force obvious distinction
481 to set methods
482 */
483 inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow dummy );
484#ifdef LIBO_INTERNAL_ONLY1
485 /**
486 Prevent code from calling the QUERY_THROW version, when they meant to use the SET_THROW version.
487 */
488 void set( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete;
489#endif
490
491 /** Queries given any for reference interface type (interface_type) and
492 sets it. An interface already set will be released.
493 Throws a RuntimeException if the demanded interface cannot be set.
494
495 @param rAny
496 an Any containing an interface
497 @param dummy
498 UNO_QUERY_THROW to force obvious distinction to set methods
499 */
500 inline void set( Any const & rAny, UnoReference_QueryThrow dummy);
501 /** sets the given interface
502 An interface already set will be released.
503 Throws a RuntimeException if the source interface is @b NULL.
504
505 @param pInterface an interface pointer
506 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
507
508 @since UDK 3.2.8
509 */
510 inline void SAL_CALL set( interface_type * pInterface, UnoReference_SetThrow dummy);
511 /** sets the given interface
512 An interface already set will be released.
513 Throws a RuntimeException if the source interface is @b NULL.
514
515 @param rRef an interface reference
516 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
517
518 @since UDK 3.2.8
519 */
520 inline void SAL_CALL set( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy);
521
522
523 /** Assignment operator: Acquires given interface pointer and sets reference.
524 An interface already set will be released.
525
526 @param pInterface an interface pointer
527 @return this reference
528 */
529 inline Reference< interface_type > & SAL_CALL operator = ( interface_type * pInterface );
530 /** Assignment operator: Acquires given interface reference and sets reference.
531 An interface already set will be released.
532
533 @param rRef an interface reference
534 @return this reference
535 */
536 inline Reference< interface_type > & SAL_CALL operator = ( const Reference< interface_type > & rRef );
537#if defined LIBO_INTERNAL_ONLY1
538 /** Assignment move operator: Acquires given interface reference and sets reference.
539 An interface already set will be released.
540
541 @param rRef an interface reference
542 @return this reference
543 */
544 inline Reference< interface_type > & SAL_CALL operator = ( Reference< interface_type > && rRef ) noexcept;
545#endif
546 /** Queries given interface reference for type interface_type.
547
548 @param rRef interface reference
549 @return interface reference of demanded type (may be null)
550 */
551 SAL_WARN_UNUSED_RESULT[[nodiscard]] inline static Reference< interface_type > SAL_CALL query( const BaseReference & rRef );
552 /** Queries given interface for type interface_type.
553
554 @param pInterface interface pointer
555 @return interface reference of demanded type (may be null)
556 */
557 SAL_WARN_UNUSED_RESULT[[nodiscard]] inline static Reference< interface_type > SAL_CALL query( XInterface * pInterface );
558};
559
560}
561}
562}
563}
564
565#endif
566
567/* vim:set shiftwidth=4 softtabstop=4 expandtab: */