1*10ff414cSEd Maste /* 2*10ff414cSEd Maste * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 3*10ff414cSEd Maste * 4*10ff414cSEd Maste * libcbor is free software; you can redistribute it and/or modify 5*10ff414cSEd Maste * it under the terms of the MIT license. See LICENSE for details. 6*10ff414cSEd Maste */ 7*10ff414cSEd Maste 8*10ff414cSEd Maste #include "cbor/common.h" 9*10ff414cSEd Maste #include "arrays.h" 10*10ff414cSEd Maste #include "bytestrings.h" 11*10ff414cSEd Maste #include "data.h" 12*10ff414cSEd Maste #include "floats_ctrls.h" 13*10ff414cSEd Maste #include "ints.h" 14*10ff414cSEd Maste #include "maps.h" 15*10ff414cSEd Maste #include "strings.h" 16*10ff414cSEd Maste #include "tags.h" 17*10ff414cSEd Maste 18*10ff414cSEd Maste bool cbor_isa_uint(const cbor_item_t *item) { 19*10ff414cSEd Maste return item->type == CBOR_TYPE_UINT; 20*10ff414cSEd Maste } 21*10ff414cSEd Maste 22*10ff414cSEd Maste bool cbor_isa_negint(const cbor_item_t *item) { 23*10ff414cSEd Maste return item->type == CBOR_TYPE_NEGINT; 24*10ff414cSEd Maste } 25*10ff414cSEd Maste 26*10ff414cSEd Maste bool cbor_isa_bytestring(const cbor_item_t *item) { 27*10ff414cSEd Maste return item->type == CBOR_TYPE_BYTESTRING; 28*10ff414cSEd Maste } 29*10ff414cSEd Maste 30*10ff414cSEd Maste bool cbor_isa_string(const cbor_item_t *item) { 31*10ff414cSEd Maste return item->type == CBOR_TYPE_STRING; 32*10ff414cSEd Maste } 33*10ff414cSEd Maste 34*10ff414cSEd Maste bool cbor_isa_array(const cbor_item_t *item) { 35*10ff414cSEd Maste return item->type == CBOR_TYPE_ARRAY; 36*10ff414cSEd Maste } 37*10ff414cSEd Maste 38*10ff414cSEd Maste bool cbor_isa_map(const cbor_item_t *item) { 39*10ff414cSEd Maste return item->type == CBOR_TYPE_MAP; 40*10ff414cSEd Maste } 41*10ff414cSEd Maste 42*10ff414cSEd Maste bool cbor_isa_tag(const cbor_item_t *item) { 43*10ff414cSEd Maste return item->type == CBOR_TYPE_TAG; 44*10ff414cSEd Maste } 45*10ff414cSEd Maste 46*10ff414cSEd Maste bool cbor_isa_float_ctrl(const cbor_item_t *item) { 47*10ff414cSEd Maste return item->type == CBOR_TYPE_FLOAT_CTRL; 48*10ff414cSEd Maste } 49*10ff414cSEd Maste 50*10ff414cSEd Maste cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; } 51*10ff414cSEd Maste 52*10ff414cSEd Maste bool cbor_is_int(const cbor_item_t *item) { 53*10ff414cSEd Maste return cbor_isa_uint(item) || cbor_isa_negint(item); 54*10ff414cSEd Maste } 55*10ff414cSEd Maste 56*10ff414cSEd Maste bool cbor_is_bool(const cbor_item_t *item) { 57*10ff414cSEd Maste return cbor_isa_float_ctrl(item) && 58*10ff414cSEd Maste (cbor_ctrl_value(item) == CBOR_CTRL_FALSE || 59*10ff414cSEd Maste cbor_ctrl_value(item) == CBOR_CTRL_TRUE); 60*10ff414cSEd Maste } 61*10ff414cSEd Maste 62*10ff414cSEd Maste bool cbor_is_null(const cbor_item_t *item) { 63*10ff414cSEd Maste return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL; 64*10ff414cSEd Maste } 65*10ff414cSEd Maste 66*10ff414cSEd Maste bool cbor_is_undef(const cbor_item_t *item) { 67*10ff414cSEd Maste return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF; 68*10ff414cSEd Maste } 69*10ff414cSEd Maste 70*10ff414cSEd Maste bool cbor_is_float(const cbor_item_t *item) { 71*10ff414cSEd Maste return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item); 72*10ff414cSEd Maste } 73*10ff414cSEd Maste 74*10ff414cSEd Maste cbor_item_t *cbor_incref(cbor_item_t *item) { 75*10ff414cSEd Maste item->refcount++; 76*10ff414cSEd Maste return item; 77*10ff414cSEd Maste } 78*10ff414cSEd Maste 79*10ff414cSEd Maste void cbor_decref(cbor_item_t **item_ref) { 80*10ff414cSEd Maste cbor_item_t *item = *item_ref; 81*10ff414cSEd Maste assert(item->refcount > 0); 82*10ff414cSEd Maste if (--item->refcount == 0) { 83*10ff414cSEd Maste switch (item->type) { 84*10ff414cSEd Maste case CBOR_TYPE_UINT: 85*10ff414cSEd Maste /* Fallthrough */ 86*10ff414cSEd Maste case CBOR_TYPE_NEGINT: 87*10ff414cSEd Maste /* Combined allocation, freeing the item suffices */ 88*10ff414cSEd Maste { break; } 89*10ff414cSEd Maste case CBOR_TYPE_BYTESTRING: { 90*10ff414cSEd Maste if (cbor_bytestring_is_definite(item)) { 91*10ff414cSEd Maste _CBOR_FREE(item->data); 92*10ff414cSEd Maste } else { 93*10ff414cSEd Maste /* We need to decref all chunks */ 94*10ff414cSEd Maste cbor_item_t **handle = cbor_bytestring_chunks_handle(item); 95*10ff414cSEd Maste for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) 96*10ff414cSEd Maste cbor_decref(&handle[i]); 97*10ff414cSEd Maste _CBOR_FREE( 98*10ff414cSEd Maste ((struct cbor_indefinite_string_data *)item->data)->chunks); 99*10ff414cSEd Maste _CBOR_FREE(item->data); 100*10ff414cSEd Maste } 101*10ff414cSEd Maste break; 102*10ff414cSEd Maste } 103*10ff414cSEd Maste case CBOR_TYPE_STRING: { 104*10ff414cSEd Maste if (cbor_string_is_definite(item)) { 105*10ff414cSEd Maste _CBOR_FREE(item->data); 106*10ff414cSEd Maste } else { 107*10ff414cSEd Maste /* We need to decref all chunks */ 108*10ff414cSEd Maste cbor_item_t **handle = cbor_string_chunks_handle(item); 109*10ff414cSEd Maste for (size_t i = 0; i < cbor_string_chunk_count(item); i++) 110*10ff414cSEd Maste cbor_decref(&handle[i]); 111*10ff414cSEd Maste _CBOR_FREE( 112*10ff414cSEd Maste ((struct cbor_indefinite_string_data *)item->data)->chunks); 113*10ff414cSEd Maste _CBOR_FREE(item->data); 114*10ff414cSEd Maste } 115*10ff414cSEd Maste break; 116*10ff414cSEd Maste } 117*10ff414cSEd Maste case CBOR_TYPE_ARRAY: { 118*10ff414cSEd Maste /* Get all items and decref them */ 119*10ff414cSEd Maste cbor_item_t **handle = cbor_array_handle(item); 120*10ff414cSEd Maste size_t size = cbor_array_size(item); 121*10ff414cSEd Maste for (size_t i = 0; i < size; i++) 122*10ff414cSEd Maste if (handle[i] != NULL) cbor_decref(&handle[i]); 123*10ff414cSEd Maste _CBOR_FREE(item->data); 124*10ff414cSEd Maste break; 125*10ff414cSEd Maste } 126*10ff414cSEd Maste case CBOR_TYPE_MAP: { 127*10ff414cSEd Maste struct cbor_pair *handle = cbor_map_handle(item); 128*10ff414cSEd Maste for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; 129*10ff414cSEd Maste i++, handle++) { 130*10ff414cSEd Maste cbor_decref(&handle->key); 131*10ff414cSEd Maste if (handle->value != NULL) cbor_decref(&handle->value); 132*10ff414cSEd Maste } 133*10ff414cSEd Maste _CBOR_FREE(item->data); 134*10ff414cSEd Maste break; 135*10ff414cSEd Maste }; 136*10ff414cSEd Maste case CBOR_TYPE_TAG: { 137*10ff414cSEd Maste if (item->metadata.tag_metadata.tagged_item != NULL) 138*10ff414cSEd Maste cbor_decref(&item->metadata.tag_metadata.tagged_item); 139*10ff414cSEd Maste _CBOR_FREE(item->data); 140*10ff414cSEd Maste break; 141*10ff414cSEd Maste } 142*10ff414cSEd Maste case CBOR_TYPE_FLOAT_CTRL: { 143*10ff414cSEd Maste /* Floats have combined allocation */ 144*10ff414cSEd Maste break; 145*10ff414cSEd Maste } 146*10ff414cSEd Maste } 147*10ff414cSEd Maste _CBOR_FREE(item); 148*10ff414cSEd Maste // TODO 149*10ff414cSEd Maste *item_ref = NULL; 150*10ff414cSEd Maste } 151*10ff414cSEd Maste } 152*10ff414cSEd Maste 153*10ff414cSEd Maste void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); } 154*10ff414cSEd Maste 155*10ff414cSEd Maste size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; } 156*10ff414cSEd Maste 157*10ff414cSEd Maste cbor_item_t *cbor_move(cbor_item_t *item) { 158*10ff414cSEd Maste item->refcount--; 159*10ff414cSEd Maste return item; 160*10ff414cSEd Maste } 161