blob: 8295d3a29b2ef39a47aa8920ab3bdfa1bcee5885 [file] [log] [blame]
// Copyright 2015 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Some free functions for manipulating strings as URIs. Wherever possible,
// these functions take const references to StringView to avoid unnecessary
// copies.
#include "android/base/StringView.h"
#include "android/base/StringFormat.h"
#include <string>
#include <type_traits>
#include <utility>
namespace android {
namespace base {
class Uri {
public:
// |Encode| is aggressive -- it will always encode a reserved character,
// disregarding a possibly included URL scheme.
static std::string Encode(StringView uri);
// |Decode| is aggressive. It will decode every occurance of %XX in a single
// pass -- even for unreserved characters.
// Returns empty string on error.
static std::string Decode(StringView uri);
// Set of functions for arguments encoding
struct FormatHelper {
// Anything which can potentially have encodable character goes here and
// is encoded into a const char*
static std::string encodeArg(StringView str);
// Forward the rest as-is (non-StringView types)
template <class T>
static T&& encodeArg(T&& t,
typename std::enable_if<
!std::is_convertible<
typename std::decay<T>::type, StringView
>::value
>::type* = nullptr) {
// Don't allow single char parameters as they have a '%c' format
// specifier but potentially may encode into a whole string. This
// is very confusing for the user (which format to use - %c or %s?)
// and is too error-prone (how to make sure no one later
// 'fixes' 'wrong' format?)
static_assert(!std::is_same<typename std::decay<T>::type, char>::value,
"Uri::FormatEncodeArguments() does not support arguments of type 'char'");
return std::forward<T>(t);
}
};
// A small convenience method to encode all arguments when formatting the
// string, but don't touch the |format| string itself
template <class... Args>
static std::string FormatEncodeArguments(const char* format,
Args&&... args) {
return android::base::StringFormat(
format,
FormatHelper::encodeArg(std::forward<Args>(args))...);
}
};
} // namespace base
} // namespace android