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 "cbor/common.h" 910ff414cSEd Maste #include "arrays.h" 1010ff414cSEd Maste #include "bytestrings.h" 1110ff414cSEd Maste #include "data.h" 1210ff414cSEd Maste #include "floats_ctrls.h" 1310ff414cSEd Maste #include "ints.h" 1410ff414cSEd Maste #include "maps.h" 1510ff414cSEd Maste #include "strings.h" 1610ff414cSEd Maste #include "tags.h" 1710ff414cSEd Maste 18*5d3e7166SEd Maste #ifdef DEBUG 19*5d3e7166SEd Maste bool _cbor_enable_assert = true; 20*5d3e7166SEd Maste #endif 21*5d3e7166SEd Maste cbor_isa_uint(const cbor_item_t * item)2210ff414cSEd Mastebool cbor_isa_uint(const cbor_item_t *item) { 2310ff414cSEd Maste return item->type == CBOR_TYPE_UINT; 2410ff414cSEd Maste } 2510ff414cSEd Maste cbor_isa_negint(const cbor_item_t * item)2610ff414cSEd Mastebool cbor_isa_negint(const cbor_item_t *item) { 2710ff414cSEd Maste return item->type == CBOR_TYPE_NEGINT; 2810ff414cSEd Maste } 2910ff414cSEd Maste cbor_isa_bytestring(const cbor_item_t * item)3010ff414cSEd Mastebool cbor_isa_bytestring(const cbor_item_t *item) { 3110ff414cSEd Maste return item->type == CBOR_TYPE_BYTESTRING; 3210ff414cSEd Maste } 3310ff414cSEd Maste cbor_isa_string(const cbor_item_t * item)3410ff414cSEd Mastebool cbor_isa_string(const cbor_item_t *item) { 3510ff414cSEd Maste return item->type == CBOR_TYPE_STRING; 3610ff414cSEd Maste } 3710ff414cSEd Maste cbor_isa_array(const cbor_item_t * item)3810ff414cSEd Mastebool cbor_isa_array(const cbor_item_t *item) { 3910ff414cSEd Maste return item->type == CBOR_TYPE_ARRAY; 4010ff414cSEd Maste } 4110ff414cSEd Maste cbor_isa_map(const cbor_item_t * item)4210ff414cSEd Mastebool cbor_isa_map(const cbor_item_t *item) { 4310ff414cSEd Maste return item->type == CBOR_TYPE_MAP; 4410ff414cSEd Maste } 4510ff414cSEd Maste cbor_isa_tag(const cbor_item_t * item)4610ff414cSEd Mastebool cbor_isa_tag(const cbor_item_t *item) { 4710ff414cSEd Maste return item->type == CBOR_TYPE_TAG; 4810ff414cSEd Maste } 4910ff414cSEd Maste cbor_isa_float_ctrl(const cbor_item_t * item)5010ff414cSEd Mastebool cbor_isa_float_ctrl(const cbor_item_t *item) { 5110ff414cSEd Maste return item->type == CBOR_TYPE_FLOAT_CTRL; 5210ff414cSEd Maste } 5310ff414cSEd Maste cbor_typeof(const cbor_item_t * item)5410ff414cSEd Mastecbor_type cbor_typeof(const cbor_item_t *item) { return item->type; } 5510ff414cSEd Maste cbor_is_int(const cbor_item_t * item)5610ff414cSEd Mastebool cbor_is_int(const cbor_item_t *item) { 5710ff414cSEd Maste return cbor_isa_uint(item) || cbor_isa_negint(item); 5810ff414cSEd Maste } 5910ff414cSEd Maste cbor_is_bool(const cbor_item_t * item)6010ff414cSEd Mastebool cbor_is_bool(const cbor_item_t *item) { 6110ff414cSEd Maste return cbor_isa_float_ctrl(item) && 6210ff414cSEd Maste (cbor_ctrl_value(item) == CBOR_CTRL_FALSE || 6310ff414cSEd Maste cbor_ctrl_value(item) == CBOR_CTRL_TRUE); 6410ff414cSEd Maste } 6510ff414cSEd Maste cbor_is_null(const cbor_item_t * item)6610ff414cSEd Mastebool cbor_is_null(const cbor_item_t *item) { 6710ff414cSEd Maste return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL; 6810ff414cSEd Maste } 6910ff414cSEd Maste cbor_is_undef(const cbor_item_t * item)7010ff414cSEd Mastebool cbor_is_undef(const cbor_item_t *item) { 7110ff414cSEd Maste return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF; 7210ff414cSEd Maste } 7310ff414cSEd Maste cbor_is_float(const cbor_item_t * item)7410ff414cSEd Mastebool cbor_is_float(const cbor_item_t *item) { 7510ff414cSEd Maste return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item); 7610ff414cSEd Maste } 7710ff414cSEd Maste cbor_incref(cbor_item_t * item)7810ff414cSEd Mastecbor_item_t *cbor_incref(cbor_item_t *item) { 7910ff414cSEd Maste item->refcount++; 8010ff414cSEd Maste return item; 8110ff414cSEd Maste } 8210ff414cSEd Maste cbor_decref(cbor_item_t ** item_ref)8310ff414cSEd Mastevoid cbor_decref(cbor_item_t **item_ref) { 8410ff414cSEd Maste cbor_item_t *item = *item_ref; 85*5d3e7166SEd Maste CBOR_ASSERT(item->refcount > 0); 8610ff414cSEd Maste if (--item->refcount == 0) { 8710ff414cSEd Maste switch (item->type) { 8810ff414cSEd Maste case CBOR_TYPE_UINT: 8910ff414cSEd Maste /* Fallthrough */ 9010ff414cSEd Maste case CBOR_TYPE_NEGINT: 9110ff414cSEd Maste /* Combined allocation, freeing the item suffices */ 9210ff414cSEd Maste { break; } 9310ff414cSEd Maste case CBOR_TYPE_BYTESTRING: { 9410ff414cSEd Maste if (cbor_bytestring_is_definite(item)) { 95*5d3e7166SEd Maste _cbor_free(item->data); 9610ff414cSEd Maste } else { 9710ff414cSEd Maste /* We need to decref all chunks */ 9810ff414cSEd Maste cbor_item_t **handle = cbor_bytestring_chunks_handle(item); 9910ff414cSEd Maste for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) 10010ff414cSEd Maste cbor_decref(&handle[i]); 101*5d3e7166SEd Maste _cbor_free( 10210ff414cSEd Maste ((struct cbor_indefinite_string_data *)item->data)->chunks); 103*5d3e7166SEd Maste _cbor_free(item->data); 10410ff414cSEd Maste } 10510ff414cSEd Maste break; 10610ff414cSEd Maste } 10710ff414cSEd Maste case CBOR_TYPE_STRING: { 10810ff414cSEd Maste if (cbor_string_is_definite(item)) { 109*5d3e7166SEd Maste _cbor_free(item->data); 11010ff414cSEd Maste } else { 11110ff414cSEd Maste /* We need to decref all chunks */ 11210ff414cSEd Maste cbor_item_t **handle = cbor_string_chunks_handle(item); 11310ff414cSEd Maste for (size_t i = 0; i < cbor_string_chunk_count(item); i++) 11410ff414cSEd Maste cbor_decref(&handle[i]); 115*5d3e7166SEd Maste _cbor_free( 11610ff414cSEd Maste ((struct cbor_indefinite_string_data *)item->data)->chunks); 117*5d3e7166SEd Maste _cbor_free(item->data); 11810ff414cSEd Maste } 11910ff414cSEd Maste break; 12010ff414cSEd Maste } 12110ff414cSEd Maste case CBOR_TYPE_ARRAY: { 12210ff414cSEd Maste /* Get all items and decref them */ 12310ff414cSEd Maste cbor_item_t **handle = cbor_array_handle(item); 12410ff414cSEd Maste size_t size = cbor_array_size(item); 12510ff414cSEd Maste for (size_t i = 0; i < size; i++) 12610ff414cSEd Maste if (handle[i] != NULL) cbor_decref(&handle[i]); 127*5d3e7166SEd Maste _cbor_free(item->data); 12810ff414cSEd Maste break; 12910ff414cSEd Maste } 13010ff414cSEd Maste case CBOR_TYPE_MAP: { 13110ff414cSEd Maste struct cbor_pair *handle = cbor_map_handle(item); 13210ff414cSEd Maste for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; 13310ff414cSEd Maste i++, handle++) { 13410ff414cSEd Maste cbor_decref(&handle->key); 13510ff414cSEd Maste if (handle->value != NULL) cbor_decref(&handle->value); 13610ff414cSEd Maste } 137*5d3e7166SEd Maste _cbor_free(item->data); 13810ff414cSEd Maste break; 139*5d3e7166SEd Maste } 14010ff414cSEd Maste case CBOR_TYPE_TAG: { 14110ff414cSEd Maste if (item->metadata.tag_metadata.tagged_item != NULL) 14210ff414cSEd Maste cbor_decref(&item->metadata.tag_metadata.tagged_item); 143*5d3e7166SEd Maste _cbor_free(item->data); 14410ff414cSEd Maste break; 14510ff414cSEd Maste } 14610ff414cSEd Maste case CBOR_TYPE_FLOAT_CTRL: { 14710ff414cSEd Maste /* Floats have combined allocation */ 14810ff414cSEd Maste break; 14910ff414cSEd Maste } 15010ff414cSEd Maste } 151*5d3e7166SEd Maste _cbor_free(item); 15210ff414cSEd Maste *item_ref = NULL; 15310ff414cSEd Maste } 15410ff414cSEd Maste } 15510ff414cSEd Maste cbor_intermediate_decref(cbor_item_t * item)15610ff414cSEd Mastevoid cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); } 15710ff414cSEd Maste cbor_refcount(const cbor_item_t * item)15810ff414cSEd Mastesize_t cbor_refcount(const cbor_item_t *item) { return item->refcount; } 15910ff414cSEd Maste cbor_move(cbor_item_t * item)16010ff414cSEd Mastecbor_item_t *cbor_move(cbor_item_t *item) { 16110ff414cSEd Maste item->refcount--; 16210ff414cSEd Maste return item; 16310ff414cSEd Maste } 164