aboutsummaryrefslogtreecommitdiffstats
path: root/src/output
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/output/AlsaOutputPlugin.cxx78
-rw-r--r--src/output/AoOutputPlugin.cxx49
-rw-r--r--src/output/FifoOutputPlugin.cxx90
-rw-r--r--src/output/HttpdClient.cxx5
-rw-r--r--src/output/HttpdClient.hxx2
-rw-r--r--src/output/HttpdInternal.hxx12
-rw-r--r--src/output/HttpdOutputPlugin.cxx65
-rw-r--r--src/output/JackOutputPlugin.cxx88
-rw-r--r--src/output/NullOutputPlugin.cxx12
-rw-r--r--src/output/OSXOutputPlugin.cxx84
-rw-r--r--src/output/OpenALOutputPlugin.cxx40
-rw-r--r--src/output/OssOutputPlugin.cxx114
-rw-r--r--src/output/PipeOutputPlugin.cxx43
-rw-r--r--src/output/PulseOutputPlugin.cxx152
-rw-r--r--src/output/PulseOutputPlugin.hxx5
-rw-r--r--src/output/RecorderOutputPlugin.cxx71
-rw-r--r--src/output/RoarOutputPlugin.cxx30
-rw-r--r--src/output/ShoutOutputPlugin.cxx154
-rw-r--r--src/output/SolarisOutputPlugin.cxx34
-rw-r--r--src/output/WinmmOutputPlugin.cxx61
20 files changed, 528 insertions, 661 deletions
diff --git a/src/output/AlsaOutputPlugin.cxx b/src/output/AlsaOutputPlugin.cxx
index d707166c5..c9bf01909 100644
--- a/src/output/AlsaOutputPlugin.cxx
+++ b/src/output/AlsaOutputPlugin.cxx
@@ -23,6 +23,8 @@
#include "MixerList.hxx"
#include "pcm/PcmExport.hxx"
#include "util/Manual.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <glib.h>
#include <alsa/asoundlib.h>
@@ -115,9 +117,9 @@ struct AlsaOutput {
AlsaOutput():mode(0), writei(snd_pcm_writei) {
}
- bool Init(const config_param &param, GError **error_r) {
+ bool Init(const config_param &param, Error &error) {
return ao_base_init(&base, &alsa_output_plugin,
- param, error_r);
+ param, error);
}
void Deinit() {
@@ -125,14 +127,7 @@ struct AlsaOutput {
}
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-alsa_output_quark(void)
-{
- return g_quark_from_static_string("alsa_output");
-}
+static constexpr Domain alsa_output_domain("alsa_output");
static const char *
alsa_device(const AlsaOutput *ad)
@@ -170,11 +165,11 @@ alsa_configure(AlsaOutput *ad, const config_param &param)
}
static struct audio_output *
-alsa_init(const config_param &param, GError **error_r)
+alsa_init(const config_param &param, Error &error)
{
AlsaOutput *ad = new AlsaOutput();
- if (!ad->Init(param, error_r)) {
+ if (!ad->Init(param, error)) {
delete ad;
return NULL;
}
@@ -197,7 +192,7 @@ alsa_finish(struct audio_output *ao)
}
static bool
-alsa_output_enable(struct audio_output *ao, gcc_unused GError **error_r)
+alsa_output_enable(struct audio_output *ao, gcc_unused Error &error)
{
AlsaOutput *ad = (AlsaOutput *)ao;
@@ -394,7 +389,7 @@ alsa_output_setup_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams,
*/
static bool
alsa_setup(AlsaOutput *ad, AudioFormat &audio_format,
- bool *packed_r, bool *reverse_endian_r, GError **error)
+ bool *packed_r, bool *reverse_endian_r, Error &error)
{
unsigned int sample_rate = audio_format.sample_rate;
unsigned int channels = audio_format.channels;
@@ -438,11 +433,11 @@ configure_hw:
err = alsa_output_setup_format(ad->pcm, hwparams, audio_format,
packed_r, reverse_endian_r);
if (err < 0) {
- g_set_error(error, alsa_output_quark(), err,
- "ALSA device \"%s\" does not support format %s: %s",
- alsa_device(ad),
- sample_format_to_string(audio_format.format),
- snd_strerror(-err));
+ error.Format(alsa_output_domain, err,
+ "ALSA device \"%s\" does not support format %s: %s",
+ alsa_device(ad),
+ sample_format_to_string(audio_format.format),
+ snd_strerror(-err));
return false;
}
@@ -454,10 +449,10 @@ configure_hw:
err = snd_pcm_hw_params_set_channels_near(ad->pcm, hwparams,
&channels);
if (err < 0) {
- g_set_error(error, alsa_output_quark(), err,
- "ALSA device \"%s\" does not support %i channels: %s",
- alsa_device(ad), (int)audio_format.channels,
- snd_strerror(-err));
+ error.Format(alsa_output_domain, err,
+ "ALSA device \"%s\" does not support %i channels: %s",
+ alsa_device(ad), (int)audio_format.channels,
+ snd_strerror(-err));
return false;
}
audio_format.channels = (int8_t)channels;
@@ -465,9 +460,9 @@ configure_hw:
err = snd_pcm_hw_params_set_rate_near(ad->pcm, hwparams,
&sample_rate, NULL);
if (err < 0 || sample_rate == 0) {
- g_set_error(error, alsa_output_quark(), err,
- "ALSA device \"%s\" does not support %u Hz audio",
- alsa_device(ad), audio_format.sample_rate);
+ error.Format(alsa_output_domain, err,
+ "ALSA device \"%s\" does not support %u Hz audio",
+ alsa_device(ad), audio_format.sample_rate);
return false;
}
audio_format.sample_rate = sample_rate;
@@ -594,16 +589,16 @@ configure_hw:
return true;
error:
- g_set_error(error, alsa_output_quark(), err,
- "Error opening ALSA device \"%s\" (%s): %s",
- alsa_device(ad), cmd, snd_strerror(-err));
+ error.Format(alsa_output_domain, err,
+ "Error opening ALSA device \"%s\" (%s): %s",
+ alsa_device(ad), cmd, snd_strerror(-err));
return false;
}
static bool
alsa_setup_dsd(AlsaOutput *ad, const AudioFormat audio_format,
bool *shift8_r, bool *packed_r, bool *reverse_endian_r,
- GError **error_r)
+ Error &error)
{
assert(ad->dsd_usb);
assert(audio_format.format == SampleFormat::DSD);
@@ -616,7 +611,7 @@ alsa_setup_dsd(AlsaOutput *ad, const AudioFormat audio_format,
const AudioFormat check = usb_format;
- if (!alsa_setup(ad, usb_format, packed_r, reverse_endian_r, error_r))
+ if (!alsa_setup(ad, usb_format, packed_r, reverse_endian_r, error))
return false;
/* if the device allows only 32 bit, shift all DSD-over-USB
@@ -631,9 +626,9 @@ alsa_setup_dsd(AlsaOutput *ad, const AudioFormat audio_format,
if (usb_format != check) {
/* no bit-perfect playback, which is required
for DSD over USB */
- g_set_error(error_r, alsa_output_quark(), 0,
- "Failed to configure DSD-over-USB on ALSA device \"%s\"",
- alsa_device(ad));
+ error.Format(alsa_output_domain,
+ "Failed to configure DSD-over-USB on ALSA device \"%s\"",
+ alsa_device(ad));
g_free(ad->silence);
return false;
}
@@ -643,7 +638,7 @@ alsa_setup_dsd(AlsaOutput *ad, const AudioFormat audio_format,
static bool
alsa_setup_or_dsd(AlsaOutput *ad, AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
bool shift8 = false, packed, reverse_endian;
@@ -652,9 +647,9 @@ alsa_setup_or_dsd(AlsaOutput *ad, AudioFormat &audio_format,
const bool success = dsd_usb
? alsa_setup_dsd(ad, audio_format,
&shift8, &packed, &reverse_endian,
- error_r)
+ error)
: alsa_setup(ad, audio_format, &packed, &reverse_endian,
- error_r);
+ error);
if (!success)
return false;
@@ -665,14 +660,14 @@ alsa_setup_or_dsd(AlsaOutput *ad, AudioFormat &audio_format,
}
static bool
-alsa_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
+alsa_open(struct audio_output *ao, AudioFormat &audio_format, Error &error)
{
AlsaOutput *ad = (AlsaOutput *)ao;
int err = snd_pcm_open(&ad->pcm, alsa_device(ad),
SND_PCM_STREAM_PLAYBACK, ad->mode);
if (err < 0) {
- g_set_error(error, alsa_output_quark(), err,
+ error.Format(alsa_output_domain, err,
"Failed to open ALSA device \"%s\": %s",
alsa_device(ad), snd_strerror(err));
return false;
@@ -800,7 +795,7 @@ alsa_close(struct audio_output *ao)
static size_t
alsa_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error)
+ Error &error)
{
AlsaOutput *ad = (AlsaOutput *)ao;
@@ -824,8 +819,7 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size,
if (ret < 0 && ret != -EAGAIN && ret != -EINTR &&
alsa_recover(ad, ret) < 0) {
- g_set_error(error, alsa_output_quark(), errno,
- "%s", snd_strerror(-errno));
+ error.Set(alsa_output_domain, ret, snd_strerror(-ret));
return 0;
}
}
diff --git a/src/output/AoOutputPlugin.cxx b/src/output/AoOutputPlugin.cxx
index db7b9a360..a54611511 100644
--- a/src/output/AoOutputPlugin.cxx
+++ b/src/output/AoOutputPlugin.cxx
@@ -20,6 +20,8 @@
#include "config.h"
#include "AoOutputPlugin.hxx"
#include "OutputAPI.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <ao/ao.h>
#include <glib.h>
@@ -42,26 +44,22 @@ struct AoOutput {
ao_option *options;
ao_device *device;
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error) {
return ao_base_init(&base, &ao_output_plugin, param,
- error_r);
+ error);
}
void Deinitialize() {
ao_base_finish(&base);
}
- bool Configure(const config_param &param, GError **error_r);
+ bool Configure(const config_param &param, Error &error);
};
-static inline GQuark
-ao_output_quark(void)
-{
- return g_quark_from_static_string("ao_output");
-}
+static constexpr Domain ao_output_domain("ao_output");
static void
-ao_output_error(GError **error_r)
+ao_output_error(Error &error_r)
{
const char *error;
@@ -87,15 +85,15 @@ ao_output_error(GError **error_r)
break;
default:
- error = g_strerror(errno);
+ error_r.SetErrno();
+ return;
}
- g_set_error(error_r, ao_output_quark(), errno,
- "%s", error);
+ error_r.Set(ao_output_domain, errno, error);
}
inline bool
-AoOutput::Configure(const config_param &param, GError **error_r)
+AoOutput::Configure(const config_param &param, Error &error)
{
const char *value;
@@ -115,16 +113,15 @@ AoOutput::Configure(const config_param &param, GError **error_r)
driver = ao_driver_id(value);
if (driver < 0) {
- g_set_error(error_r, ao_output_quark(), 0,
- "\"%s\" is not a valid ao driver",
- value);
+ error.Format(ao_output_domain,
+ "\"%s\" is not a valid ao driver",
+ value);
return false;
}
ao_info *ai = ao_driver_info(driver);
if (ai == nullptr) {
- g_set_error(error_r, ao_output_quark(), 0,
- "problems getting driver info");
+ error.Set(ao_output_domain, "problems getting driver info");
return false;
}
@@ -139,9 +136,9 @@ AoOutput::Configure(const config_param &param, GError **error_r)
gchar **key_value = g_strsplit(_options[i], "=", 2);
if (key_value[0] == nullptr || key_value[1] == nullptr) {
- g_set_error(error_r, ao_output_quark(), 0,
- "problems parsing options \"%s\"",
- _options[i]);
+ error.Format(ao_output_domain,
+ "problems parsing options \"%s\"",
+ _options[i]);
return false;
}
@@ -158,16 +155,16 @@ AoOutput::Configure(const config_param &param, GError **error_r)
}
static struct audio_output *
-ao_output_init(const config_param &param, GError **error_r)
+ao_output_init(const config_param &param, Error &error)
{
AoOutput *ad = new AoOutput();
- if (!ad->Initialize(param, error_r)) {
+ if (!ad->Initialize(param, error)) {
delete ad;
return nullptr;
}
- if (!ad->Configure(param, error_r)) {
+ if (!ad->Configure(param, error)) {
ad->Deinitialize();
delete ad;
return nullptr;
@@ -201,7 +198,7 @@ ao_output_close(struct audio_output *ao)
static bool
ao_output_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error)
+ Error &error)
{
ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
AoOutput *ad = (AoOutput *)ao;
@@ -257,7 +254,7 @@ static int ao_play_deconst(ao_device *device, const void *output_samples,
static size_t
ao_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error)
+ Error &error)
{
AoOutput *ad = (AoOutput *)ao;
diff --git a/src/output/FifoOutputPlugin.cxx b/src/output/FifoOutputPlugin.cxx
index 29dd50cb1..34199bff9 100644
--- a/src/output/FifoOutputPlugin.cxx
+++ b/src/output/FifoOutputPlugin.cxx
@@ -19,11 +19,14 @@
#include "config.h"
#include "FifoOutputPlugin.hxx"
+#include "ConfigError.hxx"
#include "OutputAPI.hxx"
#include "Timer.hxx"
#include "system/fd_util.h"
#include "fs/Path.hxx"
#include "fs/FileSystem.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include "open.h"
#include <glib.h>
@@ -53,31 +56,24 @@ struct FifoOutput {
FifoOutput()
:path(Path::Null()), input(-1), output(-1), created(false) {}
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error) {
return ao_base_init(&base, &fifo_output_plugin, param,
- error_r);
+ error);
}
void Deinitialize() {
ao_base_finish(&base);
}
- bool Create(GError **error_r);
- bool Check(GError **error_r);
+ bool Create(Error &error);
+ bool Check(Error &error);
void Delete();
- bool Open(GError **error_r);
+ bool Open(Error &error);
void Close();
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-fifo_output_quark(void)
-{
- return g_quark_from_static_string("fifo_output");
-}
+static constexpr Domain fifo_output_domain("fifo_output");
inline void
FifoOutput::Delete()
@@ -112,12 +108,11 @@ FifoOutput::Close()
}
inline bool
-FifoOutput::Create(GError **error_r)
+FifoOutput::Create(Error &error)
{
if (!MakeFifo(path, 0666)) {
- g_set_error(error_r, fifo_output_quark(), errno,
- "Couldn't create FIFO \"%s\": %s",
- path_utf8.c_str(), g_strerror(errno));
+ error.FormatErrno("Couldn't create FIFO \"%s\"",
+ path_utf8.c_str());
return false;
}
@@ -126,25 +121,24 @@ FifoOutput::Create(GError **error_r)
}
inline bool
-FifoOutput::Check(GError **error_r)
+FifoOutput::Check(Error &error)
{
struct stat st;
if (!StatFile(path, st)) {
if (errno == ENOENT) {
/* Path doesn't exist */
- return Create(error_r);
+ return Create(error);
}
- g_set_error(error_r, fifo_output_quark(), errno,
- "Failed to stat FIFO \"%s\": %s",
- path_utf8.c_str(), g_strerror(errno));
+ error.FormatErrno("Failed to stat FIFO \"%s\"",
+ path_utf8.c_str());
return false;
}
if (!S_ISFIFO(st.st_mode)) {
- g_set_error(error_r, fifo_output_quark(), 0,
- "\"%s\" already exists, but is not a FIFO",
- path_utf8.c_str());
+ error.Format(fifo_output_domain,
+ "\"%s\" already exists, but is not a FIFO",
+ path_utf8.c_str());
return false;
}
@@ -152,25 +146,23 @@ FifoOutput::Check(GError **error_r)
}
inline bool
-FifoOutput::Open(GError **error_r)
+FifoOutput::Open(Error &error)
{
- if (!Check(error_r))
+ if (!Check(error))
return false;
input = OpenFile(path, O_RDONLY|O_NONBLOCK|O_BINARY, 0);
if (input < 0) {
- g_set_error(error_r, fifo_output_quark(), errno,
- "Could not open FIFO \"%s\" for reading: %s",
- path_utf8.c_str(), g_strerror(errno));
+ error.FormatErrno("Could not open FIFO \"%s\" for reading",
+ path_utf8.c_str());
Close();
return false;
}
output = OpenFile(path, O_WRONLY|O_NONBLOCK|O_BINARY, 0);
if (output < 0) {
- g_set_error(error_r, fifo_output_quark(), errno,
- "Could not open FIFO \"%s\" for writing: %s",
- path_utf8.c_str(), g_strerror(errno));
+ error.FormatErrno("Could not open FIFO \"%s\" for writing",
+ path_utf8.c_str());
Close();
return false;
}
@@ -179,37 +171,34 @@ FifoOutput::Open(GError **error_r)
}
static bool
-fifo_open(FifoOutput *fd, GError **error_r)
+fifo_open(FifoOutput *fd, Error &error)
{
- return fd->Open(error_r);
+ return fd->Open(error);
}
static struct audio_output *
-fifo_output_init(const config_param &param, GError **error_r)
+fifo_output_init(const config_param &param, Error &error)
{
- GError *error = nullptr;
-
FifoOutput *fd = new FifoOutput();
- fd->path = param.GetBlockPath("path", &error);
+ fd->path = param.GetBlockPath("path", error);
if (fd->path.IsNull()) {
delete fd;
- if (error != nullptr)
- g_propagate_error(error_r, error);
- else
- g_set_error(error_r, fifo_output_quark(), 0,
- "No \"path\" parameter specified");
+
+ if (!error.IsDefined())
+ error.Set(config_domain,
+ "No \"path\" parameter specified");
return nullptr;
}
fd->path_utf8 = fd->path.ToUTF8();
- if (!fd->Initialize(param, error_r)) {
+ if (!fd->Initialize(param, error)) {
delete fd;
return nullptr;
}
- if (!fifo_open(fd, error_r)) {
+ if (!fifo_open(fd, error)) {
fd->Deinitialize();
delete fd;
return nullptr;
@@ -230,7 +219,7 @@ fifo_output_finish(struct audio_output *ao)
static bool
fifo_output_open(struct audio_output *ao, AudioFormat &audio_format,
- gcc_unused GError **error)
+ gcc_unused Error &error)
{
FifoOutput *fd = (FifoOutput *)ao;
@@ -277,7 +266,7 @@ fifo_output_delay(struct audio_output *ao)
static size_t
fifo_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error)
+ Error &error)
{
FifoOutput *fd = (FifoOutput *)ao;
ssize_t bytes;
@@ -301,9 +290,8 @@ fifo_output_play(struct audio_output *ao, const void *chunk, size_t size,
continue;
}
- g_set_error(error, fifo_output_quark(), errno,
- "Failed to write to FIFO %s: %s",
- fd->path_utf8.c_str(), g_strerror(errno));
+ error.FormatErrno("Failed to write to FIFO %s",
+ fd->path_utf8.c_str());
return 0;
}
}
diff --git a/src/output/HttpdClient.cxx b/src/output/HttpdClient.cxx
index c097e48f1..9ed7805dc 100644
--- a/src/output/HttpdClient.cxx
+++ b/src/output/HttpdClient.cxx
@@ -431,10 +431,9 @@ HttpdClient::OnSocketInput(const void *data, size_t length)
}
void
-HttpdClient::OnSocketError(GError *error)
+HttpdClient::OnSocketError(Error &&error)
{
- g_warning("error on HTTP client: %s", error->message);
- g_error_free(error);
+ g_warning("error on HTTP client: %s", error.GetMessage());
}
void
diff --git a/src/output/HttpdClient.hxx b/src/output/HttpdClient.hxx
index 38e4ea96d..a596814ee 100644
--- a/src/output/HttpdClient.hxx
+++ b/src/output/HttpdClient.hxx
@@ -179,7 +179,7 @@ protected:
virtual bool OnSocketReady(unsigned flags) override;
virtual InputResult OnSocketInput(const void *data,
size_t length) override;
- virtual void OnSocketError(GError *error) override;
+ virtual void OnSocketError(Error &&error) override;
virtual void OnSocketClosed() override;
};
diff --git a/src/output/HttpdInternal.hxx b/src/output/HttpdInternal.hxx
index e8a37e033..39fc700a3 100644
--- a/src/output/HttpdInternal.hxx
+++ b/src/output/HttpdInternal.hxx
@@ -33,6 +33,7 @@
#include <forward_list>
struct config_param;
+class Error;
class EventLoop;
class ServerSocket;
class HttpdClient;
@@ -123,21 +124,20 @@ struct HttpdOutput final : private ServerSocket {
HttpdOutput(EventLoop &_loop);
~HttpdOutput();
- bool Configure(const config_param &param, GError **error_r);
+ bool Configure(const config_param &param, Error &error);
- bool Bind(GError **error_r);
+ bool Bind(Error &error);
void Unbind();
/**
* Caller must lock the mutex.
*/
- bool OpenEncoder(AudioFormat &audio_format,
- GError **error_r);
+ bool OpenEncoder(AudioFormat &audio_format, Error &error);
/**
* Caller must lock the mutex.
*/
- bool Open(AudioFormat &audio_format, GError **error_r);
+ bool Open(AudioFormat &audio_format, Error &error);
/**
* Caller must lock the mutex.
@@ -194,7 +194,7 @@ struct HttpdOutput final : private ServerSocket {
*/
void BroadcastFromEncoder();
- bool EncodeAndPlay(const void *chunk, size_t size, GError **error_r);
+ bool EncodeAndPlay(const void *chunk, size_t size, Error &error);
void SendTag(const Tag *tag);
diff --git a/src/output/HttpdOutputPlugin.cxx b/src/output/HttpdOutputPlugin.cxx
index 745ed26a2..db395069e 100644
--- a/src/output/HttpdOutputPlugin.cxx
+++ b/src/output/HttpdOutputPlugin.cxx
@@ -29,6 +29,8 @@
#include "IcyMetaDataServer.hxx"
#include "system/fd_util.h"
#include "Main.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <assert.h>
@@ -45,14 +47,7 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "httpd_output"
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-httpd_output_quark(void)
-{
- return g_quark_from_static_string("httpd_output");
-}
+static constexpr Domain httpd_output_domain("httpd_output");
inline
HttpdOutput::HttpdOutput(EventLoop &_loop)
@@ -73,12 +68,12 @@ HttpdOutput::~HttpdOutput()
}
inline bool
-HttpdOutput::Bind(GError **error_r)
+HttpdOutput::Bind(Error &error)
{
open = false;
const ScopeLock protect(mutex);
- return ServerSocket::Open(error_r);
+ return ServerSocket::Open(error);
}
inline void
@@ -91,7 +86,7 @@ HttpdOutput::Unbind()
}
inline bool
-HttpdOutput::Configure(const config_param &param, GError **error_r)
+HttpdOutput::Configure(const config_param &param, Error &error)
{
/* read configuration */
name = param.GetBlockValue("name", "Set name in config");
@@ -104,8 +99,8 @@ HttpdOutput::Configure(const config_param &param, GError **error_r)
param.GetBlockValue("encoder", "vorbis");
const auto encoder_plugin = encoder_plugin_get(encoder_name);
if (encoder_plugin == NULL) {
- g_set_error(error_r, httpd_output_quark(), 0,
- "No such encoder: %s", encoder_name);
+ error.Format(httpd_output_domain,
+ "No such encoder: %s", encoder_name);
return false;
}
@@ -116,14 +111,14 @@ HttpdOutput::Configure(const config_param &param, GError **error_r)
const char *bind_to_address = param.GetBlockValue("bind_to_address");
bool success = bind_to_address != NULL &&
strcmp(bind_to_address, "any") != 0
- ? AddHost(bind_to_address, port, error_r)
- : AddPort(port, error_r);
+ ? AddHost(bind_to_address, port, error)
+ : AddPort(port, error);
if (!success)
return false;
/* initialize encoder */
- encoder = encoder_init(*encoder_plugin, param, error_r);
+ encoder = encoder_init(*encoder_plugin, param, error);
if (encoder == nullptr)
return false;
@@ -136,18 +131,17 @@ HttpdOutput::Configure(const config_param &param, GError **error_r)
}
static struct audio_output *
-httpd_output_init(const struct config_param &param,
- GError **error_r)
+httpd_output_init(const config_param &param, Error &error)
{
HttpdOutput *httpd = new HttpdOutput(*main_loop);
if (!ao_base_init(&httpd->base, &httpd_output_plugin, param,
- error_r)) {
+ error)) {
delete httpd;
return nullptr;
}
- if (!httpd->Configure(param, error_r)) {
+ if (!httpd->Configure(param, error)) {
ao_base_finish(&httpd->base);
delete httpd;
return nullptr;
@@ -205,7 +199,8 @@ HttpdOutput::OnAccept(int fd, const sockaddr &address,
#ifdef HAVE_LIBWRAP
if (address.sa_family != AF_UNIX) {
- char *hostaddr = sockaddr_to_string(&address, address_length, NULL);
+ char *hostaddr = sockaddr_to_string(&address, address_length,
+ IgnoreError());
const char *progname = g_get_prgname();
struct request_info req;
@@ -249,7 +244,7 @@ HttpdOutput::ReadPage()
/* we have fed a lot of input into the encoder, but it
didn't give anything back yet - flush now to avoid
buffer underruns */
- encoder_flush(encoder, NULL);
+ encoder_flush(encoder, IgnoreError());
unflushed_input = 0;
}
@@ -273,11 +268,11 @@ HttpdOutput::ReadPage()
}
static bool
-httpd_output_enable(struct audio_output *ao, GError **error_r)
+httpd_output_enable(struct audio_output *ao, Error &error)
{
HttpdOutput *httpd = Cast(ao);
- return httpd->Bind(error_r);
+ return httpd->Bind(error);
}
static void
@@ -289,7 +284,7 @@ httpd_output_disable(struct audio_output *ao)
}
inline bool
-HttpdOutput::OpenEncoder(AudioFormat &audio_format, GError **error)
+HttpdOutput::OpenEncoder(AudioFormat &audio_format, Error &error)
{
if (!encoder_open(encoder, audio_format, error))
return false;
@@ -305,14 +300,14 @@ HttpdOutput::OpenEncoder(AudioFormat &audio_format, GError **error)
}
inline bool
-HttpdOutput::Open(AudioFormat &audio_format, GError **error_r)
+HttpdOutput::Open(AudioFormat &audio_format, Error &error)
{
assert(!open);
assert(clients.empty());
/* open the encoder */
- if (!OpenEncoder(audio_format, error_r))
+ if (!OpenEncoder(audio_format, error))
return false;
/* initialize other attributes */
@@ -327,7 +322,7 @@ HttpdOutput::Open(AudioFormat &audio_format, GError **error_r)
static bool
httpd_output_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error)
+ Error &error)
{
HttpdOutput *httpd = Cast(ao);
@@ -439,9 +434,9 @@ HttpdOutput::BroadcastFromEncoder()
}
inline bool
-HttpdOutput::EncodeAndPlay(const void *chunk, size_t size, GError **error_r)
+HttpdOutput::EncodeAndPlay(const void *chunk, size_t size, Error &error)
{
- if (!encoder_write(encoder, chunk, size, error_r))
+ if (!encoder_write(encoder, chunk, size, error))
return false;
unflushed_input += size;
@@ -452,12 +447,12 @@ HttpdOutput::EncodeAndPlay(const void *chunk, size_t size, GError **error_r)
static size_t
httpd_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error_r)
+ Error &error)
{
HttpdOutput *httpd = Cast(ao);
if (httpd->LockHasClients()) {
- if (!httpd->EncodeAndPlay(chunk, size, error_r))
+ if (!httpd->EncodeAndPlay(chunk, size, error))
return 0;
}
@@ -476,7 +471,7 @@ httpd_output_pause(struct audio_output *ao)
if (httpd->LockHasClients()) {
static const char silence[1020] = { 0 };
return httpd_output_play(ao, silence, sizeof(silence),
- NULL) > 0;
+ IgnoreError()) > 0;
} else {
return true;
}
@@ -492,13 +487,13 @@ HttpdOutput::SendTag(const Tag *tag)
/* flush the current stream, and end it */
- encoder_pre_tag(encoder, NULL);
+ encoder_pre_tag(encoder, IgnoreError());
BroadcastFromEncoder();
/* send the tag to the encoder - which starts a new
stream now */
- encoder_tag(encoder, tag, NULL);
+ encoder_tag(encoder, tag, IgnoreError());
/* the first page generated by the encoder will now be
used as the new "header" page, which is sent to all
diff --git a/src/output/JackOutputPlugin.cxx b/src/output/JackOutputPlugin.cxx
index bca57cfc1..63e46ef5a 100644
--- a/src/output/JackOutputPlugin.cxx
+++ b/src/output/JackOutputPlugin.cxx
@@ -20,6 +20,9 @@
#include "config.h"
#include "JackOutputPlugin.hxx"
#include "OutputAPI.hxx"
+#include "ConfigError.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <assert.h>
@@ -82,7 +85,7 @@ struct JackOutput {
*/
bool pause;
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error_r) {
return ao_base_init(&base, &jack_output_plugin, param,
error_r);
}
@@ -92,14 +95,7 @@ struct JackOutput {
}
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-jack_output_quark(void)
-{
- return g_quark_from_static_string("jack_output");
-}
+static constexpr Domain jack_output_domain("jack_output");
/**
* Determine the number of frames guaranteed to be available on all
@@ -250,7 +246,7 @@ mpd_jack_disconnect(JackOutput *jd)
* (e.g. register callbacks).
*/
static bool
-mpd_jack_connect(JackOutput *jd, GError **error_r)
+mpd_jack_connect(JackOutput *jd, Error &error)
{
jack_status_t status;
@@ -261,9 +257,9 @@ mpd_jack_connect(JackOutput *jd, GError **error_r)
jd->client = jack_client_open(jd->name, jd->options, &status,
jd->server_name);
if (jd->client == nullptr) {
- g_set_error(error_r, jack_output_quark(), 0,
- "Failed to connect to JACK server, status=%d",
- status);
+ error.Format(jack_output_domain, status,
+ "Failed to connect to JACK server, status=%d",
+ status);
return false;
}
@@ -276,9 +272,9 @@ mpd_jack_connect(JackOutput *jd, GError **error_r)
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (jd->ports[i] == nullptr) {
- g_set_error(error_r, jack_output_quark(), 0,
- "Cannot register output port \"%s\"",
- jd->source_ports[i]);
+ error.Format(jack_output_domain,
+ "Cannot register output port \"%s\"",
+ jd->source_ports[i]);
mpd_jack_disconnect(jd);
return false;
}
@@ -294,16 +290,16 @@ mpd_jack_test_default_device(void)
}
static unsigned
-parse_port_list(int line, const char *source, char **dest, GError **error_r)
+parse_port_list(int line, const char *source, char **dest, Error &error)
{
char **list = g_strsplit(source, ",", 0);
unsigned n = 0;
for (n = 0; list[n] != nullptr; ++n) {
if (n >= MAX_PORTS) {
- g_set_error(error_r, jack_output_quark(), 0,
- "too many port names in line %d",
- line);
+ error.Format(config_domain,
+ "too many port names in line %d",
+ line);
return 0;
}
@@ -313,9 +309,9 @@ parse_port_list(int line, const char *source, char **dest, GError **error_r)
g_free(list);
if (n == 0) {
- g_set_error(error_r, jack_output_quark(), 0,
- "at least one port name expected in line %d",
- line);
+ error.Format(config_domain,
+ "at least one port name expected in line %d",
+ line);
return 0;
}
@@ -323,11 +319,11 @@ parse_port_list(int line, const char *source, char **dest, GError **error_r)
}
static struct audio_output *
-mpd_jack_init(const config_param &param, GError **error_r)
+mpd_jack_init(const config_param &param, Error &error)
{
JackOutput *jd = new JackOutput();
- if (!jd->Initialize(param, error_r)) {
+ if (!jd->Initialize(param, error)) {
delete jd;
return nullptr;
}
@@ -355,7 +351,7 @@ mpd_jack_init(const config_param &param, GError **error_r)
value = param.GetBlockValue("source_ports", "left,right");
jd->num_source_ports = parse_port_list(param.line, value,
- jd->source_ports, error_r);
+ jd->source_ports, error);
if (jd->num_source_ports == 0)
return nullptr;
@@ -373,7 +369,7 @@ mpd_jack_init(const config_param &param, GError **error_r)
if (value != nullptr) {
jd->num_destination_ports =
parse_port_list(param.line, value,
- jd->destination_ports, error_r);
+ jd->destination_ports, error);
if (jd->num_destination_ports == 0)
return nullptr;
} else {
@@ -414,14 +410,14 @@ mpd_jack_finish(struct audio_output *ao)
}
static bool
-mpd_jack_enable(struct audio_output *ao, GError **error_r)
+mpd_jack_enable(struct audio_output *ao, Error &error)
{
JackOutput *jd = (JackOutput *)ao;
for (unsigned i = 0; i < jd->num_source_ports; ++i)
jd->ringbuffer[i] = nullptr;
- return mpd_jack_connect(jd, error_r);
+ return mpd_jack_connect(jd, error);
}
static void
@@ -460,7 +456,7 @@ mpd_jack_stop(JackOutput *jd)
}
static bool
-mpd_jack_start(JackOutput *jd, GError **error_r)
+mpd_jack_start(JackOutput *jd, Error &error)
{
const char *destination_ports[MAX_PORTS], **jports;
const char *duplicate_port = nullptr;
@@ -484,8 +480,7 @@ mpd_jack_start(JackOutput *jd, GError **error_r)
}
if ( jack_activate(jd->client) ) {
- g_set_error(error_r, jack_output_quark(), 0,
- "cannot activate client");
+ error.Set(jack_output_domain, "cannot activate client");
mpd_jack_stop(jd);
return false;
}
@@ -496,8 +491,7 @@ mpd_jack_start(JackOutput *jd, GError **error_r)
jports = jack_get_ports(jd->client, nullptr, nullptr,
JackPortIsPhysical | JackPortIsInput);
if (jports == nullptr) {
- g_set_error(error_r, jack_output_quark(), 0,
- "no ports found");
+ error.Set(jack_output_domain, "no ports found");
mpd_jack_stop(jd);
return false;
}
@@ -551,9 +545,9 @@ mpd_jack_start(JackOutput *jd, GError **error_r)
ret = jack_connect(jd->client, jack_port_name(jd->ports[i]),
destination_ports[i]);
if (ret != 0) {
- g_set_error(error_r, jack_output_quark(), 0,
- "Not a valid JACK port: %s",
- destination_ports[i]);
+ error.Format(jack_output_domain,
+ "Not a valid JACK port: %s",
+ destination_ports[i]);
if (jports != nullptr)
free(jports);
@@ -571,9 +565,9 @@ mpd_jack_start(JackOutput *jd, GError **error_r)
ret = jack_connect(jd->client, jack_port_name(jd->ports[0]),
duplicate_port);
if (ret != 0) {
- g_set_error(error_r, jack_output_quark(), 0,
- "Not a valid JACK port: %s",
- duplicate_port);
+ error.Format(jack_output_domain,
+ "Not a valid JACK port: %s",
+ duplicate_port);
if (jports != nullptr)
free(jports);
@@ -591,7 +585,7 @@ mpd_jack_start(JackOutput *jd, GError **error_r)
static bool
mpd_jack_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
JackOutput *jd = (JackOutput *)ao;
@@ -602,13 +596,13 @@ mpd_jack_open(struct audio_output *ao, AudioFormat &audio_format,
if (jd->client != nullptr && jd->shutdown)
mpd_jack_disconnect(jd);
- if (jd->client == nullptr && !mpd_jack_connect(jd, error_r))
+ if (jd->client == nullptr && !mpd_jack_connect(jd, error))
return false;
set_audioformat(jd, audio_format);
jd->audio_format = audio_format;
- if (!mpd_jack_start(jd, error_r))
+ if (!mpd_jack_start(jd, error))
return false;
return true;
@@ -701,7 +695,7 @@ mpd_jack_write_samples(JackOutput *jd, const void *src,
static size_t
mpd_jack_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error_r)
+ Error &error)
{
JackOutput *jd = (JackOutput *)ao;
const size_t frame_size = jd->audio_format.GetFrameSize();
@@ -714,9 +708,9 @@ mpd_jack_play(struct audio_output *ao, const void *chunk, size_t size,
while (true) {
if (jd->shutdown) {
- g_set_error(error_r, jack_output_quark(), 0,
- "Refusing to play, because "
- "there is no client thread");
+ error.Set(jack_output_domain,
+ "Refusing to play, because "
+ "there is no client thread");
return 0;
}
diff --git a/src/output/NullOutputPlugin.cxx b/src/output/NullOutputPlugin.cxx
index 0ce32fbda..e2eec9dbc 100644
--- a/src/output/NullOutputPlugin.cxx
+++ b/src/output/NullOutputPlugin.cxx
@@ -31,9 +31,9 @@ struct NullOutput {
Timer *timer;
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error) {
return ao_base_init(&base, &null_output_plugin, param,
- error_r);
+ error);
}
void Deinitialize() {
@@ -42,11 +42,11 @@ struct NullOutput {
};
static struct audio_output *
-null_init(const config_param &param, GError **error_r)
+null_init(const config_param &param, Error &error)
{
NullOutput *nd = new NullOutput();
- if (!nd->Initialize(param, error_r)) {
+ if (!nd->Initialize(param, error)) {
delete nd;
return nullptr;
}
@@ -67,7 +67,7 @@ null_finish(struct audio_output *ao)
static bool
null_open(struct audio_output *ao, AudioFormat &audio_format,
- gcc_unused GError **error)
+ gcc_unused Error &error)
{
NullOutput *nd = (NullOutput *)ao;
@@ -98,7 +98,7 @@ null_delay(struct audio_output *ao)
static size_t
null_play(struct audio_output *ao, gcc_unused const void *chunk, size_t size,
- gcc_unused GError **error)
+ gcc_unused Error &error)
{
NullOutput *nd = (NullOutput *)ao;
Timer *timer = nd->timer;
diff --git a/src/output/OSXOutputPlugin.cxx b/src/output/OSXOutputPlugin.cxx
index 09f5581d5..8445a8028 100644
--- a/src/output/OSXOutputPlugin.cxx
+++ b/src/output/OSXOutputPlugin.cxx
@@ -21,6 +21,8 @@
#include "OSXOutputPlugin.hxx"
#include "OutputAPI.hxx"
#include "util/fifo_buffer.h"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
@@ -47,14 +49,7 @@ struct OSXOutput {
struct fifo_buffer *buffer;
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-osx_output_quark(void)
-{
- return g_quark_from_static_string("osx_output");
-}
+static constexpr Domain osx_output_domain("osx_output");
static bool
osx_output_test_default_device(void)
@@ -85,10 +80,10 @@ osx_output_configure(OSXOutput *oo, const config_param &param)
}
static struct audio_output *
-osx_output_init(const config_param &param, GError **error_r)
+osx_output_init(const config_param &param, Error &error)
{
OSXOutput *oo = new OSXOutput();
- if (!ao_base_init(&oo->base, &osx_output_plugin, param, error_r)) {
+ if (!ao_base_init(&oo->base, &osx_output_plugin, param, error)) {
delete oo;
return NULL;
}
@@ -107,7 +102,7 @@ osx_output_finish(struct audio_output *ao)
}
static bool
-osx_output_set_device(OSXOutput *oo, GError **error)
+osx_output_set_device(OSXOutput *oo, Error &error)
{
bool ret = true;
OSStatus status;
@@ -124,9 +119,9 @@ osx_output_set_device(OSXOutput *oo, GError **error)
&size,
NULL);
if (status != noErr) {
- g_set_error(error, osx_output_quark(), status,
- "Unable to determine number of OS X audio devices: %s",
- GetMacOSStatusCommentString(status));
+ error.Format(osx_output_domain, status,
+ "Unable to determine number of OS X audio devices: %s",
+ GetMacOSStatusCommentString(status));
ret = false;
goto done;
}
@@ -138,9 +133,9 @@ osx_output_set_device(OSXOutput *oo, GError **error)
&size,
deviceids);
if (status != noErr) {
- g_set_error(error, osx_output_quark(), status,
- "Unable to determine OS X audio device IDs: %s",
- GetMacOSStatusCommentString(status));
+ error.Format(osx_output_domain, status,
+ "Unable to determine OS X audio device IDs: %s",
+ GetMacOSStatusCommentString(status));
ret = false;
goto done;
}
@@ -152,11 +147,11 @@ osx_output_set_device(OSXOutput *oo, GError **error)
kAudioDevicePropertyDeviceName,
&size, name);
if (status != noErr) {
- g_set_error(error, osx_output_quark(), status,
- "Unable to determine OS X device name "
- "(device %u): %s",
- (unsigned int) deviceids[i],
- GetMacOSStatusCommentString(status));
+ error.Format(osx_output_domain, status,
+ "Unable to determine OS X device name "
+ "(device %u): %s",
+ (unsigned int) deviceids[i],
+ GetMacOSStatusCommentString(status));
ret = false;
goto done;
}
@@ -180,9 +175,9 @@ osx_output_set_device(OSXOutput *oo, GError **error)
&(deviceids[i]),
sizeof(AudioDeviceID));
if (status != noErr) {
- g_set_error(error, osx_output_quark(), status,
- "Unable to set OS X audio output device: %s",
- GetMacOSStatusCommentString(status));
+ error.Format(osx_output_domain, status,
+ "Unable to set OS X audio output device: %s",
+ GetMacOSStatusCommentString(status));
ret = false;
goto done;
}
@@ -237,7 +232,7 @@ osx_render(void *vdata,
}
static bool
-osx_output_enable(struct audio_output *ao, GError **error_r)
+osx_output_enable(struct audio_output *ao, Error &error)
{
OSXOutput *oo = (OSXOutput *)ao;
@@ -250,20 +245,20 @@ osx_output_enable(struct audio_output *ao, GError **error_r)
Component comp = FindNextComponent(NULL, &desc);
if (comp == 0) {
- g_set_error(error_r, osx_output_quark(), 0,
- "Error finding OS X component");
+ error.Set(osx_output_domain,
+ "Error finding OS X component");
return false;
}
OSStatus status = OpenAComponent(comp, &oo->au);
if (status != noErr) {
- g_set_error(error_r, osx_output_quark(), status,
- "Unable to open OS X component: %s",
- GetMacOSStatusCommentString(status));
+ error.Format(osx_output_domain, status,
+ "Unable to open OS X component: %s",
+ GetMacOSStatusCommentString(status));
return false;
}
- if (!osx_output_set_device(oo, error_r)) {
+ if (!osx_output_set_device(oo, error)) {
CloseComponent(oo->au);
return false;
}
@@ -279,8 +274,8 @@ osx_output_enable(struct audio_output *ao, GError **error_r)
&callback, sizeof(callback));
if (result != noErr) {
CloseComponent(oo->au);
- g_set_error(error_r, osx_output_quark(), result,
- "unable to set callback for OS X audio unit");
+ error.Set(osx_output_domain, result,
+ "unable to set callback for OS X audio unit");
return false;
}
@@ -316,7 +311,8 @@ osx_output_close(struct audio_output *ao)
}
static bool
-osx_output_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
+osx_output_open(struct audio_output *ao, AudioFormat &audio_format,
+ Error &error)
{
OSXOutput *od = (OSXOutput *)ao;
@@ -359,16 +355,16 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format, GError **err
&stream_description,
sizeof(stream_description));
if (result != noErr) {
- g_set_error(error, osx_output_quark(), result,
- "Unable to set format on OS X device");
+ error.Set(osx_output_domain, result,
+ "Unable to set format on OS X device");
return false;
}
OSStatus status = AudioUnitInitialize(od->au);
if (status != noErr) {
- g_set_error(error, osx_output_quark(), status,
- "Unable to initialize OS X audio unit: %s",
- GetMacOSStatusCommentString(status));
+ error.Set(osx_output_domain, status,
+ "Unable to initialize OS X audio unit: %s",
+ GetMacOSStatusCommentString(status));
return false;
}
@@ -379,9 +375,9 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format, GError **err
status = AudioOutputUnitStart(od->au);
if (status != 0) {
AudioUnitUninitialize(od->au);
- g_set_error(error, osx_output_quark(), status,
- "unable to start audio output: %s",
- GetMacOSStatusCommentString(status));
+ error.Format(osx_output_domain, status,
+ "unable to start audio output: %s",
+ GetMacOSStatusCommentString(status));
return false;
}
@@ -390,7 +386,7 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format, GError **err
static size_t
osx_output_play(struct audio_output *ao, const void *chunk, size_t size,
- gcc_unused GError **error)
+ gcc_unused Error &error)
{
OSXOutput *od = (OSXOutput *)ao;
diff --git a/src/output/OpenALOutputPlugin.cxx b/src/output/OpenALOutputPlugin.cxx
index bf4f58aa7..f8b1f5417 100644
--- a/src/output/OpenALOutputPlugin.cxx
+++ b/src/output/OpenALOutputPlugin.cxx
@@ -20,6 +20,8 @@
#include "config.h"
#include "OpenALOutputPlugin.hxx"
#include "OutputAPI.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <glib.h>
@@ -49,7 +51,7 @@ struct OpenALOutput {
ALenum format;
ALuint frequency;
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error_r) {
return ao_base_init(&base, &openal_output_plugin, param,
error_r);
}
@@ -59,12 +61,7 @@ struct OpenALOutput {
}
};
-gcc_const
-static inline GQuark
-openal_output_quark(void)
-{
- return g_quark_from_static_string("openal_output");
-}
+static constexpr Domain openal_output_domain("openal_output");
static ALenum
openal_audio_format(AudioFormat &audio_format)
@@ -115,24 +112,23 @@ openal_is_playing(const OpenALOutput *od)
}
static bool
-openal_setup_context(OpenALOutput *od,
- GError **error)
+openal_setup_context(OpenALOutput *od, Error &error)
{
od->device = alcOpenDevice(od->device_name);
if (od->device == nullptr) {
- g_set_error(error, openal_output_quark(), 0,
- "Error opening OpenAL device \"%s\"\n",
- od->device_name);
+ error.Format(openal_output_domain,
+ "Error opening OpenAL device \"%s\"",
+ od->device_name);
return false;
}
od->context = alcCreateContext(od->device, nullptr);
if (od->context == nullptr) {
- g_set_error(error, openal_output_quark(), 0,
- "Error creating context for \"%s\"\n",
- od->device_name);
+ error.Format(openal_output_domain,
+ "Error creating context for \"%s\"",
+ od->device_name);
alcCloseDevice(od->device);
return false;
}
@@ -141,7 +137,7 @@ openal_setup_context(OpenALOutput *od,
}
static struct audio_output *
-openal_init(const config_param &param, GError **error_r)
+openal_init(const config_param &param, Error &error)
{
const char *device_name = param.GetBlockValue("device");
if (device_name == nullptr) {
@@ -149,7 +145,7 @@ openal_init(const config_param &param, GError **error_r)
}
OpenALOutput *od = new OpenALOutput();
- if (!od->Initialize(param, error_r)) {
+ if (!od->Initialize(param, error)) {
delete od;
return nullptr;
}
@@ -170,7 +166,7 @@ openal_finish(struct audio_output *ao)
static bool
openal_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error)
+ Error &error)
{
OpenALOutput *od = (OpenALOutput *)ao;
@@ -184,16 +180,14 @@ openal_open(struct audio_output *ao, AudioFormat &audio_format,
alGenBuffers(NUM_BUFFERS, od->buffers);
if (alGetError() != AL_NO_ERROR) {
- g_set_error(error, openal_output_quark(), 0,
- "Failed to generate buffers");
+ error.Set(openal_output_domain, "Failed to generate buffers");
return false;
}
alGenSources(1, &od->source);
if (alGetError() != AL_NO_ERROR) {
- g_set_error(error, openal_output_quark(), 0,
- "Failed to generate source");
+ error.Set(openal_output_domain, "Failed to generate source");
alDeleteBuffers(NUM_BUFFERS, od->buffers);
return false;
}
@@ -231,7 +225,7 @@ openal_delay(struct audio_output *ao)
static size_t
openal_play(struct audio_output *ao, const void *chunk, size_t size,
- gcc_unused GError **error)
+ gcc_unused Error &error)
{
OpenALOutput *od = (OpenALOutput *)ao;
ALuint buffer;
diff --git a/src/output/OssOutputPlugin.cxx b/src/output/OssOutputPlugin.cxx
index b31db6c43..7bf741397 100644
--- a/src/output/OssOutputPlugin.cxx
+++ b/src/output/OssOutputPlugin.cxx
@@ -22,6 +22,8 @@
#include "OutputAPI.hxx"
#include "MixerList.hxx"
#include "system/fd_util.h"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <glib.h>
@@ -80,7 +82,7 @@ struct OssOutput {
OssOutput():fd(-1), device(nullptr) {}
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error_r) {
return ao_base_init(&base, &oss_output_plugin, param,
error_r);
}
@@ -90,14 +92,7 @@ struct OssOutput {
}
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-oss_output_quark(void)
-{
- return g_quark_from_static_string("oss_output");
-}
+static constexpr Domain oss_output_domain("oss_output");
enum oss_stat {
OSS_STAT_NO_ERROR = 0,
@@ -155,7 +150,7 @@ oss_output_test_default_device(void)
}
static struct audio_output *
-oss_open_default(GError **error)
+oss_open_default(Error &error)
{
int err[G_N_ELEMENTS(default_devices)];
enum oss_stat ret[G_N_ELEMENTS(default_devices)];
@@ -196,18 +191,18 @@ oss_open_default(GError **error)
}
}
- g_set_error(error, oss_output_quark(), 0,
- "error trying to open default OSS device");
+ error.Set(oss_output_domain,
+ "error trying to open default OSS device");
return NULL;
}
static struct audio_output *
-oss_output_init(const config_param &param, GError **error_r)
+oss_output_init(const config_param &param, Error &error)
{
const char *device = param.GetBlockValue("device");
if (device != NULL) {
OssOutput *od = new OssOutput();
- if (!od->Initialize(param, error_r)) {
+ if (!od->Initialize(param, error)) {
delete od;
return NULL;
}
@@ -216,7 +211,7 @@ oss_output_init(const config_param &param, GError **error_r)
return &od->base;
}
- return oss_open_default(error_r);
+ return oss_open_default(error);
}
static void
@@ -231,7 +226,7 @@ oss_output_finish(struct audio_output *ao)
#ifdef AFMT_S24_PACKED
static bool
-oss_output_enable(struct audio_output *ao, gcc_unused GError **error_r)
+oss_output_enable(struct audio_output *ao, gcc_unused Error &error)
{
OssOutput *od = (OssOutput *)ao;
@@ -269,16 +264,16 @@ enum oss_setup_result {
/**
* Invoke an ioctl on the OSS file descriptor. On success, SUCCESS is
* returned. If the parameter is not supported, UNSUPPORTED is
- * returned. Any other failure returns ERROR and allocates a GError.
+ * returned. Any other failure returns ERROR and allocates an #Error.
*/
static enum oss_setup_result
oss_try_ioctl_r(int fd, unsigned long request, int *value_r,
- const char *msg, GError **error_r)
+ const char *msg, Error &error)
{
assert(fd >= 0);
assert(value_r != NULL);
assert(msg != NULL);
- assert(error_r == NULL || *error_r == NULL);
+ assert(!error.IsDefined());
int ret = ioctl(fd, request, value_r);
if (ret >= 0)
@@ -287,19 +282,18 @@ oss_try_ioctl_r(int fd, unsigned long request, int *value_r,
if (errno == EINVAL)
return UNSUPPORTED;
- g_set_error(error_r, oss_output_quark(), errno,
- "%s: %s", msg, g_strerror(errno));
+ error.SetErrno(msg);
return ERROR;
}
/**
* Invoke an ioctl on the OSS file descriptor. On success, SUCCESS is
* returned. If the parameter is not supported, UNSUPPORTED is
- * returned. Any other failure returns ERROR and allocates a GError.
+ * returned. Any other failure returns ERROR and allocates an #Error.
*/
static enum oss_setup_result
oss_try_ioctl(int fd, unsigned long request, int value,
- const char *msg, GError **error_r)
+ const char *msg, Error &error_r)
{
return oss_try_ioctl_r(fd, request, &value, msg, error_r);
}
@@ -309,12 +303,12 @@ oss_try_ioctl(int fd, unsigned long request, int value,
* specified number is not supported.
*/
static bool
-oss_setup_channels(int fd, AudioFormat &audio_format, GError **error_r)
+oss_setup_channels(int fd, AudioFormat &audio_format, Error &error)
{
const char *const msg = "Failed to set channel count";
int channels = audio_format.channels;
enum oss_setup_result result =
- oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS, &channels, msg, error_r);
+ oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS, &channels, msg, error);
switch (result) {
case SUCCESS:
if (!audio_valid_channel_count(channels))
@@ -337,7 +331,7 @@ oss_setup_channels(int fd, AudioFormat &audio_format, GError **error_r)
channels = i;
result = oss_try_ioctl_r(fd, SNDCTL_DSP_CHANNELS, &channels,
- msg, error_r);
+ msg, error);
switch (result) {
case SUCCESS:
if (!audio_valid_channel_count(channels))
@@ -354,7 +348,7 @@ oss_setup_channels(int fd, AudioFormat &audio_format, GError **error_r)
}
}
- g_set_error(error_r, oss_output_quark(), EINVAL, "%s", msg);
+ error.Set(oss_output_domain, msg);
return false;
}
@@ -364,13 +358,13 @@ oss_setup_channels(int fd, AudioFormat &audio_format, GError **error_r)
*/
static bool
oss_setup_sample_rate(int fd, AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
const char *const msg = "Failed to set sample rate";
int sample_rate = audio_format.sample_rate;
enum oss_setup_result result =
oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &sample_rate,
- msg, error_r);
+ msg, error);
switch (result) {
case SUCCESS:
if (!audio_valid_sample_rate(sample_rate))
@@ -393,7 +387,7 @@ oss_setup_sample_rate(int fd, AudioFormat &audio_format,
continue;
result = oss_try_ioctl_r(fd, SNDCTL_DSP_SPEED, &sample_rate,
- msg, error_r);
+ msg, error);
switch (result) {
case SUCCESS:
if (!audio_valid_sample_rate(sample_rate))
@@ -410,7 +404,7 @@ oss_setup_sample_rate(int fd, AudioFormat &audio_format,
}
}
- g_set_error(error_r, oss_output_quark(), EINVAL, "%s", msg);
+ error.Set(oss_output_domain, msg);
return false;
}
@@ -498,7 +492,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format,
#ifdef AFMT_S24_PACKED
PcmExport &pcm_export,
#endif
- GError **error_r)
+ Error &error)
{
int oss_format = sample_format_to_oss(sample_format);
if (oss_format == AFMT_QUERY)
@@ -507,7 +501,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format,
enum oss_setup_result result =
oss_try_ioctl_r(fd, SNDCTL_DSP_SAMPLESIZE,
&oss_format,
- "Failed to set sample format", error_r);
+ "Failed to set sample format", error);
#ifdef AFMT_S24_PACKED
if (result == UNSUPPORTED && sample_format == SampleFormat::S24_P32) {
@@ -516,7 +510,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format,
oss_format = AFMT_S24_PACKED;
result = oss_try_ioctl_r(fd, SNDCTL_DSP_SAMPLESIZE,
&oss_format,
- "Failed to set sample format", error_r);
+ "Failed to set sample format", error);
}
#endif
@@ -550,7 +544,7 @@ oss_setup_sample_format(int fd, AudioFormat &audio_format,
#ifdef AFMT_S24_PACKED
PcmExport &pcm_export,
#endif
- GError **error_r)
+ Error &error)
{
SampleFormat mpd_format;
enum oss_setup_result result =
@@ -559,7 +553,7 @@ oss_setup_sample_format(int fd, AudioFormat &audio_format,
#ifdef AFMT_S24_PACKED
pcm_export,
#endif
- error_r);
+ error);
switch (result) {
case SUCCESS:
audio_format.format = mpd_format;
@@ -597,7 +591,7 @@ oss_setup_sample_format(int fd, AudioFormat &audio_format,
#ifdef AFMT_S24_PACKED
pcm_export,
#endif
- error_r);
+ error);
switch (result) {
case SUCCESS:
audio_format.format = mpd_format;
@@ -611,8 +605,7 @@ oss_setup_sample_format(int fd, AudioFormat &audio_format,
}
}
- g_set_error_literal(error_r, oss_output_quark(), EINVAL,
- "Failed to set sample format");
+ error.Set(oss_output_domain, "Failed to set sample format");
return false;
}
@@ -621,30 +614,29 @@ oss_setup_sample_format(int fd, AudioFormat &audio_format,
*/
static bool
oss_setup(OssOutput *od, AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
- return oss_setup_channels(od->fd, audio_format, error_r) &&
- oss_setup_sample_rate(od->fd, audio_format, error_r) &&
+ return oss_setup_channels(od->fd, audio_format, error) &&
+ oss_setup_sample_rate(od->fd, audio_format, error) &&
oss_setup_sample_format(od->fd, audio_format, &od->oss_format,
#ifdef AFMT_S24_PACKED
od->pcm_export,
#endif
- error_r);
+ error);
}
/**
* Reopen the device with the saved audio_format, without any probing.
*/
static bool
-oss_reopen(OssOutput *od, GError **error_r)
+oss_reopen(OssOutput *od, Error &error)
{
assert(od->fd < 0);
od->fd = open_cloexec(od->device, O_WRONLY, 0);
if (od->fd < 0) {
- g_set_error(error_r, oss_output_quark(), errno,
- "Error opening OSS device \"%s\": %s",
- od->device, g_strerror(errno));
+ error.FormatErrno("Error opening OSS device \"%s\"",
+ od->device);
return false;
}
@@ -652,35 +644,32 @@ oss_reopen(OssOutput *od, GError **error_r)
const char *const msg1 = "Failed to set channel count";
result = oss_try_ioctl(od->fd, SNDCTL_DSP_CHANNELS,
- od->audio_format.channels, msg1, error_r);
+ od->audio_format.channels, msg1, error);
if (result != SUCCESS) {
oss_close(od);
if (result == UNSUPPORTED)
- g_set_error(error_r, oss_output_quark(), EINVAL,
- "%s", msg1);
+ error.Set(oss_output_domain, msg1);
return false;
}
const char *const msg2 = "Failed to set sample rate";
result = oss_try_ioctl(od->fd, SNDCTL_DSP_SPEED,
- od->audio_format.sample_rate, msg2, error_r);
+ od->audio_format.sample_rate, msg2, error);
if (result != SUCCESS) {
oss_close(od);
if (result == UNSUPPORTED)
- g_set_error(error_r, oss_output_quark(), EINVAL,
- "%s", msg2);
+ error.Set(oss_output_domain, msg2);
return false;
}
const char *const msg3 = "Failed to set sample format";
result = oss_try_ioctl(od->fd, SNDCTL_DSP_SAMPLESIZE,
od->oss_format,
- msg3, error_r);
+ msg3, error);
if (result != SUCCESS) {
oss_close(od);
if (result == UNSUPPORTED)
- g_set_error(error_r, oss_output_quark(), EINVAL,
- "%s", msg3);
+ error.Set(oss_output_domain, msg3);
return false;
}
@@ -689,15 +678,14 @@ oss_reopen(OssOutput *od, GError **error_r)
static bool
oss_output_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error)
+ Error &error)
{
OssOutput *od = (OssOutput *)ao;
od->fd = open_cloexec(od->device, O_WRONLY, 0);
if (od->fd < 0) {
- g_set_error(error, oss_output_quark(), errno,
- "Error opening OSS device \"%s\": %s",
- od->device, g_strerror(errno));
+ error.FormatErrno("Error opening OSS device \"%s\"",
+ od->device);
return false;
}
@@ -731,7 +719,7 @@ oss_output_cancel(struct audio_output *ao)
static size_t
oss_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error)
+ Error &error)
{
OssOutput *od = (OssOutput *)ao;
ssize_t ret;
@@ -754,9 +742,7 @@ oss_output_play(struct audio_output *ao, const void *chunk, size_t size,
}
if (ret < 0 && errno != EINTR) {
- g_set_error(error, oss_output_quark(), errno,
- "Write error on %s: %s",
- od->device, g_strerror(errno));
+ error.FormatErrno("Write error on %s", od->device);
return 0;
}
}
diff --git a/src/output/PipeOutputPlugin.cxx b/src/output/PipeOutputPlugin.cxx
index 9ff3bb120..ca8f398da 100644
--- a/src/output/PipeOutputPlugin.cxx
+++ b/src/output/PipeOutputPlugin.cxx
@@ -20,6 +20,9 @@
#include "config.h"
#include "PipeOutputPlugin.hxx"
#include "OutputAPI.hxx"
+#include "ConfigError.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <stdio.h>
#include <errno.h>
@@ -30,34 +33,27 @@ struct PipeOutput {
char *cmd;
FILE *fh;
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error) {
return ao_base_init(&base, &pipe_output_plugin, param,
- error_r);
+ error);
}
void Deinitialize() {
ao_base_finish(&base);
}
- bool Configure(const config_param &param, GError **error_r);
+ bool Configure(const config_param &param, Error &error);
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-pipe_output_quark(void)
-{
- return g_quark_from_static_string("pipe_output");
-}
+static constexpr Domain pipe_output_domain("pipe_output");
inline bool
-PipeOutput::Configure(const config_param &param, GError **error_r)
+PipeOutput::Configure(const config_param &param, Error &error)
{
cmd = param.DupBlockString("command");
if (cmd == nullptr) {
- g_set_error(error_r, pipe_output_quark(), 0,
- "No \"command\" parameter specified");
+ error.Set(config_domain,
+ "No \"command\" parameter specified");
return false;
}
@@ -65,16 +61,16 @@ PipeOutput::Configure(const config_param &param, GError **error_r)
}
static struct audio_output *
-pipe_output_init(const config_param &param, GError **error_r)
+pipe_output_init(const config_param &param, Error &error)
{
PipeOutput *pd = new PipeOutput();
- if (!pd->Initialize(param, error_r)) {
+ if (!pd->Initialize(param, error)) {
delete pd;
return nullptr;
}
- if (!pd->Configure(param, error_r)) {
+ if (!pd->Configure(param, error)) {
pd->Deinitialize();
delete pd;
return nullptr;
@@ -96,15 +92,14 @@ pipe_output_finish(struct audio_output *ao)
static bool
pipe_output_open(struct audio_output *ao,
gcc_unused AudioFormat &audio_format,
- gcc_unused GError **error)
+ Error &error)
{
PipeOutput *pd = (PipeOutput *)ao;
pd->fh = popen(pd->cmd, "w");
if (pd->fh == nullptr) {
- g_set_error(error, pipe_output_quark(), errno,
- "Error opening pipe \"%s\": %s",
- pd->cmd, g_strerror(errno));
+ error.FormatErrno("Error opening pipe \"%s\"",
+ pd->cmd);
return false;
}
@@ -120,15 +115,15 @@ pipe_output_close(struct audio_output *ao)
}
static size_t
-pipe_output_play(struct audio_output *ao, const void *chunk, size_t size, GError **error)
+pipe_output_play(struct audio_output *ao, const void *chunk, size_t size,
+ Error &error)
{
PipeOutput *pd = (PipeOutput *)ao;
size_t ret;
ret = fwrite(chunk, 1, size, pd->fh);
if (ret == 0)
- g_set_error(error, pipe_output_quark(), errno,
- "Write error on pipe: %s", g_strerror(errno));
+ error.SetErrno("Write error on pipe");
return ret;
}
diff --git a/src/output/PulseOutputPlugin.cxx b/src/output/PulseOutputPlugin.cxx
index 5394edfac..d64e0af16 100644
--- a/src/output/PulseOutputPlugin.cxx
+++ b/src/output/PulseOutputPlugin.cxx
@@ -22,6 +22,8 @@
#include "OutputAPI.hxx"
#include "MixerList.hxx"
#include "mixer/PulseMixerPlugin.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <glib.h>
@@ -54,13 +56,13 @@ struct PulseOutput {
size_t writable;
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-pulse_output_quark(void)
+static constexpr Domain pulse_output_domain("pulse_output");
+
+static void
+SetError(Error &error, pa_context *context, const char *msg)
{
- return g_quark_from_static_string("pulse_output");
+ const int e = pa_context_errno(context);
+ error.Format(pulse_output_domain, e, "%s: %s", msg, pa_strerror(e));
}
void
@@ -112,14 +114,14 @@ pulse_output_clear_mixer(PulseOutput *po, gcc_unused PulseMixer *pm)
}
bool
-pulse_output_set_volume(PulseOutput *po,
- const struct pa_cvolume *volume, GError **error_r)
+pulse_output_set_volume(PulseOutput *po, const pa_cvolume *volume,
+ Error &error)
{
pa_operation *o;
if (po->context == nullptr || po->stream == nullptr ||
pa_stream_get_state(po->stream) != PA_STREAM_READY) {
- g_set_error(error_r, pulse_output_quark(), 0, "disconnected");
+ error.Set(pulse_output_domain, "disconnected");
return false;
}
@@ -127,9 +129,8 @@ pulse_output_set_volume(PulseOutput *po,
pa_stream_get_index(po->stream),
volume, nullptr, nullptr);
if (o == nullptr) {
- g_set_error(error_r, pulse_output_quark(), 0,
- "failed to set PulseAudio volume: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context,
+ "failed to set PulseAudio volume");
return false;
}
@@ -235,19 +236,15 @@ pulse_output_subscribe_cb(pa_context *context,
* @return true on success, false on error
*/
static bool
-pulse_output_connect(PulseOutput *po, GError **error_r)
+pulse_output_connect(PulseOutput *po, Error &error)
{
assert(po != nullptr);
assert(po->context != nullptr);
- int error;
-
- error = pa_context_connect(po->context, po->server,
- (pa_context_flags_t)0, nullptr);
- if (error < 0) {
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_context_connect() has failed: %s",
- pa_strerror(pa_context_errno(po->context)));
+ if (pa_context_connect(po->context, po->server,
+ (pa_context_flags_t)0, nullptr) < 0) {
+ SetError(error, po->context,
+ "pa_context_connect() has failed");
return false;
}
@@ -300,7 +297,7 @@ pulse_output_delete_context(PulseOutput *po)
* @return true on success, false on error
*/
static bool
-pulse_output_setup_context(PulseOutput *po, GError **error_r)
+pulse_output_setup_context(PulseOutput *po, Error &error)
{
assert(po != nullptr);
assert(po->mainloop != nullptr);
@@ -308,8 +305,7 @@ pulse_output_setup_context(PulseOutput *po, GError **error_r)
po->context = pa_context_new(pa_threaded_mainloop_get_api(po->mainloop),
MPD_PULSE_NAME);
if (po->context == nullptr) {
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_context_new() has failed");
+ error.Set(pulse_output_domain, "pa_context_new() has failed");
return false;
}
@@ -318,7 +314,7 @@ pulse_output_setup_context(PulseOutput *po, GError **error_r)
pa_context_set_subscribe_callback(po->context,
pulse_output_subscribe_cb, po);
- if (!pulse_output_connect(po, error_r)) {
+ if (!pulse_output_connect(po, error)) {
pulse_output_delete_context(po);
return false;
}
@@ -327,14 +323,14 @@ pulse_output_setup_context(PulseOutput *po, GError **error_r)
}
static struct audio_output *
-pulse_output_init(const config_param &param, GError **error_r)
+pulse_output_init(const config_param &param, Error &error)
{
PulseOutput *po;
g_setenv("PULSE_PROP_media.role", "music", true);
po = new PulseOutput();
- if (!ao_base_init(&po->base, &pulse_output_plugin, param, error_r)) {
+ if (!ao_base_init(&po->base, &pulse_output_plugin, param, error)) {
delete po;
return nullptr;
}
@@ -361,7 +357,7 @@ pulse_output_finish(struct audio_output *ao)
}
static bool
-pulse_output_enable(struct audio_output *ao, GError **error_r)
+pulse_output_enable(struct audio_output *ao, Error &error)
{
PulseOutput *po = (PulseOutput *)ao;
@@ -374,8 +370,8 @@ pulse_output_enable(struct audio_output *ao, GError **error_r)
if (po->mainloop == nullptr) {
g_free(po);
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_threaded_mainloop_new() has failed");
+ error.Set(pulse_output_domain,
+ "pa_threaded_mainloop_new() has failed");
return false;
}
@@ -386,14 +382,14 @@ pulse_output_enable(struct audio_output *ao, GError **error_r)
pa_threaded_mainloop_free(po->mainloop);
po->mainloop = nullptr;
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_threaded_mainloop_start() has failed");
+ error.Set(pulse_output_domain,
+ "pa_threaded_mainloop_start() has failed");
return false;
}
/* create the libpulse context and connect it */
- if (!pulse_output_setup_context(po, error_r)) {
+ if (!pulse_output_setup_context(po, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
pa_threaded_mainloop_stop(po->mainloop);
pa_threaded_mainloop_free(po->mainloop);
@@ -429,13 +425,13 @@ pulse_output_disable(struct audio_output *ao)
* @return true on success, false on error
*/
static bool
-pulse_output_wait_connection(PulseOutput *po, GError **error_r)
+pulse_output_wait_connection(PulseOutput *po, Error &error)
{
assert(po->mainloop != nullptr);
pa_context_state_t state;
- if (po->context == nullptr && !pulse_output_setup_context(po, error_r))
+ if (po->context == nullptr && !pulse_output_setup_context(po, error))
return false;
while (true) {
@@ -449,9 +445,7 @@ pulse_output_wait_connection(PulseOutput *po, GError **error_r)
case PA_CONTEXT_TERMINATED:
case PA_CONTEXT_FAILED:
/* failure */
- g_set_error(error_r, pulse_output_quark(), 0,
- "failed to connect: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context, "failed to connect");
pulse_output_delete_context(po);
return false;
@@ -530,16 +524,14 @@ pulse_output_stream_write_cb(gcc_unused pa_stream *stream, size_t nbytes,
*/
static bool
pulse_output_setup_stream(PulseOutput *po, const pa_sample_spec *ss,
- GError **error_r)
+ Error &error)
{
assert(po != nullptr);
assert(po->context != nullptr);
po->stream = pa_stream_new(po->context, po->name, ss, nullptr);
if (po->stream == nullptr) {
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_stream_new() has failed: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context, "pa_stream_new() has failed");
return false;
}
@@ -556,11 +548,10 @@ pulse_output_setup_stream(PulseOutput *po, const pa_sample_spec *ss,
static bool
pulse_output_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
PulseOutput *po = (PulseOutput *)ao;
pa_sample_spec ss;
- int error;
assert(po->mainloop != nullptr);
@@ -585,7 +576,7 @@ pulse_output_open(struct audio_output *ao, AudioFormat &audio_format,
}
}
- if (!pulse_output_wait_connection(po, error_r)) {
+ if (!pulse_output_wait_connection(po, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
return false;
}
@@ -600,22 +591,20 @@ pulse_output_open(struct audio_output *ao, AudioFormat &audio_format,
/* create a stream .. */
- if (!pulse_output_setup_stream(po, &ss, error_r)) {
+ if (!pulse_output_setup_stream(po, &ss, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
return false;
}
/* .. and connect it (asynchronously) */
- error = pa_stream_connect_playback(po->stream, po->sink,
- nullptr, pa_stream_flags_t(0),
- nullptr, nullptr);
- if (error < 0) {
+ if (pa_stream_connect_playback(po->stream, po->sink,
+ nullptr, pa_stream_flags_t(0),
+ nullptr, nullptr) < 0) {
pulse_output_delete_stream(po);
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_stream_connect_playback() has failed: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context,
+ "pa_stream_connect_playback() has failed");
pa_threaded_mainloop_unlock(po->mainloop);
return false;
}
@@ -661,7 +650,7 @@ pulse_output_close(struct audio_output *ao)
* @return true on success, false on error
*/
static bool
-pulse_output_wait_stream(PulseOutput *po, GError **error_r)
+pulse_output_wait_stream(PulseOutput *po, Error &error)
{
while (true) {
switch (pa_stream_get_state(po->stream)) {
@@ -671,10 +660,8 @@ pulse_output_wait_stream(PulseOutput *po, GError **error_r)
case PA_STREAM_FAILED:
case PA_STREAM_TERMINATED:
case PA_STREAM_UNCONNECTED:
- g_set_error(error_r, pulse_output_quark(),
- pa_context_errno(po->context),
- "failed to connect the stream: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context,
+ "failed to connect the stream");
return false;
case PA_STREAM_CREATING:
@@ -689,7 +676,7 @@ pulse_output_wait_stream(PulseOutput *po, GError **error_r)
*/
static bool
pulse_output_stream_pause(PulseOutput *po, bool pause,
- GError **error_r)
+ Error &error)
{
pa_operation *o;
@@ -700,16 +687,12 @@ pulse_output_stream_pause(PulseOutput *po, bool pause,
o = pa_stream_cork(po->stream, pause,
pulse_output_stream_success_cb, po);
if (o == nullptr) {
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_stream_cork() has failed: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context, "pa_stream_cork() has failed");
return false;
}
if (!pulse_wait_for_operation(po->mainloop, o)) {
- g_set_error(error_r, pulse_output_quark(), 0,
- "pa_stream_cork() has failed: %s",
- pa_strerror(pa_context_errno(po->context)));
+ SetError(error, po->context, "pa_stream_cork() has failed");
return false;
}
@@ -736,10 +719,9 @@ pulse_output_delay(struct audio_output *ao)
static size_t
pulse_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error_r)
+ Error &error)
{
PulseOutput *po = (PulseOutput *)ao;
- int error;
assert(po->mainloop != nullptr);
assert(po->stream != nullptr);
@@ -748,7 +730,7 @@ pulse_output_play(struct audio_output *ao, const void *chunk, size_t size,
/* check if the stream is (already) connected */
- if (!pulse_output_wait_stream(po, error_r)) {
+ if (!pulse_output_wait_stream(po, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
return 0;
}
@@ -758,7 +740,7 @@ pulse_output_play(struct audio_output *ao, const void *chunk, size_t size,
/* unpause if previously paused */
if (pa_stream_is_corked(po->stream) &&
- !pulse_output_stream_pause(po, false, error_r)) {
+ !pulse_output_stream_pause(po, false, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
return 0;
}
@@ -768,8 +750,7 @@ pulse_output_play(struct audio_output *ao, const void *chunk, size_t size,
while (po->writable == 0) {
if (pa_stream_is_suspended(po->stream)) {
pa_threaded_mainloop_unlock(po->mainloop);
- g_set_error(error_r, pulse_output_quark(), 0,
- "suspended");
+ error.Set(pulse_output_domain, "suspended");
return 0;
}
@@ -777,8 +758,7 @@ pulse_output_play(struct audio_output *ao, const void *chunk, size_t size,
if (pa_stream_get_state(po->stream) != PA_STREAM_READY) {
pa_threaded_mainloop_unlock(po->mainloop);
- g_set_error(error_r, pulse_output_quark(), 0,
- "disconnected");
+ error.Set(pulse_output_domain, "disconnected");
return 0;
}
}
@@ -791,12 +771,11 @@ pulse_output_play(struct audio_output *ao, const void *chunk, size_t size,
po->writable -= size;
- error = pa_stream_write(po->stream, chunk, size, nullptr,
- 0, PA_SEEK_RELATIVE);
+ int result = pa_stream_write(po->stream, chunk, size, nullptr,
+ 0, PA_SEEK_RELATIVE);
pa_threaded_mainloop_unlock(po->mainloop);
- if (error < 0) {
- g_set_error(error_r, pulse_output_quark(), error,
- "%s", pa_strerror(error));
+ if (result < 0) {
+ SetError(error, po->context, "pa_stream_write() failed");
return 0;
}
@@ -839,7 +818,6 @@ static bool
pulse_output_pause(struct audio_output *ao)
{
PulseOutput *po = (PulseOutput *)ao;
- GError *error = nullptr;
assert(po->mainloop != nullptr);
assert(po->stream != nullptr);
@@ -848,10 +826,10 @@ pulse_output_pause(struct audio_output *ao)
/* check if the stream is (already/still) connected */
- if (!pulse_output_wait_stream(po, &error)) {
+ Error error;
+ if (!pulse_output_wait_stream(po, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
- g_warning("%s", error->message);
- g_error_free(error);
+ g_warning("%s", error.GetMessage());
return false;
}
@@ -860,10 +838,9 @@ pulse_output_pause(struct audio_output *ao)
/* cork the stream */
if (!pa_stream_is_corked(po->stream) &&
- !pulse_output_stream_pause(po, true, &error)) {
+ !pulse_output_stream_pause(po, true, error)) {
pa_threaded_mainloop_unlock(po->mainloop);
- g_warning("%s", error->message);
- g_error_free(error);
+ g_warning("%s", error.GetMessage());
return false;
}
@@ -878,11 +855,12 @@ pulse_output_test_default_device(void)
bool success;
const config_param empty;
- PulseOutput *po = (PulseOutput *)pulse_output_init(empty, nullptr);
+ PulseOutput *po = (PulseOutput *)
+ pulse_output_init(empty, IgnoreError());
if (po == nullptr)
return false;
- success = pulse_output_wait_connection(po, nullptr);
+ success = pulse_output_wait_connection(po, IgnoreError());
pulse_output_finish(&po->base);
return success;
diff --git a/src/output/PulseOutputPlugin.hxx b/src/output/PulseOutputPlugin.hxx
index 278969f8d..0ed8404bc 100644
--- a/src/output/PulseOutputPlugin.hxx
+++ b/src/output/PulseOutputPlugin.hxx
@@ -20,11 +20,10 @@
#ifndef MPD_PULSE_OUTPUT_PLUGIN_HXX
#define MPD_PULSE_OUTPUT_PLUGIN_HXX
-#include "gerror.h"
-
struct PulseOutput;
struct PulseMixer;
struct pa_cvolume;
+class Error;
extern const struct audio_output_plugin pulse_output_plugin;
@@ -42,6 +41,6 @@ pulse_output_clear_mixer(PulseOutput *po, PulseMixer *pm);
bool
pulse_output_set_volume(PulseOutput *po,
- const struct pa_cvolume *volume, GError **error_r);
+ const struct pa_cvolume *volume, Error &error);
#endif
diff --git a/src/output/RecorderOutputPlugin.cxx b/src/output/RecorderOutputPlugin.cxx
index 9374e4c20..31c378c56 100644
--- a/src/output/RecorderOutputPlugin.cxx
+++ b/src/output/RecorderOutputPlugin.cxx
@@ -22,6 +22,9 @@
#include "OutputAPI.hxx"
#include "EncoderPlugin.hxx"
#include "EncoderList.hxx"
+#include "ConfigError.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include "system/fd_util.h"
#include "open.h"
@@ -57,7 +60,7 @@ struct RecorderOutput {
*/
char buffer[32768];
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error_r) {
return ao_base_init(&base, &recorder_output_plugin, param,
error_r);
}
@@ -66,27 +69,20 @@ struct RecorderOutput {
ao_base_finish(&base);
}
- bool Configure(const config_param &param, GError **error_r);
+ bool Configure(const config_param &param, Error &error);
- bool WriteToFile(const void *data, size_t length, GError **error_r);
+ bool WriteToFile(const void *data, size_t length, Error &error);
/**
* Writes pending data from the encoder to the output file.
*/
- bool EncoderToFile(GError **error_r);
+ bool EncoderToFile(Error &error);
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-recorder_output_quark(void)
-{
- return g_quark_from_static_string("recorder_output");
-}
+static constexpr Domain recorder_output_domain("recorder_output");
inline bool
-RecorderOutput::Configure(const config_param &param, GError **error_r)
+RecorderOutput::Configure(const config_param &param, Error &error)
{
/* read configuration */
@@ -94,21 +90,20 @@ RecorderOutput::Configure(const config_param &param, GError **error_r)
param.GetBlockValue("encoder", "vorbis");
const auto encoder_plugin = encoder_plugin_get(encoder_name);
if (encoder_plugin == nullptr) {
- g_set_error(error_r, recorder_output_quark(), 0,
- "No such encoder: %s", encoder_name);
+ error.Format(config_domain,
+ "No such encoder: %s", encoder_name);
return false;
}
path = param.GetBlockValue("path");
if (path == nullptr) {
- g_set_error(error_r, recorder_output_quark(), 0,
- "'path' not configured");
+ error.Set(config_domain, "'path' not configured");
return false;
}
/* initialize encoder */
- encoder = encoder_init(*encoder_plugin, param, error_r);
+ encoder = encoder_init(*encoder_plugin, param, error);
if (encoder == nullptr)
return false;
@@ -116,16 +111,16 @@ RecorderOutput::Configure(const config_param &param, GError **error_r)
}
static audio_output *
-recorder_output_init(const config_param &param, GError **error_r)
+recorder_output_init(const config_param &param, Error &error)
{
RecorderOutput *recorder = new RecorderOutput();
- if (!recorder->Initialize(param, error_r)) {
+ if (!recorder->Initialize(param, error)) {
delete recorder;
return nullptr;
}
- if (!recorder->Configure(param, error_r)) {
+ if (!recorder->Configure(param, error)) {
recorder->Deinitialize();
delete recorder;
return nullptr;
@@ -145,7 +140,7 @@ recorder_output_finish(struct audio_output *ao)
}
inline bool
-RecorderOutput::WriteToFile(const void *_data, size_t length, GError **error_r)
+RecorderOutput::WriteToFile(const void *_data, size_t length, Error &error)
{
assert(length > 0);
@@ -159,20 +154,18 @@ RecorderOutput::WriteToFile(const void *_data, size_t length, GError **error_r)
return true;
} else if (nbytes == 0) {
/* shouldn't happen for files */
- g_set_error(error_r, recorder_output_quark(), 0,
- "write() returned 0");
+ error.Set(recorder_output_domain,
+ "write() returned 0");
return false;
} else if (errno != EINTR) {
- g_set_error(error_r, recorder_output_quark(), 0,
- "Failed to write to '%s': %s",
- path, g_strerror(errno));
+ error.FormatErrno("Failed to write to '%s'", path);
return false;
}
}
}
inline bool
-RecorderOutput::EncoderToFile(GError **error_r)
+RecorderOutput::EncoderToFile(Error &error)
{
assert(fd >= 0);
@@ -185,7 +178,7 @@ RecorderOutput::EncoderToFile(GError **error_r)
/* write everything into the file */
- if (!WriteToFile(buffer, size, error_r))
+ if (!WriteToFile(buffer, size, error))
return false;
}
}
@@ -193,7 +186,7 @@ RecorderOutput::EncoderToFile(GError **error_r)
static bool
recorder_output_open(struct audio_output *ao,
AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
RecorderOutput *recorder = (RecorderOutput *)ao;
@@ -203,21 +196,19 @@ recorder_output_open(struct audio_output *ao,
O_CREAT|O_WRONLY|O_TRUNC|O_BINARY,
0666);
if (recorder->fd < 0) {
- g_set_error(error_r, recorder_output_quark(), 0,
- "Failed to create '%s': %s",
- recorder->path, g_strerror(errno));
+ error.FormatErrno("Failed to create '%s'", recorder->path);
return false;
}
/* open the encoder */
- if (!encoder_open(recorder->encoder, audio_format, error_r)) {
+ if (!encoder_open(recorder->encoder, audio_format, error)) {
close(recorder->fd);
unlink(recorder->path);
return false;
}
- if (!recorder->EncoderToFile(error_r)) {
+ if (!recorder->EncoderToFile(error)) {
encoder_close(recorder->encoder);
close(recorder->fd);
unlink(recorder->path);
@@ -234,8 +225,8 @@ recorder_output_close(struct audio_output *ao)
/* flush the encoder and write the rest to the file */
- if (encoder_end(recorder->encoder, nullptr))
- recorder->EncoderToFile(nullptr);
+ if (encoder_end(recorder->encoder, IgnoreError()))
+ recorder->EncoderToFile(IgnoreError());
/* now really close everything */
@@ -246,12 +237,12 @@ recorder_output_close(struct audio_output *ao)
static size_t
recorder_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error_r)
+ Error &error)
{
RecorderOutput *recorder = (RecorderOutput *)ao;
- return encoder_write(recorder->encoder, chunk, size, error_r) &&
- recorder->EncoderToFile(error_r)
+ return encoder_write(recorder->encoder, chunk, size, error) &&
+ recorder->EncoderToFile(error)
? size : 0;
}
diff --git a/src/output/RoarOutputPlugin.cxx b/src/output/RoarOutputPlugin.cxx
index 36f7c395b..f6d261372 100644
--- a/src/output/RoarOutputPlugin.cxx
+++ b/src/output/RoarOutputPlugin.cxx
@@ -23,6 +23,8 @@
#include "OutputAPI.hxx"
#include "MixerList.hxx"
#include "thread/Mutex.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <glib.h>
@@ -58,11 +60,7 @@ struct RoarOutput {
}
};
-static inline GQuark
-roar_output_quark(void)
-{
- return g_quark_from_static_string("roar_output");
-}
+static constexpr Domain roar_output_domain("roar_output");
static int
roar_output_get_volume_locked(RoarOutput *roar)
@@ -120,11 +118,11 @@ roar_configure(RoarOutput *self, const config_param &param)
}
static struct audio_output *
-roar_init(const config_param &param, GError **error_r)
+roar_init(const config_param &param, Error &error)
{
RoarOutput *self = new RoarOutput();
- if (!ao_base_init(&self->base, &roar_output_plugin, param, error_r)) {
+ if (!ao_base_init(&self->base, &roar_output_plugin, param, error)) {
delete self;
return nullptr;
}
@@ -178,15 +176,15 @@ roar_use_audio_format(struct roar_audio_info *info,
}
static bool
-roar_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
+roar_open(struct audio_output *ao, AudioFormat &audio_format, Error &error)
{
RoarOutput *self = (RoarOutput *)ao;
const ScopeLock protect(self->mutex);
if (roar_simple_connect(&(self->con), self->host, self->name) < 0)
{
- g_set_error(error, roar_output_quark(), 0,
- "Failed to connect to Roar server");
+ error.Set(roar_output_domain,
+ "Failed to connect to Roar server");
return false;
}
@@ -194,8 +192,7 @@ roar_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
if (self->vss == nullptr || self->err != ROAR_ERROR_NONE)
{
- g_set_error(error, roar_output_quark(), 0,
- "Failed to connect to server");
+ error.Set(roar_output_domain, "Failed to connect to server");
return false;
}
@@ -204,7 +201,7 @@ roar_open(struct audio_output *ao, AudioFormat &audio_format, GError **error)
if (roar_vs_stream(self->vss, &(self->info), ROAR_DIR_PLAY,
&(self->err)) < 0)
{
- g_set_error(error, roar_output_quark(), 0, "Failed to start stream");
+ error.Set(roar_output_domain, "Failed to start stream");
return false;
}
roar_vs_role(self->vss, self->role, &(self->err));
@@ -264,21 +261,22 @@ roar_cancel(struct audio_output *ao)
}
static size_t
-roar_play(struct audio_output *ao, const void *chunk, size_t size, GError **error)
+roar_play(struct audio_output *ao, const void *chunk, size_t size,
+ Error &error)
{
RoarOutput *self = (RoarOutput *)ao;
ssize_t rc;
if (self->vss == nullptr)
{
- g_set_error(error, roar_output_quark(), 0, "Connection is invalid");
+ error.Set(roar_output_domain, "Connection is invalid");
return 0;
}
rc = roar_vs_write(self->vss, chunk, size, &(self->err));
if ( rc <= 0 )
{
- g_set_error(error, roar_output_quark(), 0, "Failed to play data");
+ error.Set(roar_output_domain, "Failed to play data");
return 0;
}
diff --git a/src/output/ShoutOutputPlugin.cxx b/src/output/ShoutOutputPlugin.cxx
index 40f468031..82b61f7c8 100644
--- a/src/output/ShoutOutputPlugin.cxx
+++ b/src/output/ShoutOutputPlugin.cxx
@@ -22,6 +22,9 @@
#include "OutputAPI.hxx"
#include "EncoderPlugin.hxx"
#include "EncoderList.hxx"
+#include "ConfigError.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include "mpd_error.h"
#include <shout/shout.h>
@@ -66,28 +69,21 @@ struct ShoutOutput final {
shout_free(shout_conn);
}
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error) {
return ao_base_init(&base, &shout_output_plugin, param,
- error_r);
+ error);
}
void Deinitialize() {
ao_base_finish(&base);
}
- bool Configure(const config_param &param, GError **error_r);
+ bool Configure(const config_param &param, Error &error);
};
static int shout_init_count;
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-shout_output_quark(void)
-{
- return g_quark_from_static_string("shout_output");
-}
+static constexpr Domain shout_output_domain("shout_output");
static const EncoderPlugin *
shout_encoder_plugin_get(const char *name)
@@ -113,13 +109,13 @@ require_block_string(const config_param &param, const char *name)
}
inline bool
-ShoutOutput::Configure(const config_param &param, GError **error_r)
+ShoutOutput::Configure(const config_param &param, Error &error)
{
const AudioFormat audio_format = base.config_audio_format;
if (!audio_format.IsFullyDefined()) {
- g_set_error(error_r, shout_output_quark(), 0,
- "Need full audio format specification");
+ error.Set(config_domain,
+ "Need full audio format specification");
return nullptr;
}
@@ -127,8 +123,7 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
const char *mount = require_block_string(param, "mount");
unsigned port = param.GetBlockValue("port", 0u);
if (port == 0) {
- g_set_error(error_r, shout_output_quark(), 0,
- "shout port must be configured");
+ error.Set(config_domain, "shout port must be configured");
return false;
}
@@ -145,24 +140,24 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
quality = strtod(value, &test);
if (*test != '\0' || quality < -1.0 || quality > 10.0) {
- g_set_error(error_r, shout_output_quark(), 0,
- "shout quality \"%s\" is not a number in the "
- "range -1 to 10, line %i",
- value, param.line);
+ error.Format(config_domain,
+ "shout quality \"%s\" is not a number in the "
+ "range -1 to 10, line %i",
+ value, param.line);
return false;
}
if (param.GetBlockValue("bitrate") != nullptr) {
- g_set_error(error_r, shout_output_quark(), 0,
- "quality and bitrate are "
- "both defined");
+ error.Set(config_domain,
+ "quality and bitrate are "
+ "both defined");
return false;
}
} else {
value = param.GetBlockValue("bitrate");
if (value == nullptr) {
- g_set_error(error_r, shout_output_quark(), 0,
- "neither bitrate nor quality defined");
+ error.Set(config_domain,
+ "neither bitrate nor quality defined");
return false;
}
@@ -170,8 +165,8 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
bitrate = strtol(value, &test, 10);
if (*test != '\0' || bitrate <= 0) {
- g_set_error(error_r, shout_output_quark(), 0,
- "bitrate must be a positive integer");
+ error.Set(config_domain,
+ "bitrate must be a positive integer");
return false;
}
}
@@ -179,13 +174,13 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
const char *encoding = param.GetBlockValue("encoding", "ogg");
const auto encoder_plugin = shout_encoder_plugin_get(encoding);
if (encoder_plugin == nullptr) {
- g_set_error(error_r, shout_output_quark(), 0,
- "couldn't find shout encoder plugin \"%s\"",
- encoding);
+ error.Format(config_domain,
+ "couldn't find shout encoder plugin \"%s\"",
+ encoding);
return false;
}
- encoder = encoder_init(*encoder_plugin, param, error_r);
+ encoder = encoder_init(*encoder_plugin, param, error);
if (encoder == nullptr)
return false;
@@ -200,9 +195,9 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
if (value != nullptr) {
if (0 == strcmp(value, "shoutcast") &&
0 != strcmp(encoding, "mp3")) {
- g_set_error(error_r, shout_output_quark(), 0,
- "you cannot stream \"%s\" to shoutcast, use mp3",
- encoding);
+ error.Format(config_domain,
+ "you cannot stream \"%s\" to shoutcast, use mp3",
+ encoding);
return false;
} else if (0 == strcmp(value, "shoutcast"))
protocol = SHOUT_PROTOCOL_ICY;
@@ -211,10 +206,10 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
else if (0 == strcmp(value, "icecast2"))
protocol = SHOUT_PROTOCOL_HTTP;
else {
- g_set_error(error_r, shout_output_quark(), 0,
- "shout protocol \"%s\" is not \"shoutcast\" or "
- "\"icecast1\"or \"icecast2\"",
- value);
+ error.Format(config_domain,
+ "shout protocol \"%s\" is not \"shoutcast\" or "
+ "\"icecast1\"or \"icecast2\"",
+ value);
return false;
}
} else {
@@ -232,8 +227,7 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
!= SHOUTERR_SUCCESS ||
shout_set_protocol(shout_conn, protocol) != SHOUTERR_SUCCESS ||
shout_set_agent(shout_conn, "MPD") != SHOUTERR_SUCCESS) {
- g_set_error(error_r, shout_output_quark(), 0,
- "%s", shout_get_error(shout_conn));
+ error.Set(shout_output_domain, shout_get_error(shout_conn));
return false;
}
@@ -242,22 +236,19 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
value = param.GetBlockValue("genre");
if (value != nullptr && shout_set_genre(shout_conn, value)) {
- g_set_error(error_r, shout_output_quark(), 0,
- "%s", shout_get_error(shout_conn));
+ error.Set(shout_output_domain, shout_get_error(shout_conn));
return false;
}
value = param.GetBlockValue("description");
if (value != nullptr && shout_set_description(shout_conn, value)) {
- g_set_error(error_r, shout_output_quark(), 0,
- "%s", shout_get_error(shout_conn));
+ error.Set(shout_output_domain, shout_get_error(shout_conn));
return false;
}
value = param.GetBlockValue("url");
if (value != nullptr && shout_set_url(shout_conn, value)) {
- g_set_error(error_r, shout_output_quark(), 0,
- "%s", shout_get_error(shout_conn));
+ error.Set(shout_output_domain, shout_get_error(shout_conn));
return false;
}
@@ -287,15 +278,15 @@ ShoutOutput::Configure(const config_param &param, GError **error_r)
}
static struct audio_output *
-my_shout_init_driver(const config_param &param, GError **error_r)
+my_shout_init_driver(const config_param &param, Error &error)
{
ShoutOutput *sd = new ShoutOutput();
- if (!sd->Initialize(param, error_r)) {
+ if (!sd->Initialize(param, error)) {
delete sd;
return nullptr;
}
- if (!sd->Configure(param, error_r)) {
+ if (!sd->Configure(param, error)) {
sd->Deinitialize();
delete sd;
return nullptr;
@@ -310,7 +301,7 @@ my_shout_init_driver(const config_param &param, GError **error_r)
}
static bool
-handle_shout_error(ShoutOutput *sd, int err, GError **error)
+handle_shout_error(ShoutOutput *sd, int err, Error &error)
{
switch (err) {
case SHOUTERR_SUCCESS:
@@ -318,19 +309,19 @@ handle_shout_error(ShoutOutput *sd, int err, GError **error)
case SHOUTERR_UNCONNECTED:
case SHOUTERR_SOCKET:
- g_set_error(error, shout_output_quark(), err,
- "Lost shout connection to %s:%i: %s",
- shout_get_host(sd->shout_conn),
- shout_get_port(sd->shout_conn),
- shout_get_error(sd->shout_conn));
+ error.Format(shout_output_domain, err,
+ "Lost shout connection to %s:%i: %s",
+ shout_get_host(sd->shout_conn),
+ shout_get_port(sd->shout_conn),
+ shout_get_error(sd->shout_conn));
return false;
default:
- g_set_error(error, shout_output_quark(), err,
- "connection to %s:%i error: %s",
- shout_get_host(sd->shout_conn),
- shout_get_port(sd->shout_conn),
- shout_get_error(sd->shout_conn));
+ error.Format(shout_output_domain, err,
+ "connection to %s:%i error: %s",
+ shout_get_host(sd->shout_conn),
+ shout_get_port(sd->shout_conn),
+ shout_get_error(sd->shout_conn));
return false;
}
@@ -338,7 +329,7 @@ handle_shout_error(ShoutOutput *sd, int err, GError **error)
}
static bool
-write_page(ShoutOutput *sd, GError **error)
+write_page(ShoutOutput *sd, Error &error)
{
assert(sd->encoder != nullptr);
@@ -359,8 +350,8 @@ write_page(ShoutOutput *sd, GError **error)
static void close_shout_conn(ShoutOutput * sd)
{
if (sd->encoder != nullptr) {
- if (encoder_end(sd->encoder, nullptr))
- write_page(sd, nullptr);
+ if (encoder_end(sd->encoder, IgnoreError()))
+ write_page(sd, IgnoreError());
encoder_close(sd->encoder);
}
@@ -406,7 +397,7 @@ my_shout_close_device(struct audio_output *ao)
}
static bool
-shout_connect(ShoutOutput *sd, GError **error)
+shout_connect(ShoutOutput *sd, Error &error)
{
switch (shout_open(sd->shout_conn)) {
case SHOUTERR_SUCCESS:
@@ -414,18 +405,18 @@ shout_connect(ShoutOutput *sd, GError **error)
return true;
default:
- g_set_error(error, shout_output_quark(), 0,
- "problem opening connection to shout server %s:%i: %s",
- shout_get_host(sd->shout_conn),
- shout_get_port(sd->shout_conn),
- shout_get_error(sd->shout_conn));
+ error.Format(shout_output_domain,
+ "problem opening connection to shout server %s:%i: %s",
+ shout_get_host(sd->shout_conn),
+ shout_get_port(sd->shout_conn),
+ shout_get_error(sd->shout_conn));
return false;
}
}
static bool
my_shout_open_device(struct audio_output *ao, AudioFormat &audio_format,
- GError **error)
+ Error &error)
{
ShoutOutput *sd = (ShoutOutput *)ao;
@@ -460,7 +451,7 @@ my_shout_delay(struct audio_output *ao)
static size_t
my_shout_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error)
+ Error &error)
{
ShoutOutput *sd = (ShoutOutput *)ao;
@@ -475,7 +466,7 @@ my_shout_pause(struct audio_output *ao)
{
static char silence[1020];
- return my_shout_play(ao, silence, sizeof(silence), nullptr);
+ return my_shout_play(ao, silence, sizeof(silence), IgnoreError());
}
static void
@@ -508,24 +499,17 @@ static void my_shout_set_tag(struct audio_output *ao,
const Tag *tag)
{
ShoutOutput *sd = (ShoutOutput *)ao;
- GError *error = nullptr;
if (sd->encoder->plugin.tag != nullptr) {
/* encoder plugin supports stream tags */
- if (!encoder_pre_tag(sd->encoder, &error)) {
- g_warning("%s", error->message);
- g_error_free(error);
+ Error error;
+ if (!encoder_pre_tag(sd->encoder, error) ||
+ !write_page(sd, error) ||
+ !encoder_tag(sd->encoder, tag, error)) {
+ g_warning("%s", error.GetMessage());
return;
}
-
- if (!write_page(sd, nullptr))
- return;
-
- if (!encoder_tag(sd->encoder, tag, &error)) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
} else {
/* no stream tag support: fall back to icy-metadata */
char song[1024];
@@ -538,7 +522,7 @@ static void my_shout_set_tag(struct audio_output *ao,
}
}
- write_page(sd, nullptr);
+ write_page(sd, IgnoreError());
}
const struct audio_output_plugin shout_output_plugin = {
diff --git a/src/output/SolarisOutputPlugin.cxx b/src/output/SolarisOutputPlugin.cxx
index aa2f853e6..e3428cbc2 100644
--- a/src/output/SolarisOutputPlugin.cxx
+++ b/src/output/SolarisOutputPlugin.cxx
@@ -21,8 +21,7 @@
#include "SolarisOutputPlugin.hxx"
#include "OutputAPI.hxx"
#include "system/fd_util.h"
-
-#include <glib.h>
+#include "util/Error.hxx"
#include <sys/stropts.h>
#include <sys/types.h>
@@ -61,7 +60,7 @@ struct SolarisOutput {
int fd;
- bool Initialize(const config_param &param, GError **error_r) {
+ bool Initialize(const config_param &param, Error &error_r) {
return ao_base_init(&base, &solaris_output_plugin, param,
error_r);
}
@@ -71,15 +70,6 @@ struct SolarisOutput {
}
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-solaris_output_quark(void)
-{
- return g_quark_from_static_string("solaris_output");
-}
-
static bool
solaris_output_test_default_device(void)
{
@@ -90,7 +80,7 @@ solaris_output_test_default_device(void)
}
static struct audio_output *
-solaris_output_init(const config_param &param, GError **error_r)
+solaris_output_init(const config_param &param, Error &error_r)
{
SolarisOutput *so = new SolarisOutput();
if (!so->Initialize(param, error_r)) {
@@ -114,7 +104,7 @@ solaris_output_finish(struct audio_output *ao)
static bool
solaris_output_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error)
+ Error &error)
{
SolarisOutput *so = (SolarisOutput *)ao;
struct audio_info info;
@@ -128,9 +118,8 @@ solaris_output_open(struct audio_output *ao, AudioFormat &audio_format,
so->fd = open_cloexec(so->device, O_WRONLY|O_NONBLOCK, 0);
if (so->fd < 0) {
- g_set_error(error, solaris_output_quark(), errno,
- "Failed to open %s: %s",
- so->device, g_strerror(errno));
+ error.FormatErrno("Failed to open %s",
+ so->device);
return false;
}
@@ -144,8 +133,7 @@ solaris_output_open(struct audio_output *ao, AudioFormat &audio_format,
ret = ioctl(so->fd, AUDIO_GETINFO, &info);
if (ret < 0) {
- g_set_error(error, solaris_output_quark(), errno,
- "AUDIO_GETINFO failed: %s", g_strerror(errno));
+ error.SetErrno("AUDIO_GETINFO failed");
close(so->fd);
return false;
}
@@ -157,8 +145,7 @@ solaris_output_open(struct audio_output *ao, AudioFormat &audio_format,
ret = ioctl(so->fd, AUDIO_SETINFO, &info);
if (ret < 0) {
- g_set_error(error, solaris_output_quark(), errno,
- "AUDIO_SETINFO failed: %s", g_strerror(errno));
+ error.SetErrno("AUDIO_SETINFO failed");
close(so->fd);
return false;
}
@@ -176,15 +163,14 @@ solaris_output_close(struct audio_output *ao)
static size_t
solaris_output_play(struct audio_output *ao, const void *chunk, size_t size,
- GError **error)
+ Error &error)
{
SolarisOutput *so = (SolarisOutput *)ao;
ssize_t nbytes;
nbytes = write(so->fd, chunk, size);
if (nbytes <= 0) {
- g_set_error(error, solaris_output_quark(), errno,
- "Write failed: %s", g_strerror(errno));
+ error.SetErrno("Write failed");
return 0;
}
diff --git a/src/output/WinmmOutputPlugin.cxx b/src/output/WinmmOutputPlugin.cxx
index d02b52c58..7d81576e8 100644
--- a/src/output/WinmmOutputPlugin.cxx
+++ b/src/output/WinmmOutputPlugin.cxx
@@ -22,6 +22,8 @@
#include "OutputAPI.hxx"
#include "pcm/PcmBuffer.hxx"
#include "MixerList.hxx"
+#include "util/Error.hxx"
+#include "util/Domain.hxx"
#include <stdlib.h>
#include <string.h>
@@ -51,14 +53,7 @@ struct WinmmOutput {
unsigned next_buffer;
};
-/**
- * The quark used for GError.domain.
- */
-static inline GQuark
-winmm_output_quark(void)
-{
- return g_quark_from_static_string("winmm_output");
-}
+static constexpr Domain winmm_output_domain("winmm_output");
HWAVEOUT
winmm_output_get_handle(WinmmOutput *output)
@@ -73,7 +68,7 @@ winmm_output_test_default_device(void)
}
static bool
-get_device_id(const char *device_name, UINT *device_id, GError **error_r)
+get_device_id(const char *device_name, UINT *device_id, Error &error)
{
/* if device is not specified use wave mapper */
if (device_name == nullptr) {
@@ -108,22 +103,22 @@ get_device_id(const char *device_name, UINT *device_id, GError **error_r)
}
fail:
- g_set_error(error_r, winmm_output_quark(), 0,
- "device \"%s\" is not found", device_name);
+ error.Format(winmm_output_domain,
+ "device \"%s\" is not found", device_name);
return false;
}
static struct audio_output *
-winmm_output_init(const config_param &param, GError **error_r)
+winmm_output_init(const config_param &param, Error &error)
{
WinmmOutput *wo = new WinmmOutput();
- if (!ao_base_init(&wo->base, &winmm_output_plugin, param, error_r)) {
+ if (!ao_base_init(&wo->base, &winmm_output_plugin, param, error)) {
g_free(wo);
return nullptr;
}
const char *device = param.GetBlockValue("device");
- if (!get_device_id(device, &wo->device_id, error_r)) {
+ if (!get_device_id(device, &wo->device_id, error)) {
ao_base_finish(&wo->base);
g_free(wo);
return nullptr;
@@ -143,14 +138,13 @@ winmm_output_finish(struct audio_output *ao)
static bool
winmm_output_open(struct audio_output *ao, AudioFormat &audio_format,
- GError **error_r)
+ Error &error)
{
WinmmOutput *wo = (WinmmOutput *)ao;
wo->event = CreateEvent(nullptr, false, false, nullptr);
if (wo->event == nullptr) {
- g_set_error(error_r, winmm_output_quark(), 0,
- "CreateEvent() failed");
+ error.Set(winmm_output_domain, "CreateEvent() failed");
return false;
}
@@ -186,8 +180,7 @@ winmm_output_open(struct audio_output *ao, AudioFormat &audio_format,
(DWORD_PTR)wo->event, 0, CALLBACK_EVENT);
if (result != MMSYSERR_NOERROR) {
CloseHandle(wo->event);
- g_set_error(error_r, winmm_output_quark(), result,
- "waveOutOpen() failed");
+ error.Set(winmm_output_domain, "waveOutOpen() failed");
return false;
}
@@ -219,7 +212,7 @@ winmm_output_close(struct audio_output *ao)
static bool
winmm_set_buffer(WinmmOutput *wo, WinmmBuffer *buffer,
const void *data, size_t size,
- GError **error_r)
+ Error &error)
{
void *dest = buffer->buffer.Get(size);
assert(dest != nullptr);
@@ -233,8 +226,8 @@ winmm_set_buffer(WinmmOutput *wo, WinmmBuffer *buffer,
MMRESULT result = waveOutPrepareHeader(wo->handle, &buffer->hdr,
sizeof(buffer->hdr));
if (result != MMSYSERR_NOERROR) {
- g_set_error(error_r, winmm_output_quark(), result,
- "waveOutPrepareHeader() failed");
+ error.Set(winmm_output_domain, result,
+ "waveOutPrepareHeader() failed");
return false;
}
@@ -246,7 +239,7 @@ winmm_set_buffer(WinmmOutput *wo, WinmmBuffer *buffer,
*/
static bool
winmm_drain_buffer(WinmmOutput *wo, WinmmBuffer *buffer,
- GError **error_r)
+ Error &error)
{
if ((buffer->hdr.dwFlags & WHDR_DONE) == WHDR_DONE)
/* already finished */
@@ -259,8 +252,8 @@ winmm_drain_buffer(WinmmOutput *wo, WinmmBuffer *buffer,
if (result == MMSYSERR_NOERROR)
return true;
else if (result != WAVERR_STILLPLAYING) {
- g_set_error(error_r, winmm_output_quark(), result,
- "waveOutUnprepareHeader() failed");
+ error.Set(winmm_output_domain, result,
+ "waveOutUnprepareHeader() failed");
return false;
}
@@ -270,14 +263,14 @@ winmm_drain_buffer(WinmmOutput *wo, WinmmBuffer *buffer,
}
static size_t
-winmm_output_play(struct audio_output *ao, const void *chunk, size_t size, GError **error_r)
+winmm_output_play(struct audio_output *ao, const void *chunk, size_t size, Error &error)
{
WinmmOutput *wo = (WinmmOutput *)ao;
/* get the next buffer from the ring and prepare it */
WinmmBuffer *buffer = &wo->buffers[wo->next_buffer];
- if (!winmm_drain_buffer(wo, buffer, error_r) ||
- !winmm_set_buffer(wo, buffer, chunk, size, error_r))
+ if (!winmm_drain_buffer(wo, buffer, error) ||
+ !winmm_set_buffer(wo, buffer, chunk, size, error))
return 0;
/* enqueue the buffer */
@@ -286,8 +279,8 @@ winmm_output_play(struct audio_output *ao, const void *chunk, size_t size, GErro
if (result != MMSYSERR_NOERROR) {
waveOutUnprepareHeader(wo->handle, &buffer->hdr,
sizeof(buffer->hdr));
- g_set_error(error_r, winmm_output_quark(), result,
- "waveOutWrite() failed");
+ error.Set(winmm_output_domain, result,
+ "waveOutWrite() failed");
return 0;
}
@@ -299,14 +292,14 @@ winmm_output_play(struct audio_output *ao, const void *chunk, size_t size, GErro
}
static bool
-winmm_drain_all_buffers(WinmmOutput *wo, GError **error_r)
+winmm_drain_all_buffers(WinmmOutput *wo, Error &error)
{
for (unsigned i = wo->next_buffer; i < G_N_ELEMENTS(wo->buffers); ++i)
- if (!winmm_drain_buffer(wo, &wo->buffers[i], error_r))
+ if (!winmm_drain_buffer(wo, &wo->buffers[i], error))
return false;
for (unsigned i = 0; i < wo->next_buffer; ++i)
- if (!winmm_drain_buffer(wo, &wo->buffers[i], error_r))
+ if (!winmm_drain_buffer(wo, &wo->buffers[i], error))
return false;
return true;
@@ -329,7 +322,7 @@ winmm_output_drain(struct audio_output *ao)
{
WinmmOutput *wo = (WinmmOutput *)ao;
- if (!winmm_drain_all_buffers(wo, nullptr))
+ if (!winmm_drain_all_buffers(wo, IgnoreError()))
winmm_stop(wo);
}