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
*
* 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;
}
bool
archive_lookup(char *pathname, const char **archive,
const char **inpath)
ArchiveLookupResult
archive_lookup(char *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)
if (slash == nullptr)
return false;
return {};
//its a file ?
if (file_info.IsRegular()) {
//so the upper should be file
*archive = pathname;
*inpath = slash + 1;
return true;
return {Path::FromFS(pathname), Path::FromFS(slash + 1)};
} else {
FormatError(archive_domain,
"Not a regular file: %s",
pathname);
return false;
return {};
}
} catch (const std::system_error &e) {
if (!IsPathNotFound(e))
@ -76,7 +73,7 @@ archive_lookup(char *pathname, const char **archive,
slash = FindSlash(pathname, idx - 1);
if (slash == nullptr)
return false;
return {};
*slash = 0;
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
*
* This program is free software; you can redistribute it and/or modify
@ -20,6 +20,17 @@
#ifndef 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
@ -38,9 +49,8 @@
*
* Throws on error.
*/
bool
archive_lookup(char *pathname, const char **archive,
const char **inpath);
ArchiveLookupResult
archive_lookup(char *pathname);
#endif

View File

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

View File

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