SocketHandle.ih
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief SocketHandle internal header
16  */
17 
18 #ifndef IH_SENF_Socket_SocketHandle_
19 #define IH_SENF_Socket_SocketHandle_ 1
20 
21 // Custom includes
22 #include <map>
23 #include <string>
24 #include <boost/scoped_ptr.hpp>
25 #include "FileHandle.hh"
26 
27 //-/////////////////////////////////////////////////////////////////////////////////////////////////
28 
29 namespace senf {
30 
31 
32  class SocketProtocol;
33 
34  namespace detail {
35 
36  /** \brief String supporting automatic type conversion
37 
38  The StreamableString class is used to simplify creating a text representation of
39  arbitrary values. StreamableString is an ordinary string with an additional constructor
40  which allows constructing the string from any arbitrary, streamable type.
41 
42  \note It is generally not advisable to derive from the standard library container
43  classes. However, in this concrete case, the derivation is safe since only the
44  additional functionality is added. It is absolutely safe to convert the derived class
45  back to the base type.
46  */
47  class StreamableString : public std::string
48  {
49  public:
50  using std::string::operator=;
51 
52  template <class T>
53  StreamableString & operator<<(T const & other);
54  ///< Value assignment
55  /**< This operator will assign the string from any
56  arbitrary type. It will use boost::lexical_cast to
57  convert the argument to its string representation.
58 
59  If the string is non-empty, an additional separating
60  comma is added to the string. */
61 
62  StreamableString & operator<<(bool v); ///< Bool assignment
63  /**< The bool assignment is defined explicitly to use a
64  specialized representation (the strings 'true' and
65  'false'). */
66  };
67 
68  }
69 
70  typedef std::map<std::string, detail::StreamableString> SocketStateMap;
71 
72  namespace detail {
73  /** \brief Helper to convert SocketStateMap to multiline string representation
74  \internal
75  */
76  std::string dumpState(SocketStateMap const & map);
77  }
78 
79  template <class Policy, class Self> class ConcreteSocketProtocol;
80 
81  /** \brief SocketHandle referenced body
82 
83  \internal
84 
85  senf::SocketBody is the extended (relatively to senf::FileBody) body of
86  senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
87  FileBody). The casting and conversion operators defined will ensure this if used
88  properly. If this invariant is violated, your Program will probably crash.
89  */
90  class SocketBody
91  : public FileBody
92  {
93  public:
94  //-/////////////////////////////////////////////////////////////////////////////////////////
95  // Types
96 
97  typedef boost::intrusive_ptr<SocketBody> ptr;
98 
99  //-/////////////////////////////////////////////////////////////////////////////////////////
100  ///\name Structors and default members
101  //\{
102 
103  SocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
104  socket, false otherwise */
105  SocketBody(bool isServer, int fd);
106  /**< \param isServer \c true, if this socket is a server
107  socket, false otherwise
108  \param fd socket file descriptor */
109 
110  // no copy
111  // no conversion constructors
112 
113  //\}
114  //-/////////////////////////////////////////////////////////////////////////////////////////
115 
116  SocketProtocol & protocol() const; ///< Access the protocol instance
117 
118  bool isServer(); ///< Check socket type
119  /**< \return \c true, if this is a server socket, \c false
120  otherwise */
121 
122  void state(SocketStateMap & map, unsigned lod);
123 
124  std::unique_ptr<SocketBody> clone(bool isServer) const;
125  std::unique_ptr<SocketBody> clone(int fd, bool isServer) const;
126 
127  private:
128  virtual void v_close(); ///< Close socket
129  /**< This override will automatically \c shutdown() the
130  socket whenever it is closed.
131  \throws senf::SystemException */
132  virtual void v_terminate(); ///< Forcibly close socket
133  /**< This override will automatically \c shutdown() the
134  socket whenever it is called. Additionally it will
135  disable SO_LINGER to ensure, that v_terminate will not
136  block. Like the overridden method, this member will
137  ignore failures and will never throw. It therefore
138  safe to be called from a destructor. */
139  virtual bool v_eof() const; ///< Check for eof condition
140  /**< Since the eof check for sockets is very protocol
141  dependent, this member will forward the call to
142  senf::SocketPolicy::eof() */
143 
144  virtual SocketProtocol const & v_protocol() const = 0;
145  virtual std::string v_protocolName() const = 0;
146 
147  bool isServer_;
148  };
149 
150  template <class SProtocol>
151  class ProtocolSocketBody
152  : public SocketBody,
153  private SProtocol,
154  public senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >
155  {
156  public:
157  typedef SProtocol Protocol;
158 
159  using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator new;
160  using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator delete;
161 
162  ProtocolSocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
163  socket, false otherwise */
164  ProtocolSocketBody(bool isServer, int fd);
165  /**< \param isServer \c true, if this socket is a server
166  socket, false otherwise
167  \param fd socket file descriptor */
168 
169  private:
170  virtual SocketProtocol const & v_protocol() const;
171  virtual std::string v_protocolName() const;
172 
173  friend class ConcreteSocketProtocol<typename SProtocol::Policy, SProtocol>;
174  };
175 
176 }
177 
178 //-/////////////////////////////////////////////////////////////////////////////////////////////////
179 #endif
180 
181 
182 // Local Variables:
183 // mode: c++
184 // fill-column: 100
185 // c-file-style: "senf"
186 // indent-tabs-mode: nil
187 // ispell-local-dictionary: "american"
188 // compile-command: "scons -u test"
189 // comment-column: 40
190 // End: