fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / websocketpp-0.7.0 / websocketpp / message_buffer / message.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_MESSAGE_BUFFER_MESSAGE_HPP
29 #define WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP
30
31 #include <websocketpp/common/memory.hpp>
32 #include <websocketpp/frame.hpp>
33
34 #include <string>
35
36 namespace websocketpp {
37 namespace message_buffer {
38
39 /* # message:
40  * object that stores a message while it is being sent or received. Contains
41  * the message payload itself, the message header, the extension data, and the
42  * opcode.
43  *
44  * # connection_message_manager:
45  * An object that manages all of the message_buffers associated with a given
46  * connection. Implements the get_message_buffer(size) method that returns
47  * a message buffer at least size bytes long.
48  *
49  * Message buffers are reference counted with shared ownership semantics. Once
50  * requested from the manager the requester and it's associated downstream code
51  * may keep a pointer to the message indefinitely at a cost of extra resource
52  * usage. Once the reference count drops to the point where the manager is the
53  * only reference the messages is recycled using whatever method is implemented
54  * in the manager.
55  *
56  * # endpoint_message_manager:
57  * An object that manages connection_message_managers. Implements the
58  * get_message_manager() method. This is used once by each connection to
59  * request the message manager that they are supposed to use to manage message
60  * buffers for their own use.
61  *
62  * TYPES OF CONNECTION_MESSAGE_MANAGERS
63  * - allocate a message with the exact size every time one is requested
64  * - maintain a pool of pre-allocated messages and return one when needed.
65  *   Recycle previously used messages back into the pool
66  *
67  * TYPES OF ENDPOINT_MESSAGE_MANAGERS
68  *  - allocate a new connection manager for each connection. Message pools
69  *    become connection specific. This increases memory usage but improves
70  *    concurrency.
71  *  - allocate a single connection manager and share a pointer to it with all
72  *    connections created by this endpoint. The message pool will be shared
73  *    among all connections, improving memory usage and performance at the cost
74  *    of reduced concurrency
75  */
76
77
78 /// Represents a buffer for a single WebSocket message.
79 /**
80  *
81  *
82  */
83 template <template<class> class con_msg_manager>
84 class message {
85 public:
86     typedef lib::shared_ptr<message> ptr;
87
88     typedef con_msg_manager<message> con_msg_man_type;
89     typedef typename con_msg_man_type::ptr con_msg_man_ptr;
90     typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
91
92     /// Construct an empty message
93     /**
94      * Construct an empty message
95      */
96     message(const con_msg_man_ptr manager)
97       : m_manager(manager)
98       , m_prepared(false)
99       , m_fin(true)
100       , m_terminal(false)
101       , m_compressed(false) {}
102
103     /// Construct a message and fill in some values
104     /**
105      *
106      */
107     message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size = 128)
108       : m_manager(manager)
109       , m_opcode(op)
110       , m_prepared(false)
111       , m_fin(true)
112       , m_terminal(false)
113       , m_compressed(false)
114     {
115         m_payload.reserve(size);
116     }
117
118     /// Return whether or not the message has been prepared for sending
119     /**
120      * The prepared flag indicates that the message has been prepared by a
121      * websocket protocol processor and is ready to be written to the wire.
122      *
123      * @return whether or not the message has been prepared for sending
124      */
125     bool get_prepared() const {
126         return m_prepared;
127     }
128
129     /// Set or clear the flag that indicates that the message has been prepared
130     /**
131      * This flag should not be set by end user code without a very good reason.
132      *
133      * @param value The value to set the prepared flag to
134      */
135     void set_prepared(bool value) {
136         m_prepared = value;
137     }
138
139     /// Return whether or not the message is flagged as compressed
140     /**
141      * @return whether or not the message is/should be compressed
142      */
143     bool get_compressed() const {
144         return m_compressed;
145     }
146
147     /// Set or clear the compression flag
148     /**
149      * Setting the compression flag indicates that the data in this message
150      * would benefit from compression. If both endpoints negotiate a compression
151      * extension WebSocket++ will attempt to compress messages with this flag.
152      * Setting this flag does not guarantee that the message will be compressed.
153      *
154      * @param value The value to set the compressed flag to
155      */
156     void set_compressed(bool value) {
157         m_compressed = value;
158     }
159
160     /// Get whether or not the message is terminal
161     /**
162      * Messages can be flagged as terminal, which results in the connection
163      * being close after they are written rather than the implementation going
164      * on to the next message in the queue. This is typically used internally
165      * for close messages only.
166      *
167      * @return Whether or not this message is marked terminal
168      */
169     bool get_terminal() const {
170         return m_terminal;
171     }
172
173     /// Set the terminal flag
174     /**
175      * This flag should not be set by end user code without a very good reason.
176      *
177      * @see get_terminal()
178      *
179      * @param value The value to set the terminal flag to.
180      */
181     void set_terminal(bool value) {
182         m_terminal = value;
183     }
184     /// Read the fin bit
185     /**
186      * A message with the fin bit set will be sent as the last message of its
187      * sequence. A message with the fin bit cleared will require subsequent
188      * frames of opcode continuation until one of them has the fin bit set.
189      *
190      * The remote end likely will not deliver any bytes until the frame with the fin
191      * bit set has been received.
192      *
193      * @return Whether or not the fin bit is set
194      */
195     bool get_fin() const {
196         return m_fin;
197     }
198
199     /// Set the fin bit
200     /**
201      * @see get_fin for a more detailed explaination of the fin bit
202      *
203      * @param value The value to set the fin bit to.
204      */
205     void set_fin(bool value) {
206         m_fin = value;
207     }
208
209     /// Return the message opcode
210     frame::opcode::value get_opcode() const {
211         return m_opcode;
212     }
213
214     /// Set the opcode
215     void set_opcode(frame::opcode::value op) {
216         m_opcode = op;
217     }
218
219     /// Return the prepared frame header
220     /**
221      * This value is typically set by a websocket protocol processor
222      * and shouldn't be tampered with.
223      */
224     std::string const & get_header() const {
225         return m_header;
226     }
227
228     /// Set prepared frame header
229     /**
230      * Under normal circumstances this should not be called by end users
231      *
232      * @param header A string to set the header to.
233      */
234     void set_header(std::string const & header) {
235         m_header = header;
236     }
237
238     std::string const & get_extension_data() const {
239         return m_extension_data;
240     }
241
242     /// Get a reference to the payload string
243     /**
244      * @return A const reference to the message's payload string
245      */
246     std::string const & get_payload() const {
247         return m_payload;
248     }
249
250     /// Get a non-const reference to the payload string
251     /**
252      * @return A reference to the message's payload string
253      */
254     std::string & get_raw_payload() {
255         return m_payload;
256     }
257
258     /// Set payload data
259     /**
260      * Set the message buffer's payload to the given value.
261      *
262      * @param payload A string to set the payload to.
263      */
264     void set_payload(std::string const & payload) {
265         m_payload = payload;
266     }
267
268     /// Set payload data
269     /**
270      * Set the message buffer's payload to the given value.
271      *
272      * @param payload A pointer to a data array to set to.
273      * @param len The length of new payload in bytes.
274      */
275     void set_payload(void const * payload, size_t len) {
276         m_payload.reserve(len);
277         char const * pl = static_cast<char const *>(payload);
278         m_payload.assign(pl, pl + len);
279     }
280
281     /// Append payload data
282     /**
283      * Append data to the message buffer's payload.
284      *
285      * @param payload A string containing the data array to append.
286      */
287     void append_payload(std::string const & payload) {
288         m_payload.append(payload);
289     }
290
291     /// Append payload data
292     /**
293      * Append data to the message buffer's payload.
294      *
295      * @param payload A pointer to a data array to append
296      * @param len The length of payload in bytes
297      */
298     void append_payload(void const * payload, size_t len) {
299         m_payload.reserve(m_payload.size()+len);
300         m_payload.append(static_cast<char const *>(payload),len);
301     }
302
303     /// Recycle the message
304     /**
305      * A request to recycle this message was received. Forward that request to
306      * the connection message manager for processing. Errors and exceptions
307      * from the manager's recycle member function should be passed back up the
308      * call chain. The caller to message::recycle will deal with them.
309      *
310      * Recycle must *only* be called by the message shared_ptr's destructor.
311      * Once recycled successfully, ownership of the memory has been passed to
312      * another system and must not be accessed again.
313      *
314      * @return true if the message was successfully recycled, false otherwise.
315      */
316     bool recycle() {
317         con_msg_man_ptr shared = m_manager.lock();
318
319         if (shared) {
320             return shared->recycle(this);
321         } else {
322             return false;
323         }
324     }
325 private:
326     con_msg_man_weak_ptr        m_manager;
327     std::string                 m_header;
328     std::string                 m_extension_data;
329     std::string                 m_payload;
330     frame::opcode::value        m_opcode;
331     bool                        m_prepared;
332     bool                        m_fin;
333     bool                        m_terminal;
334     bool                        m_compressed;
335 };
336
337 } // namespace message_buffer
338 } // namespace websocketpp
339
340 #endif // WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP