GBytes * gvdb_table_get_content (GHashTable *table, gboolean byteswap) { struct gvdb_pointer root; FileBuilder *fb; GString *str; GBytes *res; fb = file_builder_new (byteswap); file_builder_add_hash (fb, table, &root); str = file_builder_serialise (fb, root); res = g_bytes_new_take (str->str, str->len); g_string_free (str, FALSE); return res; }
gboolean gvdb_table_write_contents (GHashTable *table, const gchar *filename, gboolean byteswap, GError **error) { struct gvdb_pointer root; gboolean status; FileBuilder *fb; GString *str; fb = file_builder_new (byteswap); file_builder_add_hash (fb, table, &root); str = file_builder_serialise (fb, root); status = g_file_set_contents (filename, str->str, str->len, error); g_string_free (str, TRUE); return status; }
static void file_builder_add_hash (FileBuilder *fb, GHashTable *table, struct gvdb_pointer *pointer) { guint32_le *buckets, *bloom_filter; struct gvdb_hash_item *items; HashTable *mytable; GvdbItem *item; guint32 index; gint bucket; mytable = hash_table_new (g_hash_table_size (table)); g_hash_table_foreach (table, hash_table_insert, mytable); index = 0; for (bucket = 0; bucket < mytable->n_buckets; bucket++) for (item = mytable->buckets[bucket]; item; item = item->next) item->assigned_index = guint32_to_le (index++); file_builder_allocate_for_hash (fb, mytable->n_buckets, index, 5, 0, &bloom_filter, &buckets, &items, pointer); index = 0; for (bucket = 0; bucket < mytable->n_buckets; bucket++) { buckets[bucket] = guint32_to_le (index); for (item = mytable->buckets[bucket]; item; item = item->next) { struct gvdb_hash_item *entry = items++; const gchar *basename; g_assert (index == guint32_from_le (item->assigned_index)); entry->hash_value = guint32_to_le (item->hash_value); entry->parent = item_to_index (item->parent); entry->unused = 0; if (item->parent != NULL) basename = item->key + strlen (item->parent->key); else basename = item->key; file_builder_add_string (fb, basename, &entry->key_start, &entry->key_size); if (item->value != NULL) { g_assert (item->child == NULL && item->table == NULL); file_builder_add_value (fb, item->value, &entry->value.pointer); entry->type = 'v'; } if (item->child != NULL) { guint32 children = 0, i = 0; guint32_le *offsets; GvdbItem *child; g_assert (item->table == NULL); for (child = item->child; child; child = child->sibling) children++; offsets = file_builder_allocate (fb, 4, 4 * children, &entry->value.pointer); entry->type = 'L'; for (child = item->child; child; child = child->sibling) offsets[i++] = child->assigned_index; g_assert (children == i); } if (item->table != NULL) { entry->type = 'H'; file_builder_add_hash (fb, item->table, &entry->value.pointer); } index++; } } hash_table_free (mytable); }