Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ustring.hxx
Warning:line 764, column 16
Access to field 'length' results in a dereference of a null pointer (loaded from field 'pData')

Annotated Source Code

Press '?' to see keyboard shortcuts

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

/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "file_url.hxx"
21
22#include "system.hxx"
23
24#include <algorithm>
25#include <cassert>
26#include <cstring>
27#include <stdexcept>
28#include <string_view>
29#include <type_traits>
30#include <limits.h>
31#include <errno(*__errno_location ()).h>
32#include <strings.h>
33#include <unistd.h>
34
35#include <o3tl/safeint.hxx>
36#include <osl/file.hxx>
37#include <osl/security.hxx>
38#include <osl/socket.h>
39#include <osl/diagnose.h>
40#include <osl/thread.h>
41#include <osl/process.h>
42
43#include <rtl/character.hxx>
44#include <rtl/strbuf.hxx>
45#include <rtl/uri.h>
46#include <rtl/uri.hxx>
47#include <rtl/ustring.hxx>
48#include <rtl/ustrbuf.h>
49#include <rtl/ustrbuf.hxx>
50#include <rtl/textcvt.h>
51#include <sal/log.hxx>
52
53#include <uri_internal.hxx>
54
55#include "file_error_transl.hxx"
56#include "file_path_helper.hxx"
57
58#include "uunxapi.hxx"
59
60/** @file
61
62 General note
63
64 This file contains the part that handles File URLs.
65
66 File URLs as scheme specific notion of URIs
67 (RFC2396) may be handled platform independent, but
68 will not in osl which is considered wrong.
69 Future version of osl should handle File URLs this
70 way. In rtl/uri there is already a URI parser etc.
71 so this code should be consolidated.
72
73*/
74
75using namespace osl;
76
77namespace {
78
79// A slightly modified version of Pchar in rtl/source/uri.c, but without
80// encoding slashes:
81const sal_Bool uriCharClass[128] = {
82 false, false, false, false, false, false, false, false,
83 false, false, false, false, false, false, false, false,
84 false, false, false, false, false, false, false, false,
85 false, false, false, false, false, false, false, false,
86 false, true, false, false, true, false, true, true, // !"#$%&'
87 true, true, true, true, true, true, true, true, // ()*+,-./
88 true, true, true, true, true, true, true, true, // 01234567
89 true, true, true, false, false, true, false, false, // 89:;<=>?
90 true, true, true, true, true, true, true, true, // @ABCDEFG
91 true, true, true, true, true, true, true, true, // HIJKLMNO
92 true, true, true, true, true, true, true, true, // PQRSTUVW
93 true, true, true, false, false, false, false, true, // XYZ[\]^_
94 false, true, true, true, true, true, true, true, // `abcdefg
95 true, true, true, true, true, true, true, true, // hijklmno
96 true, true, true, true, true, true, true, true, // pqrstuvw
97 true, true, true, false, false, false, true, false}; // xyz{|}~
98
99}
100
101oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
102{
103 OSL_FAIL("osl_getCanonicalName not implemented")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "103" ": "), "%s", "osl_getCanonicalName not implemented"
); } } while (false)
;
104
105 rtl_uString_newFromString(pustrValidURL, ustrFileURL);
106 return osl_File_E_None;
107}
108
109namespace {
110
111 class UnicodeToTextConverter_Impl
112 {
113 rtl_UnicodeToTextConverter m_converter;
114
115 UnicodeToTextConverter_Impl()
116 : m_converter (rtl_createUnicodeToTextConverter (osl_getThreadTextEncoding()))
117 {}
118
119 ~UnicodeToTextConverter_Impl()
120 {
121 rtl_destroyUnicodeToTextConverter (m_converter);
122 }
123 public:
124 static UnicodeToTextConverter_Impl & getInstance()
125 {
126 static UnicodeToTextConverter_Impl g_theConverter;
127 return g_theConverter;
128 }
129
130 sal_Size convert(
131 sal_Unicode const * pSrcBuf, sal_Size nSrcChars, char * pDstBuf, sal_Size nDstBytes,
132 sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtChars)
133 {
134 OSL_ASSERT(m_converter != nullptr)do { if (true && (!(m_converter != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "134" ": "), "OSL_ASSERT: %s", "m_converter != nullptr")
; } } while (false)
;
135 return rtl_convertUnicodeToText (
136 m_converter, nullptr, pSrcBuf, nSrcChars, pDstBuf, nDstBytes, nFlags, pInfo, pSrcCvtChars);
137 }
138 };
139
140bool convert(OUStringBuffer const & in, OStringBuffer * append) {
141 assert(append != nullptr)(static_cast <bool> (append != nullptr) ? void (0) : __assert_fail
("append != nullptr", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 for (sal_Size nConvert = in.getLength();;) {
143 auto const oldLen = append->getLength();
144 auto n = std::min(
145 std::max(nConvert, sal_Size(PATH_MAX4096)),
146 sal_Size(std::numeric_limits<sal_Int32>::max() - oldLen));
147 // approximation of required converted size
148 auto s = append->appendUninitialized(n);
149 sal_uInt32 info;
150 sal_Size converted;
151 //TODO: context, for reliable treatment of DESTBUFFERTOSMALL:
152 n = UnicodeToTextConverter_Impl::getInstance().convert(
153 in.getStr() + in.getLength() - nConvert, nConvert, s, n,
154 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR((sal_uInt32)0x0001) | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR((sal_uInt32)0x0010)
155 | RTL_UNICODETOTEXT_FLAGS_FLUSH((sal_uInt32)0x8000)),
156 &info, &converted);
157 if ((info & RTL_UNICODETOTEXT_INFO_ERROR((sal_uInt32)0x0001)) != 0) {
158 return false;
159 }
160 append->setLength(oldLen + n);
161 assert(converted <= nConvert)(static_cast <bool> (converted <= nConvert) ? void (
0) : __assert_fail ("converted <= nConvert", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 161, __extension__ __PRETTY_FUNCTION__))
;
162 nConvert -= converted;
163 assert((nConvert == 0) == ((info & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0))(static_cast <bool> ((nConvert == 0) == ((info & ((
sal_uInt32)0x0004)) == 0)) ? void (0) : __assert_fail ("(nConvert == 0) == ((info & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0)"
, "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 163, __extension__ __PRETTY_FUNCTION__))
;
164 if ((info & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL((sal_uInt32)0x0004)) == 0) {
165 break;
166 }
167 }
168 return true;
169}
170
171bool decodeFromUtf8(std::u16string_view text, OString * result) {
172 assert(result != nullptr)(static_cast <bool> (result != nullptr) ? void (0) : __assert_fail
("result != nullptr", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 172, __extension__ __PRETTY_FUNCTION__))
;
173 auto p = text.data();
174 auto const end = p + text.size();
175 OUStringBuffer ubuf(static_cast<int>(text.size()));
176 OStringBuffer bbuf(PATH_MAX4096);
177 while (p < end) {
178 rtl::uri::detail::EscapeType t;
179 sal_uInt32 c = rtl::uri::detail::readUcs4(&p, end, true, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), &t);
180 switch (t) {
181 case rtl::uri::detail::EscapeNo:
182 if (c == '%') {
183 return false;
184 }
185 [[fallthrough]];
186 case rtl::uri::detail::EscapeChar:
187 if (rtl::isSurrogate(c)) {
188 return false;
189 }
190 ubuf.appendUtf32(c);
191 break;
192 case rtl::uri::detail::EscapeOctet:
193 if (!convert(ubuf, &bbuf)) {
194 return false;
195 }
196 ubuf.setLength(0);
197 assert(c <= 0xFF)(static_cast <bool> (c <= 0xFF) ? void (0) : __assert_fail
("c <= 0xFF", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 197, __extension__ __PRETTY_FUNCTION__))
;
198 bbuf.append(char(c));
199 break;
200 }
201 }
202 if (!convert(ubuf, &bbuf)) {
203 return false;
204 }
205 *result = bbuf.makeStringAndClear();
206 return true;
207}
208
209template<typename T> oslFileError getSystemPathFromFileUrl(
210 OUString const & url, T * path, bool resolveHome)
211{
212 assert(path != nullptr)(static_cast <bool> (path != nullptr) ? void (0) : __assert_fail
("path != nullptr", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 212, __extension__ __PRETTY_FUNCTION__))
;
8
'?' condition is true
213 // For compatibility with assumptions in other parts of the code base,
214 // assume that anything starting with a slash is a system path instead of a
215 // (relative) file URL (except if it starts with two slashes, in which case
216 // it is a relative URL with an authority component):
217 if (url.isEmpty()
9
Calling 'OUString::isEmpty'
218 || (url[0] == '/' && (url.getLength() == 1 || url[1] != '/')))
219 {
220 return osl_File_E_INVAL;
221 }
222 // Check for non file scheme:
223 sal_Int32 i = 0;
224 if (rtl::isAsciiAlpha(url[0])) {
225 for (sal_Int32 j = 1; j != url.getLength(); ++j) {
226 auto c = url[j];
227 if (c == ':') {
228 if (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
229 url.pData->buffer, j,
230 RTL_CONSTASCII_STRINGPARAM("file")(&("file")[0]), ((sal_Int32)(sizeof(sal_n_array_size("file"
)))-1)
)
231 != 0)
232 {
233 return osl_File_E_INVAL;
234 }
235 i = j + 1;
236 break;
237 }
238 if (!rtl::isAsciiAlphanumeric(c) && c != '+' && c != '-'
239 && c != '.')
240 {
241 break;
242 }
243 }
244 }
245 // Handle query or fragment:
246 if (url.indexOf('?', i) != -1 || url.indexOf('#', i) != -1)
247 return osl_File_E_INVAL;
248 // Handle authority, supporting a host of "localhost", "127.0.0.1", or the exact value (e.g.,
249 // not supporting an additional final dot, for simplicity) reported by osl_getLocalHostname
250 // (and, in each case, ignoring case of ASCII letters):
251 if (url.getLength() - i >= 2 && url[i] == '/' && url[i + 1] == '/')
252 {
253 i += 2;
254 sal_Int32 j = url.indexOf('/', i);
255 if (j == -1)
256 j = url.getLength();
257 if (j != i
258 && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
259 url.pData->buffer + i, j - i,
260 RTL_CONSTASCII_STRINGPARAM("localhost")(&("localhost")[0]), ((sal_Int32)(sizeof(sal_n_array_size
("localhost")))-1)
)
261 != 0)
262 && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
263 url.pData->buffer + i, j - i,
264 RTL_CONSTASCII_STRINGPARAM("127.0.0.1")(&("127.0.0.1")[0]), ((sal_Int32)(sizeof(sal_n_array_size
("127.0.0.1")))-1)
)
265 != 0))
266 {
267 OUString hostname;
268 if (osl_getLocalHostname(&hostname.pData) != osl_Socket_Ok
269 || (rtl_ustr_compareIgnoreAsciiCase_WithLength(
270 url.pData->buffer + i, j - i, hostname.getStr(), hostname.getLength())
271 != 0))
272 {
273 return osl_File_E_INVAL;
274 }
275 }
276 i = j;
277 }
278 // Handle empty path:
279 if (i == url.getLength())
280 {
281 *path = "/";
282 return osl_File_E_None;
283 }
284 // Path must not contain %2F:
285 if (url.indexOf("%2F", i) != -1 || url.indexOf("%2f", i) != -1)
286 return osl_File_E_INVAL;
287
288 if constexpr (std::is_same_v<T, rtl::OString>) {
289 if (!decodeFromUtf8(std::u16string_view(url).substr(i), path)) {
290 return osl_File_E_INVAL;
291 }
292 } else if constexpr (std::is_same_v<T, rtl::OUString>) {
293 *path = rtl::Uri::decode(
294 url.copy(i), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
295 } else {
296 static_assert(std::is_same_v<T, rtl::OString> || std::is_same_v<T, rtl::OUString>);
297 }
298 // Path must not contain %2F:
299 if (path->indexOf('\0') != -1)
300 return osl_File_E_INVAL;
301
302 // Handle ~ notation:
303 if (resolveHome && path->getLength() >= 2 && (*path)[1] == '~')
304 {
305 sal_Int32 j = path->indexOf('/', 2);
306 if (j == -1)
307 j = path->getLength();
308
309 if (j == 2)
310 {
311 OUString home;
312 if (!osl::Security().getHomeDir(home))
313 {
314 SAL_WARN("sal.file", "osl::Security::getHomeDir failed")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sal.file")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "osl::Security::getHomeDir failed"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"
), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "314" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "osl::Security::getHomeDir failed"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "osl::Security::getHomeDir failed"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "314" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "osl::Security::getHomeDir failed") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "314" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "osl::Security::getHomeDir failed"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "osl::Security::getHomeDir failed"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "314" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
315 return osl_File_E_INVAL;
316 }
317
318 i = url.indexOf('/', i + 1);
319
320 if (i == -1)
321 i = url.getLength();
322 else
323 ++i;
324
325 //TODO: cheesy way of ensuring home's path ends in slash:
326 if (!home.isEmpty() && home[home.getLength() - 1] != '/')
327 home += "/";
328 try
329 {
330 home = rtl::Uri::convertRelToAbs(home, url.copy(i));
331 }
332 catch (rtl::MalformedUriException & e)
333 {
334 SAL_WARN("sal.file", "rtl::MalformedUriException " << e.getMessage())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sal.file")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "rtl::MalformedUriException "
<< e.getMessage()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "334" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "rtl::MalformedUriException " <<
e.getMessage()), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "rtl::MalformedUriException " <<
e.getMessage(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "334" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "rtl::MalformedUriException " << e.getMessage
()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "334" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "rtl::MalformedUriException " <<
e.getMessage()), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "rtl::MalformedUriException " <<
e.getMessage(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "334" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
335 return osl_File_E_INVAL;
336 }
337 return getSystemPathFromFileUrl(home, path, false);
338 }
339 // FIXME: replace ~user with user's home directory
340 return osl_File_E_INVAL;
341 }
342 return osl_File_E_None;
343}
344
345}
346
347oslFileError SAL_CALL osl_getSystemPathFromFileURL( rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath )
348{
349 OUString path;
350 oslFileError e;
351 try
352 {
353 e = getSystemPathFromFileUrl(
7
Calling 'getSystemPathFromFileUrl<rtl::OUString>'
354 OUString::unacquired(&ustrFileURL), &path, true);
355 }
356 catch (std::length_error &)
357 {
358 e = osl_File_E_RANGE;
359 }
360
361 if (e == osl_File_E_None)
362 rtl_uString_assign(pustrSystemPath, path.pData);
363
364 return e;
365}
366
367oslFileError SAL_CALL osl_getFileURLFromSystemPath( rtl_uString *ustrSystemPath, rtl_uString **pustrFileURL )
368{
369 static const sal_Unicode pDoubleSlash[2] = { '/', '/' };
370
371 rtl_uString *pTmp = nullptr;
372 sal_Int32 nIndex;
373
374 if( ustrSystemPath->length == 0 )
375 return osl_File_E_INVAL;
376
377 /* temporary hack: if already file url, return ustrSystemPath */
378
379 if( rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file:", 5 ) == 0 )
380 return osl_File_E_INVAL;
381
382 /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
383 if( ustrSystemPath->buffer[0] == '~' )
384 {
385 /* check if another user is specified */
386 if( ( ustrSystemPath->length == 1 ) ||
387 ( ustrSystemPath->buffer[1] == '/' ) )
388 {
389 /* osl_getHomeDir returns file URL */
390 oslSecurity pSecurity = osl_getCurrentSecurity();
391 osl_getHomeDir( pSecurity , &pTmp );
392 osl_freeSecurityHandle( pSecurity );
393
394 if (!pTmp)
395 return osl_File_E_INVAL;
396
397 /* remove "file://" prefix */
398 rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + 7, pTmp->length - 7 );
399
400 /* replace '~' in original string */
401 rtl_uString_newReplaceStrAt( &pTmp, ustrSystemPath, 0, 1, pTmp );
402 }
403 else
404 {
405 /* FIXME: replace ~user with users home directory */
406 return osl_File_E_INVAL;
407 }
408 }
409
410 /* check if initial string contains repeated '/' characters */
411 nIndex = rtl_ustr_indexOfStr_WithLength( ustrSystemPath->buffer, ustrSystemPath->length, pDoubleSlash, 2 );
412 if( nIndex != -1 )
413 {
414 sal_Int32 nSrcIndex;
415 sal_Int32 nDeleted = 0;
416
417 /* if pTmp is not already allocated, copy ustrSystemPath for modification */
418 if( pTmp == nullptr )
419 rtl_uString_newFromString( &pTmp, ustrSystemPath );
420
421 /* adapt index to pTmp */
422 nIndex += pTmp->length - ustrSystemPath->length;
423
424 /* replace repeated '/' characters with a single '/' */
425 for( nSrcIndex = nIndex + 1; nSrcIndex < pTmp->length; nSrcIndex++ )
426 {
427 if( (pTmp->buffer[nSrcIndex] == '/') && (pTmp->buffer[nIndex] == '/') )
428 nDeleted++;
429 else
430 pTmp->buffer[++nIndex] = pTmp->buffer[nSrcIndex];
431 }
432
433 /* adjust length member */
434 pTmp->length -= nDeleted;
435 }
436
437 if( pTmp == nullptr )
438 rtl_uString_assign( &pTmp, ustrSystemPath );
439
440 /* file URLs must be URI encoded */
441 rtl_uriEncode( pTmp, uriCharClass, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), pustrFileURL );
442
443 rtl_uString_release( pTmp );
444
445 /* absolute urls should start with 'file://' */
446 if( (*pustrFileURL)->buffer[0] == '/' )
447 {
448 rtl_uString *pProtocol = nullptr;
449
450 rtl_uString_newFromAscii( &pProtocol, "file://" );
451 rtl_uString_newConcat( pustrFileURL, pProtocol, *pustrFileURL );
452 rtl_uString_release( pProtocol );
453 }
454
455 return osl_File_E_None;
456}
457
458/*
459 * relative URLs are not accepted
460 */
461oslFileError osl_getSystemPathFromFileURL_Ex(
462 rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath)
463{
464 rtl_uString* temp = nullptr;
465 oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &temp);
466
467 if (osl_error == osl_File_E_None)
468 {
469 if (temp->buffer[0] == '/')
470 {
471 *pustrSystemPath = temp;
472 }
473 else
474 {
475 rtl_uString_release(temp);
476 osl_error = osl_File_E_INVAL;
477 }
478 }
479
480 return osl_error;
481}
482
483namespace
484{
485
486 /** Helper function, return a pointer to the final '\0'
487 of a string
488 */
489
490 sal_Unicode* ustrtoend(sal_Unicode* pStr)
491 {
492 return (pStr + rtl_ustr_getLength(pStr));
493 }
494
495 sal_Unicode* ustrchrcat(const sal_Unicode chr, sal_Unicode* d)
496 {
497 sal_Unicode* p = ustrtoend(d);
498 *p++ = chr;
499 *p = 0;
500 return d;
501 }
502
503 bool _islastchr(sal_Unicode* pStr, sal_Unicode Chr)
504 {
505 sal_Unicode* p = ustrtoend(pStr);
506 if (p > pStr)
507 p--;
508 return (*p == Chr);
509 }
510
511 /**
512 Remove the last part of a path, a path that has
513 only a '/' or no '/' at all will be returned
514 unmodified
515 */
516
517 sal_Unicode* _rmlastpathtoken(sal_Unicode* aPath)
518 {
519 /* we may always skip -2 because we
520 may at least stand on a '/' but
521 either there is no other character
522 before this '/' or it's another
523 character than the '/'
524 */
525 sal_Unicode* p = ustrtoend(aPath) - 2;
526
527 /* move back to the next path separator
528 or to the start of the string */
529 while ((p > aPath) && (*p != '/'))
530 p--;
531
532 if (p >= aPath)
533 {
534 if (*p == '/')
535 {
536 p++;
537 *p = '\0';
538 }
539 else
540 {
541 *p = '\0';
542 }
543 }
544
545 return aPath;
546 }
547
548 oslFileError _osl_resolvepath(
549 /*inout*/ sal_Unicode* path,
550 /*inout*/ bool* failed)
551 {
552 oslFileError ferr = osl_File_E_None;
553
554 if (!*failed)
555 {
556 char unresolved_path[PATH_MAX4096];
557 if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), path, rtl_ustr_getLength(path)))
558 return oslTranslateFileError(ENAMETOOLONG36);
559
560 char resolved_path[PATH_MAX4096];
561 if (realpath(unresolved_path, resolved_path))
562 {
563 if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX4096))
564 return oslTranslateFileError(ENAMETOOLONG36);
565 }
566 else
567 {
568 if (EACCES13 == errno(*__errno_location ()) || ENOTDIR20 == errno(*__errno_location ()) || ENOENT2 == errno(*__errno_location ()))
569 *failed = true;
570 else
571 ferr = oslTranslateFileError(errno(*__errno_location ()));
572 }
573 }
574
575 return ferr;
576 }
577
578 /**
579 Works even with non existing paths. The resulting path must not exceed
580 PATH_MAX else osl_File_E_NAMETOOLONG is the result
581 */
582
583 oslFileError osl_getAbsoluteFileURL_impl_(const OUString& unresolved_path, OUString& resolved_path)
584 {
585 /* the given unresolved path must not exceed PATH_MAX */
586 if (unresolved_path.getLength() >= (PATH_MAX4096 - 2))
587 return oslTranslateFileError(ENAMETOOLONG36);
588
589 sal_Unicode path_resolved_so_far[PATH_MAX4096];
590 const sal_Unicode* punresolved = unresolved_path.getStr();
591 sal_Unicode* presolvedsf = path_resolved_so_far;
592
593 /* reserve space for leading '/' and trailing '\0'
594 do not exceed this limit */
595 sal_Unicode* sentinel = path_resolved_so_far + PATH_MAX4096 - 2;
596
597 /* if realpath fails with error ENOTDIR, EACCES or ENOENT
598 we will not call it again, because _osl_realpath should also
599 work with non existing directories etc. */
600 bool realpath_failed = false;
601 oslFileError ferr;
602
603 path_resolved_so_far[0] = '\0';
604
605 while (*punresolved != '\0')
606 {
607 /* ignore '/.' , skip one part back when '/..' */
608 if ((*punresolved == '.') && (*presolvedsf == '/'))
609 {
610 if (*(punresolved + 1) == '\0')
611 {
612 punresolved++;
613 continue;
614 }
615 if (*(punresolved + 1) == '/')
616 {
617 punresolved += 2;
618 continue;
619 }
620 if ((*(punresolved + 1) == '.') && (*(punresolved + 2) == '\0' || (*(punresolved + 2) == '/')))
621 {
622 _rmlastpathtoken(path_resolved_so_far);
623
624 presolvedsf = ustrtoend(path_resolved_so_far) - 1;
625
626 if (*(punresolved + 2) == '/')
627 punresolved += 3;
628 else
629 punresolved += 2;
630
631 continue;
632 }
633
634 /* a file or directory name may start with '.' */
635 if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
636 return oslTranslateFileError(ENAMETOOLONG36);
637
638 ustrchrcat(*punresolved++, path_resolved_so_far);
639
640 if (*punresolved == '\0' && !realpath_failed)
641 {
642 ferr = _osl_resolvepath(
643 path_resolved_so_far,
644 &realpath_failed);
645
646 if (ferr != osl_File_E_None)
647 return ferr;
648 }
649 }
650 else if (*punresolved == '/')
651 {
652 if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
653 return oslTranslateFileError(ENAMETOOLONG36);
654
655 ustrchrcat(*punresolved++, path_resolved_so_far);
656
657 if (!realpath_failed)
658 {
659 ferr = _osl_resolvepath(
660 path_resolved_so_far,
661 &realpath_failed);
662
663 if (ferr != osl_File_E_None)
664 return ferr;
665
666 if (!_islastchr(path_resolved_so_far, '/'))
667 {
668 if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
669 return oslTranslateFileError(ENAMETOOLONG36);
670
671 ustrchrcat('/', path_resolved_so_far);
672 }
673 }
674 }
675 else // any other character
676 {
677 if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
678 return oslTranslateFileError(ENAMETOOLONG36);
679
680 ustrchrcat(*punresolved++, path_resolved_so_far);
681
682 if (*punresolved == '\0' && !realpath_failed)
683 {
684 ferr = _osl_resolvepath(
685 path_resolved_so_far,
686 &realpath_failed);
687
688 if (ferr != osl_File_E_None)
689 return ferr;
690 }
691 }
692 }
693
694 sal_Int32 len = rtl_ustr_getLength(path_resolved_so_far);
695
696 OSL_ASSERT(len < PATH_MAX)do { if (true && (!(len < 4096))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "696" ": "), "OSL_ASSERT: %s", "len < PATH_MAX"); } }
while (false)
;
697
698 resolved_path = OUString(path_resolved_so_far, len);
699
700 return osl_File_E_None;
701 }
702
703}
704
705oslFileError osl_getAbsoluteFileURL(
706 rtl_uString* ustrBaseDirURL,
707 rtl_uString* ustrRelativeURL,
708 rtl_uString** pustrAbsoluteURL)
709{
710 /* Work around the below call to getSystemPathFromFileURL rejecting input
711 that starts with "/" (for whatever reason it behaves that way; but
712 changing that would start to break lots of tests at least) */
713 OUString relUrl(ustrRelativeURL);
714 if (relUrl.startsWith("//"))
715 relUrl = "file:" + relUrl;
716 else if (relUrl.startsWith("/"))
717 relUrl = "file://" + relUrl;
718
719 OUString unresolved_path;
720
721 FileBase::RC frc = FileBase::getSystemPathFromFileURL(relUrl, unresolved_path);
722 if (frc != FileBase::E_None)
723 return oslFileError(frc);
724
725 if (systemPathIsRelativePath(unresolved_path))
726 {
727 OUString base_path;
728 oslFileError rc = osl_getSystemPathFromFileURL_Ex(ustrBaseDirURL, &base_path.pData);
729 if (rc != osl_File_E_None)
730 return rc;
731
732 unresolved_path = systemPathMakeAbsolutePath(base_path, unresolved_path);
733 }
734
735 OUString resolved_path;
736 oslFileError rc = osl_getAbsoluteFileURL_impl_(unresolved_path, resolved_path);
737 if (rc == osl_File_E_None)
738 {
739 rc = osl_getFileURLFromSystemPath(resolved_path.pData, pustrAbsoluteURL);
740 OSL_ASSERT(osl_File_E_None == rc)do { if (true && (!(osl_File_E_None == rc))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "740" ": "), "OSL_ASSERT: %s", "osl_File_E_None == rc");
} } while (false)
;
741 }
742
743 return rc;
744}
745
746namespace osl::detail {
747
748 /**
749 No separate error code if unicode to text conversion or getenv fails because for the
750 caller there is no difference why a file could not be found in $PATH
751 */
752 bool find_in_PATH(const OUString& file_path, OUString& result)
753 {
754 bool bfound = false;
755 OUString path("PATH");
756 OUString env_path;
757
758 if (osl_getEnvironment(path.pData, &env_path.pData) == osl_Process_E_None)
759 bfound = osl::searchPath(file_path, env_path, result);
760
761 return bfound;
762 }
763}
764
765namespace
766{
767 /**
768 No separate error code if unicode to text conversion or getcwd fails because for the
769 caller there is no difference why a file could not be found in CDW
770 */
771 bool find_in_CWD(const OUString& file_path, OUString& result)
772 {
773 bool bfound = false;
774 OUString cwd_url;
775
776 if (osl_getProcessWorkingDir(&cwd_url.pData) == osl_Process_E_None)
777 {
778 OUString cwd;
779 FileBase::getSystemPathFromFileURL(cwd_url, cwd);
780 bfound = osl::searchPath(file_path, cwd, result);
781 }
782 return bfound;
783 }
784
785 bool find_in_searchPath(const OUString& file_path, rtl_uString* search_path, OUString& result)
786 {
787 return (search_path && osl::searchPath(file_path, OUString(search_path), result));
788 }
789
790}
791
792oslFileError osl_searchFileURL(rtl_uString* ustrFilePath, rtl_uString* ustrSearchPath, rtl_uString** pustrURL)
793{
794 OSL_PRECOND(ustrFilePath && pustrURL, "osl_searchFileURL: invalid parameter")do { if (true && (!(ustrFilePath && pustrURL)
)) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "794" ": "), "%s", "osl_searchFileURL: invalid parameter"
); } } while (false)
;
1
Assuming 'ustrFilePath' is null
2
Taking true branch
3
Loop condition is false. Exiting loop
795
796 FileBase::RC rc;
797 OUString file_path;
798
799 // try to interpret search path as file url else assume it's a system path list
800 rc = FileBase::getSystemPathFromFileURL(ustrFilePath, file_path);
4
Calling 'FileBase::getSystemPathFromFileURL'
801 if (rc == FileBase::E_INVAL)
802 file_path = ustrFilePath;
803 else if (rc != FileBase::E_None)
804 return oslFileError(rc);
805
806 bool bfound = false;
807 OUString result;
808
809 if (find_in_searchPath(file_path, ustrSearchPath, result) ||
810 osl::detail::find_in_PATH(file_path, result) ||
811 find_in_CWD(file_path, result))
812 {
813 OUString resolved;
814
815 if (osl::realpath(result, resolved))
816 {
817 oslFileError osl_error = osl_getFileURLFromSystemPath(resolved.pData, pustrURL);
818 SAL_WARN_IF(osl_File_E_None != osl_error, "sal.file", "osl_getFileURLFromSystemPath failed")do { if (true && (osl_File_E_None != osl_error)) { switch
(sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sal.file"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "osl_getFileURLFromSystemPath failed") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), (
"/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "818" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "osl_getFileURLFromSystemPath failed")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "osl_getFileURLFromSystemPath failed"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "818" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "osl_getFileURLFromSystemPath failed") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), (
"/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "818" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "osl_getFileURLFromSystemPath failed")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "osl_getFileURLFromSystemPath failed"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sal.file"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "818" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
819 bfound = true;
820 }
821 }
822 return bfound ? osl_File_E_None : osl_File_E_NOENT;
823}
824
825oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL)
826{
827 OString strSystemPath;
828 oslFileError osl_error = osl::detail::convertUrlToPathname(
829 OUString::unacquired(&ustrFileURL), &strSystemPath);
830
831 if(osl_error != osl_File_E_None)
832 return osl_error;
833
834 osl_systemPathRemoveSeparator(strSystemPath.pData);
835
836 if (o3tl::make_unsigned(strSystemPath.getLength()) >= bufLen) {
837 return osl_File_E_OVERFLOW;
838 }
839 std::strcpy(buffer, strSystemPath.getStr());
840
841 return osl_error;
842}
843
844int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
845{
846 sal_uInt32 nInfo = 0;
847 sal_Size nSrcChars = 0;
848
849 sal_Size nDestBytes = UnicodeToTextConverter_Impl::getInstance().convert (
850 uniText, uniTextLen, buffer, bufLen,
851 OUSTRING_TO_OSTRING_CVTFLAGS(((sal_uInt32)0x0006) | ((sal_uInt32)0x0060) | ((sal_uInt32)0x0100
) | ((sal_uInt32)0x0400))
| RTL_UNICODETOTEXT_FLAGS_FLUSH((sal_uInt32)0x8000), &nInfo, &nSrcChars);
852
853 if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL((sal_uInt32)0x0004) )
854 {
855 errno(*__errno_location ()) = EOVERFLOW75;
856 return 0;
857 }
858
859 /* ensure trailing '\0' */
860 buffer[nDestBytes] = '\0';
861 return nDestBytes;
862}
863
864namespace
865{
866 class TextToUnicodeConverter_Impl
867 {
868 rtl_TextToUnicodeConverter m_converter;
869
870 TextToUnicodeConverter_Impl()
871 : m_converter (rtl_createTextToUnicodeConverter (osl_getThreadTextEncoding()))
872 {}
873
874 ~TextToUnicodeConverter_Impl()
875 {
876 rtl_destroyTextToUnicodeConverter (m_converter);
877 }
878
879 public:
880 static TextToUnicodeConverter_Impl & getInstance()
881 {
882 static TextToUnicodeConverter_Impl g_theConverter;
883 return g_theConverter;
884 }
885
886 sal_Size convert(
887 char const * pSrcBuf, sal_Size nSrcBytes, sal_Unicode * pDstBuf, sal_Size nDstChars,
888 sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtBytes)
889 {
890 OSL_ASSERT(m_converter != nullptr)do { if (true && (!(m_converter != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
":" "890" ": "), "OSL_ASSERT: %s", "m_converter != nullptr")
; } } while (false)
;
891 return rtl_convertTextToUnicode (
892 m_converter, nullptr, pSrcBuf, nSrcBytes, pDstBuf, nDstChars, nFlags, pInfo, pSrcCvtBytes);
893 }
894 };
895}
896
897int TextToUnicode(
898 const char* text,
899 size_t text_buffer_size,
900 sal_Unicode* unic_text,
901 sal_Int32 unic_text_buffer_size)
902{
903 sal_uInt32 nInfo = 0;
904 sal_Size nSrcChars = 0;
905
906 sal_Size nDestBytes = TextToUnicodeConverter_Impl::getInstance().convert(
907 text, text_buffer_size, unic_text, unic_text_buffer_size,
908 OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300
))
| RTL_TEXTTOUNICODE_FLAGS_FLUSH((sal_uInt32)0x8000), &nInfo, &nSrcChars);
909
910 if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL((sal_uInt32)0x0004))
911 {
912 errno(*__errno_location ()) = EOVERFLOW75;
913 return 0;
914 }
915
916 /* ensure trailing '\0' */
917 unic_text[nDestBytes] = '\0';
918 return nDestBytes;
919}
920
921oslFileError osl::detail::convertUrlToPathname(OUString const & url, OString * pathname) {
922 assert(pathname != nullptr)(static_cast <bool> (pathname != nullptr) ? void (0) : __assert_fail
("pathname != nullptr", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 922, __extension__ __PRETTY_FUNCTION__))
;
923 oslFileError e;
924 try {
925 e = getSystemPathFromFileUrl(url, pathname, true);
926 } catch (std::length_error &) {
927 e = osl_File_E_RANGE;
928 }
929 if (e == osl_File_E_None && !pathname->startsWith("/")) {
930 e = osl_File_E_INVAL;
931 }
932 return e;
933}
934
935oslFileError osl::detail::convertPathnameToUrl(OString const & pathname, OUString * url) {
936 assert(url != nullptr)(static_cast <bool> (url != nullptr) ? void (0) : __assert_fail
("url != nullptr", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 936, __extension__ __PRETTY_FUNCTION__))
;
937 OUStringBuffer buf(10+pathname.getLength());
938 buf.append("file:");
939 if (pathname.startsWith("/")) {
940 buf.append("//");
941 // so if pathname should ever start with "//" that isn't mistaken for an authority
942 // component
943 }
944 for (sal_Size convert = pathname.getLength();;) {
945 auto n = std::max(convert, sal_Size(PATH_MAX4096)); // approximation of required converted size
946 OUStringBuffer ubuf(static_cast<int>(n));
947 auto s = ubuf.appendUninitialized(n);
948 sal_uInt32 info;
949 sal_Size converted;
950 //TODO: context, for reliable treatment of DESTBUFFERTOSMALL:
951 n = TextToUnicodeConverter_Impl::getInstance().convert(
952 pathname.getStr() + pathname.getLength() - convert, convert, s, n,
953 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR((sal_uInt32)0x0001) | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR((sal_uInt32)0x0010)
954 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR((sal_uInt32)0x0100) | RTL_TEXTTOUNICODE_FLAGS_FLUSH((sal_uInt32)0x8000)),
955 &info, &converted);
956 ubuf.setLength(n);
957 buf.append(
958 rtl::Uri::encode(
959 ubuf.makeStringAndClear(), uriCharClass, rtl_UriEncodeIgnoreEscapes,
960 RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
961 assert(converted <= convert)(static_cast <bool> (converted <= convert) ? void (0
) : __assert_fail ("converted <= convert", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 961, __extension__ __PRETTY_FUNCTION__))
;
962 convert -= converted;
963 if ((info & RTL_TEXTTOUNICODE_INFO_ERROR((sal_uInt32)0x0001)) != 0) {
964 assert(convert > 0)(static_cast <bool> (convert > 0) ? void (0) : __assert_fail
("convert > 0", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 964, __extension__ __PRETTY_FUNCTION__))
;
965 //TODO: see writeEscapeOctet in sal/rtl/uri.cxx
966 buf.append("%");
967 unsigned char c = pathname[pathname.getLength() - convert];
968 assert(c >= 0x80)(static_cast <bool> (c >= 0x80) ? void (0) : __assert_fail
("c >= 0x80", "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 968, __extension__ __PRETTY_FUNCTION__))
;
969 static sal_Unicode const aHex[16]
970 = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
971 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }; /* '0'--'9', 'A'--'F' */
972 buf.append(aHex[c >> 4]);
973 buf.append(aHex[c & 15]);
974 --convert;
975 continue;
976 }
977 assert((convert == 0) == ((info & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL) == 0))(static_cast <bool> ((convert == 0) == ((info & ((sal_uInt32
)0x0004)) == 0)) ? void (0) : __assert_fail ("(convert == 0) == ((info & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL) == 0)"
, "/home/maarten/src/libreoffice/core/sal/osl/unx/file_url.cxx"
, 977, __extension__ __PRETTY_FUNCTION__))
;
978 if ((info & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL((sal_uInt32)0x0004)) == 0) {
979 break;
980 }
981 }
982 *url = buf.makeStringAndClear();
983 return osl_File_E_None;
984}
985
986/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/osl/file.hxx

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_OSL_FILE_HXX
21#define INCLUDED_OSL_FILE_HXX
22
23#include "sal/config.h"
24
25#include <string.h>
26
27#include <cstddef>
28
29#include "sal/log.hxx"
30#include "osl/time.h"
31#include "rtl/ustring.hxx"
32
33#include "osl/file.h"
34#include "osl/diagnose.h"
35
36namespace rtl { class ByteSequence; }
37
38namespace osl
39{
40
41
42/** Base class for all File System specific objects.
43
44 @see Directory
45 @see DirectoryItem
46 @see File
47 */
48
49class FileBase
50{
51public:
52
53 enum RC {
54 E_None = osl_File_E_None, ///< on success
55 E_PERM = osl_File_E_PERM, ///< operation not permitted
56 E_NOENT = osl_File_E_NOENT, ///< no such file or directory
57 E_SRCH = osl_File_E_SRCH, ///< no process matches the PID
58 E_INTR = osl_File_E_INTR, ///< function call was interrupted
59 E_IO = osl_File_E_IO, ///< I/O error occurred
60 E_NXIO = osl_File_E_NXIO, ///< no such device or address
61 E_2BIG = osl_File_E_2BIG, ///< argument list too long
62 E_NOEXEC = osl_File_E_NOEXEC, ///< invalid executable file format
63 E_BADF = osl_File_E_BADF, ///< bad file descriptor
64 E_CHILD = osl_File_E_CHILD, ///< there are no child processes
65 E_AGAIN = osl_File_E_AGAIN, ///< resource temp unavailable, try again later
66 E_NOMEM = osl_File_E_NOMEM, ///< no memory available
67 E_ACCES = osl_File_E_ACCES, ///< file permissions do not allow operation
68 E_FAULT = osl_File_E_FAULT, ///< bad address; an invalid pointer detected
69 E_BUSY = osl_File_E_BUSY, ///< resource busy
70 E_EXIST = osl_File_E_EXIST, ///< file exists where should only be created
71 E_XDEV = osl_File_E_XDEV, ///< improper link across file systems detected
72 E_NODEV = osl_File_E_NODEV, ///< wrong device type specified
73 E_NOTDIR = osl_File_E_NOTDIR, ///< file isn't a directory where one is needed
74 E_ISDIR = osl_File_E_ISDIR, ///< file is a directory, invalid operation
75 E_INVAL = osl_File_E_INVAL, ///< invalid argument to library function
76 E_NFILE = osl_File_E_NFILE, ///< too many distinct file openings
77 E_MFILE = osl_File_E_MFILE, ///< process has too many distinct files open
78 E_NOTTY = osl_File_E_NOTTY, ///< inappropriate I/O control operation
79 E_FBIG = osl_File_E_FBIG, ///< file too large
80 E_NOSPC = osl_File_E_NOSPC, ///< no space left on device, write failed
81 E_SPIPE = osl_File_E_SPIPE, ///< invalid seek operation (such as on pipe)
82 E_ROFS = osl_File_E_ROFS, ///< illegal modification to read-only filesystem
83 E_MLINK = osl_File_E_MLINK, ///< too many links to file
84 E_PIPE = osl_File_E_PIPE, ///< broken pipe; no process reading from other end of pipe
85 E_DOM = osl_File_E_DOM, ///< domain error (mathematical error)
86 E_RANGE = osl_File_E_RANGE, ///< range error (mathematical error)
87 E_DEADLK = osl_File_E_DEADLK, ///< deadlock avoided
88 E_NAMETOOLONG = osl_File_E_NAMETOOLONG, ///< filename too long
89 E_NOLCK = osl_File_E_NOLCK, ///< no locks available
90 E_NOSYS = osl_File_E_NOSYS, ///< function not implemented
91 E_NOTEMPTY = osl_File_E_NOTEMPTY, ///< directory not empty
92 E_LOOP = osl_File_E_LOOP, ///< too many levels of symbolic links found during name lookup
93 E_ILSEQ = osl_File_E_ILSEQ, ///< invalid or incomplete byte sequence of multibyte char found
94 E_NOLINK = osl_File_E_NOLINK, ///< link has been severed
95 E_MULTIHOP = osl_File_E_MULTIHOP, ///< remote resource is not directly available
96 E_USERS = osl_File_E_USERS, ///< file quote system is confused as there are too many users
97 E_OVERFLOW = osl_File_E_OVERFLOW, ///< value too large for defined data type
98 E_NOTREADY = osl_File_E_NOTREADY, ///< device not ready
99 E_invalidError = osl_File_E_invalidError, ///< unmapped error: always last entry in enum!
100 E_TIMEDOUT = osl_File_E_TIMEDOUT, ///< socket operation timed out
101 E_NETWORK = osl_File_E_NETWORK
102 };
103
104
105public:
106
107 /** Determine a valid unused canonical name for a requested name.
108
109 Determines a valid unused canonical name for a requested name.
110 Depending on the Operating System and the File System the illegal characters are replaced by valid ones.
111 If a file or directory with the requested name already exists a new name is generated following
112 the common rules on the actual Operating System and File System.
113
114 @param[in] ustrRequestedURL
115 Requested name of a file or directory.
116
117 @param[out] ustrValidURL
118 On success receives a name which is unused and valid on the actual Operating System and
119 File System.
120
121 @retval E_None on success
122 @retval E_INVAL the format of the parameters was not valid
123
124 @see DirectoryItem::getFileStatus()
125 */
126
127 static RC getCanonicalName( const ::rtl::OUString& ustrRequestedURL, ::rtl::OUString& ustrValidURL )
128 {
129 return static_cast< RC >( osl_getCanonicalName( ustrRequestedURL.pData, &ustrValidURL.pData ) );
130 }
131
132 /** Convert a path relative to a given directory into an full qualified file URL.
133
134 Convert a path relative to a given directory into an full qualified file URL.
135 The function resolves symbolic links if possible and path ellipses, so on success
136 the resulting absolute path is fully resolved.
137
138 @param[in] ustrBaseDirectoryURL
139 Base directory URL to which the relative path is related to.
140
141 @param[in] ustrRelativeFileURL
142 A URL of a file or directory relative to the directory path specified by ustrBaseDirectoryURL
143 or an absolute path.
144 If ustrRelativeFileURL denotes an absolute path ustrBaseDirectoryURL will be ignored.
145
146 @param[out] ustrAbsoluteFileURL
147 On success it receives the full qualified absolute file URL.
148
149 @retval E_None on success
150 @retval E_INVAL the format of the parameters was not valid
151 @retval E_NOMEM not enough memory for allocating structures
152 @retval E_NOTDIR not a directory
153 @retval E_ACCES permission denied
154 @retval E_NOENT no such file or directory
155 @retval E_NAMETOOLONG file name too long
156 @retval E_OVERFLOW value too large for defined data type
157 @retval E_FAULT bad address
158 @retval E_INTR function call was interrupted
159 @retval E_LOOP too many symbolic links encountered
160 @retval E_MULTIHOP multihop attempted
161 @retval E_NOLINK link has been severed
162
163 @see DirectoryItem::getFileStatus()
164 */
165
166 static RC getAbsoluteFileURL( const ::rtl::OUString& ustrBaseDirectoryURL, const ::rtl::OUString& ustrRelativeFileURL, ::rtl::OUString& ustrAbsoluteFileURL )
167 {
168 return static_cast< RC >( osl_getAbsoluteFileURL( ustrBaseDirectoryURL.pData, ustrRelativeFileURL.pData, &ustrAbsoluteFileURL.pData ) );
169 }
170
171 /** Convert a file URL into a system dependent path.
172
173 @param[in] ustrFileURL
174 A File URL.
175
176 @param[out] ustrSystemPath
177 On success it receives the system path.
178
179 @retval E_None on success
180 @retval E_INVAL the format of the parameters was not valid
181
182 @see getFileURLFromSystemPath()
183 */
184
185 static RC getSystemPathFromFileURL( const ::rtl::OUString& ustrFileURL, ::rtl::OUString& ustrSystemPath )
186 {
187 return static_cast< RC >( osl_getSystemPathFromFileURL( ustrFileURL.pData, &ustrSystemPath.pData ) );
5
Null pointer value stored to field 'pData'
6
Calling 'osl_getSystemPathFromFileURL'
188 }
189
190 /** Convert a system dependent path into a file URL.
191
192 @param[in] ustrSystemPath
193 A System dependent path of a file or directory.
194
195 @param[out] ustrFileURL
196 On success it receives the file URL.
197
198 @retval E_None on success
199 @retval E_INVAL the format of the parameters was not valid
200
201 @see getSystemPathFromFileURL()
202 */
203
204 static RC getFileURLFromSystemPath( const ::rtl::OUString& ustrSystemPath, ::rtl::OUString& ustrFileURL )
205 {
206 return static_cast< RC >( osl_getFileURLFromSystemPath( ustrSystemPath.pData, &ustrFileURL.pData ) );
207 }
208
209 /** Search a full qualified system path or a file URL.
210
211 @param[in] ustrFileName
212 A system dependent path, a file URL, a file or relative directory
213
214 @param[in] ustrSearchPath
215 A list of system paths, in which a given file has to be searched. The Notation of a path list is
216 system dependent, e.g. on UNIX system "/usr/bin:/bin" and on Windows "C:\BIN;C:\BATCH".
217 These paths are only for the search of a file or a relative path, otherwise it will be ignored.
218 If ustrSearchPath is NULL or while using the search path the search failed, the function searches for
219 a matching file in all system directories and in the directories listed in the PATH environment
220 variable.
221 The value of an environment variable should be used (e.g. LD_LIBRARY_PATH) if the caller is not
222 aware of the Operating System and so doesn't know which path list delimiter to use.
223
224 @param[out] ustrFileURL
225 On success it receives the full qualified file URL.
226
227 @retval E_None on success
228 @retval E_INVAL the format of the parameters was not valid
229 @retval E_NOTDIR not a directory
230 @retval E_NOENT no such file or directory not found
231
232 @see getFileURLFromSystemPath()
233 @see getSystemPathFromFileURL()
234 */
235
236 static RC searchFileURL( const ::rtl::OUString& ustrFileName, const ::rtl::OUString& ustrSearchPath, ::rtl::OUString& ustrFileURL )
237 {
238 return static_cast< RC >( osl_searchFileURL( ustrFileName.pData, ustrSearchPath.pData, &ustrFileURL.pData ) );
239 }
240
241 /** Retrieves the file URL of the system's temporary directory path.
242
243 @param[out] ustrTempDirURL
244 On success receives the URL of system's temporary directory path.
245
246 @retval E_None on success
247 @retval E_NOENT no such file or directory not found
248 */
249
250 static RC getTempDirURL( ::rtl::OUString& ustrTempDirURL )
251 {
252 return static_cast< RC >( osl_getTempDirURL( &ustrTempDirURL.pData ) );
253 }
254
255 /** Creates a temporary file in the directory provided by the caller or the
256 directory returned by getTempDirURL.
257 Under UNIX Operating Systems the file will be created with read and write
258 access for the user exclusively.
259 If the caller requests only a handle to the open file but not the name of
260 it, the file will be automatically removed on close else the caller is
261 responsible for removing the file on success.<br><br>
262
263 @param[in] pustrDirectoryURL
264 Specifies the full qualified URL where the temporary file should be created.
265 If pustrDirectoryURL is 0 the path returned by osl_getTempDirURL will be used.
266
267 @param[out] pHandle
268 On success receives a handle to the open file.
269 If pHandle is 0 the file will be closed on return, in this case
270 pustrTempFileURL must not be 0.
271
272 @param[out] pustrTempFileURL
273 On success receives the full qualified URL of the temporary file.
274 If pustrTempFileURL is 0 the file will be automatically removed
275 on close, in this case pHandle must not be 0.
276 If pustrTempFileURL is not 0 the caller receives the name of the
277 created file and is responsible for removing the file.
278
279 Description of the different pHandle, ppustrTempFileURL parameter combinations.
280 pHandle is 0 and pustrTempDirURL is 0 - this combination is invalid<br>
281 pHandle is not 0 and pustrTempDirURL is 0 - a handle to the open file
282 will be returned on success and the file will be automatically removed on close<br>
283 pHandle is 0 and pustrTempDirURL is not 0 - the name of the file will be
284 returned, the caller is responsible for opening, closing and removing the file.<br>
285 pHandle is not 0 and pustrTempDirURL is not 0 - a handle to the open file as well as
286 the file name will be returned, the caller is responsible for closing and removing
287 the file.<br>
288
289 @retval E_None on success
290 @retval E_INVAL the format of the parameter is invalid
291 @retval E_NOMEM not enough memory for allocating structures
292 @retval E_ACCES Permission denied
293 @retval E_NOENT No such file or directory
294 @retval E_NOTDIR Not a directory
295 @retval E_ROFS Read-only file system
296 @retval E_NOSPC No space left on device
297 @retval E_DQUOT Quota exceeded
298
299 @see getTempDirURL()
300 */
301
302 static RC createTempFile(
303 ::rtl::OUString* pustrDirectoryURL,
304 oslFileHandle* pHandle,
305 ::rtl::OUString* pustrTempFileURL)
306 {
307 rtl_uString* pustr_dir_url = pustrDirectoryURL ? pustrDirectoryURL->pData : NULL__null;
308 rtl_uString** ppustr_tmp_file_url = pustrTempFileURL ? &pustrTempFileURL->pData : NULL__null;
309
310 return static_cast< RC >( osl_createTempFile(pustr_dir_url, pHandle, ppustr_tmp_file_url) );
311 }
312};
313
314
315/** The VolumeDevice class.
316
317 @see VolumeInfo
318*/
319
320class VolumeDevice : public FileBase
321{
322 oslVolumeDeviceHandle _aHandle;
323
324public:
325
326 /** Constructor.
327 */
328
329 VolumeDevice() : _aHandle( NULL__null )
330 {
331 }
332
333 /** Copy constructor.
334
335 @param rDevice
336 The other volume device.
337 */
338
339 VolumeDevice( const VolumeDevice & rDevice )
340 {
341 _aHandle = rDevice._aHandle;
342 if ( _aHandle )
343 osl_acquireVolumeDeviceHandle( _aHandle );
344 }
345
346 /** Destructor.
347 */
348
349 ~VolumeDevice()
350 {
351 if ( _aHandle )
352 osl_releaseVolumeDeviceHandle( _aHandle );
353 }
354
355 /** Assignment operator.
356
357 @param rDevice
358 The other volume device.
359 */
360
361 VolumeDevice & operator =( const VolumeDevice & rDevice )
362 {
363 oslVolumeDeviceHandle newHandle = rDevice._aHandle;
364
365 if ( newHandle )
366 osl_acquireVolumeDeviceHandle( newHandle );
367
368 if ( _aHandle )
369 osl_releaseVolumeDeviceHandle( _aHandle );
370
371 _aHandle = newHandle;
372
373 return *this;
374 }
375
376 /** Get the full qualified URL where a device is mounted to.
377
378 @return
379 The full qualified URL where the device is mounted to.
380 */
381 rtl::OUString getMountPath()
382 {
383 rtl::OUString aPath;
384 osl_getVolumeDeviceMountPath( _aHandle, &aPath.pData );
385 return aPath;
386 }
387
388 friend class VolumeInfo;
389};
390
391
392class Directory;
393
394/** The VolumeInfo class.
395
396 Neither copy nor assignment is allowed for this class.
397
398 @see Directory::getVolumeInfo
399*/
400
401
402class VolumeInfo
403{
404 oslVolumeInfo _aInfo;
405 sal_uInt32 _nMask;
406 VolumeDevice _aDevice;
407
408 /** Copy constructor.
409 */
410
411 VolumeInfo( VolumeInfo& ) SAL_DELETED_FUNCTION= delete;
412
413 /** Assignment operator.
414 */
415
416 VolumeInfo& operator = ( VolumeInfo& ) SAL_DELETED_FUNCTION= delete;
417
418public:
419
420 /** Constructor.
421
422 @param nMask
423 Set of flags describing the demanded information.
424 */
425 VolumeInfo( sal_uInt32 nMask )
426 : _nMask( nMask )
427 {
428 memset( &_aInfo, 0, sizeof( oslVolumeInfo ));
429 _aInfo.uStructSize = sizeof( oslVolumeInfo );
430 _aInfo.pDeviceHandle = &_aDevice._aHandle;
431 }
432
433 ~VolumeInfo()
434 {
435 if( _aInfo.ustrFileSystemName )
436 rtl_uString_release( _aInfo.ustrFileSystemName );
437 }
438
439 /** Check if specified fields are valid.
440
441 @param nMask
442 Set of flags for the fields to check.
443
444 @return true if all fields are valid else false.
445 */
446 bool isValid( sal_uInt32 nMask ) const
447 {
448 return ( nMask & _aInfo.uValidFields ) == nMask;
449 }
450
451 /** Check the remote flag.
452
453 @return
454 true if Attributes are valid and the volume is remote else false.
455 */
456 bool getRemoteFlag() const
457 {
458 return (_aInfo.uAttributes & osl_Volume_Attribute_Remote0x00000002L) != 0;
459 }
460
461 /** Check the removable flag.
462
463 @return
464 true if attributes are valid and the volume is removable else false.
465 */
466 bool getRemoveableFlag() const
467 {
468 return (_aInfo.uAttributes & osl_Volume_Attribute_Removeable0x00000001L) != 0;
469 }
470
471 /** Check the compact disc flag.
472
473 @return
474 true if attributes are valid and the volume is a CDROM else false.
475 */
476
477 bool getCompactDiscFlag() const
478 {
479 return (_aInfo.uAttributes & osl_Volume_Attribute_CompactDisc0x00000004L) != 0;
480 }
481
482 /** Check the floppy disc flag.
483
484 @return
485 true if attributes are valid and the volume is a floppy disk else false.
486 */
487
488 bool getFloppyDiskFlag() const
489 {
490 return (_aInfo.uAttributes & osl_Volume_Attribute_FloppyDisk0x00000020L) != 0;
491 }
492
493 /** Check the fixed disk flag.
494
495 @return
496 true if attributes are valid and the volume is a fixed disk else false.
497 */
498
499 bool getFixedDiskFlag() const
500 {
501 return (_aInfo.uAttributes & osl_Volume_Attribute_FixedDisk0x00000008L) != 0;
502 }
503
504 /** Check the RAM disk flag.
505
506 @return
507 true if attributes are valid and the volume is a RAM disk else false.
508 */
509
510 bool getRAMDiskFlag() const
511 {
512 return (_aInfo.uAttributes & osl_Volume_Attribute_RAMDisk0x00000010L) != 0;
513 }
514
515 /** Determine the total space of a volume device.
516
517 @return
518 The total diskspace of this volume if this information is valid,
519 0 otherwise.
520 */
521
522 sal_uInt64 getTotalSpace() const
523 {
524 return _aInfo.uTotalSpace;
525 }
526
527 /** Determine the free space of a volume device.
528
529 @return
530 The free diskspace of this volume if this information is valid,
531 0 otherwise.
532 */
533
534 sal_uInt64 getFreeSpace() const
535 {
536 return _aInfo.uFreeSpace;
537 }
538
539 /** Determine the used space of a volume device.
540
541 @return
542 The used diskspace of this volume if this information is valid,
543 0 otherwise.
544 */
545
546 sal_uInt64 getUsedSpace() const
547 {
548 return _aInfo.uUsedSpace;
549 }
550
551 /** Determine the maximal length of a file name.
552
553 @return
554 The maximal length of a file name if this information is valid,
555 0 otherwise.
556 */
557
558 sal_uInt32 getMaxNameLength() const
559 {
560 return _aInfo.uMaxNameLength;
561 }
562
563 /** Determine the maximal length of a path name.
564
565 @return
566 The maximal length of a path if this information is valid,
567 0 otherwise.
568 */
569
570 sal_uInt32 getMaxPathLength() const
571 {
572 return _aInfo.uMaxPathLength;
573 }
574
575 /** Determine the name of the volume device's File System.
576
577 @return
578 The name of the volume's filesystem if this information is valid,
579 otherwise an empty string.
580 */
581
582 ::rtl::OUString getFileSystemName() const
583 {
584 return _aInfo.ustrFileSystemName ? ::rtl::OUString( _aInfo.ustrFileSystemName ) : ::rtl::OUString();
585 }
586
587
588 /** Get the volume device handle.
589
590 @return
591 The device handle of the volume if this information is valid,
592 otherwise returns NULL;
593 */
594
595 VolumeDevice getDeviceHandle() const
596 {
597 return _aDevice;
598 }
599
600 /** Return whether the file system is case sensitive or
601 case insensitive
602
603 @return
604 true if the file system is case sensitive false otherwise
605 */
606 bool isCaseSensitiveFileSystem() const
607 {
608 return (_aInfo.uAttributes & osl_Volume_Attribute_Case_Sensitive0x00000080L) != 0;
609 }
610
611 /** Return whether the file system preserves the case of
612 file and directory names or not
613
614 @return
615 true if the file system preserves the case of file and
616 directory names false otherwise
617 */
618 bool isCasePreservingFileSystem() const
619 {
620 return (_aInfo.uAttributes & osl_Volume_Attribute_Case_Is_Preserved0x00000040L) != 0;
621 }
622
623 friend class Directory;
624};
625
626
627class DirectoryItem;
628
629/** The FileStatus class.
630
631 @see DirectoryItem::getFileStatus
632*/
633
634class FileStatus
635{
636 oslFileStatus _aStatus;
637 sal_uInt32 _nMask;
638
639 /** Copy constructor.
640 */
641
642 FileStatus( FileStatus& ) SAL_DELETED_FUNCTION= delete;
643
644 /** Assignment operator.
645 */
646
647 FileStatus& operator = ( FileStatus& ) SAL_DELETED_FUNCTION= delete;
648
649public:
650
651 enum Type {
652 Directory = osl_File_Type_Directory,
653 Volume = osl_File_Type_Volume,
654 Regular = osl_File_Type_Regular,
655 Fifo = osl_File_Type_Fifo,
656 Socket = osl_File_Type_Socket,
657 Link = osl_File_Type_Link,
658 Special = osl_File_Type_Special,
659 Unknown = osl_File_Type_Unknown
660 };
661
662 /** Constructor.
663
664 @param nMask
665 Set of flags describing the demanded information.
666 */
667 FileStatus(sal_uInt32 nMask)
668 : _nMask(nMask)
669 {
670 memset(&_aStatus, 0, sizeof(_aStatus));
671 _aStatus.uStructSize = sizeof(_aStatus);
672 }
673
674 /** Destructor.
675 */
676 ~FileStatus()
677 {
678 if ( _aStatus.ustrFileURL )
679 rtl_uString_release( _aStatus.ustrFileURL );
680 if ( _aStatus.ustrLinkTargetURL )
681 rtl_uString_release( _aStatus.ustrLinkTargetURL );
682 if ( _aStatus.ustrFileName )
683 rtl_uString_release( _aStatus.ustrFileName );
684 }
685
686 /** Check if specified fields are valid.
687
688 @param nMask
689 Set of flags for the fields to check.
690
691 @return
692 true if all fields are valid else false.
693 */
694
695 bool isValid( sal_uInt32 nMask ) const
696 {
697 return ( nMask & _aStatus.uValidFields ) == nMask;
698 }
699
700 /** Get the file type.
701
702 @return
703 The file type.
704 */
705 Type getFileType() const
706 {
707 SAL_INFO_IF(do { if (true && (!isValid(0x00000001))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus Type determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Type determined"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Type determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus Type determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Type determined"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Type determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
708 !isValid(osl_FileStatus_Mask_Type), "sal.osl",do { if (true && (!isValid(0x00000001))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus Type determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Type determined"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Type determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus Type determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Type determined"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Type determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
709 "no FileStatus Type determined")do { if (true && (!isValid(0x00000001))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus Type determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Type determined"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Type determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus Type determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Type determined"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Type determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "709" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
710 return isValid(osl_FileStatus_Mask_Type0x00000001)
711 ? static_cast< Type >(_aStatus.eType) : Unknown;
712 }
713
714 /** Is it a directory?
715 This method returns True for both directories, and volumes.
716
717 @return
718 True if it's a directory, False otherwise.
719
720 @see getFileType
721 @since LibreOffice 3.6
722 */
723 bool isDirectory() const
724 {
725 return ( getFileType() == Directory || getFileType() == Volume );
726 }
727
728 /** Is it a regular file?
729
730 @return
731 True if it's a regular file, False otherwise.
732
733 @see getFileType
734 @see isFile
735 @see isLink
736 @since LibreOffice 3.6
737 */
738 bool isRegular() const
739 {
740 return ( getFileType() == Regular );
741 }
742
743 /** Is it a link?
744
745 @return
746 True if it's a link, False otherwise.
747
748 @see getFileType
749 @since LibreOffice 3.6
750 */
751 bool isLink() const
752 {
753 return ( getFileType() == Link );
754 }
755
756 /** Get the file attributes.
757
758 @return
759 The set of attribute flags of this file.
760 */
761
762 sal_uInt64 getAttributes() const
763 {
764 SAL_INFO_IF(do { if (true && (!isValid(0x00000002))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus Attributes determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Attributes determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Attributes determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus Attributes determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"766" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus Attributes determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus Attributes determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
765 !isValid(osl_FileStatus_Mask_Attributes), "sal.osl",do { if (true && (!isValid(0x00000002))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus Attributes determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Attributes determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Attributes determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus Attributes determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"766" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus Attributes determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus Attributes determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
766 "no FileStatus Attributes determined")do { if (true && (!isValid(0x00000002))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus Attributes determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus Attributes determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus Attributes determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus Attributes determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"766" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus Attributes determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus Attributes determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "766" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
767 return _aStatus.uAttributes;
768 }
769
770 /** Get the creation time of this file.
771
772 @return
773 The creation time if this information is valid, an uninitialized
774 TimeValue otherwise.
775 */
776
777 TimeValue getCreationTime() const
778 {
779 SAL_INFO_IF(do { if (true && (!isValid(0x00000010))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus CreationTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus CreationTime determined"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus CreationTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus CreationTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"781" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus CreationTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus CreationTime determined"; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
780 !isValid(osl_FileStatus_Mask_CreationTime), "sal.osl",do { if (true && (!isValid(0x00000010))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus CreationTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus CreationTime determined"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus CreationTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus CreationTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"781" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus CreationTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus CreationTime determined"; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
781 "no FileStatus CreationTime determined")do { if (true && (!isValid(0x00000010))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus CreationTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus CreationTime determined"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus CreationTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus CreationTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"781" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus CreationTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus CreationTime determined"; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "781" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
782 return _aStatus.aCreationTime;
783 }
784
785 /** Get the file access time.
786
787 @return
788 The last access time if this information is valid, an uninitialized
789 TimeValue otherwise.
790 */
791
792 TimeValue getAccessTime() const
793 {
794 SAL_INFO_IF(do { if (true && (!isValid(0x00000020))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus AccessTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus AccessTime determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus AccessTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus AccessTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"796" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus AccessTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus AccessTime determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
795 !isValid(osl_FileStatus_Mask_AccessTime), "sal.osl",do { if (true && (!isValid(0x00000020))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus AccessTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus AccessTime determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus AccessTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus AccessTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"796" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus AccessTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus AccessTime determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
796 "no FileStatus AccessTime determined")do { if (true && (!isValid(0x00000020))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus AccessTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus AccessTime determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus AccessTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus AccessTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"796" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus AccessTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus AccessTime determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "796" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
797 return _aStatus.aAccessTime;
798 }
799
800 /** Get the file modification time.
801
802 @return
803 The last modified time if this information is valid, an uninitialized
804 TimeValue otherwise.
805 */
806
807 TimeValue getModifyTime() const
808 {
809 SAL_INFO_IF(do { if (true && (!isValid(0x00000040))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus ModifyTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus ModifyTime determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus ModifyTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus ModifyTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"811" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus ModifyTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus ModifyTime determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
810 !isValid(osl_FileStatus_Mask_ModifyTime), "sal.osl",do { if (true && (!isValid(0x00000040))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus ModifyTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus ModifyTime determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus ModifyTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus ModifyTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"811" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus ModifyTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus ModifyTime determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
811 "no FileStatus ModifyTime determined")do { if (true && (!isValid(0x00000040))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus ModifyTime determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus ModifyTime determined")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus ModifyTime determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus ModifyTime determined") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), (
"/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"811" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus ModifyTime determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus ModifyTime determined"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "811" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
812 return _aStatus.aModifyTime;
813 }
814
815 /** Get the size of the file.
816
817 @return
818 The actual file size if this information is valid, 0 otherwise.
819 */
820
821 sal_uInt64 getFileSize() const
822 {
823 SAL_INFO_IF(do { if (true && (!isValid(0x00000080))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileSize determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileSize determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileSize determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileSize determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileSize determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileSize determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
824 !isValid(osl_FileStatus_Mask_FileSize), "sal.osl",do { if (true && (!isValid(0x00000080))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileSize determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileSize determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileSize determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileSize determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileSize determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileSize determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
825 "no FileStatus FileSize determined")do { if (true && (!isValid(0x00000080))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileSize determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileSize determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileSize determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileSize determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileSize determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileSize determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "825" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
826 return _aStatus.uFileSize;
827 }
828
829 /** Get the file name.
830
831 @return
832 The file name if this information is valid, an empty string otherwise.
833 */
834
835 ::rtl::OUString getFileName() const
836 {
837 SAL_INFO_IF(do { if (true && (!isValid(0x00000100))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileName determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileName determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileName determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileName determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileName determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileName determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
838 !isValid(osl_FileStatus_Mask_FileName), "sal.osl",do { if (true && (!isValid(0x00000100))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileName determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileName determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileName determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileName determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileName determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileName determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
839 "no FileStatus FileName determined")do { if (true && (!isValid(0x00000100))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileName determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileName determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileName determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileName determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileName determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileName determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "839" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
840 return isValid(osl_FileStatus_Mask_FileName0x00000100)
841 ? rtl::OUString(_aStatus.ustrFileName) : rtl::OUString();
842 }
843
844
845 /** Get the URL of the file.
846
847 @return
848 The full qualified URL of the file if this information is valid, an
849 empty string otherwise.
850 */
851
852 ::rtl::OUString getFileURL() const
853 {
854 SAL_INFO_IF(do { if (true && (!isValid(0x00000200))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileURL determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileURL determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileURL determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileURL determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileURL determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileURL determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
855 !isValid(osl_FileStatus_Mask_FileURL), "sal.osl",do { if (true && (!isValid(0x00000200))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileURL determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileURL determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileURL determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileURL determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileURL determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileURL determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
856 "no FileStatus FileURL determined")do { if (true && (!isValid(0x00000200))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus FileURL determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileURL determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileURL determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus FileURL determined") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus FileURL determined"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus FileURL determined"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "856" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
857 return isValid(osl_FileStatus_Mask_FileURL0x00000200)
858 ? rtl::OUString(_aStatus.ustrFileURL) : rtl::OUString();
859 }
860
861 /** Get the link target URL.
862
863 @return
864 The link target URL if this information is valid, an empty string
865 otherwise.
866 */
867
868 ::rtl::OUString getLinkTargetURL() const
869 {
870 SAL_INFO_IF(do { if (true && (!isValid(0x00000400))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus LinkTargetURL determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus LinkTargetURL determined"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus LinkTargetURL determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus LinkTargetURL determined") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl")
, ("/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"872" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus LinkTargetURL determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus LinkTargetURL determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
871 !isValid(osl_FileStatus_Mask_LinkTargetURL), "sal.osl",do { if (true && (!isValid(0x00000400))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus LinkTargetURL determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus LinkTargetURL determined"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus LinkTargetURL determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus LinkTargetURL determined") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl")
, ("/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"872" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus LinkTargetURL determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus LinkTargetURL determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
872 "no FileStatus LinkTargetURL determined")do { if (true && (!isValid(0x00000400))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_INFO, "sal.osl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no FileStatus LinkTargetURL determined"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"
), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no FileStatus LinkTargetURL determined"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "no FileStatus LinkTargetURL determined"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no FileStatus LinkTargetURL determined") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl")
, ("/home/maarten/src/libreoffice/core/include/osl/file.hxx" ":"
"872" ": "), ::sal::detail::unwrapStream( ::sal::detail::StreamStart
() << "no FileStatus LinkTargetURL determined"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no FileStatus LinkTargetURL determined"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sal.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "872" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
873 return isValid(osl_FileStatus_Mask_LinkTargetURL0x00000400)
874 ? rtl::OUString(_aStatus.ustrLinkTargetURL) : rtl::OUString();
875 }
876
877 friend class DirectoryItem;
878};
879
880
881/** The file class object provides access to file contents and attributes.
882
883 @see Directory
884 @see DirectoryItem
885 */
886
887class File: public FileBase
888{
889 oslFileHandle _pData;
890 ::rtl::OUString _aPath;
891
892 /** Copy constructor.
893 */
894
895 File( File& ) SAL_DELETED_FUNCTION= delete;
896
897 /** Assignment operator.
898 */
899
900 File& operator = ( File& ) SAL_DELETED_FUNCTION= delete;
901
902public:
903
904 /** Constructor.
905
906 @param[in] ustrFileURL
907 The full qualified URL of the file. Relative paths are not allowed.
908 */
909
910 File( const ::rtl::OUString& ustrFileURL ): _pData( NULL__null ), _aPath( ustrFileURL ) {}
911
912 /** Destructor
913 */
914
915 ~File()
916 {
917 close();
918 }
919
920 /** Obtain the URL.
921
922 @return
923 the URL with which this File instance was created.
924
925 @since LibreOffice 4.1
926 */
927 rtl::OUString getURL() const { return _aPath; }
928
929 /** Open a regular file.
930
931 Open a file. Only regular files can be opened.
932
933 @param[in] uFlags
934 Specifies the open mode.
935
936 @retval E_None on success
937 @retval E_NOMEM not enough memory for allocating structures
938 @retval E_INVAL the format of the parameters was not valid
939 @retval E_NAMETOOLONG pathname was too long
940 @retval E_NOENT no such file or directory
941 @retval E_ACCES permission denied
942 @retval E_AGAIN a write lock could not be established
943 @retval E_NOTDIR not a directory
944 @retval E_NXIO no such device or address
945 @retval E_NODEV no such device
946 @retval E_ROFS read-only file system
947 @retval E_TXTBSY text file busy
948 @retval E_FAULT bad address
949 @retval E_LOOP too many symbolic links encountered
950 @retval E_NOSPC no space left on device
951 @retval E_ISDIR is a directory
952 @retval E_MFILE too many open files used by the process
953 @retval E_NFILE too many open files in the system
954 @retval E_DQUOT quota exceeded
955 @retval E_EXIST file exists
956 @retval E_INTR function call was interrupted
957 @retval E_IO on I/O errors
958 @retval E_MULTIHOP multihop attempted
959 @retval E_NOLINK link has been severed
960 @retval E_EOVERFLOW value too large for defined data type
961
962 @see close()
963 @see setPos()
964 @see getPos()
965 @see read()
966 @see write()
967 @see getSize()
968 @see setSize()
969 */
970
971 RC open( sal_uInt32 uFlags )
972 {
973 return static_cast< RC >( osl_openFile( _aPath.pData, &_pData, uFlags ) );
974 }
975
976 /** Close an open file.
977
978 @retval E_None on success
979 @retval E_INVAL the format of the parameters was not valid
980 @retval E_BADF Bad file
981 @retval E_INTR function call was interrupted
982 @retval E_NOLINK link has been severed
983 @retval E_NOSPC no space left on device
984 @retval E_IO on I/O errors
985
986 @see open()
987 */
988
989 RC close()
990 {
991 oslFileError Error = osl_File_E_BADF;
992
993 if( _pData )
994 {
995 Error=osl_closeFile( _pData );
996 _pData = NULL__null;
997 }
998
999 return static_cast< RC >( Error );
1000 }
1001
1002 /** Set the internal position pointer of an open file.
1003
1004 @param[in] uHow
1005 Distance to move the internal position pointer (from uPos).
1006
1007 @param[in] uPos
1008 Absolute position from the beginning of the file.
1009
1010 @retval E_None on success
1011 @retval E_INVAL the format of the parameters was not valid
1012 @retval E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files
1013
1014 @see open()
1015 @see getPos()
1016 */
1017
1018 SAL_WARN_UNUSED_RESULT[[nodiscard]] RC setPos( sal_uInt32 uHow, sal_Int64 uPos )
1019 {
1020 return static_cast< RC >( osl_setFilePos( _pData, uHow, uPos ) );
1021 }
1022
1023 /** Retrieve the current position of the internal pointer of an open file.
1024
1025 @param[out] uPos
1026 On success receives the current position of the file pointer.
1027
1028 @retval E_None on success
1029 @retval E_INVAL the format of the parameters was not valid
1030 @retval E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files
1031
1032 @see open()
1033 @see setPos()
1034 @see read()
1035 @see write()
1036 */
1037
1038 RC getPos( sal_uInt64& uPos )
1039 {
1040 return static_cast< RC >( osl_getFilePos( _pData, &uPos ) );
1041 }
1042
1043 /** Test if the end of a file is reached.
1044
1045 @param[out] pIsEOF
1046 Points to a variable that receives the end-of-file status.
1047
1048 @retval E_None on success
1049 @retval E_INVAL the format of the parameters was not valid
1050 @retval E_INTR function call was interrupted
1051 @retval E_IO on I/O errors
1052 @retval E_ISDIR is a directory
1053 @retval E_BADF bad file
1054 @retval E_FAULT bad address
1055 @retval E_AGAIN operation would block
1056 @retval E_NOLINK link has been severed
1057
1058 @see open()
1059 @see read()
1060 @see readLine()
1061 @see setPos()
1062 */
1063
1064 RC isEndOfFile( sal_Bool *pIsEOF )
1065 {
1066 return static_cast< RC >( osl_isEndOfFile( _pData, pIsEOF ) );
1067 }
1068
1069 /** Set the file size of an open file.
1070
1071 Sets the file size of an open file. The file can be truncated or enlarged by the function.
1072 The position of the file pointer is not affeced by this function.
1073
1074 @param[in] uSize
1075 New size in bytes.
1076
1077 @retval E_None on success
1078 @retval E_INVAL the format of the parameters was not valid
1079 @retval E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files
1080
1081 @see open()
1082 @see setPos()
1083 @see getStatus()
1084 */
1085
1086 RC setSize( sal_uInt64 uSize )
1087 {
1088 return static_cast< RC >( osl_setFileSize( _pData, uSize ) );
1089 }
1090
1091 /** Get the file size of an open file.
1092
1093 Gets the file size of an open file.
1094 The position of the file pointer is not affeced by this function.
1095
1096 @param[out] rSize
1097 Current size in bytes.
1098
1099 @retval E_None on success
1100 @retval E_INVAL the format of the parameters was not valid
1101 @retval E_OVERFLOW the resulting file offset would be a value which cannot be represented correctly for regular files
1102
1103 @see open()
1104 @see setPos()
1105 @see getSize()
1106 @see setSize()
1107 @see getStatus()
1108 */
1109
1110 RC getSize( sal_uInt64 &rSize )
1111 {
1112 return static_cast< RC >( osl_getFileSize( _pData, &rSize ) );
1113 }
1114
1115 /** Read a number of bytes from a file.
1116
1117 Reads a number of bytes from a file. The internal file pointer is
1118 increased by the number of bytes read.
1119
1120 @param[out] pBuffer
1121 Points to a buffer which receives data. The buffer must be large enough
1122 to hold uBytesRequested bytes.
1123
1124 @param[in] uBytesRequested
1125 Number of bytes which should be retrieved.
1126
1127 @param[out] rBytesRead
1128 On success the number of bytes which have actually been retrieved.
1129
1130 @retval E_None on success
1131 @retval E_INVAL the format of the parameters was not valid
1132 @retval E_INTR function call was interrupted
1133 @retval E_IO on I/O errors
1134 @retval E_ISDIR is a directory
1135 @retval E_BADF bad file
1136 @retval E_FAULT bad address
1137 @retval E_AGAIN operation would block
1138 @retval E_NOLINK link has been severed
1139
1140 @see open()
1141 @see write()
1142 @see readLine()
1143 @see setPos()
1144 */
1145
1146 RC read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead )
1147 {
1148 return static_cast< RC >( osl_readFile( _pData, pBuffer, uBytesRequested, &rBytesRead ) );
1149 }
1150
1151 /** Write a number of bytes to a file.
1152
1153 Writes a number of bytes to a file.
1154 The internal file pointer is increased by the number of bytes read.
1155
1156 @param[in] pBuffer
1157 Points to a buffer which contains the data.
1158
1159 @param[in] uBytesToWrite
1160 Number of bytes which should be written.
1161
1162 @param[out] rBytesWritten
1163 On success the number of bytes which have actually been written.
1164
1165 @retval E_None on success
1166 @retval E_INVAL the format of the parameters was not valid
1167 @retval E_FBIG file too large
1168 @retval E_DQUOT quota exceeded
1169 @retval E_AGAIN operation would block
1170 @retval E_BADF bad file
1171 @retval E_FAULT bad address
1172 @retval E_INTR function call was interrupted
1173 @retval E_IO on I/O errors
1174 @retval E_NOLCK no record locks available
1175 @retval E_NOLINK link has been severed
1176 @retval E_NOSPC no space left on device
1177 @retval E_NXIO no such device or address
1178
1179 @see open()
1180 @see read()
1181 @see setPos()
1182 */
1183
1184 RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten)
1185 {
1186 return static_cast< RC >( osl_writeFile( _pData, pBuffer, uBytesToWrite, &rBytesWritten ) );
1187 }
1188
1189
1190 /** Read a line from a file.
1191
1192 Reads a line from a file. The new line delimiter is NOT returned!
1193
1194 @param[in,out] aSeq
1195 A reference to a ::rtl::ByteSequence that will hold the line read on success.
1196
1197 @retval E_None on success
1198 @retval E_INVAL the format of the parameters was not valid
1199 @retval E_INTR function call was interrupted
1200 @retval E_IO on I/O errors
1201 @retval E_ISDIR is a directory
1202 @retval E_BADF bad file
1203 @retval E_FAULT bad address
1204 @retval E_AGAIN operation would block
1205 @retval E_NOLINK link has been severed
1206
1207 @see open()
1208 @see read()
1209 @see write()
1210 @see setPos()
1211 */
1212
1213 RC readLine( ::rtl::ByteSequence& aSeq )
1214 {
1215 return static_cast< RC >( osl_readLine( _pData, reinterpret_cast<sal_Sequence**>(&aSeq) ) );
1216 }
1217
1218 /** Synchronize the memory representation of a file with that on the physical medium.
1219
1220 The function ensures that all modified data and attributes of the file associated with
1221 the given file handle have been written to the physical medium.
1222 In case the hard disk has a write cache enabled, the data may not really be on
1223 permanent storage when osl_syncFile returns.
1224
1225 @retval E_None On success
1226 @retval E_INVAL The value of the input parameter is invalid
1227 @retval E_BADF The file is not open for writing
1228 @retval E_IO An I/O error occurred
1229 @retval E_NOSPC There is no enough space on the target device
1230 @retval E_ROFS The file is located on a read only file system
1231 @retval E_TIMEDOUT A remote connection timed out. This may happen when a file is on a remote location
1232
1233 @see osl_syncFile()
1234 @see open()
1235 @see write()
1236 */
1237 RC sync() const
1238 {
1239 OSL_PRECOND(_pData, "File::sync(): File not open")do { if (true && (!(_pData))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/include/osl/file.hxx"
":" "1239" ": "), "%s", "File::sync(): File not open"); } } while
(false)
;
1240 return static_cast< RC >(osl_syncFile(_pData));
1241 }
1242
1243 /** Copy a file to a new destination.
1244
1245 Copies a file to a new destination. Copies only files not directories.
1246 No assumptions should be made about preserving attributes or file time.
1247
1248 @param[in] ustrSourceFileURL
1249 Full qualified URL of the source file.
1250
1251 @param[in] ustrDestFileURL
1252 Full qualified URL of the destination file. A directory is NOT a valid destination file!
1253
1254 @retval E_None on success
1255 @retval E_INVAL the format of the parameters was not valid
1256 @retval E_NOMEM not enough memory for allocating structures
1257 @retval E_ACCES permission denied
1258 @retval E_PERM operation not permitted
1259 @retval E_NAMETOOLONG file name too long
1260 @retval E_NOENT no such file or directory
1261 @retval E_ISDIR is a directory
1262 @retval E_ROFS read-only file system
1263
1264 @see move()
1265 @see remove()
1266 */
1267
1268 static RC copy( const ::rtl::OUString& ustrSourceFileURL, const ::rtl::OUString& ustrDestFileURL )
1269 {
1270 return static_cast< RC >( osl_copyFile( ustrSourceFileURL.pData, ustrDestFileURL.pData ) );
1271 }
1272
1273 /** Move a file or directory to a new destination or renames it.
1274
1275 Moves a file or directory to a new destination or renames it.
1276 File time and attributes are preserved.
1277
1278 @param[in] ustrSourceFileURL
1279 Full qualified URL of the source file.
1280
1281 @param[in] ustrDestFileURL
1282 Full qualified URL of the destination file. An existing directory is NOT a valid destination !
1283
1284 @retval E_None on success
1285 @retval E_INVAL the format of the parameters was not valid
1286 @retval E_NOMEM not enough memory for allocating structures
1287 @retval E_ACCES permission denied
1288 @retval E_PERM operation not permitted
1289 @retval E_NAMETOOLONG file name too long
1290 @retval E_NOENT no such file or directory
1291 @retval E_ROFS read-only file system
1292
1293 @see copy()
1294 */
1295
1296 static RC move( const ::rtl::OUString& ustrSourceFileURL, const ::rtl::OUString& ustrDestFileURL )
1297 {
1298 return static_cast< RC >( osl_moveFile( ustrSourceFileURL.pData, ustrDestFileURL.pData ) );
1299 }
1300
1301 /** Move a file to a new destination or rename it, taking old file's identity (if exists).
1302
1303 Moves or renames a file, replacing an existing file if exist. If the old file existed,
1304 moved file's metadata, e.g. creation time (on FSes which keep files' creation time) or
1305 ACLs, are set to old one's (to keep the old file's identity) - currently this is only
1306 implemented fully on Windows; on other platforms, this is mostly equivalent to osl_moveFile.
1307
1308 @param[in] ustrSourceFileURL
1309 Full qualified URL of the source file.
1310
1311 @param[in] ustrDestFileURL
1312 Full qualified URL of the destination file.
1313
1314 @retval E_None on success
1315 @retval E_INVAL the format of the parameters was not valid
1316 @retval E_NOMEM not enough memory for allocating structures
1317 @retval E_ACCES permission denied
1318 @retval E_PERM operation not permitted
1319 @retval E_NAMETOOLONG file name too long
1320 @retval E_NOENT no such file
1321 @retval E_ROFS read-only file system
1322 @retval E_BUSY device or resource busy
1323
1324 @see move()
1325
1326 @since LibreOffice 6.2
1327 */
1328 static RC replace(const ::rtl::OUString& ustrSourceFileURL,
1329 const ::rtl::OUString& ustrDestFileURL)
1330 {
1331 return static_cast<RC>(osl_replaceFile(ustrSourceFileURL.pData, ustrDestFileURL.pData));
1332 }
1333
1334 /** Remove a regular file.
1335
1336 @param[in] ustrFileURL
1337 Full qualified URL of the file to remove.
1338
1339 @retval E_None on success
1340 @retval E_INVAL the format of the parameters was not valid
1341 @retval E_NOMEM not enough memory for allocating structures
1342 @retval E_ACCES permission denied
1343 @retval E_PERM operation not permitted
1344 @retval E_NAMETOOLONG file name too long
1345 @retval E_NOENT no such file or directory
1346 @retval E_ISDIR is a directory
1347 @retval E_ROFS read-only file system
1348 @retval E_FAULT bad address
1349 @retval E_LOOP too many symbolic links encountered
1350 @retval E_IO on I/O errors
1351 @retval E_BUSY device or resource busy
1352 @retval E_INTR function call was interrupted
1353 @retval E_MULTIHOP multihop attempted
1354 @retval E_NOLINK link has been severed
1355 @retval E_TXTBSY text file busy
1356
1357 @see open()
1358 */
1359
1360 static RC remove( const ::rtl::OUString& ustrFileURL )
1361 {
1362 return static_cast< RC >( osl_removeFile( ustrFileURL.pData ) );
1363 }
1364
1365 /** Set file attributes.
1366
1367 @param[in] ustrFileURL
1368 The full qualified file URL.
1369
1370 @param[in] uAttributes
1371 Attributes of the file to be set.
1372
1373 @return
1374 @retval E_None on success
1375 @retval E_INVAL the format of the parameters was not valid
1376
1377 @see FileStatus
1378 */
1379
1380 static RC setAttributes( const ::rtl::OUString& ustrFileURL, sal_uInt64 uAttributes )
1381 {
1382 return static_cast< RC >( osl_setFileAttributes( ustrFileURL.pData, uAttributes ) );
1383 }
1384
1385 /** Set the file time.
1386
1387 @param[in] ustrFileURL
1388 The full qualified URL of the file.
1389
1390 @param[in] rCreationTime
1391 Creation time of the given file.
1392
1393 @param[in] rLastAccessTime
1394 Time of the last access of the given file.
1395
1396 @param[in] rLastWriteTime
1397 Time of the last modifying of the given file.
1398
1399 @retval E_None on success
1400 @retval E_INVAL the format of the parameters was not valid
1401 @retval E_NOENT no such file or directory not found
1402
1403 @see FileStatus
1404 */
1405
1406 static RC setTime(
1407 const ::rtl::OUString& ustrFileURL,
1408 const TimeValue& rCreationTime,
1409 const TimeValue& rLastAccessTime,
1410 const TimeValue& rLastWriteTime )
1411 {
1412 return static_cast< RC >( osl_setFileTime(
1413 ustrFileURL.pData,
1414 &rCreationTime,
1415 &rLastAccessTime,
1416 &rLastWriteTime ) );
1417 }
1418
1419 friend class DirectoryItem;
1420};
1421
1422
1423/** The directory item class object provides access to file status information.
1424
1425 @see FileStatus
1426 */
1427
1428class DirectoryItem: public FileBase
1429{
1430 oslDirectoryItem _pData;
1431
1432public:
1433
1434 /** Constructor.
1435 */
1436
1437 DirectoryItem(): _pData( NULL__null )
1438 {
1439 }
1440
1441 /** Copy constructor.
1442 */
1443
1444 DirectoryItem( const DirectoryItem& rItem ): _pData( rItem._pData)
1445 {
1446 if( _pData )
1447 osl_acquireDirectoryItem( _pData );
1448 }
1449
1450 /** Destructor.
1451 */
1452
1453 ~DirectoryItem()
1454 {
1455 if( _pData )
1456 osl_releaseDirectoryItem( _pData );
1457 }
1458
1459 /** Assignment operator.
1460 */
1461
1462 DirectoryItem& operator=(const DirectoryItem& rItem )
1463 {
1464 if (&rItem != this)
1465 {
1466 if( _pData )
1467 osl_releaseDirectoryItem( _pData );
1468
1469 _pData = rItem._pData;
1470
1471 if( _pData )
1472 osl_acquireDirectoryItem( _pData );
1473 }
1474 return *this;
1475 }
1476
1477 /** Check for validity of this instance.
1478
1479 @return
1480 true if object is valid directory item else false.
1481 */
1482
1483 bool is()
1484 {
1485 return _pData != NULL__null;
1486 }
1487
1488 /** Retrieve a single directory item.
1489
1490 Retrieves a single directory item. The returned handle has an initial refcount of 1.
1491 Due to performance issues it is not recommended to use this function while
1492 enumerating the contents of a directory. In this case use osl_getNextDirectoryItem() instead.
1493
1494 @param[in] ustrFileURL
1495 An absolute file URL.
1496
1497 @param[out] rItem
1498 On success it receives a handle which can be used for subsequent calls to osl_getFileStatus().
1499 The handle has to be released by a call to osl_releaseDirectoryItem().
1500
1501 @retval E_None on success
1502 @retval E_INVAL the format of the parameters was not valid
1503 @retval E_NOMEM not enough memory for allocating structures
1504 @retval E_ACCES permission denied
1505 @retval E_MFILE too many open files used by the process
1506 @retval E_NFILE too many open files in the system
1507 @retval E_NOENT no such file or directory
1508 @retval E_LOOP too many symbolic links encountered
1509 @retval E_NAMETOOLONG the file name is too long
1510 @retval E_NOTDIR a component of the path prefix of path is not a directory
1511 @retval E_IO on I/O errors
1512 @retval E_MULTIHOP multihop attempted
1513 @retval E_NOLINK link has been severed
1514 @retval E_FAULT bad address
1515 @retval E_INTR the function call was interrupted
1516
1517 @see FileStatus
1518 @see Directory::getNextItem()
1519 */
1520
1521 static RC get( const ::rtl::OUString& ustrFileURL, DirectoryItem& rItem )
1522 {
1523 if( rItem._pData)
1524 {
1525 osl_releaseDirectoryItem( rItem._pData );
1526 rItem._pData = NULL__null;
1527 }
1528
1529 return static_cast< RC >( osl_getDirectoryItem( ustrFileURL.pData, &rItem._pData ) );
1530 }
1531
1532 /** Retrieve information about a single file or directory.
1533
1534 @param[in,out] rStatus
1535 Reference to a class which receives the information of the file or directory
1536 represented by this directory item.
1537
1538 @retval E_None on success
1539 @retval E_NOMEM not enough memory for allocating structures
1540 @retval E_INVAL the format of the parameters was not valid
1541 @retval E_LOOP too many symbolic links encountered
1542 @retval E_ACCES permission denied
1543 @retval E_NOENT no such file or directory
1544 @retval E_NAMETOOLONG file name too long
1545 @retval E_BADF invalid oslDirectoryItem parameter
1546 @retval E_FAULT bad address
1547 @retval E_OVERFLOW value too large for defined data type
1548 @retval E_INTR function call was interrupted
1549 @retval E_NOLINK link has been severed
1550 @retval E_MULTIHOP components of path require hopping to multiple remote machines and the file system does not allow it
1551 @retval E_MFILE too many open files used by the process
1552 @retval E_NFILE too many open files in the system
1553 @retval E_NOSPC no space left on device
1554 @retval E_NXIO no such device or address
1555 @retval E_IO on I/O errors
1556 @retval E_NOSYS function not implemented
1557
1558 @see get()
1559 @see Directory::getNextItem()
1560 @see FileStatus
1561 */
1562
1563 RC getFileStatus( FileStatus& rStatus )
1564 {
1565 return static_cast< RC >( osl_getFileStatus( _pData, &rStatus._aStatus, rStatus._nMask ) );
1566 }
1567
1568/** Determine if a directory item point the same underlying file
1569
1570 The comparison is done first by URL, and then by resolving links to
1571 find the target, and finally by comparing inodes on unix.
1572
1573 @param[in] pOther
1574 A directory handle to compare with the underlying object's item
1575
1576 @retval true if the items point to an identical resource<br>
1577 @retval false if the items point to a different resource, or a fatal error occurred<br>
1578
1579 @see osl_getDirectoryItem()
1580
1581 @since LibreOffice 3.6
1582*/
1583 bool isIdenticalTo( const DirectoryItem &pOther )
1584 {
1585 return osl_identicalDirectoryItem( _pData, pOther._pData );
1586 }
1587
1588 friend class Directory;
1589};
1590
1591
1592/** Base class for observers of directory creation notifications.
1593
1594 Clients which uses the method createDirectoryPath of the class
1595 Directory may want to be informed about the directories that
1596 have been created. This may be accomplished by deriving from
1597 this base class and overwriting the virtual function
1598 DirectoryCreated.
1599
1600 @see Directory::createPath
1601*/
1602class DirectoryCreationObserver
1603{
1604public:
1605 virtual ~DirectoryCreationObserver() {}
1606
1607 /** This method will be called when a new directory has been
1608 created and needs to be overwritten by derived classes.
1609 You must not delete the directory that was just created
1610 otherwise you will run into an endless loop.
1611
1612 @param aDirectoryUrl
1613 [in]The absolute file URL of the directory that was just created by
1614 ::osl::Directory::createPath.
1615 */
1616 virtual void DirectoryCreated(const rtl::OUString& aDirectoryUrl) = 0;
1617};
1618
1619
1620// This just an internal helper function for
1621// private use.
1622extern "C" inline void SAL_CALL onDirectoryCreated(void* pData, rtl_uString* aDirectoryUrl)
1623{
1624 static_cast<DirectoryCreationObserver*>(pData)->DirectoryCreated(aDirectoryUrl);
1625}
1626
1627/** The directory class object provides an enumeration of DirectoryItems.
1628
1629 @see DirectoryItem
1630 @see File
1631 */
1632
1633class Directory: public FileBase
1634{
1635 oslDirectory _pData;
1636 ::rtl::OUString _aPath;
1637
1638 /** Copy constructor.
1639 */
1640
1641 Directory( Directory& ) SAL_DELETED_FUNCTION= delete;
1642
1643 /** Assignment operator.
1644 */
1645
1646 Directory& operator = ( Directory& ) SAL_DELETED_FUNCTION= delete;
1647
1648public:
1649
1650 /** Constructor.
1651
1652 @param[in] strPath
1653 The full qualified URL of the directory.
1654 Relative URLs are not allowed.
1655 */
1656
1657 Directory( const ::rtl::OUString& strPath ): _pData( NULL__null ), _aPath( strPath )
1658 {
1659 }
1660
1661 /** Destructor.
1662 */
1663
1664 ~Directory()
1665 {
1666 close();
1667 }
1668
1669 /** Obtain the URL.
1670
1671 @return
1672 the URL with which this Directory instance was created.
1673
1674 @since LibreOffice 4.1
1675 */
1676 rtl::OUString getURL() const { return _aPath; }
1677
1678 /** Open a directory for enumerating its contents.
1679
1680 @retval E_None on success
1681 @retval E_INVAL the format of the parameters was not valid
1682 @retval E_NOENT the specified path doesn't exist
1683 @retval E_NOTDIR the specified path is not a directory
1684 @retval E_NOMEM not enough memory for allocating structures
1685 @retval E_ACCES permission denied
1686 @retval E_MFILE too many open files used by the process
1687 @retval E_NFILE too many open files in the system
1688 @retval E_NAMETOOLONG File name too long
1689 @retval E_LOOP Too many symbolic links encountered
1690
1691 @see getNextItem()
1692 @see close()
1693 */
1694
1695 RC open()
1696 {
1697 return static_cast< RC >( osl_openDirectory( _aPath.pData, &_pData ) );
1698 }
1699
1700 /** Query if directory is open.
1701
1702 Query if directory is open and so item enumeration is valid.
1703
1704 @retval true if the directory is open else false.
1705
1706 @see open()
1707 @see close()
1708 */
1709
1710 bool isOpen() { return _pData != NULL__null; }
1711
1712 /** Close a directory.
1713
1714 @retval E_None on success
1715 @retval E_INVAL the format of the parameters was not valid
1716 @retval E_NOMEM not enough memory for allocating structures
1717 @retval E_BADF invalid oslDirectory parameter
1718 @retval E_INTR the function call was interrupted
1719
1720 @see open()
1721 */
1722
1723 RC close()
1724 {
1725 oslFileError Error = osl_File_E_BADF;
1726
1727 if( _pData )
1728 {
1729 Error=osl_closeDirectory( _pData );
1730 _pData = NULL__null;
1731 }
1732
1733 return static_cast< RC >( Error );
1734 }
1735
1736
1737 /** Resets the directory item enumeration to the beginning.
1738
1739 @retval E_None on success
1740 @retval E_INVAL the format of the parameters was not valid
1741 @retval E_NOENT the specified path doesn't exist
1742 @retval E_NOTDIR the specified path is not a directory
1743 @retval E_NOMEM not enough memory for allocating structures
1744 @retval E_ACCES permission denied
1745 @retval E_MFILE too many open files used by the process
1746 @retval E_NFILE too many open files in the system
1747 @retval E_NAMETOOLONG File name too long
1748 @retval E_LOOP Too many symbolic links encountered
1749
1750 @see open()
1751 */
1752
1753 RC reset()
1754 {
1755 close();
1756 return open();
1757 }
1758
1759 /** Retrieve the next item of a previously opened directory.
1760
1761 Retrieves the next item of a previously opened directory.
1762
1763 @param[out] rItem
1764 On success a valid DirectoryItem.
1765
1766 @param[in] nHint
1767 With this parameter the caller can tell the implementation that (s)he
1768 is going to call this function uHint times afterwards. This enables the implementation to
1769 get the information for more than one file and cache it until the next calls.
1770
1771 @retval E_None on success
1772 @retval E_INVAL the format of the parameters was not valid
1773 @retval E_NOMEM not enough memory for allocating structures
1774 @retval E_NOENT no more entries in this directory
1775 @retval E_BADF invalid oslDirectory parameter
1776 @retval E_OVERFLOW the value too large for defined data type
1777
1778 @see DirectoryItem
1779 */
1780
1781 RC getNextItem( DirectoryItem& rItem, sal_uInt32 nHint = 0 )
1782 {
1783 if( rItem._pData )
1784 {
1785 osl_releaseDirectoryItem( rItem._pData );
1786 rItem._pData = NULL__null;
1787 }
1788 return static_cast<RC>(osl_getNextDirectoryItem( _pData, &rItem._pData, nHint ));
1789 }
1790
1791
1792 /** Retrieve information about a volume.
1793
1794 Retrieves information about a volume. A volume can either be a mount point, a network
1795 resource or a drive depending on Operating System and File System.
1796
1797 @param[in] ustrDirectoryURL
1798 Full qualified URL of the volume
1799
1800 @param[out] rInfo
1801 On success it receives information about the volume.
1802
1803 @retval E_None on success
1804 @retval E_NOMEM not enough memory for allocating structures
1805 @retval E_INVAL the format of the parameters was not valid
1806 @retval E_NOTDIR not a directory
1807 @retval E_NAMETOOLONG file name too long
1808 @retval E_NOENT no such file or directory
1809 @retval E_ACCES permission denied
1810 @retval E_LOOP too many symbolic links encountered
1811 @retval E_FAULT Bad address
1812 @retval E_IO on I/O errors
1813 @retval E_NOSYS function not implemented
1814 @retval E_MULTIHOP multihop attempted
1815 @retval E_NOLINK link has been severed
1816 @retval E_INTR function call was interrupted
1817
1818 @see FileStatus
1819 @see VolumeInfo
1820 */
1821
1822 static RC getVolumeInfo( const ::rtl::OUString& ustrDirectoryURL, VolumeInfo& rInfo )
1823 {
1824 return static_cast< RC >( osl_getVolumeInformation( ustrDirectoryURL.pData, &rInfo._aInfo, rInfo._nMask ) );
1825 }
1826
1827 /** Create a directory.
1828
1829 @param[in] ustrDirectoryURL
1830 Full qualified URL of the directory to create.
1831
1832 @param[in] flags
1833 Optional flags, see osl_createDirectoryWithFlags for details. This
1834 defaulted parameter is new since LibreOffice 4.3.
1835
1836 @retval E_None on success
1837 @retval E_INVAL the format of the parameters was not valid
1838 @retval E_NOMEM not enough memory for allocating structures
1839 @retval E_EXIST file exists
1840 @retval E_ACCES permission denied
1841 @retval E_NAMETOOLONG file name too long
1842 @retval E_NOENT no such file or directory
1843 @retval E_NOTDIR not a directory
1844 @retval E_ROFS read-only file system
1845 @retval E_NOSPC no space left on device
1846 @retval E_DQUOT quota exceeded
1847 @retval E_LOOP too many symbolic links encountered
1848 @retval E_FAULT bad address
1849 @retval E_IO on I/O errors
1850 @retval E_MLINK too many links
1851 @retval E_MULTIHOP multihop attempted
1852 @retval E_NOLINK link has been severed
1853
1854 @see remove()
1855 */
1856
1857 static RC create(
1858 const ::rtl::OUString& ustrDirectoryURL,
1859 sal_uInt32 flags = osl_File_OpenFlag_Read0x00000001L | osl_File_OpenFlag_Write0x00000002L )
1860 {
1861 return static_cast< RC >(
1862 osl_createDirectoryWithFlags( ustrDirectoryURL.pData, flags ) );
1863 }
1864
1865 /** Remove an empty directory.
1866
1867 @param[in] ustrDirectoryURL
1868 Full qualified URL of the directory.
1869
1870 @retval E_None on success
1871 @retval E_INVAL the format of the parameters was not valid
1872 @retval E_NOMEM not enough memory for allocating structures
1873 @retval E_PERM operation not permitted
1874 @retval E_ACCES permission denied
1875 @retval E_NOENT no such file or directory
1876 @retval E_NOTDIR not a directory
1877 @retval E_NOTEMPTY directory not empty
1878 @retval E_FAULT bad address
1879 @retval E_NAMETOOLONG file name too long
1880 @retval E_BUSY device or resource busy
1881 @retval E_ROFS read-only file system
1882 @retval E_LOOP too many symbolic links encountered
1883 @retval E_EXIST file exists
1884 @retval E_IO on I/O errors
1885 @retval E_MULTIHOP multihop attempted
1886 @retval E_NOLINK link has been severed
1887
1888 @see create()
1889 */
1890
1891 static RC remove( const ::rtl::OUString& ustrDirectoryURL )
1892 {
1893 return static_cast< RC >( osl_removeDirectory( ustrDirectoryURL.pData ) );
1894 }
1895
1896 /** Create a directory path.
1897
1898 The osl_createDirectoryPath function creates a specified directory path.
1899 All nonexisting sub directories will be created.
1900
1901 @attention You cannot rely on getting the error code E_EXIST for existing
1902 directories. Programming against this error code is in general a strong
1903 indication of a wrong usage of osl_createDirectoryPath.
1904
1905 @param aDirectoryUrl
1906 [in] The absolute file URL of the directory path to create.
1907 A relative file URL will not be accepted.
1908
1909 @param aDirectoryCreationObserver
1910 [in] Pointer to an instance of type DirectoryCreationObserver that will
1911 be informed about the creation of a directory. The value of this
1912 parameter may be NULL, in this case notifications will not be sent.
1913
1914 @retval E_None On success
1915 @retval E_INVAL The format of the parameters was not valid
1916 @retval E_ACCES Permission denied
1917 @retval E_EXIST The final node of the specified directory path already exist
1918 @retval E_NAMETOOLONG The name of the specified directory path exceeds the maximum allowed length
1919 @retval E_NOTDIR A component of the specified directory path already exist as file in any part of the directory path
1920 @retval E_ROFS Read-only file system
1921 @retval E_NOSPC No space left on device
1922 @retval E_DQUOT Quota exceeded
1923 @retval E_FAULT Bad address
1924 @retval E_IO I/O error
1925 @retval E_LOOP Too many symbolic links encountered
1926 @retval E_NOLINK Link has been severed
1927 @retval E_invalidError An unknown error occurred
1928
1929 @see DirectoryCreationObserver
1930 @see create
1931 */
1932 static RC createPath(
1933 const ::rtl::OUString& aDirectoryUrl,
1934 DirectoryCreationObserver* aDirectoryCreationObserver = NULL__null)
1935 {
1936 return static_cast< RC >(osl_createDirectoryPath(
1937 aDirectoryUrl.pData,
1938 aDirectoryCreationObserver ? onDirectoryCreated : NULL__null,
1939 aDirectoryCreationObserver));
1940 }
1941};
1942
1943} /* namespace osl */
1944
1945#endif // INCLUDED_OSL_FILE_HXX
1946
1947/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx

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
49extern 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
61namespace rtl
62{
63
64class 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/**
74A wrapper dressing a string literal as a static-refcount rtl_uString.
75
76This class is not part of public API and is meant to be used only in LibreOffice code.
77@since LibreOffice 4.0
78*/
79template<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
83public:
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
104private:
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
126namespace libreoffice_internal {
127template<std::size_t N> struct ExceptConstCharArrayDetector<OUStringLiteral<N>> {};
128template<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
160class SAL_WARN_UNUSED__attribute__((warn_unused)) SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) OUString
161{
162public:
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;
10
Access to field 'length' results in a dereference of a null pointer (loaded from field 'pData')
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
3374private:
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//
3395void operator ==(OUString const &, std::nullptr_t) = delete;
3396void operator ==(std::nullptr_t, OUString const &) = delete;
3397void operator !=(OUString const &, std::nullptr_t) = delete;
3398void 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*/
3407template<>
3408struct 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*/
3419template<std::size_t N>
3420struct 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*/
3431template< typename charT, typename traits, typename T1, typename T2 >
3432inline 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 */
3446struct 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 */
3480inline 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 */
3504inline 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*/
3521template< typename charT, typename traits >
3522inline 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
3534namespace rtl
3535{
3536typedef 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
3544using ::rtl::OUString;
3545using ::rtl::OUStringHash;
3546using ::rtl::OStringToOUString;
3547using ::rtl::OUStringToOString;
3548using ::rtl::OUStringLiteral;
3549using ::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
3559namespace std {
3560
3561template<>
3562struct 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: */