[gnome-keyring] gcr: Display photo as icon for Gnupg keys.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: Display photo as icon for Gnupg keys.
- Date: Tue, 12 Jul 2011 12:54:21 +0000 (UTC)
commit 9938f392505415b5d8c622424a9c57e492c43298
Author: Stef Walter <stefw collabora co uk>
Date: Fri May 13 21:30:29 2011 +0200
gcr: Display photo as icon for Gnupg keys.
* Load the first photo uid and use as icon for Gnupg Keys.
* Add GcrMemoryIcon which is a GLoadableIcon which loads from
data in memory.
https://bugzilla.gnome.org/show_bug.cgi?id=650433
.gitignore | 1 +
docs/reference/gcr/gcr-sections.txt | 10 ++
gcr/Makefile.am | 1 +
gcr/gcr-gnupg-key.c | 85 ++++++++++++++-
gcr/gcr-gnupg-key.h | 2 +
gcr/gcr-memory-icon.c | 195 +++++++++++++++++++++++++++++++++
gcr/gcr-memory-icon.h | 67 +++++++++++
gcr/gcr-record.c | 14 +++
gcr/gcr-record.h | 4 +
gcr/tests/Makefile.am | 1 +
gcr/tests/test-memory-icon.c | 206 +++++++++++++++++++++++++++++++++++
gcr/tests/test-record.c | 18 +++-
12 files changed, 599 insertions(+), 5 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index fac973e..1721d51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -126,6 +126,7 @@ run-tests
/gcr/tests/test-gnupg-collection
/gcr/tests/test-gnupg-key
/gcr/tests/test-gnupg-process
+/gcr/tests/test-memory-icon
/gcr/tests/test-parser
/gcr/tests/test-pkcs11-certificate
/gcr/tests/test-record
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index 8d8b22b..adbdb3f 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -498,4 +498,14 @@ GcrGnupgKey
GcrGnupgKeyClass
GcrGnupgKeyPrivate
GcrLineCallback
+GCR_IS_MEMORY_ICON
+GCR_IS_MEMORY_ICON_CLASS
+GCR_MEMORY_ICON
+GCR_MEMORY_ICON_CLASS
+GCR_MEMORY_ICON_COLUMNS
+GCR_MEMORY_ICON_GET_CLASS
+GCR_TYPE_MEMORY_ICON
+GcrMemoryIcon
+GcrMemoryIconClass
+GcrMemoryIconPrivate
</SECTION>
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 496f9d3..a6164df 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -99,6 +99,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-key-renderer.c gcr-key-renderer.h \
gcr-key-widget.c gcr-key-widget.h \
gcr-library.c gcr-library.h \
+ gcr-memory-icon.c gcr-memory-icon.h \
gcr-parser.c gcr-parser.h \
gcr-pkcs11-certificate.c gcr-pkcs11-certificate.h \
gcr-record.c gcr-record.h \
diff --git a/gcr/gcr-gnupg-key.c b/gcr/gcr-gnupg-key.c
index 3bf768f..1274ec6 100644
--- a/gcr/gcr-gnupg-key.c
+++ b/gcr/gcr-gnupg-key.c
@@ -21,8 +21,9 @@
#include "config.h"
-#include "gcr-record.h"
#include "gcr-gnupg-key.h"
+#include "gcr-record.h"
+#include "gcr-memory-icon.h"
#include "gck/gck.h"
@@ -37,12 +38,14 @@ enum {
PROP_LABEL,
PROP_MARKUP,
PROP_DESCRIPTION,
- PROP_SHORT_KEYID
+ PROP_SHORT_KEYID,
+ PROP_ICON
};
struct _GcrGnupgKeyPrivate {
GPtrArray *public_records;
GPtrArray *secret_records;
+ GIcon *icon;
};
G_DEFINE_TYPE (GcrGnupgKey, _gcr_gnupg_key, G_TYPE_OBJECT);
@@ -159,6 +162,9 @@ _gcr_gnupg_key_get_property (GObject *obj, guint prop_id, GValue *value,
case PROP_SHORT_KEYID:
g_value_set_string (value, calculate_short_keyid (self));
break;
+ case PROP_ICON:
+ g_value_set_object (value, _gcr_gnupg_key_get_icon (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -240,6 +246,15 @@ _gcr_gnupg_key_class_init (GcrGnupgKeyClass *klass)
g_object_class_install_property (gobject_class, PROP_SHORT_KEYID,
g_param_spec_string ("short-keyid", "Short Key ID", "Display key identifier",
"", G_PARAM_READABLE));
+
+ /**
+ * GcrGnupgKey::icon:
+ *
+ * Icon for this key.
+ */
+ g_object_class_install_property (gobject_class, PROP_ICON,
+ g_param_spec_object ("icon", "Icon", "Icon for this key",
+ G_TYPE_ICON, G_PARAM_READABLE));
}
/**
@@ -421,6 +436,66 @@ _gcr_gnupg_key_get_fingerprint_for_records (GPtrArray *records)
return NULL;
}
+#define TYPE_IMAGE 0x01
+#define IMAGE_HEADER_LEN 0x10
+#define IMAGE_JPEG_SIG "\x10\x00\x01\x01"
+#define IMAGE_JPEG_SIG_LEN 4
+
+static GIcon*
+load_user_attribute_icon (GcrGnupgKey *self)
+{
+ GcrRecord *record;
+ guchar *data;
+ gsize n_data;
+ guint type;
+ guint i;
+
+ for (i = 0; i < self->pv->public_records->len; i++) {
+ record = self->pv->public_records->pdata[i];
+ if (GCR_RECORD_SCHEMA_XA1 != _gcr_record_get_schema (record))
+ continue;
+ if (!_gcr_record_get_uint (record, GCR_RECORD_XA1_TYPE, &type))
+ continue;
+ if (type != TYPE_IMAGE)
+ continue;
+
+ /* TODO: Validity? */
+
+ data = _gcr_record_get_base64 (record, GCR_RECORD_XA1_DATA, &n_data);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ /* Header is 16 bytes long */
+ if (n_data <= IMAGE_HEADER_LEN)
+ continue;
+
+ /* These are the header bytes. See gnupg doc/DETAILS */
+ g_assert (IMAGE_JPEG_SIG_LEN < IMAGE_HEADER_LEN);
+ if (memcmp (data, IMAGE_JPEG_SIG, IMAGE_JPEG_SIG_LEN) != 0)
+ continue;
+
+ /* We have a valid header */
+ return G_ICON (_gcr_memory_icon_new_full ("image/jpeg", data,
+ n_data, IMAGE_HEADER_LEN,
+ g_free));
+ }
+
+ return NULL;
+}
+
+GIcon*
+_gcr_gnupg_key_get_icon (GcrGnupgKey *self)
+{
+ g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
+
+ if (self->pv->icon == NULL) {
+ self->pv->icon = load_user_attribute_icon (self);
+ if (self->pv->icon == NULL)
+ self->pv->icon = g_themed_icon_new ("folder"); /* TODO: proper icon */
+ }
+
+ return self->pv->icon;
+}
+
/**
* _gcr_gnupg_key_get_columns:
*
@@ -432,12 +507,14 @@ const GcrColumn*
_gcr_gnupg_key_get_columns (void)
{
static GcrColumn columns[] = {
+ { "icon", /* later */ 0, /* later */ 0, NULL, 0, NULL, 0 },
{ "label", G_TYPE_STRING, G_TYPE_STRING, NC_("column", "Name"),
- GCR_COLUMN_SORTABLE },
+ GCR_COLUMN_SORTABLE, NULL, 0 },
{ "short-keyid", G_TYPE_STRING, G_TYPE_STRING, NC_("column", "Key ID"),
- GCR_COLUMN_SORTABLE },
+ GCR_COLUMN_SORTABLE, NULL, 0 },
{ NULL }
};
+ columns[0].property_type = columns[0].column_type = G_TYPE_ICON;
return columns;
}
diff --git a/gcr/gcr-gnupg-key.h b/gcr/gcr-gnupg-key.h
index 271bb90..745bec2 100644
--- a/gcr/gcr-gnupg-key.h
+++ b/gcr/gcr-gnupg-key.h
@@ -76,6 +76,8 @@ GPtrArray* _gcr_gnupg_key_get_secret_records (GcrGnupgKey *s
void _gcr_gnupg_key_set_secret_records (GcrGnupgKey *self,
GPtrArray *records);
+GIcon* _gcr_gnupg_key_get_icon (GcrGnupgKey *self);
+
const gchar* _gcr_gnupg_key_get_keyid_for_records (GPtrArray *records);
const gchar* _gcr_gnupg_key_get_fingerprint_for_records (GPtrArray *records);
diff --git a/gcr/gcr-memory-icon.c b/gcr/gcr-memory-icon.c
new file mode 100644
index 0000000..83fb5ea
--- /dev/null
+++ b/gcr/gcr-memory-icon.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program 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 program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#include "config.h"
+
+#include "gcr-memory-icon.h"
+
+#include <string.h>
+
+struct _GcrMemoryIconPrivate {
+ gpointer data;
+ gsize n_data;
+ goffset offset;
+ gchar *image_type;
+ GDestroyNotify destroy;
+};
+
+/* Forward declarations */
+static void _gcr_memory_icon_iface_icon (GIconIface *iface);
+static void _gcr_memory_icon_iface_loadable_icon (GLoadableIconIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrMemoryIcon, _gcr_memory_icon, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_ICON, _gcr_memory_icon_iface_icon);
+ G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, _gcr_memory_icon_iface_loadable_icon);
+);
+
+
+static void
+_gcr_memory_icon_init (GcrMemoryIcon *self)
+{
+ self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_MEMORY_ICON, GcrMemoryIconPrivate));
+}
+
+static void
+_gcr_memory_icon_finalize (GObject *obj)
+{
+ GcrMemoryIcon *self = GCR_MEMORY_ICON (obj);
+
+ if (self->pv->destroy)
+ (self->pv->destroy) (self->pv->data);
+ g_free (self->pv->image_type);
+
+ G_OBJECT_CLASS (_gcr_memory_icon_parent_class)->finalize (obj);
+}
+
+static void
+_gcr_memory_icon_class_init (GcrMemoryIconClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ _gcr_memory_icon_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GcrMemoryIconPrivate));
+
+ gobject_class->finalize = _gcr_memory_icon_finalize;
+}
+
+static gboolean
+_gcr_memory_icon_equal (GIcon *icon1, GIcon *icon2)
+{
+ GcrMemoryIcon *one = GCR_MEMORY_ICON (icon1);
+ GcrMemoryIcon *two = GCR_MEMORY_ICON (icon2);
+
+ if (icon1 == icon2)
+ return TRUE;
+ if (!g_str_equal (one->pv->image_type, two->pv->image_type))
+ return FALSE;
+ if ((one->pv->n_data - one->pv->offset) != (two->pv->n_data - two->pv->offset))
+ return FALSE;
+ return memcmp ((guchar*)one->pv->data + one->pv->offset,
+ (guchar*)two->pv->data + two->pv->offset,
+ one->pv->n_data - one->pv->offset) == 0;
+}
+
+static guint
+_gcr_memory_icon_hash (GIcon *icon)
+{
+ GcrMemoryIcon *self = GCR_MEMORY_ICON (icon);
+ const signed char *p, *end;
+ guint32 hash;
+
+ hash = g_str_hash (self->pv->image_type);
+
+ /* Adapted from g_str_hash */
+ p = self->pv->data;
+ end = p + self->pv->n_data;
+ p += self->pv->offset;
+ while (p < end)
+ hash = (hash << 5) + hash + *(p++);
+
+ return hash;
+}
+
+static void
+_gcr_memory_icon_iface_icon (GIconIface *iface)
+{
+ iface->equal = _gcr_memory_icon_equal;
+ iface->hash = _gcr_memory_icon_hash;
+}
+
+static GInputStream *
+_gcr_memory_icon_load (GLoadableIcon *icon, int size, gchar **type,
+ GCancellable *cancellable, GError **error)
+{
+ GcrMemoryIcon *self = GCR_MEMORY_ICON (icon);
+ GInputStream *is;
+
+ if (type != NULL)
+ *type = g_strdup (self->pv->image_type);
+
+ is = g_memory_input_stream_new_from_data ((guchar*)self->pv->data + self->pv->offset,
+ self->pv->n_data, NULL);
+ g_object_set_data_full (G_OBJECT (is), "back-reference", g_object_ref (self),
+ g_object_unref);
+
+ return is;
+}
+
+static void
+_gcr_memory_icon_load_async (GLoadableIcon *icon, int size, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ res = g_simple_async_result_new (G_OBJECT (icon), callback, user_data,
+ _gcr_memory_icon_load_async);
+
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+}
+
+static GInputStream*
+_gcr_memory_icon_finish (GLoadableIcon *icon, GAsyncResult *res, char **type,
+ GError **error)
+{
+ g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (icon),
+ _gcr_memory_icon_load_async), NULL);
+ return _gcr_memory_icon_load (icon, 0, type, NULL, error);
+}
+
+
+static void
+_gcr_memory_icon_iface_loadable_icon (GLoadableIconIface *iface)
+{
+ iface->load = _gcr_memory_icon_load;
+ iface->load_async = _gcr_memory_icon_load_async;
+ iface->load_finish = _gcr_memory_icon_finish;
+}
+
+GIcon*
+_gcr_memory_icon_new (const gchar *image_type, gconstpointer data, gsize n_data)
+{
+ g_return_val_if_fail (image_type != NULL, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ return _gcr_memory_icon_new_full (image_type, g_memdup (data, n_data),
+ n_data, 0, g_free);
+}
+
+GIcon*
+_gcr_memory_icon_new_full (const gchar *image_type, gpointer data, gsize n_data,
+ goffset offset, GDestroyNotify destroy)
+{
+ GcrMemoryIcon *self;
+
+ g_return_val_if_fail (image_type != NULL, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (offset <= n_data, NULL);
+
+ self = g_object_new (GCR_TYPE_MEMORY_ICON, NULL);
+ self->pv->data = data;
+ self->pv->n_data = n_data;
+ self->pv->offset = offset;
+ self->pv->destroy = destroy;
+ self->pv->image_type = g_strdup (image_type);
+
+ return G_ICON (self);
+}
diff --git a/gcr/gcr-memory-icon.h b/gcr/gcr-memory-icon.h
new file mode 100644
index 0000000..c02767f
--- /dev/null
+++ b/gcr/gcr-memory-icon.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program 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 program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef GCR_MEMORY_ICON_H
+#define GCR_MEMORY_ICON_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GCR_MEMORY_ICON_COLUMNS (_gcr_memory_icon_get_columns ())
+#define GCR_TYPE_MEMORY_ICON (_gcr_memory_icon_get_type ())
+#define GCR_MEMORY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_MEMORY_ICON, GcrMemoryIcon))
+#define GCR_MEMORY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_MEMORY_ICON, GcrMemoryIconClass))
+#define GCR_IS_MEMORY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_MEMORY_ICON))
+#define GCR_IS_MEMORY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_MEMORY_ICON))
+#define GCR_MEMORY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_MEMORY_ICON, GcrMemoryIconClass))
+
+typedef struct _GcrMemoryIcon GcrMemoryIcon;
+typedef struct _GcrMemoryIconClass GcrMemoryIconClass;
+typedef struct _GcrMemoryIconPrivate GcrMemoryIconPrivate;
+
+struct _GcrMemoryIcon {
+ GObject parent;
+
+ /*< private >*/
+ GcrMemoryIconPrivate *pv;
+};
+
+struct _GcrMemoryIconClass {
+ GObjectClass parent_class;
+};
+
+GType _gcr_memory_icon_get_type (void);
+
+GIcon* _gcr_memory_icon_new (const gchar *image_type,
+ gconstpointer data,
+ gsize n_data);
+
+GIcon* _gcr_memory_icon_new_full (const gchar *image_type,
+ gpointer data,
+ gsize n_data,
+ goffset offset,
+ GDestroyNotify destroy);
+
+G_END_DECLS
+
+#endif /* __GCR_MEMORY_ICON_H__ */
diff --git a/gcr/gcr-record.c b/gcr/gcr-record.c
index cd33b2d..a417d0d 100644
--- a/gcr/gcr-record.c
+++ b/gcr/gcr-record.c
@@ -216,6 +216,20 @@ _gcr_record_get_uint (GcrRecord *record, guint column, guint *value)
return TRUE;
}
+gpointer
+_gcr_record_get_base64 (GcrRecord *record, guint column, gsize *n_data)
+{
+ const gchar *raw;
+
+ g_return_val_if_fail (record, NULL);
+
+ raw = _gcr_record_get_raw (record, column);
+ if (raw == NULL)
+ return NULL;
+
+ return g_base64_decode (raw, n_data);
+}
+
const gchar*
_gcr_record_get_raw (GcrRecord *record, guint column)
{
diff --git a/gcr/gcr-record.h b/gcr/gcr-record.h
index 5b1b69a..937ef75 100644
--- a/gcr/gcr-record.h
+++ b/gcr/gcr-record.h
@@ -155,6 +155,10 @@ gboolean _gcr_record_get_uint (GcrRecord *record,
guint column,
guint *value);
+gpointer _gcr_record_get_base64 (GcrRecord *record,
+ guint column,
+ gsize *n_data);
+
const gchar* _gcr_record_get_raw (GcrRecord *record,
guint column);
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index e2ece38..91fd093 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -29,6 +29,7 @@ TEST_PROGS = \
test-trust \
test-parser \
test-record \
+ test-memory-icon \
test-gnupg-key \
test-gnupg-collection \
test-gnupg-process
diff --git a/gcr/tests/test-memory-icon.c b/gcr/tests/test-memory-icon.c
new file mode 100644
index 0000000..ebf200b
--- /dev/null
+++ b/gcr/tests/test-memory-icon.c
@@ -0,0 +1,206 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ Copyright (C) 2011 Collabora Ltd
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw collabora co uk>
+*/
+
+#include "config.h"
+
+#include "gcr/gcr-memory-icon.h"
+
+#include "egg/egg-testing.h"
+
+#include <glib.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ GIcon *icon;
+ GAsyncResult *result;
+} Test;
+
+static const unsigned char test_data[256] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
+};
+
+static void
+setup (Test *test, gconstpointer unused)
+{
+ test->icon = _gcr_memory_icon_new ("application/octet-stream",
+ test_data, sizeof (test_data));
+}
+
+static void
+teardown (Test *test, gconstpointer unused)
+{
+ g_object_unref (test->icon);
+ if (test->result)
+ g_object_unref (test->result);
+}
+
+static void
+test_equal_same (Test *test, gconstpointer unused)
+{
+ g_assert (g_icon_equal (test->icon, test->icon) == TRUE);
+}
+
+static void
+test_equal_not (Test *test, gconstpointer unused)
+{
+ GIcon *icon;
+
+ icon = g_themed_icon_new ("folder");
+ g_assert (g_icon_equal (test->icon, icon) == FALSE);
+ g_object_unref (icon);
+}
+
+static void
+test_equal_data (Test *test, gconstpointer unused)
+{
+ GIcon *icon;
+
+ icon = _gcr_memory_icon_new ("application/octet-stream",
+ test_data, sizeof (test_data));
+ g_assert (g_icon_equal (test->icon, icon) == TRUE);
+ g_assert_cmpuint (g_icon_hash (test->icon), ==, g_icon_hash (icon));
+ g_object_unref (icon);
+}
+
+static void
+test_different_type (Test *test, gconstpointer unused)
+{
+ GIcon *icon;
+
+ icon = _gcr_memory_icon_new ("application/x-other",
+ test_data, sizeof (test_data));
+ g_assert (g_icon_equal (test->icon, icon) == FALSE);
+ g_assert_cmpuint (g_icon_hash (test->icon), !=, g_icon_hash (icon));
+ g_object_unref (icon);
+}
+
+static void
+test_different_offset (Test *test, gconstpointer unused)
+{
+ GIcon *icon;
+
+ icon = _gcr_memory_icon_new_full ("application/octet-stream", (gpointer)test_data,
+ sizeof (test_data) - 16, 16, NULL);
+ g_assert (g_icon_equal (test->icon, icon) == FALSE);
+ g_assert_cmpuint (g_icon_hash (test->icon), !=, g_icon_hash (icon));
+ g_object_unref (icon);
+}
+
+static void
+test_load_sync (Test *test, gconstpointer unused)
+{
+ GError *error = NULL;
+ GInputStream *is;
+ gchar buf[1024];
+ gsize length;
+ gchar *type;
+
+ is = g_loadable_icon_load (G_LOADABLE_ICON (test->icon), 0, &type, NULL, &error);
+ g_assert (is != NULL);
+ g_assert_no_error (error);
+ g_assert_cmpstr (type, ==, "application/octet-stream");
+
+ if (!g_input_stream_read_all (is, buf, sizeof (buf), &length, NULL, &error))
+ g_assert_not_reached ();
+ g_assert_no_error (error);
+ egg_assert_cmpsize (length, ==, sizeof (test_data));
+ egg_assert_cmpmem (buf, length, ==, test_data, sizeof (test_data));
+
+ g_free (type);
+ g_object_unref (is);
+}
+
+static void
+on_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Test *test = user_data;
+
+ g_assert (G_OBJECT (test->icon) == source);
+ g_assert (test->result == NULL);
+ g_assert (g_async_result_get_source_object (result) == source);
+
+ test->result = g_object_ref (result);
+ egg_test_wait_stop ();
+}
+
+static void
+test_load_async (Test *test, gconstpointer unused)
+{
+ GError *error = NULL;
+ GInputStream *is;
+ gchar buf[1024];
+ gsize length;
+ gchar *type;
+
+ g_loadable_icon_load_async (G_LOADABLE_ICON (test->icon), 0, NULL, on_async_ready, test);
+ egg_test_wait_until (500);
+
+ g_assert (test->result);
+ is = g_loadable_icon_load_finish (G_LOADABLE_ICON (test->icon), test->result, &type, &error);
+ g_assert (is != NULL);
+ g_assert_no_error (error);
+ g_assert_cmpstr (type, ==, "application/octet-stream");
+
+ if (!g_input_stream_read_all (is, buf, sizeof (buf), &length, NULL, &error))
+ g_assert_not_reached ();
+ g_assert_no_error (error);
+ egg_assert_cmpsize (length, ==, sizeof (test_data));
+ egg_assert_cmpmem (buf, length, ==, test_data, sizeof (test_data));
+
+ g_free (type);
+ g_object_unref (is);
+}
+
+int
+main (int argc, char **argv)
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add ("/gcr/memory-icon/equal_same", Test, NULL, setup, test_equal_same, teardown);
+ g_test_add ("/gcr/memory-icon/equal_not", Test, NULL, setup, test_equal_not, teardown);
+ g_test_add ("/gcr/memory-icon/equal_data", Test, NULL, setup, test_equal_data, teardown);
+ g_test_add ("/gcr/memory-icon/different_type", Test, NULL, setup, test_different_type, teardown);
+ g_test_add ("/gcr/memory-icon/different_offset", Test, NULL, setup, test_different_offset, teardown);
+ g_test_add ("/gcr/memory-icon/load_sync", Test, NULL, setup, test_load_sync, teardown);
+ g_test_add ("/gcr/memory-icon/load_async", Test, NULL, setup, test_load_async, teardown);
+
+ return egg_tests_run_in_thread_with_loop ();
+}
diff --git a/gcr/tests/test-record.c b/gcr/tests/test-record.c
index 265d677..4c132ff 100644
--- a/gcr/tests/test-record.c
+++ b/gcr/tests/test-record.c
@@ -35,7 +35,7 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
- test->record = _gcr_record_parse_colons ("one:tab\\there::four:f\xfc""nf:3533333:-88", -1);
+ test->record = _gcr_record_parse_colons ("one:tab\\there::YW9ldTM4Mzg=:f\xfc""nf:3533333:-88", -1);
}
static void
@@ -215,6 +215,21 @@ test_get_uint_invalid (Test *test, gconstpointer unused)
}
static void
+test_get_base64 (Test *test, gconstpointer unused)
+{
+ gchar *value;
+ gsize n_value;
+
+ value = _gcr_record_get_base64 (test->record, 3, &n_value);
+ g_assert (value);
+ egg_assert_cmpsize (n_value, ==, 8);
+ g_assert (memcmp (value, "aoeu3838", n_value) == 0);
+
+ g_free (value);
+}
+
+
+static void
test_free_null (void)
{
_gcr_record_free (NULL);
@@ -294,6 +309,7 @@ main (int argc, char **argv)
g_test_add ("/gcr/record/get_uint", Test, NULL, setup, test_get_uint, teardown);
g_test_add ("/gcr/record/get_uint_invalid", Test, NULL, setup, test_get_uint_invalid, teardown);
g_test_add ("/gcr/record/get_uint_range", Test, NULL, setup, test_get_uint_range, teardown);
+ g_test_add ("/gcr/record/get_base64", Test, NULL, setup, test_get_base64, teardown);
g_test_add ("/gcr/record/get_schema", Test, NULL, setup, test_get_schema, teardown);
return g_test_run ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]