1/*
2 * Copyright (C) 2015 Andy VanWagoner (andy@vanwagoner.family)
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(INTL)
29
30#include "JSDestructibleObject.h"
31#include <unicode/unum.h>
32#include <unicode/uvernum.h>
33
34#define HAVE_ICU_FORMAT_DOUBLE_FOR_FIELDS (U_ICU_VERSION_MAJOR_NUM >= 59)
35
36namespace JSC {
37
38class IntlNumberFormatConstructor;
39class JSBoundFunction;
40
41class IntlNumberFormat final : public JSDestructibleObject {
42public:
43 typedef JSDestructibleObject Base;
44
45 static IntlNumberFormat* create(VM&, Structure*);
46 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
47
48 DECLARE_INFO;
49
50 void initializeNumberFormat(JSGlobalObject*, JSValue locales, JSValue optionsValue);
51 JSValue formatNumber(JSGlobalObject*, double number);
52#if HAVE(ICU_FORMAT_DOUBLE_FOR_FIELDS)
53 JSValue formatToParts(JSGlobalObject*, double value);
54#endif
55 JSObject* resolvedOptions(JSGlobalObject*);
56
57 JSBoundFunction* boundFormat() const { return m_boundFormat.get(); }
58 void setBoundFormat(VM&, JSBoundFunction*);
59
60protected:
61 IntlNumberFormat(VM&, Structure*);
62 void finishCreation(VM&);
63 static void destroy(JSCell*);
64 static void visitChildren(JSCell*, SlotVisitor&);
65
66private:
67 enum class Style : uint8_t { Decimal, Percent, Currency };
68 enum class CurrencyDisplay : uint8_t { Code, Symbol, Name };
69
70 struct UNumberFormatDeleter {
71 void operator()(UNumberFormat*) const;
72 };
73
74 static ASCIILiteral styleString(Style);
75 static ASCIILiteral currencyDisplayString(CurrencyDisplay);
76
77 String m_locale;
78 String m_numberingSystem;
79 String m_currency;
80 std::unique_ptr<UNumberFormat, UNumberFormatDeleter> m_numberFormat;
81 WriteBarrier<JSBoundFunction> m_boundFormat;
82 unsigned m_minimumIntegerDigits { 1 };
83 unsigned m_minimumFractionDigits { 0 };
84 unsigned m_maximumFractionDigits { 3 };
85 unsigned m_minimumSignificantDigits { 0 };
86 unsigned m_maximumSignificantDigits { 0 };
87 Style m_style { Style::Decimal };
88 CurrencyDisplay m_currencyDisplay;
89 bool m_useGrouping { true };
90 bool m_initializedNumberFormat { false };
91
92#if HAVE(ICU_FORMAT_DOUBLE_FOR_FIELDS)
93 struct UFieldPositionIteratorDeleter {
94 void operator()(UFieldPositionIterator*) const;
95 };
96
97 struct IntlNumberFormatField {
98 int32_t type;
99 int32_t size;
100 IntlNumberFormatField(int32_t type, int32_t size)
101 : type(type)
102 , size(size)
103 { }
104 };
105
106 static ASCIILiteral partTypeString(UNumberFormatFields, double);
107#endif
108};
109
110} // namespace JSC
111
112#endif // ENABLE(INTL)
113