Coverage Report

Created: 2026-05-16 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/lib/cprofiles/cprof_decode_msgpack.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  CProfiles
4
 *  =========
5
 *  Copyright (C) 2024 The CProfiles Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
21
#include <cprofiles/cprof_decode_msgpack.h>
22
#include <cprofiles/cprof_variant_utils.h>
23
#include <cprofiles/cprof_mpack_utils.h>
24
#include <cfl/cfl_sds.h>
25
26
static int unpack_context_header(mpack_reader_t *reader, size_t index, void *user_data)
27
0
{
28
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
29
0
        {
30
0
            {NULL,       NULL}
31
0
        };
32
33
0
    if (reader == NULL ||
34
0
        user_data == NULL) {
35
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
36
0
    }
37
38
0
    return cprof_mpack_unpack_map(reader,
39
0
                                  callbacks,
40
0
                                  user_data);
41
0
}
42
43
static int unpack_resource_attributes(mpack_reader_t *reader, size_t index, void *user_data)
44
0
{
45
0
    struct cprof_resource *resource;
46
0
    int                    result;
47
48
0
    if (reader == NULL ||
49
0
        user_data == NULL) {
50
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
51
0
    }
52
53
0
    resource = (struct cprof_resource *) user_data;
54
55
0
    if (resource->attributes != NULL) {
56
0
        cfl_kvlist_destroy(resource->attributes);
57
58
0
        resource->attributes = NULL;
59
0
    }
60
61
0
    result = unpack_cfl_kvlist(reader, &resource->attributes);
62
63
0
    if (result != 0) {
64
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
65
0
    }
66
67
0
    return CPROF_DECODE_MSGPACK_SUCCESS;
68
0
}
69
70
static int unpack_resource_dropped_attribute_count(mpack_reader_t *reader, size_t index, void *user_data)
71
0
{
72
0
    struct cprof_resource *resource;
73
74
0
    if (reader == NULL ||
75
0
        user_data == NULL) {
76
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
77
0
    }
78
79
0
    resource = (struct cprof_resource *) user_data;
80
81
0
    return cprof_mpack_consume_uint32_tag(reader, &resource->dropped_attributes_count);
82
0
}
83
84
static int unpack_resource_profiles_entry_resource(mpack_reader_t *reader, size_t index, void *user_data)
85
0
{
86
0
    int                                     result;
87
0
    struct cprof_resource                  *resource;
88
0
    struct cprof_resource_profiles         *profiles;
89
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
90
0
        {
91
0
            {"attributes",              unpack_resource_attributes},
92
0
            {"dropped_attribute_count", unpack_resource_dropped_attribute_count},
93
0
            {NULL,       NULL}
94
0
        };
95
96
0
    if (reader == NULL ||
97
0
        user_data == NULL) {
98
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
99
0
    }
100
101
0
    profiles = (struct cprof_resource_profiles *) user_data;
102
103
0
    resource = cprof_resource_create(NULL);
104
105
0
    if (resource == NULL) {
106
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
107
0
    }
108
109
0
    result = cprof_mpack_unpack_map(reader,
110
0
                                    callbacks,
111
0
                                    (void *) resource);
112
113
0
    if (result == CPROF_DECODE_MSGPACK_SUCCESS) {
114
0
        if (profiles->resource != NULL) {
115
0
            cprof_resource_destroy(profiles->resource);
116
0
        }
117
118
0
        profiles->resource = resource;
119
0
    }
120
0
    else {
121
0
        cprof_resource_destroy(resource);
122
0
    }
123
124
0
    return result;
125
0
}
126
127
static int unpack_instrumentation_scope_name(mpack_reader_t *reader, size_t index, void *user_data)
128
0
{
129
0
    struct cprof_instrumentation_scope *instrumentation_scope;
130
131
0
    if (reader  == NULL ||
132
0
        user_data == NULL) {
133
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
134
0
    }
135
136
0
    instrumentation_scope = (struct cprof_instrumentation_scope *) user_data;
137
138
0
    if (instrumentation_scope->name != NULL) {
139
0
        cfl_sds_destroy(instrumentation_scope->name);
140
141
0
        instrumentation_scope->name = NULL;
142
0
    }
143
144
0
    return cprof_mpack_consume_string_or_nil_tag(reader, &instrumentation_scope->name);
145
0
}
146
147
static int unpack_instrumentation_scope_version(mpack_reader_t *reader, size_t index, void *user_data)
148
0
{
149
0
    struct cprof_instrumentation_scope *instrumentation_scope;
150
151
0
    if (reader  == NULL ||
152
0
        user_data == NULL) {
153
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
154
0
    }
155
156
0
    instrumentation_scope = (struct cprof_instrumentation_scope *) user_data;
157
158
0
    if (instrumentation_scope->version != NULL) {
159
0
        cfl_sds_destroy(instrumentation_scope->version);
160
161
0
        instrumentation_scope->version = NULL;
162
0
    }
163
164
0
    return cprof_mpack_consume_string_or_nil_tag(reader, &instrumentation_scope->version);
165
0
}
166
167
static int unpack_instrumentation_scope_attributes(mpack_reader_t *reader, size_t index, void *user_data)
168
0
{
169
0
    struct cprof_instrumentation_scope *instrumentation_scope;
170
0
    int                                 result;
171
172
0
    if (reader  == NULL ||
173
0
        user_data == NULL) {
174
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
175
0
    }
176
177
0
    instrumentation_scope = (struct cprof_instrumentation_scope *) user_data;
178
179
0
    if (instrumentation_scope->attributes != NULL) {
180
0
        cfl_kvlist_destroy(instrumentation_scope->attributes);
181
182
0
        instrumentation_scope->attributes = NULL;
183
0
    }
184
185
0
    result = unpack_cfl_kvlist(reader, &instrumentation_scope->attributes);
186
187
0
    if (result != 0) {
188
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
189
0
    }
190
191
0
    return CPROF_DECODE_MSGPACK_SUCCESS;
192
0
}
193
194
static int unpack_instrumentation_scope_dropped_attribute_count(mpack_reader_t *reader, size_t index, void *user_data)
195
0
{
196
0
    struct cprof_instrumentation_scope *instrumentation_scope;
197
198
0
    if (reader  == NULL ||
199
0
        user_data == NULL) {
200
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
201
0
    }
202
203
0
    instrumentation_scope = (struct cprof_instrumentation_scope *) user_data;
204
205
0
    return cprof_mpack_consume_uint32_tag(reader, &instrumentation_scope->dropped_attributes_count);
206
0
}
207
208
static int unpack_scope_profiles_entry_instrumentation_scope(mpack_reader_t *reader, size_t index, void *user_data)
209
0
{
210
0
    struct cprof_instrumentation_scope     *instrumentation_scope;
211
0
    struct cprof_scope_profiles            *scope_profiles;
212
0
    int                                     result;
213
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
214
0
        {
215
0
            {"name",                    unpack_instrumentation_scope_name},
216
0
            {"version",                 unpack_instrumentation_scope_version},
217
0
            {"attributes",              unpack_instrumentation_scope_attributes},
218
0
            {"dropped_attribute_count", unpack_instrumentation_scope_dropped_attribute_count},
219
0
            {NULL,       NULL}
220
0
        };
221
222
0
    if (reader  == NULL ||
223
0
        user_data == NULL) {
224
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
225
0
    }
226
227
0
    scope_profiles = (struct cprof_scope_profiles *) user_data;
228
229
0
    instrumentation_scope = cprof_instrumentation_scope_create(NULL, NULL, NULL, 0);
230
231
0
    if (instrumentation_scope == NULL) {
232
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
233
0
    }
234
235
0
    result = cprof_mpack_unpack_map(reader,
236
0
                                    callbacks,
237
0
                                    (void *) instrumentation_scope);
238
239
0
    if (result == CPROF_DECODE_MSGPACK_SUCCESS) {
240
0
        if (scope_profiles->scope != NULL) {
241
0
            cprof_instrumentation_scope_destroy(scope_profiles->scope);
242
0
        }
243
244
0
        scope_profiles->scope = instrumentation_scope;
245
0
    }
246
247
0
    if (result != CPROF_DECODE_MSGPACK_SUCCESS) {
248
0
        cprof_instrumentation_scope_destroy(instrumentation_scope);
249
0
    }
250
251
0
    return result;
252
0
}
253
254
static int unpack_profile_profile_id(mpack_reader_t *reader, size_t index, void *user_data)
255
0
{
256
0
    struct cprof_profile *profile;
257
0
    int                   result;
258
0
    cfl_sds_t             value;
259
260
0
    if (reader  == NULL ||
261
0
        user_data == NULL) {
262
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
263
0
    }
264
265
0
    profile = (struct cprof_profile *) user_data;
266
267
0
    result = cprof_mpack_consume_binary_tag(reader, &value);
268
269
0
    if (result == CPROF_MPACK_SUCCESS) {
270
0
        if (cfl_sds_len(value) != sizeof(profile->profile_id)) {
271
0
            cfl_sds_destroy(value);
272
273
0
            return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
274
0
        }
275
276
0
        memcpy(profile->profile_id,
277
0
               value,
278
0
               sizeof(profile->profile_id));
279
280
0
        cfl_sds_destroy(value);
281
0
    }
282
283
0
    return result;
284
0
}
285
286
static int unpack_profile_start_time_unix_nano(mpack_reader_t *reader, size_t index, void *user_data)
287
0
{
288
0
    struct cprof_profile *profile;
289
290
0
    if (reader  == NULL ||
291
0
        user_data == NULL) {
292
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
293
0
    }
294
295
0
    profile = (struct cprof_profile *) user_data;
296
297
0
    return cprof_mpack_consume_int64_tag(reader, &profile->start_time_unix_nano);
298
0
}
299
300
static int unpack_profile_end_time_unix_nano(mpack_reader_t *reader, size_t index, void *user_data)
301
0
{
302
0
    struct cprof_profile *profile;
303
304
0
    if (reader  == NULL ||
305
0
        user_data == NULL) {
306
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
307
0
    }
308
309
0
    profile = (struct cprof_profile *) user_data;
310
311
0
    return cprof_mpack_consume_int64_tag(reader, &profile->end_time_unix_nano);
312
0
}
313
314
static int unpack_profile_attributes(mpack_reader_t *reader, size_t index, void *user_data)
315
0
{
316
0
    struct cprof_profile *profile;
317
0
    int                   result;
318
319
0
    if (reader  == NULL ||
320
0
        user_data == NULL) {
321
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
322
0
    }
323
324
0
    profile = (struct cprof_profile *) user_data;
325
326
0
    if (profile->attributes != NULL) {
327
0
        cfl_kvlist_destroy(profile->attributes);
328
329
0
        profile->attributes = NULL;
330
0
    }
331
332
0
    result = unpack_cfl_kvlist(reader, &profile->attributes);
333
334
0
    if (result != 0) {
335
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
336
0
    }
337
338
0
    return CPROF_DECODE_MSGPACK_SUCCESS;
339
0
}
340
341
static int unpack_profile_dropped_attributes(mpack_reader_t *reader, size_t index, void *user_data)
342
0
{
343
0
    struct cprof_profile *profile;
344
345
0
    if (reader  == NULL ||
346
0
        user_data == NULL) {
347
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
348
0
    }
349
350
0
    profile = (struct cprof_profile *) user_data;
351
352
0
    return cprof_mpack_consume_uint32_tag(reader, &profile->dropped_attributes_count);
353
0
}
354
355
static int unpack_value_type_type(mpack_reader_t *reader, size_t index, void *user_data)
356
0
{
357
0
    struct cprof_value_type *sample_type;
358
359
0
    if (reader  == NULL ||
360
0
        user_data == NULL) {
361
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
362
0
    }
363
364
0
    sample_type = (struct cprof_value_type *) user_data;
365
366
0
    return cprof_mpack_consume_int64_tag(reader, &sample_type->type);
367
0
}
368
369
static int unpack_value_type_unit(mpack_reader_t *reader, size_t index, void *user_data)
370
0
{
371
0
    struct cprof_value_type *sample_type;
372
373
0
    if (reader  == NULL ||
374
0
        user_data == NULL) {
375
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
376
0
    }
377
378
0
    sample_type = (struct cprof_value_type *) user_data;
379
380
0
    return cprof_mpack_consume_int64_tag(reader, &sample_type->unit);
381
0
}
382
383
static int unpack_value_type_aggregation_temporality(mpack_reader_t *reader, size_t index, void *user_data)
384
0
{
385
0
    struct cprof_value_type *sample_type;
386
0
    int                      result;
387
0
    uint64_t                 value;
388
389
0
    if (reader  == NULL ||
390
0
        user_data == NULL) {
391
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
392
0
    }
393
394
0
    sample_type = (struct cprof_value_type *) user_data;
395
396
0
    result = cprof_mpack_consume_uint64_tag(reader, &value);
397
398
0
    if (result == CPROF_MPACK_SUCCESS) {
399
0
        sample_type->aggregation_temporality = (int) value;
400
0
    }
401
402
0
    return result;
403
0
}
404
405
static int unpack_profile_sample_types_entry(mpack_reader_t *reader, size_t index, void *user_data)
406
0
{
407
0
    struct cprof_value_type *sample_type;
408
0
    struct cprof_profile    *profile;
409
0
    int                      result;
410
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
411
0
        {
412
0
            {"type",                    unpack_value_type_type},
413
0
            {"unit",                    unpack_value_type_unit},
414
0
            {"aggregation_temporality", unpack_value_type_aggregation_temporality},
415
0
            {NULL,                    NULL}
416
0
        };
417
418
0
    if (reader  == NULL ||
419
0
        user_data == NULL) {
420
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
421
0
    }
422
423
0
    profile = (struct cprof_profile *) user_data;
424
425
0
    sample_type = cprof_sample_type_create(profile, 0, 0, 0);
426
427
0
    if (sample_type == NULL) {
428
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
429
0
    }
430
431
0
    result = cprof_mpack_unpack_map(reader,
432
0
                                    callbacks,
433
0
                                    (void *) sample_type);
434
435
    /* cprof_sample_type_create automatically attaches the newly created
436
     * instance to the parent profile instance, because of
437
     * that in case of failure we just let the parent destructor take care of
438
     * it.
439
    */
440
441
0
    return result;
442
0
}
443
444
static int unpack_profile_sample_types(mpack_reader_t *reader, size_t index, void *user_data)
445
0
{
446
0
    if (reader  == NULL ||
447
0
        user_data == NULL) {
448
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
449
0
    }
450
451
0
    return cprof_mpack_unpack_array(reader,
452
0
                                    unpack_profile_sample_types_entry,
453
0
                                    user_data);
454
0
}
455
456
static int unpack_profile_sample_location_index_entry(mpack_reader_t *reader, size_t index, void *user_data)
457
0
{
458
0
    struct cprof_sample *sample;
459
460
0
    if (reader  == NULL ||
461
0
        user_data == NULL) {
462
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
463
0
    }
464
465
0
    sample = (struct cprof_sample *) user_data;
466
467
0
    if (index >= sample->location_index_count) {
468
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
469
0
    }
470
471
0
    return cprof_mpack_consume_uint64_tag(reader, &sample->location_index[index]);
472
0
}
473
474
static int unpack_profile_sample_location_index(mpack_reader_t *reader, size_t index, void *user_data)
475
0
{
476
0
    int                  array_length;
477
0
    struct cprof_sample *sample;
478
479
0
    if (reader  == NULL ||
480
0
        user_data == NULL) {
481
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
482
0
    }
483
484
0
    sample = (struct cprof_sample *) user_data;
485
486
0
    if (sample->location_index != NULL) {
487
0
        free(sample->location_index);
488
489
0
        sample->location_index = NULL;
490
0
    }
491
492
0
    array_length = cprof_mpack_peek_array_length(reader);
493
494
0
    if (array_length > 0) {
495
0
        sample->location_index = calloc(array_length, sizeof(uint64_t));
496
497
0
        if (sample->location_index == NULL) {
498
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
499
0
        }
500
501
0
        sample->location_index_count = (size_t) array_length;
502
0
    }
503
504
0
    return cprof_mpack_unpack_array(reader,
505
0
                                    unpack_profile_sample_location_index_entry,
506
0
                                    user_data);
507
0
}
508
509
static int unpack_profile_sample_locations_start_index(mpack_reader_t *reader, size_t index, void *user_data)
510
0
{
511
0
    struct cprof_sample *sample;
512
513
0
    if (reader  == NULL ||
514
0
        user_data == NULL) {
515
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
516
0
    }
517
518
0
    sample = (struct cprof_sample *) user_data;
519
520
0
    return cprof_mpack_consume_uint64_tag(reader, &sample->locations_start_index);
521
0
}
522
523
static int unpack_profile_sample_locations_length(mpack_reader_t *reader, size_t index, void *user_data)
524
0
{
525
0
    struct cprof_sample *sample;
526
527
0
    if (reader  == NULL ||
528
0
        user_data == NULL) {
529
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
530
0
    }
531
532
0
    sample = (struct cprof_sample *) user_data;
533
534
0
    return cprof_mpack_consume_uint64_tag(reader, &sample->locations_length);
535
0
}
536
537
static int unpack_profile_sample_values_entry(mpack_reader_t *reader, size_t index, void *user_data)
538
0
{
539
0
    struct cprof_sample *sample;
540
541
0
    if (reader  == NULL ||
542
0
        user_data == NULL) {
543
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
544
0
    }
545
546
0
    sample = (struct cprof_sample *) user_data;
547
548
0
    if (index >= sample->value_count) {
549
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
550
0
    }
551
552
0
    return cprof_mpack_consume_int64_tag(reader, &sample->values[index]);
553
0
}
554
555
static int unpack_profile_sample_values(mpack_reader_t *reader, size_t index, void *user_data)
556
0
{
557
0
    int                  array_length;
558
0
    struct cprof_sample *sample;
559
560
0
    if (reader  == NULL ||
561
0
        user_data == NULL) {
562
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
563
0
    }
564
565
0
    sample = (struct cprof_sample *) user_data;
566
567
0
    if (sample->values != NULL) {
568
0
        free(sample->values);
569
570
0
        sample->values = NULL;
571
0
    }
572
573
0
    array_length = cprof_mpack_peek_array_length(reader);
574
575
0
    if (array_length > 0) {
576
0
        sample->values = calloc(array_length, sizeof(int64_t));
577
578
0
        if (sample->values == NULL) {
579
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
580
0
        }
581
582
0
        sample->value_count = (size_t) array_length;
583
0
    }
584
585
0
    return cprof_mpack_unpack_array(reader,
586
0
                                    unpack_profile_sample_values_entry,
587
0
                                    user_data);
588
0
}
589
590
static int unpack_profile_sample_attributes_entry(mpack_reader_t *reader, size_t index, void *user_data)
591
0
{
592
0
    struct cprof_sample *sample;
593
594
0
    if (reader  == NULL ||
595
0
        user_data == NULL) {
596
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
597
0
    }
598
599
0
    sample = (struct cprof_sample *) user_data;
600
601
0
    if (index >= sample->attributes_count) {
602
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
603
0
    }
604
605
0
    return cprof_mpack_consume_uint64_tag(reader, &sample->attributes[index]);
606
0
}
607
608
static int unpack_profile_sample_attributes(mpack_reader_t *reader, size_t index, void *user_data)
609
0
{
610
0
    int                  array_length;
611
0
    struct cprof_sample *sample;
612
613
0
    if (reader  == NULL ||
614
0
        user_data == NULL) {
615
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
616
0
    }
617
618
0
    sample = (struct cprof_sample *) user_data;
619
620
0
    if (sample->attributes != NULL) {
621
0
        free(sample->attributes);
622
623
0
        sample->attributes = NULL;
624
0
    }
625
626
0
    array_length = cprof_mpack_peek_array_length(reader);
627
628
0
    if (array_length > 0) {
629
0
        sample->attributes = calloc(array_length, sizeof(uint64_t));
630
631
0
        if (sample->attributes == NULL) {
632
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
633
0
        }
634
635
0
        sample->attributes_count = (size_t) array_length;
636
0
    }
637
638
0
    return cprof_mpack_unpack_array(reader,
639
0
                                    unpack_profile_sample_attributes_entry,
640
0
                                    user_data);
641
0
}
642
643
static int unpack_profile_sample_link(mpack_reader_t *reader, size_t index, void *user_data)
644
0
{
645
0
    struct cprof_sample *sample;
646
647
0
    if (reader  == NULL ||
648
0
        user_data == NULL) {
649
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
650
0
    }
651
652
0
    sample = (struct cprof_sample *) user_data;
653
654
0
    return cprof_mpack_consume_uint64_tag(reader, &sample->link);
655
0
}
656
657
static int unpack_profile_sample_timestamps_unix_nano_entry(mpack_reader_t *reader, size_t index, void *user_data)
658
0
{
659
0
    struct cprof_sample *sample;
660
661
0
    if (reader  == NULL ||
662
0
        user_data == NULL) {
663
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
664
0
    }
665
666
0
    sample = (struct cprof_sample *) user_data;
667
668
0
    if (index >= sample->timestamps_count) {
669
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
670
0
    }
671
672
0
    return cprof_mpack_consume_uint64_tag(reader, &sample->timestamps_unix_nano[index]);
673
0
}
674
675
static int unpack_profile_sample_timestamps_unix_nano(mpack_reader_t *reader, size_t index, void *user_data)
676
0
{
677
0
    int                  array_length;
678
0
    struct cprof_sample *sample;
679
680
0
    if (reader  == NULL ||
681
0
        user_data == NULL) {
682
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
683
0
    }
684
685
0
    sample = (struct cprof_sample *) user_data;
686
687
0
    if (sample->timestamps_unix_nano != NULL) {
688
0
        free(sample->timestamps_unix_nano);
689
690
0
        sample->timestamps_unix_nano = NULL;
691
0
    }
692
693
0
    array_length = cprof_mpack_peek_array_length(reader);
694
695
0
    if (array_length > 0) {
696
0
        sample->timestamps_unix_nano = calloc(array_length, sizeof(uint64_t));
697
698
0
        if (sample->timestamps_unix_nano == NULL) {
699
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
700
0
        }
701
702
0
        sample->timestamps_count = (size_t) array_length;
703
0
    }
704
705
0
    return cprof_mpack_unpack_array(reader,
706
0
                                    unpack_profile_sample_timestamps_unix_nano_entry,
707
0
                                    user_data);
708
0
}
709
710
static int unpack_profile_sample_entry(mpack_reader_t *reader, size_t index, void *user_data)
711
0
{
712
0
    struct cprof_sample     *sample;
713
0
    struct cprof_profile    *profile;
714
0
    int                      result;
715
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
716
0
        {
717
0
            {"location_index",        unpack_profile_sample_location_index},
718
0
            {"locations_start_index", unpack_profile_sample_locations_start_index},
719
0
            {"locations_length",      unpack_profile_sample_locations_length},
720
0
            {"values",                unpack_profile_sample_values},
721
0
            {"attributes",            unpack_profile_sample_attributes},
722
0
            {"link",                  unpack_profile_sample_link},
723
0
            {"timestamps_unix_nano",  unpack_profile_sample_timestamps_unix_nano},
724
0
            {NULL,                    NULL}
725
0
        };
726
727
0
    if (reader  == NULL ||
728
0
        user_data == NULL) {
729
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
730
0
    }
731
732
0
    profile = (struct cprof_profile *) user_data;
733
734
0
    sample = cprof_sample_create(profile);
735
736
0
    if (sample == NULL) {
737
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
738
0
    }
739
740
0
    result = cprof_mpack_unpack_map(reader,
741
0
                                    callbacks,
742
0
                                    (void *) sample);
743
744
    /* cprof_sample_create automatically attaches the newly created
745
     * instance to the parent profile instance, because of
746
     * that in case of failure we just let the parent destructor take care of
747
     * it.
748
    */
749
750
0
    return result;
751
0
}
752
753
static int unpack_profile_sample(mpack_reader_t *reader, size_t index, void *user_data)
754
0
{
755
0
    if (reader  == NULL ||
756
0
        user_data == NULL) {
757
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
758
0
    }
759
760
0
    return cprof_mpack_unpack_array(reader,
761
0
                                    unpack_profile_sample_entry,
762
0
                                    user_data);
763
0
}
764
765
766
767
768
769
static int unpack_profile_mapping_id(mpack_reader_t *reader, size_t index, void *user_data)
770
0
{
771
0
    struct cprof_mapping *mapping;
772
773
0
    if (reader  == NULL ||
774
0
        user_data == NULL) {
775
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
776
0
    }
777
778
0
    mapping = (struct cprof_mapping *) user_data;
779
780
0
    return cprof_mpack_consume_uint64_tag(reader, &mapping->id);
781
0
}
782
783
static int unpack_profile_mapping_memory_start(mpack_reader_t *reader, size_t index, void *user_data)
784
0
{
785
0
    struct cprof_mapping *mapping;
786
787
0
    if (reader  == NULL ||
788
0
        user_data == NULL) {
789
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
790
0
    }
791
792
0
    mapping = (struct cprof_mapping *) user_data;
793
794
0
    return cprof_mpack_consume_uint64_tag(reader, &mapping->memory_start);
795
0
}
796
797
static int unpack_profile_mapping_memory_limit(mpack_reader_t *reader, size_t index, void *user_data)
798
0
{
799
0
    struct cprof_mapping *mapping;
800
801
0
    if (reader  == NULL ||
802
0
        user_data == NULL) {
803
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
804
0
    }
805
806
0
    mapping = (struct cprof_mapping *) user_data;
807
808
0
    return cprof_mpack_consume_uint64_tag(reader, &mapping->memory_limit);
809
0
}
810
811
static int unpack_profile_mapping_file_offset(mpack_reader_t *reader, size_t index, void *user_data)
812
0
{
813
0
    struct cprof_mapping *mapping;
814
815
0
    if (reader  == NULL ||
816
0
        user_data == NULL) {
817
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
818
0
    }
819
820
0
    mapping = (struct cprof_mapping *) user_data;
821
822
0
    return cprof_mpack_consume_uint64_tag(reader, &mapping->file_offset);
823
0
}
824
825
static int unpack_profile_mapping_filename(mpack_reader_t *reader, size_t index, void *user_data)
826
0
{
827
0
    struct cprof_mapping *mapping;
828
829
0
    if (reader  == NULL ||
830
0
        user_data == NULL) {
831
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
832
0
    }
833
834
0
    mapping = (struct cprof_mapping *) user_data;
835
836
0
    return cprof_mpack_consume_int64_tag(reader, &mapping->filename);
837
0
}
838
839
static int unpack_profile_mapping_attributes_entry(mpack_reader_t *reader, size_t index, void *user_data)
840
0
{
841
0
    struct cprof_mapping *mapping;
842
843
0
    if (reader  == NULL ||
844
0
        user_data == NULL) {
845
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
846
0
    }
847
848
0
    mapping = (struct cprof_mapping *) user_data;
849
850
0
    if (index >= mapping->attributes_count) {
851
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
852
0
    }
853
854
0
    return cprof_mpack_consume_uint64_tag(reader, &mapping->attributes[index]);
855
0
}
856
857
static int unpack_profile_mapping_attributes(mpack_reader_t *reader, size_t index, void *user_data)
858
0
{
859
0
    int                  array_length;
860
0
    struct cprof_mapping *mapping;
861
862
0
    if (reader  == NULL ||
863
0
        user_data == NULL) {
864
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
865
0
    }
866
867
0
    mapping = (struct cprof_mapping *) user_data;
868
869
0
    if (mapping->attributes != NULL) {
870
0
        free(mapping->attributes);
871
872
0
        mapping->attributes = NULL;
873
0
    }
874
875
0
    array_length = cprof_mpack_peek_array_length(reader);
876
877
0
    if (array_length > 0) {
878
0
        mapping->attributes = calloc(array_length, sizeof(uint64_t));
879
880
0
        if (mapping->attributes == NULL) {
881
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
882
0
        }
883
884
0
        mapping->attributes_count = (size_t) array_length;
885
0
    }
886
887
0
    return cprof_mpack_unpack_array(reader,
888
0
                                    unpack_profile_mapping_attributes_entry,
889
0
                                    user_data);
890
0
}
891
892
static int unpack_profile_mapping_has_functions(mpack_reader_t *reader, size_t index, void *user_data)
893
0
{
894
0
    struct cprof_mapping *mapping;
895
0
    int                   result;
896
0
    uint64_t              value;
897
898
0
    if (reader  == NULL ||
899
0
        user_data == NULL) {
900
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
901
0
    }
902
903
0
    mapping = (struct cprof_mapping *) user_data;
904
905
0
    result = cprof_mpack_consume_uint64_tag(reader, &value);
906
907
0
    if (result == CPROF_MPACK_SUCCESS) {
908
0
        mapping->has_functions = (bool) value;
909
0
    }
910
911
0
    return result;
912
0
}
913
914
static int unpack_profile_mapping_has_filenames(mpack_reader_t *reader, size_t index, void *user_data)
915
0
{
916
0
    struct cprof_mapping *mapping;
917
0
    int                   result;
918
0
    uint64_t              value;
919
920
0
    if (reader  == NULL ||
921
0
        user_data == NULL) {
922
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
923
0
    }
924
925
0
    mapping = (struct cprof_mapping *) user_data;
926
927
0
    result = cprof_mpack_consume_uint64_tag(reader, &value);
928
929
0
    if (result == CPROF_MPACK_SUCCESS) {
930
0
        mapping->has_filenames = (bool) value;
931
0
    }
932
933
0
    return result;
934
0
}
935
936
static int unpack_profile_mapping_has_line_numbers(mpack_reader_t *reader, size_t index, void *user_data)
937
0
{
938
0
    struct cprof_mapping *mapping;
939
0
    int                   result;
940
0
    uint64_t              value;
941
942
0
    if (reader  == NULL ||
943
0
        user_data == NULL) {
944
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
945
0
    }
946
947
0
    mapping = (struct cprof_mapping *) user_data;
948
949
0
    result = cprof_mpack_consume_uint64_tag(reader, &value);
950
951
0
    if (result == CPROF_MPACK_SUCCESS) {
952
0
        mapping->has_line_numbers = (bool) value;
953
0
    }
954
955
0
    return result;
956
0
}
957
958
static int unpack_profile_mapping_has_inline_frames(mpack_reader_t *reader, size_t index, void *user_data)
959
0
{
960
0
    struct cprof_mapping *mapping;
961
0
    int                   result;
962
0
    uint64_t              value;
963
964
0
    if (reader  == NULL ||
965
0
        user_data == NULL) {
966
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
967
0
    }
968
969
0
    mapping = (struct cprof_mapping *) user_data;
970
971
0
    result = cprof_mpack_consume_uint64_tag(reader, &value);
972
973
0
    if (result == CPROF_MPACK_SUCCESS) {
974
0
        mapping->has_inline_frames = (bool) value;
975
0
    }
976
977
0
    return result;
978
0
}
979
980
static int unpack_profile_mappings_entry(mpack_reader_t *reader, size_t index, void *user_data)
981
0
{
982
0
    struct cprof_mapping    *mapping;
983
0
    struct cprof_profile    *profile;
984
0
    int                      result;
985
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
986
0
        {
987
0
            {"id",                unpack_profile_mapping_id},
988
0
            {"memory_start",      unpack_profile_mapping_memory_start},
989
0
            {"memory_limit",      unpack_profile_mapping_memory_limit},
990
0
            {"file_offset",       unpack_profile_mapping_file_offset},
991
0
            {"filename",          unpack_profile_mapping_filename},
992
0
            {"attributes",        unpack_profile_mapping_attributes},
993
0
            {"has_functions",     unpack_profile_mapping_has_functions},
994
0
            {"has_filenames",     unpack_profile_mapping_has_filenames},
995
0
            {"has_line_numbers",  unpack_profile_mapping_has_line_numbers},
996
0
            {"has_inline_frames", unpack_profile_mapping_has_inline_frames},
997
0
            {NULL,                    NULL}
998
0
        };
999
1000
0
    if (reader  == NULL ||
1001
0
        user_data == NULL) {
1002
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1003
0
    }
1004
1005
0
    profile = (struct cprof_profile *) user_data;
1006
1007
0
    mapping = cprof_mapping_create(profile);
1008
1009
0
    if (mapping == NULL) {
1010
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1011
0
    }
1012
1013
0
    result = cprof_mpack_unpack_map(reader,
1014
0
                                    callbacks,
1015
0
                                    (void *) mapping);
1016
1017
    /* cprof_mapping_create automatically attaches the newly created
1018
     * instance to the parent profile instance, because of
1019
     * that in case of failure we just let the parent destructor take care of
1020
     * it.
1021
    */
1022
1023
0
    return result;
1024
0
}
1025
1026
static int unpack_profile_mappings(mpack_reader_t *reader, size_t index, void *user_data)
1027
0
{
1028
0
    if (reader  == NULL ||
1029
0
        user_data == NULL) {
1030
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1031
0
    }
1032
1033
0
    return cprof_mpack_unpack_array(reader,
1034
0
                                    unpack_profile_mappings_entry,
1035
0
                                    user_data);
1036
0
}
1037
1038
1039
1040
1041
1042
1043
static int unpack_location_id(mpack_reader_t *reader, size_t index, void *user_data)
1044
0
{
1045
0
    struct cprof_location *location;
1046
1047
0
    if (reader  == NULL ||
1048
0
        user_data == NULL) {
1049
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1050
0
    }
1051
1052
0
    location = (struct cprof_location *) user_data;
1053
1054
0
    return cprof_mpack_consume_uint64_tag(reader, &location->id);
1055
0
}
1056
1057
static int unpack_location_mapping_index(mpack_reader_t *reader, size_t index, void *user_data)
1058
0
{
1059
0
    struct cprof_location *location;
1060
1061
0
    if (reader  == NULL ||
1062
0
        user_data == NULL) {
1063
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1064
0
    }
1065
1066
0
    location = (struct cprof_location *) user_data;
1067
1068
0
    return cprof_mpack_consume_uint64_tag(reader, &location->mapping_index);
1069
0
}
1070
1071
static int unpack_location_address(mpack_reader_t *reader, size_t index, void *user_data)
1072
0
{
1073
0
    struct cprof_location *location;
1074
1075
0
    if (reader  == NULL ||
1076
0
        user_data == NULL) {
1077
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1078
0
    }
1079
1080
0
    location = (struct cprof_location *) user_data;
1081
1082
0
    return cprof_mpack_consume_uint64_tag(reader, &location->address);
1083
0
}
1084
1085
1086
1087
1088
1089
1090
1091
static int unpack_line_function_index(mpack_reader_t *reader, size_t index, void *user_data)
1092
0
{
1093
0
    struct cprof_line *line;
1094
1095
0
    if (reader  == NULL ||
1096
0
        user_data == NULL) {
1097
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1098
0
    }
1099
1100
0
    line = (struct cprof_line *) user_data;
1101
1102
0
    return cprof_mpack_consume_uint64_tag(reader, &line->function_index);
1103
0
}
1104
1105
static int unpack_line_line(mpack_reader_t *reader, size_t index, void *user_data)
1106
0
{
1107
0
    struct cprof_line *line;
1108
1109
0
    if (reader  == NULL ||
1110
0
        user_data == NULL) {
1111
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1112
0
    }
1113
1114
0
    line = (struct cprof_line *) user_data;
1115
1116
0
    return cprof_mpack_consume_int64_tag(reader, &line->line);
1117
0
}
1118
1119
static int unpack_line_column(mpack_reader_t *reader, size_t index, void *user_data)
1120
0
{
1121
0
    struct cprof_line *line;
1122
1123
0
    if (reader  == NULL ||
1124
0
        user_data == NULL) {
1125
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1126
0
    }
1127
1128
0
    line = (struct cprof_line *) user_data;
1129
1130
0
    return cprof_mpack_consume_int64_tag(reader, &line->column);
1131
0
}
1132
1133
static int unpack_location_lines_entry(mpack_reader_t *reader, size_t index, void *user_data)
1134
0
{
1135
0
    struct cprof_location *location;
1136
0
    struct cprof_line     *line;
1137
0
    int                    result;
1138
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1139
0
        {
1140
0
            {"function_index", unpack_line_function_index},
1141
0
            {"line",           unpack_line_line},
1142
0
            {"column",         unpack_line_column},
1143
0
            {NULL,             NULL}
1144
0
        };
1145
1146
0
    if (reader  == NULL ||
1147
0
        user_data == NULL) {
1148
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1149
0
    }
1150
1151
0
    location = (struct cprof_location *) user_data;
1152
1153
0
    line = cprof_line_create(location);
1154
1155
0
    if (line == NULL) {
1156
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1157
0
    }
1158
1159
0
    result = cprof_mpack_unpack_map(reader,
1160
0
                                    callbacks,
1161
0
                                    (void *) line);
1162
1163
    /* cprof_line_create automatically attaches the newly created
1164
     * instance to the parent location instance, because of
1165
     * that in case of failure we just let the parent destructor take care of
1166
     * it.
1167
    */
1168
1169
0
    return result;
1170
0
}
1171
1172
static int unpack_location_lines(mpack_reader_t *reader, size_t index, void *user_data)
1173
0
{
1174
0
    if (reader  == NULL ||
1175
0
        user_data == NULL) {
1176
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1177
0
    }
1178
1179
0
    return cprof_mpack_unpack_array(reader,
1180
0
                                    unpack_location_lines_entry,
1181
0
                                    user_data);
1182
0
}
1183
1184
static int unpack_location_attributes_entry(mpack_reader_t *reader, size_t index, void *user_data)
1185
0
{
1186
0
    struct cprof_location *location;
1187
1188
0
    if (reader  == NULL ||
1189
0
        user_data == NULL) {
1190
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1191
0
    }
1192
1193
0
    location = (struct cprof_location *) user_data;
1194
1195
0
    if (index >= location->attributes_count) {
1196
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1197
0
    }
1198
1199
0
    return cprof_mpack_consume_uint64_tag(reader, &location->attributes[index]);
1200
0
}
1201
1202
static int unpack_location_attributes(mpack_reader_t *reader, size_t index, void *user_data)
1203
0
{
1204
0
    int                    array_length;
1205
0
    struct cprof_location *location;
1206
1207
0
    if (reader  == NULL ||
1208
0
        user_data == NULL) {
1209
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1210
0
    }
1211
1212
0
    location = (struct cprof_location *) user_data;
1213
1214
0
    if (location->attributes != NULL) {
1215
0
        free(location->attributes);
1216
1217
0
        location->attributes = NULL;
1218
0
    }
1219
1220
0
    array_length = cprof_mpack_peek_array_length(reader);
1221
1222
0
    if (array_length > 0) {
1223
0
        location->attributes = calloc(array_length, sizeof(uint64_t));
1224
1225
0
        if (location->attributes == NULL) {
1226
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1227
0
        }
1228
1229
0
        location->attributes_count = (size_t) array_length;
1230
0
    }
1231
1232
0
    return cprof_mpack_unpack_array(reader,
1233
0
                                    unpack_location_attributes_entry,
1234
0
                                    user_data);
1235
0
}
1236
1237
static int unpack_profile_locations_entry(mpack_reader_t *reader, size_t index, void *user_data)
1238
0
{
1239
0
    struct cprof_location   *location;
1240
0
    struct cprof_profile    *profile;
1241
0
    int                      result;
1242
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1243
0
        {
1244
0
            {"id",            unpack_location_id},
1245
0
            {"mapping_index", unpack_location_mapping_index},
1246
0
            {"address",       unpack_location_address},
1247
0
            {"lines",         unpack_location_lines},
1248
0
            {"attributes",    unpack_location_attributes},
1249
0
            {NULL,            NULL}
1250
0
        };
1251
1252
0
    if (reader  == NULL ||
1253
0
        user_data == NULL) {
1254
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1255
0
    }
1256
1257
0
    profile = (struct cprof_profile *) user_data;
1258
1259
0
    location = cprof_location_create(profile);
1260
1261
0
    if (location == NULL) {
1262
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1263
0
    }
1264
1265
0
    result = cprof_mpack_unpack_map(reader,
1266
0
                                    callbacks,
1267
0
                                    (void *) location);
1268
1269
    /* cprof_location_create automatically attaches the newly created
1270
     * instance to the parent profile instance, because of
1271
     * that in case of failure we just let the parent destructor take care of
1272
     * it.
1273
    */
1274
1275
0
    return result;
1276
0
}
1277
1278
static int unpack_profile_locations(mpack_reader_t *reader, size_t index, void *user_data)
1279
0
{
1280
0
    if (reader  == NULL ||
1281
0
        user_data == NULL) {
1282
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1283
0
    }
1284
1285
0
    return cprof_mpack_unpack_array(reader,
1286
0
                                    unpack_profile_locations_entry,
1287
0
                                    user_data);
1288
0
}
1289
1290
1291
1292
static int unpack_profile_location_indices_entry(mpack_reader_t *reader, size_t index, void *user_data)
1293
0
{
1294
0
    struct cprof_profile  *profile;
1295
1296
0
    if (reader  == NULL ||
1297
0
        user_data == NULL) {
1298
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1299
0
    }
1300
1301
0
    profile = (struct cprof_profile *) user_data;
1302
1303
0
    if (index >= profile->location_indices_count) {
1304
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1305
0
    }
1306
1307
0
    return cprof_mpack_consume_int64_tag(reader, &profile->location_indices[index]);
1308
0
}
1309
1310
static int unpack_profile_location_indices(mpack_reader_t *reader, size_t index, void *user_data)
1311
0
{
1312
0
    int                    array_length;
1313
0
    struct cprof_profile  *profile;
1314
1315
0
    if (reader  == NULL ||
1316
0
        user_data == NULL) {
1317
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1318
0
    }
1319
1320
0
    profile = (struct cprof_profile *) user_data;
1321
1322
0
    if (profile->location_indices != NULL) {
1323
0
        free(profile->location_indices);
1324
1325
0
        profile->location_indices = NULL;
1326
0
        profile->location_indices_count = 0;
1327
0
    }
1328
1329
0
    array_length = cprof_mpack_peek_array_length(reader);
1330
1331
0
    if (array_length > 0) {
1332
0
        profile->location_indices = calloc(array_length, sizeof(int64_t));
1333
1334
0
        if (profile->location_indices == NULL) {
1335
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1336
0
        }
1337
1338
0
        profile->location_indices_count = (size_t) array_length;
1339
0
    }
1340
1341
0
    return cprof_mpack_unpack_array(reader,
1342
0
                                    unpack_profile_location_indices_entry,
1343
0
                                    user_data);
1344
0
}
1345
1346
1347
1348
1349
1350
1351
static int unpack_function_id(mpack_reader_t *reader, size_t index, void *user_data)
1352
0
{
1353
0
    struct cprof_function *function;
1354
1355
0
    if (reader  == NULL ||
1356
0
        user_data == NULL) {
1357
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1358
0
    }
1359
1360
0
    function = (struct cprof_function *) user_data;
1361
1362
0
    return cprof_mpack_consume_uint64_tag(reader, &function->id);
1363
0
}
1364
1365
static int unpack_function_name(mpack_reader_t *reader, size_t index, void *user_data)
1366
0
{
1367
0
    struct cprof_function *function;
1368
1369
0
    if (reader  == NULL ||
1370
0
        user_data == NULL) {
1371
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1372
0
    }
1373
1374
0
    function = (struct cprof_function *) user_data;
1375
1376
0
    return cprof_mpack_consume_int64_tag(reader, &function->name);
1377
0
}
1378
1379
static int unpack_function_system_name(mpack_reader_t *reader, size_t index, void *user_data)
1380
0
{
1381
0
    struct cprof_function *function;
1382
1383
0
    if (reader  == NULL ||
1384
0
        user_data == NULL) {
1385
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1386
0
    }
1387
1388
0
    function = (struct cprof_function *) user_data;
1389
1390
0
    return cprof_mpack_consume_int64_tag(reader, &function->system_name);
1391
0
}
1392
1393
static int unpack_function_filename(mpack_reader_t *reader, size_t index, void *user_data)
1394
0
{
1395
0
    struct cprof_function *function;
1396
1397
0
    if (reader  == NULL ||
1398
0
        user_data == NULL) {
1399
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1400
0
    }
1401
1402
0
    function = (struct cprof_function *) user_data;
1403
1404
0
    return cprof_mpack_consume_int64_tag(reader, &function->filename);
1405
0
}
1406
1407
static int unpack_function_start_line(mpack_reader_t *reader, size_t index, void *user_data)
1408
0
{
1409
0
    struct cprof_function *function;
1410
1411
0
    if (reader  == NULL ||
1412
0
        user_data == NULL) {
1413
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1414
0
    }
1415
1416
0
    function = (struct cprof_function *) user_data;
1417
1418
0
    return cprof_mpack_consume_int64_tag(reader, &function->start_line);
1419
0
}
1420
1421
static int unpack_profile_functions_entry(mpack_reader_t *reader, size_t index, void *user_data)
1422
0
{
1423
0
    struct cprof_function   *function;
1424
0
    struct cprof_profile    *profile;
1425
0
    int                      result;
1426
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1427
0
        {
1428
0
            {"id",            unpack_function_id},
1429
0
            {"name",          unpack_function_name},
1430
0
            {"system_name",   unpack_function_system_name},
1431
0
            {"filename",      unpack_function_filename},
1432
0
            {"start_line",    unpack_function_start_line},
1433
0
            {NULL,            NULL}
1434
0
        };
1435
1436
0
    if (reader  == NULL ||
1437
0
        user_data == NULL) {
1438
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1439
0
    }
1440
1441
0
    profile = (struct cprof_profile *) user_data;
1442
1443
0
    function = cprof_function_create(profile);
1444
1445
0
    if (function == NULL) {
1446
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1447
0
    }
1448
1449
0
    result = cprof_mpack_unpack_map(reader,
1450
0
                                    callbacks,
1451
0
                                    (void *) function);
1452
1453
    /* cprof_function_create automatically attaches the newly created
1454
     * instance to the parent profile instance, because of
1455
     * that in case of failure we just let the parent destructor take care of
1456
     * it.
1457
    */
1458
1459
0
    return result;
1460
0
}
1461
1462
static int unpack_profile_functions(mpack_reader_t *reader, size_t index, void *user_data)
1463
0
{
1464
0
    if (reader  == NULL ||
1465
0
        user_data == NULL) {
1466
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1467
0
    }
1468
1469
0
    return cprof_mpack_unpack_array(reader,
1470
0
                                    unpack_profile_functions_entry,
1471
0
                                    user_data);
1472
0
}
1473
1474
static int unpack_profile_attribute_table(mpack_reader_t *reader, size_t index, void *user_data)
1475
0
{
1476
0
    struct cprof_profile  *profile;
1477
0
    int                    result;
1478
1479
0
    if (reader == NULL ||
1480
0
        user_data == NULL) {
1481
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1482
0
    }
1483
1484
0
    profile = (struct cprof_profile *) user_data;
1485
1486
0
    if (profile->attribute_table != NULL) {
1487
0
        cfl_kvlist_destroy(profile->attribute_table);
1488
1489
0
        profile->attribute_table = NULL;
1490
0
    }
1491
1492
0
    result = unpack_cfl_kvlist(reader, &profile->attribute_table);
1493
1494
0
    if (result != 0) {
1495
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1496
0
    }
1497
1498
0
    return CPROF_DECODE_MSGPACK_SUCCESS;
1499
0
}
1500
1501
1502
1503
1504
1505
1506
1507
1508
static int unpack_profile_attribute_unit_attribute_key(mpack_reader_t *reader, size_t index, void *user_data)
1509
0
{
1510
0
    struct cprof_attribute_unit *attribute_unit;
1511
1512
0
    if (reader  == NULL ||
1513
0
        user_data == NULL) {
1514
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1515
0
    }
1516
1517
0
    attribute_unit = (struct cprof_attribute_unit *) user_data;
1518
1519
0
    return cprof_mpack_consume_int64_tag(reader, &attribute_unit->attribute_key);
1520
0
}
1521
1522
static int unpack_profile_attribute_unit_unit(mpack_reader_t *reader, size_t index, void *user_data)
1523
0
{
1524
0
    struct cprof_attribute_unit *attribute_unit;
1525
1526
0
    if (reader  == NULL ||
1527
0
        user_data == NULL) {
1528
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1529
0
    }
1530
1531
0
    attribute_unit = (struct cprof_attribute_unit *) user_data;
1532
1533
0
    return cprof_mpack_consume_int64_tag(reader, &attribute_unit->unit);
1534
0
}
1535
1536
static int unpack_profile_attribute_units_entry(mpack_reader_t *reader, size_t index, void *user_data)
1537
0
{
1538
0
    struct cprof_attribute_unit *attribute_unit;
1539
0
    struct cprof_profile        *profile;
1540
0
    int                          result;
1541
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1542
0
        {
1543
0
            {"attribute_key", unpack_profile_attribute_unit_attribute_key},
1544
0
            {"unit",          unpack_profile_attribute_unit_unit},
1545
0
            {NULL,            NULL}
1546
0
        };
1547
1548
0
    if (reader  == NULL ||
1549
0
        user_data == NULL) {
1550
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1551
0
    }
1552
1553
0
    profile = (struct cprof_profile *) user_data;
1554
1555
0
    attribute_unit = cprof_attribute_unit_create(profile);
1556
1557
0
    if (attribute_unit == NULL) {
1558
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1559
0
    }
1560
1561
0
    result = cprof_mpack_unpack_map(reader,
1562
0
                                    callbacks,
1563
0
                                    (void *) attribute_unit);
1564
1565
    /* cprof_attribute_unit_create automatically attaches the newly created
1566
     * instance to the parent profile instance, because of
1567
     * that in case of failure we just let the parent destructor take care of
1568
     * it.
1569
    */
1570
1571
0
    return result;
1572
0
}
1573
1574
static int unpack_profile_attribute_units(mpack_reader_t *reader, size_t index, void *user_data)
1575
0
{
1576
0
    if (reader  == NULL ||
1577
0
        user_data == NULL) {
1578
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1579
0
    }
1580
1581
0
    return cprof_mpack_unpack_array(reader,
1582
0
                                    unpack_profile_attribute_units_entry,
1583
0
                                    user_data);
1584
0
}
1585
1586
1587
static int unpack_profile_link_trace_id(mpack_reader_t *reader, size_t index, void *user_data)
1588
0
{
1589
0
    struct cprof_link *link;
1590
0
    cfl_sds_t          value;
1591
0
    int                result;
1592
1593
0
    if (reader  == NULL ||
1594
0
        user_data == NULL) {
1595
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1596
0
    }
1597
1598
0
    link = (struct cprof_link *) user_data;
1599
1600
0
    result = cprof_mpack_consume_binary_tag(reader, &value);
1601
1602
0
    if (result == CPROF_MPACK_SUCCESS) {
1603
0
        if (cfl_sds_len(value) != sizeof(link->trace_id)) {
1604
0
            cfl_sds_destroy(value);
1605
1606
0
            return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1607
0
        }
1608
1609
0
        memcpy(link->trace_id,
1610
0
               value,
1611
0
               sizeof(link->trace_id));
1612
1613
0
        cfl_sds_destroy(value);
1614
0
    }
1615
1616
0
    return result;
1617
0
}
1618
1619
static int unpack_profile_link_span_id(mpack_reader_t *reader, size_t index, void *user_data)
1620
0
{
1621
0
    struct cprof_link *link;
1622
0
    cfl_sds_t          value;
1623
0
    int                result;
1624
1625
0
    if (reader  == NULL ||
1626
0
        user_data == NULL) {
1627
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1628
0
    }
1629
1630
0
    link = (struct cprof_link *) user_data;
1631
1632
0
    result = cprof_mpack_consume_binary_tag(reader, &value);
1633
1634
0
    if (result == CPROF_MPACK_SUCCESS) {
1635
0
        if (cfl_sds_len(value) != sizeof(link->span_id)) {
1636
0
            cfl_sds_destroy(value);
1637
1638
0
            return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1639
0
        }
1640
1641
0
        memcpy(link->span_id,
1642
0
               value,
1643
0
               sizeof(link->span_id));
1644
1645
0
        cfl_sds_destroy(value);
1646
0
    }
1647
1648
0
    return result;
1649
0
}
1650
1651
static int unpack_profile_link_table_entry(mpack_reader_t *reader, size_t index, void *user_data)
1652
0
{
1653
0
    struct cprof_link           *link;
1654
0
    struct cprof_profile        *profile;
1655
0
    int                          result;
1656
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1657
0
        {
1658
0
            {"trace_id", unpack_profile_link_trace_id},
1659
0
            {"span_id",  unpack_profile_link_span_id},
1660
0
            {NULL,       NULL}
1661
0
        };
1662
1663
0
    if (reader  == NULL ||
1664
0
        user_data == NULL) {
1665
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1666
0
    }
1667
1668
0
    profile = (struct cprof_profile *) user_data;
1669
1670
0
    link = cprof_link_create(profile);
1671
1672
0
    if (link == NULL) {
1673
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1674
0
    }
1675
1676
0
    result = cprof_mpack_unpack_map(reader,
1677
0
                                    callbacks,
1678
0
                                    (void *) link);
1679
1680
    /* cprof_link_create automatically attaches the newly created
1681
     * instance to the parent profile instance, because of
1682
     * that in case of failure we just let the parent destructor take care of
1683
     * it.
1684
    */
1685
1686
0
    return result;
1687
0
}
1688
1689
static int unpack_profile_link_table(mpack_reader_t *reader, size_t index, void *user_data)
1690
0
{
1691
0
    if (reader  == NULL ||
1692
0
        user_data == NULL) {
1693
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1694
0
    }
1695
1696
0
    return cprof_mpack_unpack_array(reader,
1697
0
                                    unpack_profile_link_table_entry,
1698
0
                                    user_data);
1699
0
}
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
static int unpack_profile_string_table_entry(mpack_reader_t *reader, size_t index, void *user_data)
1712
0
{
1713
0
    struct cprof_profile  *profile;
1714
1715
0
    if (reader  == NULL ||
1716
0
        user_data == NULL) {
1717
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1718
0
    }
1719
1720
0
    profile = (struct cprof_profile *) user_data;
1721
1722
0
    if (index >= profile->string_table_count) {
1723
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1724
0
    }
1725
1726
0
    return cprof_mpack_consume_string_tag(reader, &profile->string_table[index]);
1727
0
}
1728
1729
static int unpack_profile_string_table(mpack_reader_t *reader, size_t index, void *user_data)
1730
0
{
1731
0
    int                    array_length;
1732
0
    struct cprof_profile  *profile;
1733
1734
0
    if (reader  == NULL ||
1735
0
        user_data == NULL) {
1736
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1737
0
    }
1738
1739
0
    profile = (struct cprof_profile *) user_data;
1740
1741
0
    if (profile->string_table != NULL) {
1742
0
        free(profile->string_table);
1743
1744
0
        profile->string_table = NULL;
1745
0
        profile->string_table_count = 0;
1746
0
        profile->string_table_size = 0;
1747
0
    }
1748
1749
0
    array_length = cprof_mpack_peek_array_length(reader);
1750
1751
0
    if (array_length > 0) {
1752
0
        profile->string_table = calloc(array_length, sizeof(char *));
1753
1754
0
        if (profile->string_table == NULL) {
1755
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1756
0
        }
1757
1758
0
        profile->string_table_count = (size_t) array_length;
1759
0
        profile->string_table_size = (size_t) array_length;
1760
0
    }
1761
1762
0
    return cprof_mpack_unpack_array(reader,
1763
0
                                    unpack_profile_string_table_entry,
1764
0
                                    user_data);
1765
0
}
1766
1767
1768
1769
static int unpack_profile_drop_frames(mpack_reader_t *reader, size_t index, void *user_data)
1770
0
{
1771
0
    struct cprof_profile *profile;
1772
1773
0
    if (reader  == NULL ||
1774
0
        user_data == NULL) {
1775
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1776
0
    }
1777
1778
0
    profile = (struct cprof_profile *) user_data;
1779
1780
0
    return cprof_mpack_consume_int64_tag(reader, &profile->drop_frames);
1781
0
}
1782
1783
static int unpack_profile_keep_frames(mpack_reader_t *reader, size_t index, void *user_data)
1784
0
{
1785
0
    struct cprof_profile *profile;
1786
1787
0
    if (reader  == NULL ||
1788
0
        user_data == NULL) {
1789
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1790
0
    }
1791
1792
0
    profile = (struct cprof_profile *) user_data;
1793
1794
0
    return cprof_mpack_consume_int64_tag(reader, &profile->keep_frames);
1795
0
}
1796
1797
static int unpack_profile_time_nanos(mpack_reader_t *reader, size_t index, void *user_data)
1798
0
{
1799
0
    struct cprof_profile *profile;
1800
1801
0
    if (reader  == NULL ||
1802
0
        user_data == NULL) {
1803
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1804
0
    }
1805
1806
0
    profile = (struct cprof_profile *) user_data;
1807
1808
0
    return cprof_mpack_consume_int64_tag(reader, &profile->time_nanos);
1809
0
}
1810
1811
static int unpack_profile_duration_nanos(mpack_reader_t *reader, size_t index, void *user_data)
1812
0
{
1813
0
    struct cprof_profile *profile;
1814
1815
0
    if (reader  == NULL ||
1816
0
        user_data == NULL) {
1817
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1818
0
    }
1819
1820
0
    profile = (struct cprof_profile *) user_data;
1821
1822
0
    return cprof_mpack_consume_int64_tag(reader, &profile->duration_nanos);
1823
0
}
1824
1825
1826
static int unpack_profile_period_type(mpack_reader_t *reader, size_t index, void *user_data)
1827
0
{
1828
0
    struct cprof_profile    *profile;
1829
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1830
0
        {
1831
0
            {"type",                    unpack_value_type_type},
1832
0
            {"unit",                    unpack_value_type_unit},
1833
0
            {"aggregation_temporality", unpack_value_type_aggregation_temporality},
1834
0
            {NULL,                    NULL}
1835
0
        };
1836
1837
0
    if (reader  == NULL ||
1838
0
        user_data == NULL) {
1839
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1840
0
    }
1841
1842
0
    profile = (struct cprof_profile *) user_data;
1843
1844
0
    return cprof_mpack_unpack_map(reader,
1845
0
                                  callbacks,
1846
0
                                  (void *) &profile->period_type);
1847
0
}
1848
1849
1850
static int unpack_profile_period(mpack_reader_t *reader, size_t index, void *user_data)
1851
0
{
1852
0
    struct cprof_profile *profile;
1853
1854
0
    if (reader  == NULL ||
1855
0
        user_data == NULL) {
1856
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1857
0
    }
1858
1859
0
    profile = (struct cprof_profile *) user_data;
1860
1861
0
    return cprof_mpack_consume_int64_tag(reader, &profile->period);
1862
0
}
1863
1864
1865
1866
1867
static int unpack_profile_comments_entry(mpack_reader_t *reader, size_t index, void *user_data)
1868
0
{
1869
0
    struct cprof_profile  *profile;
1870
1871
0
    if (reader  == NULL ||
1872
0
        user_data == NULL) {
1873
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1874
0
    }
1875
1876
0
    profile = (struct cprof_profile *) user_data;
1877
1878
0
    if (index >= profile->comments_count) {
1879
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1880
0
    }
1881
1882
0
    return cprof_mpack_consume_int64_tag(reader, &profile->comments[index]);
1883
0
}
1884
1885
static int unpack_profile_comments(mpack_reader_t *reader, size_t index, void *user_data)
1886
0
{
1887
0
    int                    array_length;
1888
0
    struct cprof_profile  *profile;
1889
1890
0
    if (reader  == NULL ||
1891
0
        user_data == NULL) {
1892
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1893
0
    }
1894
1895
0
    profile = (struct cprof_profile *) user_data;
1896
1897
0
    if (profile->comments != NULL) {
1898
0
        free(profile->comments);
1899
1900
0
        profile->comments = NULL;
1901
0
        profile->comments_count = 0;
1902
0
    }
1903
1904
0
    array_length = cprof_mpack_peek_array_length(reader);
1905
1906
0
    if (array_length > 0) {
1907
0
        profile->comments = calloc(array_length, sizeof(int64_t));
1908
1909
0
        if (profile->comments == NULL) {
1910
0
            return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1911
0
        }
1912
1913
0
        profile->comments_count = (size_t) array_length;
1914
0
    }
1915
1916
0
    return cprof_mpack_unpack_array(reader,
1917
0
                                    unpack_profile_comments_entry,
1918
0
                                    user_data);
1919
0
}
1920
1921
static int unpack_profile_default_sample_type(mpack_reader_t *reader, size_t index, void *user_data)
1922
0
{
1923
0
    struct cprof_profile *profile;
1924
1925
0
    if (reader  == NULL ||
1926
0
        user_data == NULL) {
1927
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1928
0
    }
1929
1930
0
    profile = (struct cprof_profile *) user_data;
1931
1932
0
    return cprof_mpack_consume_int64_tag(reader, &profile->default_sample_type);
1933
0
}
1934
1935
1936
1937
1938
static int unpack_scope_profiles_entry_profiles_entry(mpack_reader_t *reader, size_t index, void *user_data)
1939
0
{
1940
0
    struct cprof_scope_profiles *scope_profiles;
1941
0
    struct cprof_profile        *profile;
1942
0
    int                          result;
1943
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
1944
0
        {
1945
0
            {"profile_id",           unpack_profile_profile_id},
1946
0
            {"start_time_unix_nano", unpack_profile_start_time_unix_nano},
1947
0
            {"end_time_unix_nano",   unpack_profile_end_time_unix_nano},
1948
0
            {"attributes",           unpack_profile_attributes},
1949
0
            {"dropped_attributes",   unpack_profile_dropped_attributes},
1950
0
            {"sample_types",         unpack_profile_sample_types},
1951
0
            {"sample",               unpack_profile_sample},
1952
0
            {"mappings",             unpack_profile_mappings},
1953
0
            {"locations",            unpack_profile_locations},
1954
0
            {"location_indices",     unpack_profile_location_indices},
1955
0
            {"functions",            unpack_profile_functions},
1956
0
            {"attribute_table",      unpack_profile_attribute_table},
1957
0
            {"attribute_units",      unpack_profile_attribute_units},
1958
0
            {"link_table",           unpack_profile_link_table},
1959
0
            {"string_table",         unpack_profile_string_table},
1960
0
            {"drop_frames",          unpack_profile_drop_frames},
1961
0
            {"keep_frames",          unpack_profile_keep_frames},
1962
0
            {"time_nanos",           unpack_profile_time_nanos},
1963
0
            {"duration_nanos",       unpack_profile_duration_nanos},
1964
0
            {"period_type",          unpack_profile_period_type},
1965
0
            {"period",               unpack_profile_period},
1966
0
            {"comments",             unpack_profile_comments},
1967
0
            {"default_sample_type",  unpack_profile_default_sample_type},
1968
0
            {NULL,       NULL}
1969
0
        };
1970
1971
0
    if (reader  == NULL ||
1972
0
        user_data == NULL) {
1973
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
1974
0
    }
1975
1976
0
    scope_profiles = (struct cprof_scope_profiles *) user_data;
1977
1978
0
    profile = cprof_profile_create();
1979
1980
0
    if (profile == NULL) {
1981
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
1982
0
    }
1983
1984
0
    result = cprof_mpack_unpack_map(reader,
1985
0
                                    callbacks,
1986
0
                                    (void *) profile);
1987
1988
0
    if (result == CPROF_DECODE_MSGPACK_SUCCESS) {
1989
0
        cfl_list_add(&profile->_head, &scope_profiles->profiles);
1990
0
    }
1991
0
    else {
1992
0
        cprof_profile_destroy(profile);
1993
0
    }
1994
1995
0
    return result;
1996
0
}
1997
1998
static int unpack_scope_profiles_entry_profiles(mpack_reader_t *reader, size_t index, void *user_data)
1999
0
{
2000
0
    if (reader == NULL ||
2001
0
        user_data == NULL) {
2002
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2003
0
    }
2004
2005
0
    return cprof_mpack_unpack_array(reader,
2006
0
                                    unpack_scope_profiles_entry_profiles_entry,
2007
0
                                    user_data);
2008
0
}
2009
2010
2011
static int unpack_scope_profiles_entry_schema_url(mpack_reader_t *reader, size_t index, void *user_data)
2012
0
{
2013
0
    struct cprof_scope_profiles *scope_profiles;
2014
2015
0
    if (reader  == NULL ||
2016
0
        user_data == NULL) {
2017
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2018
0
    }
2019
2020
0
    scope_profiles = (struct cprof_scope_profiles *) user_data;
2021
2022
0
    if (scope_profiles->schema_url != NULL) {
2023
0
        cfl_sds_destroy(scope_profiles->schema_url);
2024
2025
0
        scope_profiles->schema_url = NULL;
2026
0
    }
2027
2028
0
    return cprof_mpack_consume_string_or_nil_tag(reader, &scope_profiles->schema_url);
2029
0
}
2030
2031
static int unpack_resource_profiles_entry_scope_profiles_entry(mpack_reader_t *reader, size_t index, void *user_data)
2032
0
{
2033
0
    struct cprof_resource_profiles *resource_profiles;
2034
0
    struct cprof_scope_profiles    *scope_profiles;
2035
0
    int                             result;
2036
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
2037
0
        {
2038
0
            {"instrumentation_scope", unpack_scope_profiles_entry_instrumentation_scope},
2039
0
            {"profiles",              unpack_scope_profiles_entry_profiles},
2040
0
            {"schema_url",            unpack_scope_profiles_entry_schema_url},
2041
0
            {NULL,                    NULL}
2042
0
        };
2043
2044
0
    if (reader == NULL ||
2045
0
        user_data == NULL) {
2046
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2047
0
    }
2048
2049
0
    resource_profiles = (struct cprof_resource_profiles *) user_data;
2050
2051
0
    scope_profiles = cprof_scope_profiles_create(resource_profiles, "");
2052
2053
0
    if (scope_profiles == NULL) {
2054
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
2055
0
    }
2056
2057
0
    result = cprof_mpack_unpack_map(reader,
2058
0
                                    callbacks,
2059
0
                                    (void *) scope_profiles);
2060
2061
    /* cprof_scope_profiles_create automatically attaches the newly created
2062
     * instance to the parent resource cprof profiles instance, because of
2063
     * that in case of failure we just let the parent destructor take care of
2064
     * it.
2065
    */
2066
2067
0
    return result;
2068
0
}
2069
2070
static int unpack_resource_profiles_entry_scope_profiles(mpack_reader_t *reader, size_t index, void *user_data)
2071
0
{
2072
0
    if (reader == NULL ||
2073
0
        user_data == NULL) {
2074
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2075
0
    }
2076
2077
0
    return cprof_mpack_unpack_array(reader,
2078
0
                                    unpack_resource_profiles_entry_scope_profiles_entry,
2079
0
                                    user_data);
2080
0
}
2081
2082
static int unpack_resource_profiles_entry_schema_url(mpack_reader_t *reader, size_t index, void *user_data)
2083
0
{
2084
0
    struct cprof_resource_profiles *profile;
2085
2086
0
    if (reader  == NULL ||
2087
0
        user_data == NULL) {
2088
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2089
0
    }
2090
2091
0
    profile = (struct cprof_resource_profiles *) user_data;
2092
2093
0
    if (profile->schema_url != NULL) {
2094
0
        cfl_sds_destroy(profile->schema_url);
2095
2096
0
        profile->schema_url = NULL;
2097
0
    }
2098
2099
0
    return cprof_mpack_consume_string_or_nil_tag(reader, &profile->schema_url);
2100
0
}
2101
2102
static int unpack_cprof_resource_profiles_entry(mpack_reader_t *reader, size_t index, void *user_data)
2103
0
{
2104
0
    struct cprof_resource_profiles *profiles;
2105
0
    struct cprof                   *context;
2106
0
    int                             result;
2107
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
2108
0
        {
2109
0
            {"resource",       unpack_resource_profiles_entry_resource},
2110
0
            {"scope_profiles", unpack_resource_profiles_entry_scope_profiles},
2111
0
            {"schema_url",     unpack_resource_profiles_entry_schema_url},
2112
0
            {NULL,       NULL}
2113
0
        };
2114
2115
0
    if (reader  == NULL ||
2116
0
        user_data == NULL) {
2117
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2118
0
    }
2119
2120
0
    context = (struct cprof *) user_data;
2121
2122
0
    profiles = cprof_resource_profiles_create("");
2123
2124
0
    if (profiles == NULL) {
2125
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
2126
0
    }
2127
2128
0
    result = cprof_mpack_unpack_map(reader,
2129
0
                                    callbacks,
2130
0
                                    (void *) profiles);
2131
2132
0
    if (result == CPROF_DECODE_MSGPACK_SUCCESS) {
2133
0
        result = cprof_resource_profiles_add(context, profiles);
2134
2135
0
        if (result != 0) {
2136
0
            result = CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2137
0
        }
2138
0
    }
2139
2140
0
    if (result != CPROF_DECODE_MSGPACK_SUCCESS) {
2141
0
        cprof_resource_profiles_destroy(profiles);
2142
0
    }
2143
2144
0
    return result;
2145
0
}
2146
2147
static int unpack_context_profiles(mpack_reader_t *reader, size_t index, void *user_data)
2148
0
{
2149
0
    if (reader == NULL ||
2150
0
        user_data == NULL) {
2151
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2152
0
    }
2153
2154
0
    return cprof_mpack_unpack_array(reader,
2155
0
                                    unpack_cprof_resource_profiles_entry,
2156
0
                                    user_data);
2157
0
}
2158
2159
2160
int unpack_context(struct crof_msgpack_decode_context *context)
2161
0
{
2162
0
    struct cprof_mpack_map_entry_callback_t callbacks[] = \
2163
0
        {
2164
0
            {"meta",     unpack_context_header},
2165
0
            {"profiles", unpack_context_profiles},
2166
0
            {NULL,       NULL}
2167
0
        };
2168
2169
0
    if (context == NULL) {
2170
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2171
0
    }
2172
2173
0
    return cprof_mpack_unpack_map(&context->reader,
2174
0
                                  callbacks,
2175
0
                                  (void *) context->inner_context);
2176
0
}
2177
2178
int cprof_decode_msgpack_create(struct cprof **result_context,
2179
                                unsigned char *in_buf,
2180
                                size_t in_size,
2181
                                size_t *offset)
