Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libcbor/src/cbor/bytestrings.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 "bytestrings.h"
9
#include <string.h>
10
#include "internal/memory_utils.h"
11
12
size_t cbor_bytestring_length(const cbor_item_t *item) {
13
CBOR_ASSERT(cbor_isa_bytestring(item));
14
return item->metadata.bytestring_metadata.length;
15
}
16
17
unsigned char *cbor_bytestring_handle(const cbor_item_t *item) {
18
CBOR_ASSERT(cbor_isa_bytestring(item));
19
return item->data;
20
}
21
22
bool cbor_bytestring_is_definite(const cbor_item_t *item) {
23
CBOR_ASSERT(cbor_isa_bytestring(item));
24
return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE;
25
}
26
27
bool cbor_bytestring_is_indefinite(const cbor_item_t *item) {
28
return !cbor_bytestring_is_definite(item);
29
}
30
31
cbor_item_t *cbor_new_definite_bytestring(void) {
32
cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
33
_CBOR_NOTNULL(item);
34
*item = (cbor_item_t){
35
.refcount = 1,
36
.type = CBOR_TYPE_BYTESTRING,
37
.metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_DEFINITE,
38
.length = 0}}};
39
return item;
40
}
41
42
cbor_item_t *cbor_new_indefinite_bytestring(void) {
43
cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
44
_CBOR_NOTNULL(item);
45
*item = (cbor_item_t){
46
.refcount = 1,
47
.type = CBOR_TYPE_BYTESTRING,
48
.metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_INDEFINITE,
49
.length = 0}},
50
.data = _cbor_malloc(sizeof(struct cbor_indefinite_string_data))};
51
_CBOR_DEPENDENT_NOTNULL(item, item->data);
52
*((struct cbor_indefinite_string_data *)item->data) =
53
(struct cbor_indefinite_string_data){
54
.chunk_count = 0,
55
.chunk_capacity = 0,
56
.chunks = NULL,
57
};
58
return item;
59
}
60
61
cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length) {
62
cbor_item_t *item = cbor_new_definite_bytestring();
63
_CBOR_NOTNULL(item);
64
void *content = _cbor_malloc(length);
65
_CBOR_DEPENDENT_NOTNULL(item, content);
66
memcpy(content, handle, length);
67
cbor_bytestring_set_handle(item, content, length);
68
return item;
69
}
70
71
void cbor_bytestring_set_handle(cbor_item_t *item,
72
cbor_mutable_data CBOR_RESTRICT_POINTER data,
73
size_t length) {
74
CBOR_ASSERT(cbor_isa_bytestring(item));
75
CBOR_ASSERT(cbor_bytestring_is_definite(item));
76
item->data = data;
77
item->metadata.bytestring_metadata.length = length;
78
}
79
80
cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item) {
81
CBOR_ASSERT(cbor_isa_bytestring(item));
82
CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
83
return ((struct cbor_indefinite_string_data *)item->data)->chunks;
84
}
85
86
size_t cbor_bytestring_chunk_count(const cbor_item_t *item) {
87
CBOR_ASSERT(cbor_isa_bytestring(item));
88
CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
89
return ((struct cbor_indefinite_string_data *)item->data)->chunk_count;
90
}
91
92
bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk) {
93
CBOR_ASSERT(cbor_isa_bytestring(item));
94
CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
95
CBOR_ASSERT(cbor_isa_bytestring(chunk));
96
CBOR_ASSERT(cbor_bytestring_is_definite(chunk));
97
struct cbor_indefinite_string_data *data =
98
(struct cbor_indefinite_string_data *)item->data;
99
if (data->chunk_count == data->chunk_capacity) {
100
if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
101
return false;
102
}
103
104
size_t new_chunk_capacity =
105
data->chunk_capacity == 0 ? 1
106
: CBOR_BUFFER_GROWTH * (data->chunk_capacity);
107
108
cbor_item_t **new_chunks_data = _cbor_realloc_multiple(
109
data->chunks, sizeof(cbor_item_t *), new_chunk_capacity);
110
111
if (new_chunks_data == NULL) {
112
return false;
113
}
114
data->chunk_capacity = new_chunk_capacity;
115
data->chunks = new_chunks_data;
116
}
117
data->chunks[data->chunk_count++] = cbor_incref(chunk);
118
return true;
119
}
120
121