1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef MOZ_DECIMAL_UTILS_H
7 #define MOZ_DECIMAL_UTILS_H
8 
9 // This file contains extra includes, defines and typedefs to allow compilation
10 // of Decimal.cpp under the Mozilla source without blink core dependencies. Do
11 // not include it into any file other than Decimal.cpp.
12 
13 #include "double-conversion/double-conversion.h"
14 #include "mozilla/ArrayUtils.h"
15 #include "mozilla/Casting.h"
16 #include "mozilla/FloatingPoint.h"
17 #include "mozilla/Span.h"
18 
19 #include <cmath>
20 #include <cstring>
21 #include <iomanip>
22 #include <limits>
23 #include <sstream>
24 
25 #ifndef UINT64_C
26 // For Android toolchain
27 #define UINT64_C(c) (c ## ULL)
28 #endif
29 
30 #ifdef ASSERT
31 #undef ASSERT
32 #endif
33 #define ASSERT MOZ_ASSERT
34 
35 #define ASSERT_NOT_REACHED() MOZ_ASSERT_UNREACHABLE("moz-decimal-utils.h")
36 
37 #define STACK_ALLOCATED() DISALLOW_NEW()
38 
39 #define WTF_MAKE_NONCOPYABLE(ClassName) \
40   private: \
41     ClassName(const ClassName&) = delete; \
42     void operator=(const ClassName&) = delete;
43 
44 typedef std::string String;
45 
mozToDouble(mozilla::Span<const char> aStr,bool * valid)46 double mozToDouble(mozilla::Span<const char> aStr, bool *valid) {
47   double_conversion::StringToDoubleConverter converter(
48     double_conversion::StringToDoubleConverter::NO_FLAGS,
49     mozilla::UnspecifiedNaN<double>(), mozilla::UnspecifiedNaN<double>(), nullptr, nullptr);
50   const char* str = aStr.Elements();
51   int length = mozilla::AssertedCast<int>(aStr.Length());
52   int processed_char_count; // unused - NO_FLAGS requires the whole string to parse
53   double result = converter.StringToDouble(str, length, &processed_char_count);
54   *valid = mozilla::IsFinite(result);
55   return result;
56 }
57 
mozToDouble(const String & aStr,bool * valid)58 double mozToDouble(const String &aStr, bool *valid) {
59   return mozToDouble(mozilla::MakeStringSpan(aStr.c_str()), valid);
60 }
61 
mozToString(double aNum)62 String mozToString(double aNum) {
63   char buffer[64];
64   int buffer_length = mozilla::ArrayLength(buffer);
65   const double_conversion::DoubleToStringConverter& converter =
66     double_conversion::DoubleToStringConverter::EcmaScriptConverter();
67   double_conversion::StringBuilder builder(buffer, buffer_length);
68   converter.ToShortest(aNum, &builder);
69   return String(builder.Finalize());
70 }
71 
mozToString(int64_t aNum)72 String mozToString(int64_t aNum) {
73   std::ostringstream o;
74   o << std::setprecision(std::numeric_limits<int64_t>::digits10) << aNum;
75   return o.str();
76 }
77 
mozToString(uint64_t aNum)78 String mozToString(uint64_t aNum) {
79   std::ostringstream o;
80   o << std::setprecision(std::numeric_limits<uint64_t>::digits10) << aNum;
81   return o.str();
82 }
83 
84 namespace moz_decimal_utils {
85 
86 class StringBuilder
87 {
88 public:
append(char c)89   void append(char c) {
90     mStr += c;
91   }
appendLiteral(const char * aStr)92   void appendLiteral(const char *aStr) {
93     mStr += aStr;
94   }
appendNumber(int aNum)95   void appendNumber(int aNum) {
96     mStr += mozToString(int64_t(aNum));
97   }
append(const String & aStr)98   void append(const String& aStr) {
99     mStr += aStr;
100   }
toString()101   std::string toString() const {
102     return mStr;
103   }
104 private:
105   std::string mStr;
106 };
107 
108 } // namespace moz_decimal_utils
109 
110 #endif
111 
112