1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #ifndef PLDM_MSGBUF_HPP
3 #define PLDM_MSGBUF_HPP
4
5 #include <libpldm/compiler.h>
6
7 #include "msgbuf/core.h"
8
9 /*
10 * Use the C++ Function Overload to keep pldm_msgbuf related function consistent
11 * and to produce compile-time errors when the wrong pldm_msgbuf type is passed.
12 *
13 * Previously we cast away `const` in `pldm_msgbuf_init_error()`, which was a
14 * hack. Instead, introduce:
15 * - pldm_msgbuf_ro: read-only buffer with a `const` cursor
16 * - pldm_msgbuf_rw: read-write buffer with a non-const cursor
17 *
18 * `pldm_msgbuf_ro` is used by decode APIs to extract payloads into PLDM
19 * structures. `pldm_msgbuf_rw` is used by encode APIs to insert payloads from
20 * PLDM structures.
21 */
22
23 #include <cstdint>
24 #include <cstdio>
25 #include <type_traits>
26
27 // NOLINTBEGIN(bugprone-macro-parentheses)
28 // NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
29 #define PLDM__MSGBUF_DEFINE_P(name, mode) \
30 struct pldm_msgbuf_##mode _##name LIBPLDM_CC_CLEANUP( \
31 pldm__msgbuf_##mode##_cleanup) = {NULL, INTMAX_MIN}; \
32 auto* name = &(_##name)
33 // NOLINTEND(bugprone-macro-parentheses)
34
35 #define PLDM_MSGBUF_RO_DEFINE_P(name) PLDM__MSGBUF_DEFINE_P(name, ro)
36 #define PLDM_MSGBUF_RW_DEFINE_P(name) PLDM__MSGBUF_DEFINE_P(name, rw)
37
pldm_msgbuf_init_errno(struct pldm_msgbuf_ro * ctx,size_t minsize,const void * buf,size_t len)38 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_init_errno(struct pldm_msgbuf_ro* ctx,
39 size_t minsize,
40 const void* buf, size_t len)
41 {
42 return pldm_msgbuf_ro_init_errno(ctx, minsize, buf, len);
43 }
44
pldm_msgbuf_init_errno(struct pldm_msgbuf_rw * ctx,size_t minsize,const void * buf,size_t len)45 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_init_errno(struct pldm_msgbuf_rw* ctx,
46 size_t minsize,
47 const void* buf, size_t len)
48 {
49 return pldm_msgbuf_rw_init_errno(ctx, minsize, buf, len);
50 }
51
pldm_msgbuf_validate(struct pldm_msgbuf_ro * ctx)52 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_validate(struct pldm_msgbuf_ro* ctx)
53 {
54 return pldm_msgbuf_ro_validate(ctx);
55 }
56
pldm_msgbuf_validate(struct pldm_msgbuf_rw * ctx)57 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_validate(struct pldm_msgbuf_rw* ctx)
58 {
59 return pldm_msgbuf_rw_validate(ctx);
60 }
61
62 // NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
pldm__msgbuf_invalidate(struct pldm_msgbuf_ro * ctx)63 LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_invalidate(struct pldm_msgbuf_ro* ctx)
64 {
65 return pldm__msgbuf_ro_invalidate(ctx);
66 }
67
68 // NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
pldm__msgbuf_invalidate(struct pldm_msgbuf_rw * ctx)69 LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_invalidate(struct pldm_msgbuf_rw* ctx)
70 {
71 return pldm__msgbuf_rw_invalidate(ctx);
72 }
73
pldm_msgbuf_consumed(struct pldm_msgbuf_ro * ctx)74 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_consumed(struct pldm_msgbuf_ro* ctx)
75 {
76 return pldm_msgbuf_ro_consumed(ctx);
77 }
78
pldm_msgbuf_consumed(struct pldm_msgbuf_rw * ctx)79 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_consumed(struct pldm_msgbuf_rw* ctx)
80 {
81 return pldm_msgbuf_rw_consumed(ctx);
82 }
83
pldm_msgbuf_discard(struct pldm_msgbuf_ro * ctx,int error)84 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_discard(struct pldm_msgbuf_ro* ctx,
85 int error)
86 {
87 return pldm_msgbuf_ro_discard(ctx, error);
88 }
89
pldm_msgbuf_discard(struct pldm_msgbuf_rw * ctx,int error)90 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_discard(struct pldm_msgbuf_rw* ctx,
91 int error)
92 {
93 return pldm_msgbuf_rw_discard(ctx, error);
94 }
95
pldm_msgbuf_complete(struct pldm_msgbuf_ro * ctx)96 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_complete(struct pldm_msgbuf_ro* ctx)
97 {
98 return pldm_msgbuf_ro_complete(ctx);
99 }
100
pldm_msgbuf_complete(struct pldm_msgbuf_rw * ctx)101 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_complete(struct pldm_msgbuf_rw* ctx)
102 {
103 return pldm_msgbuf_rw_complete(ctx);
104 }
105
106 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_complete_consumed(struct pldm_msgbuf_ro * ctx)107 pldm_msgbuf_complete_consumed(struct pldm_msgbuf_ro* ctx)
108 {
109 return pldm_msgbuf_ro_complete_consumed(ctx);
110 }
111
112 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_complete_consumed(struct pldm_msgbuf_rw * ctx)113 pldm_msgbuf_complete_consumed(struct pldm_msgbuf_rw* ctx)
114 {
115 return pldm_msgbuf_rw_complete_consumed(ctx);
116 }
117
118 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_span_required(struct pldm_msgbuf_ro * ctx,size_t required,const void ** cursor)119 pldm_msgbuf_span_required(struct pldm_msgbuf_ro* ctx, size_t required,
120 const void** cursor)
121 {
122 return pldm_msgbuf_ro_span_required(ctx, required, cursor);
123 }
124
125 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_span_required(struct pldm_msgbuf_rw * ctx,size_t required,void ** cursor)126 pldm_msgbuf_span_required(struct pldm_msgbuf_rw* ctx, size_t required,
127 void** cursor)
128 {
129 return pldm_msgbuf_rw_span_required(ctx, required, cursor);
130 }
131
132 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_span_string_ascii(struct pldm_msgbuf_rw * ctx,void ** cursor,size_t * length)133 pldm_msgbuf_span_string_ascii(struct pldm_msgbuf_rw* ctx, void** cursor,
134 size_t* length)
135 {
136 return pldm_msgbuf_rw_span_string_ascii(ctx, cursor, length);
137 }
138
139 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_span_string_ascii(struct pldm_msgbuf_ro * ctx,const void ** cursor,size_t * length)140 pldm_msgbuf_span_string_ascii(struct pldm_msgbuf_ro* ctx,
141 const void** cursor, size_t* length)
142 {
143 return pldm_msgbuf_ro_span_string_ascii(ctx, cursor, length);
144 }
145
pldm_msgbuf_span_string_utf16(pldm_msgbuf_ro * ctx,const void ** cursor,size_t * length)146 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_string_utf16(pldm_msgbuf_ro* ctx,
147 const void** cursor,
148 size_t* length)
149 {
150 return pldm_msgbuf_ro_span_string_utf16(ctx, cursor, length);
151 }
152
pldm_msgbuf_span_string_utf16(pldm_msgbuf_rw * ctx,void ** cursor,size_t * length)153 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_string_utf16(pldm_msgbuf_rw* ctx,
154 void** cursor,
155 size_t* length)
156 {
157 return pldm_msgbuf_rw_span_string_utf16(ctx, cursor, length);
158 }
159
160 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_span_remaining(struct pldm_msgbuf_rw * ctx,void ** cursor,size_t * len)161 pldm_msgbuf_span_remaining(struct pldm_msgbuf_rw* ctx, void** cursor,
162 size_t* len)
163 {
164 return pldm_msgbuf_rw_span_remaining(ctx, cursor, len);
165 }
166
167 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_span_remaining(struct pldm_msgbuf_ro * ctx,const void ** cursor,size_t * len)168 pldm_msgbuf_span_remaining(struct pldm_msgbuf_ro* ctx, const void** cursor,
169 size_t* len)
170 {
171 return pldm_msgbuf_ro_span_remaining(ctx, cursor, len);
172 }
173
pldm_msgbuf_span_until(struct pldm_msgbuf_ro * ctx,size_t trailer,const void ** cursor,size_t * length)174 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_until(struct pldm_msgbuf_ro* ctx,
175 size_t trailer,
176 const void** cursor,
177 size_t* length)
178 {
179 return pldm_msgbuf_ro_span_until(ctx, trailer, cursor, length);
180 }
181
pldm_msgbuf_span_until(struct pldm_msgbuf_rw * ctx,size_t trailer,void ** cursor,size_t * length)182 LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_until(struct pldm_msgbuf_rw* ctx,
183 size_t trailer,
184 void** cursor,
185 size_t* length)
186 {
187 return pldm_msgbuf_rw_span_until(ctx, trailer, cursor, length);
188 }
189
190 #define pldm_msgbuf_extract_typecheck(ty, fn, dst, ...) \
191 pldm_msgbuf_typecheck_##ty<decltype(dst)>(__VA_ARGS__)
192
193 #define pldm_msgbuf_extract_uint8(ctx, dst) \
194 pldm_msgbuf_extract_typecheck(uint8_t, pldm__msgbuf_extract_uint8, dst, \
195 ctx, (void*)&(dst))
196
197 #define pldm_msgbuf_extract_int8(ctx, dst) \
198 pldm_msgbuf_extract_typecheck(int8_t, pldm__msgbuf_extract_int8, dst, ctx, \
199 (void*)&(dst))
200
201 #define pldm_msgbuf_extract_uint16(ctx, dst) \
202 pldm_msgbuf_extract_typecheck(uint16_t, pldm__msgbuf_extract_uint16, dst, \
203 ctx, (void*)&(dst))
204
205 #define pldm_msgbuf_extract_int16(ctx, dst) \
206 pldm_msgbuf_extract_typecheck(int16_t, pldm__msgbuf_extract_int16, dst, \
207 ctx, (void*)&(dst))
208
209 #define pldm_msgbuf_extract_uint32(ctx, dst) \
210 pldm_msgbuf_extract_typecheck(uint32_t, pldm__msgbuf_extract_uint32, dst, \
211 ctx, (void*)&(dst))
212
213 #define pldm_msgbuf_extract_int32(ctx, dst) \
214 pldm_msgbuf_extract_typecheck(int32_t, pldm__msgbuf_extract_int32, dst, \
215 ctx, (void*)&(dst))
216
217 #define pldm_msgbuf_extract_real32(ctx, dst) \
218 pldm_msgbuf_extract_typecheck(real32_t, pldm__msgbuf_extract_real32, dst, \
219 ctx, (void*)&(dst))
220
221 template <typename T>
222 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_uint8_t(struct pldm_msgbuf_ro * ctx,void * buf)223 pldm_msgbuf_typecheck_uint8_t(struct pldm_msgbuf_ro* ctx, void* buf)
224 {
225 static_assert(std::is_same<uint8_t, T>::value);
226 return pldm__msgbuf_extract_uint8(ctx, buf);
227 }
228
229 template <typename T>
230 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_int8_t(struct pldm_msgbuf_ro * ctx,void * buf)231 pldm_msgbuf_typecheck_int8_t(struct pldm_msgbuf_ro* ctx, void* buf)
232 {
233 static_assert(std::is_same<int8_t, T>::value);
234 return pldm__msgbuf_extract_int8(ctx, buf);
235 }
236
237 template <typename T>
238 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_uint16_t(struct pldm_msgbuf_ro * ctx,void * buf)239 pldm_msgbuf_typecheck_uint16_t(struct pldm_msgbuf_ro* ctx, void* buf)
240 {
241 static_assert(std::is_same<uint16_t, T>::value);
242 return pldm__msgbuf_extract_uint16(ctx, buf);
243 }
244
245 template <typename T>
246 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_int16_t(struct pldm_msgbuf_ro * ctx,void * buf)247 pldm_msgbuf_typecheck_int16_t(struct pldm_msgbuf_ro* ctx, void* buf)
248 {
249 static_assert(std::is_same<int16_t, T>::value);
250 return pldm__msgbuf_extract_int16(ctx, buf);
251 }
252
253 template <typename T>
254 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_uint32_t(struct pldm_msgbuf_ro * ctx,void * buf)255 pldm_msgbuf_typecheck_uint32_t(struct pldm_msgbuf_ro* ctx, void* buf)
256 {
257 static_assert(std::is_same<uint32_t, T>::value);
258 return pldm__msgbuf_extract_uint32(ctx, buf);
259 }
260
261 template <typename T>
262 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_int32_t(struct pldm_msgbuf_ro * ctx,void * buf)263 pldm_msgbuf_typecheck_int32_t(struct pldm_msgbuf_ro* ctx, void* buf)
264 {
265 static_assert(std::is_same<int32_t, T>::value);
266 return pldm__msgbuf_extract_int32(ctx, buf);
267 }
268
269 template <typename T>
270 LIBPLDM_CC_ALWAYS_INLINE int
pldm_msgbuf_typecheck_real32_t(struct pldm_msgbuf_ro * ctx,void * buf)271 pldm_msgbuf_typecheck_real32_t(struct pldm_msgbuf_ro* ctx, void* buf)
272 {
273 static_assert(std::is_same<real32_t, T>::value);
274 return pldm__msgbuf_extract_real32(ctx, buf);
275 }
276
277 #endif /* BUF_HPP */
278