Create StringExtensions in azure core internal (#1837)

This commit is contained in:
Victor Vazquez 2021-03-10 22:13:51 +00:00 committed by GitHub
parent 2562df6682
commit 7fca169d25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 70 additions and 55 deletions

View File

@ -21,11 +21,12 @@ namespace Azure { namespace Core {
* comparison.
*/
using CaseInsensitiveMap
= std::map<std::string, std::string, _internal::Strings::CaseInsensitiveComparator>;
= std::map<std::string, std::string, _internal::StringExtensions::CaseInsensitiveComparator>;
/**
* @brief A type alias of `std::set<std::string>` with case-insensitive element comparison.
*/
using CaseInsensitiveSet = std::set<std::string, _internal::Strings::CaseInsensitiveComparator>;
using CaseInsensitiveSet
= std::set<std::string, _internal::StringExtensions::CaseInsensitiveComparator>;
}} // namespace Azure::Core

View File

@ -11,21 +11,31 @@
#include <algorithm>
#include <string>
namespace Azure { namespace Core { namespace _internal { namespace Strings {
namespace Azure { namespace Core { namespace _internal {
bool LocaleInvariantCaseInsensitiveEqual(const std::string& lhs, const std::string& rhs) noexcept;
std::string const ToLower(const std::string& src) noexcept;
unsigned char ToLower(const unsigned char src) noexcept;
struct CaseInsensitiveComparator
/**
* @brief Extend the functionality of std::string by offering static methods for string
* operations.
*
*/
struct StringExtensions
{
bool operator()(const std::string& lhs, const std::string& rhs) const
struct CaseInsensitiveComparator
{
return std::lexicographical_compare(
lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](char c1, char c2) {
return ToLower(c1) < ToLower(c2);
});
}
bool operator()(const std::string& lhs, const std::string& rhs) const
{
return std::lexicographical_compare(
lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](char c1, char c2) {
return ToLower(c1) < ToLower(c2);
});
}
};
static bool LocaleInvariantCaseInsensitiveEqual(
const std::string& lhs,
const std::string& rhs) noexcept;
static std::string const ToLower(const std::string& src) noexcept;
static unsigned char ToLower(const unsigned char src) noexcept;
};
}}}} // namespace Azure::Core::_internal::Strings
}}} // namespace Azure::Core::_internal

View File

