output/ao: migrate from class Error to C++ exceptions

This commit is contained in:
Max Kellermann 2016-11-02 12:36:13 +01:00
parent 6ead9750f4
commit 65e6755b8b

View File

@ -20,9 +20,10 @@
#include "config.h"
#include "AoOutputPlugin.hxx"
#include "../OutputAPI.hxx"
#include "system/Error.hxx"
#include "util/DivideString.hxx"
#include "util/SplitString.hxx"
#include "util/Error.hxx"
#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@ -38,27 +39,21 @@ static unsigned ao_output_ref;
struct AoOutput {
AudioOutput base;
size_t write_size;
const size_t write_size;
int driver;
ao_option *options;
ao_option *options = nullptr;
ao_device *device;
AoOutput()
:base(ao_output_plugin) {}
bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(block, error);
}
bool Configure(const ConfigBlock &block, Error &error);
AoOutput(const ConfigBlock &block);
};
static constexpr Domain ao_output_domain("ao_output");
static void
ao_output_error(Error &error_r)
static std::system_error
MakeAoError()
{
const char *error;
const char *error = "Unknown libao failure";
switch (errno) {
case AO_ENODRIVER:
@ -80,47 +75,33 @@ ao_output_error(Error &error_r)
case AO_EFAIL:
error = "Generic libao failure";
break;
default:
error_r.SetErrno();
return;
}
error_r.Set(ao_output_domain, errno, error);
return MakeErrno(errno, error);
}
inline bool
AoOutput::Configure(const ConfigBlock &block, Error &error)
AoOutput::AoOutput(const ConfigBlock &block)
:base(ao_output_plugin, block),
write_size(block.GetBlockValue("write_size", 1024u))
{
const char *value;
options = nullptr;
write_size = block.GetBlockValue("write_size", 1024u);
if (ao_output_ref == 0) {
ao_initialize();
}
ao_output_ref++;
value = block.GetBlockValue("driver", "default");
const char *value = block.GetBlockValue("driver", "default");
if (0 == strcmp(value, "default"))
driver = ao_default_driver_id();
else
driver = ao_driver_id(value);
if (driver < 0) {
error.Format(ao_output_domain,
"\"%s\" is not a valid ao driver",
value);
return false;
}
if (driver < 0)
throw FormatRuntimeError("\"%s\" is not a valid ao driver",
value);
ao_info *ai = ao_driver_info(driver);
if (ai == nullptr) {
error.Set(ao_output_domain, "problems getting driver info");
return false;
}
if (ai == nullptr)
throw std::runtime_error("problems getting driver info");
FormatDebug(ao_output_domain, "using ao driver \"%s\" for \"%s\"\n",
ai->short_name, block.GetBlockValue("name", nullptr));
@ -130,36 +111,19 @@ AoOutput::Configure(const ConfigBlock &block, Error &error)
for (const auto &i : SplitString(value, ';')) {
const DivideString ss(i.c_str(), '=', true);
if (!ss.IsDefined()) {
error.Format(ao_output_domain,
"problems parsing options \"%s\"",
if (!ss.IsDefined())
throw FormatRuntimeError("problems parsing options \"%s\"",
i.c_str());
return false;
}
ao_append_option(&options, ss.GetFirst(), ss.GetSecond());
}
}
return true;
}
static AudioOutput *
ao_output_init(const ConfigBlock &block, Error &error)
ao_output_init(const ConfigBlock &block, gcc_unused Error &error)
{
AoOutput *ad = new AoOutput();
if (!ad->Initialize(block, error)) {
delete ad;
return nullptr;
}
if (!ad->Configure(block, error)) {
delete ad;
return nullptr;
}
return &ad->base;
return &(new AoOutput(block))->base;
}
static void
@ -186,7 +150,7 @@ ao_output_close(AudioOutput *ao)
static bool
ao_output_open(AudioOutput *ao, AudioFormat &audio_format,
Error &error)
gcc_unused Error &error)
{
ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
AoOutput *ad = (AoOutput *)ao;
@ -215,10 +179,8 @@ ao_output_open(AudioOutput *ao, AudioFormat &audio_format,
ad->device = ao_open_live(ad->driver, &format, ad->options);
if (ad->device == nullptr) {
ao_output_error(error);
return false;
}
if (ad->device == nullptr)
throw MakeAoError();
return true;
}
@ -242,17 +204,15 @@ static int ao_play_deconst(ao_device *device, const void *output_samples,
static size_t
ao_output_play(AudioOutput *ao, const void *chunk, size_t size,
Error &error)
gcc_unused Error &error)
{
AoOutput *ad = (AoOutput *)ao;
if (size > ad->write_size)
size = ad->write_size;
if (ao_play_deconst(ad->device, chunk, size) == 0) {
ao_output_error(error);
return 0;
}
if (ao_play_deconst(ad->device, chunk, size) == 0)
throw MakeAoError();
return size;
}