summaryrefslogtreecommitdiffstats
path: root/gtk/src/create_resources.c
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2008-09-09 23:14:28 +0000
committerjstebbins <[email protected]>2008-09-09 23:14:28 +0000
commite57d4d0bf36c3b5d4691134d0fdb8171cb25f843 (patch)
treead4dddfe057558ad5cd8fd5c02eb1d156079c709 /gtk/src/create_resources.c
parentebf4b4d663b9eeeed5d9632b5a2076355cff7145 (diff)
LinGui: consolidate all resources into one stringified plist file that gets
compiled in. icons and everyting all rolled up into one ball-o-wax. hehe, plists are cool git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1685 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'gtk/src/create_resources.c')
-rw-r--r--gtk/src/create_resources.c382
1 files changed, 382 insertions, 0 deletions
diff --git a/gtk/src/create_resources.c b/gtk/src/create_resources.c
new file mode 100644
index 000000000..70d2b0fdc
--- /dev/null
+++ b/gtk/src/create_resources.c
@@ -0,0 +1,382 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include "icon_tools.h"
+#include "plist.h"
+#include "values.h"
+
+enum
+{
+ R_NONE = 0,
+ R_RESOURCES,
+ R_SECTION,
+ R_ICON,
+ R_PLIST,
+};
+
+typedef struct
+{
+ gchar *tag;
+ gint id;
+} tag_map_t;
+
+static tag_map_t tag_map[] =
+{
+ {"resources", R_RESOURCES},
+ {"section", R_SECTION},
+ {"icon", R_ICON},
+ {"plist", R_PLIST},
+};
+#define TAG_MAP_SZ (sizeof(tag_map)/sizeof(tag_map_t))
+
+typedef struct
+{
+ gchar *key;
+ gchar *value;
+ GValue *plist;
+ GQueue *stack;
+ GQueue *tag_stack;
+ gboolean closed_top;
+} parse_data_t;
+
+static const gchar*
+lookup_attr_value(
+ const gchar *name,
+ const gchar **attr_names,
+ const gchar **attr_values)
+{
+ gint ii;
+
+ if (attr_names == NULL) return NULL;
+ for (ii = 0; attr_names[ii] != NULL; ii++)
+ {
+ if (strcmp(name, attr_names[ii]) == 0)
+ return attr_values[ii];
+ }
+ return NULL;
+}
+
+static void
+start_element(
+ GMarkupParseContext *ctx,
+ const gchar *name,
+ const gchar **attr_names,
+ const gchar **attr_values,
+ gpointer ud,
+ GError **error)
+{
+ parse_data_t *pd = (parse_data_t*)ud;
+ union
+ {
+ gint id;
+ gpointer pid;
+ } id;
+ gint ii;
+
+ // Check to see if the first element found has been closed
+ // If so, ignore any junk following it.
+ if (pd->closed_top)
+ return;
+
+ for (ii = 0; ii < TAG_MAP_SZ; ii++)
+ {
+ if (strcmp(name, tag_map[ii].tag) == 0)
+ {
+ id.id = tag_map[ii].id;
+ break;
+ }
+ }
+ if (ii == TAG_MAP_SZ)
+ {
+ g_warning("Unrecognized start tag (%s)", name);
+ return;
+ }
+ g_queue_push_head(pd->tag_stack, id.pid);
+ GType gtype = 0;
+ GValue *gval = NULL;
+ GValue *current = g_queue_peek_head(pd->stack);
+ switch (id.id)
+ {
+ case R_SECTION:
+ {
+ const gchar *sect;
+
+ sect = lookup_attr_value("name", attr_names, attr_values);
+ if (sect && strcmp(sect, "icons") == 0)
+ {
+ gval = ghb_dict_value_new();
+ if (pd->key) g_free(pd->key);
+ pd->key = g_strdup(sect);
+ g_queue_push_head(pd->stack, gval);
+ }
+ } break;
+ case R_ICON:
+ {
+ const gchar *filename, *icon;
+
+ filename = lookup_attr_value("file", attr_names, attr_values);
+ icon = lookup_attr_value("name", attr_names, attr_values);
+ if (filename && icon)
+ {
+ ghb_rawdata_t *rd;
+ guint size;
+
+ rd = g_malloc(sizeof(ghb_rawdata_t));
+ rd->data = icon_file_serialize(filename, &size);
+ rd->size = size;
+ gval = ghb_rawdata_value_new(rd);
+ if (pd->key) g_free(pd->key);
+ pd->key = g_strdup(icon);
+ }
+ else
+ {
+ g_warning("%s:missing a requried attribute", name);
+ }
+ } break;
+ case R_PLIST:
+ {
+ const gchar *filename, *plist;
+
+ filename = lookup_attr_value("file", attr_names, attr_values);
+ plist = lookup_attr_value("name", attr_names, attr_values);
+ if (filename && plist)
+ {
+ gval = ghb_plist_parse_file(filename);
+ if (pd->key) g_free(pd->key);
+ pd->key = g_strdup(plist);
+ }
+ else
+ {
+ g_warning("%s:missing a requried attribute", name);
+ }
+ } break;
+ }
+ // Add the element to the current container
+ if (gval)
+ { // There's an element to add
+ if (current == NULL)
+ {
+ pd->plist = gval;
+ return;
+ }
+ gtype = G_VALUE_TYPE(current);
+ if (gtype == ghb_array_get_type())
+ {
+ ghb_array_append(current, gval);
+ }
+ else if (gtype == ghb_dict_get_type())
+ {
+ if (pd->key == NULL)
+ {
+ g_warning("No key for dictionary item");
+ ghb_value_free(gval);
+ }
+ else
+ {
+ ghb_dict_insert(current, g_strdup(pd->key), gval);
+ }
+ }
+ else
+ {
+ g_error("Invalid container type. This shouldn't happen");
+ }
+ }
+}
+
+static void
+end_element(
+ GMarkupParseContext *ctx,
+ const gchar *name,
+ gpointer ud,
+ GError **error)
+{
+ parse_data_t *pd = (parse_data_t*)ud;
+ gint id;
+ union
+ {
+ gint id;
+ gpointer pid;
+ } start_id;
+ gint ii;
+
+ // Check to see if the first element found has been closed
+ // If so, ignore any junk following it.
+ if (pd->closed_top)
+ return;
+
+ for (ii = 0; ii < TAG_MAP_SZ; ii++)
+ {
+ if (strcmp(name, tag_map[ii].tag) == 0)
+ {
+ id = tag_map[ii].id;
+ break;
+ }
+ }
+ if (ii == TAG_MAP_SZ)
+ {
+ g_warning("Unrecognized start tag (%s)", name);
+ return;
+ }
+ start_id.pid = g_queue_pop_head(pd->tag_stack);
+ if (start_id.id != id)
+ g_warning("start tag != end tag: (%s %d) %d", name, id, id);
+
+ GValue *gval = NULL;
+ GValue *current = g_queue_peek_head(pd->stack);
+ GType gtype = 0;
+ switch (id)
+ {
+ case R_SECTION:
+ {
+ g_queue_pop_head(pd->stack);
+ } break;
+ }
+ if (gval)
+ {
+ // Get the top of the data structure stack and if it's an array
+ // or dict, add the current element
+ if (current == NULL)
+ {
+ pd->plist = gval;
+ pd->closed_top = TRUE;
+ return;
+ }
+ gtype = G_VALUE_TYPE(current);
+ if (gtype == ghb_array_get_type())
+ {
+ ghb_array_append(current, gval);
+ }
+ else if (gtype == ghb_dict_get_type())
+ {
+ if (pd->key == NULL)
+ {
+ g_warning("No key for dictionary item");
+ ghb_value_free(gval);
+ }
+ else
+ {
+ ghb_dict_insert(current, g_strdup(pd->key), gval);
+ }
+ }
+ else
+ {
+ g_error("Invalid container type. This shouldn't happen");
+ }
+ }
+ if (g_queue_is_empty(pd->tag_stack))
+ pd->closed_top = TRUE;
+}
+
+static void
+text_data(
+ GMarkupParseContext *ctx,
+ const gchar *text,
+ gsize len,
+ gpointer ud,
+ GError **error)
+{
+ parse_data_t *pd = (parse_data_t*)ud;
+ if (pd->value) g_free(pd->value);
+ pd->value = g_strdup(text);
+}
+
+static void
+passthrough(
+ GMarkupParseContext *ctx,
+ const gchar *text,
+ gsize len,
+ gpointer ud,
+ GError **error)
+{
+ //parse_data_t *pd = (parse_data_t*)ud;
+
+ //g_debug("passthrough %s", text);
+}
+
+static void
+parse_error(GMarkupParseContext *ctx, GError *error, gpointer ud)
+{
+ g_warning("Resource parse error: %s", error->message);
+}
+
+// This is required or the parser crashes
+static void
+destroy_notify(gpointer data)
+{ // Do nothing
+ //g_debug("destroy parser");
+}
+
+GValue*
+ghb_resource_parse(const gchar *buf, gssize len)
+{
+ GMarkupParseContext *ctx;
+ GMarkupParser parser;
+ parse_data_t pd;
+ GError *err = NULL;
+
+ pd.stack = g_queue_new();
+ pd.tag_stack = g_queue_new();
+ pd.key = NULL;
+ pd.value = NULL;
+ pd.plist = ghb_dict_value_new();
+ g_queue_push_head(pd.stack, pd.plist);
+ pd.closed_top = FALSE;
+
+ parser.start_element = start_element;
+ parser.end_element = end_element;
+ parser.text = text_data;
+ parser.passthrough = passthrough;
+ parser.error = parse_error;
+ ctx = g_markup_parse_context_new(&parser, 0, &pd, destroy_notify);
+
+ g_markup_parse_context_parse(ctx, buf, len, &err);
+ g_markup_parse_context_end_parse(ctx, &err);
+ g_markup_parse_context_free(ctx);
+ g_queue_free(pd.stack);
+ g_queue_free(pd.tag_stack);
+ return pd.plist;
+}
+
+GValue*
+ghb_resource_parse_file(FILE *fd)
+{
+ gchar *buffer;
+ size_t size;
+ GValue *gval;
+
+ if (fd == NULL)
+ return NULL;
+ fseek(fd, 0, SEEK_END);
+ size = ftell(fd);
+ fseek(fd, 0, SEEK_SET);
+ buffer = g_malloc(size+1);
+ size = fread(buffer, 1, size, fd);
+ buffer[size] = 0;
+ gval = ghb_resource_parse(buffer, (gssize)size);
+ g_free(buffer);
+ return gval;
+}
+
+
+gint
+main(gint argc, gchar *argv[])
+{
+ FILE *file;
+ GValue *gval;
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "Usage: <in resource list> <out resource plist>\n");
+ return 1;
+ }
+ g_type_init();
+ file = g_fopen(argv[1], "r");
+ if (file == NULL)
+ return 1;
+
+ gval = ghb_resource_parse_file(file);
+ ghb_plist_write_file(argv[2], gval);
+ return 0;
+}
+