L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ipc_array
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
4 *
5 * License: see LICENSE.spdx (in this directory or the directories above)
6 */
7#pragma once
8
9#include "types"
10#include "ipc_basics"
11#include "ipc_types"
12
13namespace L4 { namespace Ipc L4_EXPORT {
14
16typedef unsigned short Array_len_default;
17
27template< typename ELEM_TYPE, typename LEN_TYPE = Array_len_default >
29{
30 typedef ELEM_TYPE *ptr_type;
31 typedef LEN_TYPE len_type;
32
33 len_type length;
34 ptr_type data;
35 Array_ref() = default;
36 Array_ref(len_type length, ptr_type data)
37 : length(length), data(data)
38 {}
39
40 template<typename X> struct Non_const
41 { typedef Array_ref<X, LEN_TYPE> type; };
42
43 template<typename X> struct Non_const<X const>
44 { typedef Array_ref<X, LEN_TYPE> type; };
45
46 Array_ref(typename Non_const<ELEM_TYPE>::type const &other)
47 : length(other.length), data(other.data)
48 {}
49
50 Array_ref &operator = (typename Non_const<ELEM_TYPE>::type const &other)
51 {
52 this->length = other.length;
53 this->data = other.data;
54 return *this;
55 }
56};
57
80template<typename ELEM_TYPE, typename LEN_TYPE = Array_len_default>
81struct Array : Array_ref<ELEM_TYPE , LEN_TYPE>
82{
84 Array() {}
86 Array(LEN_TYPE length, ELEM_TYPE *data)
87 : Array_ref<ELEM_TYPE, LEN_TYPE>(length, data)
88 {}
89
90 template<typename X> struct Non_const
91 { typedef Array<X, LEN_TYPE> type; };
92
93 template<typename X> struct Non_const<X const>
94 { typedef Array<X, LEN_TYPE> type; };
95
97 Array(typename Non_const<ELEM_TYPE>::type const &other)
98 : Array_ref<ELEM_TYPE, LEN_TYPE>(other.length, other.data)
99 {}
100
101 Array &operator = (typename Non_const<ELEM_TYPE>::type const &other)
102 {
103 this->length = other.length;
104 this->data = other.data;
105 return *this;
106 }
107};
108
122template< typename ELEM_TYPE,
123 typename LEN_TYPE = Array_len_default,
124 LEN_TYPE MAX = (L4_UTCB_GENERIC_DATA_SIZE *
125 sizeof(l4_umword_t)) / sizeof(ELEM_TYPE) >
127{
128 typedef Array_ref<ELEM_TYPE, LEN_TYPE> array;
129 typedef Array_ref<ELEM_TYPE const, LEN_TYPE> const_array;
130
132 ELEM_TYPE data[MAX];
134 LEN_TYPE length;
135
137 void copy_in(const_array a)
138 {
139 length = a.length;
140 if (length > MAX)
141 length = MAX;
142
143 for (LEN_TYPE i = 0; i < length; ++i)
144 data[i] = a.data[i];
145 }
146
148 Array_in_buf(const_array a) { copy_in(a); }
150 Array_in_buf(array a) { copy_in(a); }
151};
152
153// implementation details for transmission
154namespace Msg {
155
157template<typename A, typename LEN>
158struct Elem< Array<A, LEN> >
159{
164 typedef svr_type svr_arg_type;
165 enum { Is_optional = false };
166};
167
169template<typename A, typename LEN>
170struct Elem< Array<A, LEN> & >
171{
178 enum { Is_optional = false };
179};
180
182template<typename A, typename LEN>
183struct Elem< Array_ref<A, LEN> & >
184{
191 enum { Is_optional = false };
192};
193
194template<typename A> struct Class<Array<A> > : Class<A>::type {};
195template<typename A> struct Class<Array_ref<A> > : Class<A>::type {};
196
197namespace Detail {
198
199template<typename A, typename LEN, typename ARRAY, bool REF>
200struct Clnt_val_ops_d_in : Clnt_noops<ARRAY>
201{
202 using Clnt_noops<ARRAY>::to_msg;
203 static int to_msg(char *msg, unsigned offset, unsigned limit,
204 ARRAY a, Dir_in, Cls_data)
205 {
206 offset = align_to<LEN>(offset);
207 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
208 return -L4_EMSGTOOLONG;
209 *reinterpret_cast<LEN *>(msg + offset) = a.length;
210 offset = align_to<A>(offset + sizeof(LEN));
211 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
212 return -L4_EMSGTOOLONG;
213 typedef typename L4::Types::Remove_const<A>::type elem_type;
214 elem_type *data = reinterpret_cast<elem_type*>(msg + offset);
215
216 // we do not correctly handle overlaps
217 if (!REF || data != a.data)
218 {
219 for (LEN i = 0; i < a.length; ++i)
220 data[i] = a.data[i];
221 }
222
223 return offset + a.length * sizeof(A);
224 }
225};
226} // namespace Detail
227
228template<typename A, typename LEN>
229struct Clnt_val_ops<Array<A, LEN>, Dir_in, Cls_data> :
230 Detail::Clnt_val_ops_d_in<A, LEN, Array<A, LEN>, false> {};
231
232template<typename A, typename LEN>
233struct Clnt_val_ops<Array_ref<A, LEN>, Dir_in, Cls_data> :
234 Detail::Clnt_val_ops_d_in<A, LEN, Array_ref<A, LEN>, true> {};
235
236template<typename A, typename LEN, typename CLASS>
237struct Svr_val_ops< Array_ref<A, LEN>, Dir_in, CLASS >
238: Svr_noops< Array_ref<A, LEN> >
239{
240 typedef Array_ref<A, LEN> svr_type;
241
242 using Svr_noops<svr_type>::to_svr;
243 static int to_svr(char *msg, unsigned offset, unsigned limit,
244 svr_type &a, Dir_in, Cls_data)
245 {
246 offset = align_to<LEN>(offset);
247 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
248 return -L4_EMSGTOOSHORT;
249 a.length = *reinterpret_cast<LEN *>(msg + offset);
250 offset = align_to<A>(offset + sizeof(LEN));
251 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
252 return -L4_EMSGTOOSHORT;
253 a.data = reinterpret_cast<A*>(msg + offset);
254 return offset + a.length * sizeof(A);
255 }
256};
257
258template<typename A, typename LEN>
259struct Svr_xmit< Array<A, LEN> > : Svr_xmit< Array_ref<A, LEN> > {};
260
261template<typename A, typename LEN>
262struct Clnt_val_ops<Array<A, LEN>, Dir_out, Cls_data> : Clnt_noops<Array<A, LEN> >
263{
264 typedef Array<A, LEN> type;
265
266 using Clnt_noops<type>::from_msg;
267 static int from_msg(char *msg, unsigned offset, unsigned limit, long,
268 type &a, Dir_out, Cls_data)
269 {
270 offset = align_to<LEN>(offset);
271 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
272 return -L4_EMSGTOOSHORT;
273
274 LEN l = *reinterpret_cast<LEN *>(msg + offset);
275
276 offset = align_to<A>(offset + sizeof(LEN));
277 if (L4_UNLIKELY(!check_size<A>(offset, limit, l)))
278 return -L4_EMSGTOOSHORT;
279
280 A *data = reinterpret_cast<A*>(msg + offset);
281
282 if (l > a.length)
283 l = a.length;
284 else
285 a.length = l;
286
287 for (unsigned i = 0; i < l; ++i)
288 a.data[i] = data[i];
289
290 return offset + l * sizeof(A);
291 };
292};
293
294template<typename A, typename LEN>
295struct Clnt_val_ops<Array_ref<A, LEN>, Dir_out, Cls_data> :
296 Clnt_noops<Array_ref<A, LEN> >
297{
298 typedef Array_ref<A, LEN> type;
299
300 using Clnt_noops<type>::from_msg;
301 static int from_msg(char *msg, unsigned offset, unsigned limit, long,
302 type &a, Dir_out, Cls_data)
303 {
304 offset = align_to<LEN>(offset);
305 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
306 return -L4_EMSGTOOSHORT;
307
308 LEN l = *reinterpret_cast<LEN *>(msg + offset);
309
310 offset = align_to<A>(offset + sizeof(LEN));
311 if (L4_UNLIKELY(!check_size<A>(offset, limit, l)))
312 return -L4_EMSGTOOSHORT;
313
314 a.data = reinterpret_cast<A*>(msg + offset);
315 a.length = l;
316 return offset + l * sizeof(A);
317 };
318};
319
320template<typename A, typename LEN, typename CLASS>
321struct Svr_val_ops<Array_ref<A, LEN>, Dir_out, CLASS> :
322 Svr_noops<Array_ref<typename L4::Types::Remove_const<A>::type, LEN> &>
323{
324 typedef typename L4::Types::Remove_const<A>::type elem_type;
325 typedef Array_ref<elem_type, LEN> &svr_type;
326
327 using Svr_noops<svr_type>::to_svr;
328 static int to_svr(char *msg, unsigned offset, unsigned limit,
329 svr_type a, Dir_out, Cls_data)
330 {
331 offset = align_to<LEN>(offset);
332 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
333 return -L4_EMSGTOOLONG;
334
335 offset = align_to<A>(offset + sizeof(LEN));
336 a.data = reinterpret_cast<elem_type *>(msg + offset);
337 a.length = (limit-offset) / sizeof(A);
338 return offset;
339 }
340
341 using Svr_noops<svr_type>::from_svr;
342 static int from_svr(char *msg, unsigned offset, unsigned limit, long,
343 svr_type a, Dir_out, Cls_data)
344 {
345 offset = align_to<LEN>(offset);
346 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
347 return -L4_EMSGTOOLONG;
348
349 *reinterpret_cast<LEN *>(msg + offset) = a.length;
350
351 offset = align_to<A>(offset + sizeof(LEN));
352 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
353 return -L4_EMSGTOOLONG;
354
355 return offset + a.length * sizeof(A);
356 }
357};
358
359template<typename A, typename LEN>
360struct Svr_xmit<Array<A, LEN> &> : Svr_xmit<Array_ref<A, LEN> &> {};
361
362// Pointer to array is not implemented.
363template<typename A, typename LEN>
364struct Is_valid_rpc_type< Array_ref<A, LEN> *> : L4::Types::False {};
365
366// Optional input arrays are not implemented.
367template<typename A, typename LEN>
368struct Is_valid_rpc_type< Opt<Array_ref<A, LEN> > > : L4::Types::False {};
369
370} // namespace Msg
371
372}}
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
@ L4_EMSGTOOLONG
Message too long.
Definition err.h:57
@ L4_EMSGTOOSHORT
Message too short.
Definition err.h:56
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:275
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:210
unsigned short Array_len_default
Default type for passing length of an array.
Definition ipc_array:16
L4 low-level kernel interface.
Server-side copy in buffer for Array.
Definition ipc_array:127
LEN_TYPE length
The length of the array.
Definition ipc_array:134
void copy_in(const_array a)
copy in data from a source array
Definition ipc_array:137
Array_in_buf(array a)
Make Array_in_buf from a non-const array.
Definition ipc_array:150
Array_in_buf(const_array a)
Make Array_in_buf from a const array.
Definition ipc_array:148
Array reference data type for arrays located in the message.
Definition ipc_array:29
Array data type for dynamically sized arrays in RPCs.
Definition ipc_array:82
Array()
Make array.
Definition ipc_array:84
Array(LEN_TYPE length, ELEM_TYPE *data)
Make array from length and data pointer.
Definition ipc_array:86
Array(typename Non_const< ELEM_TYPE >::type const &other)
Make a const array from a non-const array.
Definition ipc_array:97
Array_ref< A, LEN > svr_type
Array_ref<> at the server side.
Definition ipc_array:163
Array< A, LEN > arg_type
Array<> as argument at the interface.
Definition ipc_array:161
Array_ref< A, LEN > svr_type
Array_ref<> as server storage type.
Definition ipc_array:175
svr_type & svr_arg_type
Array_ref<> & at the server side.
Definition ipc_array:177
Array< A, LEN > & arg_type
Array<> & at the interface.
Definition ipc_array:173
Array_ref< typename L4::Types::Remove_const< A >::type, LEN > svr_type
Array_ref<> as server storage.
Definition ipc_array:188
svr_type & svr_arg_type
Array_ref<> & as server argument.
Definition ipc_array:190
Array_ref< A, LEN > & arg_type
Array_ref<> at the interface.
Definition ipc_array:186
False meta value.
Definition types:296