Coverage Report

Created: 2026-03-09 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/lib/cprofiles/src/cprof_encode_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_encode_msgpack.h>
22
#include <cprofiles/cprof_variant_utils.h>
23
24
static inline void mpack_write_sds_or_nil(mpack_writer_t *writer,
25
                                          cfl_sds_t value)
26
0
{
27
0
    if (value != NULL) {
28
0
        mpack_write_str(writer,
29
0
                        value,
30
0
                        cfl_sds_len(value));
31
0
    }
32
0
    else {
33
0
        mpack_write_nil(writer);
34
0
    }
35
0
}
36
37
static int encode_string_array(
38
                struct cprof_msgpack_encoding_context *context,
39
                char **data_list,
40
                size_t data_length);
41
42
static int encode_uint64_t_array(
43
                struct cprof_msgpack_encoding_context *context,
44
                uint64_t *data_list,
45
                size_t data_length);
46
47
static int encode_int64_t_array(
48
                struct cprof_msgpack_encoding_context *context,
49
                int64_t *data_list,
50
                size_t data_length);
51
52
static int encode_cprof_value_type(
53
                struct cprof_msgpack_encoding_context *context,
54
                struct cprof_value_type *instance);
55
56
static int encode_cprof_sample(
57
                struct cprof_msgpack_encoding_context *context,
58
                struct cprof_sample *instance);
59
60
static int encode_cprof_mapping(
61
                struct cprof_msgpack_encoding_context *context,
62
                struct cprof_mapping *instance);
63
64
static int encode_cprof_line(
65
                struct cprof_msgpack_encoding_context *context,
66
                struct cprof_line *instance);
67
68
static int encode_cprof_location(
69
                struct cprof_msgpack_encoding_context *context,
70
                struct cprof_location *instance);
71
72
static int encode_cprof_function(
73
                struct cprof_msgpack_encoding_context *context,
74
                struct cprof_function *instance);
75
76
static int encode_cprof_attribute_unit(
77
                struct cprof_msgpack_encoding_context *context,
78
                struct cprof_attribute_unit *instance);
79
80
81
static int encode_cprof_link(
82
                struct cprof_msgpack_encoding_context *context,
83
                struct cprof_link *instance);
84
85
86
static int encode_cprof_profile(
87
                struct cprof_msgpack_encoding_context *context,
88
                struct cprof_profile *instance);
89
90
91
static int encode_cprof_resource_profiles(
92
                struct cprof_msgpack_encoding_context *context,
93
                struct cprof_resource_profiles *instance);
94
95
96
static int encode_cprof_instrumentation_scope(
97
                struct cprof_msgpack_encoding_context *context,
98
                struct cprof_instrumentation_scope *instance);
99
100
101
static int encode_cprof_resource(
102
            struct cprof_msgpack_encoding_context *context,
103
            struct cprof_resource *instance);
104
105
106
static int encode_cprof_scope_profiles(
107
                struct cprof_msgpack_encoding_context *context,
108
                struct cprof_scope_profiles *instance);
109
110
111
static int encode_string_array(
112
                struct cprof_msgpack_encoding_context *context,
113
                char **data_list,
114
                size_t data_length)
115
0
{
116
0
    size_t index;
117
118
0
    mpack_start_array(&context->writer,
119
0
                      data_length);
120
121
0
    for (index = 0 ; index < data_length ; index++) {
122
0
        mpack_write_cstr(&context->writer, data_list[index]);
123
0
    }
124
125
0
    mpack_finish_array(&context->writer);
126
127
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
128
0
}
129
130
static int encode_uint64_t_array(
131
                struct cprof_msgpack_encoding_context *context,
132
                uint64_t *data_list,
133
                size_t data_length)
134
0
{
135
0
    size_t index;
136
137
0
    mpack_start_array(&context->writer,
138
0
                      data_length);
139
140
0
    for (index = 0 ; index < data_length ; index++) {
141
0
        mpack_write_u64(&context->writer, data_list[index]);
142
0
    }
143
144
0
    mpack_finish_array(&context->writer);
145
146
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
147
0
}
148
149
static int encode_int64_t_array(
150
                struct cprof_msgpack_encoding_context *context,
151
                int64_t *data_list,
152
                size_t data_length)
