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