1 /*
2 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
3 * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
4 *
5 * This library is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include "evolution-data-server-config.h"
20
21 /**
22 * SECTION:e-cal-component-id
23 * @short_description: An ECalComponentId structure
24 * @include: libecal/libecal.h
25 *
26 * Contains functions to work with the #ECalComponentId structure.
27 **/
28
29 #include "e-cal-component-id.h"
30
31 G_DEFINE_BOXED_TYPE (ECalComponentId, e_cal_component_id, e_cal_component_id_copy, e_cal_component_id_free)
32
33 struct _ECalComponentId {
34 gchar *uid;
35 gchar *rid;
36 };
37
38 /**
39 * e_cal_component_id_new:
40 * @uid: a unique ID string
41 * @rid: (nullable): an optional recurrence ID string
42 *
43 * Creates a new #ECalComponentId from @uid and @rid, which should be
44 * freed with e_cal_component_id_free().
45 *
46 * Returns: (transfer full): an #ECalComponentId
47 *
48 * Since: 3.10
49 **/
50 ECalComponentId *
e_cal_component_id_new(const gchar * uid,const gchar * rid)51 e_cal_component_id_new (const gchar *uid,
52 const gchar *rid)
53 {
54 g_return_val_if_fail (uid != NULL, NULL);
55
56 /* Normalize an empty recurrence ID to NULL. */
57 if (rid && !*rid)
58 rid = NULL;
59
60 return e_cal_component_id_new_take (g_strdup (uid), g_strdup (rid));
61 }
62
63 /**
64 * e_cal_component_id_new_take:
65 * @uid: (transfer full): a unique ID string
66 * @rid: (transfer full) (nullable): an optional recurrence ID string
67 *
68 * Creates a new #ECalComponentId from @uid and @rid, which should be
69 * freed with e_cal_component_id_free(). The function assumes ownership
70 * of @uid and @rid parameters.
71 *
72 * Returns: (transfer full): an #ECalComponentId
73 *
74 * Since: 3.34
75 **/
76 ECalComponentId *
e_cal_component_id_new_take(gchar * uid,gchar * rid)77 e_cal_component_id_new_take (gchar *uid,
78 gchar *rid)
79 {
80 ECalComponentId *id;
81
82 g_return_val_if_fail (uid != NULL, NULL);
83
84 /* Normalize an empty recurrence ID to NULL. */
85 if (rid && !*rid) {
86 g_free (rid);
87 rid = NULL;
88 }
89
90 id = g_slice_new0 (ECalComponentId);
91 id->uid = uid;
92 id->rid = rid;
93
94 return id;
95 }
96
97 /**
98 * e_cal_component_id_copy:
99 * @id: (not nullable): an #ECalComponentId
100 *
101 * Returns a newly allocated copy of @id, which should be freed with
102 * e_cal_component_id_free().
103 *
104 * Returns: (transfer full): a newly allocated copy of @id
105 *
106 * Since: 3.10
107 **/
108 ECalComponentId *
e_cal_component_id_copy(const ECalComponentId * id)109 e_cal_component_id_copy (const ECalComponentId *id)
110 {
111 g_return_val_if_fail (id != NULL, NULL);
112
113 return e_cal_component_id_new (id->uid, id->rid);
114 }
115
116 /**
117 * e_cal_component_id_free: (skip)
118 * @id: (type ECalComponentId) (transfer full) (nullable): an #ECalComponentId
119 *
120 * Free the @id, previously created by e_cal_component_id_new(),
121 * e_cal_component_id_new_take() or e_cal_component_id_copy().
122 **/
123 void
e_cal_component_id_free(gpointer id)124 e_cal_component_id_free (gpointer id)
125 {
126 ECalComponentId *eid = id;
127
128 if (eid) {
129 g_free (eid->uid);
130 g_free (eid->rid);
131 g_slice_free (ECalComponentId, eid);
132 }
133 }
134
135 /**
136 * e_cal_component_id_hash:
137 * @id: (type ECalComponentId): an #ECalComponentId
138 *
139 * Generates a hash value for @id.
140 *
141 * Returns: a hash value for @id
142 *
143 * Since: 3.10
144 **/
145 guint
e_cal_component_id_hash(gconstpointer id)146 e_cal_component_id_hash (gconstpointer id)
147 {
148 const ECalComponentId *eid = id;
149 guint uid_hash;
150 guint rid_hash;
151
152 g_return_val_if_fail (id != NULL, 0);
153
154 uid_hash = g_str_hash (eid->uid);
155 rid_hash = eid->rid ? g_str_hash (eid->rid) : 0;
156
157 return uid_hash ^ rid_hash;
158 }
159
160 /**
161 * e_cal_component_id_equal:
162 * @id1: (type ECalComponentId): the first #ECalComponentId
163 * @id2: (type ECalComponentId): the second #ECalComponentId
164 *
165 * Compares two #ECalComponentId structs for equality.
166 *
167 * Returns: %TRUE if @id1 and @id2 are equal
168 *
169 * Since: 3.10
170 **/
171 gboolean
e_cal_component_id_equal(gconstpointer id1,gconstpointer id2)172 e_cal_component_id_equal (gconstpointer id1,
173 gconstpointer id2)
174 {
175 const ECalComponentId *eid1 = id1, *eid2 = id2;
176 gboolean uids_equal;
177 gboolean rids_equal;
178
179 if (id1 == id2)
180 return TRUE;
181
182 /* Safety check before we dereference. */
183 g_return_val_if_fail (id1 != NULL, FALSE);
184 g_return_val_if_fail (id2 != NULL, FALSE);
185
186 uids_equal = (g_strcmp0 (eid1->uid, eid2->uid) == 0);
187 rids_equal = (g_strcmp0 (eid1->rid, eid2->rid) == 0);
188
189 return uids_equal && rids_equal;
190 }
191
192 /**
193 * e_cal_component_id_get_uid:
194 * @id: an #ECalComponentId
195 *
196 * Returns: (transfer none): The UID part of the @id. The returned
197 * string is owned by @id and it's valid until it's changed
198 * with e_cal_component_id_set_uid() or until the @id is freed.
199 *
200 * Since: 3.34
201 **/
202 const gchar *
e_cal_component_id_get_uid(const ECalComponentId * id)203 e_cal_component_id_get_uid (const ECalComponentId *id)
204 {
205 g_return_val_if_fail (id != NULL, NULL);
206
207 return id->uid;
208 }
209
210 /**
211 * e_cal_component_id_set_uid:
212 * @id: an #ECalComponentId
213 * @uid: (not nullable): the UID to set
214 *
215 * Sets the UID part of the @id.
216 *
217 * Since: 3.34
218 **/
219 void
e_cal_component_id_set_uid(ECalComponentId * id,const gchar * uid)220 e_cal_component_id_set_uid (ECalComponentId *id,
221 const gchar *uid)
222 {
223 g_return_if_fail (id != NULL);
224 g_return_if_fail (uid != NULL);
225
226 if (g_strcmp0 (id->uid, uid) != 0) {
227 g_free (id->uid);
228 id->uid = g_strdup (uid);
229 }
230 }
231
232 /**
233 * e_cal_component_id_get_rid:
234 * @id: an #ECalComponentId
235 *
236 * Returns: (transfer none) (nullable): The RECURRENCE-ID part of the @id.
237 * The returned string is owned by @id and it's valid until it's
238 * changed with e_cal_component_id_set_rid() or until the @id is freed.
239 *
240 * Since: 3.34
241 **/
242 const gchar *
e_cal_component_id_get_rid(const ECalComponentId * id)243 e_cal_component_id_get_rid (const ECalComponentId *id)
244 {
245 g_return_val_if_fail (id != NULL, NULL);
246
247 return id->rid;
248 }
249
250 /**
251 * e_cal_component_id_set_rid:
252 * @id: an #ECalComponentId
253 * @rid: (nullable): the RECURRENCE-ID to set
254 *
255 * Sets the RECURRENCE-ID part of the @id. The @rid can be %NULL
256 * or an empty string, where both are treated as %NULL, which
257 * means the @id has not RECURRENCE-ID.
258 *
259 * Since: 3.34
260 **/
261 void
e_cal_component_id_set_rid(ECalComponentId * id,const gchar * rid)262 e_cal_component_id_set_rid (ECalComponentId *id,
263 const gchar *rid)
264 {
265 g_return_if_fail (id != NULL);
266
267 if (g_strcmp0 (id->rid, rid) != 0) {
268 g_free (id->rid);
269 id->rid = (rid && *rid) ? g_strdup (rid) : NULL;
270 }
271 }
272