153
0
{
154
0
    size_t index;
155
156
0
    mpack_start_array(&context->writer,
157
0
                      data_length);
158
159
0
    for (index = 0 ; index < data_length ; index++) {
160
0
        mpack_write_i64(&context->writer, data_list[index]);
161
0
    }
162
163
0
    mpack_finish_array(&context->writer);
164
165
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
166
0
}
167
168
169
static int encode_cprof_value_type(
170
                struct cprof_msgpack_encoding_context *context,
171
0
                struct cprof_value_type *instance) {
172
0
    mpack_start_map(&context->writer, 3);
173
174
0
    mpack_write_cstr(&context->writer, "type");
175
0
    mpack_write_i64(&context->writer, instance->type);
176
177
0
    mpack_write_cstr(&context->writer, "unit");
178
0
    mpack_write_i64(&context->writer, instance->unit);
179
180
0
    mpack_write_cstr(&context->writer, "aggregation_temporality");
181
0
    mpack_write_u64(&context->writer, instance->aggregation_temporality);
182
183
0
    mpack_finish_map(&context->writer);
184
185
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
186
0
}
187
188
static int encode_cprof_sample(
189
                struct cprof_msgpack_encoding_context *context,
190
0
                struct cprof_sample *instance) {
191
0
    int result;
192
193
0
    mpack_start_map(&context->writer, 7);
194
195
0
    mpack_write_cstr(&context->writer, "location_index");
196
197
0
    result = encode_uint64_t_array(context,
198
0
                                   instance->location_index,
199
0
                                   instance->location_index_count);
200
201
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
202
0
        return result;
203
0
    }
204
205
0
    mpack_write_cstr(&context->writer, "locations_start_index");
206
0
    mpack_write_u64(&context->writer, instance->locations_start_index);
207
208
0
    mpack_write_cstr(&context->writer, "locations_length");
209
0
    mpack_write_u64(&context->writer, instance->locations_length);
210
211
0
    mpack_write_cstr(&context->writer, "values");
212
0
    result = encode_int64_t_array(context,
213
0
                                  instance->values,
214
0
                                  instance->value_count);
215
216
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
217
0
        return result;
218
0
    }
219
220
0
    mpack_write_cstr(&context->writer, "attributes");
221
0
    result = encode_uint64_t_array(context,
222
0
                                   instance->attributes,
223
0
                                   instance->attributes_count);
224
225
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
226
0
        return result;
227
0
    }
228
229
0
    mpack_write_cstr(&context->writer, "link");
230
0
    mpack_write_u64(&context->writer, instance->link);
231
232
0
    mpack_write_cstr(&context->writer, "timestamps_unix_nano");
233
0
    result = encode_uint64_t_array(context,
234
0
                                   instance->timestamps_unix_nano,
235
0
                                   instance->timestamps_count);
236
237
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
238
0
        return result;
239
0
    }
240
241
0
    mpack_finish_map(&context->writer);
242
243
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
244
0
}
245
246
static int encode_cprof_mapping(
247
                struct cprof_msgpack_encoding_context *context,
248
0
                struct cprof_mapping *instance) {
249
0
    int result;
250
251
0
    mpack_start_map(&context->writer, 10);
252
253
0
    mpack_write_cstr(&context->writer, "id");
254
0
    mpack_write_u64(&context->writer, instance->id);
255
256
0
    mpack_write_cstr(&context->writer, "memory_start");
257
0
    mpack_write_u64(&context->writer, instance->memory_start);
258
259
0
    mpack_write_cstr(&context->writer, "memory_limit");
260
0
    mpack_write_u64(&context->writer, instance->memory_limit);
261
262
0
    mpack_write_cstr(&context->writer, "file_offset");
263
0
    mpack_write_u64(&context->writer, instance->file_offset);
264
265
0
    mpack_write_cstr(&context->writer, "filename");
266
0
    mpack_write_i64(&context->writer, instance->filename);
267
268
0
    mpack_write_cstr(&context->writer, "attributes");
269
0
    result = encode_uint64_t_array(context,
270
0
                                   instance->attributes,
271
0
                                   instance->attributes_count);
272
273
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
274
0
        return result;
275
0
    }
276
277
0
    mpack_write_cstr(&context->writer, "has_functions");
278
0
    mpack_write_u64(&context->writer, instance->has_functions);
279
280
0
    mpack_write_cstr(&context->writer, "has_filenames");
281
0
    mpack_write_u64(&context->writer, instance->has_filenames);
