From cadc67ea40d761281d768256514d6660d820500f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 21 Feb 2016 08:03:32 +0100 Subject: [PATCH] input: wrap InputStream in std::unique_ptr --- src/TagFile.cxx | 6 +--- src/TagStream.cxx | 11 ++----- src/archive/plugins/Bzip2ArchivePlugin.cxx | 14 ++++----- src/decoder/DecoderAPI.cxx | 7 ++--- src/decoder/DecoderAPI.hxx | 3 +- src/decoder/plugins/WavpackDecoderPlugin.cxx | 4 +-- src/input/InputStream.hxx | 14 ++++----- src/input/LocalOpen.cxx | 6 ++-- src/input/LocalOpen.hxx | 4 +-- src/input/Open.cxx | 14 ++++----- src/input/Ptr.hxx | 29 +++++++++++++++++++ src/playlist/PlaylistStream.cxx | 14 ++++----- .../plugins/SoundCloudPlaylistPlugin.cxx | 6 ++-- test/FakeDecoderAPI.cxx | 2 +- test/dump_playlist.cxx | 7 ++--- test/dump_text_file.cxx | 25 ++++++++-------- test/read_tags.cxx | 9 +++--- test/run_decoder.cxx | 9 ++---- test/run_input.cxx | 26 ++++++++--------- 19 files changed, 107 insertions(+), 103 deletions(-) create mode 100644 src/input/Ptr.hxx diff --git a/src/TagFile.cxx b/src/TagFile.cxx index 0640c132e..3b29e8c09 100644 --- a/src/TagFile.cxx +++ b/src/TagFile.cxx @@ -39,7 +39,7 @@ class TagFileScan { Mutex mutex; Cond cond; - InputStream *is; + InputStreamPtr is; public: TagFileScan(Path _path_fs, const char *_suffix, @@ -48,10 +48,6 @@ public: handler(_handler), handler_ctx(_handler_ctx) , is(nullptr) {} - ~TagFileScan() { - delete is; - } - bool ScanFile(const DecoderPlugin &plugin) { return plugin.ScanFile(path_fs, handler, handler_ctx); } diff --git a/src/TagStream.cxx b/src/TagStream.cxx index dd5d8f7ec..243986fdd 100644 --- a/src/TagStream.cxx +++ b/src/TagStream.cxx @@ -68,12 +68,7 @@ tag_stream_scan(const char *uri, const tag_handler &handler, void *ctx) Mutex mutex; Cond cond; - InputStream *is = InputStream::OpenReady(uri, mutex, cond, - IgnoreError()); - if (is == nullptr) - return false; - - bool success = tag_stream_scan(*is, handler, ctx); - delete is; - return success; + auto is = InputStream::OpenReady(uri, mutex, cond, + IgnoreError()); + return is && tag_stream_scan(*is, handler, ctx); } diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 3b40e0b36..0bbaba954 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -49,22 +49,18 @@ public: RefCount ref; std::string name; - InputStream *const istream; + const InputStreamPtr istream; - Bzip2ArchiveFile(Path path, InputStream *_is) + Bzip2ArchiveFile(Path path, InputStreamPtr &&_is) :ArchiveFile(bz2_archive_plugin), name(path.GetBase().c_str()), - istream(_is) { + istream(std::move(_is)) { // remove .bz2 suffix const size_t len = name.length(); if (len > 4) name.erase(len - 4); } - ~Bzip2ArchiveFile() { - delete istream; - } - void Ref() { ref.Increment(); } @@ -141,11 +137,11 @@ bz2_open(Path pathname, Error &error) { static Mutex mutex; static Cond cond; - InputStream *is = OpenLocalInputStream(pathname, mutex, cond, error); + auto is = OpenLocalInputStream(pathname, mutex, cond, error); if (is == nullptr) return nullptr; - return new Bzip2ArchiveFile(pathname, is); + return new Bzip2ArchiveFile(pathname, std::move(is)); } /* single archive handling */ diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx index 166f1eaf1..87ef6f7c9 100644 --- a/src/decoder/DecoderAPI.cxx +++ b/src/decoder/DecoderAPI.cxx @@ -256,7 +256,7 @@ void decoder_seek_error(Decoder & decoder) decoder_command_finished(decoder); } -InputStream * +InputStreamPtr decoder_open_uri(Decoder &decoder, const char *uri, Error &error) { assert(decoder.dc.state == DecoderState::START || @@ -266,8 +266,8 @@ decoder_open_uri(Decoder &decoder, const char *uri, Error &error) Mutex &mutex = dc.mutex; Cond &cond = dc.cond; - InputStream *is = InputStream::Open(uri, mutex, cond, error); - if (is == nullptr) + auto is = InputStream::Open(uri, mutex, cond, error); + if (!is) return nullptr; mutex.lock(); @@ -280,7 +280,6 @@ decoder_open_uri(Decoder &decoder, const char *uri, Error &error) if (dc.command == DecoderCommand::STOP) { mutex.unlock(); - delete is; return nullptr; } diff --git a/src/decoder/DecoderAPI.hxx b/src/decoder/DecoderAPI.hxx index 289298ba4..8e0346e28 100644 --- a/src/decoder/DecoderAPI.hxx +++ b/src/decoder/DecoderAPI.hxx @@ -30,6 +30,7 @@ // IWYU pragma: begin_exports #include "check.h" +#include "input/Ptr.hxx" #include "DecoderCommand.hxx" #include "DecoderPlugin.hxx" #include "ReplayGainInfo.hxx" @@ -116,7 +117,7 @@ decoder_seek_error(Decoder &decoder); * cancelled by DecoderCommand::STOP (returns nullptr without setting * #Error). */ -InputStream * +InputStreamPtr decoder_open_uri(Decoder &decoder, const char *uri, Error &error); /** diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx index 339fd6910..af1f65ba3 100644 --- a/src/decoder/plugins/WavpackDecoderPlugin.cxx +++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx @@ -486,13 +486,13 @@ wavpack_open_wvc(Decoder &decoder, const char *uri) 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); if (is_wvc == nullptr) return nullptr; - return new WavpackInput(decoder, *is_wvc); + return new WavpackInput(decoder, *is_wvc.release()); } /* diff --git a/src/input/InputStream.hxx b/src/input/InputStream.hxx index bf628ea64..458947eb4 100644 --- a/src/input/InputStream.hxx +++ b/src/input/InputStream.hxx @@ -22,6 +22,7 @@ #include "check.h" #include "Offset.hxx" +#include "Ptr.hxx" #include "thread/Mutex.hxx" #include "Compiler.h" @@ -123,18 +124,17 @@ public: * @return an #InputStream object on success, nullptr on error */ gcc_nonnull_all - gcc_malloc - static InputStream *Open(const char *uri, Mutex &mutex, Cond &cond, - Error &error); + static InputStreamPtr Open(const char *uri, Mutex &mutex, Cond &cond, + Error &error); /** * Just like Open(), but waits for the stream to become ready. * It is a wrapper for Open(), WaitReady() and Check(). */ - gcc_malloc gcc_nonnull_all - static InputStream *OpenReady(const char *uri, - Mutex &mutex, Cond &cond, - Error &error); + gcc_nonnull_all + static InputStreamPtr OpenReady(const char *uri, + Mutex &mutex, Cond &cond, + Error &error); /** * The absolute URI which was used to open this stream. diff --git a/src/input/LocalOpen.cxx b/src/input/LocalOpen.cxx index 25644bae1..b9cc01982 100644 --- a/src/input/LocalOpen.cxx +++ b/src/input/LocalOpen.cxx @@ -35,19 +35,19 @@ #include #endif -InputStream * +InputStreamPtr OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error) { assert(!error.IsDefined()); - InputStream *is = OpenFileInputStream(path, mutex, cond, error); + InputStreamPtr is(OpenFileInputStream(path, mutex, cond, error)); #ifdef ENABLE_ARCHIVE if (is == nullptr && error.IsDomain(errno_domain) && error.GetCode() == ENOTDIR) { /* ENOTDIR means this may be a path inside an archive file */ Error error2; - is = OpenArchiveInputStream(path, mutex, cond, error2); + is.reset(OpenArchiveInputStream(path, mutex, cond, error2)); if (is == nullptr && error2.IsDefined()) error = std::move(error2); } diff --git a/src/input/LocalOpen.hxx b/src/input/LocalOpen.hxx index 6f4ef2a2c..6335d17e6 100644 --- a/src/input/LocalOpen.hxx +++ b/src/input/LocalOpen.hxx @@ -21,8 +21,8 @@ #define MPD_INPUT_LOCAL_OPEN_HXX #include "check.h" +#include "Ptr.hxx" -class InputStream; class Path; class Mutex; class Cond; @@ -32,7 +32,7 @@ class Error; * Open a "local" file. This is a wrapper for the input plugins * "file" and "archive". */ -InputStream * +InputStreamPtr OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error); #endif diff --git a/src/input/Open.cxx b/src/input/Open.cxx index 6bcca0b84..02ad2cea1 100644 --- a/src/input/Open.cxx +++ b/src/input/Open.cxx @@ -30,7 +30,7 @@ #include "util/Error.hxx" #include "util/Domain.hxx" -InputStream * +InputStreamPtr InputStream::Open(const char *url, Mutex &mutex, Cond &cond, Error &error) @@ -51,7 +51,7 @@ InputStream::Open(const char *url, if (is != nullptr) { is = input_rewind_open(is); - return is; + return InputStreamPtr(is); } else if (error.IsDefined()) return nullptr; } @@ -60,12 +60,12 @@ InputStream::Open(const char *url, return nullptr; } -InputStream * +InputStreamPtr InputStream::OpenReady(const char *uri, Mutex &mutex, Cond &cond, Error &error) { - InputStream *is = Open(uri, mutex, cond, error); + auto is = Open(uri, mutex, cond, error); if (is == nullptr) return nullptr; @@ -74,10 +74,8 @@ InputStream::OpenReady(const char *uri, bool success = is->Check(error); mutex.unlock(); - if (!success) { - delete is; - is = nullptr; - } + if (!success) + is.reset(); return is; } diff --git a/src/input/Ptr.hxx b/src/input/Ptr.hxx new file mode 100644 index 000000000..e05b4cf95 --- /dev/null +++ b/src/input/Ptr.hxx @@ -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 + +class InputStream; + +typedef std::unique_ptr InputStreamPtr; + +#endif diff --git a/src/playlist/PlaylistStream.cxx b/src/playlist/PlaylistStream.cxx index ab3f00ee5..9663d39b6 100644 --- a/src/playlist/PlaylistStream.cxx +++ b/src/playlist/PlaylistStream.cxx @@ -44,7 +44,7 @@ try { return nullptr; Error error; - InputStream *is = OpenLocalInputStream(path, mutex, cond, error); + auto is = OpenLocalInputStream(path, mutex, cond, error); if (is == nullptr) { LogError(error); return nullptr; @@ -53,9 +53,7 @@ try { auto playlist = playlist_list_open_stream_suffix(*is, suffix_utf8.c_str()); if (playlist != nullptr) - playlist = new CloseSongEnumerator(playlist, is); - else - delete is; + playlist = new CloseSongEnumerator(playlist, is.release()); return playlist; } catch (const std::runtime_error &e) { @@ -91,7 +89,7 @@ try { return playlist; Error error; - InputStream *is = InputStream::OpenReady(uri, mutex, cond, error); + auto is = InputStream::OpenReady(uri, mutex, cond, error); if (is == nullptr) { if (error.IsDefined()) FormatError(error, "Failed to open %s", uri); @@ -100,12 +98,10 @@ try { } playlist = playlist_list_open_stream(*is, uri); - if (playlist == nullptr) { - delete is; + if (playlist == nullptr) return nullptr; - } - return new CloseSongEnumerator(playlist, is); + return new CloseSongEnumerator(playlist, is.release()); } catch (const std::runtime_error &e) { LogError(e); return nullptr; diff --git a/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx b/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx index 0d3f0fb8b..0aeefe56f 100644 --- a/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx +++ b/src/playlist/plugins/SoundCloudPlaylistPlugin.cxx @@ -234,8 +234,8 @@ soundcloud_parse_json(const char *url, yajl_handle hand, Mutex &mutex, Cond &cond) { Error error; - InputStream *input_stream = InputStream::OpenReady(url, mutex, cond, - error); + auto input_stream = InputStream::OpenReady(url, mutex, cond, + error); if (input_stream == nullptr) { if (error.IsDefined()) LogError(error); @@ -260,7 +260,6 @@ soundcloud_parse_json(const char *url, yajl_handle hand, done = true; } else { mutex.unlock(); - delete input_stream; return -1; } } @@ -279,7 +278,6 @@ soundcloud_parse_json(const char *url, yajl_handle hand, } mutex.unlock(); - delete input_stream; return 0; } diff --git a/test/FakeDecoderAPI.cxx b/test/FakeDecoderAPI.cxx index 49f7a7a5e..de6bc373b 100644 --- a/test/FakeDecoderAPI.cxx +++ b/test/FakeDecoderAPI.cxx @@ -72,7 +72,7 @@ decoder_seek_error(gcc_unused Decoder &decoder) { } -InputStream * +InputStreamPtr decoder_open_uri(Decoder &decoder, const char *uri, Error &error) { return InputStream::OpenReady(uri, decoder.mutex, decoder.cond, error); diff --git a/test/dump_playlist.cxx b/test/dump_playlist.cxx index 7ae06eacf..0da744528 100644 --- a/test/dump_playlist.cxx +++ b/test/dump_playlist.cxx @@ -50,7 +50,6 @@ tag_save(FILE *file, const Tag &tag) int main(int argc, char **argv) try { const char *uri; - InputStream *is = NULL; if (argc != 3) { fprintf(stderr, "Usage: dump_playlist CONFIG URI\n"); @@ -82,12 +81,13 @@ try { Mutex mutex; Cond cond; + InputStreamPtr is; auto playlist = playlist_list_open_uri(uri, mutex, cond); if (playlist == NULL) { /* open the stream and wait until it becomes ready */ is = InputStream::OpenReady(uri, mutex, cond, error); - if (is == NULL) { + if (!is) { if (error.IsDefined()) LogError(error); else @@ -100,7 +100,6 @@ try { playlist = playlist_list_open_stream(*is, uri); if (playlist == NULL) { - delete is; fprintf(stderr, "Failed to open playlist\n"); return 2; } @@ -132,7 +131,7 @@ try { /* deinitialize everything */ delete playlist; - delete is; + is.reset(); decoder_plugin_deinit_all(); playlist_list_global_finish(); diff --git a/test/dump_text_file.cxx b/test/dump_text_file.cxx index a207b3400..467aeb4f5 100644 --- a/test/dump_text_file.cxx +++ b/test/dump_text_file.cxx @@ -92,19 +92,20 @@ int main(int argc, char **argv) /* open the stream and dump it */ - Mutex mutex; - Cond cond; + { + Mutex mutex; + Cond cond; - InputStream *is = InputStream::OpenReady(argv[1], mutex, cond, error); - if (is != NULL) { - ret = dump_input_stream(*is); - delete is; - } else { - if (error.IsDefined()) - LogError(error); - else - fprintf(stderr, "input_stream::Open() failed\n"); - ret = EXIT_FAILURE; + auto is = InputStream::OpenReady(argv[1], mutex, cond, error); + if (is) { + ret = dump_input_stream(*is); + } else { + if (error.IsDefined()) + LogError(error); + else + fprintf(stderr, "input_stream::Open() failed\n"); + ret = EXIT_FAILURE; + } } /* deinitialize everything */ diff --git a/test/read_tags.cxx b/test/read_tags.cxx index a00e87529..d13f777bd 100644 --- a/test/read_tags.cxx +++ b/test/read_tags.cxx @@ -107,16 +107,15 @@ int main(int argc, char **argv) Mutex mutex; Cond cond; - InputStream *is = InputStream::OpenReady(path.c_str(), - mutex, cond, - error); - if (is == NULL) { + auto is = InputStream::OpenReady(path.c_str(), + mutex, cond, + error); + if (!is) { FormatError(error, "Failed to open %s", path.c_str()); return EXIT_FAILURE; } success = plugin->ScanStream(*is, print_handler, nullptr); - delete is; } decoder_plugin_deinit_all(); diff --git a/test/run_decoder.cxx b/test/run_decoder.cxx index 35d55cedf..f563f939a 100644 --- a/test/run_decoder.cxx +++ b/test/run_decoder.cxx @@ -64,10 +64,9 @@ int main(int argc, char **argv) if (plugin->file_decode != nullptr) { plugin->FileDecode(decoder, Path::FromFS(uri)); } else if (plugin->stream_decode != nullptr) { - InputStream *is = - InputStream::OpenReady(uri, decoder.mutex, - decoder.cond, error); - if (is == NULL) { + auto is = InputStream::OpenReady(uri, decoder.mutex, + decoder.cond, error); + if (!is) { if (error.IsDefined()) LogError(error); else @@ -77,8 +76,6 @@ int main(int argc, char **argv) } plugin->StreamDecode(decoder, *is); - - delete is; } else { fprintf(stderr, "Decoder plugin is not usable\n"); return EXIT_FAILURE; diff --git a/test/run_input.cxx b/test/run_input.cxx index 6d51b3749..b93f71548 100644 --- a/test/run_input.cxx +++ b/test/run_input.cxx @@ -118,20 +118,20 @@ int main(int argc, char **argv) /* open the stream and dump it */ - Mutex mutex; - Cond cond; - - InputStream *is = InputStream::OpenReady(argv[1], mutex, cond, error); int ret; - if (is != NULL) { - ret = dump_input_stream(is); - delete is; - } else { - if (error.IsDefined()) - LogError(error); - else - fprintf(stderr, "input_stream::Open() failed\n"); - ret = EXIT_FAILURE; + { + Mutex mutex; + Cond cond; + auto is = InputStream::OpenReady(argv[1], mutex, cond, error); + if (is) { + ret = dump_input_stream(is.get()); + } else { + if (error.IsDefined()) + LogError(error); + else + fprintf(stderr, "input_stream::Open() failed\n"); + ret = EXIT_FAILURE; + } } /* deinitialize everything */