summaryrefslogtreecommitdiff
path: root/libappstream-glib
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2015-01-20 14:58:57 +0000
committerRichard Hughes <richard@hughsie.com>2015-01-20 15:04:02 +0000
commitacf84d61743f5dce83cc104d6160f12a2b3ad8e4 (patch)
treedaba03a805ad37636bd319e5328daec0f66c4af9 /libappstream-glib
parent17e6d34880df2f3ef1b35d104ed971afc6eb6669 (diff)
downloadappstream-glib-acf84d61743f5dce83cc104d6160f12a2b3ad8e4.tar.gz
Add support for <bundle>
Diffstat (limited to 'libappstream-glib')
-rw-r--r--libappstream-glib/Makefile.am5
-rw-r--r--libappstream-glib/appstream-glib.h1
-rw-r--r--libappstream-glib/as-app.c119
-rw-r--r--libappstream-glib/as-app.h5
-rw-r--r--libappstream-glib/as-bundle-private.h45
-rw-r--r--libappstream-glib/as-bundle.c286
-rw-r--r--libappstream-glib/as-bundle.h96
-rw-r--r--libappstream-glib/as-self-test.c48
-rw-r--r--libappstream-glib/as-tag.c1
-rw-r--r--libappstream-glib/as-tag.gperf1
-rw-r--r--libappstream-glib/as-tag.h2
11 files changed, 609 insertions, 0 deletions
diff --git a/libappstream-glib/Makefile.am b/libappstream-glib/Makefile.am
index 3c8d45c..3a97292 100644
--- a/libappstream-glib/Makefile.am
+++ b/libappstream-glib/Makefile.am
@@ -68,6 +68,7 @@ libappstream_glib_includedir = $(includedir)/libappstream-glib
libappstream_glib_include_HEADERS = \
appstream-glib.h \
as-app.h \
+ as-bundle.h \
as-enums.h \
as-icon.h \
as-image.h \
@@ -85,6 +86,8 @@ libappstream_glib_la_SOURCES = \
as-app.c \
as-app-private.h \
as-app-validate.c \
+ as-bundle.c \
+ as-bundle-private.h \
as-cleanup.h \
as-enums.c \
as-icon.c \
@@ -154,6 +157,8 @@ introspection_sources = \
as-app.c \
as-app-validate.c \
as-app.h \
+ as-bundle.c \
+ as-bundle.h \
as-enums.c \
as-enums.h \
as-icon.c \
diff --git a/libappstream-glib/appstream-glib.h b/libappstream-glib/appstream-glib.h
index e2e1144..9d79a72 100644
--- a/libappstream-glib/appstream-glib.h
+++ b/libappstream-glib/appstream-glib.h
@@ -25,6 +25,7 @@
#define __APPSTREAM_GLIB_H_INSIDE__
#include <as-app.h>
+#include <as-bundle.h>
#include <as-enums.h>
#include <as-icon.h>
#include <as-image.h>
diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c
index ca147c0..4960c8c 100644
--- a/libappstream-glib/as-app.c
+++ b/libappstream-glib/as-app.c
@@ -38,6 +38,7 @@
#include <string.h>
#include "as-app-private.h"
+#include "as-bundle-private.h"
#include "as-cleanup.h"
#include "as-enums.h"
#include "as-icon-private.h"
@@ -75,6 +76,7 @@ struct _AsAppPrivate
GPtrArray *provides; /* of AsProvide */
GPtrArray *screenshots; /* of AsScreenshot */
GPtrArray *icons; /* of AsIcon */
+ GPtrArray *bundles; /* of AsBundle */
GPtrArray *vetos; /* of string */
AsAppSourceKind source_kind;
AsAppState state;
@@ -277,6 +279,7 @@ as_app_finalize (GObject *object)
g_ptr_array_unref (priv->provides);
g_ptr_array_unref (priv->screenshots);
g_ptr_array_unref (priv->icons);
+ g_ptr_array_unref (priv->bundles);
g_ptr_array_unref (priv->token_cache);
g_ptr_array_unref (priv->vetos);
@@ -315,6 +318,7 @@ as_app_init (AsApp *app)
priv->provides = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->icons = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ priv->bundles = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->token_cache = g_ptr_array_new_with_free_func ((GDestroyNotify) as_app_token_item_free);
priv->vetos = g_ptr_array_new_with_free_func (g_free);
@@ -609,6 +613,23 @@ as_app_get_icons (AsApp *app)
}
/**
+ * as_app_get_bundles:
+ * @app: a #AsApp instance.
+ *
+ * Gets any bundles the application has defined.
+ *
+ * Returns: (element-type AsBundle) (transfer none): an array
+ *
+ * Since: 0.3.5
+ **/
+GPtrArray *
+as_app_get_bundles (AsApp *app)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+ return priv->bundles;
+}
+
+/**
* as_app_get_names:
* @app: a #AsApp instance.
*
@@ -2105,6 +2126,20 @@ as_app_check_icon_duplicate (AsIcon *icon1, AsIcon *icon2)
}
/**
+ * as_app_check_bundle_duplicate:
+ **/
+static gboolean
+as_app_check_bundle_duplicate (AsBundle *bundle1, AsBundle *bundle2)
+{
+ if (as_bundle_get_kind (bundle1) != as_bundle_get_kind (bundle2))
+ return FALSE;
+ if (g_strcmp0 (as_bundle_get_id (bundle1),
+ as_bundle_get_id (bundle2)) != 0)
+ return FALSE;
+ return TRUE;
+}
+
+/**
* as_app_add_icon:
* @app: a #AsApp instance.
* @icon: a #AsIcon instance.
@@ -2136,6 +2171,33 @@ as_app_add_icon (AsApp *app, AsIcon *icon)
}
/**
+ * as_app_add_bundle:
+ * @app: a #AsApp instance.
+ * @bundle: a #AsBundle instance.
+ *
+ * Adds a bundle to an application.
+ *
+ * Since: 0.3.5
+ **/
+void
+as_app_add_bundle (AsApp *app, AsBundle *bundle)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+
+ /* handle untrusted */
+ if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_DUPLICATES) > 0) {
+ AsBundle *bu_tmp;
+ guint i;
+ for (i = 0; i < priv->bundles->len; i++) {
+ bu_tmp = g_ptr_array_index (priv->bundles, i);
+ if (as_app_check_bundle_duplicate (bundle, bu_tmp))
+ return;
+ }
+ }
+ g_ptr_array_add (priv->bundles, g_object_ref (bundle));
+}
+
+/**
* as_app_add_pkgname:
* @app: a #AsApp instance.
* @pkgname: the package name.
@@ -2455,6 +2517,7 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags)
{
AsAppPrivate *priv = GET_PRIVATE (donor);
AsAppPrivate *papp = GET_PRIVATE (app);
+ AsBundle *bundle;
AsScreenshot *ss;
const gchar *tmp;
const gchar *key;
@@ -2489,6 +2552,12 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags)
as_app_add_pkgname (app, tmp, -1);
}
+ /* bundles */
+ for (i = 0; i < priv->bundles->len; i++) {
+ bundle = g_ptr_array_index (priv->bundles, i);
+ as_app_add_bundle (app, bundle);
+ }
+
/* kudos */
for (i = 0; i < priv->kudos->len; i++) {
tmp = g_ptr_array_index (priv->kudos, i);
@@ -2846,6 +2915,12 @@ as_app_node_insert (AsApp *app, GNode *parent, gdouble api_version)
priv->source_pkgname, 0, NULL);
}
+ /* <bundle> */
+ for (i = 0; i < priv->bundles->len; i++) {
+ AsBundle *bu = g_ptr_array_index (priv->bundles, i);
+ as_bundle_node_insert (bu, node_app, api_version);
+ }
+
/* <name> */
as_node_insert_localized (node_app, "name",
priv->names,
@@ -3082,6 +3157,17 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, GError **e
g_ptr_array_add (priv->pkgnames, as_node_take_data (n));
break;
+ /* <bundle> */
+ case AS_TAG_BUNDLE:
+ {
+ _cleanup_object_unref_ AsBundle *ic = NULL;
+ ic = as_bundle_new ();
+ if (!as_bundle_node_parse (ic, n, error))
+ return FALSE;
+ as_app_add_bundle (app, ic);
+ break;
+ }
+
/* <name> */
case AS_TAG_NAME:
taken = as_app_parse_locale (as_node_get_attribute (n, "xml:lang"));
@@ -3467,6 +3553,7 @@ as_app_node_parse_full (AsApp *app, GNode *node, AsAppParseFlags flags, GError *
g_ptr_array_set_size (priv->architectures, 0);
g_ptr_array_set_size (priv->extends, 0);
g_ptr_array_set_size (priv->icons, 0);
+ g_ptr_array_set_size (priv->bundles, 0);
g_hash_table_remove_all (priv->keywords);
}
for (n = node->children; n != NULL; n = n->next) {
@@ -3630,6 +3717,16 @@ as_app_node_parse_dep11 (AsApp *app, GNode *node, GError **error)
}
continue;
}
+ if (g_strcmp0 (tmp, "Bundle") == 0) {
+ for (c = n->children; c != NULL; c = c->next) {
+ _cleanup_object_unref_ AsBundle *bu = NULL;
+ bu = as_bundle_new ();
+ if (!as_bundle_node_parse_dep11 (bu, c, error))
+ return FALSE;
+ as_app_add_bundle (app, bu);
+ }
+ continue;
+ }
if (g_strcmp0 (tmp, "Url") == 0) {
for (c = n->children; c != NULL; c = c->next) {
if (g_strcmp0 (as_yaml_node_get_key (c), "homepage") == 0) {
@@ -4609,6 +4706,28 @@ as_app_get_icon_default (AsApp *app)
}
/**
+ * as_app_get_bundle_default:
+ * @app: A #AsApp
+ *
+ * Finds the default bundle.
+ *
+ * Returns: (transfer none): a #AsBundle, or %NULL
+ *
+ * Since: 0.3.5
+ **/
+AsBundle *
+as_app_get_bundle_default (AsApp *app)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+ AsBundle *bundle;
+
+ if (priv->bundles->len == 0)
+ return NULL;
+ bundle = g_ptr_array_index (priv->bundles, 0);
+ return bundle;
+}
+
+/**
* as_app_get_icon_for_size:
* @app: A #AsApp
* @width: Size in pixels
diff --git a/libappstream-glib/as-app.h b/libappstream-glib/as-app.h
index dc65389..0dc0cb3 100644
--- a/libappstream-glib/as-app.h
+++ b/libappstream-glib/as-app.h
@@ -28,6 +28,7 @@
#include <glib-object.h>
+#include "as-bundle.h"
#include "as-enums.h"
#include "as-icon.h"
#include "as-provide.h"
@@ -233,6 +234,7 @@ GPtrArray *as_app_get_releases (AsApp *app);
GPtrArray *as_app_get_provides (AsApp *app);
GPtrArray *as_app_get_screenshots (AsApp *app);
GPtrArray *as_app_get_icons (AsApp *app);
+GPtrArray *as_app_get_bundles (AsApp *app);
GHashTable *as_app_get_names (AsApp *app);
GHashTable *as_app_get_comments (AsApp *app);
GHashTable *as_app_get_developer_names (AsApp *app);
@@ -354,6 +356,8 @@ void as_app_add_screenshot (AsApp *app,
AsScreenshot *screenshot);
void as_app_add_icon (AsApp *app,
AsIcon *icon);
+void as_app_add_bundle (AsApp *app,
+ AsBundle *bundle);
void as_app_add_language (AsApp *app,
gint percentage,
const gchar *locale,
@@ -406,6 +410,7 @@ AsIcon *as_app_get_icon_default (AsApp *app);
AsIcon *as_app_get_icon_for_size (AsApp *app,
guint width,
guint height);
+AsBundle *as_app_get_bundle_default (AsApp *app);
gboolean as_app_convert_icons (AsApp *app,
AsIconKind kind,
GError **error);
diff --git a/libappstream-glib/as-bundle-private.h b/libappstream-glib/as-bundle-private.h
new file mode 100644
index 0000000..cc9ceac
--- /dev/null
+++ b/libappstream-glib/as-bundle-private.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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.1 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
+ */
+
+#if !defined (__APPSTREAM_GLIB_PRIVATE_H) && !defined (AS_COMPILATION)
+#error "Only <appstream-glib.h> can be included directly."
+#endif
+
+#ifndef __AS_BUNDLE_PRIVATE_H
+#define __AS_BUNDLE_PRIVATE_H
+
+#include "as-bundle.h"
+
+G_BEGIN_DECLS
+
+GNode *as_bundle_node_insert (AsBundle *bundle,
+ GNode *parent,
+ gdouble api_version);
+gboolean as_bundle_node_parse (AsBundle *bundle,
+ GNode *node,
+ GError **error);
+gboolean as_bundle_node_parse_dep11 (AsBundle *bundle,
+ GNode *node,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __AS_BUNDLE_PRIVATE_H */
diff --git a/libappstream-glib/as-bundle.c b/libappstream-glib/as-bundle.c
new file mode 100644
index 0000000..bb01bcb
--- /dev/null
+++ b/libappstream-glib/as-bundle.c
@@ -0,0 +1,286 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014-2015 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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.1 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
+ */
+
+/**
+ * SECTION:as-bundle
+ * @short_description: Object representing a single bundle used in a screenshot.
+ * @include: appstream-glib.h
+ * @stability: Stable
+ *
+ * Screenshot may have multiple versions of an bundle in different resolutions
+ * or aspect ratios. This object allows access to the location and size of a
+ * single bundle.
+ *
+ * See also: #AsScreenshot
+ */
+
+#include "config.h"
+
+#include "as-cleanup.h"
+#include "as-bundle-private.h"
+#include "as-node-private.h"
+#include "as-utils-private.h"
+#include "as-yaml.h"
+
+typedef struct _AsBundlePrivate AsBundlePrivate;
+struct _AsBundlePrivate
+{
+ AsBundleKind kind;
+ gchar *id;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (AsBundle, as_bundle, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) (as_bundle_get_instance_private (o))
+
+/**
+ * as_bundle_finalize:
+ **/
+static void
+as_bundle_finalize (GObject *object)
+{
+ AsBundle *bundle = AS_BUNDLE (object);
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+
+ g_free (priv->id);
+
+ G_OBJECT_CLASS (as_bundle_parent_class)->finalize (object);
+}
+
+/**
+ * as_bundle_init:
+ **/
+static void
+as_bundle_init (AsBundle *bundle)
+{
+}
+
+/**
+ * as_bundle_class_init:
+ **/
+static void
+as_bundle_class_init (AsBundleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = as_bundle_finalize;
+}
+
+
+/**
+ * as_bundle_kind_from_string:
+ * @kind: the string.
+ *
+ * Converts the text representation to an enumerated value.
+ *
+ * Returns: (transfer full): a #AsBundleKind, or %AS_BUNDLE_KIND_UNKNOWN for unknown.
+ *
+ * Since: 0.3.5
+ **/
+AsBundleKind
+as_bundle_kind_from_string (const gchar *kind)
+{
+ if (g_strcmp0 (kind, "limba") == 0)
+ return AS_BUNDLE_KIND_LIMBA;
+ return AS_BUNDLE_KIND_UNKNOWN;
+}
+
+/**
+ * as_bundle_kind_to_string:
+ * @kind: the #AsBundleKind.
+ *
+ * Converts the enumerated value to an text representation.
+ *
+ * Returns: string version of @kind
+ *
+ * Since: 0.3.5
+ **/
+const gchar *
+as_bundle_kind_to_string (AsBundleKind kind)
+{
+ if (kind == AS_BUNDLE_KIND_LIMBA)
+ return "limba";
+ return NULL;
+}
+
+/**
+ * as_bundle_get_id:
+ * @bundle: a #AsBundle instance.
+ *
+ * Gets the ID for this bundle.
+ *
+ * Returns: ID, e.g. "foobar-1.0.2"
+ *
+ * Since: 0.3.5
+ **/
+const gchar *
+as_bundle_get_id (AsBundle *bundle)
+{
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+ return priv->id;
+}
+
+/**
+ * as_bundle_get_kind:
+ * @bundle: a #AsBundle instance.
+ *
+ * Gets the bundle kind.
+ *
+ * Returns: the #AsBundleKind
+ *
+ * Since: 0.3.5
+ **/
+AsBundleKind
+as_bundle_get_kind (AsBundle *bundle)
+{
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+ return priv->kind;
+}
+
+/**
+ * as_bundle_set_id:
+ * @bundle: a #AsBundle instance.
+ * @id: the URL.
+ * @id_len: the size of @id, or -1 if %NULL-terminated.
+ *
+ * Sets the ID for this bundle.
+ *
+ * Since: 0.3.5
+ **/
+void
+as_bundle_set_id (AsBundle *bundle, const gchar *id, gssize id_len)
+{
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+ g_free (priv->id);
+ priv->id = as_strndup (id, id_len);
+}
+
+/**
+ * as_bundle_set_kind:
+ * @bundle: a #AsBundle instance.
+ * @kind: the #AsBundleKind, e.g. %AS_BUNDLE_KIND_THUMBNAIL.
+ *
+ * Sets the bundle kind.
+ *
+ * Since: 0.3.5
+ **/
+void
+as_bundle_set_kind (AsBundle *bundle, AsBundleKind kind)
+{
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+ priv->kind = kind;
+}
+
+/**
+ * as_bundle_node_insert: (skip)
+ * @bundle: a #AsBundle instance.
+ * @parent: the parent #GNode to use..
+ * @api_version: the AppStream API version
+ *
+ * Inserts the bundle into the DOM tree.
+ *
+ * Returns: (transfer none): A populated #GNode
+ *
+ * Since: 0.3.5
+ **/
+GNode *
+as_bundle_node_insert (AsBundle *bundle, GNode *parent, gdouble api_version)
+{
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+ GNode *n;
+
+ n = as_node_insert (parent, "bundle", priv->id,
+ AS_NODE_INSERT_FLAG_NONE,
+ "type", as_bundle_kind_to_string (priv->kind),
+ NULL);
+ return n;
+}
+
+/**
+ * as_bundle_node_parse:
+ * @bundle: a #AsBundle instance.
+ * @node: a #GNode.
+ * @error: A #GError or %NULL.
+ *
+ * Populates the object from a DOM node.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 0.3.5
+ **/
+gboolean
+as_bundle_node_parse (AsBundle *bundle, GNode *node, GError **error)
+{
+ AsBundlePrivate *priv = GET_PRIVATE (bundle);
+ const gchar *tmp;
+ gchar *taken;
+
+ tmp = as_node_get_attribute (node, "type");
+ as_bundle_set_kind (bundle, as_bundle_kind_from_string (tmp));
+ taken = as_node_take_data (node);
+ if (taken != NULL) {
+ g_free (priv->id);
+ priv->id = taken;
+ }
+ return TRUE;
+}
+
+/**
+ * as_bundle_node_parse_dep11:
+ * @bundle: a #AsBundle instance.
+ * @node: a #GNode.
+ * @error: A #GError or %NULL.
+ *
+ * Populates the object from a DEP-11 node.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 0.3.5
+ **/
+gboolean
+as_bundle_node_parse_dep11 (AsBundle *im, GNode *node, GError **error)
+{
+ GNode *n;
+ const gchar *tmp;
+
+ for (n = node->children; n != NULL; n = n->next) {
+ tmp = as_yaml_node_get_key (n);
+ if (g_strcmp0 (tmp, "id") == 0)
+ as_bundle_set_id (im, as_yaml_node_get_value (n), -1);
+ }
+ return TRUE;
+}
+
+/**
+ * as_bundle_new:
+ *
+ * Creates a new #AsBundle.
+ *
+ * Returns: (transfer full): a #AsBundle
+ *
+ * Since: 0.3.5
+ **/
+AsBundle *
+as_bundle_new (void)
+{
+ AsBundle *bundle;
+ bundle = g_object_new (AS_TYPE_BUNDLE, NULL);
+ return AS_BUNDLE (bundle);
+}
diff --git a/libappstream-glib/as-bundle.h b/libappstream-glib/as-bundle.h
new file mode 100644
index 0000000..7255f81
--- /dev/null
+++ b/libappstream-glib/as-bundle.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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.1 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
+ */
+
+#if !defined (__APPSTREAM_GLIB_H) && !defined (AS_COMPILATION)
+#error "Only <appstream-glib.h> can be included directly."
+#endif
+
+#ifndef __AS_BUNDLE_H
+#define __AS_BUNDLE_H
+
+#include <glib-object.h>
+
+#define AS_TYPE_BUNDLE (as_bundle_get_type())
+#define AS_BUNDLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AS_TYPE_BUNDLE, AsBundle))
+#define AS_BUNDLE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), AS_TYPE_BUNDLE, AsBundleClass))
+#define AS_IS_BUNDLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), AS_TYPE_BUNDLE))
+#define AS_IS_BUNDLE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), AS_TYPE_BUNDLE))
+#define AS_BUNDLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), AS_TYPE_BUNDLE, AsBundleClass))
+
+G_BEGIN_DECLS
+
+typedef struct _AsBundle AsBundle;
+typedef struct _AsBundleClass AsBundleClass;
+
+struct _AsBundle
+{
+ GObject parent;
+};
+
+struct _AsBundleClass
+{
+ GObjectClass parent_class;
+ /*< private >*/
+ void (*_as_reserved1) (void);
+ void (*_as_reserved2) (void);
+ void (*_as_reserved3) (void);
+ void (*_as_reserved4) (void);
+ void (*_as_reserved5) (void);
+ void (*_as_reserved6) (void);
+ void (*_as_reserved7) (void);
+ void (*_as_reserved8) (void);
+};
+
+/**
+ * AsBundleKind:
+ * @AS_BUNDLE_KIND_UNKNOWN: Type invalid or not known
+ * @AS_BUNDLE_KIND_LIMBA: Limba application bundle
+ *
+ * The bundle type.
+ **/
+typedef enum {
+ AS_BUNDLE_KIND_UNKNOWN,
+ AS_BUNDLE_KIND_LIMBA,
+ /*< private >*/
+ AS_BUNDLE_KIND_LAST
+} AsBundleKind;
+
+GType as_bundle_get_type (void);
+AsBundle *as_bundle_new (void);
+
+/* helpers */
+AsBundleKind as_bundle_kind_from_string (const gchar *kind);
+const gchar *as_bundle_kind_to_string (AsBundleKind kind);
+
+/* getters */
+const gchar *as_bundle_get_id (AsBundle *bundle);
+AsBundleKind as_bundle_get_kind (AsBundle *bundle);
+
+/* setters */
+void as_bundle_set_id (AsBundle *bundle,
+ const gchar *id,
+ gssize id_len);
+void as_bundle_set_kind (AsBundle *bundle,
+ AsBundleKind kind);
+
+G_END_DECLS
+
+#endif /* __AS_BUNDLE_H */
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index b62dddd..c86f9d2 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include "as-app-private.h"
+#include "as-bundle-private.h"
#include "as-cleanup.h"
#include "as-enums.h"
#include "as-icon-private.h"
@@ -614,6 +615,44 @@ as_test_image_func (void)
}
static void
+as_test_bundle_func (void)
+{
+ GError *error = NULL;
+ GNode *n;
+ GNode *root;
+ GString *xml;
+ const gchar *src =
+ "<bundle type=\"limba\">gnome-3-16</bundle>";
+ gboolean ret;
+ _cleanup_object_unref_ AsBundle *bundle = NULL;
+
+ bundle = as_bundle_new ();
+
+ /* to object */
+ root = as_node_from_xml (src, -1, 0, &error);
+ g_assert_no_error (error);
+ g_assert (root != NULL);
+ n = as_node_find (root, "bundle");
+ g_assert (n != NULL);
+ ret = as_bundle_node_parse (bundle, n, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ as_node_unref (root);
+
+ /* verify */
+ g_assert_cmpint (as_bundle_get_kind (bundle), ==, AS_BUNDLE_KIND_LIMBA);
+ g_assert_cmpstr (as_bundle_get_id (bundle), ==, "gnome-3-16");
+
+ /* back to node */
+ root = as_node_new ();
+ n = as_bundle_node_insert (bundle, root, 0.4);
+ xml = as_node_to_xml (n, AS_NODE_TO_XML_FLAG_NONE);
+ g_assert_cmpstr (xml->str, ==, src);
+ g_string_free (xml, TRUE);
+ as_node_unref (root);
+}
+
+static void
as_test_screenshot_func (void)
{
GPtrArray *images;
@@ -675,6 +714,7 @@ static void
as_test_app_func (void)
{
AsIcon *ic;
+ AsBundle *bu;
GError *error = NULL;
GNode *n;
GNode *root;
@@ -686,6 +726,7 @@ as_test_app_func (void)
"<id>org.gnome.Software.desktop</id>"
"<pkgname>gnome-software</pkgname>"
"<source_pkgname>gnome-software-src</source_pkgname>"
+ "<bundle type=\"limba\">gnome-software-gnome-3-16</bundle>"
"<name>Software</name>"
"<name xml:lang=\"pl\">Oprogramowanie</name>"
"<summary>Application manager</summary>"
@@ -784,6 +825,12 @@ as_test_app_func (void)
g_assert (icons != NULL);
g_assert_cmpint (icons->len, ==, 1);
+ /* check bundle */
+ bu = as_app_get_bundle_default (app);
+ g_assert (bu != NULL);
+ g_assert_cmpint (as_bundle_get_kind (bu), ==, AS_BUNDLE_KIND_LIMBA);
+ g_assert_cmpstr (as_bundle_get_id (bu), ==, "gnome-software-gnome-3-16");
+
/* check we can get a specific icon */
ic = as_app_get_icon_for_size (app, 999, 999);
g_assert (ic == NULL);
@@ -3167,6 +3214,7 @@ main (int argc, char **argv)
g_test_add_func ("/AppStream/release{description}", as_test_release_desc_func);
g_test_add_func ("/AppStream/icon", as_test_icon_func);
g_test_add_func ("/AppStream/icon{embedded}", as_test_icon_embedded_func);
+ g_test_add_func ("/AppStream/bundle", as_test_bundle_func);
g_test_add_func ("/AppStream/image", as_test_image_func);
g_test_add_func ("/AppStream/image{resize}", as_test_image_resize_func);
g_test_add_func ("/AppStream/image{alpha}", as_test_image_alpha_func);
diff --git a/libappstream-glib/as-tag.c b/libappstream-glib/as-tag.c
index 2cd541a..9ed5d78 100644
--- a/libappstream-glib/as-tag.c
+++ b/libappstream-glib/as-tag.c
@@ -185,6 +185,7 @@ as_tag_to_string (AsTag tag)
"source_pkgname",
"vetos",
"veto",
+ "bundle",
NULL };
if (tag > AS_TAG_LAST)
tag = AS_TAG_LAST;
diff --git a/libappstream-glib/as-tag.gperf b/libappstream-glib/as-tag.gperf
index f5a285b..019d417 100644
--- a/libappstream-glib/as-tag.gperf
+++ b/libappstream-glib/as-tag.gperf
@@ -49,3 +49,4 @@ kudo, AS_TAG_KUDO
source_pkgname, AS_TAG_SOURCE_PKGNAME
vetos, AS_TAG_VETOS
veto, AS_TAG_VETO
+bundle, AS_TAG_BUNDLE
diff --git a/libappstream-glib/as-tag.h b/libappstream-glib/as-tag.h
index 3c69dc9..45e3cbc 100644
--- a/libappstream-glib/as-tag.h
+++ b/libappstream-glib/as-tag.h
@@ -72,6 +72,7 @@
* @AS_TAG_SOURCE_PKGNAME: `source_pkgname`
* @AS_TAG_VETOS: `vetos`
* @AS_TAG_VETO: `veto`
+ * @AS_TAG_BUNDLE: `bundle`
*
* The tag type.
**/
@@ -118,6 +119,7 @@ typedef enum {
AS_TAG_SOURCE_PKGNAME, /* Since: 0.2.4 */
AS_TAG_VETOS, /* Since: 0.3.0 */
AS_TAG_VETO, /* Since: 0.3.0 */
+ AS_TAG_BUNDLE, /* Since: 0.3.5 */
/*< private >*/
AS_TAG_LAST
} AsTag;