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 0 : static inline size_t _bf_round_next_power_of_2(size_t value)
12 : {
13 0 : value--;
14 0 : value |= value >> 1;
15 0 : value |= value >> 2;
16 0 : value |= value >> 4;
17 0 : value |= value >> 8;
18 0 : value |= value >> 16;
19 :
20 0 : return ++value;
21 : }
22 :
23 0 : void bf_dynbuf_clean(struct bf_dynbuf *buf)
24 : {
25 0 : bf_assert(buf);
26 :
27 0 : buf->len = 0;
28 0 : buf->rem = 0;
29 : freep((void *)&buf->data);
30 0 : }
31 :
32 0 : static int _bf_dynbuf_grow(struct bf_dynbuf *buf, size_t req_cap)
33 : {
34 : size_t new_cap;
35 : int r;
36 :
37 0 : bf_assert(buf);
38 :
39 0 : if (req_cap == 0)
40 : return 0;
41 :
42 0 : new_cap = _bf_round_next_power_of_2(buf->len + buf->rem + req_cap);
43 0 : r = bf_realloc(&buf->data, new_cap);
44 0 : if (r)
45 : return r;
46 :
47 0 : buf->rem = new_cap - buf->len;
48 :
49 0 : return 0;
50 : }
51 :
52 0 : int bf_dynbuf_write(struct bf_dynbuf *buf, const void *data, size_t data_len)
53 : {
54 : int r;
55 :
56 0 : bf_assert(buf);
57 0 : bf_assert(data);
58 :
59 0 : if (buf->rem < data_len) {
60 0 : r = _bf_dynbuf_grow(buf, data_len);
61 0 : if (r)
62 : return r;
63 : }
64 :
65 0 : memcpy(buf->data + buf->len, data, data_len);
66 0 : buf->len += data_len;
67 0 : buf->rem -= data_len;
68 :
69 0 : return 0;
70 : }
71 :
72 0 : void *bf_dynbuf_take(struct bf_dynbuf *buf)
73 : {
74 0 : bf_assert(buf);
75 :
76 0 : buf->len = 0;
77 0 : buf->rem = 0;
78 :
79 0 : return TAKE_PTR(buf->data);
80 : }
|