minimal build
[platform/upstream/gcr.git] / gcr / gcr-comparable.c
1 /*
2  * gnome-keyring
3  *
4  * Copyright (C) 2010 Stefan Walter
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21
22 #include "config.h"
23
24 #include "gcr-comparable.h"
25
26 #include <string.h>
27
28 /**
29  * SECTION:gcr-comparable
30  * @title: GcrComparable
31  * @short_description: Interface for comparing objects
32  *
33  * The #GcrComparable interface is implemented by objects when they should be
34  * comparable against one another.
35  */
36
37 /**
38  * GcrComparable:
39  *
40  * The #GcrComparable interface is implemented by comparable objects.
41  */
42
43 /**
44  * GcrComparableIface:
45  *
46  * The interface to implement for #GcrComparable
47  */
48
49 /* ---------------------------------------------------------------------------------
50  * INTERFACE
51  */
52
53 static void
54 gcr_comparable_base_init (gpointer g_class)
55 {
56         static volatile gsize initialized = 0;
57
58         if (g_once_init_enter (&initialized)) {
59                 /* Add properties and signals to the interface */
60                 g_once_init_leave (&initialized, 1);
61         }
62 }
63
64 GType
65 gcr_comparable_get_type (void)
66 {
67         static GType type = 0;
68         if (!type) {
69                 static const GTypeInfo info = {
70                         sizeof (GcrComparableIface),
71                         gcr_comparable_base_init,               /* base init */
72                         NULL,             /* base finalize */
73                         NULL,             /* class_init */
74                         NULL,             /* class finalize */
75                         NULL,             /* class data */
76                         0,
77                         0,                /* n_preallocs */
78                         NULL,             /* instance init */
79                 };
80                 type = g_type_register_static (G_TYPE_INTERFACE, "GcrComparableIface", &info, 0);
81                 g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
82         }
83
84         return type;
85 }
86
87
88 /* -----------------------------------------------------------------------------
89  * PUBLIC
90  */
91
92 /**
93  * gcr_comparable_compare:
94  * @self: The comparable object
95  * @other: Another comparable object
96  *
97  * Compare whether two objects represent the same thing. The return value can
98  * also be used to sort the objects.
99  *
100  * Returns: Zero if the two objects represent the same thing, non-zero if not.
101  */
102 gint
103 gcr_comparable_compare (GcrComparable *self, GcrComparable *other)
104 {
105         g_return_val_if_fail (GCR_IS_COMPARABLE (self), -1);
106         g_return_val_if_fail (GCR_COMPARABLE_GET_INTERFACE (self)->compare, -1);
107         g_return_val_if_fail (G_IS_OBJECT (self), -1);
108         return GCR_COMPARABLE_GET_INTERFACE (self)->compare (self, other);
109 }
110
111 /**
112  * gcr_comparable_memcmp: (skip)
113  * @mem1: First block of memory
114  * @size1: Length of first block
115  * @mem2: Second lock of memory
116  * @size2: Length of second block
117  *
118  * Compare two blocks of memory. The return value can be used to sort
119  * the blocks of memory.
120  *
121  * Returns: Zero if the blocks are identical, non-zero if not.
122  */
123 gint
124 gcr_comparable_memcmp (gconstpointer mem1, gsize size1,
125                        gconstpointer mem2, gsize size2)
126 {
127         gint result;
128
129         if (mem1 == mem2 && size1 == size2)
130                 return 0;
131
132         if (!mem1)
133                 return 1;
134         if (!mem2)
135                 return -1;
136
137         result = memcmp (mem1, mem2, MIN (size1, size2));
138         if (result != 0)
139                 return result;
140
141         if (size1 == size2)
142                 return 0;
143         if (size1 < size2)
144                 return -1;
145         return 1;
146 }