| 221 | |
| 222 | template <typename octet_iterator> |
| 223 | utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) |
| 224 | { |
| 225 | // Save the original value of it so we can go back in case of failure |
| 226 | // Of course, it does not make much sense with i.e. stream iterators |
| 227 | octet_iterator original_it = it; |
| 228 | |
| 229 | uint32_t cp = 0; |
| 230 | // Determine the sequence length based on the lead octet |
| 231 | typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type; |
| 232 | const octet_difference_type length = utf8::internal::sequence_length(it); |
| 233 | |
| 234 | // Get trail octets and calculate the code point |
| 235 | utf_error err = UTF8_OK; |
| 236 | switch (length) { |
| 237 | case 0: |
| 238 | return INVALID_LEAD; |
| 239 | case 1: |
| 240 | err = utf8::internal::get_sequence_1(it, end, cp); |
| 241 | break; |
| 242 | case 2: |
| 243 | err = utf8::internal::get_sequence_2(it, end, cp); |
| 244 | break; |
| 245 | case 3: |
| 246 | err = utf8::internal::get_sequence_3(it, end, cp); |
| 247 | break; |
| 248 | case 4: |
| 249 | err = utf8::internal::get_sequence_4(it, end, cp); |
| 250 | break; |
| 251 | } |
| 252 | |
| 253 | if (err == UTF8_OK) { |
| 254 | // Decoding succeeded. Now, security checks... |
| 255 | if (utf8::internal::is_code_point_valid(cp)) { |
| 256 | if (!utf8::internal::is_overlong_sequence(cp, length)){ |
| 257 | // Passed! Return here. |
| 258 | code_point = cp; |
| 259 | ++it; |
| 260 | return UTF8_OK; |
| 261 | } |
| 262 | else |
| 263 | err = OVERLONG_SEQUENCE; |
| 264 | } |
| 265 | else |
| 266 | err = INVALID_CODE_POINT; |
| 267 | } |
| 268 | |
| 269 | // Failure branch - restore the original value of the iterator |
| 270 | it = original_it; |
| 271 | return err; |
| 272 | } |
| 273 | |
| 274 | template <typename octet_iterator> |
| 275 | inline utf_error validate_next(octet_iterator& it, octet_iterator end) { |
no test coverage detected