10 #ifndef BOOST_BEAST_WEBSOCKET_DETAIL_UTF8_CHECKER_HPP 11 #define BOOST_BEAST_WEBSOCKET_DETAIL_UTF8_CHECKER_HPP 14 #include <boost/asio/buffer.hpp> 15 #include <boost/assert.hpp> 30 template<
class =
void>
33 std::size_t need_ = 0;
34 std::uint8_t* p_ = cp_;
53 write(std::uint8_t
const* in, std::size_t size);
59 template<
class ConstBufferSequence>
78 auto const success = need_ == 0;
84 template<
class ConstBufferSequence>
90 "ConstBufferSequence requirements not met");
91 using boost::asio::buffer_cast;
92 using boost::asio::buffer_size;
93 for(boost::asio::const_buffer b : bs)
94 if(!
write(buffer_cast<std::uint8_t const*>(b),
103 write(std::uint8_t
const* in, std::size_t size)
106 [](std::uint8_t
const*& p)
113 if((p[0] & 0x60) == 0x40)
115 if((p[1] & 0xc0) != 0x80)
120 if((p[0] & 0xf0) == 0xe0)
122 if((p[1] & 0xc0) != 0x80 ||
123 (p[2] & 0xc0) != 0x80 ||
124 (p[0] == 224 && p[1] < 160) ||
125 (p[0] == 237 && p[1] > 159))
130 if((p[0] & 0xf8) == 0xf0)
133 (p[1] & 0xc0) != 0x80 ||
134 (p[2] & 0xc0) != 0x80 ||
135 (p[3] & 0xc0) != 0x80 ||
136 (p[0] == 240 && p[1] < 144) ||
137 (p[0] == 244 && p[1] > 143))
144 auto const valid_have =
147 if((cp_[0] & 0x60) == 0x40)
148 return cp_[0] <= 223;
149 if((cp_[0] & 0xf0) == 0xe0)
152 ((cp_[1] & 0xc0) != 0x80 ||
153 (cp_[0] == 224 && cp_[1] < 160) ||
154 (cp_[0] == 237 && cp_[1] > 159)))
158 if((cp_[0] & 0xf8) == 0xf0)
160 auto const n = p_ - cp_;
161 if(n > 2 && (cp_[2] & 0xc0) != 0x80)
164 ((cp_[1] & 0xc0) != 0x80 ||
165 (cp_[0] == 240 && cp_[1] < 144) ||
166 (cp_[0] == 244 && cp_[1] > 143)))
172 [](std::uint8_t
const v)
187 auto const end = in + size;
193 auto n = (std::min)(size, need_);
200 BOOST_ASSERT(p_ <= cp_ + 5);
206 BOOST_ASSERT(in == end);
215 std::uint8_t
const* p = &cp_[0];
221 if(size <=
sizeof(std::size_t))
227 auto last =
reinterpret_cast<std::uint8_t const*
>(
228 ((
reinterpret_cast<std::uintptr_t
>(in) +
sizeof(std::size_t) - 1) /
229 sizeof(std::size_t)) *
sizeof(std::size_t));
237 size = size - (in - in0);
242 size = size - (in - in0);
248 auto last = in + size - 7;
249 auto constexpr mask =
static_cast< 250 std::size_t
>(0x8080808080808080 & ~
std::size_t{0});
255 std::memcpy(&temp, in,
sizeof(temp));
256 if((temp & mask) != 0)
259 if((*reinterpret_cast<std::size_t const*>(in) & mask) != 0)
262 size = size - (in - in0);
265 in +=
sizeof(std::size_t);
278 auto last = in + size - 3;
300 auto const need = needed(*in);
318 BOOST_ASSERT(in == end);
319 BOOST_ASSERT(p_ <= cp_ + 5);
332 template<
class =
void>
337 if(! c.
write(reinterpret_cast<const uint8_t*>(p), n))
BufferSequence< boost::asio::const_buffer > ConstBufferSequence
Definition: type_traits.hpp:280
Definition: async_result.hpp:20
void reset()
Definition: utf8_checker.hpp:67
bool finish()
Definition: utf8_checker.hpp:76
bool write(std::uint8_t const *in, std::size_t size)
Definition: utf8_checker.hpp:103
Definition: utf8_checker.hpp:31
Definition: type_traits.hpp:59
bool check_utf8(char const *p, std::size_t n)
Definition: utf8_checker.hpp:334