// vi:set ft=cpp: -*- Mode: C++ -*- /* * (c) 2014 Alexander Warg * * This file is part of TUD:OS and distributed under the terms of the * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. * * As a special exception, you may use this file as part of a free software * library without restriction. Specifically, if other files instantiate * templates or use macros or inline functions from this file, or you compile * this file and link it with other files to produce an executable, this * file does not by itself cause the resulting executable to be covered by * the GNU General Public License. This exception does not however * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. */ #pragma once #include "types" #include "ipc_basics" #include "ipc_array" namespace L4 { namespace Ipc { template struct String : Array { static LEN strlength(CHAR *d) { LEN l = 0; while (d[l]) ++l; return l; } String() {} String(CHAR *d) : Array(strlength(d) + 1, d) {} String(LEN len, CHAR *d) : Array(len, d) {} void copy_in(CHAR const *s) { if (this->length < 1) return; LEN i; for (i = 0; i < this->length - 1 && s[i]; ++i) this->data[i] = s[i]; this->length = i + 1; this->data[i] = CHAR(); } }; #if __cplusplus >= 201103L template< typename CHAR = char, typename LEN_TYPE = unsigned long, LEN_TYPE MAX = (L4_UTCB_GENERIC_DATA_SIZE * sizeof(l4_umword_t)) / sizeof(CHAR) > using String_in_buf = Array_in_buf; #endif namespace Msg { template struct Clnt_xmit< String > : Clnt_xmit< Array > {}; template struct Svr_val_ops< String, Dir_in, CLASS > : Svr_val_ops< Array_ref, Dir_in, CLASS > { typedef Svr_val_ops< Array_ref, Dir_in, CLASS > Base; typedef typename Base::svr_type svr_type; using Base::to_svr; static int to_svr(char *msg, unsigned offset, unsigned limit, svr_type &a, Dir_in dir, Cls_data cls) { int r = Base::to_svr(msg, offset, limit, a, dir, cls); if (r < 0) return r; // correct clients send at least the zero terminator if (a.length < 1) return -L4_EMSGTOOSHORT; typedef typename L4::Types::Remove_const::type elem_type; const_cast(a.data)[a.length - 1] = A(); return r; } }; template struct Clnt_xmit &> : Clnt_xmit &> { typedef Array &type; using Clnt_xmit::from_msg; static int from_msg(char *msg, unsigned offset, unsigned limit, long ret, Array &a, Dir_out dir, Cls_data cls) { int r = Clnt_xmit::from_msg(msg, offset, limit, ret, a, dir, cls); if (r < 0) return r; // check for a bad servers if (a.length < 1) return -L4_EMSGTOOSHORT; a.data[a.length - 1] = A(); return r; }; }; template struct Clnt_xmit *> : Clnt_xmit &> {}; template struct Svr_val_ops, Dir_out, CLASS> : Svr_val_ops, Dir_out, CLASS> {}; template struct Is_valid_rpc_type const *> : L4::Types::False {}; template struct Is_valid_rpc_type const &> : L4::Types::False {}; } // namespace Msg }}