xref: /openbmc/libpldm/tests/msgbuf.hpp (revision 7a8d932bc3cd30a0869b2e5cfd38c1b87019cffb)
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