Coverage Report

Created: 2025-11-24 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcbor/src/cbor/common.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3
 *
4
 * libcbor is free software; you can redistribute it and/or modify
5
 * it under the terms of the MIT license. See LICENSE for details.
6
 */
7
8
#include "cbor/common.h"
9
#include "arrays.h"
10
#include "bytestrings.h"
11
#include "data.h"
12
#include "floats_ctrls.h"
13
#include "ints.h"
14
#include "maps.h"
15
#include "strings.h"
16
#include "tags.h"
17
18
#ifdef DEBUG
19
bool _cbor_enable_assert = true;
20
#endif
21
22
795k
bool cbor_isa_uint(const cbor_item_t *item) {
23
795k
  return item->type == CBOR_TYPE_UINT;
24
795k
}
25
26
3.21k
bool cbor_isa_negint(const cbor_item_t *item) {
27
3.21k
  return item->type == CBOR_TYPE_NEGINT;
28
3.21k
}
29
30
551k
bool cbor_isa_bytestring(const cbor_item_t *item) {
31
551k
  return item->type == CBOR_TYPE_BYTESTRING;
32
551k
}
33
34
614k
bool cbor_isa_string(const cbor_item_t *item) {
35
614k
  return item->type == CBOR_TYPE_STRING;
36
614k
}
37
38
268k
bool cbor_isa_array(const cbor_item_t *item) {
39
268k
  return item->type == CBOR_TYPE_ARRAY;
40
268k
}
41
42
3.49M
bool cbor_isa_map(const cbor_item_t *item) {
43
3.49M
  return item->type == CBOR_TYPE_MAP;
44
3.49M
}
45
46
0
bool cbor_isa_tag(const cbor_item_t *item) {
47
0
  return item->type == CBOR_TYPE_TAG;
48
0
}
49
50
0
bool cbor_isa_float_ctrl(const cbor_item_t *item) {
51
0
  return item->type == CBOR_TYPE_FLOAT_CTRL;
52
0
}
53
54
7.88M
cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; }
55
56
2.77k
bool cbor_is_int(const cbor_item_t *item) {
57
2.77k
  return cbor_isa_uint(item) || cbor_isa_negint(item);
58
2.77k
}
59
60
0
bool cbor_is_bool(const cbor_item_t *item) {
61
0
  return cbor_isa_float_ctrl(item) &&
62
0
         (cbor_ctrl_value(item) == CBOR_CTRL_FALSE ||
63
0
          cbor_ctrl_value(item) == CBOR_CTRL_TRUE);
64
0
}
65
66
0
bool cbor_is_null(const cbor_item_t *item) {
67
0
  return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL;
68
0
}
69
70
0
bool cbor_is_undef(const cbor_item_t *item) {
71
0
  return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF;
72
0
}
73
74
0
bool cbor_is_float(const cbor_item_t *item) {
75
0
  return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item);
76
0
}
77
78
18.4M
cbor_item_t *cbor_incref(cbor_item_t *item) {
79
18.4M
  item->refcount++;
80
18.4M
  return item;
81
18.4M
}
82
83
34.5M
void cbor_decref(cbor_item_t **item_ref) {
84
34.5M
  cbor_item_t *item = *item_ref;
85
34.5M
  CBOR_ASSERT(item->refcount > 0);
86
34.5M
  if (--item->refcount == 0) {
87
16.1M
    switch (item->type) {
88
6.67M
      case CBOR_TYPE_UINT:
89
        /* Fallthrough */
90
7.25M
      case CBOR_TYPE_NEGINT:
91
        /* Combined allocation, freeing the item suffices */
92
7.25M
        { break; }
93
546k
      case CBOR_TYPE_BYTESTRING: {
94
546k
        if (cbor_bytestring_is_definite(item)) {
95
534k
          _cbor_free(item->data);
96
534k
        } else {
97
          /* We need to decref all chunks */
98
12.1k
          cbor_item_t **handle = cbor_bytestring_chunks_handle(item);
99
95.8k
          for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
100
83.7k
            cbor_decref(&handle[i]);
101
12.1k
          _cbor_free(
102
12.1k
              ((struct cbor_indefinite_string_data *)item->data)->chunks);
103
12.1k
          _cbor_free(item->data);
104
12.1k
        }
105
546k
        break;
106
6.67M
      }
107
646k
      case CBOR_TYPE_STRING: {
108
646k
        if (cbor_string_is_definite(item)) {
109
624k
          _cbor_free(item->data);
110
624k
        } else {
111
          /* We need to decref all chunks */
112
22.0k
          cbor_item_t **handle = cbor_string_chunks_handle(item);
113
71.9k
          for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
114
49.8k
            cbor_decref(&handle[i]);
115
22.0k
          _cbor_free(
116
22.0k
              ((struct cbor_indefinite_string_data *)item->data)->chunks);
117
22.0k
          _cbor_free(item->data);
118
22.0k
        }
119
646k
        break;
120
6.67M
      }
121
736k
      case CBOR_TYPE_ARRAY: {
122
        /* Get all items and decref them */
123
736k
        cbor_item_t **handle = cbor_array_handle(item);
124
736k
        size_t size = cbor_array_size(item);
125
7.63M
        for (size_t i = 0; i < size; i++)
126
6.89M
          if (handle[i] != NULL) cbor_decref(&handle[i]);
127
736k
        _cbor_free(item->data);
128
736k
        break;
129
6.67M
      }
130
6.20M
      case CBOR_TYPE_MAP: {
131
6.20M
        struct cbor_pair *handle = cbor_map_handle(item);
132
9.99M
        for (size_t i = 0; i < item->metadata.map_metadata.end_ptr;
133
6.20M
             i++, handle++) {
134
3.78M
          cbor_decref(&handle->key);
135
3.78M
          if (handle->value != NULL) cbor_decref(&handle->value);
136
3.78M
        }
137
6.20M
        _cbor_free(item->data);
138
6.20M
        break;
139
6.67M
      }
140
515k
      case CBOR_TYPE_TAG: {
141
515k
        if (item->metadata.tag_metadata.tagged_item != NULL)
142
242k
          cbor_decref(&item->metadata.tag_metadata.tagged_item);
143
515k
        _cbor_free(item->data);
144
515k
        break;
145
6.67M
      }
146
243k
      case CBOR_TYPE_FLOAT_CTRL: {
147
        /* Floats have combined allocation */
148
243k
        break;
149
6.67M
      }
150
16.1M
    }
151
16.1M
    _cbor_free(item);
152
16.1M
    *item_ref = NULL;
153
16.1M
  }
154
34.5M
}
155
156
7.98M
void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); }
157
158
0
size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; }
159
160
0
cbor_item_t *cbor_move(cbor_item_t *item) {
161
0
  item->refcount--;
162
0
  return item;
163
0
}