4 #include <glib/gstdio.h>
5 #include "icon_tools.h"
25 static tag_map_t tag_map[] =
27 {"resources", R_RESOURCES},
28 {"section", R_SECTION},
33 #define TAG_MAP_SZ (sizeof(tag_map)/sizeof(tag_map_t))
48 const gchar **attr_names,
49 const gchar **attr_values)
53 if (attr_names == NULL) return NULL;
54 for (ii = 0; attr_names[ii] != NULL; ii++)
56 if (strcmp(name, attr_names[ii]) == 0)
57 return attr_values[ii];
63 read_string_from_file(const gchar *filename)
70 fd = g_fopen(filename, "r");
73 fseek(fd, 0, SEEK_END);
75 fseek(fd, 0, SEEK_SET);
76 buffer = g_malloc(size+1);
77 size = fread(buffer, 1, size, fd);
79 gval = ghb_value_new(G_TYPE_STRING);
80 g_value_take_string(gval, buffer);
87 GMarkupParseContext *ctx,
89 const gchar **attr_names,
90 const gchar **attr_values,
94 parse_data_t *pd = (parse_data_t*)ud;
102 // Check to see if the first element found has been closed
103 // If so, ignore any junk following it.
107 for (ii = 0; ii < TAG_MAP_SZ; ii++)
109 if (strcmp(tag, tag_map[ii].tag) == 0)
111 id.id = tag_map[ii].id;
115 if (ii == TAG_MAP_SZ)
117 g_warning("Unrecognized start tag (%s)", tag);
120 g_queue_push_head(pd->tag_stack, id.pid);
123 GValue *current = g_queue_peek_head(pd->stack);
130 name = lookup_attr_value("name", attr_names, attr_values);
131 if (name && strcmp(name, "icons") == 0)
133 gval = ghb_dict_value_new();
134 if (pd->key) g_free(pd->key);
135 pd->key = g_strdup(name);
136 g_queue_push_head(pd->stack, gval);
141 const gchar *filename, *name;
143 filename = lookup_attr_value("file", attr_names, attr_values);
144 name = lookup_attr_value("name", attr_names, attr_values);
145 if (filename && name)
150 rd = g_malloc(sizeof(ghb_rawdata_t));
151 rd->data = icon_file_serialize(filename, &size);
153 gval = ghb_rawdata_value_new(rd);
154 if (pd->key) g_free(pd->key);
155 pd->key = g_strdup(name);
159 g_warning("%s:missing a requried attribute", name);
164 const gchar *filename, *name;
166 filename = lookup_attr_value("file", attr_names, attr_values);
167 name = lookup_attr_value("name", attr_names, attr_values);
168 if (filename && name)
170 gval = ghb_plist_parse_file(filename);
171 if (pd->key) g_free(pd->key);
172 pd->key = g_strdup(name);
176 g_warning("%s:missing a requried attribute", name);
181 const gchar *filename, *name;
183 filename = lookup_attr_value("file", attr_names, attr_values);
184 name = lookup_attr_value("name", attr_names, attr_values);
185 if (filename && name)
187 gval = read_string_from_file(filename);
188 if (pd->key) g_free(pd->key);
189 pd->key = g_strdup(name);
193 g_warning("%s:missing a requried attribute", name);
197 // Add the element to the current container
199 { // There's an element to add
205 gtype = G_VALUE_TYPE(current);
206 if (gtype == ghb_array_get_type())
208 ghb_array_append(current, gval);
210 else if (gtype == ghb_dict_get_type())
214 g_warning("No key for dictionary item");
215 ghb_value_free(gval);
219 ghb_dict_insert(current, g_strdup(pd->key), gval);
224 g_error("Invalid container type. This shouldn't happen");
231 GMarkupParseContext *ctx,
236 parse_data_t *pd = (parse_data_t*)ud;
245 // Check to see if the first element found has been closed
246 // If so, ignore any junk following it.
250 for (ii = 0; ii < TAG_MAP_SZ; ii++)
252 if (strcmp(name, tag_map[ii].tag) == 0)
258 if (ii == TAG_MAP_SZ)
260 g_warning("Unrecognized start tag (%s)", name);
263 start_id.pid = g_queue_pop_head(pd->tag_stack);
264 if (start_id.id != id)
265 g_warning("start tag != end tag: (%s %d) %d", name, id, id);
268 GValue *current = g_queue_peek_head(pd->stack);
274 g_queue_pop_head(pd->stack);
279 // Get the top of the data structure stack and if it's an array
280 // or dict, add the current element
284 pd->closed_top = TRUE;
287 gtype = G_VALUE_TYPE(current);
288 if (gtype == ghb_array_get_type())
290 ghb_array_append(current, gval);
292 else if (gtype == ghb_dict_get_type())
296 g_warning("No key for dictionary item");
297 ghb_value_free(gval);
301 ghb_dict_insert(current, g_strdup(pd->key), gval);
306 g_error("Invalid container type. This shouldn't happen");
309 if (g_queue_is_empty(pd->tag_stack))
310 pd->closed_top = TRUE;
315 GMarkupParseContext *ctx,
321 parse_data_t *pd = (parse_data_t*)ud;
322 if (pd->value) g_free(pd->value);
323 pd->value = g_strdup(text);
328 GMarkupParseContext *ctx,
334 //parse_data_t *pd = (parse_data_t*)ud;
336 //g_debug("passthrough %s", text);
340 parse_error(GMarkupParseContext *ctx, GError *error, gpointer ud)
342 g_warning("Resource parse error: %s", error->message);
345 // This is required or the parser crashes
347 destroy_notify(gpointer data)
349 //g_debug("destroy parser");
353 ghb_resource_parse(const gchar *buf, gssize len)
355 GMarkupParseContext *ctx;
356 GMarkupParser parser;
360 pd.stack = g_queue_new();
361 pd.tag_stack = g_queue_new();
364 pd.plist = ghb_dict_value_new();
365 g_queue_push_head(pd.stack, pd.plist);
366 pd.closed_top = FALSE;
368 parser.start_element = start_element;
369 parser.end_element = end_element;
370 parser.text = text_data;
371 parser.passthrough = passthrough;
372 parser.error = parse_error;
373 ctx = g_markup_parse_context_new(&parser, 0, &pd, destroy_notify);
375 g_markup_parse_context_parse(ctx, buf, len, &err);
376 g_markup_parse_context_end_parse(ctx, &err);
377 g_markup_parse_context_free(ctx);
378 g_queue_free(pd.stack);
379 g_queue_free(pd.tag_stack);
384 ghb_resource_parse_file(FILE *fd)
392 fseek(fd, 0, SEEK_END);
394 fseek(fd, 0, SEEK_SET);
395 buffer = g_malloc(size+1);
396 size = fread(buffer, 1, size, fd);
398 gval = ghb_resource_parse(buffer, (gssize)size);
405 main(gint argc, gchar *argv[])
412 fprintf(stderr, "Usage: <in resource list> <out resource plist>\n");
416 file = g_fopen(argv[1], "r");
420 gval = ghb_resource_parse_file(file);
421 ghb_plist_write_file(argv[2], gval);