1 /********************************************************************
2 * sixtp-to-dom-parser.c *
3 * Copyright 2001 Gnumatic, Inc. *
4 * *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License as *
7 * published by the Free Software Foundation; either version 2 of *
8 * the License, or (at your option) any later version. *
9 * *
10 * This program 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 *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License*
16 * along with this program; if not, contact: *
17 * *
18 * Free Software Foundation Voice: +1-617-542-5942 *
19 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20 * Boston, MA 02110-1301, USA gnu@gnu.org *
21 * *
22 ********************************************************************/
23 extern "C"
24 {
25 #include <config.h>
26 #include <ctype.h>
27 }
28
29 #include <glib.h>
30
31 #include "sixtp-parsers.h"
32 #include "sixtp-utils.h"
33 #include "sixtp.h"
34
35 static xmlNsPtr global_namespace = NULL;
36
37 /* Don't pass anything in the data_for_children value to this
38 function. It'll cause a segfault */
dom_start_handler(GSList * sibling_data,gpointer parent_data,gpointer global_data,gpointer * data_for_children,gpointer * result,const gchar * tag,gchar ** attrs)39 static gboolean dom_start_handler (
40 GSList* sibling_data, gpointer parent_data, gpointer global_data,
41 gpointer* data_for_children, gpointer* result, const gchar* tag,
42 gchar** attrs)
43 {
44 xmlNodePtr thing;
45 gchar** atptr = attrs;
46
47 if (parent_data == NULL)
48 {
49 thing = xmlNewNode (global_namespace, BAD_CAST tag);
50 /* only publish the result if we're the parent */
51 *result = thing;
52 }
53 else
54 {
55 thing = xmlNewChild ((xmlNodePtr) parent_data,
56 global_namespace,
57 BAD_CAST tag,
58 NULL);
59 *result = NULL;
60 }
61 *data_for_children = thing;
62
63 if (attrs != NULL)
64 {
65 while (*atptr != 0)
66 {
67 gchar* attr0 = g_strdup (atptr[0]);
68 gchar* attr1 = g_strdup (atptr[1]);
69 xmlSetProp (thing, checked_char_cast (attr0),
70 checked_char_cast (attr1));
71 g_free (attr0);
72 g_free (attr1);
73 atptr += 2;
74 }
75 }
76 return TRUE;
77 }
78
79 static void
dom_fail_handler(gpointer data_for_children,GSList * data_from_children,GSList * sibling_data,gpointer parent_data,gpointer global_data,gpointer * result,const gchar * tag)80 dom_fail_handler (gpointer data_for_children,
81 GSList* data_from_children,
82 GSList* sibling_data,
83 gpointer parent_data,
84 gpointer global_data,
85 gpointer* result,
86 const gchar* tag)
87 {
88 if (*result) xmlFreeNode (static_cast<xmlNodePtr> (*result));
89 }
90
dom_chars_handler(GSList * sibling_data,gpointer parent_data,gpointer global_data,gpointer * result,const char * text,int length)91 static gboolean dom_chars_handler (
92 GSList* sibling_data, gpointer parent_data, gpointer global_data,
93 gpointer* result, const char* text, int length)
94 {
95 if (length > 0)
96 {
97 gchar* newtext = g_strndup (text,length);
98 xmlNodeAddContentLen ((xmlNodePtr)parent_data,
99 checked_char_cast (newtext), length);
100 g_free (newtext);
101 }
102 return TRUE;
103 }
104
105 sixtp*
sixtp_dom_parser_new(sixtp_end_handler ender,sixtp_result_handler cleanup_result_by_default_func,sixtp_result_handler cleanup_result_on_fail_func)106 sixtp_dom_parser_new (sixtp_end_handler ender,
107 sixtp_result_handler cleanup_result_by_default_func,
108 sixtp_result_handler cleanup_result_on_fail_func)
109 {
110 sixtp* top_level;
111
112 g_return_val_if_fail (ender, NULL);
113
114 if (! (top_level =
115 sixtp_set_any (sixtp_new (), FALSE,
116 SIXTP_START_HANDLER_ID, dom_start_handler,
117 SIXTP_CHARACTERS_HANDLER_ID, dom_chars_handler,
118 SIXTP_END_HANDLER_ID, ender,
119 SIXTP_FAIL_HANDLER_ID, dom_fail_handler,
120 SIXTP_NO_MORE_HANDLERS)))
121 {
122 return NULL;
123 }
124
125 if (cleanup_result_by_default_func)
126 {
127 sixtp_set_cleanup_result (top_level, cleanup_result_by_default_func);
128 }
129
130 if (cleanup_result_by_default_func)
131 {
132 sixtp_set_result_fail (top_level, cleanup_result_on_fail_func);
133 }
134
135 if (!sixtp_add_sub_parser (top_level, SIXTP_MAGIC_CATCHER, top_level))
136 {
137 sixtp_destroy (top_level);
138 return NULL;
139 }
140
141 return top_level;
142 }
143