Coverage Report

Created: 2026-01-17 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcbor/src/cbor/strings.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 "strings.h"
9
#include <string.h>
10
#include "internal/memory_utils.h"
11
#include "internal/unicode.h"
12
13
721k
cbor_item_t *cbor_new_definite_string(void) {
14
721k
  cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
15
721k
  _CBOR_NOTNULL(item);
16
721k
  *item = (cbor_item_t){
17
721k
      .refcount = 1,
18
721k
      .type = CBOR_TYPE_STRING,
19
721k
      .metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}}};
20
721k
  return item;
21
721k
}
22
23
17.5k
cbor_item_t *cbor_new_indefinite_string(void) {
24
17.5k
  cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
25
17.5k
  _CBOR_NOTNULL(item);
26
17.5k
  *item = (cbor_item_t){
27
17.5k
      .refcount = 1,
28
17.5k
      .type = CBOR_TYPE_STRING,
29
17.5k
      .metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE,
30
17.5k
                                       .length = 0}},
31
17.5k
      .data = _cbor_malloc(sizeof(struct cbor_indefinite_string_data))};
32
17.5k
  _CBOR_DEPENDENT_NOTNULL(item, item->data);
33
17.5k
  *((struct cbor_indefinite_string_data *)item->data) =
34
17.5k
      (struct cbor_indefinite_string_data){
35
17.5k
          .chunk_count = 0,
36
17.5k
          .chunk_capacity = 0,
37
17.5k
          .chunks = NULL,
38
17.5k
      };
39
17.5k
  return item;
40
17.5k
}
41
42
84.6k
cbor_item_t *cbor_build_string(const char *val) {
43
84.6k
  cbor_item_t *item = cbor_new_definite_string();
44
84.6k
  _CBOR_NOTNULL(item);
45
84.6k
  size_t len = strlen(val);
46
84.6k
  unsigned char *handle = _cbor_malloc(len);
47
84.6k
  _CBOR_DEPENDENT_NOTNULL(item, handle);
48
84.6k
  memcpy(handle, val, len);
49
84.6k
  cbor_string_set_handle(item, handle, len);
50
84.6k
  return item;
51
84.6k
}
52
53
0
cbor_item_t *cbor_build_stringn(const char *val, size_t length) {
54
0
  cbor_item_t *item = cbor_new_definite_string();
55
0
  _CBOR_NOTNULL(item);
56
0
  unsigned char *handle = _cbor_malloc(length);
57
0
  _CBOR_DEPENDENT_NOTNULL(item, handle);
58
0
  memcpy(handle, val, length);
59
0
  cbor_string_set_handle(item, handle, length);
60
0
  return item;
61
0
}
62
63
void cbor_string_set_handle(cbor_item_t *item,
64
                            cbor_mutable_data CBOR_RESTRICT_POINTER data,
65
721k
                            size_t length) {
66
721k
  CBOR_ASSERT(cbor_isa_string(item));
67
721k
  CBOR_ASSERT(cbor_string_is_definite(item));
68
721k
  item->data = data;
69
721k
  item->metadata.string_metadata.length = length;
70
721k
  struct _cbor_unicode_status unicode_status;
71
721k
  size_t codepoint_count =
72
721k
      _cbor_unicode_codepoint_count(data, length, &unicode_status);
73
721k
  CBOR_ASSERT(codepoint_count <= length);
74
721k
  if (unicode_status.status == _CBOR_UNICODE_OK) {
75
653k
    item->metadata.string_metadata.codepoint_count = codepoint_count;
76
653k
  } else {
77
67.5k
    item->metadata.string_metadata.codepoint_count = 0;
78
67.5k
  }
79
721k
}
80
81
17.5k
cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item) {
82
17.5k
  CBOR_ASSERT(cbor_isa_string(item));
83
17.5k
  CBOR_ASSERT(cbor_string_is_indefinite(item));
84
17.5k
  return ((struct cbor_indefinite_string_data *)item->data)->chunks;
85
17.5k
}
86
87
110k
size_t cbor_string_chunk_count(const cbor_item_t *item) {
88
110k
  CBOR_ASSERT(cbor_isa_string(item));
89
110k
  CBOR_ASSERT(cbor_string_is_indefinite(item));
90
110k
  return ((struct cbor_indefinite_string_data *)item->data)->chunk_count;
91
110k
}
92
93
93.1k
bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk) {
94
93.1k
  CBOR_ASSERT(cbor_isa_string(item));
95
93.1k
  CBOR_ASSERT(cbor_string_is_indefinite(item));
96
93.1k
  struct cbor_indefinite_string_data *data =
97
93.1k
      (struct cbor_indefinite_string_data *)item->data;
98
93.1k
  if (data->chunk_count == data->chunk_capacity) {
99
4.49k
    if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
100
0
      return false;
101
0
    }
102
103
4.49k
    size_t new_chunk_capacity =
104
4.49k
        data->chunk_capacity == 0 ? 1
105
4.49k
                                  : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
106
4.49k
    cbor_item_t **new_chunks_data = _cbor_realloc_multiple(
107
4.49k
        data->chunks, sizeof(cbor_item_t *), new_chunk_capacity);
108
109
4.49k
    if (new_chunks_data == NULL) {
110
1
      return false;
111
1
    }
112
113
4.49k
    data->chunk_capacity = new_chunk_capacity;
114
4.49k
    data->chunks = new_chunks_data;
115
4.49k
  }
116
93.1k
  data->chunks[data->chunk_count++] = cbor_incref(chunk);
117
93.1k
  return true;
118
93.1k
}
119
120
381k
size_t cbor_string_length(const cbor_item_t *item) {
121
381k
  CBOR_ASSERT(cbor_isa_string(item));
122
381k
  return item->metadata.string_metadata.length;
123
381k
}
124
125
191k
unsigned char *cbor_string_handle(const cbor_item_t *item) {
126
191k
  CBOR_ASSERT(cbor_isa_string(item));
127
191k
  return item->data;
128
191k
}
129
130
0
size_t cbor_string_codepoint_count(const cbor_item_t *item) {
131
0
  CBOR_ASSERT(cbor_isa_string(item));
132
0
  return item->metadata.string_metadata.codepoint_count;
133
0
}
134
135
1.00M
bool cbor_string_is_definite(const cbor_item_t *item) {
136
1.00M
  CBOR_ASSERT(cbor_isa_string(item));
137
1.00M
  return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE;
138
1.00M
}
139
140
94.6k
bool cbor_string_is_indefinite(const cbor_item_t *item) {
141
94.6k
  return !cbor_string_is_definite(item);
142
94.6k
}