282
283
0
    mpack_write_cstr(&context->writer, "has_line_numbers");
284
0
    mpack_write_u64(&context->writer, instance->has_line_numbers);
285
286
0
    mpack_write_cstr(&context->writer, "has_inline_frames");
287
0
    mpack_write_u64(&context->writer, instance->has_inline_frames);
288
289
0
    mpack_finish_map(&context->writer);
290
291
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
292
0
}
293
294
295
296
297
298
static int encode_cprof_line(
299
                struct cprof_msgpack_encoding_context *context,
300
0
                struct cprof_line *instance) {
301
0
    mpack_start_map(&context->writer, 3);
302
303
0
    mpack_write_cstr(&context->writer, "function_index");
304
0
    mpack_write_u64(&context->writer, instance->function_index);
305
306
0
    mpack_write_cstr(&context->writer, "line");
307
0
    mpack_write_i64(&context->writer, instance->line);
308
309
0
    mpack_write_cstr(&context->writer, "column");
310
0
    mpack_write_i64(&context->writer, instance->column);
311
312
0
    mpack_finish_map(&context->writer);
313
314
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
315
0
}
316
317
318
319
static int encode_cprof_location(
320
                struct cprof_msgpack_encoding_context *context,
321
0
                struct cprof_location *instance) {
322
0
    struct cfl_list   *iterator;
323
0
    int                result;
324
0
    struct cprof_line *line;
325
326
0
    mpack_start_map(&context->writer, 5);
327
328
0
    mpack_write_cstr(&context->writer, "id");
329
0
    mpack_write_u64(&context->writer, instance->id);
330
331
0
    mpack_write_cstr(&context->writer, "mapping_index");
332
0
    mpack_write_u64(&context->writer, instance->mapping_index);
333
334
0
    mpack_write_cstr(&context->writer, "address");
335
0
    mpack_write_u64(&context->writer, instance->address);
336
337
0
    mpack_write_cstr(&context->writer, "lines");
338
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->lines));
339
340
0
    if (!cfl_list_is_empty(&instance->lines)) {
341
0
        cfl_list_foreach(iterator,
342
0
                        &instance->lines) {
343
0
            line = cfl_list_entry(iterator,
344
0
                                struct cprof_line, _head);
345
346
0
            result = encode_cprof_line(context, line);
347
348
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
349
0
                return result;
350
0
            }
351
0
        }
352
0
    }
353
354
0
    mpack_finish_array(&context->writer);
355
356
0
    mpack_write_cstr(&context->writer, "attributes");
357
358
0
    result = encode_uint64_t_array(context,
359
0
                                   instance->attributes,
360
0
                                   instance->attributes_count);
361
362
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
363
0
        return result;
364
0
    }
365
366
0
    mpack_finish_map(&context->writer);
367
368
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
369
0
}
370
371
372
373
374
static int encode_cprof_function(
375
                struct cprof_msgpack_encoding_context *context,
376
0
                struct cprof_function *instance) {
377
0
    mpack_start_map(&context->writer, 5);
378
379
0
    mpack_write_cstr(&context->writer, "id");
380
0
    mpack_write_u64(&context->writer, instance->id);
381
382
0
    mpack_write_cstr(&context->writer, "name");
383
0
    mpack_write_i64(&context->writer, instance->name);
384
385
0
    mpack_write_cstr(&context->writer, "system_name");
386
0
    mpack_write_i64(&context->writer, instance->system_name);
387
388
0
    mpack_write_cstr(&context->writer, "filename");
389
0
    mpack_write_i64(&context->writer, instance->filename);
390
391
0
    mpack_write_cstr(&context->writer, "start_line");
392
0
    mpack_write_i64(&context->writer, instance->start_line);
393
394
0
    mpack_finish_map(&context->writer);
395
396
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
397
0
}
398
399
400
401
402
static int encode_cprof_attribute_unit(
403
                struct cprof_msgpack_encoding_context *context,
404
0
                struct cprof_attribute_unit *instance) {
405
0
    mpack_start_map(&context->writer, 2);
406
407
0
    mpack_write_cstr(&context->writer, "attribute_key");
408
0
    mpack_write_i64(&context->writer, instance->attribute_key);
409
410
0
    mpack_write_cstr(&context->writer, "unit");
411
0
    mpack_write_i64(&context->writer, instance->unit);
412
413
0
    mpack_finish_map(&context->writer);
414
415
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
416
0
}
417
418
static int encode_cprof_link(
419
                struct cprof_msgpack_encoding_context *context,
420
                struct cprof_link *instance)
