📄 swfdec_as_array.c
字号:
const char *variable, SwfdecAsValue *value, guint flags, gpointer data){ ForeachSortData *fdata = data; gint32 idx, i; gboolean after_undefined = FALSE; idx = swfdec_as_array_to_index (variable); if (idx == -1) return variable; if (SWFDEC_AS_VALUE_IS_UNDEFINED (value)) value = &fdata->undefined; for (i = 0; i < fdata->order_size; i++) { if (fdata->order[i] == value) { fdata->order[i] = NULL; // leave room for undefined values if (after_undefined) i += fdata->length - fdata->defined_values - 1; return swfdec_as_double_to_string (object->context, i); } if (fdata->order[i] == &fdata->undefined) after_undefined = TRUE; } g_assert_not_reached (); return variable;}// fills fdata->object_new array using indexes based on the fdata->orderstatic gbooleanswfdec_as_array_foreach_sort_indexedarray (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data){ ForeachSortData *fdata = data; SwfdecAsValue val; const char *var; gint32 idx, i; gboolean after_undefined = FALSE; idx = swfdec_as_array_to_index (variable); if (idx == -1) return TRUE; if (SWFDEC_AS_VALUE_IS_UNDEFINED (value)) return TRUE; for (i = 0; i < fdata->order_size; i++) { if (fdata->order[i] == value) { fdata->order[i] = NULL; // leave room for undefined values, that are filled in afterwards if (after_undefined) i += fdata->length - fdata->defined_values - 1; var = swfdec_as_double_to_string (object->context, i); SWFDEC_AS_VALUE_SET_INT (&val, idx); swfdec_as_object_set_variable (fdata->object_new, var, &val); return TRUE; } if (fdata->order[i] == &fdata->undefined) after_undefined = TRUE; } g_assert_not_reached (); return TRUE;}// sets undefined values in the fdata->object_new array to indexes of undefined// values in the object arraystatic voidswfdec_as_array_sort_set_undefined_indexedarray (SwfdecAsObject *object, ForeachSortData *fdata){ SwfdecAsValue val; const char *var; gint32 idx, i, length, num; for (idx = 0; idx < fdata->order_size; idx++) { if (fdata->order[idx] == &fdata->undefined) break; } num = 0; length = swfdec_as_array_get_length (object); for (i = 0; i < length - fdata->defined_values; i++) { do { var = swfdec_as_double_to_string (object->context, num); num++; } while (swfdec_as_object_get_variable (object, var, &val)); var = swfdec_as_double_to_string (fdata->object_new->context, idx + i); SWFDEC_AS_VALUE_SET_INT (&val, num - 1); swfdec_as_object_set_variable (fdata->object_new, var, &val); }}// tests if any value in the array is equal to a undefined value// (in the sense that sorting compare function returns 0)// used by uniquesort when there is exactly one undefined value in the arraystatic gbooleanswfdec_as_array_foreach_sort_compare_undefined (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data){ ForeachSortData *fdata = data; gint32 idx; idx = swfdec_as_array_to_index (variable); if (idx == -1) return TRUE; if (SWFDEC_AS_VALUE_IS_UNDEFINED (value)) return TRUE; fdata->defined_values++; // when testing for uniquesort the custom compare function is NOT used if (swfdec_as_array_sort_compare (object->context, value, &fdata->undefined, fdata->options, NULL) == 0) return FALSE; return TRUE;}static gbooleanswfdec_as_array_foreach_sort_populate (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data){ ForeachSortData *fdata = data; gint32 idx, i; gint cval = -1; idx = swfdec_as_array_to_index (variable); if (idx == -1) return TRUE; if (SWFDEC_AS_VALUE_IS_UNDEFINED (value)) return TRUE; fdata->defined_values++; // find the position for this value for (i = 0; i < fdata->order_size; i++) { if (fdata->order[i] == NULL || (cval = swfdec_as_array_sort_compare (object->context, value, fdata->order[i], fdata->options, fdata->compare_custom_func)) <= 0) { SwfdecAsValue *tmp2, *tmp; // if we are doing uniquesort, see if this value is the same as some // earlier value if (fdata->options & ARRAY_SORT_OPTION_UNIQUESORT && fdata->order[i] != NULL && fdata->order[i] != &fdata->undefined) { // when using custom function, uniquesort is still based on the // equality given by the normal method, not the custom function if (fdata->compare_custom_func != NULL) { if (swfdec_as_array_sort_compare (object->context, value, fdata->order[i], fdata->options, NULL) == 0) return FALSE; } else { if (cval == 0) return FALSE; } } // move rest of the values forward tmp = fdata->order[i]; fdata->order[i] = value; while (tmp != NULL && ++i < fdata->order_size) { tmp2 = fdata->order[i]; fdata->order[i] = tmp; tmp = tmp2; } return TRUE; } } g_assert_not_reached (); return TRUE;}SWFDEC_AS_NATIVE (252, 10, swfdec_as_array_sort)voidswfdec_as_array_sort (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ ForeachSortData fdata; guint pos; fdata.length = swfdec_as_array_get_length (object); fdata.order_size = MIN ((gint32)g_hash_table_size (object->properties) + 1, fdata.length + 1); fdata.order = g_new0 (SwfdecAsValue *, fdata.order_size); SWFDEC_AS_VALUE_SET_UNDEFINED (&fdata.undefined); fdata.order[0] = &fdata.undefined; fdata.defined_values = 0; pos = 0; if (argc > 0 && !SWFDEC_AS_VALUE_IS_NUMBER (&argv[0])) { SwfdecAsFunction *fun; if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]) || !SWFDEC_IS_AS_FUNCTION ( fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]))) return; fdata.compare_custom_func = fun; pos++; } else { fdata.compare_custom_func = NULL; } if (argc > pos) { fdata.options = swfdec_as_value_to_integer (cx, &argv[pos]); } else { fdata.options = 0; } // generate fdata.order which points to the values if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate, &fdata)) { // uniquesort failed SWFDEC_AS_VALUE_SET_INT (ret, 0); g_free (fdata.order); return; } if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && fdata.defined_values + 1 < fdata.length) { // uniquesort fails, because we have more than one undefined value SWFDEC_AS_VALUE_SET_INT (ret, 0); g_free (fdata.order); return; } if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && fdata.defined_values < fdata.length) { // uniquesort used, and we have exactly one undefined value test if // anything equeals to that if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_compare_undefined, &fdata)) { SWFDEC_AS_VALUE_SET_INT (ret, 0); g_free (fdata.order); return; } } if (fdata.options & ARRAY_SORT_OPTION_RETURNINDEXEDARRAY) { // make a new array and fill it with numbers based on the order fdata.object_new = swfdec_as_array_new (cx); swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_indexedarray, &fdata); // we only have the elements that have been set so far, fill in the blanks swfdec_as_array_sort_set_undefined_indexedarray (object, &fdata); SWFDEC_AS_VALUE_SET_OBJECT (ret, fdata.object_new); } else { // rename properties based on the new order swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_sort_rename, &fdata); SWFDEC_AS_VALUE_SET_OBJECT (ret, object); } g_free (fdata.order);}SWFDEC_AS_NATIVE (252, 12, swfdec_as_array_sortOn)voidswfdec_as_array_sortOn (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ SWFDEC_ERROR ("Array.sortOn method not implemented");}// Constructorstatic voidswfdec_as_array_construct (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret){ SwfdecAsArray *array; if (!cx->frame->construct) { SwfdecAsValue val; if (!swfdec_as_context_use_mem (cx, sizeof (SwfdecAsArray))) return; object = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL); swfdec_as_object_add (object, cx, sizeof (SwfdecAsArray)); swfdec_as_object_get_variable (cx->global, SWFDEC_AS_STR_Array, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { swfdec_as_object_set_constructor (object, SWFDEC_AS_VALUE_GET_OBJECT (&val)); } else { SWFDEC_INFO ("\"Array\" is not an object"); } } array = SWFDEC_AS_ARRAY (object); if (argc == 1 && SWFDEC_AS_VALUE_IS_NUMBER (&argv[0])) { int l = swfdec_as_value_to_integer (cx, &argv[0]); swfdec_as_array_set_length (object, l < 0 ? 0 : l); } else if (argc > 0) { swfdec_as_array_append (array, argc, argv); } else { swfdec_as_array_set_length (object, 0); } SWFDEC_AS_VALUE_SET_OBJECT (ret, object);}voidswfdec_as_array_init_context (SwfdecAsContext *context, guint version){ SwfdecAsObject *array, *proto; SwfdecAsValue val; g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsArray))) return; proto = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL); swfdec_as_object_add (proto, context, sizeof (SwfdecAsArray)); array = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global, SWFDEC_AS_STR_Array, 0, SWFDEC_TYPE_AS_ARRAY, swfdec_as_array_construct, 0, proto)); if (!array) return; context->Array = array; /* set the right properties on the Array object */ SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function); swfdec_as_object_set_variable_and_flags (array, SWFDEC_AS_STR_constructor, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_CASEINSENSITIVE); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_CASEINSENSITIVE, &val); SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_DESCENDING); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_DESCENDING, &val); SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_UNIQUESORT); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_UNIQUESORT, &val); SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_RETURNINDEXEDARRAY); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_RETURNINDEXEDARRAY, &val); SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_NUMERIC); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_NUMERIC, &val); /* set the right properties on the Array.prototype object */ SWFDEC_AS_VALUE_SET_OBJECT (&val, array); swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0, swfdec_as_array_toString, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_join, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_join, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_push, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_push, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_pop, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_pop, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_unshift, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_unshift, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_shift, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_shift, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_reverse, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_reverse, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_concat, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_concat, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_slice, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_slice, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_splice, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_splice, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sort, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sort, 0); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sortOn, SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sortOn, 0); SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype); swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -