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