421
0
{
422
0
    mpack_start_map(&context->writer, 2);
423
424
0
    mpack_write_cstr(&context->writer, "trace_id");
425
0
    mpack_write_bin(&context->writer,
426
0
                    (const char *) instance->trace_id,
427
0
                    sizeof(instance->trace_id));
428
429
0
    mpack_write_cstr(&context->writer, "span_id");
430
0
    mpack_write_bin(&context->writer,
431
0
                    (const char *) instance->span_id,
432
0
                    sizeof(instance->span_id));
433
434
0
    mpack_finish_map(&context->writer);
435
436
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
437
0
}
438
439
440
static int encode_cprof_profile(
441
                struct cprof_msgpack_encoding_context *context,
442
0
                struct cprof_profile *instance) {
443
0
    struct cprof_attribute_unit *attribute_unit;
444
0
    struct cprof_value_type     *sample_type;
445
0
    struct cfl_list             *iterator;
446
0
    struct cprof_location       *location;
447
0
    struct cprof_function       *function;
448
0
    struct cprof_mapping        *mapping;
449
0
    struct cprof_sample         *sample;
450
0
    int                          result;
451
0
    struct cprof_link           *link;
452
453
454
0
    mpack_start_map(&context->writer, 23);
455
456
0
    mpack_write_cstr(&context->writer, "profile_id");
457
0
    mpack_write_bin(&context->writer,
458
0
                    (const char *) instance->profile_id,
459
0
                    sizeof(instance->profile_id));
460
461
0
    mpack_write_cstr(&context->writer, "start_time_unix_nano");
462
0
    mpack_write_i64(&context->writer, instance->start_time_unix_nano);
463
464
0
    mpack_write_cstr(&context->writer, "end_time_unix_nano");
465
0
    mpack_write_i64(&context->writer, instance->end_time_unix_nano);
466
467
0
    mpack_write_cstr(&context->writer, "attributes");
468
469
0
    result = pack_cfl_variant_kvlist(&context->writer,
470
0
                                     instance->attributes);
471
472
0
    if (result != 0) {
473
0
        return -1;
474
0
    }
475
476
0
    mpack_write_cstr(&context->writer, "dropped_attributes");
477
0
    mpack_write_u32(&context->writer,
478
0
                    instance->dropped_attributes_count);
479
480
0
    mpack_write_cstr(&context->writer, "sample_types");
481
482
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->sample_type));
483
484
0
    if (!cfl_list_is_empty(&instance->sample_type)) {
485
0
        cfl_list_foreach(iterator,
486
0
                        &instance->sample_type) {
487
0
            sample_type = cfl_list_entry(
488
0
                            iterator,
489
0
                            struct cprof_value_type, _head);
490
491
0
            result = encode_cprof_value_type(context, sample_type);
492
493
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
494
0
                return result;
495
0
            }
496
0
        }
497
0
    }
498
499
0
    mpack_finish_array(&context->writer);
500
501
0
    mpack_write_cstr(&context->writer, "sample");
502
503
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->samples));
504
505
0
    if (!cfl_list_is_empty(&instance->samples)) {
506
0
        cfl_list_foreach(iterator,
507
0
                        &instance->samples) {
508
0
            sample = cfl_list_entry(
509
0
                        iterator,
510
0
                        struct cprof_sample, _head);
511
512
0
            result = encode_cprof_sample(context, sample);
513
514
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
515
0
                return result;
516
0
            }
517
0
        }
518
0
    }
519
520
0
    mpack_finish_array(&context->writer);
521
522
0
    mpack_write_cstr(&context->writer, "mappings");
523
524
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->mappings));
525
526
0
    if (!cfl_list_is_empty(&instance->mappings)) {
527
0
        cfl_list_foreach(iterator,
528
0
                        &instance->mappings) {
529
0
            mapping = cfl_list_entry(
530
0
                        iterator,
531
0
                        struct cprof_mapping, _head);
532
533
0
            result = encode_cprof_mapping(context, mapping);
534
535
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
536
0
                return result;
537
0
            }
538
0
        }
539
0
    }
540
541
0
    mpack_finish_array(&context->writer);
542
543
0
    mpack_write_cstr(&context->writer, "locations");
