Coverage Report

Created: 2026-01-09 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/fu-uf2-struct.c
Line
Count
Source
1
/*
2
 * This file is auto-generated, do not modify!
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include <glib.h>
10
11
#include "fu-uf2-struct.h"
12
#include "fu-byte-array.h"
13
#include "fu-mem-private.h"
14
#include "fu-string.h"
15
16
#ifdef G_LOG_DOMAIN
17
  #undef G_LOG_DOMAIN
18
#endif
19
0
#define G_LOG_DOMAIN "FuStruct"
20
21
/**
22
 * fu_uf2_firmware_block_flags_to_string:
23
 * @val: value, e.g. %FU_UF2_FIRMWARE_BLOCK_FLAG_NOFLASH
24
 *
25
 * Converts an enumerated value to a string.
26
 *
27
 * Returns: identifier string
28
 **/
29
static const gchar *
30
fu_uf2_firmware_block_flags_to_string(FuUf2FirmwareBlockFlags val)
31
0
{
32
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_NONE)
33
0
        return "none";
34
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_NOFLASH)
35
0
        return "noflash";
36
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_IS_CONTAINER)
37
0
        return "is-container";
38
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_HAS_FAMILY)
39
0
        return "has-family";
40
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_HAS_MD5)
41
0
        return "has-md5";
42
0
    if (val == FU_UF2_FIRMWARE_BLOCK_FLAG_HAS_EXTENSION_TAG)
43
0
        return "has-extension-tag";
44
0
    return NULL;
45
0
}
46
47
/**
48
 * fu_uf2_firmware_tag_to_string:
49
 * @val: value, e.g. %FU_UF2_FIRMWARE_TAG_DESCRIPTION
50
 *
51
 * Converts an enumerated value to a string.
52
 *
53
 * Returns: identifier string
54
 **/
55
const gchar *
56
fu_uf2_firmware_tag_to_string(FuUf2FirmwareTag val)
57
12
{
58
12
    if (val == FU_UF2_FIRMWARE_TAG_VERSION)
59
0
        return "version";
60
12
    if (val == FU_UF2_FIRMWARE_TAG_DESCRIPTION)
61
0
        return "description";
62
12
    if (val == FU_UF2_FIRMWARE_TAG_PAGE_SZ)
63
0
        return "page-sz";
64
12
    if (val == FU_UF2_FIRMWARE_TAG_SHA2)
65
0
        return "sha2";
66
12
    if (val == FU_UF2_FIRMWARE_TAG_DEVICE_ID)
67
0
        return "device-id";
68
12
    return NULL;
69
12
}
70
/**
71
 * fu_struct_uf2_extension_ref: (skip):
72
 **/
73
FuStructUf2Extension *
74
fu_struct_uf2_extension_ref(FuStructUf2Extension *st)
75
0
{
76
0
    g_return_val_if_fail(st != NULL, NULL);
77
0
    st->refcount++;
78
0
    return st;
79
0
}
80
/**
81
 * fu_struct_uf2_extension_unref: (skip):
82
 **/
83
void
84
fu_struct_uf2_extension_unref(FuStructUf2Extension *st)
85
12.7k
{
86
12.7k
    g_return_if_fail(st != NULL);
87
12.7k
    if (st->refcount == 0) {
88
0
        g_critical("FuStructUf2Extension refcount already zero");
89
0
        return;
90
0
    }
91
12.7k
    if (--st->refcount > 0)
92
0
        return;
93
12.7k
    if (st->buf != NULL)
94
12.7k
        g_byte_array_unref(st->buf);
95
12.7k
    g_free(st);
96
12.7k
}
97
/**
98
 * fu_struct_uf2_extension_new_internal: (skip):
99
 **/
100
static FuStructUf2Extension *
101
fu_struct_uf2_extension_new_internal(void)
102
12.7k
{
103
12.7k
    FuStructUf2Extension *st = g_new0(FuStructUf2Extension, 1);
104
12.7k
    st->refcount = 1;
105
12.7k
    return st;
106
12.7k
}
107
108
/* getters */
109
/**
110
 * fu_struct_uf2_extension_get_size: (skip):
111
 **/
