mqtt_cpp
property_parse.hpp
Go to the documentation of this file.
1 // Copyright Takatoshi Kondo 2018
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #if !defined(MQTT_PROPERTY_PARSE_HPP)
8 #define MQTT_PROPERTY_PARSE_HPP
9 
10 #include <vector>
11 
12 #include <mqtt/namespace.hpp>
13 #include <mqtt/optional.hpp>
15 #include <mqtt/variable_length.hpp>
16 #include <mqtt/move.hpp>
17 
18 namespace MQTT_NS {
19 namespace v5 {
20 namespace property {
21 
22 inline
23 optional<property_variant> parse_one(buffer& buf) {
24  if (buf.empty()) return nullopt;
25  try {
26  auto id = static_cast<property::id>(buf.front());
27  buf.remove_prefix(1);
28  switch (id) {
30  if (buf.size() < 1) return nullopt;
31  auto p = payload_format_indicator(buf.begin(), std::next(buf.begin(), 1));
32  buf.remove_prefix(1);
33  return property_variant(p);
34  } break;
36  if (buf.size() < 4) return nullopt;
37  auto p = message_expiry_interval(buf.begin(), std::next(buf.begin(), 4));
38  buf.remove_prefix(4);
39  return property_variant(p);
40  } break;
41  case id::content_type: {
42  if (buf.size() < 2) return nullopt;
43  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
44  if (buf.size() < 2U + len) return nullopt;
45  auto p = content_type(buf.substr(2, len));
46  buf.remove_prefix(2 + len);
47  return property_variant(p);
48  } break;
49  case id::response_topic: {
50  if (buf.size() < 2) return nullopt;
51  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
52  if (buf.size() < 2U + len) return nullopt;
53  auto p = response_topic(buf.substr(2, len));
54  buf.remove_prefix(2 + len);
55  return property_variant(p);
56  } break;
57  case id::correlation_data: {
58  if (buf.size() < 2) return nullopt;
59  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
60  if (buf.size() < 2U + len) return nullopt;
61  auto p = correlation_data(buf.substr(2, len));
62  buf.remove_prefix(2 + len);
63  return property_variant(p);
64  } break;
66  auto val_consumed = variable_length(buf.begin(), buf.end());
67  auto val = std::get<0>(val_consumed);
68  auto consumed = std::get<1>(val_consumed);
69  if (consumed == 0) return nullopt;
70  auto p = subscription_identifier(val);
71  buf.remove_prefix(consumed);
72  return property_variant(p);
73  } break;
75  if (buf.size() < 4) return nullopt;
76  auto p = session_expiry_interval(buf.begin(), std::next(buf.begin(), 4));
77  buf.remove_prefix(4);
78  return property_variant(p);
79  } break;
81  if (buf.size() < 2) return nullopt;
82  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
83  if (buf.size() < 2U + len) return nullopt;
84  auto p = assigned_client_identifier(buf.substr(2, len));
85  buf.remove_prefix(2 + len);
86  return property_variant(p);
87  } break;
88  case id::server_keep_alive: {
89  if (buf.size() < 2) return nullopt;
90  auto p = server_keep_alive(buf.begin(), std::next(buf.begin(), 2));
91  buf.remove_prefix(2);
92  return property_variant(p);
93  } break;
95  if (buf.size() < 2) return nullopt;
96  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
97  if (buf.size() < 2U + len) return nullopt;
98  auto p = authentication_method(buf.substr(2, len));
99  buf.remove_prefix(2 + len);
100  return property_variant(p);
101  } break;
103  if (buf.size() < 2) return nullopt;
104  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
105  if (buf.size() < 2U + len) return nullopt;
106  auto p = authentication_data(buf.substr(2, len));
107  buf.remove_prefix(2 + len);
108  return property_variant(p);
109  } break;
111  if (buf.size() < 1) return nullopt;
112  auto p = request_problem_information(buf.begin(), std::next(buf.begin(), 1));
113  buf.remove_prefix(1);
114  return property_variant(p);
115  } break;
117  if (buf.size() < 4) return nullopt;
118  auto p = will_delay_interval(buf.begin(), std::next(buf.begin(), 4));
119  buf.remove_prefix(4);
120  return property_variant(p);
121  } break;
123  if (buf.size() < 1) return nullopt;
124  auto p = request_response_information(buf.begin(), std::next(buf.begin(), 1));
125  buf.remove_prefix(1);
126  return property_variant(p);
127  } break;
129  if (buf.size() < 2) return nullopt;
130  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
131  if (buf.size() < 2U + len) return nullopt;
132  auto p = response_information(buf.substr(2, len));
133  buf.remove_prefix(2 + len);
134  return property_variant(p);
135  } break;
136  case id::server_reference: {
137  if (buf.size() < 2) return nullopt;
138  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
139  if (buf.size() < 2U + len) return nullopt;
140  auto p = server_reference(buf.substr(2, len));
141  buf.remove_prefix(2 + len);
142  return property_variant(p);
143  } break;
144  case id::reason_string: {
145  if (buf.size() < 2) return nullopt;
146  auto len = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
147  if (buf.size() < 2U + len) return nullopt;
148  auto p = reason_string(buf.substr(2, len));
149  buf.remove_prefix(2 + len);
150  return property_variant(p);
151  } break;
152  case id::receive_maximum: {
153  if (buf.size() < 2) return nullopt;
154  auto p = receive_maximum(buf.begin(), std::next(buf.begin(), 2));
155  buf.remove_prefix(2);
156  return property_variant(p);
157  } break;
159  if (buf.size() < 2) return nullopt;
160  auto p = topic_alias_maximum(buf.begin(), std::next(buf.begin(), 2));
161  buf.remove_prefix(2);
162  return property_variant(p);
163  } break;
164  case id::topic_alias: {
165  if (buf.size() < 2) return nullopt;
166  auto p = topic_alias(buf.begin(), std::next(buf.begin(), 2));
167  buf.remove_prefix(2);
168  return property_variant(p);
169  } break;
170  case id::maximum_qos: {
171  if (buf.size() < 1) return nullopt;
172  auto p = maximum_qos(buf.begin(), std::next(buf.begin(), 1));
173  buf.remove_prefix(1);
174  return property_variant(p);
175  } break;
176  case id::retain_available: {
177  if (buf.size() < 1) return nullopt;
178  auto p = retain_available(buf.begin(), std::next(buf.begin(), 1));
179  buf.remove_prefix(1);
180  return property_variant(p);
181  } break;
182  case id::user_property: {
183  if (buf.size() < 2) return nullopt;
184  auto keylen = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
185  if (buf.size() < 2U + keylen) return nullopt;
186  auto key = buf.substr(2, keylen);
187  buf.remove_prefix(2 + keylen);
188 
189  if (buf.size() < 2) return nullopt;
190  auto vallen = make_uint16_t(buf.begin(), std::next(buf.begin(), 2));
191  if (buf.size() < 2U + vallen) return nullopt;
192  auto val = buf.substr(2, vallen);
193 
194  auto p = user_property(force_move(key), force_move(val));
195  buf.remove_prefix(2 + vallen);
196 
197  return property_variant(p);
198  } break;
200  if (buf.size() < 4) return nullopt;
201  auto p = maximum_packet_size(buf.begin(), std::next(buf.begin(), 4));
202  buf.remove_prefix(4);
203  return property_variant(p);
204  } break;
206  if (buf.size() < 1) return nullopt;
207  auto p = wildcard_subscription_available(buf.begin(), std::next(buf.begin(), 1));
208  buf.remove_prefix(1);
209  return property_variant(p);
210  } break;
212  if (buf.size() < 1) return nullopt;
213  auto p = subscription_identifier_available(buf.begin(), std::next(buf.begin(), 1));
214  buf.remove_prefix(1);
215  return property_variant(p);
216  } break;
218  if (buf.size() < 1) return nullopt;
219  auto p = shared_subscription_available(buf.begin(), std::next(buf.begin(), 1));
220  buf.remove_prefix(1);
221  return property_variant(p);
222  } break;
223  }
224  }
225  catch (property_parse_error const&) {
226  return nullopt;
227  }
228  return nullopt;
229 }
230 
231 inline
232 std::vector<property_variant> parse(buffer buf) {
233  std::vector<property_variant> props;
234  while (true) {
235  if (auto ret = parse_one(buf)) {
236  props.push_back(force_move(ret.value()));
237  }
238  else {
239  break;
240  }
241  }
242  return props;
243 }
244 
245 } // namespace property
246 } // namespace v5
247 } // namespace MQTT_NS
248 
249 #endif // MQTT_PROPERTY_PARSE_HPP
buffer that has string_view interface This class provides string_view interface. This class hold stri...
Definition: buffer.hpp:30
buffer substr(std::size_t offset, std::size_t length=string_view::npos) const &
get substring The returned buffer ragnge is the same as std::string_view::substr()....
Definition: buffer.hpp:68
Definition: property.hpp:373
Definition: property.hpp:301
Definition: property.hpp:313
Definition: property.hpp:641
Definition: property.hpp:495
Definition: property.hpp:439
Definition: property.hpp:445
Definition: property.hpp:307
Definition: property.hpp:517
Definition: property.hpp:351
Definition: property.hpp:433
Definition: property.hpp:462
Definition: property.hpp:479
Definition: property.hpp:534
Definition: property.hpp:395
std::vector< property_variant > parse(buffer buf)
Definition: property_parse.hpp:232
id
Definition: property_id.hpp:19
optional< property_variant > parse_one(buffer &buf)
Definition: property_parse.hpp:23
variant< property::payload_format_indicator, property::message_expiry_interval, property::content_type, property::response_topic, property::correlation_data, property::subscription_identifier, property::session_expiry_interval, property::assigned_client_identifier, property::server_keep_alive, property::authentication_method, property::authentication_data, property::request_problem_information, property::will_delay_interval, property::request_response_information, property::response_information, property::server_reference, property::reason_string, property::receive_maximum, property::topic_alias_maximum, property::topic_alias, property::maximum_qos, property::retain_available, property::user_property, property::maximum_packet_size, property::wildcard_subscription_available, property::subscription_identifier_available, property::shared_subscription_available > property_variant
Definition: property_variant.hpp:49
Definition: any.hpp:27
constexpr std::remove_reference_t< T > && force_move(T &&t)
Definition: move.hpp:20
constexpr std::tuple< std::size_t, std::size_t > variable_length(T const &bytes)
Definition: variable_length.hpp:42
constexpr std::uint16_t make_uint16_t(It b, It e)
Definition: two_byte_util.hpp:34
Definition: exception.hpp:109