544
545
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->locations));
546
547
0
    if (!cfl_list_is_empty(&instance->locations)) {
548
0
        cfl_list_foreach(iterator,
549
0
                        &instance->locations) {
550
0
            location = cfl_list_entry(
551
0
                        iterator,
552
0
                        struct cprof_location, _head);
553
554
0
            result = encode_cprof_location(context, location);
555
556
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
557
0
                return result;
558
0
            }
559
0
        }
560
0
    }
561
562
0
    mpack_finish_array(&context->writer);
563
564
0
    mpack_write_cstr(&context->writer, "location_indices");
565
566
0
    result = encode_int64_t_array(context,
567
0
                                  instance->location_indices,
568
0
                                  instance->location_indices_count);
569
570
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
571
0
        return result;
572
0
    }
573
574
0
    mpack_write_cstr(&context->writer, "functions");
575
576
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->functions));
577
578
0
    if (!cfl_list_is_empty(&instance->functions)) {
579
0
        cfl_list_foreach(iterator,
580
0
                        &instance->functions) {
581
0
            function = cfl_list_entry(
582
0
                        iterator,
583
0
                        struct cprof_function, _head);
584
585
0
            result = encode_cprof_function(context, function);
586
587
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
588
0
                return result;
589
0
            }
590
0
        }
591
0
    }
592
593
0
    mpack_finish_array(&context->writer);
594
595
0
    mpack_write_cstr(&context->writer, "attribute_table");
596
597
0
    result = pack_cfl_variant_kvlist(&context->writer,
598
0
                                     instance->attribute_table);
599
600
0
    if (result != 0) {
601
0
        return -1;
602
0
    }
603
604
0
    mpack_write_cstr(&context->writer, "attribute_units");
605
606
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->attribute_units));
607
608
0
    if (!cfl_list_is_empty(&instance->attribute_units)) {
609
0
        cfl_list_foreach(iterator,
610
0
                         &instance->attribute_units) {
611
0
            attribute_unit = cfl_list_entry(
612
0
                                iterator,
613
0
                                struct cprof_attribute_unit, _head);
614
615
0
            result = encode_cprof_attribute_unit(context, attribute_unit);
616
617
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
618
0
                return result;
619
0
            }
620
0
        }
621
0
    }
622
623
0
    mpack_finish_array(&context->writer);
624
625
0
    mpack_write_cstr(&context->writer, "link_table");
626
627
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->link_table));
628
629
0
    if (!cfl_list_is_empty(&instance->link_table)) {
630
0
        cfl_list_foreach(iterator,
631
0
                         &instance->link_table) {
632
0
            link = cfl_list_entry(
633
0
                    iterator,
634
0
                    struct cprof_link, _head);
635
636
0
            result = encode_cprof_link(context, link);
637
638
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
639
0
                return result;
640
0
            }
641
0
        }
642
0
    }
643
644
0
    mpack_finish_array(&context->writer);
645
646
0
    mpack_write_cstr(&context->writer, "string_table");
647
648
0
    result = encode_string_array(
649
0
                context,
650
0
                (char **) instance->string_table,
651
0
                instance->string_table_count);
652
653
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
654
0
        return result;
655
0
    }
656
657
0
    mpack_write_cstr(&context->writer, "drop_frames");
658
0
    mpack_write_i64(&context->writer, instance->drop_frames);
659
660
0
    mpack_write_cstr(&context->writer, "keep_frames");
661
0
    mpack_write_i64(&context->writer, instance->keep_frames);
662
663
0
    mpack_write_cstr(&context->writer, "time_nanos");
664
0
    mpack_write_i64(&context->writer, instance->time_nanos);
665
666
0
    mpack_write_cstr(&context->writer, "duration_nanos");
667
0
    mpack_write_i64(&context->writer, instance->duration_nanos);
668
669
0
    mpack_write_cstr(&context->writer, "period_type");
670
0
    result = encode_cprof_value_type(context, &instance->period_type);
671
672
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
673
0
        return result;
674
0
    }
675
676
0
    mpack_write_cstr(&context->writer, "period");
677
0
    mpack_write_i64(&context->writer, instance->period);
678
679
0
    mpack_write_cstr(&context->writer, "comments");
680
0
    result = encode_int64_t_array(context,
681
0
                                  instance->comments,
682
0
                                  instance->comments_count);
