clang-tidy: add Chrome-inspired checks
[lttng-tools.git] / src / common / dynamic-buffer.cpp
CommitLineData
5966417e 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5966417e 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
5966417e 5 *
5966417e
JG
6 */
7
c9e313bc 8#include <common/buffer-view.hpp>
28ab034a 9#include <common/dynamic-buffer.hpp>
c9e313bc 10#include <common/utils.hpp>
5966417e 11
df94ef0f
JG
12/*
13 * Round to (upper) power of two, val is returned if it already is a power of
14 * two.
15 */
28ab034a 16static size_t round_to_power_of_2(size_t val)
5966417e 17{
5966417e 18 size_t rounded;
12aacdf6 19 const int order = utils_get_count_order_u64(val);
5966417e 20
a0377dfe 21 LTTNG_ASSERT(order >= 0);
5966417e 22 rounded = (1ULL << order);
a0377dfe 23 LTTNG_ASSERT(rounded >= val);
5966417e
JG
24
25 return rounded;
26}
27
28void lttng_dynamic_buffer_init(struct lttng_dynamic_buffer *buffer)
29{
a0377dfe 30 LTTNG_ASSERT(buffer);
5966417e
JG
31 memset(buffer, 0, sizeof(*buffer));
32}
33
28ab034a 34int lttng_dynamic_buffer_append(struct lttng_dynamic_buffer *buffer, const void *buf, size_t len)
5966417e
JG
35{
36 int ret = 0;
37
38 if (!buffer || (!buf && len)) {
39 ret = -1;
40 goto end;
41 }
42
43 if (len == 0) {
44 /* Not an error, no-op. */
45 goto end;
46 }
47
a0377dfe 48 LTTNG_ASSERT(buffer->_capacity >= buffer->size);
63557623 49 if (buffer->_capacity < (len + buffer->size)) {
28ab034a
JG
50 ret = lttng_dynamic_buffer_set_capacity(
51 buffer, buffer->_capacity + (len - (buffer->_capacity - buffer->size)));
5966417e
JG
52 if (ret) {
53 goto end;
54 }
55 }
56
57 memcpy(buffer->data + buffer->size, buf, len);
58 buffer->size += len;
59end:
60 return ret;
61}
62
63int lttng_dynamic_buffer_append_buffer(struct lttng_dynamic_buffer *dst_buffer,
28ab034a 64 const struct lttng_dynamic_buffer *src_buffer)
5966417e
JG
65{
66 int ret;
67
68 if (!dst_buffer || !src_buffer) {
69 ret = -1;
70 goto end;
71 }
72
28ab034a 73 ret = lttng_dynamic_buffer_append(dst_buffer, src_buffer->data, src_buffer->size);
5966417e
JG
74end:
75 return ret;
76}
77
fbd55aae 78int lttng_dynamic_buffer_append_view(struct lttng_dynamic_buffer *buffer,
28ab034a 79 const struct lttng_buffer_view *src)
fbd55aae
JG
80{
81 int ret;
82
83 if (!buffer || !src) {
84 ret = -1;
85 goto end;
86 }
87
28ab034a 88 ret = lttng_dynamic_buffer_append(buffer, src->data, src->size);
fbd55aae
JG
89end:
90 return ret;
91}
92
28ab034a 93int lttng_dynamic_buffer_set_size(struct lttng_dynamic_buffer *buffer, size_t new_size)
5966417e
JG
94{
95 int ret = 0;
96
97 if (!buffer) {
98 goto end;
99 }
100
101 if (new_size == buffer->size) {
102 goto end;
103 }
104
63557623 105 if (new_size > buffer->_capacity) {
5966417e
JG
106 ret = lttng_dynamic_buffer_set_capacity(buffer, new_size);
107 if (ret) {
108 goto end;
109 }
1c6def05 110
6ee96b4d 111 memset(buffer->data + buffer->size, 0, new_size - buffer->size);
5966417e
JG
112 } else if (new_size > buffer->size) {
113 memset(buffer->data + buffer->size, 0, new_size - buffer->size);
114 } else {
115 /*
116 * Shrinking size. There is no need to zero-out the newly
117 * released memory as it will either be:
118 * - overwritten by lttng_dynamic_buffer_append,
119 * - expanded later, which will zero-out the memory
120 *
121 * Users of external APIs are encouraged to set the buffer's
122 * size _before_ making such calls.
123 */
124 }
12aacdf6 125
5966417e
JG
126 buffer->size = new_size;
127end:
128 return ret;
129}
130
28ab034a 131int lttng_dynamic_buffer_set_capacity(struct lttng_dynamic_buffer *buffer, size_t demanded_capacity)
5966417e
JG
132{
133 int ret = 0;
fc804d0f 134 void *new_buf;
28ab034a 135 size_t new_capacity = demanded_capacity ? round_to_power_of_2(demanded_capacity) : 0;
5966417e 136
fc804d0f
JG
137 if (!buffer || demanded_capacity < buffer->size) {
138 /*
139 * Shrinking a buffer's size by changing its capacity is
140 * unsupported.
141 */
5966417e
JG
142 ret = -1;
143 goto end;
144 }
145
63557623 146 if (new_capacity == buffer->_capacity) {
5966417e
JG
147 goto end;
148 }
149
fc804d0f
JG
150 /* Memory is initialized by the size increases. */
151 new_buf = realloc(buffer->data, new_capacity);
152 if (!new_buf) {
153 ret = -1;
154 goto end;
5966417e 155 }
12aacdf6 156
a6bc4ca9 157 buffer->data = (char *) new_buf;
63557623 158 buffer->_capacity = new_capacity;
5966417e
JG
159end:
160 return ret;
161}
162
163/* Release any memory used by the dynamic buffer. */
164void lttng_dynamic_buffer_reset(struct lttng_dynamic_buffer *buffer)
165{
166 if (!buffer) {
167 return;
168 }
12aacdf6 169
5966417e 170 buffer->size = 0;
63557623 171 buffer->_capacity = 0;
5966417e 172 free(buffer->data);
cd9adb8b 173 buffer->data = nullptr;
5966417e 174}
201bd415 175
28ab034a 176size_t lttng_dynamic_buffer_get_capacity_left(struct lttng_dynamic_buffer *buffer)
201bd415
JG
177{
178 if (!buffer) {
179 return 0;
180 }
12aacdf6 181
201bd415
JG
182 return buffer->_capacity - buffer->size;
183}
This page took 0.056725 seconds and 4 git commands to generate.