112
guint8
113
fu_struct_uf2_extension_get_size(const FuStructUf2Extension *st)
114
11.4k
{
115
11.4k
    g_return_val_if_fail(st != NULL, 0x0);
116
11.4k
    return st->buf->data[0];
117
11.4k
}
118
/**
119
 * fu_struct_uf2_extension_get_tag: (skip):
120
 **/
121
FuUf2FirmwareTag
122
fu_struct_uf2_extension_get_tag(const FuStructUf2Extension *st)
123
11.3k
{
124
11.3k
    g_return_val_if_fail(st != NULL, 0x0);
125
11.3k
    return fu_memread_uint24(st->buf->data + 1, G_LITTLE_ENDIAN);
126
11.3k
}
127
128
/* setters */
129
/**
130
 * fu_struct_uf2_extension_set_size: (skip):
131
 **/
132
void
133
fu_struct_uf2_extension_set_size(FuStructUf2Extension *st, guint8 value)
134
830
{
135
830
    g_return_if_fail(st != NULL);
136
830
    st->buf->data[0] = value;
137
830
}
138
/**
139
 * fu_struct_uf2_extension_set_tag: (skip):
140
 **/
141
void
142
fu_struct_uf2_extension_set_tag(FuStructUf2Extension *st, FuUf2FirmwareTag value)
143
830
{
144
830
    g_return_if_fail(st != NULL);
145
830
    fu_memwrite_uint24(st->buf->data + 1, value, G_LITTLE_ENDIAN);
146
830
}
147
/**
148
 * fu_struct_uf2_extension_new: (skip):
149
 **/
150
FuStructUf2Extension *
151
fu_struct_uf2_extension_new(void)
152
1.26k
{
153
1.26k
    FuStructUf2Extension *st = fu_struct_uf2_extension_new_internal();
154
1.26k
    st->buf = g_byte_array_sized_new(4);
155
1.26k
    fu_byte_array_set_size(st->buf, 4, 0x0);
156
1.26k
    return st;
157
1.26k
}
158
/**
159
 * fu_struct_uf2_extension_to_string: (skip):
160
 **/
161
static gchar *
162
fu_struct_uf2_extension_to_string(const FuStructUf2Extension *st)
163
0
{
164
0
    g_autoptr(GString) str = g_string_new("FuStructUf2Extension:\n");
165
0
    g_return_val_if_fail(st != NULL, NULL);
166
0
    g_string_append_printf(str, "  size: 0x%x\n",
167
0
                           (guint) fu_struct_uf2_extension_get_size(st));
168
0
    {
169
0
        const gchar *tmp = fu_uf2_firmware_tag_to_string(fu_struct_uf2_extension_get_tag(st));
170
0
        if (tmp != NULL) {
171
0
            g_string_append_printf(str, "  tag: 0x%x [%s]\n", (guint) fu_struct_uf2_extension_get_tag(st), tmp);
172
0
        } else {
173
0
            g_string_append_printf(str, "  tag: 0x%x\n", (guint) fu_struct_uf2_extension_get_tag(st));
174
0
        }
175
0
    }
176
0
    if (str->len > 0)
177
0
        g_string_set_size(str, str->len - 1);
178
0
    return g_string_free(g_steal_pointer(&str), FALSE);
179
0
}
180
static gboolean
181
fu_struct_uf2_extension_validate_internal(FuStructUf2Extension *st, GError **error)
182
11.4k
{
183
11.4k
    g_return_val_if_fail(st != NULL, FALSE);
184
11.4k
    return TRUE;
185
11.4k
}
186
static gboolean
187
fu_struct_uf2_extension_parse_internal(FuStructUf2Extension *st, GError **error)
188
11.4k
{
189
11.4k
    if (g_getenv("FWUPD_VERBOSE") != NULL) {
190
0
        g_autofree gchar *str = fu_struct_uf2_extension_to_string(st);
191
0
        g_debug("%s", str);
192
0
    }
193
11.4k
    if (!fu_struct_uf2_extension_validate_internal(st, error))
194
0
        return FALSE;
195
11.4k
    return TRUE;
196
11.4k
}
197
198
/**
199
 * fu_struct_uf2_extension_parse: (skip):
200
 **/
