diff options
author | Kyrega <philipp.stefan.womser@sap.com> | 2021-08-10 10:04:30 +0300 |
---|---|---|
committer | Kyrega <philipp.stefan.womser@sap.com> | 2021-08-10 18:35:07 +0300 |
commit | b952a592a480e551517468bbf4794061653b840c (patch) | |
tree | 201ecb80e78daa07c5201e959bde7a6efd5366d1 /include | |
parent | 48fbd8cd202ca54031fe799db2ad44ffa8e77c13 (diff) |
Fix RawNumber for longer char types
Diffstat (limited to 'include')
-rw-r--r-- | include/rapidjson/internal/biginteger.h | 15 | ||||
-rw-r--r-- | include/rapidjson/internal/strtod.h | 15 | ||||
-rw-r--r-- | include/rapidjson/reader.h | 38 |
3 files changed, 38 insertions, 30 deletions
diff --git a/include/rapidjson/internal/biginteger.h b/include/rapidjson/internal/biginteger.h index 12455788..7b145635 100644 --- a/include/rapidjson/internal/biginteger.h +++ b/include/rapidjson/internal/biginteger.h @@ -37,7 +37,8 @@ public: digits_[0] = u; } - BigInteger(const char* decimals, size_t length) : count_(1) { + template<typename Ch = char> + BigInteger(const Ch* decimals, size_t length) : count_(1) { RAPIDJSON_ASSERT(length > 0); digits_[0] = 0; size_t i = 0; @@ -221,7 +222,8 @@ public: bool IsZero() const { return count_ == 1 && digits_[0] == 0; } private: - void AppendDecimal64(const char* begin, const char* end) { + template<typename Ch = char> + void AppendDecimal64(const Ch* begin, const Ch* end) { uint64_t u = ParseUint64(begin, end); if (IsZero()) *this = u; @@ -236,11 +238,12 @@ private: digits_[count_++] = digit; } - static uint64_t ParseUint64(const char* begin, const char* end) { + template<typename Ch = char> + static uint64_t ParseUint64(const Ch* begin, const Ch* end) { uint64_t r = 0; - for (const char* p = begin; p != end; ++p) { - RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); - r = r * 10u + static_cast<unsigned>(*p - '0'); + for (const Ch* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9')); + r = r * 10u + static_cast<unsigned>(*p - Ch('0')); } return r; } diff --git a/include/rapidjson/internal/strtod.h b/include/rapidjson/internal/strtod.h index d61a67a4..55f0e380 100644 --- a/include/rapidjson/internal/strtod.h +++ b/include/rapidjson/internal/strtod.h @@ -128,17 +128,18 @@ inline bool StrtodFast(double d, int p, double* result) { } // Compute an approximation and see if it is within 1/2 ULP -inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result) { +template<typename Ch> +inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result) { uint64_t significand = 0; int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 for (; i < dLen; i++) { if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || - (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5'))) break; - significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0'); + significand = significand * 10u + static_cast<unsigned>(decimals[i] - Ch('0')); } - if (i < dLen && decimals[i] >= '5') // Rounding + if (i < dLen && decimals[i] >= Ch('5')) // Rounding significand++; int remaining = dLen - i; @@ -205,7 +206,8 @@ inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error); } -inline double StrtodBigInteger(double approx, const char* decimals, int dLen, int dExp) { +template<typename Ch> +inline double StrtodBigInteger(double approx, const Ch* decimals, int dLen, int dExp) { RAPIDJSON_ASSERT(dLen >= 0); const BigInteger dInt(decimals, static_cast<unsigned>(dLen)); Double a(approx); @@ -223,7 +225,8 @@ inline double StrtodBigInteger(double approx, const char* decimals, int dLen, in return a.NextPositiveDouble(); } -inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { +template<typename Ch> +inline double StrtodFullPrecision(double d, int p, const Ch* decimals, size_t length, size_t decimalPosition, int exp) { RAPIDJSON_ASSERT(d >= 0.0); RAPIDJSON_ASSERT(length >= 1); diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 09ace4eb..8f7e533f 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -1404,11 +1404,11 @@ private: } #endif // RAPIDJSON_NEON - template<typename InputStream, bool backup, bool pushOnTake> + template<typename InputStream, typename StackCharacter, bool backup, bool pushOnTake> class NumberStream; - template<typename InputStream> - class NumberStream<InputStream, false, false> { + template<typename InputStream, typename StackCharacter> + class NumberStream<InputStream, StackCharacter, false, false> { public: typedef typename InputStream::Ch Ch; @@ -1421,7 +1421,7 @@ private: size_t Tell() { return is.Tell(); } size_t Length() { return 0; } - const char* Pop() { return 0; } + const StackCharacter* Pop() { return 0; } protected: NumberStream& operator=(const NumberStream&); @@ -1429,35 +1429,35 @@ private: InputStream& is; }; - template<typename InputStream> - class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> { - typedef NumberStream<InputStream, false, false> Base; + template<typename InputStream, typename StackCharacter> + class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> { + typedef NumberStream<InputStream, StackCharacter, false, false> Base; public: NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} RAPIDJSON_FORCEINLINE Ch TakePush() { - stackStream.Put(static_cast<char>(Base::is.Peek())); + stackStream.Put(static_cast<StackCharacter>(Base::is.Peek())); return Base::is.Take(); } - RAPIDJSON_FORCEINLINE void Push(char c) { + RAPIDJSON_FORCEINLINE void Push(StackCharacter c) { stackStream.Put(c); } size_t Length() { return stackStream.Length(); } - const char* Pop() { + const StackCharacter* Pop() { stackStream.Put('\0'); return stackStream.Pop(); } private: - StackStream<char> stackStream; + StackStream<StackCharacter> stackStream; }; - template<typename InputStream> - class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> { - typedef NumberStream<InputStream, true, false> Base; + template<typename InputStream, typename StackCharacter> + class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> { + typedef NumberStream<InputStream, StackCharacter, true, false> Base; public: NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} @@ -1466,8 +1466,10 @@ private: template<unsigned parseFlags, typename InputStream, typename Handler> void ParseNumber(InputStream& is, Handler& handler) { + typedef std::conditional<(parseFlags & kParseNumbersAsStringsFlag) != 0, typename TargetEncoding::Ch, char>::type NumberCharacter; + internal::StreamLocalCopy<InputStream> copy(is); - NumberStream<InputStream, + NumberStream<InputStream, NumberCharacter, ((parseFlags & kParseNumbersAsStringsFlag) != 0) ? ((parseFlags & kParseInsituFlag) == 0) : ((parseFlags & kParseFullPrecisionFlag) != 0), @@ -1692,10 +1694,10 @@ private: } else { SizeType numCharsToCopy = static_cast<SizeType>(s.Length()); - StringStream srcStream(s.Pop()); + GenericStringStream<UTF8<NumberCharacter>> srcStream(s.Pop()); StackStream<typename TargetEncoding::Ch> dstStream(stack_); while (numCharsToCopy--) { - Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream); + Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream); } dstStream.Put('\0'); const typename TargetEncoding::Ch* str = dstStream.Pop(); @@ -1705,7 +1707,7 @@ private: } else { size_t length = s.Length(); - const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + const NumberCharacter* decimal = s.Pop(); // Pop stack no matter if it will be used or not. if (useDouble) { int p = exp + expFrac; |