aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--src/DatabasePrint.cxx13
-rw-r--r--src/DatabaseVisitor.hxx6
-rw-r--r--src/Directory.cxx11
-rw-r--r--src/Directory.hxx3
-rw-r--r--src/LightDirectory.hxx61
-rw-r--r--src/SongPrint.cxx1
-rw-r--r--src/command/OtherCommands.cxx1
-rw-r--r--src/db/ProxyDatabasePlugin.cxx27
-rw-r--r--src/db/SimpleDatabasePlugin.cxx3
-rw-r--r--src/db/UpnpDatabasePlugin.cxx13
-rw-r--r--test/DumpDatabase.cxx11
12 files changed, 109 insertions, 42 deletions
diff --git a/Makefile.am b/Makefile.am
index b70999b5c..cdeca8dc6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -197,6 +197,7 @@ src_mpd_SOURCES = \
src/SignalHandlers.cxx src/SignalHandlers.hxx \
src/DetachedSong.cxx src/DetachedSong.hxx \
src/LightSong.cxx src/LightSong.hxx \
+ src/LightDirectory.hxx \
src/Song.cxx src/Song.hxx \
src/SongUpdate.cxx \
src/SongPrint.cxx src/SongPrint.hxx \
diff --git a/src/DatabasePrint.cxx b/src/DatabasePrint.cxx
index ef7ba825b..fc149316d 100644
--- a/src/DatabasePrint.cxx
+++ b/src/DatabasePrint.cxx
@@ -23,17 +23,18 @@
#include "SongFilter.hxx"
#include "SongPrint.hxx"
#include "TimePrint.hxx"
-#include "Directory.hxx"
#include "Client.hxx"
#include "tag/Tag.hxx"
#include "LightSong.hxx"
+#include "LightDirectory.hxx"
+#include "PlaylistInfo.hxx"
#include "DatabaseGlue.hxx"
#include "DatabasePlugin.hxx"
#include <functional>
static bool
-PrintDirectoryBrief(Client &client, const Directory &directory)
+PrintDirectoryBrief(Client &client, const LightDirectory &directory)
{
if (!directory.IsRoot())
client_printf(client, "directory: %s\n", directory.GetPath());
@@ -42,7 +43,7 @@ PrintDirectoryBrief(Client &client, const Directory &directory)
}
static bool
-PrintDirectoryFull(Client &client, const Directory &directory)
+PrintDirectoryFull(Client &client, const LightDirectory &directory)
{
if (!directory.IsRoot()) {
client_printf(client, "directory: %s\n", directory.GetPath());
@@ -68,7 +69,7 @@ print_playlist_in_directory(Client &client,
static void
print_playlist_in_directory(Client &client,
- const Directory *directory,
+ const LightDirectory *directory,
const char *name_utf8)
{
if (directory == nullptr || directory->IsRoot())
@@ -105,7 +106,7 @@ PrintSongFull(Client &client, const LightSong &song)
static bool
PrintPlaylistBrief(Client &client,
const PlaylistInfo &playlist,
- const Directory &directory)
+ const LightDirectory &directory)
{
print_playlist_in_directory(client, &directory, playlist.name.c_str());
return true;
@@ -114,7 +115,7 @@ PrintPlaylistBrief(Client &client,
static bool
PrintPlaylistFull(Client &client,
const PlaylistInfo &playlist,
- const Directory &directory)
+ const LightDirectory &directory)
{
print_playlist_in_directory(client, &directory, playlist.name.c_str());
diff --git a/src/DatabaseVisitor.hxx b/src/DatabaseVisitor.hxx
index 486407765..0ec29bf49 100644
--- a/src/DatabaseVisitor.hxx
+++ b/src/DatabaseVisitor.hxx
@@ -22,14 +22,14 @@
#include <functional>
-struct Directory;
+struct LightDirectory;
struct LightSong;
struct PlaylistInfo;
class Error;
-typedef std::function<bool(const Directory &, Error &)> VisitDirectory;
+typedef std::function<bool(const LightDirectory &, Error &)> VisitDirectory;
typedef std::function<bool(const LightSong &, Error &)> VisitSong;
-typedef std::function<bool(const PlaylistInfo &, const Directory &,
+typedef std::function<bool(const PlaylistInfo &, const LightDirectory &,
Error &)> VisitPlaylist;
typedef std::function<bool(const char *, Error &)> VisitString;
diff --git a/src/Directory.cxx b/src/Directory.cxx
index b230ac642..14cf88eb5 100644
--- a/src/Directory.cxx
+++ b/src/Directory.cxx
@@ -19,6 +19,7 @@
#include "config.h"
#include "Directory.hxx"
+#include "LightDirectory.hxx"
#include "SongFilter.hxx"
#include "PlaylistVector.hxx"
#include "DatabaseLock.hxx"
@@ -272,14 +273,14 @@ Directory::Walk(bool recursive, const SongFilter *filter,
if (visit_playlist) {
for (const PlaylistInfo &p : playlists)
- if (!visit_playlist(p, *this, error))
+ if (!visit_playlist(p, Export(), error))
return false;
}
Directory *child;
directory_for_each_child(child, *this) {
if (visit_directory &&
- !visit_directory(*child, error))
+ !visit_directory(child->Export(), error))
return false;
if (recursive &&
@@ -291,3 +292,9 @@ Directory::Walk(bool recursive, const SongFilter *filter,
return true;
}
+
+LightDirectory
+Directory::Export() const
+{
+ return LightDirectory(GetPath(), mtime);
+}
diff --git a/src/Directory.hxx b/src/Directory.hxx
index 54dd58f1c..c64a028ba 100644
--- a/src/Directory.hxx
+++ b/src/Directory.hxx
@@ -234,6 +234,9 @@ public:
VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist,
Error &error) const;
+
+ gcc_pure
+ LightDirectory Export() const;
};
static inline bool
diff --git a/src/LightDirectory.hxx b/src/LightDirectory.hxx
new file mode 100644
index 000000000..d134151a4
--- /dev/null
+++ b/src/LightDirectory.hxx
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_LIGHT_DIRECTORY_HXX
+#define MPD_LIGHT_DIRECTORY_HXX
+
+#include "Compiler.h"
+
+#include <string>
+
+#include <time.h>
+
+struct Tag;
+
+/**
+ * A reference to a directory. Unlike the #Directory class, this one
+ * consists only of pointers. It is supposed to be as light as
+ * possible while still providing all the information MPD has about a
+ * directory. This class does not manage any memory, and the pointers
+ * become invalid quickly. Only to be used to pass around during
+ * well-defined situations.
+ */
+struct LightDirectory {
+ const char *uri;
+
+ time_t mtime;
+
+ constexpr LightDirectory(const char *_uri, time_t _mtime)
+ :uri(_uri), mtime(_mtime) {}
+
+ static constexpr LightDirectory Root() {
+ return LightDirectory("", 0);
+ }
+
+ bool IsRoot() const {
+ return *uri == 0;
+ }
+
+ gcc_pure
+ const char *GetPath() const {
+ return uri;
+ }
+};
+
+#endif
diff --git a/src/SongPrint.cxx b/src/SongPrint.cxx
index 810518c21..cde6ef7d1 100644
--- a/src/SongPrint.cxx
+++ b/src/SongPrint.cxx
@@ -21,7 +21,6 @@
#include "SongPrint.hxx"
#include "LightSong.hxx"
#include "DetachedSong.hxx"
-#include "Directory.hxx"
#include "TimePrint.hxx"
#include "TagPrint.hxx"
#include "Mapper.hxx"
diff --git a/src/command/OtherCommands.cxx b/src/command/OtherCommands.cxx
index 0daf62c5a..397e40b00 100644
--- a/src/command/OtherCommands.cxx
+++ b/src/command/OtherCommands.cxx
@@ -42,6 +42,7 @@
#include "Stats.hxx"
#include "Permission.hxx"
#include "PlaylistFile.hxx"
+#include "PlaylistVector.hxx"
#include "ClientFile.hxx"
#include "Client.hxx"
#include "Idle.hxx"
diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx
index f65e4f3d0..1b5c3e374 100644
--- a/src/db/ProxyDatabasePlugin.cxx
+++ b/src/db/ProxyDatabasePlugin.cxx
@@ -23,7 +23,8 @@
#include "DatabaseListener.hxx"
#include "DatabaseSelection.hxx"
#include "DatabaseError.hxx"
-#include "Directory.hxx"
+#include "PlaylistInfo.hxx"
+#include "LightDirectory.hxx"
#include "LightSong.hxx"
#include "SongFilter.hxx"
#include "Compiler.h"
@@ -71,7 +72,6 @@ class ProxyDatabase final : public Database, SocketMonitor, IdleMonitor {
unsigned port;
struct mpd_connection *connection;
- Directory *root;
/* this is mutable because GetStats() must be "const" */
mutable time_t update_stamp;
@@ -328,7 +328,6 @@ ProxyDatabase::Open(Error &error)
if (!Connect(error))
return false;
- root = Directory::NewRoot();
update_stamp = 0;
return true;
@@ -337,8 +336,6 @@ ProxyDatabase::Open(Error &error)
void
ProxyDatabase::Close()
{
- delete root;
-
if (connection != nullptr)
Disconnect();
}
@@ -515,13 +512,13 @@ ProxyDatabase::ReturnSong(const LightSong *_song) const
}
static bool
-Visit(struct mpd_connection *connection, Directory &root, const char *uri,
+Visit(struct mpd_connection *connection, const char *uri,
bool recursive, const SongFilter *filter,
VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, Error &error);
static bool
-Visit(struct mpd_connection *connection, Directory &root,
+Visit(struct mpd_connection *connection,
bool recursive, const SongFilter *filter,
const struct mpd_directory *directory,
VisitDirectory visit_directory, VisitSong visit_song,
@@ -530,11 +527,11 @@ Visit(struct mpd_connection *connection, Directory &root,
const char *path = mpd_directory_get_path(directory);
if (visit_directory &&
- !visit_directory(Directory(path, &root), error))
+ !visit_directory(LightDirectory(path, 0), error))
return false;
if (recursive &&
- !Visit(connection, root, path, recursive, filter,
+ !Visit(connection, path, recursive, filter,
visit_directory, visit_song, visit_playlist, error))
return false;
@@ -561,7 +558,7 @@ Visit(const SongFilter *filter,
}
static bool
-Visit(const struct mpd_playlist *playlist, Directory &root,
+Visit(const struct mpd_playlist *playlist,
VisitPlaylist visit_playlist, Error &error)
{
if (!visit_playlist)
@@ -570,7 +567,7 @@ Visit(const struct mpd_playlist *playlist, Directory &root,
PlaylistInfo p(mpd_playlist_get_path(playlist),
mpd_playlist_get_last_modified(playlist));
- return visit_playlist(p, root, error);
+ return visit_playlist(p, LightDirectory::Root(), error);
}
class ProxyEntity {
@@ -612,7 +609,7 @@ ReceiveEntities(struct mpd_connection *connection)
}
static bool
-Visit(struct mpd_connection *connection, Directory &root, const char *uri,
+Visit(struct mpd_connection *connection, const char *uri,
bool recursive, const SongFilter *filter,
VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, Error &error)
@@ -630,7 +627,7 @@ Visit(struct mpd_connection *connection, Directory &root, const char *uri,
break;
case MPD_ENTITY_TYPE_DIRECTORY:
- if (!Visit(connection, root, recursive, filter,
+ if (!Visit(connection, recursive, filter,
mpd_entity_get_directory(entity),
visit_directory, visit_song, visit_playlist,
error))
@@ -645,7 +642,7 @@ Visit(struct mpd_connection *connection, Directory &root, const char *uri,
break;
case MPD_ENTITY_TYPE_PLAYLIST:
- if (!Visit(mpd_entity_get_playlist(entity), root,
+ if (!Visit(mpd_entity_get_playlist(entity),
visit_playlist, error))
return false;
break;
@@ -702,7 +699,7 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
return ::SearchSongs(connection, selection, visit_song, error);
/* fall back to recursive walk (slow!) */
- return ::Visit(connection, *root, selection.uri.c_str(),
+ return ::Visit(connection, selection.uri.c_str(),
selection.recursive, selection.filter,
visit_directory, visit_song, visit_playlist,
error);
diff --git a/src/db/SimpleDatabasePlugin.cxx b/src/db/SimpleDatabasePlugin.cxx
index 3d947c042..f77d98ea5 100644
--- a/src/db/SimpleDatabasePlugin.cxx
+++ b/src/db/SimpleDatabasePlugin.cxx
@@ -21,6 +21,7 @@
#include "SimpleDatabasePlugin.hxx"
#include "DatabaseSelection.hxx"
#include "DatabaseHelpers.hxx"
+#include "LightDirectory.hxx"
#include "Directory.hxx"
#include "Song.hxx"
#include "SongFilter.hxx"
@@ -265,7 +266,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
}
if (selection.recursive && visit_directory &&
- !visit_directory(*directory, error))
+ !visit_directory(directory->Export(), error))
return false;
return directory->Walk(selection.recursive, selection.filter,
diff --git a/src/db/UpnpDatabasePlugin.cxx b/src/db/UpnpDatabasePlugin.cxx
index 75d3890ed..844a061c8 100644
--- a/src/db/UpnpDatabasePlugin.cxx
+++ b/src/db/UpnpDatabasePlugin.cxx
@@ -29,8 +29,7 @@
#include "DatabasePlugin.hxx"
#include "DatabaseSelection.hxx"
#include "DatabaseError.hxx"
-#include "PlaylistVector.hxx"
-#include "Directory.hxx"
+#include "LightDirectory.hxx"
#include "LightSong.hxx"
#include "ConfigData.hxx"
#include "tag/TagBuilder.hxx"
@@ -71,7 +70,6 @@ public:
class UpnpDatabase : public Database {
LibUPnP *m_lib;
UPnPDeviceDirectory *m_superdir;
- Directory *m_root;
public:
static Database *Create(EventLoop &loop, DatabaseListener &listener,
@@ -190,7 +188,6 @@ UpnpDatabase::Open(Error &error)
return false;
}
- m_root = Directory::NewRoot();
// Wait for device answers. This should be consistent with the value set
// in the lib (currently 2)
sleep(2);
@@ -200,7 +197,6 @@ UpnpDatabase::Open(Error &error)
void
UpnpDatabase::Close()
{
- delete m_root;
delete m_superdir;
delete m_lib;
}
@@ -602,9 +598,8 @@ UpnpDatabase::VisitServer(ContentDirectoryService &server,
case UPnPDirObject::Type::CONTAINER:
if (visit_directory) {
- Directory d((selection.uri + "/" +
- dirent.name).c_str(),
- m_root);
+ const std::string uri = selection.uri + "/" + dirent.name;
+ const LightDirectory d(uri.c_str(), 0);
if (!visit_directory(d, error))
return false;
}
@@ -673,7 +668,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection,
// pseudo-directory from the list of servers.
if (visit_directory) {
for (auto& server : servers) {
- Directory d(server.getFriendlyName(), m_root);
+ const LightDirectory d(server.getFriendlyName(), 0);
if (!visit_directory(d, error))
return false;
}
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx
index 60c20e4ae..7b959a215 100644
--- a/test/DumpDatabase.cxx
+++ b/test/DumpDatabase.cxx
@@ -22,7 +22,7 @@
#include "DatabasePlugin.hxx"
#include "DatabaseSelection.hxx"
#include "DatabaseListener.hxx"
-#include "Directory.hxx"
+#include "LightDirectory.hxx"
#include "LightSong.hxx"
#include "PlaylistVector.hxx"
#include "ConfigGlobal.hxx"
@@ -58,9 +58,9 @@ public:
};
static bool
-DumpDirectory(const Directory &directory, Error &)
+DumpDirectory(const LightDirectory &directory, Error &)
{
- cout << "D " << directory.path << endl;
+ cout << "D " << directory.GetPath() << endl;
return true;
}
@@ -76,9 +76,10 @@ DumpSong(const LightSong &song, Error &)
static bool
DumpPlaylist(const PlaylistInfo &playlist,
- const Directory &directory, Error &)
+ const LightDirectory &directory, Error &)
{
- cout << "P " << directory.path << "/" << playlist.name.c_str() << endl;
+ cout << "P " << directory.GetPath()
+ << "/" << playlist.name.c_str() << endl;
return true;
}