201
FuStructUf2Extension *
202
fu_struct_uf2_extension_parse(const guint8 *buf, gsize bufsz, gsize offset, GError **error)
203
11.4k
{
204
11.4k
    g_autoptr(FuStructUf2Extension) st = fu_struct_uf2_extension_new_internal();
205
11.4k
    g_return_val_if_fail(buf != NULL, NULL);
206
11.4k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
207
11.4k
    if (!fu_memchk_read(bufsz, offset, 4, error)) {
208
28
        g_prefix_error_literal(error, "invalid struct FuStructUf2Extension: ");
209
28
        return NULL;
210
28
    }
211
11.4k
    st->buf = g_byte_array_new();
212
11.4k
    g_byte_array_append(st->buf, buf + offset, 4);
213
11.4k
    if (!fu_struct_uf2_extension_parse_internal(st, error))
214
0
        return NULL;
215
11.4k
    return g_steal_pointer(&st);
216
11.4k
}
217
/**
218
 * fu_struct_uf2_ref: (skip):
219
 **/
220
FuStructUf2 *
221
fu_struct_uf2_ref(FuStructUf2 *st)
222
0
{
223
0
    g_return_val_if_fail(st != NULL, NULL);
224
0
    st->refcount++;
225
0
    return st;
226
0
}
227
/**
228
 * fu_struct_uf2_unref: (skip):
229
 **/
230
void
231
fu_struct_uf2_unref(FuStructUf2 *st)
232
2.11k
{
233
2.11k
    g_return_if_fail(st != NULL);
234
2.11k
    if (st->refcount == 0) {
235
0
        g_critical("FuStructUf2 refcount already zero");
236
0
        return;
237
0
    }
238
2.11k
    if (--st->refcount > 0)
239
0
        return;
240
2.11k
    if (st->buf != NULL)
241
1.23k
        g_byte_array_unref(st->buf);
242
2.11k
    g_free(st);
243
2.11k
}
244
/**
245
 * fu_struct_uf2_new_internal: (skip):
246
 **/
247
static FuStructUf2 *
248
fu_struct_uf2_new_internal(void)
249
2.11k
{
250
2.11k
    FuStructUf2 *st = g_new0(FuStructUf2, 1);
251
2.11k
    st->refcount = 1;
252
2.11k
    return st;
253
2.11k
}
254
255
/* getters */
256
/**
257
 * fu_struct_uf2_get_magic0: (skip):
258
 **/
259
static guint32
260
fu_struct_uf2_get_magic0(const FuStructUf2 *st)
261
1.28k
{
262
1.28k
    g_return_val_if_fail(st != NULL, 0x0);
263
1.28k
    return fu_memread_uint32(st->buf->data + 0, G_LITTLE_ENDIAN);
264
1.28k
}
265
/**
266
 * fu_struct_uf2_get_magic1: (skip):
267
 **/
268
static guint32
269
fu_struct_uf2_get_magic1(const FuStructUf2 *st)
270
1.22k
{
271
1.22k
    g_return_val_if_fail(st != NULL, 0x0);
272
1.22k
    return fu_memread_uint32(st->buf->data + 4, G_LITTLE_ENDIAN);
273
1.22k
}
274
/**
275
 * fu_struct_uf2_get_flags: (skip):
276
 **/
277
FuUf2FirmwareBlockFlags
278
fu_struct_uf2_get_flags(const FuStructUf2 *st)
279
1.03k
{
280
1.03k
    g_return_val_if_fail(st != NULL, 0x0);
281
1.03k
    return fu_memread_uint32(st->buf->data + 8, G_LITTLE_ENDIAN);
282
1.03k
}
283
/**
284
 * fu_struct_uf2_get_target_addr: (skip):
285
 **/
286
guint32
287
fu_struct_uf2_get_target_addr(const FuStructUf2 *st)
288
378
{
289
378
    g_return_val_if_fail(st != NULL, 0x0);
290
378
    return fu_memread_uint32(st->buf->data + 12, G_LITTLE_ENDIAN);
291
378
}
292
/**
293
 * fu_struct_uf2_get_payload_size: (skip):
294
 **/
295
guint32
296
fu_struct_uf2_get_payload_size(const FuStructUf2 *st)
297
1.03k
{
298
1.03k
    g_return_val_if_fail(st != NULL, 0x0);
299
1.03k
    return fu_memread_uint32(st->buf->data + 16, G_LITTLE_ENDIAN);
300
1.03k
}
301
/**
302
 * fu_struct_uf2_get_block_no: (skip):
303
 **/
