📄 swfdec_as_array.c
字号:
* Creates a new #SwfdecAsArray. * * Returns: the new array or %NULL on OOM. **/SwfdecAsObject *swfdec_as_array_new (SwfdecAsContext *context){ SwfdecAsObject *ret; g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); g_return_val_if_fail (context->Array != NULL, NULL); if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsArray))) return FALSE; ret = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL); swfdec_as_object_add (ret, context, sizeof (SwfdecAsArray)); swfdec_as_object_set_constructor (ret, context->Array); swfdec_as_array_set_length (ret, 0); return ret;}/*** AS CODE ***/SWFDEC_AS_NATIVE (252, 7, swfdec_as_array_join)voidswfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ int i, length; const char *var, *str, *sep; SwfdecAsValue val; if (argc > 0) { sep = swfdec_as_value_to_string (cx, &argv[0]); } else { sep = SWFDEC_AS_STR_COMMA; } length = swfdec_as_array_get_length (object); if (length > 0) { /* FIXME: implement this with the StringBuilder class */ GString *string; var = swfdec_as_double_to_string (cx, 0); swfdec_as_object_get_variable (object, var, &val); str = swfdec_as_value_to_string (cx, &val); string = g_string_new (str); for (i = 1; i < length; i++) { var = swfdec_as_double_to_string (cx, i); swfdec_as_object_get_variable (object, var, &val); var = swfdec_as_value_to_string (cx, &val); g_string_append (string, sep); g_string_append (string, var); } str = swfdec_as_context_give_string (cx, g_string_free (string, FALSE)); } else { str = SWFDEC_AS_STR_EMPTY; } SWFDEC_AS_VALUE_SET_STRING (ret, str);}SWFDEC_AS_NATIVE (252, 9, swfdec_as_array_toString)voidswfdec_as_array_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ swfdec_as_array_join (cx, object, 0, NULL, ret);}SWFDEC_AS_NATIVE (252, 1, swfdec_as_array_do_push)voidswfdec_as_array_do_push (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ // if 0 args, just return the length // manually set the length here to make the function work on non-Arrays if (argc > 0) { gint32 length = swfdec_as_array_get_length_as_integer (object); swfdec_as_array_append_internal (object, argc, argv); swfdec_as_array_set_length (object, length + argc); } SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length_as_integer (object));}SWFDEC_AS_NATIVE (252, 2, swfdec_as_array_do_pop)voidswfdec_as_array_do_pop (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gint32 length; const char *var; // we allow negative indexes here, but not 0 length = swfdec_as_array_get_length_as_integer (object); if (length == 0) return; var = swfdec_as_double_to_string (object->context, length - 1); swfdec_as_object_get_variable (object, var, ret); // if Array, the length is reduced by one (which destroys the variable also) // else the length is not reduced at all, but the variable is still deleted if (SWFDEC_IS_AS_ARRAY (object)) { swfdec_as_array_set_length (object, length - 1); } else { swfdec_as_object_delete_variable (object, var); }}SWFDEC_AS_NATIVE (252, 5, swfdec_as_array_do_unshift)voidswfdec_as_array_do_unshift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gint32 length; if (argc) { // don't allow negative length length = swfdec_as_array_get_length (object); swfdec_as_array_move_range (object, 0, length, argc); swfdec_as_array_set_range (object, 0, argc, argv); // if not Array, leave the length unchanged if (!SWFDEC_IS_AS_ARRAY (object)) swfdec_as_array_set_length (object, length); } SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length (object));}SWFDEC_AS_NATIVE (252, 4, swfdec_as_array_do_shift)voidswfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gint32 length; const char *var; // don't allow negative length length = swfdec_as_array_get_length (object); if (length <= 0) return; var = swfdec_as_double_to_string (object->context, 0); swfdec_as_object_get_variable (object, var, ret); swfdec_as_array_move_range (object, 1, length - 1, 0); // if not Array, leave the length unchanged, and don't remove the element if (SWFDEC_IS_AS_ARRAY (object)) { swfdec_as_array_set_length (object, length - 1); } else { // we have to put the last element back, because we used move, not copy SwfdecAsValue val; if (length > 1) { var = swfdec_as_double_to_string (object->context, length - 2); swfdec_as_object_get_variable (object, var, &val); } else { val = *ret; } var = swfdec_as_double_to_string (object->context, length - 1); swfdec_as_object_set_variable (object, var, &val); }}static const char *swfdec_as_array_foreach_reverse (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data){ gint32 *length = data; gint32 idx; idx = swfdec_as_array_to_index (variable); if (idx == -1) return variable; return swfdec_as_double_to_string (object->context, *length - 1 - idx);}SWFDEC_AS_NATIVE (252, 11, swfdec_as_array_reverse)voidswfdec_as_array_reverse (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gint32 length; length = swfdec_as_array_get_length (object); swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_reverse, &length); SWFDEC_AS_VALUE_SET_OBJECT (ret, object);}SWFDEC_AS_NATIVE (252, 3, swfdec_as_array_concat)voidswfdec_as_array_concat (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ guint j; SwfdecAsObject *object_new; SwfdecAsArray *array_new; const char *var; object_new = swfdec_as_array_new (cx); array_new = SWFDEC_AS_ARRAY (object_new); swfdec_as_array_append_array (array_new, object); for (j = 0; j < argc; j++) { if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[j]) && SWFDEC_IS_AS_ARRAY (SWFDEC_AS_VALUE_GET_OBJECT (&argv[j]))) { swfdec_as_array_append_array (array_new, SWFDEC_AS_VALUE_GET_OBJECT (&argv[j])); } else { var = swfdec_as_double_to_string (object->context, swfdec_as_array_get_length (object_new)); swfdec_as_object_set_variable (object_new, var, &argv[j]); } } SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);}SWFDEC_AS_NATIVE (252, 6, swfdec_as_array_slice)voidswfdec_as_array_slice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gint32 length, start_index, num; SwfdecAsObject *object_new; SwfdecAsArray *array_new; length = swfdec_as_array_get_length (object); if (argc > 0) { start_index = swfdec_as_value_to_integer (cx, &argv[0]); if (start_index < 0) start_index = length + start_index; start_index = CLAMP (start_index, 0, length); } else { start_index = 0; } if (argc > 1) { gint32 endIndex = swfdec_as_value_to_integer (cx, &argv[1]); if (endIndex < 0) endIndex = length + endIndex; endIndex = CLAMP (endIndex, start_index, length); num = endIndex - start_index; } else { num = length - start_index; } object_new = swfdec_as_array_new (cx); array_new = SWFDEC_AS_ARRAY (object_new); swfdec_as_array_append_array_range (array_new, object, start_index, num); SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);}SWFDEC_AS_NATIVE (252, 8, swfdec_as_array_splice)voidswfdec_as_array_splice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ gint32 length, start_index, num_remove, num_add; SwfdecAsObject *object_new; SwfdecAsArray *array_new; length = swfdec_as_array_get_length (object); if (argc > 0) { start_index = swfdec_as_value_to_integer (cx, &argv[0]); if (start_index < 0) start_index = length + start_index; start_index = CLAMP (start_index, 0, length); } else { start_index = 0; } if (argc > 1) { num_remove = CLAMP (swfdec_as_value_to_integer (cx, &argv[1]), 0, length - start_index); } else { num_remove = length - start_index; } num_add = (argc > 2 ? argc - 2 : 0); object_new = swfdec_as_array_new (cx); array_new = SWFDEC_AS_ARRAY (object_new); swfdec_as_array_append_array_range (array_new, object, start_index, num_remove); swfdec_as_array_move_range (object, start_index + num_remove, length - (start_index + num_remove), start_index + num_add); if (num_remove > num_add) swfdec_as_array_set_length (object, length - (num_remove - num_add)); if (argc > 2) swfdec_as_array_set_range (object, start_index, argc - 2, argv + 2); SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);}// Sortingtypedef enum { ARRAY_SORT_OPTION_CASEINSENSITIVE = 1, ARRAY_SORT_OPTION_DESCENDING = 2, ARRAY_SORT_OPTION_UNIQUESORT = 4, ARRAY_SORT_OPTION_RETURNINDEXEDARRAY = 8, ARRAY_SORT_OPTION_NUMERIC = 16} ArraySortOptions;typedef struct { SwfdecAsValue **order; gint32 order_size; SwfdecAsValue undefined; gint32 defined_values; gint32 length; gint32 options; SwfdecAsFunction *compare_custom_func; SwfdecAsObject *object_new;} ForeachSortData;static gintswfdec_as_array_sort_compare (SwfdecAsContext *cx, SwfdecAsValue *a, SwfdecAsValue *b, gint32 options, SwfdecAsFunction *fun){ gint retval; if (fun != NULL) { SwfdecAsValue argv[2] = { *a, *b }; SwfdecAsValue ret; swfdec_as_function_call (fun, NULL, 2, argv, &ret); swfdec_as_context_run (fun->object.context); retval = swfdec_as_value_to_integer (cx, &ret); } else if (options & ARRAY_SORT_OPTION_NUMERIC && (SWFDEC_AS_VALUE_IS_NUMBER (a) || SWFDEC_AS_VALUE_IS_NUMBER (b)) && !SWFDEC_AS_VALUE_IS_UNDEFINED (a) && !SWFDEC_AS_VALUE_IS_UNDEFINED (b)) { if (!SWFDEC_AS_VALUE_IS_NUMBER (a)) { retval = 1; } else if (!SWFDEC_AS_VALUE_IS_NUMBER (b)) { retval = -1; } else { double an = swfdec_as_value_to_number (cx, a); double bn = swfdec_as_value_to_number (cx, b); retval = (an < bn ? -1 : (an > bn ? 1 : 0)); } } else if (options & ARRAY_SORT_OPTION_CASEINSENSITIVE) { retval = g_strcasecmp (swfdec_as_value_to_string (cx, a), swfdec_as_value_to_string (cx, b)); } else { retval = strcmp (swfdec_as_value_to_string (cx, a), swfdec_as_value_to_string (cx, b)); } if (options & ARRAY_SORT_OPTION_DESCENDING) { return -retval; } else { return retval; }}// renames values in the array based on fdata->order valuesstatic const char *swfdec_as_array_foreach_sort_rename (SwfdecAsObject *object,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -