diff options
author | Alexander Larsson <alexl@redhat.com> | 2012-01-13 15:59:56 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2012-01-13 15:59:56 +0100 |
commit | 73acf016185f323a8caa268b53284621d805fb15 (patch) | |
tree | dc8ebafd166b690ac79975af47942a5c4bbda387 /gvdb-reader.c | |
parent | d1f6300363bb8afc5f7f1e54663a7201587bcd41 (diff) | |
download | gvdb-73acf016185f323a8caa268b53284621d805fb15.tar.gz |
Support creating a GvdbReader from data
This is needed for the glib resource work.
Diffstat (limited to 'gvdb-reader.c')
-rw-r--r-- | gvdb-reader.c | 146 |
1 files changed, 107 insertions, 39 deletions
diff --git a/gvdb-reader.c b/gvdb-reader.c index 5a1e26f..dfdb447 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,43 +126,26 @@ gvdb_table_setup_root (GvdbTable *file, file->n_hash_items = size / sizeof (struct gvdb_hash_item); } -/** - * gvdb_table_new: - * @filename: the path to the hash file - * @trusted: if the contents of @filename are trusted - * @error: %NULL, or a pointer to a %NULL #GError - * @returns: a new #GvdbTable - * - * Creates a new #GvdbTable from the contents of the file found at - * @filename. - * - * 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(). - * - * An empty or otherwise corrupted file 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 (const gchar *filename, - gboolean trusted, - GError **error) +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) { - 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->data = data; + file->size = data_len; file->trusted = trusted; - file->mapped = mapped; 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) { @@ -177,10 +163,15 @@ gvdb_table_new (const gchar *filename, else { - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, - "%s: invalid header", filename); + 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); - g_mapped_file_unref (mapped); + if (unref) + unref (user_data); return NULL; } @@ -191,6 +182,80 @@ gvdb_table_new (const gchar *filename, return file; } +/** + * gvdb_table_new: + * @filename: the path to the hash file + * @trusted: if the contents of @filename are trusted + * @error: %NULL, or a pointer to a %NULL #GError + * @returns: a new #GvdbTable + * + * Creates a new #GvdbTable from the contents of the file found at + * @filename. + * + * 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(). + * + * An empty or otherwise corrupted file 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 (const gchar *filename, + gboolean trusted, + GError **error) +{ + GMappedFile *mapped; + + if ((mapped = g_mapped_file_new (filename, FALSE, error)) == NULL) + return NULL; + + 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); +} + +/** + * 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 gvdb_table_bloom_filter (GvdbTable *file, guint32 hash_value) @@ -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); } } |