diff options
-rw-r--r-- | gvdb-reader.c | 146 | ||||
-rw-r--r-- | gvdb-reader.h | 10 |
2 files changed, 117 insertions, 39 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,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); } } 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); |