aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--src/Mapper.cxx15
-rw-r--r--src/Mapper.hxx9
-rw-r--r--src/SongLoader.cxx17
-rw-r--r--src/SongPrint.cxx14
-rw-r--r--src/db/update/Walk.cxx11
-rw-r--r--src/storage/StorageInterface.hxx8
-rw-r--r--src/storage/plugins/LocalStorage.cxx8
-rw-r--r--src/storage/plugins/SmbclientStorage.cxx8
-rw-r--r--test/test_translate_song.cxx24
10 files changed, 60 insertions, 55 deletions
diff --git a/Makefile.am b/Makefile.am
index af2d491ed..374c09f52 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1777,6 +1777,7 @@ test_test_translate_song_SOURCES = \
test_test_translate_song_CPPFLAGS = $(AM_CPPFLAGS) $(CPPUNIT_CFLAGS) -DCPPUNIT_HAVE_RTTI=0
test_test_translate_song_CXXFLAGS = $(AM_CXXFLAGS) -Wno-error=deprecated-declarations
test_test_translate_song_LDADD = \
+ $(STORAGE_LIBS) \
libtag.a \
libfs.a \
libsystem.a \
diff --git a/src/Mapper.cxx b/src/Mapper.cxx
index 5a02096e8..1073068f5 100644
--- a/src/Mapper.cxx
+++ b/src/Mapper.cxx
@@ -160,21 +160,6 @@ mapper_get_music_directory_fs(void)
#endif
-const char *
-map_to_relative_path(const char *path_utf8)
-{
-#ifdef ENABLE_DATABASE
- return !music_dir_utf8.empty() &&
- memcmp(path_utf8, music_dir_utf8.c_str(),
- music_dir_utf8_length) == 0 &&
- PathTraitsUTF8::IsSeparator(path_utf8[music_dir_utf8_length])
- ? path_utf8 + music_dir_utf8_length + 1
- : path_utf8;
-#else
- return path_utf8;
-#endif
-}
-
#ifdef ENABLE_DATABASE
AllocatedPath
diff --git a/src/Mapper.hxx b/src/Mapper.hxx
index a9551c929..0ef663b80 100644
--- a/src/Mapper.hxx
+++ b/src/Mapper.hxx
@@ -71,15 +71,6 @@ mapper_has_music_directory(void)
#endif
-/**
- * If the specified absolute path points inside the music directory,
- * this function converts it to a relative path. If not, it returns
- * the unmodified string pointer.
- */
-gcc_pure
-const char *
-map_to_relative_path(const char *path_utf8);
-
#ifdef ENABLE_DATABASE
/**
diff --git a/src/SongLoader.cxx b/src/SongLoader.cxx
index f2cf216a7..c766a16a9 100644
--- a/src/SongLoader.cxx
+++ b/src/SongLoader.cxx
@@ -20,8 +20,8 @@
#include "config.h"
#include "SongLoader.hxx"
#include "client/Client.hxx"
-#include "Mapper.hxx"
#include "db/DatabaseSong.hxx"
+#include "storage/StorageInterface.hxx"
#include "ls.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/Traits.hxx"
@@ -45,14 +45,13 @@ DetachedSong *
SongLoader::LoadFile(const char *path_utf8, Error &error) const
{
#ifdef ENABLE_DATABASE
- /* TODO fs_charset vs utf8? */
- const char *suffix = map_to_relative_path(path_utf8);
- assert(suffix != nullptr);
-
- if (suffix != path_utf8)
- /* this path was relative to the music directory -
- obtain it from the database */
- return LoadSong(suffix, error);
+ if (storage != nullptr) {
+ const char *suffix = storage->MapToRelativeUTF8(path_utf8);
+ if (suffix != nullptr)
+ /* this path was relative to the music
+ directory - obtain it from the database */
+ return LoadSong(suffix, error);
+ }
#endif
if (client != nullptr) {
diff --git a/src/SongPrint.cxx b/src/SongPrint.cxx
index b0c9ed0a6..30c248d1e 100644
--- a/src/SongPrint.cxx
+++ b/src/SongPrint.cxx
@@ -20,10 +20,10 @@
#include "config.h"
#include "SongPrint.hxx"
#include "db/LightSong.hxx"
+#include "storage/StorageInterface.hxx"
#include "DetachedSong.hxx"
#include "TimePrint.hxx"
#include "TagPrint.hxx"
-#include "Mapper.hxx"
#include "client/Client.hxx"
#include "util/UriUtil.hxx"
@@ -32,12 +32,20 @@
static void
song_print_uri(Client &client, const char *uri)
{
+#ifdef ENABLE_DATABASE
+ const Storage *storage = client.GetStorage();
+ if (storage != nullptr) {
+ const char *suffix = storage->MapToRelativeUTF8(uri);
+ if (suffix != nullptr)
+ uri = suffix;
+ }
+#endif
+
const std::string allocated = uri_remove_auth(uri);
if (!allocated.empty())
uri = allocated.c_str();
- client_printf(client, "%s%s\n", SONG_FILE,
- map_to_relative_path(uri));
+ client_printf(client, "%s%s\n", SONG_FILE, uri);
}
void
diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx
index 0ea1eb450..8acabe7ea 100644
--- a/src/db/update/Walk.cxx
+++ b/src/db/update/Walk.cxx
@@ -29,13 +29,13 @@
#include "db/Uri.hxx"
#include "storage/StorageInterface.hxx"
#include "playlist/PlaylistRegistry.hxx"
-#include "Mapper.hxx"
#include "ExcludeList.hxx"
#include "config/ConfigGlobal.hxx"
#include "config/ConfigOption.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/Traits.hxx"
#include "fs/FileSystem.hxx"
+#include "fs/Charset.hxx"
#include "storage/FileInfo.hxx"
#include "util/Alloc.hxx"
#include "util/UriUtil.hxx"
@@ -274,8 +274,13 @@ UpdateWalk::SkipSymlink(const Directory *directory,
if (PathTraitsFS::IsAbsolute(target_str)) {
/* if the symlink points to an absolute path, see if
that path is inside the music directory */
- const char *relative = map_to_relative_path(target_str);
- return relative > target_str
+ const auto target_utf8 = PathToUTF8(target_str);
+ if (target_utf8.empty())
+ return true;
+
+ const char *relative =
+ storage.MapToRelativeUTF8(target_utf8.c_str());
+ return relative != nullptr
? !follow_inside_symlinks
: !follow_outside_symlinks;
}
diff --git a/src/storage/StorageInterface.hxx b/src/storage/StorageInterface.hxx
index 18bee8cfd..892e8e43b 100644
--- a/src/storage/StorageInterface.hxx
+++ b/src/storage/StorageInterface.hxx
@@ -68,6 +68,14 @@ public:
gcc_pure
AllocatedPath MapChildFS(const char *uri_utf8,
const char *child_utf8) const;
+
+ /**
+ * Check if the given URI points inside this storage. If yes,
+ * then it returns a relative URI (pointing inside the given
+ * string); if not, returns nullptr.
+ */
+ gcc_pure
+ virtual const char *MapToRelativeUTF8(const char *uri_utf8) const = 0;
};
#endif
diff --git a/src/storage/plugins/LocalStorage.cxx b/src/storage/plugins/LocalStorage.cxx
index 23e87c1b5..5020a8fd6 100644
--- a/src/storage/plugins/LocalStorage.cxx
+++ b/src/storage/plugins/LocalStorage.cxx
@@ -68,6 +68,8 @@ public:
virtual AllocatedPath MapFS(const char *uri_utf8) const override;
+ virtual const char *MapToRelativeUTF8(const char *uri_utf8) const override;
+
private:
AllocatedPath MapFS(const char *uri_utf8, Error &error) const;
};
@@ -130,6 +132,12 @@ LocalStorage::MapFS(const char *uri_utf8) const
return MapFS(uri_utf8, IgnoreError());
}
+const char *
+LocalStorage::MapToRelativeUTF8(const char *uri_utf8) const
+{
+ return PathTraitsUTF8::Relative(base_utf8.c_str(), uri_utf8);
+}
+
bool
LocalStorage::GetInfo(const char *uri_utf8, bool follow, FileInfo &info,
Error &error)
diff --git a/src/storage/plugins/SmbclientStorage.cxx b/src/storage/plugins/SmbclientStorage.cxx
index 8dafff082..6d61ab75e 100644
--- a/src/storage/plugins/SmbclientStorage.cxx
+++ b/src/storage/plugins/SmbclientStorage.cxx
@@ -69,6 +69,8 @@ public:
Error &error) override;
virtual std::string MapUTF8(const char *uri_utf8) const override;
+
+ virtual const char *MapToRelativeUTF8(const char *uri_utf8) const override;
};
std::string
@@ -82,6 +84,12 @@ SmbclientStorage::MapUTF8(const char *uri_utf8) const
return PathTraitsUTF8::Build(base.c_str(), uri_utf8);
}
+const char *
+SmbclientStorage::MapToRelativeUTF8(const char *uri_utf8) const
+{
+ return PathTraitsUTF8::Relative(base.c_str(), uri_utf8);
+}
+
static bool
GetInfo(const char *path, FileInfo &info, Error &error)
{
diff --git a/test/test_translate_song.cxx b/test/test_translate_song.cxx
index aacc25820..6ef3a13f5 100644
--- a/test/test_translate_song.cxx
+++ b/test/test_translate_song.cxx
@@ -14,6 +14,7 @@
#include "ls.hxx"
#include "Log.hxx"
#include "db/DatabaseSong.hxx"
+#include "storage/plugins/LocalStorage.hxx"
#include "util/Error.hxx"
#include "Mapper.hxx"
@@ -38,16 +39,8 @@ uri_supported_scheme(const char *uri)
}
const char *const music_directory = "/music";
-
-const char *
-map_to_relative_path(const char *path_utf8)
-{
- size_t length = strlen(music_directory);
- if (memcmp(path_utf8, music_directory, length) == 0 &&
- path_utf8[length] == '/')
- path_utf8 += length + 1;
- return path_utf8;
-}
+static Storage *const storage = CreateLocalStorage(music_directory,
+ Path::FromFS(music_directory));
static void
BuildTag(gcc_unused TagBuilder &tag)
@@ -118,7 +111,7 @@ static const char *uri2 = "foo/bar.ogg";
DetachedSong *
DatabaseDetachSong(gcc_unused const Database &db,
- gcc_unused const Storage &storage,
+ gcc_unused const Storage &_storage,
const char *uri,
gcc_unused Error &error)
{
@@ -148,7 +141,7 @@ Client::GetDatabase(gcc_unused Error &error) const
const Storage *
Client::GetStorage() const
{
- return reinterpret_cast<const Storage *>(this);
+ return ::storage;
}
bool
@@ -252,7 +245,7 @@ class TranslateSongTest : public CppUnit::TestFixture {
void TestInDatabase() {
const SongLoader loader(reinterpret_cast<const Database *>(1),
- reinterpret_cast<const Storage *>(2));
+ storage);
DetachedSong song1("doesntexist");
CPPUNIT_ASSERT(!playlist_check_translate_song(song1, nullptr,
@@ -275,10 +268,9 @@ class TranslateSongTest : public CppUnit::TestFixture {
void TestRelative() {
const Database &db = *reinterpret_cast<const Database *>(1);
- const Storage &storage = *reinterpret_cast<const Storage *>(2);
- const SongLoader secure_loader(&db, &storage);
+ const SongLoader secure_loader(&db, storage);
const SongLoader insecure_loader(*reinterpret_cast<const Client *>(1),
- &db, &storage);
+ &db, storage);
/* map to music_directory */
DetachedSong song1("bar.ogg", MakeTag2b());