File: | home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx |
Warning: | line 1113, column 13 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <sal/config.h> | |||
22 | ||||
23 | #include <set> | |||
24 | ||||
25 | #include <ChartController.hxx> | |||
26 | #include <servicenames.hxx> | |||
27 | #include <ResId.hxx> | |||
28 | #include <dlg_DataSource.hxx> | |||
29 | #include <ChartModel.hxx> | |||
30 | #include <ChartModelHelper.hxx> | |||
31 | #include "ControllerCommandDispatch.hxx" | |||
32 | #include <strings.hrc> | |||
33 | #include <chartview/ExplicitValueProvider.hxx> | |||
34 | #include <ChartViewHelper.hxx> | |||
35 | ||||
36 | #include <ChartWindow.hxx> | |||
37 | #include <chartview/DrawModelWrapper.hxx> | |||
38 | #include <DrawViewWrapper.hxx> | |||
39 | #include <ObjectIdentifier.hxx> | |||
40 | #include <DiagramHelper.hxx> | |||
41 | #include <ControllerLockGuard.hxx> | |||
42 | #include "UndoGuard.hxx" | |||
43 | #include "ChartDropTargetHelper.hxx" | |||
44 | ||||
45 | #include <dlg_ChartType.hxx> | |||
46 | #include <AccessibleChartView.hxx> | |||
47 | #include "DrawCommandDispatch.hxx" | |||
48 | #include "ShapeController.hxx" | |||
49 | #include "UndoActions.hxx" | |||
50 | #include <ViewElementListProvider.hxx> | |||
51 | ||||
52 | #include <cppuhelper/supportsservice.hxx> | |||
53 | ||||
54 | #include <com/sun/star/chart2/XChartDocument.hpp> | |||
55 | #include <com/sun/star/chart2/data/XDataReceiver.hpp> | |||
56 | #include <com/sun/star/frame/XController2.hpp> | |||
57 | #include <com/sun/star/util/CloseVetoException.hpp> | |||
58 | #include <com/sun/star/util/XModeChangeBroadcaster.hpp> | |||
59 | #include <com/sun/star/util/XModifyBroadcaster.hpp> | |||
60 | #include <com/sun/star/frame/LayoutManagerEvents.hpp> | |||
61 | #include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp> | |||
62 | #include <com/sun/star/document/XUndoManagerSupplier.hpp> | |||
63 | #include <com/sun/star/ui/XSidebar.hpp> | |||
64 | #include <com/sun/star/chart2/XChartTypeContainer.hpp> | |||
65 | #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> | |||
66 | #include <com/sun/star/chart2/XDataProviderAccess.hpp> | |||
67 | ||||
68 | #include <sal/log.hxx> | |||
69 | #include <tools/debug.hxx> | |||
70 | #include <svx/sidebar/SelectionChangeHandler.hxx> | |||
71 | #include <toolkit/awt/vclxwindow.hxx> | |||
72 | #include <toolkit/helper/vclunohelper.hxx> | |||
73 | #include <vcl/svapp.hxx> | |||
74 | #include <vcl/weld.hxx> | |||
75 | #include <osl/mutex.hxx> | |||
76 | ||||
77 | #include <sfx2/sidebar/SidebarController.hxx> | |||
78 | ||||
79 | #include <com/sun/star/frame/XLayoutManager.hpp> | |||
80 | ||||
81 | // this is needed to properly destroy the unique_ptr to the AcceleratorExecute | |||
82 | // object in the DTOR | |||
83 | #include <svtools/acceleratorexecute.hxx> | |||
84 | #include <svx/ActionDescriptionProvider.hxx> | |||
85 | #include <tools/diagnose_ex.h> | |||
86 | ||||
87 | // enable the following define to let the controller listen to model changes and | |||
88 | // react on this by rebuilding the view | |||
89 | #define TEST_ENABLE_MODIFY_LISTENER | |||
90 | ||||
91 | namespace chart | |||
92 | { | |||
93 | ||||
94 | using namespace ::com::sun::star; | |||
95 | using namespace ::com::sun::star::accessibility; | |||
96 | using namespace ::com::sun::star::chart2; | |||
97 | using ::com::sun::star::uno::Reference; | |||
98 | using ::com::sun::star::uno::Sequence; | |||
99 | ||||
100 | ChartController::ChartController(uno::Reference<uno::XComponentContext> const & xContext) : | |||
101 | m_aLifeTimeManager( nullptr ), | |||
102 | m_bSuspended( false ), | |||
103 | m_xCC(xContext), //@todo is it allowed to hold this context?? | |||
104 | m_aModelMutex(), | |||
105 | m_aModel( nullptr, m_aModelMutex ), | |||
106 | m_xViewWindow(), | |||
107 | m_xChartView(), | |||
108 | m_pDrawModelWrapper(), | |||
109 | m_eDragMode(SdrDragMode::Move), | |||
110 | m_bWaitingForDoubleClick(false), | |||
111 | m_bWaitingForMouseUp(false), | |||
112 | m_bFieldButtonDown(false), | |||
113 | m_bConnectingToView(false), | |||
114 | m_bDisposed(false), | |||
115 | m_aDispatchContainer( m_xCC ), | |||
116 | m_eDrawMode( CHARTDRAW_SELECT ), | |||
117 | mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler( | |||
118 | [this]() { return this->GetContextName(); }, | |||
119 | this, vcl::EnumContext::Context::Cell)) | |||
120 | { | |||
121 | m_aDoubleClickTimer.SetInvokeHandler( LINK( this, ChartController, DoubleClickWaitingHdl )::tools::detail::makeLink( ::tools::detail::castTo<ChartController *>(this), &ChartController::LinkStubDoubleClickWaitingHdl ) ); | |||
122 | } | |||
123 | ||||
124 | ChartController::~ChartController() | |||
125 | { | |||
126 | stopDoubleClickWaiting(); | |||
127 | } | |||
128 | ||||
129 | ChartController::TheModel::TheModel( const uno::Reference< frame::XModel > & xModel ) : | |||
130 | m_xModel( xModel ), | |||
131 | m_bOwnership( true ) | |||
132 | { | |||
133 | m_xCloseable = | |||
134 | uno::Reference< util::XCloseable >( xModel, uno::UNO_QUERY ); | |||
135 | } | |||
136 | ||||
137 | ChartController::TheModel::~TheModel() | |||
138 | { | |||
139 | } | |||
140 | ||||
141 | void ChartController::TheModel::addListener( ChartController* pController ) | |||
142 | { | |||
143 | if(m_xCloseable.is()) | |||
144 | { | |||
145 | //if you need to be able to veto against the destruction of the model | |||
146 | // you must add as a close listener | |||
147 | ||||
148 | //otherwise you 'can' add as closelistener or 'must' add as dispose event listener | |||
149 | ||||
150 | m_xCloseable->addCloseListener( | |||
151 | static_cast<util::XCloseListener*>(pController) ); | |||
152 | } | |||
153 | else if( m_xModel.is() ) | |||
154 | { | |||
155 | //we need to add as dispose event listener | |||
156 | m_xModel->addEventListener( | |||
157 | static_cast<util::XCloseListener*>(pController) ); | |||
158 | } | |||
159 | ||||
160 | } | |||
161 | ||||
162 | void ChartController::TheModel::removeListener( ChartController* pController ) | |||
163 | { | |||
164 | if(m_xCloseable.is()) | |||
165 | m_xCloseable->removeCloseListener( | |||
166 | static_cast<util::XCloseListener*>(pController) ); | |||
167 | ||||
168 | else if( m_xModel.is() ) | |||
169 | m_xModel->removeEventListener( | |||
170 | static_cast<util::XCloseListener*>(pController) ); | |||
171 | } | |||
172 | ||||
173 | void ChartController::TheModel::tryTermination() | |||
174 | { | |||
175 | if(!m_bOwnership) | |||
176 | return; | |||
177 | ||||
178 | try | |||
179 | { | |||
180 | if(m_xCloseable.is()) | |||
181 | { | |||
182 | try | |||
183 | { | |||
184 | //@todo ? are we allowed to use sal_True here if we have the explicit ownership? | |||
185 | //I think yes, because there might be other CloseListeners later in the list which might be interested still | |||
186 | //but make sure that we do not throw the CloseVetoException here ourselves | |||
187 | //so stop listening before trying to terminate or check the source of queryclosing event | |||
188 | m_xCloseable->close(true); | |||
189 | ||||
190 | m_bOwnership = false; | |||
191 | } | |||
192 | catch( const util::CloseVetoException& ) | |||
193 | { | |||
194 | //since we have indicated to give up the ownership with parameter true in close call | |||
195 | //the one who has thrown the CloseVetoException is the new owner | |||
196 | ||||
197 | SAL_WARN_IF( m_bOwnership, "chart2.main", "a well known owner has caught a CloseVetoException after calling close(true)")do { if (true && (m_bOwnership)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "chart2.main")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "a well known owner has caught a CloseVetoException after calling close(true)" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main" ), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "a well known owner has caught a CloseVetoException after calling close(true)" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "a well known owner has caught a CloseVetoException after calling close(true)" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main" ), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "197" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "a well known owner has caught a CloseVetoException after calling close(true)" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main" ), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "197" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "a well known owner has caught a CloseVetoException after calling close(true)" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "a well known owner has caught a CloseVetoException after calling close(true)" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main" ), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "197" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
198 | m_bOwnership = false; | |||
199 | return; | |||
200 | } | |||
201 | ||||
202 | } | |||
203 | else if( m_xModel.is() ) | |||
204 | { | |||
205 | //@todo correct?? | |||
206 | m_xModel->dispose(); | |||
207 | return; | |||
208 | } | |||
209 | } | |||
210 | catch(const uno::Exception&) | |||
211 | { | |||
212 | DBG_UNHANDLED_EXCEPTION( "chart2", "Termination of model failed" )DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "212" ": ", "chart2", "Termination of model failed" );; | |||
213 | } | |||
214 | } | |||
215 | ||||
216 | ChartController::TheModelRef::TheModelRef( TheModel* pTheModel, osl::Mutex& rMutex ) : | |||
217 | m_rModelMutex(rMutex) | |||
218 | { | |||
219 | osl::Guard< osl::Mutex > aGuard( m_rModelMutex ); | |||
220 | m_xTheModel = pTheModel; | |||
221 | } | |||
222 | ChartController::TheModelRef::TheModelRef( const TheModelRef& rTheModel, ::osl::Mutex& rMutex ) : | |||
223 | m_rModelMutex(rMutex) | |||
224 | { | |||
225 | osl::Guard< osl::Mutex > aGuard( m_rModelMutex ); | |||
226 | m_xTheModel = rTheModel.m_xTheModel; | |||
227 | } | |||
228 | ChartController::TheModelRef& ChartController::TheModelRef::operator=(TheModel* pTheModel) | |||
229 | { | |||
230 | osl::Guard< osl::Mutex > aGuard( m_rModelMutex ); | |||
231 | m_xTheModel = pTheModel; | |||
232 | return *this; | |||
233 | } | |||
234 | ChartController::TheModelRef& ChartController::TheModelRef::operator=(const TheModelRef& rTheModel) | |||
235 | { | |||
236 | osl::Guard< osl::Mutex > aGuard( m_rModelMutex ); | |||
237 | m_xTheModel = rTheModel.operator->(); | |||
238 | return *this; | |||
239 | } | |||
240 | ChartController::TheModelRef::~TheModelRef() | |||
241 | { | |||
242 | osl::Guard< osl::Mutex > aGuard( m_rModelMutex ); | |||
243 | m_xTheModel.clear(); | |||
244 | } | |||
245 | bool ChartController::TheModelRef::is() const | |||
246 | { | |||
247 | return m_xTheModel.is(); | |||
248 | } | |||
249 | ||||
250 | namespace { | |||
251 | ||||
252 | css::uno::Reference<css::chart2::XChartType> getChartType( | |||
253 | const css::uno::Reference<css::chart2::XChartDocument>& xChartDoc) | |||
254 | { | |||
255 | Reference <chart2::XDiagram > xDiagram = xChartDoc->getFirstDiagram(); | |||
256 | if (!xDiagram.is()) { | |||
257 | return css::uno::Reference<css::chart2::XChartType>(); | |||
258 | } | |||
259 | ||||
260 | Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW ); | |||
261 | ||||
262 | Sequence< Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems()); | |||
263 | if (!xCooSysSequence.hasElements()) { | |||
264 | return css::uno::Reference<css::chart2::XChartType>(); | |||
265 | } | |||
266 | ||||
267 | Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[0], uno::UNO_QUERY_THROW ); | |||
268 | ||||
269 | Sequence< Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() ); | |||
270 | ||||
271 | return xChartTypeSequence[0]; | |||
272 | } | |||
273 | ||||
274 | } | |||
275 | ||||
276 | OUString ChartController::GetContextName() | |||
277 | { | |||
278 | if (m_bDisposed) | |||
279 | return OUString(); | |||
280 | ||||
281 | uno::Any aAny = getSelection(); | |||
282 | if (!aAny.hasValue()) | |||
283 | return "Chart"; | |||
284 | ||||
285 | OUString aCID; | |||
286 | aAny >>= aCID; | |||
287 | ||||
288 | if (aCID.isEmpty()) | |||
289 | return "Chart"; | |||
290 | ||||
291 | ObjectType eObjectID = ObjectIdentifier::getObjectType(aCID); | |||
292 | switch (eObjectID) | |||
293 | { | |||
294 | case OBJECTTYPE_DATA_SERIES: | |||
295 | return "Series"; | |||
296 | break; | |||
297 | case OBJECTTYPE_DATA_ERRORS_X: | |||
298 | case OBJECTTYPE_DATA_ERRORS_Y: | |||
299 | case OBJECTTYPE_DATA_ERRORS_Z: | |||
300 | return "ErrorBar"; | |||
301 | case OBJECTTYPE_AXIS: | |||
302 | return "Axis"; | |||
303 | case OBJECTTYPE_GRID: | |||
304 | return "Grid"; | |||
305 | case OBJECTTYPE_DIAGRAM: | |||
306 | { | |||
307 | css::uno::Reference<css::chart2::XChartType> xChartType = getChartType(css::uno::Reference<css::chart2::XChartDocument>(getModel(), uno::UNO_QUERY)); | |||
308 | if (xChartType.is() && xChartType->getChartType() == "com.sun.star.chart2.PieChartType") | |||
309 | return "ChartElements"; | |||
310 | break; | |||
311 | } | |||
312 | case OBJECTTYPE_DATA_CURVE: | |||
313 | case OBJECTTYPE_DATA_AVERAGE_LINE: | |||
314 | return "Trendline"; | |||
315 | default: | |||
316 | break; | |||
317 | } | |||
318 | ||||
319 | return "Chart"; | |||
320 | } | |||
321 | ||||
322 | // private methods | |||
323 | ||||
324 | bool ChartController::impl_isDisposedOrSuspended() const | |||
325 | { | |||
326 | if( m_aLifeTimeManager.impl_isDisposed() ) | |||
327 | return true; | |||
328 | ||||
329 | if( m_bSuspended ) | |||
330 | { | |||
331 | OSL_FAIL( "This Controller is suspended" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "331" ": "), "%s", "This Controller is suspended"); } } while (false); | |||
332 | return true; | |||
333 | } | |||
334 | return false; | |||
335 | } | |||
336 | ||||
337 | // lang::XServiceInfo | |||
338 | ||||
339 | OUString SAL_CALL ChartController::getImplementationName() | |||
340 | { | |||
341 | return CHART_CONTROLLER_SERVICE_IMPLEMENTATION_NAME"com.sun.star.comp.chart2.ChartController"; | |||
342 | } | |||
343 | ||||
344 | sal_Bool SAL_CALL ChartController::supportsService( const OUString& rServiceName ) | |||
345 | { | |||
346 | return cppu::supportsService(this, rServiceName); | |||
347 | } | |||
348 | ||||
349 | css::uno::Sequence< OUString > SAL_CALL ChartController::getSupportedServiceNames() | |||
350 | { | |||
351 | return { | |||
352 | CHART_CONTROLLER_SERVICE_NAME"com.sun.star.chart2.ChartController", | |||
353 | "com.sun.star.frame.Controller" | |||
354 | //// @todo : add additional services if you support any further | |||
355 | }; | |||
356 | } | |||
357 | ||||
358 | namespace { | |||
359 | ||||
360 | uno::Reference<ui::XSidebar> getSidebarFromModel(const uno::Reference<frame::XModel>& xModel) | |||
361 | { | |||
362 | uno::Reference<container::XChild> xChild(xModel, uno::UNO_QUERY); | |||
363 | if (!xChild.is()) | |||
364 | return nullptr; | |||
365 | ||||
366 | uno::Reference<frame::XModel> xParent (xChild->getParent(), uno::UNO_QUERY); | |||
367 | if (!xParent.is()) | |||
368 | return nullptr; | |||
369 | ||||
370 | uno::Reference<frame::XController2> xController(xParent->getCurrentController(), uno::UNO_QUERY); | |||
371 | if (!xController.is()) | |||
372 | return nullptr; | |||
373 | ||||
374 | uno::Reference<ui::XSidebarProvider> xSidebarProvider = xController->getSidebar(); | |||
375 | if (!xSidebarProvider.is()) | |||
376 | return nullptr; | |||
377 | ||||
378 | return xSidebarProvider->getSidebar(); | |||
379 | } | |||
380 | ||||
381 | } | |||
382 | ||||
383 | // XController | |||
384 | ||||
385 | void SAL_CALL ChartController::attachFrame( | |||
386 | const uno::Reference<frame::XFrame>& xFrame ) | |||
387 | { | |||
388 | SolarMutexGuard aGuard; | |||
389 | ||||
390 | if( impl_isDisposedOrSuspended() ) //@todo? allow attaching the frame while suspended? | |||
391 | return; //behave passive if already disposed or suspended | |||
392 | ||||
393 | mpSelectionChangeHandler->Connect(); | |||
394 | ||||
395 | uno::Reference<ui::XSidebar> xSidebar = getSidebarFromModel(getModel()); | |||
396 | if (xSidebar.is()) | |||
397 | { | |||
398 | auto pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get()); | |||
399 | assert(pSidebar)(static_cast <bool> (pSidebar) ? void (0) : __assert_fail ("pSidebar", "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" , 399, __extension__ __PRETTY_FUNCTION__)); | |||
400 | sfx2::sidebar::SidebarController::registerSidebarForFrame(pSidebar, this); | |||
401 | pSidebar->updateModel(getModel()); | |||
402 | css::lang::EventObject aEvent; | |||
403 | mpSelectionChangeHandler->selectionChanged(aEvent); | |||
404 | } | |||
405 | ||||
406 | if(m_xFrame.is()) //what happens, if we do have a Frame already?? | |||
407 | { | |||
408 | //@todo? throw exception? | |||
409 | OSL_FAIL( "there is already a frame attached to the controller" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "409" ": "), "%s", "there is already a frame attached to the controller" ); } } while (false); | |||
410 | return; | |||
411 | } | |||
412 | ||||
413 | //--attach frame | |||
414 | m_xFrame = xFrame; //the frameloader is responsible to call xFrame->setComponent | |||
415 | ||||
416 | //add as disposelistener to the frame (due to persistent reference) ??...: | |||
417 | ||||
418 | //the frame is considered to be owner of this controller and will live longer than we do | |||
419 | //the frame or the disposer of the frame has the duty to call suspend and dispose on this object | |||
420 | //so we do not need to add as lang::XEventListener for DisposingEvents right? | |||
421 | ||||
422 | //@todo nothing right??? | |||
423 | ||||
424 | //create view @todo is this the correct place here?? | |||
425 | ||||
426 | vcl::Window* pParent = nullptr; | |||
427 | //get the window parent from the frame to use as parent for our new window | |||
428 | if(xFrame.is()) | |||
429 | { | |||
430 | uno::Reference< awt::XWindow > xContainerWindow = xFrame->getContainerWindow(); | |||
431 | VCLXWindow* pParentComponent = comphelper::getUnoTunnelImplementation<VCLXWindow>(xContainerWindow); | |||
432 | assert(pParentComponent)(static_cast <bool> (pParentComponent) ? void (0) : __assert_fail ("pParentComponent", "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" , 432, __extension__ __PRETTY_FUNCTION__)); | |||
433 | if (pParentComponent) | |||
434 | pParentComponent->setVisible(true); | |||
435 | ||||
436 | pParent = VCLUnoHelper::GetWindow( xContainerWindow ).get(); | |||
437 | } | |||
438 | ||||
439 | { | |||
440 | // calls to VCL | |||
441 | SolarMutexGuard aSolarGuard; | |||
442 | auto pChartWindow = VclPtr<ChartWindow>::Create(this,pParent,pParent?pParent->GetStyle():0); | |||
443 | pChartWindow->SetBackground();//no Background | |||
444 | m_xViewWindow.set( pChartWindow->GetComponentInterface(), uno::UNO_QUERY ); | |||
445 | pChartWindow->Show(); | |||
446 | m_apDropTargetHelper.reset( | |||
447 | new ChartDropTargetHelper( pChartWindow->GetDropTarget(), | |||
448 | uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY ))); | |||
449 | ||||
450 | impl_createDrawViewController(); | |||
451 | } | |||
452 | ||||
453 | //create the menu | |||
454 | { | |||
455 | uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY ); | |||
456 | if( xPropSet.is() ) | |||
457 | { | |||
458 | try | |||
459 | { | |||
460 | uno::Reference< css::frame::XLayoutManager > xLayoutManager; | |||
461 | xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager; | |||
462 | if ( xLayoutManager.is() ) | |||
463 | { | |||
464 | xLayoutManager->lock(); | |||
465 | xLayoutManager->requestElement( "private:resource/menubar/menubar" ); | |||
466 | //@todo: createElement should become unnecessary, remove when #i79198# is fixed | |||
467 | xLayoutManager->createElement( "private:resource/toolbar/standardbar" ); | |||
468 | xLayoutManager->requestElement( "private:resource/toolbar/standardbar" ); | |||
469 | //@todo: createElement should become unnecessary, remove when #i79198# is fixed | |||
470 | xLayoutManager->createElement( "private:resource/toolbar/toolbar" ); | |||
471 | xLayoutManager->requestElement( "private:resource/toolbar/toolbar" ); | |||
472 | ||||
473 | // #i12587# support for shapes in chart | |||
474 | xLayoutManager->createElement( "private:resource/toolbar/drawbar" ); | |||
475 | xLayoutManager->requestElement( "private:resource/toolbar/drawbar" ); | |||
476 | ||||
477 | xLayoutManager->requestElement( "private:resource/statusbar/statusbar" ); | |||
478 | xLayoutManager->unlock(); | |||
479 | ||||
480 | // add as listener to get notified when | |||
481 | m_xLayoutManagerEventBroadcaster.set( xLayoutManager, uno::UNO_QUERY ); | |||
482 | if( m_xLayoutManagerEventBroadcaster.is()) | |||
483 | m_xLayoutManagerEventBroadcaster->addLayoutManagerEventListener( this ); | |||
484 | } | |||
485 | } | |||
486 | catch( const uno::Exception & ) | |||
487 | { | |||
488 | DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "488" ": ", "chart2" );; | |||
489 | } | |||
490 | } | |||
491 | } | |||
492 | } | |||
493 | ||||
494 | //XModeChangeListener | |||
495 | void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent ) | |||
496 | { | |||
497 | SolarMutexGuard aGuard; | |||
498 | auto pChartWindow(GetChartWindow()); | |||
499 | //adjust controller to view status changes | |||
500 | ||||
501 | if( rEvent.NewMode == "dirty" ) | |||
502 | { | |||
503 | //the view has become dirty, we should repaint it if we have a window | |||
504 | if( pChartWindow ) | |||
505 | pChartWindow->ForceInvalidate(); | |||
506 | } | |||
507 | else if( rEvent.NewMode == "invalid" ) | |||
508 | { | |||
509 | //the view is about to become invalid so end all actions on it | |||
510 | impl_invalidateAccessible(); | |||
511 | if( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() ) | |||
512 | this->EndTextEdit(); | |||
513 | if( m_pDrawViewWrapper ) | |||
514 | { | |||
515 | m_pDrawViewWrapper->UnmarkAll(); | |||
516 | m_pDrawViewWrapper->HideSdrPage(); | |||
517 | } | |||
518 | } | |||
519 | else | |||
520 | { | |||
521 | //the view was rebuild so we can start some actions on it again | |||
522 | if( !m_bConnectingToView ) | |||
523 | { | |||
524 | if(pChartWindow && m_aModel.is() ) | |||
525 | { | |||
526 | m_bConnectingToView = true; | |||
527 | ||||
528 | GetDrawModelWrapper(); | |||
529 | if(m_pDrawModelWrapper) | |||
530 | { | |||
531 | { | |||
532 | if( m_pDrawViewWrapper ) | |||
533 | m_pDrawViewWrapper->ReInit(); | |||
534 | } | |||
535 | ||||
536 | //reselect object | |||
537 | if( m_aSelection.hasSelection() ) | |||
538 | this->impl_selectObjectAndNotiy(); | |||
539 | else | |||
540 | ChartModelHelper::triggerRangeHighlighting( getModel() ); | |||
541 | ||||
542 | impl_initializeAccessible(); | |||
543 | ||||
544 | { | |||
545 | if( pChartWindow ) | |||
546 | pChartWindow->Invalidate(); | |||
547 | } | |||
548 | } | |||
549 | ||||
550 | m_bConnectingToView = false; | |||
551 | } | |||
552 | } | |||
553 | } | |||
554 | } | |||
555 | ||||
556 | sal_Bool SAL_CALL ChartController::attachModel( const uno::Reference< frame::XModel > & xModel ) | |||
557 | { | |||
558 | impl_invalidateAccessible(); | |||
559 | ||||
560 | //is called to attach the controller to a new model. | |||
561 | //return true if attach was successfully, false otherwise (e.g. if you do not work with a model) | |||
562 | ||||
563 | SolarMutexResettableGuard aGuard; | |||
564 | if( impl_isDisposedOrSuspended() ) //@todo? allow attaching a new model while suspended? | |||
565 | return false; //behave passive if already disposed or suspended | |||
566 | aGuard.clear(); | |||
567 | ||||
568 | TheModelRef aNewModelRef( new TheModel( xModel), m_aModelMutex); | |||
569 | TheModelRef aOldModelRef(m_aModel,m_aModelMutex); | |||
570 | m_aModel = aNewModelRef; | |||
571 | ||||
572 | //--handle relations to the old model if any | |||
573 | if( aOldModelRef.is() ) | |||
574 | { | |||
575 | uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); | |||
576 | if( xViewBroadcaster.is() ) | |||
577 | xViewBroadcaster->removeModeChangeListener(this); | |||
578 | m_pDrawModelWrapper.reset(); | |||
579 | ||||
580 | aOldModelRef->removeListener( this ); | |||
581 | #ifdef TEST_ENABLE_MODIFY_LISTENER | |||
582 | uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aOldModelRef->getModel(),uno::UNO_QUERY ); | |||
583 | if( xMBroadcaster.is()) | |||
584 | xMBroadcaster->removeModifyListener( this ); | |||
585 | #endif | |||
586 | } | |||
587 | ||||
588 | //--handle relations to the new model | |||
589 | aNewModelRef->addListener( this ); | |||
590 | ||||
591 | aGuard.reset(); // lock for m_aDispatchContainer access | |||
592 | // set new model at dispatchers | |||
593 | m_aDispatchContainer.setModel( aNewModelRef->getModel()); | |||
594 | ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this, &m_aDispatchContainer ); | |||
595 | pDispatch->initialize(); | |||
596 | ||||
597 | // the dispatch container will return "this" for all commands returned by | |||
598 | // impl_getAvailableCommands(). That means, for those commands dispatch() | |||
599 | // is called here at the ChartController. | |||
600 | m_aDispatchContainer.setChartDispatch( pDispatch, impl_getAvailableCommands() ); | |||
601 | ||||
602 | DrawCommandDispatch* pDrawDispatch = new DrawCommandDispatch( m_xCC, this ); | |||
603 | pDrawDispatch->initialize(); | |||
604 | m_aDispatchContainer.setDrawCommandDispatch( pDrawDispatch ); | |||
605 | ||||
606 | ShapeController* pShapeController = new ShapeController( m_xCC, this ); | |||
607 | pShapeController->initialize(); | |||
608 | m_aDispatchContainer.setShapeController( pShapeController ); | |||
609 | aGuard.clear(); | |||
610 | ||||
611 | #ifdef TEST_ENABLE_MODIFY_LISTENER | |||
612 | uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aNewModelRef->getModel(),uno::UNO_QUERY ); | |||
613 | if( xMBroadcaster.is()) | |||
614 | xMBroadcaster->addModifyListener( this ); | |||
615 | #endif | |||
616 | ||||
617 | // #i119999# Do not do this per default to allow the user to deselect the chart OLE with a single press to ESC | |||
618 | // select chart area per default: | |||
619 | // select( uno::Any( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) ); | |||
620 | ||||
621 | uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY ); | |||
622 | if( xFact.is()) | |||
623 | { | |||
624 | m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME"com.sun.star.chart2.ChartView" ); | |||
625 | GetDrawModelWrapper(); | |||
626 | uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); | |||
627 | if( xViewBroadcaster.is() ) | |||
628 | xViewBroadcaster->addModeChangeListener(this); | |||
629 | } | |||
630 | ||||
631 | //the frameloader is responsible to call xModel->connectController | |||
632 | { | |||
633 | SolarMutexGuard aGuard2; | |||
634 | auto pChartWindow(GetChartWindow()); | |||
635 | if( pChartWindow ) | |||
636 | pChartWindow->Invalidate(); | |||
637 | } | |||
638 | ||||
639 | uno::Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); | |||
640 | m_xUndoManager.set( xSuppUndo->getUndoManager(), uno::UNO_SET_THROW ); | |||
641 | ||||
642 | return true; | |||
643 | } | |||
644 | ||||
645 | uno::Reference< frame::XFrame > SAL_CALL ChartController::getFrame() | |||
646 | { | |||
647 | //provides access to owner frame of this controller | |||
648 | //return the frame containing this controller | |||
649 | ||||
650 | return m_xFrame; | |||
651 | } | |||
652 | ||||
653 | uno::Reference< frame::XModel > SAL_CALL ChartController::getModel() | |||
654 | { | |||
655 | //provides access to currently attached model | |||
656 | //returns the currently attached model | |||
657 | ||||
658 | //return nothing, if you do not have a model | |||
659 | TheModelRef aModelRef( m_aModel, m_aModelMutex); | |||
660 | if(aModelRef.is()) | |||
661 | return aModelRef->getModel(); | |||
662 | ||||
663 | return uno::Reference< frame::XModel > (); | |||
664 | } | |||
665 | ||||
666 | uno::Any SAL_CALL ChartController::getViewData() | |||
667 | { | |||
668 | //provides access to current view status | |||
669 | //set of data that can be used to restore the current view status at later time | |||
670 | // by using XController::restoreViewData() | |||
671 | ||||
672 | SolarMutexGuard aGuard; | |||
673 | if( impl_isDisposedOrSuspended() ) | |||
674 | return uno::Any(); //behave passive if already disposed or suspended //@todo? or throw an exception?? | |||
675 | ||||
676 | //-- collect current view state | |||
677 | uno::Any aRet; | |||
678 | //// @todo integrate specialized implementation | |||
679 | ||||
680 | return aRet; | |||
681 | } | |||
682 | ||||
683 | void SAL_CALL ChartController::restoreViewData( | |||
684 | const uno::Any& /* Value */ ) | |||
685 | { | |||
686 | //restores the view status using the data gotten from a previous call to XController::getViewData() | |||
687 | ||||
688 | SolarMutexGuard aGuard; | |||
689 | if( impl_isDisposedOrSuspended() ) | |||
690 | return; //behave passive if already disposed or suspended //@todo? or throw an exception?? | |||
691 | ||||
692 | //// @todo integrate specialized implementation | |||
693 | } | |||
694 | ||||
695 | sal_Bool SAL_CALL ChartController::suspend( sal_Bool bSuspend ) | |||
696 | { | |||
697 | //is called to prepare the controller for closing the view | |||
698 | //bSuspend==true: force the controller to suspend his work | |||
699 | //bSuspend==false try to reactivate the controller | |||
700 | //returns true if request was accepted and of course successfully finished, false otherwise | |||
701 | ||||
702 | //we may show dialogs here to ask the user for saving changes ... @todo? | |||
703 | ||||
704 | SolarMutexGuard aGuard; | |||
705 | if( m_aLifeTimeManager.impl_isDisposed() ) | |||
706 | return false; //behave passive if already disposed, return false because request was not accepted //@todo? correct | |||
707 | ||||
708 | if(bool(bSuspend) == m_bSuspended) | |||
709 | { | |||
710 | OSL_FAIL( "new suspend mode equals old suspend mode" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "710" ": "), "%s", "new suspend mode equals old suspend mode" ); } } while (false); | |||
711 | return true; | |||
712 | } | |||
713 | ||||
714 | //change suspend mode | |||
715 | m_bSuspended = bSuspend; | |||
716 | return true; | |||
717 | } | |||
718 | ||||
719 | void ChartController::impl_createDrawViewController() | |||
720 | { | |||
721 | SolarMutexGuard aGuard; | |||
722 | if(!m_pDrawViewWrapper) | |||
723 | { | |||
724 | if( m_pDrawModelWrapper ) | |||
725 | { | |||
726 | m_pDrawViewWrapper.reset( new DrawViewWrapper(m_pDrawModelWrapper->getSdrModel(),GetChartWindow()) ); | |||
727 | m_pDrawViewWrapper->attachParentReferenceDevice( getModel() ); | |||
728 | } | |||
729 | } | |||
730 | } | |||
731 | ||||
732 | void ChartController::impl_deleteDrawViewController() | |||
733 | { | |||
734 | if( m_pDrawViewWrapper ) | |||
735 | { | |||
736 | SolarMutexGuard aGuard; | |||
737 | if( m_pDrawViewWrapper->IsTextEdit() ) | |||
738 | this->EndTextEdit(); | |||
739 | m_pDrawViewWrapper.reset(); | |||
740 | } | |||
741 | } | |||
742 | ||||
743 | // XComponent (base of XController) | |||
744 | ||||
745 | void SAL_CALL ChartController::dispose() | |||
746 | { | |||
747 | m_bDisposed = true; | |||
748 | ||||
749 | if (getModel().is()) | |||
750 | { | |||
751 | uno::Reference<ui::XSidebar> xSidebar = getSidebarFromModel(getModel()); | |||
752 | if (sfx2::sidebar::SidebarController* pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get())) | |||
753 | { | |||
754 | sfx2::sidebar::SidebarController::unregisterSidebarForFrame(pSidebar, this); | |||
755 | } | |||
756 | } | |||
757 | mpSelectionChangeHandler->selectionChanged(css::lang::EventObject()); | |||
758 | mpSelectionChangeHandler->Disconnect(); | |||
759 | ||||
760 | try | |||
761 | { | |||
762 | //This object should release all resources and references in the | |||
763 | //easiest possible manner | |||
764 | //This object must notify all registered listeners using the method | |||
765 | //<member>XEventListener::disposing</member> | |||
766 | ||||
767 | //hold no mutex | |||
768 | if( !m_aLifeTimeManager.dispose() ) | |||
769 | return; | |||
770 | ||||
771 | // OSL_ENSURE( m_bSuspended, "dispose was called but controller is not suspended" ); | |||
772 | ||||
773 | this->stopDoubleClickWaiting(); | |||
774 | ||||
775 | //end range highlighting | |||
776 | if( m_aModel.is()) | |||
777 | { | |||
778 | uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener; | |||
779 | uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY ); | |||
780 | if( xDataReceiver.is() ) | |||
781 | xSelectionChangeListener.set( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY ); | |||
782 | if( xSelectionChangeListener.is() ) | |||
783 | { | |||
784 | uno::Reference< frame::XController > xController( this ); | |||
785 | lang::EventObject aEvent( xController ); | |||
786 | xSelectionChangeListener->disposing( aEvent ); | |||
787 | } | |||
788 | } | |||
789 | ||||
790 | //--release all resources and references | |||
791 | { | |||
792 | uno::Reference< util::XModeChangeBroadcaster > xViewBroadcaster( m_xChartView, uno::UNO_QUERY ); | |||
793 | if( xViewBroadcaster.is() ) | |||
794 | xViewBroadcaster->removeModeChangeListener(this); | |||
795 | ||||
796 | impl_invalidateAccessible(); | |||
797 | SolarMutexGuard aSolarGuard; | |||
798 | impl_deleteDrawViewController(); | |||
799 | m_pDrawModelWrapper.reset(); | |||
800 | ||||
801 | m_apDropTargetHelper.reset(); | |||
802 | ||||
803 | //the accessible view is disposed within window destructor of m_pChartWindow | |||
804 | if(m_xViewWindow.is()) | |||
805 | m_xViewWindow->dispose(); //ChartWindow is deleted via UNO due to dispose of m_xViewWindow (triggered by Framework (Controller pretends to be XWindow also)) | |||
806 | m_xChartView.clear(); | |||
807 | } | |||
808 | ||||
809 | // remove as listener to layout manager events | |||
810 | if( m_xLayoutManagerEventBroadcaster.is()) | |||
811 | { | |||
812 | m_xLayoutManagerEventBroadcaster->removeLayoutManagerEventListener( this ); | |||
813 | m_xLayoutManagerEventBroadcaster.set( nullptr ); | |||
814 | } | |||
815 | ||||
816 | m_xFrame.clear(); | |||
817 | m_xUndoManager.clear(); | |||
818 | ||||
819 | TheModelRef aModelRef( m_aModel, m_aModelMutex); | |||
820 | m_aModel = nullptr; | |||
821 | ||||
822 | if( aModelRef.is()) | |||
823 | { | |||
824 | uno::Reference< frame::XModel > xModel( aModelRef->getModel() ); | |||
825 | if(xModel.is()) | |||
826 | xModel->disconnectController( uno::Reference< frame::XController >( this )); | |||
827 | ||||
828 | aModelRef->removeListener( this ); | |||
829 | #ifdef TEST_ENABLE_MODIFY_LISTENER | |||
830 | try | |||
831 | { | |||
832 | uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aModelRef->getModel(),uno::UNO_QUERY ); | |||
833 | if( xMBroadcaster.is()) | |||
834 | xMBroadcaster->removeModifyListener( this ); | |||
835 | } | |||
836 | catch( const uno::Exception & ) | |||
837 | { | |||
838 | DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "838" ": ", "chart2" );; | |||
839 | } | |||
840 | #endif | |||
841 | aModelRef->tryTermination(); | |||
842 | } | |||
843 | ||||
844 | //// @todo integrate specialized implementation | |||
845 | //e.g. release further resources and references | |||
846 | ||||
847 | SolarMutexGuard g; | |||
848 | m_aDispatchContainer.DisposeAndClear(); | |||
849 | } | |||
850 | catch( const uno::Exception & ) | |||
851 | { | |||
852 | DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "852" ": ", "chart2" );; | |||
853 | assert(!m_xChartView.is())(static_cast <bool> (!m_xChartView.is()) ? void (0) : __assert_fail ("!m_xChartView.is()", "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" , 853, __extension__ __PRETTY_FUNCTION__)); | |||
854 | } | |||
855 | } | |||
856 | ||||
857 | void SAL_CALL ChartController::addEventListener( | |||
858 | const uno::Reference<lang::XEventListener>& xListener ) | |||
859 | { | |||
860 | SolarMutexGuard aGuard; | |||
861 | if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode? | |||
862 | return; //behave passive if already disposed or suspended | |||
863 | ||||
864 | //--add listener | |||
865 | m_aLifeTimeManager.m_aListenerContainer.addInterface( cppu::UnoType<lang::XEventListener>::get(), xListener ); | |||
866 | } | |||
867 | ||||
868 | void SAL_CALL ChartController::removeEventListener( | |||
869 | const uno::Reference<lang::XEventListener>& xListener ) | |||
870 | { | |||
871 | SolarMutexGuard aGuard; | |||
872 | if( m_aLifeTimeManager.impl_isDisposed(false) ) | |||
873 | return; //behave passive if already disposed or suspended | |||
874 | ||||
875 | //--remove listener | |||
876 | m_aLifeTimeManager.m_aListenerContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), xListener ); | |||
877 | } | |||
878 | ||||
879 | // util::XCloseListener | |||
880 | void SAL_CALL ChartController::queryClosing( | |||
881 | const lang::EventObject& rSource, | |||
882 | sal_Bool /*bGetsOwnership*/ ) | |||
883 | { | |||
884 | //do not use the m_aControllerMutex here because this call is not allowed to block | |||
885 | ||||
886 | TheModelRef aModelRef( m_aModel, m_aModelMutex); | |||
887 | ||||
888 | if( !aModelRef.is() ) | |||
889 | return; | |||
890 | ||||
891 | if( aModelRef->getModel() != rSource.Source ) | |||
892 | { | |||
893 | OSL_FAIL( "queryClosing was called on a controller from an unknown source" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "893" ": "), "%s", "queryClosing was called on a controller from an unknown source" ); } } while (false); | |||
894 | return; | |||
895 | } | |||
896 | ||||
897 | //@ todo prepare to closing model -> don't start any further hindering actions | |||
898 | } | |||
899 | ||||
900 | void SAL_CALL ChartController::notifyClosing( | |||
901 | const lang::EventObject& rSource ) | |||
902 | { | |||
903 | //Listener should deregister himself and release all references to the closing object. | |||
904 | ||||
905 | TheModelRef aModelRef( m_aModel, m_aModelMutex); | |||
906 | if( !impl_releaseThisModel( rSource.Source ) ) | |||
907 | return; | |||
908 | ||||
909 | //--stop listening to the closing model | |||
910 | aModelRef->removeListener( this ); | |||
911 | ||||
912 | // #i79087# If the model using this controller is closed, the frame is | |||
913 | // expected to be closed as well | |||
914 | Reference< util::XCloseable > xFrameCloseable( m_xFrame, uno::UNO_QUERY ); | |||
915 | if( xFrameCloseable.is()) | |||
916 | { | |||
917 | try | |||
918 | { | |||
919 | xFrameCloseable->close( false /* DeliverOwnership */ ); | |||
920 | m_xFrame.clear(); | |||
921 | } | |||
922 | catch( const util::CloseVetoException & ) | |||
923 | { | |||
924 | // closing was vetoed | |||
925 | } | |||
926 | } | |||
927 | } | |||
928 | ||||
929 | bool ChartController::impl_releaseThisModel( | |||
930 | const uno::Reference< uno::XInterface > & xModel ) | |||
931 | { | |||
932 | bool bReleaseModel = false; | |||
933 | { | |||
934 | ::osl::Guard< ::osl::Mutex > aGuard( m_aModelMutex ); | |||
935 | if( m_aModel.is() && m_aModel->getModel() == xModel ) | |||
936 | { | |||
937 | m_aModel = nullptr; | |||
938 | m_xUndoManager.clear(); | |||
939 | bReleaseModel = true; | |||
940 | } | |||
941 | } | |||
942 | if( bReleaseModel ) | |||
943 | { | |||
944 | SolarMutexGuard g; | |||
945 | m_aDispatchContainer.setModel( nullptr ); | |||
946 | } | |||
947 | return bReleaseModel; | |||
948 | } | |||
949 | ||||
950 | // util::XEventListener (base of XCloseListener) | |||
951 | void SAL_CALL ChartController::disposing( | |||
952 | const lang::EventObject& rSource ) | |||
953 | { | |||
954 | if( !impl_releaseThisModel( rSource.Source )) | |||
955 | { | |||
956 | if( rSource.Source == m_xLayoutManagerEventBroadcaster ) | |||
957 | m_xLayoutManagerEventBroadcaster.set( nullptr ); | |||
958 | } | |||
959 | } | |||
960 | ||||
961 | void SAL_CALL ChartController::layoutEvent( | |||
962 | const lang::EventObject& aSource, | |||
963 | sal_Int16 eLayoutEvent, | |||
964 | const uno::Any& /* aInfo */ ) | |||
965 | { | |||
966 | if( eLayoutEvent == frame::LayoutManagerEvents::MERGEDMENUBAR ) | |||
967 | { | |||
968 | Reference< frame::XLayoutManager > xLM( aSource.Source, uno::UNO_QUERY ); | |||
969 | if( xLM.is()) | |||
970 | { | |||
971 | xLM->createElement( "private:resource/statusbar/statusbar" ); | |||
972 | xLM->requestElement( "private:resource/statusbar/statusbar" ); | |||
973 | } | |||
974 | } | |||
975 | } | |||
976 | ||||
977 | // XDispatchProvider (required interface) | |||
978 | ||||
979 | namespace | |||
980 | { | |||
981 | ||||
982 | bool lcl_isFormatObjectCommand( const OUString& aCommand ) | |||
983 | { | |||
984 | return aCommand == "MainTitle" | |||
985 | || aCommand == "SubTitle" | |||
986 | || aCommand == "XTitle" | |||
987 | || aCommand == "YTitle" | |||
988 | || aCommand == "ZTitle" | |||
989 | || aCommand == "SecondaryXTitle" | |||
990 | || aCommand == "SecondaryYTitle" | |||
991 | || aCommand == "AllTitles" | |||
992 | || aCommand == "DiagramAxisX" | |||
993 | || aCommand == "DiagramAxisY" | |||
994 | || aCommand == "DiagramAxisZ" | |||
995 | || aCommand == "DiagramAxisA" | |||
996 | || aCommand == "DiagramAxisB" | |||
997 | || aCommand == "DiagramAxisAll" | |||
998 | || aCommand == "DiagramGridXMain" | |||
999 | || aCommand == "DiagramGridYMain" | |||
1000 | || aCommand == "DiagramGridZMain" | |||
1001 | || aCommand == "DiagramGridXHelp" | |||
1002 | || aCommand == "DiagramGridYHelp" | |||
1003 | || aCommand == "DiagramGridZHelp" | |||
1004 | || aCommand == "DiagramGridAll" | |||
1005 | ||||
1006 | || aCommand == "DiagramWall" | |||
1007 | || aCommand == "DiagramFloor" | |||
1008 | || aCommand == "DiagramArea" | |||
1009 | || aCommand == "Legend" | |||
1010 | ||||
1011 | || aCommand == "FormatWall" | |||
1012 | || aCommand == "FormatFloor" | |||
1013 | || aCommand == "FormatChartArea" | |||
1014 | || aCommand == "FormatLegend" | |||
1015 | ||||
1016 | || aCommand == "FormatTitle" | |||
1017 | || aCommand == "FormatAxis" | |||
1018 | || aCommand == "FormatDataSeries" | |||
1019 | || aCommand == "FormatDataPoint" | |||
1020 | || aCommand == "FormatDataLabels" | |||
1021 | || aCommand == "FormatDataLabel" | |||
1022 | || aCommand == "FormatXErrorBars" | |||
1023 | || aCommand == "FormatYErrorBars" | |||
1024 | || aCommand == "FormatMeanValue" | |||
1025 | || aCommand == "FormatTrendline" | |||
1026 | || aCommand == "FormatTrendlineEquation" | |||
1027 | || aCommand == "FormatStockLoss" | |||
1028 | || aCommand == "FormatStockGain" | |||
1029 | || aCommand == "FormatMajorGrid" | |||
1030 | || aCommand == "FormatMinorGrid"; | |||
1031 | } | |||
1032 | ||||
1033 | } // anonymous namespace | |||
1034 | ||||
1035 | uno::Reference<frame::XDispatch> SAL_CALL | |||
1036 | ChartController::queryDispatch( | |||
1037 | const util::URL& rURL, | |||
1038 | const OUString& rTargetFrameName, | |||
1039 | sal_Int32 /* nSearchFlags */) | |||
1040 | { | |||
1041 | SolarMutexGuard aGuard; | |||
1042 | ||||
1043 | if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() ) | |||
1044 | { | |||
1045 | if( !rTargetFrameName.isEmpty() && rTargetFrameName == "_self" ) | |||
1046 | return m_aDispatchContainer.getDispatchForURL( rURL ); | |||
1047 | } | |||
1048 | return uno::Reference< frame::XDispatch > (); | |||
1049 | } | |||
1050 | ||||
1051 | uno::Sequence<uno::Reference<frame::XDispatch > > | |||
1052 | ChartController::queryDispatches( | |||
1053 | const uno::Sequence<frame::DispatchDescriptor>& xDescripts ) | |||
1054 | { | |||
1055 | SolarMutexGuard g; | |||
1056 | ||||
1057 | if ( !m_aLifeTimeManager.impl_isDisposed() ) | |||
1058 | { | |||
1059 | return m_aDispatchContainer.getDispatchesForURLs( xDescripts ); | |||
1060 | } | |||
1061 | return uno::Sequence<uno::Reference<frame::XDispatch > > (); | |||
1062 | } | |||
1063 | ||||
1064 | // frame::XDispatch | |||
1065 | ||||
1066 | void SAL_CALL ChartController::dispatch( | |||
1067 | const util::URL& rURL, | |||
1068 | const uno::Sequence< beans::PropertyValue >& rArgs ) | |||
1069 | { | |||
1070 | OUString aCommand = rURL.Path; | |||
1071 | ||||
1072 | if(aCommand == "LOKSetTextSelection") | |||
| ||||
1073 | { | |||
1074 | if (rArgs.getLength() == 3) | |||
1075 | { | |||
1076 | sal_Int32 nType = -1; | |||
1077 | rArgs[0].Value >>= nType; | |||
1078 | sal_Int32 nX = 0; | |||
1079 | rArgs[1].Value >>= nX; | |||
1080 | sal_Int32 nY = 0; | |||
1081 | rArgs[2].Value >>= nY; | |||
1082 | executeDispatch_LOKSetTextSelection(nType, nX, nY); | |||
1083 | } | |||
1084 | } | |||
1085 | else if (aCommand == "LOKTransform") | |||
1086 | { | |||
1087 | if (rArgs[0].Name == "Action") | |||
1088 | { | |||
1089 | OUString sAction; | |||
1090 | if ((rArgs[0].Value >>= sAction) && sAction == "PieSegmentDragging") | |||
1091 | { | |||
1092 | if (rArgs[1].Name == "Offset") | |||
1093 | { | |||
1094 | sal_Int32 nOffset; | |||
1095 | if (rArgs[1].Value >>= nOffset) | |||
1096 | { | |||
1097 | this->executeDispatch_LOKPieSegmentDragging(nOffset); | |||
1098 | } | |||
1099 | } | |||
1100 | } | |||
1101 | } | |||
1102 | else | |||
1103 | { | |||
1104 | this->executeDispatch_PositionAndSize(&rArgs); | |||
1105 | } | |||
1106 | } | |||
1107 | else if(aCommand == "FillColor") | |||
1108 | { | |||
1109 | if (rArgs.getLength() > 0) | |||
1110 | { | |||
1111 | sal_uInt32 nColor; | |||
1112 | rArgs[0].Value >>= nColor; | |||
1113 | this->executeDispatch_FillColor(nColor); | |||
| ||||
1114 | } | |||
1115 | } | |||
1116 | else if(aCommand == "Paste") | |||
1117 | this->executeDispatch_Paste(); | |||
1118 | else if(aCommand == "Copy" ) | |||
1119 | this->executeDispatch_Copy(); | |||
1120 | else if(aCommand == "Cut" ) | |||
1121 | this->executeDispatch_Cut(); | |||
1122 | else if(aCommand == "DataRanges" ) | |||
1123 | this->executeDispatch_SourceData(); | |||
1124 | else if(aCommand == "Update" ) //Update Chart | |||
1125 | { | |||
1126 | ChartViewHelper::setViewToDirtyState( getModel() ); | |||
1127 | SolarMutexGuard aGuard; | |||
1128 | auto pChartWindow(GetChartWindow()); | |||
1129 | if( pChartWindow ) | |||
1130 | pChartWindow->Invalidate(); | |||
1131 | } | |||
1132 | else if(aCommand == "DiagramData" ) | |||
1133 | this->executeDispatch_EditData(); | |||
1134 | //insert objects | |||
1135 | else if( aCommand == "InsertTitles" | |||
1136 | || aCommand == "InsertMenuTitles") | |||
1137 | this->executeDispatch_InsertTitles(); | |||
1138 | else if( aCommand == "InsertMenuLegend" ) | |||
1139 | this->executeDispatch_OpenLegendDialog(); | |||
1140 | else if( aCommand == "InsertLegend" ) | |||
1141 | this->executeDispatch_InsertLegend(); | |||
1142 | else if( aCommand == "DeleteLegend" ) | |||
1143 | this->executeDispatch_DeleteLegend(); | |||
1144 | else if( aCommand == "InsertMenuDataLabels" ) | |||
1145 | this->executeDispatch_InsertMenu_DataLabels(); | |||
1146 | else if( aCommand == "InsertMenuAxes" | |||
1147 | || aCommand == "InsertRemoveAxes" ) | |||
1148 | this->executeDispatch_InsertAxes(); | |||
1149 | else if( aCommand == "InsertMenuGrids" ) | |||
1150 | this->executeDispatch_InsertGrid(); | |||
1151 | else if( aCommand == "InsertMenuTrendlines" ) | |||
1152 | this->executeDispatch_InsertMenu_Trendlines(); | |||
1153 | else if( aCommand == "InsertMenuMeanValues" ) | |||
1154 | this->executeDispatch_InsertMenu_MeanValues(); | |||
1155 | else if( aCommand == "InsertMenuXErrorBars" ) | |||
1156 | this->executeDispatch_InsertErrorBars(false); | |||
1157 | else if( aCommand == "InsertMenuYErrorBars" ) | |||
1158 | this->executeDispatch_InsertErrorBars(true); | |||
1159 | else if( aCommand == "InsertSymbol" ) | |||
1160 | this->executeDispatch_InsertSpecialCharacter(); | |||
1161 | else if( aCommand == "InsertTrendline" ) | |||
1162 | this->executeDispatch_InsertTrendline(); | |||
1163 | else if( aCommand == "DeleteTrendline" ) | |||
1164 | this->executeDispatch_DeleteTrendline(); | |||
1165 | else if( aCommand == "InsertMeanValue" ) | |||
1166 | this->executeDispatch_InsertMeanValue(); | |||
1167 | else if( aCommand == "DeleteMeanValue" ) | |||
1168 | this->executeDispatch_DeleteMeanValue(); | |||
1169 | else if( aCommand == "InsertXErrorBars" ) | |||
1170 | this->executeDispatch_InsertErrorBars(false); | |||
1171 | else if( aCommand == "InsertYErrorBars" ) | |||
1172 | this->executeDispatch_InsertErrorBars(true); | |||
1173 | else if( aCommand == "DeleteXErrorBars" ) | |||
1174 | this->executeDispatch_DeleteErrorBars(false); | |||
1175 | else if( aCommand == "DeleteYErrorBars" ) | |||
1176 | this->executeDispatch_DeleteErrorBars(true); | |||
1177 | else if( aCommand == "InsertTrendlineEquation" ) | |||
1178 | this->executeDispatch_InsertTrendlineEquation(); | |||
1179 | else if( aCommand == "DeleteTrendlineEquation" ) | |||
1180 | this->executeDispatch_DeleteTrendlineEquation(); | |||
1181 | else if( aCommand == "InsertTrendlineEquationAndR2" ) | |||
1182 | this->executeDispatch_InsertTrendlineEquation( true ); | |||
1183 | else if( aCommand == "InsertR2Value" ) | |||
1184 | this->executeDispatch_InsertR2Value(); | |||
1185 | else if( aCommand == "DeleteR2Value") | |||
1186 | this->executeDispatch_DeleteR2Value(); | |||
1187 | else if( aCommand == "InsertDataLabels" ) | |||
1188 | this->executeDispatch_InsertDataLabels(); | |||
1189 | else if( aCommand == "InsertDataLabel" ) | |||
1190 | this->executeDispatch_InsertDataLabel(); | |||
1191 | else if( aCommand == "DeleteDataLabels") | |||
1192 | this->executeDispatch_DeleteDataLabels(); | |||
1193 | else if( aCommand == "DeleteDataLabel" ) | |||
1194 | this->executeDispatch_DeleteDataLabel(); | |||
1195 | else if( aCommand == "ResetAllDataPoints" ) | |||
1196 | this->executeDispatch_ResetAllDataPoints(); | |||
1197 | else if( aCommand == "ResetDataPoint" ) | |||
1198 | this->executeDispatch_ResetDataPoint(); | |||
1199 | else if( aCommand == "InsertAxis" ) | |||
1200 | this->executeDispatch_InsertAxis(); | |||
1201 | else if( aCommand == "InsertMajorGrid" ) | |||
1202 | this->executeDispatch_InsertMajorGrid(); | |||
1203 | else if( aCommand == "InsertMinorGrid" ) | |||
1204 | this->executeDispatch_InsertMinorGrid(); | |||
1205 | else if( aCommand == "InsertAxisTitle" ) | |||
1206 | this->executeDispatch_InsertAxisTitle(); | |||
1207 | else if( aCommand == "DeleteAxis" ) | |||
1208 | this->executeDispatch_DeleteAxis(); | |||
1209 | else if( aCommand == "DeleteMajorGrid") | |||
1210 | this->executeDispatch_DeleteMajorGrid(); | |||
1211 | else if( aCommand == "DeleteMinorGrid" ) | |||
1212 | this->executeDispatch_DeleteMinorGrid(); | |||
1213 | //format objects | |||
1214 | else if( aCommand == "FormatSelection" ) | |||
1215 | this->executeDispatch_ObjectProperties(); | |||
1216 | else if( aCommand == "TransformDialog" ) | |||
1217 | { | |||
1218 | if ( isShapeContext() ) | |||
1219 | { | |||
1220 | this->impl_ShapeControllerDispatch( rURL, rArgs ); | |||
1221 | } | |||
1222 | else | |||
1223 | { | |||
1224 | this->executeDispatch_PositionAndSize(); | |||
1225 | } | |||
1226 | } | |||
1227 | else if( lcl_isFormatObjectCommand(aCommand) ) | |||
1228 | this->executeDispatch_FormatObject(rURL.Path); | |||
1229 | //more format | |||
1230 | else if( aCommand == "DiagramType" ) | |||
1231 | this->executeDispatch_ChartType(); | |||
1232 | else if( aCommand == "View3D" ) | |||
1233 | this->executeDispatch_View3D(); | |||
1234 | else if ( aCommand == "Forward" ) | |||
1235 | { | |||
1236 | if ( isShapeContext() ) | |||
1237 | { | |||
1238 | this->impl_ShapeControllerDispatch( rURL, rArgs ); | |||
1239 | } | |||
1240 | else | |||
1241 | { | |||
1242 | this->executeDispatch_MoveSeries( true ); | |||
1243 | } | |||
1244 | } | |||
1245 | else if ( aCommand == "Backward" ) | |||
1246 | { | |||
1247 | if ( isShapeContext() ) | |||
1248 | { | |||
1249 | this->impl_ShapeControllerDispatch( rURL, rArgs ); | |||
1250 | } | |||
1251 | else | |||
1252 | { | |||
1253 | this->executeDispatch_MoveSeries( false ); | |||
1254 | } | |||
1255 | } | |||
1256 | else if( aCommand == "NewArrangement") | |||
1257 | this->executeDispatch_NewArrangement(); | |||
1258 | else if( aCommand == "ToggleLegend" ) | |||
1259 | this->executeDispatch_ToggleLegend(); | |||
1260 | else if( aCommand == "ToggleGridHorizontal" ) | |||
1261 | this->executeDispatch_ToggleGridHorizontal(); | |||
1262 | else if( aCommand == "ToggleGridVertical" ) | |||
1263 | this->executeDispatch_ToggleGridVertical(); | |||
1264 | else if( aCommand == "ScaleText" ) | |||
1265 | this->executeDispatch_ScaleText(); | |||
1266 | else if( aCommand == "StatusBarVisible" ) | |||
1267 | { | |||
1268 | // workaround: this should not be necessary. | |||
1269 | uno::Reference< beans::XPropertySet > xPropSet( m_xFrame, uno::UNO_QUERY ); | |||
1270 | if( xPropSet.is() ) | |||
1271 | { | |||
1272 | uno::Reference< css::frame::XLayoutManager > xLayoutManager; | |||
1273 | xPropSet->getPropertyValue( "LayoutManager" ) >>= xLayoutManager; | |||
1274 | if ( xLayoutManager.is() ) | |||
1275 | { | |||
1276 | bool bIsVisible( xLayoutManager->isElementVisible( "private:resource/statusbar/statusbar" )); | |||
1277 | if( bIsVisible ) | |||
1278 | { | |||
1279 | xLayoutManager->hideElement( "private:resource/statusbar/statusbar" ); | |||
1280 | xLayoutManager->destroyElement( "private:resource/statusbar/statusbar" ); | |||
1281 | } | |||
1282 | else | |||
1283 | { | |||
1284 | xLayoutManager->createElement( "private:resource/statusbar/statusbar" ); | |||
1285 | xLayoutManager->showElement( "private:resource/statusbar/statusbar" ); | |||
1286 | } | |||
1287 | // @todo: update menu state (checkmark next to "Statusbar"). | |||
1288 | } | |||
1289 | } | |||
1290 | } | |||
1291 | } | |||
1292 | ||||
1293 | void SAL_CALL ChartController::addStatusListener( | |||
1294 | const uno::Reference<frame::XStatusListener >& /* xControl */, | |||
1295 | const util::URL& /* aURL */ ) | |||
1296 | { | |||
1297 | //@todo | |||
1298 | } | |||
1299 | ||||
1300 | void SAL_CALL ChartController::removeStatusListener( | |||
1301 | const uno::Reference<frame::XStatusListener >& /* xControl */, | |||
1302 | const util::URL& /* aURL */ ) | |||
1303 | { | |||
1304 | //@todo | |||
1305 | } | |||
1306 | ||||
1307 | // XContextMenuInterception (optional interface) | |||
1308 | void SAL_CALL ChartController::registerContextMenuInterceptor( | |||
1309 | const uno::Reference< ui::XContextMenuInterceptor >& /* xInterceptor */) | |||
1310 | { | |||
1311 | //@todo | |||
1312 | } | |||
1313 | ||||
1314 | void SAL_CALL ChartController::releaseContextMenuInterceptor( | |||
1315 | const uno::Reference< ui::XContextMenuInterceptor > & /* xInterceptor */) | |||
1316 | { | |||
1317 | //@todo | |||
1318 | } | |||
1319 | ||||
1320 | // ____ XEmbeddedClient ____ | |||
1321 | // implementation see: ChartController_EditData.cxx | |||
1322 | ||||
1323 | void ChartController::executeDispatch_ChartType() | |||
1324 | { | |||
1325 | UndoLiveUpdateGuard aUndoGuard( | |||
1326 | SchResId( STR_ACTION_EDIT_CHARTTYPEreinterpret_cast<char const *>("STR_ACTION_EDIT_CHARTTYPE" "\004" u8"Edit chart type") ), m_xUndoManager ); | |||
1327 | ||||
1328 | SolarMutexGuard aSolarGuard; | |||
1329 | //prepare and open dialog | |||
1330 | ChartTypeDialog aDlg(GetChartFrame(), getModel()); | |||
1331 | if (aDlg.run() == RET_OK) | |||
1332 | { | |||
1333 | impl_adaptDataSeriesAutoResize(); | |||
1334 | aUndoGuard.commit(); | |||
1335 | } | |||
1336 | } | |||
1337 | ||||
1338 | void ChartController::executeDispatch_SourceData() | |||
1339 | { | |||
1340 | //convert properties to ItemSet | |||
1341 | uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); | |||
1342 | OSL_ENSURE( xChartDoc.is(), "Invalid XChartDocument" )do { if (true && (!(xChartDoc.is()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1342" ": "), "%s", "Invalid XChartDocument"); } } while (false); | |||
1343 | if( !xChartDoc.is() ) | |||
1344 | return; | |||
1345 | ||||
1346 | // If there is a data table we should ask user if we really want to destroy it | |||
1347 | // and switch to data ranges. | |||
1348 | ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartDoc); | |||
1349 | if ( rModel.hasInternalDataProvider() ) | |||
1350 | { | |||
1351 | // Check if we will able to create data provider later | |||
1352 | css::uno::Reference< com::sun::star::chart2::XDataProviderAccess > xCreatorDoc( | |||
1353 | rModel.getParent(), uno::UNO_QUERY); | |||
1354 | if (!xCreatorDoc.is()) | |||
1355 | return; | |||
1356 | ||||
1357 | SolarMutexGuard aSolarGuard; | |||
1358 | ||||
1359 | std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetChartFrame(), | |||
1360 | VclMessageType::Question, VclButtonsType::YesNo, SchResId(STR_DLG_REMOVE_DATA_TABLEreinterpret_cast<char const *>("STR_DLG_REMOVE_DATA_TABLE" "\004" u8"This chart currently contains an internal data table. Do you want to proceed, deleting the internal data table, and set a new data range?" )))); | |||
1361 | // If "No" then just return | |||
1362 | if (xQueryBox->run() == RET_NO) | |||
1363 | return; | |||
1364 | ||||
1365 | // Remove data table | |||
1366 | rModel.removeDataProviders(); | |||
1367 | ||||
1368 | // Ask parent document to create new data provider | |||
1369 | ||||
1370 | uno::Reference< data::XDataProvider > xDataProvider = xCreatorDoc->createDataProvider(); | |||
1371 | SAL_WARN_IF( !xDataProvider.is(), "chart2.main", "Data provider was not created" )do { if (true && (!xDataProvider.is())) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "chart2.main")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "Data provider was not created" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main" ), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1371" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Data provider was not created"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Data provider was not created"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1371" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Data provider was not created") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1371" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Data provider was not created"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Data provider was not created"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("chart2.main"), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1371" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1372 | if (xDataProvider.is()) | |||
1373 | { | |||
1374 | rModel.attachDataProvider(xDataProvider); | |||
1375 | } | |||
1376 | } | |||
1377 | ||||
1378 | UndoLiveUpdateGuard aUndoGuard( | |||
1379 | SchResId(STR_ACTION_EDIT_DATA_RANGESreinterpret_cast<char const *>("STR_ACTION_EDIT_DATA_RANGES" "\004" u8"Edit data ranges")), m_xUndoManager); | |||
1380 | ||||
1381 | SolarMutexGuard aSolarGuard; | |||
1382 | ::chart::DataSourceDialog aDlg(GetChartFrame(), xChartDoc, m_xCC); | |||
1383 | if (aDlg.run() == RET_OK) | |||
1384 | { | |||
1385 | impl_adaptDataSeriesAutoResize(); | |||
1386 | aUndoGuard.commit(); | |||
1387 | } | |||
1388 | } | |||
1389 | ||||
1390 | void ChartController::executeDispatch_MoveSeries( bool bForward ) | |||
1391 | { | |||
1392 | ControllerLockGuardUNO aCLGuard( getModel() ); | |||
1393 | ||||
1394 | //get selected series | |||
1395 | OUString aObjectCID(m_aSelection.getSelectedCID()); | |||
1396 | uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legend entries and labels? | |||
1397 | aObjectCID, getModel() ) ); | |||
1398 | ||||
1399 | UndoGuardWithSelection aUndoGuard( | |||
1400 | ActionDescriptionProvider::createDescription( | |||
1401 | (bForward ? ActionDescriptionProvider::ActionType::MoveToTop : ActionDescriptionProvider::ActionType::MoveToBottom), | |||
1402 | SchResId(STR_OBJECT_DATASERIESreinterpret_cast<char const *>("STR_OBJECT_DATASERIES" "\004" u8"Data Series"))), | |||
1403 | m_xUndoManager ); | |||
1404 | ||||
1405 | bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward ); | |||
1406 | if( bChanged ) | |||
1407 | { | |||
1408 | m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) ); | |||
1409 | aUndoGuard.commit(); | |||
1410 | } | |||
1411 | } | |||
1412 | ||||
1413 | // ____ XMultiServiceFactory ____ | |||
1414 | uno::Reference< uno::XInterface > SAL_CALL | |||
1415 | ChartController::createInstance( const OUString& aServiceSpecifier ) | |||
1416 | { | |||
1417 | uno::Reference< uno::XInterface > xResult; | |||
1418 | ||||
1419 | if( aServiceSpecifier == CHART_ACCESSIBLE_TEXT_SERVICE_NAME"com.sun.star.accessibility.AccessibleTextComponent" ) | |||
1420 | xResult.set( impl_createAccessibleTextContext()); | |||
1421 | return xResult; | |||
1422 | } | |||
1423 | ||||
1424 | uno::Reference< uno::XInterface > SAL_CALL | |||
1425 | ChartController::createInstanceWithArguments( | |||
1426 | const OUString& ServiceSpecifier, | |||
1427 | const uno::Sequence< uno::Any >& /* Arguments */ ) | |||
1428 | { | |||
1429 | // ignore Arguments | |||
1430 | return createInstance( ServiceSpecifier ); | |||
1431 | } | |||
1432 | ||||
1433 | uno::Sequence< OUString > SAL_CALL | |||
1434 | ChartController::getAvailableServiceNames() | |||
1435 | { | |||
1436 | uno::Sequence< OUString > aServiceNames { CHART_ACCESSIBLE_TEXT_SERVICE_NAME"com.sun.star.accessibility.AccessibleTextComponent" }; | |||
1437 | return aServiceNames; | |||
1438 | } | |||
1439 | ||||
1440 | // ____ XModifyListener ____ | |||
1441 | void SAL_CALL ChartController::modified( | |||
1442 | const lang::EventObject& /* aEvent */ ) | |||
1443 | { | |||
1444 | // the source can also be a subobject of the ChartModel | |||
1445 | // @todo: change the source in ChartModel to always be the model itself ? | |||
1446 | //todo? update menu states ? | |||
1447 | } | |||
1448 | ||||
1449 | void ChartController::NotifyUndoActionHdl( std::unique_ptr<SdrUndoAction> pUndoAction ) | |||
1450 | { | |||
1451 | ENSURE_OR_RETURN_VOID( pUndoAction, "invalid Undo action" )if( !(pUndoAction) ) { do { if (true && (!(pUndoAction ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1451" ": "), "%s", "invalid Undo action"); } } while (false ); return; }; | |||
1452 | ||||
1453 | OUString aObjectCID = m_aSelection.getSelectedCID(); | |||
1454 | if ( !aObjectCID.isEmpty() ) | |||
1455 | return; | |||
1456 | ||||
1457 | try | |||
1458 | { | |||
1459 | const Reference< document::XUndoManagerSupplier > xSuppUndo( getModel(), uno::UNO_QUERY_THROW ); | |||
1460 | const Reference< document::XUndoManager > xUndoManager( xSuppUndo->getUndoManager(), uno::UNO_SET_THROW ); | |||
1461 | const Reference< document::XUndoAction > xAction( new impl::ShapeUndoElement( std::move(pUndoAction) ) ); | |||
1462 | xUndoManager->addUndoAction( xAction ); | |||
1463 | } | |||
1464 | catch( const uno::Exception& ) | |||
1465 | { | |||
1466 | DBG_UNHANDLED_EXCEPTION("chart2")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/chart2/source/controller/main/ChartController.cxx" ":" "1466" ": ", "chart2" );; | |||
1467 | } | |||
1468 | } | |||
1469 | ||||
1470 | DrawModelWrapper* ChartController::GetDrawModelWrapper() | |||
1471 | { | |||
1472 | if( !m_pDrawModelWrapper ) | |||
1473 | { | |||
1474 | ExplicitValueProvider* pProvider = comphelper::getUnoTunnelImplementation<ExplicitValueProvider>( m_xChartView ); | |||
1475 | if( pProvider ) | |||
1476 | m_pDrawModelWrapper = pProvider->getDrawModelWrapper(); | |||
1477 | if ( m_pDrawModelWrapper ) | |||
1478 | { | |||
1479 | m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( | |||
1480 | std::bind(&ChartController::NotifyUndoActionHdl, this, std::placeholders::_1) ); | |||
1481 | } | |||
1482 | } | |||
1483 | return m_pDrawModelWrapper.get(); | |||
1484 | } | |||
1485 | ||||
1486 | DrawViewWrapper* ChartController::GetDrawViewWrapper() | |||
1487 | { | |||
1488 | if ( !m_pDrawViewWrapper ) | |||
1489 | { | |||
1490 | impl_createDrawViewController(); | |||
1491 | } | |||
1492 | return m_pDrawViewWrapper.get(); | |||
1493 | } | |||
1494 | ||||
1495 | ||||
1496 | VclPtr<ChartWindow> ChartController::GetChartWindow() const | |||
1497 | { | |||
1498 | // clients getting the naked VCL Window from UNO should always have the | |||
1499 | // solar mutex (and keep it over the lifetime of this ptr), as VCL might | |||
1500 | // might deinit otherwise | |||
1501 | DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false); | |||
1502 | if(!m_xViewWindow.is()) | |||
1503 | return nullptr; | |||
1504 | return dynamic_cast<ChartWindow*>(VCLUnoHelper::GetWindow(m_xViewWindow).get()); | |||
1505 | } | |||
1506 | ||||
1507 | weld::Window* ChartController::GetChartFrame() | |||
1508 | { | |||
1509 | // clients getting the naked VCL Window from UNO should always have the | |||
1510 | // solar mutex (and keep it over the lifetime of this ptr), as VCL might | |||
1511 | // might deinit otherwise | |||
1512 | DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false); | |||
1513 | return Application::GetFrameWeld(m_xViewWindow); | |||
1514 | } | |||
1515 | ||||
1516 | bool ChartController::isAdditionalShapeSelected() const | |||
1517 | { | |||
1518 | return m_aSelection.isAdditionalShapeSelected(); | |||
1519 | } | |||
1520 | ||||
1521 | void ChartController::SetAndApplySelection(const Reference<drawing::XShape>& rxShape) | |||
1522 | { | |||
1523 | if(rxShape.is()) | |||
1524 | { | |||
1525 | m_aSelection.setSelection(rxShape); | |||
1526 | m_aSelection.applySelection(GetDrawViewWrapper()); | |||
1527 | } | |||
1528 | } | |||
1529 | ||||
1530 | ||||
1531 | ||||
1532 | uno::Reference< XAccessible > ChartController::CreateAccessible() | |||
1533 | { | |||
1534 | uno::Reference< XAccessible > xResult = new AccessibleChartView( GetDrawViewWrapper() ); | |||
1535 | impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) ); | |||
1536 | return xResult; | |||
1537 | } | |||
1538 | ||||
1539 | void ChartController::impl_invalidateAccessible() | |||
1540 | { | |||
1541 | SolarMutexGuard aGuard; | |||
1542 | auto pChartWindow(GetChartWindow()); | |||
1543 | if( pChartWindow ) | |||
1544 | { | |||
1545 | Reference< lang::XInitialization > xInit( pChartWindow->GetAccessible(false), uno::UNO_QUERY ); | |||
1546 | if(xInit.is()) | |||
1547 | { | |||
1548 | uno::Sequence< uno::Any > aArguments(3);//empty arguments -> invalid accessible | |||
1549 | xInit->initialize(aArguments); | |||
1550 | } | |||
1551 | } | |||
1552 | } | |||
1553 | void ChartController::impl_initializeAccessible() | |||
1554 | { | |||
1555 | SolarMutexGuard aGuard; | |||
1556 | auto pChartWindow(GetChartWindow()); | |||
1557 | if( pChartWindow ) | |||
1558 | this->impl_initializeAccessible( Reference< lang::XInitialization >( pChartWindow->GetAccessible(false), uno::UNO_QUERY ) ); | |||
1559 | } | |||
1560 | void ChartController::impl_initializeAccessible( const uno::Reference< lang::XInitialization >& xInit ) | |||
1561 | { | |||
1562 | if(!xInit.is()) | |||
1563 | return; | |||
1564 | ||||
1565 | uno::Sequence< uno::Any > aArguments(5); | |||
1566 | aArguments[0] <<= uno::Reference<view::XSelectionSupplier>(this); | |||
1567 | aArguments[1] <<= getModel(); | |||
1568 | aArguments[2] <<= m_xChartView; | |||
1569 | uno::Reference< XAccessible > xParent; | |||
1570 | { | |||
1571 | SolarMutexGuard aGuard; | |||
1572 | auto pChartWindow(GetChartWindow()); | |||
1573 | if( pChartWindow ) | |||
1574 | { | |||
1575 | vcl::Window* pParentWin( pChartWindow->GetAccessibleParentWindow()); | |||
1576 | if( pParentWin ) | |||
1577 | xParent.set( pParentWin->GetAccessible()); | |||
1578 | } | |||
1579 | } | |||
1580 | aArguments[3] <<= xParent; | |||
1581 | aArguments[4] <<= m_xViewWindow; | |||
1582 | ||||
1583 | xInit->initialize(aArguments); | |||
1584 | } | |||
1585 | ||||
1586 | const o3tl::sorted_vector< OUString >& ChartController::impl_getAvailableCommands() | |||
1587 | { | |||
1588 | static const o3tl::sorted_vector< OUString > s_AvailableCommands { | |||
1589 | // commands for container forward | |||
1590 | "AddDirect", "NewDoc", "Open", | |||
1591 | "Save", "SaveAs", "SendMail", | |||
1592 | "EditDoc", "ExportDirectToPDF", "PrintDefault", | |||
1593 | ||||
1594 | // own commands | |||
1595 | "Cut", "Copy", "Paste", | |||
1596 | "DataRanges", "DiagramData", | |||
1597 | // insert objects | |||
1598 | "InsertMenuTitles", "InsertTitles", | |||
1599 | "InsertMenuLegend", "InsertLegend", "DeleteLegend", | |||
1600 | "InsertMenuDataLabels", | |||
1601 | "InsertMenuAxes", "InsertRemoveAxes", "InsertMenuGrids", | |||
1602 | "InsertSymbol", | |||
1603 | "InsertTrendlineEquation", "InsertTrendlineEquationAndR2", | |||
1604 | "InsertR2Value", "DeleteR2Value", | |||
1605 | "InsertMenuTrendlines", "InsertTrendline", | |||
1606 | "InsertMenuMeanValues", "InsertMeanValue", | |||
1607 | "InsertMenuXErrorBars", "InsertXErrorBars", | |||
1608 | "InsertMenuYErrorBars", "InsertYErrorBars", | |||
1609 | "InsertDataLabels", "InsertDataLabel", | |||
1610 | "DeleteTrendline", "DeleteMeanValue", "DeleteTrendlineEquation", | |||
1611 | "DeleteXErrorBars", "DeleteYErrorBars", | |||
1612 | "DeleteDataLabels", "DeleteDataLabel", | |||
1613 | //format objects | |||
1614 | "FormatSelection", "TransformDialog", | |||
1615 | "DiagramType", "View3D", | |||
1616 | "Forward", "Backward", | |||
1617 | "MainTitle", "SubTitle", | |||
1618 | "XTitle", "YTitle", "ZTitle", | |||
1619 | "SecondaryXTitle", "SecondaryYTitle", | |||
1620 | "AllTitles", "Legend", | |||
1621 | "DiagramAxisX", "DiagramAxisY", "DiagramAxisZ", | |||
1622 | "DiagramAxisA", "DiagramAxisB", "DiagramAxisAll", | |||
1623 | "DiagramGridXMain", "DiagramGridYMain", "DiagramGridZMain", | |||
1624 | "DiagramGridXHelp", "DiagramGridYHelp", "DiagramGridZHelp", | |||
1625 | "DiagramGridAll", | |||
1626 | "DiagramWall", "DiagramFloor", "DiagramArea", | |||
1627 | ||||
1628 | //context menu - format objects entries | |||
1629 | "FormatWall", "FormatFloor", "FormatChartArea", | |||
1630 | "FormatLegend", | |||
1631 | ||||
1632 | "FormatAxis", "FormatTitle", | |||
1633 | "FormatDataSeries", "FormatDataPoint", | |||
1634 | "ResetAllDataPoints", "ResetDataPoint", | |||
1635 | "FormatDataLabels", "FormatDataLabel", | |||
1636 | "FormatMeanValue", "FormatTrendline", "FormatTrendlineEquation", | |||
1637 | "FormatXErrorBars", "FormatYErrorBars", | |||
1638 | "FormatStockLoss", "FormatStockGain", | |||
1639 | ||||
1640 | "FormatMajorGrid", "InsertMajorGrid", "DeleteMajorGrid", | |||
1641 | "FormatMinorGrid", "InsertMinorGrid", "DeleteMinorGrid", | |||
1642 | "InsertAxis", "DeleteAxis", "InsertAxisTitle", | |||
1643 | ||||
1644 | // toolbar commands | |||
1645 | "ToggleGridHorizontal", "ToggleGridVertical", "ToggleLegend", "ScaleText", | |||
1646 | "NewArrangement", "Update", | |||
1647 | "DefaultColors", "BarWidth", "NumberOfLines", | |||
1648 | "ArrangeRow", | |||
1649 | "StatusBarVisible", | |||
1650 | "ChartElementSelector"}; | |||
1651 | return s_AvailableCommands; | |||
1652 | } | |||
1653 | ||||
1654 | ViewElementListProvider ChartController::getViewElementListProvider() | |||
1655 | { | |||
1656 | return ViewElementListProvider(m_pDrawModelWrapper.get()); | |||
1657 | } | |||
1658 | ||||
1659 | } //namespace chart | |||
1660 | ||||
1661 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface * | |||
1662 | com_sun_star_comp_chart2_ChartController_get_implementation(css::uno::XComponentContext *context, | |||
1663 | css::uno::Sequence<css::uno::Any> const &) | |||
1664 | { | |||
1665 | return cppu::acquire(new chart::ChartController(context)); | |||
1666 | } | |||
1667 | ||||
1668 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_RTL_USTRING_HXX |
21 | #define INCLUDED_RTL_USTRING_HXX |
22 | |
23 | #include "sal/config.h" |
24 | |
25 | #include <cassert> |
26 | #include <cstddef> |
27 | #include <cstdlib> |
28 | #include <limits> |
29 | #include <new> |
30 | #include <ostream> |
31 | #include <utility> |
32 | |
33 | #if defined LIBO_INTERNAL_ONLY1 |
34 | #include <string_view> |
35 | #include <type_traits> |
36 | #endif |
37 | |
38 | #include "rtl/ustring.h" |
39 | #include "rtl/string.hxx" |
40 | #include "rtl/stringutils.hxx" |
41 | #include "rtl/textenc.h" |
42 | |
43 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
44 | #include "config_global.h" |
45 | #include "rtl/stringconcat.hxx" |
46 | #endif |
47 | |
48 | #ifdef RTL_STRING_UNITTEST |
49 | extern bool rtl_string_unittest_invalid_conversion; |
50 | #endif |
51 | |
52 | // The unittest uses slightly different code to help check that the proper |
53 | // calls are made. The class is put into a different namespace to make |
54 | // sure the compiler generates a different (if generating also non-inline) |
55 | // copy of the function and does not merge them together. The class |
56 | // is "brought" into the proper rtl namespace by a typedef below. |
57 | #ifdef RTL_STRING_UNITTEST |
58 | #define rtl rtlunittest |
59 | #endif |
60 | |
61 | namespace rtl |
62 | { |
63 | |
64 | class OUStringBuffer; |
65 | |
66 | #ifdef RTL_STRING_UNITTEST |
67 | #undef rtl |
68 | #endif |
69 | |
70 | #if defined LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
71 | /// @cond INTERNAL |
72 | |
73 | /** |
74 | A wrapper dressing a string literal as a static-refcount rtl_uString. |
75 | |
76 | This class is not part of public API and is meant to be used only in LibreOffice code. |
77 | @since LibreOffice 4.0 |
78 | */ |
79 | template<std::size_t N> class SAL_WARN_UNUSED__attribute__((warn_unused)) OUStringLiteral { |
80 | static_assert(N != 0); |
81 | static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long"); |
82 | |
83 | public: |
84 | #if HAVE_CPP_CONSTEVAL0 |
85 | consteval |
86 | #else |
87 | constexpr |
88 | #endif |
89 | OUStringLiteral(char16_t const (&literal)[N]) { |
90 | assertLayout(); |
91 | assert(literal[N - 1] == '\0')(static_cast <bool> (literal[N - 1] == '\0') ? void (0) : __assert_fail ("literal[N - 1] == '\\0'", "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 91, __extension__ __PRETTY_FUNCTION__)); |
92 | //TODO: Use C++20 constexpr std::copy_n (P0202R3): |
93 | for (std::size_t i = 0; i != N; ++i) { |
94 | buffer[i] = literal[i]; |
95 | } |
96 | } |
97 | |
98 | constexpr sal_Int32 getLength() const { return length; } |
99 | |
100 | constexpr sal_Unicode const * getStr() const SAL_RETURNS_NONNULL__attribute__((returns_nonnull)) { return buffer; } |
101 | |
102 | constexpr operator std::u16string_view() const { return {buffer, sal_uInt32(length)}; } |
103 | |
104 | private: |
105 | static constexpr void assertLayout() { |
106 | // These static_asserts verifying the layout compatibility with rtl_uString cannot be class |
107 | // member declarations, as offsetof requires a complete type, so defer them to here: |
108 | static_assert(offsetof(OUStringLiteral, refCount)__builtin_offsetof(OUStringLiteral, refCount) == offsetof(rtl_uString, refCount)__builtin_offsetof(rtl_uString, refCount)); |
109 | static_assert(std::is_same_v<decltype(refCount), decltype(rtl_uString::refCount)>); |
110 | static_assert(offsetof(OUStringLiteral, length)__builtin_offsetof(OUStringLiteral, length) == offsetof(rtl_uString, length)__builtin_offsetof(rtl_uString, length)); |
111 | static_assert(std::is_same_v<decltype(length), decltype(rtl_uString::length)>); |
112 | static_assert(offsetof(OUStringLiteral, buffer)__builtin_offsetof(OUStringLiteral, buffer) == offsetof(rtl_uString, buffer)__builtin_offsetof(rtl_uString, buffer)); |
113 | static_assert( |
114 | std::is_same_v< |
115 | std::remove_extent_t<decltype(buffer)>, |
116 | std::remove_extent_t<decltype(rtl_uString::buffer)>>); |
117 | } |
118 | |
119 | // Same layout as rtl_uString (include/rtl/ustring.h): |
120 | oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx) |
121 | sal_Int32 length = N - 1; |
122 | sal_Unicode buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) |
123 | }; |
124 | |
125 | #if defined RTL_STRING_UNITTEST |
126 | namespace libreoffice_internal { |
127 | template<std::size_t N> struct ExceptConstCharArrayDetector<OUStringLiteral<N>> {}; |
128 | template<std::size_t N> struct ExceptCharArrayDetector<OUStringLiteral<N>> {}; |
129 | } |
130 | #endif |
131 | |
132 | /// @endcond |
133 | #endif |
134 | |
135 | /* ======================================================================= */ |
136 | |
137 | /** |
138 | This String class provides base functionality for C++ like Unicode |
139 | character array handling. The advantage of this class is that it |
140 | handles all the memory management for you - and it does it |
141 | more efficiently. If you assign a string to another string, the |
142 | data of both strings are shared (without any copy operation or |
143 | memory allocation) as long as you do not change the string. This class |
144 | also stores the length of the string, so that many operations are |
145 | faster than the C-str-functions. |
146 | |
147 | This class provides only readonly string handling. So you could create |
148 | a string and you could only query the content from this string. |
149 | It provides also functionality to change the string, but this results |
150 | in every case in a new string instance (in the most cases with a |
151 | memory allocation). You don't have functionality to change the |
152 | content of the string. If you want to change the string content, then |
153 | you should use the OStringBuffer class, which provides these |
154 | functionalities and avoids too much memory allocation. |
155 | |
156 | The design of this class is similar to the string classes in Java so |
157 | less people should have understanding problems when they use this class. |
158 | */ |
159 | |
160 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) OUString |
161 | { |
162 | public: |
163 | /// @cond INTERNAL |
164 | rtl_uString * pData; |
165 | /// @endcond |
166 | |
167 | /** |
168 | New string containing no characters. |
169 | */ |
170 | OUString() |
171 | { |
172 | pData = NULL__null; |
173 | rtl_uString_new( &pData ); |
174 | } |
175 | |
176 | /** |
177 | New string from OUString. |
178 | |
179 | @param str an OUString. |
180 | */ |
181 | OUString( const OUString & str ) |
182 | { |
183 | pData = str.pData; |
184 | rtl_uString_acquire( pData ); |
185 | } |
186 | |
187 | #if defined LIBO_INTERNAL_ONLY1 |
188 | /** |
189 | Move constructor. |
190 | |
191 | @param str an OUString. |
192 | @since LibreOffice 5.2 |
193 | */ |
194 | OUString( OUString && str ) noexcept |
195 | { |
196 | pData = str.pData; |
197 | str.pData = nullptr; |
198 | rtl_uString_new( &str.pData ); |
199 | } |
200 | #endif |
201 | |
202 | /** |
203 | New string from OUString data. |
204 | |
205 | @param str an OUString data. |
206 | */ |
207 | OUString( rtl_uString * str ) |
208 | { |
209 | pData = str; |
210 | rtl_uString_acquire( pData ); |
211 | } |
212 | |
213 | /** New OUString from OUString data without acquiring it. Takeover of ownership. |
214 | |
215 | The SAL_NO_ACQUIRE dummy parameter is only there to distinguish this |
216 | from other constructors. |
217 | |
218 | @param str |
219 | OUString data |
220 | */ |
221 | OUString( rtl_uString * str, __sal_NoAcquire ) |
222 | { pData = str; } |
223 | |
224 | /** |
225 | New string from a single Unicode character. |
226 | |
227 | @param value a Unicode character. |
228 | */ |
229 | explicit OUString( sal_Unicode value ) |
230 | : pData (NULL__null) |
231 | { |
232 | rtl_uString_newFromStr_WithLength( &pData, &value, 1 ); |
233 | } |
234 | |
235 | #if defined LIBO_INTERNAL_ONLY1 && !defined RTL_STRING_UNITTEST_CONCAT |
236 | /// @cond INTERNAL |
237 | // Catch inadvertent conversions to the above ctor (but still allow |
238 | // construction from char literals): |
239 | OUString(int) = delete; |
240 | explicit OUString(char c): |
241 | OUString(sal_Unicode(static_cast<unsigned char>(c))) |
242 | {} |
243 | /// @endcond |
244 | #endif |
245 | |
246 | #if defined LIBO_INTERNAL_ONLY1 |
247 | |
248 | template<typename T> explicit OUString( |
249 | T const & value, |
250 | typename libreoffice_internal::CharPtrDetector<T, libreoffice_internal::Dummy>::TypeUtf16 |
251 | = libreoffice_internal::Dummy()): |
252 | pData(nullptr) |
253 | { rtl_uString_newFromStr(&pData, value); } |
254 | |
255 | template<typename T> explicit OUString( |
256 | T & value, |
257 | typename |
258 | libreoffice_internal::NonConstCharArrayDetector<T, libreoffice_internal::Dummy>::TypeUtf16 |
259 | = libreoffice_internal::Dummy()): |
260 | pData(nullptr) |
261 | { rtl_uString_newFromStr(&pData, value); } |
262 | |
263 | #else |
264 | |
265 | /** |
266 | New string from a Unicode character buffer array. |
267 | |
268 | @param value a NULL-terminated Unicode character array. |
269 | */ |
270 | OUString( const sal_Unicode * value ) |
271 | { |
272 | pData = NULL__null; |
273 | rtl_uString_newFromStr( &pData, value ); |
274 | } |
275 | |
276 | #endif |
277 | |
278 | /** |
279 | New string from a Unicode character buffer array. |
280 | |
281 | @param value a Unicode character array. |
282 | @param length the number of character which should be copied. |
283 | The character array length must be greater than |
284 | or equal to this value. |
285 | */ |
286 | OUString( const sal_Unicode * value, sal_Int32 length ) |
287 | { |
288 | pData = NULL__null; |
289 | rtl_uString_newFromStr_WithLength( &pData, value, length ); |
290 | } |
291 | |
292 | /** |
293 | New string from an 8-Bit string literal that is expected to contain only |
294 | characters in the ASCII set (i.e. first 128 characters). This constructor |
295 | allows an efficient and convenient way to create OUString |
296 | instances from ASCII literals. When creating strings from data that |
297 | is not pure ASCII, it needs to be converted to OUString by explicitly |
298 | providing the encoding to use for the conversion. |
299 | |
300 | If there are any embedded \0's in the string literal, the result is undefined. |
301 | Use the overload that explicitly accepts length. |
302 | |
303 | @param literal the 8-bit ASCII string literal |
304 | |
305 | @since LibreOffice 3.6 |
306 | */ |
307 | template< typename T > |
308 | OUString( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() ) |
309 | { |
310 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 311, __extension__ __PRETTY_FUNCTION__)) |
311 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 311, __extension__ __PRETTY_FUNCTION__)); |
312 | pData = NULL__null; |
313 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { |
314 | rtl_uString_new(&pData); |
315 | } else { |
316 | rtl_uString_newFromLiteral( |
317 | &pData, |
318 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
319 | literal), |
320 | libreoffice_internal::ConstCharArrayDetector<T>::length, 0); |
321 | } |
322 | #ifdef RTL_STRING_UNITTEST |
323 | rtl_string_unittest_const_literal = true; |
324 | #endif |
325 | } |
326 | |
327 | #if defined LIBO_INTERNAL_ONLY1 |
328 | /** @overload @since LibreOffice 5.3 */ |
329 | template<typename T> OUString( |
330 | T & literal, |
331 | typename libreoffice_internal::ConstCharArrayDetector< |
332 | T, libreoffice_internal::Dummy>::TypeUtf16 |
333 | = libreoffice_internal::Dummy()): |
334 | pData(nullptr) |
335 | { |
336 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 337, __extension__ __PRETTY_FUNCTION__)) |
337 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 337, __extension__ __PRETTY_FUNCTION__)); |
338 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { |
339 | rtl_uString_new(&pData); |
340 | } else { |
341 | rtl_uString_newFromStr_WithLength( |
342 | &pData, |
343 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
344 | literal), |
345 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
346 | } |
347 | } |
348 | #endif |
349 | |
350 | #if defined LIBO_INTERNAL_ONLY1 && defined RTL_STRING_UNITTEST |
351 | /// @cond INTERNAL |
352 | /** |
353 | * Only used by unittests to detect incorrect conversions. |
354 | * @internal |
355 | */ |
356 | template< typename T > |
357 | OUString( T&, typename libreoffice_internal::ExceptConstCharArrayDetector< T >::Type = libreoffice_internal::Dummy() ) |
358 | { |
359 | pData = NULL__null; |
360 | rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage |
361 | rtl_string_unittest_invalid_conversion = true; |
362 | } |
363 | /** |
364 | * Only used by unittests to detect incorrect conversions. |
365 | * @internal |
366 | */ |
367 | template< typename T > |
368 | OUString( const T&, typename libreoffice_internal::ExceptCharArrayDetector< T >::Type = libreoffice_internal::Dummy() ) |
369 | { |
370 | pData = NULL__null; |
371 | rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage |
372 | rtl_string_unittest_invalid_conversion = true; |
373 | } |
374 | /// @endcond |
375 | #endif |
376 | |
377 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
378 | /// @cond INTERNAL |
379 | /** |
380 | New string from a string literal. |
381 | |
382 | @since LibreOffice 5.0 |
383 | */ |
384 | template<std::size_t N> OUString(OUStringLiteral<N> const & literal): |
385 | pData(const_cast<rtl_uString *>(reinterpret_cast<rtl_uString const *>(&literal))) {} |
386 | template<std::size_t N> OUString(OUStringLiteral<N> &&) = delete; |
387 | /// @endcond |
388 | #endif |
389 | |
390 | /** |
391 | New string from an 8-Bit character buffer array. |
392 | |
393 | @param value An 8-Bit character array. |
394 | @param length The number of character which should be converted. |
395 | The 8-Bit character array length must be |
396 | greater than or equal to this value. |
397 | @param encoding The text encoding from which the 8-Bit character |
398 | sequence should be converted. |
399 | @param convertFlags Flags which control the conversion. |
400 | see RTL_TEXTTOUNICODE_FLAGS_... |
401 | |
402 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs |
403 | */ |
404 | OUString( const char * value, sal_Int32 length, |
405 | rtl_TextEncoding encoding, |
406 | sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )) ) |
407 | { |
408 | pData = NULL__null; |
409 | rtl_string2UString( &pData, value, length, encoding, convertFlags ); |
410 | if (pData == NULL__null) { |
411 | throw std::bad_alloc(); |
412 | } |
413 | } |
414 | |
415 | /** Create a new string from an array of Unicode code points. |
416 | |
417 | @param codePoints |
418 | an array of at least codePointCount code points, which each must be in |
419 | the range from 0 to 0x10FFFF, inclusive. May be null if codePointCount |
420 | is zero. |
421 | |
422 | @param codePointCount |
423 | the non-negative number of code points. |
424 | |
425 | @exception std::bad_alloc |
426 | is thrown if either an out-of-memory condition occurs or the resulting |
427 | number of UTF-16 code units would have been larger than SAL_MAX_INT32. |
428 | |
429 | @since UDK 3.2.7 |
430 | */ |
431 | explicit OUString( |
432 | sal_uInt32 const * codePoints, sal_Int32 codePointCount): |
433 | pData(NULL__null) |
434 | { |
435 | rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount); |
436 | if (pData == NULL__null) { |
437 | throw std::bad_alloc(); |
438 | } |
439 | } |
440 | |
441 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
442 | /** |
443 | @overload |
444 | @internal |
445 | */ |
446 | template< typename T1, typename T2 > |
447 | OUString( OUStringConcat< T1, T2 >&& c ) |
448 | { |
449 | const sal_Int32 l = c.length(); |
450 | pData = rtl_uString_alloc( l ); |
451 | if (l != 0) |
452 | { |
453 | sal_Unicode* end = c.addData( pData->buffer ); |
454 | pData->length = l; |
455 | *end = '\0'; |
456 | // TODO realloc in case pData->length is noticeably smaller than l? |
457 | } |
458 | } |
459 | |
460 | /** |
461 | @overload |
462 | @internal |
463 | */ |
464 | template< typename T > |
465 | OUString( OUStringNumber< T >&& n ) |
466 | : OUString( n.buf, n.length ) |
467 | {} |
468 | #endif |
469 | |
470 | #if defined LIBO_INTERNAL_ONLY1 |
471 | OUString(std::u16string_view sv) { |
472 | if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { |
473 | throw std::bad_alloc(); |
474 | } |
475 | pData = nullptr; |
476 | rtl_uString_newFromStr_WithLength(&pData, sv.data(), sv.size()); |
477 | } |
478 | #endif |
479 | |
480 | /** |
481 | Release the string data. |
482 | */ |
483 | ~OUString() |
484 | { |
485 | rtl_uString_release( pData ); |
486 | } |
487 | |
488 | /** Provides an OUString const & passing a storage pointer of an |
489 | rtl_uString * handle. |
490 | It is more convenient to use C++ OUString member functions when dealing |
491 | with rtl_uString * handles. Using this function avoids unnecessary |
492 | acquire()/release() calls for a temporary OUString object. |
493 | |
494 | @param ppHandle |
495 | pointer to storage |
496 | @return |
497 | OUString const & based on given storage |
498 | */ |
499 | static OUString const & unacquired( rtl_uString * const * ppHandle ) |
500 | { return * reinterpret_cast< OUString const * >( ppHandle ); } |
501 | |
502 | /** |
503 | Assign a new string. |
504 | |
505 | @param str an OUString. |
506 | */ |
507 | OUString & operator=( const OUString & str ) |
508 | { |
509 | rtl_uString_assign( &pData, str.pData ); |
510 | return *this; |
511 | } |
512 | |
513 | #if defined LIBO_INTERNAL_ONLY1 |
514 | /** |
515 | Move assign a new string. |
516 | |
517 | @param str an OUString. |
518 | @since LibreOffice 5.2 |
519 | */ |
520 | OUString & operator=( OUString && str ) noexcept |
521 | { |
522 | rtl_uString_release( pData ); |
523 | pData = str.pData; |
524 | str.pData = nullptr; |
525 | rtl_uString_new( &str.pData ); |
526 | return *this; |
527 | } |
528 | #endif |
529 | |
530 | /** |
531 | Assign a new string from an 8-Bit string literal that is expected to contain only |
532 | characters in the ASCII set (i.e. first 128 characters). This operator |
533 | allows an efficient and convenient way to assign OUString |
534 | instances from ASCII literals. When assigning strings from data that |
535 | is not pure ASCII, it needs to be converted to OUString by explicitly |
536 | providing the encoding to use for the conversion. |
537 | |
538 | @param literal the 8-bit ASCII string literal |
539 | |
540 | @since LibreOffice 3.6 |
541 | */ |
542 | template< typename T > |
543 | typename libreoffice_internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal ) |
544 | { |
545 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 546, __extension__ __PRETTY_FUNCTION__)) |
546 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 546, __extension__ __PRETTY_FUNCTION__)); |
547 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { |
548 | rtl_uString_new(&pData); |
549 | } else { |
550 | rtl_uString_newFromLiteral( |
551 | &pData, |
552 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
553 | literal), |
554 | libreoffice_internal::ConstCharArrayDetector<T>::length, 0); |
555 | } |
556 | return *this; |
557 | } |
558 | |
559 | #if defined LIBO_INTERNAL_ONLY1 |
560 | /** @overload @since LibreOffice 5.3 */ |
561 | template<typename T> |
562 | typename |
563 | libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 |
564 | operator =(T & literal) { |
565 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { |
566 | rtl_uString_new(&pData); |
567 | } else { |
568 | rtl_uString_newFromStr_WithLength( |
569 | &pData, |
570 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
571 | literal), |
572 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
573 | } |
574 | return *this; |
575 | } |
576 | |
577 | /** @overload @since LibreOffice 5.4 */ |
578 | template<std::size_t N> OUString & operator =(OUStringLiteral<N> const & literal) { |
579 | if (literal.getLength() == 0) { |
580 | rtl_uString_new(&pData); |
581 | } else { |
582 | rtl_uString_newFromStr_WithLength(&pData, literal.getStr(), literal.getLength()); |
583 | } |
584 | return *this; |
585 | } |
586 | |
587 | template<typename T> |
588 | OUString & operator =(OUStringNumber<T> && n) { |
589 | // n.length should never be zero, so no need to add an optimization for that case |
590 | rtl_uString_newFromStr_WithLength(&pData, n.buf, n.length); |
591 | return *this; |
592 | } |
593 | |
594 | OUString & operator =(std::u16string_view sv) { |
595 | if (sv.empty()) { |
596 | rtl_uString_new(&pData); |
597 | } else { |
598 | rtl_uString_newFromStr_WithLength(&pData, sv.data(), sv.size()); |
599 | } |
600 | return *this; |
601 | } |
602 | #endif |
603 | |
604 | #if defined LIBO_INTERNAL_ONLY1 |
605 | /** |
606 | Append the contents of an OUStringBuffer to this string. |
607 | |
608 | @param str an OUStringBuffer. |
609 | |
610 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs |
611 | @since LibreOffice 6.2 |
612 | */ |
613 | inline OUString & operator+=( const OUStringBuffer & str ) &; |
614 | #endif |
615 | |
616 | /** |
617 | Append a string to this string. |
618 | |
619 | @param str an OUString. |
620 | |
621 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs |
622 | */ |
623 | OUString & operator+=( const OUString & str ) |
624 | #if defined LIBO_INTERNAL_ONLY1 |
625 | & |
626 | #endif |
627 | { |
628 | return internalAppend(str.pData); |
629 | } |
630 | #if defined LIBO_INTERNAL_ONLY1 |
631 | void operator+=(OUString const &) && = delete; |
632 | #endif |
633 | |
634 | /** Append an ASCII string literal to this string. |
635 | |
636 | @param literal an 8-bit ASCII-only string literal |
637 | |
638 | @since LibreOffice 5.1 |
639 | */ |
640 | template<typename T> |
641 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type |
642 | operator +=(T & literal) |
643 | #if defined LIBO_INTERNAL_ONLY1 |
644 | & |
645 | #endif |
646 | { |
647 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 648, __extension__ __PRETTY_FUNCTION__)) |
648 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 648, __extension__ __PRETTY_FUNCTION__)); |
649 | rtl_uString_newConcatAsciiL( |
650 | &pData, pData, |
651 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
652 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
653 | return *this; |
654 | } |
655 | #if defined LIBO_INTERNAL_ONLY1 |
656 | template<typename T> |
657 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type |
658 | operator +=(T &) && = delete; |
659 | #endif |
660 | |
661 | #if defined LIBO_INTERNAL_ONLY1 |
662 | /** @overload @since LibreOffice 5.3 */ |
663 | template<typename T> |
664 | typename |
665 | libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 |
666 | operator +=(T & literal) & { |
667 | rtl_uString_newConcatUtf16L( |
668 | &pData, pData, |
669 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
670 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
671 | return *this; |
672 | } |
673 | template<typename T> |
674 | typename |
675 | libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 |
676 | operator +=(T &) && = delete; |
677 | |
678 | /** @overload @since LibreOffice 5.4 */ |
679 | template<std::size_t N> OUString & operator +=(OUStringLiteral<N> const & literal) & { |
680 | rtl_uString_newConcatUtf16L(&pData, pData, literal.getStr(), literal.getLength()); |
681 | return *this; |
682 | } |
683 | template<std::size_t N> void operator +=(OUStringLiteral<N> const &) && = delete; |
684 | |
685 | OUString & operator +=(std::u16string_view sv) & { |
686 | if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { |
687 | throw std::bad_alloc(); |
688 | } |
689 | rtl_uString_newConcatUtf16L(&pData, pData, sv.data(), sv.size()); |
690 | return *this; |
691 | } |
692 | void operator +=(std::u16string_view) && = delete; |
693 | #endif |
694 | |
695 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
696 | /** |
697 | @overload |
698 | @internal |
699 | */ |
700 | template< typename T1, typename T2 > |
701 | OUString& operator+=( OUStringConcat< T1, T2 >&& c ) & { |
702 | sal_Int32 l = c.length(); |
703 | if( l == 0 ) |
704 | return *this; |
705 | l += pData->length; |
706 | rtl_uString_ensureCapacity( &pData, l ); |
707 | sal_Unicode* end = c.addData( pData->buffer + pData->length ); |
708 | *end = '\0'; |
709 | pData->length = l; |
710 | return *this; |
711 | } |
712 | template<typename T1, typename T2> void operator +=( |
713 | OUStringConcat<T1, T2> &&) && = delete; |
714 | |
715 | /** |
716 | @overload |
717 | @internal |
718 | */ |
719 | template< typename T > |
720 | OUString& operator+=( OUStringNumber< T >&& n ) & { |
721 | sal_Int32 l = n.length; |
722 | if( l == 0 ) |
723 | return *this; |
724 | l += pData->length; |
725 | rtl_uString_ensureCapacity( &pData, l ); |
726 | sal_Unicode* end = addDataHelper( pData->buffer + pData->length, n.buf, n.length ); |
727 | *end = '\0'; |
728 | pData->length = l; |
729 | return *this; |
730 | } |
731 | template<typename T> void operator +=( |
732 | OUStringNumber<T> &&) && = delete; |
733 | #endif |
734 | |
735 | /** |
736 | Clears the string, i.e, makes a zero-character string |
737 | @since LibreOffice 4.4 |
738 | */ |
739 | void clear() |
740 | { |
741 | rtl_uString_new( &pData ); |
742 | } |
743 | |
744 | /** |
745 | Returns the length of this string. |
746 | |
747 | The length is equal to the number of Unicode characters in this string. |
748 | |
749 | @return the length of the sequence of characters represented by this |
750 | object. |
751 | */ |
752 | sal_Int32 getLength() const { return pData->length; } |
753 | |
754 | /** |
755 | Checks if a string is empty. |
756 | |
757 | @return true if the string is empty; |
758 | false, otherwise. |
759 | |
760 | @since LibreOffice 3.4 |
761 | */ |
762 | bool isEmpty() const |
763 | { |
764 | return pData->length == 0; |
765 | } |
766 | |
767 | /** |
768 | Returns a pointer to the Unicode character buffer for this string. |
769 | |
770 | It isn't necessarily NULL terminated. |
771 | |
772 | @return a pointer to the Unicode characters buffer for this object. |
773 | */ |
774 | const sal_Unicode * getStr() const SAL_RETURNS_NONNULL__attribute__((returns_nonnull)) { return pData->buffer; } |
775 | |
776 | /** |
777 | Access to individual characters. |
778 | |
779 | @param index must be non-negative and less than length. |
780 | |
781 | @return the character at the given index. |
782 | |
783 | @since LibreOffice 3.5 |
784 | */ |
785 | sal_Unicode operator [](sal_Int32 index) const { |
786 | // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2 |
787 | assert(index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength()))(static_cast <bool> (index >= 0 && static_cast <sal_uInt32>(index) < static_cast<sal_uInt32>( getLength())) ? void (0) : __assert_fail ("index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength())" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 787, __extension__ __PRETTY_FUNCTION__)); |
788 | return getStr()[index]; |
789 | } |
790 | |
791 | /** |
792 | Compares two strings. |
793 | |
794 | The comparison is based on the numeric value of each character in |
795 | the strings and return a value indicating their relationship. |
796 | This function can't be used for language specific sorting. |
797 | |
798 | @param str the object to be compared. |
799 | @return 0 - if both strings are equal |
800 | < 0 - if this string is less than the string argument |
801 | > 0 - if this string is greater than the string argument |
802 | */ |
803 | sal_Int32 compareTo( const OUString & str ) const |
804 | { |
805 | return rtl_ustr_compare_WithLength( pData->buffer, pData->length, |
806 | str.pData->buffer, str.pData->length ); |
807 | } |
808 | |
809 | /** |
810 | Compares two strings with a maximum count of characters. |
811 | |
812 | The comparison is based on the numeric value of each character in |
813 | the strings and return a value indicating their relationship. |
814 | This function can't be used for language specific sorting. |
815 | |
816 | @param str the object to be compared. |
817 | @param maxLength the maximum count of characters to be compared. |
818 | @return 0 - if both strings are equal |
819 | < 0 - if this string is less than the string argument |
820 | > 0 - if this string is greater than the string argument |
821 | |
822 | @since UDK 3.2.7 |
823 | */ |
824 | sal_Int32 compareTo( const OUString & str, sal_Int32 maxLength ) const |
825 | { |
826 | return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length, |
827 | str.pData->buffer, str.pData->length, maxLength ); |
828 | } |
829 | |
830 | /** |
831 | Compares two strings in reverse order. |
832 | |
833 | The comparison is based on the numeric value of each character in |
834 | the strings and return a value indicating their relationship. |
835 | This function can't be used for language specific sorting. |
836 | |
837 | @param str the object to be compared. |
838 | @return 0 - if both strings are equal |
839 | < 0 - if this string is less than the string argument |
840 | > 0 - if this string is greater than the string argument |
841 | */ |
842 | #if defined LIBO_INTERNAL_ONLY1 |
843 | sal_Int32 reverseCompareTo(std::u16string_view sv) const { |
844 | return rtl_ustr_reverseCompare_WithLength( |
845 | pData->buffer, pData->length, sv.data(), sv.size()); |
846 | } |
847 | #else |
848 | sal_Int32 reverseCompareTo( const OUString & str ) const |
849 | { |
850 | return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, |
851 | str.pData->buffer, str.pData->length ); |
852 | } |
853 | #endif |
854 | |
855 | /** |
856 | @overload |
857 | This function accepts an ASCII string literal as its argument. |
858 | @since LibreOffice 4.1 |
859 | */ |
860 | template< typename T > |
861 | typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type reverseCompareTo( T& literal ) const |
862 | { |
863 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 864, __extension__ __PRETTY_FUNCTION__)) |
864 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 864, __extension__ __PRETTY_FUNCTION__)); |
865 | return rtl_ustr_asciil_reverseCompare_WithLength( |
866 | pData->buffer, pData->length, |
867 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
868 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
869 | } |
870 | |
871 | /** |
872 | Perform a comparison of two strings. |
873 | |
874 | The result is true if and only if second string |
875 | represents the same sequence of characters as the first string. |
876 | This function can't be used for language specific comparison. |
877 | |
878 | @param str the object to be compared. |
879 | @return true if the strings are equal; |
880 | false, otherwise. |
881 | */ |
882 | bool equals( const OUString & str ) const |
883 | { |
884 | if ( pData->length != str.pData->length ) |
885 | return false; |
886 | if ( pData == str.pData ) |
887 | return true; |
888 | return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, |
889 | str.pData->buffer, str.pData->length ) == 0; |
890 | } |
891 | |
892 | /** |
893 | Perform an ASCII lowercase comparison of two strings. |
894 | |
895 | The result is true if and only if second string |
896 | represents the same sequence of characters as the first string, |
897 | ignoring the case. |
898 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
899 | values between 97 and 122 (ASCII a-z). |
900 | This function can't be used for language specific comparison. |
901 | |
902 | @param str the object to be compared. |
903 | @return true if the strings are equal; |
904 | false, otherwise. |
905 | */ |
906 | #if defined LIBO_INTERNAL_ONLY1 |
907 | bool equalsIgnoreAsciiCase(std::u16string_view sv) const { |
908 | return |
909 | rtl_ustr_compareIgnoreAsciiCase_WithLength( |
910 | pData->buffer, pData->length, sv.data(), sv.size()) |
911 | == 0; |
912 | } |
913 | #else |
914 | bool equalsIgnoreAsciiCase( const OUString & str ) const |
915 | { |
916 | if ( pData->length != str.pData->length ) |
917 | return false; |
918 | if ( pData == str.pData ) |
919 | return true; |
920 | return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, |
921 | str.pData->buffer, str.pData->length ) == 0; |
922 | } |
923 | #endif |
924 | |
925 | /** |
926 | Perform an ASCII lowercase comparison of two strings. |
927 | |
928 | Compare the two strings with uppercase ASCII |
929 | character values between 65 and 90 (ASCII A-Z) interpreted as |
930 | values between 97 and 122 (ASCII a-z). |
931 | This function can't be used for language specific comparison. |
932 | |
933 | @param str the object to be compared. |
934 | @return 0 - if both strings are equal |
935 | < 0 - if this string is less than the string argument |
936 | > 0 - if this string is greater than the string argument |
937 | |
938 | @since LibreOffice 4.0 |
939 | */ |
940 | #if defined LIBO_INTERNAL_ONLY1 |
941 | sal_Int32 compareToIgnoreAsciiCase(std::u16string_view sv) const { |
942 | return rtl_ustr_compareIgnoreAsciiCase_WithLength( |
943 | pData->buffer, pData->length, sv.data(), sv.size()); |
944 | } |
945 | #else |
946 | sal_Int32 compareToIgnoreAsciiCase( const OUString & str ) const |
947 | { |
948 | return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, |
949 | str.pData->buffer, str.pData->length ); |
950 | } |
951 | #endif |
952 | |
953 | /** |
954 | @overload |
955 | This function accepts an ASCII string literal as its argument. |
956 | @since LibreOffice 3.6 |
957 | */ |
958 | template< typename T > |
959 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const |
960 | { |
961 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 962, __extension__ __PRETTY_FUNCTION__)) |
962 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 962, __extension__ __PRETTY_FUNCTION__)); |
963 | return |
964 | (pData->length |
965 | == libreoffice_internal::ConstCharArrayDetector<T>::length) |
966 | && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( |
967 | pData->buffer, pData->length, |
968 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
969 | literal)) |
970 | == 0); |
971 | } |
972 | |
973 | /** |
974 | Match against a substring appearing in this string. |
975 | |
976 | The result is true if and only if the second string appears as a substring |
977 | of this string, at the given position. |
978 | This function can't be used for language specific comparison. |
979 | |
980 | @param str the object (substring) to be compared. |
981 | @param fromIndex the index to start the comparison from. |
982 | The index must be greater than or equal to 0 |
983 | and less or equal as the string length. |
984 | @return true if str match with the characters in the string |
985 | at the given position; |
986 | false, otherwise. |
987 | */ |
988 | #if defined LIBO_INTERNAL_ONLY1 |
989 | bool match(std::u16string_view sv, sal_Int32 fromIndex = 0) const { |
990 | return |
991 | rtl_ustr_shortenedCompare_WithLength( |
992 | pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(), |
993 | sv.size()) |
994 | == 0; |
995 | } |
996 | #else |
997 | bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const |
998 | { |
999 | return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, |
1000 | str.pData->buffer, str.pData->length, str.pData->length ) == 0; |
1001 | } |
1002 | #endif |
1003 | |
1004 | /** |
1005 | @overload |
1006 | This function accepts an ASCII string literal as its argument. |
1007 | @since LibreOffice 3.6 |
1008 | */ |
1009 | template< typename T > |
1010 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const |
1011 | { |
1012 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1013, __extension__ __PRETTY_FUNCTION__)) |
1013 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1013, __extension__ __PRETTY_FUNCTION__)); |
1014 | return |
1015 | rtl_ustr_ascii_shortenedCompare_WithLength( |
1016 | pData->buffer+fromIndex, pData->length-fromIndex, |
1017 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1018 | literal), |
1019 | libreoffice_internal::ConstCharArrayDetector<T>::length) |
1020 | == 0; |
1021 | } |
1022 | |
1023 | /** |
1024 | Match against a substring appearing in this string, ignoring the case of |
1025 | ASCII letters. |
1026 | |
1027 | The result is true if and only if the second string appears as a substring |
1028 | of this string, at the given position. |
1029 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
1030 | values between 97 and 122 (ASCII a-z). |
1031 | This function can't be used for language specific comparison. |
1032 | |
1033 | @param str the object (substring) to be compared. |
1034 | @param fromIndex the index to start the comparison from. |
1035 | The index must be greater than or equal to 0 |
1036 | and less than or equal to the string length. |
1037 | @return true if str match with the characters in the string |
1038 | at the given position; |
1039 | false, otherwise. |
1040 | */ |
1041 | #if defined LIBO_INTERNAL_ONLY1 |
1042 | bool matchIgnoreAsciiCase(std::u16string_view sv, sal_Int32 fromIndex = 0) const { |
1043 | return |
1044 | rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( |
1045 | pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(), |
1046 | sv.size()) |
1047 | == 0; |
1048 | } |
1049 | #else |
1050 | bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const |
1051 | { |
1052 | return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, |
1053 | str.pData->buffer, str.pData->length, |
1054 | str.pData->length ) == 0; |
1055 | } |
1056 | #endif |
1057 | |
1058 | /** |
1059 | @overload |
1060 | This function accepts an ASCII string literal as its argument. |
1061 | @since LibreOffice 3.6 |
1062 | */ |
1063 | template< typename T > |
1064 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const |
1065 | { |
1066 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1067, __extension__ __PRETTY_FUNCTION__)) |
1067 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1067, __extension__ __PRETTY_FUNCTION__)); |
1068 | return |
1069 | rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( |
1070 | pData->buffer+fromIndex, pData->length-fromIndex, |
1071 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1072 | literal), |
1073 | libreoffice_internal::ConstCharArrayDetector<T>::length) |
1074 | == 0; |
1075 | } |
1076 | |
1077 | /** |
1078 | Compares two strings. |
1079 | |
1080 | The comparison is based on the numeric value of each character in |
1081 | the strings and return a value indicating their relationship. |
1082 | Since this method is optimized for performance, the ASCII character |
1083 | values are not converted in any way. The caller has to make sure that |
1084 | all ASCII characters are in the allowed range between 0 and 127. |
1085 | The ASCII string must be NULL-terminated. |
1086 | This function can't be used for language specific sorting. |
1087 | |
1088 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1089 | @return 0 - if both strings are equal |
1090 | < 0 - if this string is less than the string argument |
1091 | > 0 - if this string is greater than the string argument |
1092 | */ |
1093 | sal_Int32 compareToAscii( const char* asciiStr ) const |
1094 | { |
1095 | return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, asciiStr ); |
1096 | } |
1097 | |
1098 | /** |
1099 | Compares two strings with a maximum count of characters. |
1100 | |
1101 | The comparison is based on the numeric value of each character in |
1102 | the strings and return a value indicating their relationship. |
1103 | Since this method is optimized for performance, the ASCII character |
1104 | values are not converted in any way. The caller has to make sure that |
1105 | all ASCII characters are in the allowed range between 0 and 127. |
1106 | The ASCII string must be NULL-terminated. |
1107 | This function can't be used for language specific sorting. |
1108 | |
1109 | @deprecated This is a confusing overload with unexpectedly different |
1110 | semantics from the one-parameter form, so it is marked as deprecated. |
1111 | Practically all uses compare the return value against zero and can thus |
1112 | be replaced with uses of startsWith. |
1113 | |
1114 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1115 | @param maxLength the maximum count of characters to be compared. |
1116 | @return 0 - if both strings are equal |
1117 | < 0 - if this string is less than the string argument |
1118 | > 0 - if this string is greater than the string argument |
1119 | */ |
1120 | SAL_DEPRECATED(__attribute__((deprecated("replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)" ))) |
1121 | "replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)")__attribute__((deprecated("replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)" ))) |
1122 | sal_Int32 compareToAscii( const char * asciiStr, sal_Int32 maxLength ) const |
1123 | { |
1124 | return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer, pData->length, |
1125 | asciiStr, maxLength ); |
1126 | } |
1127 | |
1128 | /** |
1129 | Compares two strings in reverse order. |
1130 | |
1131 | This could be useful, if normally both strings start with the same |
1132 | content. The comparison is based on the numeric value of each character |
1133 | in the strings and return a value indicating their relationship. |
1134 | Since this method is optimized for performance, the ASCII character |
1135 | values are not converted in any way. The caller has to make sure that |
1136 | all ASCII characters are in the allowed range between 0 and 127. |
1137 | The ASCII string must be NULL-terminated and must be greater than |
1138 | or equal to asciiStrLength. |
1139 | This function can't be used for language specific sorting. |
1140 | |
1141 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1142 | @param asciiStrLength the length of the ascii string |
1143 | @return 0 - if both strings are equal |
1144 | < 0 - if this string is less than the string argument |
1145 | > 0 - if this string is greater than the string argument |
1146 | */ |
1147 | sal_Int32 reverseCompareToAsciiL( const char * asciiStr, sal_Int32 asciiStrLength ) const |
1148 | { |
1149 | return rtl_ustr_asciil_reverseCompare_WithLength( pData->buffer, pData->length, |
1150 | asciiStr, asciiStrLength ); |
1151 | } |
1152 | |
1153 | /** |
1154 | Perform a comparison of two strings. |
1155 | |
1156 | The result is true if and only if second string |
1157 | represents the same sequence of characters as the first string. |
1158 | Since this method is optimized for performance, the ASCII character |
1159 | values are not converted in any way. The caller has to make sure that |
1160 | all ASCII characters are in the allowed range between 0 and 127. |
1161 | The ASCII string must be NULL-terminated. |
1162 | This function can't be used for language specific comparison. |
1163 | |
1164 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1165 | @return true if the strings are equal; |
1166 | false, otherwise. |
1167 | */ |
1168 | bool equalsAscii( const char* asciiStr ) const |
1169 | { |
1170 | return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, |
1171 | asciiStr ) == 0; |
1172 | } |
1173 | |
1174 | /** |
1175 | Perform a comparison of two strings. |
1176 | |
1177 | The result is true if and only if second string |
1178 | represents the same sequence of characters as the first string. |
1179 | Since this method is optimized for performance, the ASCII character |
1180 | values are not converted in any way. The caller has to make sure that |
1181 | all ASCII characters are in the allowed range between 0 and 127. |
1182 | The ASCII string must be NULL-terminated and must be greater than |
1183 | or equal to asciiStrLength. |
1184 | This function can't be used for language specific comparison. |
1185 | |
1186 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1187 | @param asciiStrLength the length of the ascii string |
1188 | @return true if the strings are equal; |
1189 | false, otherwise. |
1190 | */ |
1191 | bool equalsAsciiL( const char* asciiStr, sal_Int32 asciiStrLength ) const |
1192 | { |
1193 | if ( pData->length != asciiStrLength ) |
1194 | return false; |
1195 | |
1196 | return rtl_ustr_asciil_reverseEquals_WithLength( |
1197 | pData->buffer, asciiStr, asciiStrLength ); |
1198 | } |
1199 | |
1200 | /** |
1201 | Perform an ASCII lowercase comparison of two strings. |
1202 | |
1203 | The result is true if and only if second string |
1204 | represents the same sequence of characters as the first string, |
1205 | ignoring the case. |
1206 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
1207 | values between 97 and 122 (ASCII a-z). |
1208 | Since this method is optimized for performance, the ASCII character |
1209 | values are not converted in any way. The caller has to make sure that |
1210 | all ASCII characters are in the allowed range between 0 and 127. |
1211 | The ASCII string must be NULL-terminated. |
1212 | This function can't be used for language specific comparison. |
1213 | |
1214 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1215 | @return true if the strings are equal; |
1216 | false, otherwise. |
1217 | */ |
1218 | bool equalsIgnoreAsciiCaseAscii( const char * asciiStr ) const |
1219 | { |
1220 | return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0; |
1221 | } |
1222 | |
1223 | /** |
1224 | Compares two ASCII strings ignoring case |
1225 | |
1226 | The comparison is based on the numeric value of each character in |
1227 | the strings and return a value indicating their relationship. |
1228 | Since this method is optimized for performance, the ASCII character |
1229 | values are not converted in any way. The caller has to make sure that |
1230 | all ASCII characters are in the allowed range between 0 and 127. |
1231 | The ASCII string must be NULL-terminated. |
1232 | This function can't be used for language specific sorting. |
1233 | |
1234 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1235 | @return 0 - if both strings are equal |
1236 | < 0 - if this string is less than the string argument |
1237 | > 0 - if this string is greater than the string argument |
1238 | |
1239 | @since LibreOffice 3.5 |
1240 | */ |
1241 | sal_Int32 compareToIgnoreAsciiCaseAscii( const char * asciiStr ) const |
1242 | { |
1243 | return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ); |
1244 | } |
1245 | |
1246 | /** |
1247 | Perform an ASCII lowercase comparison of two strings. |
1248 | |
1249 | The result is true if and only if second string |
1250 | represents the same sequence of characters as the first string, |
1251 | ignoring the case. |
1252 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
1253 | values between 97 and 122 (ASCII a-z). |
1254 | Since this method is optimized for performance, the ASCII character |
1255 | values are not converted in any way. The caller has to make sure that |
1256 | all ASCII characters are in the allowed range between 0 and 127. |
1257 | The ASCII string must be NULL-terminated and must be greater than |
1258 | or equal to asciiStrLength. |
1259 | This function can't be used for language specific comparison. |
1260 | |
1261 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1262 | @param asciiStrLength the length of the ascii string |
1263 | @return true if the strings are equal; |
1264 | false, otherwise. |
1265 | */ |
1266 | bool equalsIgnoreAsciiCaseAsciiL( const char * asciiStr, sal_Int32 asciiStrLength ) const |
1267 | { |
1268 | if ( pData->length != asciiStrLength ) |
1269 | return false; |
1270 | |
1271 | return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0; |
1272 | } |
1273 | |
1274 | /** |
1275 | Match against a substring appearing in this string. |
1276 | |
1277 | The result is true if and only if the second string appears as a substring |
1278 | of this string, at the given position. |
1279 | Since this method is optimized for performance, the ASCII character |
1280 | values are not converted in any way. The caller has to make sure that |
1281 | all ASCII characters are in the allowed range between 0 and 127. |
1282 | The ASCII string must be NULL-terminated and must be greater than or |
1283 | equal to asciiStrLength. |
1284 | This function can't be used for language specific comparison. |
1285 | |
1286 | @param asciiStr the object (substring) to be compared. |
1287 | @param asciiStrLength the length of asciiStr. |
1288 | @param fromIndex the index to start the comparison from. |
1289 | The index must be greater than or equal to 0 |
1290 | and less than or equal to the string length. |
1291 | @return true if str match with the characters in the string |
1292 | at the given position; |
1293 | false, otherwise. |
1294 | */ |
1295 | bool matchAsciiL( const char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const |
1296 | { |
1297 | return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, |
1298 | asciiStr, asciiStrLength ) == 0; |
1299 | } |
1300 | |
1301 | // This overload is left undefined, to detect calls of matchAsciiL that |
1302 | // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of |
1303 | // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit |
1304 | // platforms): |
1305 | #if SAL_TYPES_SIZEOFLONG8 == 8 |
1306 | void matchAsciiL(char const *, sal_Int32, rtl_TextEncoding) const; |
1307 | #endif |
1308 | |
1309 | /** |
1310 | Match against a substring appearing in this string, ignoring the case of |
1311 | ASCII letters. |
1312 | |
1313 | The result is true if and only if the second string appears as a substring |
1314 | of this string, at the given position. |
1315 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
1316 | values between 97 and 122 (ASCII a-z). |
1317 | Since this method is optimized for performance, the ASCII character |
1318 | values are not converted in any way. The caller has to make sure that |
1319 | all ASCII characters are in the allowed range between 0 and 127. |
1320 | The ASCII string must be NULL-terminated and must be greater than or |
1321 | equal to asciiStrLength. |
1322 | This function can't be used for language specific comparison. |
1323 | |
1324 | @param asciiStr the 8-Bit ASCII character string to be compared. |
1325 | @param asciiStrLength the length of the ascii string |
1326 | @param fromIndex the index to start the comparison from. |
1327 | The index must be greater than or equal to 0 |
1328 | and less than or equal to the string length. |
1329 | @return true if str match with the characters in the string |
1330 | at the given position; |
1331 | false, otherwise. |
1332 | */ |
1333 | bool matchIgnoreAsciiCaseAsciiL( const char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const |
1334 | { |
1335 | return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, |
1336 | asciiStr, asciiStrLength ) == 0; |
1337 | } |
1338 | |
1339 | // This overload is left undefined, to detect calls of |
1340 | // matchIgnoreAsciiCaseAsciiL that erroneously use |
1341 | // RTL_CONSTASCII_USTRINGPARAM instead of RTL_CONSTASCII_STRINGPARAM (but |
1342 | // would lead to ambiguities on 32 bit platforms): |
1343 | #if SAL_TYPES_SIZEOFLONG8 == 8 |
1344 | void matchIgnoreAsciiCaseAsciiL(char const *, sal_Int32, rtl_TextEncoding) |
1345 | const; |
1346 | #endif |
1347 | |
1348 | /** |
1349 | Check whether this string starts with a given substring. |
1350 | |
1351 | @param str the substring to be compared |
1352 | |
1353 | @param rest if non-null, and this function returns true, then assign a |
1354 | copy of the remainder of this string to *rest. Available since |
1355 | LibreOffice 4.2 |
1356 | |
1357 | @return true if and only if the given str appears as a substring at the |
1358 | start of this string |
1359 | |
1360 | @since LibreOffice 4.0 |
1361 | */ |
1362 | #if defined LIBO_INTERNAL_ONLY1 |
1363 | bool startsWith(std::u16string_view sv, OUString * rest = nullptr) const { |
1364 | auto const b = match(sv); |
1365 | if (b && rest != nullptr) { |
1366 | *rest = copy(sv.size()); |
1367 | } |
1368 | return b; |
1369 | } |
1370 | #else |
1371 | bool startsWith(OUString const & str, OUString * rest = NULL__null) const { |
1372 | bool b = match(str); |
1373 | if (b && rest != NULL__null) { |
1374 | *rest = copy(str.getLength()); |
1375 | } |
1376 | return b; |
1377 | } |
1378 | #endif |
1379 | |
1380 | /** |
1381 | @overload |
1382 | This function accepts an ASCII string literal as its argument. |
1383 | @since LibreOffice 4.0 |
1384 | */ |
1385 | template< typename T > |
1386 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type startsWith( |
1387 | T & literal, OUString * rest = NULL__null) const |
1388 | { |
1389 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1390, __extension__ __PRETTY_FUNCTION__)) |
1390 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1390, __extension__ __PRETTY_FUNCTION__)); |
1391 | bool b |
1392 | = (libreoffice_internal::ConstCharArrayDetector<T>::length |
1393 | <= sal_uInt32(pData->length)) |
1394 | && rtl_ustr_asciil_reverseEquals_WithLength( |
1395 | pData->buffer, |
1396 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1397 | literal), |
1398 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1399 | if (b && rest != NULL__null) { |
1400 | *rest = copy( |
1401 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1402 | } |
1403 | return b; |
1404 | } |
1405 | |
1406 | /** |
1407 | Check whether this string starts with a given string, ignoring the case of |
1408 | ASCII letters. |
1409 | |
1410 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
1411 | values between 97 and 122 (ASCII a-z). |
1412 | This function can't be used for language specific comparison. |
1413 | |
1414 | @param str the substring to be compared |
1415 | |
1416 | @param rest if non-null, and this function returns true, then assign a |
1417 | copy of the remainder of this string to *rest. Available since |
1418 | LibreOffice 4.2 |
1419 | |
1420 | @return true if and only if the given str appears as a substring at the |
1421 | start of this string, ignoring the case of ASCII letters ("A"--"Z" and |
1422 | "a"--"z") |
1423 | |
1424 | @since LibreOffice 4.0 |
1425 | */ |
1426 | #if defined LIBO_INTERNAL_ONLY1 |
1427 | bool startsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const { |
1428 | auto const b = matchIgnoreAsciiCase(sv); |
1429 | if (b && rest != nullptr) { |
1430 | *rest = copy(sv.size()); |
1431 | } |
1432 | return b; |
1433 | } |
1434 | #else |
1435 | bool startsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL__null) |
1436 | const |
1437 | { |
1438 | bool b = matchIgnoreAsciiCase(str); |
1439 | if (b && rest != NULL__null) { |
1440 | *rest = copy(str.getLength()); |
1441 | } |
1442 | return b; |
1443 | } |
1444 | #endif |
1445 | |
1446 | /** |
1447 | @overload |
1448 | This function accepts an ASCII string literal as its argument. |
1449 | @since LibreOffice 4.0 |
1450 | */ |
1451 | template< typename T > |
1452 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type |
1453 | startsWithIgnoreAsciiCase(T & literal, OUString * rest = NULL__null) const |
1454 | { |
1455 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1456, __extension__ __PRETTY_FUNCTION__)) |
1456 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1456, __extension__ __PRETTY_FUNCTION__)); |
1457 | bool b |
1458 | = (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( |
1459 | pData->buffer, |
1460 | libreoffice_internal::ConstCharArrayDetector<T>::length, |
1461 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1462 | literal), |
1463 | libreoffice_internal::ConstCharArrayDetector<T>::length) |
1464 | == 0); |
1465 | if (b && rest != NULL__null) { |
1466 | *rest = copy( |
1467 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1468 | } |
1469 | return b; |
1470 | } |
1471 | |
1472 | /** |
1473 | Check whether this string ends with a given substring. |
1474 | |
1475 | @param str the substring to be compared |
1476 | |
1477 | @param rest if non-null, and this function returns true, then assign a |
1478 | copy of the remainder of this string to *rest. Available since |
1479 | LibreOffice 4.2 |
1480 | |
1481 | @return true if and only if the given str appears as a substring at the |
1482 | end of this string |
1483 | |
1484 | @since LibreOffice 3.6 |
1485 | */ |
1486 | #if defined LIBO_INTERNAL_ONLY1 |
1487 | bool endsWith(std::u16string_view sv, OUString * rest = nullptr) const { |
1488 | auto const b = sv.size() <= sal_uInt32(pData->length) |
1489 | && match(sv, pData->length - sv.size()); |
1490 | if (b && rest != nullptr) { |
1491 | *rest = copy(0, (pData->length - sv.size())); |
1492 | } |
1493 | return b; |
1494 | } |
1495 | #else |
1496 | bool endsWith(OUString const & str, OUString * rest = NULL__null) const { |
1497 | bool b = str.getLength() <= getLength() |
1498 | && match(str, getLength() - str.getLength()); |
1499 | if (b && rest != NULL__null) { |
1500 | *rest = copy(0, getLength() - str.getLength()); |
1501 | } |
1502 | return b; |
1503 | } |
1504 | #endif |
1505 | |
1506 | /** |
1507 | @overload |
1508 | This function accepts an ASCII string literal as its argument. |
1509 | @since LibreOffice 3.6 |
1510 | */ |
1511 | template< typename T > |
1512 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type |
1513 | endsWith(T & literal, OUString * rest = NULL__null) const |
1514 | { |
1515 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1516, __extension__ __PRETTY_FUNCTION__)) |
1516 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1516, __extension__ __PRETTY_FUNCTION__)); |
1517 | bool b |
1518 | = (libreoffice_internal::ConstCharArrayDetector<T>::length |
1519 | <= sal_uInt32(pData->length)) |
1520 | && rtl_ustr_asciil_reverseEquals_WithLength( |
1521 | (pData->buffer + pData->length |
1522 | - libreoffice_internal::ConstCharArrayDetector<T>::length), |
1523 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1524 | literal), |
1525 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1526 | if (b && rest != NULL__null) { |
1527 | *rest = copy( |
1528 | 0, |
1529 | (getLength() |
1530 | - libreoffice_internal::ConstCharArrayDetector<T>::length)); |
1531 | } |
1532 | return b; |
1533 | } |
1534 | |
1535 | /** |
1536 | Check whether this string ends with a given ASCII string. |
1537 | |
1538 | @param asciiStr a sequence of at least asciiStrLength ASCII characters |
1539 | (bytes in the range 0x00--0x7F) |
1540 | @param asciiStrLength the length of asciiStr; must be non-negative |
1541 | @return true if this string ends with asciiStr; otherwise, false is |
1542 | returned |
1543 | |
1544 | @since UDK 3.2.7 |
1545 | */ |
1546 | bool endsWithAsciiL(char const * asciiStr, sal_Int32 asciiStrLength) |
1547 | const |
1548 | { |
1549 | return asciiStrLength <= pData->length |
1550 | && rtl_ustr_asciil_reverseEquals_WithLength( |
1551 | pData->buffer + pData->length - asciiStrLength, asciiStr, |
1552 | asciiStrLength); |
1553 | } |
1554 | |
1555 | /** |
1556 | Check whether this string ends with a given string, ignoring the case of |
1557 | ASCII letters. |
1558 | |
1559 | Character values between 65 and 90 (ASCII A-Z) are interpreted as |
1560 | values between 97 and 122 (ASCII a-z). |
1561 | This function can't be used for language specific comparison. |
1562 | |
1563 | @param str the substring to be compared |
1564 | |
1565 | @param rest if non-null, and this function returns true, then assign a |
1566 | copy of the remainder of this string to *rest. Available since |
1567 | LibreOffice 4.2 |
1568 | |
1569 | @return true if and only if the given str appears as a substring at the |
1570 | end of this string, ignoring the case of ASCII letters ("A"--"Z" and |
1571 | "a"--"z") |
1572 | |
1573 | @since LibreOffice 3.6 |
1574 | */ |
1575 | #if defined LIBO_INTERNAL_ONLY1 |
1576 | bool endsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const { |
1577 | auto const b = sv.size() <= sal_uInt32(pData->length) |
1578 | && matchIgnoreAsciiCase(sv, pData->length - sv.size()); |
1579 | if (b && rest != nullptr) { |
1580 | *rest = copy(0, pData->length - sv.size()); |
1581 | } |
1582 | return b; |
1583 | } |
1584 | #else |
1585 | bool endsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL__null) const |
1586 | { |
1587 | bool b = str.getLength() <= getLength() |
1588 | && matchIgnoreAsciiCase(str, getLength() - str.getLength()); |
1589 | if (b && rest != NULL__null) { |
1590 | *rest = copy(0, getLength() - str.getLength()); |
1591 | } |
1592 | return b; |
1593 | } |
1594 | #endif |
1595 | |
1596 | /** |
1597 | @overload |
1598 | This function accepts an ASCII string literal as its argument. |
1599 | @since LibreOffice 3.6 |
1600 | */ |
1601 | template< typename T > |
1602 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type |
1603 | endsWithIgnoreAsciiCase(T & literal, OUString * rest = NULL__null) const |
1604 | { |
1605 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1606, __extension__ __PRETTY_FUNCTION__)) |
1606 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1606, __extension__ __PRETTY_FUNCTION__)); |
1607 | bool b |
1608 | = (libreoffice_internal::ConstCharArrayDetector<T>::length |
1609 | <= sal_uInt32(pData->length)) |
1610 | && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( |
1611 | (pData->buffer + pData->length |
1612 | - libreoffice_internal::ConstCharArrayDetector<T>::length), |
1613 | libreoffice_internal::ConstCharArrayDetector<T>::length, |
1614 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1615 | literal), |
1616 | libreoffice_internal::ConstCharArrayDetector<T>::length) |
1617 | == 0); |
1618 | if (b && rest != NULL__null) { |
1619 | *rest = copy( |
1620 | 0, |
1621 | (getLength() |
1622 | - libreoffice_internal::ConstCharArrayDetector<T>::length)); |
1623 | } |
1624 | return b; |
1625 | } |
1626 | |
1627 | /** |
1628 | Check whether this string ends with a given ASCII string, ignoring the |
1629 | case of ASCII letters. |
1630 | |
1631 | @param asciiStr a sequence of at least asciiStrLength ASCII characters |
1632 | (bytes in the range 0x00--0x7F) |
1633 | @param asciiStrLength the length of asciiStr; must be non-negative |
1634 | @return true if this string ends with asciiStr, ignoring the case of ASCII |
1635 | letters ("A"--"Z" and "a"--"z"); otherwise, false is returned |
1636 | */ |
1637 | bool endsWithIgnoreAsciiCaseAsciiL( |
1638 | char const * asciiStr, sal_Int32 asciiStrLength) const |
1639 | { |
1640 | return asciiStrLength <= pData->length |
1641 | && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( |
1642 | pData->buffer + pData->length - asciiStrLength, |
1643 | asciiStrLength, asciiStr, asciiStrLength) |
1644 | == 0); |
1645 | } |
1646 | |
1647 | friend bool operator == ( const OUString& rStr1, const OUString& rStr2 ) |
1648 | { return rStr1.equals(rStr2); } |
1649 | |
1650 | friend bool operator != ( const OUString& rStr1, const OUString& rStr2 ) |
1651 | { return !(operator == ( rStr1, rStr2 )); } |
1652 | |
1653 | friend bool operator < ( const OUString& rStr1, const OUString& rStr2 ) |
1654 | { return rStr1.compareTo( rStr2 ) < 0; } |
1655 | friend bool operator > ( const OUString& rStr1, const OUString& rStr2 ) |
1656 | { return rStr1.compareTo( rStr2 ) > 0; } |
1657 | friend bool operator <= ( const OUString& rStr1, const OUString& rStr2 ) |
1658 | { return rStr1.compareTo( rStr2 ) <= 0; } |
1659 | friend bool operator >= ( const OUString& rStr1, const OUString& rStr2 ) |
1660 | { return rStr1.compareTo( rStr2 ) >= 0; } |
1661 | |
1662 | #if defined LIBO_INTERNAL_ONLY1 |
1663 | |
1664 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 |
1665 | operator ==(OUString const & s1, T const & s2) { |
1666 | return rtl_ustr_compare_WithLength(s1.getStr(), s1.getLength(), s2, rtl_ustr_getLength(s2)) |
1667 | == 0; |
1668 | } |
1669 | |
1670 | template<typename T> |
1671 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 |
1672 | operator ==(OUString const & s1, T & s2) { |
1673 | return rtl_ustr_compare_WithLength(s1.getStr(), s1.getLength(), s2, rtl_ustr_getLength(s2)) |
1674 | == 0; |
1675 | } |
1676 | |
1677 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 |
1678 | operator ==(T const & s1, OUString const & s2) { |
1679 | return rtl_ustr_compare_WithLength(s1, rtl_ustr_getLength(s1), s2.getStr(), s2.getLength()) |
1680 | == 0; |
1681 | } |
1682 | |
1683 | template<typename T> |
1684 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 |
1685 | operator ==(T & s1, OUString const & s2) { |
1686 | return rtl_ustr_compare_WithLength(s1, rtl_ustr_getLength(s1), s2.getStr(), s2.getLength()) |
1687 | == 0; |
1688 | } |
1689 | |
1690 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 |
1691 | operator !=(OUString const & s1, T const & s2) { return !(s1 == s2); } |
1692 | |
1693 | template<typename T> |
1694 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 |
1695 | operator !=(OUString const & s1, T & s2) { return !(s1 == s2); } |
1696 | |
1697 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 |
1698 | operator !=(T const & s1, OUString const & s2) { return !(s1 == s2); } |
1699 | |
1700 | template<typename T> |
1701 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 |
1702 | operator !=(T & s1, OUString const & s2) { return !(s1 == s2); } |
1703 | |
1704 | #else |
1705 | |
1706 | friend bool operator == ( const OUString& rStr1, const sal_Unicode * pStr2 ) |
1707 | { return rStr1.compareTo( pStr2 ) == 0; } |
1708 | friend bool operator == ( const sal_Unicode * pStr1, const OUString& rStr2 ) |
1709 | { return OUString( pStr1 ).compareTo( rStr2 ) == 0; } |
1710 | |
1711 | friend bool operator != ( const OUString& rStr1, const sal_Unicode * pStr2 ) |
1712 | { return !(operator == ( rStr1, pStr2 )); } |
1713 | friend bool operator != ( const sal_Unicode * pStr1, const OUString& rStr2 ) |
1714 | { return !(operator == ( pStr1, rStr2 )); } |
1715 | |
1716 | #endif |
1717 | |
1718 | /** |
1719 | * Compare string to an ASCII string literal. |
1720 | * |
1721 | * This operator is equal to calling equalsAsciiL(). |
1722 | * |
1723 | * @since LibreOffice 3.6 |
1724 | */ |
1725 | template< typename T > |
1726 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& rString, T& literal ) |
1727 | { |
1728 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1729, __extension__ __PRETTY_FUNCTION__)) |
1729 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1729, __extension__ __PRETTY_FUNCTION__)); |
1730 | return rString.equalsAsciiL( |
1731 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
1732 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1733 | } |
1734 | /** |
1735 | * Compare string to an ASCII string literal. |
1736 | * |
1737 | * This operator is equal to calling equalsAsciiL(). |
1738 | * |
1739 | * @since LibreOffice 3.6 |
1740 | */ |
1741 | template< typename T > |
1742 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& rString ) |
1743 | { |
1744 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1745, __extension__ __PRETTY_FUNCTION__)) |
1745 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1745, __extension__ __PRETTY_FUNCTION__)); |
1746 | return rString.equalsAsciiL( |
1747 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
1748 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1749 | } |
1750 | /** |
1751 | * Compare string to an ASCII string literal. |
1752 | * |
1753 | * This operator is equal to calling !equalsAsciiL(). |
1754 | * |
1755 | * @since LibreOffice 3.6 |
1756 | */ |
1757 | template< typename T > |
1758 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& rString, T& literal ) |
1759 | { |
1760 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1761, __extension__ __PRETTY_FUNCTION__)) |
1761 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1761, __extension__ __PRETTY_FUNCTION__)); |
1762 | return !rString.equalsAsciiL( |
1763 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
1764 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1765 | } |
1766 | /** |
1767 | * Compare string to an ASCII string literal. |
1768 | * |
1769 | * This operator is equal to calling !equalsAsciiL(). |
1770 | * |
1771 | * @since LibreOffice 3.6 |
1772 | */ |
1773 | template< typename T > |
1774 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& rString ) |
1775 | { |
1776 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1777, __extension__ __PRETTY_FUNCTION__)) |
1777 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1777, __extension__ __PRETTY_FUNCTION__)); |
1778 | return !rString.equalsAsciiL( |
1779 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
1780 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
1781 | } |
1782 | |
1783 | #if defined LIBO_INTERNAL_ONLY1 |
1784 | /** @overload @since LibreOffice 5.3 */ |
1785 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 |
1786 | operator ==(OUString const & string, T & literal) { |
1787 | return |
1788 | rtl_ustr_reverseCompare_WithLength( |
1789 | string.pData->buffer, string.pData->length, |
1790 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1791 | literal), |
1792 | libreoffice_internal::ConstCharArrayDetector<T>::length) |
1793 | == 0; |
1794 | } |
1795 | /** @overload @since LibreOffice 5.3 */ |
1796 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 |
1797 | operator ==(T & literal, OUString const & string) { |
1798 | return |
1799 | rtl_ustr_reverseCompare_WithLength( |
1800 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1801 | literal), |
1802 | libreoffice_internal::ConstCharArrayDetector<T>::length, |
1803 | string.pData->buffer, string.pData->length) |
1804 | == 0; |
1805 | } |
1806 | /** @overload @since LibreOffice 5.3 */ |
1807 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 |
1808 | operator !=(OUString const & string, T & literal) { |
1809 | return |
1810 | rtl_ustr_reverseCompare_WithLength( |
1811 | string.pData->buffer, string.pData->length, |
1812 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1813 | literal), |
1814 | libreoffice_internal::ConstCharArrayDetector<T>::length) |
1815 | != 0; |
1816 | } |
1817 | /** @overload @since LibreOffice 5.3 */ |
1818 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 |
1819 | operator !=(T & literal, OUString const & string) { |
1820 | return |
1821 | rtl_ustr_reverseCompare_WithLength( |
1822 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( |
1823 | literal), |
1824 | libreoffice_internal::ConstCharArrayDetector<T>::length, |
1825 | string.pData->buffer, string.pData->length) |
1826 | != 0; |
1827 | } |
1828 | #endif |
1829 | |
1830 | #if defined LIBO_INTERNAL_ONLY1 |
1831 | /// @cond INTERNAL |
1832 | |
1833 | /* Comparison between OUString and OUStringLiteral. |
1834 | |
1835 | @since LibreOffice 5.0 |
1836 | */ |
1837 | |
1838 | template<std::size_t N> |
1839 | friend bool operator ==(OUString const & lhs, OUStringLiteral<N> const & rhs) { |
1840 | return |
1841 | rtl_ustr_reverseCompare_WithLength( |
1842 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength()) |
1843 | == 0; |
1844 | } |
1845 | |
1846 | template<std::size_t N> |
1847 | friend bool operator !=(OUString const & lhs, OUStringLiteral<N> const & rhs) { |
1848 | return |
1849 | rtl_ustr_reverseCompare_WithLength( |
1850 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength()) |
1851 | != 0; |
1852 | } |
1853 | |
1854 | template<std::size_t N> |
1855 | friend bool operator <(OUString const & lhs, OUStringLiteral<N> const & rhs) { |
1856 | return |
1857 | (rtl_ustr_compare_WithLength( |
1858 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) |
1859 | < 0; |
1860 | } |
1861 | |
1862 | template<std::size_t N> |
1863 | friend bool operator <=(OUString const & lhs, OUStringLiteral<N> const & rhs) { |
1864 | return |
1865 | (rtl_ustr_compare_WithLength( |
1866 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) |
1867 | <= 0; |
1868 | } |
1869 | |
1870 | template<std::size_t N> |
1871 | friend bool operator >(OUString const & lhs, OUStringLiteral<N> const & rhs) { |
1872 | return |
1873 | (rtl_ustr_compare_WithLength( |
1874 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) |
1875 | > 0; |
1876 | } |
1877 | |
1878 | template<std::size_t N> |
1879 | friend bool operator >=(OUString const & lhs, OUStringLiteral<N> const & rhs) { |
1880 | return |
1881 | (rtl_ustr_compare_WithLength( |
1882 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) |
1883 | >= 0; |
1884 | } |
1885 | |
1886 | template<std::size_t N> |
1887 | friend bool operator ==(OUStringLiteral<N> const & lhs, OUString const & rhs) { |
1888 | return |
1889 | rtl_ustr_reverseCompare_WithLength( |
1890 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length) |
1891 | == 0; |
1892 | } |
1893 | |
1894 | template<std::size_t N> |
1895 | friend bool operator !=(OUStringLiteral<N> const & lhs, OUString const & rhs) { |
1896 | return |
1897 | rtl_ustr_reverseCompare_WithLength( |
1898 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length) |
1899 | != 0; |
1900 | } |
1901 | |
1902 | template<std::size_t N> |
1903 | friend bool operator <(OUStringLiteral<N> const & lhs, OUString const & rhs) { |
1904 | return |
1905 | (rtl_ustr_compare_WithLength( |
1906 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) |
1907 | < 0; |
1908 | } |
1909 | |
1910 | template<std::size_t N> |
1911 | friend bool operator <=(OUStringLiteral<N> const & lhs, OUString const & rhs) { |
1912 | return |
1913 | (rtl_ustr_compare_WithLength( |
1914 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) |
1915 | <= 0; |
1916 | } |
1917 | |
1918 | template<std::size_t N> |
1919 | friend bool operator >(OUStringLiteral<N> const & lhs, OUString const & rhs) { |
1920 | return |
1921 | (rtl_ustr_compare_WithLength( |
1922 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) |
1923 | > 0; |
1924 | } |
1925 | |
1926 | template<std::size_t N> |
1927 | friend bool operator >=(OUStringLiteral<N> const & lhs, OUString const & rhs) { |
1928 | return |
1929 | (rtl_ustr_compare_WithLength( |
1930 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) |
1931 | >= 0; |
1932 | } |
1933 | |
1934 | /// @endcond |
1935 | #endif |
1936 | |
1937 | #if defined LIBO_INTERNAL_ONLY1 |
1938 | friend bool operator ==(OUString const & lhs, std::u16string_view rhs) { |
1939 | return |
1940 | rtl_ustr_reverseCompare_WithLength( |
1941 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size()) |
1942 | == 0; |
1943 | } |
1944 | |
1945 | friend bool operator !=(OUString const & lhs, std::u16string_view rhs) { |
1946 | return |
1947 | rtl_ustr_reverseCompare_WithLength( |
1948 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size()) |
1949 | != 0; |
1950 | } |
1951 | |
1952 | friend bool operator <(OUString const & lhs, std::u16string_view rhs) { |
1953 | return |
1954 | (rtl_ustr_compare_WithLength( |
1955 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) |
1956 | < 0; |
1957 | } |
1958 | |
1959 | friend bool operator <=(OUString const & lhs, std::u16string_view rhs) { |
1960 | return |
1961 | (rtl_ustr_compare_WithLength( |
1962 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) |
1963 | <= 0; |
1964 | } |
1965 | |
1966 | friend bool operator >(OUString const & lhs, std::u16string_view rhs) { |
1967 | return |
1968 | (rtl_ustr_compare_WithLength( |
1969 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) |
1970 | > 0; |
1971 | } |
1972 | |
1973 | friend bool operator >=(OUString const & lhs, std::u16string_view rhs) { |
1974 | return |
1975 | (rtl_ustr_compare_WithLength( |
1976 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) |
1977 | >= 0; |
1978 | } |
1979 | |
1980 | friend bool operator ==(std::u16string_view lhs, OUString const & rhs) { |
1981 | return |
1982 | rtl_ustr_reverseCompare_WithLength( |
1983 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length) |
1984 | == 0; |
1985 | } |
1986 | |
1987 | friend bool operator !=(std::u16string_view lhs, OUString const & rhs) { |
1988 | return |
1989 | rtl_ustr_reverseCompare_WithLength( |
1990 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length) |
1991 | != 0; |
1992 | } |
1993 | |
1994 | friend bool operator <(std::u16string_view lhs, OUString const & rhs) { |
1995 | return |
1996 | (rtl_ustr_compare_WithLength( |
1997 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) |
1998 | < 0; |
1999 | } |
2000 | |
2001 | friend bool operator <=(std::u16string_view lhs, OUString const & rhs) { |
2002 | return |
2003 | (rtl_ustr_compare_WithLength( |
2004 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) |
2005 | <= 0; |
2006 | } |
2007 | |
2008 | friend bool operator >(std::u16string_view lhs, OUString const & rhs) { |
2009 | return |
2010 | (rtl_ustr_compare_WithLength( |
2011 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) |
2012 | > 0; |
2013 | } |
2014 | |
2015 | friend bool operator >=(std::u16string_view lhs, OUString const & rhs) { |
2016 | return |
2017 | (rtl_ustr_compare_WithLength( |
2018 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) |
2019 | >= 0; |
2020 | } |
2021 | #endif |
2022 | |
2023 | /** |
2024 | Returns a hashcode for this string. |
2025 | |
2026 | @return a hash code value for this object. |
2027 | |
2028 | @see rtl::OUStringHash for convenient use of std::unordered_map |
2029 | */ |
2030 | sal_Int32 hashCode() const |
2031 | { |
2032 | return rtl_ustr_hashCode_WithLength( pData->buffer, pData->length ); |
2033 | } |
2034 | |
2035 | /** |
2036 | Returns the index within this string of the first occurrence of the |
2037 | specified character, starting the search at the specified index. |
2038 | |
2039 | @param ch character to be located. |
2040 | @param fromIndex the index to start the search from. |
2041 | The index must be greater than or equal to 0 |
2042 | and less than or equal to the string length. |
2043 | @return the index of the first occurrence of the character in the |
2044 | character sequence represented by this string that is |
2045 | greater than or equal to fromIndex, or |
2046 | -1 if the character does not occur. |
2047 | */ |
2048 | sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const |
2049 | { |
2050 | sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch ); |
2051 | return (ret < 0 ? ret : ret+fromIndex); |
2052 | } |
2053 | |
2054 | /** |
2055 | Returns the index within this string of the last occurrence of the |
2056 | specified character, searching backward starting at the end. |
2057 | |
2058 | @param ch character to be located. |
2059 | @return the index of the last occurrence of the character in the |
2060 | character sequence represented by this string, or |
2061 | -1 if the character does not occur. |
2062 | */ |
2063 | sal_Int32 lastIndexOf( sal_Unicode ch ) const |
2064 | { |
2065 | return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch ); |
2066 | } |
2067 | |
2068 | /** |
2069 | Returns the index within this string of the last occurrence of the |
2070 | specified character, searching backward starting before the specified |
2071 | index. |
2072 | |
2073 | @param ch character to be located. |
2074 | @param fromIndex the index before which to start the search. |
2075 | @return the index of the last occurrence of the character in the |
2076 | character sequence represented by this string that |
2077 | is less than fromIndex, or -1 |
2078 | if the character does not occur before that point. |
2079 | */ |
2080 | sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const |
2081 | { |
2082 | return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch ); |
2083 | } |
2084 | |
2085 | /** |
2086 | Returns the index within this string of the first occurrence of the |
2087 | specified substring, starting at the specified index. |
2088 | |
2089 | If str doesn't include any character, always -1 is |
2090 | returned. This is also the case, if both strings are empty. |
2091 | |
2092 | @param str the substring to search for. |
2093 | @param fromIndex the index to start the search from. |
2094 | @return If the string argument occurs one or more times as a substring |
2095 | within this string at the starting index, then the index |
2096 | of the first character of the first such substring is |
2097 | returned. If it does not occur as a substring starting |
2098 | at fromIndex or beyond, -1 is returned. |
2099 | */ |
2100 | #if defined LIBO_INTERNAL_ONLY1 |
2101 | sal_Int32 indexOf(std::u16string_view sv, sal_Int32 fromIndex = 0) const { |
2102 | auto const n = rtl_ustr_indexOfStr_WithLength( |
2103 | pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size()); |
2104 | return n < 0 ? n : n + fromIndex; |
2105 | } |
2106 | #else |
2107 | sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const |
2108 | { |
2109 | sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, |
2110 | str.pData->buffer, str.pData->length ); |
2111 | return (ret < 0 ? ret : ret+fromIndex); |
2112 | } |
2113 | #endif |
2114 | |
2115 | /** |
2116 | @overload |
2117 | This function accepts an ASCII string literal as its argument. |
2118 | @since LibreOffice 3.6 |
2119 | */ |
2120 | template< typename T > |
2121 | typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const |
2122 | { |
2123 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2124, __extension__ __PRETTY_FUNCTION__)) |
2124 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2124, __extension__ __PRETTY_FUNCTION__)); |
2125 | sal_Int32 n = rtl_ustr_indexOfAscii_WithLength( |
2126 | pData->buffer + fromIndex, pData->length - fromIndex, |
2127 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
2128 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
2129 | return n < 0 ? n : n + fromIndex; |
2130 | } |
2131 | |
2132 | /** |
2133 | Returns the index within this string of the first occurrence of the |
2134 | specified ASCII substring, starting at the specified index. |
2135 | |
2136 | @param str |
2137 | the substring to be searched for. Need not be null-terminated, but must |
2138 | be at least as long as the specified len. Must only contain characters |
2139 | in the ASCII range 0x00--7F. |
2140 | |
2141 | @param len |
2142 | the length of the substring; must be non-negative. |
2143 | |
2144 | @param fromIndex |
2145 | the index to start the search from. Must be in the range from zero to |
2146 | the length of this string, inclusive. |
2147 | |
2148 | @return |
2149 | the index (starting at 0) of the first character of the first occurrence |
2150 | of the substring within this string starting at the given fromIndex, or |
2151 | -1 if the substring does not occur. If len is zero, -1 is returned. |
2152 | |
2153 | @since UDK 3.2.7 |
2154 | */ |
2155 | sal_Int32 indexOfAsciiL( |
2156 | char const * str, sal_Int32 len, sal_Int32 fromIndex = 0) const |
2157 | { |
2158 | sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength( |
2159 | pData->buffer + fromIndex, pData->length - fromIndex, str, len); |
2160 | return ret < 0 ? ret : ret + fromIndex; |
2161 | } |
2162 | |
2163 | // This overload is left undefined, to detect calls of indexOfAsciiL that |
2164 | // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of |
2165 | // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit |
2166 | // platforms): |
2167 | #if SAL_TYPES_SIZEOFLONG8 == 8 |
2168 | void indexOfAsciiL(char const *, sal_Int32 len, rtl_TextEncoding) const; |
2169 | #endif |
2170 | |
2171 | /** |
2172 | Returns the index within this string of the last occurrence of |
2173 | the specified substring, searching backward starting at the end. |
2174 | |
2175 | The returned index indicates the starting index of the substring |
2176 | in this string. |
2177 | If str doesn't include any character, always -1 is |
2178 | returned. This is also the case, if both strings are empty. |
2179 | |
2180 | @param str the substring to search for. |
2181 | @return If the string argument occurs one or more times as a substring |
2182 | within this string, then the index of the first character of |
2183 | the last such substring is returned. If it does not occur as |
2184 | a substring, -1 is returned. |
2185 | */ |
2186 | #if defined LIBO_INTERNAL_ONLY1 |
2187 | sal_Int32 lastIndexOf(std::u16string_view sv) const { |
2188 | return rtl_ustr_lastIndexOfStr_WithLength( |
2189 | pData->buffer, pData->length, sv.data(), sv.size()); |
2190 | } |
2191 | #else |
2192 | sal_Int32 lastIndexOf( const OUString & str ) const |
2193 | { |
2194 | return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length, |
2195 | str.pData->buffer, str.pData->length ); |
2196 | } |
2197 | #endif |
2198 | |
2199 | /** |
2200 | Returns the index within this string of the last occurrence of |
2201 | the specified substring, searching backward starting before the specified |
2202 | index. |
2203 | |
2204 | The returned index indicates the starting index of the substring |
2205 | in this string. |
2206 | If str doesn't include any character, always -1 is |
2207 | returned. This is also the case, if both strings are empty. |
2208 | |
2209 | @param str the substring to search for. |
2210 | @param fromIndex the index before which to start the search. |
2211 | @return If the string argument occurs one or more times as a substring |
2212 | within this string before the starting index, then the index |
2213 | of the first character of the last such substring is |
2214 | returned. Otherwise, -1 is returned. |
2215 | */ |
2216 | #if defined LIBO_INTERNAL_ONLY1 |
2217 | sal_Int32 lastIndexOf(std::u16string_view sv, sal_Int32 fromIndex) const { |
2218 | return rtl_ustr_lastIndexOfStr_WithLength(pData->buffer, fromIndex, sv.data(), sv.size()); |
2219 | } |
2220 | #else |
2221 | sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const |
2222 | { |
2223 | return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex, |
2224 | str.pData->buffer, str.pData->length ); |
2225 | } |
2226 | #endif |
2227 | |
2228 | /** |
2229 | @overload |
2230 | This function accepts an ASCII string literal as its argument. |
2231 | @since LibreOffice 3.6 |
2232 | */ |
2233 | template< typename T > |
2234 | typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const |
2235 | { |
2236 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2237, __extension__ __PRETTY_FUNCTION__)) |
2237 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2237, __extension__ __PRETTY_FUNCTION__)); |
2238 | return rtl_ustr_lastIndexOfAscii_WithLength( |
2239 | pData->buffer, pData->length, |
2240 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), |
2241 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
2242 | } |
2243 | |
2244 | /** |
2245 | Returns the index within this string of the last occurrence of the |
2246 | specified ASCII substring. |
2247 | |
2248 | @param str |
2249 | the substring to be searched for. Need not be null-terminated, but must |
2250 | be at least as long as the specified len. Must only contain characters |
2251 | in the ASCII range 0x00--7F. |
2252 | |
2253 | @param len |
2254 | the length of the substring; must be non-negative. |
2255 | |
2256 | @return |
2257 | the index (starting at 0) of the first character of the last occurrence |
2258 | of the substring within this string, or -1 if the substring does not |
2259 | occur. If len is zero, -1 is returned. |
2260 | |
2261 | @since UDK 3.2.7 |
2262 | */ |
2263 | sal_Int32 lastIndexOfAsciiL(char const * str, sal_Int32 len) const |
2264 | { |
2265 | return rtl_ustr_lastIndexOfAscii_WithLength( |
2266 | pData->buffer, pData->length, str, len); |
2267 | } |
2268 | |
2269 | /** |
2270 | Returns a new string that is a substring of this string. |
2271 | |
2272 | The substring begins at the specified beginIndex. If |
2273 | beginIndex is negative or be greater than the length of |
2274 | this string, behaviour is undefined. |
2275 | |
2276 | @param beginIndex the beginning index, inclusive. |
2277 | @return the specified substring. |
2278 | */ |
2279 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString copy( sal_Int32 beginIndex ) const |
2280 | { |
2281 | return copy(beginIndex, getLength() - beginIndex); |
2282 | } |
2283 | |
2284 | /** |
2285 | Returns a new string that is a substring of this string. |
2286 | |
2287 | The substring begins at the specified beginIndex and contains count |
2288 | characters. If either beginIndex or count are negative, |
2289 | or beginIndex + count are greater than the length of this string |
2290 | then behaviour is undefined. |
2291 | |
2292 | @param beginIndex the beginning index, inclusive. |
2293 | @param count the number of characters. |
2294 | @return the specified substring. |
2295 | */ |
2296 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const |
2297 | { |
2298 | rtl_uString *pNew = NULL__null; |
2299 | rtl_uString_newFromSubString( &pNew, pData, beginIndex, count ); |
2300 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2301 | } |
2302 | |
2303 | /** |
2304 | Concatenates the specified string to the end of this string. |
2305 | |
2306 | @param str the string that is concatenated to the end |
2307 | of this string. |
2308 | @return a string that represents the concatenation of this string |
2309 | followed by the string argument. |
2310 | */ |
2311 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString concat( const OUString & str ) const |
2312 | { |
2313 | rtl_uString* pNew = NULL__null; |
2314 | rtl_uString_newConcat( &pNew, pData, str.pData ); |
2315 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2316 | } |
2317 | |
2318 | #ifndef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
2319 | friend OUString operator+( const OUString& rStr1, const OUString& rStr2 ) |
2320 | { |
2321 | return rStr1.concat( rStr2 ); |
2322 | } |
2323 | #endif |
2324 | |
2325 | /** |
2326 | Returns a new string resulting from replacing n = count characters |
2327 | from position index in this string with newStr. |
2328 | |
2329 | @param index the replacing index in str. |
2330 | The index must be greater than or equal to 0 and |
2331 | less than or equal to the length of the string. |
2332 | @param count the count of characters that will be replaced |
2333 | The count must be greater than or equal to 0 and |
2334 | less than or equal to the length of the string minus index. |
2335 | @param newStr the new substring. |
2336 | @return the new string. |
2337 | */ |
2338 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replaceAt( sal_Int32 index, sal_Int32 count, const OUString& newStr ) const |
2339 | { |
2340 | rtl_uString* pNew = NULL__null; |
2341 | rtl_uString_newReplaceStrAt( &pNew, pData, index, count, newStr.pData ); |
2342 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2343 | } |
2344 | |
2345 | /** |
2346 | Returns a new string resulting from replacing all occurrences of |
2347 | oldChar in this string with newChar. |
2348 | |
2349 | If the character oldChar does not occur in the character sequence |
2350 | represented by this object, then the string is assigned with |
2351 | str. |
2352 | |
2353 | @param oldChar the old character. |
2354 | @param newChar the new character. |
2355 | @return a string derived from this string by replacing every |
2356 | occurrence of oldChar with newChar. |
2357 | */ |
2358 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replace( sal_Unicode oldChar, sal_Unicode newChar ) const |
2359 | { |
2360 | rtl_uString* pNew = NULL__null; |
2361 | rtl_uString_newReplace( &pNew, pData, oldChar, newChar ); |
2362 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2363 | } |
2364 | |
2365 | /** |
2366 | Returns a new string resulting from replacing the first occurrence of a |
2367 | given substring with another substring. |
2368 | |
2369 | @param from the substring to be replaced |
2370 | |
2371 | @param to the replacing substring |
2372 | |
2373 | @param[in,out] index pointer to a start index; if the pointer is |
2374 | non-null: upon entry to the function, its value is the index into this |
2375 | string at which to start searching for the \p from substring, the value |
2376 | must be non-negative and not greater than this string's length; upon exiting |
2377 | the function its value is the index into this string at which the |
2378 | replacement took place or -1 if no replacement took place; if the pointer |
2379 | is null, searching always starts at index 0 |
2380 | |
2381 | @since LibreOffice 3.6 |
2382 | */ |
2383 | #if defined LIBO_INTERNAL_ONLY1 |
2384 | [[nodiscard]] OUString replaceFirst( |
2385 | std::u16string_view from, std::u16string_view to, sal_Int32 * index = nullptr) const |
2386 | { |
2387 | rtl_uString * s = nullptr; |
2388 | sal_Int32 i = 0; |
2389 | rtl_uString_newReplaceFirstUtf16LUtf16L( |
2390 | &s, pData, from.data(), from.size(), to.data(), to.size(), |
2391 | index == nullptr ? &i : index); |
2392 | return OUString(s, SAL_NO_ACQUIRE); |
2393 | } |
2394 | #else |
2395 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replaceFirst( |
2396 | OUString const & from, OUString const & to, sal_Int32 * index = NULL__null) const |
2397 | { |
2398 | rtl_uString * s = NULL__null; |
2399 | sal_Int32 i = 0; |
2400 | rtl_uString_newReplaceFirst( |
2401 | &s, pData, from.pData, to.pData, index == NULL__null ? &i : index); |
2402 | return OUString(s, SAL_NO_ACQUIRE); |
2403 | } |
2404 | #endif |
2405 | |
2406 | /** |
2407 | Returns a new string resulting from replacing the first occurrence of a |
2408 | given substring with another substring. |
2409 | |
2410 | @param from ASCII string literal, the substring to be replaced |
2411 | |
2412 | @param to the replacing substring |
2413 | |
2414 | @param[in,out] index pointer to a start index; if the pointer is |
2415 | non-null: upon entry to the function, its value is the index into the this |
2416 | string at which to start searching for the \p from substring, the value |
2417 | must be non-negative and not greater than this string's length; upon exiting |
2418 | the function its value is the index into this string at which the |
2419 | replacement took place or -1 if no replacement took place; if the pointer |
2420 | is null, searching always starts at index 0 |
2421 | |
2422 | @since LibreOffice 3.6 |
2423 | */ |
2424 | #if defined LIBO_INTERNAL_ONLY1 |
2425 | template<typename T> [[nodiscard]] |
2426 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceFirst( |
2427 | T & from, std::u16string_view to, sal_Int32 * index = nullptr) const |
2428 | { |
2429 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2429, __extension__ __PRETTY_FUNCTION__)); |
2430 | rtl_uString * s = nullptr; |
2431 | sal_Int32 i = 0; |
2432 | rtl_uString_newReplaceFirstAsciiLUtf16L( |
2433 | &s, pData, libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), |
2434 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.data(), to.size(), |
2435 | index == nullptr ? &i : index); |
2436 | return OUString(s, SAL_NO_ACQUIRE); |
2437 | } |
2438 | #else |
2439 | template< typename T > |
2440 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to, |
2441 | sal_Int32 * index = NULL__null) const |
2442 | { |
2443 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2443, __extension__ __PRETTY_FUNCTION__)); |
2444 | rtl_uString * s = NULL__null; |
2445 | sal_Int32 i = 0; |
2446 | rtl_uString_newReplaceFirstAsciiL( |
2447 | &s, pData, |
2448 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), |
2449 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.pData, |
2450 | index == NULL__null ? &i : index); |
2451 | return OUString(s, SAL_NO_ACQUIRE); |
2452 | } |
2453 | #endif |
2454 | |
2455 | /** |
2456 | Returns a new string resulting from replacing the first occurrence of a |
2457 | given substring with another substring. |
2458 | |
2459 | @param from the substring to be replaced |
2460 | |
2461 | @param to ASCII string literal, the replacing substring |
2462 | |
2463 | @param[in,out] index pointer to a start index; if the pointer is |
2464 | non-null: upon entry to the function, its value is the index into the this |
2465 | string at which to start searching for the \p from substring, the value |
2466 | must be non-negative and not greater than this string's length; upon exiting |
2467 | the function its value is the index into this string at which the |
2468 | replacement took place or -1 if no replacement took place; if the pointer |
2469 | is null, searching always starts at index 0 |
2470 | |
2471 | @since LibreOffice 5.1 |
2472 | */ |
2473 | #if defined LIBO_INTERNAL_ONLY1 |
2474 | template<typename T> [[nodiscard]] |
2475 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceFirst( |
2476 | std::u16string_view from, T & to, sal_Int32 * index = nullptr) const |
2477 | { |
2478 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2478, __extension__ __PRETTY_FUNCTION__)); |
2479 | rtl_uString * s = nullptr; |
2480 | sal_Int32 i = 0; |
2481 | rtl_uString_newReplaceFirstUtf16LAsciiL( |
2482 | &s, pData, from.data(), from.size(), |
2483 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), |
2484 | libreoffice_internal::ConstCharArrayDetector<T>::length, index == nullptr ? &i : index); |
2485 | return OUString(s, SAL_NO_ACQUIRE); |
2486 | } |
2487 | #else |
2488 | template< typename T > |
2489 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( OUString const & from, T& to, |
2490 | sal_Int32 * index = NULL__null) const |
2491 | { |
2492 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2492, __extension__ __PRETTY_FUNCTION__)); |
2493 | rtl_uString * s = NULL__null; |
2494 | sal_Int32 i = 0; |
2495 | rtl_uString_newReplaceFirstToAsciiL( |
2496 | &s, pData, from.pData, |
2497 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), |
2498 | libreoffice_internal::ConstCharArrayDetector<T>::length, |
2499 | index == NULL__null ? &i : index); |
2500 | return OUString(s, SAL_NO_ACQUIRE); |
2501 | } |
2502 | #endif |
2503 | |
2504 | /** |
2505 | Returns a new string resulting from replacing the first occurrence of a |
2506 | given substring with another substring. |
2507 | |
2508 | @param from ASCII string literal, the substring to be replaced |
2509 | |
2510 | @param to ASCII string literal, the substring to be replaced |
2511 | |
2512 | @param[in,out] index pointer to a start index; if the pointer is |
2513 | non-null: upon entry to the function, its value is the index into the this |
2514 | string at which to start searching for the \p from substring, the value |
2515 | must be non-negative and not greater than this string's length; upon exiting |
2516 | the function its value is the index into this string at which the |
2517 | replacement took place or -1 if no replacement took place; if the pointer |
2518 | is null, searching always starts at index 0 |
2519 | |
2520 | @since LibreOffice 3.6 |
2521 | */ |
2522 | template< typename T1, typename T2 > |
2523 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T1, typename libreoffice_internal::ConstCharArrayDetector< T2, OUString >::Type >::Type |
2524 | replaceFirst( T1& from, T2& to, sal_Int32 * index = NULL__null) const |
2525 | { |
2526 | assert(libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T1>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2526, __extension__ __PRETTY_FUNCTION__)); |
2527 | assert(libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T2>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2527, __extension__ __PRETTY_FUNCTION__)); |
2528 | rtl_uString * s = NULL__null; |
2529 | sal_Int32 i = 0; |
2530 | rtl_uString_newReplaceFirstAsciiLAsciiL( |
2531 | &s, pData, |
2532 | libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), |
2533 | libreoffice_internal::ConstCharArrayDetector<T1>::length, |
2534 | libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), |
2535 | libreoffice_internal::ConstCharArrayDetector<T2>::length, |
2536 | index == NULL__null ? &i : index); |
2537 | return OUString(s, SAL_NO_ACQUIRE); |
2538 | } |
2539 | |
2540 | /** |
2541 | Returns a new string resulting from replacing all occurrences of a given |
2542 | substring with another substring. |
2543 | |
2544 | Replacing subsequent occurrences picks up only after a given replacement. |
2545 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". |
2546 | |
2547 | @param from the substring to be replaced |
2548 | |
2549 | @param to the replacing substring |
2550 | |
2551 | @param fromIndex the position in the string where we will begin searching |
2552 | |
2553 | @since LibreOffice 4.0 |
2554 | */ |
2555 | #if defined LIBO_INTERNAL_ONLY1 |
2556 | [[nodiscard]] OUString replaceAll( |
2557 | std::u16string_view from, std::u16string_view to, sal_Int32 fromIndex = 0) const |
2558 | { |
2559 | rtl_uString * s = nullptr; |
2560 | rtl_uString_newReplaceAllFromIndexUtf16LUtf16L( |
2561 | &s, pData, from.data(), from.size(), to.data(), to.size(), fromIndex); |
2562 | return OUString(s, SAL_NO_ACQUIRE); |
2563 | } |
2564 | #else |
2565 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replaceAll( |
2566 | OUString const & from, OUString const & to, sal_Int32 fromIndex = 0) const |
2567 | { |
2568 | rtl_uString * s = NULL__null; |
2569 | rtl_uString_newReplaceAllFromIndex(&s, pData, from.pData, to.pData, fromIndex); |
2570 | return OUString(s, SAL_NO_ACQUIRE); |
2571 | } |
2572 | #endif |
2573 | |
2574 | /** |
2575 | Returns a new string resulting from replacing all occurrences of a given |
2576 | substring with another substring. |
2577 | |
2578 | Replacing subsequent occurrences picks up only after a given replacement. |
2579 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". |
2580 | |
2581 | @param from ASCII string literal, the substring to be replaced |
2582 | |
2583 | @param to the replacing substring |
2584 | |
2585 | @since LibreOffice 3.6 |
2586 | */ |
2587 | #if defined LIBO_INTERNAL_ONLY1 |
2588 | template<typename T> [[nodiscard]] |
2589 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceAll( |
2590 | T & from, std::u16string_view to) const |
2591 | { |
2592 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2592, __extension__ __PRETTY_FUNCTION__)); |
2593 | rtl_uString * s = nullptr; |
2594 | rtl_uString_newReplaceAllAsciiLUtf16L( |
2595 | &s, pData, libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), |
2596 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.data(), to.size()); |
2597 | return OUString(s, SAL_NO_ACQUIRE); |
2598 | } |
2599 | #else |
2600 | template< typename T > |
2601 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const |
2602 | { |
2603 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2603, __extension__ __PRETTY_FUNCTION__)); |
2604 | rtl_uString * s = NULL__null; |
2605 | rtl_uString_newReplaceAllAsciiL( |
2606 | &s, pData, |
2607 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), |
2608 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.pData); |
2609 | return OUString(s, SAL_NO_ACQUIRE); |
2610 | } |
2611 | #endif |
2612 | |
2613 | /** |
2614 | Returns a new string resulting from replacing all occurrences of a given |
2615 | substring with another substring. |
2616 | |
2617 | Replacing subsequent occurrences picks up only after a given replacement. |
2618 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". |
2619 | |
2620 | @param from the substring to be replaced |
2621 | |
2622 | @param to ASCII string literal, the replacing substring |
2623 | |
2624 | @since LibreOffice 5.1 |
2625 | */ |
2626 | #if defined LIBO_INTERNAL_ONLY1 |
2627 | template<typename T> [[nodiscard]] |
2628 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceAll( |
2629 | std::u16string_view from, T & to) const |
2630 | { |
2631 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2631, __extension__ __PRETTY_FUNCTION__)); |
2632 | rtl_uString * s = nullptr; |
2633 | rtl_uString_newReplaceAllUtf16LAsciiL( |
2634 | &s, pData, from.data(), from.size(), |
2635 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), |
2636 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
2637 | return OUString(s, SAL_NO_ACQUIRE); |
2638 | } |
2639 | #else |
2640 | template< typename T > |
2641 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( OUString const & from, T& to) const |
2642 | { |
2643 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2643, __extension__ __PRETTY_FUNCTION__)); |
2644 | rtl_uString * s = NULL__null; |
2645 | rtl_uString_newReplaceAllToAsciiL( |
2646 | &s, pData, from.pData, |
2647 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), |
2648 | libreoffice_internal::ConstCharArrayDetector<T>::length); |
2649 | return OUString(s, SAL_NO_ACQUIRE); |
2650 | } |
2651 | #endif |
2652 | |
2653 | /** |
2654 | Returns a new string resulting from replacing all occurrences of a given |
2655 | substring with another substring. |
2656 | |
2657 | Replacing subsequent occurrences picks up only after a given replacement. |
2658 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". |
2659 | |
2660 | @param from ASCII string literal, the substring to be replaced |
2661 | |
2662 | @param to ASCII string literal, the substring to be replaced |
2663 | |
2664 | @since LibreOffice 3.6 |
2665 | */ |
2666 | template< typename T1, typename T2 > |
2667 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T1, typename libreoffice_internal::ConstCharArrayDetector< T2, OUString >::Type >::Type |
2668 | replaceAll( T1& from, T2& to ) const |
2669 | { |
2670 | assert(libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T1>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2670, __extension__ __PRETTY_FUNCTION__)); |
2671 | assert(libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T2>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2671, __extension__ __PRETTY_FUNCTION__)); |
2672 | rtl_uString * s = NULL__null; |
2673 | rtl_uString_newReplaceAllAsciiLAsciiL( |
2674 | &s, pData, |
2675 | libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), |
2676 | libreoffice_internal::ConstCharArrayDetector<T1>::length, |
2677 | libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), |
2678 | libreoffice_internal::ConstCharArrayDetector<T2>::length); |
2679 | return OUString(s, SAL_NO_ACQUIRE); |
2680 | } |
2681 | |
2682 | /** |
2683 | Converts from this string all ASCII uppercase characters (65-90) |
2684 | to ASCII lowercase characters (97-122). |
2685 | |
2686 | This function can't be used for language specific conversion. |
2687 | If the string doesn't contain characters which must be converted, |
2688 | then the new string is assigned with str. |
2689 | |
2690 | @return the string, converted to ASCII lowercase. |
2691 | */ |
2692 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString toAsciiLowerCase() const |
2693 | { |
2694 | rtl_uString* pNew = NULL__null; |
2695 | rtl_uString_newToAsciiLowerCase( &pNew, pData ); |
2696 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2697 | } |
2698 | |
2699 | /** |
2700 | Converts from this string all ASCII lowercase characters (97-122) |
2701 | to ASCII uppercase characters (65-90). |
2702 | |
2703 | This function can't be used for language specific conversion. |
2704 | If the string doesn't contain characters which must be converted, |
2705 | then the new string is assigned with str. |
2706 | |
2707 | @return the string, converted to ASCII uppercase. |
2708 | */ |
2709 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString toAsciiUpperCase() const |
2710 | { |
2711 | rtl_uString* pNew = NULL__null; |
2712 | rtl_uString_newToAsciiUpperCase( &pNew, pData ); |
2713 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2714 | } |
2715 | |
2716 | /** |
2717 | Returns a new string resulting from removing white space from both ends |
2718 | of the string. |
2719 | |
2720 | All characters that have codes less than or equal to |
2721 | 32 (the space character), and Unicode General Punctuation area Space |
2722 | and some Control characters are considered to be white space (see |
2723 | rtl_ImplIsWhitespace). |
2724 | If the string doesn't contain white spaces at both ends, |
2725 | then the new string is assigned with str. |
2726 | |
2727 | @return the string, with white space removed from the front and end. |
2728 | */ |
2729 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString trim() const |
2730 | { |
2731 | rtl_uString* pNew = NULL__null; |
2732 | rtl_uString_newTrim( &pNew, pData ); |
2733 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2734 | } |
2735 | |
2736 | /** |
2737 | Returns a token in the string. |
2738 | |
2739 | Example: |
2740 | sal_Int32 nIndex = 0; |
2741 | do |
2742 | { |
2743 | ... |
2744 | OUString aToken = aStr.getToken( 0, ';', nIndex ); |
2745 | ... |
2746 | } |
2747 | while ( nIndex >= 0 ); |
2748 | |
2749 | @param token the number of the token to return |
2750 | @param cTok the character which separate the tokens. |
2751 | @param index the position at which the token is searched in the |
2752 | string. |
2753 | The index must not be greater than the length of the |
2754 | string. |
2755 | This param is set to the position of the |
2756 | next token or to -1, if it is the last token. |
2757 | @return the token; if either token or index is negative, an empty token |
2758 | is returned (and index is set to -1) |
2759 | */ |
2760 | OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const |
2761 | { |
2762 | rtl_uString * pNew = NULL__null; |
2763 | index = rtl_uString_getToken( &pNew, pData, token, cTok, index ); |
2764 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2765 | } |
2766 | |
2767 | /** |
2768 | Returns a token from the string. |
2769 | |
2770 | The same as getToken(sal_Int32, sal_Unicode, sal_Int32 &), but always |
2771 | passing in 0 as the start index in the third argument. |
2772 | |
2773 | @param count the number of the token to return, starting with 0 |
2774 | @param separator the character which separates the tokens |
2775 | |
2776 | @return the given token, or an empty string |
2777 | |
2778 | @since LibreOffice 3.6 |
2779 | */ |
2780 | OUString getToken(sal_Int32 count, sal_Unicode separator) const { |
2781 | sal_Int32 n = 0; |
2782 | return getToken(count, separator, n); |
2783 | } |
2784 | |
2785 | /** |
2786 | Returns the Boolean value from this string. |
2787 | |
2788 | This function can't be used for language specific conversion. |
2789 | |
2790 | @return true, if the string is 1 or "True" in any ASCII case. |
2791 | false in any other case. |
2792 | */ |
2793 | bool toBoolean() const |
2794 | { |
2795 | return rtl_ustr_toBoolean( pData->buffer ); |
2796 | } |
2797 | |
2798 | /** |
2799 | Returns the first character from this string. |
2800 | |
2801 | @return the first character from this string or 0, if this string |
2802 | is empty. |
2803 | */ |
2804 | sal_Unicode toChar() const |
2805 | { |
2806 | return pData->buffer[0]; |
2807 | } |
2808 | |
2809 | /** |
2810 | Returns the int32 value from this string. |
2811 | |
2812 | This function can't be used for language specific conversion. |
2813 | |
2814 | @param radix the radix (between 2 and 36) |
2815 | @return the int32 represented from this string. |
2816 | 0 if this string represents no number or one of too large |
2817 | magnitude. |
2818 | */ |
2819 | sal_Int32 toInt32( sal_Int16 radix = 10 ) const |
2820 | { |
2821 | return rtl_ustr_toInt32( pData->buffer, radix ); |
2822 | } |
2823 | |
2824 | /** |
2825 | Returns the uint32 value from this string. |
2826 | |
2827 | This function can't be used for language specific conversion. |
2828 | |
2829 | @param radix the radix (between 2 and 36) |
2830 | @return the uint32 represented from this string. |
2831 | 0 if this string represents no number or one of too large |
2832 | magnitude. |
2833 | |
2834 | @since LibreOffice 4.2 |
2835 | */ |
2836 | sal_uInt32 toUInt32( sal_Int16 radix = 10 ) const |
2837 | { |
2838 | return rtl_ustr_toUInt32( pData->buffer, radix ); |
2839 | } |
2840 | |
2841 | /** |
2842 | Returns the int64 value from this string. |
2843 | |
2844 | This function can't be used for language specific conversion. |
2845 | |
2846 | @param radix the radix (between 2 and 36) |
2847 | @return the int64 represented from this string. |
2848 | 0 if this string represents no number or one of too large |
2849 | magnitude. |
2850 | */ |
2851 | sal_Int64 toInt64( sal_Int16 radix = 10 ) const |
2852 | { |
2853 | return rtl_ustr_toInt64( pData->buffer, radix ); |
2854 | } |
2855 | |
2856 | /** |
2857 | Returns the uint64 value from this string. |
2858 | |
2859 | This function can't be used for language specific conversion. |
2860 | |
2861 | @param radix the radix (between 2 and 36) |
2862 | @return the uint64 represented from this string. |
2863 | 0 if this string represents no number or one of too large |
2864 | magnitude. |
2865 | |
2866 | @since LibreOffice 4.1 |
2867 | */ |
2868 | sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const |
2869 | { |
2870 | return rtl_ustr_toUInt64( pData->buffer, radix ); |
2871 | } |
2872 | |
2873 | /** |
2874 | Returns the float value from this string. |
2875 | |
2876 | This function can't be used for language specific conversion. |
2877 | |
2878 | @return the float represented from this string. |
2879 | 0.0 if this string represents no number. |
2880 | */ |
2881 | float toFloat() const |
2882 | { |
2883 | return rtl_ustr_toFloat( pData->buffer ); |
2884 | } |
2885 | |
2886 | /** |
2887 | Returns the double value from this string. |
2888 | |
2889 | This function can't be used for language specific conversion. |
2890 | |
2891 | @return the double represented from this string. |
2892 | 0.0 if this string represents no number. |
2893 | */ |
2894 | double toDouble() const |
2895 | { |
2896 | return rtl_ustr_toDouble( pData->buffer ); |
2897 | } |
2898 | |
2899 | |
2900 | /** |
2901 | Return a canonical representation for a string. |
2902 | |
2903 | A pool of strings, initially empty is maintained privately |
2904 | by the string class. On invocation, if present in the pool |
2905 | the original string will be returned. Otherwise this string, |
2906 | or a copy thereof will be added to the pool and returned. |
2907 | |
2908 | @return |
2909 | a version of the string from the pool. |
2910 | |
2911 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs |
2912 | |
2913 | @since UDK 3.2.7 |
2914 | */ |
2915 | OUString intern() const |
2916 | { |
2917 | rtl_uString * pNew = NULL__null; |
2918 | rtl_uString_intern( &pNew, pData ); |
2919 | if (pNew == NULL__null) { |
2920 | throw std::bad_alloc(); |
2921 | } |
2922 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2923 | } |
2924 | |
2925 | /** |
2926 | Return a canonical representation for a converted string. |
2927 | |
2928 | A pool of strings, initially empty is maintained privately |
2929 | by the string class. On invocation, if present in the pool |
2930 | the original string will be returned. Otherwise this string, |
2931 | or a copy thereof will be added to the pool and returned. |
2932 | |
2933 | @param value a 8-Bit character array. |
2934 | @param length the number of character which should be converted. |
2935 | The 8-Bit character array length must be |
2936 | greater than or equal to this value. |
2937 | @param encoding the text encoding from which the 8-Bit character |
2938 | sequence should be converted. |
2939 | @param convertFlags flags which controls the conversion. |
2940 | see RTL_TEXTTOUNICODE_FLAGS_... |
2941 | @param pInfo pointer to return conversion status or NULL. |
2942 | |
2943 | @return |
2944 | a version of the converted string from the pool. |
2945 | |
2946 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs |
2947 | |
2948 | @since UDK 3.2.7 |
2949 | */ |
2950 | static OUString intern( const char * value, sal_Int32 length, |
2951 | rtl_TextEncoding encoding, |
2952 | sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )), |
2953 | sal_uInt32 *pInfo = NULL__null ) |
2954 | { |
2955 | rtl_uString * pNew = NULL__null; |
2956 | rtl_uString_internConvert( &pNew, value, length, encoding, |
2957 | convertFlags, pInfo ); |
2958 | if (pNew == NULL__null) { |
2959 | throw std::bad_alloc(); |
2960 | } |
2961 | return OUString( pNew, SAL_NO_ACQUIRE ); |
2962 | } |
2963 | |
2964 | /** |
2965 | Converts to an OString, signalling failure. |
2966 | |
2967 | @param pTarget |
2968 | An out parameter receiving the converted OString. Must not be null; the |
2969 | contents are not modified if conversion fails (convertToOString returns |
2970 | false). |
2971 | |
2972 | @param nEncoding |
2973 | The text encoding to convert into. Must be an octet encoding (i.e., |
2974 | rtl_isOctetTextEncoding(nEncoding) must return true). |
2975 | |
2976 | @param nFlags |
2977 | A combination of RTL_UNICODETOTEXT_FLAGS that detail how to do the |
2978 | conversion (see rtl_convertUnicodeToText). RTL_UNICODETOTEXT_FLAGS_FLUSH |
2979 | need not be included, it is implicitly assumed. Typical uses are either |
2980 | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | |
2981 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR (fail if a Unicode character cannot |
2982 | be converted to the target nEncoding) or OUSTRING_TO_OSTRING_CVTFLAGS |
2983 | (make a best efforts conversion). |
2984 | |
2985 | @return |
2986 | True if the conversion succeeded, false otherwise. |
2987 | */ |
2988 | bool convertToString(OString * pTarget, rtl_TextEncoding nEncoding, |
2989 | sal_uInt32 nFlags) const |
2990 | { |
2991 | return rtl_convertUStringToString(&pTarget->pData, pData->buffer, |
2992 | pData->length, nEncoding, nFlags); |
2993 | } |
2994 | |
2995 | /** Iterate through this string based on code points instead of UTF-16 code |
2996 | units. |
2997 | |
2998 | See Chapter 3 of The Unicode Standard 5.0 (Addison--Wesley, 2006) for |
2999 | definitions of the various terms used in this description. |
3000 | |
3001 | This string is interpreted as a sequence of zero or more UTF-16 code |
3002 | units. For each index into this sequence (from zero to one less than |
3003 | the length of the sequence, inclusive), a code point represented |
3004 | starting at the given index is computed as follows: |
3005 | |
3006 | - If the UTF-16 code unit addressed by the index constitutes a |
3007 | well-formed UTF-16 code unit sequence, the computed code point is the |
3008 | scalar value encoded by that UTF-16 code unit sequence. |
3009 | |
3010 | - Otherwise, if the index is at least two UTF-16 code units away from |
3011 | the end of the sequence, and the sequence of two UTF-16 code units |
3012 | addressed by the index constitutes a well-formed UTF-16 code unit |
3013 | sequence, the computed code point is the scalar value encoded by that |
3014 | UTF-16 code unit sequence. |
3015 | |
3016 | - Otherwise, the computed code point is the UTF-16 code unit addressed |
3017 | by the index. (This last case catches unmatched surrogates as well as |
3018 | indices pointing into the middle of surrogate pairs.) |
3019 | |
3020 | @param indexUtf16 |
3021 | pointer to a UTF-16 based index into this string; must not be null. On |
3022 | entry, the index must be in the range from zero to the length of this |
3023 | string (in UTF-16 code units), inclusive. Upon successful return, the |
3024 | index will be updated to address the UTF-16 code unit that is the given |
3025 | incrementCodePoints away from the initial index. |
3026 | |
3027 | @param incrementCodePoints |
3028 | the number of code points to move the given *indexUtf16. If |
3029 | non-negative, moving is done after determining the code point at the |
3030 | index. If negative, moving is done before determining the code point |
3031 | at the (then updated) index. The value must be such that the resulting |
3032 | UTF-16 based index is in the range from zero to the length of this |
3033 | string (in UTF-16 code units), inclusive. |
3034 | |
3035 | @return |
3036 | the code point (an integer in the range from 0 to 0x10FFFF, inclusive) |
3037 | that is represented within this string starting at the index computed as |
3038 | follows: If incrementCodePoints is non-negative, the index is the |
3039 | initial value of *indexUtf16; if incrementCodePoints is negative, the |
3040 | index is the updated value of *indexUtf16. In either case, the computed |
3041 | index must be in the range from zero to one less than the length of this |
3042 | string (in UTF-16 code units), inclusive. |
3043 | |
3044 | @since UDK 3.2.7 |
3045 | */ |
3046 | sal_uInt32 iterateCodePoints( |
3047 | sal_Int32 * indexUtf16, sal_Int32 incrementCodePoints = 1) const |
3048 | { |
3049 | return rtl_uString_iterateCodePoints( |
3050 | pData, indexUtf16, incrementCodePoints); |
3051 | } |
3052 | |
3053 | /** |
3054 | * Convert an OString to an OUString, assuming that the OString is |
3055 | * UTF-8-encoded. |
3056 | * |
3057 | * @param rSource |
3058 | * an OString to convert |
3059 | * |
3060 | * @since LibreOffice 4.4 |
3061 | */ |
3062 | static OUString fromUtf8(const OString& rSource) |
3063 | { |
3064 | OUString aTarget; |
3065 | bool bSuccess = rtl_convertStringToUString(&aTarget.pData, |
3066 | rSource.getStr(), |
3067 | rSource.getLength(), |
3068 | RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), |
3069 | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR((sal_uInt32)0x0001)|RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR((sal_uInt32)0x0010)|RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR((sal_uInt32)0x0100)); |
3070 | (void) bSuccess; |
3071 | assert(bSuccess)(static_cast <bool> (bSuccess) ? void (0) : __assert_fail ("bSuccess", "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 3071, __extension__ __PRETTY_FUNCTION__)); |
3072 | return aTarget; |
3073 | } |
3074 | |
3075 | /** |
3076 | * Convert this string to an OString, assuming that the string can be |
3077 | * UTF-8-encoded successfully. |
3078 | * |
3079 | * In other words, you must not use this method on a random sequence of |
3080 | * UTF-16 code units, but only at places where it is assumed that the |
3081 | * content is a proper string. |
3082 | * |
3083 | * @since LibreOffice 4.4 |
3084 | */ |
3085 | OString toUtf8() const |
3086 | { |
3087 | OString aTarget; |
3088 | bool bSuccess = rtl_convertUStringToString(&aTarget.pData, |
3089 | getStr(), |
3090 | getLength(), |
3091 | RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), |
3092 | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR((sal_uInt32)0x0001)|RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR((sal_uInt32)0x0010)); |
3093 | (void) bSuccess; |
3094 | assert(bSuccess)(static_cast <bool> (bSuccess) ? void (0) : __assert_fail ("bSuccess", "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 3094, __extension__ __PRETTY_FUNCTION__)); |
3095 | return aTarget; |
3096 | } |
3097 | |
3098 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
3099 | |
3100 | static OUStringNumber< int > number( int i, sal_Int16 radix = 10 ) |
3101 | { |
3102 | return OUStringNumber< int >( i, radix ); |
3103 | } |
3104 | static OUStringNumber< long long > number( long long ll, sal_Int16 radix = 10 ) |
3105 | { |
3106 | return OUStringNumber< long long >( ll, radix ); |
3107 | } |
3108 | static OUStringNumber< unsigned long long > number( unsigned long long ll, sal_Int16 radix = 10 ) |
3109 | { |
3110 | return OUStringNumber< unsigned long long >( ll, radix ); |
3111 | } |
3112 | static OUStringNumber< unsigned long long > number( unsigned int i, sal_Int16 radix = 10 ) |
3113 | { |
3114 | return number( static_cast< unsigned long long >( i ), radix ); |
3115 | } |
3116 | static OUStringNumber< long long > number( long i, sal_Int16 radix = 10) |
3117 | { |
3118 | return number( static_cast< long long >( i ), radix ); |
3119 | } |
3120 | static OUStringNumber< unsigned long long > number( unsigned long i, sal_Int16 radix = 10 ) |
3121 | { |
3122 | return number( static_cast< unsigned long long >( i ), radix ); |
3123 | } |
3124 | static OUStringNumber< float > number( float f ) |
3125 | { |
3126 | return OUStringNumber< float >( f ); |
3127 | } |
3128 | static OUStringNumber< double > number( double d ) |
3129 | { |
3130 | return OUStringNumber< double >( d ); |
3131 | } |
3132 | #else |
3133 | /** |
3134 | Returns the string representation of the integer argument. |
3135 | |
3136 | This function can't be used for language specific conversion. |
3137 | |
3138 | @param i an integer value |
3139 | @param radix the radix (between 2 and 36) |
3140 | @return a string with the string representation of the argument. |
3141 | @since LibreOffice 4.1 |
3142 | */ |
3143 | static OUString number( int i, sal_Int16 radix = 10 ) |
3144 | { |
3145 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT3233]; |
3146 | return OUString(aBuf, rtl_ustr_valueOfInt32(aBuf, i, radix)); |
3147 | } |
3148 | /// @overload |
3149 | /// @since LibreOffice 4.1 |
3150 | static OUString number( unsigned int i, sal_Int16 radix = 10 ) |
3151 | { |
3152 | return number( static_cast< unsigned long long >( i ), radix ); |
3153 | } |
3154 | /// @overload |
3155 | /// @since LibreOffice 4.1 |
3156 | static OUString number( long i, sal_Int16 radix = 10) |
3157 | { |
3158 | return number( static_cast< long long >( i ), radix ); |
3159 | } |
3160 | /// @overload |
3161 | /// @since LibreOffice 4.1 |
3162 | static OUString number( unsigned long i, sal_Int16 radix = 10 ) |
3163 | { |
3164 | return number( static_cast< unsigned long long >( i ), radix ); |
3165 | } |
3166 | /// @overload |
3167 | /// @since LibreOffice 4.1 |
3168 | static OUString number( long long ll, sal_Int16 radix = 10 ) |
3169 | { |
3170 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT6465]; |
3171 | return OUString(aBuf, rtl_ustr_valueOfInt64(aBuf, ll, radix)); |
3172 | } |
3173 | /// @overload |
3174 | /// @since LibreOffice 4.1 |
3175 | static OUString number( unsigned long long ll, sal_Int16 radix = 10 ) |
3176 | { |
3177 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFUINT6465]; |
3178 | return OUString(aBuf, rtl_ustr_valueOfUInt64(aBuf, ll, radix)); |
3179 | } |
3180 | |
3181 | /** |
3182 | Returns the string representation of the float argument. |
3183 | |
3184 | This function can't be used for language specific conversion. |
3185 | |
3186 | @param f a float. |
3187 | @return a string with the decimal representation of the argument. |
3188 | @since LibreOffice 4.1 |
3189 | */ |
3190 | static OUString number( float f ) |
3191 | { |
3192 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFFLOAT15]; |
3193 | return OUString(aBuf, rtl_ustr_valueOfFloat(aBuf, f)); |
3194 | } |
3195 | |
3196 | /** |
3197 | Returns the string representation of the double argument. |
3198 | |
3199 | This function can't be used for language specific conversion. |
3200 | |
3201 | @param d a double. |
3202 | @return a string with the decimal representation of the argument. |
3203 | @since LibreOffice 4.1 |
3204 | */ |
3205 | static OUString number( double d ) |
3206 | { |
3207 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFDOUBLE25]; |
3208 | return OUString(aBuf, rtl_ustr_valueOfDouble(aBuf, d)); |
3209 | } |
3210 | #endif |
3211 | |
3212 | /** |
3213 | Returns the string representation of the sal_Bool argument. |
3214 | |
3215 | If the sal_Bool is true, the string "true" is returned. |
3216 | If the sal_Bool is false, the string "false" is returned. |
3217 | This function can't be used for language specific conversion. |
3218 | |
3219 | @param b a sal_Bool. |
3220 | @return a string with the string representation of the argument. |
3221 | @deprecated use boolean() |
3222 | */ |
3223 | SAL_DEPRECATED("use boolean()")__attribute__((deprecated("use boolean()"))) static OUString valueOf( sal_Bool b ) |
3224 | { |
3225 | return boolean(b); |
3226 | } |
3227 | |
3228 | /** |
3229 | Returns the string representation of the boolean argument. |
3230 | |
3231 | If the argument is true, the string "true" is returned. |
3232 | If the argument is false, the string "false" is returned. |
3233 | This function can't be used for language specific conversion. |
3234 | |
3235 | @param b a bool. |
3236 | @return a string with the string representation of the argument. |
3237 | @since LibreOffice 4.1 |
3238 | */ |
3239 | static OUString boolean( bool b ) |
3240 | { |
3241 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFBOOLEAN6]; |
3242 | return OUString(aBuf, rtl_ustr_valueOfBoolean(aBuf, b)); |
3243 | } |
3244 | |
3245 | /** |
3246 | Returns the string representation of the char argument. |
3247 | |
3248 | @param c a character. |
3249 | @return a string with the string representation of the argument. |
3250 | @deprecated use operator, function or constructor taking char or sal_Unicode argument |
3251 | */ |
3252 | SAL_DEPRECATED("convert to OUString or use directly")__attribute__((deprecated("convert to OUString or use directly" ))) static OUString valueOf( sal_Unicode c ) |
3253 | { |
3254 | return OUString( &c, 1 ); |
3255 | } |
3256 | |
3257 | /** |
3258 | Returns the string representation of the int argument. |
3259 | |
3260 | This function can't be used for language specific conversion. |
3261 | |
3262 | @param i a int32. |
3263 | @param radix the radix (between 2 and 36) |
3264 | @return a string with the string representation of the argument. |
3265 | @deprecated use number() |
3266 | */ |
3267 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) |
3268 | { |
3269 | return number( i, radix ); |
3270 | } |
3271 | |
3272 | /** |
3273 | Returns the string representation of the long argument. |
3274 | |
3275 | This function can't be used for language specific conversion. |
3276 | |
3277 | @param ll a int64. |
3278 | @param radix the radix (between 2 and 36) |
3279 | @return a string with the string representation of the argument. |
3280 | @deprecated use number() |
3281 | */ |
3282 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) |
3283 | { |
3284 | return number( ll, radix ); |
3285 | } |
3286 | |
3287 | /** |
3288 | Returns the string representation of the float argument. |
3289 | |
3290 | This function can't be used for language specific conversion. |
3291 | |
3292 | @param f a float. |
3293 | @return a string with the string representation of the argument. |
3294 | @deprecated use number() |
3295 | */ |
3296 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( float f ) |
3297 | { |
3298 | return number(f); |
3299 | } |
3300 | |
3301 | /** |
3302 | Returns the string representation of the double argument. |
3303 | |
3304 | This function can't be used for language specific conversion. |
3305 | |
3306 | @param d a double. |
3307 | @return a string with the string representation of the argument. |
3308 | @deprecated use number() |
3309 | */ |
3310 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( double d ) |
3311 | { |
3312 | return number(d); |
3313 | } |
3314 | |
3315 | /** |
3316 | Returns an OUString copied without conversion from an ASCII |
3317 | character string. |
3318 | |
3319 | Since this method is optimized for performance, the ASCII character |
3320 | values are not converted in any way. The caller has to make sure that |
3321 | all ASCII characters are in the allowed range between 0 and 127. |
3322 | The ASCII string must be NULL-terminated. |
3323 | |
3324 | Note that for string literals it is simpler and more efficient |
3325 | to directly use the OUString constructor. |
3326 | |
3327 | @param value the 8-Bit ASCII character string |
3328 | @return a string with the string representation of the argument. |
3329 | */ |
3330 | static OUString createFromAscii( const char * value ) |
3331 | { |
3332 | rtl_uString* pNew = NULL__null; |
3333 | rtl_uString_newFromAscii( &pNew, value ); |
3334 | return OUString( pNew, SAL_NO_ACQUIRE ); |
3335 | } |
3336 | |
3337 | #if defined LIBO_INTERNAL_ONLY1 |
3338 | static OUString createFromAscii(std::string_view value) { |
3339 | rtl_uString * p = nullptr; |
3340 | rtl_uString_newFromLiteral(&p, value.data(), value.size(), 0); //TODO: check for overflow |
3341 | return OUString(p, SAL_NO_ACQUIRE); |
3342 | } |
3343 | #endif |
3344 | |
3345 | #if defined LIBO_INTERNAL_ONLY1 |
3346 | operator std::u16string_view() const { return {getStr(), sal_uInt32(getLength())}; } |
3347 | #endif |
3348 | |
3349 | #if defined LIBO_INTERNAL_ONLY1 |
3350 | // A wrapper for the first expression in an |
3351 | // |
3352 | // OUString::Concat(e1) + e2 + ... |
3353 | // |
3354 | // concatenation chain, when neither of the first two e1, e2 is one of our rtl string-related |
3355 | // classes (so something like |
3356 | // |
3357 | // OUString s = "a" + (b ? std::u16string_view(u"c") : std::u16string_view(u"dd")); |
3358 | // |
3359 | // would not compile): |
3360 | template<typename T> [[nodiscard]] static |
3361 | typename std::enable_if_t< |
3362 | ToStringHelper<T>::allowOUStringConcat, OUStringConcat<OUStringConcatMarker, T>> |
3363 | Concat(T const & value) { return OUStringConcat<OUStringConcatMarker, T>({}, value); } |
3364 | |
3365 | // This overload is needed so that an argument of type 'char const[N]' ends up as |
3366 | // 'OUStringConcat<rtl::OUStringConcatMarker, char const[N]>' rather than as |
3367 | // 'OUStringConcat<rtl::OUStringConcatMarker, char[N]>': |
3368 | template<typename T, std::size_t N> [[nodiscard]] static |
3369 | typename std::enable_if_t< |
3370 | ToStringHelper<T[N]>::allowOUStringConcat, OUStringConcat<OUStringConcatMarker, T[N]>> |
3371 | Concat(T (& value)[N]) { return OUStringConcat<OUStringConcatMarker, T[N]>({}, value); } |
3372 | #endif |
3373 | |
3374 | private: |
3375 | OUString & internalAppend( rtl_uString* pOtherData ) |
3376 | { |
3377 | rtl_uString* pNewData = NULL__null; |
3378 | rtl_uString_newConcat( &pNewData, pData, pOtherData ); |
3379 | if (pNewData == NULL__null) { |
3380 | throw std::bad_alloc(); |
3381 | } |
3382 | rtl_uString_assign(&pData, pNewData); |
3383 | rtl_uString_release(pNewData); |
3384 | return *this; |
3385 | } |
3386 | |
3387 | }; |
3388 | |
3389 | #if defined LIBO_INTERNAL_ONLY1 |
3390 | // Prevent the operator ==/!= overloads with 'sal_Unicode const *' parameter from |
3391 | // being selected for nonsensical code like |
3392 | // |
3393 | // if (ouIdAttr == nullptr) |
3394 | // |
3395 | void operator ==(OUString const &, std::nullptr_t) = delete; |
3396 | void operator ==(std::nullptr_t, OUString const &) = delete; |
3397 | void operator !=(OUString const &, std::nullptr_t) = delete; |
3398 | void operator !=(std::nullptr_t, OUString const &) = delete; |
3399 | #endif |
3400 | |
3401 | #if defined LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
3402 | /// @cond INTERNAL |
3403 | |
3404 | /** |
3405 | @internal |
3406 | */ |
3407 | template<> |
3408 | struct ToStringHelper< OUString > |
3409 | { |
3410 | static std::size_t length( const OUString& s ) { return s.getLength(); } |
3411 | static sal_Unicode* addData( sal_Unicode* buffer, const OUString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); } |
3412 | static const bool allowOStringConcat = false; |
3413 | static const bool allowOUStringConcat = true; |
3414 | }; |
3415 | |
3416 | /** |
3417 | @internal |
3418 | */ |
3419 | template<std::size_t N> |
3420 | struct ToStringHelper< OUStringLiteral<N> > |
3421 | { |
3422 | static std::size_t length( const OUStringLiteral<N>& str ) { return str.getLength(); } |
3423 | static sal_Unicode* addData( sal_Unicode* buffer, const OUStringLiteral<N>& str ) { return addDataHelper( buffer, str.getStr(), str.getLength() ); } |
3424 | static const bool allowOStringConcat = false; |
3425 | static const bool allowOUStringConcat = true; |
3426 | }; |
3427 | |
3428 | /** |
3429 | @internal |
3430 | */ |
3431 | template< typename charT, typename traits, typename T1, typename T2 > |
3432 | inline std::basic_ostream<charT, traits> & operator <<( |
3433 | std::basic_ostream<charT, traits> & stream, OUStringConcat< T1, T2 >&& concat) |
3434 | { |
3435 | return stream << OUString( std::move(concat) ); |
3436 | } |
3437 | |
3438 | /// @endcond |
3439 | #endif |
3440 | |
3441 | /** A helper to use OUStrings with hash maps. |
3442 | |
3443 | Instances of this class are unary function objects that can be used as |
3444 | hash function arguments to std::unordered_map and similar constructs. |
3445 | */ |
3446 | struct OUStringHash |
3447 | { |
3448 | /** Compute a hash code for a string. |
3449 | |
3450 | @param rString |
3451 | a string. |
3452 | |
3453 | @return |
3454 | a hash code for the string. This hash code should not be stored |
3455 | persistently, as its computation may change in later revisions. |
3456 | */ |
3457 | size_t operator()(const OUString& rString) const |
3458 | { return static_cast<size_t>(rString.hashCode()); } |
3459 | }; |
3460 | |
3461 | /* ======================================================================= */ |
3462 | |
3463 | /** Convert an OString to an OUString, using a specific text encoding. |
3464 | |
3465 | The lengths of the two strings may differ (e.g., for double-byte |
3466 | encodings, UTF-7, UTF-8). |
3467 | |
3468 | @param rStr |
3469 | an OString to convert. |
3470 | |
3471 | @param encoding |
3472 | the text encoding to use for conversion. |
3473 | |
3474 | @param convertFlags |
3475 | flags which control the conversion. Either use |
3476 | OSTRING_TO_OUSTRING_CVTFLAGS, or see |
3477 | <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more |
3478 | details. |
3479 | */ |
3480 | inline OUString OStringToOUString( const OString & rStr, |
3481 | rtl_TextEncoding encoding, |
3482 | sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )) ) |
3483 | { |
3484 | return OUString( rStr.getStr(), rStr.getLength(), encoding, convertFlags ); |
3485 | } |
3486 | |
3487 | /** Convert an OUString to an OString, using a specific text encoding. |
3488 | |
3489 | The lengths of the two strings may differ (e.g., for double-byte |
3490 | encodings, UTF-7, UTF-8). |
3491 | |
3492 | @param rUnicode |
3493 | an OUString to convert. |
3494 | |
3495 | @param encoding |
3496 | the text encoding to use for conversion. |
3497 | |
3498 | @param convertFlags |
3499 | flags which control the conversion. Either use |
3500 | OUSTRING_TO_OSTRING_CVTFLAGS, or see |
3501 | <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more |
3502 | details. |
3503 | */ |
3504 | inline OString OUStringToOString( const OUString & rUnicode, |
3505 | rtl_TextEncoding encoding, |
3506 | sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS(((sal_uInt32)0x0006) | ((sal_uInt32)0x0060) | ((sal_uInt32)0x0100 ) | ((sal_uInt32)0x0400)) ) |
3507 | { |
3508 | return OString( rUnicode.getStr(), rUnicode.getLength(), encoding, convertFlags ); |
3509 | } |
3510 | |
3511 | /* ======================================================================= */ |
3512 | |
3513 | /** |
3514 | Support for rtl::OUString in std::ostream (and thus in |
3515 | CPPUNIT_ASSERT or SAL_INFO macros, for example). |
3516 | |
3517 | The rtl::OUString is converted to UTF-8. |
3518 | |
3519 | @since LibreOffice 3.5. |
3520 | */ |
3521 | template< typename charT, typename traits > |
3522 | inline std::basic_ostream<charT, traits> & operator <<( |
3523 | std::basic_ostream<charT, traits> & stream, OUString const & rString) |
3524 | { |
3525 | return stream << |
3526 | OUStringToOString(rString, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))); |
3527 | // best effort; potentially loses data due to conversion failures |
3528 | // (stray surrogate halves) and embedded null characters |
3529 | } |
3530 | |
3531 | } // namespace |
3532 | |
3533 | #ifdef RTL_STRING_UNITTEST |
3534 | namespace rtl |
3535 | { |
3536 | typedef rtlunittest::OUString OUString; |
3537 | } |
3538 | #endif |
3539 | |
3540 | // In internal code, allow to use classes like OUString without having to |
3541 | // explicitly refer to the rtl namespace, which is kind of superfluous given |
3542 | // that OUString itself is namespaced by its OU prefix: |
3543 | #if defined LIBO_INTERNAL_ONLY1 && !defined RTL_STRING_UNITTEST |
3544 | using ::rtl::OUString; |
3545 | using ::rtl::OUStringHash; |
3546 | using ::rtl::OStringToOUString; |
3547 | using ::rtl::OUStringToOString; |
3548 | using ::rtl::OUStringLiteral; |
3549 | using ::rtl::OUStringChar; |
3550 | #endif |
3551 | |
3552 | /// @cond INTERNAL |
3553 | /** |
3554 | Make OUString hashable by default for use in STL containers. |
3555 | |
3556 | @since LibreOffice 6.0 |
3557 | */ |
3558 | #if defined LIBO_INTERNAL_ONLY1 |
3559 | namespace std { |
3560 | |
3561 | template<> |
3562 | struct hash<::rtl::OUString> |
3563 | { |
3564 | std::size_t operator()(::rtl::OUString const & s) const |
3565 | { return std::size_t(s.hashCode()); } |
3566 | }; |
3567 | |
3568 | } |
3569 | |
3570 | #endif |
3571 | /// @endcond |
3572 | |
3573 | #endif /* _RTL_USTRING_HXX */ |
3574 | |
3575 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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_ANY_HXX |
20 | #define INCLUDED_COM_SUN_STAR_UNO_ANY_HXX |
21 | |
22 | #include "sal/config.h" |
23 | |
24 | #include <algorithm> |
25 | #include <cassert> |
26 | #include <cstddef> |
27 | #include <iomanip> |
28 | #include <ostream> |
29 | #include <utility> |
30 | |
31 | #include "com/sun/star/uno/Any.h" |
32 | #include "uno/data.h" |
33 | #include "uno/sequence2.h" |
34 | #include "com/sun/star/uno/Type.hxx" |
35 | #include "com/sun/star/uno/Reference.h" |
36 | #include "com/sun/star/uno/genfunc.hxx" |
37 | #include "com/sun/star/uno/RuntimeException.hpp" |
38 | #include "cppu/cppudllapi.h" |
39 | #include "cppu/unotype.hxx" |
40 | |
41 | extern "C" CPPU_DLLPUBLIC__attribute__ ((visibility("default"))) rtl_uString * SAL_CALL cppu_Any_extraction_failure_msg( |
42 | uno_Any const * pAny, typelib_TypeDescriptionReference * pType ) |
43 | SAL_THROW_EXTERN_C()throw (); |
44 | |
45 | namespace com |
46 | { |
47 | namespace sun |
48 | { |
49 | namespace star |
50 | { |
51 | namespace uno |
52 | { |
53 | |
54 | |
55 | inline Any::Any() |
56 | { |
57 | ::uno_any_construct( this, NULL__null, NULL__null, cpp_acquire ); |
58 | } |
59 | |
60 | |
61 | template <typename T> |
62 | inline Any::Any( T const & value ) |
63 | { |
64 | ::uno_type_any_construct( |
65 | this, const_cast<T *>(&value), |
66 | ::cppu::getTypeFavourUnsigned(&value).getTypeLibType(), |
67 | cpp_acquire ); |
68 | } |
69 | |
70 | inline Any::Any( bool value ) |
71 | { |
72 | sal_Bool b = value; |
73 | ::uno_type_any_construct( |
74 | this, &b, cppu::UnoType<bool>::get().getTypeLibType(), |
75 | cpp_acquire ); |
76 | } |
77 | |
78 | #if defined LIBO_INTERNAL_ONLY1 |
79 | template<typename T1, typename T2> |
80 | Any::Any(rtl::OUStringConcat<T1, T2> && value): |
81 | Any(rtl::OUString(std::move(value))) |
82 | {} |
83 | #endif |
84 | |
85 | inline Any::Any( const Any & rAny ) |
86 | { |
87 | ::uno_type_any_construct( this, rAny.pData, rAny.pType, cpp_acquire ); |
88 | } |
89 | |
90 | inline Any::Any( const void * pData_, const Type & rType ) |
91 | { |
92 | ::uno_type_any_construct( |
93 | this, const_cast< void * >( pData_ ), rType.getTypeLibType(), |
94 | cpp_acquire ); |
95 | } |
96 | |
97 | inline Any::Any( const void * pData_, typelib_TypeDescription * pTypeDescr ) |
98 | { |
99 | ::uno_any_construct( |
100 | this, const_cast< void * >( pData_ ), pTypeDescr, cpp_acquire ); |
101 | } |
102 | |
103 | inline Any::Any( const void * pData_, typelib_TypeDescriptionReference * pType_ ) |
104 | { |
105 | ::uno_type_any_construct( |
106 | this, const_cast< void * >( pData_ ), pType_, cpp_acquire ); |
107 | } |
108 | |
109 | inline Any::~Any() |
110 | { |
111 | ::uno_any_destruct( |
112 | this, cpp_release ); |
113 | } |
114 | |
115 | inline Any & Any::operator = ( const Any & rAny ) |
116 | { |
117 | if (this != &rAny) |
118 | { |
119 | ::uno_type_any_assign( |
120 | this, rAny.pData, rAny.pType, |
121 | cpp_acquire, cpp_release ); |
122 | } |
123 | return *this; |
124 | } |
125 | |
126 | #if defined LIBO_INTERNAL_ONLY1 |
127 | |
128 | namespace detail { |
129 | |
130 | inline void moveAnyInternals(Any & from, Any & to) noexcept { |
131 | uno_any_construct(&to, nullptr, nullptr, &cpp_acquire); |
132 | std::swap(from.pType, to.pType); |
133 | std::swap(from.pData, to.pData); |
134 | std::swap(from.pReserved, to.pReserved); |
135 | if (to.pData == &from.pReserved) { |
136 | to.pData = &to.pReserved; |
137 | } |
138 | // This leaves from.pData (where "from" is now VOID) dangling to somewhere (cf. |
139 | // CONSTRUCT_EMPTY_ANY, cppu/source/uno/prim.hxx), but what's relevant is |
140 | // only that it isn't a nullptr (as e.g. >>= -> uno_type_assignData -> |
141 | // _assignData takes a null pSource to mean "construct a default value"). |
142 | } |
143 | |
144 | } |
145 | |
146 | Any::Any(Any && other) noexcept { |
147 | detail::moveAnyInternals(other, *this); |
148 | } |
149 | |
150 | Any & Any::operator =(Any && other) noexcept { |
151 | uno_any_destruct(this, &cpp_release); |
152 | detail::moveAnyInternals(other, *this); |
153 | return *this; |
154 | } |
155 | |
156 | #endif |
157 | |
158 | inline ::rtl::OUString Any::getValueTypeName() const |
159 | { |
160 | return ::rtl::OUString( pType->pTypeName ); |
161 | } |
162 | |
163 | inline void Any::setValue( const void * pData_, const Type & rType ) |
164 | { |
165 | ::uno_type_any_assign( |
166 | this, const_cast< void * >( pData_ ), rType.getTypeLibType(), |
167 | cpp_acquire, cpp_release ); |
168 | } |
169 | |
170 | inline void Any::setValue( const void * pData_, typelib_TypeDescriptionReference * pType_ ) |
171 | { |
172 | ::uno_type_any_assign( |
173 | this, const_cast< void * >( pData_ ), pType_, |
174 | cpp_acquire, cpp_release ); |
175 | } |
176 | |
177 | inline void Any::setValue( const void * pData_, typelib_TypeDescription * pTypeDescr ) |
178 | { |
179 | ::uno_any_assign( |
180 | this, const_cast< void * >( pData_ ), pTypeDescr, |
181 | cpp_acquire, cpp_release ); |
182 | } |
183 | |
184 | inline void Any::clear() |
185 | { |
186 | ::uno_any_clear( |
187 | this, cpp_release ); |
188 | } |
189 | |
190 | inline bool Any::isExtractableTo( const Type & rType ) const |
191 | { |
192 | return ::uno_type_isAssignableFromData( |
193 | rType.getTypeLibType(), pData, pType, |
194 | cpp_queryInterface, cpp_release ); |
195 | } |
196 | |
197 | |
198 | template <typename T> |
199 | inline bool Any::has() const |
200 | { |
201 | Type const & rType = ::cppu::getTypeFavourUnsigned(static_cast< T * >(0)); |
202 | return ::uno_type_isAssignableFromData( |
203 | rType.getTypeLibType(), pData, pType, |
204 | cpp_queryInterface, |
205 | cpp_release ); |
206 | } |
207 | |
208 | #if defined LIBO_INTERNAL_ONLY1 |
209 | template<> bool Any::has<Any>() const = delete; |
210 | #endif |
211 | |
212 | inline bool Any::operator == ( const Any & rAny ) const |
213 | { |
214 | return ::uno_type_equalData( |
215 | pData, pType, rAny.pData, rAny.pType, |
216 | cpp_queryInterface, cpp_release ); |
217 | } |
218 | |
219 | inline bool Any::operator != ( const Any & rAny ) const |
220 | { |
221 | return (! ::uno_type_equalData( |
222 | pData, pType, rAny.pData, rAny.pType, |
223 | cpp_queryInterface, cpp_release )); |
224 | } |
225 | |
226 | |
227 | template< class C > |
228 | inline Any SAL_CALL makeAny( const C & value ) |
229 | { |
230 | return Any(value); |
231 | } |
232 | |
233 | #if !defined LIBO_INTERNAL_ONLY1 |
234 | template<> Any makeAny(sal_uInt16 const & value) |
235 | { return Any(&value, cppu::UnoType<cppu::UnoUnsignedShortType>::get()); } |
236 | #endif |
237 | |
238 | template<typename T> Any toAny(T const & value) { return makeAny(value); } |
239 | |
240 | template<> Any toAny(Any const & value) { return value; } |
241 | |
242 | #if defined LIBO_INTERNAL_ONLY1 |
243 | |
244 | template<typename T1, typename T2> |
245 | Any makeAny(rtl::OUStringConcat<T1, T2> && value) |
246 | { return Any(std::move(value)); } |
247 | |
248 | template<typename T1, typename T2> |
249 | Any toAny(rtl::OUStringConcat<T1, T2> && value) |
250 | { return makeAny(std::move(value)); } |
251 | |
252 | template<typename T> |
253 | Any makeAny(rtl::OUStringNumber<T> && value) |
254 | { return Any(OUString(std::move(value))); } |
255 | |
256 | template<typename T> |
257 | Any toAny(rtl::OUStringNumber<T> && value) |
258 | { return makeAny(std::move(value)); } |
259 | |
260 | template<typename T> bool fromAny(Any const & any, T * value) { |
261 | assert(value != nullptr)(static_cast <bool> (value != nullptr) ? void (0) : __assert_fail ("value != nullptr", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx" , 261, __extension__ __PRETTY_FUNCTION__)); |
262 | return any >>= *value; |
263 | } |
264 | |
265 | template<> bool fromAny(Any const & any, Any * value) { |
266 | assert(value != nullptr)(static_cast <bool> (value != nullptr) ? void (0) : __assert_fail ("value != nullptr", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx" , 266, __extension__ __PRETTY_FUNCTION__)); |
267 | *value = any; |
268 | return true; |
269 | } |
270 | |
271 | #endif |
272 | |
273 | template< class C > |
274 | inline void SAL_CALL operator <<= ( Any & rAny, const C & value ) |
275 | { |
276 | const Type & rType = ::cppu::getTypeFavourUnsigned(&value); |
277 | ::uno_type_any_assign( |
278 | &rAny, const_cast< C * >( &value ), rType.getTypeLibType(), |
279 | cpp_acquire, cpp_release ); |
280 | } |
281 | |
282 | // additionally for C++ bool: |
283 | |
284 | template<> |
285 | inline void SAL_CALL operator <<= ( Any & rAny, bool const & value ) |
286 | { |
287 | sal_Bool b = value; |
288 | ::uno_type_any_assign( |
289 | &rAny, &b, cppu::UnoType<bool>::get().getTypeLibType(), |
290 | cpp_acquire, cpp_release ); |
291 | } |
292 | |
293 | |
294 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" |
295 | template< class C1, class C2 > |
296 | inline void SAL_CALL operator <<= ( Any & rAny, rtl::OUStringConcat< C1, C2 >&& value ) |
297 | { |
298 | const rtl::OUString str( std::move(value) ); |
299 | const Type & rType = ::cppu::getTypeFavourUnsigned(&str); |
300 | ::uno_type_any_assign( |
301 | &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(), |
302 | cpp_acquire, cpp_release ); |
303 | } |
304 | template<typename T1, typename T2> |
305 | void operator <<=(Any &, rtl::OUStringConcat<T1, T2> const &) = delete; |
306 | template< class C > |
307 | inline void SAL_CALL operator <<= ( Any & rAny, rtl::OUStringNumber< C >&& value ) |
308 | { |
309 | const rtl::OUString str( std::move(value) ); |
310 | const Type & rType = ::cppu::getTypeFavourUnsigned(&str); |
311 | ::uno_type_any_assign( |
312 | &rAny, const_cast< rtl::OUString * >( &str ), rType.getTypeLibType(), |
313 | cpp_acquire, cpp_release ); |
314 | } |
315 | template<typename T> |
316 | void operator <<=(Any &, rtl::OUStringNumber<T> const &) = delete; |
317 | #endif |
318 | |
319 | #if defined LIBO_INTERNAL_ONLY1 |
320 | template<> void SAL_CALL operator <<=(Any &, Any const &) = delete; |
321 | #endif |
322 | |
323 | template< class C > |
324 | inline bool SAL_CALL operator >>= ( const Any & rAny, C & value ) |
325 | { |
326 | const Type & rType = ::cppu::getTypeFavourUnsigned(&value); |
327 | return ::uno_type_assignData( |
328 | &value, rType.getTypeLibType(), |
329 | rAny.pData, rAny.pType, |
330 | cpp_queryInterface, |
331 | cpp_acquire, cpp_release ); |
332 | } |
333 | |
334 | // bool |
335 | |
336 | template<> |
337 | inline bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Bool & value ) |
338 | { |
339 | if (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass) |
340 | { |
341 | value = bool(* static_cast< const sal_Bool * >( rAny.pData )); |
342 | return true; |
343 | } |
344 | return false; |
345 | } |
346 | |
347 | template<> |
348 | inline bool SAL_CALL operator == ( const Any & rAny, const sal_Bool & value ) |
349 | { |
350 | return (typelib_TypeClass_BOOLEAN == rAny.pType->eTypeClass && |
351 | bool(value) == bool(* static_cast< const sal_Bool * >( rAny.pData ))); |
352 | } |
353 | |
354 | |
355 | template<> |
356 | inline bool SAL_CALL operator >>= ( Any const & rAny, bool & value ) |
357 | { |
358 | if (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN) |
359 | { |
360 | value = *static_cast< sal_Bool const * >( rAny.pData ); |
361 | return true; |
362 | } |
363 | return false; |
364 | } |
365 | |
366 | |
367 | template<> |
368 | inline bool SAL_CALL operator == ( Any const & rAny, bool const & value ) |
369 | { |
370 | return (rAny.pType->eTypeClass == typelib_TypeClass_BOOLEAN && |
371 | (value == |
372 | bool(*static_cast< sal_Bool const * >( rAny.pData )))); |
373 | } |
374 | |
375 | // byte |
376 | |
377 | template<> |
378 | inline bool SAL_CALL operator >>= ( const ::com::sun::star::uno::Any & rAny, sal_Int8 & value ) |
379 | { |
380 | if (typelib_TypeClass_BYTE == rAny.pType->eTypeClass) |
381 | { |
382 | value = * static_cast< const sal_Int8 * >( rAny.pData ); |
383 | return true; |
384 | } |
385 | return false; |
386 | } |
387 | // short |
388 | |
389 | template<> |
390 | inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int16 & value ) |
391 | { |
392 | switch (rAny.pType->eTypeClass) |
393 | { |
394 | case typelib_TypeClass_BYTE: |
395 | value = * static_cast< const sal_Int8 * >( rAny.pData ); |
396 | return true; |
397 | case typelib_TypeClass_SHORT: |
398 | case typelib_TypeClass_UNSIGNED_SHORT: |
399 | value = * static_cast< const sal_Int16 * >( rAny.pData ); |
400 | return true; |
401 | default: |
402 | return false; |
403 | } |
404 | } |
405 | |
406 | template<> |
407 | inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt16 & value ) |
408 | { |
409 | switch (rAny.pType->eTypeClass) |
410 | { |
411 | case typelib_TypeClass_BYTE: |
412 | value = static_cast<sal_uInt16>( * static_cast< const sal_Int8 * >( rAny.pData ) ); |
413 | return true; |
414 | case typelib_TypeClass_SHORT: |
415 | case typelib_TypeClass_UNSIGNED_SHORT: |
416 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
417 | return true; |
418 | default: |
419 | return false; |
420 | } |
421 | } |
422 | // long |
423 | |
424 | template<> |
425 | inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int32 & value ) |
426 | { |
427 | switch (rAny.pType->eTypeClass) |
428 | { |
429 | case typelib_TypeClass_BYTE: |
430 | value = * static_cast< const sal_Int8 * >( rAny.pData ); |
431 | return true; |
432 | case typelib_TypeClass_SHORT: |
433 | value = * static_cast< const sal_Int16 * >( rAny.pData ); |
434 | return true; |
435 | case typelib_TypeClass_UNSIGNED_SHORT: |
436 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
437 | return true; |
438 | case typelib_TypeClass_LONG: |
439 | case typelib_TypeClass_UNSIGNED_LONG: |
440 | value = * static_cast< const sal_Int32 * >( rAny.pData ); |
441 | return true; |
442 | default: |
443 | return false; |
444 | } |
445 | } |
446 | |
447 | template<> |
448 | inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt32 & value ) |
449 | { |
450 | switch (rAny.pType->eTypeClass) |
451 | { |
452 | case typelib_TypeClass_BYTE: |
453 | value = static_cast<sal_uInt32>( * static_cast< const sal_Int8 * >( rAny.pData ) ); |
454 | return true; |
455 | case typelib_TypeClass_SHORT: |
456 | value = static_cast<sal_uInt32>( * static_cast< const sal_Int16 * >( rAny.pData ) ); |
457 | return true; |
458 | case typelib_TypeClass_UNSIGNED_SHORT: |
459 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
460 | return true; |
461 | case typelib_TypeClass_LONG: |
462 | case typelib_TypeClass_UNSIGNED_LONG: |
463 | value = * static_cast< const sal_uInt32 * >( rAny.pData ); |
464 | return true; |
465 | default: |
466 | return false; |
467 | } |
468 | } |
469 | // hyper |
470 | |
471 | template<> |
472 | inline bool SAL_CALL operator >>= ( const Any & rAny, sal_Int64 & value ) |
473 | { |
474 | switch (rAny.pType->eTypeClass) |
475 | { |
476 | case typelib_TypeClass_BYTE: |
477 | value = * static_cast< const sal_Int8 * >( rAny.pData ); |
478 | return true; |
479 | case typelib_TypeClass_SHORT: |
480 | value = * static_cast< const sal_Int16 * >( rAny.pData ); |
481 | return true; |
482 | case typelib_TypeClass_UNSIGNED_SHORT: |
483 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
484 | return true; |
485 | case typelib_TypeClass_LONG: |
486 | value = * static_cast< const sal_Int32 * >( rAny.pData ); |
487 | return true; |
488 | case typelib_TypeClass_UNSIGNED_LONG: |
489 | value = * static_cast< const sal_uInt32 * >( rAny.pData ); |
490 | return true; |
491 | case typelib_TypeClass_HYPER: |
492 | case typelib_TypeClass_UNSIGNED_HYPER: |
493 | value = * static_cast< const sal_Int64 * >( rAny.pData ); |
494 | return true; |
495 | default: |
496 | return false; |
497 | } |
498 | } |
499 | |
500 | template<> |
501 | inline bool SAL_CALL operator >>= ( const Any & rAny, sal_uInt64 & value ) |
502 | { |
503 | switch (rAny.pType->eTypeClass) |
504 | { |
505 | case typelib_TypeClass_BYTE: |
506 | value = static_cast<sal_uInt64>( * static_cast< const sal_Int8 * >( rAny.pData ) ); |
507 | return true; |
508 | case typelib_TypeClass_SHORT: |
509 | value = static_cast<sal_uInt64>( * static_cast< const sal_Int16 * >( rAny.pData ) ); |
510 | return true; |
511 | case typelib_TypeClass_UNSIGNED_SHORT: |
512 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
513 | return true; |
514 | case typelib_TypeClass_LONG: |
515 | value = static_cast<sal_uInt64>( * static_cast< const sal_Int32 * >( rAny.pData ) ); |
516 | return true; |
517 | case typelib_TypeClass_UNSIGNED_LONG: |
518 | value = * static_cast< const sal_uInt32 * >( rAny.pData ); |
519 | return true; |
520 | case typelib_TypeClass_HYPER: |
521 | case typelib_TypeClass_UNSIGNED_HYPER: |
522 | value = * static_cast< const sal_uInt64 * >( rAny.pData ); |
523 | return true; |
524 | default: |
525 | return false; |
526 | } |
527 | } |
528 | // float |
529 | |
530 | template<> |
531 | inline bool SAL_CALL operator >>= ( const Any & rAny, float & value ) |
532 | { |
533 | switch (rAny.pType->eTypeClass) |
534 | { |
535 | case typelib_TypeClass_BYTE: |
536 | value = * static_cast< const sal_Int8 * >( rAny.pData ); |
537 | return true; |
538 | case typelib_TypeClass_SHORT: |
539 | value = * static_cast< const sal_Int16 * >( rAny.pData ); |
540 | return true; |
541 | case typelib_TypeClass_UNSIGNED_SHORT: |
542 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
543 | return true; |
544 | case typelib_TypeClass_FLOAT: |
545 | value = * static_cast< const float * >( rAny.pData ); |
546 | return true; |
547 | default: |
548 | return false; |
549 | } |
550 | } |
551 | // double |
552 | |
553 | template<> |
554 | inline bool SAL_CALL operator >>= ( const Any & rAny, double & value ) |
555 | { |
556 | switch (rAny.pType->eTypeClass) |
557 | { |
558 | case typelib_TypeClass_BYTE: |
559 | value = * static_cast< const sal_Int8 * >( rAny.pData ); |
560 | return true; |
561 | case typelib_TypeClass_SHORT: |
562 | value = * static_cast< const sal_Int16 * >( rAny.pData ); |
563 | return true; |
564 | case typelib_TypeClass_UNSIGNED_SHORT: |
565 | value = * static_cast< const sal_uInt16 * >( rAny.pData ); |
566 | return true; |
567 | case typelib_TypeClass_LONG: |
568 | value = * static_cast< const sal_Int32 * >( rAny.pData ); |
569 | return true; |
570 | case typelib_TypeClass_UNSIGNED_LONG: |
571 | value = * static_cast< const sal_uInt32 * >( rAny.pData ); |
572 | return true; |
573 | case typelib_TypeClass_FLOAT: |
574 | value = * static_cast< const float * >( rAny.pData ); |
575 | return true; |
576 | case typelib_TypeClass_DOUBLE: |
577 | value = * static_cast< const double * >( rAny.pData ); |
578 | return true; |
579 | default: |
580 | return false; |
581 | } |
582 | } |
583 | // string |
584 | |
585 | template<> |
586 | inline bool SAL_CALL operator >>= ( const Any & rAny, ::rtl::OUString & value ) |
587 | { |
588 | if (typelib_TypeClass_STRING == rAny.pType->eTypeClass) |
589 | { |
590 | value = * static_cast< const ::rtl::OUString * >( rAny.pData ); |
591 | return true; |
592 | } |
593 | return false; |
594 | } |
595 | |
596 | template<> |
597 | inline bool SAL_CALL operator == ( const Any & rAny, const ::rtl::OUString & value ) |
598 | { |
599 | return (typelib_TypeClass_STRING == rAny.pType->eTypeClass && |
600 | value == * static_cast< const ::rtl::OUString * >( rAny.pData ) ); |
601 | } |
602 | // type |
603 | |
604 | template<> |
605 | inline bool SAL_CALL operator >>= ( const Any & rAny, Type & value ) |
606 | { |
607 | if (typelib_TypeClass_TYPE == rAny.pType->eTypeClass) |
608 | { |
609 | value = * static_cast< const Type * >( rAny.pData ); |
610 | return true; |
611 | } |
612 | return false; |
613 | } |
614 | |
615 | template<> |
616 | inline bool SAL_CALL operator == ( const Any & rAny, const Type & value ) |
617 | { |
618 | return (typelib_TypeClass_TYPE == rAny.pType->eTypeClass && |
619 | value.equals( * static_cast< const Type * >( rAny.pData ) )); |
620 | } |
621 | // any |
622 | |
623 | #if defined LIBO_INTERNAL_ONLY1 |
624 | template<> bool SAL_CALL operator >>=(Any const &, Any &) = delete; |
625 | #else |
626 | template<> |
627 | inline bool SAL_CALL operator >>= ( const Any & rAny, Any & value ) |
628 | { |
629 | if (&rAny != &value) |
630 | { |
631 | ::uno_type_any_assign( |
632 | &value, rAny.pData, rAny.pType, |
633 | cpp_acquire, cpp_release ); |
634 | } |
635 | return true; |
636 | } |
637 | #endif |
638 | // interface |
639 | |
640 | template<> |
641 | inline bool SAL_CALL operator == ( const Any & rAny, const BaseReference & value ) |
642 | { |
643 | if (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass) |
644 | { |
645 | return static_cast< const BaseReference * >( rAny.pData )->operator == ( value ); |
646 | } |
647 | return false; |
648 | } |
649 | |
650 | // operator to compare to an any. |
651 | |
652 | template< class C > |
653 | inline bool SAL_CALL operator == ( const Any & rAny, const C & value ) |
654 | { |
655 | const Type & rType = ::cppu::getTypeFavourUnsigned(&value); |
656 | return ::uno_type_equalData( |
657 | rAny.pData, rAny.pType, |
658 | const_cast< C * >( &value ), rType.getTypeLibType(), |
659 | cpp_queryInterface, cpp_release ); |
660 | } |
661 | // operator to compare to an any. may use specialized operators ==. |
662 | |
663 | template< class C > |
664 | inline bool SAL_CALL operator != ( const Any & rAny, const C & value ) |
665 | { |
666 | return (! operator == ( rAny, value )); |
667 | } |
668 | |
669 | template <typename T> |
670 | T Any::get() const |
671 | { |
672 | T value = T(); |
673 | if (! (*this >>= value)) { |
674 | throw RuntimeException( |
675 | ::rtl::OUString( |
676 | cppu_Any_extraction_failure_msg( |
677 | this, |
678 | ::cppu::getTypeFavourUnsigned(&value).getTypeLibType() ), |
679 | SAL_NO_ACQUIRE ) ); |
680 | } |
681 | return value; |
682 | } |
683 | |
684 | #if defined LIBO_INTERNAL_ONLY1 |
685 | template<> Any Any::get() const = delete; |
686 | #endif |
687 | |
688 | /** |
689 | Support for Any in std::ostream (and thus in CPPUNIT_ASSERT or SAL_INFO |
690 | macros, for example). |
691 | |
692 | @since LibreOffice 4.2 |
693 | */ |
694 | template<typename charT, typename traits> |
695 | inline std::basic_ostream<charT, traits> &operator<<(std::basic_ostream<charT, traits> &o, Any const &any) { |
696 | o << "<Any: (" << any.getValueTypeName() << ')'; |
697 | switch(any.pType->eTypeClass) { |
698 | case typelib_TypeClass_VOID: |
699 | break; |
700 | case typelib_TypeClass_BOOLEAN: |
701 | o << ' ' << any.get<bool>(); |
702 | break; |
703 | case typelib_TypeClass_BYTE: |
704 | case typelib_TypeClass_SHORT: |
705 | case typelib_TypeClass_LONG: |
706 | case typelib_TypeClass_HYPER: |
707 | o << ' ' << any.get<sal_Int64>(); |
708 | break; |
709 | case typelib_TypeClass_UNSIGNED_SHORT: |
710 | case typelib_TypeClass_UNSIGNED_LONG: |
711 | case typelib_TypeClass_UNSIGNED_HYPER: |
712 | o << ' ' << any.get<sal_uInt64>(); |
713 | break; |
714 | case typelib_TypeClass_FLOAT: |
715 | case typelib_TypeClass_DOUBLE: |
716 | o << ' ' << any.get<double>(); |
717 | break; |
718 | case typelib_TypeClass_CHAR: { |
719 | std::ios_base::fmtflags flgs = o.setf( |
720 | std::ios_base::hex, std::ios_base::basefield); |
721 | charT fill = o.fill('0'); |
722 | o << " U+" << std::setw(4) |
723 | << unsigned(*static_cast<sal_Unicode const *>(any.getValue())); |
724 | o.setf(flgs); |
725 | o.fill(fill); |
726 | break; |
727 | } |
728 | case typelib_TypeClass_STRING: |
729 | o << ' ' << any.get<rtl::OUString>(); |
730 | break; |
731 | case typelib_TypeClass_TYPE: |
732 | o << ' ' << any.get<css::uno::Type>().getTypeName(); |
733 | break; |
734 | case typelib_TypeClass_SEQUENCE: |
735 | o << " len " |
736 | << ((*static_cast<uno_Sequence * const *>(any.getValue()))-> |
737 | nElements); |
738 | break; |
739 | case typelib_TypeClass_ENUM: |
740 | o << ' ' << *static_cast<sal_Int32 const *>(any.getValue()); |
741 | break; |
742 | case typelib_TypeClass_STRUCT: |
743 | case typelib_TypeClass_EXCEPTION: |
744 | o << ' ' << any.getValue(); |
745 | break; |
746 | case typelib_TypeClass_INTERFACE: |
747 | o << ' ' << *static_cast<void * const *>(any.getValue()); |
748 | break; |
749 | default: |
750 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/include/com/sun/star/uno/Any.hxx" , 750, __extension__ __PRETTY_FUNCTION__)); // this cannot happen |
751 | break; |
752 | } |
753 | o << '>'; |
754 | return o; |
755 | } |
756 | |
757 | } |
758 | } |
759 | } |
760 | } |
761 | |
762 | #endif |
763 | |
764 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |