websocketpp  0.4.0
C++/Boost Asio based websocket client/server library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
base.hpp
1 /*
2  * Copyright (c) 2014, Peter Thorson. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the name of the WebSocket++ Project nor the
12  * names of its contributors may be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP
29 #define WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP
30 
31 #include <websocketpp/common/cpp11.hpp>
32 #include <websocketpp/common/functional.hpp>
33 #include <websocketpp/common/system_error.hpp>
34 
35 #include <boost/system/error_code.hpp>
36 
37 #include <boost/aligned_storage.hpp>
38 #include <boost/noncopyable.hpp>
39 #include <boost/array.hpp>
40 
41 #include <string>
42 
43 namespace websocketpp {
44 namespace transport {
46 
50 namespace asio {
51 
52 //
53 
54 // Class to manage the memory to be used for handler-based custom allocation.
55 // It contains a single block of memory which may be returned for allocation
56 // requests. If the memory is in use when an allocation request is made, the
57 // allocator delegates allocation to the global heap.
59  : private boost::noncopyable
60 {
61 public:
63  : in_use_(false)
64  {
65  }
66 
67  void* allocate(std::size_t size)
68  {
69  if (!in_use_ && size < storage_.size)
70  {
71  in_use_ = true;
72  return storage_.address();
73  }
74  else
75  {
76  return ::operator new(size);
77  }
78  }
79 
80  void deallocate(void* pointer)
81  {
82  if (pointer == storage_.address())
83  {
84  in_use_ = false;
85  }
86  else
87  {
88  ::operator delete(pointer);
89  }
90  }
91 
92 private:
93  // Storage space used for handler-based custom memory allocation.
94  boost::aligned_storage<1024> storage_;
95 
96  // Whether the handler-based custom allocation storage has been used.
97  bool in_use_;
98 };
99 
100 // Wrapper class template for handler objects to allow handler memory
101 // allocation to be customised. Calls to operator() are forwarded to the
102 // encapsulated handler.
103 template <typename Handler>
105 {
106 public:
108  : allocator_(a),
109  handler_(h)
110  {
111  }
112 
113  template <typename Arg1>
114  void operator()(Arg1 arg1)
115  {
116  handler_(arg1);
117  }
118 
119  template <typename Arg1, typename Arg2>
120  void operator()(Arg1 arg1, Arg2 arg2)
121  {
122  handler_(arg1, arg2);
123  }
124 
125  friend void* asio_handler_allocate(std::size_t size,
126  custom_alloc_handler<Handler>* this_handler)
127  {
128  return this_handler->allocator_.allocate(size);
129  }
130 
131  friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
132  custom_alloc_handler<Handler>* this_handler)
133  {
134  this_handler->allocator_.deallocate(pointer);
135  }
136 
137 private:
138  handler_allocator& allocator_;
139  Handler handler_;
140 };
141 
142 // Helper function to wrap a handler object to add custom allocation.
143 template <typename Handler>
144 inline custom_alloc_handler<Handler> make_custom_alloc_handler(
145  handler_allocator& a, Handler h)
146 {
147  return custom_alloc_handler<Handler>(a, h);
148 }
149 
150 
151 
152 
153 
154 
155 
156 // Forward declaration of class endpoint so that it can be friended/referenced
157 // before being included.
158 template <typename config>
159 class endpoint;
160 
161 typedef lib::function<void(boost::system::error_code const &)>
162  socket_shutdown_handler;
163 
164 typedef lib::function<void (boost::system::error_code const & ec,
165  size_t bytes_transferred)> async_read_handler;
166 
167 typedef lib::function<void (boost::system::error_code const & ec,
168  size_t bytes_transferred)> async_write_handler;
169 
170 typedef lib::function<void (lib::error_code const & ec)> pre_init_handler;
171 
172 // handle_timer: dynamic parameters, multiple copies
173 // handle_proxy_write
174 // handle_proxy_read
175 // handle_async_write
176 // handle_pre_init
177 
178 
180 namespace error {
181 enum value {
184  general = 1,
185 
188 
191 
194 
197 
200 };
201 
203 class category : public lib::error_category {
204 public:
205  char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
206  return "websocketpp.transport.asio";
207  }
208 
209  std::string message(int value) const {
210  switch(value) {
211  case error::general:
212  return "Generic asio transport policy error";
214  return "async_read_at_least call requested more bytes than buffer can store";
215  case error::pass_through:
216  return "Underlying Transport Error";
217  case error::proxy_failed:
218  return "Proxy connection failed";
220  return "Invalid proxy URI";
222  return "Invalid host or service";
223  default:
224  return "Unknown";
225  }
226  }
227 };
228 
230 inline lib::error_category const & get_category() {
231  static category instance;
232  return instance;
233 }
234 
236 inline lib::error_code make_error_code(error::value e) {
237  return lib::error_code(static_cast<int>(e), get_category());
238 }
239 
240 } // namespace error
241 } // namespace asio
242 } // namespace transport
243 } // namespace websocketpp
244 
245 _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
246 template<> struct is_error_code_enum<websocketpp::transport::asio::error::value>
247 {
248  static bool const value = true;
249 };
250 _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
251 #endif // WEBSOCKETPP_TRANSPORT_ASIO_HPP
uint16_t value
The type of a close code value.
Definition: close.hpp:49
lib::error_code make_error_code(error::value e)
Create an error code with the given value and the asio transport category.
Definition: base.hpp:236
async_read_at_least call requested more bytes than buffer can store
Definition: base.hpp:187
Asio transport error category.
Definition: base.hpp:203
there was an error in the underlying transport library
Definition: base.hpp:190
Namespace for the WebSocket++ project.
Definition: base64.hpp:41
Boost Asio based endpoint transport component.
Definition: base.hpp:159
The connection to the requested proxy server failed.
Definition: base.hpp:193
lib::error_category const & get_category()
Get a reference to a static copy of the asio transport error category.
Definition: base.hpp:230