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 {
230 for (LEN i = 0; i < a.length; ++i)
231 data[i] = a.data[i];
232 }
233
234 return offset + a.length * sizeof(A);
235 }
236};
237} // namespace Detail
238
239template<typename A, typename LEN>
240struct Clnt_val_ops<Array<A, LEN>, Dir_in, Cls_data> :
241 Detail::Clnt_val_ops_d_in<A, LEN, Array<A, LEN>, false> {};
242
243template<typename A, typename LEN>
244struct Clnt_val_ops<Array_ref<A, LEN>, Dir_in, Cls_data> :
245 Detail::Clnt_val_ops_d_in<A, LEN, Array_ref<A, LEN>, true> {};
246
247template<typename A, typename LEN, typename CLASS>
248struct Svr_val_ops< Array_ref<A, LEN>, Dir_in, CLASS >
249: Svr_noops< Array_ref<A, LEN> >
250{
251 typedef Array_ref<A, LEN> svr_type;
252
253 using Svr_noops<svr_type>::to_svr;
254 static int to_svr(char *msg, unsigned offset, unsigned limit,
255 svr_type &a, Dir_in, Cls_data)
256 {
257 offset = align_to<LEN>(offset);
258 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
259 return -L4_EMSGTOOSHORT;
260 a.length = *reinterpret_cast<LEN *>(msg + offset);
261 offset = align_to<A>(offset + sizeof(LEN));
262 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
263 return -L4_EMSGTOOSHORT;
264 a.data = reinterpret_cast<A*>(msg + offset);
265 return offset + a.length * sizeof(A);
266 }
267};
268
269template<typename A, typename LEN>
270struct Svr_xmit< Array<A, LEN> > : Svr_xmit< Array_ref<A, LEN> > {};
271
272template<typename A, typename LEN>
273struct Clnt_val_ops<Array<A, LEN>, Dir_out, Cls_data> : Clnt_noops<Array<A, LEN> >
274{
275 typedef Array<A, LEN> type;
276
277 using Clnt_noops<type>::from_msg;
278 static int from_msg(char *msg, unsigned offset, unsigned limit, long,
279 type &a, Dir_out, Cls_data)
280 {
281 offset = align_to<LEN>(offset);
282 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
283 return -L4_EMSGTOOSHORT;
284
285 LEN l = *reinterpret_cast<LEN *>(msg + offset);
286
287 offset = align_to<A>(offset + sizeof(LEN));
288 if (L4_UNLIKELY(!check_size<A>(offset, limit, l)))
289 return -L4_EMSGTOOSHORT;
290
291 A *data = reinterpret_cast<A*>(msg + offset);
292
293 if (l > a.length)
294 l = a.length;
295 else
296 a.length = l;
297
298 for (unsigned i = 0; i < l; ++i)
299 a.data[i] = data[i];
300
301 return offset + l * sizeof(A);
302 };
303};
304
305template<typename A, typename LEN>
306struct Clnt_val_ops<Array_ref<A, LEN>, Dir_out, Cls_data> :
307 Clnt_noops<Array_ref<A, LEN> >
308{
309 typedef Array_ref<A, LEN> type;
310
311 using Clnt_noops<type>::from_msg;
312 static int from_msg(char *msg, unsigned offset, unsigned limit, long,
313 type &a, Dir_out, Cls_data)
314 {
315 offset = align_to<LEN>(offset);
316 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
317 return -L4_EMSGTOOSHORT;
318
319 LEN l = *reinterpret_cast<LEN *>(msg + offset);
320
321 offset = align_to<A>(offset + sizeof(LEN));
322 if (L4_UNLIKELY(!check_size<A>(offset, limit, l)))
323 return -L4_EMSGTOOSHORT;
324
325 a.data = reinterpret_cast<A*>(msg + offset);
326 a.length = l;
327 return offset + l * sizeof(A);
328 };
329};
330
331template<typename A, typename LEN, typename CLASS>
332struct Svr_val_ops<Array_ref<A, LEN>, Dir_out, CLASS> :
333 Svr_noops<Array_ref<typename L4::Types::Remove_const<A>::type, LEN> &>
334{
335 typedef typename L4::Types::Remove_const<A>::type elem_type;
336 typedef Array_ref<elem_type, LEN> &svr_type;
337
338 using Svr_noops<svr_type>::to_svr;
339 static int to_svr(char *msg, unsigned offset, unsigned limit,
340 svr_type a, Dir_out, Cls_data)
341 {
342 offset = align_to<LEN>(offset);
343 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
344 return -L4_EMSGTOOLONG;
345
346 offset = align_to<A>(offset + sizeof(LEN));
347 a.data = reinterpret_cast<elem_type *>(msg + offset);
348 a.length = (limit-offset) / sizeof(A);
349 return offset;
350 }
351
352 using Svr_noops<svr_type>::from_svr;
353 static int from_svr(char *msg, unsigned offset, unsigned limit, long,
354 svr_type a, Dir_out, Cls_data)
355 {
356 offset = align_to<LEN>(offset);
357 if (L4_UNLIKELY(!check_size<LEN>(offset, limit)))
358 return -L4_EMSGTOOLONG;
359
360 *reinterpret_cast<LEN *>(msg + offset) = a.length;
361
362 offset = align_to<A>(offset + sizeof(LEN));
363 if (L4_UNLIKELY(!check_size<A>(offset, limit, a.length)))
364 return -L4_EMSGTOOLONG;
365
366 return offset + a.length * sizeof(A);
367 }
368};
369
370template<typename A, typename LEN>
371struct Svr_xmit<Array<A, LEN> &> : Svr_xmit<Array_ref<A, LEN> &> {};
372
373// Pointer to array is not implemented.
374template<typename A, typename LEN>
375struct Is_valid_rpc_type< Array_ref<A, LEN> *> : L4::Types::False {};
376
377// Optional input arrays are not implemented.
378template<typename A, typename LEN>
379struct Is_valid_rpc_type< Opt<Array_ref<A, LEN> > > : L4::Types::False {};
380
381} // namespace Msg
382
383}}
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:51
@ L4_EMSGTOOLONG
Message too long.
Definition err.h:68
@ L4_EMSGTOOSHORT
Message too short.
Definition err.h:67
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:296
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:231
unsigned short Array_len_default
Default type for passing length of an array.
Definition ipc_array:27
L4 low-level kernel interface.
Definition io_regblock.h:19
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:307