📄 swfdec_as_string.c
字号:
/* Swfdec * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include <string.h>#include "swfdec_as_string.h"#include "swfdec_as_array.h"#include "swfdec_as_context.h"#include "swfdec_as_native_function.h"#include "swfdec_as_strings.h"#include "swfdec_debug.h"#include "swfdec_player_internal.h"G_DEFINE_TYPE (SwfdecAsString, swfdec_as_string, SWFDEC_TYPE_AS_OBJECT)static voidswfdec_as_string_do_mark (SwfdecAsObject *object){ SwfdecAsString *string = SWFDEC_AS_STRING (object); swfdec_as_string_mark (string->string); SWFDEC_AS_OBJECT_CLASS (swfdec_as_string_parent_class)->mark (object);}static char *swfdec_as_string_debug (SwfdecAsObject *object){ SwfdecAsString *string = SWFDEC_AS_STRING (object); return g_strdup (string->string);}static voidswfdec_as_string_class_init (SwfdecAsStringClass *klass){ SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); asobject_class->mark = swfdec_as_string_do_mark; asobject_class->debug = swfdec_as_string_debug;}static voidswfdec_as_string_init (SwfdecAsString *string){ string->string = SWFDEC_AS_STR_EMPTY;}/*** AS CODE ***/static const char *swfdec_as_string_object_to_string (SwfdecAsContext *context, SwfdecAsObject *object){ SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); SWFDEC_AS_VALUE_SET_OBJECT (&val, object); return swfdec_as_value_to_string (context, &val);}static inline const char *swfdec_as_str_nth_char (const char *s, guint n){ while (*s && n--) s = g_utf8_next_char (s); return s;}SWFDEC_AS_NATIVE (251, 9, swfdec_as_string_lastIndexOf)voidswfdec_as_string_lastIndexOf (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ const char *string = swfdec_as_string_object_to_string (cx, object); gsize len; const char *s; s = swfdec_as_value_to_string (object->context, &argv[0]); if (argc == 2) { int offset = swfdec_as_value_to_integer (object->context, &argv[1]); if (offset < 0) { SWFDEC_AS_VALUE_SET_INT (ret, -1); return; } len = g_utf8_offset_to_pointer (string, offset + 1) - string; } else { len = G_MAXSIZE; } s = g_strrstr_len (string, len, s); if (s) { SWFDEC_AS_VALUE_SET_INT (ret, g_utf8_pointer_to_offset (string, s)); } else { SWFDEC_AS_VALUE_SET_INT (ret, -1); }}SWFDEC_AS_NATIVE (251, 8, swfdec_as_string_indexOf)voidswfdec_as_string_indexOf (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ const char *string = swfdec_as_string_object_to_string (cx, object); int offset=0, len, i=-1; const char *s, *t = NULL; s = swfdec_as_value_to_string (object->context, &argv[0]); if (argc == 2) offset = swfdec_as_value_to_integer (object->context, &argv[1]); if (offset < 0) offset = 0; len = g_utf8_strlen (string, -1); if (offset < len) { t = strstr (g_utf8_offset_to_pointer (string, offset), s); } if (t != NULL) { i = g_utf8_pointer_to_offset (string, t); } SWFDEC_AS_VALUE_SET_INT (ret, i);}SWFDEC_AS_NATIVE (251, 5, swfdec_as_string_charAt)voidswfdec_as_string_charAt (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ const char *string = swfdec_as_string_object_to_string (cx, object); int i; const char *s, *t; i = swfdec_as_value_to_integer (object->context, &argv[0]); if (i < 0) { SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY); return; } s = swfdec_as_str_nth_char (string, i); if (*s == 0) { SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY); return; } t = g_utf8_next_char (s); s = swfdec_as_context_give_string (cx, g_strndup (s, t - s)); SWFDEC_AS_VALUE_SET_STRING (ret, s);}SWFDEC_AS_NATIVE (251, 6, swfdec_as_string_charCodeAt)voidswfdec_as_string_charCodeAt (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ const char *string = swfdec_as_string_object_to_string (cx, object); int i; const char *s; gunichar c; i = swfdec_as_value_to_integer (cx, &argv[0]); if (i < 0) { SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN); return; } s = swfdec_as_str_nth_char (string, i); if (*s == 0) { if (cx->version > 5) { SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN); } else { SWFDEC_AS_VALUE_SET_INT (ret, 0); } return; } c = g_utf8_get_char (s); SWFDEC_AS_VALUE_SET_NUMBER (ret, c);}static voidswfdec_as_string_fromCharCode_5 (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ guint i, c; guint8 append; GError *error = NULL; char *s; GByteArray *array = g_byte_array_new (); for (i = 0; i < argc; i++) { c = ((guint) swfdec_as_value_to_integer (cx, &argv[i])) % 65536; if (c > 255) { append = c / 256; g_byte_array_append (array, &append, 1); } append = c; g_byte_array_append (array, &append, 1); } /* FIXME: are these the correct charset names? */ s = g_convert ((char *) array->data, array->len, "UTF-8", "LATIN1", NULL, NULL, &error); if (s) { SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_get_string (cx, s)); g_free (s); } else { SWFDEC_ERROR ("%s", error->message); g_error_free (error); } g_byte_array_free (array, TRUE);}static voidswfdec_as_string_fromCharCode (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gunichar tmp[8]; gunichar *chars; guint i; char *s; GError *error = NULL; if (argc <= 8) chars = tmp; else chars = g_new (gunichar, argc); for (i = 0; i < argc; i++) { chars[i] = ((guint) swfdec_as_value_to_integer (cx, &argv[i])) % 65536; } s = g_ucs4_to_utf8 (chars, argc, NULL, NULL, &error); if (s) { SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_get_string (cx, s)); g_free (s); } else { SWFDEC_ERROR ("%s", error->message); g_error_free (error); } if (chars != tmp) g_free (chars);}static voidswfdec_as_string_construct (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ const char *s; if (argc > 0) { s = swfdec_as_value_to_string (cx, &argv[0]); } else { s = SWFDEC_AS_STR_EMPTY; } if (swfdec_as_context_is_constructing (cx)) { SwfdecAsString *string = SWFDEC_AS_STRING (object); SwfdecAsValue val; string->string = s; SWFDEC_AS_VALUE_SET_INT (&val, g_utf8_strlen (string->string, -1)); swfdec_as_object_set_variable (object, SWFDEC_AS_STR_length, &val); SWFDEC_AS_VALUE_SET_OBJECT (ret, object); } else { SWFDEC_AS_VALUE_SET_STRING (ret, s); }}SWFDEC_AS_NATIVE (251, 2, swfdec_as_string_toString)voidswfdec_as_string_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ SwfdecAsString *string = SWFDEC_AS_STRING (object); SWFDEC_AS_VALUE_SET_STRING (ret, string->string);}SWFDEC_AS_NATIVE (251, 1, swfdec_as_string_valueOf)voidswfdec_as_string_valueOf (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ SwfdecAsString *string = SWFDEC_AS_STRING (object); SWFDEC_AS_VALUE_SET_STRING (ret, string->string);}#if 0charAt(index:Number) : StringcharCodeAt(index:Number) : Numberconcat(value:Object) : StringindexOf(value:String, [startIndex:Number]) : Numberslice(start:Number, end:Number) : Stringsplit(delimiter:String, [limit:Number]) : Array#endifstatic voidswfdec_as_string_split_5 (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ SwfdecAsArray *arr; SwfdecAsValue val; const char *str, *end, *delim; int count; str = swfdec_as_string_object_to_string (cx, object); arr = SWFDEC_AS_ARRAY (swfdec_as_array_new (cx)); if (arr == NULL) return; SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (arr)); /* hi, i'm the special case */ if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0])) { delim = SWFDEC_AS_STR_COMMA; } else { delim = swfdec_as_value_to_string (cx, &argv[0]); } if (delim == SWFDEC_AS_STR_EMPTY) { SWFDEC_AS_VALUE_SET_STRING (&val, str); swfdec_as_array_push (arr, &val); return; } if (argc > 1) { swfdec_as_value_to_string (cx, &argv[0]); count = swfdec_as_value_to_integer (cx, &argv[1]); } else { count = G_MAXINT; } if (count <= 0) return; if (str == SWFDEC_AS_STR_EMPTY || delim[1] != 0) { SWFDEC_AS_VALUE_SET_STRING (&val, str); swfdec_as_array_push (arr, &val); return; } while (*str && count > 0) { end = strchr (str, delim[0]); if (end == NULL) { SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (cx, str)); swfdec_as_array_push (arr, &val); break; } SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_give_string (cx, g_strndup (str, end - str))); swfdec_as_array_push (arr, &val); if (count) count--; str = end + 1; }}static voidswfdec_as_string_split_6 (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ SwfdecAsArray *arr; SwfdecAsValue val; const char *str, *end, *delim; int count; guint len; str = swfdec_as_string_object_to_string (cx, object); arr = SWFDEC_AS_ARRAY (swfdec_as_array_new (cx)); if (arr == NULL) return; SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (arr)); /* hi, i'm the special case */ if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0])) { SWFDEC_AS_VALUE_SET_STRING (&val, str); swfdec_as_array_push (arr, &val); return; } delim = swfdec_as_value_to_string (cx, &argv[0]); if (str == SWFDEC_AS_STR_EMPTY) { SWFDEC_AS_VALUE_SET_STRING (&val, str); swfdec_as_array_push (arr, &val); return; } if (argc > 1) count = swfdec_as_value_to_integer (cx, &argv[1]); else count = G_MAXINT; if (count <= 0) return; len = strlen (delim); while (count > 0) { if (delim == SWFDEC_AS_STR_EMPTY) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -