Coverage Report

Created: 2026-01-10 07:09

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
10
{
58
10
    if (val == FU_UF2_FIRMWARE_TAG_VERSION)
59
0
        return "version";
60
10
    if (val == FU_UF2_FIRMWARE_TAG_DESCRIPTION)
61
0
        return "description";
62
10
    if (val == FU_UF2_FIRMWARE_TAG_PAGE_SZ)
63
0
        return "page-sz";
64
10
    if (val == FU_UF2_FIRMWARE_TAG_SHA2)
65
0
        return "sha2";
66
10
    if (val == FU_UF2_FIRMWARE_TAG_DEVICE_ID)
67
0
        return "device-id";
68
10
    return NULL;
69
10
}
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
11.8k
{
86
11.8k
    g_return_if_fail(st != NULL);
87
11.8k
    if (st->refcount == 0) {
88
0
        g_critical("FuStructUf2Extension refcount already zero");
89
0
        return;
90
0
    }
91
11.8k
    if (--st->refcount > 0)
92
0
        return;
93
11.8k
    if (st->buf != NULL)
94
11.8k
        g_byte_array_unref(st->buf);
95
11.8k
    g_free(st);
96
11.8k
}
97
/**
98
 * fu_struct_uf2_extension_new_internal: (skip):
99
 **/
100
static FuStructUf2Extension *
101
fu_struct_uf2_extension_new_internal(void)
102
11.8k
{
103
11.8k
    FuStructUf2Extension *st = g_new0(FuStructUf2Extension, 1);
104
11.8k
    st->refcount = 1;
105
11.8k
    return st;
106
11.8k
}
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
10.4k
{
115
10.4k
    g_return_val_if_fail(st != NULL, 0x0);
116
10.4k
    return st->buf->data[0];
117
10.4k
}
118
/**
119
 * fu_struct_uf2_extension_get_tag: (skip):
120
 **/
