1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#ifndef QLOCALE_TOOLS_P_H
6#define QLOCALE_TOOLS_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of internal files. This header file may change from version to version
14// without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qlocale_p.h"
20#include "qstring.h"
21
22#if !defined(QT_SUPPORTS_INT128) && (defined(Q_CC_MSVC) && (_MSC_VER >= 1930) && __has_include(<__msvc_int128.hpp>))
23#include <__msvc_int128.hpp>
24#define QT_USE_MSVC_INT128
25#endif
26
27QT_BEGIN_NAMESPACE
28
29#if defined(QT_SUPPORTS_INT128)
30using qinternalint128 = qint128;
31using qinternaluint128 = quint128;
32#elif defined(QT_USE_MSVC_INT128)
33using qinternalint128 = std::_Signed128;
34using qinternaluint128 = std::_Unsigned128;
35#endif
36
37enum StrayCharacterMode {
38 TrailingJunkProhibited,
39 TrailingJunkAllowed,
40};
41
42// API note: this function can't process a number with more than 2.1 billion digits
43[[nodiscard]] QSimpleParsedNumber<double>
44qt_asciiToDouble(const char *num, qsizetype numLen,
45 StrayCharacterMode strayCharMode = TrailingJunkProhibited);
46void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision,
47 char *buf, qsizetype bufSize,
48 bool &sign, int &length, int &decpt);
49
50[[nodiscard]] QString qulltoBasicLatin(qulonglong l, int base, bool negative);
51[[nodiscard]] QString qulltoa(qulonglong l, int base, const QStringView zero);
52[[nodiscard]] char *qulltoa2(char *p, qulonglong n, int base);
53[[nodiscard]] Q_CORE_EXPORT QString qdtoa(qreal d, int *decpt, int *sign);
54[[nodiscard]] QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form,
55 int precision, bool uppercase);
56[[nodiscard]] QByteArray qdtoAscii(double d, QLocaleData::DoubleForm form,
57 int precision, bool uppercase);
58
59#if defined(QT_SUPPORTS_INT128) || defined(QT_USE_MSVC_INT128)
60[[nodiscard]] Q_CORE_EXPORT QString quint128toBasicLatin(qinternaluint128 number,
61 int base = 10);
62[[nodiscard]] Q_CORE_EXPORT QString qint128toBasicLatin(qinternalint128 number,
63 int base = 10);
64#endif
65
66#if QT_VERSION < QT_VERSION_CHECK(6, 12, 0)
67[[deprecated("Use qIsNull(double) instead.")]]
68[[nodiscard]] constexpr inline bool isZero(double d)
69{
70 return qIsNull(d);
71}
72#endif
73
74// Enough space for the digits before the decimal separator:
75[[nodiscard]] inline int wholePartSpace(double d)
76{
77 Q_ASSERT(d >= 0); // caller should call qAbs() if needed
78 // Optimize for numbers between -512k and 512k - otherwise, use the
79 // maximum number of digits in the whole number part of a double:
80 return d > (1 << 19) ? std::numeric_limits<double>::max_exponent10 + 1 : 6;
81}
82
83// Returns code-point of same kind (UCS2 or UCS4) as zero; digit is 0 through 9
84template <typename UcsInt>
85[[nodiscard]] inline UcsInt unicodeForDigit(uint digit, UcsInt zero)
86{
87 // Must match qlocale.cpp's NumericTokenizer's digit-digestion.
88 Q_ASSERT(digit < 10);
89 if (!digit)
90 return zero;
91
92 // See QTBUG-85409: Suzhou's digits are U+3007, U+3021, ..., U+3029
93 if (zero == u'\u3007')
94 return u'\u3020' + digit;
95 // In util/locale_database/ldml.py, LocaleScanner.numericData() asserts no
96 // other number system in CLDR has discontinuous digits.
97
98 return zero + digit;
99}
100
101[[nodiscard]] Q_CORE_EXPORT double qstrntod(const char *s00, qsizetype len,
102 char const **se, bool *ok);
103[[nodiscard]] inline double qstrtod(const char *s00, char const **se, bool *ok)
104{
105 qsizetype len = qsizetype(strlen(s: s00));
106 return qstrntod(s00, len, se, ok);
107}
108
109[[nodiscard]] Q_AUTOTEST_EXPORT
110QSimpleParsedNumber<qlonglong> qstrntoll(const char *nptr, qsizetype size, int base);
111[[nodiscard]] QSimpleParsedNumber<qulonglong> qstrntoull(const char *nptr, qsizetype size, int base);
112
113QT_END_NAMESPACE
114
115#endif
116

source code of qtbase/src/corelib/text/qlocale_tools_p.h