1 // Copyright 2017 PDFium Authors. All rights reserved.
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 <limits>
10 #include <vector>
11
12 #include "core/fxcrt/cfx_utf8decoder.h"
13 #include "core/fxcrt/cfx_utf8encoder.h"
14 #include "core/fxcrt/fx_extension.h"
15 #include "third_party/base/compiler_specific.h"
16
FX_UTF8Encode(WideStringView wsStr)17 ByteString FX_UTF8Encode(WideStringView wsStr) {
18 CFX_UTF8Encoder encoder;
19 for (size_t i = 0; i < wsStr.GetLength(); ++i)
20 encoder.Input(wsStr[i]);
21
22 return ByteString(encoder.GetResult());
23 }
24
FX_UTF8Decode(ByteStringView bsStr)25 WideString FX_UTF8Decode(ByteStringView bsStr) {
26 if (bsStr.IsEmpty())
27 return WideString();
28
29 CFX_UTF8Decoder decoder;
30 for (size_t i = 0; i < bsStr.GetLength(); i++)
31 decoder.Input(bsStr[i]);
32
33 return WideString(decoder.GetResult());
34 }
35
36 namespace {
37
38 constexpr float kFractionScalesFloat[] = {
39 0.1f, 0.01f, 0.001f, 0.0001f,
40 0.00001f, 0.000001f, 0.0000001f, 0.00000001f,
41 0.000000001f, 0.0000000001f, 0.00000000001f};
42
43 const double kFractionScalesDouble[] = {
44 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,
45 0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001};
46
47 template <class T>
StringTo(ByteStringView strc,const T fractional_scales[],size_t fractional_scales_size)48 T StringTo(ByteStringView strc,
49 const T fractional_scales[],
50 size_t fractional_scales_size) {
51 if (strc.IsEmpty())
52 return 0;
53
54 int cc = 0;
55 bool bNegative = false;
56 int len = strc.GetLength();
57 if (strc[0] == '+') {
58 cc++;
59 } else if (strc[0] == '-') {
60 bNegative = true;
61 cc++;
62 }
63 while (cc < len) {
64 if (strc[cc] != '+' && strc[cc] != '-')
65 break;
66 cc++;
67 }
68 T value = 0;
69 while (cc < len) {
70 if (strc[cc] == '.')
71 break;
72 value = value * 10 + FXSYS_DecimalCharToInt(strc.CharAt(cc));
73 cc++;
74 }
75 size_t scale = 0;
76 if (cc < len && strc[cc] == '.') {
77 cc++;
78 while (cc < len) {
79 value +=
80 fractional_scales[scale] * FXSYS_DecimalCharToInt(strc.CharAt(cc));
81 scale++;
82 if (scale == fractional_scales_size)
83 break;
84 cc++;
85 }
86 }
87 return bNegative ? -value : value;
88 }
89
90 template <class T>
ToString(T value,int (* round_func)(T),char * buf)91 size_t ToString(T value, int (*round_func)(T), char* buf) {
92 buf[0] = '0';
93 buf[1] = '\0';
94 if (value == 0) {
95 return 1;
96 }
97 bool bNegative = false;
98 if (value < 0) {
99 bNegative = true;
100 value = -value;
101 }
102 int scale = 1;
103 int scaled = round_func(value);
104 while (scaled < 100000) {
105 if (scale == 1000000) {
106 break;
107 }
108 scale *= 10;
109 scaled = round_func(value * scale);
110 }
111 if (scaled == 0) {
112 return 1;
113 }
114 char buf2[32];
115 size_t buf_size = 0;
116 if (bNegative) {
117 buf[buf_size++] = '-';
118 }
119 int i = scaled / scale;
120 FXSYS_itoa(i, buf2, 10);
121 size_t len = strlen(buf2);
122 memcpy(buf + buf_size, buf2, len);
123 buf_size += len;
124 int fraction = scaled % scale;
125 if (fraction == 0) {
126 return buf_size;
127 }
128 buf[buf_size++] = '.';
129 scale /= 10;
130 while (fraction) {
131 buf[buf_size++] = '0' + fraction / scale;
132 fraction %= scale;
133 scale /= 10;
134 }
135 return buf_size;
136 }
137
138 } // namespace
139
StringToFloat(ByteStringView strc)140 float StringToFloat(ByteStringView strc) {
141 return StringTo<float>(strc, kFractionScalesFloat,
142 FX_ArraySize(kFractionScalesFloat));
143 }
144
StringToFloat(WideStringView wsStr)145 float StringToFloat(WideStringView wsStr) {
146 return StringToFloat(FX_UTF8Encode(wsStr).c_str());
147 }
148
FloatToString(float f,char * buf)149 size_t FloatToString(float f, char* buf) {
150 return ToString<float>(f, FXSYS_roundf, buf);
151 }
152
StringToDouble(ByteStringView strc)153 double StringToDouble(ByteStringView strc) {
154 return StringTo<double>(strc, kFractionScalesDouble,
155 FX_ArraySize(kFractionScalesDouble));
156 }
157
StringToDouble(WideStringView wsStr)158 double StringToDouble(WideStringView wsStr) {
159 return StringToDouble(FX_UTF8Encode(wsStr).c_str());
160 }
161
DoubleToString(double d,char * buf)162 size_t DoubleToString(double d, char* buf) {
163 return ToString<double>(d, FXSYS_round, buf);
164 }
165