input/InputStream: migrate from class Error to C++ exceptions

This commit is contained in:
Max Kellermann
2016-09-09 18:47:42 +02:00
parent 597e59f10d
commit 8c744efd56
64 changed files with 440 additions and 473 deletions

View File

@@ -334,15 +334,8 @@ try {
is.cond.wait(is.mutex);
}
Error error;
size_t nbytes = is.Read(buffer, length, error);
assert(nbytes == 0 || !error.IsDefined());
assert(nbytes > 0 || error.IsDefined() || is.IsEOF());
lock.Unlock();
if (gcc_unlikely(nbytes == 0 && error.IsDefined()))
LogError(error);
size_t nbytes = is.Read(buffer, length);
assert(nbytes > 0 || is.IsEOF());
return nbytes;
} catch (const std::runtime_error &e) {

View File

@@ -73,9 +73,7 @@ decoder_input_stream_open(DecoderControl &dc, const char *uri)
is->Update();
}
Error error;
if (!is->Check(error))
throw error;
is->Check();
return is;
}
@@ -112,7 +110,10 @@ decoder_stream_decode(const DecoderPlugin &plugin,
throw StopDecoder();
/* rewind the stream, so each plugin gets a fresh start */
input_stream.Rewind(IgnoreError());
try {
input_stream.Rewind();
} catch (const std::runtime_error &) {
}
{
const ScopeUnlock unlock(decoder.dc.mutex);

View File

@@ -30,6 +30,8 @@
#include <audiofile.h>
#include <af_vfs.h>
#include <stdexcept>
#include <assert.h>
#include <stdio.h>
@@ -115,11 +117,11 @@ audiofile_file_seek(AFvirtualfile *vfile, AFfileoffset _offset,
if (is_relative)
offset += is.GetOffset();
Error error;
if (is.LockSeek(offset, error)) {
try {
is.LockSeek(offset);
return is.GetOffset();
} else {
LogError(error, "Seek failed");
} catch (const std::runtime_error &e) {
LogError(e, "Seek failed");
return -1;
}
}

View File

@@ -28,15 +28,16 @@
#include "../DecoderAPI.hxx"
#include "input/InputStream.hxx"
#include "tag/TagId3.hxx"
#include "util/Error.hxx"
#include <string.h>
#include <stdlib.h>
#ifdef ENABLE_ID3TAG
#include <id3tag.h>
#endif
#include <stdexcept>
#include <string.h>
#include <stdlib.h>
bool
DsdId::Equals(const char *s) const
{
@@ -53,8 +54,13 @@ bool
dsdlib_skip_to(Decoder *decoder, InputStream &is,
offset_type offset)
{
if (is.IsSeekable())
return is.LockSeek(offset, IgnoreError());
if (is.IsSeekable()) {
try {
is.LockSeek(offset);
} catch (const std::runtime_error &) {
return false;
}
}
if (is.GetOffset() > offset)
return false;
@@ -72,8 +78,13 @@ dsdlib_skip(Decoder *decoder, InputStream &is,
if (delta == 0)
return true;
if (is.IsSeekable())
return is.LockSeek(is.GetOffset() + delta, IgnoreError());
if (is.IsSeekable()) {
try {
is.LockSeek(is.GetOffset() + delta);
} catch (const std::runtime_error &) {
return false;
}
}
if (delta > 1024 * 1024)
/* don't skip more than one megabyte; it would be too

View File

@@ -31,6 +31,8 @@
#include <neaacdec.h>
#include <stdexcept>
#include <assert.h>
#include <string.h>
@@ -192,7 +194,10 @@ faad_song_duration(DecoderBuffer &buffer, InputStream &is)
auto song_length = adts_song_duration(buffer);
is.LockSeek(tagsize, IgnoreError());
try {
is.LockSeek(tagsize);
} catch (const std::runtime_error &) {
}
buffer.Clear();

View File

@@ -460,9 +460,15 @@ ffmpeg_probe(Decoder *decoder, InputStream &is)
unsigned char buffer[BUFFER_SIZE];
size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE);
if (nbytes <= PADDING || !is.LockRewind(IgnoreError()))
if (nbytes <= PADDING)
return nullptr;
try {
is.LockRewind();
} catch (const std::runtime_error &) {
return nullptr;
}
/* some ffmpeg parsers (e.g. ac3_parser.c) read a few bytes
beyond the declared buffer limit, which makes valgrind
angry; this workaround removes some padding from the buffer

View File

@@ -24,7 +24,8 @@
#include "FfmpegIo.hxx"
#include "../DecoderAPI.hxx"
#include "input/InputStream.hxx"
#include "util/Error.hxx"
#include <stdexcept>
AvioStream::~AvioStream()
{
@@ -68,10 +69,12 @@ AvioStream::Seek(int64_t pos, int whence)
return -1;
}
if (!input.LockSeek(pos, IgnoreError()))
try {
input.LockSeek(pos);
return input.GetOffset();
} catch (const std::runtime_error &) {
return -1;
return input.GetOffset();
}
}
int

View File

@@ -330,7 +330,10 @@ oggflac_decode(Decoder &decoder, InputStream &input_stream)
/* rewind the stream, because ogg_codec_detect() has
moved it */
input_stream.LockRewind(IgnoreError());
try {
input_stream.LockRewind();
} catch (const std::runtime_error &) {
}
flac_decode_internal(decoder, input_stream, true);
}

View File

@@ -19,10 +19,11 @@
#include "config.h"
#include "FlacIOHandle.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include "Compiler.h"
#include <system_error>
#include <errno.h>
#include <stdio.h>
@@ -37,24 +38,29 @@ FlacIORead(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
/* libFLAC is very picky about short reads, and expects the IO
callback to fill the whole buffer (undocumented!) */
Error error;
while (p < end) {
size_t nbytes = is->LockRead(p, end - p, error);
if (nbytes == 0) {
if (!error.IsDefined())
try {
size_t nbytes = is->LockRead(p, end - p);
if (nbytes == 0)
/* end of file */
break;
if (error.IsDomain(errno_domain))
errno = error.GetCode();
else
/* just some random non-zero
errno value */
errno = EINVAL;
p += nbytes;
#ifndef WIN32
} catch (const std::system_error &e) {
errno = e.code().category() == std::system_category()
? e.code().value()
/* just some random non-zero errno
value */
: EINVAL;
return 0;
#endif
} catch (const std::runtime_error &) {
/* just some random non-zero errno value */
errno = EINVAL;
return 0;
}
p += nbytes;
}
/* libFLAC expects a clean errno after returning from the IO
@@ -88,13 +94,13 @@ FlacIOSeek(FLAC__IOHandle handle, FLAC__int64 _offset, int whence)
return -1;
}
Error error;
if (!is->LockSeek(offset, error)) {
LogError(error);
try {
is->LockSeek(offset);
return 0;
} catch (const std::runtime_error &e) {
LogError(e);
return -1;
}
return 0;
}
static FLAC__int64

View File

@@ -22,10 +22,11 @@
#include "FlacDomain.hxx"
#include "../DecoderAPI.hxx"
#include "input/InputStream.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include "Compiler.h"
#include <stdexcept>
FLAC__StreamDecoderReadStatus
FlacInput::Read(FLAC__byte buffer[], size_t *bytes)
{
@@ -50,13 +51,13 @@ FlacInput::Seek(FLAC__uint64 absolute_byte_offset)
if (!input_stream.IsSeekable())
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
::Error error;
if (!input_stream.LockSeek(absolute_byte_offset, error)) {
LogError(error);
try {
input_stream.LockSeek(absolute_byte_offset);
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
} catch (const std::runtime_error &e) {
LogError(e);
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
}
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
FLAC__StreamDecoderTellStatus

View File

@@ -39,6 +39,8 @@
#include <id3tag.h>
#endif
#include <stdexcept>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
@@ -217,9 +219,11 @@ MadDecoder::MadDecoder(Decoder *_decoder,
inline bool
MadDecoder::Seek(long offset)
{
Error error;
if (!input_stream.LockSeek(offset, error))
try {
input_stream.LockSeek(offset);
} catch (const std::runtime_error &) {
return false;
}
mad_stream_buffer(&stream, input_buffer, 0);
stream.error = MAD_ERROR_NONE;

View File

@@ -32,6 +32,8 @@
#include <mpc/mpcdec.h>
#include <stdexcept>
#include <math.h>
struct mpc_decoder_data {
@@ -62,7 +64,12 @@ mpc_seek_cb(mpc_reader *reader, mpc_int32_t offset)
struct mpc_decoder_data *data =
(struct mpc_decoder_data *)reader->data;
return data->is.LockSeek(offset, IgnoreError());
try {
data->is.LockSeek(offset);
return true;
} catch (const std::runtime_error &) {
return false;
}
}
static mpc_int32_t

View File

@@ -21,7 +21,8 @@
#include "OggDecoder.hxx"
#include "lib/xiph/OggFind.hxx"
#include "input/InputStream.hxx"
#include "util/Error.hxx"
#include <stdexcept>
/**
* Load the end-of-stream packet and restore the previous file
@@ -52,7 +53,10 @@ OggDecoder::LoadEndPacket(ogg_packet &packet) const
}
/* restore the previous file position */
input_stream.LockSeek(old_offset, IgnoreError());
try {
input_stream.LockSeek(old_offset);
} catch (const std::runtime_error &) {
}
return result;
}
@@ -67,8 +71,8 @@ OggDecoder::LoadEndGranulePos() const
return packet.granulepos;
}
bool
OggDecoder::SeekGranulePos(ogg_int64_t where_granulepos, Error &error)
void
OggDecoder::SeekGranulePos(ogg_int64_t where_granulepos)
{
assert(IsSeekable());
@@ -78,10 +82,7 @@ OggDecoder::SeekGranulePos(ogg_int64_t where_granulepos, Error &error)
offset_type offset(where_granulepos * input_stream.GetSize()
/ end_granulepos);
if (!input_stream.LockSeek(offset, error))
return false;
input_stream.LockSeek(offset);
PostSeek();
return true;
}

View File

@@ -24,8 +24,6 @@
#include "lib/xiph/OggVisitor.hxx"
#include "decoder/Reader.hxx"
class Error;
class OggDecoder : public OggVisitor {
ogg_int64_t end_granulepos;
@@ -58,7 +56,7 @@ protected:
return end_granulepos > 0;
}
bool SeekGranulePos(ogg_int64_t where_granulepos, Error &error);
void SeekGranulePos(ogg_int64_t where_granulepos);
};
#endif

View File

@@ -261,7 +261,12 @@ MPDOpusDecoder::Seek(uint64_t where_frame)
const ogg_int64_t where_granulepos(where_frame);
return SeekGranulePos(where_granulepos, IgnoreError());
try {
SeekGranulePos(where_granulepos);
return true;
} catch (const std::runtime_error &) {
return false;
}
}
static void
@@ -273,7 +278,10 @@ mpd_opus_stream_decode(Decoder &decoder,
/* rewind the stream, because ogg_codec_detect() has
moved it */
input_stream.LockRewind(IgnoreError());
try {
input_stream.LockRewind();
} catch (const std::runtime_error &) {
}
DecoderReader reader(decoder, input_stream);

View File

@@ -29,6 +29,8 @@
#include "util/MimeType.hxx"
#include "Log.hxx"
#include <stdexcept>
#include <string.h>
static void
@@ -145,11 +147,11 @@ pcm_stream_decode(Decoder &decoder, InputStream &is)
uint64_t frame = decoder_seek_where_frame(decoder);
offset_type offset = frame * frame_size;
Error error;
if (is.LockSeek(offset, error)) {
try {
is.LockSeek(offset);
decoder_command_finished(decoder);
} else {
LogError(error);
} catch (const std::runtime_error &e) {
LogError(e);
decoder_seek_error(decoder);
}

View File

@@ -27,6 +27,8 @@
#include "util/Domain.hxx"
#include "Log.hxx"
#include <stdexcept>
#include <sndfile.h>
static constexpr Domain sndfile_domain("sndfile");
@@ -89,13 +91,13 @@ sndfile_vio_seek(sf_count_t _offset, int whence, void *user_data)
return -1;
}
Error error;
if (!is.LockSeek(offset, error)) {
LogError(error, "Seek failed");
try {
is.LockSeek(offset);
return is.GetOffset();
} catch (const std::runtime_error &e) {
LogError(e, "Seek failed");
return -1;
}
return is.GetOffset();
}
static sf_count_t

View File

@@ -126,11 +126,13 @@ VorbisDecoder::Seek(uint64_t where_frame)
const ogg_int64_t where_granulepos(where_frame);
if (!SeekGranulePos(where_granulepos, IgnoreError()))
try {
SeekGranulePos(where_granulepos);
vorbis_synthesis_restart(&dsp);
return true;
} catch (const std::runtime_error &) {
return false;
vorbis_synthesis_restart(&dsp);
return true;
}
}
void
@@ -311,7 +313,10 @@ vorbis_stream_decode(Decoder &decoder,
/* rewind the stream, because ogg_codec_detect() has
moved it */
input_stream.LockRewind(IgnoreError());
try {
input_stream.LockRewind();
} catch (const std::runtime_error &) {
}
DecoderReader reader(decoder, input_stream);
VorbisDecoder d(reader);

View File

@@ -400,7 +400,12 @@ wavpack_input_set_pos_abs(void *id, uint32_t pos)
{
WavpackInput &wpi = *wpin(id);
return wpi.is.LockSeek(pos, IgnoreError()) ? 0 : -1;
try {
wpi.is.LockSeek(pos);
return 0;
} catch (const std::runtime_error &) {
return -1;
}
}
static int
@@ -429,7 +434,12 @@ wavpack_input_set_pos_rel(void *id, int32_t delta, int mode)
return -1;
}
return is.LockSeek(offset, IgnoreError()) ? 0 : -1;
try {
wpi.is.LockSeek(offset);
return 0;
} catch (const std::runtime_error &) {
return -1;
}
}
static int