Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-only */
2 : : /*
3 : : * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4 : : */
5 : :
6 : : #include "bpfilter/dynbuf.h"
7 : :
8 : : #include "bpfilter/helper.h"
9 : : #include "bpfilter/logger.h"
10 : :
11 : 262 : static inline size_t _bf_round_next_power_of_2(size_t value)
12 : : {
13 : 262 : value--;
14 : 262 : value |= value >> 1;
15 : 262 : value |= value >> 2;
16 : 262 : value |= value >> 4;
17 : 262 : value |= value >> 8;
18 : 262 : value |= value >> 16;
19 : :
20 : 262 : return ++value;
21 : : }
22 : :
23 : 216 : void bf_dynbuf_clean(struct bf_dynbuf *buf)
24 : : {
25 : : bf_assert(buf);
26 : :
27 : 216 : buf->len = 0;
28 : 216 : buf->rem = 0;
29 : : freep((void *)&buf->data);
30 : 216 : }
31 : :
32 : 262 : static int _bf_dynbuf_grow(struct bf_dynbuf *buf, size_t req_cap)
33 : : {
34 : : size_t new_cap;
35 : : int r;
36 : :
37 : : bf_assert(buf);
38 : :
39 [ - + ]: 262 : if (req_cap == 0)
40 : : return 0;
41 : :
42 : 262 : new_cap = _bf_round_next_power_of_2(buf->len + buf->rem + req_cap);
43 : 262 : r = bf_realloc(&buf->data, new_cap);
44 [ + - ]: 262 : if (r)
45 : : return r;
46 : :
47 : 262 : buf->rem = new_cap - buf->len;
48 : :
49 : 262 : return 0;
50 : : }
51 : :
52 : 65801 : int bf_dynbuf_write(struct bf_dynbuf *buf, const void *data, size_t data_len)
53 : : {
54 : : int r;
55 : :
56 : : bf_assert(buf);
57 : : bf_assert(data);
58 : :
59 [ + + ]: 65801 : if (buf->rem < data_len) {
60 : 262 : r = _bf_dynbuf_grow(buf, data_len);
61 [ + - ]: 262 : if (r)
62 : : return r;
63 : : }
64 : :
65 : 65801 : memcpy(buf->data + buf->len, data, data_len);
66 : 65801 : buf->len += data_len;
67 : 65801 : buf->rem -= data_len;
68 : :
69 : 65801 : return 0;
70 : : }
71 : :
72 : 211 : void *bf_dynbuf_take(struct bf_dynbuf *buf)
73 : : {
74 : : bf_assert(buf);
75 : :
76 : 211 : buf->len = 0;
77 : 211 : buf->rem = 0;
78 : :
79 : 211 : return TAKE_PTR(buf->data);
80 : : }
|