From a5d0300787137ec3509956f3ed3fdf0e8656eff6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 11 May 2014 15:32:47 +0200 Subject: input/curl: move code to IcyInputStream --- src/input/plugins/CurlInputPlugin.cxx | 102 ++++++---------------------------- 1 file changed, 16 insertions(+), 86 deletions(-) (limited to 'src/input/plugins/CurlInputPlugin.cxx') diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index 1b00258ea..738937a26 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -19,13 +19,13 @@ #include "config.h" #include "CurlInputPlugin.hxx" +#include "../IcyInputStream.hxx" #include "../InputStream.hxx" #include "../InputPlugin.hxx" #include "config/ConfigGlobal.hxx" #include "config/ConfigData.hxx" #include "tag/Tag.hxx" #include "tag/TagBuilder.hxx" -#include "IcyMetaDataParser.hxx" #include "event/SocketMonitor.hxx" #include "event/TimeoutMonitor.hxx" #include "event/Call.hxx" @@ -93,10 +93,7 @@ struct CurlInputStream final : public InputStream { char error_buffer[CURL_ERROR_SIZE]; /** parser for icy-metadata */ - IcyMetaDataParser icy; - - /** the stream name from the icy-name response header */ - std::string meta_name; + IcyInputStream *icy; /** the tag object ready to be requested via InputStream::ReadTag() */ @@ -110,6 +107,7 @@ struct CurlInputStream final : public InputStream { request_headers(nullptr), buffer((uint8_t *)_buffer, CURL_MAX_BUFFERED), paused(false), + icy(new IcyInputStream(this)), tag(nullptr) {} ~CurlInputStream(); @@ -155,8 +153,6 @@ struct CurlInputStream final : public InputStream { return buffer.GetSize(); } - void CopyIcyTag(); - /** * A HTTP request is finished. * @@ -683,83 +679,19 @@ CurlInputStream::FillBuffer(Error &error) return !buffer.IsEmpty(); } -static size_t -read_from_buffer(IcyMetaDataParser &icy, CircularBuffer &buffer, - void *dest0, size_t length) -{ - uint8_t *dest = (uint8_t *)dest0; - size_t nbytes = 0; - - while (true) { - auto r = buffer.Read(); - if (r.IsEmpty()) - break; - - if (r.size > length) - r.size = length; - - size_t chunk = icy.Data(r.size); - if (chunk > 0) { - memcpy(dest, r.data, chunk); - buffer.Consume(chunk); - - nbytes += chunk; - dest += chunk; - length -= chunk; - - if (length == 0) - break; - } - - r = buffer.Read(); - if (r.IsEmpty()) - break; - - chunk = icy.Meta(r.data, r.size); - if (chunk > 0) { - buffer.Consume(chunk); - if (length == 0) - break; - } - } - - return nbytes; -} - -inline void -CurlInputStream::CopyIcyTag() -{ - Tag *new_tag = icy.ReadTag(); - if (new_tag == nullptr) - return; - - delete tag; - - if (!meta_name.empty() && !new_tag->HasType(TAG_NAME)) { - TagBuilder tag_builder(std::move(*new_tag)); - tag_builder.AddItem(TAG_NAME, meta_name.c_str()); - *new_tag = tag_builder.Commit(); - } - - tag = new_tag; -} - size_t CurlInputStream::Read(void *ptr, size_t read_size, Error &error) { - size_t nbytes; - - do { - /* fill the buffer */ - - if (!FillBuffer(error)) - return 0; + if (!FillBuffer(error)) + return 0; - nbytes = read_from_buffer(icy, buffer, ptr, read_size); - } while (nbytes == 0); + auto r = buffer.Read(); + if (r.IsEmpty()) + return 0; - if (icy.IsDefined()) - CopyIcyTag(); + const size_t nbytes = std::min(read_size, r.size); + memcpy(ptr, r.data, nbytes); + buffer.Consume(nbytes); offset += (InputPlugin::offset_type)nbytes; @@ -781,7 +713,7 @@ CurlInputStream::HeaderReceived(const char *name, std::string &&value) { if (StringEqualsCaseASCII(name, "accept-ranges")) { /* a stream with icy-metadata is not seekable */ - if (!icy.IsDefined()) + if (!icy->IsEnabled()) seekable = true; } else if (StringEqualsCaseASCII(name, "content-length")) { size = offset + ParseUint64(value.c_str()); @@ -790,23 +722,21 @@ CurlInputStream::HeaderReceived(const char *name, std::string &&value) } else if (StringEqualsCaseASCII(name, "icy-name") || StringEqualsCaseASCII(name, "ice-name") || StringEqualsCaseASCII(name, "x-audiocast-name")) { - meta_name = std::move(value); - delete tag; TagBuilder tag_builder; - tag_builder.AddItem(TAG_NAME, meta_name.c_str()); + tag_builder.AddItem(TAG_NAME, value.c_str()); tag = tag_builder.CommitNew(); } else if (StringEqualsCaseASCII(name, "icy-metaint")) { - if (icy.IsDefined()) + if (icy->IsEnabled()) return; size_t icy_metaint = ParseUint64(value.c_str()); FormatDebug(curl_domain, "icy-metaint=%zu", icy_metaint); if (icy_metaint > 0) { - icy.Start(icy_metaint); + icy->Enable(icy_metaint); /* a stream with icy-metadata is not seekable */ @@ -1072,7 +1002,7 @@ CurlInputStream::Open(const char *url, Mutex &mutex, Cond &cond, return nullptr; } - return c; + return c->icy; } static InputStream * -- cgit v1.2.3