/src/libreoffice/sal/rtl/strtmpl.hxx
Line | Count | Source |
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 | | #pragma once |
21 | | |
22 | | #include <algorithm> |
23 | | #include <cassert> |
24 | | #include <cmath> |
25 | | #include <cstddef> |
26 | | #include <cstdlib> |
27 | | #include <cstring> |
28 | | #include <cwchar> |
29 | | #include <limits> |
30 | | #include <new> |
31 | | #include <string_view> |
32 | | #include <type_traits> |
33 | | #include <utility> |
34 | | |
35 | | #include "strimp.hxx" |
36 | | |
37 | | #include <o3tl/safeint.hxx> |
38 | | #include <o3tl/string_view.hxx> |
39 | | #include <osl/diagnose.h> |
40 | | #include <sal/log.hxx> |
41 | | #include <rtl/character.hxx> |
42 | | #include <rtl/math.h> |
43 | | #include <rtl/string.h> |
44 | | #include <rtl/ustring.h> |
45 | | |
46 | | #include <dragonbox/dragonbox.h> |
47 | | |
48 | | void internRelease(rtl_uString*); |
49 | | |
50 | | namespace rtl::str |
51 | | { |
52 | 13.3G | template <typename C> auto UChar(C c) { return std::make_unsigned_t<C>(c); }auto rtl::str::UChar<char>(char) Line | Count | Source | 52 | 1.60G | template <typename C> auto UChar(C c) { return std::make_unsigned_t<C>(c); } |
auto rtl::str::UChar<char16_t>(char16_t) Line | Count | Source | 52 | 11.7G | template <typename C> auto UChar(C c) { return std::make_unsigned_t<C>(c); } |
|
53 | | |
54 | | // Wrappers around null-terminated/known-length strings, that allow to generalize algorithms |
55 | | // without overhead (e.g., without need to get length of null-terminated strings). |
56 | | |
57 | | template <typename C> struct null_terminated |
58 | | { |
59 | | C* p; |
60 | | null_terminated(C* pStr) |
61 | 374M | : p(pStr) |
62 | 374M | { |
63 | 374M | assert(pStr); |
64 | 374M | } rtl::str::null_terminated<char const>::null_terminated(char const*) Line | Count | Source | 61 | 355M | : p(pStr) | 62 | 355M | { | 63 | | assert(pStr); | 64 | 355M | } |
Unexecuted instantiation: rtl::str::null_terminated<char>::null_terminated(char*) rtl::str::null_terminated<char16_t const>::null_terminated(char16_t const*) Line | Count | Source | 61 | 19.2M | : p(pStr) | 62 | 19.2M | { | 63 | | assert(pStr); | 64 | 19.2M | } |
Unexecuted instantiation: rtl::str::null_terminated<char16_t>::null_terminated(char16_t*) |
65 | 374M | auto begin() const { return p; }rtl::str::null_terminated<char const>::begin() const Line | Count | Source | 65 | 355M | auto begin() const { return p; } |
Unexecuted instantiation: rtl::str::null_terminated<char>::begin() const rtl::str::null_terminated<char16_t const>::begin() const Line | Count | Source | 65 | 19.2M | auto begin() const { return p; } |
Unexecuted instantiation: rtl::str::null_terminated<char16_t>::begin() const |
66 | | struct EndDetector |
67 | | { |
68 | | friend bool operator==(EndDetector, C* iter) { return *iter == 0; } |
69 | 1.02G | friend bool operator==(C* iter, EndDetector) { return *iter == 0; }rtl::str::operator==(char const*, rtl::str::null_terminated<char const>::EndDetector) Line | Count | Source | 69 | 826M | friend bool operator==(C* iter, EndDetector) { return *iter == 0; } |
Unexecuted instantiation: rtl::str::operator==(char*, rtl::str::null_terminated<char>::EndDetector) rtl::str::operator==(char16_t const*, rtl::str::null_terminated<char16_t const>::EndDetector) Line | Count | Source | 69 | 199M | friend bool operator==(C* iter, EndDetector) { return *iter == 0; } |
Unexecuted instantiation: rtl::str::operator==(char16_t*, rtl::str::null_terminated<char16_t>::EndDetector) |
70 | | }; |
71 | 374M | static auto end() { return EndDetector{}; }rtl::str::null_terminated<char const>::end() Line | Count | Source | 71 | 355M | static auto end() { return EndDetector{}; } |
Unexecuted instantiation: rtl::str::null_terminated<char>::end() rtl::str::null_terminated<char16_t const>::end() Line | Count | Source | 71 | 19.2M | static auto end() { return EndDetector{}; } |
Unexecuted instantiation: rtl::str::null_terminated<char16_t>::end() |
72 | | }; |
73 | | |
74 | | template <typename C> struct with_length |
75 | | { |
76 | | C* p; |
77 | | sal_Int32 len; |
78 | | with_length(C* pStr, sal_Int32 nLength) |
79 | 9.11G | : p(pStr) |
80 | 9.11G | , len(nLength) |
81 | 9.11G | { |
82 | 9.11G | assert(len >= 0); |
83 | 9.11G | } rtl::str::with_length<char const>::with_length(char const*, int) Line | Count | Source | 79 | 320M | : p(pStr) | 80 | 320M | , len(nLength) | 81 | 320M | { | 82 | | assert(len >= 0); | 83 | 320M | } |
Unexecuted instantiation: rtl::str::with_length<char>::with_length(char*, int) rtl::str::with_length<char16_t const>::with_length(char16_t const*, int) Line | Count | Source | 79 | 8.79G | : p(pStr) | 80 | 8.79G | , len(nLength) | 81 | 8.79G | { | 82 | | assert(len >= 0); | 83 | 8.79G | } |
rtl::str::with_length<char16_t>::with_length(char16_t*, int) Line | Count | Source | 79 | 376k | : p(pStr) | 80 | 376k | , len(nLength) | 81 | 376k | { | 82 | | assert(len >= 0); | 83 | 376k | } |
|
84 | 575M | auto begin() const { return p; }rtl::str::with_length<char const>::begin() const Line | Count | Source | 84 | 18.1M | auto begin() const { return p; } |
Unexecuted instantiation: rtl::str::with_length<char>::begin() const rtl::str::with_length<char16_t const>::begin() const Line | Count | Source | 84 | 557M | auto begin() const { return p; } |
rtl::str::with_length<char16_t>::begin() const Line | Count | Source | 84 | 376k | auto begin() const { return p; } |
|
85 | 575M | auto end() const { return p + len; }rtl::str::with_length<char const>::end() const Line | Count | Source | 85 | 18.1M | auto end() const { return p + len; } |
Unexecuted instantiation: rtl::str::with_length<char>::end() const rtl::str::with_length<char16_t const>::end() const Line | Count | Source | 85 | 557M | auto end() const { return p + len; } |
rtl::str::with_length<char16_t>::end() const Line | Count | Source | 85 | 376k | auto end() const { return p + len; } |
|
86 | | }; |
87 | | |
88 | | template <bool (&fApplicable)(sal_uInt32), sal_uInt32 (&fReplace)(sal_uInt32)> struct CaseReplace |
89 | | { |
90 | 54.6M | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; }rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>::Applicable() Line | Count | Source | 90 | 9.19M | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; } |
rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>::Applicable() Line | Count | Source | 90 | 6.48M | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; } |
auto rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>::Applicable()::{lambda(auto:1)#1}::operator()<char>(char) constLine | Count | Source | 90 | 34.8k | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; } |
auto rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>::Applicable()::{lambda(auto:1)#1}::operator()<char>(char) constLine | Count | Source | 90 | 80 | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; } |
auto rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>::Applicable()::{lambda(auto:1)#1}::operator()<char16_t>(char16_t) constLine | Count | Source | 90 | 28.9M | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; } |
auto rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>::Applicable()::{lambda(auto:1)#1}::operator()<char16_t>(char16_t) constLine | Count | Source | 90 | 25.6M | static auto Applicable() { return [](auto c) { return fApplicable(UChar(c)); }; } |
|
91 | 82.7M | template <typename C> static C Replace(C c) { return fReplace(UChar(c)); }char rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>::Replace<char>(char) Line | Count | Source | 91 | 68.5k | template <typename C> static C Replace(C c) { return fReplace(UChar(c)); } |
char rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>::Replace<char>(char) Line | Count | Source | 91 | 80 | template <typename C> static C Replace(C c) { return fReplace(UChar(c)); } |
char16_t rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>::Replace<char16_t>(char16_t) Line | Count | Source | 91 | 53.3M | template <typename C> static C Replace(C c) { return fReplace(UChar(c)); } |
char16_t rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>::Replace<char16_t>(char16_t) Line | Count | Source | 91 | 29.3M | template <typename C> static C Replace(C c) { return fReplace(UChar(c)); } |
|
92 | | }; |
93 | | constexpr CaseReplace<rtl::isAsciiUpperCase, rtl::toAsciiLowerCase> toAsciiLower; |
94 | | constexpr CaseReplace<rtl::isAsciiLowerCase, rtl::toAsciiUpperCase> toAsciiUpper; |
95 | | |
96 | | template <typename C> struct FromTo |
97 | | { |
98 | | C from; |
99 | | C to; |
100 | 530k | FromTo(C cFrom, C cTo) : from(cFrom), to(cTo) {}Unexecuted instantiation: rtl::str::FromTo<char>::FromTo(char, char) rtl::str::FromTo<char16_t>::FromTo(char16_t, char16_t) Line | Count | Source | 100 | 530k | FromTo(C cFrom, C cTo) : from(cFrom), to(cTo) {} |
|
101 | 13.5M | auto Applicable() const { return [this](C c) { return c == from; }; }Unexecuted instantiation: rtl::str::FromTo<char>::Applicable() const rtl::str::FromTo<char16_t>::Applicable() const Line | Count | Source | 101 | 530k | auto Applicable() const { return [this](C c) { return c == from; }; } |
Unexecuted instantiation: rtl::str::FromTo<char>::Applicable() const::{lambda(char)#1}::operator()(char) constrtl::str::FromTo<char16_t>::Applicable() const::{lambda(char16_t)#1}::operator()(char16_t) constLine | Count | Source | 101 | 13.5M | auto Applicable() const { return [this](C c) { return c == from; }; } |
|
102 | 10.8M | C Replace(C c) const { return c == from ? to : c; }Unexecuted instantiation: rtl::str::FromTo<char>::Replace(char) const rtl::str::FromTo<char16_t>::Replace(char16_t) const Line | Count | Source | 102 | 10.8M | C Replace(C c) const { return c == from ? to : c; } |
|
103 | | }; |
104 | | |
105 | | template <typename C> void Copy(C* _pDest, const C* _pSrc, sal_Int32 _nCount) |
106 | 2.16G | { |
107 | | // take advantage of builtin optimisations |
108 | 2.16G | std::copy(_pSrc, _pSrc + _nCount, _pDest); |
109 | 2.16G | } void rtl::str::Copy<char>(char*, char const*, int) Line | Count | Source | 106 | 122M | { | 107 | | // take advantage of builtin optimisations | 108 | 122M | std::copy(_pSrc, _pSrc + _nCount, _pDest); | 109 | 122M | } |
void rtl::str::Copy<char16_t>(char16_t*, char16_t const*, int) Line | Count | Source | 106 | 2.04G | { | 107 | | // take advantage of builtin optimisations | 108 | 2.04G | std::copy(_pSrc, _pSrc + _nCount, _pDest); | 109 | 2.04G | } |
|
110 | | |
111 | | template <typename C> void CopyBackward(C* _pDest, const C* _pSrc, sal_Int32 _nCount) |
112 | 12.8M | { |
113 | | // take advantage of builtin optimisations |
114 | 12.8M | std::copy_backward(_pSrc, _pSrc + _nCount, _pDest + _nCount); |
115 | 12.8M | } Unexecuted instantiation: void rtl::str::CopyBackward<char>(char*, char const*, int) void rtl::str::CopyBackward<char16_t>(char16_t*, char16_t const*, int) Line | Count | Source | 112 | 12.8M | { | 113 | | // take advantage of builtin optimisations | 114 | 12.8M | std::copy_backward(_pSrc, _pSrc + _nCount, _pDest + _nCount); | 115 | 12.8M | } |
|
116 | | |
117 | | inline void Copy(sal_Unicode* _pDest, const char* _pSrc, sal_Int32 _nCount) |
118 | 75.0M | { |
119 | 75.0M | std::transform(_pSrc, _pSrc + _nCount, _pDest, |
120 | 75.0M | [](char c) |
121 | 1.68G | { |
122 | 1.68G | assert(rtl::isAscii(static_cast<unsigned char>(c))); |
123 | 1.68G | SAL_WARN_IF(c == '\0', "rtl.string", "Found embedded \\0 ASCII character"); |
124 | 1.68G | return static_cast<unsigned char>(c); |
125 | 1.68G | }); |
126 | 75.0M | } |
127 | | |
128 | | inline sal_Int16 implGetDigit(sal_Unicode ch, sal_Int16 nRadix) |
129 | 251M | { |
130 | 251M | sal_Int16 n = -1; |
131 | 251M | if ((ch >= '0') && (ch <= '9')) |
132 | 246M | n = ch - '0'; |
133 | 4.97M | else if ((ch >= 'a') && (ch <= 'z')) |
134 | 487k | n = ch - 'a' + 10; |
135 | 4.48M | else if ((ch >= 'A') && (ch <= 'Z')) |
136 | 763k | n = ch - 'A' + 10; |
137 | 251M | return (n < nRadix) ? n : -1; |
138 | 251M | } |
139 | | |
140 | | /* ======================================================================= */ |
141 | | /* C-String functions which could be used without the String-Class */ |
142 | | /* ======================================================================= */ |
143 | | |
144 | | template <typename T> sal_Int32 getLength( const T* pStr ) |
145 | 196M | { |
146 | 196M | assert(pStr); |
147 | | if constexpr (std::is_class_v<T>) |
148 | 176k | { |
149 | 176k | return pStr->length; |
150 | | } |
151 | | else |
152 | 195M | { |
153 | | // take advantage of builtin optimisations |
154 | 195M | return std::char_traits<T>::length(pStr); |
155 | 195M | } |
156 | 196M | } int rtl::str::getLength<char>(char const*) Line | Count | Source | 145 | 181M | { | 146 | 181M | assert(pStr); | 147 | | if constexpr (std::is_class_v<T>) | 148 | | { | 149 | | return pStr->length; | 150 | | } | 151 | | else | 152 | 181M | { | 153 | | // take advantage of builtin optimisations | 154 | 181M | return std::char_traits<T>::length(pStr); | 155 | 181M | } | 156 | 181M | } |
Unexecuted instantiation: int rtl::str::getLength<_rtl_String>(_rtl_String const*) int rtl::str::getLength<char16_t>(char16_t const*) Line | Count | Source | 145 | 14.8M | { | 146 | 14.8M | assert(pStr); | 147 | | if constexpr (std::is_class_v<T>) | 148 | | { | 149 | | return pStr->length; | 150 | | } | 151 | | else | 152 | 14.8M | { | 153 | | // take advantage of builtin optimisations | 154 | 14.8M | return std::char_traits<T>::length(pStr); | 155 | 14.8M | } | 156 | 14.8M | } |
int rtl::str::getLength<_rtl_uString>(_rtl_uString const*) Line | Count | Source | 145 | 176k | { | 146 | 176k | assert(pStr); | 147 | | if constexpr (std::is_class_v<T>) | 148 | 176k | { | 149 | 176k | return pStr->length; | 150 | | } | 151 | | else | 152 | | { | 153 | | // take advantage of builtin optimisations | 154 | | return std::char_traits<T>::length(pStr); | 155 | | } | 156 | 176k | } |
|
157 | | |
158 | | /* ----------------------------------------------------------------------- */ |
159 | | |
160 | | template <typename C> void warnIfCharAndNotAscii(C c) |
161 | 1.67G | { |
162 | | if constexpr (sizeof(c) == sizeof(char)) |
163 | 839M | SAL_WARN_IF(!rtl::isAscii(static_cast<unsigned char>(c)), "rtl.string", |
164 | 1.67G | "Found non-ASCII char"); |
165 | 1.67G | } void rtl::str::warnIfCharAndNotAscii<char16_t>(char16_t) Line | Count | Source | 161 | 839M | { | 162 | | if constexpr (sizeof(c) == sizeof(char)) | 163 | | SAL_WARN_IF(!rtl::isAscii(static_cast<unsigned char>(c)), "rtl.string", | 164 | 839M | "Found non-ASCII char"); | 165 | 839M | } |
void rtl::str::warnIfCharAndNotAscii<char>(char) Line | Count | Source | 161 | 839M | { | 162 | | if constexpr (sizeof(c) == sizeof(char)) | 163 | 839M | SAL_WARN_IF(!rtl::isAscii(static_cast<unsigned char>(c)), "rtl.string", | 164 | 839M | "Found non-ASCII char"); | 165 | 839M | } |
|
166 | | |
167 | | template <typename C1, typename C2> void warnIfOneIsCharAndNotAscii(C1 c1, C2 c2) |
168 | 4.48G | { |
169 | | if constexpr (sizeof(c1) != sizeof(c2)) |
170 | 839M | { |
171 | 839M | warnIfCharAndNotAscii(c1); |
172 | 839M | warnIfCharAndNotAscii(c2); |
173 | 839M | } |
174 | 4.48G | } void rtl::str::warnIfOneIsCharAndNotAscii<char, char>(char, char) Line | Count | Source | 168 | 365M | { | 169 | | if constexpr (sizeof(c1) != sizeof(c2)) | 170 | | { | 171 | | warnIfCharAndNotAscii(c1); | 172 | | warnIfCharAndNotAscii(c2); | 173 | | } | 174 | 365M | } |
void rtl::str::warnIfOneIsCharAndNotAscii<char16_t, char>(char16_t, char) Line | Count | Source | 168 | 839M | { | 169 | | if constexpr (sizeof(c1) != sizeof(c2)) | 170 | 839M | { | 171 | 839M | warnIfCharAndNotAscii(c1); | 172 | 839M | warnIfCharAndNotAscii(c2); | 173 | 839M | } | 174 | 839M | } |
void rtl::str::warnIfOneIsCharAndNotAscii<char16_t, char16_t>(char16_t, char16_t) Line | Count | Source | 168 | 3.28G | { | 169 | | if constexpr (sizeof(c1) != sizeof(c2)) | 170 | | { | 171 | | warnIfCharAndNotAscii(c1); | 172 | | warnIfCharAndNotAscii(c2); | 173 | | } | 174 | 3.28G | } |
|
175 | | |
176 | | struct CompareNormal |
177 | | { |
178 | | template <typename C1, typename C2> static sal_Int32 compare(C1 c1, C2 c2) |
179 | 4.20G | { |
180 | 4.20G | warnIfOneIsCharAndNotAscii(c1, c2); |
181 | 4.20G | return static_cast<sal_Int32>(UChar(c1)) |
182 | 4.20G | - static_cast<sal_Int32>(UChar(c2)); |
183 | 4.20G | } int rtl::str::CompareNormal::compare<char, char>(char, char) Line | Count | Source | 179 | 365M | { | 180 | 365M | warnIfOneIsCharAndNotAscii(c1, c2); | 181 | 365M | return static_cast<sal_Int32>(UChar(c1)) | 182 | 365M | - static_cast<sal_Int32>(UChar(c2)); | 183 | 365M | } |
int rtl::str::CompareNormal::compare<char16_t, char>(char16_t, char) Line | Count | Source | 179 | 806M | { | 180 | 806M | warnIfOneIsCharAndNotAscii(c1, c2); | 181 | 806M | return static_cast<sal_Int32>(UChar(c1)) | 182 | 806M | - static_cast<sal_Int32>(UChar(c2)); | 183 | 806M | } |
int rtl::str::CompareNormal::compare<char16_t, char16_t>(char16_t, char16_t) Line | Count | Source | 179 | 3.03G | { | 180 | 3.03G | warnIfOneIsCharAndNotAscii(c1, c2); | 181 | 3.03G | return static_cast<sal_Int32>(UChar(c1)) | 182 | 3.03G | - static_cast<sal_Int32>(UChar(c2)); | 183 | 3.03G | } |
|
184 | | }; |
185 | | |
186 | | struct CompareIgnoreAsciiCase |
187 | | { |
188 | | template <typename C1, typename C2> static sal_Int32 compare(C1 c1, C2 c2) |
189 | 281M | { |
190 | 281M | warnIfOneIsCharAndNotAscii(c1, c2); |
191 | 281M | return rtl::compareIgnoreAsciiCase(UChar(c1), UChar(c2)); |
192 | 281M | } int rtl::str::CompareIgnoreAsciiCase::compare<char, char>(char, char) Line | Count | Source | 189 | 614k | { | 190 | 614k | warnIfOneIsCharAndNotAscii(c1, c2); | 191 | 614k | return rtl::compareIgnoreAsciiCase(UChar(c1), UChar(c2)); | 192 | 614k | } |
int rtl::str::CompareIgnoreAsciiCase::compare<char16_t, char>(char16_t, char) Line | Count | Source | 189 | 33.5M | { | 190 | 33.5M | warnIfOneIsCharAndNotAscii(c1, c2); | 191 | 33.5M | return rtl::compareIgnoreAsciiCase(UChar(c1), UChar(c2)); | 192 | 33.5M | } |
int rtl::str::CompareIgnoreAsciiCase::compare<char16_t, char16_t>(char16_t, char16_t) Line | Count | Source | 189 | 247M | { | 190 | 247M | warnIfOneIsCharAndNotAscii(c1, c2); | 191 | 247M | return rtl::compareIgnoreAsciiCase(UChar(c1), UChar(c2)); | 192 | 247M | } |
|
193 | | }; |
194 | | |
195 | | /* ----------------------------------------------------------------------- */ |
196 | | |
197 | | struct NoShortening |
198 | | { |
199 | 0 | constexpr bool operator>=(int) { return true; } // for assert |
200 | 0 | constexpr bool operator==(int) { return false; } // for loop break check |
201 | 765M | constexpr void operator--() {} // for decrement in loop |
202 | | } constexpr noShortening; |
203 | | |
204 | | template <class S1, class S2, class Compare, typename Shorten_t> |
205 | | sal_Int32 compare(S1 s1, S2 s2, Compare, Shorten_t shortenedLength) |
206 | 427M | { |
207 | 427M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); |
208 | 427M | assert(shortenedLength >= 0); |
209 | 427M | auto pStr1 = s1.begin(); |
210 | 427M | const auto end1 = s1.end(); |
211 | 427M | auto pStr2 = s2.begin(); |
212 | 427M | const auto end2 = s2.end(); |
213 | 427M | for (;;) |
214 | 1.21G | { |
215 | 1.21G | if (shortenedLength == 0) |
216 | 629k | return 0; |
217 | 1.21G | if (pStr2 == end2) |
218 | 40.9M | return pStr1 == end1 ? 0 : 1; |
219 | 1.17G | if (pStr1 == end1) |
220 | 4.32M | return -1; |
221 | 1.16G | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) |
222 | 381M | return nRet; |
223 | 786M | --shortenedLength; |
224 | 786M | ++pStr1; |
225 | 786M | ++pStr2; |
226 | 786M | } |
227 | 427M | } int rtl::str::compare<rtl::str::null_terminated<char const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::null_terminated<char const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) Line | Count | Source | 206 | 142k | { | 207 | 142k | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 142k | assert(shortenedLength >= 0); | 209 | 142k | auto pStr1 = s1.begin(); | 210 | 142k | const auto end1 = s1.end(); | 211 | 142k | auto pStr2 = s2.begin(); | 212 | 142k | const auto end2 = s2.end(); | 213 | 142k | for (;;) | 214 | 448k | { | 215 | 448k | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 448k | if (pStr2 == end2) | 218 | 20.3k | return pStr1 == end1 ? 0 : 1; | 219 | 428k | if (pStr1 == end1) | 220 | 0 | return -1; | 221 | 428k | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 122k | return nRet; | 223 | 305k | --shortenedLength; | 224 | 305k | ++pStr1; | 225 | 305k | ++pStr2; | 226 | 305k | } | 227 | 142k | } |
int rtl::str::compare<rtl::str::with_length<char const>, rtl::str::with_length<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::with_length<char const>, rtl::str::with_length<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) Line | Count | Source | 206 | 160k | { | 207 | 160k | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 160k | assert(shortenedLength >= 0); | 209 | 160k | auto pStr1 = s1.begin(); | 210 | 160k | const auto end1 = s1.end(); | 211 | 160k | auto pStr2 = s2.begin(); | 212 | 160k | const auto end2 = s2.end(); | 213 | 160k | for (;;) | 214 | 188k | { | 215 | 188k | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 188k | if (pStr2 == end2) | 218 | 2.13k | return pStr1 == end1 ? 0 : 1; | 219 | 186k | if (pStr1 == end1) | 220 | 0 | return -1; | 221 | 186k | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 158k | return nRet; | 223 | 28.5k | --shortenedLength; | 224 | 28.5k | ++pStr1; | 225 | 28.5k | ++pStr2; | 226 | 28.5k | } | 227 | 160k | } |
int rtl::str::compare<rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareNormal, rtl::str::NoShortening>(rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareNormal, rtl::str::NoShortening) Line | Count | Source | 206 | 314k | { | 207 | 314k | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 314k | assert(shortenedLength >= 0); | 209 | 314k | auto pStr1 = s1.begin(); | 210 | 314k | const auto end1 = s1.end(); | 211 | 314k | auto pStr2 = s2.begin(); | 212 | 314k | const auto end2 = s2.end(); | 213 | 314k | for (;;) | 214 | 1.50M | { | 215 | 1.50M | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 1.50M | if (pStr2 == end2) | 218 | 227k | return pStr1 == end1 ? 0 : 1; | 219 | 1.27M | if (pStr1 == end1) | 220 | 0 | return -1; | 221 | 1.27M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 86.8k | return nRet; | 223 | 1.18M | --shortenedLength; | 224 | 1.18M | ++pStr1; | 225 | 1.18M | ++pStr2; | 226 | 1.18M | } | 227 | 314k | } |
int rtl::str::compare<rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareNormal, rtl::str::NoShortening>(rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareNormal, rtl::str::NoShortening) Line | Count | Source | 206 | 343M | { | 207 | 343M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 343M | assert(shortenedLength >= 0); | 209 | 343M | auto pStr1 = s1.begin(); | 210 | 343M | const auto end1 = s1.end(); | 211 | 343M | auto pStr2 = s2.begin(); | 212 | 343M | const auto end2 = s2.end(); | 213 | 343M | for (;;) | 214 | 789M | { | 215 | 789M | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 789M | if (pStr2 == end2) | 218 | 10.2M | return pStr1 == end1 ? 0 : 1; | 219 | 779M | if (pStr1 == end1) | 220 | 1.86M | return -1; | 221 | 777M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 331M | return nRet; | 223 | 445M | --shortenedLength; | 224 | 445M | ++pStr1; | 225 | 445M | ++pStr2; | 226 | 445M | } | 227 | 343M | } |
int rtl::str::compare<rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareNormal, int>(rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareNormal, int) Line | Count | Source | 206 | 7.85M | { | 207 | 7.85M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 7.85M | assert(shortenedLength >= 0); | 209 | 7.85M | auto pStr1 = s1.begin(); | 210 | 7.85M | const auto end1 = s1.end(); | 211 | 7.85M | auto pStr2 = s2.begin(); | 212 | 7.85M | const auto end2 = s2.end(); | 213 | 7.85M | for (;;) | 214 | 28.0M | { | 215 | 28.0M | if (shortenedLength == 0) | 216 | 542k | return 0; | 217 | 27.4M | if (pStr2 == end2) | 218 | 0 | return pStr1 == end1 ? 0 : 1; | 219 | 27.4M | if (pStr1 == end1) | 220 | 51 | return -1; | 221 | 27.4M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 7.31M | return nRet; | 223 | 20.1M | --shortenedLength; | 224 | 20.1M | ++pStr1; | 225 | 20.1M | ++pStr2; | 226 | 20.1M | } | 227 | 7.85M | } |
Unexecuted instantiation: int rtl::str::compare<rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) int rtl::str::compare<rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) Line | Count | Source | 206 | 2.69M | { | 207 | 2.69M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 2.69M | assert(shortenedLength >= 0); | 209 | 2.69M | auto pStr1 = s1.begin(); | 210 | 2.69M | const auto end1 = s1.end(); | 211 | 2.69M | auto pStr2 = s2.begin(); | 212 | 2.69M | const auto end2 = s2.end(); | 213 | 2.69M | for (;;) | 214 | 5.68M | { | 215 | 5.68M | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 5.68M | if (pStr2 == end2) | 218 | 370k | return pStr1 == end1 ? 0 : 1; | 219 | 5.31M | if (pStr1 == end1) | 220 | 6.44k | return -1; | 221 | 5.31M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 2.31M | return nRet; | 223 | 2.99M | --shortenedLength; | 224 | 2.99M | ++pStr1; | 225 | 2.99M | ++pStr2; | 226 | 2.99M | } | 227 | 2.69M | } |
int rtl::str::compare<rtl::str::with_length<char16_t const>, rtl::str::with_length<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::with_length<char16_t const>, rtl::str::with_length<char const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) Line | Count | Source | 206 | 8.32M | { | 207 | 8.32M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 8.32M | assert(shortenedLength >= 0); | 209 | 8.32M | auto pStr1 = s1.begin(); | 210 | 8.32M | const auto end1 = s1.end(); | 211 | 8.32M | auto pStr2 = s2.begin(); | 212 | 8.32M | const auto end2 = s2.end(); | 213 | 8.32M | for (;;) | 214 | 31.6M | { | 215 | 31.6M | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 31.6M | if (pStr2 == end2) | 218 | 4.50M | return pStr1 == end1 ? 0 : 1; | 219 | 27.1M | if (pStr1 == end1) | 220 | 53.7k | return -1; | 221 | 27.0M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 3.76M | return nRet; | 223 | 23.3M | --shortenedLength; | 224 | 23.3M | ++pStr1; | 225 | 23.3M | ++pStr2; | 226 | 23.3M | } | 227 | 8.32M | } |
int rtl::str::compare<rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, int>(rtl::str::with_length<char16_t const>, rtl::str::null_terminated<char const>, rtl::str::CompareIgnoreAsciiCase, int) Line | Count | Source | 206 | 575k | { | 207 | 575k | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 575k | assert(shortenedLength >= 0); | 209 | 575k | auto pStr1 = s1.begin(); | 210 | 575k | const auto end1 = s1.end(); | 211 | 575k | auto pStr2 = s2.begin(); | 212 | 575k | const auto end2 = s2.end(); | 213 | 575k | for (;;) | 214 | 1.22M | { | 215 | 1.22M | if (shortenedLength == 0) | 216 | 87.0k | return 0; | 217 | 1.14M | if (pStr2 == end2) | 218 | 0 | return pStr1 == end1 ? 0 : 1; | 219 | 1.14M | if (pStr1 == end1) | 220 | 20.3k | return -1; | 221 | 1.12M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 468k | return nRet; | 223 | 652k | --shortenedLength; | 224 | 652k | ++pStr1; | 225 | 652k | ++pStr2; | 226 | 652k | } | 227 | 575k | } |
int rtl::str::compare<rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char16_t const>, rtl::str::CompareNormal, rtl::str::NoShortening>(rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char16_t const>, rtl::str::CompareNormal, rtl::str::NoShortening) Line | Count | Source | 206 | 5.70M | { | 207 | 5.70M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 5.70M | assert(shortenedLength >= 0); | 209 | 5.70M | auto pStr1 = s1.begin(); | 210 | 5.70M | const auto end1 = s1.end(); | 211 | 5.70M | auto pStr2 = s2.begin(); | 212 | 5.70M | const auto end2 = s2.end(); | 213 | 5.70M | for (;;) | 214 | 80.9M | { | 215 | 80.9M | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 80.9M | if (pStr2 == end2) | 218 | 252k | return pStr1 == end1 ? 0 : 1; | 219 | 80.6M | if (pStr1 == end1) | 220 | 21.1k | return -1; | 221 | 80.6M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 5.43M | return nRet; | 223 | 75.2M | --shortenedLength; | 224 | 75.2M | ++pStr1; | 225 | 75.2M | ++pStr2; | 226 | 75.2M | } | 227 | 5.70M | } |
Unexecuted instantiation: int rtl::str::compare<rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char16_t const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::null_terminated<char16_t const>, rtl::str::null_terminated<char16_t const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) int rtl::str::compare<rtl::str::with_length<char16_t const>, rtl::str::with_length<char16_t const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening>(rtl::str::with_length<char16_t const>, rtl::str::with_length<char16_t const>, rtl::str::CompareIgnoreAsciiCase, rtl::str::NoShortening) Line | Count | Source | 206 | 57.9M | { | 207 | 57.9M | static_assert(std::is_same_v<Shorten_t, NoShortening> || std::is_same_v<Shorten_t, sal_Int32>); | 208 | 57.9M | assert(shortenedLength >= 0); | 209 | 57.9M | auto pStr1 = s1.begin(); | 210 | 57.9M | const auto end1 = s1.end(); | 211 | 57.9M | auto pStr2 = s2.begin(); | 212 | 57.9M | const auto end2 = s2.end(); | 213 | 57.9M | for (;;) | 214 | 274M | { | 215 | 274M | if (shortenedLength == 0) | 216 | 0 | return 0; | 217 | 274M | if (pStr2 == end2) | 218 | 25.3M | return pStr1 == end1 ? 0 : 1; | 219 | 249M | if (pStr1 == end1) | 220 | 2.36M | return -1; | 221 | 247M | if (const sal_Int32 nRet = Compare::compare(*pStr1, *pStr2)) | 222 | 30.2M | return nRet; | 223 | 217M | --shortenedLength; | 224 | 217M | ++pStr1; | 225 | 217M | ++pStr2; | 226 | 217M | } | 227 | 57.9M | } |
|
228 | | |
229 | | // take advantage of builtin optimisations |
230 | | template <typename C> requires (sizeof(C) == sizeof(wchar_t)) |
231 | | sal_Int32 compare(null_terminated<C> s1, null_terminated<C> s2, CompareNormal, NoShortening) |
232 | | { |
233 | | return wcscmp(reinterpret_cast<wchar_t const*>(s1.p), reinterpret_cast<wchar_t const*>(s2.p)); |
234 | | } |
235 | | template <typename C> requires (sizeof(C) == sizeof(char)) |
236 | | sal_Int32 compare(null_terminated<C> s1, null_terminated<C> s2, CompareNormal, NoShortening) |
237 | 5.50k | { |
238 | 5.50k | return strcmp(reinterpret_cast<char const*>(s1.p), reinterpret_cast<char const*>(s2.p)); |
239 | 5.50k | } |
240 | | template <typename C> |
241 | | sal_Int32 compare(with_length<C> s1, with_length<C> s2, CompareNormal, NoShortening) |
242 | 4.27G | { |
243 | 4.27G | std::basic_string_view sv1(s1.p, s1.len); |
244 | 4.27G | return sv1.compare(std::basic_string_view(s2.p, s2.len)); |
245 | 4.27G | } int rtl::str::compare<char const>(rtl::str::with_length<char const>, rtl::str::with_length<char const>, rtl::str::CompareNormal, rtl::str::NoShortening) Line | Count | Source | 242 | 151M | { | 243 | 151M | std::basic_string_view sv1(s1.p, s1.len); | 244 | 151M | return sv1.compare(std::basic_string_view(s2.p, s2.len)); | 245 | 151M | } |
int rtl::str::compare<char16_t const>(rtl::str::with_length<char16_t const>, rtl::str::with_length<char16_t const>, rtl::str::CompareNormal, rtl::str::NoShortening) Line | Count | Source | 242 | 4.11G | { | 243 | 4.11G | std::basic_string_view sv1(s1.p, s1.len); | 244 | 4.11G | return sv1.compare(std::basic_string_view(s2.p, s2.len)); | 245 | 4.11G | } |
|
246 | | template <typename C1, typename C2, class Compare> |
247 | | sal_Int32 compare(with_length<C1> s1, with_length<C2> s2, Compare cf, sal_Int32 nShortenedLength) |
248 | 1.81G | { |
249 | 1.81G | assert(nShortenedLength >= 0); |
250 | 1.81G | s1.len = std::min(s1.len, nShortenedLength); |
251 | 1.81G | s2.len = std::min(s2.len, nShortenedLength); |
252 | 1.81G | return compare(s1, s2, cf, noShortening); |
253 | 1.81G | } int rtl::str::compare<char const, char const, rtl::str::CompareNormal>(rtl::str::with_length<char const>, rtl::str::with_length<char const>, rtl::str::CompareNormal, int) Line | Count | Source | 248 | 3.19M | { | 249 | | assert(nShortenedLength >= 0); | 250 | 3.19M | s1.len = std::min(s1.len, nShortenedLength); | 251 | 3.19M | s2.len = std::min(s2.len, nShortenedLength); | 252 | 3.19M | return compare(s1, s2, cf, noShortening); | 253 | 3.19M | } |
Unexecuted instantiation: int rtl::str::compare<char const, char const, rtl::str::CompareIgnoreAsciiCase>(rtl::str::with_length<char const>, rtl::str::with_length<char const>, rtl::str::CompareIgnoreAsciiCase, int) int rtl::str::compare<char16_t const, char16_t const, rtl::str::CompareNormal>(rtl::str::with_length<char16_t const>, rtl::str::with_length<char16_t const>, rtl::str::CompareNormal, int) Line | Count | Source | 248 | 1.80G | { | 249 | | assert(nShortenedLength >= 0); | 250 | 1.80G | s1.len = std::min(s1.len, nShortenedLength); | 251 | 1.80G | s2.len = std::min(s2.len, nShortenedLength); | 252 | 1.80G | return compare(s1, s2, cf, noShortening); | 253 | 1.80G | } |
int rtl::str::compare<char16_t const, char16_t const, rtl::str::CompareIgnoreAsciiCase>(rtl::str::with_length<char16_t const>, rtl::str::with_length<char16_t const>, rtl::str::CompareIgnoreAsciiCase, int) Line | Count | Source | 248 | 8.32M | { | 249 | | assert(nShortenedLength >= 0); | 250 | 8.32M | s1.len = std::min(s1.len, nShortenedLength); | 251 | 8.32M | s2.len = std::min(s2.len, nShortenedLength); | 252 | 8.32M | return compare(s1, s2, cf, noShortening); | 253 | 8.32M | } |
|
254 | | |
255 | | /* ----------------------------------------------------------------------- */ |
256 | | |
257 | | template <typename C1, typename C2, class Compare> |
258 | | sal_Int32 reverseCompare_WithLengths(const C1* pStr1, sal_Int32 nStr1Len, |
259 | | const C2* pStr2, sal_Int32 nStr2Len, Compare) |
260 | 398M | { |
261 | 398M | assert(pStr1 || nStr1Len == 0); |
262 | 398M | assert(nStr1Len >= 0); |
263 | 398M | assert(pStr2 || nStr2Len == 0); |
264 | 398M | assert(nStr2Len >= 0); |
265 | 398M | const C1* pStr1Run = pStr1+nStr1Len; |
266 | 398M | const C2* pStr2Run = pStr2+nStr2Len; |
267 | 3.49G | while ((pStr1 < pStr1Run) && (pStr2 < pStr2Run)) |
268 | 3.31G | { |
269 | 3.31G | pStr1Run--; |
270 | 3.31G | pStr2Run--; |
271 | 3.31G | if (const sal_Int32 nRet = Compare::compare(*pStr1Run, *pStr2Run)) |
272 | 218M | return nRet; |
273 | 3.31G | } |
274 | | |
275 | 180M | return nStr1Len - nStr2Len; |
276 | 398M | } int rtl::str::reverseCompare_WithLengths<char, char, rtl::str::CompareNormal>(char const*, int, char const*, int, rtl::str::CompareNormal) Line | Count | Source | 260 | 29.0M | { | 261 | 29.0M | assert(pStr1 || nStr1Len == 0); | 262 | 29.0M | assert(nStr1Len >= 0); | 263 | 29.0M | assert(pStr2 || nStr2Len == 0); | 264 | 29.0M | assert(nStr2Len >= 0); | 265 | 29.0M | const C1* pStr1Run = pStr1+nStr1Len; | 266 | 29.0M | const C2* pStr2Run = pStr2+nStr2Len; | 267 | 394M | while ((pStr1 < pStr1Run) && (pStr2 < pStr2Run)) | 268 | 365M | { | 269 | 365M | pStr1Run--; | 270 | 365M | pStr2Run--; | 271 | 365M | if (const sal_Int32 nRet = Compare::compare(*pStr1Run, *pStr2Run)) | 272 | 64.9k | return nRet; | 273 | 365M | } | 274 | | | 275 | 28.9M | return nStr1Len - nStr2Len; | 276 | 29.0M | } |
int rtl::str::reverseCompare_WithLengths<char16_t, char, rtl::str::CompareNormal>(char16_t const*, int, char const*, int, rtl::str::CompareNormal) Line | Count | Source | 260 | 3.48k | { | 261 | 3.48k | assert(pStr1 || nStr1Len == 0); | 262 | 3.48k | assert(nStr1Len >= 0); | 263 | 3.48k | assert(pStr2 || nStr2Len == 0); | 264 | 3.48k | assert(nStr2Len >= 0); | 265 | 3.48k | const C1* pStr1Run = pStr1+nStr1Len; | 266 | 3.48k | const C2* pStr2Run = pStr2+nStr2Len; | 267 | 4.72k | while ((pStr1 < pStr1Run) && (pStr2 < pStr2Run)) | 268 | 4.64k | { | 269 | 4.64k | pStr1Run--; | 270 | 4.64k | pStr2Run--; | 271 | 4.64k | if (const sal_Int32 nRet = Compare::compare(*pStr1Run, *pStr2Run)) | 272 | 3.41k | return nRet; | 273 | 4.64k | } | 274 | | | 275 | 75 | return nStr1Len - nStr2Len; | 276 | 3.48k | } |
int rtl::str::reverseCompare_WithLengths<char16_t, char16_t, rtl::str::CompareNormal>(char16_t const*, int, char16_t const*, int, rtl::str::CompareNormal) Line | Count | Source | 260 | 369M | { | 261 | 369M | assert(pStr1 || nStr1Len == 0); | 262 | 369M | assert(nStr1Len >= 0); | 263 | 369M | assert(pStr2 || nStr2Len == 0); | 264 | 369M | assert(nStr2Len >= 0); | 265 | 369M | const C1* pStr1Run = pStr1+nStr1Len; | 266 | 369M | const C2* pStr2Run = pStr2+nStr2Len; | 267 | 3.10G | while ((pStr1 < pStr1Run) && (pStr2 < pStr2Run)) | 268 | 2.95G | { | 269 | 2.95G | pStr1Run--; | 270 | 2.95G | pStr2Run--; | 271 | 2.95G | if (const sal_Int32 nRet = Compare::compare(*pStr1Run, *pStr2Run)) | 272 | 218M | return nRet; | 273 | 2.95G | } | 274 | | | 275 | 151M | return nStr1Len - nStr2Len; | 276 | 369M | } |
|
277 | | |
278 | | /* ----------------------------------------------------------------------- */ |
279 | | |
280 | | template <typename C> sal_Int32 hashCode_WithLength(const C* pStr, sal_Int32 nLen) |
281 | 115M | { |
282 | 115M | assert(nLen >= 0); |
283 | 115M | sal_uInt32 h = static_cast<sal_uInt32>(nLen); |
284 | 3.99G | while ( nLen > 0 ) |
285 | 3.88G | { |
286 | 3.88G | h = (h*37U) + UChar( *pStr ); |
287 | 3.88G | pStr++; |
288 | 3.88G | nLen--; |
289 | 3.88G | } |
290 | 115M | return static_cast<sal_Int32>(h); |
291 | 115M | } int rtl::str::hashCode_WithLength<char>(char const*, int) Line | Count | Source | 281 | 644 | { | 282 | 644 | assert(nLen >= 0); | 283 | 644 | sal_uInt32 h = static_cast<sal_uInt32>(nLen); | 284 | 54.1k | while ( nLen > 0 ) | 285 | 53.4k | { | 286 | 53.4k | h = (h*37U) + UChar( *pStr ); | 287 | 53.4k | pStr++; | 288 | 53.4k | nLen--; | 289 | 53.4k | } | 290 | 644 | return static_cast<sal_Int32>(h); | 291 | 644 | } |
int rtl::str::hashCode_WithLength<char16_t>(char16_t const*, int) Line | Count | Source | 281 | 115M | { | 282 | 115M | assert(nLen >= 0); | 283 | 115M | sal_uInt32 h = static_cast<sal_uInt32>(nLen); | 284 | 3.99G | while ( nLen > 0 ) | 285 | 3.88G | { | 286 | 3.88G | h = (h*37U) + UChar( *pStr ); | 287 | 3.88G | pStr++; | 288 | 3.88G | nLen--; | 289 | 3.88G | } | 290 | 115M | return static_cast<sal_Int32>(h); | 291 | 115M | } |
|
292 | | |
293 | | /* ----------------------------------------------------------------------- */ |
294 | | |
295 | | template <typename C> sal_Int32 hashCode(const C* pStr) |
296 | 244k | { |
297 | 244k | return hashCode_WithLength( pStr, getLength( pStr ) ); |
298 | 244k | } int rtl::str::hashCode<char>(char const*) Line | Count | Source | 296 | 644 | { | 297 | 644 | return hashCode_WithLength( pStr, getLength( pStr ) ); | 298 | 644 | } |
int rtl::str::hashCode<char16_t>(char16_t const*) Line | Count | Source | 296 | 243k | { | 297 | 243k | return hashCode_WithLength( pStr, getLength( pStr ) ); | 298 | 243k | } |
|
299 | | |
300 | | /* ----------------------------------------------------------------------- */ |
301 | | |
302 | | template <typename C> sal_Int32 indexOfChar(const C* pStr, C c) |
303 | 108 | { |
304 | 108 | assert(pStr); |
305 | 108 | if (!c) |
306 | 0 | return -1; // Unifies behavior of strchr/wcschr and unoptimized algorithm wrt '\0' |
307 | | |
308 | | if constexpr (sizeof(C) == sizeof(char)) |
309 | 0 | { |
310 | | // take advantage of builtin optimisations |
311 | 0 | const C* p = strchr(pStr, c); |
312 | 0 | return p ? p - pStr : -1; |
313 | | } |
314 | | else if constexpr (sizeof(C) == sizeof(wchar_t)) |
315 | | { |
316 | | // take advantage of builtin optimisations |
317 | | wchar_t const * p = wcschr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c)); |
318 | | return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1; |
319 | | } |
320 | | else |
321 | 108 | { |
322 | 108 | const C* pTempStr = pStr; |
323 | 108 | while ( *pTempStr ) |
324 | 108 | { |
325 | 108 | if ( *pTempStr == c ) |
326 | 108 | return pTempStr-pStr; |
327 | | |
328 | 0 | pTempStr++; |
329 | 0 | } |
330 | | |
331 | 0 | return -1; |
332 | 108 | } |
333 | 108 | } Unexecuted instantiation: int rtl::str::indexOfChar<char>(char const*, char) int rtl::str::indexOfChar<char16_t>(char16_t const*, char16_t) Line | Count | Source | 303 | 108 | { | 304 | 108 | assert(pStr); | 305 | 108 | if (!c) | 306 | 0 | return -1; // Unifies behavior of strchr/wcschr and unoptimized algorithm wrt '\0' | 307 | | | 308 | | if constexpr (sizeof(C) == sizeof(char)) | 309 | | { | 310 | | // take advantage of builtin optimisations | 311 | | const C* p = strchr(pStr, c); | 312 | | return p ? p - pStr : -1; | 313 | | } | 314 | | else if constexpr (sizeof(C) == sizeof(wchar_t)) | 315 | | { | 316 | | // take advantage of builtin optimisations | 317 | | wchar_t const * p = wcschr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c)); | 318 | | return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1; | 319 | | } | 320 | | else | 321 | 108 | { | 322 | 108 | const C* pTempStr = pStr; | 323 | 108 | while ( *pTempStr ) | 324 | 108 | { | 325 | 108 | if ( *pTempStr == c ) | 326 | 108 | return pTempStr-pStr; | 327 | | | 328 | 0 | pTempStr++; | 329 | 0 | } | 330 | | | 331 | 0 | return -1; | 332 | 108 | } | 333 | 108 | } |
|
334 | | |
335 | | /* ----------------------------------------------------------------------- */ |
336 | | |
337 | | template <typename C> sal_Int32 indexOfChar_WithLength(const C* pStr, sal_Int32 nLen, C c) |
338 | 105M | { |
339 | | // assert(nLen >= 0); |
340 | 105M | if (nLen <= 0) |
341 | 21.3M | return -1; |
342 | | // take advantage of builtin optimisations |
343 | 84.1M | std::basic_string_view v(pStr, nLen); |
344 | 84.1M | auto idx = v.find(c); |
345 | 84.1M | return idx == v.npos ? -1 : idx; |
346 | 105M | } int rtl::str::indexOfChar_WithLength<char>(char const*, int, char) Line | Count | Source | 338 | 3.77M | { | 339 | | // assert(nLen >= 0); | 340 | 3.77M | if (nLen <= 0) | 341 | 145 | return -1; | 342 | | // take advantage of builtin optimisations | 343 | 3.77M | std::basic_string_view v(pStr, nLen); | 344 | 3.77M | auto idx = v.find(c); | 345 | 3.77M | return idx == v.npos ? -1 : idx; | 346 | 3.77M | } |
int rtl::str::indexOfChar_WithLength<char16_t>(char16_t const*, int, char16_t) Line | Count | Source | 338 | 101M | { | 339 | | // assert(nLen >= 0); | 340 | 101M | if (nLen <= 0) | 341 | 21.3M | return -1; | 342 | | // take advantage of builtin optimisations | 343 | 80.3M | std::basic_string_view v(pStr, nLen); | 344 | 80.3M | auto idx = v.find(c); | 345 | 80.3M | return idx == v.npos ? -1 : idx; | 346 | 101M | } |
|
347 | | |
348 | | /* ----------------------------------------------------------------------- */ |
349 | | |
350 | | template <typename C> sal_Int32 lastIndexOfChar_WithLength(const C* pStr, sal_Int32 nLen, C c) |
351 | 3.31M | { |
352 | 3.31M | assert(nLen >= 0); |
353 | | // take advantage of builtin optimisations |
354 | 3.31M | std::basic_string_view v(pStr, nLen); |
355 | 3.31M | auto idx = v.rfind(c); |
356 | 3.31M | return idx == v.npos ? -1 : idx; |
357 | 3.31M | } int rtl::str::lastIndexOfChar_WithLength<char>(char const*, int, char) Line | Count | Source | 351 | 328k | { | 352 | 328k | assert(nLen >= 0); | 353 | | // take advantage of builtin optimisations | 354 | 328k | std::basic_string_view v(pStr, nLen); | 355 | 328k | auto idx = v.rfind(c); | 356 | 328k | return idx == v.npos ? -1 : idx; | 357 | 328k | } |
int rtl::str::lastIndexOfChar_WithLength<char16_t>(char16_t const*, int, char16_t) Line | Count | Source | 351 | 2.99M | { | 352 | 2.99M | assert(nLen >= 0); | 353 | | // take advantage of builtin optimisations | 354 | 2.99M | std::basic_string_view v(pStr, nLen); | 355 | 2.99M | auto idx = v.rfind(c); | 356 | 2.99M | return idx == v.npos ? -1 : idx; | 357 | 2.99M | } |
|
358 | | |
359 | | /* ----------------------------------------------------------------------- */ |
360 | | |
361 | | template <typename C> sal_Int32 lastIndexOfChar(const C* pStr, C c) |
362 | 0 | { |
363 | 0 | assert(pStr); |
364 | 0 | if (!c) |
365 | 0 | return -1; // Unifies behavior of strrchr/wcsrchr and lastIndexOfChar_WithLength wrt '\0' |
366 | | |
367 | | if constexpr (sizeof(C) == sizeof(char)) |
368 | 0 | { |
369 | | // take advantage of builtin optimisations |
370 | 0 | const C* p = strrchr(pStr, c); |
371 | 0 | return p ? p - pStr : -1; |
372 | | } |
373 | | else if constexpr (sizeof(C) == sizeof(wchar_t)) |
374 | | { |
375 | | // take advantage of builtin optimisations |
376 | | wchar_t const * p = wcsrchr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c)); |
377 | | return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1; |
378 | | } |
379 | | else |
380 | 0 | { |
381 | 0 | return lastIndexOfChar_WithLength( pStr, getLength( pStr ), c ); |
382 | 0 | } |
383 | 0 | } Unexecuted instantiation: int rtl::str::lastIndexOfChar<char>(char const*, char) Unexecuted instantiation: int rtl::str::lastIndexOfChar<char16_t>(char16_t const*, char16_t) |
384 | | |
385 | | /* ----------------------------------------------------------------------- */ |
386 | | |
387 | | template <typename C> |
388 | | sal_Int32 indexOfStr_WithLength(const C* pStr, sal_Int32 nStrLen, |
389 | | const C* pSubStr, sal_Int32 nSubLen) |
390 | 80.9M | { |
391 | 80.9M | assert(nStrLen >= 0); |
392 | 80.9M | assert(nSubLen >= 0); |
393 | | /* an empty SubString is always not findable */ |
394 | 80.9M | if ( nSubLen == 0 ) |
395 | 4.94M | return -1; |
396 | | // take advantage of builtin optimisations |
397 | 76.0M | std::basic_string_view v(pStr, nStrLen); |
398 | 76.0M | auto idx = nSubLen == 1 ? v.find(*pSubStr) : v.find(pSubStr, 0, nSubLen); |
399 | 76.0M | return idx == v.npos ? -1 : idx; |
400 | 80.9M | } int rtl::str::indexOfStr_WithLength<char>(char const*, int, char const*, int) Line | Count | Source | 390 | 2.92M | { | 391 | 2.92M | assert(nStrLen >= 0); | 392 | 2.92M | assert(nSubLen >= 0); | 393 | | /* an empty SubString is always not findable */ | 394 | 2.92M | if ( nSubLen == 0 ) | 395 | 0 | return -1; | 396 | | // take advantage of builtin optimisations | 397 | 2.92M | std::basic_string_view v(pStr, nStrLen); | 398 | 2.92M | auto idx = nSubLen == 1 ? v.find(*pSubStr) : v.find(pSubStr, 0, nSubLen); | 399 | 2.92M | return idx == v.npos ? -1 : idx; | 400 | 2.92M | } |
int rtl::str::indexOfStr_WithLength<char16_t>(char16_t const*, int, char16_t const*, int) Line | Count | Source | 390 | 78.0M | { | 391 | 78.0M | assert(nStrLen >= 0); | 392 | 78.0M | assert(nSubLen >= 0); | 393 | | /* an empty SubString is always not findable */ | 394 | 78.0M | if ( nSubLen == 0 ) | 395 | 4.94M | return -1; | 396 | | // take advantage of builtin optimisations | 397 | 73.1M | std::basic_string_view v(pStr, nStrLen); | 398 | 73.1M | auto idx = nSubLen == 1 ? v.find(*pSubStr) : v.find(pSubStr, 0, nSubLen); | 399 | 73.1M | return idx == v.npos ? -1 : idx; | 400 | 78.0M | } |
|
401 | | |
402 | | inline sal_Int32 indexOfStr_WithLength(const sal_Unicode* pStr, sal_Int32 nStrLen, |
403 | | const char* pSubStr, sal_Int32 nSubLen) |
404 | 28.6M | { |
405 | 28.6M | assert(nStrLen >= 0); |
406 | 28.6M | assert(nSubLen >= 0); |
407 | 28.6M | if (nSubLen > 0 && nSubLen <= nStrLen) |
408 | 23.2M | { |
409 | 23.2M | sal_Unicode const* end = pStr + nStrLen; |
410 | 23.2M | sal_Unicode const* cursor = pStr; |
411 | | |
412 | 28.6M | while (cursor < end) |
413 | 28.6M | { |
414 | 28.6M | cursor = std::char_traits<sal_Unicode>::find(cursor, end - cursor, *pSubStr); |
415 | 28.6M | if (!cursor || (end - cursor < nSubLen)) |
416 | 16.1M | { |
417 | | /* no enough left to actually have a match */ |
418 | 16.1M | break; |
419 | 16.1M | } |
420 | | /* now it is worth trying a full match */ |
421 | 12.5M | if (nSubLen == 1 || rtl_ustr_asciil_reverseEquals_WithLength(cursor, pSubStr, nSubLen)) |
422 | 7.08M | { |
423 | 7.08M | return cursor - pStr; |
424 | 7.08M | } |
425 | 5.48M | cursor += 1; |
426 | 5.48M | } |
427 | 23.2M | } |
428 | 21.5M | return -1; |
429 | 28.6M | } |
430 | | |
431 | | /* ----------------------------------------------------------------------- */ |
432 | | |
433 | | template <typename C> sal_Int32 indexOfStr(const C* pStr, const C* pSubStr) |
434 | 0 | { |
435 | 0 | assert(pStr); |
436 | 0 | assert(pSubStr); |
437 | | /* an empty SubString is always not findable */ |
438 | 0 | if (*pSubStr == 0) |
439 | 0 | return -1; |
440 | | if constexpr (sizeof(C) == sizeof(char)) |
441 | 0 | { |
442 | | // take advantage of builtin optimisations |
443 | 0 | const C* p = strstr(pStr, pSubStr); |
444 | 0 | return p ? p - pStr : -1; |
445 | | } |
446 | | else if constexpr (sizeof(C) == sizeof(wchar_t)) |
447 | | { |
448 | | // take advantage of builtin optimisations |
449 | | wchar_t const * p = wcsstr(reinterpret_cast<wchar_t const *>(pStr), reinterpret_cast<wchar_t const *>(pSubStr)); |
450 | | return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1; |
451 | | } |
452 | | else |
453 | 0 | { |
454 | 0 | return indexOfStr_WithLength( pStr, getLength( pStr ), |
455 | 0 | pSubStr, getLength( pSubStr ) ); |
456 | 0 | } |
457 | 0 | } Unexecuted instantiation: int rtl::str::indexOfStr<char>(char const*, char const*) Unexecuted instantiation: int rtl::str::indexOfStr<char16_t>(char16_t const*, char16_t const*) |
458 | | |
459 | | /* ----------------------------------------------------------------------- */ |
460 | | |
461 | | template <typename C> |
462 | | sal_Int32 lastIndexOfStr_WithLength(const C* pStr, sal_Int32 nStrLen, |
463 | | const C* pSubStr, sal_Int32 nSubLen) |
464 | 0 | { |
465 | 0 | assert(nStrLen >= 0); |
466 | 0 | assert(nSubLen >= 0); |
467 | | /* an empty SubString is always not findable */ |
468 | 0 | if ( nSubLen == 0 ) |
469 | 0 | return -1; |
470 | | // take advantage of builtin optimisations |
471 | 0 | std::basic_string_view v(pStr, nStrLen); |
472 | 0 | std::basic_string_view needle(pSubStr, nSubLen); |
473 | 0 | auto idx = v.rfind(needle); |
474 | 0 | return idx == v.npos ? -1 : idx; |
475 | 0 | } Unexecuted instantiation: int rtl::str::lastIndexOfStr_WithLength<char>(char const*, int, char const*, int) Unexecuted instantiation: int rtl::str::lastIndexOfStr_WithLength<char16_t>(char16_t const*, int, char16_t const*, int) |
476 | | |
477 | | /* ----------------------------------------------------------------------- */ |
478 | | |
479 | | template <typename C> sal_Int32 lastIndexOfStr(const C* pStr, const C* pSubStr) |
480 | 0 | { |
481 | 0 | return lastIndexOfStr_WithLength(pStr, getLength(pStr), pSubStr, getLength(pSubStr)); |
482 | 0 | } Unexecuted instantiation: int rtl::str::lastIndexOfStr<char>(char const*, char const*) Unexecuted instantiation: int rtl::str::lastIndexOfStr<char16_t>(char16_t const*, char16_t const*) |
483 | | |
484 | | /* ----------------------------------------------------------------------- */ |
485 | | |
486 | | template <class S, class Replacer> void replaceChars(S str, Replacer replacer) |
487 | 376k | { |
488 | 376k | for (auto& rChar : str) |
489 | 1.11M | rChar = replacer.Replace(rChar); |
490 | 376k | } Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::null_terminated<char>, rtl::str::FromTo<char> >(rtl::str::null_terminated<char>, rtl::str::FromTo<char>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::with_length<char>, rtl::str::FromTo<char> >(rtl::str::with_length<char>, rtl::str::FromTo<char>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::null_terminated<char>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)> >(rtl::str::null_terminated<char>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::with_length<char>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)> >(rtl::str::with_length<char>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::null_terminated<char>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)> >(rtl::str::null_terminated<char>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::with_length<char>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)> >(rtl::str::with_length<char>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::null_terminated<char16_t>, rtl::str::FromTo<char16_t> >(rtl::str::null_terminated<char16_t>, rtl::str::FromTo<char16_t>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::with_length<char16_t>, rtl::str::FromTo<char16_t> >(rtl::str::with_length<char16_t>, rtl::str::FromTo<char16_t>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::null_terminated<char16_t>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)> >(rtl::str::null_terminated<char16_t>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::with_length<char16_t>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)> >(rtl::str::with_length<char16_t>, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>) Unexecuted instantiation: void rtl::str::replaceChars<rtl::str::null_terminated<char16_t>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)> >(rtl::str::null_terminated<char16_t>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>) void rtl::str::replaceChars<rtl::str::with_length<char16_t>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)> >(rtl::str::with_length<char16_t>, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>) Line | Count | Source | 487 | 376k | { | 488 | 376k | for (auto& rChar : str) | 489 | 1.11M | rChar = replacer.Replace(rChar); | 490 | 376k | } |
|
491 | | |
492 | | /* ----------------------------------------------------------------------- */ |
493 | | |
494 | | template <typename C> sal_Int32 trim_WithLength(C* pStr, sal_Int32 nLen) |
495 | 0 | { |
496 | 0 | const auto view = o3tl::trim(std::basic_string_view(pStr, nLen)); |
497 | |
|
498 | 0 | if (static_cast<sal_Int32>(view.size()) != nLen) |
499 | 0 | { |
500 | 0 | nLen = static_cast<sal_Int32>(view.size()); |
501 | 0 | if (view.data() != pStr) |
502 | 0 | Copy(pStr, view.data(), nLen); |
503 | 0 | *(pStr+nLen) = 0; |
504 | 0 | } |
505 | |
|
506 | 0 | return nLen; |
507 | 0 | } Unexecuted instantiation: int rtl::str::trim_WithLength<char>(char*, int) Unexecuted instantiation: int rtl::str::trim_WithLength<char16_t>(char16_t*, int) |
508 | | |
509 | | /* ----------------------------------------------------------------------- */ |
510 | | |
511 | 0 | template <typename C> sal_Int32 trim(C* pStr) { return trim_WithLength(pStr, getLength(pStr)); }Unexecuted instantiation: int rtl::str::trim<char>(char*) Unexecuted instantiation: int rtl::str::trim<char16_t>(char16_t*) |
512 | | |
513 | | /* ----------------------------------------------------------------------- */ |
514 | | |
515 | | template <typename C> sal_Int32 valueOfBoolean(C* pStr, sal_Bool b) |
516 | 0 | { |
517 | 0 | assert(pStr); |
518 | 0 | if ( b ) |
519 | 0 | { |
520 | 0 | *pStr = 't'; |
521 | 0 | pStr++; |
522 | 0 | *pStr = 'r'; |
523 | 0 | pStr++; |
524 | 0 | *pStr = 'u'; |
525 | 0 | pStr++; |
526 | 0 | *pStr = 'e'; |
527 | 0 | pStr++; |
528 | 0 | *pStr = 0; |
529 | 0 | return 4; |
530 | 0 | } |
531 | 0 | else |
532 | 0 | { |
533 | 0 | *pStr = 'f'; |
534 | 0 | pStr++; |
535 | 0 | *pStr = 'a'; |
536 | 0 | pStr++; |
537 | 0 | *pStr = 'l'; |
538 | 0 | pStr++; |
539 | 0 | *pStr = 's'; |
540 | 0 | pStr++; |
541 | 0 | *pStr = 'e'; |
542 | 0 | pStr++; |
543 | 0 | *pStr = 0; |
544 | 0 | return 5; |
545 | 0 | } |
546 | 0 | } Unexecuted instantiation: int rtl::str::valueOfBoolean<char>(char*, unsigned char) Unexecuted instantiation: int rtl::str::valueOfBoolean<char16_t>(char16_t*, unsigned char) |
547 | | |
548 | | /* ----------------------------------------------------------------------- */ |
549 | | |
550 | | template <typename C> sal_Int32 valueOfChar(C* pStr, C c) |
551 | 0 | { |
552 | 0 | assert(pStr); |
553 | 0 | *pStr++ = c; |
554 | 0 | *pStr = 0; |
555 | 0 | return 1; |
556 | 0 | } Unexecuted instantiation: int rtl::str::valueOfChar<char>(char*, char) Unexecuted instantiation: int rtl::str::valueOfChar<char16_t>(char16_t*, char16_t) |
557 | | |
558 | | /* ----------------------------------------------------------------------- */ |
559 | | |
560 | | template <sal_Int32 maxLen, typename C, typename T> |
561 | | sal_Int32 valueOfInt(C* pStr, T n, sal_Int16 nRadix) |
562 | 74.2M | { |
563 | 74.2M | assert(pStr); |
564 | 74.2M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); |
565 | 74.2M | const auto* const pStart = pStr; |
566 | 74.2M | char aBuf[maxLen]; |
567 | 74.2M | char* pBuf = aBuf; |
568 | 74.2M | using uT = std::make_unsigned_t<T>; |
569 | 74.2M | uT nValue; |
570 | | |
571 | | /* Radix must be valid */ |
572 | 74.2M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) |
573 | 0 | nRadix = 10; |
574 | | |
575 | | if constexpr (std::is_signed_v<T>) |
576 | 71.6M | { |
577 | | /* is value negative */ |
578 | 71.6M | if ( n < 0 ) |
579 | 3.49M | { |
580 | 3.49M | *pStr = '-'; |
581 | 3.49M | pStr++; |
582 | 3.49M | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; |
583 | 3.49M | } |
584 | 68.1M | else |
585 | 68.1M | nValue = n; |
586 | | } |
587 | | else |
588 | 2.61M | nValue = n; |
589 | | |
590 | | /* create a recursive buffer with all values, except the last one */ |
591 | 74.2M | do |
592 | 179M | { |
593 | 179M | char nDigit = static_cast<char>(nValue % nRadix); |
594 | 179M | nValue /= nRadix; |
595 | 179M | if ( nDigit > 9 ) |
596 | 4.04M | *pBuf = (nDigit-10) + 'a'; |
597 | 175M | else |
598 | 175M | *pBuf = (nDigit + '0' ); |
599 | 179M | pBuf++; |
600 | 179M | } |
601 | 179M | while ( nValue > 0 ); |
602 | | |
603 | | /* copy the values in the right direction into the destination buffer */ |
604 | 74.2M | pStr = std::reverse_copy(aBuf, pBuf, pStr); |
605 | 74.2M | *pStr = 0; |
606 | | |
607 | 74.2M | return pStr - pStart; |
608 | 74.2M | } int rtl::str::valueOfInt<33, char, int>(char*, int, short) Line | Count | Source | 562 | 8.06M | { | 563 | 8.06M | assert(pStr); | 564 | 8.06M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 565 | 8.06M | const auto* const pStart = pStr; | 566 | 8.06M | char aBuf[maxLen]; | 567 | 8.06M | char* pBuf = aBuf; | 568 | 8.06M | using uT = std::make_unsigned_t<T>; | 569 | 8.06M | uT nValue; | 570 | | | 571 | | /* Radix must be valid */ | 572 | 8.06M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 573 | 0 | nRadix = 10; | 574 | | | 575 | | if constexpr (std::is_signed_v<T>) | 576 | 8.06M | { | 577 | | /* is value negative */ | 578 | 8.06M | if ( n < 0 ) | 579 | 2.15M | { | 580 | 2.15M | *pStr = '-'; | 581 | 2.15M | pStr++; | 582 | 2.15M | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; | 583 | 2.15M | } | 584 | 5.90M | else | 585 | 5.90M | nValue = n; | 586 | | } | 587 | | else | 588 | | nValue = n; | 589 | | | 590 | | /* create a recursive buffer with all values, except the last one */ | 591 | 8.06M | do | 592 | 11.0M | { | 593 | 11.0M | char nDigit = static_cast<char>(nValue % nRadix); | 594 | 11.0M | nValue /= nRadix; | 595 | 11.0M | if ( nDigit > 9 ) | 596 | 0 | *pBuf = (nDigit-10) + 'a'; | 597 | 11.0M | else | 598 | 11.0M | *pBuf = (nDigit + '0' ); | 599 | 11.0M | pBuf++; | 600 | 11.0M | } | 601 | 11.0M | while ( nValue > 0 ); | 602 | | | 603 | | /* copy the values in the right direction into the destination buffer */ | 604 | 8.06M | pStr = std::reverse_copy(aBuf, pBuf, pStr); | 605 | 8.06M | *pStr = 0; | 606 | | | 607 | 8.06M | return pStr - pStart; | 608 | 8.06M | } |
int rtl::str::valueOfInt<65, char, long>(char*, long, short) Line | Count | Source | 562 | 78.8k | { | 563 | 78.8k | assert(pStr); | 564 | 78.8k | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 565 | 78.8k | const auto* const pStart = pStr; | 566 | 78.8k | char aBuf[maxLen]; | 567 | 78.8k | char* pBuf = aBuf; | 568 | 78.8k | using uT = std::make_unsigned_t<T>; | 569 | 78.8k | uT nValue; | 570 | | | 571 | | /* Radix must be valid */ | 572 | 78.8k | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 573 | 0 | nRadix = 10; | 574 | | | 575 | | if constexpr (std::is_signed_v<T>) | 576 | 78.8k | { | 577 | | /* is value negative */ | 578 | 78.8k | if ( n < 0 ) | 579 | 7.31k | { | 580 | 7.31k | *pStr = '-'; | 581 | 7.31k | pStr++; | 582 | 7.31k | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; | 583 | 7.31k | } | 584 | 71.5k | else | 585 | 71.5k | nValue = n; | 586 | | } | 587 | | else | 588 | | nValue = n; | 589 | | | 590 | | /* create a recursive buffer with all values, except the last one */ | 591 | 78.8k | do | 592 | 238k | { | 593 | 238k | char nDigit = static_cast<char>(nValue % nRadix); | 594 | 238k | nValue /= nRadix; | 595 | 238k | if ( nDigit > 9 ) | 596 | 0 | *pBuf = (nDigit-10) + 'a'; | 597 | 238k | else | 598 | 238k | *pBuf = (nDigit + '0' ); | 599 | 238k | pBuf++; | 600 | 238k | } | 601 | 238k | while ( nValue > 0 ); | 602 | | | 603 | | /* copy the values in the right direction into the destination buffer */ | 604 | 78.8k | pStr = std::reverse_copy(aBuf, pBuf, pStr); | 605 | 78.8k | *pStr = 0; | 606 | | | 607 | 78.8k | return pStr - pStart; | 608 | 78.8k | } |
int rtl::str::valueOfInt<65, char, unsigned long>(char*, unsigned long, short) Line | Count | Source | 562 | 237k | { | 563 | 237k | assert(pStr); | 564 | 237k | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 565 | 237k | const auto* const pStart = pStr; | 566 | 237k | char aBuf[maxLen]; | 567 | 237k | char* pBuf = aBuf; | 568 | 237k | using uT = std::make_unsigned_t<T>; | 569 | 237k | uT nValue; | 570 | | | 571 | | /* Radix must be valid */ | 572 | 237k | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 573 | 0 | nRadix = 10; | 574 | | | 575 | | if constexpr (std::is_signed_v<T>) | 576 | | { | 577 | | /* is value negative */ | 578 | | if ( n < 0 ) | 579 | | { | 580 | | *pStr = '-'; | 581 | | pStr++; | 582 | | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; | 583 | | } | 584 | | else | 585 | | nValue = n; | 586 | | } | 587 | | else | 588 | 237k | nValue = n; | 589 | | | 590 | | /* create a recursive buffer with all values, except the last one */ | 591 | 237k | do | 592 | 1.06M | { | 593 | 1.06M | char nDigit = static_cast<char>(nValue % nRadix); | 594 | 1.06M | nValue /= nRadix; | 595 | 1.06M | if ( nDigit > 9 ) | 596 | 0 | *pBuf = (nDigit-10) + 'a'; | 597 | 1.06M | else | 598 | 1.06M | *pBuf = (nDigit + '0' ); | 599 | 1.06M | pBuf++; | 600 | 1.06M | } | 601 | 1.06M | while ( nValue > 0 ); | 602 | | | 603 | | /* copy the values in the right direction into the destination buffer */ | 604 | 237k | pStr = std::reverse_copy(aBuf, pBuf, pStr); | 605 | 237k | *pStr = 0; | 606 | | | 607 | 237k | return pStr - pStart; | 608 | 237k | } |
int rtl::str::valueOfInt<33, char16_t, int>(char16_t*, int, short) Line | Count | Source | 562 | 61.6M | { | 563 | 61.6M | assert(pStr); | 564 | 61.6M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 565 | 61.6M | const auto* const pStart = pStr; | 566 | 61.6M | char aBuf[maxLen]; | 567 | 61.6M | char* pBuf = aBuf; | 568 | 61.6M | using uT = std::make_unsigned_t<T>; | 569 | 61.6M | uT nValue; | 570 | | | 571 | | /* Radix must be valid */ | 572 | 61.6M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 573 | 0 | nRadix = 10; | 574 | | | 575 | | if constexpr (std::is_signed_v<T>) | 576 | 61.6M | { | 577 | | /* is value negative */ | 578 | 61.6M | if ( n < 0 ) | 579 | 1.32M | { | 580 | 1.32M | *pStr = '-'; | 581 | 1.32M | pStr++; | 582 | 1.32M | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; | 583 | 1.32M | } | 584 | 60.2M | else | 585 | 60.2M | nValue = n; | 586 | | } | 587 | | else | 588 | | nValue = n; | 589 | | | 590 | | /* create a recursive buffer with all values, except the last one */ | 591 | 61.6M | do | 592 | 138M | { | 593 | 138M | char nDigit = static_cast<char>(nValue % nRadix); | 594 | 138M | nValue /= nRadix; | 595 | 138M | if ( nDigit > 9 ) | 596 | 481k | *pBuf = (nDigit-10) + 'a'; | 597 | 137M | else | 598 | 137M | *pBuf = (nDigit + '0' ); | 599 | 138M | pBuf++; | 600 | 138M | } | 601 | 138M | while ( nValue > 0 ); | 602 | | | 603 | | /* copy the values in the right direction into the destination buffer */ | 604 | 61.6M | pStr = std::reverse_copy(aBuf, pBuf, pStr); | 605 | 61.6M | *pStr = 0; | 606 | | | 607 | 61.6M | return pStr - pStart; | 608 | 61.6M | } |
int rtl::str::valueOfInt<65, char16_t, long>(char16_t*, long, short) Line | Count | Source | 562 | 1.89M | { | 563 | 1.89M | assert(pStr); | 564 | 1.89M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 565 | 1.89M | const auto* const pStart = pStr; | 566 | 1.89M | char aBuf[maxLen]; | 567 | 1.89M | char* pBuf = aBuf; | 568 | 1.89M | using uT = std::make_unsigned_t<T>; | 569 | 1.89M | uT nValue; | 570 | | | 571 | | /* Radix must be valid */ | 572 | 1.89M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 573 | 0 | nRadix = 10; | 574 | | | 575 | | if constexpr (std::is_signed_v<T>) | 576 | 1.89M | { | 577 | | /* is value negative */ | 578 | 1.89M | if ( n < 0 ) | 579 | 63 | { | 580 | 63 | *pStr = '-'; | 581 | 63 | pStr++; | 582 | 63 | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; | 583 | 63 | } | 584 | 1.89M | else | 585 | 1.89M | nValue = n; | 586 | | } | 587 | | else | 588 | | nValue = n; | 589 | | | 590 | | /* create a recursive buffer with all values, except the last one */ | 591 | 1.89M | do | 592 | 16.5M | { | 593 | 16.5M | char nDigit = static_cast<char>(nValue % nRadix); | 594 | 16.5M | nValue /= nRadix; | 595 | 16.5M | if ( nDigit > 9 ) | 596 | 2.19M | *pBuf = (nDigit-10) + 'a'; | 597 | 14.3M | else | 598 | 14.3M | *pBuf = (nDigit + '0' ); | 599 | 16.5M | pBuf++; | 600 | 16.5M | } | 601 | 16.5M | while ( nValue > 0 ); | 602 | | | 603 | | /* copy the values in the right direction into the destination buffer */ | 604 | 1.89M | pStr = std::reverse_copy(aBuf, pBuf, pStr); | 605 | 1.89M | *pStr = 0; | 606 | | | 607 | 1.89M | return pStr - pStart; | 608 | 1.89M | } |
int rtl::str::valueOfInt<65, char16_t, unsigned long>(char16_t*, unsigned long, short) Line | Count | Source | 562 | 2.37M | { | 563 | 2.37M | assert(pStr); | 564 | 2.37M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 565 | 2.37M | const auto* const pStart = pStr; | 566 | 2.37M | char aBuf[maxLen]; | 567 | 2.37M | char* pBuf = aBuf; | 568 | 2.37M | using uT = std::make_unsigned_t<T>; | 569 | 2.37M | uT nValue; | 570 | | | 571 | | /* Radix must be valid */ | 572 | 2.37M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 573 | 0 | nRadix = 10; | 574 | | | 575 | | if constexpr (std::is_signed_v<T>) | 576 | | { | 577 | | /* is value negative */ | 578 | | if ( n < 0 ) | 579 | | { | 580 | | *pStr = '-'; | 581 | | pStr++; | 582 | | nValue = n == std::numeric_limits<T>::min() ? static_cast<uT>(n) : -n; | 583 | | } | 584 | | else | 585 | | nValue = n; | 586 | | } | 587 | | else | 588 | 2.37M | nValue = n; | 589 | | | 590 | | /* create a recursive buffer with all values, except the last one */ | 591 | 2.37M | do | 592 | 12.2M | { | 593 | 12.2M | char nDigit = static_cast<char>(nValue % nRadix); | 594 | 12.2M | nValue /= nRadix; | 595 | 12.2M | if ( nDigit > 9 ) | 596 | 1.37M | *pBuf = (nDigit-10) + 'a'; | 597 | 10.9M | else | 598 | 10.9M | *pBuf = (nDigit + '0' ); | 599 | 12.2M | pBuf++; | 600 | 12.2M | } | 601 | 12.2M | while ( nValue > 0 ); | 602 | | | 603 | | /* copy the values in the right direction into the destination buffer */ | 604 | 2.37M | pStr = std::reverse_copy(aBuf, pBuf, pStr); | 605 | 2.37M | *pStr = 0; | 606 | | | 607 | 2.37M | return pStr - pStart; | 608 | 2.37M | } |
|
609 | | |
610 | | /* ----------------------------------------------------------------------- */ |
611 | | |
612 | | template <typename C> sal_Bool toBoolean(const C* pStr) |
613 | 14.1k | { |
614 | 14.1k | assert(pStr); |
615 | 14.1k | if ( *pStr == '1' ) |
616 | 228 | return true; |
617 | | |
618 | 13.9k | if ( (*pStr == 'T') || (*pStr == 't') ) |
619 | 6 | { |
620 | 6 | pStr++; |
621 | 6 | if ( (*pStr == 'R') || (*pStr == 'r') ) |
622 | 6 | { |
623 | 6 | pStr++; |
624 | 6 | if ( (*pStr == 'U') || (*pStr == 'u') ) |
625 | 6 | { |
626 | 6 | pStr++; |
627 | 6 | if ( (*pStr == 'E') || (*pStr == 'e') ) |
628 | 6 | return true; |
629 | 6 | } |
630 | 6 | } |
631 | 6 | } |
632 | | |
633 | 13.8k | return false; |
634 | 13.9k | } Unexecuted instantiation: unsigned char rtl::str::toBoolean<char>(char const*) unsigned char rtl::str::toBoolean<char16_t>(char16_t const*) Line | Count | Source | 613 | 14.1k | { | 614 | 14.1k | assert(pStr); | 615 | 14.1k | if ( *pStr == '1' ) | 616 | 228 | return true; | 617 | | | 618 | 13.9k | if ( (*pStr == 'T') || (*pStr == 't') ) | 619 | 6 | { | 620 | 6 | pStr++; | 621 | 6 | if ( (*pStr == 'R') || (*pStr == 'r') ) | 622 | 6 | { | 623 | 6 | pStr++; | 624 | 6 | if ( (*pStr == 'U') || (*pStr == 'u') ) | 625 | 6 | { | 626 | 6 | pStr++; | 627 | 6 | if ( (*pStr == 'E') || (*pStr == 'e') ) | 628 | 6 | return true; | 629 | 6 | } | 630 | 6 | } | 631 | 6 | } | 632 | | | 633 | 13.8k | return false; | 634 | 13.9k | } |
|
635 | | |
636 | | /* ----------------------------------------------------------------------- */ |
637 | | |
638 | | template <typename T, class Iter> inline bool HandleSignChar(Iter& iter) |
639 | 94.9M | { |
640 | | if constexpr (std::numeric_limits<T>::is_signed) |
641 | 94.9M | { |
642 | 94.9M | if (*iter == '-') |
643 | 185k | { |
644 | 185k | ++iter; |
645 | 185k | return true; |
646 | 185k | } |
647 | 94.9M | } |
648 | 94.9M | if (*iter == '+') |
649 | 4.01k | ++iter; |
650 | 94.9M | return false; |
651 | 94.9M | } bool rtl::str::HandleSignChar<int, char const*>(char const*&) Line | Count | Source | 639 | 511 | { | 640 | | if constexpr (std::numeric_limits<T>::is_signed) | 641 | 511 | { | 642 | 511 | if (*iter == '-') | 643 | 0 | { | 644 | 0 | ++iter; | 645 | 0 | return true; | 646 | 0 | } | 647 | 511 | } | 648 | 511 | if (*iter == '+') | 649 | 0 | ++iter; | 650 | 511 | return false; | 651 | 511 | } |
bool rtl::str::HandleSignChar<long, char const*>(char const*&) Line | Count | Source | 639 | 9.46M | { | 640 | | if constexpr (std::numeric_limits<T>::is_signed) | 641 | 9.46M | { | 642 | 9.46M | if (*iter == '-') | 643 | 50.4k | { | 644 | 50.4k | ++iter; | 645 | 50.4k | return true; | 646 | 50.4k | } | 647 | 9.46M | } | 648 | 9.46M | if (*iter == '+') | 649 | 20 | ++iter; | 650 | 9.46M | return false; | 651 | 9.46M | } |
Unexecuted instantiation: bool rtl::str::HandleSignChar<unsigned int, char const*>(char const*&) Unexecuted instantiation: bool rtl::str::HandleSignChar<unsigned long, char const*>(char const*&) bool rtl::str::HandleSignChar<int, char16_t const*>(char16_t const*&) Line | Count | Source | 639 | 7.34M | { | 640 | | if constexpr (std::numeric_limits<T>::is_signed) | 641 | 7.34M | { | 642 | 7.34M | if (*iter == '-') | 643 | 4.69k | { | 644 | 4.69k | ++iter; | 645 | 4.69k | return true; | 646 | 4.69k | } | 647 | 7.34M | } | 648 | 7.34M | if (*iter == '+') | 649 | 1.03k | ++iter; | 650 | 7.34M | return false; | 651 | 7.34M | } |
bool rtl::str::HandleSignChar<long, char16_t const*>(char16_t const*&) Line | Count | Source | 639 | 78.1M | { | 640 | | if constexpr (std::numeric_limits<T>::is_signed) | 641 | 78.1M | { | 642 | 78.1M | if (*iter == '-') | 643 | 130k | { | 644 | 130k | ++iter; | 645 | 130k | return true; | 646 | 130k | } | 647 | 78.1M | } | 648 | 78.1M | if (*iter == '+') | 649 | 2.95k | ++iter; | 650 | 78.1M | return false; | 651 | 78.1M | } |
bool rtl::str::HandleSignChar<unsigned int, char16_t const*>(char16_t const*&) Line | Count | Source | 639 | 28.0k | { | 640 | | if constexpr (std::numeric_limits<T>::is_signed) | 641 | | { | 642 | | if (*iter == '-') | 643 | | { | 644 | | ++iter; | 645 | | return true; | 646 | | } | 647 | | } | 648 | 28.0k | if (*iter == '+') | 649 | 0 | ++iter; | 650 | 28.0k | return false; | 651 | 28.0k | } |
Unexecuted instantiation: bool rtl::str::HandleSignChar<unsigned long, char16_t const*>(char16_t const*&) |
652 | | |
653 | | template <typename T> std::pair<T, sal_Int16> DivMod(sal_Int16 nRadix, [[maybe_unused]] bool bNeg) |
654 | 94.9M | { |
655 | | if constexpr (std::numeric_limits<T>::is_signed) |
656 | 94.9M | if (bNeg) |
657 | 185k | return { -(std::numeric_limits<T>::min() / nRadix), |
658 | 185k | -(std::numeric_limits<T>::min() % nRadix) }; |
659 | 94.7M | return { std::numeric_limits<T>::max() / nRadix, std::numeric_limits<T>::max() % nRadix }; |
660 | 94.9M | } std::__1::pair<int, short> rtl::str::DivMod<int>(short, bool) Line | Count | Source | 654 | 7.34M | { | 655 | | if constexpr (std::numeric_limits<T>::is_signed) | 656 | 7.34M | if (bNeg) | 657 | 4.69k | return { -(std::numeric_limits<T>::min() / nRadix), | 658 | 4.69k | -(std::numeric_limits<T>::min() % nRadix) }; | 659 | 7.33M | return { std::numeric_limits<T>::max() / nRadix, std::numeric_limits<T>::max() % nRadix }; | 660 | 7.34M | } |
std::__1::pair<long, short> rtl::str::DivMod<long>(short, bool) Line | Count | Source | 654 | 87.5M | { | 655 | | if constexpr (std::numeric_limits<T>::is_signed) | 656 | 87.5M | if (bNeg) | 657 | 180k | return { -(std::numeric_limits<T>::min() / nRadix), | 658 | 180k | -(std::numeric_limits<T>::min() % nRadix) }; | 659 | 87.3M | return { std::numeric_limits<T>::max() / nRadix, std::numeric_limits<T>::max() % nRadix }; | 660 | 87.5M | } |
std::__1::pair<unsigned int, short> rtl::str::DivMod<unsigned int>(short, bool) Line | Count | Source | 654 | 28.0k | { | 655 | | if constexpr (std::numeric_limits<T>::is_signed) | 656 | | if (bNeg) | 657 | | return { -(std::numeric_limits<T>::min() / nRadix), | 658 | | -(std::numeric_limits<T>::min() % nRadix) }; | 659 | 28.0k | return { std::numeric_limits<T>::max() / nRadix, std::numeric_limits<T>::max() % nRadix }; | 660 | 28.0k | } |
Unexecuted instantiation: std::__1::pair<unsigned long, short> rtl::str::DivMod<unsigned long>(short, bool) |
661 | | |
662 | | template <typename T, class S> T toInt(S str, sal_Int16 nRadix) |
663 | 95.1M | { |
664 | 95.1M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); |
665 | | |
666 | 95.1M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) |
667 | 0 | nRadix = 10; |
668 | | |
669 | 95.1M | auto pStr = str.begin(); |
670 | 95.1M | const auto end = str.end(); |
671 | | |
672 | | /* Skip whitespaces */ |
673 | 95.2M | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) |
674 | 123k | pStr++; |
675 | 95.1M | if (pStr == end) |
676 | 221k | return 0; |
677 | | |
678 | 94.9M | const bool bNeg = HandleSignChar<T>(pStr); |
679 | 94.9M | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); |
680 | 94.9M | assert(nDiv > 0); |
681 | | |
682 | 94.9M | std::make_unsigned_t<T> n = 0; |
683 | 342M | while (pStr != end) |
684 | 251M | { |
685 | 251M | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); |
686 | 251M | if ( nDigit < 0 ) |
687 | 4.10M | break; |
688 | 247M | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) |
689 | 189k | return 0; |
690 | | |
691 | 247M | n *= nRadix; |
692 | 247M | n += nDigit; |
693 | | |
694 | 247M | pStr++; |
695 | 247M | } |
696 | | |
697 | | if constexpr (std::numeric_limits<T>::is_signed) |
698 | 94.7M | if (bNeg) |
699 | 184k | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) |
700 | 184k | ? std::numeric_limits<T>::min() |
701 | 184k | : -static_cast<T>(n); |
702 | 94.5M | return static_cast<T>(n); |
703 | 94.9M | } int rtl::str::toInt<int, rtl::str::null_terminated<char const> >(rtl::str::null_terminated<char const>, short) Line | Count | Source | 663 | 511 | { | 664 | 511 | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 665 | | | 666 | 511 | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 667 | 0 | nRadix = 10; | 668 | | | 669 | 511 | auto pStr = str.begin(); | 670 | 511 | const auto end = str.end(); | 671 | | | 672 | | /* Skip whitespaces */ | 673 | 511 | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) | 674 | 0 | pStr++; | 675 | 511 | if (pStr == end) | 676 | 0 | return 0; | 677 | | | 678 | 511 | const bool bNeg = HandleSignChar<T>(pStr); | 679 | 511 | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); | 680 | 511 | assert(nDiv > 0); | 681 | | | 682 | 511 | std::make_unsigned_t<T> n = 0; | 683 | 1.65k | while (pStr != end) | 684 | 1.14k | { | 685 | 1.14k | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); | 686 | 1.14k | if ( nDigit < 0 ) | 687 | 0 | break; | 688 | 1.14k | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) | 689 | 0 | return 0; | 690 | | | 691 | 1.14k | n *= nRadix; | 692 | 1.14k | n += nDigit; | 693 | | | 694 | 1.14k | pStr++; | 695 | 1.14k | } | 696 | | | 697 | | if constexpr (std::numeric_limits<T>::is_signed) | 698 | 511 | if (bNeg) | 699 | 0 | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) | 700 | 0 | ? std::numeric_limits<T>::min() | 701 | 0 | : -static_cast<T>(n); | 702 | 511 | return static_cast<T>(n); | 703 | 511 | } |
Unexecuted instantiation: long rtl::str::toInt<long, rtl::str::null_terminated<char const> >(rtl::str::null_terminated<char const>, short) long rtl::str::toInt<long, rtl::str::with_length<char const> >(rtl::str::with_length<char const>, short) Line | Count | Source | 663 | 9.46M | { | 664 | 9.46M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 665 | | | 666 | 9.46M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 667 | 0 | nRadix = 10; | 668 | | | 669 | 9.46M | auto pStr = str.begin(); | 670 | 9.46M | const auto end = str.end(); | 671 | | | 672 | | /* Skip whitespaces */ | 673 | 9.46M | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) | 674 | 498 | pStr++; | 675 | 9.46M | if (pStr == end) | 676 | 800 | return 0; | 677 | | | 678 | 9.46M | const bool bNeg = HandleSignChar<T>(pStr); | 679 | 9.46M | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); | 680 | 9.46M | assert(nDiv > 0); | 681 | | | 682 | 9.46M | std::make_unsigned_t<T> n = 0; | 683 | 30.9M | while (pStr != end) | 684 | 21.4M | { | 685 | 21.4M | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); | 686 | 21.4M | if ( nDigit < 0 ) | 687 | 6.39k | break; | 688 | 21.4M | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) | 689 | 3.73k | return 0; | 690 | | | 691 | 21.4M | n *= nRadix; | 692 | 21.4M | n += nDigit; | 693 | | | 694 | 21.4M | pStr++; | 695 | 21.4M | } | 696 | | | 697 | | if constexpr (std::numeric_limits<T>::is_signed) | 698 | 9.45M | if (bNeg) | 699 | 50.3k | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) | 700 | 50.3k | ? std::numeric_limits<T>::min() | 701 | 50.3k | : -static_cast<T>(n); | 702 | 9.40M | return static_cast<T>(n); | 703 | 9.46M | } |
Unexecuted instantiation: unsigned int rtl::str::toInt<unsigned int, rtl::str::null_terminated<char const> >(rtl::str::null_terminated<char const>, short) Unexecuted instantiation: unsigned long rtl::str::toInt<unsigned long, rtl::str::null_terminated<char const> >(rtl::str::null_terminated<char const>, short) int rtl::str::toInt<int, rtl::str::null_terminated<char16_t const> >(rtl::str::null_terminated<char16_t const>, short) Line | Count | Source | 663 | 7.47M | { | 664 | 7.47M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 665 | | | 666 | 7.47M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 667 | 0 | nRadix = 10; | 668 | | | 669 | 7.47M | auto pStr = str.begin(); | 670 | 7.47M | const auto end = str.end(); | 671 | | | 672 | | /* Skip whitespaces */ | 673 | 7.49M | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) | 674 | 13.2k | pStr++; | 675 | 7.47M | if (pStr == end) | 676 | 135k | return 0; | 677 | | | 678 | 7.34M | const bool bNeg = HandleSignChar<T>(pStr); | 679 | 7.34M | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); | 680 | 7.34M | assert(nDiv > 0); | 681 | | | 682 | 7.34M | std::make_unsigned_t<T> n = 0; | 683 | 20.7M | while (pStr != end) | 684 | 14.2M | { | 685 | 14.2M | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); | 686 | 14.2M | if ( nDigit < 0 ) | 687 | 754k | break; | 688 | 13.5M | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) | 689 | 161k | return 0; | 690 | | | 691 | 13.3M | n *= nRadix; | 692 | 13.3M | n += nDigit; | 693 | | | 694 | 13.3M | pStr++; | 695 | 13.3M | } | 696 | | | 697 | | if constexpr (std::numeric_limits<T>::is_signed) | 698 | 7.18M | if (bNeg) | 699 | 4.59k | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) | 700 | 4.59k | ? std::numeric_limits<T>::min() | 701 | 4.59k | : -static_cast<T>(n); | 702 | 7.17M | return static_cast<T>(n); | 703 | 7.34M | } |
long rtl::str::toInt<long, rtl::str::null_terminated<char16_t const> >(rtl::str::null_terminated<char16_t const>, short) Line | Count | Source | 663 | 11.7k | { | 664 | 11.7k | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 665 | | | 666 | 11.7k | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 667 | 0 | nRadix = 10; | 668 | | | 669 | 11.7k | auto pStr = str.begin(); | 670 | 11.7k | const auto end = str.end(); | 671 | | | 672 | | /* Skip whitespaces */ | 673 | 11.7k | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) | 674 | 0 | pStr++; | 675 | 11.7k | if (pStr == end) | 676 | 0 | return 0; | 677 | | | 678 | 11.7k | const bool bNeg = HandleSignChar<T>(pStr); | 679 | 11.7k | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); | 680 | 11.7k | assert(nDiv > 0); | 681 | | | 682 | 11.7k | std::make_unsigned_t<T> n = 0; | 683 | 57.6k | while (pStr != end) | 684 | 45.9k | { | 685 | 45.9k | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); | 686 | 45.9k | if ( nDigit < 0 ) | 687 | 57 | break; | 688 | 45.9k | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) | 689 | 18 | return 0; | 690 | | | 691 | 45.9k | n *= nRadix; | 692 | 45.9k | n += nDigit; | 693 | | | 694 | 45.9k | pStr++; | 695 | 45.9k | } | 696 | | | 697 | | if constexpr (std::numeric_limits<T>::is_signed) | 698 | 11.7k | if (bNeg) | 699 | 11 | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) | 700 | 11 | ? std::numeric_limits<T>::min() | 701 | 11 | : -static_cast<T>(n); | 702 | 11.7k | return static_cast<T>(n); | 703 | 11.7k | } |
long rtl::str::toInt<long, rtl::str::with_length<char16_t const> >(rtl::str::with_length<char16_t const>, short) Line | Count | Source | 663 | 78.1M | { | 664 | 78.1M | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 665 | | | 666 | 78.1M | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 667 | 0 | nRadix = 10; | 668 | | | 669 | 78.1M | auto pStr = str.begin(); | 670 | 78.1M | const auto end = str.end(); | 671 | | | 672 | | /* Skip whitespaces */ | 673 | 78.2M | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) | 674 | 110k | pStr++; | 675 | 78.1M | if (pStr == end) | 676 | 84.6k | return 0; | 677 | | | 678 | 78.0M | const bool bNeg = HandleSignChar<T>(pStr); | 679 | 78.0M | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); | 680 | 78.0M | assert(nDiv > 0); | 681 | | | 682 | 78.0M | std::make_unsigned_t<T> n = 0; | 683 | 290M | while (pStr != end) | 684 | 215M | { | 685 | 215M | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); | 686 | 215M | if ( nDigit < 0 ) | 687 | 3.34M | break; | 688 | 212M | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) | 689 | 23.7k | return 0; | 690 | | | 691 | 212M | n *= nRadix; | 692 | 212M | n += nDigit; | 693 | | | 694 | 212M | pStr++; | 695 | 212M | } | 696 | | | 697 | | if constexpr (std::numeric_limits<T>::is_signed) | 698 | 78.0M | if (bNeg) | 699 | 129k | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) | 700 | 129k | ? std::numeric_limits<T>::min() | 701 | 129k | : -static_cast<T>(n); | 702 | 77.9M | return static_cast<T>(n); | 703 | 78.0M | } |
unsigned int rtl::str::toInt<unsigned int, rtl::str::null_terminated<char16_t const> >(rtl::str::null_terminated<char16_t const>, short) Line | Count | Source | 663 | 28.2k | { | 664 | 28.2k | assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX ); | 665 | | | 666 | 28.2k | if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) | 667 | 0 | nRadix = 10; | 668 | | | 669 | 28.2k | auto pStr = str.begin(); | 670 | 28.2k | const auto end = str.end(); | 671 | | | 672 | | /* Skip whitespaces */ | 673 | 28.2k | while (pStr != end && o3tl::internal::implIsWhitespace(UChar(*pStr))) | 674 | 0 | pStr++; | 675 | 28.2k | if (pStr == end) | 676 | 130 | return 0; | 677 | | | 678 | 28.0k | const bool bNeg = HandleSignChar<T>(pStr); | 679 | 28.0k | const auto& [nDiv, nMod] = DivMod<T>(nRadix, bNeg); | 680 | 28.0k | assert(nDiv > 0); | 681 | | | 682 | 28.0k | std::make_unsigned_t<T> n = 0; | 683 | 85.2k | while (pStr != end) | 684 | 57.2k | { | 685 | 57.2k | sal_Int16 nDigit = implGetDigit(UChar(*pStr), nRadix); | 686 | 57.2k | if ( nDigit < 0 ) | 687 | 0 | break; | 688 | 57.2k | if (static_cast<std::make_unsigned_t<T>>(nMod < nDigit ? nDiv - 1 : nDiv) < n) | 689 | 60 | return 0; | 690 | | | 691 | 57.1k | n *= nRadix; | 692 | 57.1k | n += nDigit; | 693 | | | 694 | 57.1k | pStr++; | 695 | 57.1k | } | 696 | | | 697 | | if constexpr (std::numeric_limits<T>::is_signed) | 698 | | if (bNeg) | 699 | | return n == static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::min()) | 700 | | ? std::numeric_limits<T>::min() | 701 | | : -static_cast<T>(n); | 702 | 28.0k | return static_cast<T>(n); | 703 | 28.0k | } |
Unexecuted instantiation: unsigned long rtl::str::toInt<unsigned long, rtl::str::null_terminated<char16_t const> >(rtl::str::null_terminated<char16_t const>, short) |
704 | | |
705 | | /* ======================================================================= */ |
706 | | /* Internal String-Class help functions */ |
707 | | /* ======================================================================= */ |
708 | | |
709 | | template <class rtl_tString> using Char_T = std::remove_extent_t<decltype(rtl_tString::buffer)>; |
710 | | |
711 | | template <typename rtl_tString> rtl_tString* Alloc(sal_Int32 nLen) |
712 | 1.44G | { |
713 | 1.44G | constexpr auto fix = offsetof(rtl_tString, buffer) + sizeof rtl_tString::buffer; |
714 | 1.44G | rtl_tString * pData |
715 | 1.44G | = (o3tl::make_unsigned(nLen) |
716 | 1.44G | <= ((std::numeric_limits<std::size_t>::max() - fix) |
717 | 1.44G | / sizeof (Char_T<rtl_tString>))) |
718 | 1.44G | ? static_cast<rtl_tString *>(rtl_allocateString( |
719 | 1.44G | fix + nLen * sizeof (Char_T<rtl_tString>))) |
720 | 1.44G | : nullptr; |
721 | 1.44G | if (pData != nullptr) { |
722 | 1.44G | pData->refCount = 1; |
723 | 1.44G | pData->length = nLen; |
724 | 1.44G | pData->buffer[nLen] = 0; |
725 | 1.44G | } |
726 | 1.44G | return pData; |
727 | 1.44G | } _rtl_String* rtl::str::Alloc<_rtl_String>(int) Line | Count | Source | 712 | 121M | { | 713 | 121M | constexpr auto fix = offsetof(rtl_tString, buffer) + sizeof rtl_tString::buffer; | 714 | 121M | rtl_tString * pData | 715 | 121M | = (o3tl::make_unsigned(nLen) | 716 | 121M | <= ((std::numeric_limits<std::size_t>::max() - fix) | 717 | 121M | / sizeof (Char_T<rtl_tString>))) | 718 | 121M | ? static_cast<rtl_tString *>(rtl_allocateString( | 719 | 121M | fix + nLen * sizeof (Char_T<rtl_tString>))) | 720 | 121M | : nullptr; | 721 | 121M | if (pData != nullptr) { | 722 | 121M | pData->refCount = 1; | 723 | 121M | pData->length = nLen; | 724 | 121M | pData->buffer[nLen] = 0; | 725 | 121M | } | 726 | 121M | return pData; | 727 | 121M | } |
_rtl_uString* rtl::str::Alloc<_rtl_uString>(int) Line | Count | Source | 712 | 1.32G | { | 713 | 1.32G | constexpr auto fix = offsetof(rtl_tString, buffer) + sizeof rtl_tString::buffer; | 714 | 1.32G | rtl_tString * pData | 715 | 1.32G | = (o3tl::make_unsigned(nLen) | 716 | 1.32G | <= ((std::numeric_limits<std::size_t>::max() - fix) | 717 | 1.32G | / sizeof (Char_T<rtl_tString>))) | 718 | 1.32G | ? static_cast<rtl_tString *>(rtl_allocateString( | 719 | 1.32G | fix + nLen * sizeof (Char_T<rtl_tString>))) | 720 | 1.32G | : nullptr; | 721 | 1.32G | if (pData != nullptr) { | 722 | 1.32G | pData->refCount = 1; | 723 | 1.32G | pData->length = nLen; | 724 | 1.32G | pData->buffer[nLen] = 0; | 725 | 1.32G | } | 726 | 1.32G | return pData; | 727 | 1.32G | } |
|
728 | | |
729 | | /* ======================================================================= */ |
730 | | /* String-Class functions */ |
731 | | /* ======================================================================= */ |
732 | | |
733 | | template <typename rtl_tString> void acquire(rtl_tString* pThis) |
734 | 7.10G | { |
735 | 7.10G | if (!SAL_STRING_IS_STATIC (pThis)) |
736 | 3.03G | osl_atomic_increment( &((pThis)->refCount) ); |
737 | 7.10G | } void rtl::str::acquire<_rtl_String>(_rtl_String*) Line | Count | Source | 734 | 24.2M | { | 735 | 24.2M | if (!SAL_STRING_IS_STATIC (pThis)) | 736 | 23.0M | osl_atomic_increment( &((pThis)->refCount) ); | 737 | 24.2M | } |
void rtl::str::acquire<_rtl_uString>(_rtl_uString*) Line | Count | Source | 734 | 7.07G | { | 735 | 7.07G | if (!SAL_STRING_IS_STATIC (pThis)) | 736 | 3.01G | osl_atomic_increment( &((pThis)->refCount) ); | 737 | 7.07G | } |
|
738 | | |
739 | | /* ----------------------------------------------------------------------- */ |
740 | | |
741 | | template <typename rtl_tString> void release(rtl_tString* pThis) |
742 | 15.4G | { |
743 | 15.4G | if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis))) |
744 | 10.9G | return; |
745 | | |
746 | | /* OString doesn't have an 'intern' */ |
747 | | if constexpr (sizeof(Char_T<rtl_tString>) == sizeof(sal_Unicode)) |
748 | 4.33G | { |
749 | 4.33G | if (SAL_STRING_IS_INTERN (pThis)) |
750 | 0 | { |
751 | 0 | internRelease (pThis); |
752 | 0 | return; |
753 | 0 | } |
754 | 4.33G | } |
755 | | |
756 | 4.47G | if ( !osl_atomic_decrement( &(pThis->refCount) ) ) |
757 | 1.44G | { |
758 | 1.44G | RTL_LOG_STRING_DELETE( pThis ); |
759 | 1.44G | rtl_freeString( pThis ); |
760 | 1.44G | } |
761 | 4.47G | } void rtl::str::release<_rtl_String>(_rtl_String*) Line | Count | Source | 742 | 270M | { | 743 | 270M | if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis))) | 744 | 126M | return; | 745 | | | 746 | | /* OString doesn't have an 'intern' */ | 747 | | if constexpr (sizeof(Char_T<rtl_tString>) == sizeof(sal_Unicode)) | 748 | | { | 749 | | if (SAL_STRING_IS_INTERN (pThis)) | 750 | | { | 751 | | internRelease (pThis); | 752 | | return; | 753 | | } | 754 | | } | 755 | | | 756 | 144M | if ( !osl_atomic_decrement( &(pThis->refCount) ) ) | 757 | 121M | { | 758 | 121M | RTL_LOG_STRING_DELETE( pThis ); | 759 | 121M | rtl_freeString( pThis ); | 760 | 121M | } | 761 | 144M | } |
void rtl::str::release<_rtl_uString>(_rtl_uString*) Line | Count | Source | 742 | 15.1G | { | 743 | 15.1G | if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis))) | 744 | 10.8G | return; | 745 | | | 746 | | /* OString doesn't have an 'intern' */ | 747 | | if constexpr (sizeof(Char_T<rtl_tString>) == sizeof(sal_Unicode)) | 748 | 4.33G | { | 749 | 4.33G | if (SAL_STRING_IS_INTERN (pThis)) | 750 | 0 | { | 751 | 0 | internRelease (pThis); | 752 | 0 | return; | 753 | 0 | } | 754 | 4.33G | } | 755 | | | 756 | 4.33G | if ( !osl_atomic_decrement( &(pThis->refCount) ) ) | 757 | 1.32G | { | 758 | 1.32G | RTL_LOG_STRING_DELETE( pThis ); | 759 | 1.32G | rtl_freeString( pThis ); | 760 | 1.32G | } | 761 | 4.33G | } |
|
762 | | |
763 | | /* ----------------------------------------------------------------------- */ |
764 | | |
765 | | /* static data to be referenced by all empty strings |
766 | | * the refCount is predefined to 1 and must never become 0 ! |
767 | | */ |
768 | | template <typename rtl_tString> struct EmptyStringImpl |
769 | | { |
770 | | static rtl_tString data; |
771 | | }; |
772 | | |
773 | | template <> |
774 | | inline rtl_uString EmptyStringImpl<rtl_uString>::data = { |
775 | | sal_Int32(SAL_STRING_INTERN_FLAG | SAL_STRING_STATIC_FLAG | 1), /* sal_Int32 refCount; */ |
776 | | 0, /* sal_Int32 length; */ |
777 | | { 0 } /* sal_Unicode buffer[1]; */ |
778 | | }; |
779 | | |
780 | | template <> |
781 | | inline rtl_String EmptyStringImpl<rtl_String>::data = { |
782 | | SAL_STRING_STATIC_FLAG | 1, /* sal_Int32 refCount; */ |
783 | | 0, /* sal_Int32 length; */ |
784 | | { 0 } /* char buffer[1]; */ |
785 | | }; |
786 | | |
787 | | template <typename rtl_tString> void new_(rtl_tString** ppThis) |
788 | 2.43G | { |
789 | 2.43G | assert(ppThis); |
790 | 2.43G | if ( *ppThis) |
791 | 176M | release( *ppThis ); |
792 | | |
793 | 2.43G | *ppThis = &EmptyStringImpl<rtl_tString>::data; |
794 | 2.43G | } void rtl::str::new_<_rtl_String>(_rtl_String**) Line | Count | Source | 788 | 38.8M | { | 789 | 38.8M | assert(ppThis); | 790 | 38.8M | if ( *ppThis) | 791 | 16.2M | release( *ppThis ); | 792 | | | 793 | 38.8M | *ppThis = &EmptyStringImpl<rtl_tString>::data; | 794 | 38.8M | } |
void rtl::str::new_<_rtl_uString>(_rtl_uString**) Line | Count | Source | 788 | 2.39G | { | 789 | 2.39G | assert(ppThis); | 790 | 2.39G | if ( *ppThis) | 791 | 160M | release( *ppThis ); | 792 | | | 793 | 2.39G | *ppThis = &EmptyStringImpl<rtl_tString>::data; | 794 | 2.39G | } |
|
795 | | |
796 | | /* ----------------------------------------------------------------------- */ |
797 | | |
798 | | template <typename rtl_tString> void new_WithLength(rtl_tString** ppThis, sal_Int32 nLen) |
799 | 367M | { |
800 | 367M | assert(ppThis); |
801 | 367M | assert(nLen >= 0); |
802 | 367M | if ( nLen <= 0 ) |
803 | 12.5M | new_( ppThis ); |
804 | 354M | else |
805 | 354M | { |
806 | 354M | if ( *ppThis) |
807 | 2.09M | release( *ppThis ); |
808 | | |
809 | 354M | *ppThis = Alloc<rtl_tString>( nLen ); |
810 | 354M | assert(*ppThis != nullptr); |
811 | 354M | (*ppThis)->length = 0; |
812 | 354M | (*ppThis)->buffer[0] = 0; |
813 | 354M | } |
814 | 367M | } void rtl::str::new_WithLength<_rtl_String>(_rtl_String**, int) Line | Count | Source | 799 | 18.7M | { | 800 | 18.7M | assert(ppThis); | 801 | 18.7M | assert(nLen >= 0); | 802 | 18.7M | if ( nLen <= 0 ) | 803 | 0 | new_( ppThis ); | 804 | 18.7M | else | 805 | 18.7M | { | 806 | 18.7M | if ( *ppThis) | 807 | 0 | release( *ppThis ); | 808 | | | 809 | 18.7M | *ppThis = Alloc<rtl_tString>( nLen ); | 810 | | assert(*ppThis != nullptr); | 811 | 18.7M | (*ppThis)->length = 0; | 812 | 18.7M | (*ppThis)->buffer[0] = 0; | 813 | 18.7M | } | 814 | 18.7M | } |
void rtl::str::new_WithLength<_rtl_uString>(_rtl_uString**, int) Line | Count | Source | 799 | 348M | { | 800 | 348M | assert(ppThis); | 801 | 348M | assert(nLen >= 0); | 802 | 348M | if ( nLen <= 0 ) | 803 | 12.5M | new_( ppThis ); | 804 | 335M | else | 805 | 335M | { | 806 | 335M | if ( *ppThis) | 807 | 2.09M | release( *ppThis ); | 808 | | | 809 | 335M | *ppThis = Alloc<rtl_tString>( nLen ); | 810 | | assert(*ppThis != nullptr); | 811 | 335M | (*ppThis)->length = 0; | 812 | 335M | (*ppThis)->buffer[0] = 0; | 813 | 335M | } | 814 | 348M | } |
|
815 | | |
816 | | /* ----------------------------------------------------------------------- */ |
817 | | |
818 | | template <typename rtl_tString, typename C> |
819 | | void newFromStr_WithLength(rtl_tString** ppThis, const C* pCharStr, sal_Int32 nLen, |
820 | | sal_Int32 allocExtra = 0) |
821 | 425M | { |
822 | 425M | assert(ppThis); |
823 | 425M | assert(nLen >= 0); |
824 | 425M | assert(pCharStr || nLen == 0); |
825 | 425M | assert(allocExtra >= 0); |
826 | | |
827 | 425M | if (nLen + allocExtra == 0) |
828 | 6.94M | return new_(ppThis); |
829 | | |
830 | 418M | rtl_tString* pOrg = *ppThis; |
831 | 418M | *ppThis = Alloc<rtl_tString>(nLen + allocExtra); |
832 | 418M | assert(*ppThis != nullptr); |
833 | 418M | if (nLen > 0) |
834 | 414M | Copy((*ppThis)->buffer, pCharStr, nLen); |
835 | 418M | if (allocExtra > 0) |
836 | 36.6M | { |
837 | 36.6M | (*ppThis)->length = nLen; |
838 | 36.6M | (*ppThis)->buffer[nLen] = 0; |
839 | 36.6M | } |
840 | | |
841 | 418M | RTL_LOG_STRING_NEW(*ppThis); |
842 | | |
843 | | /* must be done last, if pCharStr belongs to *ppThis */ |
844 | 418M | if (pOrg) |
845 | 75.7M | release(pOrg); |
846 | 418M | } void rtl::str::newFromStr_WithLength<_rtl_String, char>(_rtl_String**, char const*, int, int) Line | Count | Source | 821 | 14.3M | { | 822 | 14.3M | assert(ppThis); | 823 | 14.3M | assert(nLen >= 0); | 824 | 14.3M | assert(pCharStr || nLen == 0); | 825 | 14.3M | assert(allocExtra >= 0); | 826 | | | 827 | 14.3M | if (nLen + allocExtra == 0) | 828 | 162k | return new_(ppThis); | 829 | | | 830 | 14.2M | rtl_tString* pOrg = *ppThis; | 831 | 14.2M | *ppThis = Alloc<rtl_tString>(nLen + allocExtra); | 832 | 14.2M | assert(*ppThis != nullptr); | 833 | 14.2M | if (nLen > 0) | 834 | 14.1M | Copy((*ppThis)->buffer, pCharStr, nLen); | 835 | 14.2M | if (allocExtra > 0) | 836 | 606k | { | 837 | 606k | (*ppThis)->length = nLen; | 838 | 606k | (*ppThis)->buffer[nLen] = 0; | 839 | 606k | } | 840 | | | 841 | 14.2M | RTL_LOG_STRING_NEW(*ppThis); | 842 | | | 843 | | /* must be done last, if pCharStr belongs to *ppThis */ | 844 | 14.2M | if (pOrg) | 845 | 606k | release(pOrg); | 846 | 14.2M | } |
void rtl::str::newFromStr_WithLength<_rtl_uString, char>(_rtl_uString**, char const*, int, int) Line | Count | Source | 821 | 58.8M | { | 822 | 58.8M | assert(ppThis); | 823 | 58.8M | assert(nLen >= 0); | 824 | 58.8M | assert(pCharStr || nLen == 0); | 825 | 58.8M | assert(allocExtra >= 0); | 826 | | | 827 | 58.8M | if (nLen + allocExtra == 0) | 828 | 100 | return new_(ppThis); | 829 | | | 830 | 58.8M | rtl_tString* pOrg = *ppThis; | 831 | 58.8M | *ppThis = Alloc<rtl_tString>(nLen + allocExtra); | 832 | 58.8M | assert(*ppThis != nullptr); | 833 | 58.8M | if (nLen > 0) | 834 | 58.8M | Copy((*ppThis)->buffer, pCharStr, nLen); | 835 | 58.8M | if (allocExtra > 0) | 836 | 427k | { | 837 | 427k | (*ppThis)->length = nLen; | 838 | 427k | (*ppThis)->buffer[nLen] = 0; | 839 | 427k | } | 840 | | | 841 | 58.8M | RTL_LOG_STRING_NEW(*ppThis); | 842 | | | 843 | | /* must be done last, if pCharStr belongs to *ppThis */ | 844 | 58.8M | if (pOrg) | 845 | 32.9M | release(pOrg); | 846 | 58.8M | } |
void rtl::str::newFromStr_WithLength<_rtl_uString, char16_t>(_rtl_uString**, char16_t const*, int, int) Line | Count | Source | 821 | 351M | { | 822 | 351M | assert(ppThis); | 823 | 351M | assert(nLen >= 0); | 824 | 351M | assert(pCharStr || nLen == 0); | 825 | 351M | assert(allocExtra >= 0); | 826 | | | 827 | 351M | if (nLen + allocExtra == 0) | 828 | 6.77M | return new_(ppThis); | 829 | | | 830 | 345M | rtl_tString* pOrg = *ppThis; | 831 | 345M | *ppThis = Alloc<rtl_tString>(nLen + allocExtra); | 832 | 345M | assert(*ppThis != nullptr); | 833 | 345M | if (nLen > 0) | 834 | 341M | Copy((*ppThis)->buffer, pCharStr, nLen); | 835 | 345M | if (allocExtra > 0) | 836 | 35.6M | { | 837 | 35.6M | (*ppThis)->length = nLen; | 838 | 35.6M | (*ppThis)->buffer[nLen] = 0; | 839 | 35.6M | } | 840 | | | 841 | 345M | RTL_LOG_STRING_NEW(*ppThis); | 842 | | | 843 | | /* must be done last, if pCharStr belongs to *ppThis */ | 844 | 345M | if (pOrg) | 845 | 42.1M | release(pOrg); | 846 | 345M | } |
|
847 | | |
848 | | template <typename rtl_tString> void newFromString(rtl_tString** ppThis, const rtl_tString* pStr) |
849 | 294 | { |
850 | 294 | assert(pStr); |
851 | | |
852 | 294 | newFromStr_WithLength(ppThis, pStr->buffer, pStr->length); |
853 | 294 | } Unexecuted instantiation: void rtl::str::newFromString<_rtl_String>(_rtl_String**, _rtl_String const*) void rtl::str::newFromString<_rtl_uString>(_rtl_uString**, _rtl_uString const*) Line | Count | Source | 849 | 294 | { | 850 | 294 | assert(pStr); | 851 | | | 852 | 294 | newFromStr_WithLength(ppThis, pStr->buffer, pStr->length); | 853 | 294 | } |
|
854 | | |
855 | | /* ----------------------------------------------------------------------- */ |
856 | | |
857 | | template <typename rtl_tString> |
858 | | void newFromStr(rtl_tString** ppThis, const Char_T<rtl_tString>* pCharStr) |
859 | 22.2M | { |
860 | 22.2M | newFromStr_WithLength(ppThis, pCharStr, getLength(pCharStr)); |
861 | 22.2M | } _ZN3rtl3str10newFromStrI11_rtl_StringEEvPPT_PKu15__remove_extentIDtsrS3_6bufferEE Line | Count | Source | 859 | 9.34M | { | 860 | 9.34M | newFromStr_WithLength(ppThis, pCharStr, getLength(pCharStr)); | 861 | 9.34M | } |
_ZN3rtl3str10newFromStrI12_rtl_uStringEEvPPT_PKu15__remove_extentIDtsrS3_6bufferEE Line | Count | Source | 859 | 12.9M | { | 860 | 12.9M | newFromStr_WithLength(ppThis, pCharStr, getLength(pCharStr)); | 861 | 12.9M | } |
|
862 | | |
863 | | /* ----------------------------------------------------------------------- */ |
864 | | |
865 | | template <typename rtl_tString> void assign(rtl_tString** ppThis, rtl_tString* pStr) |
866 | 2.24G | { |
867 | 2.24G | assert(ppThis); |
868 | | /* must be done at first, if pStr == *ppThis */ |
869 | 2.24G | acquire( pStr ); |
870 | | |
871 | 2.24G | if ( *ppThis ) |
872 | 2.01G | release( *ppThis ); |
873 | | |
874 | 2.24G | *ppThis = pStr; |
875 | 2.24G | } void rtl::str::assign<_rtl_String>(_rtl_String**, _rtl_String*) Line | Count | Source | 866 | 2.45M | { | 867 | 2.45M | assert(ppThis); | 868 | | /* must be done at first, if pStr == *ppThis */ | 869 | 2.45M | acquire( pStr ); | 870 | | | 871 | 2.45M | if ( *ppThis ) | 872 | 1.46M | release( *ppThis ); | 873 | | | 874 | 2.45M | *ppThis = pStr; | 875 | 2.45M | } |
void rtl::str::assign<_rtl_uString>(_rtl_uString**, _rtl_uString*) Line | Count | Source | 866 | 2.23G | { | 867 | 2.23G | assert(ppThis); | 868 | | /* must be done at first, if pStr == *ppThis */ | 869 | 2.23G | acquire( pStr ); | 870 | | | 871 | 2.23G | if ( *ppThis ) | 872 | 2.01G | release( *ppThis ); | 873 | | | 874 | 2.23G | *ppThis = pStr; | 875 | 2.23G | } |
|
876 | | |
877 | | /* ----------------------------------------------------------------------- */ |
878 | | |
879 | | template <typename rtl_tString> |
880 | | void newFromSubString(rtl_tString** ppThis, const rtl_tString* pFrom, sal_Int32 beginIndex, |
881 | | sal_Int32 count) |
882 | 56.9M | { |
883 | 56.9M | assert(ppThis); |
884 | 56.9M | if ( beginIndex == 0 && count == pFrom->length ) |
885 | 31.4M | return assign(ppThis, const_cast<rtl_tString*>(pFrom)); |
886 | 25.4M | if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length ) |
887 | 13 | { |
888 | 13 | assert(false); // fail fast at least in debug builds |
889 | 13 | return newFromStr_WithLength(ppThis, "!!br0ken!!", 10); |
890 | 13 | } |
891 | | |
892 | 25.4M | newFromStr_WithLength( ppThis, pFrom->buffer + beginIndex, count ); |
893 | 25.4M | } void rtl::str::newFromSubString<_rtl_String>(_rtl_String**, _rtl_String const*, int, int) Line | Count | Source | 882 | 1.72M | { | 883 | 1.72M | assert(ppThis); | 884 | 1.72M | if ( beginIndex == 0 && count == pFrom->length ) | 885 | 988k | return assign(ppThis, const_cast<rtl_tString*>(pFrom)); | 886 | 733k | if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length ) | 887 | 0 | { | 888 | 0 | assert(false); // fail fast at least in debug builds | 889 | 0 | return newFromStr_WithLength(ppThis, "!!br0ken!!", 10); | 890 | 0 | } | 891 | | | 892 | 733k | newFromStr_WithLength( ppThis, pFrom->buffer + beginIndex, count ); | 893 | 733k | } |
void rtl::str::newFromSubString<_rtl_uString>(_rtl_uString**, _rtl_uString const*, int, int) Line | Count | Source | 882 | 55.1M | { | 883 | 55.1M | assert(ppThis); | 884 | 55.1M | if ( beginIndex == 0 && count == pFrom->length ) | 885 | 30.4M | return assign(ppThis, const_cast<rtl_tString*>(pFrom)); | 886 | 24.7M | if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length ) | 887 | 13 | { | 888 | 13 | assert(false); // fail fast at least in debug builds | 889 | 13 | return newFromStr_WithLength(ppThis, "!!br0ken!!", 10); | 890 | 13 | } | 891 | | | 892 | 24.7M | newFromStr_WithLength( ppThis, pFrom->buffer + beginIndex, count ); | 893 | 24.7M | } |
|
894 | | |
895 | | /* ----------------------------------------------------------------------- */ |
896 | | |
897 | | template <typename rtl_tString> auto* getStr(rtl_tString* pThis) |
898 | 121k | { |
899 | 121k | assert(pThis); |
900 | 121k | return pThis->buffer; |
901 | 121k | } auto* rtl::str::getStr<_rtl_String>(_rtl_String*) Line | Count | Source | 898 | 60.6k | { | 899 | | assert(pThis); | 900 | 60.6k | return pThis->buffer; | 901 | 60.6k | } |
auto* rtl::str::getStr<_rtl_uString>(_rtl_uString*) Line | Count | Source | 898 | 60.7k | { | 899 | | assert(pThis); | 900 | 60.7k | return pThis->buffer; | 901 | 60.7k | } |
|
902 | | |
903 | | /* ----------------------------------------------------------------------- */ |
904 | | |
905 | | enum ThrowPolicy { NoThrow, Throw }; |
906 | | |
907 | | template <ThrowPolicy throwPolicy, typename rtl_tString, typename C1, typename C2> |
908 | | void newConcat(rtl_tString** ppThis, const C1* pLeft, sal_Int32 nLeftLength, |
909 | | const C2* pRight, sal_Int32 nRightLength) |
910 | 255M | { |
911 | 255M | assert(ppThis); |
912 | 255M | assert(nLeftLength >= 0); |
913 | 255M | assert(pLeft || nLeftLength == 0); |
914 | 255M | assert(nRightLength >= 0); |
915 | 255M | assert(pRight || nRightLength == 0); |
916 | 255M | rtl_tString* pOrg = *ppThis; |
917 | | |
918 | 255M | if (nLeftLength > std::numeric_limits<sal_Int32>::max() - nRightLength) |
919 | 0 | { |
920 | | if constexpr (throwPolicy == NoThrow) |
921 | 0 | *ppThis = nullptr; |
922 | | else |
923 | 0 | { |
924 | 0 | #if !defined(__COVERITY__) || __COVERITY_MAJOR__ > 2024 |
925 | 0 | throw std::length_error("newConcat"); |
926 | | #else |
927 | | //coverity doesn't report std::bad_alloc as an unhandled exception when |
928 | | //potentially thrown from destructors but does report std::length_error |
929 | | throw std::bad_alloc(); |
930 | | #endif |
931 | 0 | } |
932 | 0 | } |
933 | 255M | else |
934 | 255M | { |
935 | 255M | auto* pTempStr = Alloc<rtl_tString>(nLeftLength + nRightLength); |
936 | 255M | OSL_ASSERT(pTempStr != nullptr); |
937 | 255M | *ppThis = pTempStr; |
938 | 255M | if (*ppThis != nullptr) { |
939 | 255M | if (nLeftLength) |
940 | 252M | Copy( pTempStr->buffer, pLeft, nLeftLength ); |
941 | 255M | if (nRightLength) |
942 | 255M | Copy( pTempStr->buffer+nLeftLength, pRight, nRightLength ); |
943 | | |
944 | 255M | RTL_LOG_STRING_NEW( *ppThis ); |
945 | 255M | } |
946 | 255M | } |
947 | | |
948 | | /* must be done last, if left or right == *ppThis */ |
949 | 255M | if ( pOrg ) |
950 | 22.8M | release( pOrg ); |
951 | 255M | } Unexecuted instantiation: void rtl::str::newConcat<(rtl::str::ThrowPolicy)1, _rtl_String, char, char>(_rtl_String**, char const*, int, char const*, int) void rtl::str::newConcat<(rtl::str::ThrowPolicy)0, _rtl_String, char, char>(_rtl_String**, char const*, int, char const*, int) Line | Count | Source | 910 | 100k | { | 911 | 100k | assert(ppThis); | 912 | 100k | assert(nLeftLength >= 0); | 913 | 100k | assert(pLeft || nLeftLength == 0); | 914 | 100k | assert(nRightLength >= 0); | 915 | 100k | assert(pRight || nRightLength == 0); | 916 | 100k | rtl_tString* pOrg = *ppThis; | 917 | | | 918 | 100k | if (nLeftLength > std::numeric_limits<sal_Int32>::max() - nRightLength) | 919 | 0 | { | 920 | | if constexpr (throwPolicy == NoThrow) | 921 | 0 | *ppThis = nullptr; | 922 | | else | 923 | | { | 924 | | #if !defined(__COVERITY__) || __COVERITY_MAJOR__ > 2024 | 925 | | throw std::length_error("newConcat"); | 926 | | #else | 927 | | //coverity doesn't report std::bad_alloc as an unhandled exception when | 928 | | //potentially thrown from destructors but does report std::length_error | 929 | | throw std::bad_alloc(); | 930 | | #endif | 931 | | } | 932 | 0 | } | 933 | 100k | else | 934 | 100k | { | 935 | 100k | auto* pTempStr = Alloc<rtl_tString>(nLeftLength + nRightLength); | 936 | 100k | OSL_ASSERT(pTempStr != nullptr); | 937 | 100k | *ppThis = pTempStr; | 938 | 100k | if (*ppThis != nullptr) { | 939 | 100k | if (nLeftLength) | 940 | 100k | Copy( pTempStr->buffer, pLeft, nLeftLength ); | 941 | 100k | if (nRightLength) | 942 | 100k | Copy( pTempStr->buffer+nLeftLength, pRight, nRightLength ); | 943 | | | 944 | 100k | RTL_LOG_STRING_NEW( *ppThis ); | 945 | 100k | } | 946 | 100k | } | 947 | | | 948 | | /* must be done last, if left or right == *ppThis */ | 949 | 100k | if ( pOrg ) | 950 | 100k | release( pOrg ); | 951 | 100k | } |
void rtl::str::newConcat<(rtl::str::ThrowPolicy)1, _rtl_uString, char16_t, char>(_rtl_uString**, char16_t const*, int, char const*, int) Line | Count | Source | 910 | 3.41M | { | 911 | 3.41M | assert(ppThis); | 912 | 3.41M | assert(nLeftLength >= 0); | 913 | 3.41M | assert(pLeft || nLeftLength == 0); | 914 | 3.41M | assert(nRightLength >= 0); | 915 | 3.41M | assert(pRight || nRightLength == 0); | 916 | 3.41M | rtl_tString* pOrg = *ppThis; | 917 | | | 918 | 3.41M | if (nLeftLength > std::numeric_limits<sal_Int32>::max() - nRightLength) | 919 | 0 | { | 920 | | if constexpr (throwPolicy == NoThrow) | 921 | | *ppThis = nullptr; | 922 | | else | 923 | 0 | { | 924 | 0 | #if !defined(__COVERITY__) || __COVERITY_MAJOR__ > 2024 | 925 | 0 | throw std::length_error("newConcat"); | 926 | | #else | 927 | | //coverity doesn't report std::bad_alloc as an unhandled exception when | 928 | | //potentially thrown from destructors but does report std::length_error | 929 | | throw std::bad_alloc(); | 930 | | #endif | 931 | 0 | } | 932 | 0 | } | 933 | 3.41M | else | 934 | 3.41M | { | 935 | 3.41M | auto* pTempStr = Alloc<rtl_tString>(nLeftLength + nRightLength); | 936 | 3.41M | OSL_ASSERT(pTempStr != nullptr); | 937 | 3.41M | *ppThis = pTempStr; | 938 | 3.41M | if (*ppThis != nullptr) { | 939 | 3.41M | if (nLeftLength) | 940 | 2.32M | Copy( pTempStr->buffer, pLeft, nLeftLength ); | 941 | 3.41M | if (nRightLength) | 942 | 3.41M | Copy( pTempStr->buffer+nLeftLength, pRight, nRightLength ); | 943 | | | 944 | 3.41M | RTL_LOG_STRING_NEW( *ppThis ); | 945 | 3.41M | } | 946 | 3.41M | } | 947 | | | 948 | | /* must be done last, if left or right == *ppThis */ | 949 | 3.41M | if ( pOrg ) | 950 | 3.41M | release( pOrg ); | 951 | 3.41M | } |
void rtl::str::newConcat<(rtl::str::ThrowPolicy)1, _rtl_uString, char16_t, char16_t>(_rtl_uString**, char16_t const*, int, char16_t const*, int) Line | Count | Source | 910 | 18.2M | { | 911 | 18.2M | assert(ppThis); | 912 | 18.2M | assert(nLeftLength >= 0); | 913 | 18.2M | assert(pLeft || nLeftLength == 0); | 914 | 18.2M | assert(nRightLength >= 0); | 915 | 18.2M | assert(pRight || nRightLength == 0); | 916 | 18.2M | rtl_tString* pOrg = *ppThis; | 917 | | | 918 | 18.2M | if (nLeftLength > std::numeric_limits<sal_Int32>::max() - nRightLength) | 919 | 0 | { | 920 | | if constexpr (throwPolicy == NoThrow) | 921 | | *ppThis = nullptr; | 922 | | else | 923 | 0 | { | 924 | 0 | #if !defined(__COVERITY__) || __COVERITY_MAJOR__ > 2024 | 925 | 0 | throw std::length_error("newConcat"); | 926 | | #else | 927 | | //coverity doesn't report std::bad_alloc as an unhandled exception when | 928 | | //potentially thrown from destructors but does report std::length_error | 929 | | throw std::bad_alloc(); | 930 | | #endif | 931 | 0 | } | 932 | 0 | } | 933 | 18.2M | else | 934 | 18.2M | { | 935 | 18.2M | auto* pTempStr = Alloc<rtl_tString>(nLeftLength + nRightLength); | 936 | 18.2M | OSL_ASSERT(pTempStr != nullptr); | 937 | 18.2M | *ppThis = pTempStr; | 938 | 18.2M | if (*ppThis != nullptr) { | 939 | 18.2M | if (nLeftLength) | 940 | 15.6M | Copy( pTempStr->buffer, pLeft, nLeftLength ); | 941 | 18.2M | if (nRightLength) | 942 | 18.2M | Copy( pTempStr->buffer+nLeftLength, pRight, nRightLength ); | 943 | | | 944 | 18.2M | RTL_LOG_STRING_NEW( *ppThis ); | 945 | 18.2M | } | 946 | 18.2M | } | 947 | | | 948 | | /* must be done last, if left or right == *ppThis */ | 949 | 18.2M | if ( pOrg ) | 950 | 18.2M | release( pOrg ); | 951 | 18.2M | } |
void rtl::str::newConcat<(rtl::str::ThrowPolicy)0, _rtl_uString, char16_t, char16_t>(_rtl_uString**, char16_t const*, int, char16_t const*, int) Line | Count | Source | 910 | 234M | { | 911 | 234M | assert(ppThis); | 912 | 234M | assert(nLeftLength >= 0); | 913 | 234M | assert(pLeft || nLeftLength == 0); | 914 | 234M | assert(nRightLength >= 0); | 915 | 234M | assert(pRight || nRightLength == 0); | 916 | 234M | rtl_tString* pOrg = *ppThis; | 917 | | | 918 | 234M | if (nLeftLength > std::numeric_limits<sal_Int32>::max() - nRightLength) | 919 | 0 | { | 920 | | if constexpr (throwPolicy == NoThrow) | 921 | 0 | *ppThis = nullptr; | 922 | | else | 923 | | { | 924 | | #if !defined(__COVERITY__) || __COVERITY_MAJOR__ > 2024 | 925 | | throw std::length_error("newConcat"); | 926 | | #else | 927 | | //coverity doesn't report std::bad_alloc as an unhandled exception when | 928 | | //potentially thrown from destructors but does report std::length_error | 929 | | throw std::bad_alloc(); | 930 | | #endif | 931 | | } | 932 | 0 | } | 933 | 234M | else | 934 | 234M | { | 935 | 234M | auto* pTempStr = Alloc<rtl_tString>(nLeftLength + nRightLength); | 936 | 234M | OSL_ASSERT(pTempStr != nullptr); | 937 | 234M | *ppThis = pTempStr; | 938 | 234M | if (*ppThis != nullptr) { | 939 | 234M | if (nLeftLength) | 940 | 234M | Copy( pTempStr->buffer, pLeft, nLeftLength ); | 941 | 234M | if (nRightLength) | 942 | 234M | Copy( pTempStr->buffer+nLeftLength, pRight, nRightLength ); | 943 | | | 944 | 234M | RTL_LOG_STRING_NEW( *ppThis ); | 945 | 234M | } | 946 | 234M | } | 947 | | | 948 | | /* must be done last, if left or right == *ppThis */ | 949 | 234M | if ( pOrg ) | 950 | 996k | release( pOrg ); | 951 | 234M | } |
|
952 | | |
953 | | template <typename rtl_tString, typename C> |
954 | | void newConcat(rtl_tString** ppThis, rtl_tString* pLeft, const C* pRight, sal_Int32 nRightLength) |
955 | 22.3M | { |
956 | 22.3M | assert(pLeft != nullptr); |
957 | 22.3M | if (nRightLength == 0) |
958 | 631k | assign(ppThis, pLeft); |
959 | 21.7M | else |
960 | 21.7M | newConcat<Throw>(ppThis, pLeft->buffer, pLeft->length, pRight, nRightLength); |
961 | 22.3M | } Unexecuted instantiation: void rtl::str::newConcat<_rtl_String, char>(_rtl_String**, _rtl_String*, char const*, int) void rtl::str::newConcat<_rtl_uString, char>(_rtl_uString**, _rtl_uString*, char const*, int) Line | Count | Source | 955 | 3.41M | { | 956 | 3.41M | assert(pLeft != nullptr); | 957 | 3.41M | if (nRightLength == 0) | 958 | 0 | assign(ppThis, pLeft); | 959 | 3.41M | else | 960 | 3.41M | newConcat<Throw>(ppThis, pLeft->buffer, pLeft->length, pRight, nRightLength); | 961 | 3.41M | } |
void rtl::str::newConcat<_rtl_uString, char16_t>(_rtl_uString**, _rtl_uString*, char16_t const*, int) Line | Count | Source | 955 | 18.9M | { | 956 | 18.9M | assert(pLeft != nullptr); | 957 | 18.9M | if (nRightLength == 0) | 958 | 631k | assign(ppThis, pLeft); | 959 | 18.2M | else | 960 | 18.2M | newConcat<Throw>(ppThis, pLeft->buffer, pLeft->length, pRight, nRightLength); | 961 | 18.9M | } |
|
962 | | |
963 | | template <typename rtl_tString> |
964 | | void newConcat(rtl_tString** ppThis, rtl_tString* pLeft, rtl_tString* pRight) |
965 | 375M | { |
966 | | /* Test for 0-Pointer - if not, change newReplaceStrAt! */ |
967 | 375M | if ( !pRight || !pRight->length ) |
968 | 72.4M | { |
969 | 72.4M | assert(pLeft != nullptr); |
970 | 72.4M | assign(ppThis, pLeft); |
971 | 72.4M | } |
972 | 303M | else if ( !pLeft || !pLeft->length ) |
973 | 69.1M | assign(ppThis, pRight); |
974 | 234M | else |
975 | 234M | newConcat<NoThrow>(ppThis, pLeft->buffer, pLeft->length, pRight->buffer, pRight->length); |
976 | 375M | } void rtl::str::newConcat<_rtl_String>(_rtl_String**, _rtl_String*, _rtl_String*) Line | Count | Source | 965 | 169k | { | 966 | | /* Test for 0-Pointer - if not, change newReplaceStrAt! */ | 967 | 169k | if ( !pRight || !pRight->length ) | 968 | 18.6k | { | 969 | 18.6k | assert(pLeft != nullptr); | 970 | 18.6k | assign(ppThis, pLeft); | 971 | 18.6k | } | 972 | 151k | else if ( !pLeft || !pLeft->length ) | 973 | 51.1k | assign(ppThis, pRight); | 974 | 100k | else | 975 | 100k | newConcat<NoThrow>(ppThis, pLeft->buffer, pLeft->length, pRight->buffer, pRight->length); | 976 | 169k | } |
void rtl::str::newConcat<_rtl_uString>(_rtl_uString**, _rtl_uString*, _rtl_uString*) Line | Count | Source | 965 | 375M | { | 966 | | /* Test for 0-Pointer - if not, change newReplaceStrAt! */ | 967 | 375M | if ( !pRight || !pRight->length ) | 968 | 72.4M | { | 969 | 72.4M | assert(pLeft != nullptr); | 970 | 72.4M | assign(ppThis, pLeft); | 971 | 72.4M | } | 972 | 303M | else if ( !pLeft || !pLeft->length ) | 973 | 69.1M | assign(ppThis, pRight); | 974 | 234M | else | 975 | 234M | newConcat<NoThrow>(ppThis, pLeft->buffer, pLeft->length, pRight->buffer, pRight->length); | 976 | 375M | } |
|
977 | | |
978 | | /* ----------------------------------------------------------------------- */ |
979 | | |
980 | | template <typename rtl_tString> void ensureCapacity(rtl_tString** ppThis, sal_Int32 size) |
981 | 10.9M | { |
982 | 10.9M | assert(ppThis); |
983 | 10.9M | rtl_tString* const pOrg = *ppThis; |
984 | 10.9M | if ( pOrg->refCount == 1 && pOrg->length >= size ) |
985 | 0 | return; |
986 | 10.9M | assert( pOrg->length <= size ); // do not truncate |
987 | 10.9M | auto* pTempStr = Alloc<rtl_tString>( size ); |
988 | 10.9M | Copy( pTempStr->buffer, pOrg->buffer, pOrg->length ); |
989 | | // right now the length is still the same as of the original |
990 | 10.9M | pTempStr->length = pOrg->length; |
991 | 10.9M | pTempStr->buffer[ pOrg->length ] = '\0'; |
992 | 10.9M | *ppThis = pTempStr; |
993 | 10.9M | RTL_LOG_STRING_NEW( *ppThis ); |
994 | | |
995 | 10.9M | release( pOrg ); |
996 | 10.9M | } void rtl::str::ensureCapacity<_rtl_String>(_rtl_String**, int) Line | Count | Source | 981 | 3.22M | { | 982 | 3.22M | assert(ppThis); | 983 | 3.22M | rtl_tString* const pOrg = *ppThis; | 984 | 3.22M | if ( pOrg->refCount == 1 && pOrg->length >= size ) | 985 | 0 | return; | 986 | 3.22M | assert( pOrg->length <= size ); // do not truncate | 987 | 3.22M | auto* pTempStr = Alloc<rtl_tString>( size ); | 988 | 3.22M | Copy( pTempStr->buffer, pOrg->buffer, pOrg->length ); | 989 | | // right now the length is still the same as of the original | 990 | 3.22M | pTempStr->length = pOrg->length; | 991 | 3.22M | pTempStr->buffer[ pOrg->length ] = '\0'; | 992 | 3.22M | *ppThis = pTempStr; | 993 | 3.22M | RTL_LOG_STRING_NEW( *ppThis ); | 994 | | | 995 | 3.22M | release( pOrg ); | 996 | 3.22M | } |
void rtl::str::ensureCapacity<_rtl_uString>(_rtl_uString**, int) Line | Count | Source | 981 | 7.72M | { | 982 | 7.72M | assert(ppThis); | 983 | 7.72M | rtl_tString* const pOrg = *ppThis; | 984 | 7.72M | if ( pOrg->refCount == 1 && pOrg->length >= size ) | 985 | 0 | return; | 986 | 7.72M | assert( pOrg->length <= size ); // do not truncate | 987 | 7.72M | auto* pTempStr = Alloc<rtl_tString>( size ); | 988 | 7.72M | Copy( pTempStr->buffer, pOrg->buffer, pOrg->length ); | 989 | | // right now the length is still the same as of the original | 990 | 7.72M | pTempStr->length = pOrg->length; | 991 | 7.72M | pTempStr->buffer[ pOrg->length ] = '\0'; | 992 | 7.72M | *ppThis = pTempStr; | 993 | 7.72M | RTL_LOG_STRING_NEW( *ppThis ); | 994 | | | 995 | 7.72M | release( pOrg ); | 996 | 7.72M | } |
|
997 | | |
998 | | /* ----------------------------------------------------------------------- */ |
999 | | |
1000 | | template <typename rtl_tString, typename C> |
1001 | | void newReplaceStrAt(rtl_tString** ppThis, rtl_tString* pStr, sal_Int32 nIndex, sal_Int32 nCount, |
1002 | | const C* pNewSubStr, sal_Int32 nNewSubStrLen) |
1003 | 8.67M | { |
1004 | 8.67M | assert(ppThis); |
1005 | 8.67M | assert(nIndex >= 0 && nIndex <= pStr->length); |
1006 | 8.67M | assert(nCount >= 0); |
1007 | 8.67M | assert(nCount <= pStr->length - nIndex); |
1008 | 8.67M | assert(pNewSubStr != nullptr || nNewSubStrLen == 0); |
1009 | 8.67M | assert(nNewSubStrLen >= 0); |
1010 | | /* Append? */ |
1011 | 8.67M | if ( nIndex >= pStr->length ) |
1012 | 44.5k | return newConcat(ppThis, pStr, pNewSubStr, nNewSubStrLen); |
1013 | | |
1014 | | /* not more than the String length could be deleted */ |
1015 | 8.63M | if ( nCount >= pStr->length-nIndex ) |
1016 | 4.52M | { |
1017 | | /* Assign of NewSubStr? */ |
1018 | 4.52M | if (nIndex == 0) |
1019 | 1.56M | return newFromStr_WithLength( ppThis, pNewSubStr, nNewSubStrLen ); |
1020 | | |
1021 | 2.95M | nCount = pStr->length - nIndex; |
1022 | 2.95M | } |
1023 | | |
1024 | | /* Assign of Str? */ |
1025 | 7.06M | if ( !nCount && !nNewSubStrLen ) |
1026 | 3.23k | return assign(ppThis, pStr); |
1027 | | |
1028 | 7.06M | rtl_tString* pOrg = *ppThis; |
1029 | | |
1030 | | /* Alloc New Buffer */ |
1031 | 7.06M | *ppThis = Alloc<rtl_tString>(pStr->length - nCount + nNewSubStrLen); |
1032 | 7.06M | assert(*ppThis != nullptr); |
1033 | 7.06M | auto* pBuffer = (*ppThis)->buffer; |
1034 | 7.06M | if ( nIndex ) |
1035 | 6.17M | { |
1036 | 6.17M | Copy( pBuffer, pStr->buffer, nIndex ); |
1037 | 6.17M | pBuffer += nIndex; |
1038 | 6.17M | } |
1039 | 7.06M | if ( nNewSubStrLen ) |
1040 | 6.51M | { |
1041 | 6.51M | Copy( pBuffer, pNewSubStr, nNewSubStrLen ); |
1042 | 6.51M | pBuffer += nNewSubStrLen; |
1043 | 6.51M | } |
1044 | 7.06M | Copy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount ); |
1045 | | |
1046 | 7.06M | RTL_LOG_STRING_NEW( *ppThis ); |
1047 | | /* must be done last, if pStr or pNewSubStr == *ppThis */ |
1048 | 7.06M | if ( pOrg ) |
1049 | 0 | release( pOrg ); |
1050 | 7.06M | } void rtl::str::newReplaceStrAt<_rtl_String, char>(_rtl_String**, _rtl_String*, int, int, char const*, int) Line | Count | Source | 1003 | 5.45k | { | 1004 | 5.45k | assert(ppThis); | 1005 | 5.45k | assert(nIndex >= 0 && nIndex <= pStr->length); | 1006 | 5.45k | assert(nCount >= 0); | 1007 | 5.45k | assert(nCount <= pStr->length - nIndex); | 1008 | 5.45k | assert(pNewSubStr != nullptr || nNewSubStrLen == 0); | 1009 | 5.45k | assert(nNewSubStrLen >= 0); | 1010 | | /* Append? */ | 1011 | 5.45k | if ( nIndex >= pStr->length ) | 1012 | 0 | return newConcat(ppThis, pStr, pNewSubStr, nNewSubStrLen); | 1013 | | | 1014 | | /* not more than the String length could be deleted */ | 1015 | 5.45k | if ( nCount >= pStr->length-nIndex ) | 1016 | 0 | { | 1017 | | /* Assign of NewSubStr? */ | 1018 | 0 | if (nIndex == 0) | 1019 | 0 | return newFromStr_WithLength( ppThis, pNewSubStr, nNewSubStrLen ); | 1020 | | | 1021 | 0 | nCount = pStr->length - nIndex; | 1022 | 0 | } | 1023 | | | 1024 | | /* Assign of Str? */ | 1025 | 5.45k | if ( !nCount && !nNewSubStrLen ) | 1026 | 0 | return assign(ppThis, pStr); | 1027 | | | 1028 | 5.45k | rtl_tString* pOrg = *ppThis; | 1029 | | | 1030 | | /* Alloc New Buffer */ | 1031 | 5.45k | *ppThis = Alloc<rtl_tString>(pStr->length - nCount + nNewSubStrLen); | 1032 | 5.45k | assert(*ppThis != nullptr); | 1033 | 5.45k | auto* pBuffer = (*ppThis)->buffer; | 1034 | 5.45k | if ( nIndex ) | 1035 | 5.45k | { | 1036 | 5.45k | Copy( pBuffer, pStr->buffer, nIndex ); | 1037 | 5.45k | pBuffer += nIndex; | 1038 | 5.45k | } | 1039 | 5.45k | if ( nNewSubStrLen ) | 1040 | 5.45k | { | 1041 | 5.45k | Copy( pBuffer, pNewSubStr, nNewSubStrLen ); | 1042 | 5.45k | pBuffer += nNewSubStrLen; | 1043 | 5.45k | } | 1044 | 5.45k | Copy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount ); | 1045 | | | 1046 | 5.45k | RTL_LOG_STRING_NEW( *ppThis ); | 1047 | | /* must be done last, if pStr or pNewSubStr == *ppThis */ | 1048 | 5.45k | if ( pOrg ) | 1049 | 0 | release( pOrg ); | 1050 | 5.45k | } |
void rtl::str::newReplaceStrAt<_rtl_uString, char>(_rtl_uString**, _rtl_uString*, int, int, char const*, int) Line | Count | Source | 1003 | 1.37k | { | 1004 | 1.37k | assert(ppThis); | 1005 | 1.37k | assert(nIndex >= 0 && nIndex <= pStr->length); | 1006 | 1.37k | assert(nCount >= 0); | 1007 | 1.37k | assert(nCount <= pStr->length - nIndex); | 1008 | 1.37k | assert(pNewSubStr != nullptr || nNewSubStrLen == 0); | 1009 | 1.37k | assert(nNewSubStrLen >= 0); | 1010 | | /* Append? */ | 1011 | 1.37k | if ( nIndex >= pStr->length ) | 1012 | 0 | return newConcat(ppThis, pStr, pNewSubStr, nNewSubStrLen); | 1013 | | | 1014 | | /* not more than the String length could be deleted */ | 1015 | 1.37k | if ( nCount >= pStr->length-nIndex ) | 1016 | 479 | { | 1017 | | /* Assign of NewSubStr? */ | 1018 | 479 | if (nIndex == 0) | 1019 | 0 | return newFromStr_WithLength( ppThis, pNewSubStr, nNewSubStrLen ); | 1020 | | | 1021 | 479 | nCount = pStr->length - nIndex; | 1022 | 479 | } | 1023 | | | 1024 | | /* Assign of Str? */ | 1025 | 1.37k | if ( !nCount && !nNewSubStrLen ) | 1026 | 0 | return assign(ppThis, pStr); | 1027 | | | 1028 | 1.37k | rtl_tString* pOrg = *ppThis; | 1029 | | | 1030 | | /* Alloc New Buffer */ | 1031 | 1.37k | *ppThis = Alloc<rtl_tString>(pStr->length - nCount + nNewSubStrLen); | 1032 | 1.37k | assert(*ppThis != nullptr); | 1033 | 1.37k | auto* pBuffer = (*ppThis)->buffer; | 1034 | 1.37k | if ( nIndex ) | 1035 | 1.37k | { | 1036 | 1.37k | Copy( pBuffer, pStr->buffer, nIndex ); | 1037 | 1.37k | pBuffer += nIndex; | 1038 | 1.37k | } | 1039 | 1.37k | if ( nNewSubStrLen ) | 1040 | 1.37k | { | 1041 | 1.37k | Copy( pBuffer, pNewSubStr, nNewSubStrLen ); | 1042 | 1.37k | pBuffer += nNewSubStrLen; | 1043 | 1.37k | } | 1044 | 1.37k | Copy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount ); | 1045 | | | 1046 | 1.37k | RTL_LOG_STRING_NEW( *ppThis ); | 1047 | | /* must be done last, if pStr or pNewSubStr == *ppThis */ | 1048 | 1.37k | if ( pOrg ) | 1049 | 0 | release( pOrg ); | 1050 | 1.37k | } |
void rtl::str::newReplaceStrAt<_rtl_uString, char16_t>(_rtl_uString**, _rtl_uString*, int, int, char16_t const*, int) Line | Count | Source | 1003 | 8.66M | { | 1004 | 8.66M | assert(ppThis); | 1005 | 8.66M | assert(nIndex >= 0 && nIndex <= pStr->length); | 1006 | 8.66M | assert(nCount >= 0); | 1007 | 8.66M | assert(nCount <= pStr->length - nIndex); | 1008 | 8.66M | assert(pNewSubStr != nullptr || nNewSubStrLen == 0); | 1009 | 8.66M | assert(nNewSubStrLen >= 0); | 1010 | | /* Append? */ | 1011 | 8.66M | if ( nIndex >= pStr->length ) | 1012 | 44.5k | return newConcat(ppThis, pStr, pNewSubStr, nNewSubStrLen); | 1013 | | | 1014 | | /* not more than the String length could be deleted */ | 1015 | 8.62M | if ( nCount >= pStr->length-nIndex ) | 1016 | 4.52M | { | 1017 | | /* Assign of NewSubStr? */ | 1018 | 4.52M | if (nIndex == 0) | 1019 | 1.56M | return newFromStr_WithLength( ppThis, pNewSubStr, nNewSubStrLen ); | 1020 | | | 1021 | 2.95M | nCount = pStr->length - nIndex; | 1022 | 2.95M | } | 1023 | | | 1024 | | /* Assign of Str? */ | 1025 | 7.05M | if ( !nCount && !nNewSubStrLen ) | 1026 | 3.23k | return assign(ppThis, pStr); | 1027 | | | 1028 | 7.05M | rtl_tString* pOrg = *ppThis; | 1029 | | | 1030 | | /* Alloc New Buffer */ | 1031 | 7.05M | *ppThis = Alloc<rtl_tString>(pStr->length - nCount + nNewSubStrLen); | 1032 | 7.05M | assert(*ppThis != nullptr); | 1033 | 7.05M | auto* pBuffer = (*ppThis)->buffer; | 1034 | 7.05M | if ( nIndex ) | 1035 | 6.16M | { | 1036 | 6.16M | Copy( pBuffer, pStr->buffer, nIndex ); | 1037 | 6.16M | pBuffer += nIndex; | 1038 | 6.16M | } | 1039 | 7.05M | if ( nNewSubStrLen ) | 1040 | 6.50M | { | 1041 | 6.50M | Copy( pBuffer, pNewSubStr, nNewSubStrLen ); | 1042 | 6.50M | pBuffer += nNewSubStrLen; | 1043 | 6.50M | } | 1044 | 7.05M | Copy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount ); | 1045 | | | 1046 | 7.05M | RTL_LOG_STRING_NEW( *ppThis ); | 1047 | | /* must be done last, if pStr or pNewSubStr == *ppThis */ | 1048 | 7.05M | if ( pOrg ) | 1049 | 0 | release( pOrg ); | 1050 | 7.05M | } |
|
1051 | | |
1052 | | /* ----------------------------------------------------------------------- */ |
1053 | | |
1054 | | template <typename rtl_tString> |
1055 | | void newReplaceStrAt(rtl_tString** ppThis, rtl_tString* pStr, sal_Int32 nIndex, sal_Int32 nCount, |
1056 | | rtl_tString* pNewSubStr) |
1057 | 46.9M | { |
1058 | 46.9M | assert(ppThis); |
1059 | 46.9M | assert(nIndex >= 0 && nIndex <= pStr->length); |
1060 | 46.9M | assert(nCount >= 0); |
1061 | 46.9M | assert(nCount <= pStr->length - nIndex); |
1062 | | /* Append? */ |
1063 | 46.9M | if (nIndex >= pStr->length) |
1064 | 41.0M | { |
1065 | | /* newConcat test, if pNewSubStr is 0 */ |
1066 | 41.0M | newConcat(ppThis, pStr, pNewSubStr); |
1067 | 41.0M | return; |
1068 | 41.0M | } |
1069 | | |
1070 | | /* not more than the String length could be deleted */ |
1071 | 5.90M | if (nCount >= pStr->length-nIndex) |
1072 | 5.13M | { |
1073 | | /* Assign of NewSubStr? */ |
1074 | 5.13M | if (nIndex == 0) |
1075 | 2.56M | { |
1076 | 2.56M | if (!pNewSubStr) |
1077 | 0 | return new_(ppThis); |
1078 | 2.56M | else |
1079 | 2.56M | return assign(ppThis, pNewSubStr); |
1080 | 2.56M | } |
1081 | 2.57M | nCount = pStr->length - nIndex; |
1082 | 2.57M | } |
1083 | | |
1084 | 3.34M | const auto* pNewSubStrBuf = pNewSubStr ? pNewSubStr->buffer : nullptr; |
1085 | 3.34M | const sal_Int32 nNewSubStrLength = pNewSubStr ? pNewSubStr->length : 0; |
1086 | 3.34M | newReplaceStrAt(ppThis, pStr, nIndex, nCount, pNewSubStrBuf, nNewSubStrLength); |
1087 | 3.34M | } Unexecuted instantiation: void rtl::str::newReplaceStrAt<_rtl_String>(_rtl_String**, _rtl_String*, int, int, _rtl_String*) void rtl::str::newReplaceStrAt<_rtl_uString>(_rtl_uString**, _rtl_uString*, int, int, _rtl_uString*) Line | Count | Source | 1057 | 46.9M | { | 1058 | 46.9M | assert(ppThis); | 1059 | 46.9M | assert(nIndex >= 0 && nIndex <= pStr->length); | 1060 | 46.9M | assert(nCount >= 0); | 1061 | 46.9M | assert(nCount <= pStr->length - nIndex); | 1062 | | /* Append? */ | 1063 | 46.9M | if (nIndex >= pStr->length) | 1064 | 41.0M | { | 1065 | | /* newConcat test, if pNewSubStr is 0 */ | 1066 | 41.0M | newConcat(ppThis, pStr, pNewSubStr); | 1067 | 41.0M | return; | 1068 | 41.0M | } | 1069 | | | 1070 | | /* not more than the String length could be deleted */ | 1071 | 5.90M | if (nCount >= pStr->length-nIndex) | 1072 | 5.13M | { | 1073 | | /* Assign of NewSubStr? */ | 1074 | 5.13M | if (nIndex == 0) | 1075 | 2.56M | { | 1076 | 2.56M | if (!pNewSubStr) | 1077 | 0 | return new_(ppThis); | 1078 | 2.56M | else | 1079 | 2.56M | return assign(ppThis, pNewSubStr); | 1080 | 2.56M | } | 1081 | 2.57M | nCount = pStr->length - nIndex; | 1082 | 2.57M | } | 1083 | | | 1084 | 3.34M | const auto* pNewSubStrBuf = pNewSubStr ? pNewSubStr->buffer : nullptr; | 1085 | 3.34M | const sal_Int32 nNewSubStrLength = pNewSubStr ? pNewSubStr->length : 0; | 1086 | 3.34M | newReplaceStrAt(ppThis, pStr, nIndex, nCount, pNewSubStrBuf, nNewSubStrLength); | 1087 | 3.34M | } |
|
1088 | | |
1089 | | /* ----------------------------------------------------------------------- */ |
1090 | | |
1091 | | template <typename rtl_tString, class Replacer> |
1092 | | void newReplaceChars(rtl_tString** ppThis, rtl_tString* pStr, Replacer replacer) |
1093 | 16.2M | { |
1094 | 16.2M | assert(ppThis); |
1095 | 16.2M | assert(pStr); |
1096 | | |
1097 | 16.2M | const auto pEnd = pStr->buffer + pStr->length; |
1098 | 16.2M | auto pCharStr = std::find_if(pStr->buffer, pEnd, replacer.Applicable()); |
1099 | 16.2M | if (pCharStr != pEnd) |
1100 | 6.59M | { |
1101 | 6.59M | rtl_tString* pOrg = *ppThis; |
1102 | 6.59M | *ppThis = Alloc<rtl_tString>(pStr->length); |
1103 | 6.59M | assert(*ppThis != nullptr); |
1104 | 6.59M | auto* pNewCharStr = (*ppThis)->buffer; |
1105 | | /* Copy String */ |
1106 | 6.59M | const sal_Int32 nCount = pCharStr - pStr->buffer; |
1107 | 6.59M | Copy(pNewCharStr, pStr->buffer, nCount); |
1108 | 6.59M | pNewCharStr += nCount; |
1109 | | /* replace/copy rest of the string */ |
1110 | 6.59M | do |
1111 | 92.5M | { |
1112 | 92.5M | *pNewCharStr = replacer.Replace(*pCharStr); |
1113 | 92.5M | pNewCharStr++; |
1114 | 92.5M | pCharStr++; |
1115 | 92.5M | } while (pCharStr != pEnd); |
1116 | | |
1117 | 6.59M | RTL_LOG_STRING_NEW(*ppThis); |
1118 | | /* must be done last, if pStr == *ppThis */ |
1119 | 6.59M | if (pOrg) |
1120 | 0 | release(pOrg); |
1121 | 6.59M | } |
1122 | 9.61M | else |
1123 | 9.61M | assign(ppThis, pStr); |
1124 | 16.2M | } Unexecuted instantiation: void rtl::str::newReplaceChars<_rtl_String, rtl::str::FromTo<char> >(_rtl_String**, _rtl_String*, rtl::str::FromTo<char>) void rtl::str::newReplaceChars<_rtl_String, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)> >(_rtl_String**, _rtl_String*, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>) Line | Count | Source | 1093 | 14.2k | { | 1094 | 14.2k | assert(ppThis); | 1095 | 14.2k | assert(pStr); | 1096 | | | 1097 | 14.2k | const auto pEnd = pStr->buffer + pStr->length; | 1098 | 14.2k | auto pCharStr = std::find_if(pStr->buffer, pEnd, replacer.Applicable()); | 1099 | 14.2k | if (pCharStr != pEnd) | 1100 | 14.2k | { | 1101 | 14.2k | rtl_tString* pOrg = *ppThis; | 1102 | 14.2k | *ppThis = Alloc<rtl_tString>(pStr->length); | 1103 | 14.2k | assert(*ppThis != nullptr); | 1104 | 14.2k | auto* pNewCharStr = (*ppThis)->buffer; | 1105 | | /* Copy String */ | 1106 | 14.2k | const sal_Int32 nCount = pCharStr - pStr->buffer; | 1107 | 14.2k | Copy(pNewCharStr, pStr->buffer, nCount); | 1108 | 14.2k | pNewCharStr += nCount; | 1109 | | /* replace/copy rest of the string */ | 1110 | 14.2k | do | 1111 | 68.5k | { | 1112 | 68.5k | *pNewCharStr = replacer.Replace(*pCharStr); | 1113 | 68.5k | pNewCharStr++; | 1114 | 68.5k | pCharStr++; | 1115 | 68.5k | } while (pCharStr != pEnd); | 1116 | | | 1117 | 14.2k | RTL_LOG_STRING_NEW(*ppThis); | 1118 | | /* must be done last, if pStr == *ppThis */ | 1119 | 14.2k | if (pOrg) | 1120 | 0 | release(pOrg); | 1121 | 14.2k | } | 1122 | 32 | else | 1123 | 32 | assign(ppThis, pStr); | 1124 | 14.2k | } |
void rtl::str::newReplaceChars<_rtl_String, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)> >(_rtl_String**, _rtl_String*, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>) Line | Count | Source | 1093 | 80 | { | 1094 | 80 | assert(ppThis); | 1095 | 80 | assert(pStr); | 1096 | | | 1097 | 80 | const auto pEnd = pStr->buffer + pStr->length; | 1098 | 80 | auto pCharStr = std::find_if(pStr->buffer, pEnd, replacer.Applicable()); | 1099 | 80 | if (pCharStr != pEnd) | 1100 | 80 | { | 1101 | 80 | rtl_tString* pOrg = *ppThis; | 1102 | 80 | *ppThis = Alloc<rtl_tString>(pStr->length); | 1103 | 80 | assert(*ppThis != nullptr); | 1104 | 80 | auto* pNewCharStr = (*ppThis)->buffer; | 1105 | | /* Copy String */ | 1106 | 80 | const sal_Int32 nCount = pCharStr - pStr->buffer; | 1107 | 80 | Copy(pNewCharStr, pStr->buffer, nCount); | 1108 | 80 | pNewCharStr += nCount; | 1109 | | /* replace/copy rest of the string */ | 1110 | 80 | do | 1111 | 80 | { | 1112 | 80 | *pNewCharStr = replacer.Replace(*pCharStr); | 1113 | 80 | pNewCharStr++; | 1114 | 80 | pCharStr++; | 1115 | 80 | } while (pCharStr != pEnd); | 1116 | | | 1117 | 80 | RTL_LOG_STRING_NEW(*ppThis); | 1118 | | /* must be done last, if pStr == *ppThis */ | 1119 | 80 | if (pOrg) | 1120 | 0 | release(pOrg); | 1121 | 80 | } | 1122 | 0 | else | 1123 | 0 | assign(ppThis, pStr); | 1124 | 80 | } |
void rtl::str::newReplaceChars<_rtl_uString, rtl::str::FromTo<char16_t> >(_rtl_uString**, _rtl_uString*, rtl::str::FromTo<char16_t>) Line | Count | Source | 1093 | 530k | { | 1094 | 530k | assert(ppThis); | 1095 | 530k | assert(pStr); | 1096 | | | 1097 | 530k | const auto pEnd = pStr->buffer + pStr->length; | 1098 | 530k | auto pCharStr = std::find_if(pStr->buffer, pEnd, replacer.Applicable()); | 1099 | 530k | if (pCharStr != pEnd) | 1100 | 330k | { | 1101 | 330k | rtl_tString* pOrg = *ppThis; | 1102 | 330k | *ppThis = Alloc<rtl_tString>(pStr->length); | 1103 | 330k | assert(*ppThis != nullptr); | 1104 | 330k | auto* pNewCharStr = (*ppThis)->buffer; | 1105 | | /* Copy String */ | 1106 | 330k | const sal_Int32 nCount = pCharStr - pStr->buffer; | 1107 | 330k | Copy(pNewCharStr, pStr->buffer, nCount); | 1108 | 330k | pNewCharStr += nCount; | 1109 | | /* replace/copy rest of the string */ | 1110 | 330k | do | 1111 | 10.8M | { | 1112 | 10.8M | *pNewCharStr = replacer.Replace(*pCharStr); | 1113 | 10.8M | pNewCharStr++; | 1114 | 10.8M | pCharStr++; | 1115 | 10.8M | } while (pCharStr != pEnd); | 1116 | | | 1117 | 330k | RTL_LOG_STRING_NEW(*ppThis); | 1118 | | /* must be done last, if pStr == *ppThis */ | 1119 | 330k | if (pOrg) | 1120 | 0 | release(pOrg); | 1121 | 330k | } | 1122 | 199k | else | 1123 | 199k | assign(ppThis, pStr); | 1124 | 530k | } |
void rtl::str::newReplaceChars<_rtl_uString, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)> >(_rtl_uString**, _rtl_uString*, rtl::str::CaseReplace<rtl::isAsciiUpperCase(unsigned int), rtl::toAsciiLowerCase(unsigned int)>) Line | Count | Source | 1093 | 9.18M | { | 1094 | 9.18M | assert(ppThis); | 1095 | 9.18M | assert(pStr); | 1096 | | | 1097 | 9.18M | const auto pEnd = pStr->buffer + pStr->length; | 1098 | 9.18M | auto pCharStr = std::find_if(pStr->buffer, pEnd, replacer.Applicable()); | 1099 | 9.18M | if (pCharStr != pEnd) | 1100 | 4.39M | { | 1101 | 4.39M | rtl_tString* pOrg = *ppThis; | 1102 | 4.39M | *ppThis = Alloc<rtl_tString>(pStr->length); | 1103 | 4.39M | assert(*ppThis != nullptr); | 1104 | 4.39M | auto* pNewCharStr = (*ppThis)->buffer; | 1105 | | /* Copy String */ | 1106 | 4.39M | const sal_Int32 nCount = pCharStr - pStr->buffer; | 1107 | 4.39M | Copy(pNewCharStr, pStr->buffer, nCount); | 1108 | 4.39M | pNewCharStr += nCount; | 1109 | | /* replace/copy rest of the string */ | 1110 | 4.39M | do | 1111 | 53.3M | { | 1112 | 53.3M | *pNewCharStr = replacer.Replace(*pCharStr); | 1113 | 53.3M | pNewCharStr++; | 1114 | 53.3M | pCharStr++; | 1115 | 53.3M | } while (pCharStr != pEnd); | 1116 | | | 1117 | 4.39M | RTL_LOG_STRING_NEW(*ppThis); | 1118 | | /* must be done last, if pStr == *ppThis */ | 1119 | 4.39M | if (pOrg) | 1120 | 0 | release(pOrg); | 1121 | 4.39M | } | 1122 | 4.78M | else | 1123 | 4.78M | assign(ppThis, pStr); | 1124 | 9.18M | } |
void rtl::str::newReplaceChars<_rtl_uString, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)> >(_rtl_uString**, _rtl_uString*, rtl::str::CaseReplace<rtl::isAsciiLowerCase(unsigned int), rtl::toAsciiUpperCase(unsigned int)>) Line | Count | Source | 1093 | 6.48M | { | 1094 | 6.48M | assert(ppThis); | 1095 | 6.48M | assert(pStr); | 1096 | | | 1097 | 6.48M | const auto pEnd = pStr->buffer + pStr->length; | 1098 | 6.48M | auto pCharStr = std::find_if(pStr->buffer, pEnd, replacer.Applicable()); | 1099 | 6.48M | if (pCharStr != pEnd) | 1100 | 1.85M | { | 1101 | 1.85M | rtl_tString* pOrg = *ppThis; | 1102 | 1.85M | *ppThis = Alloc<rtl_tString>(pStr->length); | 1103 | 1.85M | assert(*ppThis != nullptr); | 1104 | 1.85M | auto* pNewCharStr = (*ppThis)->buffer; | 1105 | | /* Copy String */ | 1106 | 1.85M | const sal_Int32 nCount = pCharStr - pStr->buffer; | 1107 | 1.85M | Copy(pNewCharStr, pStr->buffer, nCount); | 1108 | 1.85M | pNewCharStr += nCount; | 1109 | | /* replace/copy rest of the string */ | 1110 | 1.85M | do | 1111 | 28.2M | { | 1112 | 28.2M | *pNewCharStr = replacer.Replace(*pCharStr); | 1113 | 28.2M | pNewCharStr++; | 1114 | 28.2M | pCharStr++; | 1115 | 28.2M | } while (pCharStr != pEnd); | 1116 | | | 1117 | 1.85M | RTL_LOG_STRING_NEW(*ppThis); | 1118 | | /* must be done last, if pStr == *ppThis */ | 1119 | 1.85M | if (pOrg) | 1120 | 0 | release(pOrg); | 1121 | 1.85M | } | 1122 | 4.63M | else | 1123 | 4.63M | assign(ppThis, pStr); | 1124 | 6.48M | } |
|
1125 | | |
1126 | | /* ----------------------------------------------------------------------- */ |
1127 | | |
1128 | | template <typename rtl_tString> void newTrim(rtl_tString** ppThis, rtl_tString* pStr) |
1129 | 1.17M | { |
1130 | 1.17M | assert(pStr); |
1131 | 1.17M | const auto view = o3tl::trim(std::basic_string_view(pStr->buffer, pStr->length)); |
1132 | | |
1133 | 1.17M | if (static_cast<sal_Int32>(view.size()) == pStr->length) |
1134 | 363k | assign(ppThis, pStr); |
1135 | 810k | else |
1136 | 810k | newFromStr_WithLength(ppThis, view.data(), view.size()); |
1137 | 1.17M | } Unexecuted instantiation: void rtl::str::newTrim<_rtl_String>(_rtl_String**, _rtl_String*) void rtl::str::newTrim<_rtl_uString>(_rtl_uString**, _rtl_uString*) Line | Count | Source | 1129 | 1.17M | { | 1130 | 1.17M | assert(pStr); | 1131 | 1.17M | const auto view = o3tl::trim(std::basic_string_view(pStr->buffer, pStr->length)); | 1132 | | | 1133 | 1.17M | if (static_cast<sal_Int32>(view.size()) == pStr->length) | 1134 | 363k | assign(ppThis, pStr); | 1135 | 810k | else | 1136 | 810k | newFromStr_WithLength(ppThis, view.data(), view.size()); | 1137 | 1.17M | } |
|
1138 | | |
1139 | | /* ----------------------------------------------------------------------- */ |
1140 | | |
1141 | | template <typename rtl_tString> |
1142 | | sal_Int32 getToken(rtl_tString** ppThis, rtl_tString* pStr, sal_Int32 nToken, |
1143 | | Char_T<rtl_tString> cTok, sal_Int32 nIndex) |
1144 | 8.33M | { |
1145 | 8.33M | assert(ppThis); |
1146 | 8.33M | assert(pStr); |
1147 | 8.33M | assert(nIndex <= pStr->length); |
1148 | | |
1149 | | // Set ppThis to an empty string and return -1 if either nToken or nIndex is |
1150 | | // negative: |
1151 | 8.33M | if (nIndex >= 0 && nToken >= 0) |
1152 | 8.33M | { |
1153 | 8.33M | const auto* pOrgCharStr = pStr->buffer; |
1154 | 8.33M | const auto* pCharStr = pOrgCharStr + nIndex; |
1155 | 8.33M | sal_Int32 nLen = pStr->length - nIndex; |
1156 | 8.33M | sal_Int32 nTokCount = 0; |
1157 | 8.33M | const auto* pCharStrStart = pCharStr; |
1158 | 107M | while (nLen > 0) |
1159 | 101M | { |
1160 | 101M | if (*pCharStr == cTok) |
1161 | 3.25M | { |
1162 | 3.25M | nTokCount++; |
1163 | | |
1164 | 3.25M | if (nTokCount > nToken) |
1165 | 3.25M | break; |
1166 | 10 | if (nTokCount == nToken) |
1167 | 10 | pCharStrStart = pCharStr + 1; |
1168 | 10 | } |
1169 | | |
1170 | 98.6M | pCharStr++; |
1171 | 98.6M | nLen--; |
1172 | 98.6M | } |
1173 | 8.33M | if (nTokCount >= nToken) |
1174 | 8.33M | { |
1175 | 8.33M | newFromStr_WithLength(ppThis, pCharStrStart, pCharStr - pCharStrStart); |
1176 | 8.33M | if (nLen > 0) |
1177 | 3.25M | return pCharStr - pOrgCharStr + 1; |
1178 | 5.07M | else |
1179 | 5.07M | return -1; |
1180 | 8.33M | } |
1181 | 8.33M | } |
1182 | | |
1183 | 1.71k | new_(ppThis); |
1184 | 1.71k | return -1; |
1185 | 8.33M | } _ZN3rtl3str8getTokenI11_rtl_StringEEiPPT_S4_iu15__remove_extentIDtsrS3_6bufferEEi Line | Count | Source | 1144 | 324 | { | 1145 | 324 | assert(ppThis); | 1146 | 324 | assert(pStr); | 1147 | 324 | assert(nIndex <= pStr->length); | 1148 | | | 1149 | | // Set ppThis to an empty string and return -1 if either nToken or nIndex is | 1150 | | // negative: | 1151 | 324 | if (nIndex >= 0 && nToken >= 0) | 1152 | 324 | { | 1153 | 324 | const auto* pOrgCharStr = pStr->buffer; | 1154 | 324 | const auto* pCharStr = pOrgCharStr + nIndex; | 1155 | 324 | sal_Int32 nLen = pStr->length - nIndex; | 1156 | 324 | sal_Int32 nTokCount = 0; | 1157 | 324 | const auto* pCharStrStart = pCharStr; | 1158 | 13.8k | while (nLen > 0) | 1159 | 13.7k | { | 1160 | 13.7k | if (*pCharStr == cTok) | 1161 | 216 | { | 1162 | 216 | nTokCount++; | 1163 | | | 1164 | 216 | if (nTokCount > nToken) | 1165 | 216 | break; | 1166 | 0 | if (nTokCount == nToken) | 1167 | 0 | pCharStrStart = pCharStr + 1; | 1168 | 0 | } | 1169 | | | 1170 | 13.5k | pCharStr++; | 1171 | 13.5k | nLen--; | 1172 | 13.5k | } | 1173 | 324 | if (nTokCount >= nToken) | 1174 | 324 | { | 1175 | 324 | newFromStr_WithLength(ppThis, pCharStrStart, pCharStr - pCharStrStart); | 1176 | 324 | if (nLen > 0) | 1177 | 216 | return pCharStr - pOrgCharStr + 1; | 1178 | 108 | else | 1179 | 108 | return -1; | 1180 | 324 | } | 1181 | 324 | } | 1182 | | | 1183 | 0 | new_(ppThis); | 1184 | 0 | return -1; | 1185 | 324 | } |
_ZN3rtl3str8getTokenI12_rtl_uStringEEiPPT_S4_iu15__remove_extentIDtsrS3_6bufferEEi Line | Count | Source | 1144 | 8.33M | { | 1145 | 8.33M | assert(ppThis); | 1146 | 8.33M | assert(pStr); | 1147 | 8.33M | assert(nIndex <= pStr->length); | 1148 | | | 1149 | | // Set ppThis to an empty string and return -1 if either nToken or nIndex is | 1150 | | // negative: | 1151 | 8.33M | if (nIndex >= 0 && nToken >= 0) | 1152 | 8.33M | { | 1153 | 8.33M | const auto* pOrgCharStr = pStr->buffer; | 1154 | 8.33M | const auto* pCharStr = pOrgCharStr + nIndex; | 1155 | 8.33M | sal_Int32 nLen = pStr->length - nIndex; | 1156 | 8.33M | sal_Int32 nTokCount = 0; | 1157 | 8.33M | const auto* pCharStrStart = pCharStr; | 1158 | 106M | while (nLen > 0) | 1159 | 101M | { | 1160 | 101M | if (*pCharStr == cTok) | 1161 | 3.25M | { | 1162 | 3.25M | nTokCount++; | 1163 | | | 1164 | 3.25M | if (nTokCount > nToken) | 1165 | 3.25M | break; | 1166 | 10 | if (nTokCount == nToken) | 1167 | 10 | pCharStrStart = pCharStr + 1; | 1168 | 10 | } | 1169 | | | 1170 | 98.6M | pCharStr++; | 1171 | 98.6M | nLen--; | 1172 | 98.6M | } | 1173 | 8.33M | if (nTokCount >= nToken) | 1174 | 8.33M | { | 1175 | 8.33M | newFromStr_WithLength(ppThis, pCharStrStart, pCharStr - pCharStrStart); | 1176 | 8.33M | if (nLen > 0) | 1177 | 3.25M | return pCharStr - pOrgCharStr + 1; | 1178 | 5.07M | else | 1179 | 5.07M | return -1; | 1180 | 8.33M | } | 1181 | 8.33M | } | 1182 | | | 1183 | 1.71k | new_(ppThis); | 1184 | 1.71k | return -1; | 1185 | 8.33M | } |
|
1186 | | |
1187 | | /* ======================================================================= */ |
1188 | | /* String buffer help functions */ |
1189 | | /* ======================================================================= */ |
1190 | | |
1191 | | template <class rtl_tString> |
1192 | | void stringbuffer_newFromStr_WithLength(rtl_tString** ppThis, |
1193 | | const Char_T<rtl_tString>* pStr, sal_Int32 count) |
1194 | 28.6M | { |
1195 | 28.6M | assert(ppThis); |
1196 | 28.6M | assert(count >= 0); |
1197 | 28.6M | if (!pStr) |
1198 | 0 | count = 0; // Because old code didn't care about count when !pStr |
1199 | | |
1200 | 28.6M | newFromStr_WithLength(ppThis, pStr, count, 16); |
1201 | 28.6M | } Unexecuted instantiation: _ZN3rtl3str34stringbuffer_newFromStr_WithLengthI11_rtl_StringEEvPPT_PKu15__remove_extentIDtsrS3_6bufferEEi _ZN3rtl3str34stringbuffer_newFromStr_WithLengthI12_rtl_uStringEEvPPT_PKu15__remove_extentIDtsrS3_6bufferEEi Line | Count | Source | 1194 | 28.6M | { | 1195 | 28.6M | assert(ppThis); | 1196 | 28.6M | assert(count >= 0); | 1197 | 28.6M | if (!pStr) | 1198 | 0 | count = 0; // Because old code didn't care about count when !pStr | 1199 | | | 1200 | 28.6M | newFromStr_WithLength(ppThis, pStr, count, 16); | 1201 | 28.6M | } |
|
1202 | | |
1203 | | template <class rtl_tString> |
1204 | | sal_Int32 stringbuffer_newFromStringBuffer(rtl_tString** ppThis, sal_Int32 capacity, |
1205 | | rtl_tString* pStr) |
1206 | 712k | { |
1207 | 712k | assert(capacity >= 0); |
1208 | 712k | assert(pStr); |
1209 | | |
1210 | 712k | if (capacity < pStr->length) |
1211 | 0 | capacity = pStr->length; |
1212 | | |
1213 | 712k | newFromStr_WithLength(ppThis, pStr->buffer, pStr->length, capacity - pStr->length); |
1214 | 712k | return capacity; |
1215 | 712k | } Unexecuted instantiation: int rtl::str::stringbuffer_newFromStringBuffer<_rtl_String>(_rtl_String**, int, _rtl_String*) int rtl::str::stringbuffer_newFromStringBuffer<_rtl_uString>(_rtl_uString**, int, _rtl_uString*) Line | Count | Source | 1206 | 712k | { | 1207 | 712k | assert(capacity >= 0); | 1208 | 712k | assert(pStr); | 1209 | | | 1210 | 712k | if (capacity < pStr->length) | 1211 | 0 | capacity = pStr->length; | 1212 | | | 1213 | 712k | newFromStr_WithLength(ppThis, pStr->buffer, pStr->length, capacity - pStr->length); | 1214 | 712k | return capacity; | 1215 | 712k | } |
|
1216 | | |
1217 | | template <class rtl_tString> |
1218 | | void stringbuffer_ensureCapacity(rtl_tString** ppThis, sal_Int32* capacity, |
1219 | | sal_Int32 minimumCapacity) |
1220 | 1.43G | { |
1221 | 1.43G | assert(ppThis); |
1222 | 1.43G | assert(capacity && *capacity >= 0); |
1223 | | // assert(minimumCapacity >= 0); // It was commented out in rtl_stringbuffer_ensureCapacity |
1224 | 1.43G | if (minimumCapacity <= *capacity) |
1225 | 1.42G | return; |
1226 | | |
1227 | 7.42M | const auto nLength = (*ppThis)->length; |
1228 | 7.42M | *capacity = (nLength + 1) * 2; |
1229 | 7.42M | if (minimumCapacity > *capacity) |
1230 | 3.36M | *capacity = minimumCapacity; |
1231 | | |
1232 | 7.42M | newFromStr_WithLength(ppThis, (*ppThis)->buffer, nLength, *capacity - nLength); |
1233 | 7.42M | } void rtl::str::stringbuffer_ensureCapacity<_rtl_String>(_rtl_String**, int*, int) Line | Count | Source | 1220 | 254M | { | 1221 | 254M | assert(ppThis); | 1222 | 254M | assert(capacity && *capacity >= 0); | 1223 | | // assert(minimumCapacity >= 0); // It was commented out in rtl_stringbuffer_ensureCapacity | 1224 | 254M | if (minimumCapacity <= *capacity) | 1225 | 254M | return; | 1226 | | | 1227 | 606k | const auto nLength = (*ppThis)->length; | 1228 | 606k | *capacity = (nLength + 1) * 2; | 1229 | 606k | if (minimumCapacity > *capacity) | 1230 | 196k | *capacity = minimumCapacity; | 1231 | | | 1232 | 606k | newFromStr_WithLength(ppThis, (*ppThis)->buffer, nLength, *capacity - nLength); | 1233 | 606k | } |
void rtl::str::stringbuffer_ensureCapacity<_rtl_uString>(_rtl_uString**, int*, int) Line | Count | Source | 1220 | 1.18G | { | 1221 | 1.18G | assert(ppThis); | 1222 | 1.18G | assert(capacity && *capacity >= 0); | 1223 | | // assert(minimumCapacity >= 0); // It was commented out in rtl_stringbuffer_ensureCapacity | 1224 | 1.18G | if (minimumCapacity <= *capacity) | 1225 | 1.17G | return; | 1226 | | | 1227 | 6.81M | const auto nLength = (*ppThis)->length; | 1228 | 6.81M | *capacity = (nLength + 1) * 2; | 1229 | 6.81M | if (minimumCapacity > *capacity) | 1230 | 3.17M | *capacity = minimumCapacity; | 1231 | | | 1232 | 6.81M | newFromStr_WithLength(ppThis, (*ppThis)->buffer, nLength, *capacity - nLength); | 1233 | 6.81M | } |
|
1234 | | |
1235 | | template <class rtl_tString, typename C> |
1236 | | void stringbuffer_insert(rtl_tString** ppThis, sal_Int32* capacity, sal_Int32 offset, |
1237 | | const C* pStr, sal_Int32 len) |
1238 | 1.45G | { |
1239 | 1.45G | assert(ppThis); |
1240 | 1.45G | assert(capacity && *capacity >= 0); |
1241 | 1.45G | assert(offset >= 0 && offset <= (*ppThis)->length); |
1242 | 1.45G | assert(len >= 0); |
1243 | 1.45G | if (len == 0) |
1244 | 15.8M | return; |
1245 | 1.43G | if (len > std::numeric_limits<sal_Int32>::max() - (*ppThis)->length) { |
1246 | 0 | throw std::bad_alloc(); |
1247 | 0 | } |
1248 | | |
1249 | 1.43G | stringbuffer_ensureCapacity(ppThis, capacity, (*ppThis)->length + len); |
1250 | | |
1251 | 1.43G | sal_Int32 nOldLen = (*ppThis)->length; |
1252 | 1.43G | auto* pBuf = (*ppThis)->buffer; |
1253 | | |
1254 | | /* copy the tail */ |
1255 | 1.43G | const sal_Int32 n = nOldLen - offset; |
1256 | 1.43G | if (n > 0) |
1257 | 12.8M | CopyBackward(pBuf + offset + len, pBuf + offset, n); |
1258 | | |
1259 | | /* insert the new characters */ |
1260 | 1.43G | if (pStr != nullptr) |
1261 | 1.27G | Copy(pBuf + offset, pStr, len); |
1262 | | |
1263 | 1.43G | (*ppThis)->length = nOldLen + len; |
1264 | 1.43G | pBuf[nOldLen + len] = 0; |
1265 | 1.43G | } void rtl::str::stringbuffer_insert<_rtl_String, char>(_rtl_String**, int*, int, char const*, int) Line | Count | Source | 1238 | 254M | { | 1239 | 254M | assert(ppThis); | 1240 | 254M | assert(capacity && *capacity >= 0); | 1241 | 254M | assert(offset >= 0 && offset <= (*ppThis)->length); | 1242 | 254M | assert(len >= 0); | 1243 | 254M | if (len == 0) | 1244 | 125k | return; | 1245 | 254M | if (len > std::numeric_limits<sal_Int32>::max() - (*ppThis)->length) { | 1246 | 0 | throw std::bad_alloc(); | 1247 | 0 | } | 1248 | | | 1249 | 254M | stringbuffer_ensureCapacity(ppThis, capacity, (*ppThis)->length + len); | 1250 | | | 1251 | 254M | sal_Int32 nOldLen = (*ppThis)->length; | 1252 | 254M | auto* pBuf = (*ppThis)->buffer; | 1253 | | | 1254 | | /* copy the tail */ | 1255 | 254M | const sal_Int32 n = nOldLen - offset; | 1256 | 254M | if (n > 0) | 1257 | 0 | CopyBackward(pBuf + offset + len, pBuf + offset, n); | 1258 | | | 1259 | | /* insert the new characters */ | 1260 | 254M | if (pStr != nullptr) | 1261 | 104M | Copy(pBuf + offset, pStr, len); | 1262 | | | 1263 | 254M | (*ppThis)->length = nOldLen + len; | 1264 | 254M | pBuf[nOldLen + len] = 0; | 1265 | 254M | } |
void rtl::str::stringbuffer_insert<_rtl_uString, char>(_rtl_uString**, int*, int, char const*, int) Line | Count | Source | 1238 | 12.9M | { | 1239 | 12.9M | assert(ppThis); | 1240 | 12.9M | assert(capacity && *capacity >= 0); | 1241 | 12.9M | assert(offset >= 0 && offset <= (*ppThis)->length); | 1242 | 12.9M | assert(len >= 0); | 1243 | 12.9M | if (len == 0) | 1244 | 138k | return; | 1245 | 12.7M | if (len > std::numeric_limits<sal_Int32>::max() - (*ppThis)->length) { | 1246 | 0 | throw std::bad_alloc(); | 1247 | 0 | } | 1248 | | | 1249 | 12.7M | stringbuffer_ensureCapacity(ppThis, capacity, (*ppThis)->length + len); | 1250 | | | 1251 | 12.7M | sal_Int32 nOldLen = (*ppThis)->length; | 1252 | 12.7M | auto* pBuf = (*ppThis)->buffer; | 1253 | | | 1254 | | /* copy the tail */ | 1255 | 12.7M | const sal_Int32 n = nOldLen - offset; | 1256 | 12.7M | if (n > 0) | 1257 | 4.60M | CopyBackward(pBuf + offset + len, pBuf + offset, n); | 1258 | | | 1259 | | /* insert the new characters */ | 1260 | 12.7M | if (pStr != nullptr) | 1261 | 12.7M | Copy(pBuf + offset, pStr, len); | 1262 | | | 1263 | 12.7M | (*ppThis)->length = nOldLen + len; | 1264 | 12.7M | pBuf[nOldLen + len] = 0; | 1265 | 12.7M | } |
void rtl::str::stringbuffer_insert<_rtl_uString, char16_t>(_rtl_uString**, int*, int, char16_t const*, int) Line | Count | Source | 1238 | 1.18G | { | 1239 | 1.18G | assert(ppThis); | 1240 | 1.18G | assert(capacity && *capacity >= 0); | 1241 | 1.18G | assert(offset >= 0 && offset <= (*ppThis)->length); | 1242 | 1.18G | assert(len >= 0); | 1243 | 1.18G | if (len == 0) | 1244 | 15.5M | return; | 1245 | 1.16G | if (len > std::numeric_limits<sal_Int32>::max() - (*ppThis)->length) { | 1246 | 0 | throw std::bad_alloc(); | 1247 | 0 | } | 1248 | | | 1249 | 1.16G | stringbuffer_ensureCapacity(ppThis, capacity, (*ppThis)->length + len); | 1250 | | | 1251 | 1.16G | sal_Int32 nOldLen = (*ppThis)->length; | 1252 | 1.16G | auto* pBuf = (*ppThis)->buffer; | 1253 | | | 1254 | | /* copy the tail */ | 1255 | 1.16G | const sal_Int32 n = nOldLen - offset; | 1256 | 1.16G | if (n > 0) | 1257 | 8.23M | CopyBackward(pBuf + offset + len, pBuf + offset, n); | 1258 | | | 1259 | | /* insert the new characters */ | 1260 | 1.16G | if (pStr != nullptr) | 1261 | 1.16G | Copy(pBuf + offset, pStr, len); | 1262 | | | 1263 | 1.16G | (*ppThis)->length = nOldLen + len; | 1264 | 1.16G | pBuf[nOldLen + len] = 0; | 1265 | 1.16G | } |
|
1266 | | |
1267 | | template <class rtl_tString> |
1268 | | void stringbuffer_remove(rtl_tString** ppThis, sal_Int32 start, sal_Int32 len) |
1269 | 33.8M | { |
1270 | 33.8M | assert(ppThis); |
1271 | 33.8M | assert(start >= 0 && start <= (*ppThis)->length); |
1272 | 33.8M | assert(len >= 0); |
1273 | | |
1274 | 33.8M | if (len > (*ppThis)->length - start) |
1275 | 371 | len = (*ppThis)->length - start; |
1276 | | |
1277 | | //remove nothing |
1278 | 33.8M | if (!len) |
1279 | 606k | return; |
1280 | | |
1281 | 33.2M | auto* pBuf = (*ppThis)->buffer; |
1282 | 33.2M | const sal_Int32 nTailLen = (*ppThis)->length - (start + len); |
1283 | | |
1284 | 33.2M | if (nTailLen) |
1285 | 5.60M | { |
1286 | | /* move the tail */ |
1287 | 5.60M | Copy(pBuf + start, pBuf + start + len, nTailLen); |
1288 | 5.60M | } |
1289 | | |
1290 | 33.2M | (*ppThis)->length -= len; |
1291 | 33.2M | pBuf[(*ppThis)->length] = 0; |
1292 | 33.2M | } Unexecuted instantiation: void rtl::str::stringbuffer_remove<_rtl_String>(_rtl_String**, int, int) void rtl::str::stringbuffer_remove<_rtl_uString>(_rtl_uString**, int, int) Line | Count | Source | 1269 | 33.8M | { | 1270 | 33.8M | assert(ppThis); | 1271 | 33.8M | assert(start >= 0 && start <= (*ppThis)->length); | 1272 | 33.8M | assert(len >= 0); | 1273 | | | 1274 | 33.8M | if (len > (*ppThis)->length - start) | 1275 | 371 | len = (*ppThis)->length - start; | 1276 | | | 1277 | | //remove nothing | 1278 | 33.8M | if (!len) | 1279 | 606k | return; | 1280 | | | 1281 | 33.2M | auto* pBuf = (*ppThis)->buffer; | 1282 | 33.2M | const sal_Int32 nTailLen = (*ppThis)->length - (start + len); | 1283 | | | 1284 | 33.2M | if (nTailLen) | 1285 | 5.60M | { | 1286 | | /* move the tail */ | 1287 | 5.60M | Copy(pBuf + start, pBuf + start + len, nTailLen); | 1288 | 5.60M | } | 1289 | | | 1290 | 33.2M | (*ppThis)->length -= len; | 1291 | 33.2M | pBuf[(*ppThis)->length] = 0; | 1292 | 33.2M | } |
|
1293 | | |
1294 | | template <class S, typename CharTypeFrom, typename CharTypeTo> |
1295 | | void newReplaceAllFromIndex(S** s, S* s1, CharTypeFrom const* from, sal_Int32 fromLength, |
1296 | | CharTypeTo const* to, sal_Int32 toLength, sal_Int32 fromIndex) |
1297 | 43.7M | { |
1298 | 43.7M | assert(s != nullptr); |
1299 | 43.7M | assert(s1 != nullptr); |
1300 | 43.7M | assert(fromLength >= 0); |
1301 | 43.7M | assert(from != nullptr || fromLength == 0); |
1302 | 43.7M | assert(toLength >= 0); |
1303 | 43.7M | assert(to != nullptr || toLength == 0); |
1304 | 43.7M | assert(fromIndex >= 0 && fromIndex <= s1->length); |
1305 | 43.7M | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, |
1306 | 43.7M | from, fromLength); |
1307 | 43.7M | if (i >= 0) |
1308 | 4.47M | { |
1309 | 4.47M | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) |
1310 | 0 | std::abort(); |
1311 | 4.47M | i += fromIndex; |
1312 | 4.47M | sal_Int32 nCapacity = s1->length + (toLength - fromLength); |
1313 | 4.47M | if (fromLength < toLength) |
1314 | 123k | { |
1315 | | // Pre-allocate up to 16 replacements more |
1316 | 123k | const sal_Int32 nMaxMoreFinds = (s1->length - i - fromLength) / fromLength; |
1317 | 123k | const sal_Int32 nIncrease = toLength - fromLength; |
1318 | 123k | const sal_Int32 nMoreReplacements = std::min( |
1319 | 123k | { nMaxMoreFinds, (SAL_MAX_INT32 - nCapacity) / nIncrease, sal_Int32(16) }); |
1320 | 123k | nCapacity += nMoreReplacements * nIncrease; |
1321 | 123k | } |
1322 | 4.47M | const auto pOld = *s; |
1323 | 4.47M | *s = Alloc<S>(nCapacity); |
1324 | 4.47M | (*s)->length = 0; |
1325 | 4.47M | fromIndex = 0; |
1326 | 4.47M | do |
1327 | 8.67M | { |
1328 | 8.67M | stringbuffer_insert(s, &nCapacity, (*s)->length, s1->buffer + fromIndex, i); |
1329 | 8.67M | stringbuffer_insert(s, &nCapacity, (*s)->length, to, toLength); |
1330 | 8.67M | fromIndex += i + fromLength; |
1331 | 8.67M | i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, |
1332 | 8.67M | from, fromLength); |
1333 | 8.67M | } while (i >= 0); |
1334 | | // the rest |
1335 | 4.47M | stringbuffer_insert(s, &nCapacity, (*s)->length, |
1336 | 4.47M | s1->buffer + fromIndex, s1->length - fromIndex); |
1337 | 4.47M | if (pOld) |
1338 | 0 | release(pOld); // Must be last in case *s == s1 |
1339 | 4.47M | } |
1340 | 39.2M | else |
1341 | 39.2M | assign(s, s1); |
1342 | | |
1343 | 43.7M | RTL_LOG_STRING_NEW(*s); |
1344 | 43.7M | } void rtl::str::newReplaceAllFromIndex<_rtl_String, char, char>(_rtl_String**, _rtl_String*, char const*, int, char const*, int, int) Line | Count | Source | 1297 | 1.62k | { | 1298 | 1.62k | assert(s != nullptr); | 1299 | 1.62k | assert(s1 != nullptr); | 1300 | 1.62k | assert(fromLength >= 0); | 1301 | 1.62k | assert(from != nullptr || fromLength == 0); | 1302 | 1.62k | assert(toLength >= 0); | 1303 | 1.62k | assert(to != nullptr || toLength == 0); | 1304 | 1.62k | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1305 | 1.62k | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1306 | 1.62k | from, fromLength); | 1307 | 1.62k | if (i >= 0) | 1308 | 216 | { | 1309 | 216 | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1310 | 0 | std::abort(); | 1311 | 216 | i += fromIndex; | 1312 | 216 | sal_Int32 nCapacity = s1->length + (toLength - fromLength); | 1313 | 216 | if (fromLength < toLength) | 1314 | 0 | { | 1315 | | // Pre-allocate up to 16 replacements more | 1316 | 0 | const sal_Int32 nMaxMoreFinds = (s1->length - i - fromLength) / fromLength; | 1317 | 0 | const sal_Int32 nIncrease = toLength - fromLength; | 1318 | 0 | const sal_Int32 nMoreReplacements = std::min( | 1319 | 0 | { nMaxMoreFinds, (SAL_MAX_INT32 - nCapacity) / nIncrease, sal_Int32(16) }); | 1320 | 0 | nCapacity += nMoreReplacements * nIncrease; | 1321 | 0 | } | 1322 | 216 | const auto pOld = *s; | 1323 | 216 | *s = Alloc<S>(nCapacity); | 1324 | 216 | (*s)->length = 0; | 1325 | 216 | fromIndex = 0; | 1326 | 216 | do | 1327 | 216 | { | 1328 | 216 | stringbuffer_insert(s, &nCapacity, (*s)->length, s1->buffer + fromIndex, i); | 1329 | 216 | stringbuffer_insert(s, &nCapacity, (*s)->length, to, toLength); | 1330 | 216 | fromIndex += i + fromLength; | 1331 | 216 | i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1332 | 216 | from, fromLength); | 1333 | 216 | } while (i >= 0); | 1334 | | // the rest | 1335 | 216 | stringbuffer_insert(s, &nCapacity, (*s)->length, | 1336 | 216 | s1->buffer + fromIndex, s1->length - fromIndex); | 1337 | 216 | if (pOld) | 1338 | 0 | release(pOld); // Must be last in case *s == s1 | 1339 | 216 | } | 1340 | 1.40k | else | 1341 | 1.40k | assign(s, s1); | 1342 | | | 1343 | 1.62k | RTL_LOG_STRING_NEW(*s); | 1344 | 1.62k | } |
void rtl::str::newReplaceAllFromIndex<_rtl_uString, char, char>(_rtl_uString**, _rtl_uString*, char const*, int, char const*, int, int) Line | Count | Source | 1297 | 8.51M | { | 1298 | 8.51M | assert(s != nullptr); | 1299 | 8.51M | assert(s1 != nullptr); | 1300 | 8.51M | assert(fromLength >= 0); | 1301 | 8.51M | assert(from != nullptr || fromLength == 0); | 1302 | 8.51M | assert(toLength >= 0); | 1303 | 8.51M | assert(to != nullptr || toLength == 0); | 1304 | 8.51M | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1305 | 8.51M | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1306 | 8.51M | from, fromLength); | 1307 | 8.51M | if (i >= 0) | 1308 | 154k | { | 1309 | 154k | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1310 | 0 | std::abort(); | 1311 | 154k | i += fromIndex; | 1312 | 154k | sal_Int32 nCapacity = s1->length + (toLength - fromLength); | 1313 | 154k | if (fromLength < toLength) | 1314 | 348 | { | 1315 | | // Pre-allocate up to 16 replacements more | 1316 | 348 | const sal_Int32 nMaxMoreFinds = (s1->length - i - fromLength) / fromLength; | 1317 | 348 | const sal_Int32 nIncrease = toLength - fromLength; | 1318 | 348 | const sal_Int32 nMoreReplacements = std::min( | 1319 | 348 | { nMaxMoreFinds, (SAL_MAX_INT32 - nCapacity) / nIncrease, sal_Int32(16) }); | 1320 | 348 | nCapacity += nMoreReplacements * nIncrease; | 1321 | 348 | } | 1322 | 154k | const auto pOld = *s; | 1323 | 154k | *s = Alloc<S>(nCapacity); | 1324 | 154k | (*s)->length = 0; | 1325 | 154k | fromIndex = 0; | 1326 | 154k | do | 1327 | 1.02M | { | 1328 | 1.02M | stringbuffer_insert(s, &nCapacity, (*s)->length, s1->buffer + fromIndex, i); | 1329 | 1.02M | stringbuffer_insert(s, &nCapacity, (*s)->length, to, toLength); | 1330 | 1.02M | fromIndex += i + fromLength; | 1331 | 1.02M | i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1332 | 1.02M | from, fromLength); | 1333 | 1.02M | } while (i >= 0); | 1334 | | // the rest | 1335 | 154k | stringbuffer_insert(s, &nCapacity, (*s)->length, | 1336 | 154k | s1->buffer + fromIndex, s1->length - fromIndex); | 1337 | 154k | if (pOld) | 1338 | 0 | release(pOld); // Must be last in case *s == s1 | 1339 | 154k | } | 1340 | 8.35M | else | 1341 | 8.35M | assign(s, s1); | 1342 | | | 1343 | 8.51M | RTL_LOG_STRING_NEW(*s); | 1344 | 8.51M | } |
void rtl::str::newReplaceAllFromIndex<_rtl_uString, char, char16_t>(_rtl_uString**, _rtl_uString*, char const*, int, char16_t const*, int, int) Line | Count | Source | 1297 | 1.05M | { | 1298 | 1.05M | assert(s != nullptr); | 1299 | 1.05M | assert(s1 != nullptr); | 1300 | 1.05M | assert(fromLength >= 0); | 1301 | 1.05M | assert(from != nullptr || fromLength == 0); | 1302 | 1.05M | assert(toLength >= 0); | 1303 | 1.05M | assert(to != nullptr || toLength == 0); | 1304 | 1.05M | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1305 | 1.05M | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1306 | 1.05M | from, fromLength); | 1307 | 1.05M | if (i >= 0) | 1308 | 993k | { | 1309 | 993k | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1310 | 0 | std::abort(); | 1311 | 993k | i += fromIndex; | 1312 | 993k | sal_Int32 nCapacity = s1->length + (toLength - fromLength); | 1313 | 993k | if (fromLength < toLength) | 1314 | 0 | { | 1315 | | // Pre-allocate up to 16 replacements more | 1316 | 0 | const sal_Int32 nMaxMoreFinds = (s1->length - i - fromLength) / fromLength; | 1317 | 0 | const sal_Int32 nIncrease = toLength - fromLength; | 1318 | 0 | const sal_Int32 nMoreReplacements = std::min( | 1319 | 0 | { nMaxMoreFinds, (SAL_MAX_INT32 - nCapacity) / nIncrease, sal_Int32(16) }); | 1320 | 0 | nCapacity += nMoreReplacements * nIncrease; | 1321 | 0 | } | 1322 | 993k | const auto pOld = *s; | 1323 | 993k | *s = Alloc<S>(nCapacity); | 1324 | 993k | (*s)->length = 0; | 1325 | 993k | fromIndex = 0; | 1326 | 993k | do | 1327 | 995k | { | 1328 | 995k | stringbuffer_insert(s, &nCapacity, (*s)->length, s1->buffer + fromIndex, i); | 1329 | 995k | stringbuffer_insert(s, &nCapacity, (*s)->length, to, toLength); | 1330 | 995k | fromIndex += i + fromLength; | 1331 | 995k | i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1332 | 995k | from, fromLength); | 1333 | 995k | } while (i >= 0); | 1334 | | // the rest | 1335 | 993k | stringbuffer_insert(s, &nCapacity, (*s)->length, | 1336 | 993k | s1->buffer + fromIndex, s1->length - fromIndex); | 1337 | 993k | if (pOld) | 1338 | 0 | release(pOld); // Must be last in case *s == s1 | 1339 | 993k | } | 1340 | 66.4k | else | 1341 | 66.4k | assign(s, s1); | 1342 | | | 1343 | 1.05M | RTL_LOG_STRING_NEW(*s); | 1344 | 1.05M | } |
void rtl::str::newReplaceAllFromIndex<_rtl_uString, char16_t, char>(_rtl_uString**, _rtl_uString*, char16_t const*, int, char const*, int, int) Line | Count | Source | 1297 | 4.71k | { | 1298 | 4.71k | assert(s != nullptr); | 1299 | 4.71k | assert(s1 != nullptr); | 1300 | 4.71k | assert(fromLength >= 0); | 1301 | 4.71k | assert(from != nullptr || fromLength == 0); | 1302 | 4.71k | assert(toLength >= 0); | 1303 | 4.71k | assert(to != nullptr || toLength == 0); | 1304 | 4.71k | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1305 | 4.71k | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1306 | 4.71k | from, fromLength); | 1307 | 4.71k | if (i >= 0) | 1308 | 0 | { | 1309 | 0 | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1310 | 0 | std::abort(); | 1311 | 0 | i += fromIndex; | 1312 | 0 | sal_Int32 nCapacity = s1->length + (toLength - fromLength); | 1313 | 0 | if (fromLength < toLength) | 1314 | 0 | { | 1315 | | // Pre-allocate up to 16 replacements more | 1316 | 0 | const sal_Int32 nMaxMoreFinds = (s1->length - i - fromLength) / fromLength; | 1317 | 0 | const sal_Int32 nIncrease = toLength - fromLength; | 1318 | 0 | const sal_Int32 nMoreReplacements = std::min( | 1319 | 0 | { nMaxMoreFinds, (SAL_MAX_INT32 - nCapacity) / nIncrease, sal_Int32(16) }); | 1320 | 0 | nCapacity += nMoreReplacements * nIncrease; | 1321 | 0 | } | 1322 | 0 | const auto pOld = *s; | 1323 | 0 | *s = Alloc<S>(nCapacity); | 1324 | 0 | (*s)->length = 0; | 1325 | 0 | fromIndex = 0; | 1326 | 0 | do | 1327 | 0 | { | 1328 | 0 | stringbuffer_insert(s, &nCapacity, (*s)->length, s1->buffer + fromIndex, i); | 1329 | 0 | stringbuffer_insert(s, &nCapacity, (*s)->length, to, toLength); | 1330 | 0 | fromIndex += i + fromLength; | 1331 | 0 | i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1332 | 0 | from, fromLength); | 1333 | 0 | } while (i >= 0); | 1334 | | // the rest | 1335 | 0 | stringbuffer_insert(s, &nCapacity, (*s)->length, | 1336 | 0 | s1->buffer + fromIndex, s1->length - fromIndex); | 1337 | 0 | if (pOld) | 1338 | 0 | release(pOld); // Must be last in case *s == s1 | 1339 | 0 | } | 1340 | 4.71k | else | 1341 | 4.71k | assign(s, s1); | 1342 | | | 1343 | 4.71k | RTL_LOG_STRING_NEW(*s); | 1344 | 4.71k | } |
void rtl::str::newReplaceAllFromIndex<_rtl_uString, char16_t, char16_t>(_rtl_uString**, _rtl_uString*, char16_t const*, int, char16_t const*, int, int) Line | Count | Source | 1297 | 34.1M | { | 1298 | 34.1M | assert(s != nullptr); | 1299 | 34.1M | assert(s1 != nullptr); | 1300 | 34.1M | assert(fromLength >= 0); | 1301 | 34.1M | assert(from != nullptr || fromLength == 0); | 1302 | 34.1M | assert(toLength >= 0); | 1303 | 34.1M | assert(to != nullptr || toLength == 0); | 1304 | 34.1M | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1305 | 34.1M | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1306 | 34.1M | from, fromLength); | 1307 | 34.1M | if (i >= 0) | 1308 | 3.32M | { | 1309 | 3.32M | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1310 | 0 | std::abort(); | 1311 | 3.32M | i += fromIndex; | 1312 | 3.32M | sal_Int32 nCapacity = s1->length + (toLength - fromLength); | 1313 | 3.32M | if (fromLength < toLength) | 1314 | 123k | { | 1315 | | // Pre-allocate up to 16 replacements more | 1316 | 123k | const sal_Int32 nMaxMoreFinds = (s1->length - i - fromLength) / fromLength; | 1317 | 123k | const sal_Int32 nIncrease = toLength - fromLength; | 1318 | 123k | const sal_Int32 nMoreReplacements = std::min( | 1319 | 123k | { nMaxMoreFinds, (SAL_MAX_INT32 - nCapacity) / nIncrease, sal_Int32(16) }); | 1320 | 123k | nCapacity += nMoreReplacements * nIncrease; | 1321 | 123k | } | 1322 | 3.32M | const auto pOld = *s; | 1323 | 3.32M | *s = Alloc<S>(nCapacity); | 1324 | 3.32M | (*s)->length = 0; | 1325 | 3.32M | fromIndex = 0; | 1326 | 3.32M | do | 1327 | 6.65M | { | 1328 | 6.65M | stringbuffer_insert(s, &nCapacity, (*s)->length, s1->buffer + fromIndex, i); | 1329 | 6.65M | stringbuffer_insert(s, &nCapacity, (*s)->length, to, toLength); | 1330 | 6.65M | fromIndex += i + fromLength; | 1331 | 6.65M | i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1332 | 6.65M | from, fromLength); | 1333 | 6.65M | } while (i >= 0); | 1334 | | // the rest | 1335 | 3.32M | stringbuffer_insert(s, &nCapacity, (*s)->length, | 1336 | 3.32M | s1->buffer + fromIndex, s1->length - fromIndex); | 1337 | 3.32M | if (pOld) | 1338 | 0 | release(pOld); // Must be last in case *s == s1 | 1339 | 3.32M | } | 1340 | 30.8M | else | 1341 | 30.8M | assign(s, s1); | 1342 | | | 1343 | 34.1M | RTL_LOG_STRING_NEW(*s); | 1344 | 34.1M | } |
|
1345 | | |
1346 | | template <class rtl_tString, typename C1, typename C2> |
1347 | | void newReplaceFirst(rtl_tString** s, rtl_tString* s1, C1 const* from, sal_Int32 fromLength, |
1348 | | C2 const* to, sal_Int32 toLength, sal_Int32& fromIndex) |
1349 | 162k | { |
1350 | 162k | assert(s != nullptr); |
1351 | 162k | assert(s1 != nullptr); |
1352 | 162k | assert(fromLength >= 0); |
1353 | 162k | assert(from != nullptr || fromLength == 0); |
1354 | 162k | assert(toLength >= 0); |
1355 | 162k | assert(to != nullptr || toLength == 0); |
1356 | 162k | assert(fromIndex >= 0 && fromIndex <= s1->length); |
1357 | 162k | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, |
1358 | 162k | from, fromLength); |
1359 | 162k | if (i >= 0) |
1360 | 162k | { |
1361 | 162k | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) |
1362 | 0 | std::abort(); |
1363 | 162k | i += fromIndex; |
1364 | 162k | newReplaceStrAt(s, s1, i, fromLength, to, toLength); |
1365 | 162k | } |
1366 | 0 | else |
1367 | 0 | assign(s, s1); |
1368 | | |
1369 | 162k | fromIndex = i; |
1370 | 162k | } void rtl::str::newReplaceFirst<_rtl_uString, char, char>(_rtl_uString**, _rtl_uString*, char const*, int, char const*, int, int&) Line | Count | Source | 1349 | 1.37k | { | 1350 | 1.37k | assert(s != nullptr); | 1351 | 1.37k | assert(s1 != nullptr); | 1352 | 1.37k | assert(fromLength >= 0); | 1353 | 1.37k | assert(from != nullptr || fromLength == 0); | 1354 | 1.37k | assert(toLength >= 0); | 1355 | 1.37k | assert(to != nullptr || toLength == 0); | 1356 | 1.37k | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1357 | 1.37k | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1358 | 1.37k | from, fromLength); | 1359 | 1.37k | if (i >= 0) | 1360 | 1.37k | { | 1361 | 1.37k | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1362 | 0 | std::abort(); | 1363 | 1.37k | i += fromIndex; | 1364 | 1.37k | newReplaceStrAt(s, s1, i, fromLength, to, toLength); | 1365 | 1.37k | } | 1366 | 0 | else | 1367 | 0 | assign(s, s1); | 1368 | | | 1369 | 1.37k | fromIndex = i; | 1370 | 1.37k | } |
void rtl::str::newReplaceFirst<_rtl_uString, char, char16_t>(_rtl_uString**, _rtl_uString*, char const*, int, char16_t const*, int, int&) Line | Count | Source | 1349 | 161k | { | 1350 | 161k | assert(s != nullptr); | 1351 | 161k | assert(s1 != nullptr); | 1352 | 161k | assert(fromLength >= 0); | 1353 | 161k | assert(from != nullptr || fromLength == 0); | 1354 | 161k | assert(toLength >= 0); | 1355 | 161k | assert(to != nullptr || toLength == 0); | 1356 | 161k | assert(fromIndex >= 0 && fromIndex <= s1->length); | 1357 | 161k | sal_Int32 i = indexOfStr_WithLength(s1->buffer + fromIndex, s1->length - fromIndex, | 1358 | 161k | from, fromLength); | 1359 | 161k | if (i >= 0) | 1360 | 161k | { | 1361 | 161k | if (s1->length - fromLength > SAL_MAX_INT32 - toLength) | 1362 | 0 | std::abort(); | 1363 | 161k | i += fromIndex; | 1364 | 161k | newReplaceStrAt(s, s1, i, fromLength, to, toLength); | 1365 | 161k | } | 1366 | 0 | else | 1367 | 0 | assign(s, s1); | 1368 | | | 1369 | 161k | fromIndex = i; | 1370 | 161k | } |
Unexecuted instantiation: void rtl::str::newReplaceFirst<_rtl_uString, char16_t, char>(_rtl_uString**, _rtl_uString*, char16_t const*, int, char const*, int, int&) Unexecuted instantiation: void rtl::str::newReplaceFirst<_rtl_uString, char16_t, char16_t>(_rtl_uString**, _rtl_uString*, char16_t const*, int, char16_t const*, int, int&) |
1371 | | |
1372 | | // doubleToString implementation |
1373 | | |
1374 | | static inline constexpr sal_uInt64 eX[] = { 10ull, |
1375 | | 100ull, |
1376 | | 1000ull, |
1377 | | 10000ull, |
1378 | | 100000ull, |
1379 | | 1000000ull, |
1380 | | 10000000ull, |
1381 | | 100000000ull, |
1382 | | 1000000000ull, |
1383 | | 10000000000ull, |
1384 | | 100000000000ull, |
1385 | | 1000000000000ull, |
1386 | | 10000000000000ull, |
1387 | | 100000000000000ull, |
1388 | | 1000000000000000ull, |
1389 | | 10000000000000000ull, |
1390 | | 100000000000000000ull, |
1391 | | 1000000000000000000ull, |
1392 | | 10000000000000000000ull }; |
1393 | | |
1394 | | template <typename rtl_tString> |
1395 | | void doubleToString(rtl_tString** pResult, sal_Int32* pResultCapacity, sal_Int32 nResultOffset, |
1396 | | double fValue, rtl_math_StringFormat eFormat, sal_Int32 nDecPlaces, |
1397 | | Char_T<rtl_tString> cDecSeparator, sal_Int32 const* pGroups, |
1398 | | Char_T<rtl_tString> cGroupSeparator, bool bEraseTrailingDecZeros) |
1399 | 18.7M | { |
1400 | 18.7M | auto decimalDigits = [](sal_uInt64 n) { |
1401 | 18.7M | return std::distance(std::begin(eX), std::upper_bound(std::begin(eX), std::end(eX), n)) + 1; |
1402 | 18.7M | }; _ZZN3rtl3str14doubleToStringI11_rtl_StringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlmE_clEm Line | Count | Source | 1400 | 1.51M | auto decimalDigits = [](sal_uInt64 n) { | 1401 | 1.51M | return std::distance(std::begin(eX), std::upper_bound(std::begin(eX), std::end(eX), n)) + 1; | 1402 | 1.51M | }; |
_ZZN3rtl3str14doubleToStringI12_rtl_uStringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlmE_clEm Line | Count | Source | 1400 | 17.2M | auto decimalDigits = [](sal_uInt64 n) { | 1401 | 17.2M | return std::distance(std::begin(eX), std::upper_bound(std::begin(eX), std::end(eX), n)) + 1; | 1402 | 17.2M | }; |
|
1403 | | |
1404 | 18.7M | auto roundToPow10 = [](sal_uInt64 n, int e) { |
1405 | 16.4M | assert(e > 0 && o3tl::make_unsigned(e) <= std::size(eX)); |
1406 | 16.4M | const sal_uInt64 d = eX[e - 1]; |
1407 | 16.4M | return (n + d / 2) / d * d; |
1408 | 16.4M | }; _ZZN3rtl3str14doubleToStringI11_rtl_StringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlmiE_clEmi Line | Count | Source | 1404 | 349k | auto roundToPow10 = [](sal_uInt64 n, int e) { | 1405 | | assert(e > 0 && o3tl::make_unsigned(e) <= std::size(eX)); | 1406 | 349k | const sal_uInt64 d = eX[e - 1]; | 1407 | 349k | return (n + d / 2) / d * d; | 1408 | 349k | }; |
_ZZN3rtl3str14doubleToStringI12_rtl_uStringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlmiE_clEmi Line | Count | Source | 1404 | 16.0M | auto roundToPow10 = [](sal_uInt64 n, int e) { | 1405 | | assert(e > 0 && o3tl::make_unsigned(e) <= std::size(eX)); | 1406 | 16.0M | const sal_uInt64 d = eX[e - 1]; | 1407 | 16.0M | return (n + d / 2) / d * d; | 1408 | 16.0M | }; |
|
1409 | | |
1410 | 18.7M | auto append = [](rtl_tString** s, sal_Int32* pCapacity, sal_Int32 rOffset, auto sv) |
1411 | 18.7M | { |
1412 | 18.7M | if (!pCapacity) |
1413 | 17.0M | newFromStr_WithLength(s, sv.data(), sv.size()); |
1414 | 1.64M | else |
1415 | 1.64M | stringbuffer_insert(s, pCapacity, rOffset, sv.data(), sv.size()); |
1416 | 18.7M | }; _ZZN3rtl3str14doubleToStringI11_rtl_StringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlPPS2_S6_iS3_E_clINSt3__117basic_string_viewIcNSG_11char_traitsIcEEEEEEDaSD_S6_iS3_ Line | Count | Source | 1411 | 1.51M | { | 1412 | 1.51M | if (!pCapacity) | 1413 | 121k | newFromStr_WithLength(s, sv.data(), sv.size()); | 1414 | 1.39M | else | 1415 | 1.39M | stringbuffer_insert(s, pCapacity, rOffset, sv.data(), sv.size()); | 1416 | 1.51M | }; |
_ZZN3rtl3str14doubleToStringI12_rtl_uStringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlPPS2_S6_iS3_E_clINSt3__117basic_string_viewIcNSG_11char_traitsIcEEEEEEDaSD_S6_iS3_ Line | Count | Source | 1411 | 2.12k | { | 1412 | 2.12k | if (!pCapacity) | 1413 | 1.84k | newFromStr_WithLength(s, sv.data(), sv.size()); | 1414 | 286 | else | 1415 | 286 | stringbuffer_insert(s, pCapacity, rOffset, sv.data(), sv.size()); | 1416 | 2.12k | }; |
_ZZN3rtl3str14doubleToStringI12_rtl_uStringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_bENKUlPPS2_S6_iS3_E_clINSt3__117basic_string_viewIDsNSG_11char_traitsIDsEEEEEEDaSD_S6_iS3_ Line | Count | Source | 1411 | 17.2M | { | 1412 | 17.2M | if (!pCapacity) | 1413 | 16.9M | newFromStr_WithLength(s, sv.data(), sv.size()); | 1414 | 252k | else | 1415 | 252k | stringbuffer_insert(s, pCapacity, rOffset, sv.data(), sv.size()); | 1416 | 17.2M | }; |
|
1417 | | |
1418 | 18.7M | if (std::isnan(fValue)) |
1419 | 1.81k | { |
1420 | | // #i112652# XMLSchema-2 |
1421 | 1.81k | static constexpr std::string_view nan{ "NaN" }; |
1422 | 1.81k | return append(pResult, pResultCapacity, nResultOffset, nan); |
1423 | 1.81k | } |
1424 | | |
1425 | | // sign adjustment, instead of testing for fValue<0.0 this will also fetch -0.0 |
1426 | 18.7M | bool bSign = std::signbit(fValue); |
1427 | | |
1428 | 18.7M | if (std::isinf(fValue)) |
1429 | 307 | { |
1430 | | // #i112652# XMLSchema-2 |
1431 | 307 | std::string_view inf = bSign ? std::string_view("-INF") : std::string_view("INF"); |
1432 | 307 | return append(pResult, pResultCapacity, nResultOffset, inf); |
1433 | 307 | } |
1434 | | |
1435 | 18.7M | if (bSign) |
1436 | 337k | fValue = -fValue; |
1437 | | |
1438 | 18.7M | decltype(jkj::dragonbox::to_decimal(fValue, jkj::dragonbox::policy::sign::ignore, |
1439 | 18.7M | jkj::dragonbox::policy::trailing_zero::ignore)) aParts{}; |
1440 | 18.7M | if (fValue) // to_decimal is documented to only handle non-zero finite numbers |
1441 | 17.0M | aParts = jkj::dragonbox::to_decimal(fValue, jkj::dragonbox::policy::sign::ignore, |
1442 | 17.0M | jkj::dragonbox::policy::trailing_zero::ignore); |
1443 | | |
1444 | 18.7M | int nOrigDigits = decimalDigits(aParts.significand); |
1445 | 18.7M | int nExp = nOrigDigits + aParts.exponent - 1; |
1446 | 18.7M | int nRoundDigits = 15; |
1447 | | |
1448 | | // Unfortunately the old rounding below writes 1.79769313486232e+308 for |
1449 | | // DBL_MAX and 4 subsequent nextafter(...,0). |
1450 | 18.7M | static const double fB1 = std::nextafter(std::numeric_limits<double>::max(), 0); |
1451 | 18.7M | static const double fB2 = std::nextafter(fB1, 0); |
1452 | 18.7M | static const double fB3 = std::nextafter(fB2, 0); |
1453 | 18.7M | static const double fB4 = std::nextafter(fB3, 0); |
1454 | 18.7M | if ((fValue >= fB4) && eFormat != rtl_math_StringFormat_F) |
1455 | 591 | { |
1456 | | // 1.7976931348623157e+308 instead of rounded 1.79769313486232e+308 |
1457 | | // that can't be converted back as out of range. For rounded values if |
1458 | | // they exceed range they should not be written to exchange strings or |
1459 | | // file formats. |
1460 | | |
1461 | 591 | eFormat = rtl_math_StringFormat_E; |
1462 | 591 | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, 0, 16); |
1463 | 591 | nRoundDigits = 17; |
1464 | 591 | } |
1465 | | |
1466 | | // Use integer representation for integer values that fit into the |
1467 | | // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy. |
1468 | 18.7M | if ((eFormat == rtl_math_StringFormat_Automatic || eFormat == rtl_math_StringFormat_F) |
1469 | 1.91M | && aParts.exponent >= 0 && fValue < 0x1p53) |
1470 | 1.13M | { |
1471 | 1.13M | eFormat = rtl_math_StringFormat_F; |
1472 | 1.13M | if (nDecPlaces == rtl_math_DecimalPlaces_Max) |
1473 | 27.6k | nDecPlaces = 0; |
1474 | 1.11M | else |
1475 | 1.11M | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, -15, 15); |
1476 | | |
1477 | 1.13M | if (bEraseTrailingDecZeros && nDecPlaces > 0) |
1478 | 1.10M | nDecPlaces = 0; |
1479 | | |
1480 | 1.13M | nRoundDigits = nOrigDigits; // no rounding |
1481 | 1.13M | } |
1482 | | |
1483 | 18.7M | switch (eFormat) |
1484 | 18.7M | { |
1485 | 408k | case rtl_math_StringFormat_Automatic: |
1486 | | // E or F depending on exponent magnitude |
1487 | 408k | if (nExp <= -15 || nExp >= 15) |
1488 | 11.6k | { |
1489 | 11.6k | if (nDecPlaces == rtl_math_DecimalPlaces_Max) |
1490 | 11.6k | nDecPlaces = 14; |
1491 | 11.6k | eFormat = rtl_math_StringFormat_E; |
1492 | 11.6k | } |
1493 | 396k | else |
1494 | 396k | { |
1495 | 396k | if (nDecPlaces == rtl_math_DecimalPlaces_Max) |
1496 | 396k | nDecPlaces = (nExp < 14) ? 15 - nExp - 1 : 15; |
1497 | 396k | eFormat = rtl_math_StringFormat_F; |
1498 | 396k | } |
1499 | 408k | break; |
1500 | | |
1501 | 16.8M | case rtl_math_StringFormat_G: |
1502 | 16.8M | case rtl_math_StringFormat_G1: |
1503 | 16.8M | case rtl_math_StringFormat_G2: |
1504 | | // G-Point, similar to sprintf %G |
1505 | 16.8M | if (nDecPlaces == rtl_math_DecimalPlaces_DefaultSignificance) |
1506 | 0 | nDecPlaces = 6; |
1507 | | |
1508 | 16.8M | if (nExp < -4 || nExp >= nDecPlaces) |
1509 | 47.1k | { |
1510 | 47.1k | nDecPlaces = std::max<sal_Int32>(1, nDecPlaces - 1); |
1511 | | |
1512 | 47.1k | if (eFormat == rtl_math_StringFormat_G) |
1513 | 47.1k | eFormat = rtl_math_StringFormat_E; |
1514 | 0 | else if (eFormat == rtl_math_StringFormat_G2) |
1515 | 0 | eFormat = rtl_math_StringFormat_E2; |
1516 | 0 | else if (eFormat == rtl_math_StringFormat_G1) |
1517 | 0 | eFormat = rtl_math_StringFormat_E1; |
1518 | 47.1k | } |
1519 | 16.7M | else |
1520 | 16.7M | { |
1521 | 16.7M | if (nOrigDigits <= nDecPlaces && aParts.exponent >= 0 && fValue < 0x1p53) |
1522 | 579k | { |
1523 | | // Use integer representation with highest accuracy. |
1524 | 579k | nRoundDigits = nOrigDigits; // no rounding |
1525 | 579k | } |
1526 | 16.7M | nDecPlaces = std::max<sal_Int32>(0, nDecPlaces - nExp - 1); |
1527 | 16.7M | eFormat = rtl_math_StringFormat_F; |
1528 | 16.7M | } |
1529 | 16.8M | break; |
1530 | | |
1531 | 1.51M | default: |
1532 | 1.51M | break; |
1533 | 18.7M | } |
1534 | | |
1535 | | // Too large values for nDecPlaces make no sense; it might also be |
1536 | | // rtl_math_DecimalPlaces_Max was passed with rtl_math_StringFormat_F or |
1537 | | // others, but we don't want to allocate/deallocate 2GB just to fill it |
1538 | | // with trailing '0' characters.. |
1539 | 18.7M | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, -309, 309); |
1540 | | |
1541 | 18.7M | sal_Int32 nDigits = nDecPlaces + 1; |
1542 | | |
1543 | 18.7M | if (eFormat == rtl_math_StringFormat_F) |
1544 | 18.6M | nDigits += nExp; |
1545 | | |
1546 | | // Round the number |
1547 | 18.7M | nRoundDigits = std::min<int>(nDigits, nRoundDigits); |
1548 | 18.7M | if (nDigits >= 0 && nOrigDigits > nRoundDigits) |
1549 | 16.4M | { |
1550 | 16.4M | aParts.significand = roundToPow10(aParts.significand, nOrigDigits - nRoundDigits); |
1551 | 16.4M | assert(aParts.significand <= eX[nOrigDigits - 1]); |
1552 | 16.4M | if (aParts.significand == eX[nOrigDigits - 1]) // up-rounding to the next decade |
1553 | 670 | { |
1554 | 670 | nOrigDigits++; |
1555 | 670 | nExp++; |
1556 | | |
1557 | 670 | if (eFormat == rtl_math_StringFormat_F) |
1558 | 314 | nDigits++; |
1559 | 670 | } |
1560 | 16.4M | } |
1561 | | |
1562 | 18.7M | sal_Int32 nBuf |
1563 | 18.7M | = (nDigits <= 0 ? std::max<sal_Int32>(nDecPlaces, std::abs(nExp)) : nDigits + nDecPlaces) |
1564 | 18.7M | + 10 + (pGroups ? std::abs(nDigits) * 2 : 0); |
1565 | | // max(nDigits) = max(nDecPlaces) + 1 + max(nExp) + 1 = 309 + 1 + 308 + 1 = 619 |
1566 | | // max(nBuf) = max(nDigits) + max(nDecPlaces) + 10 + max(nDigits) * 2 = 619 * 3 + 309 + 10 = 2176 |
1567 | 18.7M | assert(nBuf <= 2176); |
1568 | 18.7M | auto* const pBuf = static_cast<Char_T<rtl_tString>*>(alloca(nBuf * sizeof(Char_T<rtl_tString>))); |
1569 | 18.7M | auto* p = pBuf; |
1570 | 18.7M | if (bSign) |
1571 | 337k | *p++ = '-'; |
1572 | | |
1573 | 18.7M | bool bHasDec = false; |
1574 | | |
1575 | 18.7M | int nDecPos; |
1576 | | // Check for F format and number < 1 |
1577 | 18.7M | if (eFormat == rtl_math_StringFormat_F) |
1578 | 18.6M | { |
1579 | 18.6M | if (nExp < 0) |
1580 | 5.34M | { |
1581 | 5.34M | *p++ = '0'; |
1582 | 5.34M | if (nDecPlaces > 0) |
1583 | 5.34M | { |
1584 | 5.34M | *p++ = cDecSeparator; |
1585 | 5.34M | bHasDec = true; |
1586 | 5.34M | } |
1587 | | |
1588 | 5.34M | sal_Int32 i = (nDigits <= 0 ? nDecPlaces : -nExp - 1); |
1589 | | |
1590 | 9.95M | while ((i--) > 0) |
1591 | 4.61M | *p++ = '0'; |
1592 | | |
1593 | 5.34M | nDecPos = 0; |
1594 | 5.34M | } |
1595 | 13.3M | else |
1596 | 13.3M | nDecPos = nExp + 1; |
1597 | 18.6M | } |
1598 | 64.1k | else |
1599 | 64.1k | nDecPos = 1; |
1600 | | |
1601 | 18.7M | int nGrouping = 0, nGroupSelector = 0, nGroupExceed = 0; |
1602 | 18.7M | if (nDecPos > 1 && pGroups && pGroups[0] && cGroupSeparator) |
1603 | 0 | { |
1604 | 0 | while (nGrouping + pGroups[nGroupSelector] < nDecPos) |
1605 | 0 | { |
1606 | 0 | nGrouping += pGroups[nGroupSelector]; |
1607 | 0 | if (pGroups[nGroupSelector + 1]) |
1608 | 0 | { |
1609 | 0 | if (nGrouping + pGroups[nGroupSelector + 1] >= nDecPos) |
1610 | 0 | break; // while |
1611 | | |
1612 | 0 | ++nGroupSelector; |
1613 | 0 | } |
1614 | 0 | else if (!nGroupExceed) |
1615 | 0 | nGroupExceed = nGrouping; |
1616 | 0 | } |
1617 | 0 | } |
1618 | | |
1619 | | // print the number |
1620 | 18.7M | if (nDigits > 0) |
1621 | 18.7M | { |
1622 | 18.7M | for (int nCurExp = nOrigDigits - 1;;) |
1623 | 298M | { |
1624 | 298M | int nDigit; |
1625 | 298M | if (aParts.significand > 0 && nCurExp > 0) |
1626 | 218M | { |
1627 | 218M | --nCurExp; |
1628 | 218M | nDigit = aParts.significand / eX[nCurExp]; |
1629 | 218M | aParts.significand %= eX[nCurExp]; |
1630 | 218M | } |
1631 | 80.0M | else |
1632 | 80.0M | { |
1633 | 80.0M | nDigit = aParts.significand; |
1634 | 80.0M | aParts.significand = 0; |
1635 | 80.0M | } |
1636 | 298M | assert(nDigit >= 0 && nDigit < 10); |
1637 | 298M | *p++ = nDigit + '0'; |
1638 | | |
1639 | 298M | if (!--nDigits) |
1640 | 18.7M | break; // for |
1641 | | |
1642 | 279M | if (nDecPos) |
1643 | 22.7M | { |
1644 | 22.7M | if (!--nDecPos) |
1645 | 12.2M | { |
1646 | 12.2M | *p++ = cDecSeparator; |
1647 | 12.2M | bHasDec = true; |
1648 | 12.2M | } |
1649 | 10.5M | else if (nDecPos == nGrouping) |
1650 | 0 | { |
1651 | 0 | *p++ = cGroupSeparator; |
1652 | 0 | nGrouping -= pGroups[nGroupSelector]; |
1653 | |
|
1654 | 0 | if (nGroupSelector && nGrouping < nGroupExceed) |
1655 | 0 | --nGroupSelector; |
1656 | 0 | } |
1657 | 22.7M | } |
1658 | 279M | } |
1659 | 18.7M | } |
1660 | | |
1661 | 18.7M | if (!bHasDec && eFormat == rtl_math_StringFormat_F) |
1662 | 1.17M | { // nDecPlaces < 0 did round the value |
1663 | 1.17M | while (--nDecPos > 0) |
1664 | 0 | { // fill before decimal point |
1665 | 0 | if (nDecPos == nGrouping) |
1666 | 0 | { |
1667 | 0 | *p++ = cGroupSeparator; |
1668 | 0 | nGrouping -= pGroups[nGroupSelector]; |
1669 | |
|
1670 | 0 | if (nGroupSelector && nGrouping < nGroupExceed) |
1671 | 0 | --nGroupSelector; |
1672 | 0 | } |
1673 | |
|
1674 | 0 | *p++ = '0'; |
1675 | 0 | } |
1676 | 1.17M | } |
1677 | | |
1678 | 18.7M | if (bEraseTrailingDecZeros && bHasDec) |
1679 | 17.5M | { |
1680 | 95.5M | while (*(p - 1) == '0') |
1681 | 77.9M | p--; |
1682 | | |
1683 | 17.5M | if (*(p - 1) == cDecSeparator) |
1684 | 1.12M | p--; |
1685 | 17.5M | } |
1686 | | |
1687 | | // Print the exponent ('E', followed by '+' or '-', followed by exactly |
1688 | | // three digits for rtl_math_StringFormat_E). The code in |
1689 | | // rtl_[u]str_valueOf{Float|Double} relies on this format. |
1690 | 18.7M | if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 |
1691 | 18.6M | || eFormat == rtl_math_StringFormat_E1) |
1692 | 64.1k | { |
1693 | 64.1k | if (p == pBuf) |
1694 | 0 | *p++ = '1'; |
1695 | | // maybe no nDigits if nDecPlaces < 0 |
1696 | | |
1697 | 64.1k | *p++ = 'E'; |
1698 | 64.1k | if (nExp < 0) |
1699 | 39.9k | { |
1700 | 39.9k | nExp = -nExp; |
1701 | 39.9k | *p++ = '-'; |
1702 | 39.9k | } |
1703 | 24.2k | else |
1704 | 24.2k | *p++ = '+'; |
1705 | | |
1706 | 64.1k | if (eFormat == rtl_math_StringFormat_E || nExp >= 100) |
1707 | 63.9k | *p++ = nExp / 100 + '0'; |
1708 | | |
1709 | 64.1k | nExp %= 100; |
1710 | | |
1711 | 64.1k | if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 || nExp >= 10) |
1712 | 64.1k | *p++ = nExp / 10 + '0'; |
1713 | | |
1714 | 64.1k | *p++ = nExp % 10 + '0'; |
1715 | 64.1k | } |
1716 | | |
1717 | 18.7M | append(pResult, pResultCapacity, nResultOffset, std::basic_string_view(pBuf, p - pBuf)); |
1718 | 18.7M | } _ZN3rtl3str14doubleToStringI11_rtl_StringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_b Line | Count | Source | 1399 | 1.51M | { | 1400 | 1.51M | auto decimalDigits = [](sal_uInt64 n) { | 1401 | 1.51M | return std::distance(std::begin(eX), std::upper_bound(std::begin(eX), std::end(eX), n)) + 1; | 1402 | 1.51M | }; | 1403 | | | 1404 | 1.51M | auto roundToPow10 = [](sal_uInt64 n, int e) { | 1405 | 1.51M | assert(e > 0 && o3tl::make_unsigned(e) <= std::size(eX)); | 1406 | 1.51M | const sal_uInt64 d = eX[e - 1]; | 1407 | 1.51M | return (n + d / 2) / d * d; | 1408 | 1.51M | }; | 1409 | | | 1410 | 1.51M | auto append = [](rtl_tString** s, sal_Int32* pCapacity, sal_Int32 rOffset, auto sv) | 1411 | 1.51M | { | 1412 | 1.51M | if (!pCapacity) | 1413 | 1.51M | newFromStr_WithLength(s, sv.data(), sv.size()); | 1414 | 1.51M | else | 1415 | 1.51M | stringbuffer_insert(s, pCapacity, rOffset, sv.data(), sv.size()); | 1416 | 1.51M | }; | 1417 | | | 1418 | 1.51M | if (std::isnan(fValue)) | 1419 | 0 | { | 1420 | | // #i112652# XMLSchema-2 | 1421 | 0 | static constexpr std::string_view nan{ "NaN" }; | 1422 | 0 | return append(pResult, pResultCapacity, nResultOffset, nan); | 1423 | 0 | } | 1424 | | | 1425 | | // sign adjustment, instead of testing for fValue<0.0 this will also fetch -0.0 | 1426 | 1.51M | bool bSign = std::signbit(fValue); | 1427 | | | 1428 | 1.51M | if (std::isinf(fValue)) | 1429 | 0 | { | 1430 | | // #i112652# XMLSchema-2 | 1431 | 0 | std::string_view inf = bSign ? std::string_view("-INF") : std::string_view("INF"); | 1432 | 0 | return append(pResult, pResultCapacity, nResultOffset, inf); | 1433 | 0 | } | 1434 | | | 1435 | 1.51M | if (bSign) | 1436 | 0 | fValue = -fValue; | 1437 | | | 1438 | 1.51M | decltype(jkj::dragonbox::to_decimal(fValue, jkj::dragonbox::policy::sign::ignore, | 1439 | 1.51M | jkj::dragonbox::policy::trailing_zero::ignore)) aParts{}; | 1440 | 1.51M | if (fValue) // to_decimal is documented to only handle non-zero finite numbers | 1441 | 410k | aParts = jkj::dragonbox::to_decimal(fValue, jkj::dragonbox::policy::sign::ignore, | 1442 | 410k | jkj::dragonbox::policy::trailing_zero::ignore); | 1443 | | | 1444 | 1.51M | int nOrigDigits = decimalDigits(aParts.significand); | 1445 | 1.51M | int nExp = nOrigDigits + aParts.exponent - 1; | 1446 | 1.51M | int nRoundDigits = 15; | 1447 | | | 1448 | | // Unfortunately the old rounding below writes 1.79769313486232e+308 for | 1449 | | // DBL_MAX and 4 subsequent nextafter(...,0). | 1450 | 1.51M | static const double fB1 = std::nextafter(std::numeric_limits<double>::max(), 0); | 1451 | 1.51M | static const double fB2 = std::nextafter(fB1, 0); | 1452 | 1.51M | static const double fB3 = std::nextafter(fB2, 0); | 1453 | 1.51M | static const double fB4 = std::nextafter(fB3, 0); | 1454 | 1.51M | if ((fValue >= fB4) && eFormat != rtl_math_StringFormat_F) | 1455 | 0 | { | 1456 | | // 1.7976931348623157e+308 instead of rounded 1.79769313486232e+308 | 1457 | | // that can't be converted back as out of range. For rounded values if | 1458 | | // they exceed range they should not be written to exchange strings or | 1459 | | // file formats. | 1460 | |
| 1461 | 0 | eFormat = rtl_math_StringFormat_E; | 1462 | 0 | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, 0, 16); | 1463 | 0 | nRoundDigits = 17; | 1464 | 0 | } | 1465 | | | 1466 | | // Use integer representation for integer values that fit into the | 1467 | | // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy. | 1468 | 1.51M | if ((eFormat == rtl_math_StringFormat_Automatic || eFormat == rtl_math_StringFormat_F) | 1469 | 1.39M | && aParts.exponent >= 0 && fValue < 0x1p53) | 1470 | 1.10M | { | 1471 | 1.10M | eFormat = rtl_math_StringFormat_F; | 1472 | 1.10M | if (nDecPlaces == rtl_math_DecimalPlaces_Max) | 1473 | 0 | nDecPlaces = 0; | 1474 | 1.10M | else | 1475 | 1.10M | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, -15, 15); | 1476 | | | 1477 | 1.10M | if (bEraseTrailingDecZeros && nDecPlaces > 0) | 1478 | 1.10M | nDecPlaces = 0; | 1479 | | | 1480 | 1.10M | nRoundDigits = nOrigDigits; // no rounding | 1481 | 1.10M | } | 1482 | | | 1483 | 1.51M | switch (eFormat) | 1484 | 1.51M | { | 1485 | 0 | case rtl_math_StringFormat_Automatic: | 1486 | | // E or F depending on exponent magnitude | 1487 | 0 | if (nExp <= -15 || nExp >= 15) | 1488 | 0 | { | 1489 | 0 | if (nDecPlaces == rtl_math_DecimalPlaces_Max) | 1490 | 0 | nDecPlaces = 14; | 1491 | 0 | eFormat = rtl_math_StringFormat_E; | 1492 | 0 | } | 1493 | 0 | else | 1494 | 0 | { | 1495 | 0 | if (nDecPlaces == rtl_math_DecimalPlaces_Max) | 1496 | 0 | nDecPlaces = (nExp < 14) ? 15 - nExp - 1 : 15; | 1497 | 0 | eFormat = rtl_math_StringFormat_F; | 1498 | 0 | } | 1499 | 0 | break; | 1500 | | | 1501 | 121k | case rtl_math_StringFormat_G: | 1502 | 121k | case rtl_math_StringFormat_G1: | 1503 | 121k | case rtl_math_StringFormat_G2: | 1504 | | // G-Point, similar to sprintf %G | 1505 | 121k | if (nDecPlaces == rtl_math_DecimalPlaces_DefaultSignificance) | 1506 | 0 | nDecPlaces = 6; | 1507 | | | 1508 | 121k | if (nExp < -4 || nExp >= nDecPlaces) | 1509 | 0 | { | 1510 | 0 | nDecPlaces = std::max<sal_Int32>(1, nDecPlaces - 1); | 1511 | |
| 1512 | 0 | if (eFormat == rtl_math_StringFormat_G) | 1513 | 0 | eFormat = rtl_math_StringFormat_E; | 1514 | 0 | else if (eFormat == rtl_math_StringFormat_G2) | 1515 | 0 | eFormat = rtl_math_StringFormat_E2; | 1516 | 0 | else if (eFormat == rtl_math_StringFormat_G1) | 1517 | 0 | eFormat = rtl_math_StringFormat_E1; | 1518 | 0 | } | 1519 | 121k | else | 1520 | 121k | { | 1521 | 121k | if (nOrigDigits <= nDecPlaces && aParts.exponent >= 0 && fValue < 0x1p53) | 1522 | 0 | { | 1523 | | // Use integer representation with highest accuracy. | 1524 | 0 | nRoundDigits = nOrigDigits; // no rounding | 1525 | 0 | } | 1526 | 121k | nDecPlaces = std::max<sal_Int32>(0, nDecPlaces - nExp - 1); | 1527 | 121k | eFormat = rtl_math_StringFormat_F; | 1528 | 121k | } | 1529 | 121k | break; | 1530 | | | 1531 | 1.39M | default: | 1532 | 1.39M | break; | 1533 | 1.51M | } | 1534 | | | 1535 | | // Too large values for nDecPlaces make no sense; it might also be | 1536 | | // rtl_math_DecimalPlaces_Max was passed with rtl_math_StringFormat_F or | 1537 | | // others, but we don't want to allocate/deallocate 2GB just to fill it | 1538 | | // with trailing '0' characters.. | 1539 | 1.51M | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, -309, 309); | 1540 | | | 1541 | 1.51M | sal_Int32 nDigits = nDecPlaces + 1; | 1542 | | | 1543 | 1.51M | if (eFormat == rtl_math_StringFormat_F) | 1544 | 1.51M | nDigits += nExp; | 1545 | | | 1546 | | // Round the number | 1547 | 1.51M | nRoundDigits = std::min<int>(nDigits, nRoundDigits); | 1548 | 1.51M | if (nDigits >= 0 && nOrigDigits > nRoundDigits) | 1549 | 349k | { | 1550 | 349k | aParts.significand = roundToPow10(aParts.significand, nOrigDigits - nRoundDigits); | 1551 | 349k | assert(aParts.significand <= eX[nOrigDigits - 1]); | 1552 | 349k | if (aParts.significand == eX[nOrigDigits - 1]) // up-rounding to the next decade | 1553 | 0 | { | 1554 | 0 | nOrigDigits++; | 1555 | 0 | nExp++; | 1556 | |
| 1557 | 0 | if (eFormat == rtl_math_StringFormat_F) | 1558 | 0 | nDigits++; | 1559 | 0 | } | 1560 | 349k | } | 1561 | | | 1562 | 1.51M | sal_Int32 nBuf | 1563 | 1.51M | = (nDigits <= 0 ? std::max<sal_Int32>(nDecPlaces, std::abs(nExp)) : nDigits + nDecPlaces) | 1564 | 1.51M | + 10 + (pGroups ? std::abs(nDigits) * 2 : 0); | 1565 | | // max(nDigits) = max(nDecPlaces) + 1 + max(nExp) + 1 = 309 + 1 + 308 + 1 = 619 | 1566 | | // max(nBuf) = max(nDigits) + max(nDecPlaces) + 10 + max(nDigits) * 2 = 619 * 3 + 309 + 10 = 2176 | 1567 | 1.51M | assert(nBuf <= 2176); | 1568 | 1.51M | auto* const pBuf = static_cast<Char_T<rtl_tString>*>(alloca(nBuf * sizeof(Char_T<rtl_tString>))); | 1569 | 1.51M | auto* p = pBuf; | 1570 | 1.51M | if (bSign) | 1571 | 0 | *p++ = '-'; | 1572 | | | 1573 | 1.51M | bool bHasDec = false; | 1574 | | | 1575 | 1.51M | int nDecPos; | 1576 | | // Check for F format and number < 1 | 1577 | 1.51M | if (eFormat == rtl_math_StringFormat_F) | 1578 | 1.51M | { | 1579 | 1.51M | if (nExp < 0) | 1580 | 127k | { | 1581 | 127k | *p++ = '0'; | 1582 | 127k | if (nDecPlaces > 0) | 1583 | 127k | { | 1584 | 127k | *p++ = cDecSeparator; | 1585 | 127k | bHasDec = true; | 1586 | 127k | } | 1587 | | | 1588 | 127k | sal_Int32 i = (nDigits <= 0 ? nDecPlaces : -nExp - 1); | 1589 | | | 1590 | 190k | while ((i--) > 0) | 1591 | 62.6k | *p++ = '0'; | 1592 | | | 1593 | 127k | nDecPos = 0; | 1594 | 127k | } | 1595 | 1.38M | else | 1596 | 1.38M | nDecPos = nExp + 1; | 1597 | 1.51M | } | 1598 | 0 | else | 1599 | 0 | nDecPos = 1; | 1600 | | | 1601 | 1.51M | int nGrouping = 0, nGroupSelector = 0, nGroupExceed = 0; | 1602 | 1.51M | if (nDecPos > 1 && pGroups && pGroups[0] && cGroupSeparator) | 1603 | 0 | { | 1604 | 0 | while (nGrouping + pGroups[nGroupSelector] < nDecPos) | 1605 | 0 | { | 1606 | 0 | nGrouping += pGroups[nGroupSelector]; | 1607 | 0 | if (pGroups[nGroupSelector + 1]) | 1608 | 0 | { | 1609 | 0 | if (nGrouping + pGroups[nGroupSelector + 1] >= nDecPos) | 1610 | 0 | break; // while | 1611 | | | 1612 | 0 | ++nGroupSelector; | 1613 | 0 | } | 1614 | 0 | else if (!nGroupExceed) | 1615 | 0 | nGroupExceed = nGrouping; | 1616 | 0 | } | 1617 | 0 | } | 1618 | | | 1619 | | // print the number | 1620 | 1.51M | if (nDigits > 0) | 1621 | 1.51M | { | 1622 | 1.51M | for (int nCurExp = nOrigDigits - 1;;) | 1623 | 5.10M | { | 1624 | 5.10M | int nDigit; | 1625 | 5.10M | if (aParts.significand > 0 && nCurExp > 0) | 1626 | 2.72M | { | 1627 | 2.72M | --nCurExp; | 1628 | 2.72M | nDigit = aParts.significand / eX[nCurExp]; | 1629 | 2.72M | aParts.significand %= eX[nCurExp]; | 1630 | 2.72M | } | 1631 | 2.37M | else | 1632 | 2.37M | { | 1633 | 2.37M | nDigit = aParts.significand; | 1634 | 2.37M | aParts.significand = 0; | 1635 | 2.37M | } | 1636 | 5.10M | assert(nDigit >= 0 && nDigit < 10); | 1637 | 5.10M | *p++ = nDigit + '0'; | 1638 | | | 1639 | 5.10M | if (!--nDigits) | 1640 | 1.51M | break; // for | 1641 | | | 1642 | 3.59M | if (nDecPos) | 1643 | 767k | { | 1644 | 767k | if (!--nDecPos) | 1645 | 282k | { | 1646 | 282k | *p++ = cDecSeparator; | 1647 | 282k | bHasDec = true; | 1648 | 282k | } | 1649 | 485k | else if (nDecPos == nGrouping) | 1650 | 0 | { | 1651 | 0 | *p++ = cGroupSeparator; | 1652 | 0 | nGrouping -= pGroups[nGroupSelector]; | 1653 | |
| 1654 | 0 | if (nGroupSelector && nGrouping < nGroupExceed) | 1655 | 0 | --nGroupSelector; | 1656 | 0 | } | 1657 | 767k | } | 1658 | 3.59M | } | 1659 | 1.51M | } | 1660 | | | 1661 | 1.51M | if (!bHasDec && eFormat == rtl_math_StringFormat_F) | 1662 | 1.10M | { // nDecPlaces < 0 did round the value | 1663 | 1.10M | while (--nDecPos > 0) | 1664 | 0 | { // fill before decimal point | 1665 | 0 | if (nDecPos == nGrouping) | 1666 | 0 | { | 1667 | 0 | *p++ = cGroupSeparator; | 1668 | 0 | nGrouping -= pGroups[nGroupSelector]; | 1669 | |
| 1670 | 0 | if (nGroupSelector && nGrouping < nGroupExceed) | 1671 | 0 | --nGroupSelector; | 1672 | 0 | } | 1673 | |
| 1674 | 0 | *p++ = '0'; | 1675 | 0 | } | 1676 | 1.10M | } | 1677 | | | 1678 | 1.51M | if (bEraseTrailingDecZeros && bHasDec) | 1679 | 410k | { | 1680 | 1.62M | while (*(p - 1) == '0') | 1681 | 1.21M | p--; | 1682 | | | 1683 | 410k | if (*(p - 1) == cDecSeparator) | 1684 | 41.4k | p--; | 1685 | 410k | } | 1686 | | | 1687 | | // Print the exponent ('E', followed by '+' or '-', followed by exactly | 1688 | | // three digits for rtl_math_StringFormat_E). The code in | 1689 | | // rtl_[u]str_valueOf{Float|Double} relies on this format. | 1690 | 1.51M | if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 | 1691 | 1.51M | || eFormat == rtl_math_StringFormat_E1) | 1692 | 0 | { | 1693 | 0 | if (p == pBuf) | 1694 | 0 | *p++ = '1'; | 1695 | | // maybe no nDigits if nDecPlaces < 0 | 1696 | |
| 1697 | 0 | *p++ = 'E'; | 1698 | 0 | if (nExp < 0) | 1699 | 0 | { | 1700 | 0 | nExp = -nExp; | 1701 | 0 | *p++ = '-'; | 1702 | 0 | } | 1703 | 0 | else | 1704 | 0 | *p++ = '+'; | 1705 | |
| 1706 | 0 | if (eFormat == rtl_math_StringFormat_E || nExp >= 100) | 1707 | 0 | *p++ = nExp / 100 + '0'; | 1708 | |
| 1709 | 0 | nExp %= 100; | 1710 | |
| 1711 | 0 | if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 || nExp >= 10) | 1712 | 0 | *p++ = nExp / 10 + '0'; | 1713 | |
| 1714 | 0 | *p++ = nExp % 10 + '0'; | 1715 | 0 | } | 1716 | | | 1717 | 1.51M | append(pResult, pResultCapacity, nResultOffset, std::basic_string_view(pBuf, p - pBuf)); | 1718 | 1.51M | } |
_ZN3rtl3str14doubleToStringI12_rtl_uStringEEvPPT_Piid21rtl_math_StringFormatiu15__remove_extentIDtsrS3_6bufferEEPKiS9_b Line | Count | Source | 1399 | 17.2M | { | 1400 | 17.2M | auto decimalDigits = [](sal_uInt64 n) { | 1401 | 17.2M | return std::distance(std::begin(eX), std::upper_bound(std::begin(eX), std::end(eX), n)) + 1; | 1402 | 17.2M | }; | 1403 | | | 1404 | 17.2M | auto roundToPow10 = [](sal_uInt64 n, int e) { | 1405 | 17.2M | assert(e > 0 && o3tl::make_unsigned(e) <= std::size(eX)); | 1406 | 17.2M | const sal_uInt64 d = eX[e - 1]; | 1407 | 17.2M | return (n + d / 2) / d * d; | 1408 | 17.2M | }; | 1409 | | | 1410 | 17.2M | auto append = [](rtl_tString** s, sal_Int32* pCapacity, sal_Int32 rOffset, auto sv) | 1411 | 17.2M | { | 1412 | 17.2M | if (!pCapacity) | 1413 | 17.2M | newFromStr_WithLength(s, sv.data(), sv.size()); | 1414 | 17.2M | else | 1415 | 17.2M | stringbuffer_insert(s, pCapacity, rOffset, sv.data(), sv.size()); | 1416 | 17.2M | }; | 1417 | | | 1418 | 17.2M | if (std::isnan(fValue)) | 1419 | 1.81k | { | 1420 | | // #i112652# XMLSchema-2 | 1421 | 1.81k | static constexpr std::string_view nan{ "NaN" }; | 1422 | 1.81k | return append(pResult, pResultCapacity, nResultOffset, nan); | 1423 | 1.81k | } | 1424 | | | 1425 | | // sign adjustment, instead of testing for fValue<0.0 this will also fetch -0.0 | 1426 | 17.2M | bool bSign = std::signbit(fValue); | 1427 | | | 1428 | 17.2M | if (std::isinf(fValue)) | 1429 | 307 | { | 1430 | | // #i112652# XMLSchema-2 | 1431 | 307 | std::string_view inf = bSign ? std::string_view("-INF") : std::string_view("INF"); | 1432 | 307 | return append(pResult, pResultCapacity, nResultOffset, inf); | 1433 | 307 | } | 1434 | | | 1435 | 17.2M | if (bSign) | 1436 | 337k | fValue = -fValue; | 1437 | | | 1438 | 17.2M | decltype(jkj::dragonbox::to_decimal(fValue, jkj::dragonbox::policy::sign::ignore, | 1439 | 17.2M | jkj::dragonbox::policy::trailing_zero::ignore)) aParts{}; | 1440 | 17.2M | if (fValue) // to_decimal is documented to only handle non-zero finite numbers | 1441 | 16.6M | aParts = jkj::dragonbox::to_decimal(fValue, jkj::dragonbox::policy::sign::ignore, | 1442 | 16.6M | jkj::dragonbox::policy::trailing_zero::ignore); | 1443 | | | 1444 | 17.2M | int nOrigDigits = decimalDigits(aParts.significand); | 1445 | 17.2M | int nExp = nOrigDigits + aParts.exponent - 1; | 1446 | 17.2M | int nRoundDigits = 15; | 1447 | | | 1448 | | // Unfortunately the old rounding below writes 1.79769313486232e+308 for | 1449 | | // DBL_MAX and 4 subsequent nextafter(...,0). | 1450 | 17.2M | static const double fB1 = std::nextafter(std::numeric_limits<double>::max(), 0); | 1451 | 17.2M | static const double fB2 = std::nextafter(fB1, 0); | 1452 | 17.2M | static const double fB3 = std::nextafter(fB2, 0); | 1453 | 17.2M | static const double fB4 = std::nextafter(fB3, 0); | 1454 | 17.2M | if ((fValue >= fB4) && eFormat != rtl_math_StringFormat_F) | 1455 | 591 | { | 1456 | | // 1.7976931348623157e+308 instead of rounded 1.79769313486232e+308 | 1457 | | // that can't be converted back as out of range. For rounded values if | 1458 | | // they exceed range they should not be written to exchange strings or | 1459 | | // file formats. | 1460 | | | 1461 | 591 | eFormat = rtl_math_StringFormat_E; | 1462 | 591 | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, 0, 16); | 1463 | 591 | nRoundDigits = 17; | 1464 | 591 | } | 1465 | | | 1466 | | // Use integer representation for integer values that fit into the | 1467 | | // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy. | 1468 | 17.2M | if ((eFormat == rtl_math_StringFormat_Automatic || eFormat == rtl_math_StringFormat_F) | 1469 | 522k | && aParts.exponent >= 0 && fValue < 0x1p53) | 1470 | 37.5k | { | 1471 | 37.5k | eFormat = rtl_math_StringFormat_F; | 1472 | 37.5k | if (nDecPlaces == rtl_math_DecimalPlaces_Max) | 1473 | 27.6k | nDecPlaces = 0; | 1474 | 9.81k | else | 1475 | 9.81k | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, -15, 15); | 1476 | | | 1477 | 37.5k | if (bEraseTrailingDecZeros && nDecPlaces > 0) | 1478 | 5.88k | nDecPlaces = 0; | 1479 | | | 1480 | 37.5k | nRoundDigits = nOrigDigits; // no rounding | 1481 | 37.5k | } | 1482 | | | 1483 | 17.2M | switch (eFormat) | 1484 | 17.2M | { | 1485 | 408k | case rtl_math_StringFormat_Automatic: | 1486 | | // E or F depending on exponent magnitude | 1487 | 408k | if (nExp <= -15 || nExp >= 15) | 1488 | 11.6k | { | 1489 | 11.6k | if (nDecPlaces == rtl_math_DecimalPlaces_Max) | 1490 | 11.6k | nDecPlaces = 14; | 1491 | 11.6k | eFormat = rtl_math_StringFormat_E; | 1492 | 11.6k | } | 1493 | 396k | else | 1494 | 396k | { | 1495 | 396k | if (nDecPlaces == rtl_math_DecimalPlaces_Max) | 1496 | 396k | nDecPlaces = (nExp < 14) ? 15 - nExp - 1 : 15; | 1497 | 396k | eFormat = rtl_math_StringFormat_F; | 1498 | 396k | } | 1499 | 408k | break; | 1500 | | | 1501 | 16.6M | case rtl_math_StringFormat_G: | 1502 | 16.6M | case rtl_math_StringFormat_G1: | 1503 | 16.6M | case rtl_math_StringFormat_G2: | 1504 | | // G-Point, similar to sprintf %G | 1505 | 16.6M | if (nDecPlaces == rtl_math_DecimalPlaces_DefaultSignificance) | 1506 | 0 | nDecPlaces = 6; | 1507 | | | 1508 | 16.6M | if (nExp < -4 || nExp >= nDecPlaces) | 1509 | 47.1k | { | 1510 | 47.1k | nDecPlaces = std::max<sal_Int32>(1, nDecPlaces - 1); | 1511 | | | 1512 | 47.1k | if (eFormat == rtl_math_StringFormat_G) | 1513 | 47.1k | eFormat = rtl_math_StringFormat_E; | 1514 | 0 | else if (eFormat == rtl_math_StringFormat_G2) | 1515 | 0 | eFormat = rtl_math_StringFormat_E2; | 1516 | 0 | else if (eFormat == rtl_math_StringFormat_G1) | 1517 | 0 | eFormat = rtl_math_StringFormat_E1; | 1518 | 47.1k | } | 1519 | 16.6M | else | 1520 | 16.6M | { | 1521 | 16.6M | if (nOrigDigits <= nDecPlaces && aParts.exponent >= 0 && fValue < 0x1p53) | 1522 | 579k | { | 1523 | | // Use integer representation with highest accuracy. | 1524 | 579k | nRoundDigits = nOrigDigits; // no rounding | 1525 | 579k | } | 1526 | 16.6M | nDecPlaces = std::max<sal_Int32>(0, nDecPlaces - nExp - 1); | 1527 | 16.6M | eFormat = rtl_math_StringFormat_F; | 1528 | 16.6M | } | 1529 | 16.6M | break; | 1530 | | | 1531 | 119k | default: | 1532 | 119k | break; | 1533 | 17.2M | } | 1534 | | | 1535 | | // Too large values for nDecPlaces make no sense; it might also be | 1536 | | // rtl_math_DecimalPlaces_Max was passed with rtl_math_StringFormat_F or | 1537 | | // others, but we don't want to allocate/deallocate 2GB just to fill it | 1538 | | // with trailing '0' characters.. | 1539 | 17.2M | nDecPlaces = std::clamp<sal_Int32>(nDecPlaces, -309, 309); | 1540 | | | 1541 | 17.2M | sal_Int32 nDigits = nDecPlaces + 1; | 1542 | | | 1543 | 17.2M | if (eFormat == rtl_math_StringFormat_F) | 1544 | 17.1M | nDigits += nExp; | 1545 | | | 1546 | | // Round the number | 1547 | 17.2M | nRoundDigits = std::min<int>(nDigits, nRoundDigits); | 1548 | 17.2M | if (nDigits >= 0 && nOrigDigits > nRoundDigits) | 1549 | 16.0M | { | 1550 | 16.0M | aParts.significand = roundToPow10(aParts.significand, nOrigDigits - nRoundDigits); | 1551 | 16.0M | assert(aParts.significand <= eX[nOrigDigits - 1]); | 1552 | 16.0M | if (aParts.significand == eX[nOrigDigits - 1]) // up-rounding to the next decade | 1553 | 670 | { | 1554 | 670 | nOrigDigits++; | 1555 | 670 | nExp++; | 1556 | | | 1557 | 670 | if (eFormat == rtl_math_StringFormat_F) | 1558 | 314 | nDigits++; | 1559 | 670 | } | 1560 | 16.0M | } | 1561 | | | 1562 | 17.2M | sal_Int32 nBuf | 1563 | 17.2M | = (nDigits <= 0 ? std::max<sal_Int32>(nDecPlaces, std::abs(nExp)) : nDigits + nDecPlaces) | 1564 | 17.2M | + 10 + (pGroups ? std::abs(nDigits) * 2 : 0); | 1565 | | // max(nDigits) = max(nDecPlaces) + 1 + max(nExp) + 1 = 309 + 1 + 308 + 1 = 619 | 1566 | | // max(nBuf) = max(nDigits) + max(nDecPlaces) + 10 + max(nDigits) * 2 = 619 * 3 + 309 + 10 = 2176 | 1567 | 17.2M | assert(nBuf <= 2176); | 1568 | 17.2M | auto* const pBuf = static_cast<Char_T<rtl_tString>*>(alloca(nBuf * sizeof(Char_T<rtl_tString>))); | 1569 | 17.2M | auto* p = pBuf; | 1570 | 17.2M | if (bSign) | 1571 | 337k | *p++ = '-'; | 1572 | | | 1573 | 17.2M | bool bHasDec = false; | 1574 | | | 1575 | 17.2M | int nDecPos; | 1576 | | // Check for F format and number < 1 | 1577 | 17.2M | if (eFormat == rtl_math_StringFormat_F) | 1578 | 17.1M | { | 1579 | 17.1M | if (nExp < 0) | 1580 | 5.21M | { | 1581 | 5.21M | *p++ = '0'; | 1582 | 5.21M | if (nDecPlaces > 0) | 1583 | 5.21M | { | 1584 | 5.21M | *p++ = cDecSeparator; | 1585 | 5.21M | bHasDec = true; | 1586 | 5.21M | } | 1587 | | | 1588 | 5.21M | sal_Int32 i = (nDigits <= 0 ? nDecPlaces : -nExp - 1); | 1589 | | | 1590 | 9.76M | while ((i--) > 0) | 1591 | 4.54M | *p++ = '0'; | 1592 | | | 1593 | 5.21M | nDecPos = 0; | 1594 | 5.21M | } | 1595 | 11.9M | else | 1596 | 11.9M | nDecPos = nExp + 1; | 1597 | 17.1M | } | 1598 | 64.1k | else | 1599 | 64.1k | nDecPos = 1; | 1600 | | | 1601 | 17.2M | int nGrouping = 0, nGroupSelector = 0, nGroupExceed = 0; | 1602 | 17.2M | if (nDecPos > 1 && pGroups && pGroups[0] && cGroupSeparator) | 1603 | 0 | { | 1604 | 0 | while (nGrouping + pGroups[nGroupSelector] < nDecPos) | 1605 | 0 | { | 1606 | 0 | nGrouping += pGroups[nGroupSelector]; | 1607 | 0 | if (pGroups[nGroupSelector + 1]) | 1608 | 0 | { | 1609 | 0 | if (nGrouping + pGroups[nGroupSelector + 1] >= nDecPos) | 1610 | 0 | break; // while | 1611 | | | 1612 | 0 | ++nGroupSelector; | 1613 | 0 | } | 1614 | 0 | else if (!nGroupExceed) | 1615 | 0 | nGroupExceed = nGrouping; | 1616 | 0 | } | 1617 | 0 | } | 1618 | | | 1619 | | // print the number | 1620 | 17.2M | if (nDigits > 0) | 1621 | 17.2M | { | 1622 | 17.2M | for (int nCurExp = nOrigDigits - 1;;) | 1623 | 293M | { | 1624 | 293M | int nDigit; | 1625 | 293M | if (aParts.significand > 0 && nCurExp > 0) | 1626 | 215M | { | 1627 | 215M | --nCurExp; | 1628 | 215M | nDigit = aParts.significand / eX[nCurExp]; | 1629 | 215M | aParts.significand %= eX[nCurExp]; | 1630 | 215M | } | 1631 | 77.7M | else | 1632 | 77.7M | { | 1633 | 77.7M | nDigit = aParts.significand; | 1634 | 77.7M | aParts.significand = 0; | 1635 | 77.7M | } | 1636 | 293M | assert(nDigit >= 0 && nDigit < 10); | 1637 | 293M | *p++ = nDigit + '0'; | 1638 | | | 1639 | 293M | if (!--nDigits) | 1640 | 17.2M | break; // for | 1641 | | | 1642 | 275M | if (nDecPos) | 1643 | 21.9M | { | 1644 | 21.9M | if (!--nDecPos) | 1645 | 11.9M | { | 1646 | 11.9M | *p++ = cDecSeparator; | 1647 | 11.9M | bHasDec = true; | 1648 | 11.9M | } | 1649 | 10.0M | else if (nDecPos == nGrouping) | 1650 | 0 | { | 1651 | 0 | *p++ = cGroupSeparator; | 1652 | 0 | nGrouping -= pGroups[nGroupSelector]; | 1653 | |
| 1654 | 0 | if (nGroupSelector && nGrouping < nGroupExceed) | 1655 | 0 | --nGroupSelector; | 1656 | 0 | } | 1657 | 21.9M | } | 1658 | 275M | } | 1659 | 17.2M | } | 1660 | | | 1661 | 17.2M | if (!bHasDec && eFormat == rtl_math_StringFormat_F) | 1662 | 69.6k | { // nDecPlaces < 0 did round the value | 1663 | 69.6k | while (--nDecPos > 0) | 1664 | 0 | { // fill before decimal point | 1665 | 0 | if (nDecPos == nGrouping) | 1666 | 0 | { | 1667 | 0 | *p++ = cGroupSeparator; | 1668 | 0 | nGrouping -= pGroups[nGroupSelector]; | 1669 | |
| 1670 | 0 | if (nGroupSelector && nGrouping < nGroupExceed) | 1671 | 0 | --nGroupSelector; | 1672 | 0 | } | 1673 | |
| 1674 | 0 | *p++ = '0'; | 1675 | 0 | } | 1676 | 69.6k | } | 1677 | | | 1678 | 17.2M | if (bEraseTrailingDecZeros && bHasDec) | 1679 | 17.1M | { | 1680 | 93.8M | while (*(p - 1) == '0') | 1681 | 76.7M | p--; | 1682 | | | 1683 | 17.1M | if (*(p - 1) == cDecSeparator) | 1684 | 1.08M | p--; | 1685 | 17.1M | } | 1686 | | | 1687 | | // Print the exponent ('E', followed by '+' or '-', followed by exactly | 1688 | | // three digits for rtl_math_StringFormat_E). The code in | 1689 | | // rtl_[u]str_valueOf{Float|Double} relies on this format. | 1690 | 17.2M | if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 | 1691 | 17.1M | || eFormat == rtl_math_StringFormat_E1) | 1692 | 64.1k | { | 1693 | 64.1k | if (p == pBuf) | 1694 | 0 | *p++ = '1'; | 1695 | | // maybe no nDigits if nDecPlaces < 0 | 1696 | | | 1697 | 64.1k | *p++ = 'E'; | 1698 | 64.1k | if (nExp < 0) | 1699 | 39.9k | { | 1700 | 39.9k | nExp = -nExp; | 1701 | 39.9k | *p++ = '-'; | 1702 | 39.9k | } | 1703 | 24.2k | else | 1704 | 24.2k | *p++ = '+'; | 1705 | | | 1706 | 64.1k | if (eFormat == rtl_math_StringFormat_E || nExp >= 100) | 1707 | 63.9k | *p++ = nExp / 100 + '0'; | 1708 | | | 1709 | 64.1k | nExp %= 100; | 1710 | | | 1711 | 64.1k | if (eFormat == rtl_math_StringFormat_E || eFormat == rtl_math_StringFormat_E2 || nExp >= 10) | 1712 | 64.1k | *p++ = nExp / 10 + '0'; | 1713 | | | 1714 | 64.1k | *p++ = nExp % 10 + '0'; | 1715 | 64.1k | } | 1716 | | | 1717 | 17.2M | append(pResult, pResultCapacity, nResultOffset, std::basic_string_view(pBuf, p - pBuf)); | 1718 | 17.2M | } |
|
1719 | | |
1720 | | template <sal_Int32 maxLen, typename C, typename T> sal_Int32 SAL_CALL valueOfFP(C* pStr, T f) |
1721 | 0 | { |
1722 | 0 | assert(pStr); |
1723 | 0 | rtl_String* pResult = nullptr; |
1724 | 0 | doubleToString(&pResult, nullptr, 0, f, rtl_math_StringFormat_G, |
1725 | 0 | maxLen - std::size("-x.E-xxx") + 1, '.', nullptr, 0, true); |
1726 | 0 | const sal_Int32 nLen = pResult->length; |
1727 | | assert(nLen < maxLen); |
1728 | 0 | Copy(pStr, pResult->buffer, nLen + 1); |
1729 | 0 | release(pResult); |
1730 | 0 | return nLen; |
1731 | 0 | } Unexecuted instantiation: int rtl::str::valueOfFP<15, char, float>(char*, float) Unexecuted instantiation: int rtl::str::valueOfFP<25, char, double>(char*, double) Unexecuted instantiation: int rtl::str::valueOfFP<15, char16_t, float>(char16_t*, float) Unexecuted instantiation: int rtl::str::valueOfFP<25, char16_t, double>(char16_t*, double) |
1732 | | |
1733 | | } |
1734 | | |
1735 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |