2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
24 #include "swfdec_amf.h"
25 #include "swfdec_as_array.h"
26 #include "swfdec_debug.h"
28 typedef gboolean (* SwfdecAmfParseFunc
) (SwfdecAsContext
*cx
, SwfdecBits
*bits
, SwfdecAsValue
*val
);
29 extern const SwfdecAmfParseFunc parse_funcs
[SWFDEC_AMF_N_TYPES
];
32 swfdec_amf_parse_boolean (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsValue
*val
)
34 SWFDEC_AS_VALUE_SET_BOOLEAN (val
, swfdec_bits_get_u8 (bits
) ? TRUE
: FALSE
);
39 swfdec_amf_parse_number (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsValue
*val
)
41 SWFDEC_AS_VALUE_SET_NUMBER (val
, swfdec_bits_get_bdouble (bits
));
46 swfdec_amf_parse_string (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsValue
*val
)
48 guint len
= swfdec_bits_get_bu16 (bits
);
51 /* FIXME: the supplied version is likely incorrect */
52 s
= swfdec_bits_get_string_length (bits
, len
, context
->version
);
55 SWFDEC_AS_VALUE_SET_STRING (val
, swfdec_as_context_give_string (context
, s
));
60 swfdec_amf_parse_properties (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsObject
*object
)
63 SwfdecAmfParseFunc func
;
65 while (swfdec_bits_left (bits
)) {
69 if (!swfdec_amf_parse_string (context
, bits
, &val
))
71 name
= SWFDEC_AS_VALUE_GET_STRING (&val
);
72 type
= swfdec_bits_get_u8 (bits
);
73 if (type
== SWFDEC_AMF_END_OBJECT
)
75 if (type
>= SWFDEC_AMF_N_TYPES
||
76 (func
= parse_funcs
[type
]) == NULL
) {
77 SWFDEC_ERROR ("no parse func for AMF type %u", type
);
80 swfdec_as_object_set_variable (object
, name
, &val
); /* GC... */
81 if (!func (context
, bits
, &val
)) {
84 swfdec_as_object_set_variable (object
, name
, &val
);
86 /* no more bytes seems to end automatically */
94 swfdec_amf_parse_object (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsValue
*val
)
96 SwfdecAsObject
*object
;
98 object
= swfdec_as_object_new (context
);
101 if (!swfdec_amf_parse_properties (context
, bits
, object
))
103 SWFDEC_AS_VALUE_SET_OBJECT (val
, object
);
108 swfdec_amf_parse_mixed_array (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsValue
*val
)
111 SwfdecAsObject
*array
;
113 len
= swfdec_bits_get_bu32 (bits
);
114 array
= swfdec_as_array_new (context
);
117 if (!swfdec_amf_parse_properties (context
, bits
, array
))
119 SWFDEC_AS_VALUE_SET_OBJECT (val
, array
);
124 swfdec_amf_parse_array (SwfdecAsContext
*context
, SwfdecBits
*bits
, SwfdecAsValue
*val
)
127 SwfdecAsObject
*array
;
129 SwfdecAmfParseFunc func
;
131 len
= swfdec_bits_get_bu32 (bits
);
132 array
= swfdec_as_array_new (context
);
135 for (i
= 0; i
< len
; i
++) {
137 type
= swfdec_bits_get_u8 (bits
);
138 if (type
>= SWFDEC_AMF_N_TYPES
||
139 (func
= parse_funcs
[type
]) == NULL
) {
140 SWFDEC_ERROR ("no parse func for AMF type %u", type
);
143 if (!func (context
, bits
, &tmp
))
145 swfdec_as_array_push (SWFDEC_AS_ARRAY (array
), &tmp
);
148 SWFDEC_AS_VALUE_SET_OBJECT (val
, array
);
155 const SwfdecAmfParseFunc parse_funcs
[SWFDEC_AMF_N_TYPES
] = {
156 [SWFDEC_AMF_NUMBER
] = swfdec_amf_parse_number
,
157 [SWFDEC_AMF_BOOLEAN
] = swfdec_amf_parse_boolean
,
158 [SWFDEC_AMF_STRING
] = swfdec_amf_parse_string
,
159 [SWFDEC_AMF_OBJECT
] = swfdec_amf_parse_object
,
160 [SWFDEC_AMF_MIXED_ARRAY
] = swfdec_amf_parse_mixed_array
,
161 [SWFDEC_AMF_ARRAY
] = swfdec_amf_parse_array
,
163 SWFDEC_AMF_MOVIECLIP
= 4,
165 SWFDEC_AMF_UNDEFINED
= 6,
166 SWFDEC_AMF_REFERENCE
= 7,
167 SWFDEC_AMF_END_OBJECT
= 9,
168 SWFDEC_AMF_ARRAY
= 10,
169 SWFDEC_AMF_DATE
= 11,
170 SWFDEC_AMF_BIG_STRING
= 12,
171 SWFDEC_AMF_RECORDSET
= 14,
173 SWFDEC_AMF_CLASS
= 16,
174 SWFDEC_AMF_FLASH9
= 17,
179 swfdec_amf_parse_one (SwfdecAsContext
*context
, SwfdecBits
*bits
,
180 SwfdecAmfType expected_type
, SwfdecAsValue
*rval
)
182 SwfdecAmfParseFunc func
;
185 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), 0);
186 g_return_val_if_fail (bits
!= NULL
, FALSE
);
187 g_return_val_if_fail (rval
!= NULL
, FALSE
);
188 g_return_val_if_fail (expected_type
< SWFDEC_AMF_N_TYPES
, FALSE
);
190 type
= swfdec_bits_get_u8 (bits
);
191 if (type
!= expected_type
) {
192 SWFDEC_ERROR ("parse object should be type %u, but is %u",
193 expected_type
, type
);
196 if (type
>= SWFDEC_AMF_N_TYPES
||
197 (func
= parse_funcs
[type
]) == NULL
) {
198 SWFDEC_ERROR ("no parse func for AMF type %u", type
);
201 return func (context
, bits
, rval
);
205 swfdec_amf_parse (SwfdecAsContext
*context
, SwfdecBits
*bits
, guint n_items
, ...)
210 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), 0);
211 g_return_val_if_fail (bits
!= NULL
, 0);
213 va_start (args
, n_items
);
214 for (i
= 0; i
< n_items
; i
++) {
215 SwfdecAmfType type
= va_arg (args
, SwfdecAmfType
);
216 SwfdecAsValue
*val
= va_arg (args
, SwfdecAsValue
*);
217 if (!swfdec_amf_parse_one (context
, bits
, type
, val
))