165 lines
3.8 KiB
C++
165 lines
3.8 KiB
C++
// Copyright 2017 PDFium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
|
|
|
#include "core/fxcrt/fx_string.h"
|
|
|
|
#include <limits>
|
|
#include <vector>
|
|
|
|
#include "core/fxcrt/cfx_utf8decoder.h"
|
|
#include "core/fxcrt/cfx_utf8encoder.h"
|
|
#include "core/fxcrt/fx_extension.h"
|
|
#include "third_party/base/compiler_specific.h"
|
|
|
|
ByteString FX_UTF8Encode(WideStringView wsStr) {
|
|
CFX_UTF8Encoder encoder;
|
|
for (size_t i = 0; i < wsStr.GetLength(); ++i)
|
|
encoder.Input(wsStr[i]);
|
|
|
|
return ByteString(encoder.GetResult());
|
|
}
|
|
|
|
WideString FX_UTF8Decode(ByteStringView bsStr) {
|
|
if (bsStr.IsEmpty())
|
|
return WideString();
|
|
|
|
CFX_UTF8Decoder decoder;
|
|
for (size_t i = 0; i < bsStr.GetLength(); i++)
|
|
decoder.Input(bsStr[i]);
|
|
|
|
return WideString(decoder.GetResult());
|
|
}
|
|
|
|
namespace {
|
|
|
|
constexpr float kFractionScalesFloat[] = {
|
|
0.1f, 0.01f, 0.001f, 0.0001f,
|
|
0.00001f, 0.000001f, 0.0000001f, 0.00000001f,
|
|
0.000000001f, 0.0000000001f, 0.00000000001f};
|
|
|
|
const double kFractionScalesDouble[] = {
|
|
0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,
|
|
0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001};
|
|
|
|
template <class T>
|
|
T StringTo(ByteStringView strc,
|
|
const T fractional_scales[],
|
|
size_t fractional_scales_size) {
|
|
if (strc.IsEmpty())
|
|
return 0;
|
|
|
|
int cc = 0;
|
|
bool bNegative = false;
|
|
int len = strc.GetLength();
|
|
if (strc[0] == '+') {
|
|
cc++;
|
|
} else if (strc[0] == '-') {
|
|
bNegative = true;
|
|
cc++;
|
|
}
|
|
while (cc < len) {
|
|
if (strc[cc] != '+' && strc[cc] != '-')
|
|
break;
|
|
cc++;
|
|
}
|
|
T value = 0;
|
|
while (cc < len) {
|
|
if (strc[cc] == '.')
|
|
break;
|
|
value = value * 10 + FXSYS_DecimalCharToInt(strc.CharAt(cc));
|
|
cc++;
|
|
}
|
|
size_t scale = 0;
|
|
if (cc < len && strc[cc] == '.') {
|
|
cc++;
|
|
while (cc < len) {
|
|
value +=
|
|
fractional_scales[scale] * FXSYS_DecimalCharToInt(strc.CharAt(cc));
|
|
scale++;
|
|
if (scale == fractional_scales_size)
|
|
break;
|
|
cc++;
|
|
}
|
|
}
|
|
return bNegative ? -value : value;
|
|
}
|
|
|
|
template <class T>
|
|
size_t ToString(T value, int (*round_func)(T), char* buf) {
|
|
buf[0] = '0';
|
|
buf[1] = '\0';
|
|
if (value == 0) {
|
|
return 1;
|
|
}
|
|
bool bNegative = false;
|
|
if (value < 0) {
|
|
bNegative = true;
|
|
value = -value;
|
|
}
|
|
int scale = 1;
|
|
int scaled = round_func(value);
|
|
while (scaled < 100000) {
|
|
if (scale == 1000000) {
|
|
break;
|
|
}
|
|
scale *= 10;
|
|
scaled = round_func(value * scale);
|
|
}
|
|
if (scaled == 0) {
|
|
return 1;
|
|
}
|
|
char buf2[32];
|
|
size_t buf_size = 0;
|
|
if (bNegative) {
|
|
buf[buf_size++] = '-';
|
|
}
|
|
int i = scaled / scale;
|
|
FXSYS_itoa(i, buf2, 10);
|
|
size_t len = strlen(buf2);
|
|
memcpy(buf + buf_size, buf2, len);
|
|
buf_size += len;
|
|
int fraction = scaled % scale;
|
|
if (fraction == 0) {
|
|
return buf_size;
|
|
}
|
|
buf[buf_size++] = '.';
|
|
scale /= 10;
|
|
while (fraction) {
|
|
buf[buf_size++] = '0' + fraction / scale;
|
|
fraction %= scale;
|
|
scale /= 10;
|
|
}
|
|
return buf_size;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
float StringToFloat(ByteStringView strc) {
|
|
return StringTo<float>(strc, kFractionScalesFloat,
|
|
FX_ArraySize(kFractionScalesFloat));
|
|
}
|
|
|
|
float StringToFloat(WideStringView wsStr) {
|
|
return StringToFloat(FX_UTF8Encode(wsStr).c_str());
|
|
}
|
|
|
|
size_t FloatToString(float f, char* buf) {
|
|
return ToString<float>(f, FXSYS_roundf, buf);
|
|
}
|
|
|
|
double StringToDouble(ByteStringView strc) {
|
|
return StringTo<double>(strc, kFractionScalesDouble,
|
|
FX_ArraySize(kFractionScalesDouble));
|
|
}
|
|
|
|
double StringToDouble(WideStringView wsStr) {
|
|
return StringToDouble(FX_UTF8Encode(wsStr).c_str());
|
|
}
|
|
|
|
size_t DoubleToString(double d, char* buf) {
|
|
return ToString<double>(d, FXSYS_round, buf);
|
|
}
|