MPD  0.20.15
Directory.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef MPD_DIRECTORY_HXX
21 #define MPD_DIRECTORY_HXX
22 
23 #include "check.h"
24 #include "Compiler.h"
25 #include "db/Visitor.hxx"
26 #include "db/PlaylistVector.hxx"
27 #include "Song.hxx"
28 
29 #include <boost/intrusive/list.hpp>
30 
31 #include <string>
32 
37 static constexpr unsigned DEVICE_INARCHIVE = -1;
38 
44 static constexpr unsigned DEVICE_CONTAINER = -2;
45 
46 class SongFilter;
47 class Database;
48 
49 struct Directory {
50  static constexpr auto link_mode = boost::intrusive::normal_link;
51  typedef boost::intrusive::link_mode<link_mode> LinkMode;
52  typedef boost::intrusive::list_member_hook<LinkMode> Hook;
53 
63 
64  typedef boost::intrusive::member_hook<Directory, Hook,
66  typedef boost::intrusive::list<Directory, SiblingsHook,
67  boost::intrusive::constant_time_size<false>> List;
68 
76 
84 
86 
88  time_t mtime;
89  uint64_t inode, device;
90 
91  std::string path;
92 
98 
99 public:
100  Directory(std::string &&_path_utf8, Directory *_parent);
101  ~Directory();
102 
106  gcc_malloc
107  static Directory *NewRoot() {
108  return new Directory(std::string(), nullptr);
109  }
110 
111  bool IsMount() const {
112  return mounted_database != nullptr;
113  }
114 
121  void Delete();
122 
130  Directory *CreateChild(const char *name_utf8);
131 
135  gcc_pure
136  const Directory *FindChild(const char *name) const noexcept;
137 
138  gcc_pure
139  Directory *FindChild(const char *name) noexcept {
140  const Directory *cthis = this;
141  return const_cast<Directory *>(cthis->FindChild(name));
142  }
143 
150  Directory *MakeChild(const char *name_utf8) {
151  Directory *child = FindChild(name_utf8);
152  if (child == nullptr)
153  child = CreateChild(name_utf8);
154  return child;
155  }
156 
157  struct LookupResult {
164 
169  const char *uri;
170  };
171 
178  gcc_pure
179  LookupResult LookupDirectory(const char *uri) noexcept;
180 
181  gcc_pure
182  bool IsEmpty() const noexcept {
183  return children.empty() &&
184  songs.empty() &&
185  playlists.empty();
186  }
187 
188  gcc_pure
189  const char *GetPath() const noexcept {
190  return path.c_str();
191  }
192 
196  gcc_pure
197  const char *GetName() const noexcept;
198 
202  gcc_pure
203  bool IsRoot() const noexcept {
204  return parent == nullptr;
205  }
206 
207  template<typename T>
208  void ForEachChildSafe(T &&t) {
209  const auto end = children.end();
210  for (auto i = children.begin(), next = i; i != end; i = next) {
211  next = std::next(i);
212  t(*i);
213  }
214  }
215 
216  template<typename T>
217  void ForEachSongSafe(T &&t) {
218  const auto end = songs.end();
219  for (auto i = songs.begin(), next = i; i != end; i = next) {
220  next = std::next(i);
221  t(*i);
222  }
223  }
224 
230  gcc_pure
231  const Song *FindSong(const char *name_utf8) const noexcept;
232 
233  gcc_pure
234  Song *FindSong(const char *name_utf8) noexcept {
235  const Directory *cthis = this;
236  return const_cast<Song *>(cthis->FindSong(name_utf8));
237  }
238 
243  void AddSong(Song *song);
244 
250  void RemoveSong(Song *song) noexcept;
251 
255  void PruneEmpty() noexcept;
256 
262  void Sort() noexcept;
263 
267  void Walk(bool recursive, const SongFilter *match,
268  VisitDirectory visit_directory, VisitSong visit_song,
269  VisitPlaylist visit_playlist) const;
270 
271  gcc_pure
272  LightDirectory Export() const noexcept;
273 };
274 
275 #endif
gcc_pure const Directory * FindChild(const char *name) const noexcept
Caller must lock the db_mutex.
gcc_pure Directory * FindChild(const char *name) noexcept
Definition: Directory.hxx:139
static constexpr unsigned DEVICE_CONTAINER
Virtual directory that is really a song file with one or more "sub" songs as specified by DecoderPlug...
Definition: Directory.hxx:44
const char * uri
The remaining URI part (without leading slash) or nullptr if the given URI was consumed completely...
Definition: Directory.hxx:169
SongList songs
A doubly linked list of songs within this directory.
Definition: Directory.hxx:83
boost::intrusive::list< Song, boost::intrusive::member_hook< Song, Song::Hook, &Song::siblings >, boost::intrusive::constant_time_size< false > > SongList
Definition: Song.hxx:135
gcc_pure bool IsEmpty() const noexcept
Definition: Directory.hxx:182
boost::intrusive::link_mode< link_mode > LinkMode
Definition: Directory.hxx:51
static constexpr auto link_mode
Definition: Directory.hxx:50
std::function< void(const LightDirectory &)> VisitDirectory
Definition: Visitor.hxx:28
#define gcc_malloc
Definition: Compiler.h:112
bool IsMount() const
Definition: Directory.hxx:111
PlaylistVector playlists
Definition: Directory.hxx:85
uint64_t device
Definition: Directory.hxx:89
List children
A doubly linked list of child directories.
Definition: Directory.hxx:75
std::function< void(const PlaylistInfo &, const LightDirectory &)> VisitPlaylist
Definition: Visitor.hxx:33
Hook siblings
Pointers to the siblings of this directory within the parent directory.
Definition: Directory.hxx:62
void ForEachChildSafe(T &&t)
Definition: Directory.hxx:208
Directory * CreateChild(const char *name_utf8)
Create a new Directory object as a child of the given one.
void AddSong(Song *song)
Add a song object to this directory.
A song file inside the configured music directory.
Definition: Song.hxx:44
void Sort() noexcept
Sort all directory entries recursively.
gcc_pure LookupResult LookupDirectory(const char *uri) noexcept
Looks up a directory by its relative URI.
boost::intrusive::list< Directory, SiblingsHook, boost::intrusive::constant_time_size< false > > List
Definition: Directory.hxx:67
gcc_pure const char * GetName() const noexcept
Returns the base name of the directory.
Directory * directory
The last directory that was found.
Definition: Directory.hxx:163
time_t mtime
Definition: Directory.hxx:88
gcc_pure bool IsRoot() const noexcept
Is this the root directory of the music database?
Definition: Directory.hxx:203
void RemoveSong(Song *song) noexcept
Remove a song object from this directory (which effectively invalidates the song object, because the "parent" attribute becomes stale), but does not free it.
gcc_pure const char * GetPath() const noexcept
Definition: Directory.hxx:189
void PruneEmpty() noexcept
Caller must lock the db_mutex.
void Delete()
Remove this Directory object from its parent and free it.
Directory * parent
Definition: Directory.hxx:87
static gcc_malloc Directory * NewRoot()
Create a new root Directory object.
Definition: Directory.hxx:107
std::function< void(const LightSong &)> VisitSong
Definition: Visitor.hxx:31
gcc_pure LightDirectory Export() const noexcept
gcc_pure Song * FindSong(const char *name_utf8) noexcept
Definition: Directory.hxx:234
static constexpr unsigned DEVICE_INARCHIVE
Virtual directory that is really an archive file or a folder inside the archive (special value for Di...
Definition: Directory.hxx:37
boost::intrusive::list_member_hook< LinkMode > Hook
Definition: Directory.hxx:52
Directory * MakeChild(const char *name_utf8)
Look up a sub directory, and create the object if it does not exist.
Definition: Directory.hxx:150
void ForEachSongSafe(T &&t)
Definition: Directory.hxx:217
Directory(std::string &&_path_utf8, Directory *_parent)
void Walk(bool recursive, const SongFilter *match, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist) const
Caller must lock db_mutex.
Database * mounted_database
If this is not nullptr, then this directory does not really exist, but is a mount point for another D...
Definition: Directory.hxx:97
A reference to a directory.
#define gcc_pure
Definition: Compiler.h:116
uint64_t inode
Definition: Directory.hxx:89
const Storage const char * uri
boost::intrusive::member_hook< Directory, Hook, &Directory::siblings > SiblingsHook
Definition: Directory.hxx:65
std::string path
Definition: Directory.hxx:91
gcc_pure const Song * FindSong(const char *name_utf8) const noexcept
Look up a song in this directory by its name.
const Partition const char * name
Definition: Count.hxx:34