GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 91.5% 301 / 0 / 329
Functions: 96.2% 25 / 0 / 26
Branches: 62.3% 114 / 0 / 183

libfprint/fp-print.c
Line Branch Exec Source
1 /*
2 * FPrint Print handling
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
4 * Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but 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 library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #define FP_COMPONENT "print"
22
23 #include "fp-print-private.h"
24 #include "fpi-compat.h"
25 #include "fpi-log.h"
26
27 /**
28 * SECTION: fp-print
29 * @title: FpPrint
30 * @short_description: Fingerprint handling
31 *
32 * Interaction with prints and their storage.
33 */
34
35 /**
36 * SECTION: fpi-print
37 * @title: Internal FpPrint
38 * @short_description: Internal fingerprint handling routines
39 *
40 * Interaction with prints and their storage. See also the public
41 * #FpPrint routines.
42 */
43
44
4/6
fp_print_class_intern_init:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 73 times.
fp_print_get_type:
✓ Branch 2 → 3 taken 77 times.
✓ Branch 2 → 7 taken 1019734 times.
✓ Branch 4 → 5 taken 77 times.
✗ Branch 4 → 7 not taken.
1019961 G_DEFINE_TYPE (FpPrint, fp_print, G_TYPE_INITIALLY_UNOWNED)
45
46 enum {
47 PROP_0,
48 PROP_DRIVER,
49 PROP_DEVICE_ID,
50 PROP_DEVICE_STORED,
51 PROP_IMAGE,
52
53 /* The following is metadata that is stored by default for each print.
54 * Drivers may make use of these during enrollment (e.g. to additionally store
55 * the metadata on the device). */
56 PROP_FINGER,
57 PROP_USERNAME,
58 PROP_DESCRIPTION,
59 PROP_ENROLL_DATE,
60
61 /* Private property*/
62 PROP_FPI_TYPE,
63 PROP_FPI_DATA,
64 PROP_FPI_PRINTS,
65 N_PROPS
66 };
67
68 static GParamSpec *properties[N_PROPS];
69
70 static void
71 6293 fp_print_finalize (GObject *object)
72 {
73 6293 FpPrint *self = (FpPrint *) object;
74
75
2/2
✓ Branch 2 → 3 taken 33 times.
✓ Branch 2 → 4 taken 6260 times.
6293 g_clear_object (&self->image);
76
1/2
✓ Branch 4 → 5 taken 6293 times.
✗ Branch 4 → 6 not taken.
6293 g_clear_pointer (&self->device_id, g_free);
77
1/2
✓ Branch 6 → 7 taken 6293 times.
✗ Branch 6 → 8 not taken.
6293 g_clear_pointer (&self->driver, g_free);
78
2/2
✓ Branch 8 → 9 taken 46 times.
✓ Branch 8 → 10 taken 6247 times.
6293 g_clear_pointer (&self->username, g_free);
79
2/2
✓ Branch 10 → 11 taken 100 times.
✓ Branch 10 → 12 taken 6193 times.
6293 g_clear_pointer (&self->description, g_free);
80
2/2
✓ Branch 12 → 13 taken 87 times.
✓ Branch 12 → 14 taken 6206 times.
6293 g_clear_pointer (&self->enroll_date, g_date_free);
81
2/2
✓ Branch 14 → 15 taken 6207 times.
✓ Branch 14 → 16 taken 86 times.
6293 g_clear_pointer (&self->data, g_variant_unref);
82
2/2
✓ Branch 16 → 17 taken 54 times.
✓ Branch 16 → 18 taken 6239 times.
6293 g_clear_pointer (&self->prints, g_ptr_array_unref);
83
84 6293 G_OBJECT_CLASS (fp_print_parent_class)->finalize (object);
85 6293 }
86
87 static void
88 442 fp_print_get_property (GObject *object,
89 guint prop_id,
90 GValue *value,
91 GParamSpec *pspec)
92 {
93 442 FpPrint *self = FP_PRINT (object);
94
95
10/12
✓ Branch 2 → 3 taken 28 times.
✓ Branch 2 → 5 taken 28 times.
✓ Branch 2 → 7 taken 28 times.
✓ Branch 2 → 9 taken 24 times.
✓ Branch 2 → 11 taken 1 time.
✓ Branch 2 → 13 taken 1 time.
✓ Branch 2 → 15 taken 6 times.
✓ Branch 2 → 17 taken 1 time.
✓ Branch 2 → 19 taken 132 times.
✓ Branch 2 → 21 taken 193 times.
✗ Branch 2 → 23 not taken.
✗ Branch 2 → 25 not taken.
442 switch (prop_id)
96 {
97 28 case PROP_DRIVER:
98 28 g_value_set_string (value, self->driver);
99 28 break;
100
101 28 case PROP_DEVICE_ID:
102 28 g_value_set_string (value, self->device_id);
103 28 break;
104
105 28 case PROP_DEVICE_STORED:
106 28 g_value_set_boolean (value, self->device_stored);
107 28 break;
108
109 24 case PROP_IMAGE:
110 24 g_value_set_object (value, self->image);
111 24 break;
112
113 1 case PROP_FINGER:
114 1 g_value_set_enum (value, self->finger);
115 1 break;
116
117 1 case PROP_USERNAME:
118 1 g_value_set_string (value, self->username);
119 1 break;
120
121 6 case PROP_DESCRIPTION:
122 6 g_value_set_string (value, self->description);
123 6 break;
124
125 1 case PROP_ENROLL_DATE:
126 1 g_value_set_boxed (value, self->enroll_date);
127 1 break;
128
129 132 case PROP_FPI_TYPE:
130 132 g_value_set_enum (value, self->type);
131 132 break;
132
133 193 case PROP_FPI_DATA:
134 193 g_value_set_variant (value, self->data);
135 193 break;
136
137 case PROP_FPI_PRINTS:
138 g_value_set_pointer (value, self->prints);
139 break;
140
141 default:
142 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
143 }
144 442 }
145
146 static void
147 25267 fp_print_set_property (GObject *object,
148 guint prop_id,
149 const GValue *value,
150 GParamSpec *pspec)
151 {
152 25267 FpPrint *self = FP_PRINT (object);
153
154
9/11
✓ Branch 2 → 3 taken 12 times.
✓ Branch 2 → 6 taken 6301 times.
✓ Branch 2 → 8 taken 6301 times.
✓ Branch 2 → 10 taken 6301 times.
✓ Branch 2 → 12 taken 17 times.
✓ Branch 2 → 14 taken 17 times.
✓ Branch 2 → 18 taken 94 times.
✓ Branch 2 → 22 taken 17 times.
✓ Branch 2 → 26 taken 6207 times.
✗ Branch 2 → 30 not taken.
✗ Branch 2 → 34 not taken.
25267 switch (prop_id)
155 {
156 12 case PROP_FPI_TYPE:
157 12 fpi_print_set_type (self, g_value_get_enum (value));
158 12 break;
159
160 6301 case PROP_DRIVER:
161 6301 self->driver = g_value_dup_string (value);
162 6301 break;
163
164 6301 case PROP_DEVICE_ID:
165 6301 self->device_id = g_value_dup_string (value);
166 6301 break;
167
168 6301 case PROP_DEVICE_STORED:
169 6301 self->device_stored = g_value_get_boolean (value);
170 6301 break;
171
172 17 case PROP_FINGER:
173 17 self->finger = g_value_get_enum (value);
174 17 break;
175
176 17 case PROP_USERNAME:
177
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 17 times.
17 g_clear_pointer (&self->username, g_free);
178 17 self->username = g_value_dup_string (value);
179 17 break;
180
181 94 case PROP_DESCRIPTION:
182
1/2
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 94 times.
94 g_clear_pointer (&self->description, g_free);
183 94 self->description = g_value_dup_string (value);
184 94 break;
185
186 17 case PROP_ENROLL_DATE:
187
1/2
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 17 times.
17 g_clear_pointer (&self->enroll_date, g_date_free);
188 17 self->enroll_date = g_value_dup_boxed (value);
189 17 break;
190
191 6207 case PROP_FPI_DATA:
192
1/2
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 28 taken 6207 times.
6207 g_clear_pointer (&self->data, g_variant_unref);
193 6207 self->data = g_value_dup_variant (value);
194 6207 break;
195
196 case PROP_FPI_PRINTS:
197 g_clear_pointer (&self->prints, g_ptr_array_unref);
198 self->prints = g_value_get_pointer (value);
199 break;
200
201 default:
202 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
203 }
204 25267 }
205
206 static void
207 6301 fp_print_constructed (GObject *obj)
208 {
209 6301 FpPrint *self = FP_PRINT (obj);
210
211
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6301 times.
6301 g_assert (self->driver != NULL);
212
1/2
✓ Branch 4 → 5 taken 6301 times.
✗ Branch 4 → 6 not taken.
6301 g_assert (self->device_id != NULL);
213 6301 }
214
215 static void
216 73 fp_print_class_init (FpPrintClass *klass)
217 {
218 73 GObjectClass *object_class = G_OBJECT_CLASS (klass);
219
220 73 object_class->constructed = fp_print_constructed;
221 73 object_class->finalize = fp_print_finalize;
222 73 object_class->get_property = fp_print_get_property;
223 73 object_class->set_property = fp_print_set_property;
224
225 146 properties[PROP_DRIVER] =
226 73 g_param_spec_string ("driver",
227 "Driver",
228 "The name of the driver that created the print",
229 NULL,
230 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
231
232 146 properties[PROP_DEVICE_ID] =
233 73 g_param_spec_string ("device-id",
234 "Device ID",
235 "Unique ID allowing to check if a device is compatible with the print",
236 NULL,
237 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
238
239 146 properties[PROP_DEVICE_STORED] =
240 73 g_param_spec_boolean ("device-stored",
241 "Device Stored",
242 "Whether the print is a handle for data that is stored on the device",
243 FALSE,
244 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
245
246 146 properties[PROP_IMAGE] =
247 73 g_param_spec_object ("image",
248 "Image",
249 "The image that was used for the print, only valid for newly enrolled prints on image based devices",
250 FP_TYPE_IMAGE,
251 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
252
253 146 properties[PROP_FINGER] =
254 73 g_param_spec_enum ("finger",
255 "Finger",
256 "The enrolled finger",
257 FP_TYPE_FINGER,
258 FP_FINGER_UNKNOWN,
259 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
260
261 146 properties[PROP_USERNAME] =
262 73 g_param_spec_string ("username",
263 "Username",
264 "The username that the enrolled print belongs to",
265 NULL,
266 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
267
268 146 properties[PROP_DESCRIPTION] =
269 73 g_param_spec_string ("description",
270 "Description",
271 "A user defined description for the print",
272 NULL,
273 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
274
275 146 properties[PROP_ENROLL_DATE] =
276 73 g_param_spec_boxed ("enroll-date",
277 "Enroll Date",
278 "The date of enrollment",
279 G_TYPE_DATE,
280 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
281
282 /**
283 * FpPrint::fpi-type: (skip)
284 *
285 * This property is only for internal purposes.
286 *
287 * Stability: private
288 */
289 146 properties[PROP_FPI_TYPE] =
290 73 g_param_spec_enum ("fpi-type",
291 "Type",
292 "Private: The type of the print data",
293 FPI_TYPE_PRINT_TYPE,
294 FPI_PRINT_UNDEFINED,
295 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
296
297 /**
298 * FpPrint::fpi-data: (skip)
299 *
300 * This property is only for internal purposes.
301 *
302 * Stability: private
303 */
304 146 properties[PROP_FPI_DATA] =
305 73 g_param_spec_variant ("fpi-data",
306 "Raw Data",
307 "The raw data for internal use only",
308 G_VARIANT_TYPE_ANY,
309 NULL,
310 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
311
312 /**
313 * FpPrint::fpi-prints: (skip)
314 *
315 * This property is only for internal purposes.
316 *
317 * Stability: private
318 */
319 146 properties[PROP_FPI_PRINTS] =
320 73 g_param_spec_pointer ("fpi-prints",
321 "Prints",
322 "Prints for internal use only",
323 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
324
325 73 g_object_class_install_properties (object_class, N_PROPS, properties);
326 73 }
327
328 static void
329 6301 fp_print_init (FpPrint *self)
330 {
331 6301 }
332
333 /**
334 * fp_print_new:
335 * @device: A #FpDevice
336 *
337 * Create a new #FpPrint. This is only useful to prepare an enrollment
338 * of a new print using fp_device_enroll(). For this you should first
339 * create a new print, fill in the relevant metadata, and then start
340 * enrollment.
341 *
342 * Returns: (transfer floating): A newly created #FpPrint
343 */
344 FpPrint *
345 6288 fp_print_new (FpDevice *device)
346 {
347
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6288 times.
6288 g_return_val_if_fail (device, NULL);
348
349 6288 return g_object_new (FP_TYPE_PRINT,
350 "driver", fp_device_get_driver (device),
351 "device-id", fp_device_get_device_id (device),
352 NULL);
353 }
354
355 /**
356 * fp_print_get_driver:
357 * @print: A #FpPrint
358 *
359 * Returns the driver that the print was created for.
360 *
361 * Returns: (transfer none): The driver
362 */
363 const gchar *
364 6 fp_print_get_driver (FpPrint *print)
365 {
366
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 6 times.
6 g_return_val_if_fail (FP_IS_PRINT (print), NULL);
367
368 6 return print->driver;
369 }
370
371 /**
372 * fp_print_get_device_id:
373 * @print: A #FpPrint
374 *
375 * Returns the device ID that the print was created for.
376 *
377 * Returns: (transfer none): The device ID
378 */
379 const gchar *
380 fp_print_get_device_id (FpPrint *print)
381 {
382 g_return_val_if_fail (FP_IS_PRINT (print), NULL);
383
384 return print->device_id;
385 }
386
387 /**
388 * fp_print_get_device_stored:
389 * @print: A #FpPrint
390 *
391 * Whether the print is actually stored on the device and this is
392 * just a handle to use that references the device stored data.
393 *
394 * Returns: Whether the print is stored on the device
395 */
396 gboolean
397 23 fp_print_get_device_stored (FpPrint *print)
398 {
399
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 23 times.
23 g_return_val_if_fail (FP_IS_PRINT (print), FALSE);
400
401 23 return print->device_stored;
402 }
403
404 /**
405 * fp_print_get_image:
406 * @print: A #FpPrint
407 *
408 * Returns the image that the print was created from, or %NULL
409 *
410 * Returns: (transfer none) (nullable): The #FpImage
411 */
412 FpImage *
413 5 fp_print_get_image (FpPrint *print)
414 {
415
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 5 times.
5 g_return_val_if_fail (FP_IS_PRINT (print), NULL);
416
417 5 return print->image;
418 }
419
420 /**
421 * fp_print_get_finger:
422 * @print: A #FpPrint
423 *
424 * Returns the finger that the print was created for.
425 *
426 * Returns: The #FpFinger
427 */
428 FpFinger
429 87 fp_print_get_finger (FpPrint *print)
430 {
431
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 87 times.
87 g_return_val_if_fail (FP_IS_PRINT (print), FP_FINGER_UNKNOWN);
432
433 87 return print->finger;
434 }
435
436 /**
437 * fp_print_get_username:
438 * @print: A #FpPrint
439 *
440 * Returns the user defined username for the print.
441 *
442 * Returns: (transfer none) (nullable): The username
443 */
444 const gchar *
445 30 fp_print_get_username (FpPrint *print)
446 {
447
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 30 times.
30 g_return_val_if_fail (FP_IS_PRINT (print), NULL);
448
449 30 return print->username;
450 }
451
452 /**
453 * fp_print_get_description:
454 * @print: A #FpPrint
455 *
456 * Returns the user defined description for the print.
457 *
458 * Returns: (transfer none) (nullable): The description
459 */
460 const gchar *
461 1054 fp_print_get_description (FpPrint *print)
462 {
463
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1054 times.
1054 g_return_val_if_fail (FP_IS_PRINT (print), NULL);
464
465 1054 return print->description;
466 }
467
468 /**
469 * fp_print_get_enroll_date:
470 * @print: A #FpPrint
471 *
472 * Returns the user defined enroll date for the print.
473 *
474 * Returns: (transfer none) (nullable): The #GDate
475 */
476 const GDate *
477 17 fp_print_get_enroll_date (FpPrint *print)
478 {
479
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 17 times.
17 g_return_val_if_fail (FP_IS_PRINT (print), NULL);
480
481 17 return print->enroll_date;
482 }
483
484 /**
485 * fp_print_set_finger:
486 * @print: A #FpPrint
487 * @finger: The #FpFinger
488 *
489 * Set the finger that the print is for.
490 */
491 void
492 112 fp_print_set_finger (FpPrint *print,
493 FpFinger finger)
494 {
495
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 112 times.
112 g_return_if_fail (FP_IS_PRINT (print));
496
497 112 print->finger = finger;
498 112 g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_FINGER]);
499 }
500
501 /**
502 * fp_print_set_username:
503 * @print: A #FpPrint
504 * @username: (transfer none): The new username
505 *
506 * Set the username for the print.
507 */
508 void
509 39 fp_print_set_username (FpPrint *print,
510 const gchar *username)
511 {
512
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 39 times.
39 g_return_if_fail (FP_IS_PRINT (print));
513
514
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 39 times.
39 g_clear_pointer (&print->username, g_free);
515
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 39 times.
39 print->username = g_strdup (username);
516 39 g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_USERNAME]);
517 }
518
519 /**
520 * fp_print_set_description:
521 * @print: A #FpPrint
522 * @description: (transfer none): The new description
523 *
524 * Set the description for the print.
525 */
526 void
527 7 fp_print_set_description (FpPrint *print,
528 const gchar *description)
529 {
530
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 7 times.
7 g_return_if_fail (FP_IS_PRINT (print));
531
532
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 7 times.
7 g_clear_pointer (&print->description, g_free);
533
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 7 times.
7 print->description = g_strdup (description);
534 7 g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_DESCRIPTION]);
535 }
536
537 /**
538 * fp_print_set_enroll_date:
539 * @print: A #FpPrint
540 * @enroll_date: (transfer none): The new enroll date
541 *
542 * Set the enroll date for the print.
543 */
544 void
545 70 fp_print_set_enroll_date (FpPrint *print,
546 const GDate *enroll_date)
547 {
548
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 70 times.
70 g_return_if_fail (FP_IS_PRINT (print));
549
550
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 70 times.
70 g_clear_pointer (&print->enroll_date, g_date_free);
551
1/2
✓ Branch 7 → 8 taken 70 times.
✗ Branch 7 → 10 not taken.
70 if (enroll_date)
552 70 print->enroll_date = g_date_copy (enroll_date);
553
554 70 g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_ENROLL_DATE]);
555 }
556
557 /**
558 * fp_print_compatible:
559 * @self: A #FpPrint
560 * @device: A #FpDevice
561 *
562 * Tests whether the prints is compatible with the given device.
563 *
564 * Returns: %TRUE if the print is compatible with the device
565 */
566 gboolean
567 4 fp_print_compatible (FpPrint *self, FpDevice *device)
568 {
569
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 4 times.
4 g_return_val_if_fail (FP_IS_PRINT (self), FALSE);
570
1/2
✓ Branch 6 → 7 taken 4 times.
✗ Branch 6 → 10 not taken.
4 g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
571
572
2/2
✓ Branch 9 → 11 taken 3 times.
✓ Branch 9 → 15 taken 1 time.
4 if (g_strcmp0 (self->driver, fp_device_get_driver (device)))
573 return FALSE;
574
575
2/2
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 2 times.
3 if (g_strcmp0 (self->device_id, fp_device_get_device_id (device)))
576 1 return FALSE;
577
578 return TRUE;
579 }
580
581 /**
582 * fp_print_equal:
583 * @self: First #FpPrint
584 * @other: Second #FpPrint
585 *
586 * Tests whether the prints can be considered equal. This only compares the
587 * actual information about the print, not the metadata.
588 *
589 * Returns: %TRUE if the prints are equal
590 */
591 gboolean
592 502372 fp_print_equal (FpPrint *self, FpPrint *other)
593 {
594
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 502372 times.
502372 g_return_val_if_fail (FP_IS_PRINT (self), FALSE);
595
1/2
✓ Branch 6 → 7 taken 502372 times.
✗ Branch 6 → 8 not taken.
502372 g_return_val_if_fail (FP_IS_PRINT (other), FALSE);
596
1/2
✓ Branch 7 → 9 taken 502372 times.
✗ Branch 7 → 10 not taken.
502372 g_return_val_if_fail (self->type != FPI_PRINT_UNDEFINED, FALSE);
597
1/2
✓ Branch 9 → 11 taken 502372 times.
✗ Branch 9 → 12 not taken.
502372 g_return_val_if_fail (other->type != FPI_PRINT_UNDEFINED, FALSE);
598
599
2/2
✓ Branch 11 → 13 taken 500367 times.
✓ Branch 11 → 26 taken 2005 times.
502372 if (self == other)
600 return TRUE;
601
602
2/2
✓ Branch 13 → 14 taken 500365 times.
✓ Branch 13 → 26 taken 2 times.
500367 if (self->type != other->type)
603 return FALSE;
604
605
1/2
✓ Branch 15 → 16 taken 500365 times.
✗ Branch 15 → 26 not taken.
500365 if (g_strcmp0 (self->driver, other->driver))
606 return FALSE;
607
608
1/2
✓ Branch 17 → 18 taken 500365 times.
✗ Branch 17 → 26 not taken.
500365 if (g_strcmp0 (self->device_id, other->device_id))
609 return FALSE;
610
611
2/4
✓ Branch 18 → 19 taken 500357 times.
✓ Branch 18 → 20 taken 8 times.
✗ Branch 18 → 24 not taken.
✗ Branch 18 → 25 not taken.
500365 switch (self->type)
612 {
613 500357 case FPI_PRINT_RAW:
614 500357 return g_variant_equal (self->data, other->data);
615
616 8 case FPI_PRINT_NBIS:
617
2/2
✓ Branch 20 → 23 taken 4 times.
✓ Branch 20 → 26 taken 4 times.
8 if (self->prints->len != other->prints->len)
618 return FALSE;
619
620
2/2
✓ Branch 23 → 21 taken 7 times.
✓ Branch 23 → 26 taken 3 times.
10 for (guint i = 0; i < self->prints->len; i++)
621 {
622 7 struct xyt_struct *a = g_ptr_array_index (self->prints, i);
623 7 struct xyt_struct *b = g_ptr_array_index (other->prints, i);
624
625
2/2
✓ Branch 21 → 22 taken 6 times.
✓ Branch 21 → 26 taken 1 time.
7 if (memcmp (a, b, sizeof (struct xyt_struct)) != 0)
626 return FALSE;
627 }
628
629 return TRUE;
630
631 case FPI_PRINT_UNDEFINED:
632 g_assert_not_reached ();
633 }
634
635 g_return_val_if_reached (FALSE);
636 }
637
638 #define FPI_PRINT_VARIANT_TYPE G_VARIANT_TYPE ("(issbymsmsia{sv}v)")
639
640 G_STATIC_ASSERT (sizeof (((struct xyt_struct *) NULL)->xcol[0]) == 4);
641
642 /**
643 * fp_print_serialize:
644 * @print: A #FpPrint
645 * @data: (array length=length) (transfer full) (out): Return location for data pointer
646 * @length: (transfer full) (out): Length of @data
647 * @error: Return location for error
648 *
649 * Serialize a print definition for permanent storage. Note that this is
650 * lossy in the sense that e.g. the image data is discarded.
651 *
652 * Returns: (type void): %TRUE on success
653 */
654 gboolean
655 13 fp_print_serialize (FpPrint *print,
656 guchar **data,
657 gsize *length,
658 GError **error)
659 {
660 26 g_autoptr(GVariant) result = NULL;
661 13 GVariantBuilder builder = G_VARIANT_BUILDER_INIT (FPI_PRINT_VARIANT_TYPE);
662 13 gsize len;
663
664
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 13 times.
13 g_assert (data);
665
1/2
✓ Branch 5 → 6 taken 13 times.
✗ Branch 5 → 14 not taken.
13 g_assert (length);
666
667 13 g_variant_builder_add (&builder, "i", print->type);
668 13 g_variant_builder_add (&builder, "s", print->driver);
669 13 g_variant_builder_add (&builder, "s", print->device_id);
670 13 g_variant_builder_add (&builder, "b", print->device_stored);
671
672 /* Metadata */
673 13 g_variant_builder_add (&builder, "y", print->finger);
674 13 g_variant_builder_add (&builder, "ms", print->username);
675 13 g_variant_builder_add (&builder, "ms", print->description);
676
3/4
✓ Branch 13 → 15 taken 13 times.
✗ Branch 13 → 19 not taken.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 19 taken 12 times.
13 if (print->enroll_date && g_date_valid (print->enroll_date))
677 1 g_variant_builder_add (&builder, "i", g_date_get_julian (print->enroll_date));
678 else
679 12 g_variant_builder_add (&builder, "i", G_MININT32);
680
681 /* Unused a{sv} for expansion */
682 13 g_variant_builder_open (&builder, G_VARIANT_TYPE_VARDICT);
683 13 g_variant_builder_close (&builder);
684
685 /* Insert NBIS print data for type NBIS, otherwise the GVariant directly */
686
2/2
✓ Branch 22 → 23 taken 1 time.
✓ Branch 22 → 42 taken 12 times.
13 if (print->type == FPI_PRINT_NBIS)
687 {
688 1 GVariantBuilder nested = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(a(aiaiai))"));
689 1 guint i;
690
691 1 g_variant_builder_open (&nested, G_VARIANT_TYPE ("a(aiaiai)"));
692
2/2
✓ Branch 37 → 27 taken 5 times.
✓ Branch 37 → 38 taken 1 time.
7 for (i = 0; i < print->prints->len; i++)
693 {
694 5 struct xyt_struct *xyt = g_ptr_array_index (print->prints, i);
695
696 5 g_variant_builder_open (&nested, G_VARIANT_TYPE ("(aiaiai)"));
697
698 5 g_variant_builder_add_value (&nested,
699 g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
700 5 xyt->xcol,
701 5 xyt->nrows,
702 sizeof (xyt->xcol[0])));
703 5 g_variant_builder_add_value (&nested,
704 g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
705 5 xyt->ycol,
706 5 xyt->nrows,
707 sizeof (xyt->ycol[0])));
708 5 g_variant_builder_add_value (&nested,
709 g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
710 5 xyt->thetacol,
711 5 xyt->nrows,
712 sizeof (xyt->thetacol[0])));
713 5 g_variant_builder_close (&nested);
714 }
715
716 1 g_variant_builder_close (&nested);
717 1 g_variant_builder_add (&builder, "v", g_variant_builder_end (&nested));
718 }
719 else
720 {
721 12 g_variant_builder_add (&builder, "v", g_variant_new_variant (print->data));
722 }
723
724 13 result = g_variant_builder_end (&builder);
725
726 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
727 GVariant *tmp;
728 tmp = g_variant_byteswap (result);
729 g_variant_unref (result);
730 result = tmp;
731 #endif
732
733 13 len = g_variant_get_size (result);
734 /* Add 3 bytes of header */
735 13 len += 3;
736
737 13 *data = g_malloc (len);
738 13 *length = len;
739
740 13 (*data)[0] = (guchar) 'F';
741 13 (*data)[1] = (guchar) 'P';
742 13 (*data)[2] = (guchar) '3';
743
744 13 g_variant_get_data (result);
745 13 g_variant_store (result, (*data) + 3);
746
747
1/2
✓ Branch 49 → 50 taken 13 times.
✗ Branch 49 → 51 not taken.
13 return TRUE;
748 }
749
750 /**
751 * fp_print_deserialize:
752 * @data: (array length=length): The binary data
753 * @length: Length of the data
754 * @error: Return location for error
755 *
756 * Deserialize a print definition from permanent storage.
757 *
758 * Returns: (transfer full): A newly created #FpPrint on success
759 */
760 FpPrint *
761 13 fp_print_deserialize (const guchar *data,
762 gsize length,
763 GError **error)
764 {
765 26 g_autoptr(FpPrint) result = NULL;
766
1/2
✗ Branch 80 → 81 not taken.
✓ Branch 80 → 82 taken 13 times.
13 g_autoptr(GVariant) raw_value = NULL;
767
1/2
✓ Branch 78 → 79 taken 13 times.
✗ Branch 78 → 80 not taken.
13 g_autoptr(GVariant) value = NULL;
768
1/2
✓ Branch 76 → 77 taken 13 times.
✗ Branch 76 → 78 not taken.
13 g_autoptr(GVariant) print_data = NULL;
769
1/2
✓ Branch 74 → 75 taken 13 times.
✗ Branch 74 → 76 not taken.
13 g_autoptr(GDate) date = NULL;
770
1/2
✓ Branch 72 → 73 taken 13 times.
✗ Branch 72 → 74 not taken.
13 g_autoptr(GBytes) bytes = NULL;
771 13 guint8 finger_int8;
772 13 FpFinger finger;
773
1/2
✓ Branch 70 → 71 taken 13 times.
✗ Branch 70 → 72 not taken.
13 g_autofree gchar *username = NULL;
774 13 g_autofree gchar *description = NULL;
775 13 gint julian_date;
776 13 FpiPrintType type;
777 13 const gchar *driver;
778 13 const gchar *device_id;
779 13 gboolean device_stored;
780
781
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 13 times.
13 g_assert (data);
782
1/2
✓ Branch 4 → 5 taken 13 times.
✗ Branch 4 → 6 not taken.
13 g_assert (length > 3);
783
784
1/2
✗ Branch 5 → 7 not taken.
✓ Branch 5 → 8 taken 13 times.
13 if (memcmp (data, "FP3", 3) != 0)
785 goto invalid_format;
786
787 /* NOTE:
788 * We make sure that we have no variant left over from the parsing at the end
789 * of this function (meaning we don't need to keep the data around.
790 */
791
792 /* We need to copy the backing store for the raw data that we may keep for
793 * longer. Using a GBytes also ensures the data is correctly aligned. */
794 13 bytes = g_bytes_new (data + 3, length - 3);
795 13 raw_value = g_variant_new_from_bytes (FPI_PRINT_VARIANT_TYPE, bytes, FALSE);
796
797
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 13 times.
13 if (!raw_value)
798 goto invalid_format;
799
800 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
801 value = g_variant_byteswap (raw_value);
802 #else
803 13 value = g_variant_get_normal_form (raw_value);
804 #endif
805
806 13 g_variant_get (value,
807 "(i&s&sbymsmsi@a{sv}v)",
808 &type,
809 &driver,
810 &device_id,
811 &device_stored,
812 &finger_int8,
813 &username,
814 &description,
815 &julian_date,
816 NULL,
817 &print_data);
818
819 13 finger = finger_int8;
820
821 /* Assume data is valid at this point if the values are somewhat sane. */
822
2/4
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 52 taken 12 times.
✗ Branch 15 → 58 not taken.
✗ Branch 15 → 62 not taken.
13 switch (type)
823 {
824 1 case FPI_PRINT_NBIS:
825 {
826 1 g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
827 1 guint i;
828
829 1 result = g_object_new (FP_TYPE_PRINT,
830 "driver", driver,
831 "device-id", device_id,
832 "device-stored", device_stored,
833 NULL);
834 1 g_object_ref_sink (result);
835 1 fpi_print_set_type (result, FPI_PRINT_NBIS);
836
2/2
✓ Branch 49 → 21 taken 5 times.
✓ Branch 49 → 50 taken 1 time.
7 for (i = 0; i < g_variant_n_children (prints); i++)
837 {
838
0/2
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 65 not taken.
5 g_autofree struct xyt_struct *xyt = NULL;
839 5 const gint32 *xcol, *ycol, *thetacol;
840 5 gsize xlen, ylen, thetalen;
841 5 g_autoptr(GVariant) xyt_data = NULL;
842 5 GVariant *child;
843
844 5 xyt_data = g_variant_get_child_value (prints, i);
845
846 5 child = g_variant_get_child_value (xyt_data, 0);
847 5 xcol = g_variant_get_fixed_array (child, &xlen, sizeof (gint32));
848 5 g_variant_unref (child);
849
850 5 child = g_variant_get_child_value (xyt_data, 1);
851 5 ycol = g_variant_get_fixed_array (child, &ylen, sizeof (gint32));
852 5 g_variant_unref (child);
853
854 5 child = g_variant_get_child_value (xyt_data, 2);
855 5 thetacol = g_variant_get_fixed_array (child, &thetalen, sizeof (gint32));
856 5 g_variant_unref (child);
857
858
2/4
✓ Branch 31 → 32 taken 5 times.
✗ Branch 31 → 33 not taken.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 34 taken 5 times.
5 if (xlen != ylen || xlen != thetalen)
859 goto invalid_format;
860
861
1/2
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 36 taken 5 times.
5 if (xlen > G_N_ELEMENTS (xyt->xcol))
862 goto invalid_format;
863
864 5 xyt = g_new0 (struct xyt_struct, 1);
865 5 xyt->nrows = xlen;
866 5 memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
867 5 memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
868 5 memcpy (xyt->thetacol, thetacol, sizeof (xcol[0]) * xlen);
869
870
1/2
✓ Branch 38 → 39 taken 5 times.
✗ Branch 38 → 40 not taken.
5 g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
871 }
872 }
873 break;
874
875 12 case FPI_PRINT_RAW:
876 {
877 12 g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
878
879 12 result = g_object_new (FP_TYPE_PRINT,
880 "fpi-type", type,
881 "driver", driver,
882 "device-id", device_id,
883 "device-stored", device_stored,
884 "fpi-data", fp_data,
885 NULL);
886
1/2
✓ Branch 56 → 57 taken 12 times.
✗ Branch 56 → 62 not taken.
12 g_object_ref_sink (result);
887 }
888 break;
889
890 case FPI_PRINT_UNDEFINED:
891 {
892 g_autofree char *type_str = g_enum_to_string (fpi_print_type_get_type (), type);
893 g_warning ("Invalid print type: 0x%X (%s)", type, type_str);
894
895 goto invalid_format;
896 }
897 }
898
899 13 date = g_date_new_julian (julian_date);
900 13 g_object_set (result,
901 "finger", finger,
902 "username", username,
903 "description", description,
904 "enroll_date", date,
905 NULL);
906
907 13 return g_steal_pointer (&result);
908
909 invalid_format:
910 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
911 "Data could not be parsed");
912 return NULL;
913 }
914