@ -53,7 +53,8 @@ namespace Azure { namespace Core {
*/
bool operator==(const OperationStatus& other) const noexcept
{
return _internal::Strings::LocaleInvariantCaseInsensitiveEqual(m_value, other.m_value);
return _internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual(
m_value, other.m_value);
}
/**

View File

@ -51,7 +51,7 @@ Logger::Level const* GetEnvironmentLogLevel()
if (envVar)
{
auto const logLevelStr = _internal::Strings::ToLower(envVar);
auto const logLevelStr = _internal::StringExtensions::ToLower(envVar);
// See https://github.com/Azure/azure-sdk-for-java/wiki/Logging-with-Azure-SDK
// And

View File

@ -30,7 +30,7 @@ void RawResponse::SetHeader(uint8_t const* const first, uint8_t const* const las
}
// Always toLower() headers
auto headerName = Azure::Core::_internal::Strings::ToLower(std::string(start, end));
auto headerName = Azure::Core::_internal::StringExtensions::ToLower(std::string(start, end));
start = end + 1; // start value
while (start < last && (*start == ' ' || *start == '\t'))
{

View File

@ -24,7 +24,7 @@ static Azure::Core::CaseInsensitiveMap MergeMaps(
void Request::SetHeader(std::string const& name, std::string const& value)
{
auto headerNameLowerCase = Azure::Core::_internal::Strings::ToLower(name);
auto headerNameLowerCase = Azure::Core::_internal::StringExtensions::ToLower(name);
return this->m_retryModeEnabled
? _detail::InsertHeaderWithValidation(this->m_retryHeaders, headerNameLowerCase, value)
: _detail::InsertHeaderWithValidation(this->m_headers, headerNameLowerCase, value);

View File

@ -22,7 +22,7 @@ Url::Url(const std::string& url)
{
std::transform(url.begin(), url.begin() + schemeIter, std::back_inserter(m_scheme), [](char c) {
return static_cast<char>(
Azure::Core::_internal::Strings::ToLower(static_cast<unsigned char>(c)));
Azure::Core::_internal::StringExtensions::ToLower(static_cast<unsigned char>(c)));
});
pos = url.begin() + schemeIter + schemeEnd.length();

View File

@ -67,14 +67,14 @@ const unsigned char LocaleInvariantLowercaseTable[256] = {
};
} // unnamed namespace
namespace Azure { namespace Core { namespace _internal { namespace Strings {
namespace Azure { namespace Core { namespace _internal {
unsigned char ToLower(const unsigned char symbol) noexcept
unsigned char StringExtensions::ToLower(const unsigned char symbol) noexcept
{
return LocaleInvariantLowercaseTable[symbol];
}
std::string const ToLower(const std::string& src) noexcept
std::string const StringExtensions::ToLower(const std::string& src) noexcept
{
auto result = std::string(src);
for (auto i = result.begin(); i < result.end(); i++)
@ -84,7 +84,9 @@ namespace Azure { namespace Core { namespace _internal { namespace Strings {
return result;
}
bool LocaleInvariantCaseInsensitiveEqual(const std::string& lhs, const std::string& rhs) noexcept
bool StringExtensions::LocaleInvariantCaseInsensitiveEqual(
const std::string& lhs,
const std::string& rhs) noexcept
{
return std::equal(
lhs.begin(),
@ -97,4 +99,4 @@ namespace Azure { namespace Core { namespace _internal { namespace Strings {
});
}
}}}} // namespace Azure::Core::_internal::Strings
}}} // namespace Azure::Core::_internal

View File

@ -7,31 +7,31 @@
TEST(String, invariantCompare)
{
using Azure::Core::_internal::Strings::LocaleInvariantCaseInsensitiveEqual;
EXPECT_TRUE(LocaleInvariantCaseInsensitiveEqual("", ""));
EXPECT_TRUE(LocaleInvariantCaseInsensitiveEqual("a", "a"));
EXPECT_TRUE(LocaleInvariantCaseInsensitiveEqual("A", "a"));
EXPECT_TRUE(LocaleInvariantCaseInsensitiveEqual("AA", "aa"));
EXPECT_TRUE(LocaleInvariantCaseInsensitiveEqual("aA", "aa"));
EXPECT_TRUE(LocaleInvariantCaseInsensitiveEqual("ABC", "abc"));
EXPECT_FALSE(LocaleInvariantCaseInsensitiveEqual("", "a"));
EXPECT_FALSE(LocaleInvariantCaseInsensitiveEqual("a", ""));
EXPECT_FALSE(LocaleInvariantCaseInsensitiveEqual("A", "aA"));
EXPECT_FALSE(LocaleInvariantCaseInsensitiveEqual("ABC", "abcd"));
using Azure::Core::_internal::StringExtensions;
EXPECT_TRUE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("", ""));
EXPECT_TRUE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("a", "a"));
EXPECT_TRUE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("A", "a"));
EXPECT_TRUE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("AA", "aa"));
EXPECT_TRUE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("aA", "aa"));
EXPECT_TRUE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("ABC", "abc"));
EXPECT_FALSE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("", "a"));
EXPECT_FALSE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("a", ""));
EXPECT_FALSE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("A", "aA"));
EXPECT_FALSE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("ABC", "abcd"));
}
TEST(String, toLower)
{
using Azure::Core::_internal::Strings::ToLower;
EXPECT_TRUE(ToLower("") == "");
EXPECT_TRUE(ToLower("a") == "a");
EXPECT_TRUE(ToLower("A") == "a");
EXPECT_TRUE(ToLower("AA") == "aa");
EXPECT_TRUE(ToLower("aA") == "aa");
EXPECT_TRUE(ToLower("ABC") == "abc");
EXPECT_TRUE(ToLower("ABC-1-,!@#$%^&*()_+=ABC") == "abc-1-,!@#$%^&*()_+=abc");
EXPECT_FALSE(ToLower("") == "a");
EXPECT_FALSE(ToLower("a") == "");
EXPECT_FALSE(ToLower("a") == "aA");
EXPECT_FALSE(ToLower("abc") == "abcd");
using Azure::Core::_internal::StringExtensions;
EXPECT_TRUE(StringExtensions::ToLower("") == "");
EXPECT_TRUE(StringExtensions::ToLower("a") == "a");
EXPECT_TRUE(StringExtensions::ToLower("A") == "a");
EXPECT_TRUE(StringExtensions::ToLower("AA") == "aa");
EXPECT_TRUE(StringExtensions::ToLower("aA") == "aa");
EXPECT_TRUE(StringExtensions::ToLower("ABC") == "abc");
EXPECT_TRUE(StringExtensions::ToLower("ABC-1-,!@#$%^&*()_+=ABC") == "abc-1-,!@#$%^&*()_+=abc");
EXPECT_FALSE(StringExtensions::ToLower("") == "a");
EXPECT_FALSE(StringExtensions::ToLower("a") == "");
EXPECT_FALSE(StringExtensions::ToLower("a") == "aA");
EXPECT_FALSE(StringExtensions::ToLower("abc") == "abcd");
}

View File

@ -41,7 +41,8 @@ inline Azure::Perf::TestMetadata const* GetTestMetadata(
for (auto& test : tests)
{
if (Azure::Core::_internal::Strings::LocaleInvariantCaseInsensitiveEqual(test.Name, testName))
if (Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual(
test.Name, testName))
{
return &test;
}

View File

@ -31,14 +31,14 @@ TEST_F(MockedTransportAdapterTest, keyvaultTelemetryId)
auto foundHeader = false;
for (auto& header : response.GetRawResponse().GetHeaders())
{
if (Azure::Core::_internal::Strings::LocaleInvariantCaseInsensitiveEqual(
if (Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual(
header.first, "User-Agent"))
{
foundHeader = true;
EXPECT_PRED2(
[](std::string const& received, std::string const& sent) {
auto telemetryInfoWithNoOSAndDate = received.substr(0, sent.size());
return Azure::Core::_internal::Strings::LocaleInvariantCaseInsensitiveEqual(
return Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual(
telemetryInfoWithNoOSAndDate, sent);
},
header.second,

View File

@ -32,7 +32,7 @@ namespace Azure { namespace Storage { namespace _detail {
"If-Unmodified-Since",
"Range"})
{
auto ite = headers.find(Azure::Core::_internal::Strings::ToLower(headerName));
auto ite = headers.find(Azure::Core::_internal::StringExtensions::ToLower(headerName));
if (ite != headers.end())
{
if (headerName == "Content-Length" && ite->second == "0")
@ -54,7 +54,7 @@ namespace Azure { namespace Storage { namespace _detail {
ite != headers.end() && ite->first.substr(0, prefix.length()) == prefix;
++ite)
{
std::string key = Azure::Core::_internal::Strings::ToLower(ite->first);
std::string key = Azure::Core::_internal::StringExtensions::ToLower(ite->first);
ordered_kv.emplace_back(std::make_pair(std::move(key), ite->second));
}
std::sort(ordered_kv.begin(), ordered_kv.end());
@ -68,7 +68,7 @@ namespace Azure { namespace Storage { namespace _detail {
string_to_sign += "/" + m_credential->AccountName + "/" + request.GetUrl().GetPath() + "\n";
for (const auto& query : request.GetUrl().GetQueryParameters())
{
std::string key = Azure::Core::_internal::Strings::ToLower(query.first);
std::string key = Azure::Core::_internal::StringExtensions::ToLower(query.first);
ordered_kv.emplace_back(std::make_pair(
Azure::Core::Http::Url::Decode(key), Azure::Core::Http::Url::Decode(query.second)));
}

View File

@ -172,7 +172,7 @@ namespace Azure { namespace Storage { namespace Test {
std::string LowercaseRandomString(size_t size)
{
return Azure::Core::_internal::Strings::ToLower(RandomString(size));
return Azure::Core::_internal::StringExtensions::ToLower(RandomString(size));
}
Storage::Metadata RandomMetadata(size_t size)