683
684
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
685
0
        return result;
686
0
    }
687
688
0
    mpack_write_cstr(&context->writer, "default_sample_type");
689
0
    mpack_write_i64(&context->writer, instance->default_sample_type);
690
691
0
    mpack_finish_map(&context->writer);
692
693
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
694
0
}
695
696
static int encode_cprof_resource_profiles(
697
                struct cprof_msgpack_encoding_context *context,
698
0
                struct cprof_resource_profiles *instance) {
699
0
    int                          result;
700
0
    struct cfl_list             *iterator;
701
0
    struct cprof_scope_profiles *scope_profile;
702
703
0
    mpack_start_map(&context->writer, 3);
704
0
    mpack_write_cstr(&context->writer, "resource");
705
706
0
    result = encode_cprof_resource(context, instance->resource);
707
708
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
709
0
        return result;
710
0
    }
711
712
0
    mpack_write_cstr(&context->writer, "scope_profiles");
713
714
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->scope_profiles));
715
716
0
    if (!cfl_list_is_empty(&instance->scope_profiles)) {
717
0
        cfl_list_foreach(iterator,
718
0
                         &instance->scope_profiles) {
719
0
            scope_profile = cfl_list_entry(
720
0
                                iterator,
721
0
                                struct cprof_scope_profiles, _head);
722
723
0
            result = encode_cprof_scope_profiles(context, scope_profile);
724
725
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
726
0
                return result;
727
0
            }
728
0
        }
729
0
    }
730
731
0
    mpack_finish_array(&context->writer);
732
733
0
    mpack_write_cstr(&context->writer, "schema_url");
734
735
0
    mpack_write_sds_or_nil(&context->writer,
736
0
                           instance->schema_url);
737
738
0
    mpack_finish_map(&context->writer);
739
740
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
741
0
}
742
743
static int encode_cprof_instrumentation_scope(
744
                struct cprof_msgpack_encoding_context *context,
745
0
                struct cprof_instrumentation_scope *instance) {
746
0
    int result;
747
748
0
    mpack_start_map(&context->writer, 4);
749
750
0
    mpack_write_cstr(&context->writer, "name");
751
0
    mpack_write_sds_or_nil(&context->writer,
752
0
                           instance->name);
753
754
755
0
    mpack_write_cstr(&context->writer, "version");
756
0
    mpack_write_sds_or_nil(&context->writer,
757
0
                           instance->version);
758
759
760
0
    mpack_write_cstr(&context->writer, "attributes");
761
762
0
    result = pack_cfl_variant_kvlist(&context->writer,
763
0
                                     instance->attributes);
764
765
0
    if (result != 0) {
766
0
        return -1;
767
0
    }
768
769
0
    mpack_write_cstr(&context->writer, "dropped_attribute_count");
770
0
    mpack_write_u32(&context->writer, instance->dropped_attributes_count);
771
772
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
773
0
}
774
775
776
777
static int encode_cprof_resource(
778
            struct cprof_msgpack_encoding_context *context,
779
0
            struct cprof_resource *instance) {
780
0
    int result;
781
782
0
    mpack_start_map(&context->writer, 2);
783
784
0
    mpack_write_cstr(&context->writer, "attributes");
785
786
0
    result = pack_cfl_variant_kvlist(&context->writer,
787
0
                                     instance->attributes);
788
789
0
    if (result != 0) {
790
0
        return -1;
791
0
    }
792
793
0
    mpack_write_cstr(&context->writer, "dropped_attribute_count");
794
0
    mpack_write_u32(&context->writer, instance->dropped_attributes_count);
795
796
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
797
0
}
798
799
800
801
802
803
static int encode_cprof_scope_profiles(
804
                struct cprof_msgpack_encoding_context *context,
805
0
                struct cprof_scope_profiles *instance) {
806
0
    int                   result;
807
0
    struct cfl_list      *iterator;
808
0
    struct cprof_profile *profile;
809
810
0
    mpack_start_map(&context->writer, 3);
811
0
    mpack_write_cstr(&context->writer, "instrumentation_scope");
812
813
0
    result = encode_cprof_instrumentation_scope(context, instance->scope);
814
815
0
    if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
816
0
        return result;
817
0
    }
818
819
0
    mpack_write_cstr(&context->writer, "profiles");
820
821
0
    mpack_start_array(&context->writer, cfl_list_size(&instance->profiles));
