Path: blob/main/contrib/libcbor/src/cbor/bytestrings.c
39536 views
/*1* Copyright (c) 2014-2020 Pavel Kalvoda <[email protected]>2*3* libcbor is free software; you can redistribute it and/or modify4* it under the terms of the MIT license. See LICENSE for details.5*/67#include "bytestrings.h"8#include <string.h>9#include "internal/memory_utils.h"1011size_t cbor_bytestring_length(const cbor_item_t *item) {12CBOR_ASSERT(cbor_isa_bytestring(item));13return item->metadata.bytestring_metadata.length;14}1516unsigned char *cbor_bytestring_handle(const cbor_item_t *item) {17CBOR_ASSERT(cbor_isa_bytestring(item));18return item->data;19}2021bool cbor_bytestring_is_definite(const cbor_item_t *item) {22CBOR_ASSERT(cbor_isa_bytestring(item));23return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE;24}2526bool cbor_bytestring_is_indefinite(const cbor_item_t *item) {27return !cbor_bytestring_is_definite(item);28}2930cbor_item_t *cbor_new_definite_bytestring(void) {31cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));32_CBOR_NOTNULL(item);33*item = (cbor_item_t){34.refcount = 1,35.type = CBOR_TYPE_BYTESTRING,36.metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_DEFINITE,37.length = 0}}};38return item;39}4041cbor_item_t *cbor_new_indefinite_bytestring(void) {42cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));43_CBOR_NOTNULL(item);44*item = (cbor_item_t){45.refcount = 1,46.type = CBOR_TYPE_BYTESTRING,47.metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_INDEFINITE,48.length = 0}},49.data = _cbor_malloc(sizeof(struct cbor_indefinite_string_data))};50_CBOR_DEPENDENT_NOTNULL(item, item->data);51*((struct cbor_indefinite_string_data *)item->data) =52(struct cbor_indefinite_string_data){53.chunk_count = 0,54.chunk_capacity = 0,55.chunks = NULL,56};57return item;58}5960cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length) {61cbor_item_t *item = cbor_new_definite_bytestring();62_CBOR_NOTNULL(item);63void *content = _cbor_malloc(length);64_CBOR_DEPENDENT_NOTNULL(item, content);65memcpy(content, handle, length);66cbor_bytestring_set_handle(item, content, length);67return item;68}6970void cbor_bytestring_set_handle(cbor_item_t *item,71cbor_mutable_data CBOR_RESTRICT_POINTER data,72size_t length) {73CBOR_ASSERT(cbor_isa_bytestring(item));74CBOR_ASSERT(cbor_bytestring_is_definite(item));75item->data = data;76item->metadata.bytestring_metadata.length = length;77}7879cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item) {80CBOR_ASSERT(cbor_isa_bytestring(item));81CBOR_ASSERT(cbor_bytestring_is_indefinite(item));82return ((struct cbor_indefinite_string_data *)item->data)->chunks;83}8485size_t cbor_bytestring_chunk_count(const cbor_item_t *item) {86CBOR_ASSERT(cbor_isa_bytestring(item));87CBOR_ASSERT(cbor_bytestring_is_indefinite(item));88return ((struct cbor_indefinite_string_data *)item->data)->chunk_count;89}9091bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk) {92CBOR_ASSERT(cbor_isa_bytestring(item));93CBOR_ASSERT(cbor_bytestring_is_indefinite(item));94CBOR_ASSERT(cbor_isa_bytestring(chunk));95CBOR_ASSERT(cbor_bytestring_is_definite(chunk));96struct cbor_indefinite_string_data *data =97(struct cbor_indefinite_string_data *)item->data;98if (data->chunk_count == data->chunk_capacity) {99if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {100return false;101}102103size_t new_chunk_capacity =104data->chunk_capacity == 0 ? 1105: CBOR_BUFFER_GROWTH * (data->chunk_capacity);106107cbor_item_t **new_chunks_data = _cbor_realloc_multiple(108data->chunks, sizeof(cbor_item_t *), new_chunk_capacity);109110if (new_chunks_data == NULL) {111return false;112}113data->chunk_capacity = new_chunk_capacity;114data->chunks = new_chunks_data;115}116data->chunks[data->chunk_count++] = cbor_incref(chunk);117return true;118}119120121