input: wrap InputStream in std::unique_ptr

This commit is contained in:
Max Kellermann 2016-02-21 08:03:32 +01:00
parent 054e9ecaae
commit cadc67ea40
19 changed files with 107 additions and 103 deletions

View File

@ -39,7 +39,7 @@ class TagFileScan {
Mutex mutex; Mutex mutex;
Cond cond; Cond cond;
InputStream *is; InputStreamPtr is;
public: public:
TagFileScan(Path _path_fs, const char *_suffix, TagFileScan(Path _path_fs, const char *_suffix,
@ -48,10 +48,6 @@ public:
handler(_handler), handler_ctx(_handler_ctx) , handler(_handler), handler_ctx(_handler_ctx) ,
is(nullptr) {} is(nullptr) {}
~TagFileScan() {
delete is;
}
bool ScanFile(const DecoderPlugin &plugin) { bool ScanFile(const DecoderPlugin &plugin) {
return plugin.ScanFile(path_fs, handler, handler_ctx); return plugin.ScanFile(path_fs, handler, handler_ctx);
} }

View File

@ -68,12 +68,7 @@ tag_stream_scan(const char *uri, const tag_handler &handler, void *ctx)
Mutex mutex; Mutex mutex;
Cond cond; Cond cond;
InputStream *is = InputStream::OpenReady(uri, mutex, cond, auto is = InputStream::OpenReady(uri, mutex, cond,
IgnoreError()); IgnoreError());
if (is == nullptr) return is && tag_stream_scan(*is, handler, ctx);
return false;
bool success = tag_stream_scan(*is, handler, ctx);
delete is;
return success;
} }

View File

@ -49,22 +49,18 @@ public:
RefCount ref; RefCount ref;
std::string name; std::string name;
InputStream *const istream; const InputStreamPtr istream;
Bzip2ArchiveFile(Path path, InputStream *_is) Bzip2ArchiveFile(Path path, InputStreamPtr &&_is)
:ArchiveFile(bz2_archive_plugin), :ArchiveFile(bz2_archive_plugin),
name(path.GetBase().c_str()), name(path.GetBase().c_str()),
istream(_is) { istream(std::move(_is)) {
// remove .bz2 suffix // remove .bz2 suffix
const size_t len = name.length(); const size_t len = name.length();
if (len > 4) if (len > 4)
name.erase(len - 4); name.erase(len - 4);
} }
~Bzip2ArchiveFile() {
delete istream;
}
void Ref() { void Ref() {
ref.Increment(); ref.Increment();
} }
@ -141,11 +137,11 @@ bz2_open(Path pathname, Error &error)
{ {
static Mutex mutex; static Mutex mutex;
static Cond cond; static Cond cond;
InputStream *is = OpenLocalInputStream(pathname, mutex, cond, error); auto is = OpenLocalInputStream(pathname, mutex, cond, error);
if (is == nullptr) if (is == nullptr)
return nullptr; return nullptr;
return new Bzip2ArchiveFile(pathname, is); return new Bzip2ArchiveFile(pathname, std::move(is));
} }
/* single archive handling */ /* single archive handling */

View File

@ -256,7 +256,7 @@ void decoder_seek_error(Decoder & decoder)
decoder_command_finished(decoder); decoder_command_finished(decoder);
} }
InputStream * InputStreamPtr
decoder_open_uri(Decoder &decoder, const char *uri, Error &error) decoder_open_uri(Decoder &decoder, const char *uri, Error &error)
{ {
assert(decoder.dc.state == DecoderState::START || assert(decoder.dc.state == DecoderState::START ||
@ -266,8 +266,8 @@ decoder_open_uri(Decoder &decoder, const char *uri, Error &error)
Mutex &mutex = dc.mutex; Mutex &mutex = dc.mutex;
Cond &cond = dc.cond; Cond &cond = dc.cond;
InputStream *is = InputStream::Open(uri, mutex, cond, error); auto is = InputStream::Open(uri, mutex, cond, error);
if (is == nullptr) if (!is)
return nullptr; return nullptr;
mutex.lock(); mutex.lock();
@ -280,7 +280,6 @@ decoder_open_uri(Decoder &decoder, const char *uri, Error &error)
if (dc.command == DecoderCommand::STOP) { if (dc.command == DecoderCommand::STOP) {
mutex.unlock(); mutex.unlock();
delete is;
return nullptr; return nullptr;
} }

View File

@ -30,6 +30,7 @@
// IWYU pragma: begin_exports // IWYU pragma: begin_exports
#include "check.h" #include "check.h"
#include "input/Ptr.hxx"
#include "DecoderCommand.hxx" #include "DecoderCommand.hxx"
#include "DecoderPlugin.hxx" #include "DecoderPlugin.hxx"
#include "ReplayGainInfo.hxx" #include "ReplayGainInfo.hxx"
@ -116,7 +117,7 @@ decoder_seek_error(Decoder &decoder);
* cancelled by DecoderCommand::STOP (returns nullptr without setting * cancelled by DecoderCommand::STOP (returns nullptr without setting
* #Error). * #Error).
*/ */
InputStream * InputStreamPtr
decoder_open_uri(Decoder &decoder, const char *uri, Error &error); decoder_open_uri(Decoder &decoder, const char *uri, Error &error);
/** /**

View File

@ -486,13 +486,13 @@ wavpack_open_wvc(Decoder &decoder, const char *uri)
char *wvc_url = xstrcatdup(uri, "c"); char *wvc_url = xstrcatdup(uri, "c");
InputStream *is_wvc = decoder_open_uri(decoder, uri, IgnoreError()); auto is_wvc = decoder_open_uri(decoder, uri, IgnoreError());
free(wvc_url); free(wvc_url);
if (is_wvc == nullptr) if (is_wvc == nullptr)
return nullptr; return nullptr;
return new WavpackInput(decoder, *is_wvc); return new WavpackInput(decoder, *is_wvc.release());
} }
/* /*

View File

@ -22,6 +22,7 @@
#include "check.h" #include "check.h"
#include "Offset.hxx" #include "Offset.hxx"
#include "Ptr.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "Compiler.h" #include "Compiler.h"
@ -123,18 +124,17 @@ public:
* @return an #InputStream object on success, nullptr on error * @return an #InputStream object on success, nullptr on error
*/ */
gcc_nonnull_all gcc_nonnull_all
gcc_malloc static InputStreamPtr Open(const char *uri, Mutex &mutex, Cond &cond,
static InputStream *Open(const char *uri, Mutex &mutex, Cond &cond, Error &error);
Error &error);
/** /**
* Just like Open(), but waits for the stream to become ready. * Just like Open(), but waits for the stream to become ready.
* It is a wrapper for Open(), WaitReady() and Check(). * It is a wrapper for Open(), WaitReady() and Check().
*/ */
gcc_malloc gcc_nonnull_all gcc_nonnull_all
static InputStream *OpenReady(const char *uri, static InputStreamPtr OpenReady(const char *uri,
Mutex &mutex, Cond &cond, Mutex &mutex, Cond &cond,
Error &error); Error &error);
/** /**
* The absolute URI which was used to open this stream. * The absolute URI which was used to open this stream.

View File

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

View File

@ -21,8 +21,8 @@
#define MPD_INPUT_LOCAL_OPEN_HXX #define MPD_INPUT_LOCAL_OPEN_HXX
#include "check.h" #include "check.h"
#include "Ptr.hxx"
class InputStream;
class Path; class Path;
class Mutex; class Mutex;
class Cond; class Cond;
@ -32,7 +32,7 @@ class Error;
* Open a "local" file. This is a wrapper for the input plugins * Open a "local" file. This is a wrapper for the input plugins
* "file" and "archive". * "file" and "archive".
*/ */
InputStream * InputStreamPtr
OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error); OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error);
#endif #endif

View File

@ -30,7 +30,7 @@
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
InputStream * InputStreamPtr
InputStream::Open(const char *url, InputStream::Open(const char *url,
Mutex &mutex, Cond &cond, Mutex &mutex, Cond &cond,
Error &error) Error &error)
@ -51,7 +51,7 @@ InputStream::Open(const char *url,
if (is != nullptr) { if (is != nullptr) {
is = input_rewind_open(is); is = input_rewind_open(is);
return is; return InputStreamPtr(is);
} else if (error.IsDefined()) } else if (error.IsDefined())
return nullptr; return nullptr;
} }
@ -60,12 +60,12 @@ InputStream::Open(const char *url,
return nullptr; return nullptr;
} }
InputStream * InputStreamPtr
InputStream::OpenReady(const char *uri, InputStream::OpenReady(const char *uri,
Mutex &mutex, Cond &cond, Mutex &mutex, Cond &cond,
Error &error) Error &error)
{ {
InputStream *is = Open(uri, mutex, cond, error); auto is = Open(uri, mutex, cond, error);
if (is == nullptr) if (is == nullptr)
return nullptr; return nullptr;
@ -74,10 +74,8 @@ InputStream::OpenReady(const char *uri,
bool success = is->Check(error); bool success = is->Check(error);
mutex.unlock(); mutex.unlock();
if (!success) { if (!success)
delete is; is.reset();
is = nullptr;
}
return is; return is;
} }

29
src/input/Ptr.hxx Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_INPUT_STREAM_PTR_HXX
#define MPD_INPUT_STREAM_PTR_HXX
#include <memory>
class InputStream;
typedef std::unique_ptr<InputStream> InputStreamPtr;
#endif

View File

@ -44,7 +44,7 @@ try {
return nullptr; return nullptr;
Error error; Error error;
InputStream *is = OpenLocalInputStream(path, mutex, cond, error); auto is = OpenLocalInputStream(path, mutex, cond, error);
if (is == nullptr) { if (is == nullptr) {
LogError(error); LogError(error);
return nullptr; return nullptr;
@ -53,9 +53,7 @@ try {
auto playlist = playlist_list_open_stream_suffix(*is, auto playlist = playlist_list_open_stream_suffix(*is,
suffix_utf8.c_str()); suffix_utf8.c_str());
if (playlist != nullptr) if (playlist != nullptr)
playlist = new CloseSongEnumerator(playlist, is); playlist = new CloseSongEnumerator(playlist, is.release());
else
delete is;
return playlist; return playlist;
} catch (const std::runtime_error &e) { } catch (const std::runtime_error &e) {
@ -91,7 +89,7 @@ try {
return playlist; return playlist;
Error error; Error error;
InputStream *is = InputStream::OpenReady(uri, mutex, cond, error); auto is = InputStream::OpenReady(uri, mutex, cond, error);
if (is == nullptr) { if (is == nullptr) {
if (error.IsDefined()) if (error.IsDefined())
FormatError(error, "Failed to open %s", uri); FormatError(error, "Failed to open %s", uri);
@ -100,12 +98,10 @@ try {
} }
playlist = playlist_list_open_stream(*is, uri); playlist = playlist_list_open_stream(*is, uri);
if (playlist == nullptr) { if (playlist == nullptr)
delete is;
return nullptr; return nullptr;
}
return new CloseSongEnumerator(playlist, is); return new CloseSongEnumerator(playlist, is.release());
} catch (const std::runtime_error &e) { } catch (const std::runtime_error &e) {
LogError(e); LogError(e);
return nullptr; return nullptr;

View File

@ -234,8 +234,8 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
Mutex &mutex, Cond &cond) Mutex &mutex, Cond &cond)
{ {
Error error; Error error;
InputStream *input_stream = InputStream::OpenReady(url, mutex, cond, auto input_stream = InputStream::OpenReady(url, mutex, cond,
error); error);
if (input_stream == nullptr) { if (input_stream == nullptr) {
if (error.IsDefined()) if (error.IsDefined())
LogError(error); LogError(error);
@ -260,7 +260,6 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
done = true; done = true;
} else { } else {
mutex.unlock(); mutex.unlock();
delete input_stream;
return -1; return -1;
} }
} }
@ -279,7 +278,6 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
} }
mutex.unlock(); mutex.unlock();
delete input_stream;
return 0; return 0;
} }

View File

@ -72,7 +72,7 @@ decoder_seek_error(gcc_unused Decoder &decoder)
{ {
} }
InputStream * InputStreamPtr
decoder_open_uri(Decoder &decoder, const char *uri, Error &error) decoder_open_uri(Decoder &decoder, const char *uri, Error &error)
{ {
return InputStream::OpenReady(uri, decoder.mutex, decoder.cond, error); return InputStream::OpenReady(uri, decoder.mutex, decoder.cond, error);

View File

@ -50,7 +50,6 @@ tag_save(FILE *file, const Tag &tag)
int main(int argc, char **argv) int main(int argc, char **argv)
try { try {
const char *uri; const char *uri;
InputStream *is = NULL;
if (argc != 3) { if (argc != 3) {
fprintf(stderr, "Usage: dump_playlist CONFIG URI\n"); fprintf(stderr, "Usage: dump_playlist CONFIG URI\n");
@ -82,12 +81,13 @@ try {
Mutex mutex; Mutex mutex;
Cond cond; Cond cond;
InputStreamPtr is;
auto playlist = playlist_list_open_uri(uri, mutex, cond); auto playlist = playlist_list_open_uri(uri, mutex, cond);
if (playlist == NULL) { if (playlist == NULL) {
/* open the stream and wait until it becomes ready */ /* open the stream and wait until it becomes ready */
is = InputStream::OpenReady(uri, mutex, cond, error); is = InputStream::OpenReady(uri, mutex, cond, error);
if (is == NULL) { if (!is) {
if (error.IsDefined()) if (error.IsDefined())
LogError(error); LogError(error);
else else
@ -100,7 +100,6 @@ try {
playlist = playlist_list_open_stream(*is, uri); playlist = playlist_list_open_stream(*is, uri);
if (playlist == NULL) { if (playlist == NULL) {
delete is;
fprintf(stderr, "Failed to open playlist\n"); fprintf(stderr, "Failed to open playlist\n");
return 2; return 2;
} }
@ -132,7 +131,7 @@ try {
/* deinitialize everything */ /* deinitialize everything */
delete playlist; delete playlist;
delete is; is.reset();
decoder_plugin_deinit_all(); decoder_plugin_deinit_all();
playlist_list_global_finish(); playlist_list_global_finish();

View File

@ -92,19 +92,20 @@ int main(int argc, char **argv)
/* open the stream and dump it */ /* open the stream and dump it */
Mutex mutex; {
Cond cond; Mutex mutex;
Cond cond;
InputStream *is = InputStream::OpenReady(argv[1], mutex, cond, error); auto is = InputStream::OpenReady(argv[1], mutex, cond, error);
if (is != NULL) { if (is) {
ret = dump_input_stream(*is); ret = dump_input_stream(*is);
delete is; } else {
} else { if (error.IsDefined())
if (error.IsDefined()) LogError(error);
LogError(error); else
else fprintf(stderr, "input_stream::Open() failed\n");
fprintf(stderr, "input_stream::Open() failed\n"); ret = EXIT_FAILURE;
ret = EXIT_FAILURE; }
} }
/* deinitialize everything */ /* deinitialize everything */

View File

@ -107,16 +107,15 @@ int main(int argc, char **argv)
Mutex mutex; Mutex mutex;
Cond cond; Cond cond;
InputStream *is = InputStream::OpenReady(path.c_str(), auto is = InputStream::OpenReady(path.c_str(),
mutex, cond, mutex, cond,
error); error);
if (is == NULL) { if (!is) {
FormatError(error, "Failed to open %s", path.c_str()); FormatError(error, "Failed to open %s", path.c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
success = plugin->ScanStream(*is, print_handler, nullptr); success = plugin->ScanStream(*is, print_handler, nullptr);
delete is;
} }
decoder_plugin_deinit_all(); decoder_plugin_deinit_all();

View File

@ -64,10 +64,9 @@ int main(int argc, char **argv)
if (plugin->file_decode != nullptr) { if (plugin->file_decode != nullptr) {
plugin->FileDecode(decoder, Path::FromFS(uri)); plugin->FileDecode(decoder, Path::FromFS(uri));
} else if (plugin->stream_decode != nullptr) { } else if (plugin->stream_decode != nullptr) {
InputStream *is = auto is = InputStream::OpenReady(uri, decoder.mutex,
InputStream::OpenReady(uri, decoder.mutex, decoder.cond, error);
decoder.cond, error); if (!is) {
if (is == NULL) {
if (error.IsDefined()) if (error.IsDefined())
LogError(error); LogError(error);
else else
@ -77,8 +76,6 @@ int main(int argc, char **argv)
} }
plugin->StreamDecode(decoder, *is); plugin->StreamDecode(decoder, *is);
delete is;
} else { } else {
fprintf(stderr, "Decoder plugin is not usable\n"); fprintf(stderr, "Decoder plugin is not usable\n");
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -118,20 +118,20 @@ int main(int argc, char **argv)
/* open the stream and dump it */ /* open the stream and dump it */
Mutex mutex;
Cond cond;
InputStream *is = InputStream::OpenReady(argv[1], mutex, cond, error);
int ret; int ret;
if (is != NULL) { {
ret = dump_input_stream(is); Mutex mutex;
delete is; Cond cond;
} else { auto is = InputStream::OpenReady(argv[1], mutex, cond, error);
if (error.IsDefined()) if (is) {
LogError(error); ret = dump_input_stream(is.get());
else } else {
fprintf(stderr, "input_stream::Open() failed\n"); if (error.IsDefined())
ret = EXIT_FAILURE; LogError(error);
else
fprintf(stderr, "input_stream::Open() failed\n");
ret = EXIT_FAILURE;
}
} }
/* deinitialize everything */ /* deinitialize everything */