Coverage Report

Created: 2026-03-11 07:30

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