Telnet++ 4.0.0.9
A C++ library for interacting with Telnet streams
Loading...
Searching...
No Matches
request_parser_helper.hpp
1#pragma once
2
3#include "telnetpp/options/new_environ/detail/stream.hpp"
4#include "telnetpp/options/new_environ/protocol.hpp"
5
6#include <cassert>
7
8namespace telnetpp::options::new_environ::detail {
9
10enum class request_parser_state : std::uint8_t
11{
12 state_send,
13 state_type,
14 state_name,
15 state_name_esc,
16};
17
18struct request_parsing_state
19{
20 request_parser_state state_ = request_parser_state::state_send;
21 request req_;
22};
23
24// ==========================================================================
25// PARSE_REQUEST_SEND
26// ==========================================================================
27template <typename Continuation>
28constexpr void parse_request_send(
29 request_parsing_state &state,
30 telnetpp::byte /*current*/,
31 Continuation && /*cont*/)
32{
33 state.state_ = request_parser_state::state_type;
34}
35
36// ==========================================================================
37// PARSE_REQUEST_TYPE
38// ==========================================================================
39template <typename Continuation>
40constexpr void parse_request_type(
41 request_parsing_state &state,
42 telnetpp::byte current,
43 Continuation && /*cont*/)
44{
45 state.req_.type = byte_to_type(current);
46 state.state_ = request_parser_state::state_name;
47}
48
49// ==========================================================================
50// PARSE_REQUEST_NAME
51// ==========================================================================
52template <typename Continuation>
53constexpr void parse_request_name(
54 request_parsing_state &state, telnetpp::byte current, Continuation &&cont)
55{
56 switch (current)
57 {
58 case detail::esc:
59 state.state_ = request_parser_state::state_name_esc;
60 break;
61
62 case detail::var: // Fall-through
63 case detail::uservar:
64 cont(state.req_);
65 state.req_ = {};
66 state.req_.type = byte_to_type(current);
67 break;
68
69 default:
70 state.req_.name.push_back(current);
71 break;
72 }
73}
74
75// ==========================================================================
76// PARSE_REQUEST_NAME_ESC
77// ==========================================================================
78template <typename Continuation>
79constexpr void parse_request_name_esc(
80 request_parsing_state &state,
81 telnetpp::byte current,
82 Continuation && /*cont*/)
83{
84 state.req_.name.push_back(current);
85 state.state_ = request_parser_state::state_name;
86}
87
88// ==========================================================================
89// PARSE_REQUEST_BYTE
90// ==========================================================================
91template <typename Continuation>
92constexpr void parse_request_byte(
93 request_parsing_state &state, telnetpp::byte current, Continuation &&cont)
94{
95 switch (state.state_)
96 {
97 case request_parser_state::state_send:
98 parse_request_send(state, current, cont);
99 break;
100
101 case request_parser_state::state_type:
102 parse_request_type(state, current, cont);
103 break;
104
105 case request_parser_state::state_name:
106 parse_request_name(state, current, cont);
107 break;
108
109 case request_parser_state::state_name_esc:
110 parse_request_name_esc(state, current, cont);
111 break;
112
113 default:
114 assert(!"Invalid state in request parser");
115 break;
116 }
117}
118
119// ==========================================================================
120// PARSE_REQUEST_BYTE
121// ==========================================================================
122template <typename Continuation>
123constexpr void parse_request_end(
124 request_parsing_state &state, Continuation &&cont)
125{
126 if (!state.req_.name.empty())
127 {
128 cont(state.req_);
129 }
130}
131
132} // namespace telnetpp::options::new_environ::detail