[core] add util::isURL() for checking whether a string starts with a URL scheme
This commit is contained in:
@@ -112,5 +112,6 @@ set(MBGL_TEST_FILES
|
||||
test/util/tile_cover.test.cpp
|
||||
test/util/timer.test.cpp
|
||||
test/util/token.test.cpp
|
||||
test/util/url.test.cpp
|
||||
test/util/work_queue.test.cpp
|
||||
)
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
#include <mbgl/util/url.hpp>
|
||||
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// std::alnum etc. suffer from locale-dependence.
|
||||
|
||||
inline bool isAlphaCharacter(char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
}
|
||||
|
||||
inline bool isAlphaNumericCharacter(char c) {
|
||||
return isAlphaCharacter(c) || (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
inline bool isSchemeCharacter(char c) {
|
||||
return isAlphaNumericCharacter(c) || c == '-' || c == '+' || c == '.';
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
@@ -17,7 +35,7 @@ std::string percentEncode(const std::string& input) {
|
||||
encoded << std::hex;
|
||||
|
||||
for (auto c : input) {
|
||||
if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
if (isAlphaNumericCharacter(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
encoded << c;
|
||||
} else {
|
||||
encoded << '%' << std::setw(2) << int(c);
|
||||
@@ -47,5 +65,18 @@ std::string percentDecode(const std::string& input) {
|
||||
return decoded;
|
||||
}
|
||||
|
||||
// Checks whether the input string contains ://, and the part before it is all alphanumeric ASCII.
|
||||
bool isURL(const std::string& input) {
|
||||
auto it = input.begin();
|
||||
// First character has to be alphabetic
|
||||
if (it == input.end() || !isAlphaCharacter(*it++)) return false;
|
||||
// The remaining characters of the scheme can be alphanumeric, or be one of +.-
|
||||
while (it != input.end() && isSchemeCharacter(*it)) ++it;
|
||||
// Check that :// follows
|
||||
return (it != input.end() && *it++ == ':') &&
|
||||
(it != input.end() && *it++ == '/') &&
|
||||
(it != input.end() && *it++ == '/');
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace util {
|
||||
|
||||
std::string percentEncode(const std::string&);
|
||||
std::string percentDecode(const std::string&);
|
||||
bool isURL(const std::string&);
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
25
test/util/url.test.cpp
Normal file
25
test/util/url.test.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/util/url.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace mbgl::util;
|
||||
|
||||
TEST(URL, isURL) {
|
||||
EXPECT_TRUE(isURL("mapbox://foo"));
|
||||
EXPECT_TRUE(isURL("mapbox://"));
|
||||
EXPECT_TRUE(isURL("mapbox-test-scheme://foo"));
|
||||
EXPECT_TRUE(isURL("mapbox+style://foo"));
|
||||
EXPECT_TRUE(isURL("mapbox-2.0://foo"));
|
||||
EXPECT_TRUE(isURL("mapbox99://foo"));
|
||||
|
||||
EXPECT_FALSE(isURL("mapbox:/"));
|
||||
EXPECT_FALSE(isURL(" mapbox://"));
|
||||
EXPECT_FALSE(isURL("://"));
|
||||
EXPECT_FALSE(isURL("mapbox"));
|
||||
EXPECT_FALSE(isURL("mapbox:foo"));
|
||||
EXPECT_FALSE(isURL("mapbox:/foo"));
|
||||
EXPECT_FALSE(isURL("test/mapbox://foo"));
|
||||
EXPECT_FALSE(isURL("123://foo"));
|
||||
}
|
||||
Reference in New Issue
Block a user