Coverage Report

Created: 2026-01-17 07:04

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
2
{
58
2
    if (val == FU_UF2_FIRMWARE_TAG_VERSION)
59
0
        return "version";
60
2
    if (val == FU_UF2_FIRMWARE_TAG_DESCRIPTION)
61
0
        return "description";
62
2
    if (val == FU_UF2_FIRMWARE_TAG_PAGE_SZ)
63
0
        return "page-sz";
64
2
    if (val == FU_UF2_FIRMWARE_TAG_SHA2)
65
0
        return "sha2";
66
2
    if (val == FU_UF2_FIRMWARE_TAG_DEVICE_ID)
67
0
        return "device-id";
68
2
    return NULL;
69
2
}
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.5k
{
86
12.5k
    g_return_if_fail(st != NULL);
87
12.5k
    if (st->refcount == 0) {
88
0
        g_critical("FuStructUf2Extension refcount already zero");
89
0
        return;
90
0
    }
91
12.5k
    if (--st->refcount > 0)
92
0
        return;
93
12.5k
    if (st->buf != NULL)
94
12.5k
        g_byte_array_unref(st->buf);
95
12.5k
    g_free(st);
96
12.5k
}
97
/**
98
 * fu_struct_uf2_extension_new_internal: (skip):
99
 **/
100
static FuStructUf2Extension *
101
fu_struct_uf2_extension_new_internal(void)
102
12.5k
{
103
12.5k
    FuStructUf2Extension *st = g_new0(FuStructUf2Extension, 1);
104
12.5k
    st->refcount = 1;
105
12.5k
    return st;
106
12.5k
}
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.2k
{
115
11.2k
    g_return_val_if_fail(st != NULL, 0x0);
116
11.2k
    return st->buf->data[0];
117
11.2k
}
118
/**
119
 * fu_struct_uf2_extension_get_tag: (skip):
120
 **/
121
FuUf2FirmwareTag
122
fu_struct_uf2_extension_get_tag(const FuStructUf2Extension *st)
123
11.1k
{
124
11.1k
    g_return_val_if_fail(st != NULL, 0x0);
125
11.1k
    return fu_memread_uint24(st->buf->data + 1, G_LITTLE_ENDIAN);
126
11.1k
}
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
813
{
135
813
    g_return_if_fail(st != NULL);
136
813
    st->buf->data[0] = value;
137
813
}
138
/**
139
 * fu_struct_uf2_extension_set_tag: (skip):
140
 **/
141
void
142
fu_struct_uf2_extension_set_tag(FuStructUf2Extension *st, FuUf2FirmwareTag value)
143
813
{
144
813
    g_return_if_fail(st != NULL);
145
813
    fu_memwrite_uint24(st->buf->data + 1, value, G_LITTLE_ENDIAN);
146
813
}
147
/**
148
 * fu_struct_uf2_extension_new: (skip):
149
 **/
150
FuStructUf2Extension *
151
fu_struct_uf2_extension_new(void)
152
1.24k
{
153
1.24k
    FuStructUf2Extension *st = fu_struct_uf2_extension_new_internal();
154
1.24k
    st->buf = g_byte_array_sized_new(4);
155
1.24k
    fu_byte_array_set_size(st->buf, 4, 0x0);
156
1.24k
    return st;
157
1.24k
}
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.2k
{
183
11.2k
    g_return_val_if_fail(st != NULL, FALSE);
184
11.2k
    return TRUE;
185
11.2k
}
186
static gboolean
187
fu_struct_uf2_extension_parse_internal(FuStructUf2Extension *st, GError **error)
188
11.2k
{
189
11.2k
    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.2k
    if (!fu_struct_uf2_extension_validate_internal(st, error))
194
0
        return FALSE;
195
11.2k
    return TRUE;
196
11.2k
}
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.3k
{
204
11.3k
    g_autoptr(FuStructUf2Extension) st = fu_struct_uf2_extension_new_internal();
205
11.3k
    g_return_val_if_fail(buf != NULL, NULL);
206
11.3k
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
207
11.3k
    if (!fu_memchk_read(bufsz, offset, 4, error)) {
208
12
        g_prefix_error_literal(error, "invalid struct FuStructUf2Extension: ");
209
12
        return NULL;
210
12
    }
211
11.2k
    st->buf = g_byte_array_new();
212
11.2k
    g_byte_array_append(st->buf, buf + offset, 4);
213
11.2k
    if (!fu_struct_uf2_extension_parse_internal(st, error))
214
0
        return NULL;
215
11.2k
    return g_steal_pointer(&st);
216
11.2k
}
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.29k
{
262
1.29k
    g_return_val_if_fail(st != NULL, 0x0);
263
1.29k
    return fu_memread_uint32(st->buf->data + 0, G_LITTLE_ENDIAN);
264
1.29k
}
265
/**
266
 * fu_struct_uf2_get_magic1: (skip):
267
 **/