304
guint32
305
fu_struct_uf2_get_block_no(const FuStructUf2 *st)
306
1.05k
{
307
1.05k
    g_return_val_if_fail(st != NULL, 0x0);
308
1.05k
    return fu_memread_uint32(st->buf->data + 20, G_LITTLE_ENDIAN);
309
1.05k
}
310
/**
311
 * fu_struct_uf2_get_num_blocks: (skip):
312
 **/
313
guint32
314
fu_struct_uf2_get_num_blocks(const FuStructUf2 *st)
315
949
{
316
949
    g_return_val_if_fail(st != NULL, 0x0);
317
949
    return fu_memread_uint32(st->buf->data + 24, G_LITTLE_ENDIAN);
318
949
}
319
/**
320
 * fu_struct_uf2_get_family_id: (skip):
321
 **/
322
guint32
323
fu_struct_uf2_get_family_id(const FuStructUf2 *st)
324
676
{
325
676
    g_return_val_if_fail(st != NULL, 0x0);
326
676
    return fu_memread_uint32(st->buf->data + 28, G_LITTLE_ENDIAN);
327
676
}
328
/**
329
 * fu_struct_uf2_get_data: (skip):
330
 **/
331
const guint8 *
332
fu_struct_uf2_get_data(const FuStructUf2 *st, gsize *bufsz)
333
946
{
334
946
    g_return_val_if_fail(st != NULL, NULL);
335
946
    if (bufsz != NULL)
336
0
        *bufsz = 476;
337
946
    return st->buf->data + 32;
338
946
}
339
/**
340
 * fu_struct_uf2_get_magic_end: (skip):
341
 **/
342
static guint32
343
fu_struct_uf2_get_magic_end(const FuStructUf2 *st)
344
1.18k
{
345
1.18k
    g_return_val_if_fail(st != NULL, 0x0);
346
1.18k
    return fu_memread_uint32(st->buf->data + 508, G_LITTLE_ENDIAN);
347
1.18k
}
348
349
/* setters */
350
/**
351
 * fu_struct_uf2_set_magic0: (skip):
352
 **/
353
static void
354
fu_struct_uf2_set_magic0(FuStructUf2 *st, guint32 value)
355
853
{
356
853
    g_return_if_fail(st != NULL);
357
853
    fu_memwrite_uint32(st->buf->data + 0, value, G_LITTLE_ENDIAN);
358
853
}
359
/**
360
 * fu_struct_uf2_set_magic1: (skip):
361
 **/
362
static void
363
fu_struct_uf2_set_magic1(FuStructUf2 *st, guint32 value)
364
853
{
365
853
    g_return_if_fail(st != NULL);
366
853
    fu_memwrite_uint32(st->buf->data + 4, value, G_LITTLE_ENDIAN);
367
853
}
368
/**
369
 * fu_struct_uf2_set_flags: (skip):
370
 **/
371
void
372
fu_struct_uf2_set_flags(FuStructUf2 *st, FuUf2FirmwareBlockFlags value)
373
853
{
374
853
    g_return_if_fail(st != NULL);
375
853
    fu_memwrite_uint32(st->buf->data + 8, value, G_LITTLE_ENDIAN);
376
853
}
377
/**
378
 * fu_struct_uf2_set_target_addr: (skip):
379
 **/
380
void
381
fu_struct_uf2_set_target_addr(FuStructUf2 *st, guint32 value)
382
853
{
383
853
    g_return_if_fail(st != NULL);
384
853
    fu_memwrite_uint32(st->buf->data + 12, value, G_LITTLE_ENDIAN);
385
853
}
386
/**
387
 * fu_struct_uf2_set_payload_size: (skip):
388
 **/
389
void
390
fu_struct_uf2_set_payload_size(FuStructUf2 *st, guint32 value)
391
853
{
392
853
    g_return_if_fail(st != NULL);
393
853
    fu_memwrite_uint32(st->buf->data + 16, value, G_LITTLE_ENDIAN);
394
853
}
395
/**
396
 * fu_struct_uf2_set_block_no: (skip):
397
 **/
398
void
399
fu_struct_uf2_set_block_no(FuStructUf2 *st, guint32 value)
400
853
{
401
853
    g_return_if_fail(st != NULL);
402
853
    fu_memwrite_uint32(st->buf->data + 20, value, G_LITTLE_ENDIAN);
403
853
}
404
/**
405
 * fu_struct_uf2_set_num_blocks: (skip):
406
 **/
