Skip to content

Commit

Permalink
Optimize port state
Browse files Browse the repository at this point in the history
* Do not convert port to int if it contains more than 5 digits

* Avoid converting int to string when appending port to URL
  • Loading branch information
rmisev committed Aug 5, 2024
1 parent 1a18bad commit 7734cc8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
21 changes: 13 additions & 8 deletions include/upa/url.h
Original file line number Diff line number Diff line change
Expand Up @@ -1952,19 +1952,24 @@ inline validation_errc url_parser::url_parse(url_serializer& urls, const CharT*

if (is_end_of_authority || state_override) {
if (pointer < end_of_digits) {
// is port
// url string contains port
// skip the leading zeros except the last
pointer = std::find_if(pointer, end_of_digits - 1, [](CharT c) { return c != '0'; });
// check port <= 65535 (0xFFFF)
if (std::distance(pointer, end_of_digits) > 5)
return validation_errc::port_out_of_range;
// port length <= 5
int port = 0;
for (auto it = pointer; it < end_of_digits; ++it) {
for (auto it = pointer; it < end_of_digits; ++it)
port = port * 10 + (*it - '0');
// 2.1.2. If port is greater than 2^16 − 1, port-out-of-range
// validation error, return failure
if (port > 0xFFFF)
return validation_errc::port_out_of_range;
}
// 2.1.2. If port is greater than 2^16 − 1, port-out-of-range
// validation error, return failure
if (port > 0xFFFF)
return validation_errc::port_out_of_range;
if (urls.need_save()) {
// set port if not default
if (urls.scheme_inf() == nullptr || urls.scheme_inf()->default_port != port) {
util::unsigned_to_str(port, urls.start_part(url::PORT), 10);
util::append(urls.start_part(url::PORT), str_arg<CharT>{ pointer, end_of_digits });
urls.save_part();
urls.set_flag(url::PORT_FLAG);
} else {
Expand Down
18 changes: 15 additions & 3 deletions include/upa/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,28 @@ inline std::size_t add_sizes(std::size_t size1, std::size_t size2, std::size_t m
return size1 + size2;
}

template <class StrT>
inline void append(std::string& dest, const StrT& src) {
#ifdef _MSC_VER
// the value_type of dest and src are the same (char)
template <class StrT,
typename std::enable_if<std::is_same<typename StrT::value_type, char>::value, int>::type = 0>
inline void append(std::string& dest, const StrT& src) {
dest.append(src.begin(), src.end());
}

// the value_type of dest and src are different
template <class StrT,
typename std::enable_if<!std::is_same<typename StrT::value_type, char>::value, int>::type = 0>
inline void append(std::string& dest, const StrT& src) {
dest.reserve(add_sizes(dest.size(), src.size(), dest.max_size()));
for (const auto c : src)
dest.push_back(static_cast<char>(c));
}
#else
template <class StrT>
inline void append(std::string& dest, const StrT& src) {
dest.append(src.begin(), src.end());
#endif
}
#endif

template <class CharT, class UnaryOperation>
inline void append_tr(std::string& dest, const CharT* first, const CharT* last, UnaryOperation unary_op) {
Expand Down

0 comments on commit 7734cc8

Please sign in to comment.