void gvdb_hash_table_insert_string (GHashTable *table, const gchar *key, const gchar *value) { GvdbItem *item; item = gvdb_hash_table_insert (table, key); gvdb_item_set_value (item, g_variant_new_string (value)); }
static void end_element (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { ParseState *state = user_data; if (strcmp (element_name, "default") == 0) { state->value = g_variant_parse (state->type, state->string->str, NULL, NULL, error); if (state->value == NULL) return; if (state->l10n) { if (state->context) { gint len; /* Contextified messages are supported by prepending the * context, followed by '\004' to the start of the message * string. We do that here to save GSettings the work * later on. * * Note: we are about to g_free() the context anyway... */ len = strlen (state->context); state->context[len] = '\004'; g_string_prepend_len (state->string, state->context, len + 1); } g_variant_builder_add (&state->key_options, "{sv}", "l10n", g_variant_new ("(ys)", state->l10n, state->string->str)); } g_string_free (state->string, TRUE); state->string = NULL; g_free (state->context); state->context = NULL; } else if (strcmp (element_name, "key") == 0) { if (state->value == NULL) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "element <default> is required in <key>\n"); return; } if (state->min != NULL) { if (g_variant_compare (state->value, state->min) < 0 || g_variant_compare (state->value, state->max) > 0) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<default> is not contained in the specified range"); return; } state->min = state->max = NULL; } else if (state->choices != NULL) { if (!is_valid_choices (state->value, state->choices->str)) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<default> contains string not in <choices>"); return; } state->choices = NULL; } gvdb_item_set_value (state->key, state->value); gvdb_item_set_options (state->key, g_variant_builder_end (&state->key_options)); state->value = NULL; } else if (strcmp (element_name, "summary") == 0 || strcmp (element_name, "description") == 0) { g_string_free (state->string, TRUE); state->string = NULL; } else if (strcmp (element_name, "choices") == 0) { gchar *choices; choices = g_string_free (state->choices, FALSE); g_variant_builder_add (&state->key_options, "{sv}", "choices", g_variant_new_byte_array (choices, -1)); g_free (choices); } }
static GHashTable * parse_resource_file (const gchar *filename, gboolean collect_data, GHashTable *files) { GMarkupParser parser = { start_element, end_element, text }; ParseState state = { 0, }; GMarkupParseContext *context; GError *error = NULL; gchar *contents; GHashTable *table = NULL; gsize size; if (!g_file_get_contents (filename, &contents, &size, &error)) { g_printerr ("%s\n", error->message); g_clear_error (&error); return NULL; } state.collect_data = collect_data; state.table = g_hash_table_ref (files); context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT | G_MARKUP_PREFIX_ERROR_POSITION, &state, NULL); if (!g_markup_parse_context_parse (context, contents, size, &error) || !g_markup_parse_context_end_parse (context, &error)) { g_printerr ("%s: %s.\n", filename, error->message); g_clear_error (&error); } else { GHashTableIter iter; const char *key; char *mykey; gsize key_len; FileData *data; GVariant *v_data; GVariantBuilder builder; GvdbItem *item; table = gvdb_hash_table_new (NULL, NULL); g_hash_table_iter_init (&iter, state.table); while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&data)) { key_len = strlen (key); mykey = g_strdup (key); item = gvdb_hash_table_insert (table, key); gvdb_item_set_parent (item, get_parent (table, mykey, key_len)); g_free (mykey); g_variant_builder_init (&builder, G_VARIANT_TYPE ("(uuay)")); g_variant_builder_add (&builder, "u", data->size); /* Size */ g_variant_builder_add (&builder, "u", data->flags); /* Flags */ v_data = g_variant_new_from_data (G_VARIANT_TYPE("ay"), data->content, data->content_size, TRUE, g_free, data->content); g_variant_builder_add_value (&builder, v_data); data->content = NULL; /* Take ownership */ gvdb_item_set_value (item, g_variant_builder_end (&builder)); } } g_hash_table_unref (state.table); g_markup_parse_context_free (context); g_free (contents); return table; }