2 * Copyright (C) 2007-2008 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_as_value_mark (&xml
->content_type
);
52 swfdec_as_value_mark (&xml
->loaded
);
54 SWFDEC_GC_OBJECT_CLASS (swfdec_xml_parent_class
)->mark (object
);
58 swfdec_xml_class_init (SwfdecXmlClass
*klass
)
60 SwfdecGcObjectClass
*gc_class
= SWFDEC_GC_OBJECT_CLASS (klass
);
62 gc_class
->mark
= swfdec_xml_mark
;
66 swfdec_xml_init (SwfdecXml
*xml
)
68 SWFDEC_AS_VALUE_SET_STRING (&xml
->content_type
,
69 SWFDEC_AS_STR_application_x_www_form_urlencoded
);
77 static EntityConversion xml_entities
[] = {
88 swfdec_xml_escape_len (const char *orginal
, gssize length
)
91 const char *p
, *start
;
94 string
= g_string_new ("");
96 // Note: we don't escape non-breaking space to
98 while (*(p
+= strcspn (p
, "&<>\"'")) != '\0' && p
- orginal
< length
) {
99 string
= g_string_append_len (string
, start
, p
- start
);
102 for (i
= 0; xml_entities
[i
].escaped
!= NULL
; i
++) {
103 if (xml_entities
[i
].character
== *p
) {
104 string
= g_string_append (string
, xml_entities
[i
].escaped
);
108 g_assert (xml_entities
[i
].escaped
!= NULL
);
113 string
= g_string_append_len (string
, start
, length
- (start
- orginal
));
115 return g_string_free (string
, FALSE
);
119 swfdec_xml_escape (const char *orginal
)
121 return swfdec_xml_escape_len (orginal
, strlen (orginal
));
125 swfdec_xml_unescape_len (SwfdecAsContext
*cx
, const char *orginal
,
126 gssize length
, gboolean unescape_nbsp
)
129 const char *p
, *start
, *end
;
132 string
= g_string_new ("");
135 end
= orginal
+ length
;
136 while ((p
= memchr (p
, '&', end
- p
)) != NULL
) {
137 string
= g_string_append_len (string
, start
, p
- start
);
139 for (i
= 0; xml_entities
[i
].escaped
!= NULL
; i
++) {
140 if (!g_ascii_strncasecmp (p
, xml_entities
[i
].escaped
,
141 strlen (xml_entities
[i
].escaped
))) {
142 // FIXME: Do this cleaner
143 if (xml_entities
[i
].character
== '\xa0') {
145 string
= g_string_append_c (string
, '\xc2');
149 string
= g_string_append_c (string
, xml_entities
[i
].character
);
150 p
+= strlen (xml_entities
[i
].escaped
);
154 if (xml_entities
[i
].escaped
== NULL
) {
155 string
= g_string_append_c (string
, '&');
161 string
= g_string_append_len (string
, start
, length
- (start
- orginal
));
163 return g_string_free (string
, FALSE
);
167 swfdec_xml_unescape (SwfdecAsContext
*cx
, const char *orginal
)
169 return swfdec_xml_unescape_len (cx
, orginal
, strlen (orginal
), TRUE
);
172 // this is never declared, only available as ASnative (100, 5)
173 SWFDEC_AS_NATIVE (100, 5, swfdec_xml_do_escape
)
175 swfdec_xml_do_escape (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
176 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
181 SWFDEC_AS_CHECK (0, NULL
, "s", &s
);
183 escaped
= swfdec_xml_escape (s
);
184 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_as_context_give_string (cx
, escaped
));
188 swfdec_xml_get_ignoreWhite (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
189 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
193 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "");
195 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
, xml
->ignore_white
);
199 swfdec_xml_set_ignoreWhite (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
200 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
205 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &ignore
);
208 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
212 swfdec_as_value_to_boolean (cx
, argv
[0]);
216 swfdec_xml_get_xmlDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
217 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
221 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "");
223 if (xml
->xml_decl
!= NULL
) {
224 SWFDEC_AS_VALUE_SET_STRING (ret
, xml
->xml_decl
);
226 SWFDEC_AS_VALUE_SET_UNDEFINED (ret
);
231 swfdec_xml_set_xmlDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
232 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
237 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &s
);
240 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
247 swfdec_xml_get_docTypeDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
248 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
252 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "");
254 if (xml
->doc_type_decl
!= NULL
) {
255 SWFDEC_AS_VALUE_SET_STRING (ret
, xml
->doc_type_decl
);
257 SWFDEC_AS_VALUE_SET_UNDEFINED (ret
);
262 swfdec_xml_set_docTypeDecl (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
263 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
268 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &s
);
271 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
274 xml
->doc_type_decl
= s
;
278 swfdec_xml_get_contentType (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
279 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
283 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "");
285 *ret
= xml
->content_type
;
289 swfdec_xml_set_contentType (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
290 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
295 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "v", &val
);
298 if (SWFDEC_AS_VALUE_IS_UNDEFINED (val
))
301 xml
->content_type
= val
;
305 swfdec_xml_get_loaded (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
306 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
310 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "");
316 swfdec_xml_set_loaded (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
317 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
322 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &ignore
);
325 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
328 SWFDEC_AS_VALUE_SET_BOOLEAN (&xml
->loaded
,
329 swfdec_as_value_to_boolean (cx
, argv
[0]));
333 swfdec_xml_get_status (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
334 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
338 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "");
340 swfdec_as_value_set_integer (cx
, ret
, xml
->status
);
344 swfdec_xml_set_status (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
345 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
351 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &ignore
);
354 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
357 d
= swfdec_as_value_to_number (cx
, *&argv
[0]);
365 swfdec_xml_parse_xmlDecl (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *p
)
370 g_assert (p
!= NULL
);
371 g_return_val_if_fail (g_ascii_strncasecmp (p
, "<?xml", strlen ("<?xml")) == 0,
373 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
375 end
= strstr (p
, "?>");
377 xml
->status
= XML_PARSE_STATUS_XMLDECL_NOT_TERMINATED
;
378 return strchr (p
, '\0');
381 end
+= strlen ("?>");
383 string
= g_string_new ((xml
->xml_decl
!= NULL
? xml
->xml_decl
: ""));
384 string
= g_string_append_len (string
, p
, end
- p
);
385 xml
->xml_decl
= swfdec_as_context_give_string (
386 swfdec_gc_object_get_context (xml
), g_string_free (string
, FALSE
));
388 // in version 5 parsing xmlDecl or docType always adds undefined element to
389 // the childNodes array
390 if (swfdec_gc_object_get_context (xml
)->version
< 6)
391 SWFDEC_FIXME ("Need to add undefined element to childNodes array");
393 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
399 swfdec_xml_parse_docTypeDecl (SwfdecXml
*xml
, SwfdecXmlNode
*node
,
405 g_assert (p
!= NULL
);
406 g_return_val_if_fail (
407 g_ascii_strncasecmp (p
, "<!DOCTYPE", strlen ("<!DOCTYPE")) == 0,
409 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
414 end
+= strcspn (end
, "<>");
418 } else if (*end
== '>') {
422 } while (*end
!= '\0' && open
> 0);
425 xml
->status
= XML_PARSE_STATUS_DOCTYPEDECL_NOT_TERMINATED
;
427 xml
->doc_type_decl
= swfdec_as_context_give_string (
428 swfdec_gc_object_get_context (xml
), g_strndup (p
, end
- p
));
430 // in version 5 parsing xmlDecl or docType always adds undefined element to
431 // the childNodes array
432 if (swfdec_gc_object_get_context (xml
)->version
< 6)
433 SWFDEC_FIXME ("Need to add undefined element to childNodes array");
436 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
442 swfdec_xml_parse_comment (SwfdecXml
*xml
, const char *p
)
446 g_assert (p
!= NULL
);
447 g_return_val_if_fail (strncmp (p
, "<!--", strlen ("<!--")) == 0,
449 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
451 end
= strstr (p
, "-->");
454 xml
->status
= XML_PARSE_STATUS_COMMENT_NOT_TERMINATED
;
455 return strchr (p
, '\0');
458 end
+= strlen("-->");
460 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
466 swfdec_xml_add_id_map (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *id
)
468 SwfdecAsObject
*object
;
469 SwfdecAsContext
*context
;
472 g_return_if_fail (SWFDEC_IS_XML (xml
));
473 g_return_if_fail (SWFDEC_IS_XML_NODE (xml
));
474 g_return_if_fail (id
!= NULL
&& id
!= SWFDEC_AS_STR_EMPTY
);
476 context
= swfdec_gc_object_get_context (xml
);
477 object
= swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml
));
478 if (context
->version
>= 8) {
479 if (swfdec_as_object_get_variable (object
,
480 SWFDEC_AS_STR_idMap
, &val
)) {
481 if (SWFDEC_AS_VALUE_IS_OBJECT (val
)) {
482 object
= SWFDEC_AS_VALUE_GET_OBJECT (val
);
487 object
= swfdec_as_object_new_empty (context
);
488 SWFDEC_AS_VALUE_SET_OBJECT (&val
, object
);
489 swfdec_as_object_set_variable (swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml
)),
490 SWFDEC_AS_STR_idMap
, &val
);
494 SWFDEC_AS_VALUE_SET_OBJECT (&val
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node
)));
495 swfdec_as_object_set_variable (object
, id
, &val
);
499 swfdec_xml_parse_attribute (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *p
)
503 const char *end
, *name
;
506 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
507 g_return_val_if_fail (SWFDEC_IS_XML_NODE (node
), strchr (p
, '\0'));
508 g_return_val_if_fail ((*p
!= '>' && *p
!= '\0'), p
);
510 end
= p
+ strcspn (p
, "=> \r\n\t");
512 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
513 return strchr (p
, '\0');
516 cx
= swfdec_gc_object_get_context (node
);
517 text
= g_strndup (p
, end
- p
);
518 name
= swfdec_as_context_give_string (cx
, swfdec_xml_unescape (cx
, text
));
521 p
= end
+ strspn (end
, " \r\n\t");
523 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
524 return strchr (p
, '\0');
526 p
= p
+ 1 + strspn (p
+ 1, " \r\n\t");
528 if (*p
!= '"' && *p
!= '\'') {
529 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
530 return strchr (p
, '\0');
535 end
= strchr (end
, *p
);
536 } while (end
!= NULL
&& *(end
- 1) == '\\');
539 xml
->status
= XML_PARSE_STATUS_ATTRIBUTE_NOT_TERMINATED
;
540 return strchr (p
, '\0');
543 if (!swfdec_as_object_get_variable (node
->attributes
, name
, NULL
)) {
547 unescaped
= swfdec_xml_unescape_len (cx
, p
+ 1, end
- (p
+ 1), TRUE
);
548 value
= swfdec_as_context_give_string (cx
, unescaped
);
549 SWFDEC_AS_VALUE_SET_STRING (&val
, value
);
551 swfdec_as_object_set_variable (node
->attributes
, name
, &val
);
554 g_return_val_if_fail (end
+ 1 > p
, strchr (p
, '\0'));
560 swfdec_xml_parse_tag (SwfdecXml
*xml
, SwfdecXmlNode
**node
, const char *p
)
562 SwfdecAsObject
*object
;
564 SwfdecXmlNode
*child
= NULL
; // supress warning
569 g_assert (p
!= NULL
);
570 g_return_val_if_fail (*p
== '<', strchr (p
, '\0'));
571 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
573 object
= swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml
));
574 cx
= swfdec_gc_object_get_context (xml
);
576 // closing tag or opening tag?
577 if (*(p
+ 1) == '/') {
584 // find the end of the name
585 end
= p
+ strcspn (p
, "> \r\n\t");
587 // don't count trailing / as part of the name if it's followed by >
588 // note we do this for close tags also, so <test/ ></test/> doesn't work
589 if (*end
== '>' && *(end
- 1) == '/')
592 if (end
- (p
+ 1) <= 0 || *end
== '\0') {
593 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
594 return strchr (p
, '\0');
597 name
= g_strndup (p
+ 1 , end
- (p
+ 1));
600 end
= strchr (end
, '>');
602 end
= strchr (p
, '\0');
604 // create the new element
605 child
= swfdec_xml_node_new_no_properties (cx
, SWFDEC_XML_NODE_ELEMENT
,
606 swfdec_as_context_give_string (cx
, name
));
607 end
= end
+ strspn (end
, " \r\n\t");
608 while (*end
!= '\0' && *end
!= '>' && (*end
!= '/' || *(end
+ 1) != '>')) {
609 end
= swfdec_xml_parse_attribute (xml
, child
, end
);
610 end
= end
+ strspn (end
, " \r\n\t");
617 if (xml
->status
== XML_PARSE_STATUS_OK
)
618 xml
->status
= XML_PARSE_STATUS_ELEMENT_MALFORMED
;
625 if ((*node
)->parent
!= NULL
&& !g_ascii_strcasecmp ((*node
)->name
, name
)) {
626 *node
= (*node
)->parent
;
629 SwfdecXmlNode
*iter
= *node
;
630 while (iter
!= NULL
&& (iter
->name
== NULL
|| g_ascii_strcasecmp (iter
->name
, name
))) {
634 xml
->status
= XML_PARSE_STATUS_TAG_NOT_CLOSED
;
636 xml
->status
= XML_PARSE_STATUS_TAG_MISMATCH
;
643 swfdec_xml_node_appendChild (*node
, child
);
645 id
= swfdec_xml_node_get_attribute (child
, SWFDEC_AS_STR_id
);
647 swfdec_xml_add_id_map (xml
, child
, id
);
649 if (*(end
- 1) != '/')
655 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
661 swfdec_xml_parse_cdata (SwfdecXml
*xml
, SwfdecXmlNode
*node
, const char *p
)
664 SwfdecXmlNode
*child
;
668 g_assert (p
!= NULL
);
669 g_return_val_if_fail (strncmp (p
, "<![CDATA[", strlen ("<![CDATA[")) == 0,
671 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
673 p
+= strlen ("<![CDATA[");
675 end
= strstr (p
, "]]>");
678 xml
->status
= XML_PARSE_STATUS_CDATA_NOT_TERMINATED
;
679 return strchr (p
, '\0');
682 text
= g_strndup (p
, end
- p
);
684 cx
= swfdec_gc_object_get_context (xml
);
685 child
= swfdec_xml_node_new_no_properties (cx
, SWFDEC_XML_NODE_TEXT
,
686 swfdec_as_context_give_string (cx
, text
));
687 swfdec_xml_node_appendChild (node
, child
);
689 end
+= strlen("]]>");
691 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
697 swfdec_xml_parse_text (SwfdecXml
*xml
, SwfdecXmlNode
*node
,
698 const char *p
, gboolean ignore_white
)
700 SwfdecXmlNode
*child
;
702 char *text
, *unescaped
;
704 g_assert (p
!= NULL
);
705 g_return_val_if_fail (*p
!= '\0', p
);
706 g_return_val_if_fail (SWFDEC_IS_XML (xml
), strchr (p
, '\0'));
708 end
= strchr (p
, '<');
710 end
= strchr (p
, '\0');
712 if (!ignore_white
|| strspn (p
, " \t\r\n") < (gsize
)(end
- p
))
714 SwfdecAsContext
*cx
= swfdec_gc_object_get_context (xml
);
715 text
= g_strndup (p
, end
- p
);
716 unescaped
= swfdec_xml_unescape (cx
, text
);
718 child
= swfdec_xml_node_new_no_properties (cx
, SWFDEC_XML_NODE_TEXT
,
719 swfdec_as_context_give_string (cx
, unescaped
));
720 swfdec_xml_node_appendChild (node
, child
);
723 g_return_val_if_fail (end
> p
, strchr (p
, '\0'));
729 swfdec_xml_parseXML (SwfdecXml
*xml
, const char *value
)
731 SwfdecAsObject
*object
;
734 gboolean ignore_white
;
736 g_return_if_fail (SWFDEC_IS_XML (xml
));
737 g_return_if_fail (value
!= NULL
);
739 object
= swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml
));
740 node
= SWFDEC_XML_NODE (xml
);
742 swfdec_xml_node_removeChildren (SWFDEC_XML_NODE (xml
));
743 xml
->xml_decl
= NULL
;
744 xml
->doc_type_decl
= NULL
;
745 xml
->status
= XML_PARSE_STATUS_OK
;
749 // special case: we only use the ignoreWhite set at the start
750 ignore_white
= xml
->ignore_white
;
752 while (xml
->status
== XML_PARSE_STATUS_OK
&& *p
!= '\0') {
754 if (g_ascii_strncasecmp (p
+ 1, "?xml", strlen ("?xml")) == 0) {
755 p
= swfdec_xml_parse_xmlDecl (xml
, node
, p
);
756 } else if (g_ascii_strncasecmp (p
+ 1, "!DOCTYPE", strlen ("!DOCTYPE")) == 0) {
757 p
= swfdec_xml_parse_docTypeDecl (xml
, node
, p
);
758 } else if (strncmp (p
+ 1, "!--", strlen ("!--")) == 0) {
759 p
= swfdec_xml_parse_comment (xml
, p
);
760 } else if (g_ascii_strncasecmp (p
+ 1, "![CDATA", strlen ("![CDATA")) == 0) {
761 p
= swfdec_xml_parse_cdata (xml
, node
, p
);
763 p
= swfdec_xml_parse_tag (xml
, &node
, p
);
766 p
= swfdec_xml_parse_text (xml
, node
, p
, ignore_white
);
768 g_assert (p
!= NULL
);
771 if (xml
->status
== XML_PARSE_STATUS_OK
&& node
!= SWFDEC_XML_NODE (xml
))
772 xml
->status
= XML_PARSE_STATUS_TAG_NOT_CLOSED
;
775 // this is an old XML parsing function that is only available trough the
777 SWFDEC_AS_NATIVE (300, 0, swfdec_xml_do_oldParseXML
)
779 swfdec_xml_do_oldParseXML (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
780 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
782 SWFDEC_STUB ("XML.oldParseXML (not-really-named)");
785 SWFDEC_AS_NATIVE (253, 12, swfdec_xml_do_parseXML
)
787 swfdec_xml_do_parseXML (SwfdecAsContext
*cx
, SwfdecAsObject
*object
, guint argc
,
788 SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
793 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &s
);
795 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
798 swfdec_xml_parseXML (xml
, s
);
801 SWFDEC_AS_NATIVE (253, 10, swfdec_xml_createElement
)
803 swfdec_xml_createElement (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
804 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
810 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &s
);
813 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
816 node
= swfdec_xml_node_new (cx
, SWFDEC_XML_NODE_ELEMENT
, s
);
818 SWFDEC_AS_VALUE_SET_OBJECT (rval
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node
)));
821 SWFDEC_AS_NATIVE (253, 11, swfdec_xml_createTextNode
)
823 swfdec_xml_createTextNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
824 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
830 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML
, &xml
, "s", &s
);
833 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
836 node
= swfdec_xml_node_new (cx
, SWFDEC_XML_NODE_TEXT
, s
);
838 SWFDEC_AS_VALUE_SET_OBJECT (rval
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node
)));
842 swfdec_xml_init_properties (SwfdecAsContext
*cx
)
845 SwfdecAsObject
*xml
, *proto
;
847 // FIXME: We should only initialize if the prototype Object has not been
848 // initialized by any object's constructor with native properties
849 // (TextField, TextFormat, XML, XMLNode at least)
851 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (cx
));
853 swfdec_as_object_get_variable (cx
->global
, SWFDEC_AS_STR_XML
, &val
);
854 if (!SWFDEC_AS_VALUE_IS_OBJECT (val
))
856 xml
= SWFDEC_AS_VALUE_GET_OBJECT (val
);
858 swfdec_as_object_get_variable (xml
, SWFDEC_AS_STR_prototype
, &val
);
859 if (!SWFDEC_AS_VALUE_IS_OBJECT (val
))
861 proto
= SWFDEC_AS_VALUE_GET_OBJECT (val
);
863 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_ignoreWhite
,
864 swfdec_xml_get_ignoreWhite
, swfdec_xml_set_ignoreWhite
);
865 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_status
,
866 swfdec_xml_get_status
, swfdec_xml_set_status
);
867 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_xmlDecl
,
868 swfdec_xml_get_xmlDecl
, swfdec_xml_set_xmlDecl
);
869 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_docTypeDecl
,
870 swfdec_xml_get_docTypeDecl
, swfdec_xml_set_docTypeDecl
);
872 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_contentType
,
873 swfdec_xml_get_contentType
, swfdec_xml_set_contentType
);
874 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_loaded
,
875 swfdec_xml_get_loaded
, swfdec_xml_set_loaded
);
878 SWFDEC_AS_NATIVE (253, 9, swfdec_xml_construct
)
880 swfdec_xml_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
881 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
885 if (!swfdec_as_context_is_constructing (cx
))
888 swfdec_xml_init_properties (cx
);
890 xml
= g_object_new (SWFDEC_TYPE_XML
, "context", cx
, NULL
);
891 swfdec_xml_node_init_values (SWFDEC_XML_NODE (xml
), SWFDEC_XML_NODE_ELEMENT
, SWFDEC_AS_STR_EMPTY
);
892 SWFDEC_XML_NODE (xml
)->name
= NULL
;
893 swfdec_as_object_set_relay (object
, SWFDEC_AS_RELAY (xml
));
896 if (!SWFDEC_IS_VALID_XML_NODE (xml
))
899 if (argc
>= 1 && !SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0])) {
900 swfdec_xml_parseXML (xml
, swfdec_as_value_to_string (cx
, argv
[0]));
905 swfdec_xml_new_no_properties (SwfdecAsContext
*context
, const char *str
,
906 gboolean ignore_white
)
908 SwfdecAsObject
*object
;
911 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
913 xml
= g_object_new (SWFDEC_TYPE_XML
, "context", context
, NULL
);
914 xml
->ignore_white
= ignore_white
;
915 swfdec_xml_node_init_values (SWFDEC_XML_NODE (xml
),
916 SWFDEC_XML_NODE_ELEMENT
, SWFDEC_AS_STR_EMPTY
);
918 object
= swfdec_as_object_new (context
, NULL
);
919 swfdec_as_object_set_constructor_by_name (object
, SWFDEC_AS_STR_XML
, NULL
);
920 swfdec_as_object_set_relay (object
, SWFDEC_AS_RELAY (xml
));
923 swfdec_xml_parseXML (xml
, str
);
929 swfdec_xml_new (SwfdecAsContext
*context
, const char *str
,
930 gboolean ignore_white
)
932 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
934 swfdec_xml_init_properties (context
);
936 return swfdec_xml_new_no_properties (context
, str
, ignore_white
);