2182
0
{
2183
0
    int                                result;
2184
0
    struct crof_msgpack_decode_context context;
2185
0
    size_t                             remainder;
2186
2187
0
    if (result_context == NULL ||
2188
0
        in_buf == NULL ||
2189
0
        offset == NULL ||
2190
0
        in_size < *offset ) {
2191
0
        return CPROF_DECODE_MSGPACK_INVALID_ARGUMENT_ERROR;
2192
0
    }
2193
2194
0
    if (in_size == 0 ||
2195
0
        (in_size - *offset) == 0) {
2196
0
        return CPROF_DECODE_MSGPACK_INSUFFICIENT_DATA;
2197
0
    }
2198
2199
0
    memset(&context, 0, sizeof(struct crof_msgpack_decode_context));
2200
2201
0
    context.inner_context = cprof_create();
2202
2203
0
    if (context.inner_context == NULL) {
2204
0
        return CPROF_DECODE_MSGPACK_ALLOCATION_ERROR;
2205
0
    }
2206
2207
0
    in_size -= *offset;
2208
2209
0
    mpack_reader_init_data(&context.reader, (const char *) &in_buf[*offset], in_size);
2210
2211
0
    result = unpack_context(&context);
2212
2213
0
    remainder = mpack_reader_remaining(&context.reader, NULL);
2214
2215
0
    *offset += in_size - remainder;
2216
2217
0
    mpack_reader_destroy(&context.reader);
2218
2219
0
    if (result != CPROF_DECODE_MSGPACK_SUCCESS) {
2220
0
        cprof_destroy(context.inner_context);
2221
0
    }
2222
0
    else {
2223
0
        *result_context = context.inner_context;
2224
0
    }
2225
2226
0
    return result;
2227
0
}
2228
2229
void cprof_decode_msgpack_destroy(struct cprof *context)
2230
0
{
2231
0
    if (context != NULL) {
2232
0
        cprof_destroy(context);
2233
0
    }
2234
0
}