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(); ~UPnPDirContent();
gcc_pure gcc_pure
UPnPDirObject *FindObject(const char *name) noexcept { UPnPDirObject *FindObject(std::string_view name) noexcept {
for (auto &o : objects) for (auto &o : objects)
if (o.name == name) if (o.name == name)
return &o; return &o;

View File

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

View File

@ -23,7 +23,7 @@
#include "ixmlwrap.hxx" #include "ixmlwrap.hxx"
#include "util/UriRelative.hxx" #include "util/UriRelative.hxx"
#include "util/RuntimeError.hxx" #include "util/RuntimeError.hxx"
#include "util/SplitString.hxx" #include "util/IterableSplitString.hxx"
#include <upnptools.h> #include <upnptools.h>
@ -73,5 +73,8 @@ ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl) const
understand that */ understand that */
return std::forward_list<std::string>(); 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 ContentDirectoryService
UPnPDeviceDirectory::GetServer(const char *friendly_name) UPnPDeviceDirectory::GetServer(std::string_view friendly_name)
{ {
const std::lock_guard<Mutex> protect(mutex); const std::lock_guard<Mutex> protect(mutex);

View File

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

View File

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

View File

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

View File

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