Skip to content

Commit

Permalink
some optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
lemire committed Nov 13, 2023
1 parent e0ee054 commit 0d00f61
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
4 changes: 3 additions & 1 deletion include/ada/checkers.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ ada_really_inline bool begins_with(std::string_view view,
std::string_view prefix);

/**
* Returns true if an input is an ipv4 address.
* Returns true if an input is an ipv4 address. It is assumed that the string
* does not contain uppercase ASCII characters (the input should have been
* lowered cased before calling this function) and is not empty.
*/
ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept;

Expand Down
35 changes: 32 additions & 3 deletions src/checkers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
namespace ada::checkers {

ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept {
// The string is not empty and does not contain upper case ASCII characters.
//
// Optimization. To be considered as a possible ipv4, the string must end
// with 'x' or a lowercase hex character.
// Most of the time, this will be false so this simple check will save a lot
// of effort.
const char last_char = view.back();
bool possible_ipv4 = (last_char >= '0' && last_char <= '9') ||
(last_char >= 'a' && last_char <= 'f') ||
last_char == 'x';
if (!possible_ipv4) {
return false;
}
// From the last character, find the last dot.
size_t last_dot = view.rfind('.');
if (last_dot != std::string_view::npos) {
// We have at least one dot.
Expand All @@ -20,6 +34,8 @@ ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept {
view = view.substr(last_dot + 1);
}
}
// We may have an empty result if the address ends with two dots (..).
// It is an unlikely case.
if (view.empty()) {
return false;
}
Expand All @@ -29,9 +45,22 @@ ada_really_inline ada_constexpr bool is_ipv4(std::string_view view) noexcept {
if (std::all_of(view.begin(), view.end(), ada::checkers::is_digit)) {
return true;
}
return (checkers::has_hex_prefix(view) &&
(view.size() == 2 || std::all_of(view.begin() + 2, view.end(),
ada::unicode::is_lowercase_hex)));
// It could be hex (0x), but not if there is a single character.
if(view.size() == 1) {
return false;
}
// It must start with 0x.
if(!std::equal(view.begin(), view.begin() + 2, "0x")) {
return false;
}
// We must allow "0x".
if(view.size() == 2) {
return true;
}
// We have 0x followed by some characters, we need to check that they are
// hexadecimals.
return std::all_of(view.begin() + 2, view.end(),
ada::unicode::is_lowercase_hex);
}

// for use with path_signature, we include all characters that need percent
Expand Down

0 comments on commit 0d00f61

Please sign in to comment.