xref: /freebsd/contrib/libcbor/src/cbor/bytestrings.c (revision 5d3e7166)
110ff414cSEd Maste /*
210ff414cSEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
310ff414cSEd Maste  *
410ff414cSEd Maste  * libcbor is free software; you can redistribute it and/or modify
510ff414cSEd Maste  * it under the terms of the MIT license. See LICENSE for details.
610ff414cSEd Maste  */
710ff414cSEd Maste 
810ff414cSEd Maste #include "bytestrings.h"
910ff414cSEd Maste #include <string.h>
1010ff414cSEd Maste #include "internal/memory_utils.h"
1110ff414cSEd Maste 
cbor_bytestring_length(const cbor_item_t * item)1210ff414cSEd Maste size_t cbor_bytestring_length(const cbor_item_t *item) {
13*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
1410ff414cSEd Maste   return item->metadata.bytestring_metadata.length;
1510ff414cSEd Maste }
1610ff414cSEd Maste 
cbor_bytestring_handle(const cbor_item_t * item)1710ff414cSEd Maste unsigned char *cbor_bytestring_handle(const cbor_item_t *item) {
18*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
1910ff414cSEd Maste   return item->data;
2010ff414cSEd Maste }
2110ff414cSEd Maste 
cbor_bytestring_is_definite(const cbor_item_t * item)2210ff414cSEd Maste bool cbor_bytestring_is_definite(const cbor_item_t *item) {
23*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
2410ff414cSEd Maste   return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE;
2510ff414cSEd Maste }
2610ff414cSEd Maste 
cbor_bytestring_is_indefinite(const cbor_item_t * item)2710ff414cSEd Maste bool cbor_bytestring_is_indefinite(const cbor_item_t *item) {
2810ff414cSEd Maste   return !cbor_bytestring_is_definite(item);
2910ff414cSEd Maste }
3010ff414cSEd Maste 
cbor_new_definite_bytestring(void)31*5d3e7166SEd Maste cbor_item_t *cbor_new_definite_bytestring(void) {
32*5d3e7166SEd Maste   cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
3310ff414cSEd Maste   _CBOR_NOTNULL(item);
3410ff414cSEd Maste   *item = (cbor_item_t){
3510ff414cSEd Maste       .refcount = 1,
3610ff414cSEd Maste       .type = CBOR_TYPE_BYTESTRING,
37*5d3e7166SEd Maste       .metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_DEFINITE,
38*5d3e7166SEd Maste                                            .length = 0}}};
3910ff414cSEd Maste   return item;
4010ff414cSEd Maste }
4110ff414cSEd Maste 
cbor_new_indefinite_bytestring(void)42*5d3e7166SEd Maste cbor_item_t *cbor_new_indefinite_bytestring(void) {
43*5d3e7166SEd Maste   cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
4410ff414cSEd Maste   _CBOR_NOTNULL(item);
4510ff414cSEd Maste   *item = (cbor_item_t){
4610ff414cSEd Maste       .refcount = 1,
4710ff414cSEd Maste       .type = CBOR_TYPE_BYTESTRING,
4810ff414cSEd Maste       .metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_INDEFINITE,
4910ff414cSEd Maste                                            .length = 0}},
50*5d3e7166SEd Maste       .data = _cbor_malloc(sizeof(struct cbor_indefinite_string_data))};
5110ff414cSEd Maste   _CBOR_DEPENDENT_NOTNULL(item, item->data);
5210ff414cSEd Maste   *((struct cbor_indefinite_string_data *)item->data) =
5310ff414cSEd Maste       (struct cbor_indefinite_string_data){
5410ff414cSEd Maste           .chunk_count = 0,
5510ff414cSEd Maste           .chunk_capacity = 0,
5610ff414cSEd Maste           .chunks = NULL,
5710ff414cSEd Maste       };
5810ff414cSEd Maste   return item;
5910ff414cSEd Maste }
6010ff414cSEd Maste 
cbor_build_bytestring(cbor_data handle,size_t length)6110ff414cSEd Maste cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length) {
6210ff414cSEd Maste   cbor_item_t *item = cbor_new_definite_bytestring();
6310ff414cSEd Maste   _CBOR_NOTNULL(item);
64*5d3e7166SEd Maste   void *content = _cbor_malloc(length);
6510ff414cSEd Maste   _CBOR_DEPENDENT_NOTNULL(item, content);
6610ff414cSEd Maste   memcpy(content, handle, length);
6710ff414cSEd Maste   cbor_bytestring_set_handle(item, content, length);
6810ff414cSEd Maste   return item;
6910ff414cSEd Maste }
7010ff414cSEd Maste 
cbor_bytestring_set_handle(cbor_item_t * item,cbor_mutable_data CBOR_RESTRICT_POINTER data,size_t length)7110ff414cSEd Maste void cbor_bytestring_set_handle(cbor_item_t *item,
7210ff414cSEd Maste                                 cbor_mutable_data CBOR_RESTRICT_POINTER data,
7310ff414cSEd Maste                                 size_t length) {
74*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
75*5d3e7166SEd Maste   CBOR_ASSERT(cbor_bytestring_is_definite(item));
7610ff414cSEd Maste   item->data = data;
7710ff414cSEd Maste   item->metadata.bytestring_metadata.length = length;
7810ff414cSEd Maste }
7910ff414cSEd Maste 
cbor_bytestring_chunks_handle(const cbor_item_t * item)8010ff414cSEd Maste cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item) {
81*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
82*5d3e7166SEd Maste   CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
8310ff414cSEd Maste   return ((struct cbor_indefinite_string_data *)item->data)->chunks;
8410ff414cSEd Maste }
8510ff414cSEd Maste 
cbor_bytestring_chunk_count(const cbor_item_t * item)8610ff414cSEd Maste size_t cbor_bytestring_chunk_count(const cbor_item_t *item) {
87*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
88*5d3e7166SEd Maste   CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
8910ff414cSEd Maste   return ((struct cbor_indefinite_string_data *)item->data)->chunk_count;
9010ff414cSEd Maste }
9110ff414cSEd Maste 
cbor_bytestring_add_chunk(cbor_item_t * item,cbor_item_t * chunk)9210ff414cSEd Maste bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk) {
93*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(item));
94*5d3e7166SEd Maste   CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
95*5d3e7166SEd Maste   CBOR_ASSERT(cbor_isa_bytestring(chunk));
96*5d3e7166SEd Maste   CBOR_ASSERT(cbor_bytestring_is_definite(chunk));
9710ff414cSEd Maste   struct cbor_indefinite_string_data *data =
9810ff414cSEd Maste       (struct cbor_indefinite_string_data *)item->data;
9910ff414cSEd Maste   if (data->chunk_count == data->chunk_capacity) {
10010ff414cSEd Maste     if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
10110ff414cSEd Maste       return false;
10210ff414cSEd Maste     }
10310ff414cSEd Maste 
10410ff414cSEd Maste     size_t new_chunk_capacity =
10510ff414cSEd Maste         data->chunk_capacity == 0 ? 1
10610ff414cSEd Maste                                   : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
10710ff414cSEd Maste 
10810ff414cSEd Maste     cbor_item_t **new_chunks_data = _cbor_realloc_multiple(
10910ff414cSEd Maste         data->chunks, sizeof(cbor_item_t *), new_chunk_capacity);
11010ff414cSEd Maste 
11110ff414cSEd Maste     if (new_chunks_data == NULL) {
11210ff414cSEd Maste       return false;
11310ff414cSEd Maste     }
11410ff414cSEd Maste     data->chunk_capacity = new_chunk_capacity;
11510ff414cSEd Maste     data->chunks = new_chunks_data;
11610ff414cSEd Maste   }
11710ff414cSEd Maste   data->chunks[data->chunk_count++] = cbor_incref(chunk);
11810ff414cSEd Maste   return true;
11910ff414cSEd Maste }
120