Re: open an existing file in buffer and write on it



On Fri, Jan 25, 2013 at 9:00 AM, Rudra Banerjee <rudra banerjee aol co uk>wrote:

But this writes the data in unformatted form.
Can you kindly explain a bit more?


A good tool glib has for serializing data is GVariant:
http://developer.gnome.org/glib/stable/glib-GVariant.html
All the example below is untested, so if it blows up try and figure out
what I was thinking ;)

Say you have some data in a list:
struct my_data {
  gchar *name;
  gint32 id;
};
GList *datas = NULL;

struct my_data *data = g_new0(struct my_data, 1);
data->id = 1;
datas = g_list_append(datas, data);
struct my_data *data = g_new0(struct my_data, 1);
data->id = 2;
datas = g_list_append(datas, data);

Your goal with serialization is to save everything in the list to a file,
so you can read it back later. So in terms of what you want to create in
the GVariant, you want an array of tuples that contain a string and a
gint32.

gsize num_elements = g_list_length(datas);
GVariant **v_array = g_new(GVariant*, num_elements);
for (GList *iter = g_list_first(datas), gsize i = 0; iter != NULL; iter =
g_list_next(iter), ++i;) {
    struct my_data *this_data = (struct my_data*) iter->data;
    v_array[i] = g_variant_new("si", this_data->name, this_data->id);
}

GVariant *v = g_variant_new_array(g_variant_get_type(v_array[0]), v_array,
num_elements);
g_variant_ref_sink(v);

Okay, now we have a variant that contains all the data that was in your
list. You can get a nice buffer of "binary data" to write to file:
gsize size = g_variant_get_size(v);
gconstpointer buf = g_variant_get_data(v);
GError *error = NULL;
gboolean res = g_file_set_contents("filename.dat", buf, size, &error);
if (!res) {
  /* handle an error */
}
That's it! Your data is on disk. Be sure to free everything we allocated
above:
g_variant_unref(v);
g_free(v_array);


The next time your program starts, you're probably going to want to read
that data off the disk.
GList *datas = NULL;
gpointer buf;
gsize size;
GError *error = NULL;
gboolean res = g_file_get_contents("filename.dat", &buf, &size, &error);
if (res) {
  GVariant *v = g_variant_new_from_data("a(si)", buf, size, FALSE, g_free,
buf);
  g_variant_ref_sink(v);
  for (gsize i = 0; i < g_variant_n_children(v); ++i) {
    struct my_data *this_data = g_new0(struct my_data, 1);
    g_variant_get_child(v, i, "si", &this_data->name, &this_data->id);
    datas = g_list_append(datas, this_data);
  }
  g_variant_unref(v);
}

Now we're back where we started. I hope this is enough to help you get
started. You might also take a look at GFile and GFileOutputStream and
such. In general, read through all the glib documentation so you know
what's available to you.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]