MPD  0.20.6
CompositeStorage.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_COMPOSITE_STORAGE_HXX
21 #define MPD_COMPOSITE_STORAGE_HXX
22 
23 #include "check.h"
24 #include "StorageInterface.hxx"
25 #include "thread/Mutex.hxx"
26 #include "Compiler.h"
27 
28 #include <string>
29 #include <map>
30 
39 class CompositeStorage final : public Storage {
43  struct Directory {
51 
52  std::map<std::string, Directory> children;
53 
54  Directory():storage(nullptr) {}
55  ~Directory();
56 
57  gcc_pure
58  bool IsEmpty() const {
59  return storage == nullptr && children.empty();
60  }
61 
62  gcc_pure
63  const Directory *Find(const char *uri) const;
64 
65  Directory &Make(const char *uri);
66 
67  bool Unmount();
68  bool Unmount(const char *uri);
69 
70  gcc_pure
71  bool MapToRelativeUTF8(std::string &buffer,
72  const char *uri) const;
73  };
74 
75  struct FindResult {
76  const Directory *directory;
77  const char *uri;
78  };
79 
85  mutable Mutex mutex;
86 
87  Directory root;
88 
89  mutable std::string relative_buffer;
90 
91 public:
93  virtual ~CompositeStorage();
94 
104  Storage *GetMount(const char *uri);
105 
111  template<typename T>
112  void VisitMounts(T t) const {
113  const std::lock_guard<Mutex> protect(mutex);
114  std::string uri;
115  VisitMounts(uri, root, t);
116  }
117 
118  void Mount(const char *uri, Storage *storage);
119  bool Unmount(const char *uri);
120 
121  /* virtual methods from class Storage */
122  StorageFileInfo GetInfo(const char *uri, bool follow) override;
123 
124  StorageDirectoryReader *OpenDirectory(const char *uri) override;
125 
126  std::string MapUTF8(const char *uri) const override;
127 
128  AllocatedPath MapFS(const char *uri) const override;
129 
130  const char *MapToRelativeUTF8(const char *uri) const override;
131 
132 private:
133  template<typename T>
134  void VisitMounts(std::string &uri, const Directory &directory,
135  T t) const {
136  const Storage *const storage = directory.storage;
137  if (storage != nullptr)
138  t(uri.c_str(), *storage);
139 
140  if (!uri.empty())
141  uri.push_back('/');
142 
143  const size_t uri_length = uri.length();
144 
145  for (const auto &i : directory.children) {
146  uri.resize(uri_length);
147  uri.append(i.first);
148 
149  VisitMounts(uri, i.second, t);
150  }
151  }
152 
161  gcc_pure
162  FindResult FindStorage(const char *uri) const;
163 
164  const char *MapToRelativeUTF8(const Directory &directory,
165  const char *uri) const;
166 };
167 
168 #endif
std::string MapUTF8(const char *uri) const override
Map the given relative URI to an absolute URI.
bool Unmount(const char *uri)
#define gcc_nonnull_all
Definition: Compiler.h:122
A path name in the native file system character set.
void Mount(const char *uri, Storage *storage)
StorageDirectoryReader * OpenDirectory(const char *uri) override
Throws #std::runtime_error on error.
Definition: Mutex.hxx:43
virtual ~CompositeStorage()
StorageFileInfo GetInfo(const char *uri, bool follow) override
Throws #std::runtime_error on error.
const Storage & storage
void VisitMounts(T t) const
Call the given function for each mounted storage, including the root storage.
Directory(std::string &&_path_utf8, Directory *_parent)
A Storage implementation that combines multiple other Storage instances in one virtual tree...
gcc_pure gcc_nonnull_all Storage * GetMount(const char *uri)
Get the Storage at the specified mount point.
#define gcc_pure
Definition: Compiler.h:116
const Storage const char * uri
AllocatedPath MapFS(const char *uri) const override
Map the given relative URI to a local file path.
const char * MapToRelativeUTF8(const char *uri) const override
Check if the given URI points inside this storage.