19#pragma GCC system_header
26template<
typename T,
template <
typename X>
class B >
27struct Generic_va_type : B<T>
29 enum { Id = B<T>::Id };
31 typedef T
const &Ret_value;
34 static Ret_value value(
void const *d)
35 {
return *
reinterpret_cast<Value
const *
>(d); }
37 static void const *addr_of(Value
const &v) {
return &v; }
39 static unsigned size(
void const *) {
return sizeof(T); }
41 static L4_varg_type unsigned_id()
43 return static_cast<L4_varg_type
>(Id & ~L4_VARG_TYPE_SIGN);
46 static L4_varg_type signed_id()
48 return static_cast<L4_varg_type
>(Id | L4_VARG_TYPE_SIGN);
51 static L4_varg_type id()
53 return static_cast<L4_varg_type
>(Id);
57template<
typename T >
struct Va_type_id;
58template<>
struct Va_type_id<
l4_umword_t> {
enum { Id = L4_VARG_TYPE_UMWORD }; };
59template<>
struct Va_type_id<
l4_mword_t> {
enum { Id = L4_VARG_TYPE_MWORD }; };
60template<>
struct Va_type_id<
l4_fpage_t> {
enum { Id = L4_VARG_TYPE_FPAGE }; };
61template<>
struct Va_type_id<void> {
enum { Id = L4_VARG_TYPE_NIL }; };
62template<>
struct Va_type_id<char const *> {
enum { Id = L4_VARG_TYPE_STRING }; };
64template<
typename T >
struct Va_type;
66template<>
struct Va_type<
l4_umword_t> : Generic_va_type<l4_umword_t, Va_type_id> {};
67template<>
struct Va_type<
l4_mword_t> : Generic_va_type<l4_mword_t, Va_type_id> {};
68template<>
struct Va_type<
l4_fpage_t> : Generic_va_type<l4_fpage_t, Va_type_id> {};
70template<>
struct Va_type<void>
72 typedef void Ret_value;
75 static void const *addr_of(
void) {
return 0; }
77 static void value(
void const *) {}
78 static L4_varg_type id() {
return L4_VARG_TYPE_NIL; }
79 static unsigned size(
void const *) {
return 0; }
82template<>
struct Va_type<char const *>
84 typedef char const *Ret_value;
85 typedef char const *Value;
87 static void const *addr_of(Value v) {
return v; }
89 static L4_varg_type id() {
return L4_VARG_TYPE_STRING; }
90 static unsigned size(
void const *s)
92 char const *_s =
reinterpret_cast<char const *
>(s);
101 static Ret_value value(
void const *d) {
return static_cast<char const *
>(d); }
110 enum { Direct_data = 0x8000 };
120 L4_varg_type
type()
const {
return static_cast<L4_varg_type
>(_tag & 0xff); }
125 unsigned length()
const {
return _tag >> 16; }
127 Tag tag()
const {
return _tag & ~Direct_data; }
131 void data(
char const *d) { _d = d; }
136 if (_tag & Direct_data)
138 union T {
char const *d;
char v[
sizeof(
char const *)]; };
139 return reinterpret_cast<T
const *
>(&_d)->v;
145#if __cplusplus >= 201103L
152 Varg(L4_varg_type t,
void const *v,
int len)
153 : _tag(t | (static_cast<
l4_mword_t>(len) << 16)),
154 _d(static_cast<char const *>(v))
157 static Varg nil() {
return Varg(L4_VARG_TYPE_NIL, 0, 0); }
165 template<
typename V >
166 typename Va_type<V>::Ret_value
value()
const
168 if (_tag & Direct_data)
170 union X {
char const *d; V v; };
171 return reinterpret_cast<X
const &
>(_d).v;
174 return Va_type<V>::value(_d);
179 template<
typename T >
180 bool is_of()
const {
return Va_type<T>::id() ==
type(); }
183 bool is_nil()
const {
return is_of<void>(); }
187 {
return (
type() & ~L4_VARG_TYPE_SIGN) == L4_VARG_TYPE_UMWORD; }
195 template<
typename T >
201 *v = this->value<T>();
206 template<
typename T >
209 typedef Va_type<T> Vt;
210 _tag = Vt::id() | (Vt::size(d) << 16);
211 _d =
static_cast<char const *
>(d);
218 static_assert(
sizeof(T) <=
sizeof(
char const *),
"direct Varg value too big");
219 typedef Va_type<T> Vt;
220 _tag = Vt::id() | (
sizeof(T) << 16) | Direct_data;
221 union X {
char const *d; T v; };
222 reinterpret_cast<X &
>(_d).v = val;
226 template<
typename T>
explicit
232 template<
typename T>
explicit
233 Varg(T
data,
typename L4::Types::Enable_if<
sizeof(T) <=
sizeof(
char const *),
bool>
::type =
true)
234 { set_direct_value<T>(
data); }
239class Varg_t :
public Varg
242 typedef typename Va_type<T>::Value Value;
243 explicit Varg_t(Value v) :
Varg()
244 { _data = v; set_value<T>(Va_type<T>::addr_of(_data)); }
250template<
unsigned MAX = L4_UTCB_GENERIC_DATA_SIZE>
275 using Mp = M
const *;
280 Mp next_arg(
Varg const &a)
const
282 return _c + 1 + (Msg::align_to<M>(a.
length()) /
sizeof(M));
287 Iter_state() : _c(
nullptr), _e(
nullptr) {}
290 Iter_state(Mp c, Mp e) : _c(c), _e(e)
295 {
return _c && _c < _e; }
298 Mp begin()
const {
return _c; }
301 Mp end()
const {
return _e; }
314 a.
data(
reinterpret_cast<char const *
>(&_c[1]));
323 bool operator == (Iter_state
const &o)
const
324 {
return _c == o._c; }
327 bool operator != (Iter_state
const &o)
const
328 {
return _c != o._c; }
364 explicit operator bool ()
const
389 bool operator == (
Iterator const &o)
const
392 bool operator != (Iterator
const &o)
const
421template<
unsigned MAX>
435 unsigned c = r._s.end() - rs;
436 for (
unsigned i = 0; i < c; ++i)
439 this->_s = Iter_state(data, data + c);
445template<>
struct Elem<Varg const *>
447 typedef Varg
const *arg_type;
448 typedef Varg_list_ref svr_type;
449 typedef Varg_list_ref svr_arg_type;
450 enum { Is_optional =
false };
458template<>
struct Direction<Varg const *> : Dir_in {};
459template<>
struct Class<Varg const *> : Cls_data {};
461template<
typename DIR,
typename CLASS>
462struct Clnt_val_ops<Varg, DIR, CLASS>;
465struct Clnt_val_ops<Varg, Dir_in, Cls_data> :
466 Clnt_noops<Varg const &>
468 using Clnt_noops<Varg
const &>::to_msg;
469 static int to_msg(
char *msg,
unsigned offs,
unsigned limit,
470 Varg
const &a, Dir_in, Cls_data)
472 for (Varg
const *i = &a; i->tag(); ++i)
474 offs = align_to<l4_umword_t>(offs);
475 if (
L4_UNLIKELY(!check_size<l4_umword_t>(offs, limit)))
477 *
reinterpret_cast<l4_umword_t*
>(msg + offs) = i->tag();
479 if (
L4_UNLIKELY(!check_size<char>(offs, limit, i->length())))
481 char const *d = i->data();
482 for (
unsigned x = 0; x < i->length(); ++x)
491struct Svr_val_ops<Varg_list_ref, Dir_in, Cls_data> :
492 Svr_noops<Varg_list_ref>
494 using Svr_noops<Varg_list_ref>::to_svr;
495 static int to_svr(
char *msg,
unsigned offset,
unsigned limit,
496 Varg_list_ref &a, Dir_in, Cls_data)
498 unsigned start = align_to<l4_umword_t>(offset);
500 for (offs = start; offs < limit;)
502 unsigned noffs = align_to<l4_umword_t>(offs);
503 if (
L4_UNLIKELY(!check_size<l4_umword_t>(noffs, limit)))
508 arg.tag(*
reinterpret_cast<l4_umword_t*
>(msg + offs));
515 if (
L4_UNLIKELY(!check_size<char>(offs, limit, arg.length())))
517 offs += arg.length();
520 a = Varg_list_ref(msg + start, msg + align_to<l4_umword_t>(offs));
Iterator(Iter_state const &s)
Create a new iterator.
bool equals(Iterator const &o) const
check for equality
Iterator & operator++()
increment iterator to the next arg
Varg operator*() const
dereference the iterator, get Varg
List of variable-sized RPC parameters as received by the server.
Iterator begin() const
Returns an interator to the first Varg.
Varg pop_front()
Get the next parameter in the list.
Varg next()
Get the next parameter in the list.
Varg_list_ref(void const *start, void const *end)
Create a parameter list over a given memory region.
Iterator end() const
Returns the end of the list.
Varg_list_ref()=default
Create an empty parameter list.
Self-contained list of variable-sized RPC parameters.
Varg_list(Varg_list_ref const &r)
Create a parameter list as a copy from a referencing list.
Variably sized RPC argument.
Varg(char const *data)
Make Varg from null-terminated string.
char const * data() const
Varg(L4_varg_type t, void const *v, int len)
Make an indirect varg.
Varg()=default
Make uninitialized Varg.
l4_umword_t Tag
The data type for the tag.
Va_type< V >::Ret_value value() const
void set_direct_value(T val, typename L4::Types::Enable_if< sizeof(T)<=sizeof(char const *), bool >::type=true)
Set to directly stored value of type T.
unsigned length() const
Get the size of the RPC argument.
void set_value(void const *d)
Set to indirect value of type T.
L4_varg_type type() const
void tag(Tag tag)
Set Varg tag (usually from message)
Varg(T const *data)
Make Varg from indirect value (pointer)
Varg(T data, typename L4::Types::Enable_if< sizeof(T)<=sizeof(char const *), bool >::type=true)
Make Varg from direct value.
void data(char const *d)
Set Varg to indirect data value (usually in UTCB)
bool get_value(typename Va_type< T >::Value *v) const
Get the value of the Varg as type T.
unsigned long l4_umword_t
Unsigned machine word.
signed long l4_mword_t
Signed machine word.
@ L4_EMSGTOOLONG
Message too long.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
#define L4_DEPRECATED(s)
Mark symbol deprecated.
L4 low-level kernel interface.