util/Error: new error passing library
Replaces GLib's GError.
This commit is contained in:
parent
c9fcc7f148
commit
29030b54c9
22
Makefile.am
22
Makefile.am
@ -91,7 +91,7 @@ src_mpd_SOURCES = \
|
||||
src/CheckAudioFormat.cxx src/CheckAudioFormat.hxx \
|
||||
src/AudioFormat.cxx src/AudioFormat.hxx \
|
||||
src/AudioParser.cxx src/AudioParser.hxx \
|
||||
src/protocol/Ack.hxx \
|
||||
src/protocol/Ack.cxx src/protocol/Ack.hxx \
|
||||
src/protocol/ArgParser.cxx src/protocol/ArgParser.hxx \
|
||||
src/protocol/Result.cxx src/protocol/Result.hxx \
|
||||
src/CommandError.cxx src/CommandError.hxx \
|
||||
@ -107,7 +107,7 @@ src_mpd_SOURCES = \
|
||||
src/CommandLine.cxx src/CommandLine.hxx \
|
||||
src/CrossFade.cxx src/CrossFade.hxx \
|
||||
src/cue/CueParser.cxx src/cue/CueParser.hxx \
|
||||
src/DecoderError.hxx \
|
||||
src/DecoderError.cxx src/DecoderError.hxx \
|
||||
src/DecoderThread.cxx src/DecoderThread.hxx \
|
||||
src/DecoderCommand.hxx \
|
||||
src/DecoderControl.cxx src/DecoderControl.hxx \
|
||||
@ -122,7 +122,7 @@ src_mpd_SOURCES = \
|
||||
src/DatabasePrint.cxx src/DatabasePrint.hxx \
|
||||
src/DatabaseQueue.cxx src/DatabaseQueue.hxx \
|
||||
src/DatabasePlaylist.cxx src/DatabasePlaylist.hxx \
|
||||
src/DatabaseError.hxx \
|
||||
src/DatabaseError.cxx src/DatabaseError.hxx \
|
||||
src/DatabaseLock.cxx src/DatabaseLock.hxx \
|
||||
src/DatabaseSave.cxx src/DatabaseSave.hxx \
|
||||
src/DatabasePlugin.hxx \
|
||||
@ -160,7 +160,6 @@ src_mpd_SOURCES = \
|
||||
src/Listen.cxx src/Listen.hxx \
|
||||
src/Log.cxx src/Log.hxx \
|
||||
src/ls.cxx src/ls.hxx \
|
||||
src/io_error.h \
|
||||
src/IOThread.cxx src/IOThread.hxx \
|
||||
src/Main.cxx src/Main.hxx \
|
||||
src/Instance.cxx src/Instance.hxx \
|
||||
@ -178,7 +177,7 @@ src_mpd_SOURCES = \
|
||||
src/PlayerThread.cxx src/PlayerThread.hxx \
|
||||
src/PlayerControl.cxx src/PlayerControl.hxx \
|
||||
src/Playlist.cxx \
|
||||
src/PlaylistError.hxx \
|
||||
src/PlaylistError.cxx src/PlaylistError.hxx \
|
||||
src/PlaylistGlobal.cxx src/PlaylistGlobal.hxx \
|
||||
src/PlaylistControl.cxx \
|
||||
src/PlaylistEdit.cxx \
|
||||
@ -261,6 +260,7 @@ endif
|
||||
# Generic utility library
|
||||
|
||||
libutil_a_SOURCES = \
|
||||
src/util/Error.cxx src/util/Error.hxx \
|
||||
src/util/ReusableArray.hxx \
|
||||
src/util/StringUtil.cxx src/util/StringUtil.hxx \
|
||||
src/util/Tokenizer.cxx src/util/Tokenizer.hxx \
|
||||
@ -284,7 +284,7 @@ libsystem_a_SOURCES = \
|
||||
src/system/FatalError.cxx src/system/FatalError.hxx \
|
||||
src/system/fd_util.c src/system/fd_util.h \
|
||||
src/system/SocketUtil.cxx src/system/SocketUtil.hxx \
|
||||
src/system/SocketError.hxx \
|
||||
src/system/SocketError.cxx src/system/SocketError.hxx \
|
||||
src/system/Resolver.cxx src/system/Resolver.hxx \
|
||||
src/system/EventPipe.cxx src/system/EventPipe.hxx \
|
||||
src/system/EventFD.cxx src/system/EventFD.hxx \
|
||||
@ -420,7 +420,7 @@ libconf_a_SOURCES = \
|
||||
src/ConfigGlobal.cxx src/ConfigGlobal.hxx \
|
||||
src/ConfigFile.cxx src/ConfigFile.hxx \
|
||||
src/ConfigTemplates.cxx src/ConfigTemplates.hxx \
|
||||
src/ConfigQuark.hxx \
|
||||
src/ConfigError.cxx src/ConfigError.hxx \
|
||||
src/ConfigOption.hxx
|
||||
|
||||
# tag plugins
|
||||
@ -793,7 +793,7 @@ OUTPUT_API_SRC = \
|
||||
src/OutputList.cxx src/OutputList.hxx \
|
||||
src/OutputAll.cxx src/OutputAll.hxx \
|
||||
src/OutputThread.cxx src/OutputThread.hxx \
|
||||
src/OutputError.hxx \
|
||||
src/OutputError.cxx src/OutputError.hxx \
|
||||
src/OutputControl.cxx src/OutputControl.hxx \
|
||||
src/OutputState.cxx src/OutputState.hxx \
|
||||
src/OutputPrint.cxx src/OutputPrint.hxx \
|
||||
@ -1071,6 +1071,7 @@ test_read_conf_SOURCES = test/read_conf.cxx
|
||||
|
||||
test_run_resolver_LDADD = \
|
||||
libsystem.a \
|
||||
libutil.a \
|
||||
$(GLIB_LIBS)
|
||||
test_run_resolver_SOURCES = test/run_resolver.cxx
|
||||
|
||||
@ -1082,6 +1083,7 @@ test_DumpDatabase_LDADD = \
|
||||
libfs.a \
|
||||
$(GLIB_LIBS)
|
||||
test_DumpDatabase_SOURCES = test/DumpDatabase.cxx \
|
||||
src/DatabaseError.cxx \
|
||||
src/DatabaseRegistry.cxx \
|
||||
src/DatabaseSelection.cxx \
|
||||
src/Directory.cxx src/DirectorySave.cxx \
|
||||
@ -1217,6 +1219,7 @@ test_read_tags_SOURCES = test/read_tags.cxx \
|
||||
if HAVE_ID3TAG
|
||||
test_dump_rva2_LDADD = \
|
||||
$(ID3TAG_LIBS) \
|
||||
libutil.a \
|
||||
$(GLIB_LIBS)
|
||||
test_dump_rva2_SOURCES = test/dump_rva2.cxx \
|
||||
src/riff.c src/aiff.c \
|
||||
@ -1296,6 +1299,7 @@ test_software_volume_SOURCES = test/software_volume.cxx \
|
||||
src/AudioParser.cxx
|
||||
test_software_volume_LDADD = \
|
||||
$(PCM_LIBS) \
|
||||
libutil.a \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
test_run_normalize_SOURCES = test/run_normalize.cxx \
|
||||
@ -1304,6 +1308,7 @@ test_run_normalize_SOURCES = test/run_normalize.cxx \
|
||||
src/AudioParser.cxx \
|
||||
src/AudioCompress/compress.c
|
||||
test_run_normalize_LDADD = \
|
||||
libutil.a \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
test_run_convert_SOURCES = test/run_convert.cxx \
|
||||
@ -1337,6 +1342,7 @@ test_run_output_SOURCES = test/run_output.cxx \
|
||||
src/Timer.cxx \
|
||||
src/Tag.cxx src/TagNames.c src/TagPool.cxx \
|
||||
src/Page.cxx \
|
||||
src/OutputError.cxx \
|
||||
src/OutputInit.cxx src/OutputFinish.cxx src/OutputList.cxx \
|
||||
src/OutputPlugin.cxx \
|
||||
src/MixerControl.cxx \
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "protocol/Result.hxx"
|
||||
#include "Client.hxx"
|
||||
#include "util/Tokenizer.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#ifdef ENABLE_SQLITE
|
||||
#include "StickerCommands.hxx"
|
||||
@ -315,7 +316,7 @@ command_checked_lookup(Client *client, unsigned permission,
|
||||
enum command_return
|
||||
command_process(Client *client, unsigned num, char *line)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
char *argv[COMMAND_ARGV_MAX] = { NULL };
|
||||
const struct command *cmd;
|
||||
enum command_return ret = COMMAND_RETURN_ERROR;
|
||||
@ -325,17 +326,16 @@ command_process(Client *client, unsigned num, char *line)
|
||||
/* get the command name (first word on the line) */
|
||||
|
||||
Tokenizer tokenizer(line);
|
||||
argv[0] = tokenizer.NextWord(&error);
|
||||
argv[0] = tokenizer.NextWord(error);
|
||||
if (argv[0] == NULL) {
|
||||
current_command = "";
|
||||
if (tokenizer.IsEnd())
|
||||
command_error(client, ACK_ERROR_UNKNOWN,
|
||||
"No command given");
|
||||
else {
|
||||
else
|
||||
command_error(client, ACK_ERROR_UNKNOWN,
|
||||
"%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
"%s", error.GetMessage());
|
||||
|
||||
current_command = NULL;
|
||||
|
||||
return COMMAND_RETURN_ERROR;
|
||||
@ -347,7 +347,7 @@ command_process(Client *client, unsigned num, char *line)
|
||||
|
||||
while (argc < COMMAND_ARGV_MAX &&
|
||||
(argv[argc] =
|
||||
tokenizer.NextParam(&error)) != NULL)
|
||||
tokenizer.NextParam(error)) != NULL)
|
||||
++argc;
|
||||
|
||||
/* some error checks; we have to set current_command because
|
||||
@ -362,10 +362,8 @@ command_process(Client *client, unsigned num, char *line)
|
||||
}
|
||||
|
||||
if (!tokenizer.IsEnd()) {
|
||||
command_error(client, ACK_ERROR_ARG,
|
||||
"%s", error->message);
|
||||
command_error(client, ACK_ERROR_ARG, "%s", error.GetMessage());
|
||||
current_command = NULL;
|
||||
g_error_free(error);
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#ifndef MPD_ARCHIVE_FILE_HXX
|
||||
#define MPD_ARCHIVE_FILE_HXX
|
||||
|
||||
class Error;
|
||||
|
||||
class ArchiveFile {
|
||||
public:
|
||||
const struct archive_plugin &plugin;
|
||||
@ -50,7 +52,7 @@ public:
|
||||
*/
|
||||
virtual input_stream *OpenStream(const char *path,
|
||||
Mutex &mutex, Cond &cond,
|
||||
GError **error_r) = 0;
|
||||
Error &error) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -17,27 +17,23 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ArchivePlugin.hxx"
|
||||
#include "ArchiveFile.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
ArchiveFile *
|
||||
archive_file_open(const struct archive_plugin *plugin, const char *path,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
assert(plugin != NULL);
|
||||
assert(plugin->open != NULL);
|
||||
assert(path != NULL);
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
|
||||
ArchiveFile *file = plugin->open(path, error_r);
|
||||
|
||||
if (file != NULL) {
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
} else {
|
||||
assert(error_r == NULL || *error_r != NULL);
|
||||
}
|
||||
ArchiveFile *file = plugin->open(path, error);
|
||||
assert((file == nullptr) == error.IsDefined());
|
||||
|
||||
return file;
|
||||
}
|
||||
|
@ -22,11 +22,11 @@
|
||||
|
||||
#include "thread/Mutex.hxx"
|
||||
#include "thread/Cond.hxx"
|
||||
#include "gerror.h"
|
||||
|
||||
struct input_stream;
|
||||
class ArchiveFile;
|
||||
class ArchiveVisitor;
|
||||
class Error;
|
||||
|
||||
struct archive_plugin {
|
||||
const char *name;
|
||||
@ -49,7 +49,7 @@ struct archive_plugin {
|
||||
* returns pointer to handle used is all operations with this archive
|
||||
* or NULL when opening fails
|
||||
*/
|
||||
ArchiveFile *(*open)(const char *path_fs, GError **error_r);
|
||||
ArchiveFile *(*open)(const char *path_fs, Error &error);
|
||||
|
||||
/**
|
||||
* suffixes handled by this plugin.
|
||||
@ -60,6 +60,6 @@ struct archive_plugin {
|
||||
|
||||
ArchiveFile *
|
||||
archive_file_open(const struct archive_plugin *plugin, const char *path,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "AudioParser.hxx"
|
||||
#include "conf.h"
|
||||
#include "mpd_error.h"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
static AudioFormat configured_audio_format;
|
||||
|
||||
@ -37,15 +38,13 @@ getOutputAudioFormat(AudioFormat inAudioFormat)
|
||||
void initAudioConfig(void)
|
||||
{
|
||||
const struct config_param *param = config_get_param(CONF_AUDIO_OUTPUT_FORMAT);
|
||||
GError *error = NULL;
|
||||
bool ret;
|
||||
|
||||
if (param == NULL)
|
||||
return;
|
||||
|
||||
ret = audio_format_parse(configured_audio_format, param->value,
|
||||
true, &error);
|
||||
if (!ret)
|
||||
Error error;
|
||||
if (!audio_format_parse(configured_audio_format, param->value,
|
||||
true, error))
|
||||
MPD_ERROR("error parsing line %i: %s",
|
||||
param->line, error->message);
|
||||
param->line, error.GetMessage());
|
||||
}
|
||||
|
@ -26,24 +26,16 @@
|
||||
#include "AudioParser.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "CheckAudioFormat.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* The GLib quark used for errors reported by this library.
|
||||
*/
|
||||
static inline GQuark
|
||||
audio_parser_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("audio_parser");
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_sample_rate(const char *src, bool mask, uint32_t *sample_rate_r,
|
||||
const char **endptr_r, GError **error_r)
|
||||
const char **endptr_r, Error &error)
|
||||
{
|
||||
unsigned long value;
|
||||
char *endptr;
|
||||
@ -56,10 +48,10 @@ parse_sample_rate(const char *src, bool mask, uint32_t *sample_rate_r,
|
||||
|
||||
value = strtoul(src, &endptr, 10);
|
||||
if (endptr == src) {
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
"Failed to parse the sample rate");
|
||||
error.Set(audio_format_domain,
|
||||
"Failed to parse the sample rate");
|
||||
return false;
|
||||
} else if (!audio_check_sample_rate(value, error_r))
|
||||
} else if (!audio_check_sample_rate(value, error))
|
||||
return false;
|
||||
|
||||
*sample_rate_r = value;
|
||||
@ -70,7 +62,7 @@ parse_sample_rate(const char *src, bool mask, uint32_t *sample_rate_r,
|
||||
static bool
|
||||
parse_sample_format(const char *src, bool mask,
|
||||
SampleFormat *sample_format_r,
|
||||
const char **endptr_r, GError **error_r)
|
||||
const char **endptr_r, Error &error)
|
||||
{
|
||||
unsigned long value;
|
||||
char *endptr;
|
||||
@ -96,8 +88,8 @@ parse_sample_format(const char *src, bool mask,
|
||||
|
||||
value = strtoul(src, &endptr, 10);
|
||||
if (endptr == src) {
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
"Failed to parse the sample format");
|
||||
error.Set(audio_format_domain,
|
||||
"Failed to parse the sample format");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -123,8 +115,8 @@ parse_sample_format(const char *src, bool mask,
|
||||
break;
|
||||
|
||||
default:
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
"Invalid sample format: %lu", value);
|
||||
error.Format(audio_format_domain,
|
||||
"Invalid sample format: %lu", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -137,7 +129,7 @@ parse_sample_format(const char *src, bool mask,
|
||||
|
||||
static bool
|
||||
parse_channel_count(const char *src, bool mask, uint8_t *channels_r,
|
||||
const char **endptr_r, GError **error_r)
|
||||
const char **endptr_r, Error &error)
|
||||
{
|
||||
unsigned long value;
|
||||
char *endptr;
|
||||
@ -150,10 +142,10 @@ parse_channel_count(const char *src, bool mask, uint8_t *channels_r,
|
||||
|
||||
value = strtoul(src, &endptr, 10);
|
||||
if (endptr == src) {
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
"Failed to parse the channel count");
|
||||
error.Set(audio_format_domain,
|
||||
"Failed to parse the channel count");
|
||||
return false;
|
||||
} else if (!audio_check_channel_count(value, error_r))
|
||||
} else if (!audio_check_channel_count(value, error))
|
||||
return false;
|
||||
|
||||
*channels_r = value;
|
||||
@ -163,7 +155,7 @@ parse_channel_count(const char *src, bool mask, uint8_t *channels_r,
|
||||
|
||||
bool
|
||||
audio_format_parse(AudioFormat &dest, const char *src,
|
||||
bool mask, GError **error_r)
|
||||
bool mask, Error &error)
|
||||
{
|
||||
uint32_t rate;
|
||||
SampleFormat sample_format;
|
||||
@ -178,12 +170,11 @@ audio_format_parse(AudioFormat &dest, const char *src,
|
||||
rate = 0;
|
||||
#endif
|
||||
|
||||
if (!parse_sample_rate(src, mask, &rate, &src, error_r))
|
||||
if (!parse_sample_rate(src, mask, &rate, &src, error))
|
||||
return false;
|
||||
|
||||
if (*src++ != ':') {
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
"Sample format missing");
|
||||
error.Set(audio_format_domain, "Sample format missing");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -194,22 +185,21 @@ audio_format_parse(AudioFormat &dest, const char *src,
|
||||
sample_format = SampleFormat::UNDEFINED;
|
||||
#endif
|
||||
|
||||
if (!parse_sample_format(src, mask, &sample_format, &src, error_r))
|
||||
if (!parse_sample_format(src, mask, &sample_format, &src, error))
|
||||
return false;
|
||||
|
||||
if (*src++ != ':') {
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
"Channel count missing");
|
||||
error.Set(audio_format_domain, "Channel count missing");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* parse channel count */
|
||||
|
||||
if (!parse_channel_count(src, mask, &channels, &src, error_r))
|
||||
if (!parse_channel_count(src, mask, &channels, &src, error))
|
||||
return false;
|
||||
|
||||
if (*src != 0) {
|
||||
g_set_error(error_r, audio_parser_quark(), 0,
|
||||
error.Format(audio_format_domain,
|
||||
"Extra data after channel count: %s", src);
|
||||
return false;
|
||||
}
|
||||
|
@ -25,9 +25,8 @@
|
||||
#ifndef MPD_AUDIO_PARSER_HXX
|
||||
#define MPD_AUDIO_PARSER_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
struct AudioFormat;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Parses a string in the form "SAMPLE_RATE:BITS:CHANNELS" into an
|
||||
@ -42,6 +41,6 @@ struct AudioFormat;
|
||||
*/
|
||||
bool
|
||||
audio_format_parse(AudioFormat &dest, const char *src,
|
||||
bool mask, GError **error_r);
|
||||
bool mask, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -17,17 +17,22 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "CheckAudioFormat.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
const Domain audio_format_domain("audio_format");
|
||||
|
||||
bool
|
||||
audio_check_sample_rate(unsigned long sample_rate, GError **error_r)
|
||||
audio_check_sample_rate(unsigned long sample_rate, Error &error)
|
||||
{
|
||||
if (!audio_valid_sample_rate(sample_rate)) {
|
||||
g_set_error(error_r, audio_format_quark(), 0,
|
||||
"Invalid sample rate: %lu", sample_rate);
|
||||
error.Format(audio_format_domain,
|
||||
"Invalid sample rate: %lu", sample_rate);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -35,12 +40,12 @@ audio_check_sample_rate(unsigned long sample_rate, GError **error_r)
|
||||
}
|
||||
|
||||
bool
|
||||
audio_check_sample_format(SampleFormat sample_format, GError **error_r)
|
||||
audio_check_sample_format(SampleFormat sample_format, Error &error)
|
||||
{
|
||||
if (!audio_valid_sample_format(sample_format)) {
|
||||
g_set_error(error_r, audio_format_quark(), 0,
|
||||
"Invalid sample format: %u",
|
||||
unsigned(sample_format));
|
||||
error.Format(audio_format_domain,
|
||||
"Invalid sample format: %u",
|
||||
unsigned(sample_format));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -48,11 +53,11 @@ audio_check_sample_format(SampleFormat sample_format, GError **error_r)
|
||||
}
|
||||
|
||||
bool
|
||||
audio_check_channel_count(unsigned channels, GError **error_r)
|
||||
audio_check_channel_count(unsigned channels, Error &error)
|
||||
{
|
||||
if (!audio_valid_channel_count(channels)) {
|
||||
g_set_error(error_r, audio_format_quark(), 0,
|
||||
"Invalid channel count: %u", channels);
|
||||
error.Format(audio_format_domain,
|
||||
"Invalid channel count: %u", channels);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -62,11 +67,11 @@ audio_check_channel_count(unsigned channels, GError **error_r)
|
||||
bool
|
||||
audio_format_init_checked(AudioFormat &af, unsigned long sample_rate,
|
||||
SampleFormat sample_format, unsigned channels,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
if (audio_check_sample_rate(sample_rate, error_r) &&
|
||||
audio_check_sample_format(sample_format, error_r) &&
|
||||
audio_check_channel_count(channels, error_r)) {
|
||||
if (audio_check_sample_rate(sample_rate, error) &&
|
||||
audio_check_sample_format(sample_format, error) &&
|
||||
audio_check_channel_count(channels, error)) {
|
||||
af = AudioFormat(sample_rate, sample_format, channels);
|
||||
assert(af.IsValid());
|
||||
return true;
|
||||
|
@ -22,26 +22,18 @@
|
||||
|
||||
#include "AudioFormat.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* The GLib quark used for errors reported by this library.
|
||||
*/
|
||||
gcc_const
|
||||
static inline GQuark
|
||||
audio_format_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("audio_format");
|
||||
}
|
||||
extern const class Domain audio_format_domain;
|
||||
|
||||
bool
|
||||
audio_check_sample_rate(unsigned long sample_rate, GError **error_r);
|
||||
audio_check_sample_rate(unsigned long sample_rate, Error &error);
|
||||
|
||||
bool
|
||||
audio_check_sample_format(SampleFormat sample_format, GError **error_r);
|
||||
audio_check_sample_format(SampleFormat sample_format, Error &error);
|
||||
|
||||
bool
|
||||
audio_check_channel_count(unsigned sample_format, GError **error_r);
|
||||
audio_check_channel_count(unsigned sample_format, Error &error);
|
||||
|
||||
/**
|
||||
* Wrapper for audio_format_init(), which checks all attributes.
|
||||
@ -49,6 +41,6 @@ audio_check_channel_count(unsigned sample_format, GError **error_r);
|
||||
bool
|
||||
audio_format_init_checked(AudioFormat &af, unsigned long sample_rate,
|
||||
SampleFormat sample_format, unsigned channels,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -19,14 +19,14 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "ClientInternal.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
void
|
||||
Client::OnSocketError(GError *error)
|
||||
Client::OnSocketError(Error &&error)
|
||||
{
|
||||
g_warning("error on client %d: %s", num, error->message);
|
||||
g_error_free(error);
|
||||
g_warning("error on client %d: %s", num, error.GetMessage());
|
||||
|
||||
SetExpired();
|
||||
}
|
||||
|
@ -21,9 +21,10 @@
|
||||
#include "ClientFile.hxx"
|
||||
#include "Client.hxx"
|
||||
#include "protocol/Ack.hxx"
|
||||
#include "io_error.h"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -32,14 +33,13 @@
|
||||
|
||||
bool
|
||||
client_allow_file(const Client *client, const Path &path_fs,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
#ifdef WIN32
|
||||
(void)client;
|
||||
(void)path_fs;
|
||||
|
||||
g_set_error(error_r, ack_quark(), ACK_ERROR_PERMISSION,
|
||||
"Access denied");
|
||||
error.Set(ack_domain, ACK_ERROR_PERMISSION, "Access denied");
|
||||
return false;
|
||||
#else
|
||||
const int uid = client_get_uid(client);
|
||||
@ -50,21 +50,19 @@ client_allow_file(const Client *client, const Path &path_fs,
|
||||
|
||||
if (uid <= 0) {
|
||||
/* unauthenticated client */
|
||||
g_set_error(error_r, ack_quark(), ACK_ERROR_PERMISSION,
|
||||
"Access denied");
|
||||
error.Set(ack_domain, ACK_ERROR_PERMISSION, "Access denied");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (!StatFile(path_fs, st)) {
|
||||
set_error_errno(error_r);
|
||||
error.SetErrno();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (st.st_uid != (uid_t)uid && (st.st_mode & 0444) != 0444) {
|
||||
/* client is not owner */
|
||||
g_set_error(error_r, ack_quark(), ACK_ERROR_PERMISSION,
|
||||
"Access denied");
|
||||
error.Set(ack_domain, ACK_ERROR_PERMISSION, "Access denied");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -20,10 +20,9 @@
|
||||
#ifndef MPD_CLIENT_FILE_HXX
|
||||
#define MPD_CLIENT_FILE_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
class Client;
|
||||
class Path;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Is this client allowed to use the specified local file?
|
||||
@ -37,6 +36,6 @@ class Path;
|
||||
*/
|
||||
bool
|
||||
client_allow_file(const Client *client, const Path &path_fs,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -116,7 +116,7 @@ private:
|
||||
/* virtual methods from class BufferedSocket */
|
||||
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;
|
||||
|
||||
/* virtual methods from class TimeoutMonitor */
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "system/fd_util.h"
|
||||
#include "system/Resolver.hxx"
|
||||
#include "Permission.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
@ -70,7 +71,8 @@ client_new(EventLoop &loop, Partition &partition,
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
if (sa->sa_family != AF_UNIX) {
|
||||
char *hostaddr = sockaddr_to_string(sa, sa_length, NULL);
|
||||
char *hostaddr = sockaddr_to_string(sa, sa_length,
|
||||
IgnoreError());
|
||||
const char *progname = g_get_prgname();
|
||||
|
||||
struct request_info req;
|
||||
@ -107,7 +109,7 @@ client_new(EventLoop &loop, Partition &partition,
|
||||
|
||||
client_list.Add(*client);
|
||||
|
||||
remote = sockaddr_to_string(sa, sa_length, NULL);
|
||||
remote = sockaddr_to_string(sa, sa_length, IgnoreError());
|
||||
g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE,
|
||||
"[%u] opened from %s", client->num, remote);
|
||||
g_free(remote);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "protocol/Result.hxx"
|
||||
#include "AllCommands.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define CLIENT_LIST_MODE_BEGIN "command_list_begin"
|
||||
|
@ -20,8 +20,10 @@
|
||||
#include "config.h"
|
||||
#include "CommandError.hxx"
|
||||
#include "DatabaseError.hxx"
|
||||
#include "io_error.h"
|
||||
#include "protocol/Result.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
@ -85,50 +87,38 @@ print_playlist_result(Client *client, enum playlist_result result)
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the GError to the client and free the GError.
|
||||
*/
|
||||
enum command_return
|
||||
print_error(Client *client, GError *error)
|
||||
print_error(Client *client, const Error &error)
|
||||
{
|
||||
assert(client != NULL);
|
||||
assert(error != NULL);
|
||||
assert(error.IsDefined());
|
||||
|
||||
g_warning("%s", error->message);
|
||||
g_warning("%s", error.GetMessage());
|
||||
|
||||
if (error->domain == playlist_quark()) {
|
||||
enum playlist_result result = (playlist_result)error->code;
|
||||
g_error_free(error);
|
||||
return print_playlist_result(client, result);
|
||||
} else if (error->domain == ack_quark()) {
|
||||
command_error(client, (ack)error->code, "%s", error->message);
|
||||
g_error_free(error);
|
||||
if (error.IsDomain(playlist_domain)) {
|
||||
return print_playlist_result(client,
|
||||
playlist_result(error.GetCode()));
|
||||
} else if (error.IsDomain(ack_domain)) {
|
||||
command_error(client, (ack)error.GetCode(),
|
||||
"%s", error.GetMessage());
|
||||
return COMMAND_RETURN_ERROR;
|
||||
} else if (error->domain == db_quark()) {
|
||||
switch ((enum db_error)error->code) {
|
||||
} else if (error.IsDomain(db_domain)) {
|
||||
switch ((enum db_error)error.GetCode()) {
|
||||
case DB_DISABLED:
|
||||
command_error(client, ACK_ERROR_NO_EXIST, "%s",
|
||||
error->message);
|
||||
g_error_free(error);
|
||||
error.GetMessage());
|
||||
return COMMAND_RETURN_ERROR;
|
||||
|
||||
case DB_NOT_FOUND:
|
||||
g_error_free(error);
|
||||
command_error(client, ACK_ERROR_NO_EXIST, "Not found");
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
} else if (error->domain == errno_quark()) {
|
||||
} else if (error.IsDomain(errno_domain)) {
|
||||
command_error(client, ACK_ERROR_SYSTEM, "%s",
|
||||
g_strerror(error->code));
|
||||
g_error_free(error);
|
||||
return COMMAND_RETURN_ERROR;
|
||||
} else if (error->domain == g_file_error_quark()) {
|
||||
command_error(client, ACK_ERROR_SYSTEM, "%s", error->message);
|
||||
g_error_free(error);
|
||||
g_strerror(error.GetCode()));
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
g_error_free(error);
|
||||
command_error(client, ACK_ERROR_UNKNOWN, "error");
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
@ -22,17 +22,17 @@
|
||||
|
||||
#include "command.h"
|
||||
#include "PlaylistError.hxx"
|
||||
#include "gerror.h"
|
||||
|
||||
class Client;
|
||||
class Error;
|
||||
|
||||
enum command_return
|
||||
print_playlist_result(Client *client, enum playlist_result result);
|
||||
|
||||
/**
|
||||
* Send the GError to the client and free the GError.
|
||||
* Send the #Error to the client.
|
||||
*/
|
||||
enum command_return
|
||||
print_error(Client *client, GError *error);
|
||||
print_error(Client *client, const Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "mpd_error.h"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#ifdef ENABLE_ENCODER
|
||||
#include "EncoderList.hxx"
|
||||
@ -57,11 +59,7 @@
|
||||
#define USER_CONFIG_FILE_LOCATION_XDG "mpd/mpd.conf"
|
||||
#endif
|
||||
|
||||
static GQuark
|
||||
cmdline_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("cmdline");
|
||||
}
|
||||
static constexpr Domain cmdline_domain("cmdline");
|
||||
|
||||
gcc_noreturn
|
||||
static void version(void)
|
||||
@ -147,9 +145,8 @@ PathBuildChecked(const Path &a, Path::const_pointer b)
|
||||
|
||||
bool
|
||||
parse_cmdline(int argc, char **argv, struct options *options,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
bool ret;
|
||||
static gboolean option_version,
|
||||
@ -183,11 +180,12 @@ parse_cmdline(int argc, char **argv, struct options *options,
|
||||
|
||||
g_option_context_set_summary(context, summary);
|
||||
|
||||
ret = g_option_context_parse(context, &argc, &argv, &error);
|
||||
GError *gerror = nullptr;
|
||||
ret = g_option_context_parse(context, &argc, &argv, &gerror);
|
||||
g_option_context_free(context);
|
||||
|
||||
if (!ret)
|
||||
MPD_ERROR("option parsing failed: %s\n", error->message);
|
||||
MPD_ERROR("option parsing failed: %s\n", gerror->message);
|
||||
|
||||
if (option_version)
|
||||
version();
|
||||
@ -208,7 +206,7 @@ parse_cmdline(int argc, char **argv, struct options *options,
|
||||
Path path = PathBuildChecked(Path::FromUTF8(g_get_user_config_dir()),
|
||||
CONFIG_FILE_LOCATION);
|
||||
if (!path.IsNull() && FileExists(path))
|
||||
return ReadConfigFile(path, error_r);
|
||||
return ReadConfigFile(path, error);
|
||||
|
||||
const char *const*system_config_dirs =
|
||||
g_get_system_config_dirs();
|
||||
@ -217,38 +215,36 @@ parse_cmdline(int argc, char **argv, struct options *options,
|
||||
path = PathBuildChecked(Path::FromUTF8(system_config_dirs[i]),
|
||||
CONFIG_FILE_LOCATION);
|
||||
if (!path.IsNull() && FileExists(path))
|
||||
return ReadConfigFile(path, error_r);
|
||||
return ReadConfigFile(path, error);
|
||||
}
|
||||
#else /* G_OS_WIN32 */
|
||||
Path path = PathBuildChecked(Path::FromUTF8(g_get_user_config_dir()),
|
||||
USER_CONFIG_FILE_LOCATION_XDG);
|
||||
if (!path.IsNull() && FileExists(path))
|
||||
return ReadConfigFile(path, error_r);
|
||||
return ReadConfigFile(path, error);
|
||||
|
||||
path = PathBuildChecked(Path::FromUTF8(g_get_home_dir()),
|
||||
USER_CONFIG_FILE_LOCATION1);
|
||||
if (!path.IsNull() && FileExists(path))
|
||||
return ReadConfigFile(path, error_r);
|
||||
return ReadConfigFile(path, error);
|
||||
|
||||
path = PathBuildChecked(Path::FromUTF8(g_get_home_dir()),
|
||||
USER_CONFIG_FILE_LOCATION2);
|
||||
if (!path.IsNull() && FileExists(path))
|
||||
return ReadConfigFile(path, error_r);
|
||||
return ReadConfigFile(path, error);
|
||||
|
||||
path = Path::FromUTF8(SYSTEM_CONFIG_FILE_LOCATION);
|
||||
if (!path.IsNull() && FileExists(path))
|
||||
return ReadConfigFile(path, error_r);
|
||||
return ReadConfigFile(path, error);
|
||||
#endif
|
||||
|
||||
g_set_error(error_r, cmdline_quark(), 0,
|
||||
"No configuration file found");
|
||||
error.Set(cmdline_domain, "No configuration file found");
|
||||
return false;
|
||||
} else if (argc == 2) {
|
||||
/* specified configuration file */
|
||||
return ReadConfigFile(Path::FromFS(argv[1]), error_r);
|
||||
return ReadConfigFile(Path::FromFS(argv[1]), error);
|
||||
} else {
|
||||
g_set_error(error_r, cmdline_quark(), 0,
|
||||
"too many arguments");
|
||||
error.Set(cmdline_domain, "too many arguments");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
class Error;
|
||||
|
||||
struct options {
|
||||
gboolean kill;
|
||||
gboolean daemon;
|
||||
@ -31,6 +33,6 @@ struct options {
|
||||
|
||||
bool
|
||||
parse_cmdline(int argc, char **argv, struct options *options,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ConfigData.hxx"
|
||||
#include "ConfigParser.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "mpd_error.h"
|
||||
@ -97,10 +98,9 @@ config_param::DupBlockString(const char *name, const char *default_value) const
|
||||
|
||||
Path
|
||||
config_param::GetBlockPath(const char *name, const char *default_value,
|
||||
GError **error_r) const
|
||||
Error &error) const
|
||||
{
|
||||
assert(error_r != nullptr);
|
||||
assert(*error_r == nullptr);
|
||||
assert(!error.IsDefined());
|
||||
|
||||
int line2 = line;
|
||||
const char *s;
|
||||
@ -112,19 +112,18 @@ config_param::GetBlockPath(const char *name, const char *default_value,
|
||||
} else
|
||||
s = default_value;
|
||||
|
||||
Path path = ParsePath(s, error_r);
|
||||
Path path = ParsePath(s, error);
|
||||
if (gcc_unlikely(path.IsNull()))
|
||||
g_prefix_error(error_r,
|
||||
"Invalid path in \"%s\" at line %i: ",
|
||||
name, line2);
|
||||
error.FormatPrefix("Invalid path in \"%s\" at line %i: ",
|
||||
name, line2);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
Path
|
||||
config_param::GetBlockPath(const char *name, GError **error_r) const
|
||||
config_param::GetBlockPath(const char *name, Error &error) const
|
||||
{
|
||||
return GetBlockPath(name, nullptr, error_r);
|
||||
return GetBlockPath(name, nullptr, error);
|
||||
}
|
||||
|
||||
unsigned
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define MPD_CONFIG_DATA_HXX
|
||||
|
||||
#include "ConfigOption.hxx"
|
||||
#include "gerror.h"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <string>
|
||||
@ -29,6 +28,7 @@
|
||||
#include <vector>
|
||||
|
||||
class Path;
|
||||
class Error;
|
||||
|
||||
struct block_param {
|
||||
std::string name;
|
||||
@ -113,9 +113,9 @@ struct config_param {
|
||||
* specified block.
|
||||
*/
|
||||
Path GetBlockPath(const char *name, const char *default_value,
|
||||
GError **error_r) const;
|
||||
Error &error) const;
|
||||
|
||||
Path GetBlockPath(const char *name, GError **error_r) const;
|
||||
Path GetBlockPath(const char *name, Error &error) const;
|
||||
|
||||
gcc_pure
|
||||
unsigned GetBlockValue(const char *name, unsigned default_value) const;
|
||||
|
23
src/ConfigError.cxx
Normal file
23
src/ConfigError.cxx
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ConfigError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
const Domain config_domain("config");
|
@ -17,22 +17,9 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_CONFIG_QUARK_HXX
|
||||
#define MPD_CONFIG_QUARK_HXX
|
||||
#ifndef MPD_CONFIG_ERROR_HXX
|
||||
#define MPD_CONFIG_ERROR_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* A GQuark for GError instances, resulting from malformed
|
||||
* configuration.
|
||||
*/
|
||||
gcc_const
|
||||
static inline GQuark
|
||||
config_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("config");
|
||||
}
|
||||
extern const class Domain config_domain;
|
||||
|
||||
#endif
|
@ -19,12 +19,14 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "ConfigFile.hxx"
|
||||
#include "ConfigQuark.hxx"
|
||||
#include "ConfigError.hxx"
|
||||
#include "ConfigData.hxx"
|
||||
#include "ConfigTemplates.hxx"
|
||||
#include "conf.h"
|
||||
#include "util/Tokenizer.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
|
||||
@ -42,42 +44,41 @@
|
||||
|
||||
#define CONF_COMMENT '#'
|
||||
|
||||
static constexpr Domain config_file_domain("config_file");
|
||||
|
||||
static bool
|
||||
config_read_name_value(struct config_param *param, char *input, unsigned line,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
Tokenizer tokenizer(input);
|
||||
|
||||
const char *name = tokenizer.NextWord(error_r);
|
||||
const char *name = tokenizer.NextWord(error);
|
||||
if (name == NULL) {
|
||||
assert(!tokenizer.IsEnd());
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *value = tokenizer.NextString(error_r);
|
||||
const char *value = tokenizer.NextString(error);
|
||||
if (value == NULL) {
|
||||
if (tokenizer.IsEnd()) {
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"Value missing");
|
||||
error.Set(config_file_domain, "Value missing");
|
||||
} else {
|
||||
assert(error_r == NULL || *error_r != NULL);
|
||||
assert(error.IsDefined());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tokenizer.IsEnd() && tokenizer.CurrentChar() != CONF_COMMENT) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"Unknown tokens after value");
|
||||
error.Set(config_file_domain, "Unknown tokens after value");
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct block_param *bp = param->GetBlockParam(name);
|
||||
if (bp != NULL) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"\"%s\" is duplicate, first defined on line %i",
|
||||
name, bp->line);
|
||||
error.Format(config_file_domain,
|
||||
"\"%s\" is duplicate, first defined on line %i",
|
||||
name, bp->line);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -86,10 +87,9 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
|
||||
}
|
||||
|
||||
static struct config_param *
|
||||
config_read_block(FILE *fp, int *count, char *string, GError **error_r)
|
||||
config_read_block(FILE *fp, int *count, char *string, Error &error)
|
||||
{
|
||||
struct config_param *ret = new config_param(*count);
|
||||
GError *error = NULL;
|
||||
|
||||
while (true) {
|
||||
char *line;
|
||||
@ -97,8 +97,8 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
|
||||
line = fgets(string, MAX_STRING_SIZE, fp);
|
||||
if (line == NULL) {
|
||||
delete ret;
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"Expected '}' before end-of-file");
|
||||
error.Set(config_file_domain,
|
||||
"Expected '}' before end-of-file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -114,9 +114,9 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
|
||||
line = strchug_fast(line + 1);
|
||||
if (*line != 0 && *line != CONF_COMMENT) {
|
||||
delete ret;
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"line %i: Unknown tokens after '}'",
|
||||
*count);
|
||||
error.Format(config_file_domain,
|
||||
"line %i: Unknown tokens after '}'",
|
||||
*count);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -125,11 +125,10 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
|
||||
|
||||
/* parse name and value */
|
||||
|
||||
if (!config_read_name_value(ret, line, *count, &error)) {
|
||||
if (!config_read_name_value(ret, line, *count, error)) {
|
||||
assert(*line != 0);
|
||||
delete ret;
|
||||
g_propagate_prefixed_error(error_r, error,
|
||||
"line %i: ", *count);
|
||||
error.FormatPrefix("line %i: ", *count);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -149,7 +148,7 @@ Append(config_param *&head, config_param *p)
|
||||
}
|
||||
|
||||
static bool
|
||||
ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
ReadConfigFile(ConfigData &config_data, FILE *fp, Error &error)
|
||||
{
|
||||
assert(fp != nullptr);
|
||||
|
||||
@ -160,7 +159,6 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
while (fgets(string, MAX_STRING_SIZE, fp)) {
|
||||
char *line;
|
||||
const char *name, *value;
|
||||
GError *error = NULL;
|
||||
|
||||
count++;
|
||||
|
||||
@ -172,11 +170,10 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
by either the value or '{' */
|
||||
|
||||
Tokenizer tokenizer(line);
|
||||
name = tokenizer.NextWord(&error);
|
||||
name = tokenizer.NextWord(error);
|
||||
if (name == NULL) {
|
||||
assert(!tokenizer.IsEnd());
|
||||
g_propagate_prefixed_error(error_r, error,
|
||||
"line %i: ", count);
|
||||
error.FormatPrefix("line %i: ", count);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -185,9 +182,9 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
|
||||
const ConfigOption o = ParseConfigOptionName(name);
|
||||
if (o == CONF_MAX) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"unrecognized parameter in config file at "
|
||||
"line %i: %s\n", count, name);
|
||||
error.Format(config_file_domain,
|
||||
"unrecognized parameter in config file at "
|
||||
"line %i: %s\n", count, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -197,10 +194,10 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
|
||||
if (head != nullptr && !option.repeatable) {
|
||||
param = head;
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"config parameter \"%s\" is first defined "
|
||||
"on line %i and redefined on line %i\n",
|
||||
name, param->line, count);
|
||||
error.Format(config_file_domain,
|
||||
"config parameter \"%s\" is first defined "
|
||||
"on line %i and redefined on line %i\n",
|
||||
name, param->line, count);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -210,47 +207,43 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
/* it's a block, call config_read_block() */
|
||||
|
||||
if (tokenizer.CurrentChar() != '{') {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"line %i: '{' expected", count);
|
||||
error.Format(config_file_domain,
|
||||
"line %i: '{' expected", count);
|
||||
return false;
|
||||
}
|
||||
|
||||
line = strchug_fast(tokenizer.Rest() + 1);
|
||||
if (*line != 0 && *line != CONF_COMMENT) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"line %i: Unknown tokens after '{'",
|
||||
count);
|
||||
error.Format(config_file_domain,
|
||||
"line %i: Unknown tokens after '{'",
|
||||
count);
|
||||
return false;
|
||||
}
|
||||
|
||||
param = config_read_block(fp, &count, string, error_r);
|
||||
param = config_read_block(fp, &count, string, error);
|
||||
if (param == NULL) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* a string value */
|
||||
|
||||
value = tokenizer.NextString(&error);
|
||||
value = tokenizer.NextString(error);
|
||||
if (value == NULL) {
|
||||
if (tokenizer.IsEnd())
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"line %i: Value missing",
|
||||
count);
|
||||
else {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"line %i: %s", count,
|
||||
error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
error.Format(config_file_domain,
|
||||
"line %i: Value missing",
|
||||
count);
|
||||
else
|
||||
error.FormatPrefix("line %i: ", count);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tokenizer.IsEnd() &&
|
||||
tokenizer.CurrentChar() != CONF_COMMENT) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"line %i: Unknown tokens after value",
|
||||
count);
|
||||
error.Format(config_file_domain,
|
||||
"line %i: Unknown tokens after value",
|
||||
count);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -264,7 +257,7 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r)
|
||||
}
|
||||
|
||||
bool
|
||||
ReadConfigFile(ConfigData &config_data, const Path &path, GError **error_r)
|
||||
ReadConfigFile(ConfigData &config_data, const Path &path, Error &error)
|
||||
{
|
||||
assert(!path.IsNull());
|
||||
const std::string path_utf8 = path.ToUTF8();
|
||||
@ -273,13 +266,11 @@ ReadConfigFile(ConfigData &config_data, const Path &path, GError **error_r)
|
||||
|
||||
FILE *fp = FOpen(path, FOpenMode::ReadText);
|
||||
if (fp == nullptr) {
|
||||
g_set_error(error_r, config_quark(), errno,
|
||||
"Failed to open %s: %s",
|
||||
path_utf8.c_str(), g_strerror(errno));
|
||||
error.FormatErrno("Failed to open %s", path_utf8.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = ReadConfigFile(config_data, fp, error_r);
|
||||
bool result = ReadConfigFile(config_data, fp, error);
|
||||
fclose(fp);
|
||||
return result;
|
||||
}
|
||||
|
@ -20,12 +20,11 @@
|
||||
#ifndef MPD_CONFIG_FILE_HXX
|
||||
#define MPD_CONFIG_FILE_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
class Error;
|
||||
class Path;
|
||||
struct ConfigData;
|
||||
|
||||
bool
|
||||
ReadConfigFile(ConfigData &data, const Path &path, GError **error_r);
|
||||
ReadConfigFile(ConfigData &data, const Path &path, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "ConfigFile.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "mpd_error.h"
|
||||
|
||||
#include <glib.h>
|
||||
@ -47,9 +48,9 @@ void config_global_init(void)
|
||||
}
|
||||
|
||||
bool
|
||||
ReadConfigFile(const Path &path, GError **error_r)
|
||||
ReadConfigFile(const Path &path, Error &error)
|
||||
{
|
||||
return ReadConfigFile(config_data, path, error_r);
|
||||
return ReadConfigFile(config_data, path, error);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -98,20 +99,16 @@ config_get_string(ConfigOption option, const char *default_value)
|
||||
}
|
||||
|
||||
Path
|
||||
config_get_path(ConfigOption option, GError **error_r)
|
||||
config_get_path(ConfigOption option, Error &error)
|
||||
{
|
||||
assert(error_r != NULL);
|
||||
assert(*error_r == NULL);
|
||||
|
||||
const struct config_param *param = config_get_param(option);
|
||||
if (param == NULL)
|
||||
return Path::Null();
|
||||
|
||||
Path path = ParsePath(param->value, error_r);
|
||||
Path path = ParsePath(param->value, error);
|
||||
if (gcc_unlikely(path.IsNull()))
|
||||
g_prefix_error(error_r,
|
||||
"Invalid path at line %i: ",
|
||||
param->line);
|
||||
error.FormatPrefix("Invalid path at line %i: ",
|
||||
param->line);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define MPD_CONFIG_GLOBAL_HXX
|
||||
|
||||
#include "ConfigOption.hxx"
|
||||
#include "gerror.h"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
@ -30,6 +29,7 @@
|
||||
#define DEFAULT_PLAYLIST_MAX_LENGTH (1024*16)
|
||||
#define DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS false
|
||||
|
||||
class Error;
|
||||
class Path;
|
||||
|
||||
void config_global_init(void);
|
||||
@ -42,7 +42,7 @@ void config_global_finish(void);
|
||||
void config_global_check(void);
|
||||
|
||||
bool
|
||||
ReadConfigFile(const Path &path, GError **error_r);
|
||||
ReadConfigFile(const Path &path, Error &error);
|
||||
|
||||
/* don't free the returned value
|
||||
set _last_ to NULL to get first entry */
|
||||
@ -76,7 +76,7 @@ config_get_string(enum ConfigOption option, const char *default_value);
|
||||
* could not be parsed, returns Path::Null() and sets the error.
|
||||
*/
|
||||
Path
|
||||
config_get_path(enum ConfigOption option, GError **error_r);
|
||||
config_get_path(enum ConfigOption option, Error &error);
|
||||
|
||||
gcc_pure
|
||||
unsigned
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "config.h"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
#include <glib.h>
|
||||
@ -46,31 +48,25 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
gcc_const
|
||||
static inline GQuark
|
||||
parse_path_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("path");
|
||||
}
|
||||
static constexpr Domain path_domain("path");
|
||||
|
||||
Path
|
||||
ParsePath(const char *path, GError **error_r)
|
||||
ParsePath(const char *path, Error &error)
|
||||
{
|
||||
assert(path != nullptr);
|
||||
assert(error_r == nullptr || *error_r == nullptr);
|
||||
|
||||
Path path2 = Path::FromUTF8(path);
|
||||
if (path2.IsNull()) {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"Failed to convert path to file system charset: %s",
|
||||
path);
|
||||
error.Format(path_domain,
|
||||
"Failed to convert path to file system charset: %s",
|
||||
path);
|
||||
return Path::Null();
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (!g_path_is_absolute(path) && path[0] != '~') {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"not an absolute path: %s", path);
|
||||
error.Format(path_domain,
|
||||
"not an absolute path: %s", path);
|
||||
return Path::Null();
|
||||
} else if (path[0] == '~') {
|
||||
const char *home;
|
||||
@ -80,8 +76,8 @@ ParsePath(const char *path, GError **error_r)
|
||||
if (user != nullptr) {
|
||||
struct passwd *passwd = getpwnam(user);
|
||||
if (!passwd) {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"no such user: %s", user);
|
||||
error.Format(path_domain,
|
||||
"no such user: %s", user);
|
||||
return Path::Null();
|
||||
}
|
||||
|
||||
@ -89,9 +85,9 @@ ParsePath(const char *path, GError **error_r)
|
||||
} else {
|
||||
home = g_get_home_dir();
|
||||
if (home == nullptr) {
|
||||
g_set_error_literal(error_r, parse_path_quark(), 0,
|
||||
"problems getting home "
|
||||
"for current user");
|
||||
error.Set(path_domain,
|
||||
"problems getting home "
|
||||
"for current user");
|
||||
return Path::Null();
|
||||
}
|
||||
}
|
||||
@ -107,8 +103,8 @@ ParsePath(const char *path, GError **error_r)
|
||||
|
||||
struct passwd *passwd = getpwnam(user);
|
||||
if (!passwd) {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"no such user: %s", user);
|
||||
error.Format(path_domain,
|
||||
"no such user: %s", user);
|
||||
g_free(user);
|
||||
return Path::Null();
|
||||
}
|
||||
|
@ -20,11 +20,10 @@
|
||||
#ifndef MPD_CONFIG_PATH_HXX
|
||||
#define MPD_CONFIG_PATH_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
class Path;
|
||||
class Error;
|
||||
|
||||
Path
|
||||
ParsePath(const char *path, GError **error_r);
|
||||
ParsePath(const char *path, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "ClientInternal.hxx"
|
||||
#include "Tag.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "SongFilter.hxx"
|
||||
#include "protocol/Result.hxx"
|
||||
|
||||
@ -46,8 +47,8 @@ handle_lsinfo2(Client *client, int argc, char *argv[])
|
||||
|
||||
const DatabaseSelection selection(uri, false);
|
||||
|
||||
GError *error = NULL;
|
||||
if (!db_selection_print(client, selection, true, &error))
|
||||
Error error;
|
||||
if (!db_selection_print(client, selection, true, error))
|
||||
return print_error(client, error);
|
||||
|
||||
return COMMAND_RETURN_OK;
|
||||
@ -64,8 +65,8 @@ handle_match(Client *client, int argc, char *argv[], bool fold_case)
|
||||
|
||||
const DatabaseSelection selection("", true, &filter);
|
||||
|
||||
GError *error = NULL;
|
||||
return db_selection_print(client, selection, true, &error)
|
||||
Error error;
|
||||
return db_selection_print(client, selection, true, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -92,8 +93,8 @@ handle_match_add(Client *client, int argc, char *argv[], bool fold_case)
|
||||
}
|
||||
|
||||
const DatabaseSelection selection("", true, &filter);
|
||||
GError *error = NULL;
|
||||
return AddFromDatabase(client->partition, selection, &error)
|
||||
Error error;
|
||||
return AddFromDatabase(client->partition, selection, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -121,8 +122,8 @@ handle_searchaddpl(Client *client, int argc, char *argv[])
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
GError *error = NULL;
|
||||
return search_add_to_playlist("", playlist, &filter, &error)
|
||||
Error error;
|
||||
return search_add_to_playlist("", playlist, &filter, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -136,8 +137,8 @@ handle_count(Client *client, int argc, char *argv[])
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
GError *error = NULL;
|
||||
return searchStatsForSongsIn(client, "", &filter, &error)
|
||||
Error error;
|
||||
return searchStatsForSongsIn(client, "", &filter, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -150,8 +151,8 @@ handle_listall(Client *client, gcc_unused int argc, char *argv[])
|
||||
if (argc == 2)
|
||||
directory = argv[1];
|
||||
|
||||
GError *error = NULL;
|
||||
return printAllIn(client, directory, &error)
|
||||
Error error;
|
||||
return printAllIn(client, directory, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -194,9 +195,9 @@ handle_list(Client *client, int argc, char *argv[])
|
||||
} else
|
||||
filter = nullptr;
|
||||
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
enum command_return ret =
|
||||
listAllUniqueTags(client, tagType, filter, &error)
|
||||
listAllUniqueTags(client, tagType, filter, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
|
||||
@ -213,8 +214,8 @@ handle_listallinfo(Client *client, gcc_unused int argc, char *argv[])
|
||||
if (argc == 2)
|
||||
directory = argv[1];
|
||||
|
||||
GError *error = NULL;
|
||||
return printInfoForAllIn(client, directory, &error)
|
||||
Error error;
|
||||
return printInfoForAllIn(client, directory, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
|
24
src/DatabaseError.cxx
Normal file
24
src/DatabaseError.cxx
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "DatabaseError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
const Domain db_domain("db");
|
@ -20,9 +20,7 @@
|
||||
#ifndef MPD_DB_ERROR_HXX
|
||||
#define MPD_DB_ERROR_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
class Domain;
|
||||
|
||||
enum db_error {
|
||||
/**
|
||||
@ -34,14 +32,6 @@ enum db_error {
|
||||
DB_NOT_FOUND,
|
||||
};
|
||||
|
||||
/**
|
||||
* Quark for GError.domain; the code is an enum #db_error.
|
||||
*/
|
||||
gcc_const
|
||||
static inline GQuark
|
||||
db_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("db");
|
||||
}
|
||||
extern const Domain db_domain;
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "DatabaseSave.hxx"
|
||||
#include "DatabaseError.hxx"
|
||||
#include "Directory.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
extern "C" {
|
||||
@ -50,7 +51,7 @@ static bool db_is_open;
|
||||
static bool is_simple;
|
||||
|
||||
bool
|
||||
DatabaseGlobalInit(const config_param ¶m, GError **error_r)
|
||||
DatabaseGlobalInit(const config_param ¶m, Error &error)
|
||||
{
|
||||
assert(db == NULL);
|
||||
assert(!db_is_open);
|
||||
@ -61,12 +62,12 @@ DatabaseGlobalInit(const config_param ¶m, GError **error_r)
|
||||
|
||||
const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name);
|
||||
if (plugin == NULL) {
|
||||
g_set_error(error_r, db_quark(), 0,
|
||||
"No such database plugin: %s", plugin_name);
|
||||
error.Format(db_domain,
|
||||
"No such database plugin: %s", plugin_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
db = plugin->create(param, error_r);
|
||||
db = plugin->create(param, error);
|
||||
return db != NULL;
|
||||
}
|
||||
|
||||
@ -89,13 +90,12 @@ GetDatabase()
|
||||
}
|
||||
|
||||
const Database *
|
||||
GetDatabase(GError **error_r)
|
||||
GetDatabase(Error &error)
|
||||
{
|
||||
assert(db == nullptr || db_is_open);
|
||||
|
||||
if (db == nullptr)
|
||||
g_set_error_literal(error_r, db_quark(), DB_DISABLED,
|
||||
"No database");
|
||||
error.Set(db_domain, DB_DISABLED, "No database");
|
||||
|
||||
return db;
|
||||
}
|
||||
@ -131,17 +131,17 @@ db_get_directory(const char *name)
|
||||
}
|
||||
|
||||
bool
|
||||
db_save(GError **error_r)
|
||||
db_save(Error &error)
|
||||
{
|
||||
assert(db != NULL);
|
||||
assert(db_is_open);
|
||||
assert(db_is_simple());
|
||||
|
||||
return ((SimpleDatabase *)db)->Save(error_r);
|
||||
return ((SimpleDatabase *)db)->Save(error);
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseGlobalOpen(GError **error)
|
||||
DatabaseGlobalOpen(Error &error)
|
||||
{
|
||||
assert(db != NULL);
|
||||
assert(!db_is_open);
|
||||
|
@ -21,10 +21,10 @@
|
||||
#define MPD_DATABASE_GLUE_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
#include "gerror.h"
|
||||
|
||||
struct config_param;
|
||||
class Database;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Initialize the database library.
|
||||
@ -32,13 +32,13 @@ class Database;
|
||||
* @param param the database configuration block
|
||||
*/
|
||||
bool
|
||||
DatabaseGlobalInit(const config_param ¶m, GError **error_r);
|
||||
DatabaseGlobalInit(const config_param ¶m, Error &error);
|
||||
|
||||
void
|
||||
DatabaseGlobalDeinit(void);
|
||||
|
||||
bool
|
||||
DatabaseGlobalOpen(GError **error);
|
||||
DatabaseGlobalOpen(Error &error);
|
||||
|
||||
/**
|
||||
* Returns the global #Database instance. May return NULL if this MPD
|
||||
@ -54,6 +54,6 @@ GetDatabase();
|
||||
*/
|
||||
gcc_pure
|
||||
const Database *
|
||||
GetDatabase(GError **error_r);
|
||||
GetDatabase(Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -61,17 +61,17 @@ bool
|
||||
VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
|
||||
enum tag_type tag_type,
|
||||
VisitString visit_string,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
StringSet set;
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(CollectTags, std::ref(set), tag_type, _1);
|
||||
if (!db.Visit(selection, f, error_r))
|
||||
if (!db.Visit(selection, f, error))
|
||||
return false;
|
||||
|
||||
for (auto value : set)
|
||||
if (!visit_string(value, error_r))
|
||||
if (!visit_string(value, error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -116,7 +116,7 @@ StatsVisitSong(DatabaseStats &stats, StringSet &artists, StringSet &albums,
|
||||
|
||||
bool
|
||||
GetStats(const Database &db, const DatabaseSelection &selection,
|
||||
DatabaseStats &stats, GError **error_r)
|
||||
DatabaseStats &stats, Error &error)
|
||||
{
|
||||
stats.Clear();
|
||||
|
||||
@ -125,7 +125,7 @@ GetStats(const Database &db, const DatabaseSelection &selection,
|
||||
const auto f = std::bind(StatsVisitSong,
|
||||
std::ref(stats), std::ref(artists),
|
||||
std::ref(albums), _1);
|
||||
if (!db.Visit(selection, f, error_r))
|
||||
if (!db.Visit(selection, f, error))
|
||||
return false;
|
||||
|
||||
stats.artist_count = artists.size();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "TagType.h"
|
||||
#include "gcc.h"
|
||||
|
||||
class Error;
|
||||
class Database;
|
||||
struct DatabaseSelection;
|
||||
struct DatabaseStats;
|
||||
@ -32,10 +33,10 @@ bool
|
||||
VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
|
||||
enum tag_type tag_type,
|
||||
VisitString visit_string,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
bool
|
||||
GetStats(const Database &db, const DatabaseSelection &selection,
|
||||
DatabaseStats &stats, GError **error_r);
|
||||
DatabaseStats &stats, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -28,17 +28,17 @@
|
||||
|
||||
static bool
|
||||
AddSong(const char *playlist_path_utf8,
|
||||
Song &song, GError **error_r)
|
||||
Song &song, Error &error)
|
||||
{
|
||||
return spl_append_song(playlist_path_utf8, &song, error_r);
|
||||
return spl_append_song(playlist_path_utf8, &song, error);
|
||||
}
|
||||
|
||||
bool
|
||||
search_add_to_playlist(const char *uri, const char *playlist_path_utf8,
|
||||
const SongFilter *filter,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = GetDatabase(error_r);
|
||||
const Database *db = GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@ -46,5 +46,5 @@ search_add_to_playlist(const char *uri, const char *playlist_path_utf8,
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(AddSong, playlist_path_utf8, _1, _2);
|
||||
return db->Visit(selection, f, error_r);
|
||||
return db->Visit(selection, f, error);
|
||||
}
|
||||
|
@ -21,14 +21,14 @@
|
||||
#define MPD_DATABASE_PLAYLIST_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
#include "gerror.h"
|
||||
|
||||
class SongFilter;
|
||||
class Error;
|
||||
|
||||
gcc_nonnull(1,2)
|
||||
bool
|
||||
search_add_to_playlist(const char *uri, const char *path_utf8,
|
||||
const SongFilter *filter,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -34,6 +34,7 @@ struct config_param;
|
||||
struct DatabaseSelection;
|
||||
struct db_visitor;
|
||||
struct Song;
|
||||
class Error;
|
||||
|
||||
struct DatabaseStats {
|
||||
/**
|
||||
@ -73,7 +74,7 @@ public:
|
||||
/**
|
||||
* Open the database. Read it into memory if applicable.
|
||||
*/
|
||||
virtual bool Open(gcc_unused GError **error_r) {
|
||||
virtual bool Open(gcc_unused Error &error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -90,7 +91,7 @@ public:
|
||||
* directory (UTF-8)
|
||||
*/
|
||||
virtual Song *GetSong(const char *uri_utf8,
|
||||
GError **error_r) const = 0;
|
||||
Error &error) const = 0;
|
||||
|
||||
/**
|
||||
* Mark the song object as "unused". Call this on objects
|
||||
@ -105,19 +106,19 @@ public:
|
||||
VisitDirectory visit_directory,
|
||||
VisitSong visit_song,
|
||||
VisitPlaylist visit_playlist,
|
||||
GError **error_r) const = 0;
|
||||
Error &error) const = 0;
|
||||
|
||||
bool Visit(const DatabaseSelection &selection,
|
||||
VisitDirectory visit_directory,
|
||||
VisitSong visit_song,
|
||||
GError **error_r) const {
|
||||
Error &error) const {
|
||||
return Visit(selection, visit_directory, visit_song,
|
||||
VisitPlaylist(), error_r);
|
||||
VisitPlaylist(), error);
|
||||
}
|
||||
|
||||
bool Visit(const DatabaseSelection &selection, VisitSong visit_song,
|
||||
GError **error_r) const {
|
||||
return Visit(selection, VisitDirectory(), visit_song, error_r);
|
||||
Error &error) const {
|
||||
return Visit(selection, VisitDirectory(), visit_song, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,11 +127,11 @@ public:
|
||||
virtual bool VisitUniqueTags(const DatabaseSelection &selection,
|
||||
enum tag_type tag_type,
|
||||
VisitString visit_string,
|
||||
GError **error_r) const = 0;
|
||||
Error &error) const = 0;
|
||||
|
||||
virtual bool GetStats(const DatabaseSelection &selection,
|
||||
DatabaseStats &stats,
|
||||
GError **error_r) const = 0;
|
||||
Error &error) const = 0;
|
||||
};
|
||||
|
||||
struct DatabasePlugin {
|
||||
@ -140,7 +141,7 @@ struct DatabasePlugin {
|
||||
* Allocates and configures a database.
|
||||
*/
|
||||
Database *(*create)(const config_param ¶m,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -118,9 +118,9 @@ PrintPlaylistFull(Client *client,
|
||||
|
||||
bool
|
||||
db_selection_print(Client *client, const DatabaseSelection &selection,
|
||||
bool full, GError **error_r)
|
||||
bool full, Error &error)
|
||||
{
|
||||
const Database *db = GetDatabase(error_r);
|
||||
const Database *db = GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@ -136,7 +136,7 @@ db_selection_print(Client *client, const DatabaseSelection &selection,
|
||||
client, _1, _2)
|
||||
: VisitPlaylist();
|
||||
|
||||
return db->Visit(selection, d, s, p, error_r);
|
||||
return db->Visit(selection, d, s, p, error);
|
||||
}
|
||||
|
||||
struct SearchStats {
|
||||
@ -162,9 +162,9 @@ stats_visitor_song(SearchStats &stats, Song &song)
|
||||
bool
|
||||
searchStatsForSongsIn(Client *client, const char *name,
|
||||
const SongFilter *filter,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = GetDatabase(error_r);
|
||||
const Database *db = GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@ -177,7 +177,7 @@ searchStatsForSongsIn(Client *client, const char *name,
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(stats_visitor_song, std::ref(stats),
|
||||
_1);
|
||||
if (!db->Visit(selection, f, error_r))
|
||||
if (!db->Visit(selection, f, error))
|
||||
return false;
|
||||
|
||||
printSearchStats(client, &stats);
|
||||
@ -185,18 +185,18 @@ searchStatsForSongsIn(Client *client, const char *name,
|
||||
}
|
||||
|
||||
bool
|
||||
printAllIn(Client *client, const char *uri_utf8, GError **error_r)
|
||||
printAllIn(Client *client, const char *uri_utf8, Error &error)
|
||||
{
|
||||
const DatabaseSelection selection(uri_utf8, true);
|
||||
return db_selection_print(client, selection, false, error_r);
|
||||
return db_selection_print(client, selection, false, error);
|
||||
}
|
||||
|
||||
bool
|
||||
printInfoForAllIn(Client *client, const char *uri_utf8,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
const DatabaseSelection selection(uri_utf8, true);
|
||||
return db_selection_print(client, selection, true, error_r);
|
||||
return db_selection_print(client, selection, true, error);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -218,9 +218,9 @@ PrintUniqueTag(Client *client, enum tag_type tag_type,
|
||||
bool
|
||||
listAllUniqueTags(Client *client, int type,
|
||||
const SongFilter *filter,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = GetDatabase(error_r);
|
||||
const Database *db = GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@ -229,12 +229,12 @@ listAllUniqueTags(Client *client, int type,
|
||||
if (type == LOCATE_TAG_FILE_TYPE) {
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(PrintSongURIVisitor, client, _1);
|
||||
return db->Visit(selection, f, error_r);
|
||||
return db->Visit(selection, f, error);
|
||||
} else {
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(PrintUniqueTag, client,
|
||||
(enum tag_type)type, _1);
|
||||
return db->VisitUniqueTags(selection, (enum tag_type)type,
|
||||
f, error_r);
|
||||
f, error);
|
||||
}
|
||||
}
|
||||
|
@ -21,37 +21,37 @@
|
||||
#define MPD_DB_PRINT_H
|
||||
|
||||
#include "gcc.h"
|
||||
#include "gerror.h"
|
||||
|
||||
class SongFilter;
|
||||
struct DatabaseSelection;
|
||||
struct db_visitor;
|
||||
class Client;
|
||||
class Error;
|
||||
|
||||
gcc_nonnull(1)
|
||||
bool
|
||||
db_selection_print(Client *client, const DatabaseSelection &selection,
|
||||
bool full, GError **error_r);
|
||||
bool full, Error &error);
|
||||
|
||||
gcc_nonnull(1,2)
|
||||
bool
|
||||
printAllIn(Client *client, const char *uri_utf8, GError **error_r);
|
||||
printAllIn(Client *client, const char *uri_utf8, Error &error);
|
||||
|
||||
gcc_nonnull(1,2)
|
||||
bool
|
||||
printInfoForAllIn(Client *client, const char *uri_utf8,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
gcc_nonnull(1,2)
|
||||
bool
|
||||
searchStatsForSongsIn(Client *client, const char *name,
|
||||
const SongFilter *filter,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
gcc_nonnull(1)
|
||||
bool
|
||||
listAllUniqueTags(Client *client, int type,
|
||||
const SongFilter *filter,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -23,17 +23,17 @@
|
||||
#include "DatabaseGlue.hxx"
|
||||
#include "DatabasePlugin.hxx"
|
||||
#include "Partition.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <functional>
|
||||
|
||||
static bool
|
||||
AddToQueue(Partition &partition, Song &song, GError **error_r)
|
||||
AddToQueue(Partition &partition, Song &song, Error &error)
|
||||
{
|
||||
enum playlist_result result =
|
||||
partition.playlist.AppendSong(partition.pc, &song, NULL);
|
||||
if (result != PLAYLIST_RESULT_SUCCESS) {
|
||||
g_set_error(error_r, playlist_quark(), result,
|
||||
"Playlist error");
|
||||
error.Set(playlist_domain, result, "Playlist error");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -42,13 +42,13 @@ AddToQueue(Partition &partition, Song &song, GError **error_r)
|
||||
|
||||
bool
|
||||
AddFromDatabase(Partition &partition, const DatabaseSelection &selection,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = GetDatabase(error_r);
|
||||
const Database *db = GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(AddToQueue, std::ref(partition), _1, _2);
|
||||
return db->Visit(selection, f, error_r);
|
||||
return db->Visit(selection, f, error);
|
||||
}
|
||||
|
@ -20,13 +20,12 @@
|
||||
#ifndef MPD_DATABASE_QUEUE_HXX
|
||||
#define MPD_DATABASE_QUEUE_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
struct Partition;
|
||||
struct DatabaseSelection;
|
||||
class Error;
|
||||
|
||||
bool
|
||||
AddFromDatabase(Partition &partition, const DatabaseSelection &selection,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "TagInternal.hxx"
|
||||
#include "Tag.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -69,7 +70,7 @@ db_save_internal(FILE *fp, const Directory *music_root)
|
||||
}
|
||||
|
||||
bool
|
||||
db_load_internal(TextFile &file, Directory *music_root, GError **error)
|
||||
db_load_internal(TextFile &file, Directory *music_root, Error &error)
|
||||
{
|
||||
char *line;
|
||||
int format = 0;
|
||||
@ -82,7 +83,7 @@ db_load_internal(TextFile &file, Directory *music_root, GError **error)
|
||||
/* get initial info */
|
||||
line = file.ReadLine();
|
||||
if (line == NULL || strcmp(DIRECTORY_INFO_BEGIN, line) != 0) {
|
||||
g_set_error(error, db_quark(), 0, "Database corrupted");
|
||||
error.Set(db_domain, "Database corrupted");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -94,8 +95,7 @@ db_load_internal(TextFile &file, Directory *music_root, GError **error)
|
||||
format = atoi(line + sizeof(DB_FORMAT_PREFIX) - 1);
|
||||
} else if (g_str_has_prefix(line, DIRECTORY_MPD_VERSION)) {
|
||||
if (found_version) {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Duplicate version line");
|
||||
error.Set(db_domain, "Duplicate version line");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -104,8 +104,7 @@ db_load_internal(TextFile &file, Directory *music_root, GError **error)
|
||||
const char *new_charset;
|
||||
|
||||
if (found_charset) {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Duplicate charset line");
|
||||
error.Set(db_domain, "Duplicate charset line");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -115,44 +114,43 @@ db_load_internal(TextFile &file, Directory *music_root, GError **error)
|
||||
const std::string &old_charset = Path::GetFSCharset();
|
||||
if (!old_charset.empty()
|
||||
&& strcmp(new_charset, old_charset.c_str())) {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Existing database has charset "
|
||||
"\"%s\" instead of \"%s\"; "
|
||||
"discarding database file",
|
||||
new_charset, old_charset.c_str());
|
||||
error.Format(db_domain,
|
||||
"Existing database has charset "
|
||||
"\"%s\" instead of \"%s\"; "
|
||||
"discarding database file",
|
||||
new_charset, old_charset.c_str());
|
||||
return false;
|
||||
}
|
||||
} else if (g_str_has_prefix(line, DB_TAG_PREFIX)) {
|
||||
const char *name = line + sizeof(DB_TAG_PREFIX) - 1;
|
||||
enum tag_type tag = tag_name_parse(name);
|
||||
if (tag == TAG_NUM_OF_ITEM_TYPES) {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Unrecognized tag '%s', "
|
||||
"discarding database file",
|
||||
name);
|
||||
error.Format(db_domain,
|
||||
"Unrecognized tag '%s', "
|
||||
"discarding database file",
|
||||
name);
|
||||
return false;
|
||||
}
|
||||
|
||||
tags[tag] = true;
|
||||
} else {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Malformed line: %s", line);
|
||||
error.Format(db_domain, "Malformed line: %s", line);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (format != DB_FORMAT) {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Database format mismatch, "
|
||||
"discarding database file");
|
||||
error.Set(db_domain,
|
||||
"Database format mismatch, "
|
||||
"discarding database file");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) {
|
||||
if (!ignore_tag_items[i] && !tags[i]) {
|
||||
g_set_error(error, db_quark(), 0,
|
||||
"Tag list mismatch, "
|
||||
"discarding database file");
|
||||
error.Set(db_domain,
|
||||
"Tag list mismatch, "
|
||||
"discarding database file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -20,17 +20,16 @@
|
||||
#ifndef MPD_DATABASE_SAVE_HXX
|
||||
#define MPD_DATABASE_SAVE_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct Directory;
|
||||
class TextFile;
|
||||
class Error;
|
||||
|
||||
void
|
||||
db_save_internal(FILE *file, const Directory *root);
|
||||
|
||||
bool
|
||||
db_load_internal(TextFile &file, Directory *root, GError **error);
|
||||
db_load_internal(TextFile &file, Directory *root, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define MPD_DATABASE_SIMPLE_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
#include "gerror.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
@ -29,6 +28,7 @@ struct config_param;
|
||||
struct Directory;
|
||||
struct db_selection;
|
||||
struct db_visitor;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Check whether the default #SimpleDatabasePlugin is used. This
|
||||
@ -60,7 +60,7 @@ db_get_directory(const char *name);
|
||||
* May only be used if db_is_simple() returns true.
|
||||
*/
|
||||
bool
|
||||
db_save(GError **error_r);
|
||||
db_save(Error &error);
|
||||
|
||||
/**
|
||||
* May only be used if db_is_simple() returns true.
|
||||
|
@ -20,19 +20,18 @@
|
||||
#ifndef MPD_DATABASE_VISITOR_HXX
|
||||
#define MPD_DATABASE_VISITOR_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct Directory;
|
||||
struct Song;
|
||||
struct PlaylistInfo;
|
||||
class Error;
|
||||
|
||||
typedef std::function<bool(const Directory &, GError **)> VisitDirectory;
|
||||
typedef std::function<bool(struct Song &, GError **)> VisitSong;
|
||||
typedef std::function<bool(const Directory &, Error &)> VisitDirectory;
|
||||
typedef std::function<bool(struct Song &, Error &)> VisitSong;
|
||||
typedef std::function<bool(const PlaylistInfo &, const Directory &,
|
||||
GError **)> VisitPlaylist;
|
||||
Error &)> VisitPlaylist;
|
||||
|
||||
typedef std::function<bool(const char *, GError **)> VisitString;
|
||||
typedef std::function<bool(const char *, Error &)> VisitString;
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "DecoderInternal.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -257,8 +258,6 @@ size_t decoder_read(struct decoder *decoder,
|
||||
void *buffer, size_t length)
|
||||
{
|
||||
/* XXX don't allow decoder==NULL */
|
||||
GError *error = NULL;
|
||||
size_t nbytes;
|
||||
|
||||
assert(decoder == NULL ||
|
||||
decoder->dc->state == DECODE_STATE_START ||
|
||||
@ -283,14 +282,13 @@ size_t decoder_read(struct decoder *decoder,
|
||||
is->cond.wait(is->mutex);
|
||||
}
|
||||
|
||||
nbytes = input_stream_read(is, buffer, length, &error);
|
||||
assert(nbytes == 0 || error == NULL);
|
||||
assert(nbytes > 0 || error != NULL || input_stream_eof(is));
|
||||
Error error;
|
||||
size_t nbytes = input_stream_read(is, buffer, length, error);
|
||||
assert(nbytes == 0 || !error.IsDefined());
|
||||
assert(nbytes > 0 || error.IsDefined() || input_stream_eof(is));
|
||||
|
||||
if (gcc_unlikely(nbytes == 0 && error != nullptr)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
if (gcc_unlikely(nbytes == 0 && error.IsDefined()))
|
||||
g_warning("%s", error.GetMessage());
|
||||
|
||||
input_stream_unlock(is);
|
||||
|
||||
@ -364,7 +362,6 @@ decoder_data(struct decoder *decoder,
|
||||
uint16_t kbit_rate)
|
||||
{
|
||||
struct decoder_control *dc = decoder->dc;
|
||||
GError *error = NULL;
|
||||
enum decoder_command cmd;
|
||||
|
||||
assert(dc->state == DECODE_STATE_DECODE);
|
||||
@ -397,16 +394,17 @@ decoder_data(struct decoder *decoder,
|
||||
}
|
||||
|
||||
if (dc->in_audio_format != dc->out_audio_format) {
|
||||
Error error;
|
||||
data = decoder->conv_state.Convert(dc->in_audio_format,
|
||||
data, length,
|
||||
dc->out_audio_format,
|
||||
&length,
|
||||
&error);
|
||||
error);
|
||||
if (data == NULL) {
|
||||
/* the PCM conversion has failed - stop
|
||||
playback, since we have no better way to
|
||||
bail out */
|
||||
g_warning("%s", error->message);
|
||||
g_warning("%s", error.GetMessage());
|
||||
return DECODE_COMMAND_STOP;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "AudioFormat.hxx"
|
||||
#include "thread/Mutex.hxx"
|
||||
#include "thread/Cond.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -77,7 +78,7 @@ struct decoder_control {
|
||||
* The object must be freed when this object transitions to
|
||||
* any other state (usually #DECODE_STATE_START).
|
||||
*/
|
||||
GError *error;
|
||||
Error error;
|
||||
|
||||
bool quit;
|
||||
bool seek_error;
|
||||
@ -218,38 +219,41 @@ struct decoder_control {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an error has occurred, and if so, returns a newly
|
||||
* allocated copy of the #GError object.
|
||||
* Checks whether an error has occurred, and if so, returns a
|
||||
* copy of the #Error object.
|
||||
*
|
||||
* Caller must lock the object.
|
||||
*/
|
||||
GError *GetError() const {
|
||||
gcc_pure
|
||||
Error GetError() const {
|
||||
assert(command == DECODE_COMMAND_NONE);
|
||||
assert(state != DECODE_STATE_ERROR || error != nullptr);
|
||||
assert(state != DECODE_STATE_ERROR || error.IsDefined());
|
||||
|
||||
return state == DECODE_STATE_ERROR
|
||||
? g_error_copy(error)
|
||||
: nullptr;
|
||||
Error result;
|
||||
if (state == DECODE_STATE_ERROR)
|
||||
result.Set(error);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like dc_get_error(), but locks and unlocks the object.
|
||||
*/
|
||||
GError *LockGetError() const {
|
||||
gcc_pure
|
||||
Error LockGetError() const {
|
||||
Lock();
|
||||
GError *result = GetError();
|
||||
Error result = GetError();
|
||||
Unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the error condition and free the #GError object (if any).
|
||||
* Clear the error condition and free the #Error object (if any).
|
||||
*
|
||||
* Caller must lock the object.
|
||||
*/
|
||||
void ClearError() {
|
||||
if (state == DECODE_STATE_ERROR) {
|
||||
g_error_free(error);
|
||||
error.Clear();
|
||||
state = DECODE_STATE_STOP;
|
||||
}
|
||||
}
|
||||
|
23
src/DecoderError.cxx
Normal file
23
src/DecoderError.cxx
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "DecoderError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
const Domain decoder_domain("decoder");
|
@ -20,18 +20,6 @@
|
||||
#ifndef MPD_DECODER_ERROR_HXX
|
||||
#define MPD_DECODER_ERROR_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* Quark for GError.domain.
|
||||
*/
|
||||
gcc_pure
|
||||
static inline GQuark
|
||||
decoder_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("decoder");
|
||||
}
|
||||
extern const class Domain decoder_domain;
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "InputStream.hxx"
|
||||
#include "DecoderList.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "ApeReplayGain.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
@ -72,15 +73,12 @@ decoder_command_finished_locked(struct decoder_control *dc)
|
||||
static struct input_stream *
|
||||
decoder_input_stream_open(struct decoder_control *dc, const char *uri)
|
||||
{
|
||||
GError *error = NULL;
|
||||
struct input_stream *is;
|
||||
Error error;
|
||||
|
||||
is = input_stream_open(uri, dc->mutex, dc->cond, &error);
|
||||
input_stream *is = input_stream_open(uri, dc->mutex, dc->cond, error);
|
||||
if (is == NULL) {
|
||||
if (error != NULL) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
if (error.IsDefined())
|
||||
g_warning("%s", error.GetMessage());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -98,12 +96,10 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
|
||||
input_stream_update(is);
|
||||
}
|
||||
|
||||
if (!input_stream_check(is, &error)) {
|
||||
if (!input_stream_check(is, error)) {
|
||||
dc->Unlock();
|
||||
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
||||
g_warning("%s", error.GetMessage());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -132,7 +128,10 @@ decoder_stream_decode(const struct decoder_plugin *plugin,
|
||||
return true;
|
||||
|
||||
/* rewind the stream, so each plugin gets a fresh start */
|
||||
input_stream_seek(input_stream, 0, SEEK_SET, NULL);
|
||||
{
|
||||
Error error;
|
||||
input_stream_seek(input_stream, 0, SEEK_SET, error);
|
||||
}
|
||||
|
||||
decoder->dc->Unlock();
|
||||
|
||||
@ -411,8 +410,8 @@ decoder_run_song(struct decoder_control *dc,
|
||||
if (allocated != NULL)
|
||||
error_uri = allocated;
|
||||
|
||||
dc->error = g_error_new(decoder_quark(), 0,
|
||||
"Failed to decode %s", error_uri);
|
||||
dc->error.Format(decoder_domain,
|
||||
"Failed to decode %s", error_uri);
|
||||
g_free(allocated);
|
||||
}
|
||||
|
||||
@ -436,8 +435,7 @@ decoder_run(struct decoder_control *dc)
|
||||
|
||||
if (uri == NULL) {
|
||||
dc->state = DECODE_STATE_ERROR;
|
||||
dc->error = g_error_new(decoder_quark(), 0,
|
||||
"Failed to map song");
|
||||
dc->error.Set(decoder_domain, "Failed to map song");
|
||||
|
||||
decoder_command_finished_locked(dc);
|
||||
return;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "DatabaseLock.hxx"
|
||||
#include "SongSort.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "util/list_sort.h"
|
||||
@ -300,34 +301,34 @@ bool
|
||||
Directory::Walk(bool recursive, const SongFilter *filter,
|
||||
VisitDirectory visit_directory, VisitSong visit_song,
|
||||
VisitPlaylist visit_playlist,
|
||||
GError **error_r) const
|
||||
Error &error) const
|
||||
{
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
assert(!error.IsDefined());
|
||||
|
||||
if (visit_song) {
|
||||
Song *song;
|
||||
directory_for_each_song(song, this)
|
||||
if ((filter == nullptr || filter->Match(*song)) &&
|
||||
!visit_song(*song, error_r))
|
||||
!visit_song(*song, error))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (visit_playlist) {
|
||||
for (const PlaylistInfo &p : playlists)
|
||||
if (!visit_playlist(p, *this, error_r))
|
||||
if (!visit_playlist(p, *this, error))
|
||||
return false;
|
||||
}
|
||||
|
||||
Directory *child;
|
||||
directory_for_each_child(child, this) {
|
||||
if (visit_directory &&
|
||||
!visit_directory(*child, error_r))
|
||||
!visit_directory(*child, error))
|
||||
return false;
|
||||
|
||||
if (recursive &&
|
||||
!child->Walk(recursive, filter,
|
||||
visit_directory, visit_song, visit_playlist,
|
||||
error_r))
|
||||
error))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "gcc.h"
|
||||
#include "DatabaseVisitor.hxx"
|
||||
#include "PlaylistVector.hxx"
|
||||
#include "gerror.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -47,6 +46,7 @@
|
||||
struct Song;
|
||||
struct db_visitor;
|
||||
class SongFilter;
|
||||
class Error;
|
||||
|
||||
struct Directory {
|
||||
/**
|
||||
@ -251,7 +251,7 @@ public:
|
||||
bool Walk(bool recursive, const SongFilter *match,
|
||||
VisitDirectory visit_directory, VisitSong visit_song,
|
||||
VisitPlaylist visit_playlist,
|
||||
GError **error_r) const;
|
||||
Error &error) const;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "SongSave.hxx"
|
||||
#include "PlaylistDatabase.hxx"
|
||||
#include "TextFile.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
@ -33,14 +35,7 @@
|
||||
#define DIRECTORY_BEGIN "begin: "
|
||||
#define DIRECTORY_END "end: "
|
||||
|
||||
/**
|
||||
* The quark used for GError.domain.
|
||||
*/
|
||||
static inline GQuark
|
||||
directory_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("directory");
|
||||
}
|
||||
static constexpr Domain directory_domain("directory");
|
||||
|
||||
void
|
||||
directory_save(FILE *fp, const Directory *directory)
|
||||
@ -77,13 +72,13 @@ directory_save(FILE *fp, const Directory *directory)
|
||||
|
||||
static Directory *
|
||||
directory_load_subdir(TextFile &file, Directory *parent, const char *name,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
bool success;
|
||||
|
||||
if (parent->FindChild(name) != nullptr) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Duplicate subdirectory '%s'", name);
|
||||
error.Format(directory_domain,
|
||||
"Duplicate subdirectory '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -91,8 +86,7 @@ directory_load_subdir(TextFile &file, Directory *parent, const char *name,
|
||||
|
||||
const char *line = file.ReadLine();
|
||||
if (line == NULL) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Unexpected end of file");
|
||||
error.Set(directory_domain, "Unexpected end of file");
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
}
|
||||
@ -104,21 +98,19 @@ directory_load_subdir(TextFile &file, Directory *parent, const char *name,
|
||||
|
||||
line = file.ReadLine();
|
||||
if (line == NULL) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Unexpected end of file");
|
||||
error.Set(directory_domain, "Unexpected end of file");
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Malformed line: %s", line);
|
||||
error.Format(directory_domain, "Malformed line: %s", line);
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
success = directory_load(file, directory, error_r);
|
||||
success = directory_load(file, directory, error);
|
||||
if (!success) {
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
@ -128,7 +120,7 @@ directory_load_subdir(TextFile &file, Directory *parent, const char *name,
|
||||
}
|
||||
|
||||
bool
|
||||
directory_load(TextFile &file, Directory *directory, GError **error)
|
||||
directory_load(TextFile &file, Directory *directory, Error &error)
|
||||
{
|
||||
const char *line;
|
||||
|
||||
@ -146,8 +138,8 @@ directory_load(TextFile &file, Directory *directory, GError **error)
|
||||
Song *song;
|
||||
|
||||
if (directory->FindSong(name) != nullptr) {
|
||||
g_set_error(error, directory_quark(), 0,
|
||||
"Duplicate song '%s'", name);
|
||||
error.Format(directory_domain,
|
||||
"Duplicate song '%s'", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -170,8 +162,8 @@ directory_load(TextFile &file, Directory *directory, GError **error)
|
||||
|
||||
g_free(name);
|
||||
} else {
|
||||
g_set_error(error, directory_quark(), 0,
|
||||
"Malformed line: %s", line);
|
||||
error.Format(directory_domain,
|
||||
"Malformed line: %s", line);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -20,17 +20,16 @@
|
||||
#ifndef MPD_DIRECTORY_SAVE_HXX
|
||||
#define MPD_DIRECTORY_SAVE_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct Directory;
|
||||
class TextFile;
|
||||
class Error;
|
||||
|
||||
void
|
||||
directory_save(FILE *fp, const Directory *directory);
|
||||
|
||||
bool
|
||||
directory_load(TextFile &file, Directory *directory, GError **error);
|
||||
directory_load(TextFile &file, Directory *directory, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -20,8 +20,6 @@
|
||||
#ifndef MPD_ENCODER_PLUGIN_HXX
|
||||
#define MPD_ENCODER_PLUGIN_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@ -30,6 +28,7 @@ struct EncoderPlugin;
|
||||
struct AudioFormat;
|
||||
struct config_param;
|
||||
struct Tag;
|
||||
class Error;
|
||||
|
||||
struct Encoder {
|
||||
const EncoderPlugin &plugin;
|
||||
@ -50,28 +49,28 @@ struct EncoderPlugin {
|
||||
const char *name;
|
||||
|
||||
Encoder *(*init)(const config_param ¶m,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
void (*finish)(Encoder *encoder);
|
||||
|
||||
bool (*open)(Encoder *encoder,
|
||||
AudioFormat &audio_format,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
void (*close)(Encoder *encoder);
|
||||
|
||||
bool (*end)(Encoder *encoder, GError **error);
|
||||
bool (*end)(Encoder *encoder, Error &error);
|
||||
|
||||
bool (*flush)(Encoder *encoder, GError **error);
|
||||
bool (*flush)(Encoder *encoder, Error &error);
|
||||
|
||||
bool (*pre_tag)(Encoder *encoder, GError **error);
|
||||
bool (*pre_tag)(Encoder *encoder, Error &error);
|
||||
|
||||
bool (*tag)(Encoder *encoder, const Tag *tag,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
bool (*write)(Encoder *encoder,
|
||||
const void *data, size_t length,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
size_t (*read)(Encoder *encoder, void *dest, size_t length);
|
||||
|
||||
@ -88,7 +87,7 @@ struct EncoderPlugin {
|
||||
*/
|
||||
static inline Encoder *
|
||||
encoder_init(const EncoderPlugin &plugin, const config_param ¶m,
|
||||
GError **error_r)
|
||||
Error &error_r)
|
||||
{
|
||||
return plugin.init(param, error_r);
|
||||
}
|
||||
@ -123,7 +122,7 @@ encoder_finish(Encoder *encoder)
|
||||
*/
|
||||
static inline bool
|
||||
encoder_open(Encoder *encoder, AudioFormat &audio_format,
|
||||
GError **error)
|
||||
Error &error)
|
||||
{
|
||||
assert(!encoder->open);
|
||||
|
||||
@ -168,7 +167,7 @@ encoder_close(Encoder *encoder)
|
||||
* @return true on success
|
||||
*/
|
||||
static inline bool
|
||||
encoder_end(Encoder *encoder, GError **error)
|
||||
encoder_end(Encoder *encoder, Error &error)
|
||||
{
|
||||
assert(encoder->open);
|
||||
assert(!encoder->end);
|
||||
@ -192,7 +191,7 @@ encoder_end(Encoder *encoder, GError **error)
|
||||
* @return true on success
|
||||
*/
|
||||
static inline bool
|
||||
encoder_flush(Encoder *encoder, GError **error)
|
||||
encoder_flush(Encoder *encoder, Error &error)
|
||||
{
|
||||
assert(encoder->open);
|
||||
assert(!encoder->pre_tag);
|
||||
@ -216,7 +215,7 @@ encoder_flush(Encoder *encoder, GError **error)
|
||||
* @return true on success
|
||||
*/
|
||||
static inline bool
|
||||
encoder_pre_tag(Encoder *encoder, GError **error)
|
||||
encoder_pre_tag(Encoder *encoder, Error &error)
|
||||
{
|
||||
assert(encoder->open);
|
||||
assert(!encoder->pre_tag);
|
||||
@ -246,7 +245,7 @@ encoder_pre_tag(Encoder *encoder, GError **error)
|
||||
* @return true on success
|
||||
*/
|
||||
static inline bool
|
||||
encoder_tag(Encoder *encoder, const Tag *tag, GError **error)
|
||||
encoder_tag(Encoder *encoder, const Tag *tag, Error &error)
|
||||
{
|
||||
assert(encoder->open);
|
||||
assert(!encoder->pre_tag);
|
||||
@ -274,7 +273,7 @@ encoder_tag(Encoder *encoder, const Tag *tag, GError **error)
|
||||
*/
|
||||
static inline bool
|
||||
encoder_write(Encoder *encoder, const void *data, size_t length,
|
||||
GError **error)
|
||||
Error &error)
|
||||
{
|
||||
assert(encoder->open);
|
||||
assert(!encoder->pre_tag);
|
||||
|
@ -24,35 +24,31 @@
|
||||
#include "FilterPlugin.hxx"
|
||||
#include "FilterInternal.hxx"
|
||||
#include "FilterRegistry.hxx"
|
||||
#include "ConfigError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static GQuark
|
||||
filter_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("filter");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the "filter" configuration block for the specified name.
|
||||
*
|
||||
* @param filter_template_name the name of the filter template
|
||||
* @param error_r space to return an error description
|
||||
* @param error space to return an error description
|
||||
* @return the configuration block, or NULL if none was configured
|
||||
*/
|
||||
static const struct config_param *
|
||||
filter_plugin_config(const char *filter_template_name, GError **error_r)
|
||||
filter_plugin_config(const char *filter_template_name, Error &error)
|
||||
{
|
||||
const struct config_param *param = NULL;
|
||||
|
||||
while ((param = config_get_next_param(CONF_AUDIO_FILTER, param)) != NULL) {
|
||||
const char *name = param->GetBlockValue("name");
|
||||
if (name == NULL) {
|
||||
g_set_error(error_r, filter_quark(), 1,
|
||||
"filter configuration without 'name' name in line %d",
|
||||
param->line);
|
||||
error.Format(config_domain,
|
||||
"filter configuration without 'name' name in line %d",
|
||||
param->line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -60,10 +56,9 @@ filter_plugin_config(const char *filter_template_name, GError **error_r)
|
||||
return param;
|
||||
}
|
||||
|
||||
g_set_error(error_r, filter_quark(), 1,
|
||||
"filter template not found: %s",
|
||||
filter_template_name);
|
||||
|
||||
error.Format(config_domain,
|
||||
"filter template not found: %s",
|
||||
filter_template_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -73,11 +68,11 @@ filter_plugin_config(const char *filter_template_name, GError **error_r)
|
||||
* configured filter sections.
|
||||
* @param chain the chain to append filters on
|
||||
* @param spec the filter chain specification
|
||||
* @param error_r space to return an error description
|
||||
* @param error space to return an error description
|
||||
* @return the number of filters which were successfully added
|
||||
*/
|
||||
unsigned int
|
||||
filter_chain_parse(Filter &chain, const char *spec, GError **error_r)
|
||||
filter_chain_parse(Filter &chain, const char *spec, Error &error)
|
||||
{
|
||||
|
||||
// Split on comma
|
||||
@ -92,14 +87,14 @@ filter_chain_parse(Filter &chain, const char *spec, GError **error_r)
|
||||
g_strstrip(*template_names);
|
||||
|
||||
const struct config_param *cfg =
|
||||
filter_plugin_config(*template_names, error_r);
|
||||
filter_plugin_config(*template_names, error);
|
||||
if (cfg == NULL) {
|
||||
// The error has already been set, just stop.
|
||||
break;
|
||||
}
|
||||
|
||||
// Instantiate one of those filter plugins with the template name as a hint
|
||||
Filter *f = filter_configured_new(*cfg, error_r);
|
||||
Filter *f = filter_configured_new(*cfg, error);
|
||||
if (f == NULL) {
|
||||
// The error has already been set, just stop.
|
||||
break;
|
||||
|
@ -25,9 +25,8 @@
|
||||
#ifndef MPD_FILTER_CONFIG_HXX
|
||||
#define MPD_FILTER_CONFIG_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
class Filter;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Builds a filter chain from a configuration string on the form
|
||||
@ -39,6 +38,6 @@ class Filter;
|
||||
* @return the number of filters which were successfully added
|
||||
*/
|
||||
unsigned int
|
||||
filter_chain_parse(Filter &chain, const char *spec, GError **error_r);
|
||||
filter_chain_parse(Filter &chain, const char *spec, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -25,7 +25,10 @@
|
||||
#ifndef MPD_FILTER_INTERNAL_HXX
|
||||
#define MPD_FILTER_INTERNAL_HXX
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct AudioFormat;
|
||||
class Error;
|
||||
|
||||
class Filter {
|
||||
public:
|
||||
@ -43,7 +46,7 @@ public:
|
||||
* @return the format of outgoing data or
|
||||
* AudioFormat::Undefined() on error
|
||||
*/
|
||||
virtual AudioFormat Open(AudioFormat &af, GError **error_r) = 0;
|
||||
virtual AudioFormat Open(AudioFormat &af, Error &error) = 0;
|
||||
|
||||
/**
|
||||
* Closes the filter. After that, you may call Open() again.
|
||||
@ -65,7 +68,7 @@ public:
|
||||
*/
|
||||
virtual const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r,
|
||||
GError **error_r) = 0;
|
||||
Error &error) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -22,40 +22,38 @@
|
||||
#include "FilterInternal.hxx"
|
||||
#include "FilterRegistry.hxx"
|
||||
#include "conf.h"
|
||||
#include "ConfigQuark.hxx"
|
||||
#include "ConfigError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
Filter *
|
||||
filter_new(const struct filter_plugin *plugin,
|
||||
const config_param ¶m, GError **error_r)
|
||||
const config_param ¶m, Error &error)
|
||||
{
|
||||
assert(plugin != NULL);
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
assert(!error.IsDefined());
|
||||
|
||||
return plugin->init(param, error_r);
|
||||
return plugin->init(param, error);
|
||||
}
|
||||
|
||||
Filter *
|
||||
filter_configured_new(const config_param ¶m, GError **error_r)
|
||||
filter_configured_new(const config_param ¶m, Error &error)
|
||||
{
|
||||
const struct filter_plugin *plugin;
|
||||
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
assert(!error.IsDefined());
|
||||
|
||||
const char *plugin_name = param.GetBlockValue("plugin");
|
||||
if (plugin_name == NULL) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"No filter plugin specified");
|
||||
error.Set(config_domain, "No filter plugin specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plugin = filter_plugin_by_name(plugin_name);
|
||||
const filter_plugin *plugin = filter_plugin_by_name(plugin_name);
|
||||
if (plugin == NULL) {
|
||||
g_set_error(error_r, config_quark(), 0,
|
||||
"No such filter plugin: %s", plugin_name);
|
||||
error.Format(config_domain,
|
||||
"No such filter plugin: %s", plugin_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return filter_new(plugin, param, error_r);
|
||||
return filter_new(plugin, param, error);
|
||||
}
|
||||
|
@ -26,12 +26,9 @@
|
||||
#ifndef MPD_FILTER_PLUGIN_HXX
|
||||
#define MPD_FILTER_PLUGIN_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct config_param;
|
||||
class Filter;
|
||||
class Error;
|
||||
|
||||
struct filter_plugin {
|
||||
const char *name;
|
||||
@ -39,7 +36,7 @@ struct filter_plugin {
|
||||
/**
|
||||
* Allocates and configures a filter.
|
||||
*/
|
||||
Filter *(*init)(const config_param ¶m, GError **error_r);
|
||||
Filter *(*init)(const config_param ¶m, Error &error);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -53,7 +50,7 @@ struct filter_plugin {
|
||||
*/
|
||||
Filter *
|
||||
filter_new(const struct filter_plugin *plugin,
|
||||
const config_param ¶m, GError **error_r);
|
||||
const config_param ¶m, Error &error);
|
||||
|
||||
/**
|
||||
* Creates a new filter, loads configuration and the plugin name from
|
||||
@ -65,6 +62,6 @@ filter_new(const struct filter_plugin *plugin,
|
||||
* @return a new filter object, or NULL on error
|
||||
*/
|
||||
Filter *
|
||||
filter_configured_new(const config_param ¶m, GError **error_r);
|
||||
filter_configured_new(const config_param ¶m, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "InotifySource.hxx"
|
||||
#include "util/fifo_buffer.h"
|
||||
#include "util/Error.hxx"
|
||||
#include "system/fd_util.h"
|
||||
#include "system/FatalError.hxx"
|
||||
|
||||
@ -32,15 +33,6 @@
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "inotify"
|
||||
|
||||
/**
|
||||
* A GQuark for GError instances.
|
||||
*/
|
||||
static inline GQuark
|
||||
mpd_inotify_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("inotify");
|
||||
}
|
||||
|
||||
bool
|
||||
InotifySource::OnSocketReady(gcc_unused unsigned flags)
|
||||
{
|
||||
@ -97,13 +89,11 @@ InotifySource::InotifySource(EventLoop &_loop,
|
||||
InotifySource *
|
||||
InotifySource::Create(EventLoop &loop,
|
||||
mpd_inotify_callback_t callback, void *callback_ctx,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
int fd = inotify_init_cloexec();
|
||||
if (fd < 0) {
|
||||
g_set_error(error_r, mpd_inotify_quark(), errno,
|
||||
"inotify_init() has failed: %s",
|
||||
g_strerror(errno));
|
||||
error.SetErrno("inotify_init() has failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -116,13 +106,11 @@ InotifySource::~InotifySource()
|
||||
}
|
||||
|
||||
int
|
||||
InotifySource::Add(const char *path_fs, unsigned mask, GError **error_r)
|
||||
InotifySource::Add(const char *path_fs, unsigned mask, Error &error)
|
||||
{
|
||||
int wd = inotify_add_watch(Get(), path_fs, mask);
|
||||
if (wd < 0)
|
||||
g_set_error(error_r, mpd_inotify_quark(), errno,
|
||||
"inotify_add_watch() has failed: %s",
|
||||
g_strerror(errno));
|
||||
error.SetErrno("inotify_add_watch() has failed");
|
||||
|
||||
return wd;
|
||||
}
|
||||
|
@ -21,9 +21,10 @@
|
||||
#define MPD_INOTIFY_SOURCE_HXX
|
||||
|
||||
#include "event/SocketMonitor.hxx"
|
||||
#include "gerror.h"
|
||||
#include "gcc.h"
|
||||
|
||||
class Error;
|
||||
|
||||
typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask,
|
||||
const char *name, void *ctx);
|
||||
|
||||
@ -46,7 +47,7 @@ public:
|
||||
static InotifySource *Create(EventLoop &_loop,
|
||||
mpd_inotify_callback_t callback,
|
||||
void *ctx,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
~InotifySource();
|
||||
|
||||
@ -56,7 +57,7 @@ public:
|
||||
*
|
||||
* @return a watch descriptor or -1 on error
|
||||
*/
|
||||
int Add(const char *path_fs, unsigned mask, GError **error_r);
|
||||
int Add(const char *path_fs, unsigned mask, Error &error);
|
||||
|
||||
/**
|
||||
* Removes a path from the notify list.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "Mapper.hxx"
|
||||
#include "Main.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -162,7 +163,7 @@ static void
|
||||
recursive_watch_subdirectories(WatchDirectory *directory,
|
||||
const char *path_fs, unsigned depth)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
|
||||
@ -204,12 +205,11 @@ recursive_watch_subdirectories(WatchDirectory *directory,
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = inotify_source->Add(child_path_fs, IN_MASK, &error);
|
||||
ret = inotify_source->Add(child_path_fs, IN_MASK, error);
|
||||
if (ret < 0) {
|
||||
g_warning("Failed to register %s: %s",
|
||||
child_path_fs, error->message);
|
||||
g_error_free(error);
|
||||
error = NULL;
|
||||
child_path_fs, error.GetMessage());
|
||||
error.Clear();
|
||||
g_free(child_path_fs);
|
||||
continue;
|
||||
}
|
||||
@ -309,8 +309,6 @@ mpd_inotify_callback(int wd, unsigned mask,
|
||||
void
|
||||
mpd_inotify_init(unsigned max_depth)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_debug("initializing inotify");
|
||||
|
||||
const Path &path = mapper_get_music_directory_fs();
|
||||
@ -319,21 +317,20 @@ mpd_inotify_init(unsigned max_depth)
|
||||
return;
|
||||
}
|
||||
|
||||
Error error;
|
||||
inotify_source = InotifySource::Create(*main_loop,
|
||||
mpd_inotify_callback, nullptr,
|
||||
&error);
|
||||
error);
|
||||
if (inotify_source == NULL) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
g_warning("%s", error.GetMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
inotify_max_depth = max_depth;
|
||||
|
||||
int descriptor = inotify_source->Add(path.c_str(), IN_MASK, &error);
|
||||
int descriptor = inotify_source->Add(path.c_str(), IN_MASK, error);
|
||||
if (descriptor < 0) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
g_warning("%s", error.GetMessage());
|
||||
delete inotify_source;
|
||||
inotify_source = NULL;
|
||||
return;
|
||||
|
@ -21,16 +21,14 @@
|
||||
#include "InputInit.hxx"
|
||||
#include "InputRegistry.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline GQuark
|
||||
input_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("input");
|
||||
}
|
||||
extern constexpr Domain input_domain("input");
|
||||
|
||||
/**
|
||||
* Find the "input" configuration block for the specified plugin.
|
||||
@ -39,16 +37,16 @@ input_quark(void)
|
||||
* @return the configuration block, or NULL if none was configured
|
||||
*/
|
||||
static const struct config_param *
|
||||
input_plugin_config(const char *plugin_name, GError **error_r)
|
||||
input_plugin_config(const char *plugin_name, Error &error)
|
||||
{
|
||||
const struct config_param *param = NULL;
|
||||
|
||||
while ((param = config_get_next_param(CONF_INPUT, param)) != NULL) {
|
||||
const char *name = param->GetBlockValue("plugin");
|
||||
if (name == NULL) {
|
||||
g_set_error(error_r, input_quark(), 0,
|
||||
"input configuration without 'plugin' name in line %d",
|
||||
param->line);
|
||||
error.Format(input_domain,
|
||||
"input configuration without 'plugin' name in line %d",
|
||||
param->line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -60,12 +58,10 @@ input_plugin_config(const char *plugin_name, GError **error_r)
|
||||
}
|
||||
|
||||
bool
|
||||
input_stream_global_init(GError **error_r)
|
||||
input_stream_global_init(Error &error)
|
||||
{
|
||||
const config_param empty;
|
||||
|
||||
GError *error = NULL;
|
||||
|
||||
for (unsigned i = 0; input_plugins[i] != NULL; ++i) {
|
||||
const struct input_plugin *plugin = input_plugins[i];
|
||||
|
||||
@ -74,24 +70,21 @@ input_stream_global_init(GError **error_r)
|
||||
assert(plugin->open != NULL);
|
||||
|
||||
const struct config_param *param =
|
||||
input_plugin_config(plugin->name, &error);
|
||||
input_plugin_config(plugin->name, error);
|
||||
if (param == nullptr) {
|
||||
if (error != nullptr) {
|
||||
g_propagate_error(error_r, error);
|
||||
if (error.IsDefined())
|
||||
return false;
|
||||
}
|
||||
|
||||
param = ∅
|
||||
} else if (!param->GetBlockValue("enabled", true))
|
||||
/* the plugin is disabled in mpd.conf */
|
||||
continue;
|
||||
|
||||
if (plugin->init == NULL || plugin->init(*param, &error))
|
||||
if (plugin->init == NULL || plugin->init(*param, error))
|
||||
input_plugins_enabled[i] = true;
|
||||
else {
|
||||
g_propagate_prefixed_error(error_r, error,
|
||||
"Failed to initialize input plugin '%s': ",
|
||||
plugin->name);
|
||||
error.FormatPrefix("Failed to initialize input plugin '%s': ",
|
||||
plugin->name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef MPD_INPUT_INIT_HXX
|
||||
#define MPD_INPUT_INIT_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Initializes this library and all input_stream implementations.
|
||||
@ -29,7 +29,7 @@
|
||||
* ignore errors
|
||||
*/
|
||||
bool
|
||||
input_stream_global_init(GError **error_r);
|
||||
input_stream_global_init(Error &error);
|
||||
|
||||
/**
|
||||
* Deinitializes this library and all input_stream implementations.
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
struct Tag;
|
||||
struct input_stream;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Opens a new input stream. You may not access it until the "ready"
|
||||
@ -48,7 +49,7 @@ gcc_malloc
|
||||
struct input_stream *
|
||||
input_stream_open(const char *uri,
|
||||
Mutex &mutex, Cond &cond,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Close the input stream and free resources.
|
||||
@ -66,7 +67,7 @@ input_stream_close(struct input_stream *is);
|
||||
*/
|
||||
gcc_nonnull(1)
|
||||
bool
|
||||
input_stream_check(struct input_stream *is, GError **error_r);
|
||||
input_stream_check(struct input_stream *is, Error &error);
|
||||
|
||||
/**
|
||||
* Update the public attributes. Call before accessing attributes
|
||||
@ -133,7 +134,7 @@ input_stream_cheap_seeking(const struct input_stream *is);
|
||||
gcc_nonnull(1)
|
||||
bool
|
||||
input_stream_seek(struct input_stream *is, goffset offset, int whence,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Wrapper for input_stream_seek() which locks and unlocks the
|
||||
@ -142,7 +143,7 @@ input_stream_seek(struct input_stream *is, goffset offset, int whence,
|
||||
gcc_nonnull(1)
|
||||
bool
|
||||
input_stream_lock_seek(struct input_stream *is, goffset offset, int whence,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Returns true if the stream has reached end-of-file.
|
||||
@ -210,7 +211,7 @@ input_stream_available(struct input_stream *is);
|
||||
gcc_nonnull(1, 2)
|
||||
size_t
|
||||
input_stream_read(struct input_stream *is, void *ptr, size_t size,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Wrapper for input_stream_tag() which locks and unlocks the
|
||||
@ -219,6 +220,6 @@ input_stream_read(struct input_stream *is, void *ptr, size_t size,
|
||||
gcc_nonnull(1, 2)
|
||||
size_t
|
||||
input_stream_lock_read(struct input_stream *is, void *ptr, size_t size,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -23,10 +23,10 @@
|
||||
#include "InputLegacy.hxx"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct config_param;
|
||||
struct input_stream;
|
||||
class Error;
|
||||
|
||||
struct input_plugin {
|
||||
const char *name;
|
||||
@ -39,7 +39,7 @@ struct input_plugin {
|
||||
* @return true on success, false if the plugin should be
|
||||
* disabled
|
||||
*/
|
||||
bool (*init)(const config_param ¶m, GError **error_r);
|
||||
bool (*init)(const config_param ¶m, Error &error);
|
||||
|
||||
/**
|
||||
* Global deinitialization. Called once before MPD shuts
|
||||
@ -49,7 +49,7 @@ struct input_plugin {
|
||||
|
||||
struct input_stream *(*open)(const char *uri,
|
||||
Mutex &mutex, Cond &cond,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
void (*close)(struct input_stream *is);
|
||||
|
||||
/**
|
||||
@ -58,7 +58,7 @@ struct input_plugin {
|
||||
*
|
||||
* @return false on error
|
||||
*/
|
||||
bool (*check)(struct input_stream *is, GError **error_r);
|
||||
bool (*check)(struct input_stream *is, Error &error);
|
||||
|
||||
/**
|
||||
* Update the public attributes. Call before access. Can be
|
||||
@ -79,10 +79,10 @@ struct input_plugin {
|
||||
bool (*available)(struct input_stream *is);
|
||||
|
||||
size_t (*read)(struct input_stream *is, void *ptr, size_t size,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
bool (*eof)(struct input_stream *is);
|
||||
bool (*seek)(struct input_stream *is, goffset offset, int whence,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,29 +23,22 @@
|
||||
#include "InputPlugin.hxx"
|
||||
#include "input/RewindInputPlugin.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
#include <assert.h>
|
||||
|
||||
static inline GQuark
|
||||
input_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("input");
|
||||
}
|
||||
static constexpr Domain input_domain("input");
|
||||
|
||||
struct input_stream *
|
||||
input_stream_open(const char *url,
|
||||
Mutex &mutex, Cond &cond,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
assert(error_r == NULL || *error_r == NULL);
|
||||
|
||||
input_plugins_for_each_enabled(plugin) {
|
||||
struct input_stream *is;
|
||||
|
||||
is = plugin->open(url, mutex, cond, &error);
|
||||
is = plugin->open(url, mutex, cond, error);
|
||||
if (is != NULL) {
|
||||
assert(is->plugin.close != NULL);
|
||||
assert(is->plugin.read != NULL);
|
||||
@ -55,23 +48,21 @@ input_stream_open(const char *url,
|
||||
is = input_rewind_open(is);
|
||||
|
||||
return is;
|
||||
} else if (error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
} else if (error.IsDefined())
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_set_error(error_r, input_quark(), 0, "Unrecognized URI");
|
||||
error.Set(input_domain, "Unrecognized URI");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
input_stream_check(struct input_stream *is, GError **error_r)
|
||||
input_stream_check(struct input_stream *is, Error &error)
|
||||
{
|
||||
assert(is != NULL);
|
||||
|
||||
return is->plugin.check == NULL ||
|
||||
is->plugin.check(is, error_r);
|
||||
is->plugin.check(is, error);
|
||||
}
|
||||
|
||||
void
|
||||
@ -159,19 +150,19 @@ input_stream_cheap_seeking(const struct input_stream *is)
|
||||
|
||||
bool
|
||||
input_stream_seek(struct input_stream *is, goffset offset, int whence,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
assert(is != NULL);
|
||||
|
||||
if (is->plugin.seek == NULL)
|
||||
return false;
|
||||
|
||||
return is->plugin.seek(is, offset, whence, error_r);
|
||||
return is->plugin.seek(is, offset, whence, error);
|
||||
}
|
||||
|
||||
bool
|
||||
input_stream_lock_seek(struct input_stream *is, goffset offset, int whence,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
assert(is != NULL);
|
||||
|
||||
@ -179,7 +170,7 @@ input_stream_lock_seek(struct input_stream *is, goffset offset, int whence,
|
||||
return false;
|
||||
|
||||
const ScopeLock protect(is->mutex);
|
||||
return input_stream_seek(is, offset, whence, error_r);
|
||||
return input_stream_seek(is, offset, whence, error);
|
||||
}
|
||||
|
||||
Tag *
|
||||
@ -216,23 +207,23 @@ input_stream_available(struct input_stream *is)
|
||||
|
||||
size_t
|
||||
input_stream_read(struct input_stream *is, void *ptr, size_t size,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(size > 0);
|
||||
|
||||
return is->plugin.read(is, ptr, size, error_r);
|
||||
return is->plugin.read(is, ptr, size, error);
|
||||
}
|
||||
|
||||
size_t
|
||||
input_stream_lock_read(struct input_stream *is, void *ptr, size_t size,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
assert(size > 0);
|
||||
|
||||
const ScopeLock protect(is->mutex);
|
||||
return input_stream_read(is, ptr, size, error_r);
|
||||
return input_stream_read(is, ptr, size, error);
|
||||
}
|
||||
|
||||
void input_stream_close(struct input_stream *is)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "Client.hxx"
|
||||
#include "conf.h"
|
||||
#include "event/ServerSocket.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -55,7 +56,7 @@ int listen_port;
|
||||
static bool
|
||||
listen_add_config_param(unsigned int port,
|
||||
const struct config_param *param,
|
||||
GError **error_r)
|
||||
Error &error_r)
|
||||
{
|
||||
assert(param != NULL);
|
||||
|
||||
@ -69,7 +70,7 @@ listen_add_config_param(unsigned int port,
|
||||
}
|
||||
|
||||
static bool
|
||||
listen_systemd_activation(GError **error_r)
|
||||
listen_systemd_activation(Error &error_r)
|
||||
{
|
||||
#ifdef ENABLE_SYSTEMD_DAEMON
|
||||
int n = sd_listen_fds(true);
|
||||
@ -93,7 +94,7 @@ listen_systemd_activation(GError **error_r)
|
||||
}
|
||||
|
||||
bool
|
||||
listen_global_init(GError **error_r)
|
||||
listen_global_init(Error &error)
|
||||
{
|
||||
assert(main_loop != nullptr);
|
||||
|
||||
@ -101,29 +102,24 @@ listen_global_init(GError **error_r)
|
||||
const struct config_param *param =
|
||||
config_get_next_param(CONF_BIND_TO_ADDRESS, NULL);
|
||||
bool success;
|
||||
GError *error = NULL;
|
||||
|
||||
listen_socket = new ClientListener();
|
||||
|
||||
if (listen_systemd_activation(&error))
|
||||
if (listen_systemd_activation(error))
|
||||
return true;
|
||||
|
||||
if (error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
if (error.IsDefined())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param != NULL) {
|
||||
/* "bind_to_address" is configured, create listeners
|
||||
for all values */
|
||||
|
||||
do {
|
||||
success = listen_add_config_param(port, param, &error);
|
||||
if (!success) {
|
||||
if (!listen_add_config_param(port, param, error)) {
|
||||
delete listen_socket;
|
||||
g_propagate_prefixed_error(error_r, error,
|
||||
"Failed to listen on %s (line %i): ",
|
||||
param->value, param->line);
|
||||
error.FormatPrefix("Failed to listen on %s (line %i): ",
|
||||
param->value, param->line);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -134,17 +130,15 @@ listen_global_init(GError **error_r)
|
||||
/* no "bind_to_address" configured, bind the
|
||||
configured port on all interfaces */
|
||||
|
||||
success = listen_socket->AddPort(port, error_r);
|
||||
success = listen_socket->AddPort(port, error);
|
||||
if (!success) {
|
||||
delete listen_socket;
|
||||
g_propagate_prefixed_error(error_r, error,
|
||||
"Failed to listen on *:%d: ",
|
||||
port);
|
||||
error.FormatPrefix("Failed to listen on *:%d: ", port);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!listen_socket->Open(error_r)) {
|
||||
if (!listen_socket->Open(error)) {
|
||||
delete listen_socket;
|
||||
return false;
|
||||
}
|
||||
|
@ -20,12 +20,12 @@
|
||||
#ifndef MPD_LISTEN_HXX
|
||||
#define MPD_LISTEN_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
class Error;
|
||||
|
||||
extern int listen_port;
|
||||
|
||||
bool
|
||||
listen_global_init(GError **error_r);
|
||||
listen_global_init(Error &error);
|
||||
|
||||
void listen_global_finish(void);
|
||||
|
||||
|
39
src/Log.cxx
39
src/Log.cxx
@ -25,6 +25,8 @@
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "mpd_error.h"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
@ -51,6 +53,8 @@
|
||||
#define LOG_DATE_BUF_SIZE 16
|
||||
#define LOG_DATE_LEN (LOG_DATE_BUF_SIZE - 1)
|
||||
|
||||
static constexpr Domain log_domain("log");
|
||||
|
||||
static GLogLevelFlags log_threshold = G_LOG_LEVEL_MESSAGE;
|
||||
|
||||
static const char *log_charset;
|
||||
@ -92,7 +96,7 @@ chomp_length(const char *p)
|
||||
}
|
||||
|
||||
static void
|
||||
file_log_func(const gchar *log_domain,
|
||||
file_log_func(const gchar *domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message, gcc_unused gpointer user_data)
|
||||
{
|
||||
@ -110,12 +114,12 @@ file_log_func(const gchar *log_domain,
|
||||
} else
|
||||
converted = NULL;
|
||||
|
||||
if (log_domain == NULL)
|
||||
log_domain = "";
|
||||
if (domain == nullptr)
|
||||
domain = "";
|
||||
|
||||
fprintf(stderr, "%s%s%s%.*s\n",
|
||||
stdout_mode ? "" : log_date(),
|
||||
log_domain, *log_domain == 0 ? "" : ": ",
|
||||
domain, *domain == 0 ? "" : ": ",
|
||||
chomp_length(message), message);
|
||||
|
||||
g_free(converted);
|
||||
@ -136,16 +140,15 @@ open_log_file(void)
|
||||
}
|
||||
|
||||
static bool
|
||||
log_init_file(unsigned line, GError **error_r)
|
||||
log_init_file(unsigned line, Error &error)
|
||||
{
|
||||
assert(!out_path.IsNull());
|
||||
|
||||
out_fd = open_log_file();
|
||||
if (out_fd < 0) {
|
||||
const std::string out_path_utf8 = out_path.ToUTF8();
|
||||
g_set_error(error_r, log_quark(), errno,
|
||||
"failed to open log file \"%s\" (config line %u): %s",
|
||||
out_path_utf8.c_str(), line, g_strerror(errno));
|
||||
error.FormatErrno("failed to open log file \"%s\" (config line %u)",
|
||||
out_path_utf8.c_str(), line);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -181,14 +184,14 @@ glib_to_syslog_level(GLogLevelFlags log_level)
|
||||
}
|
||||
|
||||
static void
|
||||
syslog_log_func(const gchar *log_domain,
|
||||
syslog_log_func(const gchar *domain,
|
||||
GLogLevelFlags log_level, const gchar *message,
|
||||
gcc_unused gpointer user_data)
|
||||
{
|
||||
if (stdout_mode) {
|
||||
/* fall back to the file log function during
|
||||
startup */
|
||||
file_log_func(log_domain, log_level,
|
||||
file_log_func(domain, log_level,
|
||||
message, user_data);
|
||||
return;
|
||||
}
|
||||
@ -196,11 +199,11 @@ syslog_log_func(const gchar *log_domain,
|
||||
if (log_level > log_threshold)
|
||||
return;
|
||||
|
||||
if (log_domain == NULL)
|
||||
log_domain = "";
|
||||
if (domain == nullptr)
|
||||
domain = "";
|
||||
|
||||
syslog(glib_to_syslog_level(log_level), "%s%s%.*s",
|
||||
log_domain, *log_domain == 0 ? "" : ": ",
|
||||
domain, *domain == 0 ? "" : ": ",
|
||||
chomp_length(message), message);
|
||||
}
|
||||
|
||||
@ -241,7 +244,7 @@ log_early_init(bool verbose)
|
||||
}
|
||||
|
||||
bool
|
||||
log_init(bool verbose, bool use_stdout, GError **error_r)
|
||||
log_init(bool verbose, bool use_stdout, Error &error)
|
||||
{
|
||||
const struct config_param *param;
|
||||
|
||||
@ -264,8 +267,8 @@ log_init(bool verbose, bool use_stdout, GError **error_r)
|
||||
log_init_syslog();
|
||||
return true;
|
||||
#else
|
||||
g_set_error(error_r, log_quark(), 0,
|
||||
"config parameter 'log_file' not found");
|
||||
error.Set(log_domain,
|
||||
"config parameter 'log_file' not found");
|
||||
return false;
|
||||
#endif
|
||||
#ifdef HAVE_SYSLOG
|
||||
@ -274,9 +277,9 @@ log_init(bool verbose, bool use_stdout, GError **error_r)
|
||||
return true;
|
||||
#endif
|
||||
} else {
|
||||
out_path = config_get_path(CONF_LOG_FILE, error_r);
|
||||
out_path = config_get_path(CONF_LOG_FILE, error);
|
||||
return !out_path.IsNull() &&
|
||||
log_init_file(param->line, error_r);
|
||||
log_init_file(param->line, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
src/Log.hxx
13
src/Log.hxx
@ -20,16 +20,7 @@
|
||||
#ifndef MPD_LOG_HXX
|
||||
#define MPD_LOG_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
gcc_const
|
||||
static inline GQuark
|
||||
log_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("log");
|
||||
}
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Configure a logging destination for daemon startup, before the
|
||||
@ -43,7 +34,7 @@ void
|
||||
log_early_init(bool verbose);
|
||||
|
||||
bool
|
||||
log_init(bool verbose, bool use_stdout, GError **error_r);
|
||||
log_init(bool verbose, bool use_stdout, Error &error);
|
||||
|
||||
void
|
||||
log_deinit(void);
|
||||
|
107
src/Main.cxx
107
src/Main.cxx
@ -56,6 +56,7 @@
|
||||
#include "pcm/PcmResample.hxx"
|
||||
#include "Daemon.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "stats.h"
|
||||
@ -107,15 +108,11 @@ static inline GQuark main_quark()
|
||||
}
|
||||
|
||||
static bool
|
||||
glue_daemonize_init(const struct options *options, GError **error_r)
|
||||
glue_daemonize_init(const struct options *options, Error &error)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
Path pid_file = config_get_path(CONF_PID_FILE, &error);
|
||||
if (pid_file.IsNull() && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
Path pid_file = config_get_path(CONF_PID_FILE, error);
|
||||
if (pid_file.IsNull() && error.IsDefined())
|
||||
return false;
|
||||
}
|
||||
|
||||
daemonize_init(config_get_string(CONF_USER, NULL),
|
||||
config_get_string(CONF_GROUP, NULL),
|
||||
@ -128,20 +125,15 @@ glue_daemonize_init(const struct options *options, GError **error_r)
|
||||
}
|
||||
|
||||
static bool
|
||||
glue_mapper_init(GError **error_r)
|
||||
glue_mapper_init(Error &error)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Path music_dir = config_get_path(CONF_MUSIC_DIR, &error);
|
||||
if (music_dir.IsNull() && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
Path music_dir = config_get_path(CONF_MUSIC_DIR, error);
|
||||
if (music_dir.IsNull() && error.IsDefined())
|
||||
return false;
|
||||
}
|
||||
|
||||
Path playlist_dir = config_get_path(CONF_PLAYLIST_DIR, &error);
|
||||
if (playlist_dir.IsNull() && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
Path playlist_dir = config_get_path(CONF_PLAYLIST_DIR, error);
|
||||
if (playlist_dir.IsNull() && error.IsDefined())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (music_dir.IsNull())
|
||||
music_dir = Path::FromUTF8(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC));
|
||||
@ -164,9 +156,6 @@ glue_db_init_and_load(void)
|
||||
if (param != NULL && path != NULL)
|
||||
g_message("Found both 'database' and 'db_file' setting - ignoring the latter");
|
||||
|
||||
GError *error = NULL;
|
||||
bool ret;
|
||||
|
||||
if (!mapper_has_music_directory()) {
|
||||
if (param != NULL)
|
||||
g_message("Found database setting without "
|
||||
@ -185,13 +174,13 @@ glue_db_init_and_load(void)
|
||||
param = allocated;
|
||||
}
|
||||
|
||||
if (!DatabaseGlobalInit(*param, &error))
|
||||
Error error;
|
||||
if (!DatabaseGlobalInit(*param, error))
|
||||
FatalError(error);
|
||||
|
||||
delete allocated;
|
||||
|
||||
ret = DatabaseGlobalOpen(&error);
|
||||
if (!ret)
|
||||
if (!DatabaseGlobalOpen(error))
|
||||
FatalError(error);
|
||||
|
||||
/* run database update after daemonization? */
|
||||
@ -205,36 +194,22 @@ static void
|
||||
glue_sticker_init(void)
|
||||
{
|
||||
#ifdef ENABLE_SQLITE
|
||||
GError *error = NULL;
|
||||
Path sticker_file = config_get_path(CONF_STICKER_FILE, &error);
|
||||
if (sticker_file.IsNull() && error != NULL)
|
||||
Error error;
|
||||
Path sticker_file = config_get_path(CONF_STICKER_FILE, error);
|
||||
if (sticker_file.IsNull() && error.IsDefined())
|
||||
FatalError(error);
|
||||
|
||||
if (!sticker_global_init(std::move(sticker_file), &error))
|
||||
if (!sticker_global_init(std::move(sticker_file), error))
|
||||
FatalError(error);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
glue_state_file_init(GError **error_r)
|
||||
glue_state_file_init(Error &error)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
Path path_fs = config_get_path(CONF_STATE_FILE, &error);
|
||||
if (path_fs.IsNull()) {
|
||||
if (error != nullptr) {
|
||||
g_propagate_error(error_r, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path_fs.IsNull()) {
|
||||
g_set_error(error_r, main_quark(), 0,
|
||||
"Failed to convert state file path to FS encoding");
|
||||
return false;
|
||||
}
|
||||
Path path_fs = config_get_path(CONF_STATE_FILE, error);
|
||||
if (path_fs.IsNull())
|
||||
return !error.IsDefined();
|
||||
|
||||
state_file = new StateFile(std::move(path_fs),
|
||||
*instance->partition, *main_loop);
|
||||
@ -364,7 +339,7 @@ int mpd_main(int argc, char *argv[])
|
||||
struct options options;
|
||||
clock_t start;
|
||||
bool create_db;
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
bool success;
|
||||
|
||||
daemonize_close_stdin();
|
||||
@ -385,25 +360,22 @@ int mpd_main(int argc, char *argv[])
|
||||
winsock_init();
|
||||
config_global_init();
|
||||
|
||||
success = parse_cmdline(argc, argv, &options, &error);
|
||||
success = parse_cmdline(argc, argv, &options, error);
|
||||
if (!success) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
g_warning("%s", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!glue_daemonize_init(&options, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
if (!glue_daemonize_init(&options, error)) {
|
||||
g_printerr("%s\n", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
stats_global_init();
|
||||
tag_lib_init();
|
||||
|
||||
if (!log_init(options.verbose, options.log_stderr, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
if (!log_init(options.verbose, options.log_stderr, error)) {
|
||||
g_warning("%s", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -415,10 +387,9 @@ int mpd_main(int argc, char *argv[])
|
||||
const unsigned max_clients = config_get_positive(CONF_MAX_CONN, 10);
|
||||
instance->client_list = new ClientList(max_clients);
|
||||
|
||||
success = listen_global_init(&error);
|
||||
success = listen_global_init(error);
|
||||
if (!success) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
g_warning("%s", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -432,9 +403,8 @@ int mpd_main(int argc, char *argv[])
|
||||
|
||||
Path::GlobalInit();
|
||||
|
||||
if (!glue_mapper_init(&error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
if (!glue_mapper_init(error)) {
|
||||
g_printerr("%s\n", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -445,9 +415,8 @@ int mpd_main(int argc, char *argv[])
|
||||
archive_plugin_init_all();
|
||||
#endif
|
||||
|
||||
if (!pcm_resample_global_init(&error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
if (!pcm_resample_global_init(error)) {
|
||||
g_warning("%s", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -466,9 +435,8 @@ int mpd_main(int argc, char *argv[])
|
||||
client_manager_init();
|
||||
replay_gain_global_init();
|
||||
|
||||
if (!input_stream_global_init(&error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
if (!input_stream_global_init(error)) {
|
||||
g_warning("%s", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -494,9 +462,8 @@ int mpd_main(int argc, char *argv[])
|
||||
FatalError("directory update failed");
|
||||
}
|
||||
|
||||
if (!glue_state_file_init(&error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
if (!glue_state_file_init(error)) {
|
||||
g_printerr("%s\n", error.GetMessage());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#define MPD_MAPPER_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
#include "gerror.h"
|
||||
|
||||
#define PLAYLIST_FILE_SUFFIX ".m3u"
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "OutputAll.hxx"
|
||||
#include "pcm/PcmVolume.hxx"
|
||||
#include "OutputInternal.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -38,7 +39,6 @@ output_mixer_get_volume(unsigned i)
|
||||
{
|
||||
struct audio_output *output;
|
||||
int volume;
|
||||
GError *error = NULL;
|
||||
|
||||
assert(i < audio_output_count());
|
||||
|
||||
@ -50,12 +50,11 @@ output_mixer_get_volume(unsigned i)
|
||||
if (mixer == NULL)
|
||||
return -1;
|
||||
|
||||
volume = mixer_get_volume(mixer, &error);
|
||||
if (volume < 0 && error != NULL) {
|
||||
Error error;
|
||||
volume = mixer_get_volume(mixer, error);
|
||||
if (volume < 0 && error.IsDefined())
|
||||
g_warning("Failed to read mixer for '%s': %s",
|
||||
output->name, error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
output->name, error.GetMessage());
|
||||
|
||||
return volume;
|
||||
}
|
||||
@ -85,7 +84,6 @@ output_mixer_set_volume(unsigned i, unsigned volume)
|
||||
{
|
||||
struct audio_output *output;
|
||||
bool success;
|
||||
GError *error = NULL;
|
||||
|
||||
assert(i < audio_output_count());
|
||||
assert(volume <= 100);
|
||||
@ -98,12 +96,11 @@ output_mixer_set_volume(unsigned i, unsigned volume)
|
||||
if (mixer == NULL)
|
||||
return false;
|
||||
|
||||
success = mixer_set_volume(mixer, volume, &error);
|
||||
if (!success && error != NULL) {
|
||||
Error error;
|
||||
success = mixer_set_volume(mixer, volume, error);
|
||||
if (!success && error.IsDefined())
|
||||
g_warning("Failed to set mixer for '%s': %s",
|
||||
output->name, error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
output->name, error.GetMessage());
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -138,7 +135,7 @@ output_mixer_get_software_volume(unsigned i)
|
||||
if (mixer == NULL || !mixer->IsPlugin(software_mixer_plugin))
|
||||
return -1;
|
||||
|
||||
return mixer_get_volume(mixer, NULL);
|
||||
return mixer_get_volume(mixer, IgnoreError());
|
||||
}
|
||||
|
||||
int
|
||||
@ -172,6 +169,6 @@ mixer_all_set_software_volume(unsigned volume)
|
||||
struct audio_output *output = audio_output_get(i);
|
||||
if (output->mixer != NULL &&
|
||||
output->mixer->plugin == &software_mixer_plugin)
|
||||
mixer_set_volume(output->mixer, volume, NULL);
|
||||
mixer_set_volume(output->mixer, volume, IgnoreError());
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "MixerControl.hxx"
|
||||
#include "MixerInternal.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
@ -32,13 +31,13 @@
|
||||
Mixer *
|
||||
mixer_new(const struct mixer_plugin *plugin, void *ao,
|
||||
const config_param ¶m,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
Mixer *mixer;
|
||||
|
||||
assert(plugin != NULL);
|
||||
|
||||
mixer = plugin->init(ao, param, error_r);
|
||||
mixer = plugin->init(ao, param, error);
|
||||
|
||||
assert(mixer == NULL || mixer->IsPlugin(*plugin));
|
||||
|
||||
@ -59,7 +58,7 @@ mixer_free(Mixer *mixer)
|
||||
}
|
||||
|
||||
bool
|
||||
mixer_open(Mixer *mixer, GError **error_r)
|
||||
mixer_open(Mixer *mixer, Error &error)
|
||||
{
|
||||
bool success;
|
||||
|
||||
@ -73,7 +72,7 @@ mixer_open(Mixer *mixer, GError **error_r)
|
||||
else if (mixer->plugin->open == NULL)
|
||||
success = mixer->open = true;
|
||||
else
|
||||
success = mixer->open = mixer->plugin->open(mixer, error_r);
|
||||
success = mixer->open = mixer->plugin->open(mixer, error);
|
||||
|
||||
mixer->failed = !success;
|
||||
|
||||
@ -127,26 +126,22 @@ mixer_failed(Mixer *mixer)
|
||||
}
|
||||
|
||||
int
|
||||
mixer_get_volume(Mixer *mixer, GError **error_r)
|
||||
mixer_get_volume(Mixer *mixer, Error &error)
|
||||
{
|
||||
int volume;
|
||||
|
||||
assert(mixer != NULL);
|
||||
|
||||
if (mixer->plugin->global && !mixer->failed &&
|
||||
!mixer_open(mixer, error_r))
|
||||
!mixer_open(mixer, error))
|
||||
return -1;
|
||||
|
||||
const ScopeLock protect(mixer->mutex);
|
||||
|
||||
if (mixer->open) {
|
||||
GError *error = NULL;
|
||||
|
||||
volume = mixer->plugin->get_volume(mixer, &error);
|
||||
if (volume < 0 && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
volume = mixer->plugin->get_volume(mixer, error);
|
||||
if (volume < 0 && error.IsDefined())
|
||||
mixer_failed(mixer);
|
||||
}
|
||||
} else
|
||||
volume = -1;
|
||||
|
||||
@ -154,17 +149,17 @@ mixer_get_volume(Mixer *mixer, GError **error_r)
|
||||
}
|
||||
|
||||
bool
|
||||
mixer_set_volume(Mixer *mixer, unsigned volume, GError **error_r)
|
||||
mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
|
||||
{
|
||||
assert(mixer != NULL);
|
||||
assert(volume <= 100);
|
||||
|
||||
if (mixer->plugin->global && !mixer->failed &&
|
||||
!mixer_open(mixer, error_r))
|
||||
!mixer_open(mixer, error))
|
||||
return false;
|
||||
|
||||
const ScopeLock protect(mixer->mutex);
|
||||
|
||||
return mixer->open &&
|
||||
mixer->plugin->set_volume(mixer, volume, error_r);
|
||||
mixer->plugin->set_volume(mixer, volume, error);
|
||||
}
|
||||
|
@ -25,8 +25,7 @@
|
||||
#ifndef MPD_MIXER_CONTROL_HXX
|
||||
#define MPD_MIXER_CONTROL_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
class Error;
|
||||
class Mixer;
|
||||
struct mixer_plugin;
|
||||
struct config_param;
|
||||
@ -34,13 +33,13 @@ struct config_param;
|
||||
Mixer *
|
||||
mixer_new(const struct mixer_plugin *plugin, void *ao,
|
||||
const config_param ¶m,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
void
|
||||
mixer_free(Mixer *mixer);
|
||||
|
||||
bool
|
||||
mixer_open(Mixer *mixer, GError **error_r);
|
||||
mixer_open(Mixer *mixer, Error &error);
|
||||
|
||||
void
|
||||
mixer_close(Mixer *mixer);
|
||||
@ -53,9 +52,9 @@ void
|
||||
mixer_auto_close(Mixer *mixer);
|
||||
|
||||
int
|
||||
mixer_get_volume(Mixer *mixer, GError **error_r);
|
||||
mixer_get_volume(Mixer *mixer, Error &error);
|
||||
|
||||
bool
|
||||
mixer_set_volume(Mixer *mixer, unsigned volume, GError **error_r);
|
||||
mixer_set_volume(Mixer *mixer, unsigned volume, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -27,10 +27,9 @@
|
||||
#ifndef MPD_MIXER_PLUGIN_HXX
|
||||
#define MPD_MIXER_PLUGIN_HXX
|
||||
|
||||
#include "gerror.h"
|
||||
|
||||
struct config_param;
|
||||
class Mixer;
|
||||
class Error;
|
||||
|
||||
struct mixer_plugin {
|
||||
/**
|
||||
@ -43,7 +42,7 @@ struct mixer_plugin {
|
||||
* @return a mixer object, or NULL on error
|
||||
*/
|
||||
Mixer *(*init)(void *ao, const config_param ¶m,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Finish and free mixer data
|
||||
@ -57,7 +56,7 @@ struct mixer_plugin {
|
||||
* NULL to ignore errors
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool (*open)(Mixer *data, GError **error_r);
|
||||
bool (*open)(Mixer *data, Error &error);
|
||||
|
||||
/**
|
||||
* Close mixer device
|
||||
@ -70,9 +69,9 @@ struct mixer_plugin {
|
||||
* @param error_r location to store the error occurring, or
|
||||
* NULL to ignore errors
|
||||
* @return the current volume (0..100 including) or -1 if
|
||||
* unavailable or on error (error_r set, mixer will be closed)
|
||||
* unavailable or on error (error set, mixer will be closed)
|
||||
*/
|
||||
int (*get_volume)(Mixer *mixer, GError **error_r);
|
||||
int (*get_volume)(Mixer *mixer, Error &error);
|
||||
|
||||
/**
|
||||
* Sets the volume.
|
||||
@ -83,7 +82,7 @@ struct mixer_plugin {
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool (*set_volume)(Mixer *mixer, unsigned volume,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* If true, then the mixer is automatically opened, even if
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "ls.hxx"
|
||||
#include "Volume.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
|
||||
extern "C" {
|
||||
@ -126,8 +127,8 @@ handle_lsinfo(Client *client, int argc, char *argv[])
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
GError *error = NULL;
|
||||
if (!client_allow_file(client, path_fs, &error))
|
||||
Error error;
|
||||
if (!client_allow_file(client, path_fs, error))
|
||||
return print_error(client, error);
|
||||
|
||||
Song *song = Song::LoadFile(path_utf8, nullptr);
|
||||
@ -147,7 +148,8 @@ handle_lsinfo(Client *client, int argc, char *argv[])
|
||||
return result;
|
||||
|
||||
if (isRootDirectory(uri)) {
|
||||
const auto &list = ListPlaylistFiles(NULL);
|
||||
Error error;
|
||||
const auto &list = ListPlaylistFiles(error);
|
||||
print_spl_list(client, list);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "MusicPipe.hxx"
|
||||
#include "MusicChunk.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "conf.h"
|
||||
#include "notify.hxx"
|
||||
|
||||
@ -104,7 +105,7 @@ audio_output_all_init(struct player_control *pc)
|
||||
{
|
||||
const struct config_param *param = NULL;
|
||||
unsigned int i;
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
|
||||
num_audio_outputs = audio_output_config_count();
|
||||
audio_outputs = g_new(struct audio_output *, num_audio_outputs);
|
||||
@ -125,11 +126,12 @@ audio_output_all_init(struct player_control *pc)
|
||||
param = ∅
|
||||
}
|
||||
|
||||
struct audio_output *output = audio_output_new(*param, pc, &error);
|
||||
audio_output *output = audio_output_new(*param, pc, error);
|
||||
if (output == NULL) {
|
||||
if (param != NULL)
|
||||
FormatFatalError("line %i: %s",
|
||||
param->line, error->message);
|
||||
param->line,
|
||||
error.GetMessage());
|
||||
else
|
||||
FatalError(error);
|
||||
}
|
||||
@ -271,7 +273,7 @@ audio_output_all_set_replay_gain_mode(enum replay_gain_mode mode)
|
||||
}
|
||||
|
||||
bool
|
||||
audio_output_all_play(struct music_chunk *chunk, GError **error_r)
|
||||
audio_output_all_play(struct music_chunk *chunk, Error &error)
|
||||
{
|
||||
bool ret;
|
||||
unsigned int i;
|
||||
@ -284,8 +286,7 @@ audio_output_all_play(struct music_chunk *chunk, GError **error_r)
|
||||
ret = audio_output_all_update();
|
||||
if (!ret) {
|
||||
/* TODO: obtain real error */
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"Failed to open audio output");
|
||||
error.Set(output_domain, "Failed to open audio output");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -300,7 +301,7 @@ audio_output_all_play(struct music_chunk *chunk, GError **error_r)
|
||||
bool
|
||||
audio_output_all_open(const AudioFormat audio_format,
|
||||
struct music_buffer *buffer,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
bool ret = false, enabled = false;
|
||||
unsigned int i;
|
||||
@ -338,12 +339,10 @@ audio_output_all_open(const AudioFormat audio_format,
|
||||
}
|
||||
|
||||
if (!enabled)
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"All audio outputs are disabled");
|
||||
error.Set(output_domain, "All audio outputs are disabled");
|
||||
else if (!ret)
|
||||
/* TODO: obtain real error */
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"Failed to open audio output");
|
||||
error.Set(output_domain, "Failed to open audio output");
|
||||
|
||||
if (!ret)
|
||||
/* close all devices if there was an error */
|
||||
|
@ -27,12 +27,12 @@
|
||||
#define OUTPUT_ALL_H
|
||||
|
||||
#include "replay_gain_info.h"
|
||||
#include "gerror.h"
|
||||
|
||||
struct AudioFormat;
|
||||
struct music_buffer;
|
||||
struct music_chunk;
|
||||
struct player_control;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* Global initialization: load audio outputs from the configuration
|
||||
@ -84,7 +84,7 @@ audio_output_all_enable_disable(void);
|
||||
bool
|
||||
audio_output_all_open(AudioFormat audio_format,
|
||||
struct music_buffer *buffer,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Closes all audio outputs.
|
||||
@ -111,7 +111,7 @@ audio_output_all_set_replay_gain_mode(enum replay_gain_mode mode);
|
||||
* (all closed then)
|
||||
*/
|
||||
bool
|
||||
audio_output_all_play(struct music_chunk *chunk, GError **error_r);
|
||||
audio_output_all_play(struct music_chunk *chunk, Error &error);
|
||||
|
||||
/**
|
||||
* Checks if the output devices have drained their music pipe, and
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "notify.hxx"
|
||||
#include "filter/ReplayGainFilterPlugin.hxx"
|
||||
#include "FilterPlugin.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -187,13 +188,10 @@ audio_output_open(struct audio_output *ao,
|
||||
open = ao->open;
|
||||
|
||||
if (open && ao->mixer != NULL) {
|
||||
GError *error = NULL;
|
||||
|
||||
if (!mixer_open(ao->mixer, &error)) {
|
||||
Error error;
|
||||
if (!mixer_open(ao->mixer, error))
|
||||
g_warning("Failed to open mixer for '%s': %s",
|
||||
ao->name, error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
ao->name, error.GetMessage());
|
||||
}
|
||||
|
||||
return open;
|
||||
|
23
src/OutputError.cxx
Normal file
23
src/OutputError.cxx
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "OutputError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
const Domain output_domain("output");
|
@ -20,18 +20,6 @@
|
||||
#ifndef MPD_OUTPUT_ERROR_HXX
|
||||
#define MPD_OUTPUT_ERROR_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* Quark for GError.domain.
|
||||
*/
|
||||
gcc_const
|
||||
static inline GQuark
|
||||
output_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("output");
|
||||
}
|
||||
extern const class Domain output_domain;
|
||||
|
||||
#endif
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "filter/AutoConvertFilterPlugin.hxx"
|
||||
#include "filter/ReplayGainFilterPlugin.hxx"
|
||||
#include "filter/ChainFilterPlugin.hxx"
|
||||
#include "ConfigError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -49,7 +51,7 @@
|
||||
#define AUDIO_FILTERS "filters"
|
||||
|
||||
static const struct audio_output_plugin *
|
||||
audio_output_detect(GError **error)
|
||||
audio_output_detect(Error &error)
|
||||
{
|
||||
g_warning("Attempt to detect audio output device");
|
||||
|
||||
@ -63,8 +65,7 @@ audio_output_detect(GError **error)
|
||||
return plugin;
|
||||
}
|
||||
|
||||
g_set_error(error, output_quark(), 0,
|
||||
"Unable to detect an audio device");
|
||||
error.Set(output_domain, "Unable to detect an audio device");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -99,7 +100,7 @@ audio_output_load_mixer(struct audio_output *ao,
|
||||
const config_param ¶m,
|
||||
const struct mixer_plugin *plugin,
|
||||
Filter &filter_chain,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
Mixer *mixer;
|
||||
|
||||
@ -112,12 +113,12 @@ audio_output_load_mixer(struct audio_output *ao,
|
||||
if (plugin == NULL)
|
||||
return NULL;
|
||||
|
||||
return mixer_new(plugin, ao, param, error_r);
|
||||
return mixer_new(plugin, ao, param, error);
|
||||
|
||||
case MIXER_TYPE_SOFTWARE:
|
||||
mixer = mixer_new(&software_mixer_plugin, nullptr,
|
||||
config_param(),
|
||||
nullptr);
|
||||
IgnoreError());
|
||||
assert(mixer != NULL);
|
||||
|
||||
filter_chain_append(filter_chain, "software_mixer",
|
||||
@ -132,7 +133,7 @@ audio_output_load_mixer(struct audio_output *ao,
|
||||
bool
|
||||
ao_base_init(struct audio_output *ao,
|
||||
const struct audio_output_plugin *plugin,
|
||||
const config_param ¶m, GError **error_r)
|
||||
const config_param ¶m, Error &error)
|
||||
{
|
||||
assert(ao != NULL);
|
||||
assert(plugin != NULL);
|
||||
@ -141,13 +142,11 @@ ao_base_init(struct audio_output *ao,
|
||||
assert(plugin->close != NULL);
|
||||
assert(plugin->play != NULL);
|
||||
|
||||
GError *error = NULL;
|
||||
|
||||
if (!param.IsNull()) {
|
||||
ao->name = param.GetBlockValue(AUDIO_OUTPUT_NAME);
|
||||
if (ao->name == NULL) {
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"Missing \"name\" configuration");
|
||||
error.Set(config_domain,
|
||||
"Missing \"name\" configuration");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -155,7 +154,7 @@ ao_base_init(struct audio_output *ao,
|
||||
if (p != NULL) {
|
||||
bool success =
|
||||
audio_format_parse(ao->config_audio_format,
|
||||
p, true, error_r);
|
||||
p, true, error);
|
||||
if (!success)
|
||||
return false;
|
||||
} else
|
||||
@ -186,25 +185,23 @@ ao_base_init(struct audio_output *ao,
|
||||
if (config_get_bool(CONF_VOLUME_NORMALIZATION, false)) {
|
||||
Filter *normalize_filter =
|
||||
filter_new(&normalize_filter_plugin, config_param(),
|
||||
nullptr);
|
||||
IgnoreError());
|
||||
assert(normalize_filter != NULL);
|
||||
|
||||
filter_chain_append(*ao->filter, "normalize",
|
||||
autoconvert_filter_new(normalize_filter));
|
||||
}
|
||||
|
||||
Error filter_error;
|
||||
filter_chain_parse(*ao->filter,
|
||||
param.GetBlockValue(AUDIO_FILTERS, ""),
|
||||
&error
|
||||
);
|
||||
filter_error);
|
||||
|
||||
// It's not really fatal - Part of the filter chain has been set up already
|
||||
// and even an empty one will work (if only with unexpected behaviour)
|
||||
if (error != NULL) {
|
||||
if (filter_error.IsDefined())
|
||||
g_warning("Failed to initialize filter chain for '%s': %s",
|
||||
ao->name, error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
ao->name, filter_error.GetMessage());
|
||||
|
||||
ao->thread = NULL;
|
||||
ao->command = AO_COMMAND_NONE;
|
||||
@ -220,7 +217,7 @@ ao_base_init(struct audio_output *ao,
|
||||
|
||||
static bool
|
||||
audio_output_setup(struct audio_output *ao, const config_param ¶m,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
|
||||
/* create the replay_gain filter */
|
||||
@ -230,13 +227,14 @@ audio_output_setup(struct audio_output *ao, const config_param ¶m,
|
||||
|
||||
if (strcmp(replay_gain_handler, "none") != 0) {
|
||||
ao->replay_gain_filter = filter_new(&replay_gain_filter_plugin,
|
||||
param, NULL);
|
||||
param, IgnoreError());
|
||||
assert(ao->replay_gain_filter != NULL);
|
||||
|
||||
ao->replay_gain_serial = 0;
|
||||
|
||||
ao->other_replay_gain_filter = filter_new(&replay_gain_filter_plugin,
|
||||
param, NULL);
|
||||
param,
|
||||
IgnoreError());
|
||||
assert(ao->other_replay_gain_filter != NULL);
|
||||
|
||||
ao->other_replay_gain_serial = 0;
|
||||
@ -247,15 +245,13 @@ audio_output_setup(struct audio_output *ao, const config_param ¶m,
|
||||
|
||||
/* set up the mixer */
|
||||
|
||||
GError *error = NULL;
|
||||
Error mixer_error;
|
||||
ao->mixer = audio_output_load_mixer(ao, param,
|
||||
ao->plugin->mixer_plugin,
|
||||
*ao->filter, &error);
|
||||
if (ao->mixer == NULL && error != NULL) {
|
||||
*ao->filter, mixer_error);
|
||||
if (ao->mixer == NULL && mixer_error.IsDefined())
|
||||
g_warning("Failed to initialize hardware mixer for '%s': %s",
|
||||
ao->name, error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
ao->name, mixer_error.GetMessage());
|
||||
|
||||
/* use the hardware mixer for replay gain? */
|
||||
|
||||
@ -267,15 +263,15 @@ audio_output_setup(struct audio_output *ao, const config_param ¶m,
|
||||
g_warning("No such mixer for output '%s'", ao->name);
|
||||
} else if (strcmp(replay_gain_handler, "software") != 0 &&
|
||||
ao->replay_gain_filter != NULL) {
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"Invalid \"replay_gain_handler\" value");
|
||||
error.Set(config_domain,
|
||||
"Invalid \"replay_gain_handler\" value");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* the "convert" filter must be the last one in the chain */
|
||||
|
||||
ao->convert_filter = filter_new(&convert_filter_plugin, config_param(),
|
||||
nullptr);
|
||||
IgnoreError());
|
||||
assert(ao->convert_filter != NULL);
|
||||
|
||||
filter_chain_append(*ao->filter, "convert", ao->convert_filter);
|
||||
@ -286,7 +282,7 @@ audio_output_setup(struct audio_output *ao, const config_param ¶m,
|
||||
struct audio_output *
|
||||
audio_output_new(const config_param ¶m,
|
||||
struct player_control *pc,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
const struct audio_output_plugin *plugin;
|
||||
|
||||
@ -295,21 +291,21 @@ audio_output_new(const config_param ¶m,
|
||||
|
||||
p = param.GetBlockValue(AUDIO_OUTPUT_TYPE);
|
||||
if (p == NULL) {
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"Missing \"type\" configuration");
|
||||
error.Set(config_domain,
|
||||
"Missing \"type\" configuration");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
plugin = audio_output_plugin_get(p);
|
||||
if (plugin == NULL) {
|
||||
g_set_error(error_r, output_quark(), 0,
|
||||
"No such audio output plugin: %s", p);
|
||||
error.Format(config_domain,
|
||||
"No such audio output plugin: %s", p);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
g_warning("No 'audio_output' defined in config file\n");
|
||||
|
||||
plugin = audio_output_detect(error_r);
|
||||
plugin = audio_output_detect(error);
|
||||
if (plugin == NULL)
|
||||
return nullptr;
|
||||
|
||||
@ -317,11 +313,11 @@ audio_output_new(const config_param ¶m,
|
||||
plugin->name);
|
||||
}
|
||||
|
||||
struct audio_output *ao = ao_plugin_init(plugin, param, error_r);
|
||||
struct audio_output *ao = ao_plugin_init(plugin, param, error);
|
||||
if (ao == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!audio_output_setup(ao, param, error_r)) {
|
||||
if (!audio_output_setup(ao, param, error)) {
|
||||
ao_plugin_finish(ao);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
class Error;
|
||||
class Filter;
|
||||
struct config_param;
|
||||
|
||||
@ -263,12 +264,12 @@ audio_output_command_is_finished(const struct audio_output *ao)
|
||||
struct audio_output *
|
||||
audio_output_new(const config_param ¶m,
|
||||
struct player_control *pc,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
bool
|
||||
ao_base_init(struct audio_output *ao,
|
||||
const struct audio_output_plugin *plugin,
|
||||
const config_param ¶m, GError **error_r);
|
||||
const config_param ¶m, Error &error);
|
||||
|
||||
void
|
||||
ao_base_finish(struct audio_output *ao);
|
||||
|
@ -24,7 +24,7 @@
|
||||
struct audio_output *
|
||||
ao_plugin_init(const struct audio_output_plugin *plugin,
|
||||
const config_param ¶m,
|
||||
GError **error)
|
||||
Error &error)
|
||||
{
|
||||
assert(plugin != NULL);
|
||||
assert(plugin->init != NULL);
|
||||
@ -39,7 +39,7 @@ ao_plugin_finish(struct audio_output *ao)
|
||||
}
|
||||
|
||||
bool
|
||||
ao_plugin_enable(struct audio_output *ao, GError **error_r)
|
||||
ao_plugin_enable(struct audio_output *ao, Error &error_r)
|
||||
{
|
||||
return ao->plugin->enable != NULL
|
||||
? ao->plugin->enable(ao, error_r)
|
||||
@ -55,7 +55,7 @@ ao_plugin_disable(struct audio_output *ao)
|
||||
|
||||
bool
|
||||
ao_plugin_open(struct audio_output *ao, AudioFormat &audio_format,
|
||||
GError **error)
|
||||
Error &error)
|
||||
{
|
||||
return ao->plugin->open(ao, audio_format, error);
|
||||
}
|
||||
@ -83,7 +83,7 @@ ao_plugin_send_tag(struct audio_output *ao, const Tag *tag)
|
||||
|
||||
size_t
|
||||
ao_plugin_play(struct audio_output *ao, const void *chunk, size_t size,
|
||||
GError **error)
|
||||
Error &error)
|
||||
{
|
||||
return ao->plugin->play(ao, chunk, size, error);
|
||||
}
|
||||
|
@ -21,13 +21,13 @@
|
||||
#define MPD_OUTPUT_PLUGIN_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
#include "gerror.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct config_param;
|
||||
struct AudioFormat;
|
||||
struct Tag;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
* A plugin which controls an audio output device.
|
||||
@ -56,7 +56,7 @@ struct audio_output_plugin {
|
||||
* data
|
||||
*/
|
||||
struct audio_output *(*init)(const config_param ¶m,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Free resources allocated by this device.
|
||||
@ -73,7 +73,7 @@ struct audio_output_plugin {
|
||||
* NULL to ignore errors
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool (*enable)(struct audio_output *data, GError **error_r);
|
||||
bool (*enable)(struct audio_output *data, Error &error);
|
||||
|
||||
/**
|
||||
* Disables the device. It is closed before this method is
|
||||
@ -90,7 +90,7 @@ struct audio_output_plugin {
|
||||
* to ignore errors
|
||||
*/
|
||||
bool (*open)(struct audio_output *data, AudioFormat &audio_format,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Close the device.
|
||||
@ -122,7 +122,7 @@ struct audio_output_plugin {
|
||||
*/
|
||||
size_t (*play)(struct audio_output *data,
|
||||
const void *chunk, size_t size,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
* Wait until the device has finished playing.
|
||||
@ -169,20 +169,20 @@ gcc_malloc
|
||||
struct audio_output *
|
||||
ao_plugin_init(const struct audio_output_plugin *plugin,
|
||||
const config_param ¶m,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
void
|
||||
ao_plugin_finish(struct audio_output *ao);
|
||||
|
||||
bool
|
||||
ao_plugin_enable(struct audio_output *ao, GError **error_r);
|
||||
ao_plugin_enable(struct audio_output *ao, Error &error);
|
||||
|
||||
void
|
||||
ao_plugin_disable(struct audio_output *ao);
|
||||
|
||||
bool
|
||||
ao_plugin_open(struct audio_output *ao, AudioFormat &audio_format,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
void
|
||||
ao_plugin_close(struct audio_output *ao);
|
||||
@ -196,7 +196,7 @@ ao_plugin_send_tag(struct audio_output *ao, const Tag *tag);
|
||||
|
||||
size_t
|
||||
ao_plugin_play(struct audio_output *ao, const void *chunk, size_t size,
|
||||
GError **error);
|
||||
Error &error);
|
||||
|
||||
void
|
||||
ao_plugin_drain(struct audio_output *ao);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "MusicPipe.hxx"
|
||||
#include "MusicChunk.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
@ -55,19 +56,18 @@ static void ao_command_finished(struct audio_output *ao)
|
||||
static bool
|
||||
ao_enable(struct audio_output *ao)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
bool success;
|
||||
|
||||
if (ao->really_enabled)
|
||||
return true;
|
||||
|
||||
ao->mutex.unlock();
|
||||
success = ao_plugin_enable(ao, &error);
|
||||
success = ao_plugin_enable(ao, error);
|
||||
ao->mutex.lock();
|
||||
if (!success) {
|
||||
g_warning("Failed to enable \"%s\" [%s]: %s\n",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name, error.GetMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ ao_disable(struct audio_output *ao)
|
||||
|
||||
static AudioFormat
|
||||
ao_filter_open(struct audio_output *ao, AudioFormat &format,
|
||||
GError **error_r)
|
||||
Error &error_r)
|
||||
{
|
||||
assert(format.IsValid());
|
||||
|
||||
@ -131,7 +131,7 @@ static void
|
||||
ao_open(struct audio_output *ao)
|
||||
{
|
||||
bool success;
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
struct audio_format_string af_string;
|
||||
|
||||
assert(!ao->open);
|
||||
@ -157,11 +157,10 @@ ao_open(struct audio_output *ao)
|
||||
/* open the filter */
|
||||
|
||||
const AudioFormat filter_audio_format =
|
||||
ao_filter_open(ao, ao->in_audio_format, &error);
|
||||
ao_filter_open(ao, ao->in_audio_format, error);
|
||||
if (!filter_audio_format.IsDefined()) {
|
||||
g_warning("Failed to open filter for \"%s\" [%s]: %s",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name, error.GetMessage());
|
||||
|
||||
ao->fail_timer = g_timer_new();
|
||||
return;
|
||||
@ -173,15 +172,14 @@ ao_open(struct audio_output *ao)
|
||||
ao->out_audio_format.ApplyMask(ao->config_audio_format);
|
||||
|
||||
ao->mutex.unlock();
|
||||
success = ao_plugin_open(ao, ao->out_audio_format, &error);
|
||||
success = ao_plugin_open(ao, ao->out_audio_format, error);
|
||||
ao->mutex.lock();
|
||||
|
||||
assert(!ao->open);
|
||||
|
||||
if (!success) {
|
||||
g_warning("Failed to open \"%s\" [%s]: %s",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name, error.GetMessage());
|
||||
|
||||
ao_filter_close(ao);
|
||||
ao->fail_timer = g_timer_new();
|
||||
@ -231,15 +229,14 @@ ao_close(struct audio_output *ao, bool drain)
|
||||
static void
|
||||
ao_reopen_filter(struct audio_output *ao)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
|
||||
ao_filter_close(ao);
|
||||
const AudioFormat filter_audio_format =
|
||||
ao_filter_open(ao, ao->in_audio_format, &error);
|
||||
ao_filter_open(ao, ao->in_audio_format, error);
|
||||
if (!filter_audio_format.IsDefined()) {
|
||||
g_warning("Failed to open filter for \"%s\" [%s]: %s",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name, error.GetMessage());
|
||||
|
||||
/* this is a little code duplication fro ao_close(),
|
||||
but we cannot call this function because we must
|
||||
@ -333,13 +330,12 @@ ao_chunk_data(struct audio_output *ao, const struct music_chunk *chunk,
|
||||
*replay_gain_serial_p = chunk->replay_gain_serial;
|
||||
}
|
||||
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
data = replay_gain_filter->FilterPCM(data, length,
|
||||
&length, &error);
|
||||
&length, error);
|
||||
if (data == NULL) {
|
||||
g_warning("\"%s\" [%s] failed to filter: %s",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name, error.GetMessage());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -352,8 +348,6 @@ static const void *
|
||||
ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
|
||||
size_t *length_r)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
size_t length;
|
||||
const void *data = ao_chunk_data(ao, chunk, ao->replay_gain_filter,
|
||||
&ao->replay_gain_serial, &length);
|
||||
@ -407,11 +401,11 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
|
||||
|
||||
/* apply filter chain */
|
||||
|
||||
data = ao->filter->FilterPCM(data, length, &length, &error);
|
||||
Error error;
|
||||
data = ao->filter->FilterPCM(data, length, &length, error);
|
||||
if (data == NULL) {
|
||||
g_warning("\"%s\" [%s] failed to filter: %s",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name, error.GetMessage());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -422,8 +416,6 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
|
||||
static bool
|
||||
ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
assert(ao != NULL);
|
||||
assert(ao->filter != NULL);
|
||||
|
||||
@ -448,6 +440,8 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
|
||||
return false;
|
||||
}
|
||||
|
||||
Error error;
|
||||
|
||||
while (size > 0 && ao->command == AO_COMMAND_NONE) {
|
||||
size_t nbytes;
|
||||
|
||||
@ -455,13 +449,13 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
|
||||
break;
|
||||
|
||||
ao->mutex.unlock();
|
||||
nbytes = ao_plugin_play(ao, data, size, &error);
|
||||
nbytes = ao_plugin_play(ao, data, size, error);
|
||||
ao->mutex.lock();
|
||||
if (nbytes == 0) {
|
||||
/* play()==0 means failure */
|
||||
g_warning("\"%s\" [%s] failed to play: %s",
|
||||
ao->name, ao->plugin->name, error->message);
|
||||
g_error_free(error);
|
||||
ao->name, ao->plugin->name,
|
||||
error.GetMessage());
|
||||
|
||||
ao_close(ao, false);
|
||||
|
||||
|
@ -40,7 +40,6 @@ player_control::player_control(unsigned _buffer_chunks,
|
||||
command(PLAYER_COMMAND_NONE),
|
||||
state(PLAYER_STATE_STOP),
|
||||
error_type(PLAYER_ERROR_NONE),
|
||||
error(nullptr),
|
||||
next_song(nullptr),
|
||||
cross_fade_seconds(0),
|
||||
mixramp_db(0),
|
||||
@ -216,16 +215,13 @@ player_control::GetStatus()
|
||||
}
|
||||
|
||||
void
|
||||
player_control::SetError(player_error type, GError *_error)
|
||||
player_control::SetError(player_error type, Error &&_error)
|
||||
{
|
||||
assert(type != PLAYER_ERROR_NONE);
|
||||
assert(_error != NULL);
|
||||
|
||||
if (error_type != PLAYER_ERROR_NONE)
|
||||
g_error_free(error);
|
||||
assert(_error.IsDefined());
|
||||
|
||||
error_type = type;
|
||||
error = _error;
|
||||
error = std::move(_error);
|
||||
}
|
||||
|
||||
void
|
||||
@ -235,7 +231,7 @@ player_control::ClearError()
|
||||
|
||||
if (error_type != PLAYER_ERROR_NONE) {
|
||||
error_type = PLAYER_ERROR_NONE;
|
||||
g_error_free(error);
|
||||
error.Clear();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
@ -246,7 +242,7 @@ player_control::GetErrorMessage() const
|
||||
{
|
||||
Lock();
|
||||
char *message = error_type != PLAYER_ERROR_NONE
|
||||
? g_strdup(error->message)
|
||||
? g_strdup(error.GetMessage())
|
||||
: NULL;
|
||||
Unlock();
|
||||
return message;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "AudioFormat.hxx"
|
||||
#include "thread/Mutex.hxx"
|
||||
#include "thread/Cond.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -127,7 +128,7 @@ struct player_control {
|
||||
* #PLAYER_ERROR_NONE. The object must be freed when this
|
||||
* object transitions back to #PLAYER_ERROR_NONE.
|
||||
*/
|
||||
GError *error;
|
||||
Error error;
|
||||
|
||||
uint16_t bit_rate;
|
||||
AudioFormat audio_format;
|
||||
@ -262,10 +263,9 @@ struct player_control {
|
||||
* Caller must lock the object.
|
||||
*
|
||||
* @param type the error type; must not be #PLAYER_ERROR_NONE
|
||||
* @param error detailed error information; must not be NULL; the
|
||||
* #player_control takes over ownership of this #GError instance
|
||||
* @param error detailed error information; must be defined.
|
||||
*/
|
||||
void SetError(player_error type, GError *error);
|
||||
void SetError(player_error type, Error &&error);
|
||||
|
||||
void ClearError();
|
||||
|
||||
|
@ -251,10 +251,10 @@ player_wait_for_decoder(struct player *player)
|
||||
|
||||
player->queued = false;
|
||||
|
||||
GError *error = dc->LockGetError();
|
||||
if (error != NULL) {
|
||||
Error error = dc->LockGetError();
|
||||
if (error.IsDefined()) {
|
||||
pc->Lock();
|
||||
pc->SetError(PLAYER_ERROR_DECODER, error);
|
||||
pc->SetError(PLAYER_ERROR_DECODER, std::move(error));
|
||||
|
||||
pc->next_song->Free();
|
||||
pc->next_song = NULL;
|
||||
@ -327,9 +327,9 @@ player_open_output(struct player *player)
|
||||
assert(pc->state == PLAYER_STATE_PLAY ||
|
||||
pc->state == PLAYER_STATE_PAUSE);
|
||||
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
if (audio_output_all_open(player->play_audio_format, player_buffer,
|
||||
&error)) {
|
||||
error)) {
|
||||
player->output_open = true;
|
||||
player->paused = false;
|
||||
|
||||
@ -341,7 +341,7 @@ player_open_output(struct player *player)
|
||||
|
||||
return true;
|
||||
} else {
|
||||
g_warning("%s", error->message);
|
||||
g_warning("%s", error.GetMessage());
|
||||
|
||||
player->output_open = false;
|
||||
|
||||
@ -350,7 +350,7 @@ player_open_output(struct player *player)
|
||||
player->paused = true;
|
||||
|
||||
pc->Lock();
|
||||
pc->SetError(PLAYER_ERROR_OUTPUT, error);
|
||||
pc->SetError(PLAYER_ERROR_OUTPUT, std::move(error));
|
||||
pc->state = PLAYER_STATE_PAUSE;
|
||||
pc->Unlock();
|
||||
|
||||
@ -377,13 +377,13 @@ player_check_decoder_startup(struct player *player)
|
||||
|
||||
dc->Lock();
|
||||
|
||||
GError *error = dc->GetError();
|
||||
if (error != NULL) {
|
||||
Error error = dc->GetError();
|
||||
if (error.IsDefined()) {
|
||||
/* the decoder failed */
|
||||
dc->Unlock();
|
||||
|
||||
pc->Lock();
|
||||
pc->SetError(PLAYER_ERROR_DECODER, error);
|
||||
pc->SetError(PLAYER_ERROR_DECODER, std::move(error));
|
||||
pc->Unlock();
|
||||
|
||||
return false;
|
||||
@ -460,11 +460,9 @@ player_send_silence(struct player *player)
|
||||
chunk->length = num_frames * frame_size;
|
||||
memset(chunk->data, 0, chunk->length);
|
||||
|
||||
GError *error = NULL;
|
||||
if (!audio_output_all_play(chunk, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
||||
Error error;
|
||||
if (!audio_output_all_play(chunk, error)) {
|
||||
g_warning("%s", error.GetMessage());
|
||||
music_buffer_return(player_buffer, chunk);
|
||||
return false;
|
||||
}
|
||||
@ -689,7 +687,7 @@ static bool
|
||||
play_chunk(struct player_control *pc,
|
||||
Song *song, struct music_chunk *chunk,
|
||||
const AudioFormat format,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
assert(chunk->CheckFormat(format));
|
||||
|
||||
@ -707,7 +705,7 @@ play_chunk(struct player_control *pc,
|
||||
|
||||
/* send the chunk to the audio outputs */
|
||||
|
||||
if (!audio_output_all_play(chunk, error_r))
|
||||
if (!audio_output_all_play(chunk, error))
|
||||
return false;
|
||||
|
||||
pc->total_play_time += (double)chunk->length /
|
||||
@ -822,16 +820,16 @@ play_next_chunk(struct player *player)
|
||||
|
||||
/* play the current chunk */
|
||||
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
if (!play_chunk(player->pc, player->song, chunk,
|
||||
player->play_audio_format, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
player->play_audio_format, error)) {
|
||||
g_warning("%s", error.GetMessage());
|
||||
|
||||
music_buffer_return(player_buffer, chunk);
|
||||
|
||||
pc->Lock();
|
||||
|
||||
pc->SetError(PLAYER_ERROR_OUTPUT, error);
|
||||
pc->SetError(PLAYER_ERROR_OUTPUT, std::move(error));
|
||||
|
||||
/* pause: the user may resume playback as soon as an
|
||||
audio output becomes available */
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "PlaylistMapper.hxx"
|
||||
#include "PlaylistRegistry.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "InputLegacy.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
@ -39,14 +40,12 @@ playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond,
|
||||
return playlist;
|
||||
}
|
||||
|
||||
GError *error = NULL;
|
||||
struct input_stream *is = input_stream_open(uri, mutex, cond, &error);
|
||||
Error error;
|
||||
input_stream *is = input_stream_open(uri, mutex, cond, error);
|
||||
if (is == NULL) {
|
||||
if (error != NULL) {
|
||||
if (error.IsDefined())
|
||||
g_warning("Failed to open %s: %s",
|
||||
uri, error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
uri, error.GetMessage());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "ls.hxx"
|
||||
#include "Playlist.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -64,7 +65,7 @@ handle_load(Client *client, int argc, char *argv[])
|
||||
|
||||
if (argc < 3) {
|
||||
start_index = 0;
|
||||
end_index = G_MAXUINT;
|
||||
end_index = unsigned(-1);
|
||||
} else if (!check_range(client, &start_index, &end_index, argv[2]))
|
||||
return COMMAND_RETURN_ERROR;
|
||||
|
||||
@ -77,19 +78,22 @@ handle_load(Client *client, int argc, char *argv[])
|
||||
if (result != PLAYLIST_RESULT_NO_SUCH_LIST)
|
||||
return print_playlist_result(client, result);
|
||||
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
if (playlist_load_spl(&client->playlist, client->player_control,
|
||||
argv[1], start_index, end_index,
|
||||
&error))
|
||||
error))
|
||||
return COMMAND_RETURN_OK;
|
||||
|
||||
if (error->domain == playlist_quark() &&
|
||||
error->code == PLAYLIST_RESULT_BAD_NAME)
|
||||
if (error.IsDomain(playlist_domain) &&
|
||||
error.GetCode() == PLAYLIST_RESULT_BAD_NAME) {
|
||||
/* the message for BAD_NAME is confusing when the
|
||||
client wants to load a playlist file from the music
|
||||
directory; patch the GError object to show "no such
|
||||
directory; patch the Error object to show "no such
|
||||
playlist" instead */
|
||||
error->code = PLAYLIST_RESULT_NO_SUCH_LIST;
|
||||
Error error2(playlist_domain, PLAYLIST_RESULT_NO_SUCH_LIST,
|
||||
error.GetMessage());
|
||||
error = std::move(error2);
|
||||
}
|
||||
|
||||
return print_error(client, error);
|
||||
}
|
||||
@ -100,8 +104,8 @@ handle_listplaylist(Client *client, gcc_unused int argc, char *argv[])
|
||||
if (playlist_file_print(client, argv[1], false))
|
||||
return COMMAND_RETURN_OK;
|
||||
|
||||
GError *error = NULL;
|
||||
return spl_print(client, argv[1], false, &error)
|
||||
Error error;
|
||||
return spl_print(client, argv[1], false, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -113,8 +117,8 @@ handle_listplaylistinfo(Client *client,
|
||||
if (playlist_file_print(client, argv[1], true))
|
||||
return COMMAND_RETURN_OK;
|
||||
|
||||
GError *error = NULL;
|
||||
return spl_print(client, argv[1], true, &error)
|
||||
Error error;
|
||||
return spl_print(client, argv[1], true, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -122,8 +126,8 @@ handle_listplaylistinfo(Client *client,
|
||||
enum command_return
|
||||
handle_rm(Client *client, gcc_unused int argc, char *argv[])
|
||||
{
|
||||
GError *error = NULL;
|
||||
return spl_delete(argv[1], &error)
|
||||
Error error;
|
||||
return spl_delete(argv[1], error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -131,8 +135,8 @@ handle_rm(Client *client, gcc_unused int argc, char *argv[])
|
||||
enum command_return
|
||||
handle_rename(Client *client, gcc_unused int argc, char *argv[])
|
||||
{
|
||||
GError *error = NULL;
|
||||
return spl_rename(argv[1], argv[2], &error)
|
||||
Error error;
|
||||
return spl_rename(argv[1], argv[2], error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -146,8 +150,8 @@ handle_playlistdelete(Client *client,
|
||||
if (!check_unsigned(client, &from, argv[2]))
|
||||
return COMMAND_RETURN_ERROR;
|
||||
|
||||
GError *error = NULL;
|
||||
return spl_remove_index(playlist, from, &error)
|
||||
Error error;
|
||||
return spl_remove_index(playlist, from, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -163,8 +167,8 @@ handle_playlistmove(Client *client, gcc_unused int argc, char *argv[])
|
||||
if (!check_unsigned(client, &to, argv[3]))
|
||||
return COMMAND_RETURN_ERROR;
|
||||
|
||||
GError *error = NULL;
|
||||
return spl_move_index(playlist, from, to, &error)
|
||||
Error error;
|
||||
return spl_move_index(playlist, from, to, error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -172,8 +176,8 @@ handle_playlistmove(Client *client, gcc_unused int argc, char *argv[])
|
||||
enum command_return
|
||||
handle_playlistclear(Client *client, gcc_unused int argc, char *argv[])
|
||||
{
|
||||
GError *error = NULL;
|
||||
return spl_clear(argv[1], &error)
|
||||
Error error;
|
||||
return spl_clear(argv[1], error)
|
||||
? COMMAND_RETURN_OK
|
||||
: print_error(client, error);
|
||||
}
|
||||
@ -185,7 +189,7 @@ handle_playlistadd(Client *client, gcc_unused int argc, char *argv[])
|
||||
char *uri = argv[2];
|
||||
|
||||
bool success;
|
||||
GError *error = NULL;
|
||||
Error error;
|
||||
if (uri_has_scheme(uri)) {
|
||||
if (!uri_supported_scheme(uri)) {
|
||||
command_error(client, ACK_ERROR_NO_EXIST,
|
||||
@ -193,12 +197,12 @@ handle_playlistadd(Client *client, gcc_unused int argc, char *argv[])
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
success = spl_append_uri(uri, playlist, &error);
|
||||
success = spl_append_uri(uri, playlist, error);
|
||||
} else
|
||||
success = search_add_to_playlist(uri, playlist, nullptr,
|
||||
&error);
|
||||
error);
|
||||
|
||||
if (!success && error == NULL) {
|
||||
if (!success && !error.IsDefined()) {
|
||||
command_error(client, ACK_ERROR_NO_EXIST,
|
||||
"directory or file not found");
|
||||
return COMMAND_RETURN_ERROR;
|
||||
@ -211,9 +215,9 @@ enum command_return
|
||||
handle_listplaylists(Client *client,
|
||||
gcc_unused int argc, gcc_unused char *argv[])
|
||||
{
|
||||
GError *error = NULL;
|
||||
const auto list = ListPlaylistFiles(&error);
|
||||
if (list.empty() && error != NULL)
|
||||
Error error;
|
||||
const auto list = ListPlaylistFiles(error);
|
||||
if (list.empty() && error.IsDefined())
|
||||
return print_error(client, error);
|
||||
|
||||
print_spl_list(client, list);
|
||||
|
@ -22,15 +22,13 @@
|
||||
#include "PlaylistVector.hxx"
|
||||
#include "TextFile.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static GQuark
|
||||
playlist_database_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string("playlist_database");
|
||||
}
|
||||
static constexpr Domain playlist_database_domain("playlist_database");
|
||||
|
||||
void
|
||||
playlist_vector_save(FILE *fp, const PlaylistVector &pv)
|
||||
@ -44,7 +42,7 @@ playlist_vector_save(FILE *fp, const PlaylistVector &pv)
|
||||
|
||||
bool
|
||||
playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name,
|
||||
GError **error_r)
|
||||
Error &error)
|
||||
{
|
||||
PlaylistInfo pm(name, 0);
|
||||
|
||||
@ -55,8 +53,8 @@ playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name,
|
||||
strcmp(line, "playlist_end") != 0) {
|
||||
colon = strchr(line, ':');
|
||||
if (colon == NULL || colon == line) {
|
||||
g_set_error(error_r, playlist_database_quark(), 0,
|
||||
"unknown line in db: %s", line);
|
||||
error.Format(playlist_database_domain,
|
||||
"unknown line in db: %s", line);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -66,8 +64,8 @@ playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name,
|
||||
if (strcmp(line, "mtime") == 0)
|
||||
pm.mtime = strtol(value, NULL, 10);
|
||||
else {
|
||||
g_set_error(error_r, playlist_database_quark(), 0,
|
||||
"unknown line in db: %s", line);
|
||||
error.Format(playlist_database_domain,
|
||||
"unknown line in db: %s", line);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define MPD_PLAYLIST_DATABASE_HXX
|
||||
|
||||
#include "check.h"
|
||||
#include "gerror.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -29,12 +28,13 @@
|
||||
|
||||
class PlaylistVector;
|
||||
class TextFile;
|
||||
class Error;
|
||||
|
||||
void
|
||||
playlist_vector_save(FILE *fp, const PlaylistVector &pv);
|
||||
|
||||
bool
|
||||
playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name,
|
||||
GError **error_r);
|
||||
Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "Playlist.hxx"
|
||||
#include "PlayerControl.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "Idle.hxx"
|
||||
#include "DatabaseGlue.hxx"
|
||||
@ -110,11 +111,11 @@ playlist::AppendURI(struct player_control &pc,
|
||||
if (uri_has_scheme(uri)) {
|
||||
song = Song::NewRemote(uri);
|
||||
} else {
|
||||
db = GetDatabase(nullptr);
|
||||
db = GetDatabase(IgnoreError());
|
||||
if (db == nullptr)
|
||||
return PLAYLIST_RESULT_NO_SUCH_SONG;
|
||||
|
||||
song = db->GetSong(uri, nullptr);
|
||||
song = db->GetSong(uri, IgnoreError());
|
||||
if (song == nullptr)
|
||||
return PLAYLIST_RESULT_NO_SUCH_SONG;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user