268
static guint32
269
fu_struct_uf2_get_magic1(const FuStructUf2 *st)
270
1.21k
{
271
1.21k
    g_return_val_if_fail(st != NULL, 0x0);
272
1.21k
    return fu_memread_uint32(st->buf->data + 4, G_LITTLE_ENDIAN);
273
1.21k
}
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
359
{
289
359
    g_return_val_if_fail(st != NULL, 0x0);
290
359
    return fu_memread_uint32(st->buf->data + 12, G_LITTLE_ENDIAN);
291
359
}
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
953
{
316
953
    g_return_val_if_fail(st != NULL, 0x0);
317
953
    return fu_memread_uint32(st->buf->data + 24, G_LITTLE_ENDIAN);
318
953
}
319
/**
320
 * fu_struct_uf2_get_family_id: (skip):
321
 **/
322
guint32
323
fu_struct_uf2_get_family_id(const FuStructUf2 *st)
324
701
{
325
701
    g_return_val_if_fail(st != NULL, 0x0);
326
701
    return fu_memread_uint32(st->buf->data + 28, G_LITTLE_ENDIAN);
327
701
}
328
/**
329
 * fu_struct_uf2_get_data: (skip):
330
 **/
331
const guint8 *
332
fu_struct_uf2_get_data(const FuStructUf2 *st, gsize *bufsz)
333
950
{
334
950
    g_return_val_if_fail(st != NULL, NULL);
335
950
    if (bufsz != NULL)
336
0
        *bufsz = 476;
337
950
    return st->buf->data + 32;
338
950
}
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.19k
{
345
1.19k
    g_return_val_if_fail(st != NULL, 0x0);
346
1.19k
    return fu_memread_uint32(st->buf->data + 508, G_LITTLE_ENDIAN);
347
1.19k
}
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
846
{
356
846
    g_return_if_fail(st != NULL);
357
846
    fu_memwrite_uint32(st->buf->data + 0, value, G_LITTLE_ENDIAN);
358
846
}
359
/**
360
 * fu_struct_uf2_set_magic1: (skip):
361
 **/
362
static void
363
fu_struct_uf2_set_magic1(FuStructUf2 *st, guint32 value)
364
846
{
365
846
    g_return_if_fail(st != NULL);
366
846
    fu_memwrite_uint32(st->buf->data + 4, value, G_LITTLE_ENDIAN);
367
846
}
368
/**
369
 * fu_struct_uf2_set_flags: (skip):
370
 **/
371
void
372
fu_struct_uf2_set_flags(FuStructUf2 *st, FuUf2FirmwareBlockFlags value)
373
846
{
374
846
    g_return_if_fail(st != NULL);
375
846
    fu_memwrite_uint32(st->buf->data + 8, value, G_LITTLE_ENDIAN);
376
846
}
377
/**
378
 * fu_struct_uf2_set_target_addr: (skip):
379
 **/
380
void
381
fu_struct_uf2_set_target_addr(FuStructUf2 *st, guint32 value)
382
846
{
383
846
    g_return_if_fail(st != NULL);
384
846
    fu_memwrite_uint32(st->buf->data + 12, value, G_LITTLE_ENDIAN);
385
846
}
386
/**
387
 * fu_struct_uf2_set_payload_size: (skip):
388
 **/
389
void
390
fu_struct_uf2_set_payload_size(FuStructUf2 *st, guint32 value)
391
846
{
392
846
    g_return_if_fail(st != NULL);
393
846
    fu_memwrite_uint32(st->buf->data + 16, value, G_LITTLE_ENDIAN);
394
846
}
395
/**
396
 * fu_struct_uf2_set_block_no: (skip):
397
 **/
