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
27 #include "swfdec_as_string.h"
28 #include "swfdec_as_array.h"
29 #include "swfdec_as_context.h"
30 #include "swfdec_as_native_function.h"
31 #include "swfdec_as_strings.h"
32 #include "swfdec_debug.h"
33 #include "swfdec_player_internal.h"
35 G_DEFINE_TYPE (SwfdecAsString
, swfdec_as_string
, SWFDEC_TYPE_AS_OBJECT
)
38 swfdec_as_string_do_mark (SwfdecAsObject
*object
)
40 SwfdecAsString
*string
= SWFDEC_AS_STRING (object
);
42 swfdec_as_string_mark (string
->string
);
44 SWFDEC_AS_OBJECT_CLASS (swfdec_as_string_parent_class
)->mark (object
);
48 swfdec_as_string_debug (SwfdecAsObject
*object
)
50 SwfdecAsString
*string
= SWFDEC_AS_STRING (object
);
52 return g_strdup (string
->string
);
56 swfdec_as_string_class_init (SwfdecAsStringClass
*klass
)
58 SwfdecAsObjectClass
*asobject_class
= SWFDEC_AS_OBJECT_CLASS (klass
);
60 asobject_class
->mark
= swfdec_as_string_do_mark
;
61 asobject_class
->debug
= swfdec_as_string_debug
;
65 swfdec_as_string_init (SwfdecAsString
*string
)
67 string
->string
= SWFDEC_AS_STR_EMPTY
;
73 swfdec_as_string_object_to_string (SwfdecAsContext
*context
,
74 SwfdecAsObject
*object
)
78 g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object
), NULL
);
80 SWFDEC_AS_VALUE_SET_OBJECT (&val
, object
);
82 return swfdec_as_value_to_string (context
, &val
);
85 static inline const char *
86 swfdec_as_str_nth_char (const char *s
, guint n
)
89 s
= g_utf8_next_char (s
);
93 SWFDEC_AS_NATIVE (251, 9, swfdec_as_string_lastIndexOf
)
95 swfdec_as_string_lastIndexOf (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
96 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
98 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
102 s
= swfdec_as_value_to_string (object
->context
, &argv
[0]);
104 int offset
= swfdec_as_value_to_integer (object
->context
, &argv
[1]);
106 SWFDEC_AS_VALUE_SET_INT (ret
, -1);
109 len
= g_utf8_offset_to_pointer (string
, offset
+ 1) - string
;
113 s
= g_strrstr_len (string
, len
, s
);
115 SWFDEC_AS_VALUE_SET_INT (ret
, g_utf8_pointer_to_offset (string
, s
));
117 SWFDEC_AS_VALUE_SET_INT (ret
, -1);
121 SWFDEC_AS_NATIVE (251, 8, swfdec_as_string_indexOf
)
123 swfdec_as_string_indexOf (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
124 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
126 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
127 int offset
=0, len
, i
=-1;
128 const char *s
, *t
= NULL
;
130 s
= swfdec_as_value_to_string (object
->context
, &argv
[0]);
132 offset
= swfdec_as_value_to_integer (object
->context
, &argv
[1]);
135 len
= g_utf8_strlen (string
, -1);
137 t
= strstr (g_utf8_offset_to_pointer (string
, offset
), s
);
140 i
= g_utf8_pointer_to_offset (string
, t
);
143 SWFDEC_AS_VALUE_SET_INT (ret
, i
);
146 SWFDEC_AS_NATIVE (251, 5, swfdec_as_string_charAt
)
148 swfdec_as_string_charAt (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
149 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
151 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
155 i
= swfdec_as_value_to_integer (object
->context
, &argv
[0]);
157 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
160 s
= swfdec_as_str_nth_char (string
, i
);
162 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
165 t
= g_utf8_next_char (s
);
166 s
= swfdec_as_context_give_string (cx
, g_strndup (s
, t
- s
));
167 SWFDEC_AS_VALUE_SET_STRING (ret
, s
);
170 SWFDEC_AS_NATIVE (251, 6, swfdec_as_string_charCodeAt
)
172 swfdec_as_string_charCodeAt (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
173 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
175 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
180 i
= swfdec_as_value_to_integer (cx
, &argv
[0]);
182 SWFDEC_AS_VALUE_SET_NUMBER (ret
, NAN
);
185 s
= swfdec_as_str_nth_char (string
, i
);
187 if (cx
->version
> 5) {
188 SWFDEC_AS_VALUE_SET_NUMBER (ret
, NAN
);
190 SWFDEC_AS_VALUE_SET_INT (ret
, 0);
194 c
= g_utf8_get_char (s
);
195 SWFDEC_AS_VALUE_SET_NUMBER (ret
, c
);
199 swfdec_as_string_fromCharCode_5 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
200 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
204 GError
*error
= NULL
;
206 GByteArray
*array
= g_byte_array_new ();
208 for (i
= 0; i
< argc
; i
++) {
209 c
= ((guint
) swfdec_as_value_to_integer (cx
, &argv
[i
])) % 65536;
212 g_byte_array_append (array
, &append
, 1);
215 g_byte_array_append (array
, &append
, 1);
218 /* FIXME: are these the correct charset names? */
219 s
= g_convert ((char *) array
->data
, array
->len
, "UTF-8", "LATIN1", NULL
, NULL
, &error
);
221 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_get_string (cx
, s
));
224 SWFDEC_ERROR ("%s", error
->message
);
225 g_error_free (error
);
227 g_byte_array_free (array
, TRUE
);
231 swfdec_as_string_fromCharCode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
232 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
238 GError
*error
= NULL
;
243 chars
= g_new (gunichar
, argc
);
245 for (i
= 0; i
< argc
; i
++) {
246 chars
[i
] = ((guint
) swfdec_as_value_to_integer (cx
, &argv
[i
])) % 65536;
249 s
= g_ucs4_to_utf8 (chars
, argc
, NULL
, NULL
, &error
);
251 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_get_string (cx
, s
));
254 SWFDEC_ERROR ("%s", error
->message
);
255 g_error_free (error
);
263 swfdec_as_string_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
264 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
269 s
= swfdec_as_value_to_string (cx
, &argv
[0]);
271 s
= SWFDEC_AS_STR_EMPTY
;
274 if (swfdec_as_context_is_constructing (cx
)) {
275 SwfdecAsString
*string
= SWFDEC_AS_STRING (object
);
279 SWFDEC_AS_VALUE_SET_INT (&val
, g_utf8_strlen (string
->string
, -1));
280 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_length
, &val
);
281 SWFDEC_AS_VALUE_SET_OBJECT (ret
, object
);
283 SWFDEC_AS_VALUE_SET_STRING (ret
, s
);
287 SWFDEC_AS_NATIVE (251, 2, swfdec_as_string_toString
)
289 swfdec_as_string_toString (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
290 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
292 SwfdecAsString
*string
= SWFDEC_AS_STRING (object
);
294 SWFDEC_AS_VALUE_SET_STRING (ret
, string
->string
);
297 SWFDEC_AS_NATIVE (251, 1, swfdec_as_string_valueOf
)
299 swfdec_as_string_valueOf (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
300 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
302 SwfdecAsString
*string
= SWFDEC_AS_STRING (object
);
304 SWFDEC_AS_VALUE_SET_STRING (ret
, string
->string
);
308 charAt(index
:Number
) : String
309 charCodeAt(index
:Number
) : Number
310 concat(value
:Object
) : String
311 indexOf(value
:String
, [startIndex
:Number
]) : Number
312 slice(start
:Number
, end
:Number
) : String
313 split(delimiter
:String
, [limit
:Number
]) : Array
317 swfdec_as_string_split_5 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
318 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
322 const char *str
, *end
, *delim
;
325 str
= swfdec_as_string_object_to_string (cx
, object
);
326 arr
= SWFDEC_AS_ARRAY (swfdec_as_array_new (cx
));
329 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (arr
));
330 /* hi, i'm the special case */
331 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0])) {
332 delim
= SWFDEC_AS_STR_COMMA
;
334 delim
= swfdec_as_value_to_string (cx
, &argv
[0]);
336 if (delim
== SWFDEC_AS_STR_EMPTY
) {
337 SWFDEC_AS_VALUE_SET_STRING (&val
, str
);
338 swfdec_as_array_push (arr
, &val
);
342 swfdec_as_value_to_string (cx
, &argv
[0]);
343 count
= swfdec_as_value_to_integer (cx
, &argv
[1]);
349 if (str
== SWFDEC_AS_STR_EMPTY
|| delim
[1] != 0) {
350 SWFDEC_AS_VALUE_SET_STRING (&val
, str
);
351 swfdec_as_array_push (arr
, &val
);
354 while (*str
&& count
> 0) {
355 end
= strchr (str
, delim
[0]);
357 SWFDEC_AS_VALUE_SET_STRING (&val
, swfdec_as_context_get_string (cx
, str
));
358 swfdec_as_array_push (arr
, &val
);
361 SWFDEC_AS_VALUE_SET_STRING (&val
, swfdec_as_context_give_string (cx
, g_strndup (str
, end
- str
)));
362 swfdec_as_array_push (arr
, &val
);
370 swfdec_as_string_split_6 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
371 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
375 const char *str
, *end
, *delim
;
379 str
= swfdec_as_string_object_to_string (cx
, object
);
380 arr
= SWFDEC_AS_ARRAY (swfdec_as_array_new (cx
));
383 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (arr
));
384 /* hi, i'm the special case */
385 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0])) {
386 SWFDEC_AS_VALUE_SET_STRING (&val
, str
);
387 swfdec_as_array_push (arr
, &val
);
390 delim
= swfdec_as_value_to_string (cx
, &argv
[0]);
391 if (str
== SWFDEC_AS_STR_EMPTY
) {
392 SWFDEC_AS_VALUE_SET_STRING (&val
, str
);
393 swfdec_as_array_push (arr
, &val
);
397 count
= swfdec_as_value_to_integer (cx
, &argv
[1]);
402 len
= strlen (delim
);
404 if (delim
== SWFDEC_AS_STR_EMPTY
) {
410 end
= strstr (str
, delim
);
412 SWFDEC_AS_VALUE_SET_STRING (&val
, swfdec_as_context_get_string (cx
, str
));
413 swfdec_as_array_push (arr
, &val
);
417 SWFDEC_AS_VALUE_SET_STRING (&val
, swfdec_as_context_give_string (cx
, g_strndup (str
, end
- str
)));
418 swfdec_as_array_push (arr
, &val
);
425 SWFDEC_AS_NATIVE (251, 12, swfdec_as_string_split
)
427 swfdec_as_string_split (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
428 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
430 if (cx
->version
== 5) {
431 swfdec_as_string_split_5 (cx
, object
, argc
, argv
, ret
);
433 swfdec_as_string_split_6 (cx
, object
, argc
, argv
, ret
);
438 swfdec_as_str_sub (SwfdecAsContext
*cx
, const char *str
, guint offset
, guint len
)
442 str
= g_utf8_offset_to_pointer (str
, offset
);
443 end
= g_utf8_offset_to_pointer (str
, len
);
444 str
= swfdec_as_context_give_string (cx
, g_strndup (str
, end
- str
));
448 SWFDEC_AS_NATIVE (251, 13, swfdec_as_string_substr
)
450 swfdec_as_string_substr (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
451 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
453 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
456 from
= swfdec_as_value_to_integer (cx
, &argv
[0]);
457 len
= g_utf8_strlen (string
, -1);
460 to
= swfdec_as_value_to_integer (cx
, &argv
[1]);
469 if (from
< 0 && to
>= -from
)
477 from
= CLAMP (from
, 0, len
);
478 to
= CLAMP (to
, 0, len
- from
);
479 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_str_sub (cx
, string
, from
, to
));
482 SWFDEC_AS_NATIVE (251, 11, swfdec_as_string_substring
)
484 swfdec_as_string_substring (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
485 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
487 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
490 len
= g_utf8_strlen (string
, -1);
491 from
= swfdec_as_value_to_integer (cx
, &argv
[0]);
493 to
= swfdec_as_value_to_integer (cx
, &argv
[1]);
497 from
= MAX (from
, 0);
499 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
502 to
= CLAMP (to
, 0, len
);
508 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_str_sub (cx
, string
, from
, to
- from
));
511 SWFDEC_AS_NATIVE (251, 4, swfdec_as_string_toLowerCase
)
513 swfdec_as_string_toLowerCase (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
514 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
516 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
519 s
= g_utf8_strdown (string
, -1);
520 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_get_string (cx
, s
));
524 SWFDEC_AS_NATIVE (251, 3, swfdec_as_string_toUpperCase
)
526 swfdec_as_string_toUpperCase (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
527 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
529 const char *string
= swfdec_as_string_object_to_string (cx
, object
);
532 s
= g_utf8_strup (string
, -1);
533 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_get_string (cx
, s
));
537 /* escape and unescape are implemented here so the mad string functions share the same place */
540 swfdec_as_string_unescape_5 (SwfdecAsContext
*cx
, const char *msg
)
543 char cur
= 0; /* currently decoded character */
545 guint decoding
= 0; /* set if we're decoding a %XY string */
547 /* attention: c is a char* */
548 #define APPEND(chr) G_STMT_START{ \
549 g_byte_array_append (array, (guchar *) chr, 1); \
551 array
= g_byte_array_new ();
552 in
= s
= g_convert (msg
, -1, "LATIN1", "UTF-8", NULL
, NULL
, NULL
);
554 SWFDEC_FIXME ("%s can not be converted to utf8 - is this Flash 5 or what?", msg
);
560 if (*s
>= '0' && *s
<= '9') {
561 cur
= cur
* 16 + *s
- '0';
562 } else if (*s
>= 'A' && *s
<= 'F') {
563 cur
= cur
* 16 + *s
- 'A' + 10;
564 } else if (*s
>= 'a' && *s
<= 'f') {
565 cur
= cur
* 16 + *s
- 'a' + 10;
575 } else if (*s
== '%') {
577 } else if (*s
== '+') {
589 g_byte_array_append (array
, (guchar
*) &cur
, 1);
590 out
= g_convert ((char *) array
->data
, -1, "UTF-8", "LATIN1", NULL
, NULL
, NULL
);
591 g_byte_array_free (array
, TRUE
);
595 g_warning ("can't convert %s to UTF-8", msg
);
597 return g_strdup ("");
603 swfdec_as_string_escape (SwfdecAsContext
*cx
, const char *s
)
608 array
= g_byte_array_new ();
609 if (cx
->version
<= 5) {
610 in
= g_convert (s
, -1, "LATIN1", "UTF-8", NULL
, NULL
, NULL
);
612 SWFDEC_FIXME ("%s can not be converted to utf8 - is this Flash 5 or what?", s
);
619 if ((*s
>= '0' && *s
<= '9') ||
620 (*s
>= 'A' && *s
<= 'Z') ||
621 (*s
>= 'a' && *s
<= 'z')) {
622 g_byte_array_append (array
, (guchar
*) s
, 1);
624 guchar add
[3] = { '%', 0, 0 };
625 add
[1] = (guchar
) *s
/ 16;
626 add
[2] = (guchar
) *s
% 16;
627 add
[1] += add
[1] < 10 ? '0' : ('A' - 10);
628 add
[2] += add
[2] < 10 ? '0' : ('A' - 10);
629 g_byte_array_append (array
, add
, 3);
633 g_byte_array_append (array
, (guchar
*) s
, 1);
635 return (char *) g_byte_array_free (array
, FALSE
);
639 swfdec_as_string_escape_internal (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
640 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
645 swfdec_as_string_escape (cx
, swfdec_as_value_to_string (cx
, &argv
[0]));
646 if (result
!= NULL
) {
647 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_get_string (cx
, result
));
650 SWFDEC_AS_VALUE_SET_UNDEFINED (ret
);
655 swfdec_as_string_unescape_6 (SwfdecAsContext
*cx
, const char *s
)
659 char cur
= 0; /* currently decoded character */
660 guint decoding
= 0; /* set if we're decoding a %XY string */
661 guint utf8left
= 0; /* how many valid utf8 chars are still required */
662 const guchar invalid
[3] = { 0xEF, 0xBF, 0xBD };
664 /* attention: c is a char* */
665 #define APPEND(chr) G_STMT_START{ \
668 if ((c & 0xC0) == 0x80) { \
669 g_byte_array_append (array, &c, 1); \
672 guint __len = array->len - 1; \
673 while ((array->data[__len] & 0xC0) != 0xC0) \
675 g_byte_array_set_size (array, __len); \
676 g_byte_array_append (array, invalid, 3); \
681 g_byte_array_append (array, &c, 1); \
682 } else if (c < 0xC0) { \
683 guchar __foo = 0xC2; \
684 g_byte_array_append (array, &__foo, 1); \
685 g_byte_array_append (array, &c, 1); \
686 } else if (c > 0xF7) { \
689 g_byte_array_append (array, &c, 1); \
690 utf8left = (c < 0xE0) ? 1 : ((c < 0xF0) ? 2 : 3); \
694 array
= g_byte_array_new ();
699 if (*s
>= '0' && *s
<= '9') {
700 cur
= cur
* 16 + *s
- '0';
701 } else if (*s
>= 'A' && *s
<= 'F') {
702 cur
= cur
* 16 + *s
- 'A' + 10;
703 } else if (*s
>= 'a' && *s
<= 'f') {
704 cur
= cur
* 16 + *s
- 'a' + 10;
708 if ((guchar
) *s
> 0x7F) {
717 } else if (*s
== '%') {
719 } else if (*s
== '+') {
728 /* loop for break statement in APPEND macro */
730 guint __len
= array
->len
- 1;
731 while ((array
->data
[__len
] & 0xC0) != 0xC0)
733 g_byte_array_set_size (array
, __len
);
735 g_byte_array_append (array
, (guchar
*) &cur
, 1);
736 if (g_utf8_validate ((char *) array
->data
, -1, NULL
)) {
737 return (char *) g_byte_array_free (array
, FALSE
);
739 g_warning ("%s unescaped is invalid UTF-8", msg
);
740 g_byte_array_free (array
, TRUE
);
741 return g_strdup ("");
747 swfdec_as_string_unescape (SwfdecAsContext
*context
, const char *string
)
749 if (context
->version
< 6) {
750 return swfdec_as_string_unescape_5 (context
, string
);
752 return swfdec_as_string_unescape_6 (context
, string
);
757 swfdec_as_string_unescape_internal (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
758 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
763 swfdec_as_string_unescape (cx
, swfdec_as_value_to_string (cx
, &argv
[0]));
764 if (result
!= NULL
) {
765 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_get_string (cx
, result
));
768 SWFDEC_AS_VALUE_SET_UNDEFINED (ret
);
773 swfdec_as_string_init_context (SwfdecAsContext
*context
, guint version
)
775 SwfdecAsObject
*string
, *proto
;
778 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context
));
780 proto
= swfdec_as_object_new_empty (context
);
783 string
= SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context
->global
,
784 SWFDEC_AS_STR_String
, 0, SWFDEC_TYPE_AS_STRING
,
785 swfdec_as_string_construct
, 0, proto
));
788 /* set the right properties on the String object */
790 swfdec_as_object_add_function (string
, SWFDEC_AS_STR_fromCharCode
, 0, swfdec_as_string_fromCharCode_5
, 0);
792 swfdec_as_object_add_function (string
, SWFDEC_AS_STR_fromCharCode
, 0, swfdec_as_string_fromCharCode
, 0);
795 /* set the right properties on the String.prototype object */
796 SWFDEC_AS_VALUE_SET_OBJECT (&val
, string
);
797 swfdec_as_object_set_variable_and_flags (proto
, SWFDEC_AS_STR_constructor
,
798 &val
, SWFDEC_AS_VARIABLE_HIDDEN
| SWFDEC_AS_VARIABLE_PERMANENT
);
799 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_charAt
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_charAt
, 1);
800 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_indexOf
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_indexOf
, 1);
801 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_lastIndexOf
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_lastIndexOf
, 1);
802 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_charCodeAt
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_charCodeAt
, 1);
803 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_substr
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_substr
, 1);
804 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_substring
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_substring
, 1);
805 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_toLowerCase
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_toLowerCase
, 0);
806 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_toString
, SWFDEC_TYPE_AS_STRING
, swfdec_as_string_toString
, 0);
807 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_toUpperCase
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_toUpperCase
, 0);
808 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_valueOf
, SWFDEC_TYPE_AS_STRING
, swfdec_as_string_valueOf
, 0);
809 swfdec_as_object_add_function (proto
, SWFDEC_AS_STR_split
, SWFDEC_TYPE_AS_OBJECT
, swfdec_as_string_split
, 1);
810 SWFDEC_AS_VALUE_SET_OBJECT (&val
, context
->Object_prototype
);
811 swfdec_as_object_set_variable_and_flags (proto
, SWFDEC_AS_STR___proto__
, &val
,
812 SWFDEC_AS_VARIABLE_HIDDEN
| SWFDEC_AS_VARIABLE_PERMANENT
);
814 /* add properties to global object */
815 swfdec_as_object_add_function (context
->global
, SWFDEC_AS_STR_escape
, 0, swfdec_as_string_escape_internal
, 1);
816 swfdec_as_object_add_function (context
->global
, SWFDEC_AS_STR_unescape
, 0, swfdec_as_string_unescape_internal
, 1);