diff options
Diffstat (limited to '')
-rw-r--r-- | src/decoder/plugins/SndfileDecoderPlugin.cxx | 55 |
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; |