summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2016-11-17 22:21:36 +0100
committerMax Kellermann <max@musicpd.org>2016-11-21 22:43:09 +0100
commit114fcee2ae897bd5dd740cb04a3f12b7ae60cb3f (patch)
treeac1b1a8c32dabd6f62339df66289eb28363bee8e
parentb488204093d8fcabcb4a523da17f53276946888b (diff)
decoder/Client: add virtual method Read()
-rw-r--r--src/decoder/Bridge.cxx31
-rw-r--r--src/decoder/Bridge.hxx1
-rw-r--r--src/decoder/Client.hxx11
-rw-r--r--src/decoder/DecoderAPI.cxx41
-rw-r--r--test/FakeDecoderAPI.cxx40
-rw-r--r--test/FakeDecoderAPI.hxx1
6 files changed, 53 insertions, 72 deletions
diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx
index 314c067bf..25f169d41 100644
--- a/src/decoder/Bridge.cxx
+++ b/src/decoder/Bridge.cxx
@@ -401,6 +401,37 @@ DecoderBridge::OpenUri(const char *uri)
}
}
+size_t
+DecoderBridge::Read(InputStream &is, void *buffer, size_t length)
+try {
+ assert(buffer != nullptr);
+ assert(dc.state == DecoderState::START ||
+ dc.state == DecoderState::DECODE);
+
+ if (length == 0)
+ return 0;
+
+ ScopeLock lock(is.mutex);
+
+ while (true) {
+ if (CheckCancelRead())
+ return 0;
+
+ if (is.IsAvailable())
+ break;
+
+ is.cond.wait(is.mutex);
+ }
+
+ size_t nbytes = is.Read(buffer, length);
+ assert(nbytes > 0 || is.IsEOF());
+
+ return nbytes;
+} catch (const std::runtime_error &e) {
+ error = std::current_exception();
+ return 0;
+}
+
void
DecoderBridge::SubmitTimestamp(double t)
{
diff --git a/src/decoder/Bridge.hxx b/src/decoder/Bridge.hxx
index 49d810633..7203ce28a 100644
--- a/src/decoder/Bridge.hxx
+++ b/src/decoder/Bridge.hxx
@@ -140,6 +140,7 @@ public:
uint64_t GetSeekFrame() override;
void SeekError() override;
InputStreamPtr OpenUri(const char *uri) override;
+ size_t Read(InputStream &is, void *buffer, size_t length) override;
void SubmitTimestamp(double t) override;
DecoderCommand SubmitData(InputStream *is,
const void *data, size_t length,
diff --git a/src/decoder/Client.hxx b/src/decoder/Client.hxx
index d77f2ed8e..b0e1af0e0 100644
--- a/src/decoder/Client.hxx
+++ b/src/decoder/Client.hxx
@@ -99,6 +99,17 @@ public:
virtual InputStreamPtr OpenUri(const char *uri) = 0;
/**
+ * Blocking read from the input stream.
+ *
+ * @param is the input stream to read from
+ * @param buffer the destination buffer
+ * @param length the maximum number of bytes to read
+ * @return the number of bytes read, or 0 if one of the following
+ * occurs: end of file; error; command (like SEEK or STOP).
+ */
+ virtual size_t Read(InputStream &is, void *buffer, size_t length) = 0;
+
+ /**
* Sets the time stamp for the next data chunk [seconds]. The MPD
* core automatically counts it up, and a decoder plugin only needs to
* use this function if it thinks that adding to the time stamp based
diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx
index 6258b2a0a..1091690ce 100644
--- a/src/decoder/DecoderAPI.cxx
+++ b/src/decoder/DecoderAPI.cxx
@@ -19,8 +19,6 @@
#include "config.h"
#include "DecoderAPI.hxx"
-#include "DecoderControl.hxx"
-#include "Bridge.hxx"
#include "input/InputStream.hxx"
#include "Log.hxx"
@@ -30,44 +28,19 @@ size_t
decoder_read(DecoderClient *client,
InputStream &is,
void *buffer, size_t length)
-try {
+{
assert(buffer != nullptr);
/* XXX don't allow client==nullptr */
- if (client == nullptr)
- return is.LockRead(buffer, length);
-
- auto &bridge = *(DecoderBridge *)client;
-
- assert(bridge.dc.state == DecoderState::START ||
- bridge.dc.state == DecoderState::DECODE);
+ if (client != nullptr)
+ return client->Read(is, buffer, length);
- if (length == 0)
+ try {
+ return is.LockRead(buffer, length);
+ } catch (const std::runtime_error &e) {
+ LogError(e);
return 0;
-
- ScopeLock lock(is.mutex);
-
- while (true) {
- if (bridge.CheckCancelRead())
- return 0;
-
- if (is.IsAvailable())
- break;
-
- is.cond.wait(is.mutex);
}
-
- size_t nbytes = is.Read(buffer, length);
- assert(nbytes > 0 || is.IsEOF());
-
- return nbytes;
-} catch (const std::runtime_error &e) {
- auto *bridge = (DecoderBridge *)client;
- if (bridge != nullptr)
- bridge->error = std::current_exception();
- else
- LogError(e);
- return 0;
}
bool
diff --git a/test/FakeDecoderAPI.cxx b/test/FakeDecoderAPI.cxx
index cd8d52cf2..9204835fe 100644
--- a/test/FakeDecoderAPI.cxx
+++ b/test/FakeDecoderAPI.cxx
@@ -80,51 +80,15 @@ FakeDecoder::OpenUri(const char *uri)
}
size_t
-decoder_read(gcc_unused DecoderClient *client,
- InputStream &is,
- void *buffer, size_t length)
+FakeDecoder::Read(InputStream &is, void *buffer, size_t length)
{
try {
return is.LockRead(buffer, length);
- } catch (const std::runtime_error &) {
+ } catch (const std::runtime_error &e) {
return 0;
}
}
-bool
-decoder_read_full(DecoderClient *client, InputStream &is,
- void *_buffer, size_t size)
-{
- uint8_t *buffer = (uint8_t *)_buffer;
-
- while (size > 0) {
- size_t nbytes = decoder_read(client, is, buffer, size);
- if (nbytes == 0)
- return false;
-
- buffer += nbytes;
- size -= nbytes;
- }
-
- return true;
-}
-
-bool
-decoder_skip(DecoderClient *client, InputStream &is, size_t size)
-{
- while (size > 0) {
- char buffer[1024];
- size_t nbytes = decoder_read(client, is, buffer,
- std::min(sizeof(buffer), size));
- if (nbytes == 0)
- return false;
-
- size -= nbytes;
- }
-
- return true;
-}
-
void
FakeDecoder::SubmitTimestamp(gcc_unused double t)
{
diff --git a/test/FakeDecoderAPI.hxx b/test/FakeDecoderAPI.hxx
index 5b9256a74..2850e9f9a 100644
--- a/test/FakeDecoderAPI.hxx
+++ b/test/FakeDecoderAPI.hxx
@@ -40,6 +40,7 @@ struct FakeDecoder final : DecoderClient {
uint64_t GetSeekFrame() override;
void SeekError() override;
InputStreamPtr OpenUri(const char *uri) override;
+ size_t Read(InputStream &is, void *buffer, size_t length) override;
void SubmitTimestamp(double t) override;
DecoderCommand SubmitData(InputStream *is,
const void *data, size_t length,