L4Re Operating System Framework – Interface and Usage Documentation
Loading...
Searching...
No Matches
ipc_array
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
4 *
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
8 *
9 * As a special exception, you may use this file as part of a free software
10 * library without restriction. Specifically, if other files instantiate
11 * templates or use macros or inline functions from this file, or you compile
12 * this file and link it with other files to produce an executable, this
13 * file does not by itself cause the resulting executable to be covered by
14 * the GNU General Public License. This exception does not however
15 * invalidate any other reasons why the executable file might be covered by
16 * the GNU General Public License.
17 */
18#pragma once
19
20#include "types"
21#include "ipc_basics"
22#include "ipc_types"
23
24namespace L4 { namespace Ipc L4_EXPORT {
25
27typedef unsigned short Array_len_default;
28
38template< typename ELEM_TYPE, typename LEN_TYPE = Array_len_default >
40{
41 typedef ELEM_TYPE *ptr_type;
42 typedef LEN_TYPE len_type;
43
44 len_type length;
45 ptr_type data;
46 Array_ref() = default;
47 Array_ref(len_type length, ptr_type data)
48 : length(length), data(data)
49 {}
50
51 template<typename X> struct Non_const
52 { typedef Array_ref<X, LEN_TYPE> type; };
53
54 template<typename X> struct Non_const<X const>
55 { typedef Array_ref<X, LEN_TYPE> type; };
56
57 Array_ref(typename Non_const<ELEM_TYPE>::type const &other)
58 : length(other.length), data(other.data)
59 {}
60
61 Array_ref &operator = (typename Non_const<ELEM_TYPE>::type const &other)
62 {
63 this->length = other.length;
64 this->data = other.data;
65 return *this;
66 }
67};
68
91template<typename ELEM_TYPE, typename LEN_TYPE = Array_len_default>
92struct Array : Array_ref<ELEM_TYPE , LEN_TYPE>
93{
95 Array() {}
97 Array(LEN_TYPE length, ELEM_TYPE *data)
98 : Array_ref<ELEM_TYPE, LEN_TYPE>(length, data)
99 {}
100
101 template<typename X> struct Non_const
102 { typedef Array<X, LEN_TYPE> type; };
103
104 template<typename X> struct Non_const<X const>
105 { typedef Array<X, LEN_TYPE> type; };
106
108 Array(typename Non_const<ELEM_TYPE>::type const &other)
109 : Array_ref<ELEM_TYPE, LEN_TYPE>(other.length, other.data)
110 {}
111
112 Array &operator = (typename Non_const<ELEM_TYPE>::type const &other)
113 {
114 this->length = other.length;
115 this->data = other.data;
116 return *this;
117 }
118};
119
133template< typename ELEM_TYPE,
134 typename LEN_TYPE = Array_len_default,
135 LEN_TYPE MAX = (L4_UTCB_GENERIC_DATA_SIZE *
136 sizeof(l4_umword_t)) / sizeof(ELEM_TYPE) >
138{
139 typedef Array_ref<ELEM_TYPE, LEN_TYPE> array;
140 typedef Array_ref<ELEM_TYPE const, LEN_TYPE> const_array;
141
143 ELEM_TYPE data[MAX];
145 LEN_TYPE length;
146
148 void copy_in(const_array a)
149 {
150 length = a.length;
151 if (length > MAX)
152 length = MAX;
153
154 for (LEN_TYPE i = 0; i < length; ++i)
155 data[i] = a.data[i];
156 }
157
159 Array_in_buf(const_array a) { copy_in(a); }
161 Array_in_buf(array a) { copy_in(a); }
162};
163
164// implementation details for transmission
165namespace Msg {
166
168template<typename A, typename LEN>
169struct Elem< Array<A, LEN> >
170{
175 typedef svr_type svr_arg_type;
176 enum { Is_optional = false };
177};
178
180template<typename A, typename LEN>
181struct Elem< Array<A, LEN> & >
182{
189 enum { Is_optional = false };
190};
191
193template<typename A, typename LEN>
194struct Elem< Array_ref<A, LEN> & >
195{
202 enum { Is_optional = false };
203};
204
205template<typename A> struct Class<Array<A> > : Class<A>::type {};
206template<typename A> struct Class<Array_ref<A> > : Class<A>::type {};
207
208namespace Detail {
209
210template<typename A, typename LEN, typename ARRAY, bool REF>
211struct Clnt_val_ops_d_in : Clnt_noops<ARRAY>
212{
213 using Clnt_noops<ARRAY>::to_msg;
214 static int to_msg(char *msg, unsigned offset, unsigned limit,
215 ARRAY a, Dir_in, Cls_data)
216 {
217 offset = align_to<LEN>(offset);
218 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
219 return -L4_EMSGTOOLONG;
220 *reinterpret_cast<LEN *>(msg + offset) = a.length;
221 offset = align_to<A>(offset + sizeof(LEN));
222 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
223 return -L4_EMSGTOOLONG;
224 typedef typename L4::Types::Remove_const<A>::type elem_type;
225 elem_type *data = reinterpret_cast<elem_type*>(msg + offset);
226
227 // we do not correctly handle overlaps
228 if (!REF || data != a.data)
229 for (LEN i = 0; i < a.length; ++i)
230 data[i] = a.data[i];
231
232 return offset + a.length * sizeof(A);
233 }
234};
235} // namespace Detail
236
237template<typename A, typename LEN>
238struct Clnt_val_ops<Array<A, LEN>, Dir_in, Cls_data> :
239 Detail::Clnt_val_ops_d_in<A, LEN, Array<A, LEN>, false> {};
240
241template<typename A, typename LEN>
242struct Clnt_val_ops<Array_ref<A, LEN>, Dir_in, Cls_data> :
243 Detail::Clnt_val_ops_d_in<A, LEN, Array_ref<A, LEN>, true> {};
244
245template<typename A, typename LEN, typename CLASS>
246struct Svr_val_ops< Array_ref<A, LEN>, Dir_in, CLASS >
247: Svr_noops< Array_ref<A, LEN> >
248{
249 typedef Array_ref<A, LEN> svr_type;
250
251 using Svr_noops<svr_type>::to_svr;
252 static int to_svr(char *msg, unsigned offset, unsigned limit,
253 svr_type &a, Dir_in, Cls_data)
254 {
255 offset = align_to<LEN>(offset);
256 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
257 return -L4_EMSGTOOSHORT;
258 a.length = *reinterpret_cast<LEN *>(msg + offset);
259 offset = align_to<A>(offset + sizeof(LEN));
260 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
261 return -L4_EMSGTOOSHORT;
262 a.data = reinterpret_cast<A*>(msg + offset);
263 return offset + a.length * sizeof(A);
264 }
265};
266
267template<typename A, typename LEN>
268struct Svr_xmit< Array<A, LEN> > : Svr_xmit< Array_ref<A, LEN> > {};
269
270template<typename A, typename LEN>
271struct Clnt_val_ops<Array<A, LEN>, Dir_out, Cls_data> : Clnt_noops<Array<A, LEN> >
272{
273 typedef Array<A, LEN> type;
274
275 using Clnt_noops<type>::from_msg;
276 static int from_msg(char *msg, unsigned offset, unsigned limit, long,
277 type &a, Dir_out, Cls_data)
278 {
279 offset = align_to<LEN>(offset);
280 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
281 return -L4_EMSGTOOSHORT;
282
283 LEN l = *reinterpret_cast<LEN *>(msg + offset);
284
285 offset = align_to<A>(offset + sizeof(LEN));
286 if (L4_UNLIKELY(!check_size<A>(offset, limit, l)))
287 return -L4_EMSGTOOSHORT;
288
289 A *data = reinterpret_cast<A*>(msg + offset);
290
291 if (l > a.length)
292 l = a.length;
293 else
294 a.length = l;
295
296 for (unsigned i = 0; i < l; ++i)
297 a.data[i] = data[i];
298
299 return offset + l * sizeof(A);
300 };
301};
302
303template<typename A, typename LEN>
304struct Clnt_val_ops<Array_ref<A, LEN>, Dir_out, Cls_data> :
305 Clnt_noops<Array_ref<A, LEN> >
306{
307 typedef Array_ref<A, LEN> type;
308
309 using Clnt_noops<type>::from_msg;
310 static int from_msg(char *msg, unsigned offset, unsigned limit, long,
311 type &a, Dir_out, Cls_data)
312 {
313 offset = align_to<LEN>(offset);
314 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
315 return -L4_EMSGTOOSHORT;
316
317 LEN l = *reinterpret_cast<LEN *>(msg + offset);
318
319 offset = align_to<A>(offset + sizeof(LEN));
320 if (L4_UNLIKELY(!check_size<A>(offset, limit, l)))
321 return -L4_EMSGTOOSHORT;
322
323 a.data = reinterpret_cast<A*>(msg + offset);
324 a.length = l;
325 return offset + l * sizeof(A);
326 };
327};
328
329template<typename A, typename LEN, typename CLASS>
330struct Svr_val_ops<Array_ref<A, LEN>, Dir_out, CLASS> :
331 Svr_noops<Array_ref<typename L4::Types::Remove_const<A>::type, LEN> &>
332{
333 typedef typename L4::Types::Remove_const<A>::type elem_type;
334 typedef Array_ref<elem_type, LEN> &svr_type;
335
336 using Svr_noops<svr_type>::to_svr;
337 static int to_svr(char *msg, unsigned offset, unsigned limit,
338 svr_type a, Dir_out, Cls_data)
339 {
340 offset = align_to<LEN>(offset);
341 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
342 return -L4_EMSGTOOLONG;
343
344 offset = align_to<A>(offset + sizeof(LEN));
345 a.data = reinterpret_cast<elem_type *>(msg + offset);
346 a.length = (limit-offset) / sizeof(A);
347 return offset;
348 }
349
350 using Svr_noops<svr_type>::from_svr;
351 static int from_svr(char *msg, unsigned offset, unsigned limit, long,
352 svr_type a, Dir_out, Cls_data)
353 {
354 offset = align_to<LEN>(offset);
355 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
356 return -L4_EMSGTOOLONG;
357
358 *reinterpret_cast<LEN *>(msg + offset) = a.length;
359
360 offset = align_to<A>(offset + sizeof(LEN));
361 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
362 return -L4_EMSGTOOLONG;
363
364 return offset + a.length * sizeof(A);
365 }
366};
367
368template<typename A, typename LEN>
369struct Svr_xmit<Array<A, LEN> &> : Svr_xmit<Array_ref<A, LEN> &> {};
370
371// Pointer to array is not implemented.
372template<typename A, typename LEN>
373struct Is_valid_rpc_type< Array_ref<A, LEN> *> : L4::Types::False {};
374
375// Optional input arrays are not implemented.
376template<typename A, typename LEN>
377struct Is_valid_rpc_type< Opt<Array_ref<A, LEN> > > : L4::Types::False {};
378
379} // namespace Msg
380
381}}
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:51
@ L4_EMSGTOOLONG
Message too long.
Definition err.h:67
@ L4_EMSGTOOSHORT
Message too short.
Definition err.h:66
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:285
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:221
unsigned short Array_len_default
Default type for passing length of an array.
Definition ipc_array:27
L4 low-level kernel interface.
Server-side copy in buffer for Array.
Definition ipc_array:138
LEN_TYPE length
The length of the array.
Definition ipc_array:145
void copy_in(const_array a)
copy in data from a source array
Definition ipc_array:148
Array_in_buf(array a)
Make Array_in_buf from a non-const array.
Definition ipc_array:161
Array_in_buf(const_array a)
Make Array_in_buf from a const array.
Definition ipc_array:159
Array reference data type for arrays located in the message.
Definition ipc_array:40
Array data type for dynamically sized arrays in RPCs.
Definition ipc_array:93
Array()
Make array.
Definition ipc_array:95
Array(LEN_TYPE length, ELEM_TYPE *data)
Make array from length and data pointer.
Definition ipc_array:97
Array(typename Non_const< ELEM_TYPE >::type const &other)
Make a const array from a non-const array.
Definition ipc_array:108
Array_ref< A, LEN > svr_type
Array_ref<> at the server side.
Definition ipc_array:174
Array< A, LEN > arg_type
Array<> as argument at the interface.
Definition ipc_array:172
Array_ref< A, LEN > svr_type
Array_ref<> as server storage type.
Definition ipc_array:186
svr_type & svr_arg_type
Array_ref<> & at the server side.
Definition ipc_array:188
Array< A, LEN > & arg_type
Array<> & at the interface.
Definition ipc_array:184
Array_ref< typename L4::Types::Remove_const< A >::type, LEN > svr_type
Array_ref<> as server storage.
Definition ipc_array:199
svr_type & svr_arg_type
Array_ref<> & as server argument.
Definition ipc_array:201
Array_ref< A, LEN > & arg_type
Array_ref<> at the interface.
Definition ipc_array:197
False meta value.
Definition types:308