398
void
399
fu_struct_uf2_set_block_no(FuStructUf2 *st, guint32 value)
400
846
{
401
846
    g_return_if_fail(st != NULL);
402
846
    fu_memwrite_uint32(st->buf->data + 20, value, G_LITTLE_ENDIAN);
403
846
}
404
/**
405
 * fu_struct_uf2_set_num_blocks: (skip):
406
 **/
407
void
408
fu_struct_uf2_set_num_blocks(FuStructUf2 *st, guint32 value)
409
846
{
410
846
    g_return_if_fail(st != NULL);
411
846
    fu_memwrite_uint32(st->buf->data + 24, value, G_LITTLE_ENDIAN);
412
846
}
413
/**
414
 * fu_struct_uf2_set_family_id: (skip):
415
 **/
416
void
417
fu_struct_uf2_set_family_id(FuStructUf2 *st, guint32 value)
418
846
{
419
846
    g_return_if_fail(st != NULL);
420
846
    fu_memwrite_uint32(st->buf->data + 28, value, G_LITTLE_ENDIAN);
421
846
}
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
846
{
428
846
    g_return_val_if_fail(st != NULL, FALSE);
429
846
    g_return_val_if_fail(buf != NULL, FALSE);
430
846
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
431
846
    return fu_memcpy_safe(st->buf->data, st->buf->len, 32, buf, bufsz, 0x0, bufsz, error);
432
846
}
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
846
{
439
846
    g_return_if_fail(st != NULL);
440
846
    fu_memwrite_uint32(st->buf->data + 508, value, G_LITTLE_ENDIAN);
441
846
}
442
/**
443
 * fu_struct_uf2_new: (skip):
444
 **/
445
FuStructUf2 *
446
fu_struct_uf2_new(void)
447
846
{
448
846
    FuStructUf2 *st = fu_struct_uf2_new_internal();
449
846
    st->buf = g_byte_array_sized_new(512);
450
846
    fu_byte_array_set_size(st->buf, 512, 0x0);
451
846
    fu_struct_uf2_set_magic0(st, 0x0A324655);
452
846
    fu_struct_uf2_set_magic1(st, 0x9E5D5157);
453
846
    fu_struct_uf2_set_magic_end(st, 0x0AB16F30);
454
846
    return st;
455
846
}
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
65
        g_set_error(error,
506
65
                    FWUPD_ERROR,
507
65
                    FWUPD_ERROR_INVALID_DATA,
508
65
                    "constant FuStructUf2.magic0 was not valid, "
509
65
                    "expected 0x%x and got 0x%x",
510
65
                    (guint) 0x0A324655,
511
65
                    (guint) fu_struct_uf2_get_magic0(st));
512
65
        return FALSE;
513
65
    }
514
1.16k
    if (fu_struct_uf2_get_magic1(st) != 0x9E5D5157) {
515
51
        g_set_error(error,
516
51
                    FWUPD_ERROR,
517
51
                    FWUPD_ERROR_INVALID_DATA,
518
51
                    "constant FuStructUf2.magic1 was not valid, "
519
51
                    "expected 0x%x and got 0x%x",
520
51
                    (guint) 0x9E5D5157,
521
51
                    (guint) fu_struct_uf2_get_magic1(st));
522
51
        return FALSE;
523
51
    }
524
1.11k
    if (fu_struct_uf2_get_magic_end(st) != 0x0AB16F30) {
525
78
        g_set_error(error,
526
78
                    FWUPD_ERROR,
527
78
                    FWUPD_ERROR_INVALID_DATA,
528
78
                    "constant FuStructUf2.magic_end was not valid, "
529
78
                    "expected 0x%x and got 0x%x",
530
78
                    (guint) 0x0AB16F30,
531
78
                    (guint) fu_struct_uf2_get_magic_end(st));
532
78
        return FALSE;
533
78
    }
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
194
        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
38
        g_prefix_error_literal(error, "invalid struct FuStructUf2: ");
559
38
        return NULL;
560
38
    }
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
194
        return NULL;
565
1.03k
    return g_steal_pointer(&st);
566
1.22k
}