GCC Code Coverage Report


Directory: src/
File: mail/msg-mail-message.c
Date: 2026-08-08 00:54:14
Exec Total Coverage
Lines: 117 131 89.3%
Functions: 28 28 100.0%
Branches: 57 80 71.2%

Line Branch Exec Source
1 /* Copyright 2022-2024 Jan-Michael Brummer <jan-michael.brummer1@volkswagen.de>
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "mail/msg-mail-message.h"
18 #include "msg-error.h"
19 #include "msg-json-utils.h"
20
21 /**
22 * MsgMailMessage:
23 *
24 * Handling of mail message specific functions.
25 */
26
27 struct _MsgMailMessage {
28 GObject parent_instance;
29
30 char *id;
31 char *subject;
32 char *body_preview;
33 char *body;
34
35 char *sender;
36 char *receiver;
37 char *cc;
38
39 int unread;
40 GDateTime *received_date;
41 gboolean has_attachment;
42 };
43
44
5/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 17 times.
23 G_DEFINE_TYPE (MsgMailMessage, msg_mail_message, G_TYPE_OBJECT);
45
46 static void
47 6 msg_mail_message_dispose (GObject *object)
48 {
49 6 MsgMailMessage *self = MSG_MAIL_MESSAGE (object);
50
51
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 g_clear_pointer (&self->subject, g_free);
52
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 g_clear_pointer (&self->body_preview, g_free);
53
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 g_clear_pointer (&self->body, g_free);
54
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 g_clear_pointer (&self->id, g_free);
55
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 g_clear_pointer (&self->sender, g_free);
56
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 g_clear_pointer (&self->receiver, g_free);
57
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 g_clear_pointer (&self->cc, g_free);
58
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 g_clear_pointer (&self->received_date, g_date_time_unref);
59
60 6 G_OBJECT_CLASS (msg_mail_message_parent_class)->dispose (object);
61 6 }
62
63 static void
64 8 msg_mail_message_init (__attribute__ ((unused)) MsgMailMessage *self)
65 {
66 8 }
67
68 static void
69 2 msg_mail_message_class_init (MsgMailMessageClass *class)
70 {
71 2 GObjectClass *object_class = G_OBJECT_CLASS (class);
72
73 2 object_class->dispose = msg_mail_message_dispose;
74 2 }
75
76 /**
77 * msg_mail_message_new:
78 *
79 * Creates a new `MsgMailMessage`.
80 *
81 * Returns: the newly created `MsgMailMessage`
82 */
83 MsgMailMessage *
84 8 msg_mail_message_new (void)
85 {
86 8 return g_object_new (MSG_TYPE_MAIL_MESSAGE, NULL);
87 }
88
89 /**
90 * msg_mail_message_new_from_json:
91 * @json_object: The json object to parse
92 * @error: a #GError
93 *
94 * Creates a new `MsgMailMessage` from json response object.
95 *
96 * Returns: the newly created `MsgMailMessage`
97 */
98 MsgMailMessage *
99 4 msg_mail_message_new_from_json (JsonObject *json_object,
100 __attribute__ ((unused)) GError **error)
101 {
102 MsgMailMessage *self;
103
104 4 self = msg_mail_message_new ();
105
106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (json_object_has_member (json_object, "from")) {
107 JsonObject *obj = json_object_get_object_member (json_object, "from");
108 JsonObject *email_address = json_object_get_object_member (obj, "emailAddress");
109 const char *address = msg_json_object_get_string (email_address, "address");
110 const char *name = msg_json_object_get_string (email_address, "name");
111
112 self->sender = g_strdup_printf ("%s%s<%s>", name ? name : "", name ? " " : "", address);
113 }
114 4 self->received_date = g_date_time_new_from_iso8601 (msg_json_object_get_string (json_object, "receivedDateTime"), NULL);
115
116 8 self->subject = g_strstrip (g_strdup (msg_json_object_get_string (json_object, "subject")));
117
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (json_object_has_member (json_object, "body")) {
118 2 JsonObject *obj = json_object_get_object_member (json_object, "body");
119 2 const char *content = msg_json_object_get_string (obj, "content");
120
121 2 self->body = g_strdup (content);
122 }
123
124 4 self->body_preview = g_strdup (msg_json_object_get_string (json_object, "bodyPreview"));
125
126
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (json_object_has_member (json_object, "isRead")) {
127 4 self->unread = json_object_get_boolean_member (json_object, "isRead") != TRUE;
128 } else {
129 self->unread = 0;
130 }
131
132 4 self->id = g_strdup (msg_json_object_get_string (json_object, "id"));
133
134
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (json_object_has_member (json_object, "toRecipients")) {
135 4 JsonArray *array = json_object_get_array_member (json_object, "toRecipients");
136 4 int array_length = json_array_get_length (array);
137 4 GString *receiver = g_string_new ("");
138
139
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (int index = 0; index < array_length; index++) {
140 4 JsonObject *to = NULL;
141
142 4 to = json_array_get_object_element (array, index);
143
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (to) {
144 4 JsonObject *email_address = json_object_get_object_member (to, "emailAddress");
145 4 const char *address = msg_json_object_get_string (email_address, "address");
146 4 const char *name = msg_json_object_get_string (email_address, "name");
147
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (receiver->len) {
149 g_string_append (receiver, ";");
150 }
151
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 g_string_append_printf (receiver, "%s%s<%s>", name ? name : "", name ? " " : "", address);
152 }
153 }
154
155 4 self->receiver = g_string_free (receiver, FALSE);
156 }
157
158
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (json_object_has_member (json_object, "ccRecipients")) {
159 4 JsonArray *array = json_object_get_array_member (json_object, "ccRecipients");
160 4 int array_length = json_array_get_length (array);
161
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 for (int index = 0; index < array_length; index++) {
163 JsonObject *to = NULL;
164
165 to = json_array_get_object_element (array, index);
166 if (to) {
167 JsonObject *email_address = json_object_get_object_member (to, "emailAddress");
168 const char *address = msg_json_object_get_string (email_address, "address");
169 const char *name = msg_json_object_get_string (email_address, "name");
170
171 self->cc = g_strdup_printf ("%s%s<%s>", name ? name : "", name ? " " : "", address);
172 }
173 }
174 }
175
176
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (json_object_has_member (json_object, "hasAttachments")) {
177 4 self->has_attachment = msg_json_object_get_boolean (json_object, "hasAttachments");
178 }
179
180 4 return self;
181 }
182
183 /**
184 * msg_mail_message_get_subject:
185 * @self: a mail_message
186 *
187 * Get mail subject.
188 *
189 * Returns: (transfer none): subject of mail_message
190 */
191 const char *
192 7 msg_mail_message_get_subject (MsgMailMessage *self)
193 {
194 7 return self->subject;
195 }
196
197 /**
198 * msg_mail_message_get_body_preview:
199 * @self: a mail_message
200 *
201 * Get mail body preview.
202 *
203 * Returns: (transfer none): body preview of mail_message
204 */
205 const char *
206 4 msg_mail_message_get_body_preview (MsgMailMessage *self)
207 {
208 4 return self->body_preview;
209 }
210
211 void
212 2 msg_mail_message_set_body_preview (MsgMailMessage *self,
213 const char *preview)
214 {
215
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 g_clear_pointer (&self->body_preview, g_free);
216 2 self->body_preview = g_strdup (preview);
217 2 }
218
219 /**
220 * msg_mail_message_set_body:
221 * @self: a mail_message
222 * @body: mail body
223 *
224 * Set mail body.
225 */
226 void
227 5 msg_mail_message_set_body (MsgMailMessage *self,
228 const char *body)
229 {
230
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (self->body == body)
231 1 return;
232
233
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 g_clear_pointer (&self->body, g_free);
234 4 self->body = g_strdup (body);
235 }
236
237 /**
238 * msg_mail_message_set_subject:
239 * @self: a mail_message
240 * @subject: mail subject
241 *
242 * Set mail subject.
243 */
244 void
245 5 msg_mail_message_set_subject (MsgMailMessage *self,
246 const char *subject)
247 {
248
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (self->subject == subject)
249 1 return;
250
251
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 g_clear_pointer (&self->subject, g_free);
252 4 self->subject = g_strdup (subject);
253 }
254
255 /**
256 * msg_mail_message_get_id:
257 * @self: a mail_message
258 *
259 * Get id.
260 *
261 * Returns: (transfer none): unique mail id
262 */
263 const char *
264 8 msg_mail_message_get_id (MsgMailMessage *self)
265 {
266 8 return self->id;
267 }
268
269 /**
270 * msg_mail_message_set_id:
271 * @self: a mail_message
272 * @id: mail_message id
273 *
274 * Set mail id.
275 */
276 void
277 3 msg_mail_message_set_id (MsgMailMessage *self,
278 const char *id)
279 {
280
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 g_clear_pointer (&self->id, g_free);
281 3 self->id = g_strdup (id);
282 3 }
283
284 /**
285 * msg_mail_message_get_sender:
286 * @self: a mail_message
287 *
288 * Get mail sender.
289 *
290 * Returns: (transfer none): mail sender
291 */
292 const char *
293 3 msg_mail_message_get_sender (MsgMailMessage *self)
294 {
295 3 return self->sender;
296 }
297
298 /**
299 * msg_mail_message_set_sender:
300 * @self: a mail_message
301 * @sender: mail_message sender
302 *
303 * Set mail sender.
304 */
305 void
306 6 msg_mail_message_set_sender (MsgMailMessage *self,
307 const char *sender)
308 {
309
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 g_clear_pointer (&self->sender, g_free);
310 6 self->sender = g_strdup (sender);
311 6 }
312
313 /**
314 * msg_mail_message_get_receiver:
315 * @self: a mail_message
316 *
317 * Get mail receiver.
318 *
319 * Returns: (transfer none): mail receiver
320 */
321 const char *
322 5 msg_mail_message_get_receiver (MsgMailMessage *self)
323 {
324 5 return self->receiver;
325 }
326
327 /**
328 * msg_mail_message_set_receiver:
329 * @self: a mail_message
330 * @receiver: mail_message receiver
331 *
332 * Set mail receiver.
333 */
334 void
335 5 msg_mail_message_set_receiver (MsgMailMessage *self,
336 const char *receiver)
337 {
338
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 g_clear_pointer (&self->receiver, g_free);
339 5 self->receiver = g_strdup (receiver);
340 5 }
341
342 /**
343 * msg_mail_message_get_cc:
344 * @self: a mail_message
345 *
346 * Get mail cc.
347 *
348 * Returns: (transfer none): mail cc
349 */
350 const char *
351 3 msg_mail_message_get_cc (MsgMailMessage *self)
352 {
353 3 return self->cc;
354 }
355
356 /**
357 * msg_mail_message_set_cc:
358 * @self: a mail_message
359 * @cc: carbon copy string
360 *
361 * Set mail cc.
362 */
363 void
364 4 msg_mail_message_set_cc (MsgMailMessage *self,
365 const char *cc)
366 {
367
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 g_clear_pointer (&self->cc, g_free);
368 4 self->cc = g_strdup (cc);
369 4 }
370
371 /**
372 * msg_mail_message_get_unread:
373 * @self: a mail_message
374 *
375 * Get mail unread.
376 *
377 * Returns: unread count
378 */
379 int
380 2 msg_mail_message_get_unread (MsgMailMessage *self)
381 {
382 2 return self->unread;
383 }
384
385 /**
386 * msg_mail_message_set_unread:
387 * @self: a mail_message
388 * @unread: unread count
389 *
390 * Set mail unread count.
391 */
392 void
393 2 msg_mail_message_set_unread (MsgMailMessage *self,
394 int unread)
395 {
396 2 self->unread = unread;
397 2 }
398
399 /**
400 * msg_mail_message_get_received_date:
401 * @self: a mail_message
402 *
403 * Get mail received date.
404 *
405 * Returns: (transfer none): received date
406 */
407 GDateTime *
408 2 msg_mail_message_get_received_date (MsgMailMessage *self)
409 {
410 2 return self->received_date;
411 }
412
413 /**
414 * msg_mail_message_set_received_date:
415 * @self: a mail_message
416 * @timestamp: received timestamp
417 *
418 * Set mail received timestamp.
419 */
420 void
421 2 msg_mail_message_set_received_date (MsgMailMessage *self,
422 gint64 timestamp)
423 {
424
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 g_clear_pointer (&self->received_date, g_date_time_unref);
425 2 self->received_date = g_date_time_new_from_unix_utc (timestamp);
426 2 }
427
428 /**
429 * msg_mail_message_get_body:
430 * @self: a mail_message
431 *
432 * Get mail body.
433 *
434 * Returns: (transfer none): mail body
435 */
436 const char *
437 4 msg_mail_message_get_body (MsgMailMessage *self,
438 gboolean *is_html)
439 {
440
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (is_html)
441 1 *is_html = TRUE;
442
443 4 return self->body;
444 }
445
446 /**
447 * msg_mail_message_get_has_attachment:
448 * @self: a mail_message
449 *
450 * Get whether mail has attachments.
451 *
452 * Returns: %TRUE if mail has attachments otherwise %FALSE
453 */
454 gboolean
455 2 msg_mail_message_get_has_attachment (MsgMailMessage *self)
456 {
457 2 return self->has_attachment;
458 }
459
460 /**
461 * msg_mail_message_set_has_attachment:
462 * @self: a mail_message
463 * @has_attachment: flag to set attachments
464 *
465 * Set whether mail has attachments.
466 */
467 void
468 2 msg_mail_message_set_has_attachment (MsgMailMessage *self,
469 gboolean has_attachment)
470 {
471 2 self->has_attachment = has_attachment;
472 2 }
473