📄 swfdec_as_types.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_types.h"#include "swfdec_as_object.h"#include "swfdec_as_context.h"#include "swfdec_as_function.h"#include "swfdec_as_number.h"#include "swfdec_as_stack.h"#include "swfdec_as_strings.h"#include "swfdec_as_super.h"#include "swfdec_debug.h"#include "swfdec_movie.h"/*** GTK-DOC ***//** * SECTION:SwfdecAsValue * @title: SwfdecAsValue * @short_description: exchanging values with the Actionscript engine * * This section describes how values are handled inside the Actionscript * engine. Since Actionscript is a dynamically typed language, the variable type * has to be carried with every value. #SwfdecAsValue accomplishes that. Swfdec * allows two possible ways of accessing these values: The common method is to * use the provided functions to explicitly convert the values to a given type * with a function such as swfdec_as_value_to_string (). This is convenient, * but can be very slow as it can call back into the Actionscript engine when * converting various objects. So it can be unsuitable in some cases. * A different possibiltiy is accessing the values directly using the accessor * macros. You must check the type before doing so though. For setting values, * there only exist macros, since type conversion is not necessary. *//** * SwfdecAsValueType: * @SWFDEC_AS_TYPE_UNDEFINED: the special undefined value * @SWFDEC_AS_TYPE_BOOLEAN: a boolean value - true or false * @SWFDEC_AS_TYPE_INT: reserved value for integers. Should the need arise for * performance enhancements - especially on embedded * devices - it might be useful to implement this type. * For now, this type will never appear in Swfdec. Using * it will cause Swfdec to crash. * @SWFDEC_AS_TYPE_NUMBER: a double value - also used for integer numbers * @SWFDEC_AS_TYPE_STRING: a string. Strings are garbage-collected and unique. * @SWFDEC_AS_TYPE_NULL: the spaecial null value * @SWFDEC_AS_TYPE_OBJECT: an object - must be of type #SwfdecAsObject * * These are the possible values the Swfdec Actionscript engine knows about. *//** * SwfdecAsValue: * @type: the type of this value. * * This is the type used to present an opaque value in the Actionscript * engine. See #SwfdecAsValueType for possible types. It's similar in * spirit to #GValue. The value held is garbage-collected. Apart from the type * member, use the provided macros to access this structure. * <note>If you memset a SwfdecAsValue to 0, it is a valid undefined value.</note> *//** * SWFDEC_AS_VALUE_SET_UNDEFINED: * @val: value to set as undefined * * Sets @val to the special undefined value. If you create a temporary value, * you can instead use code such as |[ SwfdecAsValue val = { 0, }; ]| *//** * SWFDEC_AS_VALUE_GET_BOOLEAN: * @val: value to get, the value must reference a boolean * * Gets the boolean associated with value. If you are not sure if the value is * a boolean, use swfdec_as_value_to_boolean () instead. * * Returns: %TRUE or %FALSE *//** * SWFDEC_AS_VALUE_SET_BOOLEAN: * @val: value to set * @b: boolean value to set, must be either %TRUE or %FALSE * * Sets @val to the specified boolean value. *//** * SWFDEC_AS_VALUE_GET_NUMBER: * @val: value to get, the value must reference a number * * Gets the number associated with @val. If you are not sure that the value is * a valid number value, consider using swfdec_as_value_to_number() or * swfdec_as_value_to_int() instead. * * Returns: a double. It can be NaN or +-Infinity, but not -0.0 *//** * SWFDEC_AS_VALUE_SET_NUMBER: * @val: value to set * @d: double value to set * * Sets @val to the given value. If you are sure the value is a valid * integer value, use SWFDEC_AS_VALUE_SET_INT() instead. *//** * SWFDEC_AS_VALUE_SET_INT: * @val: value to set * @d: integer value to set * * Sets @val to the given value. Currently this macro is equivalent to * SWFDEC_AS_VALUE_SET_NUMBER(), but this may change in future versions of * Swfdec. *//** * SWFDEC_AS_VALUE_GET_STRING: * @val: value to get, the value must reference a string * * Gets the string associated with @val. If you are not sure that the value is * a string value, consider using swfdec_as_value_to_string() instead. * * Returns: a garbage-collected string. *//** * SWFDEC_AS_VALUE_SET_STRING: * @val: value to set * @s: garbage-collected string to use * * Sets @val to the given string value. *//** * SWFDEC_AS_VALUE_SET_NULL: * @val: value to set * * Sets @val to the special null value. *//** * SWFDEC_AS_VALUE_GET_OBJECT: * @val: value to get, the value must reference an object * * Gets the object associated with @val. If you are not sure that the value is * an object value, consider using swfdec_as_value_to_object() instead. * * Returns: a #SwfdecAsObject *//** * SWFDEC_AS_VALUE_SET_OBJECT: * @val: value to set * @o: garbage-collected #SwfdecAsObject to use * * Sets @val to the given object. The object must have been added to the * garbage collector via swfdec_as_object_add() previously. *//*** actual code ***//** * swfdec_as_str_concat: * @cx: a #SwfdecAsContext * @s1: first string * @s2: second string * * Convenience function to concatenate two garbage-collected strings. This * function is equivalent to g_strconcat (). * * Returns: A new garbage-collected string **/const char *swfdec_as_str_concat (SwfdecAsContext *cx, const char * s1, const char *s2){ const char *ret; char *s; g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (cx), SWFDEC_AS_STR_EMPTY); g_return_val_if_fail (s1, SWFDEC_AS_STR_EMPTY); g_return_val_if_fail (s2, SWFDEC_AS_STR_EMPTY); s = g_strconcat (s1, s2, NULL); ret = swfdec_as_context_get_string (cx, s); g_free (s); return ret;}/** * swfdec_as_double_to_string: * @context: a #SwfdecAsContext * @d: a double * * Converts @d into a string using the same conversion algorithm as the * official Flash player. * * Returns: a garbage-collected string **//* FIXME: this function is still buggy - and it's ugly as hell. * Someone with the right expertise should rewrite it * Some pointers: * http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf * http://lxr.mozilla.org/mozilla/source/js/tamarin/core/MathUtils.cpp */const char *swfdec_as_double_to_string (SwfdecAsContext *context, double d){ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), SWFDEC_AS_STR_EMPTY); switch (fpclassify (d)) { case FP_ZERO: return SWFDEC_AS_STR_0; case FP_INFINITE: return d < 0 ? SWFDEC_AS_STR__Infinity : SWFDEC_AS_STR_Infinity; case FP_NAN: return SWFDEC_AS_STR_NaN; default: { gboolean found = FALSE, gotdot = FALSE; guint digits = 15; char tmp[50], *end, *start, *s; tmp[0] = ' '; s = &tmp[1]; if (ABS (d) > 0.00001 && ABS (d) < 1e+15) { g_ascii_formatd (s, 50, "%.22f", d); } else { g_ascii_formatd (s, 50, "%.25e", d); } start = s; /* skip - sign */ if (*start == '-') start++; /* count digits (maximum allowed is 15) */ while (digits) { if (*start == '.') { start++; gotdot = TRUE; continue; } if (*start < '0' || *start > '9') break; if (found || *start != '0') { digits--; found = TRUE; } start++; } end = start; /* go to end of string */ while (*end != 'e' && *end != 0) end++; /* round using the next digit */ if (*start >= '5' && *start <= '9') { char *finish = NULL; /* skip all 9s at the end */ while (start[-1] == '9') start--; /* if we're before the dot, replace 9s with 0s */ if (start[-1] == '.') { finish = start; start--; } while (start[-1] == '9') { start[-1] = '0'; start--; } /* write out correct number */ if (start[-1] == '-') { s--; start[-2] = '-'; start[-1] = '1'; } else if (start[-1] == ' ') { s--; start[-1] = '1'; } else { start[-1]++; } /* reposition cursor at end */ if (finish) start = finish; } /* remove trailing zeros (note we skipped zero above, so there will be non-0 bytes left) */ if (gotdot) { while (start[-1] == '0') start--; if (start[-1] == '.') start--; } /* add exponent */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -