util/SplitString: convert return value to std::string_view

Eliminates lots of overhead.
This commit is contained in:
Max Kellermann 2020-04-03 16:42:49 +02:00
parent 2c02a04566
commit db93bb996c
8 changed files with 27 additions and 32 deletions

View File

@ -40,7 +40,7 @@ public:
~UPnPDirContent();
gcc_pure
UPnPDirObject *FindObject(const char *name) noexcept {
UPnPDirObject *FindObject(std::string_view name) noexcept {
for (auto &o : objects)
if (o.name == name)
return &o;

View File

@ -106,7 +106,7 @@ public:
private:
void VisitServer(const ContentDirectoryService &server,
std::forward_list<std::string> &&vpath,
std::forward_list<std::string_view> &&vpath,
const DatabaseSelection &selection,
const VisitDirectory& visit_directory,
const VisitSong& visit_song,
@ -126,7 +126,7 @@ private:
const DatabaseSelection &selection) const;
UPnPDirObject Namei(const ContentDirectoryService &server,
std::forward_list<std::string> &&vpath) const;
std::forward_list<std::string_view> &&vpath) const;
/**
* Take server and objid, return metadata.
@ -192,7 +192,7 @@ UpnpDatabase::GetSong(const char *uri) const
throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"No such song");
auto server = discovery->GetServer(vpath.front().c_str());
auto server = discovery->GetServer(vpath.front());
vpath.pop_front();
if (vpath.empty())
@ -208,7 +208,7 @@ UpnpDatabase::GetSong(const char *uri) const
throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"No such song");
dirent = ReadNode(server, vpath.front().c_str());
dirent = ReadNode(server, std::string(vpath.front()).c_str());
}
return new UpnpSong(std::move(dirent), uri);
@ -407,7 +407,7 @@ UpnpDatabase::BuildPath(const ContentDirectoryService &server,
// Take server and internal title pathname and return objid and metadata.
UPnPDirObject
UpnpDatabase::Namei(const ContentDirectoryService &server,
std::forward_list<std::string> &&vpath) const
std::forward_list<std::string_view> &&vpath) const
{
if (vpath.empty())
// looking for root info
@ -420,7 +420,7 @@ UpnpDatabase::Namei(const ContentDirectoryService &server,
auto dirbuf = server.readDir(handle, objid.c_str());
// Look for the name in the sub-container list
UPnPDirObject *child = dirbuf.FindObject(vpath.front().c_str());
UPnPDirObject *child = dirbuf.FindObject(vpath.front());
if (child == nullptr)
throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"No such object");
@ -495,7 +495,7 @@ VisitObject(const UPnPDirObject &object, const char *uri,
// really just one path parameter.
void
UpnpDatabase::VisitServer(const ContentDirectoryService &server,
std::forward_list<std::string> &&vpath,
std::forward_list<std::string_view> &&vpath,
const DatabaseSelection &selection,
const VisitDirectory& visit_directory,
const VisitSong& visit_song,
@ -514,7 +514,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
if (vpath.empty())
return;
const std::string objid(std::move(vpath.front()));
const std::string objid(vpath.front());
vpath.pop_front();
if (!vpath.empty())
throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
@ -611,7 +611,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection,
}
// We do have a path: the first element selects the server
std::string servername(std::move(vpath.front()));
std::string servername(vpath.front());
vpath.pop_front();
auto server = discovery->GetServer(servername.c_str());

View File

@ -23,7 +23,7 @@
#include "ixmlwrap.hxx"
#include "util/UriRelative.hxx"
#include "util/RuntimeError.hxx"
#include "util/SplitString.hxx"
#include "util/IterableSplitString.hxx"
#include <upnptools.h>
@ -73,5 +73,8 @@ ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl) const
understand that */
return std::forward_list<std::string>();
return SplitString(s, ',', false);
std::forward_list<std::string> result;
for (const auto &i : IterableSplitString(s, ','))
result.emplace_front(i);
return result;
}

View File

@ -325,7 +325,7 @@ UPnPDeviceDirectory::GetDirectories()
}
ContentDirectoryService
UPnPDeviceDirectory::GetServer(const char *friendly_name)
UPnPDeviceDirectory::GetServer(std::string_view friendly_name)
{
const std::lock_guard<Mutex> protect(mutex);

View File

@ -176,7 +176,7 @@ public:
/**
* Get server by friendly name.
*/
ContentDirectoryService GetServer(const char *friendly_name);
ContentDirectoryService GetServer(std::string_view friendly_name);
private:
void Search();

View File

@ -25,6 +25,7 @@
#include "util/ASCII.hxx"
#include "util/RuntimeError.hxx"
#include "util/SplitString.hxx"
#include "util/StringView.hxx"
void
TagLoadConfig(const ConfigData &config)
@ -44,15 +45,11 @@ TagLoadConfig(const ConfigData &config)
/* no "+-": not incremental */
global_tag_mask = TagMask::None();
for (const auto &i : SplitString(value, ',')) {
const char *name = i.c_str();
if (*name == '+') {
for (StringView name : SplitString(value, ',')) {
if (name.SkipPrefix("+")) {
plus = true;
++name;
} else if (*name == '-') {
} else if (name.SkipPrefix("-")) {
plus = false;
++name;
}
const auto type = tag_name_parse_i(name);

View File

@ -31,28 +31,24 @@
#include "IterableSplitString.hxx"
#include "StringStrip.hxx"
std::forward_list<std::string>
std::forward_list<std::string_view>
SplitString(std::string_view _s, char separator, bool strip) noexcept
{
StringView s(_s);
if (strip)
s.StripLeft();
std::forward_list<std::string> list;
std::forward_list<std::string_view> list;
if (s.empty())
return list;
auto i = list.before_begin();
for (auto value : IterableSplitString(s, separator)) {
const char *begin = value.begin(), *end = value.end();
if (strip)
value.Strip();
if (strip) {
begin = StripLeft(begin, end);
end = StripRight(begin, end);
}
i = list.emplace_after(i, begin, end);
i = list.emplace_after(i, value);
}
return list;

View File

@ -31,7 +31,6 @@
#define SPLIT_STRING_HXX
#include <forward_list>
#include <string>
#include <string_view>
/**
@ -44,7 +43,7 @@
* An empty input string, as a special case, results in an empty list
* (and not a list with an empty string).
*/
std::forward_list<std::string>
std::forward_list<std::string_view>
SplitString(std::string_view s, char separator, bool strip=true) noexcept;
#endif