mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-03 22:52:09 +01:00
reader: embrace GBytes
Drop gvdb_table_new_from_data() and add gvdb_table_new_from_bytes(). Since the underlying backingstore of a GvdbTable is now always refcounted, drop the refcounting on GvdbTable itself.
This commit is contained in:
parent
fc37611a97
commit
2600082151
168
gvdb-reader.c
168
gvdb-reader.c
@ -25,15 +25,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct _GvdbTable {
|
struct _GvdbTable {
|
||||||
gint ref_count;
|
GBytes *bytes;
|
||||||
|
|
||||||
const gchar *data;
|
const gchar *data;
|
||||||
gsize size;
|
gsize size;
|
||||||
|
|
||||||
gpointer user_data;
|
|
||||||
GvdbRefFunc ref_user_data;
|
|
||||||
GDestroyNotify unref_user_data;
|
|
||||||
|
|
||||||
gboolean byteswapped;
|
gboolean byteswapped;
|
||||||
gboolean trusted;
|
gboolean trusted;
|
||||||
|
|
||||||
@ -126,27 +122,32 @@ gvdb_table_setup_root (GvdbTable *file,
|
|||||||
file->n_hash_items = size / sizeof (struct gvdb_hash_item);
|
file->n_hash_items = size / sizeof (struct gvdb_hash_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GvdbTable *
|
/**
|
||||||
new_from_data (const void *data,
|
* gvdb_table_new_from_bytes:
|
||||||
gsize data_len,
|
* @bytes: the #GBytes with the data
|
||||||
gboolean trusted,
|
* @trusted: if the contents of @bytes are trusted
|
||||||
gpointer user_data,
|
* @error: %NULL, or a pointer to a %NULL #GError
|
||||||
GvdbRefFunc ref,
|
* @returns: a new #GvdbTable
|
||||||
GDestroyNotify unref,
|
*
|
||||||
const char *filename,
|
* Creates a new #GvdbTable from the contents of @bytes.
|
||||||
GError **error)
|
*
|
||||||
|
* This call can fail if the header contained in @bytes is invalid.
|
||||||
|
*
|
||||||
|
* You should call gvdb_table_free() on the return result when you no
|
||||||
|
* longer require it.
|
||||||
|
**/
|
||||||
|
GvdbTable *
|
||||||
|
gvdb_table_new_from_bytes (GBytes *bytes,
|
||||||
|
gboolean trusted,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
const struct gvdb_header *header;
|
const struct gvdb_header *header;
|
||||||
GvdbTable *file;
|
GvdbTable *file;
|
||||||
|
|
||||||
file = g_slice_new0 (GvdbTable);
|
file = g_slice_new0 (GvdbTable);
|
||||||
file->data = data;
|
file->bytes = g_bytes_ref (bytes);
|
||||||
file->size = data_len;
|
file->data = g_bytes_get_data (bytes, &file->size);
|
||||||
file->trusted = trusted;
|
file->trusted = trusted;
|
||||||
file->ref_count = 1;
|
|
||||||
file->ref_user_data = ref;
|
|
||||||
file->unref_user_data = unref;
|
|
||||||
file->user_data = user_data;
|
|
||||||
|
|
||||||
if (file->size < sizeof (struct gvdb_header))
|
if (file->size < sizeof (struct gvdb_header))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
@ -171,38 +172,24 @@ new_from_data (const void *data,
|
|||||||
return file;
|
return file;
|
||||||
|
|
||||||
invalid:
|
invalid:
|
||||||
if (filename)
|
g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "invalid gvdb header");
|
||||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s: invalid header", filename);
|
|
||||||
else
|
g_bytes_unref (file->bytes);
|
||||||
g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "invalid gvdb header");
|
|
||||||
|
|
||||||
g_slice_free (GvdbTable, file);
|
g_slice_free (GvdbTable, file);
|
||||||
|
|
||||||
if (unref)
|
|
||||||
unref (user_data);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gvdb_table_new:
|
* gvdb_table_new:
|
||||||
* @filename: the path to the hash file
|
* @filename: a filename
|
||||||
* @trusted: if the contents of @filename are trusted
|
* @trusted: if the contents of @bytes are trusted
|
||||||
* @error: %NULL, or a pointer to a %NULL #GError
|
* @error: %NULL, or a pointer to a %NULL #GError
|
||||||
* @returns: a new #GvdbTable
|
* @returns: a new #GvdbTable
|
||||||
*
|
*
|
||||||
* Creates a new #GvdbTable from the contents of the file found at
|
* Creates a new #GvdbTable using the #GMappedFile for @filename as the
|
||||||
* @filename.
|
* #GBytes.
|
||||||
*
|
|
||||||
* 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 *
|
GvdbTable *
|
||||||
gvdb_table_new (const gchar *filename,
|
gvdb_table_new (const gchar *filename,
|
||||||
@ -210,52 +197,21 @@ gvdb_table_new (const gchar *filename,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GMappedFile *mapped;
|
GMappedFile *mapped;
|
||||||
|
GvdbTable *table;
|
||||||
|
GBytes *bytes;
|
||||||
|
|
||||||
if ((mapped = g_mapped_file_new (filename, FALSE, error)) == NULL)
|
mapped = g_mapped_file_new (filename, FALSE, error);
|
||||||
|
if (!mapped)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return new_from_data (g_mapped_file_get_contents (mapped),
|
bytes = g_mapped_file_get_bytes (mapped);
|
||||||
g_mapped_file_get_length (mapped),
|
table = gvdb_table_new_from_bytes (bytes, trusted, error);
|
||||||
trusted,
|
g_mapped_file_unref (mapped);
|
||||||
mapped,
|
g_bytes_unref (bytes);
|
||||||
(GvdbRefFunc)g_mapped_file_ref,
|
|
||||||
(GDestroyNotify)g_mapped_file_unref,
|
|
||||||
filename,
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
g_prefix_error (error, "%s: ", filename);
|
||||||
* gvdb_table_new_from_data:
|
|
||||||
* @data: the data
|
return table;
|
||||||
* @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
|
static gboolean
|
||||||
@ -611,6 +567,7 @@ gvdb_table_value_from_item (GvdbTable *table,
|
|||||||
{
|
{
|
||||||
GVariant *variant, *value;
|
GVariant *variant, *value;
|
||||||
gconstpointer data;
|
gconstpointer data;
|
||||||
|
GBytes *bytes;
|
||||||
gsize size;
|
gsize size;
|
||||||
|
|
||||||
data = gvdb_table_dereference (table, &item->value.pointer, 8, &size);
|
data = gvdb_table_dereference (table, &item->value.pointer, 8, &size);
|
||||||
@ -618,12 +575,11 @@ gvdb_table_value_from_item (GvdbTable *table,
|
|||||||
if G_UNLIKELY (data == NULL)
|
if G_UNLIKELY (data == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT,
|
bytes = g_bytes_new_from_bytes (table->bytes, ((gchar *) data) - table->data, size);
|
||||||
data, size, table->trusted,
|
variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, bytes, table->trusted);
|
||||||
table->unref_user_data,
|
|
||||||
table->ref_user_data ? table->ref_user_data (table->user_data) : table->user_data);
|
|
||||||
value = g_variant_get_variant (variant);
|
value = g_variant_get_variant (variant);
|
||||||
g_variant_unref (variant);
|
g_variant_unref (variant);
|
||||||
|
g_bytes_unref (bytes);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -706,7 +662,7 @@ gvdb_table_get_raw_value (GvdbTable *table,
|
|||||||
* contained in the file. This newly-created #GvdbTable does not depend
|
* contained in the file. This newly-created #GvdbTable does not depend
|
||||||
* on the continued existence of @file.
|
* on the continued existence of @file.
|
||||||
*
|
*
|
||||||
* You should call gvdb_table_unref() on the return result when you no
|
* You should call gvdb_table_free() on the return result when you no
|
||||||
* longer require it.
|
* longer require it.
|
||||||
**/
|
**/
|
||||||
GvdbTable *
|
GvdbTable *
|
||||||
@ -722,14 +678,11 @@ gvdb_table_get_table (GvdbTable *file,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
new = g_slice_new0 (GvdbTable);
|
new = g_slice_new0 (GvdbTable);
|
||||||
new->user_data = file->ref_user_data ? file->ref_user_data (file->user_data) : file->user_data;
|
new->bytes = g_bytes_ref (file->bytes);
|
||||||
new->ref_user_data = file->ref_user_data;
|
|
||||||
new->unref_user_data = file->unref_user_data;
|
|
||||||
new->byteswapped = file->byteswapped;
|
new->byteswapped = file->byteswapped;
|
||||||
new->trusted = file->trusted;
|
new->trusted = file->trusted;
|
||||||
new->data = file->data;
|
new->data = file->data;
|
||||||
new->size = file->size;
|
new->size = file->size;
|
||||||
new->ref_count = 1;
|
|
||||||
|
|
||||||
gvdb_table_setup_root (new, &item->value.pointer);
|
gvdb_table_setup_root (new, &item->value.pointer);
|
||||||
|
|
||||||
@ -737,37 +690,16 @@ gvdb_table_get_table (GvdbTable *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gvdb_table_ref:
|
* gvdb_table_free:
|
||||||
* @file: a #GvdbTable
|
|
||||||
* @returns: a new reference on @file
|
|
||||||
*
|
|
||||||
* Increases the reference count on @file.
|
|
||||||
**/
|
|
||||||
GvdbTable *
|
|
||||||
gvdb_table_ref (GvdbTable *file)
|
|
||||||
{
|
|
||||||
g_atomic_int_inc (&file->ref_count);
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gvdb_table_unref:
|
|
||||||
* @file: a #GvdbTable
|
* @file: a #GvdbTable
|
||||||
*
|
*
|
||||||
* Decreases the reference count on @file, possibly freeing it.
|
* Frees @file.
|
||||||
*
|
|
||||||
* Since: 2.26
|
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gvdb_table_unref (GvdbTable *file)
|
gvdb_table_free (GvdbTable *file)
|
||||||
{
|
{
|
||||||
if (g_atomic_int_dec_and_test (&file->ref_count))
|
g_bytes_unref (file->bytes);
|
||||||
{
|
g_slice_free (GvdbTable, file);
|
||||||
if (file->unref_user_data)
|
|
||||||
file->unref_user_data (file->user_data);
|
|
||||||
g_slice_free (GvdbTable, file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,26 +26,18 @@
|
|||||||
|
|
||||||
typedef struct _GvdbTable GvdbTable;
|
typedef struct _GvdbTable GvdbTable;
|
||||||
|
|
||||||
typedef gpointer (*GvdbRefFunc) (gpointer data);
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GvdbTable * gvdb_table_new_from_bytes (GBytes *bytes,
|
||||||
|
gboolean trusted,
|
||||||
|
GError **error);
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
GvdbTable * gvdb_table_new (const gchar *filename,
|
GvdbTable * gvdb_table_new (const gchar *filename,
|
||||||
gboolean trusted,
|
gboolean trusted,
|
||||||
GError **error);
|
GError **error);
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
GvdbTable * gvdb_table_new_from_data (const void *data,
|
void gvdb_table_free (GvdbTable *table);
|
||||||
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);
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
gchar ** gvdb_table_get_names (GvdbTable *table,
|
gchar ** gvdb_table_get_names (GvdbTable *table,
|
||||||
gint *length);
|
gint *length);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user