Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
3
* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef builtin_intl_NumberFormat_h
8
#define builtin_intl_NumberFormat_h
9
10
#include "mozilla/Attributes.h"
11
12
#include <stdint.h>
13
14
#include "builtin/SelfHostingDefines.h"
15
#include "gc/Barrier.h"
16
#include "js/Class.h"
17
#include "vm/NativeObject.h"
18
#include "vm/Runtime.h"
19
20
struct UFormattedNumber;
21
struct UFormattedValue;
22
struct UNumberFormatter;
23
24
namespace js {
25
26
class NumberFormatObject : public NativeObject {
27
public:
28
static const JSClass class_;
29
static const JSClass& protoClass_;
30
31
static constexpr uint32_t INTERNALS_SLOT = 0;
32
static constexpr uint32_t UNUMBER_FORMATTER_SLOT = 1;
33
static constexpr uint32_t UFORMATTED_NUMBER_SLOT = 2;
34
static constexpr uint32_t SLOT_COUNT = 3;
35
36
static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
37
"INTERNALS_SLOT must match self-hosting define for internals "
38
"object slot");
39
40
// Estimated memory use for UNumberFormatter and UFormattedNumber.
41
static constexpr size_t EstimatedMemoryUse = 750;
42
43
UNumberFormatter* getNumberFormatter() const {
44
const auto& slot = getFixedSlot(UNUMBER_FORMATTER_SLOT);
45
if (slot.isUndefined()) {
46
return nullptr;
47
}
48
return static_cast<UNumberFormatter*>(slot.toPrivate());
49
}
50
51
void setNumberFormatter(UNumberFormatter* formatter) {
52
setFixedSlot(UNUMBER_FORMATTER_SLOT, PrivateValue(formatter));
53
}
54
55
UFormattedNumber* getFormattedNumber() const {
56
const auto& slot = getFixedSlot(UFORMATTED_NUMBER_SLOT);
57
if (slot.isUndefined()) {
58
return nullptr;
59
}
60
return static_cast<UFormattedNumber*>(slot.toPrivate());
61
}
62
63
void setFormattedNumber(UFormattedNumber* formatted) {
64
setFixedSlot(UFORMATTED_NUMBER_SLOT, PrivateValue(formatted));
65
}
66
67
private:
68
static const JSClassOps classOps_;
69
static const ClassSpec classSpec_;
70
71
static void finalize(JSFreeOp* fop, JSObject* obj);
72
};
73
74
/**
75
* Returns a new instance of the standard built-in NumberFormat constructor.
76
* Self-hosted code cannot cache this constructor (as it does for others in
77
* Utilities.js) because it is initialized after self-hosted code is compiled.
78
*
79
* Usage: numberFormat = intl_NumberFormat(locales, options)
80
*/
81
extern MOZ_MUST_USE bool intl_NumberFormat(JSContext* cx, unsigned argc,
82
Value* vp);
83
84
/**
85
* Returns the numbering system type identifier per Unicode
86
* Technical Standard 35, Unicode Locale Data Markup Language, for the
87
* default numbering system for the given locale.
88
*
89
* Usage: defaultNumberingSystem = intl_numberingSystem(locale)
90
*/
91
extern MOZ_MUST_USE bool intl_numberingSystem(JSContext* cx, unsigned argc,
92
Value* vp);
93
94
/**
95
* Returns a string representing the number x according to the effective
96
* locale and the formatting options of the given NumberFormat.
97
*
98
* Spec: ECMAScript Internationalization API Specification, 11.3.2.
99
*
100
* Usage: formatted = intl_FormatNumber(numberFormat, x, formatToParts)
101
*/
102
extern MOZ_MUST_USE bool intl_FormatNumber(JSContext* cx, unsigned argc,
103
Value* vp);
104
105
#if DEBUG || MOZ_SYSTEM_ICU
106
/**
107
* Returns an object with all available measurement units.
108
*
109
* Usage: units = intl_availableMeasurementUnits()
110
*/
111
extern MOZ_MUST_USE bool intl_availableMeasurementUnits(JSContext* cx,
112
unsigned argc,
113
Value* vp);
114
#endif
115
116
namespace intl {
117
118
/**
119
* Class to create a number formatter skeleton.
120
*
121
* The skeleton syntax is documented at:
123
*/
124
class MOZ_STACK_CLASS NumberFormatterSkeleton final {
125
static constexpr size_t DefaultVectorSize = 128;
126
using SkeletonVector = Vector<char16_t, DefaultVectorSize>;
127
128
SkeletonVector vector_;
129
130
bool append(char16_t c) { return vector_.append(c); }
131
132
bool appendN(char16_t c, size_t times) { return vector_.appendN(c, times); }
133
134
template <size_t N>
135
bool append(const char16_t (&chars)[N]) {
136
static_assert(N > 0,
137
"should only be used with string literals or properly "
138
"null-terminated arrays");
139
MOZ_ASSERT(chars[N - 1] == '\0',
140
"should only be used with string literals or properly "
141
"null-terminated arrays");
142
return vector_.append(chars, N - 1); // Without trailing \0.
143
}
144
145
template <size_t N>
146
bool appendToken(const char16_t (&token)[N]) {
147
return append(token) && append(' ');
148
}
149
150
bool append(const char* chars, size_t length) {
151
return vector_.append(chars, length);
152
}
153
154
public:
155
explicit NumberFormatterSkeleton(JSContext* cx) : vector_(cx) {}
156
157
/**
158
* Return a new UNumberFormatter based on this skeleton.
159
*/
160
UNumberFormatter* toFormatter(JSContext* cx, const char* locale);
161
162
/**
163
* Set this skeleton to display a currency amount. |currency| must be a
164
* three-letter currency code.
165
*
167
*/
168
MOZ_MUST_USE bool currency(JSLinearString* currency);
169
170
enum class CurrencyDisplay { Code, Name, Symbol, NarrowSymbol };
171
172
/**
173
* Set the currency display style for this skeleton.
174
*
176
*/
177
MOZ_MUST_USE bool currencyDisplay(CurrencyDisplay display);
178
179
/**
180
* Set this skeleton to display a unit amount. |unit| must be a well-formed
181
* unit identifier.
182
*
185
*/
186
MOZ_MUST_USE bool unit(JSLinearString* unit);
187
188
enum class UnitDisplay { Short, Narrow, Long };
189
190
/**
191
* Set the unit display style for this skeleton.
192
*
194
*/
195
MOZ_MUST_USE bool unitDisplay(UnitDisplay display);
196
197
/**
198
* Set this skeleton to display a percent number.
199
*
202
*/
203
MOZ_MUST_USE bool percent();
204
205
/**
206
* Set the fraction digits settings for this skeleton. |min| can be zero,
207
* |max| must be larger-or-equal to |min|.
208
*
210
*/
211
MOZ_MUST_USE bool fractionDigits(uint32_t min, uint32_t max);
212
213
/**
214
* Set the integer-width settings for this skeleton. |min| must be a non-zero
215
* number.
216
*
218
*/
219
MOZ_MUST_USE bool integerWidth(uint32_t min);
220
221
/**
222
* Set the significant digits settings for this skeleton. |min| must be a
223
* non-zero number, |max| must be larger-or-equal to |min|.
224
*
226
*/
227
MOZ_MUST_USE bool significantDigits(uint32_t min, uint32_t max);
228
229
/**
230
* Enable or disable grouping for this skeleton.
231
*
233
*/
234
MOZ_MUST_USE bool useGrouping(bool on);
235
236
enum class Notation {
237
Standard,
238
Scientific,
239
Engineering,
240
CompactShort,
241
CompactLong
242
};
243
244
/**
245
* Set the notation style for this skeleton.
246
*
248
*/
249
MOZ_MUST_USE bool notation(Notation style);
250
251
enum class SignDisplay {
252
Auto,
253
Never,
254
Always,
255
ExceptZero,
256
Accounting,
257
AccountingAlways,
258
AccountingExceptZero
259
};
260
261
/**
262
* Set the sign-display for this skeleton.
263
*
265
*/
266
MOZ_MUST_USE bool signDisplay(SignDisplay display);
267
268
/**
269
* Set the rounding mode to 'half-up' for this skeleton.
270
*
272
*/
273
MOZ_MUST_USE bool roundingModeHalfUp();
274
};
275
276
using FieldType = js::ImmutablePropertyNamePtr JSAtomState::*;
277
278
#ifndef U_HIDE_DRAFT_API
279
MOZ_MUST_USE bool FormattedNumberToParts(JSContext* cx,
280
const UFormattedValue* formattedValue,
281
HandleValue number, FieldType unitType,
282
MutableHandleValue result);
283
#endif
284
285
} // namespace intl
286
} // namespace js
287
288
#endif /* builtin_intl_NumberFormat_h */