407
void
408
fu_struct_uf2_set_num_blocks(FuStructUf2 *st, guint32 value)
409
853
{
410
853
    g_return_if_fail(st != NULL);
411
853
    fu_memwrite_uint32(st->buf->data + 24, value, G_LITTLE_ENDIAN);
412
853
}
413
/**
414
 * fu_struct_uf2_set_family_id: (skip):
415
 **/
416
void
417
fu_struct_uf2_set_family_id(FuStructUf2 *st, guint32 value)
418
853
{
419
853
    g_return_if_fail(st != NULL);
420
853
    fu_memwrite_uint32(st->buf->data + 28, value, G_LITTLE_ENDIAN);
421
853
}
422
/**
423
 * fu_struct_uf2_set_data: (skip):
424
 **/
425
gboolean
426
fu_struct_uf2_set_data(FuStructUf2 *st, const guint8 *buf, gsize bufsz, GError **error)
427
853
{
428
853
    g_return_val_if_fail(st != NULL, FALSE);
429
853
    g_return_val_if_fail(buf != NULL, FALSE);
430
853
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
431
853
    return fu_memcpy_safe(st->buf->data, st->buf->len, 32, buf, bufsz, 0x0, bufsz, error);
432
853
}
433
/**
434
 * fu_struct_uf2_set_magic_end: (skip):
435
 **/
436
static void
437
fu_struct_uf2_set_magic_end(FuStructUf2 *st, guint32 value)
438
853
{
439
853
    g_return_if_fail(st != NULL);
440
853
    fu_memwrite_uint32(st->buf->data + 508, value, G_LITTLE_ENDIAN);
441
853
}
442
/**
443
 * fu_struct_uf2_new: (skip):
444
 **/
445
FuStructUf2 *
446
fu_struct_uf2_new(void)
447
853
{
448
853
    FuStructUf2 *st = fu_struct_uf2_new_internal();
449
853
    st->buf = g_byte_array_sized_new(512);
450
853
    fu_byte_array_set_size(st->buf, 512, 0x0);
451
853
    fu_struct_uf2_set_magic0(st, 0x0A324655);
452
853
    fu_struct_uf2_set_magic1(st, 0x9E5D5157);
453
853
    fu_struct_uf2_set_magic_end(st, 0x0AB16F30);
454
853
    return st;
455
853
}
456
/**
457
 * fu_struct_uf2_to_string: (skip):
458
 **/
