summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-12-06 14:44:55 +0100
committerKonstantin Käfer <mail@kkaefer.com>2016-12-07 10:46:43 +0100
commitdc1bda435fa1345737604767ee71859377d41530 (patch)
treef8d4207e70383513efc765280dcc78bdf43efd84
parentcc6e5c9df9b7b42eba9cdb51bea529c1d5c3a497 (diff)
downloadqtlocation-mapboxgl-dc1bda435fa1345737604767ee71859377d41530.tar.gz
[core] add util::isURL() for checking whether a string starts with a URL scheme
-rw-r--r--cmake/test-files.cmake1
-rw-r--r--src/mbgl/util/url.cpp35
-rw-r--r--src/mbgl/util/url.hpp1
-rw-r--r--test/util/url.test.cpp25
4 files changed, 60 insertions, 2 deletions
diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake
index ceff50ef64..7d8dc82756 100644
--- a/cmake/test-files.cmake
+++ b/cmake/test-files.cmake
@@ -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
)
diff --git a/src/mbgl/util/url.cpp b/src/mbgl/util/url.cpp
index bf6fc70ff5..9831bc9038 100644
--- a/src/mbgl/util/url.cpp
+++ b/src/mbgl/util/url.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
diff --git a/src/mbgl/util/url.hpp b/src/mbgl/util/url.hpp
index b9c66261df..2d18f7476a 100644
--- a/src/mbgl/util/url.hpp
+++ b/src/mbgl/util/url.hpp
@@ -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
diff --git a/test/util/url.test.cpp b/test/util/url.test.cpp
new file mode 100644
index 0000000000..c0ee30efab
--- /dev/null
+++ b/test/util/url.test.cpp
@@ -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"));
+}