Coverage Report

Created: 2026-02-26 06:27

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