return FALSE;
}
+typedef enum
+{
+ GstXmpTagTypeSimple = 0,
+ GstXmpTagTypeBag,
+ GstXmpTagTypeSeq,
+ GstXmpTagTypeStruct,
+
+ /* Not really a xmp type, this is a tag that in gst is represented with
+ * a single value and on xmp it needs 2 (or more) simple values
+ *
+ * e.g. GST_TAG_GEO_LOCATION_ELEVATION needs to be mapped into 2 complementary
+ * tags in the exif's schema. One of them stores the absolute elevation,
+ * and the other one stores if it is above of below sea level.
+ */
+ GstXmpTagTypeCompound
+} GstXmpTagType;
-#define GST_XMP_TAG_TYPE_SIMPLE 0
-#define GST_XMP_TAG_TYPE_BAG 1
-#define GST_XMP_TAG_TYPE_SEQ 2
struct _XmpTag
{
+ const gchar *gst_tag;
const gchar *tag_name;
- gint type;
+ GstXmpTagType type;
+
+ /* Used for struct and compound types */
+ GSList *children;
XmpSerializationFunc serialize;
XmpDeserializationFunc deserialize;
xmp_tag_get_merge_mode (XmpTag * xmptag)
{
switch (xmptag->type) {
- case GST_XMP_TAG_TYPE_BAG:
- case GST_XMP_TAG_TYPE_SEQ:
+ case GstXmpTagTypeBag:
+ case GstXmpTagTypeSeq:
return GST_TAG_MERGE_APPEND;
- case GST_XMP_TAG_TYPE_SIMPLE:
+ case GstXmpTagTypeSimple:
default:
return GST_TAG_MERGE_KEEP;
}
xmp_tag_get_type_name (XmpTag * xmptag)
{
switch (xmptag->type) {
- case GST_XMP_TAG_TYPE_SEQ:
+ case GstXmpTagTypeSeq:
return "rdf:Seq";
default:
g_assert_not_reached ();
- case GST_XMP_TAG_TYPE_BAG:
+ case GstXmpTagTypeBag:
return "rdf:Bag";
}
}
};
typedef struct _PendingXmpTag PendingXmpTag;
-
/*
* A schema is a mapping of strings (the tag name in gstreamer) to a list of
- * tags in xmp (XmpTag). We need a list because some tags are split into 2
- * when serialized into xmp.
- * e.g. GST_TAG_GEO_LOCATION_ELEVATION needs to be mapped into 2 complementary
- * tags in the exif's schema. One of them stores the absolute elevation,
- * and the other one stores if it is above of below sea level.
+ * tags in xmp (XmpTag).
*/
typedef GHashTable GstXmpSchema;
#define gst_xmp_schema_lookup g_hash_table_lookup
}
static void
-_gst_xmp_schema_add_mapping (GstXmpSchema * schema, const gchar * gst_tag,
- GPtrArray * array)
+_gst_xmp_schema_add_mapping (GstXmpSchema * schema, XmpTag * tag)
{
GQuark key;
- key = g_quark_from_string (gst_tag);
+ key = g_quark_from_string (tag->gst_tag);
if (gst_xmp_schema_lookup (schema, GUINT_TO_POINTER (key))) {
- GST_WARNING ("Tag %s already present for the schema", gst_tag);
+ GST_WARNING ("Tag %s already present for the schema", tag->gst_tag);
g_assert_not_reached ();
return;
}
- gst_xmp_schema_insert (schema, GUINT_TO_POINTER (key), array);
+ gst_xmp_schema_insert (schema, GUINT_TO_POINTER (key), tag);
}
-static void
-_gst_xmp_schema_add_simple_mapping (GstXmpSchema * schema,
- const gchar * gst_tag, const gchar * xmp_tag, gint xmp_type,
- XmpSerializationFunc serialization_func,
+static XmpTag *
+gst_xmp_tag_create (const gchar * gst_tag, const gchar * xmp_tag,
+ gint xmp_type, XmpSerializationFunc serialization_func,
XmpDeserializationFunc deserialization_func)
{
XmpTag *xmpinfo;
- GPtrArray *array;
xmpinfo = g_slice_new (XmpTag);
+ xmpinfo->gst_tag = gst_tag;
xmpinfo->tag_name = xmp_tag;
xmpinfo->type = xmp_type;
xmpinfo->serialize = serialization_func;
xmpinfo->deserialize = deserialization_func;
+ xmpinfo->children = NULL;
- array = g_ptr_array_sized_new (1);
- g_ptr_array_add (array, xmpinfo);
+ return xmpinfo;
+}
- _gst_xmp_schema_add_mapping (schema, gst_tag, array);
+static XmpTag *
+gst_xmp_tag_create_compound (const gchar * gst_tag, const gchar * xmp_tag_a,
+ const gchar * xmp_tag_b, XmpSerializationFunc serialization_func_a,
+ XmpSerializationFunc serialization_func_b,
+ XmpDeserializationFunc deserialization_func)
+{
+ XmpTag *xmptag;
+ XmpTag *xmptag_a =
+ gst_xmp_tag_create (gst_tag, xmp_tag_a, GstXmpTagTypeSimple,
+ serialization_func_a, deserialization_func);
+ XmpTag *xmptag_b =
+ gst_xmp_tag_create (gst_tag, xmp_tag_b, GstXmpTagTypeSimple,
+ serialization_func_b, deserialization_func);
+
+ xmptag =
+ gst_xmp_tag_create (gst_tag, NULL, GstXmpTagTypeCompound, NULL, NULL);
+
+ xmptag->children = g_slist_prepend (xmptag->children, xmptag_b);
+ xmptag->children = g_slist_prepend (xmptag->children, xmptag_a);
+
+ return xmptag;
+}
+
+static void
+_gst_xmp_schema_add_simple_mapping (GstXmpSchema * schema,
+ const gchar * gst_tag, const gchar * xmp_tag, gint xmp_type,
+ XmpSerializationFunc serialization_func,
+ XmpDeserializationFunc deserialization_func)
+{
+ _gst_xmp_schema_add_mapping (schema,
+ gst_xmp_tag_create (gst_tag, xmp_tag, xmp_type, serialization_func,
+ deserialization_func));
}
/*
GHashTableIter iter;
gpointer key, value;
const gchar *ret = NULL;
- gint index;
/* Iterate over the hashtable */
g_hash_table_iter_init (&iter, schema);
while (!ret && g_hash_table_iter_next (&iter, &key, &value)) {
- GPtrArray *array = (GPtrArray *) value;
-
- /* each mapping might contain complementary tags */
- for (index = 0; index < array->len; index++) {
- XmpTag *xmpinfo = (XmpTag *) g_ptr_array_index (array, index);
+ XmpTag *xmpinfo = (XmpTag *) value;
+ if (xmpinfo->tag_name) {
if (strcmp (xmpinfo->tag_name, xmp_tag) == 0) {
*_xmp_tag = xmpinfo;
ret = g_quark_to_string (GPOINTER_TO_UINT (key));
goto out;
}
+ } else if (xmpinfo->children) {
+ GSList *iter;
+ for (iter = xmpinfo->children; iter; iter = g_slist_next (iter)) {
+ XmpTag *child = iter->data;
+ if (strcmp (child->tag_name, xmp_tag) == 0) {
+ *_xmp_tag = child;
+ ret = g_quark_to_string (GPOINTER_TO_UINT (key));
+ goto out;
+ }
+ }
+ } else {
+ g_assert_not_reached ();
}
}
static gpointer
_init_xmp_tag_map (gpointer user_data)
{
- GPtrArray *array;
XmpTag *xmpinfo;
GstXmpSchema *schema;
*/
schema = gst_xmp_schema_new ();
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_ARTIST,
- "dc:creator", GST_XMP_TAG_TYPE_SEQ, NULL, NULL);
+ "dc:creator", GstXmpTagTypeSeq, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_COPYRIGHT,
- "dc:rights", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "dc:rights", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DATE, "dc:date",
- GST_XMP_TAG_TYPE_SEQ, NULL, NULL);
+ GstXmpTagTypeSeq, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DESCRIPTION,
- "dc:description", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "dc:description", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_KEYWORDS,
- "dc:subject", GST_XMP_TAG_TYPE_BAG, NULL, NULL);
+ "dc:subject", GstXmpTagTypeBag, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_TITLE, "dc:title",
- GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ GstXmpTagTypeSimple, NULL, NULL);
/* FIXME: we probably want GST_TAG_{,AUDIO_,VIDEO_}MIME_TYPE */
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_VIDEO_CODEC,
- "dc:format", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "dc:format", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_add_schema ("dc", schema);
/* xap (xmp) schema */
schema = gst_xmp_schema_new ();
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_USER_RATING,
- "xmp:Rating", GST_XMP_TAG_TYPE_SIMPLE, NULL, deserialize_xmp_rating);
+ "xmp:Rating", GstXmpTagTypeSimple, NULL, deserialize_xmp_rating);
_gst_xmp_add_schema ("xap", schema);
/* tiff */
schema = gst_xmp_schema_new ();
_gst_xmp_schema_add_simple_mapping (schema,
- GST_TAG_DEVICE_MANUFACTURER, "tiff:Make", GST_XMP_TAG_TYPE_SIMPLE, NULL,
+ GST_TAG_DEVICE_MANUFACTURER, "tiff:Make", GstXmpTagTypeSimple, NULL,
NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DEVICE_MODEL,
- "tiff:Model", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "tiff:Model", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_APPLICATION_NAME,
- "tiff:Software", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "tiff:Software", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_IMAGE_ORIENTATION,
- "tiff:Orientation", GST_XMP_TAG_TYPE_SIMPLE, serialize_tiff_orientation,
+ "tiff:Orientation", GstXmpTagTypeSimple, serialize_tiff_orientation,
deserialize_tiff_orientation);
_gst_xmp_add_schema ("tiff", schema);
/* exif schema */
schema = gst_xmp_schema_new ();
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DATE_TIME,
- "exif:DateTimeOriginal", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "exif:DateTimeOriginal", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema,
GST_TAG_GEO_LOCATION_LATITUDE, "exif:GPSLatitude",
- GST_XMP_TAG_TYPE_SIMPLE, serialize_exif_latitude,
- deserialize_exif_latitude);
+ GstXmpTagTypeSimple, serialize_exif_latitude, deserialize_exif_latitude);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_LONGITUDE,
- "exif:GPSLongitude", GST_XMP_TAG_TYPE_SIMPLE, serialize_exif_longitude,
+ "exif:GPSLongitude", GstXmpTagTypeSimple, serialize_exif_longitude,
deserialize_exif_longitude);
_gst_xmp_schema_add_simple_mapping (schema,
GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, "exif:ExposureBiasValue",
- GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ GstXmpTagTypeSimple, NULL, NULL);
/* compound exif tags */
- array = g_ptr_array_sized_new (2);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSAltitude";
- xmpinfo->serialize = serialize_exif_altitude;
- xmpinfo->deserialize = deserialize_exif_altitude;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSAltitudeRef";
- xmpinfo->serialize = serialize_exif_altituderef;
- xmpinfo->deserialize = deserialize_exif_altitude;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- _gst_xmp_schema_add_mapping (schema, GST_TAG_GEO_LOCATION_ELEVATION, array);
-
- array = g_ptr_array_sized_new (2);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSSpeed";
- xmpinfo->serialize = serialize_exif_gps_speed;
- xmpinfo->deserialize = deserialize_exif_gps_speed;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSSpeedRef";
- xmpinfo->serialize = serialize_exif_gps_speedref;
- xmpinfo->deserialize = deserialize_exif_gps_speed;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- _gst_xmp_schema_add_mapping (schema,
- GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, array);
-
- array = g_ptr_array_sized_new (2);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSTrack";
- xmpinfo->serialize = serialize_exif_gps_direction;
- xmpinfo->deserialize = deserialize_exif_gps_track;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSTrackRef";
- xmpinfo->serialize = serialize_exif_gps_directionref;
- xmpinfo->deserialize = deserialize_exif_gps_track;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- _gst_xmp_schema_add_mapping (schema,
- GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, array);
+ xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_ELEVATION,
+ "exif:GPSAltitude", "exif:GPSAltitudeRef", serialize_exif_altitude,
+ serialize_exif_altituderef, deserialize_exif_altitude);
+ _gst_xmp_schema_add_mapping (schema, xmpinfo);
+
+ xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED,
+ "exif:GPSSpeed", "exif:GPSSpeedRef", serialize_exif_gps_speed,
+ serialize_exif_gps_speedref, deserialize_exif_gps_speed);
+ _gst_xmp_schema_add_mapping (schema, xmpinfo);
+
+ xmpinfo =
+ gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION,
+ "exif:GPSTrack", "exif:GPSTrackRef", serialize_exif_gps_direction,
+ serialize_exif_gps_directionref, deserialize_exif_gps_track);
+ _gst_xmp_schema_add_mapping (schema, xmpinfo);
+
+ xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION,
+ "exif:GPSImgDirection", "exif:GPSImgDirectionRef",
+ serialize_exif_gps_direction, serialize_exif_gps_directionref,
+ deserialize_exif_gps_img_direction);
+ _gst_xmp_schema_add_mapping (schema, xmpinfo);
- array = g_ptr_array_sized_new (2);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSImgDirection";
- xmpinfo->serialize = serialize_exif_gps_direction;
- xmpinfo->deserialize = deserialize_exif_gps_img_direction;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- xmpinfo = g_slice_new (XmpTag);
- xmpinfo->tag_name = "exif:GPSImgDirectionRef";
- xmpinfo->serialize = serialize_exif_gps_directionref;
- xmpinfo->deserialize = deserialize_exif_gps_img_direction;
- xmpinfo->type = GST_XMP_TAG_TYPE_SIMPLE;
- g_ptr_array_add (array, xmpinfo);
- _gst_xmp_schema_add_mapping (schema,
- GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, array);
_gst_xmp_add_schema ("exif", schema);
/* photoshop schema */
schema = gst_xmp_schema_new ();
_gst_xmp_schema_add_simple_mapping (schema,
GST_TAG_GEO_LOCATION_COUNTRY, "photoshop:Country",
- GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_CITY,
- "photoshop:City", GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ "photoshop:City", GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_add_schema ("photoshop", schema);
/* iptc4xmpcore schema */
schema = gst_xmp_schema_new ();
_gst_xmp_schema_add_simple_mapping (schema,
GST_TAG_GEO_LOCATION_SUBLOCATION, "Iptc4xmpCore:Location",
- GST_XMP_TAG_TYPE_SIMPLE, NULL, NULL);
+ GstXmpTagTypeSimple, NULL, NULL);
_gst_xmp_add_schema ("Iptc4xmpCore", schema);
return NULL;
}
static void
-write_one_tag (const GstTagList * list, const gchar * tag,
- GPtrArray * xmp_tag_array, gpointer user_data)
+write_one_tag (const GstTagList * list, XmpTag * xmp_tag, gpointer user_data)
{
- guint i = 0, ct = gst_tag_list_get_tag_size (list, tag), tag_index;
+ guint i = 0, ct;
XmpSerializationData *serialization_data = user_data;
GString *data = serialization_data->data;
char *s;
- for (tag_index = 0; tag_index < xmp_tag_array->len; tag_index++) {
- XmpTag *xmp_tag;
+ /* struct type handled differently */
+ if (xmp_tag->type == GstXmpTagTypeStruct ||
+ xmp_tag->type == GstXmpTagTypeCompound) {
+ GSList *iter;
+ gboolean use_it = FALSE;
+
+ /* check if any of the inner tags are present on the taglist */
+ for (iter = xmp_tag->children; iter && !use_it; iter = g_slist_next (iter)) {
+ XmpTag *child_tag = iter->data;
- xmp_tag = g_ptr_array_index (xmp_tag_array, tag_index);
- string_open_tag (data, xmp_tag->tag_name);
+ if (gst_tag_list_get_value_index (list, child_tag->gst_tag, 0) != NULL) {
+ use_it = TRUE;
+ break;
+ }
+ }
- /* fast path for single valued tag */
- if (ct == 1 || xmp_tag->type == GST_XMP_TAG_TYPE_SIMPLE) {
+ if (use_it) {
+ if (xmp_tag->tag_name)
+ string_open_tag (data, xmp_tag->tag_name);
+ /* now write it */
+ for (iter = xmp_tag->children; iter; iter = g_slist_next (iter)) {
+ write_one_tag (list, iter->data, user_data);
+ }
+ if (xmp_tag->tag_name)
+ string_close_tag (data, xmp_tag->tag_name);
+ }
+ return;
+ }
+
+ /* at this point we must have a gst_tag */
+ g_assert (xmp_tag->gst_tag);
+ if (gst_tag_list_get_value_index (list, xmp_tag->gst_tag, 0) == NULL)
+ return;
+
+ ct = gst_tag_list_get_tag_size (list, xmp_tag->gst_tag);
+ string_open_tag (data, xmp_tag->tag_name);
+
+ /* fast path for single valued tag */
+ if (ct == 1 || xmp_tag->type == GstXmpTagTypeSimple) {
+ if (xmp_tag->serialize) {
+ s = xmp_tag->serialize (gst_tag_list_get_value_index (list,
+ xmp_tag->gst_tag, 0));
+ } else {
+ s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list,
+ xmp_tag->gst_tag, 0));
+ }
+ if (s) {
+ g_string_append (data, s);
+ g_free (s);
+ } else {
+ GST_WARNING ("unhandled type for %s to xmp", xmp_tag->gst_tag);
+ }
+ } else {
+ const gchar *typename;
+
+ typename = xmp_tag_get_type_name (xmp_tag);
+
+ string_open_tag (data, typename);
+ for (i = 0; i < ct; i++) {
+ GST_DEBUG ("mapping %s[%u/%u] to xmp", xmp_tag->gst_tag, i, ct);
if (xmp_tag->serialize) {
- s = xmp_tag->serialize (gst_tag_list_get_value_index (list, tag, 0));
+ s = xmp_tag->serialize (gst_tag_list_get_value_index (list,
+ xmp_tag->gst_tag, i));
} else {
- s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, tag,
- 0));
+ s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list,
+ xmp_tag->gst_tag, i));
}
if (s) {
+ string_open_tag (data, "rdf:li");
g_string_append (data, s);
+ string_close_tag (data, "rdf:li");
g_free (s);
} else {
- GST_WARNING ("unhandled type for %s to xmp", tag);
- }
- } else {
- const gchar *typename;
-
- typename = xmp_tag_get_type_name (xmp_tag);
-
- string_open_tag (data, typename);
- for (i = 0; i < ct; i++) {
- GST_DEBUG ("mapping %s[%u/%u] to xmp", tag, i, ct);
- if (xmp_tag->serialize) {
- s = xmp_tag->serialize (gst_tag_list_get_value_index (list, tag, i));
- } else {
- s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list, tag,
- i));
- }
- if (s) {
- string_open_tag (data, "rdf:li");
- g_string_append (data, s);
- string_close_tag (data, "rdf:li");
- g_free (s);
- } else {
- GST_WARNING ("unhandled type for %s to xmp", tag);
- }
+ GST_WARNING ("unhandled type for %s to xmp", xmp_tag->gst_tag);
}
- string_close_tag (data, typename);
}
-
- string_close_tag (data, xmp_tag->tag_name);
+ string_close_tag (data, typename);
}
+
+ string_close_tag (data, xmp_tag->tag_name);
}
/**
/* use all schemas */
schemas = gst_tag_xmp_list_schemas ();
}
- i = 0;
for (i = 0; schemas[i] != NULL; i++) {
GstXmpSchema *schema = _gst_xmp_get_schema (schemas[i]);
GHashTableIter iter;
/* Iterate over the hashtable */
g_hash_table_iter_init (&iter, schema);
while (g_hash_table_iter_next (&iter, &key, &value)) {
- const gchar *tag = g_quark_to_string (GPOINTER_TO_UINT (key));
-
- if (gst_tag_list_get_value_index (list, tag, 0) != NULL) {
- write_one_tag (list, tag, value, (gpointer) & serialization_data);
- }
-
+ write_one_tag (list, value, (gpointer) & serialization_data);
}
}