archive/ArchiveLookup: replace output parameters with a struct

This commit is contained in:
Max Kellermann 2019-05-31 19:29:13 +02:00
parent 7866d1a005
commit e1ac377812
4 changed files with 42 additions and 36 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2018 The Music Player Daemon Project * Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -36,9 +36,8 @@ FindSlash(char *p, size_t i) noexcept
return nullptr; return nullptr;
} }
bool ArchiveLookupResult
archive_lookup(char *pathname, const char **archive, archive_lookup(char *pathname)
const char **inpath)
{ {
size_t idx = strlen(pathname); size_t idx = strlen(pathname);
@ -51,19 +50,17 @@ archive_lookup(char *pathname, const char **archive,
//is something found ins original path (is not an archive) //is something found ins original path (is not an archive)
if (slash == nullptr) if (slash == nullptr)
return false; return {};
//its a file ? //its a file ?
if (file_info.IsRegular()) { if (file_info.IsRegular()) {
//so the upper should be file //so the upper should be file
*archive = pathname; return {Path::FromFS(pathname), Path::FromFS(slash + 1)};
*inpath = slash + 1;
return true;
} else { } else {
FormatError(archive_domain, FormatError(archive_domain,
"Not a regular file: %s", "Not a regular file: %s",
pathname); pathname);
return false; return {};
} }
} catch (const std::system_error &e) { } catch (const std::system_error &e) {
if (!IsPathNotFound(e)) if (!IsPathNotFound(e))
@ -76,7 +73,7 @@ archive_lookup(char *pathname, const char **archive,
slash = FindSlash(pathname, idx - 1); slash = FindSlash(pathname, idx - 1);
if (slash == nullptr) if (slash == nullptr)
return false; return {};
*slash = 0; *slash = 0;
idx = slash - pathname; idx = slash - pathname;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2018 The Music Player Daemon Project * Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,6 +20,17 @@
#ifndef MPD_ARCHIVE_LOOKUP_HXX #ifndef MPD_ARCHIVE_LOOKUP_HXX
#define MPD_ARCHIVE_LOOKUP_HXX #define MPD_ARCHIVE_LOOKUP_HXX
#include "fs/Path.hxx"
struct ArchiveLookupResult {
Path archive = nullptr;
Path inside = nullptr;
constexpr operator bool() const noexcept {
return !archive.IsNull();
}
};
/** /**
* *
* archive_lookup is used to determine if part of pathname refers to an regular * archive_lookup is used to determine if part of pathname refers to an regular
@ -38,9 +49,8 @@
* *
* Throws on error. * Throws on error.
*/ */
bool ArchiveLookupResult
archive_lookup(char *pathname, const char **archive, archive_lookup(char *pathname);
const char **inpath);
#endif #endif

View File

@ -44,9 +44,10 @@ OpenArchiveInputStream(Path path, Mutex &mutex)
}; };
// archive_lookup will modify pname when true is returned // archive_lookup will modify pname when true is returned
const char *archive, *filename; ArchiveLookupResult l;
try { try {
if (!archive_lookup(pname, &archive, &filename)) { l = archive_lookup(pname);
if (l.archive.IsNull()) {
FormatDebug(archive_domain, FormatDebug(archive_domain,
"not an archive, lookup %s failed", pname); "not an archive, lookup %s failed", pname);
return nullptr; return nullptr;
@ -57,7 +58,7 @@ OpenArchiveInputStream(Path path, Mutex &mutex)
return nullptr; return nullptr;
} }
const char *suffix = Path::FromFS(archive).GetSuffix(); const char *suffix = l.archive.GetSuffix();
if (suffix == nullptr) if (suffix == nullptr)
return nullptr; return nullptr;
@ -65,10 +66,10 @@ OpenArchiveInputStream(Path path, Mutex &mutex)
arplug = archive_plugin_from_suffix(suffix); arplug = archive_plugin_from_suffix(suffix);
if (!arplug) { if (!arplug) {
FormatWarning(archive_domain, FormatWarning(archive_domain,
"can't handle archive %s", archive); "can't handle archive %s", l.archive.c_str());
return nullptr; return nullptr;
} }
return archive_file_open(arplug, Path::FromFS(archive)) return archive_file_open(arplug, l.archive)
->OpenStream(filename, mutex); ->OpenStream(l.inside.c_str(), mutex);
} }

View File

@ -8,39 +8,37 @@
TEST(ArchiveTest, Lookup) TEST(ArchiveTest, Lookup)
{ {
const char *archive, *inpath;
char *path = strdup(""); char *path = strdup("");
EXPECT_THROW(archive_lookup(path, &archive, &inpath), EXPECT_THROW(archive_lookup(path), std::system_error);
std::system_error);
free(path); free(path);
path = strdup("."); path = strdup(".");
EXPECT_FALSE(archive_lookup(path, &archive, &inpath)); EXPECT_FALSE(archive_lookup(path));
free(path); free(path);
path = strdup("config.h"); path = strdup("config.h");
EXPECT_FALSE(archive_lookup(path, &archive, &inpath)); EXPECT_FALSE(archive_lookup(path));
free(path); free(path);
path = strdup("src/foo/bar"); path = strdup("src/foo/bar");
EXPECT_THROW(archive_lookup(path, &archive, &inpath), EXPECT_THROW(archive_lookup(path), std::system_error);
std::system_error);
free(path); free(path);
fclose(fopen("dummy", "w")); fclose(fopen("dummy", "w"));
path = strdup("dummy/foo/bar"); path = strdup("dummy/foo/bar");
EXPECT_TRUE(archive_lookup(path, &archive, &inpath)); auto result = archive_lookup(path);
EXPECT_EQ((const char *)path, archive); EXPECT_TRUE(result);
EXPECT_STREQ(archive, "dummy"); EXPECT_EQ((const char *)path, result.archive.c_str());
EXPECT_STREQ(inpath, "foo/bar"); EXPECT_STREQ(result.archive.c_str(), "dummy");
EXPECT_STREQ(result.inside.c_str(), "foo/bar");
free(path); free(path);
path = strdup("config.h/foo/bar"); path = strdup("config.h/foo/bar");
EXPECT_TRUE(archive_lookup(path, &archive, &inpath)); result = archive_lookup(path);
EXPECT_EQ((const char *)path, archive); EXPECT_TRUE(result);
EXPECT_STREQ(archive, "config.h"); EXPECT_EQ((const char *)path, result.archive.c_str());
EXPECT_STREQ(inpath, "foo/bar"); EXPECT_STREQ(result.archive.c_str(), "config.h");
EXPECT_STREQ(result.inside.c_str(), "foo/bar");
free(path); free(path);
} }