]> git.proxmox.com Git - mirror_frr.git/blame - nhrpd/zbuf.h
Merge pull request #12933 from Orange-OpenSource/link_state
[mirror_frr.git] / nhrpd / zbuf.h
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
2fb975da
TT
2/* Stream/packet buffer API
3 * Copyright (c) 2014-2015 Timo Teräs
2fb975da
TT
4 */
5
6#ifndef ZBUF_H
7#define ZBUF_H
8
9#include <stdint.h>
10#include <string.h>
11#include <endian.h>
12#include <sys/types.h>
13
f9aa07b1
DL
14#include "typesafe.h"
15
16PREDECL_DLIST(zbuf_queue);
2fb975da
TT
17
18struct zbuf {
f9aa07b1 19 struct zbuf_queue_item queue_entry;
2fb975da
TT
20 unsigned allocated : 1;
21 unsigned error : 1;
22 uint8_t *buf, *end;
23 uint8_t *head, *tail;
24};
25
f9aa07b1
DL
26DECLARE_DLIST(zbuf_queue, struct zbuf, queue_entry);
27
2fb975da 28struct zbuf_queue {
f9aa07b1 29 struct zbuf_queue_head queue_head;
2fb975da
TT
30};
31
32struct zbuf *zbuf_alloc(size_t size);
33void zbuf_init(struct zbuf *zb, void *buf, size_t len, size_t datalen);
34void zbuf_free(struct zbuf *zb);
35
36static inline size_t zbuf_size(struct zbuf *zb)
37{
38 return zb->end - zb->buf;
39}
40
41static inline size_t zbuf_used(struct zbuf *zb)
42{
43 return zb->tail - zb->head;
44}
45
46static inline size_t zbuf_tailroom(struct zbuf *zb)
47{
48 return zb->end - zb->tail;
49}
50
51static inline size_t zbuf_headroom(struct zbuf *zb)
52{
53 return zb->head - zb->buf;
54}
55
56void zbuf_reset(struct zbuf *zb);
57void zbuf_reset_head(struct zbuf *zb, void *ptr);
58ssize_t zbuf_read(struct zbuf *zb, int fd, size_t maxlen);
59ssize_t zbuf_write(struct zbuf *zb, int fd);
60ssize_t zbuf_recv(struct zbuf *zb, int fd);
61ssize_t zbuf_send(struct zbuf *zb, int fd);
62
63static inline void zbuf_set_rerror(struct zbuf *zb)
64{
65 zb->error = 1;
66 zb->head = zb->tail;
67}
68
69static inline void zbuf_set_werror(struct zbuf *zb)
70{
71 zb->error = 1;
72 zb->tail = zb->end;
73}
74
75static inline void *__zbuf_pull(struct zbuf *zb, size_t size, int error)
76{
77 void *head = zb->head;
78 if (size > zbuf_used(zb)) {
996c9314
LB
79 if (error)
80 zbuf_set_rerror(zb);
2fb975da
TT
81 return NULL;
82 }
83 zb->head += size;
84 return head;
85}
86
87#define zbuf_pull(zb, type) ((type *)__zbuf_pull(zb, sizeof(type), 1))
c4efd0f4 88#define zbuf_pulln(zb, sz) (__zbuf_pull(zb, sz, 1))
2fb975da 89#define zbuf_may_pull(zb, type) ((type *)__zbuf_pull(zb, sizeof(type), 0))
c4efd0f4 90#define zbuf_may_pulln(zb, sz) (__zbuf_pull(zb, sz, 0))
2fb975da
TT
91
92void *zbuf_may_pull_until(struct zbuf *zb, const char *sep, struct zbuf *msg);
93
94static inline void zbuf_get(struct zbuf *zb, void *dst, size_t len)
95{
96 void *src = zbuf_pulln(zb, len);
996c9314
LB
97 if (src)
98 memcpy(dst, src, len);
2fb975da
TT
99}
100
101static inline uint8_t zbuf_get8(struct zbuf *zb)
102{
103 uint8_t *src = zbuf_pull(zb, uint8_t);
996c9314
LB
104 if (src)
105 return *src;
2fb975da
TT
106 return 0;
107}
108
109static inline uint32_t zbuf_get32(struct zbuf *zb)
110{
111 struct unaligned32 {
112 uint32_t value;
113 } __attribute__((packed));
114
115 struct unaligned32 *v = zbuf_pull(zb, struct unaligned32);
996c9314
LB
116 if (v)
117 return v->value;
2fb975da
TT
118 return 0;
119}
120
121static inline uint16_t zbuf_get_be16(struct zbuf *zb)
122{
123 struct unaligned16 {
124 uint16_t value;
125 } __attribute__((packed));
126
127 struct unaligned16 *v = zbuf_pull(zb, struct unaligned16);
996c9314
LB
128 if (v)
129 return be16toh(v->value);
2fb975da
TT
130 return 0;
131}
132
133static inline uint32_t zbuf_get_be32(struct zbuf *zb)
134{
135 return be32toh(zbuf_get32(zb));
136}
137
138static inline void *__zbuf_push(struct zbuf *zb, size_t size, int error)
139{
140 void *tail = zb->tail;
141 if (size > zbuf_tailroom(zb)) {
996c9314
LB
142 if (error)
143 zbuf_set_werror(zb);
2fb975da
TT
144 return NULL;
145 }
146 zb->tail += size;
147 return tail;
148}
149
150#define zbuf_push(zb, type) ((type *)__zbuf_push(zb, sizeof(type), 1))
c4efd0f4 151#define zbuf_pushn(zb, sz) (__zbuf_push(zb, sz, 1))
2fb975da 152#define zbuf_may_push(zb, type) ((type *)__zbuf_may_push(zb, sizeof(type), 0))
c4efd0f4 153#define zbuf_may_pushn(zb, sz) (__zbuf_push(zb, sz, 0))
2fb975da
TT
154
155static inline void zbuf_put(struct zbuf *zb, const void *src, size_t len)
156{
157 void *dst = zbuf_pushn(zb, len);
996c9314
LB
158 if (dst)
159 memcpy(dst, src, len);
2fb975da
TT
160}
161
162static inline void zbuf_put8(struct zbuf *zb, uint8_t val)
163{
164 uint8_t *dst = zbuf_push(zb, uint8_t);
996c9314
LB
165 if (dst)
166 *dst = val;
2fb975da
TT
167}
168
169static inline void zbuf_put_be16(struct zbuf *zb, uint16_t val)
170{
171 struct unaligned16 {
172 uint16_t value;
173 } __attribute__((packed));
174
175 struct unaligned16 *v = zbuf_push(zb, struct unaligned16);
996c9314
LB
176 if (v)
177 v->value = htobe16(val);
2fb975da
TT
178}
179
180static inline void zbuf_put_be32(struct zbuf *zb, uint32_t val)
181{
182 struct unaligned32 {
183 uint32_t value;
184 } __attribute__((packed));
185
186 struct unaligned32 *v = zbuf_push(zb, struct unaligned32);
996c9314
LB
187 if (v)
188 v->value = htobe32(val);
2fb975da
TT
189}
190
191void zbuf_copy(struct zbuf *zb, struct zbuf *src, size_t len);
d5dc926f 192void zbuf_copy_peek(struct zbuf *zdst, struct zbuf *zsrc, size_t len);
2fb975da
TT
193
194void zbufq_init(struct zbuf_queue *);
195void zbufq_reset(struct zbuf_queue *);
196void zbufq_queue(struct zbuf_queue *, struct zbuf *);
197int zbufq_write(struct zbuf_queue *, int);
198
199#endif