1  /*
   2   * \brief  Helpers for non-ordinary RPC arguments
   3   * \author Norman Feske
   4   * \date   2011-04-06
   5   */

   6  
   7  /*
   8   * Copyright (C) 2011-2013 Genode Labs GmbH
   9   *
  10   * This file is part of the Genode OS framework, which is distributed
  11   * under the terms of the GNU General Public License version 2.
  12   */

  13  
  14  #ifndef _INCLUDE__BASE__RPC_ARGS_H_
  15  #define _INCLUDE__BASE__RPC_ARGS_H_
  16  
  17  #include <util/string.h>
  18  #include <base/stdint.h>
  19  
  20  namespace Genode {
  21  
  22     class Rpc_in_buffer_base;
  23     template <size_t> class Rpc_in_buffer;
  24  }

  25  
  26  
  27  /**
  28   * Base class of `Rpc_in_buffer`
  29   */

  30  class Genode::Rpc_in_buffer_base
  31  {
  32     protected:
  33  
  34        const char *_base;
  35        size_t      _size;
  36  
  37        /**
  38         * Construct buffer from null-terminated string
  39         */

  40        explicit Rpc_in_buffer_base(const char *str)
  41        : _base(str), _size(strlen(str) + 1) { }

  42  
  43        /**
  44         * Construct an empty buffer by default
  45         */

  46        Rpc_in_buffer_base(): _base(0), _size(0) { }

  47  
  48     public:
  49  
  50        /**
  51         * Construct buffer
  52         */

  53        Rpc_in_buffer_base(const char *base, size_t size)
  54        : _base(base), _size(size) { }

  55  
  56        const char *base() const { return _base; }
  57        size_t      size() const { return _size; }

  58  }
;

  59  
  60  
  61  /**
  62   * Buffer with size constrain
  63   */

  64  template <Genode::size_t MAX>
  65  class Genode::Rpc_in_buffer : public Rpc_in_buffer_base
  66  {
  67     private:
  68  
  69        /*
  70         * This member is only there to pump up the size of the object such
  71         * that `sizeof()` returns the maximum buffer size when queried by
  72         * the RPC framework.
  73         */

  74        char _balloon[MAX];

  75  
  76     public:
  77  
  78        enum { MAX_SIZE = MAX };
  79  
  80        /**
  81         * Construct buffer
  82         */

  83        Rpc_in_buffer(const char *base, size_t size)
  84        : Rpc_in_buffer_base(base, min(size, (size_t)MAX_SIZE)) { }

  85  
  86        /**
  87         * Construct buffer from null-terminated string
  88         */

  89        Rpc_in_buffer(const char *str) : Rpc_in_buffer_base(str)
  90        {
  91           if (_size >= MAX_SIZE)
  92              _size = MAX_SIZE;

  93        }

  94  
  95        /**
  96         * Default constructor creates invalid buffer
  97         */

  98        Rpc_in_buffer() { }

  99  
 100        void operator = (Rpc_in_buffer<MAX_SIZE> const &from)
 101        {
 102           _base = from.base();
 103           _size = from.size();

 104        }

 105  
 106        /**
 107         * Return true if buffer contains a valid null-terminated string
 108         */

 109        bool is_valid_string() const {
 110           return (_size <= MAX_SIZE) && (_size > 0) && (_base[_size - 1] == `\0`); }

 111  
 112        /**
 113         * Return buffer content as null-terminated string
 114         *
 115         * \return  pointer to null-terminated string
 116         *
 117         * The method returns an empty string if the buffer does not hold
 118         * a valid null-terminated string. To distinguish a buffer holding
 119         * an invalid string from a buffer holding a valid empty string,
 120         * the function `is_valid_string` can be used.
 121         */

 122        char const *string() const { return is_valid_string() ? base() : ""; }

 123  }
;

 124  
 125  #endif /* _INCLUDE__BASE__RPC_ARGS_H_ */