459
static gchar *
460
fu_struct_uf2_to_string(const FuStructUf2 *st)
461
0
{
462
0
    g_autoptr(GString) str = g_string_new("FuStructUf2:\n");
463
0
    g_return_val_if_fail(st != NULL, NULL);
464
0
    g_string_append_printf(str, "  magic0: 0x%x\n",
465
0
                           (guint) fu_struct_uf2_get_magic0(st));
466
0
    g_string_append_printf(str, "  magic1: 0x%x\n",
467
0
                           (guint) fu_struct_uf2_get_magic1(st));
468
0
    {
469
0
        const gchar *tmp = fu_uf2_firmware_block_flags_to_string(fu_struct_uf2_get_flags(st));
470
0
        if (tmp != NULL) {
471
0
            g_string_append_printf(str, "  flags: 0x%x [%s]\n", (guint) fu_struct_uf2_get_flags(st), tmp);
472
0
        } else {
473
0
            g_string_append_printf(str, "  flags: 0x%x\n", (guint) fu_struct_uf2_get_flags(st));
474
0
        }
475
0
    }
476
0
    g_string_append_printf(str, "  target_addr: 0x%x\n",
477
0
                           (guint) fu_struct_uf2_get_target_addr(st));
478
0
    g_string_append_printf(str, "  payload_size: 0x%x\n",
479
0
                           (guint) fu_struct_uf2_get_payload_size(st));
480
0
    g_string_append_printf(str, "  block_no: 0x%x\n",
481
0
                           (guint) fu_struct_uf2_get_block_no(st));
482
0
    g_string_append_printf(str, "  num_blocks: 0x%x\n",
483
0
                           (guint) fu_struct_uf2_get_num_blocks(st));
484
0
    g_string_append_printf(str, "  family_id: 0x%x\n",
485
0
                           (guint) fu_struct_uf2_get_family_id(st));
486
0
    {
487
0
        gsize bufsz = 0;
488
0
        const guint8 *buf = fu_struct_uf2_get_data(st, &bufsz);
489
0
        g_autoptr(GString) tmp = g_string_new(NULL);
490
0
        for (gsize i = 0; i < bufsz; i++)
491
0
            g_string_append_printf(tmp, "%02X", buf[i]);
492
0
        g_string_append_printf(str, "  data: 0x%s\n", tmp->str);
493
0
    }
494
0
    g_string_append_printf(str, "  magic_end: 0x%x\n",
495
0
                           (guint) fu_struct_uf2_get_magic_end(st));
496
0
    if (str->len > 0)
497
0
        g_string_set_size(str, str->len - 1);
498
0
    return g_string_free(g_steal_pointer(&str), FALSE);
499
0
}
500
static gboolean
501
fu_struct_uf2_validate_internal(FuStructUf2 *st, GError **error)
502
1.22k
{
503
1.22k
    g_return_val_if_fail(st != NULL, FALSE);
504
1.22k
    if (fu_struct_uf2_get_magic0(st) != 0x0A324655) {
505
59
        g_set_error(error,
506
59
                    FWUPD_ERROR,
507
59
                    FWUPD_ERROR_INVALID_DATA,
508
59
                    "constant FuStructUf2.magic0 was not valid, "
509
59
                    "expected 0x%x and got 0x%x",
510
59
                    (guint) 0x0A324655,
511
59
                    (guint) fu_struct_uf2_get_magic0(st));
512
59
        return FALSE;
513
59
    }
514
1.16k
    if (fu_struct_uf2_get_magic1(st) != 0x9E5D5157) {
515
56
        g_set_error(error,
516
56
                    FWUPD_ERROR,
517
56
                    FWUPD_ERROR_INVALID_DATA,
518
56
                    "constant FuStructUf2.magic1 was not valid, "
519
56
                    "expected 0x%x and got 0x%x",
520
56
                    (guint) 0x9E5D5157,
521
56
                    (guint) fu_struct_uf2_get_magic1(st));
522
56
        return FALSE;
523
56
    }
524
1.11k
    if (fu_struct_uf2_get_magic_end(st) != 0x0AB16F30) {
525
77
        g_set_error(error,
526
77
                    FWUPD_ERROR,
527
77
                    FWUPD_ERROR_INVALID_DATA,
528
77
                    "constant FuStructUf2.magic_end was not valid, "
529
77
                    "expected 0x%x and got 0x%x",
530
77
                    (guint) 0x0AB16F30,
531
77
                    (guint) fu_struct_uf2_get_magic_end(st));
532
77
        return FALSE;
533
77
    }
534
1.03k
    return TRUE;
535
1.11k
}
536
static gboolean
537
fu_struct_uf2_parse_internal(FuStructUf2 *st, GError **error)
538
1.22k
{
539
1.22k
    if (g_getenv("FWUPD_VERBOSE") != NULL) {
540
0
        g_autofree gchar *str = fu_struct_uf2_to_string(st);
541
0
        g_debug("%s", str);
542
0
    }
543
1.22k
    if (!fu_struct_uf2_validate_internal(st, error))
544
192
        return FALSE;
545
1.03k
    return TRUE;
546
1.22k
}
547
548
/**
549
 * fu_struct_uf2_parse: (skip):
550
 **/
551
FuStructUf2 *
552
fu_struct_uf2_parse(const guint8 *buf, gsize bufsz, gsize offset, GError **error)
553
1.26k
{
554
1.26k
    g_autoptr(FuStructUf2) st = fu_struct_uf2_new_internal();
555
1.26k
    g_return_val_if_fail(buf != NULL, NULL);
556
1.26k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
557
1.26k
    if (!fu_memchk_read(bufsz, offset, 512, error)) {
558
39
        g_prefix_error_literal(error, "invalid struct FuStructUf2: ");
559
39
        return NULL;
560
39
    }
561
1.22k
    st->buf = g_byte_array_new();
562
1.22k
    g_byte_array_append(st->buf, buf + offset, 512);
563
1.22k
    if (!fu_struct_uf2_parse_internal(st, error))
564
192
        return NULL;
565
1.03k
    return g_steal_pointer(&st);
566
1.22k
}