Replaces the usage of boost::string_view with std::string_view (#4509)

This commit is contained in:
Chenna Keshava B S
2024-06-17 13:41:03 -07:00
committed by GitHub
parent 06733ec21a
commit 825864032a
24 changed files with 132 additions and 91 deletions

View File

@@ -107,6 +107,20 @@ then you will need to choose the `libstdc++11` ABI:
conan profile update settings.compiler.libcxx=libstdc++11 default
```
Ensure inter-operability between `boost::string_view` and `std::string_view` types:
```
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_BEAST_USE_STD_STRING_VIEW"]' default
conan profile update 'env.CXXFLAGS="-DBOOST_BEAST_USE_STD_STRING_VIEW"' default
```
If you have other flags in the `conf.tools.build` or `env.CXXFLAGS` sections, make sure to retain the existing flags and append the new ones. You can check them with:
```
conan profile show default
```
**Windows** developers may need to use the x64 native build tools.
An easy way to do that is to run the shortcut "x64 Native Tools Command
Prompt" for the version of Visual Studio that you have installed.

View File

@@ -633,7 +633,7 @@ public:
*/
std::optional<Json::Value>
getAvailable(
boost::beast::string_view const& pubKey,
std::string_view pubKey,
std::optional<std::uint32_t> forceVersion = {});
/** Return the number of configured validator list sites. */

View File

@@ -34,7 +34,6 @@
#include <boost/regex.hpp>
#include <cmath>
#include <mutex>
#include <numeric>
#include <shared_mutex>
@@ -215,7 +214,8 @@ ValidatorList::load(
return false;
}
auto const id = parseBase58<PublicKey>(TokenType::NodePublic, match[1]);
auto const id =
parseBase58<PublicKey>(TokenType::NodePublic, match[1].str());
if (!id)
{
@@ -1707,7 +1707,7 @@ ValidatorList::for_each_available(
std::optional<Json::Value>
ValidatorList::getAvailable(
boost::beast::string_view const& pubKey,
std::string_view pubKey,
std::optional<std::uint32_t> forceVersion /* = {} */)
{
std::shared_lock read_lock{mutex_};

View File

@@ -110,7 +110,7 @@ strUnHex(std::string const& strSrc)
}
inline std::optional<Blob>
strViewUnHex(boost::string_view const& strSrc)
strViewUnHex(std::string_view strSrc)
{
return strUnHex(strSrc.size(), strSrc.cbegin(), strSrc.cend());
}
@@ -150,7 +150,7 @@ to_uint64(std::string const& s);
doesn't check whether the TLD is valid.
*/
bool
isProperlyFormedTomlDomain(std::string const& domain);
isProperlyFormedTomlDomain(std::string_view domain);
} // namespace ripple

View File

@@ -73,7 +73,7 @@ base64_encode(std::string const& s)
}
std::string
base64_decode(std::string const& data);
base64_decode(std::string_view data);
} // namespace ripple

View File

@@ -120,7 +120,7 @@ to_uint64(std::string const& s)
}
bool
isProperlyFormedTomlDomain(std::string const& domain)
isProperlyFormedTomlDomain(std::string_view domain)
{
// The domain must be between 4 and 128 characters long
if (domain.size() < 4 || domain.size() > 128)
@@ -143,7 +143,7 @@ isProperlyFormedTomlDomain(std::string const& domain)
,
boost::regex_constants::optimize);
return boost::regex_match(domain, re);
return boost::regex_match(domain.begin(), domain.end(), re);
}
} // namespace ripple

View File

@@ -242,7 +242,7 @@ base64_encode(std::uint8_t const* data, std::size_t len)
}
std::string
base64_decode(std::string const& data)
base64_decode(std::string_view data)
{
std::string dest;
dest.resize(base64::decoded_size(data.size()));

View File

@@ -20,6 +20,7 @@
#ifndef BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
#define BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
#include <boost/core/detail/string_view.hpp>
#include <algorithm>
#include <cassert>
#include <cerrno>
@@ -64,9 +65,9 @@ struct LexicalCast<std::string, In>
}
};
// Parse std::string to number
template <class Out>
struct LexicalCast<Out, std::string>
// Parse a std::string_view into a number
template <typename Out>
struct LexicalCast<Out, std::string_view>
{
explicit LexicalCast() = default;
@@ -78,7 +79,7 @@ struct LexicalCast<Out, std::string>
std::enable_if_t<
std::is_integral_v<Integral> && !std::is_same_v<Integral, bool>,
bool>
operator()(Integral& out, std::string const& in) const
operator()(Integral& out, std::string_view in) const
{
auto first = in.data();
auto last = in.data() + in.size();
@@ -92,20 +93,23 @@ struct LexicalCast<Out, std::string>
}
bool
operator()(bool& out, std::string in) const
operator()(bool& out, std::string_view in) const
{
std::string result;
// Convert the input to lowercase
std::transform(in.begin(), in.end(), in.begin(), [](auto c) {
std::transform(
in.begin(), in.end(), std::back_inserter(result), [](auto c) {
return std::tolower(static_cast<unsigned char>(c));
});
if (in == "1" || in == "true")
if (result == "1" || result == "true")
{
out = true;
return true;
}
if (in == "0" || in == "false")
if (result == "0" || result == "false")
{
out = false;
return true;
@@ -114,9 +118,38 @@ struct LexicalCast<Out, std::string>
return false;
}
};
//------------------------------------------------------------------------------
// Parse boost library's string_view to number or boolean value
// Note: As of Jan 2024, Boost contains three different types of string_view
// (boost::core::basic_string_view<char>, boost::string_ref and
// boost::string_view). The below template specialization is included because
// it is used in the handshake.cpp file
template <class Out>
struct LexicalCast<Out, boost::core::basic_string_view<char>>
{
explicit LexicalCast() = default;
bool
operator()(Out& out, boost::core::basic_string_view<char> in) const
{
return LexicalCast<Out, std::string_view>()(out, in);
}
};
// Parse std::string to number or boolean value
template <class Out>
struct LexicalCast<Out, std::string>
{
explicit LexicalCast() = default;
bool
operator()(Out& out, std::string in) const
{
return LexicalCast<Out, std::string_view>()(out, in);
}
};
// Conversion from null terminated char const*
template <class Out>
struct LexicalCast<Out, char const*>
@@ -126,7 +159,8 @@ struct LexicalCast<Out, char const*>
bool
operator()(Out& out, char const* in) const
{
return LexicalCast<Out, std::string>()(out, in);
assert(in);
return LexicalCast<Out, std::string_view>()(out, in);
}
};
@@ -140,7 +174,8 @@ struct LexicalCast<Out, char*>
bool
operator()(Out& out, char* in) const
{
return LexicalCast<Out, std::string>()(out, in);
assert(in);
return LexicalCast<Out, std::string_view>()(out, in);
}
};

View File

@@ -22,6 +22,7 @@
#include <boost/beast/core/string.hpp>
#include <functional>
#include <string>
namespace Json {

View File

@@ -17,7 +17,6 @@
*/
//==============================================================================
#include <ripple/app/main/Application.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/core/Config.h>
@@ -27,7 +26,6 @@
#include <ripple/protocol/jss.h>
#include <ripple/protocol/tokens.h>
#include <boost/regex.hpp>
#include <memory.h>
namespace ripple {
@@ -113,7 +111,8 @@ Cluster::load(Section const& nodes)
return false;
}
auto const id = parseBase58<PublicKey>(TokenType::NodePublic, match[1]);
auto const id =
parseBase58<PublicKey>(TokenType::NodePublic, match[1].str());
if (!id)
{

View File

@@ -20,16 +20,12 @@
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/main/Application.h>
#include <ripple/basics/base64.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/beast/core/LexicalCast.h>
#include <ripple/beast/rfc2616.h>
#include <ripple/overlay/impl/Handshake.h>
#include <ripple/protocol/digest.h>
#include <boost/regex.hpp>
#include <algorithm>
#include <chrono>
// VFALCO Shouldn't we have to include the OpenSSL
// headers or something for SSL_get_finished?
@@ -46,8 +42,8 @@ getFeatureValue(
return {};
boost::smatch match;
boost::regex rx(feature + "=([^;\\s]+)");
std::string const value = header->value();
if (boost::regex_search(value, match, rx))
std::string const allFeatures(header->value());
if (boost::regex_search(allFeatures, match, rx))
return {match[1]};
return {};
}
@@ -243,7 +239,7 @@ verifyHandshake(
{
std::uint32_t nid;
if (!beast::lexicalCastChecked(nid, std::string(iter->value())))
if (!beast::lexicalCastChecked(nid, iter->value()))
throw std::runtime_error("Invalid peer network identifier");
if (networkID && nid != *networkID)
@@ -252,8 +248,7 @@ verifyHandshake(
if (auto const iter = headers.find("Network-Time"); iter != headers.end())
{
auto const netTime =
[str = std::string(iter->value())]() -> TimeKeeper::time_point {
auto const netTime = [str = iter->value()]() -> TimeKeeper::time_point {
TimeKeeper::duration::rep val;
if (beast::lexicalCastChecked(val, str))

View File

@@ -39,7 +39,6 @@
#include <ripple/server/SimpleWriter.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/utility/in_place_factory.hpp>
namespace ripple {
@@ -826,7 +825,7 @@ OverlayImpl::getOverlayInfo()
auto version{sp->getVersion()};
if (!version.empty())
// Could move here if Json::value supported moving from strings
pv[jss::version] = version;
pv[jss::version] = std::string{version};
}
std::uint32_t minSeq, maxSeq;
@@ -994,9 +993,9 @@ OverlayImpl::processValidatorList(
return true;
};
auto key = req.target().substr(prefix.size());
std::string_view key = req.target().substr(prefix.size());
if (auto slash = key.find('/'); slash != boost::string_view::npos)
if (auto slash = key.find('/'); slash != std::string_view::npos)
{
auto verString = key.substr(0, slash);
if (!boost::conversion::try_lexical_convert(verString, version))

View File

@@ -33,7 +33,6 @@
#include <ripple/basics/random.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/beast/core/LexicalCast.h>
#include <ripple/beast/core/SemanticVersion.h>
#include <ripple/nodestore/DatabaseShard.h>
#include <ripple/overlay/Cluster.h>
#include <ripple/overlay/impl/PeerImp.h>
@@ -41,7 +40,6 @@
#include <ripple/overlay/predicates.h>
#include <ripple/protocol/digest.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/beast/core/ostream.hpp>
@@ -160,7 +158,7 @@ PeerImp::run()
return post(strand_, std::bind(&PeerImp::run, shared_from_this()));
auto parseLedgerHash =
[](std::string const& value) -> std::optional<uint256> {
[](std::string_view value) -> std::optional<uint256> {
if (uint256 ret; ret.parseHex(value))
return ret;
@@ -397,15 +395,15 @@ PeerImp::json()
}
if (auto const d = domain(); !d.empty())
ret[jss::server_domain] = domain();
ret[jss::server_domain] = std::string{d};
if (auto const nid = headers_["Network-ID"]; !nid.empty())
ret[jss::network_id] = std::string(nid);
ret[jss::network_id] = std::string{nid};
ret[jss::load] = usage_.balance();
if (auto const version = getVersion(); !version.empty())
ret[jss::version] = version;
ret[jss::version] = std::string{version};
ret[jss::protocol] = to_string(protocol_);

View File

@@ -49,7 +49,7 @@ public:
newInboundEndpoint(
beast::IP::Endpoint const& address,
bool const proxy,
boost::string_view const& forwardedFor) = 0;
std::string_view forwardedFor) = 0;
/** Create a new endpoint keyed by outbound IP address and port. */
virtual Consumer

View File

@@ -77,14 +77,13 @@ public:
newInboundEndpoint(
beast::IP::Endpoint const& address,
bool const proxy,
boost::string_view const& forwardedFor) override
std::string_view forwardedFor) override
{
if (!proxy)
return newInboundEndpoint(address);
boost::system::error_code ec;
auto const proxiedIp =
boost::asio::ip::make_address(forwardedFor.to_string(), ec);
auto const proxiedIp = boost::asio::ip::make_address(forwardedFor, ec);
if (ec)
{
journal_.warn()

View File

@@ -57,8 +57,8 @@ struct JsonContext : public Context
*/
struct Headers
{
boost::string_view user;
boost::string_view forwardedFor;
std::string_view user;
std::string_view forwardedFor;
};
Json::Value params;

View File

@@ -56,15 +56,15 @@ requestRole(
Port const& port,
Json::Value const& params,
beast::IP::Endpoint const& remoteIp,
boost::string_view const& user);
std::string_view user);
Resource::Consumer
requestInboundEndpoint(
Resource::Manager& manager,
beast::IP::Endpoint const& remoteAddress,
Role const& role,
boost::string_view const& user,
boost::string_view const& forwardedFor);
std::string_view user,
std::string_view forwardedFor);
/**
* Check if the role entitles the user to unlimited resources.
@@ -85,7 +85,7 @@ ipAllowed(
std::vector<boost::asio::ip::network_v4> const& nets4,
std::vector<boost::asio::ip::network_v6> const& nets6);
boost::string_view
std::string_view
forwardedFor(http_request_type const& request);
} // namespace ripple

View File

@@ -208,8 +208,8 @@ private:
beast::IP::Endpoint const& remoteIPAddress,
Output&&,
std::shared_ptr<JobQueue::Coro> coro,
boost::string_view forwardedFor,
boost::string_view user);
std::string_view forwardedFor,
std::string_view user);
Handoff
statusResponse(http_request_type const& request) const;

View File

@@ -39,13 +39,13 @@ doPing(RPC::JsonContext& context)
break;
case Role::IDENTIFIED:
ret[jss::role] = "identified";
ret[jss::username] = context.headers.user.to_string();
ret[jss::username] = std::string{context.headers.user};
if (context.headers.forwardedFor.size())
ret[jss::ip] = context.headers.forwardedFor.to_string();
ret[jss::ip] = std::string{context.headers.forwardedFor};
break;
case Role::PROXY:
ret[jss::role] = "proxied";
ret[jss::ip] = context.headers.forwardedFor.to_string();
ret[jss::ip] = std::string{context.headers.forwardedFor};
default:;
}

View File

@@ -18,9 +18,7 @@
//==============================================================================
#include <ripple/rpc/Role.h>
#include <boost/beast/core/string.hpp>
#include <boost/beast/http/field.hpp>
#include <boost/beast/http/rfc7230.hpp>
#include <boost/utility/string_view.hpp>
#include <algorithm>
#include <tuple>
@@ -96,7 +94,7 @@ requestRole(
Port const& port,
Json::Value const& params,
beast::IP::Endpoint const& remoteIp,
boost::string_view const& user)
std::string_view user)
{
if (isAdmin(port, params, remoteIp.address()))
return Role::ADMIN;
@@ -142,8 +140,8 @@ requestInboundEndpoint(
Resource::Manager& manager,
beast::IP::Endpoint const& remoteAddress,
Role const& role,
boost::string_view const& user,
boost::string_view const& forwardedFor)
std::string_view user,
std::string_view forwardedFor)
{
if (isUnlimited(role))
return manager.newUnlimitedEndpoint(remoteAddress);
@@ -152,18 +150,18 @@ requestInboundEndpoint(
remoteAddress, role == Role::PROXY, forwardedFor);
}
static boost::string_view
extractIpAddrFromField(boost::string_view field)
static std::string_view
extractIpAddrFromField(std::string_view field)
{
// Lambda to trim leading and trailing spaces on the field.
auto trim = [](boost::string_view str) -> boost::string_view {
boost::string_view ret = str;
auto trim = [](std::string_view str) -> std::string_view {
std::string_view ret = str;
// Only do the work if there's at least one leading space.
if (!ret.empty() && ret.front() == ' ')
{
std::size_t const firstNonSpace = ret.find_first_not_of(' ');
if (firstNonSpace == boost::string_view::npos)
if (firstNonSpace == std::string_view::npos)
// We know there's at least one leading space. So if we got
// npos, then it must be all spaces. Return empty string_view.
return {};
@@ -178,7 +176,7 @@ extractIpAddrFromField(boost::string_view field)
c == ' ' || c == '\r' || c == '\n')
{
std::size_t const lastNonSpace = ret.find_last_not_of(" \r\n");
if (lastNonSpace == boost::string_view::npos)
if (lastNonSpace == std::string_view::npos)
// We know there's at least one leading space. So if we
// got npos, then it must be all spaces.
return {};
@@ -189,7 +187,7 @@ extractIpAddrFromField(boost::string_view field)
return ret;
};
boost::string_view ret = trim(field);
std::string_view ret = trim(field);
if (ret.empty())
return {};
@@ -251,13 +249,13 @@ extractIpAddrFromField(boost::string_view field)
// If there's a port appended to the IP address, strip that by
// terminating at the colon.
if (std::size_t colon = ret.find(':'); colon != boost::string_view::npos)
if (std::size_t colon = ret.find(':'); colon != std::string_view::npos)
ret = ret.substr(0, colon);
return ret;
}
boost::string_view
std::string_view
forwardedFor(http_request_type const& request)
{
// Look for the Forwarded field in the request.
@@ -286,10 +284,9 @@ forwardedFor(http_request_type const& request)
// We found a "for=". Scan for the end of the IP address.
std::size_t const pos = [&found, &it]() {
std::size_t pos =
boost::string_view(found, it->value().end() - found)
std::size_t pos = std::string_view(found, it->value().end() - found)
.find_first_of(",;");
if (pos != boost::string_view::npos)
if (pos != std::string_view::npos)
return pos;
return it->value().size() - forStr.size();

View File

@@ -247,6 +247,8 @@ build_map(boost::beast::http::fields const& h)
std::map<std::string, std::string> c;
for (auto const& e : h)
{
// key cannot be a std::string_view because it needs to be used in
// map and along with iterators
std::string key(e.name_string());
std::transform(key.begin(), key.end(), key.begin(), [](auto kc) {
return std::tolower(static_cast<unsigned char>(kc));
@@ -592,8 +594,8 @@ ServerHandler::processRequest(
beast::IP::Endpoint const& remoteIPAddress,
Output&& output,
std::shared_ptr<JobQueue::Coro> coro,
boost::string_view forwardedFor,
boost::string_view user)
std::string_view forwardedFor,
std::string_view user)
{
auto rpcJ = app_.journal("RPC");
@@ -847,8 +849,8 @@ ServerHandler::processRequest(
*/
if (role != Role::IDENTIFIED && role != Role::PROXY)
{
forwardedFor.clear();
user.clear();
forwardedFor.remove_suffix(forwardedFor.size());
user.remove_suffix(user.size());
}
JLOG(m_journal.debug()) << "Query: " << strMethod << params;

View File

@@ -55,13 +55,13 @@ public:
}
}
boost::string_view
std::string_view
user() const
{
return user_;
}
boost::string_view
std::string_view
forwarded_for() const
{
return fwdfor_;

View File

@@ -185,7 +185,7 @@ class NFTokenDir_test : public beast::unit_test::suite
// Create accounts for all of the seeds and fund those accounts.
std::vector<Account> accounts;
accounts.reserve(seeds.size());
for (std::string_view const& seed : seeds)
for (std::string_view seed : seeds)
{
Account const& account = accounts.emplace_back(
Account::base58Seed, std::string(seed));
@@ -409,7 +409,7 @@ class NFTokenDir_test : public beast::unit_test::suite
// Create accounts for all of the seeds and fund those accounts.
std::vector<Account> accounts;
accounts.reserve(seeds.size());
for (std::string_view const& seed : seeds)
for (std::string_view seed : seeds)
{
Account const& account = accounts.emplace_back(
Account::base58Seed, std::string(seed));
@@ -659,7 +659,7 @@ class NFTokenDir_test : public beast::unit_test::suite
// Create accounts for all of the seeds and fund those accounts.
std::vector<Account> accounts;
accounts.reserve(seeds.size());
for (std::string_view const& seed : seeds)
for (std::string_view seed : seeds)
{
Account const& account =
accounts.emplace_back(Account::base58Seed, std::string(seed));
@@ -840,7 +840,7 @@ class NFTokenDir_test : public beast::unit_test::suite
// Create accounts for all of the seeds and fund those accounts.
std::vector<Account> accounts;
accounts.reserve(seeds.size());
for (std::string_view const& seed : seeds)
for (std::string_view seed : seeds)
{
Account const& account =
accounts.emplace_back(Account::base58Seed, std::string(seed));

View File

@@ -574,7 +574,7 @@ private:
if (ec)
break;
std::string path = req.target();
std::string_view const path = req.target();
res.insert("Server", "TrustedPublisherServer");
res.version(req.version());
res.keep_alive(req.keep_alive());
@@ -677,7 +677,9 @@ private:
// unknown request
res.result(boost::beast::http::status::not_found);
res.insert("Content-Type", "text/html");
res.body() = "The file '" + path + "' was not found";
res.body() = "The file '" + std::string(path) +
"' was not "
"found";
}
if (prepare)