JayBeams  0.1
Another project to have fun coding.
process_buffer_mlist.hpp
Go to the documentation of this file.
1 #ifndef jb_itch5_process_buffer_mlist_hpp
2 #define jb_itch5_process_buffer_mlist_hpp
3 
4 #include <jb/itch5/decoder.hpp>
6 
7 #include <cstddef>
8 
9 namespace jb {
10 namespace itch5 {
11 
12 /**
13  * Process a buffer with a single message: parse it and call the handler.
14  *
15  * As messages are received and broken down by
16  * jb::itch5::process_iostream_mlist() they need to be parsed and then
17  * the right member function on the message handler must be invoked.
18  * Two partial specializations of this class implement this
19  * functionality. The fully generic version is, in fact, not
20  * implemented and this is intentional.
21  *
22  * We use a class instead of a standalone function because partial
23  * template specialization for functions is not allowed in C++11,
24  * though it is trivially simulated, as show here.
25  *
26  * Please see @ref jb::itch5::message_handler_concept for a detailed
27  * description of the message_handler requirements.
28  */
29 template <typename message_handler, typename... message_types>
31 
32 /**
33  * Partial specialization for an empty list of messages.
34  *
35  * Call the handle_unknown() member function in the message handler.
36  *
37  * @tparam message_handler a type that meets the interface defined in
38  * jb::itch5::message_handler_concept.
39  */
40 template <typename message_handler>
41 class process_buffer_mlist<message_handler> {
42 public:
43  /**
44  * Always call handle_unknown(), as the message type list is empty.
45  *
46  * @param handler a message handler per @ref
47  * jb::itch5::message_handler_concept.
48  * @param recv_ts the timestamp when the message was received
49  * @param msgcnt the number of messages received before this message
50  * @param msgoffset the number of bytes received before this message
51  * @param msgbuf the raw message buffer
52  * @param msglen the raw message length
53  */
54  static void process(
55  message_handler& handler,
56  typename message_handler::time_point const& recv_ts, std::uint64_t msgcnt,
57  std::size_t msgoffset, char const* msgbuf, std::size_t msglen) {
58  handler.handle_unknown(
59  recv_ts, jb::itch5::unknown_message(msgcnt, msgoffset, msglen, msgbuf));
60  }
61 };
62 
63 /**
64  * Partial specialization for a list with at least one message.
65  *
66  * Recurse through the message list until it is parsed or handled by
67  * the specialization for an empty message type list
68  *
69  * @tparam message_handler a type that meets the interface defined in
70  * jb::itch5::message_handler_concept.
71  * @tparam head_t the first message type in the message type list
72  * @tparam tail_t the remaining message types in the message type list
73  */
74 template <typename message_handler, typename head_t, typename... tail_t>
75 class process_buffer_mlist<message_handler, head_t, tail_t...> {
76 public:
77  /**
78  * If any of the message types in the list matches the contents of
79  * the buffer call handle_message() for that type in the handler.
80  * Otherwise call handle_unknown().
81  *
82  * @param handler a message handler per @ref
83  * jb::itch5::message_handler_concept.
84  * @param recv_ts the timestamp when the message was received
85  * @param msgcnt the number of messages received before this message
86  * @param msgoffset the number of bytes received before this message
87  * @param msgbuf the raw message buffer
88  * @param msglen the raw message length
89  */
90  static void process(
91  message_handler& handler,
92  typename message_handler::time_point const& recv_ts, std::uint64_t msgcnt,
93  std::size_t msgoffset, char const* msgbuf, std::size_t msglen) {
94  // if the message received matches the head then ...
95  if (msgbuf[0] == head_t::message_type) {
96  // ... parse the message ...
97  head_t msg = jb::itch5::decoder<true, head_t>::r(msglen, msgbuf, 0);
98  // ... the right handle_message() member function in the message
99  // handler ...
100  handler.handle_message(recv_ts, msgcnt, msgoffset, msg);
101  return;
102  }
103  // ... recurse through the message list ...
105  handler, recv_ts, msgcnt, msgoffset, msgbuf, msglen);
106  }
107 };
108 
109 } // namespace itch5
110 } // namespace jb
111 
112 #endif // jb_itch5_process_buffer_mlist_hpp
static T r(std::size_t size, void const *msg, std::size_t offset)
Read a single message or field.
clock_type::time_point time_point
A convenience alias for clock_type::time_point.
static void process(message_handler &handler, typename message_handler::time_point const &recv_ts, std::uint64_t msgcnt, std::size_t msgoffset, char const *msgbuf, std::size_t msglen)
Always call handle_unknown(), as the message type list is empty.
Process a buffer with a single message: parse it and call the handler.
static void process(message_handler &handler, typename message_handler::time_point const &recv_ts, std::uint64_t msgcnt, std::size_t msgoffset, char const *msgbuf, std::size_t msglen)
If any of the message types in the list matches the contents of the buffer call handle_message() for ...
The top-level namespace for the JayBeams library.
Definition: as_hhmmss.hpp:7