Telnet++ 4.0.0.9
A C++ library for interacting with Telnet streams
Loading...
Searching...
No Matches
response_parser_helper.hpp
1#pragma once
2
3#include "telnetpp/options/new_environ/detail/protocol.hpp"
4#include "telnetpp/options/new_environ/detail/stream.hpp"
5
6#include <cassert>
7
8namespace telnetpp::options::new_environ::detail {
9
10constexpr telnetpp::byte type_to_byte(variable_type type)
11{
12 return type == variable_type::var
13 ? telnetpp::options::new_environ::detail::var
14 : telnetpp::options::new_environ::detail::uservar;
15}
16
17enum class parser_state
18{
19 state_is_or_info,
20 state_type,
21 state_name,
22 state_name_esc,
23 state_value,
24 state_value_esc,
25};
26
27struct parsing_state
28{
29 parser_state state = parser_state::state_is_or_info;
30 response rsp;
31};
32
33template <typename Continuation>
34void parse_is_or_info(
35 telnetpp::bytes::iterator /*current*/,
36 parsing_state &state,
37 Continuation && /*cont*/)
38{
39 state.state = parser_state::state_type;
40}
41
42template <typename Continuation>
43void parse_type(
44 telnetpp::bytes::iterator current,
45 parsing_state &state,
46 Continuation && /*cont*/)
47{
48 state.rsp.type = byte_to_type(*current);
49 state.state = parser_state::state_name;
50}
51
52template <typename Continuation>
53void parse_name(
54 telnetpp::bytes::iterator current,
55 parsing_state &state,
56 Continuation &&cont)
57{
58 using namespace telnetpp::literals; // NOLINT
59
60 switch (*current)
61 {
62 case detail::var: // Fall-through
63 case detail::uservar:
64 cont(state.rsp);
65 state.rsp = {};
66 state.rsp.type = byte_to_type(*current);
67 state.state = parser_state::state_name;
68 break;
69
70 case detail::esc:
71 state.state = parser_state::state_name_esc;
72 break;
73
74 case detail::value:
75 state.rsp.value = ""_tb;
76 state.state = parser_state::state_value;
77 break;
78
79 default:
80 state.rsp.name.push_back(*current);
81 break;
82 }
83}
84
85template <typename Continuation>
86void parse_name_esc(
87 telnetpp::bytes::iterator current,
88 parsing_state &state,
89 Continuation && /*cont*/)
90{
91 state.rsp.name.push_back(*current);
92 state.state = parser_state::state_name;
93}
94
95template <typename Continuation>
96void parse_value(
97 telnetpp::bytes::iterator current,
98 parsing_state &state,
99 Continuation &&cont)
100{
101 switch (*current)
102 {
103 case detail::var: // Fall-through
104 case detail::uservar:
105 cont(state.rsp);
106 state.rsp = {};
107 state.rsp.type = byte_to_type(*current);
108 state.state = parser_state::state_name;
109 break;
110
111 case detail::esc:
112 state.state = parser_state::state_value_esc;
113 break;
114
115 default:
116 state.rsp.value->push_back(*current);
117 break;
118 }
119}
120
121template <typename Continuation>
122void parse_value_esc(
123 telnetpp::bytes::iterator current,
124 parsing_state &state,
125 Continuation && /*cont*/)
126{
127 state.rsp.value->push_back(*current);
128 state.state = parser_state::state_value;
129}
130
131template <typename Continuation>
132void parse_byte(
133 telnetpp::bytes::iterator current,
134 parsing_state &state,
135 Continuation &&cont)
136{
137 switch (state.state)
138 {
139 case parser_state::state_is_or_info:
140 parse_is_or_info(current, state, cont);
141 break;
142
143 case parser_state::state_type:
144 parse_type(current, state, cont);
145 break;
146
147 case parser_state::state_name:
148 parse_name(current, state, cont);
149 break;
150
151 case parser_state::state_name_esc:
152 parse_name_esc(current, state, cont);
153 break;
154
155 case parser_state::state_value:
156 parse_value(current, state, cont);
157 break;
158
159 case parser_state::state_value_esc:
160 parse_value_esc(current, state, cont);
161 break;
162
163 default:
164 assert(!"Invalid state in NEW_ENVIRON response parser");
165 break;
166 }
167}
168
169template <typename Continuation>
170void parse_end(parsing_state &state, Continuation &&cont)
171{
172 if (!state.rsp.name.empty())
173 {
174 cont(state.rsp);
175 }
176}
177
178} // namespace telnetpp::options::new_environ::detail
variable_type
An enumeration of the type of variables that NEW_ENVIRON handles.
Definition protocol.hpp:13