From 73e69edac3fc6960d6bf89fca420c27f83b95d8e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 20 Dec 2017 15:15:27 +0100 Subject: [PATCH] input/InputStream: ReadTag() returns std::unique_ptr --- src/decoder/Bridge.cxx | 2 +- src/input/AsyncInputStream.cxx | 14 +++++++++----- src/input/AsyncInputStream.hxx | 11 ++++------- src/input/IcyInputStream.cxx | 15 ++++++++------- src/input/IcyInputStream.hxx | 2 +- src/input/InputStream.cxx | 5 +++-- src/input/InputStream.hxx | 11 +++++------ src/input/ProxyInputStream.cxx | 3 ++- src/input/ProxyInputStream.hxx | 2 +- src/input/plugins/CurlInputPlugin.cxx | 2 +- test/run_input.cxx | 11 ++++++----- 11 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx index 0bd6d9e1c..d4038f0ac 100644 --- a/src/decoder/Bridge.cxx +++ b/src/decoder/Bridge.cxx @@ -223,7 +223,7 @@ bool DecoderBridge::UpdateStreamTag(InputStream *is) { auto *tag = is != nullptr - ? is->LockReadTag() + ? is->LockReadTag().release() : nullptr; if (tag == nullptr) { tag = song_tag; diff --git a/src/input/AsyncInputStream.cxx b/src/input/AsyncInputStream.cxx index 1cf4b81cd..52c1b18d0 100644 --- a/src/input/AsyncInputStream.cxx +++ b/src/input/AsyncInputStream.cxx @@ -45,15 +45,19 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url, AsyncInputStream::~AsyncInputStream() { - delete tag; - buffer.Clear(); } void -AsyncInputStream::SetTag(Tag *_tag) noexcept +AsyncInputStream::SetTag(std::unique_ptr _tag) noexcept { - delete std::exchange(tag, _tag); + tag = std::move(_tag); +} + +void +AsyncInputStream::ClearTag() noexcept +{ + tag.reset(); } void @@ -151,7 +155,7 @@ AsyncInputStream::SeekDone() noexcept cond.broadcast(); } -Tag * +std::unique_ptr AsyncInputStream::ReadTag() { return std::exchange(tag, nullptr); diff --git a/src/input/AsyncInputStream.hxx b/src/input/AsyncInputStream.hxx index 1985daf1f..117ebfc3a 100644 --- a/src/input/AsyncInputStream.hxx +++ b/src/input/AsyncInputStream.hxx @@ -61,7 +61,7 @@ class AsyncInputStream : public InputStream { * The #Tag object ready to be requested via * InputStream::ReadTag(). */ - Tag *tag = nullptr; + std::unique_ptr tag; offset_type seek_offset; @@ -84,7 +84,7 @@ public: void Check() final; bool IsEOF() noexcept final; void Seek(offset_type new_offset) final; - Tag *ReadTag() final; + std::unique_ptr ReadTag() final; bool IsAvailable() noexcept final; size_t Read(void *ptr, size_t read_size) final; @@ -92,11 +92,8 @@ protected: /** * Pass an tag from the I/O thread to the client thread. */ - void SetTag(Tag *_tag) noexcept; - - void ClearTag() noexcept { - SetTag(nullptr); - } + void SetTag(std::unique_ptr _tag) noexcept; + void ClearTag() noexcept; void Pause() noexcept; diff --git a/src/input/IcyInputStream.cxx b/src/input/IcyInputStream.cxx index 66b78b60f..23a971573 100644 --- a/src/input/IcyInputStream.cxx +++ b/src/input/IcyInputStream.cxx @@ -38,22 +38,23 @@ IcyInputStream::Update() offset = override_offset; } -Tag * +std::unique_ptr IcyInputStream::ReadTag() { - Tag *new_input_tag = ProxyInputStream::ReadTag(); + auto new_input_tag = ProxyInputStream::ReadTag(); if (!IsEnabled()) return new_input_tag; + const bool had_new_input_tag = !!new_input_tag; if (new_input_tag != nullptr) - input_tag.reset(new_input_tag); + input_tag = std::move(new_input_tag); auto new_icy_tag = parser.ReadTag(); const bool had_new_icy_tag = !!new_icy_tag; if (new_icy_tag != nullptr) icy_tag = std::move(new_icy_tag); - if (new_input_tag == nullptr && !had_new_icy_tag) + if (!had_new_input_tag && !had_new_icy_tag) /* no change */ return nullptr; @@ -62,12 +63,12 @@ IcyInputStream::ReadTag() return nullptr; if (input_tag == nullptr) - return new Tag(*icy_tag); + return std::make_unique(*icy_tag); if (icy_tag == nullptr) - return new Tag(*input_tag); + return std::make_unique(*input_tag); - return Tag::Merge(*input_tag, *icy_tag).release(); + return Tag::Merge(*input_tag, *icy_tag); } size_t diff --git a/src/input/IcyInputStream.hxx b/src/input/IcyInputStream.hxx index fa89ce655..986abdca2 100644 --- a/src/input/IcyInputStream.hxx +++ b/src/input/IcyInputStream.hxx @@ -63,7 +63,7 @@ public: /* virtual methods from InputStream */ void Update() override; - Tag *ReadTag() override; + std::unique_ptr ReadTag() override; size_t Read(void *ptr, size_t size) override; }; diff --git a/src/input/InputStream.cxx b/src/input/InputStream.cxx index d17a95f1e..94db21dbc 100644 --- a/src/input/InputStream.cxx +++ b/src/input/InputStream.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "InputStream.hxx" +#include "tag/Tag.hxx" #include "thread/Cond.hxx" #include "util/StringCompare.hxx" @@ -107,13 +108,13 @@ InputStream::LockSkip(offset_type _offset) Skip(_offset); } -Tag * +std::unique_ptr InputStream::ReadTag() { return nullptr; } -Tag * +std::unique_ptr InputStream::LockReadTag() { const std::lock_guard protect(mutex); diff --git a/src/input/InputStream.hxx b/src/input/InputStream.hxx index b5237ee4b..3d5b7542c 100644 --- a/src/input/InputStream.hxx +++ b/src/input/InputStream.hxx @@ -27,6 +27,7 @@ #include "Compiler.h" #include +#include #include @@ -322,18 +323,16 @@ public: * * The caller must lock the mutex. * - * @return a tag object which must be freed by the caller, or - * nullptr if the tag has not changed since the last call + * @return a tag object or nullptr if the tag has not changed + * since the last call */ - gcc_malloc - virtual Tag *ReadTag(); + virtual std::unique_ptr ReadTag(); /** * Wrapper for ReadTag() which locks and unlocks the mutex; * the caller must not be holding it already. */ - gcc_malloc - Tag *LockReadTag(); + std::unique_ptr LockReadTag(); /** * Returns true if the next read operation will not block: either data diff --git a/src/input/ProxyInputStream.cxx b/src/input/ProxyInputStream.cxx index c8e66fecf..8a6d3a22b 100644 --- a/src/input/ProxyInputStream.cxx +++ b/src/input/ProxyInputStream.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "ProxyInputStream.hxx" +#include "tag/Tag.hxx" ProxyInputStream::ProxyInputStream(InputStream *_input) :InputStream(_input->GetURI(), _input->mutex, _input->cond), @@ -75,7 +76,7 @@ ProxyInputStream::IsEOF() noexcept return input.IsEOF(); } -Tag * +std::unique_ptr ProxyInputStream::ReadTag() { return input.ReadTag(); diff --git a/src/input/ProxyInputStream.hxx b/src/input/ProxyInputStream.hxx index bce35c224..075e3da5b 100644 --- a/src/input/ProxyInputStream.hxx +++ b/src/input/ProxyInputStream.hxx @@ -47,7 +47,7 @@ public: void Update() override; void Seek(offset_type new_offset) override; bool IsEOF() noexcept override; - Tag *ReadTag() override; + std::unique_ptr ReadTag() override; bool IsAvailable() noexcept override; size_t Read(void *ptr, size_t read_size) override; diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index ab568e62a..bb264381d 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -223,7 +223,7 @@ CurlInputStream::OnHeaders(unsigned status, TagBuilder tag_builder; tag_builder.AddItem(TAG_NAME, i->second.c_str()); - SetTag(tag_builder.CommitNew().release()); + SetTag(tag_builder.CommitNew()); } if (!icy->IsEnabled()) { diff --git a/test/run_input.cxx b/test/run_input.cxx index d7bf58824..1c374d3d6 100644 --- a/test/run_input.cxx +++ b/test/run_input.cxx @@ -82,11 +82,12 @@ dump_input_stream(InputStream *is) /* read data and tags from the stream */ while (!is->IsEOF()) { - Tag *tag = is->ReadTag(); - if (tag != NULL) { - fprintf(stderr, "Received a tag:\n"); - tag_save(stderr, *tag); - delete tag; + { + auto tag = is->ReadTag(); + if (tag) { + fprintf(stderr, "Received a tag:\n"); + tag_save(stderr, *tag); + } } char buffer[4096];