RESTinio
utf8.hpp
Go to the documentation of this file.
1 /*!
2  UTF-8 .
3 */
4 
5 #pragma once
6 
7 #include <string>
8 #include <array>
9 #include <exception>
10 #include <iostream> // std::cout, debug
11 #include <algorithm>
12 
13 #include <restinio/string_view.hpp>
14 
15 namespace restinio
16 {
17 
18 namespace websocket
19 {
20 
21 namespace basic
22 {
23 
24 namespace impl
25 {
26 
27 //
28 // utf8_checker_t
29 //
30 
32 {
33  public:
34 
35  utf8_checker_t() = default;
36 
37  bool
38  process_byte( std::uint8_t byte )
39  {
40  check_overlong( byte );
41 
43  {
44  // check byte is 10xxxxxx.
45  if( (byte & 0xC0) == 0x80 )
46  {
47  m_current_symbol <<= 6;
48  byte &= 0x3F;
49 
50  m_current_symbol |= byte;
51 
52  if( --m_current_symbol_rest_bytes == 0 )
53  {
55  }
56  }
57  else
58  {
60  }
61  }
62  else
63  {
64  m_current_symbol = 0;
65 
66  if( (byte & 0x80) == 0x00)
67  {
68  // mask 0xxxxxxx
70  }
71  else if( (byte & 0xE0) == 0xC0)
72  {
73  // mask 110xxxxx
75  byte &= 0x1F;
76  }
77  else if( (byte & 0xF0) == 0xE0)
78  {
79  // mask 1110xxxx
81  byte &= 0xF;
82  }
83  else if( (byte & 0xF8) == 0xF0)
84  {
85  // mask 11110xxx
87  byte &= 0x7;
88  }
89  else if( (byte & 0xFC) == 0xF8)
90  {
91  // mask 111110xx
93  byte &= 0x3;
94  }
95  else if( (byte & 0xFE) == 0xFC)
96  {
97  // mask 1111110x
99  byte &= 0x1;
100  }
101  else
102  {
104  }
105 
106  m_current_symbol = byte;
107  }
108 
110  }
111 
112  bool
113  final() const
114  {
115  return m_current_symbol_rest_bytes == 0;
116  }
117 
118  void
120  {
121  m_current_symbol = 0;
123  }
124 
125  private:
126 
127  void
129  {
130  if( (m_current_symbol >= 0xD800 && m_current_symbol <= 0xDFFF) ||
131  (m_current_symbol >= 0x110000) )
132  {
134  }
135  }
136 
137  void
138  check_overlong( std::uint8_t byte )
139  {
140  if( m_current_symbol_rest_bytes > 0 &&
142  {
143  if( m_current_symbol_rest_bytes == 2 &&
144  (byte & 0xE0) == 0x80 )
146  else if( m_current_symbol_rest_bytes == 3 &&
147  (byte & 0xF0) == 0x80 )
149  else if( m_current_symbol_rest_bytes == 4 &&
150  (byte & 0xF8) == 0x80 )
152  else if( m_current_symbol_rest_bytes == 5 &&
153  (byte & 0xFC) == 0x80 )
155  else
157  }
158  else
159  {
160  if( byte == 0xC0 || byte == 0xC1 )
161  {
163  }
164  else if( byte == 0xE0 )
165  {
167  }
168  else if( byte == 0xF0 )
169  {
171  }
172  if( byte == 0xF8 )
173  {
175  }
176  if( byte == 0xFC )
177  {
179  }
180  }
181  }
182 
184 
186 
187  enum class state_t
188  {
189  valid,
190  invalid,
192  overlong
193  };
194 
196 };
197 
198 //
199 // check_utf8_is_correct
200 //
201 
202 inline bool
203 check_utf8_is_correct( string_view_t sv )
204 {
205  utf8_checker_t checker;
206 
207  for( const auto & ch : sv )
208  {
209  if( ! checker.process_byte( static_cast<std::uint8_t>(ch) ))
210  {
211  return false;
212  }
213  }
214 
215  return checker.final();
216 }
217 
218 } /* namespace impl */
219 
220 } /* namespace basic */
221 
222 } /* namespace websocket */
223 
224 } /* namespace restinio */
bool check_utf8_is_correct(string_view_t sv)
Definition: utf8.hpp:203
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
Definition: value_or.hpp:64