Fix GNU C++ version check
[LibreOffice.git] / ucb / source / ucp / tdoc / tdoc_datasupplier.cxx
blob54d108704eda72c42245cf8469e77995e0636c8f
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 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
25 *************************************************************************/
27 #include <optional>
29 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
30 #include <com/sun/star/ucb/ResultSetException.hpp>
31 #include <osl/diagnose.h>
32 #include <ucbhelper/contentidentifier.hxx>
33 #include <utility>
35 #include "tdoc_datasupplier.hxx"
36 #include "tdoc_content.hxx"
38 using namespace com::sun::star;
39 using namespace tdoc_ucp;
41 namespace tdoc_ucp
45 // struct ResultListEntry.
47 namespace {
52 // struct DataSupplier_Impl.
57 // DataSupplier Implementation.
58 ResultSetDataSupplier::ResultSetDataSupplier(
59 uno::Reference< uno::XComponentContext > xContext,
60 rtl::Reference< Content > xContent )
61 : m_xContent(std::move( xContent )), m_xContext(std::move( xContext )),
62 m_bCountFinal( false ), m_bThrowException( false )
66 // virtual
67 ResultSetDataSupplier::~ResultSetDataSupplier()
71 // virtual
72 OUString
73 ResultSetDataSupplier::queryContentIdentifierString( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
75 std::unique_lock aGuard( m_aMutex );
76 return queryContentIdentifierStringImpl(rResultSetGuard, aGuard, nIndex);
79 OUString
80 ResultSetDataSupplier::queryContentIdentifierStringImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
82 if ( nIndex < m_aResults.size() )
84 OUString aId = m_aResults[ nIndex ].aURL;
85 if ( !aId.isEmpty() )
87 // Already cached.
88 return aId;
92 if ( getResultImpl(rResultSetGuard, rGuard, nIndex) )
94 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
95 return m_aResults[ nIndex ].aURL;
97 return OUString();
100 // virtual
101 uno::Reference< ucb::XContentIdentifier >
102 ResultSetDataSupplier::queryContentIdentifier( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
104 std::unique_lock aGuard( m_aMutex );
105 return queryContentIdentifierImpl(rResultSetGuard, aGuard, nIndex);
108 uno::Reference< ucb::XContentIdentifier >
109 ResultSetDataSupplier::queryContentIdentifierImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
111 if ( nIndex < m_aResults.size() )
113 uno::Reference< ucb::XContentIdentifier > xId
114 = m_aResults[ nIndex ].xId;
115 if ( xId.is() )
117 // Already cached.
118 return xId;
122 OUString aId = queryContentIdentifierStringImpl( rResultSetGuard, rGuard, nIndex );
123 if ( !aId.isEmpty() )
125 uno::Reference< ucb::XContentIdentifier > xId
126 = new ::ucbhelper::ContentIdentifier( aId );
127 m_aResults[ nIndex ].xId = xId;
128 return xId;
130 return uno::Reference< ucb::XContentIdentifier >();
133 // virtual
134 uno::Reference< ucb::XContent >
135 ResultSetDataSupplier::queryContent( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
137 std::unique_lock aGuard( m_aMutex );
139 if ( nIndex < m_aResults.size() )
141 uno::Reference< ucb::XContent > xContent
142 = m_aResults[ nIndex ].xContent;
143 if ( xContent.is() )
145 // Already cached.
146 return xContent;
150 uno::Reference< ucb::XContentIdentifier > xId
151 = queryContentIdentifierImpl( rResultSetGuard, aGuard, nIndex );
152 if ( xId.is() )
156 uno::Reference< ucb::XContent > xContent
157 = m_xContent->getProvider()->queryContent( xId );
158 m_aResults[ nIndex ].xContent = xContent;
159 return xContent;
162 catch ( ucb::IllegalIdentifierException const & )
166 return uno::Reference< ucb::XContent >();
169 // virtual
170 bool ResultSetDataSupplier::getResult( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
172 std::unique_lock aGuard( m_aMutex );
173 return getResultImpl(rResultSetGuard, aGuard, nIndex);
176 bool ResultSetDataSupplier::getResultImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
178 if ( m_aResults.size() > nIndex )
180 // Result already present.
181 return true;
184 // Result not (yet) present.
186 if ( m_bCountFinal )
187 return false;
189 // Try to obtain result...
191 sal_uInt32 nOldCount = m_aResults.size();
192 bool bFound = false;
194 if ( queryNamesOfChildren(rGuard) )
196 for ( sal_uInt32 n = nOldCount;
197 n < sal::static_int_cast<sal_uInt32>(
198 m_xNamesOfChildren->getLength());
199 ++n )
201 const OUString & rName
202 = m_xNamesOfChildren->getConstArray()[ n ];
204 if ( rName.isEmpty() )
206 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
207 break;
210 // Assemble URL for child.
211 OUString aURL = assembleChildURL( rName );
213 m_aResults.emplace_back( aURL );
215 if ( n == nIndex )
217 // Result obtained.
218 bFound = true;
219 break;
224 if ( !bFound )
225 m_bCountFinal = true;
227 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
228 if ( xResultSet.is() )
230 // Callbacks follow!
231 rGuard.unlock();
233 if ( nOldCount < m_aResults.size() )
234 xResultSet->rowCountChanged( rResultSetGuard, nOldCount, m_aResults.size() );
236 if ( m_bCountFinal )
237 xResultSet->rowCountFinal(rResultSetGuard);
239 rGuard.lock();
242 return bFound;
245 // virtual
246 sal_uInt32 ResultSetDataSupplier::totalCount(std::unique_lock<std::mutex>& rResultSetGuard)
248 std::unique_lock aGuard( m_aMutex );
250 if ( m_bCountFinal )
251 return m_aResults.size();
253 sal_uInt32 nOldCount = m_aResults.size();
255 if ( queryNamesOfChildren(aGuard) )
257 for ( sal_uInt32 n = nOldCount;
258 n < sal::static_int_cast<sal_uInt32>(
259 m_xNamesOfChildren->getLength());
260 ++n )
262 const OUString & rName
263 = m_xNamesOfChildren->getConstArray()[ n ];
265 if ( rName.isEmpty() )
267 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
268 break;
271 // Assemble URL for child.
272 OUString aURL = assembleChildURL( rName );
274 m_aResults.emplace_back( aURL );
278 m_bCountFinal = true;
280 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
281 if ( xResultSet.is() )
283 // Callbacks follow!
284 aGuard.unlock();
286 if ( nOldCount < m_aResults.size() )
287 xResultSet->rowCountChanged( rResultSetGuard, nOldCount, m_aResults.size() );
289 xResultSet->rowCountFinal(rResultSetGuard);
292 return m_aResults.size();
295 // virtual
296 sal_uInt32 ResultSetDataSupplier::currentCount()
298 return m_aResults.size();
301 // virtual
302 bool ResultSetDataSupplier::isCountFinal()
304 return m_bCountFinal;
307 // virtual
308 uno::Reference< sdbc::XRow >
309 ResultSetDataSupplier::queryPropertyValues( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
311 std::unique_lock aGuard( m_aMutex );
313 if ( nIndex < m_aResults.size() )
315 uno::Reference< sdbc::XRow > xRow = m_aResults[ nIndex ].xRow;
316 if ( xRow.is() )
318 // Already cached.
319 return xRow;
323 if ( getResultImpl( rResultSetGuard, aGuard, nIndex ) )
325 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
326 m_xContext,
327 getResultSet()->getProperties(),
328 m_xContent->getContentProvider().get(),
329 queryContentIdentifierStringImpl( rResultSetGuard, aGuard, nIndex ) );
330 m_aResults[ nIndex ].xRow = xRow;
331 return xRow;
334 return uno::Reference< sdbc::XRow >();
337 // virtual
338 void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
340 std::unique_lock aGuard( m_aMutex );
342 if ( nIndex < m_aResults.size() )
343 m_aResults[ nIndex ].xRow.clear();
346 // virtual
347 void ResultSetDataSupplier::close()
351 // virtual
352 void ResultSetDataSupplier::validate()
354 if ( m_bThrowException )
355 throw ucb::ResultSetException();
358 bool ResultSetDataSupplier::queryNamesOfChildren(std::unique_lock<std::mutex>& /*rGuard*/)
360 if ( !m_xNamesOfChildren )
362 uno::Sequence< OUString > aNamesOfChildren;
364 if ( !m_xContent->getContentProvider()->queryNamesOfChildren(
365 m_xContent->getIdentifier()->getContentIdentifier(),
366 aNamesOfChildren ) )
368 OSL_FAIL( "Got no list of children!" );
369 m_bThrowException = true;
370 return false;
372 else
374 m_xNamesOfChildren = std::move( aNamesOfChildren );
377 return true;
380 OUString
381 ResultSetDataSupplier::assembleChildURL( std::u16string_view aName )
383 OUString aURL
384 = m_xContent->getIdentifier()->getContentIdentifier();
386 sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
387 if ( nUrlEnd != aURL.getLength() - 1 )
388 aURL += "/";
390 aURL += aName;
391 return aURL;
394 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */