From d1f6300363bb8afc5f7f1e54663a7201587bcd41 Mon Sep 17 00:00:00 2001 From: Murray Cumming Date: Fri, 13 Jan 2012 09:21:46 +0100 Subject: [PATCH 1/2] Docs: Changed can not to cannot. This is a backport from the glib commit 30fdc1a79938540af7bad0af68d0a3b8af14f117 --- gvdb-reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gvdb-reader.c b/gvdb-reader.c index 57816af73..5a1e26f2e 100644 --- a/gvdb-reader.c +++ b/gvdb-reader.c @@ -133,7 +133,7 @@ gvdb_table_setup_root (GvdbTable *file, * Creates a new #GvdbTable from the contents of the file found at * @filename. * - * The only time this function fails is if the file can not be opened. + * The only time this function fails is if the file cannot be opened. * In that case, the #GError that is returned will be an error from * g_mapped_file_new(). * From 73acf016185f323a8caa268b53284621d805fb15 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 13 Jan 2012 15:59:56 +0100 Subject: [PATCH 2/2] Support creating a GvdbReader from data This is needed for the glib resource work. --- gvdb-reader.c | 148 ++++++++++++++++++++++++++++++++++++-------------- gvdb-reader.h | 10 ++++ 2 files changed, 118 insertions(+), 40 deletions(-) diff --git a/gvdb-reader.c b/gvdb-reader.c index 5a1e26f2e..dfdb4479f 100644 --- a/gvdb-reader.c +++ b/gvdb-reader.c @@ -30,7 +30,10 @@ struct _GvdbTable { const gchar *data; gsize size; - GMappedFile *mapped; + gpointer user_data; + GvdbRefFunc ref_user_data; + GDestroyNotify unref_user_data; + gboolean byteswapped; gboolean trusted; @@ -123,6 +126,62 @@ gvdb_table_setup_root (GvdbTable *file, file->n_hash_items = size / sizeof (struct gvdb_hash_item); } +static GvdbTable * +new_from_data (const void *data, + gsize data_len, + gboolean trusted, + gpointer user_data, + GvdbRefFunc ref, + GDestroyNotify unref, + const char *filename, + GError **error) +{ + GvdbTable *file; + + file = g_slice_new0 (GvdbTable); + file->data = data; + file->size = data_len; + file->trusted = trusted; + file->ref_count = 1; + file->ref_user_data = ref; + file->unref_user_data = unref; + file->user_data = user_data; + + if (sizeof (struct gvdb_header) <= file->size) + { + const struct gvdb_header *header = (gpointer) file->data; + + if (header->signature[0] == GVDB_SIGNATURE0 && + header->signature[1] == GVDB_SIGNATURE1 && + guint32_from_le (header->version) == 0) + file->byteswapped = FALSE; + + else if (header->signature[0] == GVDB_SWAPPED_SIGNATURE0 && + header->signature[1] == GVDB_SWAPPED_SIGNATURE1 && + guint32_from_le (header->version) == 0) + file->byteswapped = TRUE; + + else + { + if (filename) + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, + "%s: invalid header", filename); + else + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, + "invalid gvdb header"); + g_slice_free (GvdbTable, file); + if (unref) + unref (user_data); + + return NULL; + } + + gvdb_table_setup_root (file, &header->root); + } + + return file; +} + /** * gvdb_table_new: * @filename: the path to the hash file @@ -149,46 +208,52 @@ gvdb_table_new (const gchar *filename, GError **error) { GMappedFile *mapped; - GvdbTable *file; if ((mapped = g_mapped_file_new (filename, FALSE, error)) == NULL) return NULL; - file = g_slice_new0 (GvdbTable); - file->data = g_mapped_file_get_contents (mapped); - file->size = g_mapped_file_get_length (mapped); - file->trusted = trusted; - file->mapped = mapped; - file->ref_count = 1; + return new_from_data (g_mapped_file_get_contents (mapped), + g_mapped_file_get_length (mapped), + trusted, + mapped, + (GvdbRefFunc)g_mapped_file_ref, + (GDestroyNotify)g_mapped_file_unref, + filename, + error); +} - if (sizeof (struct gvdb_header) <= file->size) - { - const struct gvdb_header *header = (gpointer) file->data; - - if (header->signature[0] == GVDB_SIGNATURE0 && - header->signature[1] == GVDB_SIGNATURE1 && - guint32_from_le (header->version) == 0) - file->byteswapped = FALSE; - - else if (header->signature[0] == GVDB_SWAPPED_SIGNATURE0 && - header->signature[1] == GVDB_SWAPPED_SIGNATURE1 && - guint32_from_le (header->version) == 0) - file->byteswapped = TRUE; - - else - { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, - "%s: invalid header", filename); - g_slice_free (GvdbTable, file); - g_mapped_file_unref (mapped); - - return NULL; - } - - gvdb_table_setup_root (file, &header->root); - } - - return file; +/** + * gvdb_table_new_from_data: + * @data: the data + * @data_len: the length of @data in bytes + * @trusted: if the contents of @data are trusted + * @user_data: User supplied data that owns @data + * @ref: Ref function for @user_data + * @unref: Unref function for @user_data + * @returns: a new #GvdbTable + * + * Creates a new #GvdbTable from the data in @data. + * + * An empty or otherwise corrupted data is considered to be a valid + * #GvdbTable with no entries. + * + * You should call gvdb_table_unref() on the return result when you no + * longer require it. + **/ +GvdbTable * +gvdb_table_new_from_data (const void *data, + gsize data_len, + gboolean trusted, + gpointer user_data, + GvdbRefFunc ref, + GDestroyNotify unref, + GError **error) +{ + return new_from_data (data, data_len, + trusted, + user_data, ref, unref, + NULL, + error); } static gboolean @@ -408,8 +473,8 @@ gvdb_table_value_from_item (GvdbTable *table, variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, table->trusted, - (GDestroyNotify) g_mapped_file_unref, - g_mapped_file_ref (table->mapped)); + table->unref_user_data, + table->ref_user_data ? table->ref_user_data (table->user_data) : table->user_data); value = g_variant_get_variant (variant); g_variant_unref (variant); @@ -510,7 +575,9 @@ gvdb_table_get_table (GvdbTable *file, return NULL; new = g_slice_new0 (GvdbTable); - new->mapped = g_mapped_file_ref (file->mapped); + new->user_data = file->ref_user_data ? file->ref_user_data (file->user_data) : file->user_data; + new->ref_user_data = file->ref_user_data; + new->unref_user_data = file->unref_user_data; new->byteswapped = file->byteswapped; new->trusted = file->trusted; new->data = file->data; @@ -550,7 +617,8 @@ gvdb_table_unref (GvdbTable *file) { if (g_atomic_int_dec_and_test (&file->ref_count)) { - g_mapped_file_unref (file->mapped); + if (file->unref_user_data) + file->unref_user_data (file->user_data); g_slice_free (GvdbTable, file); } } diff --git a/gvdb-reader.h b/gvdb-reader.h index e6921e9e8..e6878c3f0 100644 --- a/gvdb-reader.h +++ b/gvdb-reader.h @@ -26,6 +26,8 @@ typedef struct _GvdbTable GvdbTable; +typedef gpointer (*GvdbRefFunc) (gpointer data); + G_BEGIN_DECLS G_GNUC_INTERNAL @@ -33,6 +35,14 @@ GvdbTable * gvdb_table_new (const g gboolean trusted, GError **error); G_GNUC_INTERNAL +GvdbTable * gvdb_table_new_from_data (const void *data, + gsize data_len, + gboolean trusted, + gpointer user_data, + GvdbRefFunc ref, + GDestroyNotify unref, + GError **error); +G_GNUC_INTERNAL GvdbTable * gvdb_table_ref (GvdbTable *table); G_GNUC_INTERNAL void gvdb_table_unref (GvdbTable *table);