Path: blob/main/contrib/libcbor/src/cbor/common.c
104852 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 "cbor/common.h"8#include "arrays.h"9#include "bytestrings.h"10#include "data.h"11#include "floats_ctrls.h"12#include "ints.h"13#include "maps.h"14#include "strings.h"15#include "tags.h"1617#ifdef DEBUG18bool _cbor_enable_assert = true;19#endif2021bool cbor_isa_uint(const cbor_item_t *item) {22return item->type == CBOR_TYPE_UINT;23}2425bool cbor_isa_negint(const cbor_item_t *item) {26return item->type == CBOR_TYPE_NEGINT;27}2829bool cbor_isa_bytestring(const cbor_item_t *item) {30return item->type == CBOR_TYPE_BYTESTRING;31}3233bool cbor_isa_string(const cbor_item_t *item) {34return item->type == CBOR_TYPE_STRING;35}3637bool cbor_isa_array(const cbor_item_t *item) {38return item->type == CBOR_TYPE_ARRAY;39}4041bool cbor_isa_map(const cbor_item_t *item) {42return item->type == CBOR_TYPE_MAP;43}4445bool cbor_isa_tag(const cbor_item_t *item) {46return item->type == CBOR_TYPE_TAG;47}4849bool cbor_isa_float_ctrl(const cbor_item_t *item) {50return item->type == CBOR_TYPE_FLOAT_CTRL;51}5253cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; }5455bool cbor_is_int(const cbor_item_t *item) {56return cbor_isa_uint(item) || cbor_isa_negint(item);57}5859bool cbor_is_bool(const cbor_item_t *item) {60return cbor_isa_float_ctrl(item) &&61(cbor_ctrl_value(item) == CBOR_CTRL_FALSE ||62cbor_ctrl_value(item) == CBOR_CTRL_TRUE);63}6465bool cbor_is_null(const cbor_item_t *item) {66return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL;67}6869bool cbor_is_undef(const cbor_item_t *item) {70return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF;71}7273bool cbor_is_float(const cbor_item_t *item) {74return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item);75}7677cbor_item_t *cbor_incref(cbor_item_t *item) {78item->refcount++;79return item;80}8182void cbor_decref(cbor_item_t **item_ref) {83cbor_item_t *item = *item_ref;84CBOR_ASSERT(item->refcount > 0);85if (--item->refcount == 0) {86switch (item->type) {87case CBOR_TYPE_UINT:88/* Fallthrough */89case CBOR_TYPE_NEGINT:90/* Combined allocation, freeing the item suffices */91{ break; }92case CBOR_TYPE_BYTESTRING: {93if (cbor_bytestring_is_definite(item)) {94_cbor_free(item->data);95} else {96/* We need to decref all chunks */97cbor_item_t **handle = cbor_bytestring_chunks_handle(item);98for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)99cbor_decref(&handle[i]);100_cbor_free(101((struct cbor_indefinite_string_data *)item->data)->chunks);102_cbor_free(item->data);103}104break;105}106case CBOR_TYPE_STRING: {107if (cbor_string_is_definite(item)) {108_cbor_free(item->data);109} else {110/* We need to decref all chunks */111cbor_item_t **handle = cbor_string_chunks_handle(item);112for (size_t i = 0; i < cbor_string_chunk_count(item); i++)113cbor_decref(&handle[i]);114_cbor_free(115((struct cbor_indefinite_string_data *)item->data)->chunks);116_cbor_free(item->data);117}118break;119}120case CBOR_TYPE_ARRAY: {121/* Get all items and decref them */122cbor_item_t **handle = cbor_array_handle(item);123size_t size = cbor_array_size(item);124for (size_t i = 0; i < size; i++)125if (handle[i] != NULL) cbor_decref(&handle[i]);126_cbor_free(item->data);127break;128}129case CBOR_TYPE_MAP: {130struct cbor_pair *handle = cbor_map_handle(item);131for (size_t i = 0; i < item->metadata.map_metadata.end_ptr;132i++, handle++) {133cbor_decref(&handle->key);134if (handle->value != NULL) cbor_decref(&handle->value);135}136_cbor_free(item->data);137break;138}139case CBOR_TYPE_TAG: {140if (item->metadata.tag_metadata.tagged_item != NULL)141cbor_decref(&item->metadata.tag_metadata.tagged_item);142_cbor_free(item->data);143break;144}145case CBOR_TYPE_FLOAT_CTRL: {146/* Floats have combined allocation */147break;148}149}150_cbor_free(item);151*item_ref = NULL;152}153}154155void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); }156157size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; }158159cbor_item_t *cbor_move(cbor_item_t *item) {160item->refcount--;161return item;162}163164165