121
FuUf2FirmwareTag
122
fu_struct_uf2_extension_get_tag(const FuStructUf2Extension *st)
123
10.3k
{
124
10.3k
    g_return_val_if_fail(st != NULL, 0x0);
125
10.3k
    return fu_memread_uint24(st->buf->data + 1, G_LITTLE_ENDIAN);
126
10.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
879
{
135
879
    g_return_if_fail(st != NULL);
136
879
    st->buf->data[0] = value;
137
879
}
138
/**
139
 * fu_struct_uf2_extension_set_tag: (skip):
140
 **/
141
void
142
fu_struct_uf2_extension_set_tag(FuStructUf2Extension *st, FuUf2FirmwareTag value)
143
879
{
144
879
    g_return_if_fail(st != NULL);
145
879
    fu_memwrite_uint24(st->buf->data + 1, value, G_LITTLE_ENDIAN);
146
879
}
147
/**
148
 * fu_struct_uf2_extension_new: (skip):
149
 **/
150
FuStructUf2Extension *
151
fu_struct_uf2_extension_new(void)
152
1.34k
{
153
1.34k
    FuStructUf2Extension *st = fu_struct_uf2_extension_new_internal();
154
1.34k
    st->buf = g_byte_array_sized_new(4);
155
1.34k
    fu_byte_array_set_size(st->buf, 4, 0x0);
156
1.34k
    return st;
157
1.34k
}
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
10.4k
{
183
10.4k
    g_return_val_if_fail(st != NULL, FALSE);
184
10.4k
    return TRUE;
185
10.4k
}
186
static gboolean
187
fu_struct_uf2_extension_parse_internal(FuStructUf2Extension *st, GError **error)
188
10.4k
{
189
10.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
10.4k
    if (!fu_struct_uf2_extension_validate_internal(st, error))
194
0
        return FALSE;
195
10.4k
    return TRUE;
196
10.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
10.4k
{
204
10.4k
    g_autoptr(FuStructUf2Extension) st = fu_struct_uf2_extension_new_internal();
205
10.4k
    g_return_val_if_fail(buf != NULL, NULL);
206
10.4k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
207
10.4k
    if (!fu_memchk_read(bufsz, offset, 4, error)) {
208
24
        g_prefix_error_literal(error, "invalid struct FuStructUf2Extension: ");
209
24
        return NULL;
210
24
    }
211
10.4k
    st->buf = g_byte_array_new();
212
10.4k
    g_byte_array_append(st->buf, buf + offset, 4);
213
10.4k
    if (!fu_struct_uf2_extension_parse_internal(st, error))
214
0
        return NULL;
215
10.4k
    return g_steal_pointer(&st);
216
10.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.21k
{
233
2.21k
    g_return_if_fail(st != NULL);
234
2.21k
    if (st->refcount == 0) {
235
0
        g_critical("FuStructUf2 refcount already zero");
236
0
        return;
237
0
    }
238
2.21k
    if (--st->refcount > 0)
239
0
        return;
240
2.21k
    if (st->buf != NULL)
241
1.28k
        g_byte_array_unref(st->buf);
242
2.21k
    g_free(st);
243
2.21k
}
244
/**
245
 * fu_struct_uf2_new_internal: (skip):
246
 **/
247
static FuStructUf2 *
248
fu_struct_uf2_new_internal(void)
249
2.21k
{
250
2.21k
    FuStructUf2 *st = g_new0(FuStructUf2, 1);
251
2.21k
    st->refcount = 1;
252
2.21k
    return st;
253
2.21k
}
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.33k
{
262
1.33k
    g_return_val_if_fail(st != NULL, 0x0);
263
1.33k
    return fu_memread_uint32(st->buf->data + 0, G_LITTLE_ENDIAN);
264
1.33k
}
265
/**
266
 * fu_struct_uf2_get_magic1: (skip):
267
 **/
268
static guint32
269
fu_struct_uf2_get_magic1(const FuStructUf2 *st)
270
1.26k
{
271
1.26k
    g_return_val_if_fail(st != NULL, 0x0);
272
1.26k
    return fu_memread_uint32(st->buf->data + 4, G_LITTLE_ENDIAN);
273
1.26k
}
274
/**
275
 * fu_struct_uf2_get_flags: (skip):
276
 **/
277
FuUf2FirmwareBlockFlags
278
fu_struct_uf2_get_flags(const FuStructUf2 *st)
279
1.07k
{
280
1.07k
    g_return_val_if_fail(st != NULL, 0x0);
281
1.07k
    return fu_memread_uint32(st->buf->data + 8, G_LITTLE_ENDIAN);
282
1.07k
}
283
/**
284
 * fu_struct_uf2_get_target_addr: (skip):
285
 **/
286
guint32
287
fu_struct_uf2_get_target_addr(const FuStructUf2 *st)
288
386
{
289
386
    g_return_val_if_fail(st != NULL, 0x0);
290
386
    return fu_memread_uint32(st->buf->data + 12, G_LITTLE_ENDIAN);
291
386
}
292
/**
293
 * fu_struct_uf2_get_payload_size: (skip):
294
 **/
295
guint32
296
fu_struct_uf2_get_payload_size(const FuStructUf2 *st)
297
1.07k
{
298
1.07k
    g_return_val_if_fail(st != NULL, 0x0);
299
1.07k
    return fu_memread_uint32(st->buf->data + 16, G_LITTLE_ENDIAN);
300
1.07k
}
301
/**
302
 * fu_struct_uf2_get_block_no: (skip):
303
 **/
304
guint32
305
fu_struct_uf2_get_block_no(const FuStructUf2 *st)
306
1.09k
{
307
1.09k
    g_return_val_if_fail(st != NULL, 0x0);
308
1.09k
    return fu_memread_uint32(st->buf->data + 20, G_LITTLE_ENDIAN);
309
1.09k
}
310
/**
311
 * fu_struct_uf2_get_num_blocks: (skip):
312
 **/
313
guint32
314
fu_struct_uf2_get_num_blocks(const FuStructUf2 *st)
315
994
{
316
994
    g_return_val_if_fail(st != NULL, 0x0);
317
994
    return fu_memread_uint32(st->buf->data + 24, G_LITTLE_ENDIAN);
318
994
}
319
/**
320
 * fu_struct_uf2_get_family_id: (skip):
321
 **/
322
guint32
323
fu_struct_uf2_get_family_id(const FuStructUf2 *st)
324
715
{
325
715
    g_return_val_if_fail(st != NULL, 0x0);
326
715
    return fu_memread_uint32(st->buf->data + 28, G_LITTLE_ENDIAN);
327
715
}
328
/**
329
 * fu_struct_uf2_get_data: (skip):
330
 **/
331
const guint8 *
332
fu_struct_uf2_get_data(const FuStructUf2 *st, gsize *bufsz)
333
991
{
334
991
    g_return_val_if_fail(st != NULL, NULL);
335
991
    if (bufsz != NULL)
336
0
        *bufsz = 476;
337
991
    return st->buf->data + 32;
338
991
}
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.24k
{
345
1.24k
    g_return_val_if_fail(st != NULL, 0x0);
346
1.24k
    return fu_memread_uint32(st->buf->data + 508, G_LITTLE_ENDIAN);
347
1.24k
}
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
906
{
356
906
    g_return_if_fail(st != NULL);
357
906
    fu_memwrite_uint32(st->buf->data + 0, value, G_LITTLE_ENDIAN);
358
906
}
359
/**
360
 * fu_struct_uf2_set_magic1: (skip):
361
 **/
362
static void
363
fu_struct_uf2_set_magic1(FuStructUf2 *st, guint32 value)
364
906
{
365
906
    g_return_if_fail(st != NULL);
366
906
    fu_memwrite_uint32(st->buf->data + 4, value, G_LITTLE_ENDIAN);
367
906
}
368
/**
369
 * fu_struct_uf2_set_flags: (skip):
370
 **/
371
void
372
fu_struct_uf2_set_flags(FuStructUf2 *st, FuUf2FirmwareBlockFlags value)
373
906
{
374
906
    g_return_if_fail(st != NULL);
375
906
    fu_memwrite_uint32(st->buf->data + 8, value, G_LITTLE_ENDIAN);
376
906
}
377
/**
378
 * fu_struct_uf2_set_target_addr: (skip):
379
 **/
380
void
381
fu_struct_uf2_set_target_addr(FuStructUf2 *st, guint32 value)
382
906
{
383
906
    g_return_if_fail(st != NULL);
384
906
    fu_memwrite_uint32(st->buf->data + 12, value, G_LITTLE_ENDIAN);
385
906
}
386
/**
387
 * fu_struct_uf2_set_payload_size: (skip):
388
 **/
389
void
390
fu_struct_uf2_set_payload_size(FuStructUf2 *st, guint32 value)
391
906
{
392
906
    g_return_if_fail(st != NULL);
393
906
    fu_memwrite_uint32(st->buf->data + 16, value, G_LITTLE_ENDIAN);
394
906
}
395
/**
396
 * fu_struct_uf2_set_block_no: (skip):
397
 **/
398
void
399
fu_struct_uf2_set_block_no(FuStructUf2 *st, guint32 value)
400
906
{
401
906
    g_return_if_fail(st != NULL);
402
906
    fu_memwrite_uint32(st->buf->data + 20, value, G_LITTLE_ENDIAN);
403
906
}
404
/**
405
 * fu_struct_uf2_set_num_blocks: (skip):
406
 **/
407
void
408
fu_struct_uf2_set_num_blocks(FuStructUf2 *st, guint32 value)
409
906
{
410
906
    g_return_if_fail(st != NULL);
411
906
    fu_memwrite_uint32(st->buf->data + 24, value, G_LITTLE_ENDIAN);
412
906
}
413
/**
414
 * fu_struct_uf2_set_family_id: (skip):
415
 **/
416
void
417
fu_struct_uf2_set_family_id(FuStructUf2 *st, guint32 value)
418
906
{
419
906
    g_return_if_fail(st != NULL);
420
906
    fu_memwrite_uint32(st->buf->data + 28, value, G_LITTLE_ENDIAN);
421
906
}
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
906
{
428
906
    g_return_val_if_fail(st != NULL, FALSE);
429
906
    g_return_val_if_fail(buf != NULL, FALSE);
430
906
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
431
906
    return fu_memcpy_safe(st->buf->data, st->buf->len, 32, buf, bufsz, 0x0, bufsz, error);
432
906
}
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
906
{
439
906
    g_return_if_fail(st != NULL);
440
906
    fu_memwrite_uint32(st->buf->data + 508, value, G_LITTLE_ENDIAN);
441
906
}
442
/**
443
 * fu_struct_uf2_new: (skip):
444
 **/
445
FuStructUf2 *
446
fu_struct_uf2_new(void)
447
906
{
448
906
    FuStructUf2 *st = fu_struct_uf2_new_internal();
449
906
    st->buf = g_byte_array_sized_new(512);
450
906
    fu_byte_array_set_size(st->buf, 512, 0x0);
451
906
    fu_struct_uf2_set_magic0(st, 0x0A324655);
452
906
    fu_struct_uf2_set_magic1(st, 0x9E5D5157);
453
906
    fu_struct_uf2_set_magic_end(st, 0x0AB16F30);
454
906
    return st;
455
906
}
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.27k
{
503
1.27k
    g_return_val_if_fail(st != NULL, FALSE);
504
1.27k
    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.21k
    if (fu_struct_uf2_get_magic1(st) != 0x9E5D5157) {
515
52
        g_set_error(error,
516
52
                    FWUPD_ERROR,
517
52
                    FWUPD_ERROR_INVALID_DATA,
518
52
                    "constant FuStructUf2.magic1 was not valid, "
519
52
                    "expected 0x%x and got 0x%x",
520
52
                    (guint) 0x9E5D5157,
521
52
                    (guint) fu_struct_uf2_get_magic1(st));
522
52
        return FALSE;
523
52
    }
524
1.16k
    if (fu_struct_uf2_get_magic_end(st) != 0x0AB16F30) {
525
85
        g_set_error(error,
526
85
                    FWUPD_ERROR,
527
85
                    FWUPD_ERROR_INVALID_DATA,
528
85
                    "constant FuStructUf2.magic_end was not valid, "
529
85
                    "expected 0x%x and got 0x%x",
530
85
                    (guint) 0x0AB16F30,
531
85
                    (guint) fu_struct_uf2_get_magic_end(st));
532
85
        return FALSE;
533
85
    }
534
1.07k
    return TRUE;
535
1.16k
}
536
static gboolean
537
fu_struct_uf2_parse_internal(FuStructUf2 *st, GError **error)
538
1.27k
{
539
1.27k
    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.27k
    if (!fu_struct_uf2_validate_internal(st, error))
544
196
        return FALSE;
545
1.07k
    return TRUE;
546
1.27k
}
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.31k
{
554
1.31k
    g_autoptr(FuStructUf2) st = fu_struct_uf2_new_internal();
555
1.31k
    g_return_val_if_fail(buf != NULL, NULL);
556
1.31k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
557
1.31k
    if (!fu_memchk_read(bufsz, offset, 512, error)) {
558
40
        g_prefix_error_literal(error, "invalid struct FuStructUf2: ");
559
40
        return NULL;
560
40
    }
561
1.27k
    st->buf = g_byte_array_new();
562
1.27k
    g_byte_array_append(st->buf, buf + offset, 512);
563
1.27k
    if (!fu_struct_uf2_parse_internal(st, error))
564
196
        return NULL;
565
1.07k
    return g_steal_pointer(&st);
566
1.27k
}