aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/plugins/SndfileDecoderPlugin.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/decoder/plugins/SndfileDecoderPlugin.cxx55
1 files changed, 27 insertions, 28 deletions
diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx
index cf3aa61d5..1901ea7e4 100644
--- a/src/decoder/plugins/SndfileDecoderPlugin.cxx
+++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx
@@ -32,10 +32,24 @@
static constexpr Domain sndfile_domain("sndfile");
+struct SndfileInputStream {
+ Decoder *const decoder;
+ InputStream &is;
+
+ size_t Read(void *buffer, size_t size) {
+ /* libsndfile chokes on partial reads; therefore
+ always force full reads */
+ return decoder_read_full(decoder, is, buffer, size)
+ ? size
+ : 0;
+ }
+};
+
static sf_count_t
sndfile_vio_get_filelen(void *user_data)
{
- const InputStream &is = *(const InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
+ const InputStream &is = sis.is;
return is.GetSize();
}
@@ -43,7 +57,8 @@ sndfile_vio_get_filelen(void *user_data)
static sf_count_t
sndfile_vio_seek(sf_count_t _offset, int whence, void *user_data)
{
- InputStream &is = *(InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
+ InputStream &is = sis.is;
InputStream::offset_type offset = _offset;
switch (whence) {
@@ -65,8 +80,11 @@ sndfile_vio_seek(sf_count_t _offset, int whence, void *user_data)
return -1;
}
- if (!is.LockSeek(offset, IgnoreError()))
+ Error error;
+ if (!is.LockSeek(offset, error)) {
+ LogError(error, "Seek failed");
return -1;
+ }
return is.GetOffset();
}
@@ -74,30 +92,9 @@ sndfile_vio_seek(sf_count_t _offset, int whence, void *user_data)
static sf_count_t
sndfile_vio_read(void *ptr, sf_count_t count, void *user_data)
{
- InputStream &is = *(InputStream *)user_data;
-
- sf_count_t total_bytes = 0;
- Error error;
-
- /* this loop is necessary because libsndfile chokes on partial
- reads */
-
- do {
- size_t nbytes = is.LockRead((char *)ptr + total_bytes,
- count - total_bytes, error);
- if (nbytes == 0) {
- if (error.IsDefined()) {
- LogError(error);
- return -1;
- }
-
- break;
- }
-
- total_bytes += nbytes;
- } while (total_bytes < count);
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
- return total_bytes;
+ return sis.Read(ptr, count);
}
static sf_count_t
@@ -112,7 +109,8 @@ sndfile_vio_write(gcc_unused const void *ptr,
static sf_count_t
sndfile_vio_tell(void *user_data)
{
- const InputStream &is = *(const InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
+ const InputStream &is = sis.is;
return is.GetOffset();
}
@@ -158,7 +156,8 @@ sndfile_stream_decode(Decoder &decoder, InputStream &is)
info.format = 0;
- sf = sf_open_virtual(&vio, SFM_READ, &info, &is);
+ SndfileInputStream sis{&decoder, is};
+ sf = sf_open_virtual(&vio, SFM_READ, &info, &sis);
if (sf == nullptr) {
LogWarning(sndfile_domain, "sf_open_virtual() failed");
return;