2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
26 #include "swfdec_as_number.h"
27 #include "swfdec_as_context.h"
28 #include "swfdec_as_frame.h"
29 #include "swfdec_as_internal.h"
30 #include "swfdec_as_native_function.h"
31 #include "swfdec_as_strings.h"
32 #include "swfdec_debug.h"
34 G_DEFINE_TYPE (SwfdecAsNumber
, swfdec_as_number
, SWFDEC_TYPE_AS_OBJECT
)
37 swfdec_as_number_class_init (SwfdecAsNumberClass
*klass
)
42 swfdec_as_number_init (SwfdecAsNumber
*number
)
48 SWFDEC_AS_CONSTRUCTOR (106, 2, swfdec_as_number_construct
, swfdec_as_number_get_type
)
50 swfdec_as_number_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
51 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
56 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (object
), &argv
[0]);
61 if (swfdec_as_context_is_constructing (cx
)) {
62 SwfdecAsNumber
*num
= SWFDEC_AS_NUMBER (object
);
64 SWFDEC_AS_VALUE_SET_OBJECT (ret
, object
);
66 SWFDEC_AS_VALUE_SET_NUMBER (ret
, d
);
70 // code adapted from Tamarin's convertDoubleToStringRadix in MathUtils.cpp
73 swfdec_as_number_toStringRadix (SwfdecAsContext
*context
, double value
,
78 double left
= floor (value
);
80 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), SWFDEC_AS_STR_NaN
);
81 g_return_val_if_fail (radix
>= 2 && radix
<= 36, SWFDEC_AS_STR_NaN
);
82 g_return_val_if_fail (!isinf (value
) && !isnan (value
), SWFDEC_AS_STR_NaN
);
92 return SWFDEC_AS_STR_0
;
94 str
= g_string_new ("");
101 left
= floor (left
/ radix
);
102 val
-= (left
* radix
);
104 g_string_prepend_c (str
,
105 (val
< 10 ? ((int)val
+ '0') : ((int)val
+ ('a' - 10))));
109 g_string_prepend_c (str
, '-');
111 return swfdec_as_context_give_string (context
, g_string_free (str
, FALSE
));
114 SWFDEC_AS_NATIVE (106, 1, swfdec_as_number_toString
)
116 swfdec_as_number_toString (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
117 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
124 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_NUMBER
, &num
, "|i", &radix
);
126 if (radix
== 10 || radix
< 2 || radix
> 36 || isinf (num
->number
) ||
127 isnan (num
->number
)) {
128 SWFDEC_AS_VALUE_SET_NUMBER (&val
, num
->number
);
129 s
= swfdec_as_value_to_string (cx
, &val
);
131 s
= swfdec_as_number_toStringRadix (cx
, num
->number
, radix
);
133 SWFDEC_AS_VALUE_SET_STRING (ret
, s
);
136 SWFDEC_AS_NATIVE (106, 0, swfdec_as_number_valueOf
)
138 swfdec_as_number_valueOf (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
139 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
143 if (!SWFDEC_IS_AS_NUMBER (object
))
146 num
= SWFDEC_AS_NUMBER (object
);
147 SWFDEC_AS_VALUE_SET_NUMBER (ret
, num
->number
);
150 // only available as ASnative
151 SWFDEC_AS_NATIVE (3, 1, swfdec_as_number_old_constructor
)
153 swfdec_as_number_old_constructor (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
154 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
156 SWFDEC_STUB ("old 'Number' function (only available as ASnative)");
159 // only available as ASnative
160 SWFDEC_AS_NATIVE (3, 4, swfdec_as_number_old_toString
)
162 swfdec_as_number_old_toString (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
163 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
165 SWFDEC_STUB ("old 'Number.prototype.toString' function (only available as ASnative)");