[gupnp-dlna] Add native sets implementation
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp-dlna] Add native sets implementation
- Date: Fri, 30 Nov 2012 23:34:54 +0000 (UTC)
commit eace62f28b1d14b17eac0d3f8ad36238089caca5
Author: Krzesimir Nowak <krnowak openismus com>
Date: Thu Nov 15 15:01:14 2012 +0100
Add native sets implementation
Tailored for GUPnP-DLNA needs. It will replace the use of GstCaps.
Called "native" because of lack of better name.
.../native/sets/gupnp-dlna-native-info-set.c | 282 ++++++++
.../native/sets/gupnp-dlna-native-info-set.h | 93 +++
.../native/sets/gupnp-dlna-native-info-value.c | 180 +++++
.../native/sets/gupnp-dlna-native-info-value.h | 67 ++
.../native/sets/gupnp-dlna-native-restriction.c | 261 ++++++++
.../native/sets/gupnp-dlna-native-restriction.h | 77 +++
.../native/sets/gupnp-dlna-native-sets-private.h | 139 ++++
.../native/sets/gupnp-dlna-native-value-list.c | 337 ++++++++++
.../native/sets/gupnp-dlna-native-value-list.h | 50 ++
.../native/sets/gupnp-dlna-native-value-type.c | 686 ++++++++++++++++++++
.../native/sets/gupnp-dlna-native-value-type.h | 45 ++
.../native/sets/gupnp-dlna-native-value.c | 393 +++++++++++
.../native/sets/gupnp-dlna-native-value.h | 70 ++
libgupnp-dlna/profile-backends/native/sets/sets.am | 14 +
14 files changed, 2694 insertions(+), 0 deletions(-)
---
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-set.c b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-set.c
new file mode 100644
index 0000000..c7b2bfd
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-set.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+
+#include "gupnp-dlna-native-info-set.h"
+#include "gupnp-dlna-native-info-value.h"
+#include "gupnp-dlna-native-sets-private.h"
+
+struct _GUPnPDLNANativeInfoSet {
+ gchar *mime;
+ GHashTable *entries; /* <gchar *, GUPnPDLNANativeInfoValue *> */
+};
+
+GUPnPDLNANativeInfoSet *
+gupnp_dlna_native_info_set_new (const gchar *mime)
+{
+ GUPnPDLNANativeInfoSet *info_set;
+
+ g_return_val_if_fail (mime != NULL, NULL);
+
+ info_set = g_slice_new (GUPnPDLNANativeInfoSet);
+ info_set->mime = g_strdup (mime);
+ info_set->entries = g_hash_table_new_full
+ (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify) gupnp_dlna_native_info_value_free);
+
+ return info_set;
+}
+
+void
+gupnp_dlna_native_info_set_free (GUPnPDLNANativeInfoSet *info_set)
+{
+ if (info_set == NULL)
+ return;
+ g_free (info_set->mime);
+ g_hash_table_unref (info_set->entries);
+ g_slice_free (GUPnPDLNANativeInfoSet, info_set);
+}
+
+static gboolean
+insert_value (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ GUPnPDLNANativeInfoValue *value)
+{
+ if (value == NULL) {
+ g_debug ("Info set: value '%s' is NULL.", name);
+
+ return FALSE;
+ }
+
+ if (g_hash_table_contains (info_set->entries, name)) {
+ g_debug ("Info set: value '%s' already exists.", name);
+ gupnp_dlna_native_info_value_free (value);
+
+ return FALSE;
+ }
+ g_hash_table_insert (info_set->entries, g_strdup (name), value);
+
+ return TRUE;
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_bool (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ gboolean value)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_bool (value));
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_bool
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value
+ (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_unsupported_bool ());
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_fraction (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ gint numerator,
+ gint denominator)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_fraction
+ (numerator,
+ denominator));
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_fraction
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value
+ (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_unsupported_fraction ());
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_int (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ gint value)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_int (value));
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_int
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value
+ (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_unsupported_int ());
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_string (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ const gchar *value)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ return insert_value (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_string (value));
+}
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_string
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name)
+{
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ return insert_value
+ (info_set,
+ name,
+ gupnp_dlna_native_info_value_new_unsupported_string ());
+}
+
+gboolean
+gupnp_dlna_native_info_set_fits_restriction
+ (GUPnPDLNANativeInfoSet *info_set,
+ GUPnPDLNANativeRestriction *restriction)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+ gboolean unsupported_match;
+
+ g_return_val_if_fail (info_set != NULL, FALSE);
+ g_return_val_if_fail (restriction != NULL, FALSE);
+
+ if (g_strcmp0 (info_set->mime,
+ gupnp_dlna_native_restriction_get_mime (restriction)))
+ return FALSE;
+
+ unsupported_match = FALSE;
+ g_hash_table_iter_init (&iter,
+ gupnp_dlna_native_restriction_get_entries
+ (restriction));
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GUPnPDLNANativeInfoValue *info_value;
+ GUPnPDLNANativeValueList *value_list;
+ gboolean unsupported;
+
+ if (!g_hash_table_lookup_extended (info_set->entries,
+ key,
+ NULL,
+ (gpointer *) &info_value))
+ return FALSE;
+ value_list = (GUPnPDLNANativeValueList *) value;
+ if (!gupnp_dlna_native_value_list_is_superset (value_list,
+ info_value,
+ &unsupported))
+ return FALSE;
+ else if (unsupported)
+ unsupported_match = TRUE;
+ }
+
+ if (unsupported_match)
+ g_warning ("Info set matched restriction, but it has an "
+ "unsupported value.");
+
+ return TRUE;
+}
+
+static gboolean
+gupnp_dlna_native_info_set_is_empty (GUPnPDLNANativeInfoSet *info_set)
+{
+ g_return_val_if_fail (info_set != NULL, TRUE);
+
+ return (info_set->mime == NULL &&
+ g_hash_table_size (info_set->entries) == 0);
+}
+
+gchar *
+gupnp_dlna_native_info_set_to_string (GUPnPDLNANativeInfoSet *info_set)
+{
+ GString *str;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ g_return_val_if_fail (info_set != NULL, NULL);
+
+ if (gupnp_dlna_native_info_set_is_empty (info_set))
+ return g_strdup ("EMPTY");
+
+ str = g_string_new (info_set->mime ? info_set->mime : "(null)");
+ g_hash_table_iter_init (&iter, info_set->entries);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ gchar *raw = gupnp_dlna_native_info_value_to_string (value);
+
+ g_string_append_printf (str, ", %s=%s", (gchar *) key, raw);
+ g_free (raw);
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+const gchar *
+gupnp_dlna_native_info_set_get_mime (GUPnPDLNANativeInfoSet *info_set)
+{
+ g_return_val_if_fail (info_set != NULL, NULL);
+
+ return info_set->mime;
+}
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-set.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-set.h
new file mode 100644
index 0000000..5b87ce6
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-set.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_INFO_SET_H__
+#define __GUPNP_DLNA_NATIVE_INFO_SET_H__
+
+#include <glib.h>
+
+#include "gupnp-dlna-native-restriction.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GUPnPDLNANativeInfoSet GUPnPDLNANativeInfoSet;
+
+GUPnPDLNANativeInfoSet *
+gupnp_dlna_native_info_set_new (const gchar *mime);
+
+void
+gupnp_dlna_native_info_set_free (GUPnPDLNANativeInfoSet *info_set);
+
+gboolean
+gupnp_dlna_native_info_set_add_bool (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ gboolean value);
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_bool
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name);
+
+gboolean
+gupnp_dlna_native_info_set_add_fraction (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ gint numerator,
+ gint denominator);
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_fraction
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name);
+
+gboolean
+gupnp_dlna_native_info_set_add_int (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ gint value);
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_int
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name);
+
+gboolean
+gupnp_dlna_native_info_set_add_string (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name,
+ const gchar *value);
+
+gboolean
+gupnp_dlna_native_info_set_add_unsupported_string
+ (GUPnPDLNANativeInfoSet *info_set,
+ const gchar *name);
+
+gboolean
+gupnp_dlna_native_info_set_fits_restriction
+ (GUPnPDLNANativeInfoSet *info_set,
+ GUPnPDLNANativeRestriction *restriction);
+
+gchar *
+gupnp_dlna_native_info_set_to_string (GUPnPDLNANativeInfoSet *info_set);
+
+const gchar *
+gupnp_dlna_native_info_set_get_mime (GUPnPDLNANativeInfoSet *info_set);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_INFO_SET_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-value.c b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-value.c
new file mode 100644
index 0000000..93f6611
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-value.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h> /* for memset */
+#include "gupnp-dlna-native-info-value.h"
+#include "gupnp-dlna-native-value-type.h"
+#include "gupnp-dlna-native-sets-private.h"
+
+/* private */
+struct _GUPnPDLNANativeInfoValue {
+ GUPnPDLNANativeValueType *type;
+ GUPnPDLNANativeValueUnion value;
+ gboolean unsupported;
+};
+
+static GUPnPDLNANativeInfoValue *
+value_new (GUPnPDLNANativeValueType *type,
+ gchar *raw)
+{
+ GUPnPDLNANativeInfoValue *info_value =
+ g_slice_new (GUPnPDLNANativeInfoValue);
+
+ info_value->type = type;
+ if (!gupnp_dlna_native_value_type_init (type,
+ &info_value->value,
+ raw)) {
+ g_slice_free (GUPnPDLNANativeInfoValue, info_value);
+ info_value = NULL;
+ }
+ g_free (raw);
+ info_value->unsupported = FALSE;
+
+ return info_value;
+}
+
+static GUPnPDLNANativeInfoValue *
+value_unsupported (GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeInfoValue *info_value =
+ g_slice_new (GUPnPDLNANativeInfoValue);
+
+ info_value->type = type;
+ memset (&info_value->value, 0, sizeof (GUPnPDLNANativeValueUnion));
+ info_value->unsupported = TRUE;
+
+ return info_value;
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_bool (gboolean value)
+{
+ return value_new (gupnp_dlna_native_value_type_bool (),
+ g_strdup (value ? "true" : "false"));
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_bool (void)
+{
+ return value_unsupported (gupnp_dlna_native_value_type_bool ());
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_fraction (gint numerator,
+ gint denominator)
+{
+ return value_new (gupnp_dlna_native_value_type_fraction (),
+ g_strdup_printf ("%d/%d",
+ numerator,
+ denominator));
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_fraction (void)
+{
+ return value_unsupported (gupnp_dlna_native_value_type_fraction ());
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_int (gint value)
+{
+ return value_new (gupnp_dlna_native_value_type_int (),
+ g_strdup_printf ("%d", value));
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_int (void)
+{
+ return value_unsupported (gupnp_dlna_native_value_type_int ());
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_string (const gchar *value)
+{
+ return value_new (gupnp_dlna_native_value_type_string (),
+ g_strdup (value));
+}
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_string (void)
+{
+ return value_unsupported (gupnp_dlna_native_value_type_string ());
+}
+
+void
+gupnp_dlna_native_info_value_free (GUPnPDLNANativeInfoValue *info_value)
+{
+ if (info_value == NULL)
+ return;
+
+ if (!info_value->unsupported)
+ gupnp_dlna_native_value_type_clean (info_value->type,
+ &info_value->value);
+ g_slice_free (GUPnPDLNANativeInfoValue, info_value);
+}
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_info_value_get_type (GUPnPDLNANativeInfoValue *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->type;
+}
+
+GUPnPDLNANativeValueUnion *
+gupnp_dlna_native_info_value_get_value (GUPnPDLNANativeInfoValue *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ if (info->unsupported)
+ return NULL;
+ else
+ return &info->value;
+}
+
+gchar *
+gupnp_dlna_native_info_value_to_string (GUPnPDLNANativeInfoValue *info)
+{
+ const gchar *type;
+ gchar *raw;
+ gchar *str;
+
+ g_return_val_if_fail (info != NULL, NULL);
+
+ type = gupnp_dlna_native_value_type_name (info->type);
+ if (info->unsupported)
+ raw = g_strdup ("<UNSUPPORTED>");
+ else
+ raw = gupnp_dlna_native_value_type_to_string (info->type,
+ &info->value);
+ str = g_strdup_printf ("(%s)%s", type, raw);
+ g_free (raw);
+
+ return str;
+}
+
+gboolean
+gupnp_dlna_native_info_value_is_unsupported (GUPnPDLNANativeInfoValue *info)
+{
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ return info->unsupported;
+}
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-value.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-value.h
new file mode 100644
index 0000000..68b897a
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-info-value.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_INFO_VALUE_H__
+#define __GUPNP_DLNA_NATIVE_INFO_VALUE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GUPnPDLNANativeInfoValue GUPnPDLNANativeInfoValue;
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_bool (gboolean value);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_bool (void);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_fraction (gint numerator,
+ gint denominator);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_fraction (void);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_int (gint value);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_int (void);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_string (const gchar *value);
+
+GUPnPDLNANativeInfoValue *
+gupnp_dlna_native_info_value_new_unsupported_string (void);
+
+void
+gupnp_dlna_native_info_value_free (GUPnPDLNANativeInfoValue *info_value);
+
+gchar *
+gupnp_dlna_native_info_value_to_string (GUPnPDLNANativeInfoValue *info_value);
+
+gboolean
+gupnp_dlna_native_info_value_is_unsupported (GUPnPDLNANativeInfoValue *info);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_INFO_VALUE_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-restriction.c b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-restriction.c
new file mode 100644
index 0000000..a565b3d
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-restriction.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+
+#include "gupnp-dlna-native-restriction.h"
+#include "gupnp-dlna-native-value-list.h"
+#include "gupnp-dlna-native-sets-private.h"
+
+struct _GUPnPDLNANativeRestriction {
+ gchar *mime;
+ GHashTable *entries; /* <gchar *, GUPnPDLNANativeValueList *> */
+};
+
+GUPnPDLNANativeRestriction *
+gupnp_dlna_native_restriction_new (const gchar *mime)
+{
+ GUPnPDLNANativeRestriction *restriction =
+ g_slice_new (GUPnPDLNANativeRestriction);
+
+ restriction->mime = g_strdup (mime);
+ restriction->entries = g_hash_table_new_full
+ (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify) gupnp_dlna_native_value_list_free);
+
+ return restriction;
+}
+
+GUPnPDLNANativeRestriction *
+gupnp_dlna_native_restriction_copy (GUPnPDLNANativeRestriction *restriction)
+{
+ GUPnPDLNANativeRestriction *dup;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ g_return_val_if_fail (restriction != NULL, NULL);
+
+ dup = gupnp_dlna_native_restriction_new (restriction->mime);
+ g_hash_table_iter_init (&iter, restriction->entries);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GUPnPDLNANativeValueList * dup_entry;
+
+ if (key == NULL || value == NULL)
+ continue;
+ dup_entry = gupnp_dlna_native_value_list_copy (value);
+
+ if (dup_entry == NULL)
+ continue;
+ g_hash_table_insert (dup->entries, g_strdup (key), dup_entry);
+ }
+
+ return dup;
+}
+
+void
+gupnp_dlna_native_restriction_free (GUPnPDLNANativeRestriction *restriction)
+{
+ if (restriction == NULL)
+ return;
+ g_free (restriction->mime);
+ g_hash_table_unref (restriction->entries);
+ g_slice_free (GUPnPDLNANativeRestriction, restriction);
+}
+
+gboolean
+gupnp_dlna_native_restriction_add_value_list
+ (GUPnPDLNANativeRestriction *restriction,
+ const gchar *name,
+ GUPnPDLNANativeValueList *list)
+{
+ g_return_val_if_fail (restriction != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (list != NULL, FALSE);
+
+ if (gupnp_dlna_native_value_list_is_empty (list))
+ return FALSE;
+ if (g_hash_table_contains (restriction->entries, name))
+ return FALSE;
+ gupnp_dlna_native_value_list_sort_items (list);
+ g_hash_table_insert (restriction->entries, g_strdup (name), list);
+
+ return TRUE;
+}
+
+static gboolean
+check_merge_possibility (GUPnPDLNANativeRestriction *restriction,
+ GUPnPDLNANativeRestriction *merged)
+{
+ GHashTableIter iter;
+ gpointer mrg_name_ptr;
+ gpointer mrg_value_list_ptr;
+
+ g_hash_table_iter_init (&iter, merged->entries);
+ while (g_hash_table_iter_next (&iter,
+ &mrg_name_ptr,
+ &mrg_value_list_ptr)) {
+ gpointer value_list_ptr;
+
+ if (g_hash_table_lookup_extended (restriction->entries,
+ mrg_name_ptr,
+ NULL,
+ &value_list_ptr)) {
+ GUPnPDLNANativeValueList *value_list =
+ (GUPnPDLNANativeValueList *) value_list_ptr;
+ GUPnPDLNANativeValueList *mrg_value_list =
+ (GUPnPDLNANativeValueList *) mrg_value_list_ptr;
+
+ if (!gupnp_dlna_native_value_list_mergeable
+ (value_list,
+ mrg_value_list))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+gupnp_dlna_native_restriction_merge
+ (GUPnPDLNANativeRestriction *restriction,
+ GUPnPDLNANativeRestriction *merged,
+ GUPnPDLNANativeRestrictionMergeResolution resolution)
+{
+ GHashTableIter iter;
+ gpointer mrg_name_ptr;
+ gpointer mrg_value_list_ptr;
+ gboolean change_mime;
+
+ g_return_val_if_fail (restriction != NULL, FALSE);
+ g_return_val_if_fail (merged != NULL, FALSE);
+
+ switch (resolution) {
+ case GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_FROM_TARGET:
+ change_mime = (restriction->mime == NULL);
+
+ break;
+ case GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_FROM_SOURCE:
+ change_mime = (merged->mime != NULL);
+
+ break;
+ case GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_NONE:
+ change_mime = (restriction->mime == NULL &&
+ merged->mime != NULL);
+
+ break;
+ default:
+ change_mime = FALSE;
+ g_critical ("Unknown conflict resolution: %d", resolution);
+ }
+ if (change_mime) {
+ g_free (restriction->mime);
+ restriction->mime = merged->mime;
+ merged->mime = NULL;
+ }
+
+ if (resolution == GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_NONE &&
+ !check_merge_possibility (restriction, merged))
+ return FALSE;
+
+ g_hash_table_iter_init (&iter, merged->entries);
+ while (g_hash_table_iter_next (&iter,
+ &mrg_name_ptr,
+ &mrg_value_list_ptr)) {
+ gpointer value_list_ptr;
+
+ if (g_hash_table_lookup_extended (restriction->entries,
+ mrg_name_ptr,
+ NULL,
+ &value_list_ptr)) {
+ GUPnPDLNANativeValueList *value_list =
+ (GUPnPDLNANativeValueList *) value_list_ptr;
+ GUPnPDLNANativeValueList *mrg_value_list =
+ (GUPnPDLNANativeValueList *) mrg_value_list_ptr;
+
+ gupnp_dlna_native_value_list_merge (value_list,
+ mrg_value_list,
+ resolution);
+ } else {
+ g_hash_table_iter_steal (&iter);
+ g_hash_table_insert (restriction->entries,
+ mrg_name_ptr,
+ mrg_value_list_ptr);
+ }
+ }
+ gupnp_dlna_native_restriction_free (merged);
+
+ return TRUE;
+}
+
+gboolean
+gupnp_dlna_native_restriction_is_empty (GUPnPDLNANativeRestriction *restriction)
+{
+ g_return_val_if_fail (restriction != NULL, TRUE);
+
+ return (restriction->mime == NULL &&
+ g_hash_table_size (restriction->entries) == 0);
+}
+
+gchar *
+gupnp_dlna_native_restriction_to_string
+ (GUPnPDLNANativeRestriction *restriction)
+{
+ GString *str;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ g_return_val_if_fail (restriction != NULL, NULL);
+
+ if (gupnp_dlna_native_restriction_is_empty (restriction))
+ return g_strdup ("EMPTY");
+
+ str = g_string_new (restriction->mime ? restriction->mime : "(null)");
+ g_hash_table_iter_init (&iter, restriction->entries);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ gchar *raw = gupnp_dlna_native_value_list_to_string (value);
+
+ g_string_append_printf (str, ", %s=%s", (gchar *) key, raw);
+ g_free (raw);
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+const gchar *
+gupnp_dlna_native_restriction_get_mime (GUPnPDLNANativeRestriction *restriction)
+{
+ g_return_val_if_fail (restriction != NULL, NULL);
+
+ return restriction->mime;
+}
+
+GHashTable *
+gupnp_dlna_native_restriction_get_entries
+ (GUPnPDLNANativeRestriction *restriction)
+{
+ g_return_val_if_fail (restriction != NULL, NULL);
+
+ return restriction->entries;
+}
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-restriction.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-restriction.h
new file mode 100644
index 0000000..63bdeca
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-restriction.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_RESTRICTION_H__
+#define __GUPNP_DLNA_NATIVE_RESTRICTION_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include "gupnp-dlna-native-value-list.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+ GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_FROM_TARGET,
+ GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_FROM_SOURCE,
+ GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_NONE
+} GUPnPDLNANativeRestrictionMergeResolution;
+
+typedef struct _GUPnPDLNANativeRestriction GUPnPDLNANativeRestriction;
+
+#define GUPNP_DLNA_NATIVE_RESTRICTION(x) \
+ ((GUPnPDLNANativeRestriction *) x)
+
+GUPnPDLNANativeRestriction *
+gupnp_dlna_native_restriction_new (const gchar *mime);
+
+GUPnPDLNANativeRestriction *
+gupnp_dlna_native_restriction_copy (GUPnPDLNANativeRestriction *restriction);
+
+void
+gupnp_dlna_native_restriction_free (GUPnPDLNANativeRestriction *restriction);
+
+gboolean
+gupnp_dlna_native_restriction_add_value_list
+ (GUPnPDLNANativeRestriction *restriction,
+ const gchar *name,
+ GUPnPDLNANativeValueList *list);
+
+gboolean
+gupnp_dlna_native_restriction_merge
+ (GUPnPDLNANativeRestriction *restriction,
+ GUPnPDLNANativeRestriction *merged,
+ GUPnPDLNANativeRestrictionMergeResolution override);
+
+gboolean
+gupnp_dlna_native_restriction_is_empty
+ (GUPnPDLNANativeRestriction *restriction);
+
+gchar *
+gupnp_dlna_native_restriction_to_string
+ (GUPnPDLNANativeRestriction *restriction);
+
+const gchar *
+gupnp_dlna_native_restriction_get_mime
+ (GUPnPDLNANativeRestriction *restriction);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_RESTRICTION_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-sets-private.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-sets-private.h
new file mode 100644
index 0000000..f45f9bd
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-sets-private.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_SETS_PRIVATE_H__
+#define __GUPNP_DLNA_NATIVE_SETS_PRIVATE_H__
+
+#include <glib.h>
+#include "gupnp-dlna-native-value-type.h"
+#include "gupnp-dlna-native-value-list.h"
+#include "gupnp-dlna-native-info-value.h"
+#include "gupnp-dlna-native-restriction.h"
+
+G_BEGIN_DECLS
+
+/* private */
+typedef union _GUPnPDLNANativeValueUnion GUPnPDLNANativeValueUnion;
+typedef struct _GUPnPDLNANativeFraction GUPnPDLNANativeFraction;
+
+struct _GUPnPDLNANativeFraction {
+ gint numerator;
+ gint denominator;
+};
+
+union _GUPnPDLNANativeValueUnion {
+ gboolean bool_value;
+ GUPnPDLNANativeFraction fraction_value;
+ gint int_value;
+ gchar *string_value;
+};
+
+/* ValueType */
+gboolean
+gupnp_dlna_native_value_type_init (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw);
+
+gboolean
+gupnp_dlna_native_value_type_copy (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to);
+
+void
+gupnp_dlna_native_value_type_clean (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value_union);
+
+gboolean
+gupnp_dlna_native_value_type_is_equal (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second);
+
+gboolean
+gupnp_dlna_native_value_type_is_in_range (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max,
+ GUPnPDLNANativeValueUnion *value);
+
+const gchar *
+gupnp_dlna_native_value_type_name (GUPnPDLNANativeValueType *type);
+
+gboolean
+gupnp_dlna_native_value_type_verify_range (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max);
+
+gchar *
+gupnp_dlna_native_value_type_to_string (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value);
+
+gint
+gupnp_dlna_native_value_type_compare (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b);
+
+/* ValueList */
+GUPnPDLNANativeValueList *
+gupnp_dlna_native_value_list_copy (GUPnPDLNANativeValueList *list);
+
+gboolean
+gupnp_dlna_native_value_list_is_superset
+ (GUPnPDLNANativeValueList *list,
+ GUPnPDLNANativeInfoValue *value,
+ gboolean *unsupported);
+
+void
+gupnp_dlna_native_value_list_merge
+ (GUPnPDLNANativeValueList *value_list,
+ GUPnPDLNANativeValueList *mrg_value_list,
+ GUPnPDLNANativeRestrictionMergeResolution resolution);
+
+gboolean
+gupnp_dlna_native_value_list_is_empty (GUPnPDLNANativeValueList *value_list);
+
+GList *
+gupnp_dlna_native_value_list_get_list (GUPnPDLNANativeValueList *value_list);
+
+gboolean
+gupnp_dlna_native_value_list_mergeable
+ (GUPnPDLNANativeValueList *value_list,
+ GUPnPDLNANativeValueList *mrg_value_list);
+
+gchar *
+gupnp_dlna_native_value_list_to_string (GUPnPDLNANativeValueList *value_list);
+
+void
+gupnp_dlna_native_value_list_sort_items (GUPnPDLNANativeValueList *value_list);
+
+/* InfoValue */
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_info_value_get_type (GUPnPDLNANativeInfoValue *info);
+
+GUPnPDLNANativeValueUnion *
+gupnp_dlna_native_info_value_get_value (GUPnPDLNANativeInfoValue *info);
+
+/* Restriction */
+GHashTable *
+gupnp_dlna_native_restriction_get_entries
+ (GUPnPDLNANativeRestriction *restriction);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_SETS_PRIVATE_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-list.c b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-list.c
new file mode 100644
index 0000000..aa412c1
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-list.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gupnp-dlna-native-value-list.h"
+#include "gupnp-dlna-native-value.h"
+#include "gupnp-dlna-native-sets-private.h"
+
+struct _GUPnPDLNANativeValueList {
+ GUPnPDLNANativeValueType *type;
+ GList *values; /* <GUPnPDLNANativeValue *> */
+ gboolean sorted;
+};
+
+GUPnPDLNANativeValueList *
+gupnp_dlna_native_value_list_new (GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueList *list;
+
+ g_return_val_if_fail (type != NULL, NULL);
+
+ list = g_slice_new (GUPnPDLNANativeValueList);
+ list->type = type;
+ list->values = NULL;
+ list->sorted = FALSE;
+
+ return list;
+}
+
+static void
+free_value (GUPnPDLNANativeValue *value,
+ GUPnPDLNANativeValueType *type)
+{
+ gupnp_dlna_native_value_free (value, type);
+}
+
+static void
+free_value_list (GUPnPDLNANativeValueList *list)
+{
+ if (list->values) {
+ g_list_foreach (list->values,
+ (GFunc) free_value,
+ list->type);
+ g_list_free (list->values);
+ list->values = NULL;
+ }
+}
+
+void
+gupnp_dlna_native_value_list_free (GUPnPDLNANativeValueList *list)
+{
+ if (!list)
+ return;
+
+ free_value_list (list);
+ g_slice_free (GUPnPDLNANativeValueList, list);
+}
+
+static gint
+value_compare (GUPnPDLNANativeValue *a,
+ GUPnPDLNANativeValue *b,
+ GUPnPDLNANativeValueType *type)
+{
+ return gupnp_dlna_native_value_compare (a, b, type);
+}
+
+static gboolean
+insert_value (GUPnPDLNANativeValueList *list,
+ GUPnPDLNANativeValue *value)
+{
+ if (value) {
+ if (list->sorted)
+ list->values = g_list_insert_sorted_with_data
+ (list->values,
+ value,
+ (GCompareDataFunc) value_compare,
+ list->type);
+ else
+ list->values = g_list_prepend (list->values, value);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+gupnp_dlna_native_value_list_add_single (GUPnPDLNANativeValueList *list,
+ const gchar *single)
+{
+ GUPnPDLNANativeValue *value;
+
+ g_return_val_if_fail (list != NULL, FALSE);
+ g_return_val_if_fail (single != NULL, FALSE);
+
+ value = gupnp_dlna_native_value_new_single (list->type, single);
+
+ return insert_value (list, value);
+}
+
+gboolean
+gupnp_dlna_native_value_list_add_range (GUPnPDLNANativeValueList *list,
+ const gchar *min,
+ const gchar *max)
+{
+ GUPnPDLNANativeValue *range;
+
+ g_return_val_if_fail (list != NULL, FALSE);
+ g_return_val_if_fail (min != NULL, FALSE);
+ g_return_val_if_fail (max != NULL, FALSE);
+
+ range = gupnp_dlna_native_value_new_ranged (list->type, min, max);
+
+ if (range) {
+ list->values = g_list_prepend (list->values, range);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* private */
+GUPnPDLNANativeValueList *
+gupnp_dlna_native_value_list_copy (GUPnPDLNANativeValueList *list)
+{
+ GUPnPDLNANativeValueList *dup;
+
+ if (list) {
+ GList *iter;
+
+ dup = gupnp_dlna_native_value_list_new (list->type);
+ for (iter = list->values; iter != NULL; iter = iter->next) {
+ GUPnPDLNANativeValue *base =
+ (GUPnPDLNANativeValue *) iter->data;
+ GUPnPDLNANativeValue *copy;
+
+ if (base == NULL)
+ continue;
+
+ copy = gupnp_dlna_native_value_copy (base, list->type);
+ if (copy != NULL)
+ dup->values = g_list_prepend (dup->values,
+ copy);
+ }
+ dup->values = g_list_reverse (dup->values);
+ } else {
+ dup = NULL;
+ }
+
+ return dup;
+}
+
+gboolean
+gupnp_dlna_native_value_list_is_superset (GUPnPDLNANativeValueList *list,
+ GUPnPDLNANativeInfoValue *value,
+ gboolean *unsupported)
+{
+ GList *iter;
+
+ g_return_val_if_fail (list != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (unsupported != NULL, FALSE);
+
+ if (list->type != gupnp_dlna_native_info_value_get_type (value))
+ return FALSE;
+
+ if (gupnp_dlna_native_info_value_is_unsupported (value)) {
+ *unsupported = TRUE;
+
+ return TRUE;
+ }
+
+ for (iter = list->values; iter != NULL; iter = iter->next) {
+ GUPnPDLNANativeValue *base =
+ (GUPnPDLNANativeValue *) iter->data;
+
+ if (gupnp_dlna_native_value_is_superset (base, value)) {
+ *unsupported = FALSE;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+gboolean
+gupnp_dlna_native_value_list_mergeable
+ (GUPnPDLNANativeValueList *value_list,
+ GUPnPDLNANativeValueList *mrg_value_list)
+{
+ if (value_list->type != mrg_value_list->type) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+gupnp_dlna_native_value_list_merge
+ (GUPnPDLNANativeValueList *value_list,
+ GUPnPDLNANativeValueList *mrg_value_list,
+ GUPnPDLNANativeRestrictionMergeResolution resolution)
+{
+ g_return_if_fail (value_list != NULL);
+ g_return_if_fail (mrg_value_list != NULL);
+
+ switch (resolution) {
+ case GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_FROM_TARGET:
+ /* do nothing */
+ break;
+ case GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_FROM_SOURCE:
+ free_value_list (value_list);
+ value_list->values = mrg_value_list->values;
+ value_list->type = mrg_value_list->type;
+ mrg_value_list->values = NULL;
+ case GUPNP_DLNA_NATIVE_RESTRICTION_MERGE_RESOLUTION_NONE:
+ if (!gupnp_dlna_native_value_list_mergeable (value_list,
+ mrg_value_list)) {
+ g_critical ("Tried to merge values of type '%s' into "
+ "values of type '%s'.",
+ gupnp_dlna_native_value_type_name
+ (mrg_value_list->type),
+ gupnp_dlna_native_value_type_name
+ (value_list->type));
+
+ return;
+ }
+ value_list->values = g_list_concat (value_list->values,
+ mrg_value_list->values);
+ mrg_value_list->values = NULL;
+
+ break;
+ default:
+ g_critical ("Unknown conflict resolution: %d", resolution);
+ }
+}
+
+gboolean
+gupnp_dlna_native_value_list_is_empty (GUPnPDLNANativeValueList *value_list)
+{
+ g_return_val_if_fail (value_list != NULL, TRUE);
+
+ return (value_list->values == NULL);
+}
+
+GList *
+gupnp_dlna_native_value_list_get_list (GUPnPDLNANativeValueList *value_list)
+{
+ g_return_val_if_fail (value_list != NULL, NULL);
+
+ return value_list->values;
+}
+
+static gchar *
+list_to_string (GUPnPDLNANativeValueList *value_list)
+{
+ GList *iter;
+ GPtrArray* strings = g_ptr_array_new_with_free_func (g_free);
+ gchar *str;
+
+ for (iter = value_list->values; iter != NULL; iter = iter->next) {
+ GUPnPDLNANativeValue *value =
+ (GUPnPDLNANativeValue *) iter->data;
+
+ g_ptr_array_add (strings,
+ gupnp_dlna_native_value_to_string
+ (value,
+ value_list->type));
+ }
+ g_ptr_array_add (strings, NULL);
+
+ str = g_strjoinv (", ", (gchar **) strings->pdata);
+ g_ptr_array_unref (strings);
+
+ return str;
+}
+
+gchar *
+gupnp_dlna_native_value_list_to_string (GUPnPDLNANativeValueList *value_list)
+{
+ GString *str;
+ gchar *val_str;
+
+ g_return_val_if_fail (value_list != NULL, NULL);
+
+ if (value_list->values == NULL)
+ return g_strdup ("");
+
+ str = g_string_new (NULL);
+ g_string_append_printf (str,
+ "(%s)",
+ gupnp_dlna_native_value_type_name
+ (value_list->type));
+ if (value_list->values->next != NULL) {
+ g_string_append (str, "{ ");
+ val_str = list_to_string (value_list);
+ g_string_append (str, val_str);
+ g_string_append (str, " }");
+ } else {
+ val_str = list_to_string (value_list);
+ g_string_append (str, val_str);
+ }
+ g_free (val_str);
+
+ return g_string_free (str, FALSE);
+}
+
+void
+gupnp_dlna_native_value_list_sort_items (GUPnPDLNANativeValueList *value_list)
+{
+ g_return_if_fail (value_list != NULL);
+
+ if (!value_list->sorted) {
+ value_list->values = g_list_sort_with_data
+ (value_list->values,
+ (GCompareDataFunc) value_compare,
+ value_list->type);
+ value_list->sorted = TRUE;
+ }
+}
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-list.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-list.h
new file mode 100644
index 0000000..8922375
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-list.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_VALUE_LIST_H__
+#define __GUPNP_DLNA_NATIVE_VALUE_LIST_H__
+
+#include <glib.h>
+
+#include "gupnp-dlna-native-value-type.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GUPnPDLNANativeValueList GUPnPDLNANativeValueList;
+
+GUPnPDLNANativeValueList *
+gupnp_dlna_native_value_list_new (GUPnPDLNANativeValueType *type);
+
+void
+gupnp_dlna_native_value_list_free (GUPnPDLNANativeValueList *list);
+
+gboolean
+gupnp_dlna_native_value_list_add_range (GUPnPDLNANativeValueList *list,
+ const gchar *min,
+ const gchar *max);
+
+gboolean
+gupnp_dlna_native_value_list_add_single (GUPnPDLNANativeValueList *list,
+ const gchar *single);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_VALUE_LIST_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-type.c b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-type.c
new file mode 100644
index 0000000..62842db
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-type.c
@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include "gupnp-dlna-native-value-type.h"
+#include "gupnp-dlna-native-sets-private.h"
+
+struct _GUPnPDLNANativeValueType {
+ gboolean
+ (* init) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw);
+
+ gboolean
+ (* copy) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to);
+
+ void
+ (* clean) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value_union);
+
+ gboolean
+ (* is_equal) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second);
+
+ gboolean
+ (* is_in_range) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max,
+ GUPnPDLNANativeValueUnion *value);
+
+ const gchar *
+ (* name) (GUPnPDLNANativeValueType *type);
+
+ gboolean
+ (* verify_range) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max);
+
+ gchar *
+ (* to_string) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value);
+
+ gint
+ (* compare) (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b);
+};
+
+/* utils */
+static gboolean
+get_int (const gchar *raw,
+ gint *store)
+{
+ char *end;
+ long num;
+
+ g_return_val_if_fail (store != NULL, FALSE);
+
+ end = NULL;
+ num = strtol (raw, &end, 10);
+ if (*end != '\0')
+ return FALSE;
+ *store = (gint) num;
+
+ return TRUE;
+}
+
+/* TODO: replace it with better implementation */
+static void
+equalize_denominators (GUPnPDLNANativeFraction *first,
+ GUPnPDLNANativeFraction *second)
+{
+ gint common;
+
+ if (first->denominator == second->denominator)
+ return;
+
+ common = first->denominator * second->denominator;
+ first->numerator *= second->denominator;
+ second->numerator *= first->denominator;
+ first->denominator = common;
+ second->denominator = common;
+}
+
+static gboolean
+fraction_equal (GUPnPDLNANativeFraction first,
+ GUPnPDLNANativeFraction second)
+{
+ equalize_denominators (&first, &second);
+
+ return first.numerator == second.numerator;
+}
+
+static gboolean
+fraction_in_range (GUPnPDLNANativeFraction min,
+ GUPnPDLNANativeFraction max,
+ GUPnPDLNANativeFraction value)
+{
+ GUPnPDLNANativeFraction value_dup = value;
+
+ equalize_denominators (&min, &value);
+ if (min.numerator > value.numerator)
+ return FALSE;
+ equalize_denominators (&max, &value_dup);
+ if (max.numerator < value_dup.numerator)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gint
+int_comparison (gint a,
+ gint b)
+{
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+
+ return 0;
+}
+
+static gint
+fraction_comparison (GUPnPDLNANativeFraction a,
+ GUPnPDLNANativeFraction b)
+{
+ equalize_denominators (&a, &b);
+
+ return int_comparison (a.numerator, b.numerator);
+}
+
+static gboolean
+fraction_range_valid (GUPnPDLNANativeFraction min,
+ GUPnPDLNANativeFraction max)
+{
+ equalize_denominators (&min, &max);
+
+ return (min.numerator <= max.numerator);
+}
+
+/* bool */
+static gboolean
+bool_init (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw)
+{
+ if (!g_strcmp0 (raw, "true"))
+ value->bool_value = TRUE;
+ else if (!g_strcmp0 (raw, "false"))
+ value->bool_value = FALSE;
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+bool_copy (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to)
+{
+ to->bool_value = from->bool_value;
+
+ return TRUE;
+}
+
+static void
+bool_clean (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value_union G_GNUC_UNUSED)
+{
+
+}
+
+static gboolean
+bool_is_equal (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second)
+{
+ return !!first->bool_value == !!second->bool_value;
+}
+
+static gboolean
+bool_is_in_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *max G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value G_GNUC_UNUSED)
+{
+ /* boolean range? */
+ return FALSE;
+}
+
+static const gchar *
+bool_name (GUPnPDLNANativeValueType *type G_GNUC_UNUSED)
+{
+ return "boolean";
+}
+
+static gboolean
+bool_verify_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *max G_GNUC_UNUSED)
+{
+ return FALSE;
+}
+
+static gchar *
+bool_to_string (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value)
+{
+ return g_strdup (value->bool_value ? "true" : "false");
+}
+
+gint
+bool_compare (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b)
+{
+ if ((a->bool_value && b->bool_value) ||
+ (!a->bool_value && !b->bool_value))
+ return 0;
+ else if (a->bool_value)
+ return 1;
+ else
+ return -1;
+}
+
+static GUPnPDLNANativeValueType bool_type_impl = {
+ bool_init,
+ bool_copy,
+ bool_clean,
+ bool_is_equal,
+ bool_is_in_range,
+ bool_name,
+ bool_verify_range,
+ bool_to_string,
+ bool_compare
+};
+
+/* fraction */
+static gboolean
+fraction_init (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw)
+{
+ gchar **tokens = g_strsplit (raw, "/", 2);
+ gboolean result = FALSE;
+ gint numerator;
+ gint denominator;
+
+ if (g_strv_length (tokens) != 2)
+ goto out;
+
+ if (!get_int (tokens[0], &numerator) ||
+ !get_int (tokens[1], &denominator))
+ goto out;
+
+ if (!denominator)
+ goto out;
+
+ value->fraction_value.numerator = numerator;
+ value->fraction_value.denominator = denominator;
+ result = TRUE;
+ out:
+ g_strfreev (tokens);
+
+ return result;
+}
+
+static gboolean
+fraction_copy (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to)
+{
+ to->fraction_value = from->fraction_value;
+
+ return TRUE;
+}
+
+static void
+fraction_clean (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value_union G_GNUC_UNUSED)
+{
+
+}
+
+static gboolean
+fraction_is_equal (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second)
+{
+ return fraction_equal (first->fraction_value,
+ second->fraction_value);
+}
+
+static gboolean
+fraction_is_in_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max,
+ GUPnPDLNANativeValueUnion *value)
+{
+ /* fraction range? */
+ return fraction_in_range (min->fraction_value,
+ max->fraction_value,
+ value->fraction_value);
+}
+
+static const gchar *
+fraction_name (GUPnPDLNANativeValueType *type G_GNUC_UNUSED)
+{
+ return "fraction";
+}
+
+static gboolean
+fraction_verify_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max)
+{
+ return fraction_range_valid (min->fraction_value, max->fraction_value);
+}
+
+static gchar *
+fraction_to_string (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value)
+{
+ return g_strdup_printf ("%d/%d",
+ value->fraction_value.numerator,
+ value->fraction_value.denominator);
+}
+
+gint
+fraction_compare (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b)
+{
+ return fraction_comparison (a->fraction_value, b->fraction_value);
+}
+
+static GUPnPDLNANativeValueType fraction_type_impl = {
+ fraction_init,
+ fraction_copy,
+ fraction_clean,
+ fraction_is_equal,
+ fraction_is_in_range,
+ fraction_name,
+ fraction_verify_range,
+ fraction_to_string,
+ fraction_compare
+};
+
+/* int */
+static gboolean
+int_init (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw)
+{
+ gint num;
+
+ if (get_int (raw, &num)) {
+ value->int_value = num;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+int_copy (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to)
+{
+ to->int_value = from->int_value;
+
+ return TRUE;
+}
+
+static void
+int_clean (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value_union G_GNUC_UNUSED)
+{
+
+}
+
+static gboolean
+int_is_equal (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second)
+{
+ return first->int_value == second->int_value;
+}
+
+static gboolean
+int_is_in_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max,
+ GUPnPDLNANativeValueUnion *value)
+{
+ return (min->int_value <= value->int_value &&
+ max->int_value >= value->int_value);
+}
+
+static const gchar *
+int_name (GUPnPDLNANativeValueType *type G_GNUC_UNUSED)
+{
+ return "int";
+}
+
+static gboolean
+int_verify_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max)
+{
+ return (min->int_value <= max->int_value);
+}
+
+static gchar *
+int_to_string (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value)
+{
+ return g_strdup_printf ("%d", value->int_value);
+}
+
+gint
+int_compare (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b)
+{
+ return int_comparison (a->int_value, b->int_value);
+}
+
+static GUPnPDLNANativeValueType int_type_impl = {
+ int_init,
+ int_copy,
+ int_clean,
+ int_is_equal,
+ int_is_in_range,
+ int_name,
+ int_verify_range,
+ int_to_string,
+ int_compare
+};
+
+/* string */
+static gboolean
+string_init (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw)
+{
+ value->string_value = g_strdup (raw);
+
+ return TRUE;
+}
+
+static gboolean
+string_copy (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to)
+{
+ to->string_value = g_strdup (from->string_value);
+
+ return TRUE;
+}
+
+static void
+string_clean (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value_union)
+{
+ g_free (value_union->string_value);
+}
+
+static gboolean
+string_is_equal (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second)
+{
+ return !g_strcmp0 (first->string_value, second->string_value);
+}
+
+static gboolean
+string_is_in_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max,
+ GUPnPDLNANativeValueUnion *value)
+{
+ /* string range? */
+ return (!g_strcmp0 (min->string_value,
+ value->string_value) ||
+ !g_strcmp0 (max->string_value,
+ value->string_value));
+}
+
+static const gchar *
+string_name (GUPnPDLNANativeValueType *type G_GNUC_UNUSED)
+{
+ return "string";
+}
+
+static gboolean
+string_verify_range (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *min G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *max G_GNUC_UNUSED)
+{
+ return FALSE;
+}
+
+static gchar *
+string_to_string (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *value)
+{
+ return g_strdup (value->string_value);
+}
+
+gint
+string_compare (GUPnPDLNANativeValueType *type G_GNUC_UNUSED,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b)
+{
+ return g_strcmp0 (a->string_value, b->string_value);
+}
+
+static GUPnPDLNANativeValueType string_type_impl = {
+ string_init,
+ string_copy,
+ string_clean,
+ string_is_equal,
+ string_is_in_range,
+ string_name,
+ string_verify_range,
+ string_to_string,
+ string_compare
+};
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_bool (void)
+{
+ return &bool_type_impl;
+}
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_fraction (void)
+{
+ return &fraction_type_impl;
+}
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_int (void)
+{
+ return &int_type_impl;
+}
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_string (void)
+{
+ return &string_type_impl;
+}
+
+gboolean
+gupnp_dlna_native_value_type_init (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value,
+ const gchar *raw)
+{
+ g_return_val_if_fail (type != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (raw != NULL, FALSE);
+ g_return_val_if_fail (type->init != NULL, FALSE);
+
+ return type->init (type, value, raw);
+}
+
+gboolean
+gupnp_dlna_native_value_type_copy (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *from,
+ GUPnPDLNANativeValueUnion *to)
+{
+ g_return_val_if_fail (type != NULL, FALSE);
+ g_return_val_if_fail (from != NULL, FALSE);
+ g_return_val_if_fail (to != NULL, FALSE);
+ g_return_val_if_fail (type->copy != NULL, FALSE);
+
+ return type->copy (type, from, to);
+}
+
+void
+gupnp_dlna_native_value_type_clean (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value)
+{
+ g_return_if_fail (type != NULL);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (type->clean != NULL);
+
+ type->clean (type, value);
+}
+
+gboolean
+gupnp_dlna_native_value_type_is_equal (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *first,
+ GUPnPDLNANativeValueUnion *second)
+{
+ g_return_val_if_fail (type != NULL, FALSE);
+ g_return_val_if_fail (first != NULL, FALSE);
+ g_return_val_if_fail (second != NULL, FALSE);
+ g_return_val_if_fail (type->is_equal != NULL, FALSE);
+
+ return type->is_equal (type, first, second);
+}
+
+gboolean
+gupnp_dlna_native_value_type_is_in_range (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max,
+ GUPnPDLNANativeValueUnion *value)
+{
+ g_return_val_if_fail (type != NULL, FALSE);
+ g_return_val_if_fail (min != NULL, FALSE);
+ g_return_val_if_fail (max != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (type->is_in_range != NULL, FALSE);
+
+ return type->is_in_range (type, min, max, value);
+}
+
+const gchar *
+gupnp_dlna_native_value_type_name (GUPnPDLNANativeValueType *type)
+{
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (type->name != NULL, NULL);
+
+ return type->name (type);
+}
+
+gboolean
+gupnp_dlna_native_value_type_verify_range (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *min,
+ GUPnPDLNANativeValueUnion *max)
+{
+ g_return_val_if_fail (type != NULL, FALSE);
+ g_return_val_if_fail (min != NULL, FALSE);
+ g_return_val_if_fail (max != NULL, FALSE);
+ g_return_val_if_fail (type->verify_range != NULL, FALSE);
+
+ return type->verify_range (type, min, max);
+}
+
+gchar *
+gupnp_dlna_native_value_type_to_string (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *value)
+{
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+ g_return_val_if_fail (type->to_string != NULL, NULL);
+
+ return type->to_string (type, value);
+}
+
+gint
+gupnp_dlna_native_value_type_compare (GUPnPDLNANativeValueType *type,
+ GUPnPDLNANativeValueUnion *a,
+ GUPnPDLNANativeValueUnion *b)
+{
+ g_return_val_if_fail (type != NULL, 0);
+ g_return_val_if_fail (a != NULL, 0);
+ g_return_val_if_fail (b != NULL, 0);
+ g_return_val_if_fail (type->compare != NULL, 0);
+
+ return type->compare (type, a, b);
+}
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-type.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-type.h
new file mode 100644
index 0000000..23de547
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value-type.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_VALUE_TYPE_H__
+#define __GUPNP_DLNA_NATIVE_VALUE_TYPE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GUPnPDLNANativeValueType GUPnPDLNANativeValueType;
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_bool (void);
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_fraction (void);
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_int (void);
+
+GUPnPDLNANativeValueType *
+gupnp_dlna_native_value_type_string (void);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_VALUE_TYPE_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value.c b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value.c
new file mode 100644
index 0000000..a9a3d44
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gupnp-dlna-native-value.h"
+#include "gupnp-dlna-native-sets-private.h"
+
+struct _GUPnPDLNANativeValueVTable {
+ gboolean
+ (* is_superset) (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *info);
+
+ GUPnPDLNANativeValue *
+ (* copy) (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+ void
+ (* free) (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+ gchar *
+ (* to_string) (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+ GUPnPDLNANativeValueUnion *
+ (* get_sort_value) (GUPnPDLNANativeValue *base);
+};
+
+/* single */
+typedef struct _GUPnPDLNANativeValueSingle GUPnPDLNANativeValueSingle;
+
+struct _GUPnPDLNANativeValueSingle {
+ GUPnPDLNANativeValue base;
+ GUPnPDLNANativeValueUnion value;
+};
+
+static gboolean
+single_is_superset (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *info);
+
+static GUPnPDLNANativeValue *
+single_copy (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+static void
+single_free (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+static gchar *
+single_to_string (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+static GUPnPDLNANativeValueUnion *
+single_get_sort_value (GUPnPDLNANativeValue *base);
+
+static GUPnPDLNANativeValueVTable single_vtable = {
+ single_is_superset,
+ single_copy,
+ single_free,
+ single_to_string,
+ single_get_sort_value
+};
+
+static gboolean
+single_is_superset (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *info)
+{
+ GUPnPDLNANativeValueSingle *value = (GUPnPDLNANativeValueSingle *) base;
+ GUPnPDLNANativeValueType *info_type =
+ gupnp_dlna_native_info_value_get_type (info);
+ GUPnPDLNANativeValueUnion *info_value =
+ gupnp_dlna_native_info_value_get_value (info);
+
+ return gupnp_dlna_native_value_type_is_equal (info_type,
+ &value->value,
+ info_value);
+}
+
+static GUPnPDLNANativeValue *
+single_copy (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueSingle *value = (GUPnPDLNANativeValueSingle *) base;
+ GUPnPDLNANativeValueSingle *dup =
+ g_slice_new (GUPnPDLNANativeValueSingle);
+
+ dup->base.vtable = &single_vtable;
+ if (!gupnp_dlna_native_value_type_copy (type,
+ &value->value,
+ &dup->value)) {
+ g_slice_free (GUPnPDLNANativeValueSingle, dup);
+ dup = NULL;
+ }
+
+ return (GUPnPDLNANativeValue *) dup;
+}
+
+static void
+single_free (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueSingle *value = (GUPnPDLNANativeValueSingle *) base;
+
+ gupnp_dlna_native_value_type_clean (type, &value->value);
+ g_slice_free (GUPnPDLNANativeValueSingle, value);
+}
+
+static gchar *
+single_to_string (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueSingle *value = (GUPnPDLNANativeValueSingle *) base;
+
+ return gupnp_dlna_native_value_type_to_string (type,
+ &value->value);
+}
+
+static GUPnPDLNANativeValueUnion *
+single_get_sort_value (GUPnPDLNANativeValue *base)
+{
+ GUPnPDLNANativeValueSingle *value = (GUPnPDLNANativeValueSingle *) base;
+
+ return &value->value;
+}
+
+/* range */
+typedef struct _GUPnPDLNANativeValueRange GUPnPDLNANativeValueRange;
+
+struct _GUPnPDLNANativeValueRange {
+ GUPnPDLNANativeValue base;
+ GUPnPDLNANativeValueUnion min;
+ GUPnPDLNANativeValueUnion max;
+};
+
+static gboolean
+range_is_superset (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *info);
+
+static GUPnPDLNANativeValue *
+range_copy (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+static void
+range_free (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+static gchar *
+range_to_string (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+static GUPnPDLNANativeValueUnion *
+range_get_sort_value (GUPnPDLNANativeValue *base);
+
+static GUPnPDLNANativeValueVTable range_vtable = {
+ range_is_superset,
+ range_copy,
+ range_free,
+ range_to_string,
+ range_get_sort_value
+};
+
+static gboolean
+range_is_superset (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *info)
+{
+ GUPnPDLNANativeValueRange *range = (GUPnPDLNANativeValueRange *) base;
+ GUPnPDLNANativeValueType *info_type =
+ gupnp_dlna_native_info_value_get_type (info);
+ GUPnPDLNANativeValueUnion *info_value =
+ gupnp_dlna_native_info_value_get_value (info);
+
+ return gupnp_dlna_native_value_type_is_in_range (info_type,
+ &range->min,
+ &range->max,
+ info_value);
+}
+
+static GUPnPDLNANativeValue *
+range_copy (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueRange *range = (GUPnPDLNANativeValueRange *) base;
+ GUPnPDLNANativeValueRange *dup =
+ g_slice_new (GUPnPDLNANativeValueRange);
+
+ dup->base.vtable = &range_vtable;
+ if (!gupnp_dlna_native_value_type_copy (type,
+ &range->min,
+ &dup->min)) {
+ g_slice_free (GUPnPDLNANativeValueRange, dup);
+ dup = NULL;
+ }
+ if (dup &&
+ !gupnp_dlna_native_value_type_copy (type,
+ &range->max,
+ &dup->max)) {
+ gupnp_dlna_native_value_type_clean (type,
+ &dup->min);
+ g_slice_free (GUPnPDLNANativeValueRange, dup);
+ dup = NULL;
+ }
+
+ return (GUPnPDLNANativeValue *) dup;
+}
+
+static void
+range_free (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueRange *range = (GUPnPDLNANativeValueRange *) base;
+
+ gupnp_dlna_native_value_type_clean (type, &range->min);
+ gupnp_dlna_native_value_type_clean (type, &range->max);
+ g_slice_free (GUPnPDLNANativeValueRange, range);
+}
+
+static gchar *
+range_to_string (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueRange *range = (GUPnPDLNANativeValueRange *) base;
+ gchar *str;
+ gchar *min = gupnp_dlna_native_value_type_to_string (type,
+ &range->min);
+ gchar *max = gupnp_dlna_native_value_type_to_string (type,
+ &range->max);
+
+ str = g_strdup_printf ("[ %s, %s ]", min, max);
+ g_free (min);
+ g_free (max);
+
+ return str;
+}
+
+static GUPnPDLNANativeValueUnion *
+range_get_sort_value (GUPnPDLNANativeValue *base)
+{
+ GUPnPDLNANativeValueRange *range = (GUPnPDLNANativeValueRange *) base;
+
+ return &range->min;
+}
+
+GUPnPDLNANativeValue *
+gupnp_dlna_native_value_new_single (GUPnPDLNANativeValueType *type,
+ const gchar *raw)
+{
+ GUPnPDLNANativeValueSingle *value;
+
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (raw != NULL, NULL);
+
+ value = g_slice_new (GUPnPDLNANativeValueSingle);
+ value->base.vtable = &single_vtable;
+ if (!gupnp_dlna_native_value_type_init (type, &value->value, raw)) {
+ g_slice_free (GUPnPDLNANativeValueSingle, value);
+ value = NULL;
+ }
+
+ return (GUPnPDLNANativeValue *) value;
+}
+
+GUPnPDLNANativeValue *
+gupnp_dlna_native_value_new_ranged (GUPnPDLNANativeValueType *type,
+ const gchar *min,
+ const gchar *max)
+{
+ GUPnPDLNANativeValueRange *range;
+
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (min != NULL, NULL);
+ g_return_val_if_fail (max != NULL, NULL);
+
+ range = g_slice_new (GUPnPDLNANativeValueRange);
+ range->base.vtable = &range_vtable;
+ if (!gupnp_dlna_native_value_type_init (type, &range->min, min)) {
+ g_slice_free (GUPnPDLNANativeValueRange, range);
+ range = NULL;
+ }
+ if (range &&
+ !gupnp_dlna_native_value_type_init (type, &range->max, max)) {
+ gupnp_dlna_native_value_type_clean (type, &range->min);
+ g_slice_free (GUPnPDLNANativeValueRange, range);
+ range = NULL;
+ }
+ if (range &&
+ !gupnp_dlna_native_value_type_verify_range (type,
+ &range->min,
+ &range->max)) {
+ gupnp_dlna_native_value_type_clean (type, &range->min);
+ gupnp_dlna_native_value_type_clean (type, &range->max);
+ g_slice_free (GUPnPDLNANativeValueRange, range);
+ range = NULL;
+ }
+
+ return (GUPnPDLNANativeValue *) range;
+}
+
+gboolean
+gupnp_dlna_native_value_is_superset (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *single)
+{
+ g_return_val_if_fail (base != NULL, FALSE);
+ g_return_val_if_fail (single != NULL, FALSE);
+ g_return_val_if_fail (base->vtable != NULL, FALSE);
+ g_return_val_if_fail (base->vtable->is_superset != NULL, FALSE);
+
+ return base->vtable->is_superset (base, single);
+}
+
+GUPnPDLNANativeValue *
+gupnp_dlna_native_value_copy (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ g_return_val_if_fail (base != NULL, NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (base->vtable != NULL, NULL);
+ g_return_val_if_fail (base->vtable->copy != NULL, NULL);
+
+ return base->vtable->copy (base, type);
+}
+
+void
+gupnp_dlna_native_value_free (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ if (base == NULL)
+ return;
+
+ g_return_if_fail (type != NULL);
+ g_return_if_fail (base->vtable != NULL);
+ g_return_if_fail (base->vtable->free != NULL);
+
+ base->vtable->free (base, type);
+}
+
+gchar *
+gupnp_dlna_native_value_to_string (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type)
+{
+ g_return_val_if_fail (base != NULL, NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (base->vtable != NULL, NULL);
+ g_return_val_if_fail (base->vtable->to_string != NULL, NULL);
+
+ return base->vtable->to_string (base, type);
+}
+
+static GUPnPDLNANativeValueUnion *
+gupnp_dlna_native_value_get_sort_value (GUPnPDLNANativeValue *base)
+{
+ g_return_val_if_fail (base->vtable != NULL, NULL);
+ g_return_val_if_fail (base->vtable->get_sort_value != NULL, NULL);
+
+ return base->vtable->get_sort_value (base);
+}
+
+gint
+gupnp_dlna_native_value_compare (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValue *other,
+ GUPnPDLNANativeValueType *type)
+{
+ GUPnPDLNANativeValueUnion *base_union;
+ GUPnPDLNANativeValueUnion *other_union;
+
+ g_return_val_if_fail (base != NULL, 0);
+ g_return_val_if_fail (other != NULL, 0);
+ g_return_val_if_fail (type != NULL, 0);
+
+ base_union = gupnp_dlna_native_value_get_sort_value (base);
+ other_union = gupnp_dlna_native_value_get_sort_value (other);
+
+ return gupnp_dlna_native_value_type_compare (type,
+ base_union,
+ other_union);
+
+}
diff --git a/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value.h b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value.h
new file mode 100644
index 0000000..0c722d7
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/gupnp-dlna-native-value.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Krzesimir Nowak <krnowak openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_DLNA_NATIVE_VALUE_H__
+#define __GUPNP_DLNA_NATIVE_VALUE_H__
+
+#include <glib.h>
+#include "gupnp-dlna-native-info-value.h"
+#include "gupnp-dlna-native-value-type.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GUPnPDLNANativeValue GUPnPDLNANativeValue;
+typedef struct _GUPnPDLNANativeValueVTable GUPnPDLNANativeValueVTable;
+
+struct _GUPnPDLNANativeValue {
+ GUPnPDLNANativeValueVTable *vtable;
+};
+
+GUPnPDLNANativeValue *
+gupnp_dlna_native_value_new_single (GUPnPDLNANativeValueType *type,
+ const gchar *single);
+
+GUPnPDLNANativeValue *
+gupnp_dlna_native_value_new_ranged (GUPnPDLNANativeValueType *type,
+ const gchar *min,
+ const gchar *max);
+
+gboolean
+gupnp_dlna_native_value_is_superset (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeInfoValue *single);
+
+GUPnPDLNANativeValue *
+gupnp_dlna_native_value_copy (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+void
+gupnp_dlna_native_value_free (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+gchar *
+gupnp_dlna_native_value_to_string (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValueType *type);
+
+gint
+gupnp_dlna_native_value_compare (GUPnPDLNANativeValue *base,
+ GUPnPDLNANativeValue *other,
+ GUPnPDLNANativeValueType *type);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DLNA_NATIVE_VALUE_H__ */
diff --git a/libgupnp-dlna/profile-backends/native/sets/sets.am b/libgupnp-dlna/profile-backends/native/sets/sets.am
new file mode 100644
index 0000000..816be70
--- /dev/null
+++ b/libgupnp-dlna/profile-backends/native/sets/sets.am
@@ -0,0 +1,14 @@
+sets_sources = \
+ profile-backends/native/sets/gupnp-dlna-native-info-set.c \
+ profile-backends/native/sets/gupnp-dlna-native-info-set.h \
+ profile-backends/native/sets/gupnp-dlna-native-info-value.c \
+ profile-backends/native/sets/gupnp-dlna-native-info-value.h \
+ profile-backends/native/sets/gupnp-dlna-native-restriction.c \
+ profile-backends/native/sets/gupnp-dlna-native-restriction.h \
+ profile-backends/native/sets/gupnp-dlna-native-sets-private.h \
+ profile-backends/native/sets/gupnp-dlna-native-value.c \
+ profile-backends/native/sets/gupnp-dlna-native-value.h \
+ profile-backends/native/sets/gupnp-dlna-native-value-list.c \
+ profile-backends/native/sets/gupnp-dlna-native-value-list.h \
+ profile-backends/native/sets/gupnp-dlna-native-value-type.c \
+ profile-backends/native/sets/gupnp-dlna-native-value-type.h
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]