Loading...
Searching...
No Matches
ipc_ret_array
// vi:set ft=cpp: -*- Mode: C++ -*-
/*
* (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "types"
#include "ipc_basics"
namespace L4 { namespace Ipc L4_EXPORT {
// ---------------------------------------------------------------
template<typename T> struct L4_EXPORT Ret_array
{
typedef T const **ptr_type;
T *value = nullptr;
unsigned max = 0;
Ret_array() {}
Ret_array(T *v, unsigned max) : value(v), max(max) {}
};
namespace Msg {
template<typename A> struct Elem< Ret_array<A> >
{
enum { Is_optional = false };
typedef Ret_array<A> type;
typedef typename type::ptr_type arg_type;
typedef type svr_type;
typedef type svr_arg_type;
};
template<typename A>
struct Is_valid_rpc_type<Ret_array<A> *> : L4::Types::False {};
template<typename A>
struct Is_valid_rpc_type<Ret_array<A> &> : L4::Types::False {};
template<typename A>
struct Is_valid_rpc_type<Ret_array<A> const &> : L4::Types::False {};
template<typename A>
struct Is_valid_rpc_type<Ret_array<A> const *> : L4::Types::False {};
template<typename A> struct Class< Ret_array<A> > : Class<A>::type {};
template<typename A> struct Direction< Ret_array<A> > : Dir_out {};
template<typename A, typename CLASS>
struct Clnt_val_ops<A const *, Dir_out, CLASS> : Clnt_noops<A const *>
{
using Clnt_noops<A const *>::from_msg;
static int from_msg(char *msg, unsigned offset, unsigned limit, long ret,
A const *&arg, Dir_out, Cls_data)
{
offset = align_to<A>(offset);
arg = reinterpret_cast<A const *>(msg + offset);
if (L4_UNLIKELY(!check_size<A>(offset, limit, ret)))
return -1;
return offset + ret * sizeof(A);
}
};
template<typename A, typename CLASS>
struct Svr_val_ops<Ret_array<A>, Dir_out, CLASS> :
Svr_noops<Ret_array<A> >
{
typedef Ret_array<A> ret_array;
using Svr_noops<ret_array>::from_svr;
static int from_svr(char *, unsigned offset, unsigned limit, long ret,
ret_array const &, Dir_out, CLASS)
{
offset = align_to<A>(offset);
if (L4_UNLIKELY(!check_size<A>(offset, limit, ret)))
return -1;
offset += sizeof(A) * ret;
return offset;
}
using Svr_noops<ret_array>::to_svr;
static int to_svr(char *msg, unsigned offset, unsigned limit,
ret_array &arg, Dir_out, CLASS)
{
// there can be actually no limit check here, as this
// is variably sized output array
// FIXME: we could somehow makesure that this is the last
// output value...
offset = align_to<A>(offset);
arg = ret_array(reinterpret_cast<A*>(msg + offset),
(limit - offset) / sizeof(A));
// FIXME: we dont know the length of the array here so, cheat
return offset;
}
};
} // namespace Msg
}}
L4_UNLIKELY
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:284
L4_EXPORT
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:214
L4::Ipc::Msg
IPC Message related functionality.
Definition ipc_array:154
L4::Ipc::Msg::check_size
constexpr bool check_size(unsigned offset, unsigned limit) noexcept
Check if there is enough space for T from offset to limit.
Definition ipc_basics:53
L4::Ipc::Msg::align_to
constexpr unsigned long align_to(unsigned long bytes, unsigned long align) noexcept
Pad bytes to the given alignment align (in bytes).
Definition ipc_basics:30
L4::Ipc
IPC related functionality.
Definition ipc_array:13
L4
L4 low-level kernel interface.
Definition l4sys-l4f-groups.dox:50
L4::Ipc::Msg::Cls_data
Marker type for data values.
Definition ipc_basics:150
L4::Ipc::Msg::Dir_out
Marker type for output values.
Definition ipc_basics:147
L4::Ipc::Msg::Is_valid_rpc_type
Type trait defining a valid RPC parameter type.
Definition ipc_basics:339
L4::Ipc::Msg::Svr_val_ops
Defines client-side handling of `MTYPE' as RPC argument.
Definition ipc_basics:264
L4::Ipc::Ret_array
Dynamically sized output array of type T.
Definition ipc_ret_array:24
L4::Types::False
False meta value.
Definition types:296
types