2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
3 * 2007 Pekka Lampila <pekka.lampila@iki.fi>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
28 #include "swfdec_xml.h"
29 #include "swfdec_xml_node.h"
30 #include "swfdec_as_native_function.h"
31 #include "swfdec_as_array.h"
32 #include "swfdec_as_object.h"
33 #include "swfdec_as_strings.h"
34 #include "swfdec_debug.h"
35 #include "swfdec_internal.h"
36 #include "swfdec_as_internal.h"
37 #include "swfdec_player_internal.h"
39 G_DEFINE_TYPE (SwfdecXml
, swfdec_xml
, SWFDEC_TYPE_XML_NODE
)
42 swfdec_xml_mark (SwfdecGcObject
*object
)
44 SwfdecXml
*xml
= SWFDEC_XML (object
);
46 if (xml
->xml_decl
!= NULL
)
47 swfdec_as_string_mark (xml
->xml_decl
);
48 if (xml
->doc_type_decl
!= NULL
)
49 swfdec_as_string_mark (xml
->doc_type_decl
);
51 SWFDEC_GC_OBJECT_CLASS (swfdec_xml_parent_class
)->mark (object
);
55 swfdec_xml_class_init (SwfdecXmlClass
*klass
)
57 SwfdecGcObjectClass
*gc_class
= SWFDEC_GC_OBJECT_CLASS (klass
);
59 gc_class
->mark
= swfdec_xml_mark
;
63 swfdec_xml_init (SwfdecXml
*xml
)
72 static EntityConversion xml_entities
[] = {
83 swfdec_xml_escape_len (const char *orginal
, gssize length
)
86 const char *p
, *start
;
89 string
= g_string_new ("");
91 // Note: we don't escape non-breaking space to
93 while (*(p
+= strcspn (p
, "&<>\"'")) != '\0' && p
- orginal
< length
) {
94 string
= g_string_append_len (string
, start
, p
- start
);
97 for (i
= 0; xml_entities
[i
].escaped
!= NULL
; i
++) {
98 if (xml_entities
[i
].character
== *p
) {
99 string
= g_string_append (string
, xml_entities
[i
].escaped
);
103 g_assert (xml_entities
[i
].escaped
!= NULL
);
108 string
= g_string_append_len (string
, start
, length
- (start
- orginal
));
110 return g_string_free (string
, FALSE
);
114 swfdec_xml_escape (const char *orginal
)
116 return swfdec_xml_escape_len (orginal
, strlen (orginal
));
120 swfdec_xml_unescape_len (SwfdecAsContext
*cx
, const char *orginal
,
121 gssize length
, gboolean unescape_nbsp
)
124 const char *p
, *start
, *end
;
127 string
= g_string_new ("");
130 end
= orginal
+ length
;
131 while ((p
= memchr (p
, '&', end
- p
)) != NULL
) {
132 string
= g_string_append_len (string
, start
, p
- start
);
134 for (i
= 0; xml_entities
[i
].escaped
!= NULL
; i
++) {
135 if (!g_ascii_strncasecmp (p
, xml_entities
[i
].escaped
,
136 strlen (xml_entities
[i
].escaped
))) {
137 // FIXME: Do this cleaner
138 if (xml_entities
[i
].character
== '\xa0') {
140 string
= g_string_append_c (string
, '\xc2');
144 string
= g_string_append_c (string
, xml_entities
[i
].character
);
145 p
+= strlen (xml_entities
[i
].escaped
);
149 if (xml_entities
[i
].escaped
== NULL
) {
150 string
= g_string_append_c (string
, '&');
156 string
= g_string_append_len (string
, start
, length
- (start
- orginal
));
158 return g_string_free (string
, FALSE
);
162 swfdec_xml_unescape (SwfdecAsContext
*cx
, const char *orginal
)
164 return swfdec_xml_unescape_len (cx
, orginal
, strlen (orginal
), TRUE
);
167 // this is never declared, only available as ASnative (100, 5)
168 SWFDEC_AS_NATIVE (100, 5, swfdec_xml_do_escape
)
170 swfdec_xml_do_escape (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
171 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
178 escaped
= swfdec_xml_escape (swfdec_as_value_to_string (cx
, &argv
[0]));
179 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_give_string (cx
, escaped
));
183 swfdec_xml_get_ignoreWhite (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
184 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
186 if (!SWFDEC_IS_XML (object
))
189 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
, SWFDEC_XML (object
)->ignore_white
);
193 swfdec_xml_set_ignoreWhite (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
194 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
196 if (!SWFDEC_IS_XML (object
))
203 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
206 // special case, call toString of objects
207 if (SWFDEC_AS_VALUE_IS_OBJECT (&argv
[0]))
208 swfdec_as_value_to_string (cx
, &argv
[0]);
210 SWFDEC_XML (object
)->ignore_white
=
211 swfdec_as_value_to_boolean (cx
, &argv
[0]);
215 swfdec_xml_get_xmlDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
216 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
218 if (!SWFDEC_IS_XML (object
))
221 if (SWFDEC_XML (object
)->xml_decl
!= NULL
) {
222 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_XML (object
)->xml_decl
);
224 SWFDEC_AS_VALUE_SET_UNDEFINED (ret
);
229 swfdec_xml_set_xmlDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
230 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
232 if (!SWFDEC_IS_XML (object
))
239 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
242 SWFDEC_XML (object
)->xml_decl
= swfdec_as_value_to_string (cx
, &argv
[0]);
246 swfdec_xml_get_docTypeDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
247 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
249 if (!SWFDEC_IS_XML (object
))
252 if (SWFDEC_XML (object
)->doc_type_decl
!= NULL
) {
253 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_XML (object
)->doc_type_decl
);
255 SWFDEC_AS_VALUE_SET_UNDEFINED (ret
);
260 swfdec_xml_set_docTypeDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
261 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
263 if (!SWFDEC_IS_XML (object
))
270 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
273 SWFDEC_XML (object
)->doc_type_decl
=
274 swfdec_as_value_to_string (cx
, &argv
[0]);
278 swfdec_xml_get_contentType (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
279 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
281 if (!SWFDEC_IS_XML (object
))
284 *ret
= SWFDEC_XML (object
)->content_type
;
288 swfdec_xml_set_contentType (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
289 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
291 if (!SWFDEC_IS_XML (object
))
298 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
301 SWFDEC_XML (object
)->content_type
= argv
[0];
305 swfdec_xml_get_loaded (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
306 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
308 if (!SWFDEC_IS_XML (object
))
311 *ret
= SWFDEC_XML (object
)->loaded
;
315 swfdec_xml_set_loaded (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
316 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
318 if (!SWFDEC_IS_XML (object
))
324 // special case, call toString of objects
325 if (SWFDEC_AS_VALUE_IS_OBJECT (&argv
[0]))
326 swfdec_as_value_to_string (cx
, &argv
[0]);
329 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
332 SWFDEC_AS_VALUE_SET_BOOLEAN (&SWFDEC_XML (object
)->loaded
,
333 swfdec_as_value_to_boolean (cx
, &argv
[0]));
337 swfdec_xml_get_status (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
338 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
340 if (!SWFDEC_IS_XML (object
))
343 SWFDEC_AS_VALUE_SET_INT (ret
, SWFDEC_XML (object
)->status
);
347 swfdec_xml_set_status (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
348 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
352 if (!SWFDEC_IS_XML (object
))
359 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
362 swfdec_as_value_to_string (cx
, &argv
[0]);
363 d
= swfdec_as_value_to_number (cx
, &argv
[0]);
365 SWFDEC_XML (object
)->status
= 0;
367 SWFDEC_XML (object
)->status
= d
;
371 swfdec_xml_parse_xmlDecl (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *p
)
376 g_assert (p
!= NULL
);
377 g_return_val_if_fail (g_ascii_strncasecmp (p
, "<?xml", strlen ("<?xml")) == 0,
379 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
381 end
= strstr (p
, "?>");
383 xml
->status
= XML_PARSE_STATUS_XMLDECL_NOT_TERMINATED
;
384 return strchr (p
, '\0');
387 end
+= strlen ("?>");
389 string
= g_string_new ((xml
->xml_decl
!= NULL
? xml
->xml_decl
: ""));
390 string
= g_string_append_len (string
, p
, end
- p
);
391 xml
->xml_decl
= swfdec_as_context_give_string (
392 swfdec_gc_object_get_context (xml
), g_string_free (string
, FALSE
));
394 // in version 5 parsing xmlDecl or docType always adds undefined element to
395 // the childNodes array
396 if (swfdec_gc_object_get_context (xml
)->version
< 6)
397 SWFDEC_FIXME ("Need to add undefined element to childNodes array");
399 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
405 swfdec_xml_parse_docTypeDecl (SwfdecXml
*xml
, SwfdecXmlNode
*node
,
411 g_assert (p
!= NULL
);
412 g_return_val_if_fail (
413 g_ascii_strncasecmp (p
, "<!DOCTYPE", strlen ("<!DOCTYPE")) == 0,
415 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
420 end
+= strcspn (end
, "<>");
424 } else if (*end
== '>') {
428 } while (*end
!= '\0' && open
> 0);
431 xml
->status
= XML_PARSE_STATUS_DOCTYPEDECL_NOT_TERMINATED
;
433 xml
->doc_type_decl
= swfdec_as_context_give_string (
434 swfdec_gc_object_get_context (xml
), g_strndup (p
, end
- p
));
436 // in version 5 parsing xmlDecl or docType always adds undefined element to
437 // the childNodes array
438 if (swfdec_gc_object_get_context (xml
)->version
< 6)
439 SWFDEC_FIXME ("Need to add undefined element to childNodes array");
442 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
448 swfdec_xml_parse_comment (SwfdecXml
*xml
, const char *p
)
452 g_assert (p
!= NULL
);
453 g_return_val_if_fail (strncmp (p
, "<!--", strlen ("<!--")) == 0,
455 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
457 end
= strstr (p
, "-->");
460 xml
->status
= XML_PARSE_STATUS_COMMENT_NOT_TERMINATED
;
461 return strchr (p
, '\0');
464 end
+= strlen("-->");
466 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
472 swfdec_xml_add_id_map (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *id
)
474 SwfdecAsObject
*object
;
477 g_return_if_fail (SWFDEC_IS_XML (xml
));
478 g_return_if_fail (SWFDEC_IS_XML_NODE (xml
));
479 g_return_if_fail (id
!= NULL
&& id
!= SWFDEC_AS_STR_EMPTY
);
481 if (swfdec_gc_object_get_context (xml
)->version
>= 8) {
482 if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (xml
),
483 SWFDEC_AS_STR_idMap
, &val
)) {
484 if (SWFDEC_AS_VALUE_IS_OBJECT (&val
)) {
485 object
= SWFDEC_AS_VALUE_GET_OBJECT (&val
);
490 object
= swfdec_as_object_new_empty (swfdec_gc_object_get_context (xml
));
491 SWFDEC_AS_VALUE_SET_OBJECT (&val
, object
);
492 swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (xml
),
493 SWFDEC_AS_STR_idMap
, &val
);
496 object
= SWFDEC_AS_OBJECT (xml
);
499 SWFDEC_AS_VALUE_SET_OBJECT (&val
, SWFDEC_AS_OBJECT (node
));
500 swfdec_as_object_set_variable (object
, id
, &val
);
504 swfdec_xml_parse_attribute (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *p
)
507 const char *end
, *name
;
510 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
511 g_return_val_if_fail (SWFDEC_IS_XML_NODE (node
), strchr (p
, '\0'));
512 g_return_val_if_fail ((*p
!= '>' && *p
!= '\0'), p
);
514 end
= p
+ strcspn (p
, "=> \r\n\t");
516 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
517 return strchr (p
, '\0');
520 text
= g_strndup (p
, end
- p
);
521 name
= swfdec_as_context_give_string (swfdec_gc_object_get_context (node
),
522 swfdec_xml_unescape (swfdec_gc_object_get_context (xml
), text
));
525 p
= end
+ strspn (end
, " \r\n\t");
527 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
528 return strchr (p
, '\0');
530 p
= p
+ 1 + strspn (p
+ 1, " \r\n\t");
532 if (*p
!= '"' && *p
!= '\'') {
533 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
534 return strchr (p
, '\0');
539 end
= strchr (end
, *p
);
540 } while (end
!= NULL
&& *(end
- 1) == '\\');
543 xml
->status
= XML_PARSE_STATUS_ATTRIBUTE_NOT_TERMINATED
;
544 return strchr (p
, '\0');
547 if (!swfdec_as_object_get_variable (node
->attributes
, name
, NULL
)) {
551 unescaped
= swfdec_xml_unescape_len (swfdec_gc_object_get_context (xml
),
552 p
+ 1, end
- (p
+ 1), TRUE
);
553 value
= swfdec_as_context_give_string (swfdec_gc_object_get_context (node
),
555 SWFDEC_AS_VALUE_SET_STRING (&val
, value
);
557 swfdec_as_object_set_variable (node
->attributes
, name
, &val
);
560 g_return_val_if_fail (end
+ 1 > p
, strchr (p
, '\0'));
566 swfdec_xml_parse_tag (SwfdecXml
*xml
, SwfdecXmlNode
**node
, const char *p
)
568 SwfdecAsObject
*object
;
569 SwfdecXmlNode
*child
= NULL
; // surpress warning
574 g_assert (p
!= NULL
);
575 g_return_val_if_fail (*p
== '<', strchr (p
, '\0'));
576 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
578 object
= SWFDEC_AS_OBJECT (xml
);
580 // closing tag or opening tag?
581 if (*(p
+ 1) == '/') {
588 // find the end of the name
589 end
= p
+ strcspn (p
, "> \r\n\t");
591 // don't count trailing / as part of the name if it's followed by >
592 // note we do this for close tags also, so <test/ ></test/> doesn't work
593 if (*end
== '>' && *(end
- 1) == '/')
596 if (end
- (p
+ 1) <= 0 || *end
== '\0') {
597 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
598 return strchr (p
, '\0');
601 name
= g_strndup (p
+ 1 , end
- (p
+ 1));
603 // create the new element
605 child
= swfdec_xml_node_new_no_properties (
606 swfdec_gc_object_get_context (*node
), SWFDEC_XML_NODE_ELEMENT
,
607 swfdec_as_context_give_string (swfdec_gc_object_get_context (*node
),
610 return strchr (p
, '\0');
614 end
= strchr (end
, '>');
616 end
= strchr (p
, '\0');
618 end
= end
+ strspn (end
, " \r\n\t");
619 while (*end
!= '\0' && *end
!= '>' && (*end
!= '/' || *(end
+ 1) != '>')) {
620 end
= swfdec_xml_parse_attribute (xml
, child
, end
);
621 end
= end
+ strspn (end
, " \r\n\t");
628 if (xml
->status
== XML_PARSE_STATUS_OK
)
629 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
636 if ((*node
)->parent
!= NULL
&& !g_ascii_strcasecmp ((*node
)->name
, name
))
638 *node
= (*node
)->parent
;
642 SwfdecXmlNode
*iter
= *node
;
643 while (iter
!= NULL
&& (iter
->name
== NULL
|| g_ascii_strcasecmp (iter
->name
, name
))) {
647 xml
->status
= XML_PARSE_STATUS_TAG_NOT_CLOSED
;
649 xml
->status
= XML_PARSE_STATUS_TAG_MISMATCH
;
656 swfdec_xml_node_appendChild (*node
, child
);
658 id
= swfdec_xml_node_get_attribute (child
, SWFDEC_AS_STR_id
);
660 swfdec_xml_add_id_map (xml
, child
, id
);
662 if (*(end
- 1) != '/')
668 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
674 swfdec_xml_parse_cdata (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *p
)
676 SwfdecXmlNode
*child
;
680 g_assert (p
!= NULL
);
681 g_return_val_if_fail (strncmp (p
, "<![CDATA[", strlen ("<![CDATA[")) == 0,
683 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
685 p
+= strlen ("<![CDATA[");
687 end
= strstr (p
, "]]>");
690 xml
->status
= XML_PARSE_STATUS_CDATA_NOT_TERMINATED
;
691 return strchr (p
, '\0');
694 text
= g_strndup (p
, end
- p
);
696 child
= swfdec_xml_node_new_no_properties (
697 swfdec_gc_object_get_context (node
), SWFDEC_XML_NODE_TEXT
,
698 swfdec_as_context_give_string (swfdec_gc_object_get_context (xml
), text
));
700 return strchr (p
, '\0');
701 swfdec_xml_node_appendChild (node
, child
);
703 end
+= strlen("]]>");
705 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
711 swfdec_xml_parse_text (SwfdecXml
*xml
, SwfdecXmlNode
*node
,
712 const char *p
, gboolean ignore_white
)
714 SwfdecXmlNode
*child
;
716 char *text
, *unescaped
;
718 g_assert (p
!= NULL
);
719 g_return_val_if_fail (*p
!= '\0', p
);
720 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
722 end
= strchr (p
, '<');
724 end
= strchr (p
, '\0');
726 if (!ignore_white
|| strspn (p
, " \t\r\n") < (gsize
)(end
- p
))
728 text
= g_strndup (p
, end
- p
);
729 unescaped
= swfdec_xml_unescape (swfdec_gc_object_get_context (xml
), text
);
731 child
= swfdec_xml_node_new_no_properties (
732 swfdec_gc_object_get_context (node
), SWFDEC_XML_NODE_TEXT
,
733 swfdec_as_context_give_string (swfdec_gc_object_get_context (xml
),
736 return strchr (p
, '\0');
737 swfdec_xml_node_appendChild (node
, child
);
740 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
746 swfdec_xml_parseXML (SwfdecXml
*xml
, const char *value
)
748 SwfdecAsObject
*object
;
751 gboolean ignore_white
;
753 g_return_if_fail (SWFDEC_IS_XML (xml
));
754 g_return_if_fail (value
!= NULL
);
756 object
= SWFDEC_AS_OBJECT (xml
);
758 swfdec_xml_node_removeChildren (SWFDEC_XML_NODE (xml
));
759 xml
->xml_decl
= NULL
;
760 xml
->doc_type_decl
= NULL
;
761 xml
->status
= XML_PARSE_STATUS_OK
;
764 node
= SWFDEC_XML_NODE (xml
);
766 // special case: we only use the ignoreWhite set at the start
767 ignore_white
= xml
->ignore_white
;
769 while (xml
->status
== XML_PARSE_STATUS_OK
&& *p
!= '\0') {
771 if (g_ascii_strncasecmp (p
+ 1, "?xml", strlen ("?xml")) == 0) {
772 p
= swfdec_xml_parse_xmlDecl (xml
, node
, p
);
773 } else if (g_ascii_strncasecmp (p
+ 1, "!DOCTYPE", strlen ("!DOCTYPE")) == 0) {
774 p
= swfdec_xml_parse_docTypeDecl (xml
, node
, p
);
775 } else if (strncmp (p
+ 1, "!--", strlen ("!--")) == 0) {
776 p
= swfdec_xml_parse_comment (xml
, p
);
777 } else if (g_ascii_strncasecmp (p
+ 1, "![CDATA", strlen ("![CDATA")) == 0) {
778 p
= swfdec_xml_parse_cdata (xml
, node
, p
);
780 p
= swfdec_xml_parse_tag (xml
, &node
, p
);
783 p
= swfdec_xml_parse_text (xml
, node
, p
, ignore_white
);
785 g_assert (p
!= NULL
);
788 if (xml
->status
== XML_PARSE_STATUS_OK
&& node
!= SWFDEC_XML_NODE (xml
))
789 xml
->status
= XML_PARSE_STATUS_TAG_NOT_CLOSED
;
792 // this is an old XML parsing function that is only available trough the
794 SWFDEC_AS_NATIVE (300, 0, swfdec_xml_do_oldParseXML
)
796 swfdec_xml_do_oldParseXML (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
797 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
799 SWFDEC_STUB ("XML.oldParseXML (not-really-named)");
802 SWFDEC_AS_NATIVE (253, 12, swfdec_xml_do_parseXML
)
804 swfdec_xml_do_parseXML (SwfdecAsContext
*cx
, SwfdecAsObject
*object
, guint argc
,
805 SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
807 if (!SWFDEC_IS_XML (object
))
810 if (!SWFDEC_IS_VALID_XML_NODE (object
))
816 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
819 swfdec_xml_parseXML (SWFDEC_XML (object
),
820 swfdec_as_value_to_string (cx
, &argv
[0]));
823 SWFDEC_AS_NATIVE (253, 10, swfdec_xml_createElement
)
825 swfdec_xml_createElement (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
826 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
830 if (!SWFDEC_IS_XML (object
))
837 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
840 node
= swfdec_xml_node_new (cx
, SWFDEC_XML_NODE_ELEMENT
,
841 swfdec_as_value_to_string (cx
, &argv
[0]));
845 SWFDEC_AS_VALUE_SET_OBJECT (rval
, SWFDEC_AS_OBJECT (node
));
848 SWFDEC_AS_NATIVE (253, 11, swfdec_xml_createTextNode
)
850 swfdec_xml_createTextNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
851 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
855 if (!SWFDEC_IS_XML (object
))
862 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
865 node
= swfdec_xml_node_new (cx
, SWFDEC_XML_NODE_TEXT
,
866 swfdec_as_value_to_string (cx
, &argv
[0]));
870 SWFDEC_AS_VALUE_SET_OBJECT (rval
, SWFDEC_AS_OBJECT (node
));
874 swfdec_xml_init_properties (SwfdecAsContext
*cx
)
877 SwfdecAsObject
*xml
, *proto
;
879 // FIXME: We should only initialize if the prototype Object has not been
880 // initialized by any object's constructor with native properties
881 // (TextField, TextFormat, XML, XMLNode at least)
883 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (cx
));
885 swfdec_as_object_get_variable (cx
->global
, SWFDEC_AS_STR_XML
, &val
);
886 if (!SWFDEC_AS_VALUE_IS_OBJECT (&val
))
888 xml
= SWFDEC_AS_VALUE_GET_OBJECT (&val
);
890 swfdec_as_object_get_variable (xml
, SWFDEC_AS_STR_prototype
, &val
);
891 if (!SWFDEC_AS_VALUE_IS_OBJECT (&val
))
893 proto
= SWFDEC_AS_VALUE_GET_OBJECT (&val
);
895 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_ignoreWhite
,
896 swfdec_xml_get_ignoreWhite
, swfdec_xml_set_ignoreWhite
);
897 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_status
,
898 swfdec_xml_get_status
, swfdec_xml_set_status
);
899 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_xmlDecl
,
900 swfdec_xml_get_xmlDecl
, swfdec_xml_set_xmlDecl
);
901 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_docTypeDecl
,
902 swfdec_xml_get_docTypeDecl
, swfdec_xml_set_docTypeDecl
);
904 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_contentType
,
905 swfdec_xml_get_contentType
, swfdec_xml_set_contentType
);
906 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_loaded
,
907 swfdec_xml_get_loaded
, swfdec_xml_set_loaded
);
910 SWFDEC_AS_CONSTRUCTOR (253, 9, swfdec_xml_construct
, swfdec_xml_get_type
)
912 swfdec_xml_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
913 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
915 if (!swfdec_as_context_is_constructing (cx
))
918 g_assert (SWFDEC_IS_XML (object
));
920 swfdec_xml_init_properties (cx
);
922 swfdec_xml_node_init_values (SWFDEC_XML_NODE (object
),
923 SWFDEC_XML_NODE_ELEMENT
, SWFDEC_AS_STR_EMPTY
);
925 SWFDEC_AS_VALUE_SET_STRING (&SWFDEC_XML (object
)->content_type
,
926 SWFDEC_AS_STR_application_x_www_form_urlencoded
);
928 SWFDEC_XML_NODE (object
)->name
= NULL
;
930 if (!SWFDEC_IS_VALID_XML_NODE (object
))
933 if (argc
>= 1 && !SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0])) {
934 swfdec_xml_parseXML (SWFDEC_XML (object
),
935 swfdec_as_value_to_string (cx
, &argv
[0]));
940 swfdec_xml_new_no_properties (SwfdecAsContext
*context
, const char *str
,
941 gboolean ignore_white
)
945 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
947 xml
= g_object_new (SWFDEC_TYPE_XML
, "context", context
, NULL
);
949 swfdec_as_object_set_constructor_by_name (SWFDEC_AS_OBJECT (xml
), SWFDEC_AS_STR_XML
, NULL
);
950 xml
->ignore_white
= ignore_white
;
952 swfdec_xml_node_init_values (SWFDEC_XML_NODE (xml
),
953 SWFDEC_XML_NODE_ELEMENT
, SWFDEC_AS_STR_EMPTY
);
955 SWFDEC_AS_VALUE_SET_STRING (&xml
->content_type
,
956 SWFDEC_AS_STR_application_x_www_form_urlencoded
);
959 swfdec_xml_parseXML (xml
, str
);
965 swfdec_xml_new (SwfdecAsContext
*context
, const char *str
,
966 gboolean ignore_white
)
968 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
970 swfdec_xml_init_properties (context
);
972 return swfdec_xml_new_no_properties (context
, str
, ignore_white
);