Commit 73e69eda authored by Max Kellermann's avatar Max Kellermann

input/InputStream: ReadTag() returns std::unique_ptr<Tag>

parent 4c4fa682
...@@ -223,7 +223,7 @@ bool ...@@ -223,7 +223,7 @@ bool
DecoderBridge::UpdateStreamTag(InputStream *is) DecoderBridge::UpdateStreamTag(InputStream *is)
{ {
auto *tag = is != nullptr auto *tag = is != nullptr
? is->LockReadTag() ? is->LockReadTag().release()
: nullptr; : nullptr;
if (tag == nullptr) { if (tag == nullptr) {
tag = song_tag; tag = song_tag;
......
...@@ -45,15 +45,19 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url, ...@@ -45,15 +45,19 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url,
AsyncInputStream::~AsyncInputStream() AsyncInputStream::~AsyncInputStream()
{ {
delete tag;
buffer.Clear(); buffer.Clear();
} }
void void
AsyncInputStream::SetTag(Tag *_tag) noexcept AsyncInputStream::SetTag(std::unique_ptr<Tag> _tag) noexcept
{
tag = std::move(_tag);
}
void
AsyncInputStream::ClearTag() noexcept
{ {
delete std::exchange(tag, _tag); tag.reset();
} }
void void
...@@ -151,7 +155,7 @@ AsyncInputStream::SeekDone() noexcept ...@@ -151,7 +155,7 @@ AsyncInputStream::SeekDone() noexcept
cond.broadcast(); cond.broadcast();
} }
Tag * std::unique_ptr<Tag>
AsyncInputStream::ReadTag() AsyncInputStream::ReadTag()
{ {
return std::exchange(tag, nullptr); return std::exchange(tag, nullptr);
......
...@@ -61,7 +61,7 @@ class AsyncInputStream : public InputStream { ...@@ -61,7 +61,7 @@ class AsyncInputStream : public InputStream {
* The #Tag object ready to be requested via * The #Tag object ready to be requested via
* InputStream::ReadTag(). * InputStream::ReadTag().
*/ */
Tag *tag = nullptr; std::unique_ptr<Tag> tag;
offset_type seek_offset; offset_type seek_offset;
...@@ -84,7 +84,7 @@ public: ...@@ -84,7 +84,7 @@ public:
void Check() final; void Check() final;
bool IsEOF() noexcept final; bool IsEOF() noexcept final;
void Seek(offset_type new_offset) final; void Seek(offset_type new_offset) final;
Tag *ReadTag() final; std::unique_ptr<Tag> ReadTag() final;
bool IsAvailable() noexcept final; bool IsAvailable() noexcept final;
size_t Read(void *ptr, size_t read_size) final; size_t Read(void *ptr, size_t read_size) final;
...@@ -92,11 +92,8 @@ protected: ...@@ -92,11 +92,8 @@ protected:
/** /**
* Pass an tag from the I/O thread to the client thread. * Pass an tag from the I/O thread to the client thread.
*/ */
void SetTag(Tag *_tag) noexcept; void SetTag(std::unique_ptr<Tag> _tag) noexcept;
void ClearTag() noexcept;
void ClearTag() noexcept {
SetTag(nullptr);
}
void Pause() noexcept; void Pause() noexcept;
......
...@@ -38,22 +38,23 @@ IcyInputStream::Update() ...@@ -38,22 +38,23 @@ IcyInputStream::Update()
offset = override_offset; offset = override_offset;
} }
Tag * std::unique_ptr<Tag>
IcyInputStream::ReadTag() IcyInputStream::ReadTag()
{ {
Tag *new_input_tag = ProxyInputStream::ReadTag(); auto new_input_tag = ProxyInputStream::ReadTag();
if (!IsEnabled()) if (!IsEnabled())
return new_input_tag; return new_input_tag;
const bool had_new_input_tag = !!new_input_tag;
if (new_input_tag != nullptr) if (new_input_tag != nullptr)
input_tag.reset(new_input_tag); input_tag = std::move(new_input_tag);
auto new_icy_tag = parser.ReadTag(); auto new_icy_tag = parser.ReadTag();
const bool had_new_icy_tag = !!new_icy_tag; const bool had_new_icy_tag = !!new_icy_tag;
if (new_icy_tag != nullptr) if (new_icy_tag != nullptr)
icy_tag = std::move(new_icy_tag); 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 */ /* no change */
return nullptr; return nullptr;
...@@ -62,12 +63,12 @@ IcyInputStream::ReadTag() ...@@ -62,12 +63,12 @@ IcyInputStream::ReadTag()
return nullptr; return nullptr;
if (input_tag == nullptr) if (input_tag == nullptr)
return new Tag(*icy_tag); return std::make_unique<Tag>(*icy_tag);
if (icy_tag == nullptr) if (icy_tag == nullptr)
return new Tag(*input_tag); return std::make_unique<Tag>(*input_tag);
return Tag::Merge(*input_tag, *icy_tag).release(); return Tag::Merge(*input_tag, *icy_tag);
} }
size_t size_t
......
...@@ -63,7 +63,7 @@ public: ...@@ -63,7 +63,7 @@ public:
/* virtual methods from InputStream */ /* virtual methods from InputStream */
void Update() override; void Update() override;
Tag *ReadTag() override; std::unique_ptr<Tag> ReadTag() override;
size_t Read(void *ptr, size_t size) override; size_t Read(void *ptr, size_t size) override;
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "InputStream.hxx" #include "InputStream.hxx"
#include "tag/Tag.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include "util/StringCompare.hxx" #include "util/StringCompare.hxx"
...@@ -107,13 +108,13 @@ InputStream::LockSkip(offset_type _offset) ...@@ -107,13 +108,13 @@ InputStream::LockSkip(offset_type _offset)
Skip(_offset); Skip(_offset);
} }
Tag * std::unique_ptr<Tag>
InputStream::ReadTag() InputStream::ReadTag()
{ {
return nullptr; return nullptr;
} }
Tag * std::unique_ptr<Tag>
InputStream::LockReadTag() InputStream::LockReadTag()
{ {
const std::lock_guard<Mutex> protect(mutex); const std::lock_guard<Mutex> protect(mutex);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "Compiler.h" #include "Compiler.h"
#include <string> #include <string>
#include <memory>
#include <assert.h> #include <assert.h>
...@@ -322,18 +323,16 @@ public: ...@@ -322,18 +323,16 @@ public:
* *
* The caller must lock the mutex. * The caller must lock the mutex.
* *
* @return a tag object which must be freed by the caller, or * @return a tag object or nullptr if the tag has not changed
* nullptr if the tag has not changed since the last call * since the last call
*/ */
gcc_malloc virtual std::unique_ptr<Tag> ReadTag();
virtual Tag *ReadTag();
/** /**
* Wrapper for ReadTag() which locks and unlocks the mutex; * Wrapper for ReadTag() which locks and unlocks the mutex;
* the caller must not be holding it already. * the caller must not be holding it already.
*/ */
gcc_malloc std::unique_ptr<Tag> LockReadTag();
Tag *LockReadTag();
/** /**
* Returns true if the next read operation will not block: either data * Returns true if the next read operation will not block: either data
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "ProxyInputStream.hxx" #include "ProxyInputStream.hxx"
#include "tag/Tag.hxx"
ProxyInputStream::ProxyInputStream(InputStream *_input) ProxyInputStream::ProxyInputStream(InputStream *_input)
:InputStream(_input->GetURI(), _input->mutex, _input->cond), :InputStream(_input->GetURI(), _input->mutex, _input->cond),
...@@ -75,7 +76,7 @@ ProxyInputStream::IsEOF() noexcept ...@@ -75,7 +76,7 @@ ProxyInputStream::IsEOF() noexcept
return input.IsEOF(); return input.IsEOF();
} }
Tag * std::unique_ptr<Tag>
ProxyInputStream::ReadTag() ProxyInputStream::ReadTag()
{ {
return input.ReadTag(); return input.ReadTag();
......
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
void Update() override; void Update() override;
void Seek(offset_type new_offset) override; void Seek(offset_type new_offset) override;
bool IsEOF() noexcept override; bool IsEOF() noexcept override;
Tag *ReadTag() override; std::unique_ptr<Tag> ReadTag() override;
bool IsAvailable() noexcept override; bool IsAvailable() noexcept override;
size_t Read(void *ptr, size_t read_size) override; size_t Read(void *ptr, size_t read_size) override;
......
...@@ -223,7 +223,7 @@ CurlInputStream::OnHeaders(unsigned status, ...@@ -223,7 +223,7 @@ CurlInputStream::OnHeaders(unsigned status,
TagBuilder tag_builder; TagBuilder tag_builder;
tag_builder.AddItem(TAG_NAME, i->second.c_str()); tag_builder.AddItem(TAG_NAME, i->second.c_str());
SetTag(tag_builder.CommitNew().release()); SetTag(tag_builder.CommitNew());
} }
if (!icy->IsEnabled()) { if (!icy->IsEnabled()) {
......
...@@ -82,11 +82,12 @@ dump_input_stream(InputStream *is) ...@@ -82,11 +82,12 @@ dump_input_stream(InputStream *is)
/* read data and tags from the stream */ /* read data and tags from the stream */
while (!is->IsEOF()) { while (!is->IsEOF()) {
Tag *tag = is->ReadTag(); {
if (tag != NULL) { auto tag = is->ReadTag();
if (tag) {
fprintf(stderr, "Received a tag:\n"); fprintf(stderr, "Received a tag:\n");
tag_save(stderr, *tag); tag_save(stderr, *tag);
delete tag; }
} }
char buffer[4096]; char buffer[4096];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment