My Project
NPLMsgIn_parser.h
1 #pragma once
2 #include "NPLMsgIn.h"
3 #include <boost/logic/tribool.hpp>
4 #include <boost/tuple/tuple.hpp>
5 
6 namespace NPL
7 {
8  struct NPLMsgIn;
9 
119  {
120  public:
121  enum Consume_Result
122  {
123  c_res_indeterminate,
124  c_res_code_body,
125  c_res_true,
126  c_res_false,
127  };
128 
130  NPLMsgIn_parser();
131 
133  void reset();
134 
139  template <typename InputIterator>
140  boost::tuple<boost::tribool, InputIterator> parse(NPLMsgIn& req,
141  InputIterator begin, InputIterator end)
142  {
143  Consume_Result result = c_res_indeterminate;
144  while (begin != end && (result == c_res_indeterminate))
145  {
146  result = consume(req, *begin++);
147  }
148  if(begin != end && result == c_res_code_body)
149  {
150  // we can read to end or length instead of doing the lexical work one char at a time.
151  int nOldSize = req.m_code.size();
152  int nByteCount = end-begin;
153  if(req.m_nLength < (nOldSize+nByteCount))
154  {
155  nByteCount = req.m_nLength - nOldSize;
156  }
157  req.m_code.resize(nOldSize+nByteCount);
158  memcpy(&(req.m_code[nOldSize]), begin, nByteCount);
159  begin = begin + nByteCount;
160  if (req.m_nLength ==(int)req.m_code.size())
161  {
162  result = c_res_true;
163  }
164  }
165  if(result == c_res_true)
166  {
167  if(m_bCompressed)
168  Decompress(req);
169  reset();
170  boost::tribool result_ = true;
171  return boost::make_tuple(result_, begin);
172  }
173  else if(result == c_res_false)
174  {
175  boost::tribool result_ = false;
176  return boost::make_tuple(result_, begin);
177  }
178  else
179  {
180  boost::tribool result_ = boost::indeterminate;
181  return boost::make_tuple(result_, begin);
182  }
183  }
184 
185  private:
187  Consume_Result consume(NPLMsgIn& req, char input);
188 
190  void Decompress(NPLMsgIn& req);
191 
193  void Decode(NPLMsgIn& req);
194 
196  static bool is_char(int c);
197 
199  static bool is_ctl(int c);
200 
202  static bool is_tspecial(int c);
203 
205  static bool is_digit(int c);
206 
208  enum state
209  {
210  method_start,
211  method,
212  uri,
213  uri_rts_name,
214  npl_version_n,
215  npl_version_p,
216  npl_version_l,
217  npl_version_slash,
218  npl_version_major,
219  npl_version_minor,
220  header_line_start,
221  header_lws,
222  header_name,
223  header_value,
224  code_length,
225  code_body,
226  uri_http,
227  } state_;
229  bool m_bCompressed;
230  };
231 }
232 
233 
std::string m_code
msg body
Definition: NPLMsgIn.h:26
define this to enable debugging of NPL code in visual studio
Definition: INPL.h:9
int m_nLength
number of bytes in m_code
Definition: NPLMsgIn.h:24
Parser for incoming requests.
Definition: NPLMsgIn_parser.h:118
NPLMsgIn_parser()
Construct ready to parse the NPLMsgIn method.
Definition: NPLMsgIn_parser.cpp:17
boost::tuple< boost::tribool, InputIterator > parse(NPLMsgIn &req, InputIterator begin, InputIterator end)
Parse some data.
Definition: NPLMsgIn_parser.h:140
A NPL msg received from a socket.
Definition: NPLMsgIn.h:8
void reset()
Reset to initial parser state.
Definition: NPLMsgIn_parser.cpp:22