822
823
0
    if (!cfl_list_is_empty(&instance->profiles)) {
824
0
        cfl_list_foreach(iterator,
825
0
                         &instance->profiles) {
826
0
            profile = cfl_list_entry(
827
0
                        iterator,
828
0
                        struct cprof_profile, _head);
829
830
0
            result = encode_cprof_profile(context, profile);
831
832
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
833
0
                return result;
834
0
            }
835
0
        }
836
0
    }
837
838
0
    mpack_finish_array(&context->writer);
839
840
0
    mpack_write_cstr(&context->writer, "schema_url");
841
842
0
    mpack_write_sds_or_nil(&context->writer,
843
0
                           instance->schema_url);
844
845
0
    mpack_finish_map(&context->writer);
846
847
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
848
0
}
849
850
static int pack_context_header(struct cprof_msgpack_encoding_context *context,
851
                               struct cprof *profile)
852
0
{
853
0
    mpack_write_cstr(&context->writer, "meta");
854
0
    mpack_start_map(&context->writer, 0);
855
0
    mpack_finish_map(&context->writer);
856
857
0
    return 0;
858
0
}
859
860
static int pack_context_profiles(struct cprof_msgpack_encoding_context *context,
861
                                 struct cprof *profile)
862
0
{
863
0
    int                             result;
864
0
    struct cfl_list                *iterator;
865
0
    size_t                          profile_count;
866
0
    struct cprof_resource_profiles *resource_profiles;
867
868
0
    profile_count = 0 ;
869
0
    profile_count = cfl_list_size(&profile->profiles);
870
871
0
    mpack_write_cstr(&context->writer, "profiles");
872
0
    mpack_start_array(&context->writer, profile_count);
873
874
0
    if (!cfl_list_is_empty(&profile->profiles)) {
875
0
        cfl_list_foreach(iterator,
876
0
                         &profile->profiles) {
877
0
            resource_profiles = cfl_list_entry(
878
0
                                    iterator,
879
0
                                    struct cprof_resource_profiles, _head);
880
881
0
            result = encode_cprof_resource_profiles(context, resource_profiles);
882
883
0
            if (result != CPROF_ENCODE_MSGPACK_SUCCESS) {
884
0
                return result;
885
0
            }
886
0
        }
887
0
    }
888
889
0
    mpack_finish_array(&context->writer);
890
891
0
    return CPROF_ENCODE_MSGPACK_SUCCESS;
892
0
}
893
894
static int pack_context(struct cprof_msgpack_encoding_context *context,
895
                        struct cprof *profile)
896
0
{
897
0
    int result;
898
899
0
    mpack_start_map(&context->writer, 2);
900
901
0
    result = pack_context_header(context, profile);
902
903
0
    if (result != 0) {
904
0
        return -1;
905
0
    }
906
907
0
    result = pack_context_profiles(context, profile);
908
909
0
    if (result != 0) {
910
0
        return -2;
911
0
    }
912
913
0
    mpack_finish_map(&context->writer); /* outermost context scope */
914
915
0
    return 0;
916
0
}
917
918
int cprof_encode_msgpack_create(cfl_sds_t *result_buffer,
919
                                struct cprof *profile)
920
0
{
921
0
    int                                   result;
922
0
    struct cprof_msgpack_encoding_context context;
923
924
0
    *result_buffer = NULL;
925
926
0
    memset(&context, 0, sizeof(context));
927
928
0
    mpack_writer_init_growable(&context.writer,
929
0
                               &context.output_buffer,
930
0
                               &context.output_size);
931
932
933
0
    result = pack_context(&context, profile);
934
935
0
    if (mpack_writer_destroy(&context.writer) != mpack_ok) {
936
0
        fprintf(stderr, "An error occurred encoding the data!\n");
937
0
    }
938
939
0
    if (result == CPROF_ENCODE_MSGPACK_SUCCESS) {
940
0
        *result_buffer = cfl_sds_create_len(context.output_buffer, context.output_size);
941
0
    }
942
943
0
    if (context.output_buffer != NULL) {
944
0
        free(context.output_buffer);
945
0
    }
946
947
0
    return result;
948
0
}
949
950
void cprof_encode_msgpack_destroy(cfl_sds_t instance)
951
0
{
952
0
    if (instance != NULL) {
953
0
        cfl_sds_destroy(instance);
954
0
    }
955
0
}