Coverage Report

Created: 2025-11-11 06:59

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