libcbor 0.12.0
libcbor is a C library for parsing and generating CBOR, the general-purpose schema-less binary data format.
Loading...
Searching...
No Matches
arrays.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3 *
4 * libcbor is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8#include "arrays.h"
9#include <string.h>
11
12size_t cbor_array_size(const cbor_item_t* item) {
14 return item->metadata.array_metadata.end_ptr;
15}
16
17size_t cbor_array_allocated(const cbor_item_t* item) {
20}
21
22cbor_item_t* cbor_array_get(const cbor_item_t* item, size_t index) {
23 return cbor_incref(((cbor_item_t**)item->data)[index]);
24}
25
26bool cbor_array_set(cbor_item_t* item, size_t index, cbor_item_t* value) {
27 if (index == item->metadata.array_metadata.end_ptr) {
28 return cbor_array_push(item, value);
29 } else if (index < item->metadata.array_metadata.end_ptr) {
30 return cbor_array_replace(item, index, value);
31 } else {
32 return false;
33 }
34}
35
36bool cbor_array_replace(cbor_item_t* item, size_t index, cbor_item_t* value) {
37 if (index >= item->metadata.array_metadata.end_ptr) return false;
38 /* We cannot use cbor_array_get as that would increase the refcount */
39 cbor_intermediate_decref(((cbor_item_t**)item->data)[index]);
40 ((cbor_item_t**)item->data)[index] = cbor_incref(value);
41 return true;
42}
43
46 struct _cbor_array_metadata* metadata =
47 (struct _cbor_array_metadata*)&array->metadata;
48 cbor_item_t** data = (cbor_item_t**)array->data;
49 if (cbor_array_is_definite(array)) {
50 /* Do not reallocate definite arrays */
51 if (metadata->end_ptr >= metadata->allocated) {
52 return false;
53 }
54 data[metadata->end_ptr++] = pushee;
55 } else {
56 /* Exponential realloc */
57 if (metadata->end_ptr >= metadata->allocated) {
58 // Check for overflows first
59 if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) {
60 return false;
61 }
62
63 size_t new_allocation = metadata->allocated == 0
64 ? 1
65 : CBOR_BUFFER_GROWTH * metadata->allocated;
66
67 unsigned char* new_data = _cbor_realloc_multiple(
68 array->data, sizeof(cbor_item_t*), new_allocation);
69 if (new_data == NULL) {
70 return false;
71 }
72
73 array->data = new_data;
74 metadata->allocated = new_allocation;
75 }
76 ((cbor_item_t**)array->data)[metadata->end_ptr++] = pushee;
77 }
78 cbor_incref(pushee);
79 return true;
80}
81
86
91
94 return (cbor_item_t**)item->data;
95}
96
98 cbor_item_t* item = _cbor_malloc(sizeof(cbor_item_t));
99 _CBOR_NOTNULL(item);
100 cbor_item_t** data = _cbor_alloc_multiple(sizeof(cbor_item_t*), size);
101 _CBOR_DEPENDENT_NOTNULL(item, data);
102
103 for (size_t i = 0; i < size; i++) {
104 data[i] = NULL;
105 }
106
107 *item = (cbor_item_t){
108 .refcount = 1,
109 .type = CBOR_TYPE_ARRAY,
110 .metadata = {.array_metadata = {.type = _CBOR_METADATA_DEFINITE,
111 .allocated = size,
112 .end_ptr = 0}},
113 .data = (unsigned char*)data};
114
115 return item;
116}
117
119 cbor_item_t* item = _cbor_malloc(sizeof(cbor_item_t));
120 _CBOR_NOTNULL(item);
121
122 *item = (cbor_item_t){
123 .refcount = 1,
124 .type = CBOR_TYPE_ARRAY,
125 .metadata = {.array_metadata = {.type = _CBOR_METADATA_INDEFINITE,
126 .allocated = 0,
127 .end_ptr = 0}},
128 .data = NULL /* Can be safely realloc-ed */
129 };
130 return item;
131}
_cbor_malloc_t _cbor_malloc
Definition allocators.c:10
bool cbor_array_is_indefinite(const cbor_item_t *item)
Is the array indefinite?
Definition arrays.c:87
bool cbor_array_set(cbor_item_t *item, size_t index, cbor_item_t *value)
Set item by index.
Definition arrays.c:26
bool cbor_array_replace(cbor_item_t *item, size_t index, cbor_item_t *value)
Replace item at an index.
Definition arrays.c:36
size_t cbor_array_size(const cbor_item_t *item)
Get the number of members.
Definition arrays.c:12
size_t cbor_array_allocated(const cbor_item_t *item)
Get the size of the allocated storage.
Definition arrays.c:17
cbor_item_t ** cbor_array_handle(const cbor_item_t *item)
Get the array contents.
Definition arrays.c:92
bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee)
Append to the end.
Definition arrays.c:44
bool cbor_array_is_definite(const cbor_item_t *item)
Is the array definite?
Definition arrays.c:82
cbor_item_t * cbor_new_definite_array(size_t size)
Create new definite array.
Definition arrays.c:97
cbor_item_t * cbor_array_get(const cbor_item_t *item, size_t index)
Get item by index.
Definition arrays.c:22
cbor_item_t * cbor_new_indefinite_array(void)
Create new indefinite array.
Definition arrays.c:118
void cbor_intermediate_decref(cbor_item_t *item)
Decreases the item's reference count by one, deallocating the item if needed.
Definition common.c:154
bool cbor_isa_array(const cbor_item_t *item)
Does the item have the appropriate major type?
Definition common.c:38
cbor_item_t * cbor_incref(cbor_item_t *item)
Increases the item's reference count by one.
Definition common.c:78
#define _CBOR_DEPENDENT_NOTNULL(cbor_item, pointer)
Definition common.h:119
#define _CBOR_NOTNULL(cbor_item)
Definition common.h:111
#define CBOR_ASSERT(e)
Definition common.h:73
@ CBOR_TYPE_ARRAY
4 - arrays
Definition data.h:33
@ _CBOR_METADATA_DEFINITE
Definition data.h:78
@ _CBOR_METADATA_INDEFINITE
Definition data.h:79
void * _cbor_realloc_multiple(void *pointer, size_t item_size, size_t item_count)
Overflow-proof contiguous array reallocation.
void * _cbor_alloc_multiple(size_t item_size, size_t item_count)
Overflow-proof contiguous array allocation.
bool _cbor_safe_to_multiply(size_t a, size_t b)
Can a and b be multiplied without overflowing size_t?
Arrays specific metadata.
Definition data.h:116
_cbor_dst_metadata type
Definition data.h:119
The item handle.
Definition data.h:171
unsigned char * data
Raw data block - interpretation depends on metadata.
Definition data.h:179
union cbor_item_metadata metadata
Discriminated by type.
Definition data.h:173
struct _cbor_array_metadata array_metadata
Definition data.h:164