📄 swfdec_amf.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 */#ifndef HAVE_CONFIG_H#include "config.h"#endif#include "swfdec_amf.h"#include "swfdec_as_array.h"#include "swfdec_debug.h"typedef gboolean (* SwfdecAmfParseFunc) (SwfdecAsContext *cx, SwfdecBits *bits, SwfdecAsValue *val);extern const SwfdecAmfParseFunc parse_funcs[SWFDEC_AMF_N_TYPES];static gbooleanswfdec_amf_parse_boolean (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val){ SWFDEC_AS_VALUE_SET_BOOLEAN (val, swfdec_bits_get_u8 (bits) ? TRUE : FALSE); return TRUE;}static gbooleanswfdec_amf_parse_number (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val){ SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_bits_get_bdouble (bits)); return TRUE;}static gbooleanswfdec_amf_parse_string (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val){ guint len = swfdec_bits_get_bu16 (bits); char *s; s = swfdec_bits_get_string_length (bits, len); if (s == NULL) return FALSE; SWFDEC_AS_VALUE_SET_STRING (val, swfdec_as_context_get_string (context, s)); return TRUE;}static gbooleanswfdec_amf_parse_properties (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsObject *object){ guint type; SwfdecAmfParseFunc func; while (swfdec_bits_left (bits)) { SwfdecAsValue val; const char *name; if (!swfdec_amf_parse_string (context, bits, &val)) return FALSE; name = SWFDEC_AS_VALUE_GET_STRING (&val); type = swfdec_bits_get_u8 (bits); if (type == SWFDEC_AMF_END_OBJECT) break; if (type >= SWFDEC_AMF_N_TYPES || (func = parse_funcs[type]) == NULL) { SWFDEC_ERROR ("no parse func for AMF type %u", type); goto error; } swfdec_as_object_set_variable (object, name, &val); /* GC... */ if (!func (context, bits, &val)) { goto error; } swfdec_as_object_set_variable (object, name, &val); } /* no more bytes seems to end automatically */ return TRUE;error: return FALSE;}static gbooleanswfdec_amf_parse_object (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val){ SwfdecAsObject *object; object = swfdec_as_object_new (context); if (object == NULL) return FALSE; if (!swfdec_amf_parse_properties (context, bits, object)) return FALSE; SWFDEC_AS_VALUE_SET_OBJECT (val, object); return TRUE;}static gbooleanswfdec_amf_parse_mixed_array (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val){ guint len; SwfdecAsObject *array; len = swfdec_bits_get_bu32 (bits); array = swfdec_as_array_new (context); if (array == NULL) return FALSE; if (!swfdec_amf_parse_properties (context, bits, array)) return FALSE; SWFDEC_AS_VALUE_SET_OBJECT (val, array); return TRUE;}static gbooleanswfdec_amf_parse_array (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val){ guint i, len; SwfdecAsObject *array; guint type; SwfdecAmfParseFunc func; len = swfdec_bits_get_bu32 (bits); array = swfdec_as_array_new (context); if (array == NULL) return FALSE; for (i = 0; i < len; i++) { SwfdecAsValue tmp; type = swfdec_bits_get_u8 (bits); if (type >= SWFDEC_AMF_N_TYPES || (func = parse_funcs[type]) == NULL) { SWFDEC_ERROR ("no parse func for AMF type %u", type); goto fail; } if (!func (context, bits, &tmp)) goto fail; swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &tmp); } SWFDEC_AS_VALUE_SET_OBJECT (val, array); return TRUE;fail: return FALSE;}const SwfdecAmfParseFunc parse_funcs[SWFDEC_AMF_N_TYPES] = { [SWFDEC_AMF_NUMBER] = swfdec_amf_parse_number, [SWFDEC_AMF_BOOLEAN] = swfdec_amf_parse_boolean, [SWFDEC_AMF_STRING] = swfdec_amf_parse_string, [SWFDEC_AMF_OBJECT] = swfdec_amf_parse_object, [SWFDEC_AMF_MIXED_ARRAY] = swfdec_amf_parse_mixed_array, [SWFDEC_AMF_ARRAY] = swfdec_amf_parse_array,#if 0 SWFDEC_AMF_MOVIECLIP = 4, SWFDEC_AMF_NULL = 5, SWFDEC_AMF_UNDEFINED = 6, SWFDEC_AMF_REFERENCE = 7, SWFDEC_AMF_END_OBJECT = 9, SWFDEC_AMF_ARRAY = 10, SWFDEC_AMF_DATE = 11, SWFDEC_AMF_BIG_STRING = 12, SWFDEC_AMF_RECORDSET = 14, SWFDEC_AMF_XML = 15, SWFDEC_AMF_CLASS = 16, SWFDEC_AMF_FLASH9 = 17,#endif};gbooleanswfdec_amf_parse_one (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAmfType expected_type, SwfdecAsValue *rval){ SwfdecAmfParseFunc func; guint type; g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), 0); g_return_val_if_fail (bits != NULL, FALSE); g_return_val_if_fail (rval != NULL, FALSE); g_return_val_if_fail (expected_type < SWFDEC_AMF_N_TYPES, FALSE); type = swfdec_bits_get_u8 (bits); if (type != expected_type) { SWFDEC_ERROR ("parse object should be type %u, but is %u", expected_type, type); return FALSE; } if (type >= SWFDEC_AMF_N_TYPES || (func = parse_funcs[type]) == NULL) { SWFDEC_ERROR ("no parse func for AMF type %u", type); return FALSE; } return func (context, bits, rval);}guintswfdec_amf_parse (SwfdecAsContext *context, SwfdecBits *bits, guint n_items, ...){ va_list args; guint i; g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), 0); g_return_val_if_fail (bits != NULL, 0); va_start (args, n_items); for (i = 0; i < n_items; i++) { SwfdecAmfType type = va_arg (args, SwfdecAmfType); SwfdecAsValue *val = va_arg (args, SwfdecAsValue *); if (!swfdec_amf_parse_one (context, bits, type, val)) break; } va_end (args); return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -