input/Icy: manage the parser in a std::shared_ptr
This resolves the circular dependency between IcyInputStream and CurlInputStream.
This commit is contained in:
parent
cd38aa3b2a
commit
fb9a2c5431
@ -19,15 +19,25 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "IcyInputStream.hxx"
|
#include "IcyInputStream.hxx"
|
||||||
|
#include "IcyMetaDataParser.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
|
|
||||||
IcyInputStream::IcyInputStream(InputStream *_input) noexcept
|
IcyInputStream::IcyInputStream(InputStream *_input,
|
||||||
:ProxyInputStream(_input)
|
std::shared_ptr<IcyMetaDataParser> _parser) noexcept
|
||||||
|
:ProxyInputStream(_input), parser(std::move(_parser))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IcyInputStream::~IcyInputStream() noexcept = default;
|
IcyInputStream::~IcyInputStream() noexcept = default;
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
IcyInputStream::IsEnabled() const noexcept
|
||||||
|
{
|
||||||
|
assert(parser);
|
||||||
|
|
||||||
|
return parser->IsDefined();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IcyInputStream::Update() noexcept
|
IcyInputStream::Update() noexcept
|
||||||
{
|
{
|
||||||
@ -48,7 +58,7 @@ IcyInputStream::ReadTag()
|
|||||||
if (new_input_tag != nullptr)
|
if (new_input_tag != nullptr)
|
||||||
input_tag = std::move(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);
|
||||||
@ -81,7 +91,7 @@ IcyInputStream::Read(void *ptr, size_t read_size)
|
|||||||
if (nbytes == 0)
|
if (nbytes == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
size_t result = parser.ParseInPlace(ptr, nbytes);
|
size_t result = parser->ParseInPlace(ptr, nbytes);
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
override_offset += result;
|
override_offset += result;
|
||||||
offset = override_offset;
|
offset = override_offset;
|
||||||
|
@ -21,18 +21,18 @@
|
|||||||
#define MPD_ICY_INPUT_STREAM_HXX
|
#define MPD_ICY_INPUT_STREAM_HXX
|
||||||
|
|
||||||
#include "ProxyInputStream.hxx"
|
#include "ProxyInputStream.hxx"
|
||||||
#include "IcyMetaDataParser.hxx"
|
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
class IcyMetaDataParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An #InputStream filter that parses Icy metadata.
|
* An #InputStream filter that parses Icy metadata.
|
||||||
*/
|
*/
|
||||||
class IcyInputStream final : public ProxyInputStream {
|
class IcyInputStream final : public ProxyInputStream {
|
||||||
IcyMetaDataParser parser;
|
std::shared_ptr<IcyMetaDataParser> parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The #Tag object ready to be requested via ReadTag().
|
* The #Tag object ready to be requested via ReadTag().
|
||||||
@ -47,19 +47,21 @@ class IcyInputStream final : public ProxyInputStream {
|
|||||||
offset_type override_offset = 0;
|
offset_type override_offset = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IcyInputStream(InputStream *_input) noexcept;
|
/**
|
||||||
|
* @param _parser a IcyMetaDataParser instance which is shared
|
||||||
|
* with our input; it needs to be shared because our input
|
||||||
|
* needs to feed parameters (e.g. from the "icy-metaint"
|
||||||
|
* header) into it
|
||||||
|
*/
|
||||||
|
IcyInputStream(InputStream *_input,
|
||||||
|
std::shared_ptr<IcyMetaDataParser> _parser) noexcept;
|
||||||
virtual ~IcyInputStream() noexcept;
|
virtual ~IcyInputStream() noexcept;
|
||||||
|
|
||||||
IcyInputStream(const IcyInputStream &) = delete;
|
IcyInputStream(const IcyInputStream &) = delete;
|
||||||
IcyInputStream &operator=(const IcyInputStream &) = delete;
|
IcyInputStream &operator=(const IcyInputStream &) = delete;
|
||||||
|
|
||||||
void Enable(size_t _data_size) noexcept {
|
gcc_pure
|
||||||
parser.Start(_data_size);
|
bool IsEnabled() const noexcept;
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEnabled() const noexcept {
|
|
||||||
return parser.IsDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual methods from InputStream */
|
/* virtual methods from InputStream */
|
||||||
void Update() noexcept override;
|
void Update() noexcept override;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "lib/curl/Slist.hxx"
|
#include "lib/curl/Slist.hxx"
|
||||||
#include "../AsyncInputStream.hxx"
|
#include "../AsyncInputStream.hxx"
|
||||||
#include "../IcyInputStream.hxx"
|
#include "../IcyInputStream.hxx"
|
||||||
|
#include "IcyMetaDataParser.hxx"
|
||||||
#include "../InputPlugin.hxx"
|
#include "../InputPlugin.hxx"
|
||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
@ -72,14 +73,14 @@ struct CurlInputStream final : public AsyncInputStream, CurlResponseHandler {
|
|||||||
CurlRequest *request = nullptr;
|
CurlRequest *request = nullptr;
|
||||||
|
|
||||||
/** parser for icy-metadata */
|
/** parser for icy-metadata */
|
||||||
IcyInputStream *icy;
|
std::shared_ptr<IcyMetaDataParser> icy;
|
||||||
|
|
||||||
CurlInputStream(EventLoop &event_loop, const char *_url,
|
CurlInputStream(EventLoop &event_loop, const char *_url,
|
||||||
Mutex &_mutex, Cond &_cond)
|
Mutex &_mutex, Cond &_cond)
|
||||||
:AsyncInputStream(event_loop, _url, _mutex, _cond,
|
:AsyncInputStream(event_loop, _url, _mutex, _cond,
|
||||||
CURL_MAX_BUFFERED,
|
CURL_MAX_BUFFERED,
|
||||||
CURL_RESUME_AT),
|
CURL_RESUME_AT),
|
||||||
icy(new IcyInputStream(this)) {
|
icy(new IcyMetaDataParser()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~CurlInputStream();
|
~CurlInputStream();
|
||||||
@ -199,7 +200,7 @@ CurlInputStream::OnHeaders(unsigned status,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!icy->IsEnabled() &&
|
if (!icy->IsDefined() &&
|
||||||
headers.find("accept-ranges") != headers.end())
|
headers.find("accept-ranges") != headers.end())
|
||||||
/* a stream with icy-metadata is not seekable */
|
/* a stream with icy-metadata is not seekable */
|
||||||
seekable = true;
|
seekable = true;
|
||||||
@ -226,7 +227,7 @@ CurlInputStream::OnHeaders(unsigned status,
|
|||||||
SetTag(tag_builder.CommitNew());
|
SetTag(tag_builder.CommitNew());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!icy->IsEnabled()) {
|
if (!icy->IsDefined()) {
|
||||||
i = headers.find("icy-metaint");
|
i = headers.find("icy-metaint");
|
||||||
|
|
||||||
if (i != headers.end()) {
|
if (i != headers.end()) {
|
||||||
@ -237,7 +238,7 @@ CurlInputStream::OnHeaders(unsigned status,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (icy_metaint > 0) {
|
if (icy_metaint > 0) {
|
||||||
icy->Enable(icy_metaint);
|
icy->Start(icy_metaint);
|
||||||
|
|
||||||
/* a stream with icy-metadata is not
|
/* a stream with icy-metadata is not
|
||||||
seekable */
|
seekable */
|
||||||
@ -450,7 +451,8 @@ CurlInputStream::Open(const char *url, Mutex &mutex, Cond &cond)
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return c->icy;
|
auto icy = c->icy;
|
||||||
|
return new IcyInputStream(c, std::move(icy));
|
||||||
}
|
}
|
||||||
|
|
||||||
static InputStream *
|
static InputStream *
|
||||||
|
Loading…
Reference in New Issue
Block a user