1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * SPDX-FileCopyrightText: (C) 2016 Red Hat, Inc. (www.redhat.com)
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include <stdio.h>
12
13 #include "camel/camel.h"
14 #include "camel-ews-summary.h"
15
16 #include "camel-ews-message-info.h"
17
18 struct _CamelEwsMessageInfoPrivate {
19 guint32 server_flags;
20 gint32 item_type;
21 gchar *change_key;
22 };
23
24 enum {
25 PROP_0,
26 PROP_SERVER_FLAGS,
27 PROP_ITEM_TYPE,
28 PROP_CHANGE_KEY,
29 };
30
G_DEFINE_TYPE_WITH_PRIVATE(CamelEwsMessageInfo,camel_ews_message_info,CAMEL_TYPE_MESSAGE_INFO_BASE)31 G_DEFINE_TYPE_WITH_PRIVATE (CamelEwsMessageInfo, camel_ews_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
32
33 static CamelMessageInfo *
34 ews_message_info_clone (const CamelMessageInfo *mi,
35 CamelFolderSummary *assign_summary)
36 {
37 CamelMessageInfo *result;
38
39 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (mi), NULL);
40
41 result = CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->clone (mi, assign_summary);
42 if (!result)
43 return NULL;
44
45 if (CAMEL_IS_EWS_MESSAGE_INFO (result)) {
46 CamelEwsMessageInfo *emi, *emi_result;
47
48 emi = CAMEL_EWS_MESSAGE_INFO (mi);
49 emi_result = CAMEL_EWS_MESSAGE_INFO (result);
50
51 camel_ews_message_info_set_server_flags (emi_result, camel_ews_message_info_get_server_flags (emi));
52 camel_ews_message_info_set_item_type (emi_result, camel_ews_message_info_get_item_type (emi));
53 camel_ews_message_info_take_change_key (emi_result, camel_ews_message_info_dup_change_key (emi));
54 }
55
56 return result;
57 }
58
59 static gboolean
ews_message_info_load(CamelMessageInfo * mi,const CamelMIRecord * record,gchar ** bdata_ptr)60 ews_message_info_load (CamelMessageInfo *mi,
61 const CamelMIRecord *record,
62 /* const */ gchar **bdata_ptr)
63 {
64 CamelEwsMessageInfo *emi;
65
66 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (mi), FALSE);
67 g_return_val_if_fail (record != NULL, FALSE);
68 g_return_val_if_fail (bdata_ptr != NULL, FALSE);
69
70 if (!CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->load ||
71 !CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->load (mi, record, bdata_ptr))
72 return FALSE;
73
74 emi = CAMEL_EWS_MESSAGE_INFO (mi);
75
76 if (*bdata_ptr) {
77 gchar **values;
78
79 values = g_strsplit (*bdata_ptr, " ", -1);
80
81 if (values && values[0] && values[1] && values[2]) {
82 camel_ews_message_info_set_server_flags (emi, g_ascii_strtoll (values[0], NULL, 10));
83 camel_ews_message_info_set_item_type (emi, g_ascii_strtoll (values[1], NULL, 10));
84 camel_ews_message_info_set_change_key (emi, values[2]);
85 }
86
87 g_strfreev (values);
88 }
89
90 return TRUE;
91 }
92
93 static gboolean
ews_message_info_save(const CamelMessageInfo * mi,CamelMIRecord * record,GString * bdata_str)94 ews_message_info_save (const CamelMessageInfo *mi,
95 CamelMIRecord *record,
96 GString *bdata_str)
97 {
98 CamelEwsMessageInfo *emi;
99
100 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (mi), FALSE);
101 g_return_val_if_fail (record != NULL, FALSE);
102 g_return_val_if_fail (bdata_str != NULL, FALSE);
103
104 if (!CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->save ||
105 !CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->save (mi, record, bdata_str))
106 return FALSE;
107
108 emi = CAMEL_EWS_MESSAGE_INFO (mi);
109
110 g_string_append_printf (bdata_str, "%u %d %s",
111 camel_ews_message_info_get_server_flags (emi),
112 camel_ews_message_info_get_item_type (emi),
113 camel_ews_message_info_get_change_key (emi));
114
115 return TRUE;
116 }
117
118 static void
ews_message_info_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)119 ews_message_info_set_property (GObject *object,
120 guint property_id,
121 const GValue *value,
122 GParamSpec *pspec)
123 {
124 CamelEwsMessageInfo *emi = CAMEL_EWS_MESSAGE_INFO (object);
125
126 switch (property_id) {
127 case PROP_SERVER_FLAGS:
128 camel_ews_message_info_set_server_flags (emi, g_value_get_uint (value));
129 return;
130
131 case PROP_ITEM_TYPE:
132 camel_ews_message_info_set_item_type (emi, g_value_get_int (value));
133 return;
134
135 case PROP_CHANGE_KEY:
136 camel_ews_message_info_set_change_key (emi, g_value_get_string (value));
137 return;
138 }
139
140 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
141 }
142
143 static void
ews_message_info_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)144 ews_message_info_get_property (GObject *object,
145 guint property_id,
146 GValue *value,
147 GParamSpec *pspec)
148 {
149 CamelEwsMessageInfo *emi = CAMEL_EWS_MESSAGE_INFO (object);
150
151 switch (property_id) {
152
153 case PROP_SERVER_FLAGS:
154 g_value_set_uint (value, camel_ews_message_info_get_server_flags (emi));
155 return;
156
157 case PROP_ITEM_TYPE:
158 g_value_set_int (value, camel_ews_message_info_get_item_type (emi));
159 return;
160
161 case PROP_CHANGE_KEY:
162 g_value_take_string (value, camel_ews_message_info_dup_change_key (emi));
163 return;
164 }
165
166 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
167 }
168
169 static void
ews_message_info_dispose(GObject * object)170 ews_message_info_dispose (GObject *object)
171 {
172 CamelEwsMessageInfo *emi = CAMEL_EWS_MESSAGE_INFO (object);
173
174 g_free (emi->priv->change_key);
175 emi->priv->change_key = NULL;
176
177 /* Chain up to parent's method. */
178 G_OBJECT_CLASS (camel_ews_message_info_parent_class)->dispose (object);
179 }
180
181 static void
camel_ews_message_info_class_init(CamelEwsMessageInfoClass * class)182 camel_ews_message_info_class_init (CamelEwsMessageInfoClass *class)
183 {
184 CamelMessageInfoClass *mi_class;
185 GObjectClass *object_class;
186
187 mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
188 mi_class->clone = ews_message_info_clone;
189 mi_class->load = ews_message_info_load;
190 mi_class->save = ews_message_info_save;
191
192 object_class = G_OBJECT_CLASS (class);
193 object_class->set_property = ews_message_info_set_property;
194 object_class->get_property = ews_message_info_get_property;
195 object_class->dispose = ews_message_info_dispose;
196
197 /**
198 * CamelEwsMessageInfo:server-flags
199 *
200 * Last known server flags of the message.
201 *
202 * Since: 3.24
203 **/
204 g_object_class_install_property (
205 object_class,
206 PROP_SERVER_FLAGS,
207 g_param_spec_uint (
208 "server-flags",
209 "Server Flags",
210 NULL,
211 0, G_MAXUINT32, 0,
212 G_PARAM_READWRITE));
213
214 /**
215 * CamelEwsMessageInfo:item-type
216 *
217 * Item type of the message.
218 *
219 * Since: 3.24
220 **/
221 g_object_class_install_property (
222 object_class,
223 PROP_ITEM_TYPE,
224 g_param_spec_int (
225 "item-type",
226 "Item Type",
227 NULL,
228 0, G_MAXINT32, 0,
229 G_PARAM_READWRITE));
230
231 /**
232 * CamelEwsMessageInfo:change-key
233 *
234 * Change key of the message on the server.
235 *
236 * Since: 3.24
237 **/
238 g_object_class_install_property (
239 object_class,
240 PROP_CHANGE_KEY,
241 g_param_spec_string (
242 "change-key",
243 "Change Key",
244 NULL,
245 NULL,
246 G_PARAM_READWRITE));
247 }
248
249 static void
camel_ews_message_info_init(CamelEwsMessageInfo * emi)250 camel_ews_message_info_init (CamelEwsMessageInfo *emi)
251 {
252 emi->priv = camel_ews_message_info_get_instance_private (emi);
253 }
254
255 guint32
camel_ews_message_info_get_server_flags(const CamelEwsMessageInfo * emi)256 camel_ews_message_info_get_server_flags (const CamelEwsMessageInfo *emi)
257 {
258 CamelMessageInfo *mi;
259 guint32 result;
260
261 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), 0);
262
263 mi = CAMEL_MESSAGE_INFO (emi);
264
265 camel_message_info_property_lock (mi);
266 result = emi->priv->server_flags;
267 camel_message_info_property_unlock (mi);
268
269 return result;
270 }
271
272 gboolean
camel_ews_message_info_set_server_flags(CamelEwsMessageInfo * emi,guint32 server_flags)273 camel_ews_message_info_set_server_flags (CamelEwsMessageInfo *emi,
274 guint32 server_flags)
275 {
276 CamelMessageInfo *mi;
277 gboolean changed;
278
279 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
280
281 mi = CAMEL_MESSAGE_INFO (emi);
282
283 camel_message_info_property_lock (mi);
284
285 changed = emi->priv->server_flags != server_flags;
286
287 if (changed)
288 emi->priv->server_flags = server_flags;
289
290 camel_message_info_property_unlock (mi);
291
292 if (changed && !camel_message_info_get_abort_notifications (mi)) {
293 g_object_notify (G_OBJECT (emi), "server-flags");
294 camel_message_info_set_dirty (mi, TRUE);
295 }
296
297 return changed;
298 }
299
300 gint32
camel_ews_message_info_get_item_type(const CamelEwsMessageInfo * emi)301 camel_ews_message_info_get_item_type (const CamelEwsMessageInfo *emi)
302 {
303 CamelMessageInfo *mi;
304 gint32 result;
305
306 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), 0);
307
308 mi = CAMEL_MESSAGE_INFO (emi);
309
310 camel_message_info_property_lock (mi);
311 result = emi->priv->item_type;
312 camel_message_info_property_unlock (mi);
313
314 return result;
315 }
316
317 gboolean
camel_ews_message_info_set_item_type(CamelEwsMessageInfo * emi,gint32 item_type)318 camel_ews_message_info_set_item_type (CamelEwsMessageInfo *emi,
319 gint32 item_type)
320 {
321 CamelMessageInfo *mi;
322 gboolean changed;
323
324 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
325
326 mi = CAMEL_MESSAGE_INFO (emi);
327
328 camel_message_info_property_lock (mi);
329
330 changed = emi->priv->item_type != item_type;
331
332 if (changed)
333 emi->priv->item_type = item_type;
334
335 camel_message_info_property_unlock (mi);
336
337 if (changed && !camel_message_info_get_abort_notifications (mi)) {
338 g_object_notify (G_OBJECT (emi), "item-type");
339 camel_message_info_set_dirty (mi, TRUE);
340 }
341
342 return changed;
343 }
344
345 const gchar *
camel_ews_message_info_get_change_key(const CamelEwsMessageInfo * emi)346 camel_ews_message_info_get_change_key (const CamelEwsMessageInfo *emi)
347 {
348 CamelMessageInfo *mi;
349 const gchar *result;
350
351 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), NULL);
352
353 mi = CAMEL_MESSAGE_INFO (emi);
354
355 camel_message_info_property_lock (mi);
356 result = emi->priv->change_key;
357 camel_message_info_property_unlock (mi);
358
359 return result;
360 }
361
362 gchar *
camel_ews_message_info_dup_change_key(const CamelEwsMessageInfo * emi)363 camel_ews_message_info_dup_change_key (const CamelEwsMessageInfo *emi)
364 {
365 CamelMessageInfo *mi;
366 gchar *result;
367
368 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), NULL);
369
370 mi = CAMEL_MESSAGE_INFO (emi);
371
372 camel_message_info_property_lock (mi);
373 result = g_strdup (emi->priv->change_key);
374 camel_message_info_property_unlock (mi);
375
376 return result;
377 }
378
379 gboolean
camel_ews_message_info_set_change_key(CamelEwsMessageInfo * emi,const gchar * change_key)380 camel_ews_message_info_set_change_key (CamelEwsMessageInfo *emi,
381 const gchar *change_key)
382 {
383 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
384
385 return camel_ews_message_info_take_change_key (emi, g_strdup (change_key));
386 }
387
388 gboolean
camel_ews_message_info_take_change_key(CamelEwsMessageInfo * emi,gchar * change_key)389 camel_ews_message_info_take_change_key (CamelEwsMessageInfo *emi,
390 gchar *change_key)
391 {
392 CamelMessageInfo *mi;
393 gboolean changed;
394
395 g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
396
397 mi = CAMEL_MESSAGE_INFO (emi);
398
399 camel_message_info_property_lock (mi);
400
401 changed = g_strcmp0 (emi->priv->change_key, change_key) != 0;
402
403 if (changed) {
404 g_free (emi->priv->change_key);
405 emi->priv->change_key = change_key;
406 } else if (change_key != emi->priv->change_key) {
407 g_free (change_key);
408 }
409
410 camel_message_info_property_unlock (mi);
411
412 if (changed && !camel_message_info_get_abort_notifications (mi)) {
413 g_object_notify (G_OBJECT (emi), "change-key");
414 camel_message_info_set_dirty (mi, TRUE);
415 }
416
417 return changed;
418 }
419