input/Open: use OpenLocalInputStream()

Make the "open" method of plugins "file" and "archive" dummy methods
that always fail.  Instead, let InputStream::Open() hard-code access
to these two plugins by using OpenLocalInputStream().  This allows
simplifyin the algorithm for falling back to probing archive plugins.
This commit is contained in:
Max Kellermann 2014-10-02 21:17:31 +02:00
parent 20346b0da4
commit 7e12aea1d8
5 changed files with 34 additions and 33 deletions

View File

@ -115,9 +115,7 @@ decoder_input_stream_open(DecoderControl &dc, Path path)
InputStream *is = OpenLocalInputStream(path, dc.mutex, dc.cond, error); InputStream *is = OpenLocalInputStream(path, dc.mutex, dc.cond, error);
if (is == nullptr) { if (is == nullptr) {
if (error.IsDefined()) LogError(error);
LogError(error);
return nullptr; return nullptr;
} }

View File

@ -31,6 +31,10 @@
#include <assert.h> #include <assert.h>
#ifdef ENABLE_ARCHIVE
#include <errno.h>
#endif
InputStream * InputStream *
OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error) OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error)
{ {
@ -38,8 +42,15 @@ OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error)
InputStream *is = OpenFileInputStream(path, mutex, cond, error); InputStream *is = OpenFileInputStream(path, mutex, cond, error);
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
if (is == nullptr && !error.IsDefined()) if (is == nullptr && error.IsDomain(errno_domain) &&
is = OpenArchiveInputStream(path, mutex, cond, error); error.GetCode() == ENOTDIR) {
/* ENOTDIR means this may be a path inside an archive
file */
Error error2;
is = OpenArchiveInputStream(path, mutex, cond, error2);
if (is == nullptr && error2.IsDefined())
error = std::move(error2);
}
#endif #endif
assert(is == nullptr || is->IsReady()); assert(is == nullptr || is->IsReady());

View File

@ -21,7 +21,10 @@
#include "InputStream.hxx" #include "InputStream.hxx"
#include "Registry.hxx" #include "Registry.hxx"
#include "InputPlugin.hxx" #include "InputPlugin.hxx"
#include "LocalOpen.hxx"
#include "plugins/RewindInputPlugin.hxx" #include "plugins/RewindInputPlugin.hxx"
#include "fs/Traits.hxx"
#include "fs/Path.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
@ -32,6 +35,11 @@ InputStream::Open(const char *url,
Mutex &mutex, Cond &cond, Mutex &mutex, Cond &cond,
Error &error) Error &error)
{ {
if (PathTraitsFS::IsAbsolute(url))
/* TODO: the parameter is UTF-8, not filesystem charset */
return OpenLocalInputStream(Path::FromFS(url),
mutex, cond, error);
input_plugins_for_each_enabled(plugin) { input_plugins_for_each_enabled(plugin) {
InputStream *is; InputStream *is;

View File

@ -71,25 +71,14 @@ OpenArchiveInputStream(Path path, Mutex &mutex, Cond &cond, Error &error)
return is; return is;
} }
/**
* select correct archive plugin to handle the input stream
* may allow stacking of archive plugins. for example for handling
* tar.gz a gzip handler opens file (through inputfile stream)
* then it opens a tar handler and sets gzip inputstream as
* parent_stream so tar plugin fetches file data from gzip
* plugin and gzip fetches file from disk
*/
static InputStream * static InputStream *
input_archive_open(const char *pathname, input_archive_open(gcc_unused const char *filename,
Mutex &mutex, Cond &cond, gcc_unused Mutex &mutex, gcc_unused Cond &cond,
Error &error) gcc_unused Error &error)
{ {
if (!PathTraitsFS::IsAbsolute(pathname)) /* dummy method; use OpenArchiveInputStream() instead */
return nullptr;
/* TODO: the parameter is UTF-8, not filesystem charset */ return nullptr;
return OpenArchiveInputStream(Path::FromFS(pathname),
mutex, cond, error);
} }
const InputPlugin input_plugin_archive = { const InputPlugin input_plugin_archive = {

View File

@ -68,9 +68,8 @@ OpenFileInputStream(Path path,
{ {
const int fd = OpenFile(path, O_RDONLY|O_BINARY, 0); const int fd = OpenFile(path, O_RDONLY|O_BINARY, 0);
if (fd < 0) { if (fd < 0) {
if (errno != ENOTDIR) error.FormatErrno("Failed to open \"%s\"",
error.FormatErrno("Failed to open \"%s\"", path.c_str());
path.c_str());
return nullptr; return nullptr;
} }
@ -96,17 +95,13 @@ OpenFileInputStream(Path path,
} }
static InputStream * static InputStream *
input_file_open(const char *filename, input_file_open(gcc_unused const char *filename,
Mutex &mutex, Cond &cond, gcc_unused Mutex &mutex, gcc_unused Cond &cond,
Error &error) gcc_unused Error &error)
{ {
if (!PathTraitsFS::IsAbsolute(filename)) /* dummy method; use OpenFileInputStream() instead */
return nullptr;
/* TODO: the parameter is UTF-8, not filesystem charset */ return nullptr;
const Path path = Path::FromFS(filename);
return OpenFileInputStream(path, mutex, cond, error);
} }
bool bool