Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fx_string.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "core/fxcrt/fx_string.h"
8
9#include <stdint.h>
10
11#include <iterator>
12
13#include "build/build_config.h"
14#include "core/fxcrt/bytestring.h"
15#include "core/fxcrt/code_point_view.h"
16#include "core/fxcrt/fx_extension.h"
17#include "core/fxcrt/span_util.h"
18#include "core/fxcrt/string_view_template.h"
19#include "core/fxcrt/utf16.h"
20#include "core/fxcrt/widestring.h"
21#include "third_party/base/compiler_specific.h"
22#include "third_party/base/containers/span.h"
23
24#if !defined(WCHAR_T_IS_16_BIT) && !defined(WCHAR_T_IS_32_BIT)
25#error "Unknown wchar_t size"
26#endif
27#if defined(WCHAR_T_IS_16_BIT) && defined(WCHAR_T_IS_32_BIT)
28#error "Conflicting wchar_t sizes"
29#endif
30
31namespace {
32
33// Appends a Unicode code point to a `ByteString` using UTF-8.
34//
35// TODO(crbug.com/pdfium/2041): Migrate to `ByteString`.
36void AppendCodePointToByteString(char32_t code_point, ByteString& buffer) {
37 if (code_point > pdfium::kMaximumSupplementaryCodePoint) {
38 // Invalid code point above U+10FFFF.
39 return;
40 }
41
42 if (code_point < 0x80) {
43 // 7-bit code points are unchanged in UTF-8.
44 buffer += code_point;
45 return;
46 }
47
48 int byte_size;
49 if (code_point < 0x800) {
50 byte_size = 2;
51 } else if (code_point < 0x10000) {
52 byte_size = 3;
53 } else {
54 byte_size = 4;
55 }
56
57 static constexpr uint8_t kPrefix[] = {0xc0, 0xe0, 0xf0};
58 int order = 1 << ((byte_size - 1) * 6);
59 buffer += kPrefix[byte_size - 2] | (code_point / order);
60 for (int i = 0; i < byte_size - 1; i++) {
61 code_point = code_point % order;
62 order >>= 6;
63 buffer += 0x80 | (code_point / order);
64 }
65}
66
67} // namespace
68
69ByteString FX_UTF8Encode(WideStringView wsStr) {
70 ByteString buffer;
71 for (char32_t code_point : pdfium::CodePointView(wsStr)) {
72 AppendCodePointToByteString(code_point, buffer);
73 }
74 return buffer;
75}
76
77std::u16string FX_UTF16Encode(WideStringView wsStr) {
78 if (wsStr.IsEmpty()) {
79 return {};
80 }
81
82 std::u16string result;
83 result.reserve(wsStr.GetLength());
84
85 for (wchar_t c : wsStr) {
86#if defined(WCHAR_T_IS_32_BIT)
87 if (pdfium::IsSupplementary(c)) {
88 pdfium::SurrogatePair pair(c);
89 result.push_back(pair.high());
90 result.push_back(pair.low());
91 continue;
92 }
93#endif // defined(WCHAR_T_IS_32_BIT)
94 result.push_back(c);
95 }
96
97 return result;
98}
99
100namespace {
101
102constexpr float kFractionScalesFloat[] = {
103 0.1f, 0.01f, 0.001f, 0.0001f,
104 0.00001f, 0.000001f, 0.0000001f, 0.00000001f,
105 0.000000001f, 0.0000000001f, 0.00000000001f};
106
107const double kFractionScalesDouble[] = {
108 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,
109 0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001};
110
111template <class T>
112T StringTo(ByteStringView strc, pdfium::span<const T> fractional_scales) {
113 if (strc.IsEmpty())
114 return 0;
115
116 bool bNegative = false;
117 size_t cc = 0;
118 size_t len = strc.GetLength();
119 if (strc[0] == '+') {
120 cc++;
121 } else if (strc[0] == '-') {
122 bNegative = true;
123 cc++;
124 }
125 while (cc < len) {
126 if (strc[cc] != '+' && strc[cc] != '-')
127 break;
128 cc++;
129 }
130 T value = 0;
131 while (cc < len) {
132 if (strc[cc] == '.')
133 break;
134 value = value * 10 + FXSYS_DecimalCharToInt(strc.CharAt(cc));
135 cc++;
136 }
137 size_t scale = 0;
138 if (cc < len && strc[cc] == '.') {
139 cc++;
140 while (cc < len) {
141 value +=
142 fractional_scales[scale] * FXSYS_DecimalCharToInt(strc.CharAt(cc));
143 scale++;
144 if (scale == fractional_scales.size())
145 break;
146 cc++;
147 }
148 }
149 return bNegative ? -value : value;
150}
151
152template <class T>
153size_t ToString(T value, int (*round_func)(T), pdfium::span<char> buf) {
154 buf[0] = '0';
155 buf[1] = '\0';
156 if (value == 0) {
157 return 1;
158 }
159 bool bNegative = false;
160 if (value < 0) {
161 bNegative = true;
162 value = -value;
163 }
164 int scale = 1;
165 int scaled = round_func(value);
166 while (scaled < 100000) {
167 if (scale == 1000000) {
168 break;
169 }
170 scale *= 10;
171 scaled = round_func(value * scale);
172 }
173 if (scaled == 0) {
174 return 1;
175 }
176 char buf2[32];
177 size_t buf_size = 0;
178 if (bNegative) {
179 buf[buf_size++] = '-';
180 }
181 int i = scaled / scale;
182 FXSYS_itoa(i, buf2, 10);
183 size_t len = strlen(buf2);
184 fxcrt::spancpy(buf.subspan(buf_size), pdfium::make_span(buf2).first(len));
185 buf_size += len;
186 int fraction = scaled % scale;
187 if (fraction == 0) {
188 return buf_size;
189 }
190 buf[buf_size++] = '.';
191 scale /= 10;
192 while (fraction) {
193 buf[buf_size++] = '0' + fraction / scale;
194 fraction %= scale;
195 scale /= 10;
196 }
197 return buf_size;
198}
199
200} // namespace
201
202float StringToFloat(ByteStringView strc) {
203 return StringTo<float>(strc, kFractionScalesFloat);
204}
205
206float StringToFloat(WideStringView wsStr) {
207 return StringToFloat(FX_UTF8Encode(wsStr).AsStringView());
208}
209
210size_t FloatToString(float f, pdfium::span<char> buf) {
211 return ToString<float>(f, FXSYS_roundf, buf);
212}
213
214double StringToDouble(ByteStringView strc) {
215 return StringTo<double>(strc, kFractionScalesDouble);
216}
217
218double StringToDouble(WideStringView wsStr) {
219 return StringToDouble(FX_UTF8Encode(wsStr).AsStringView());
220}
221
222size_t DoubleToString(double d, pdfium::span<char> buf) {
223 return ToString<double>(d, FXSYS_round, buf);
224}
225
226namespace fxcrt {
227
232
233} // namespace fxcrt
ByteString & operator+=(char ch)
size_t FloatToString(float f, pdfium::span< char > buf)
double StringToDouble(WideStringView wsStr)
float StringToFloat(ByteStringView str)
ByteString FX_UTF8Encode(WideStringView wsStr)
Definition fx_string.cpp:69
std::u16string FX_UTF16Encode(WideStringView wsStr)
Definition fx_string.cpp:77
size_t DoubleToString(double d, pdfium::span< char > buf)
float StringToFloat(WideStringView wsStr)
double StringToDouble(ByteStringView str)
int FXSYS_roundf(float f)
Definition fx_system.cpp:92
int FXSYS_round(double d)
char * FXSYS_itoa(int value, char *str, int radix)
constexpr char32_t kMaximumSupplementaryCodePoint
Definition utf16.h:22