db/simple: pass std::string_view to Directory::LookupDirectory()

This commit is contained in:
Max Kellermann 2020-04-03 17:03:35 +02:00
parent 9f8dc31b50
commit dd831d3922
5 changed files with 31 additions and 19 deletions

View File

@ -20,10 +20,18 @@
#ifndef MPD_DB_URI_HXX #ifndef MPD_DB_URI_HXX
#define MPD_DB_URI_HXX #define MPD_DB_URI_HXX
#include <string_view>
static inline bool static inline bool
isRootDirectory(const char *name) isRootDirectory(const char *name)
{ {
return name[0] == 0 || (name[0] == '/' && name[1] == 0); return name[0] == 0 || (name[0] == '/' && name[1] == 0);
} }
static inline bool
isRootDirectory(std::string_view name) noexcept
{
return name.empty() || (name.size() == 1 && name.front() == '/');
}
#endif #endif

View File

@ -127,13 +127,12 @@ Directory::PruneEmpty() noexcept
} }
Directory::LookupResult Directory::LookupResult
Directory::LookupDirectory(const char *_uri) noexcept Directory::LookupDirectory(std::string_view _uri) noexcept
{ {
assert(holding_db_lock()); assert(holding_db_lock());
assert(_uri != nullptr);
if (isRootDirectory(_uri)) if (isRootDirectory(_uri))
return { this, _uri, nullptr }; return { this, _uri, {} };
StringView uri(_uri); StringView uri(_uri);
@ -156,7 +155,7 @@ Directory::LookupDirectory(const char *_uri) noexcept
uri = rest; uri = rest;
} while (uri != nullptr); } while (uri != nullptr);
return { d, StringView(_uri, uri.data - 1), uri.data }; return { d, _uri.substr(0, uri.data - _uri.data()), uri };
} }
void void

View File

@ -189,9 +189,9 @@ public:
/** /**
* The remaining URI part (without leading slash) or * The remaining URI part (without leading slash) or
* nullptr if the given URI was consumed completely. * empty if the given URI was consumed completely.
*/ */
const char *rest; std::string_view rest;
}; };
/** /**
@ -201,7 +201,7 @@ public:
* @return the Directory, or nullptr if none was found * @return the Directory, or nullptr if none was found
*/ */
gcc_pure gcc_pure
LookupResult LookupDirectory(const char *uri) noexcept; LookupResult LookupDirectory(std::string_view uri) noexcept;
gcc_pure gcc_pure
bool IsEmpty() const noexcept { bool IsEmpty() const noexcept {

View File

@ -211,8 +211,10 @@ SimpleDatabase::GetSong(const char *uri) const
/* pass the request to the mounted database */ /* pass the request to the mounted database */
protect.unlock(); protect.unlock();
/* note: r.rest.data() is actually null-terminated
because it points inside the "uri" parameter */
const LightSong *song = const LightSong *song =
r.directory->mounted_database->GetSong(r.rest); r.directory->mounted_database->GetSong(r.rest.data());
if (song == nullptr) if (song == nullptr)
return nullptr; return nullptr;
@ -222,12 +224,12 @@ SimpleDatabase::GetSong(const char *uri) const
return prefixed_light_song; return prefixed_light_song;
} }
if (r.rest == nullptr) if (r.rest.data() == nullptr)
/* it's a directory */ /* it's a directory */
throw DatabaseError(DatabaseErrorCode::NOT_FOUND, throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"No such song"); "No such song");
if (strchr(r.rest, '/') != nullptr) if (r.rest.find('/') != std::string_view::npos)
/* refers to a URI "below" the actual song */ /* refers to a URI "below" the actual song */
throw DatabaseError(DatabaseErrorCode::NOT_FOUND, throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"No such song"); "No such song");
@ -283,14 +285,15 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
{ {
ScopeDatabaseLock protect; ScopeDatabaseLock protect;
auto r = root->LookupDirectory(selection.uri.c_str()); auto r = root->LookupDirectory(selection.uri);
if (r.directory->IsMount()) { if (r.directory->IsMount()) {
/* pass the request and the remaining uri to the mounted database */ /* pass the request and the remaining uri to the mounted database */
protect.unlock(); protect.unlock();
WalkMount(r.uri, *(r.directory->mounted_database), WalkMount(r.uri, *(r.directory->mounted_database),
(r.rest == nullptr)?"":r.rest, selection, r.rest,
selection,
visit_directory, visit_song, visit_playlist); visit_directory, visit_song, visit_playlist);
return; return;
@ -298,7 +301,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
DatabaseVisitorHelper helper(CheckSelection(selection), visit_song); DatabaseVisitorHelper helper(CheckSelection(selection), visit_song);
if (r.rest == nullptr) { if (r.rest.data() == nullptr) {
/* it's a directory */ /* it's a directory */
if (selection.recursive && visit_directory) if (selection.recursive && visit_directory)
@ -311,7 +314,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
return; return;
} }
if (strchr(r.rest, '/') == nullptr) { if (r.rest.find('/') == std::string_view::npos) {
if (visit_song) { if (visit_song) {
Song *song = r.directory->FindSong(r.rest); Song *song = r.directory->FindSong(r.rest);
if (song != nullptr) { if (song != nullptr) {
@ -402,11 +405,11 @@ SimpleDatabase::Mount(const char *uri, DatabasePtr db)
ScopeDatabaseLock protect; ScopeDatabaseLock protect;
auto r = root->LookupDirectory(uri); auto r = root->LookupDirectory(uri);
if (r.rest == nullptr) if (r.rest.data() == nullptr)
throw DatabaseError(DatabaseErrorCode::CONFLICT, throw DatabaseError(DatabaseErrorCode::CONFLICT,
"Already exists"); "Already exists");
if (strchr(r.rest, '/') != nullptr) if (r.rest.find('/') != std::string_view::npos)
throw DatabaseError(DatabaseErrorCode::NOT_FOUND, throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"Parent not found"); "Parent not found");
@ -461,7 +464,7 @@ SimpleDatabase::LockUmountSteal(const char *uri) noexcept
ScopeDatabaseLock protect; ScopeDatabaseLock protect;
auto r = root->LookupDirectory(uri); auto r = root->LookupDirectory(uri);
if (r.rest != nullptr || !r.directory->IsMount()) if (r.rest.data() != nullptr || !r.directory->IsMount())
return nullptr; return nullptr;
auto db = std::move(r.directory->mounted_database); auto db = std::move(r.directory->mounted_database);

View File

@ -169,7 +169,7 @@ UpdateService::GenerateId() noexcept
} }
unsigned unsigned
UpdateService::Enqueue(const char *path, bool discard) UpdateService::Enqueue(const char *_path, bool discard)
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
@ -178,6 +178,8 @@ UpdateService::Enqueue(const char *path, bool discard)
SimpleDatabase *db2; SimpleDatabase *db2;
Storage *storage2; Storage *storage2;
std::string_view path(_path);
Directory::LookupResult lr; Directory::LookupResult lr;
{ {
const ScopeDatabaseLock protect; const ScopeDatabaseLock protect;
@ -192,7 +194,7 @@ UpdateService::Enqueue(const char *path, bool discard)
if (db2 == nullptr) if (db2 == nullptr)
throw std::runtime_error("Cannot update this type of database"); throw std::runtime_error("Cannot update this type of database");
if (lr.rest == nullptr) { if (lr.rest.data() == nullptr) {
storage2 = storage.GetMount(path); storage2 = storage.GetMount(path);
path = ""; path = "";
} else { } else {