| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/url
- //
- #ifndef BOOST_URL_DETAIL_IMPL_DECODE_IPP
- #define BOOST_URL_DETAIL_IMPL_DECODE_IPP
- #include <boost/url/detail/decode.hpp>
- #include <boost/url/grammar/charset.hpp>
- #include <memory>
- namespace boost {
- namespace urls {
- namespace detail {
- char
- decode_one(
- char const* const it) noexcept
- {
- auto d0 = grammar::hexdig_value(it[0]);
- auto d1 = grammar::hexdig_value(it[1]);
- return static_cast<char>(
- ((static_cast<
- unsigned char>(d0) << 4) +
- (static_cast<
- unsigned char>(d1))));
- }
- std::size_t
- decode_bytes_unsafe(
- string_view s) noexcept
- {
- auto p = s.begin();
- auto const end = s.end();
- std::size_t dn = 0;
- if(s.size() >= 3)
- {
- auto const safe_end = end - 2;
- while(p < safe_end)
- {
- if(*p != '%')
- p += 1;
- else
- p += 3;
- ++dn;
- }
- }
- dn += end - p;
- return dn;
- }
- std::size_t
- decode_unsafe(
- char* const dest0,
- char const* end,
- string_view s,
- encoding_opts opt) noexcept
- {
- auto it = s.data();
- auto const last = it + s.size();
- auto dest = dest0;
- if(opt.space_as_plus)
- {
- while(it != last)
- {
- if(dest == end)
- {
- // dest too small
- return dest - dest0;
- }
- if(*it == '+')
- {
- // plus to space
- *dest++ = ' ';
- ++it;
- continue;
- }
- if(*it == '%')
- {
- // escaped
- ++it;
- if(last - it < 2)
- {
- // missing input,
- // initialize output
- std::memset(dest,
- 0, end - dest);
- return dest - dest0;
- }
- *dest++ = decode_one(it);
- it += 2;
- continue;
- }
- // unescaped
- *dest++ = *it++;
- }
- return dest - dest0;
- }
- while(it != last)
- {
- if(dest == end)
- {
- // dest too small
- return dest - dest0;
- }
- if(*it == '%')
- {
- // escaped
- ++it;
- if(last - it < 2)
- {
- // missing input,
- // initialize output
- std::memset(dest,
- 0, end - dest);
- return dest - dest0;
- }
- *dest++ = decode_one(it);
- it += 2;
- continue;
- }
- // unescaped
- *dest++ = *it++;
- }
- return dest - dest0;
- }
- } // detail
- } // urls
- } // boost
- #endif
|