oops, I shifted the wrong value.
[swfdec.git] / swfdec / swfdec_as_number.c
blob75d0cb53ab49c27f055b5d3dcad6d56d52af7e83
1 /* Swfdec
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.
8 *
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
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <math.h>
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)
36 static void
37 swfdec_as_number_class_init (SwfdecAsNumberClass *klass)
41 static void
42 swfdec_as_number_init (SwfdecAsNumber *number)
46 /*** AS CODE ***/
48 SWFDEC_AS_CONSTRUCTOR (106, 2, swfdec_as_number_construct, swfdec_as_number_get_type)
49 void
50 swfdec_as_number_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
51 guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
53 double d;
55 if (argc > 0) {
56 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (object), &argv[0]);
57 } else {
58 d = NAN;
61 if (swfdec_as_context_is_constructing (cx)) {
62 SwfdecAsNumber *num = SWFDEC_AS_NUMBER (object);
63 num->number = d;
64 SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
65 } else {
66 SWFDEC_AS_VALUE_SET_NUMBER (ret, d);
70 // code adapted from Tamarin's convertDoubleToStringRadix in MathUtils.cpp
71 // 2008-02-16
72 static const char *
73 swfdec_as_number_toStringRadix (SwfdecAsContext *context, double value,
74 int radix)
76 gboolean negative;
77 GString *str;
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);
84 if (value < 0) {
85 negative = TRUE;
86 value = -value;
87 } else {
88 negative = FALSE;
91 if (value < 1)
92 return SWFDEC_AS_STR_0;
94 str = g_string_new ("");
96 left = floor (value);
98 while (left != 0)
100 double val = left;
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))));
108 if (negative)
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)
115 void
116 swfdec_as_number_toString (SwfdecAsContext *cx, SwfdecAsObject *object,
117 guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
119 SwfdecAsNumber *num;
120 SwfdecAsValue val;
121 const char *s;
122 int radix = 10;
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);
130 } else {
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)
137 void
138 swfdec_as_number_valueOf (SwfdecAsContext *cx, SwfdecAsObject *object,
139 guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
141 SwfdecAsNumber *num;
143 if (!SWFDEC_IS_AS_NUMBER (object))
144 return;
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)
152 void
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)
161 void
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)");