summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CommandLine.cxx17
-rw-r--r--src/Main.cxx7
-rw-r--r--src/PlaylistFile.cxx6
-rw-r--r--src/StateFile.cxx11
-rw-r--r--src/config/ConfigFile.cxx44
-rw-r--r--src/config/ConfigFile.hxx4
-rw-r--r--src/config/ConfigGlobal.cxx6
-rw-r--r--src/config/ConfigGlobal.hxx4
-rw-r--r--src/db/plugins/simple/SimpleDatabasePlugin.cxx11
-rw-r--r--src/db/update/ExcludeList.cxx36
-rw-r--r--src/fs/FileInfo.hxx15
-rw-r--r--src/fs/StandardDirectory.cxx9
-rw-r--r--src/fs/io/AutoGunzipReader.cxx34
-rw-r--r--src/fs/io/AutoGunzipReader.hxx4
-rw-r--r--src/fs/io/BufferedReader.cxx10
-rw-r--r--src/fs/io/BufferedReader.hxx17
-rw-r--r--src/fs/io/FileReader.cxx67
-rw-r--r--src/fs/io/FileReader.hxx11
-rw-r--r--src/fs/io/GunzipReader.cxx32
-rw-r--r--src/fs/io/GunzipReader.hxx22
-rw-r--r--src/fs/io/PeekReader.cxx8
-rw-r--r--src/fs/io/PeekReader.hxx4
-rw-r--r--src/fs/io/Reader.hxx6
-rw-r--r--src/fs/io/TextFile.cxx26
-rw-r--r--src/fs/io/TextFile.hxx19
-rw-r--r--src/input/plugins/FileInputPlugin.cxx34
-rw-r--r--test/DumpDatabase.cxx5
-rw-r--r--test/dump_playlist.cxx5
-rw-r--r--test/read_conf.cxx7
-rw-r--r--test/run_filter.cxx4
-rw-r--r--test/run_gunzip.cxx31
-rw-r--r--test/run_neighbor_explorer.cxx5
-rw-r--r--test/run_output.cxx5
33 files changed, 192 insertions, 334 deletions
diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx
index b59a39e40..ce0fa543b 100644
--- a/src/CommandLine.cxx
+++ b/src/CommandLine.cxx
@@ -277,13 +277,7 @@ static void help(void)
class ConfigLoader
{
- Error &error;
- bool result;
public:
- ConfigLoader(Error &_error) : error(_error), result(false) { }
-
- bool GetResult() const { return result; }
-
bool TryFile(const Path path);
bool TryFile(const AllocatedPath &base_path,
PathTraitsFS::const_pointer path);
@@ -292,7 +286,7 @@ public:
bool ConfigLoader::TryFile(Path path)
{
if (FileExists(path)) {
- result = ReadConfigFile(path, error);
+ ReadConfigFile(path);
return true;
}
return false;
@@ -386,15 +380,16 @@ parse_cmdline(int argc, char **argv, struct options *options,
return false;
}
- return ReadConfigFile(Path::FromFS(buffer), error);
+ ReadConfigFile(Path::FromFS(buffer));
#else
- return ReadConfigFile(Path::FromFS(config_file), error);
+ ReadConfigFile(Path::FromFS(config_file));
#endif
+ return true;
}
/* use default configuration file path */
- ConfigLoader loader(error);
+ ConfigLoader loader;
bool found =
#ifdef WIN32
@@ -413,5 +408,5 @@ parse_cmdline(int argc, char **argv, struct options *options,
return false;
}
- return loader.GetResult();
+ return true;
}
diff --git a/src/Main.cxx b/src/Main.cxx
index de950c05a..bf0f82ccb 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -453,11 +453,8 @@ int mpd_main(int argc, char *argv[])
if (!sdcard.IsNull()) {
const auto config_path =
AllocatedPath::Build(sdcard, "mpd.conf");
- if (FileExists(config_path) &&
- !ReadConfigFile(config_path, error)) {
- LogError(error);
- return EXIT_FAILURE;
- }
+ if (FileExists(config_path))
+ ReadConfigFile(config_path);
}
#else
if (!parse_cmdline(argc, argv, &options, error)) {
diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx
index d0af1c7f5..8b86afcfc 100644
--- a/src/PlaylistFile.cxx
+++ b/src/PlaylistFile.cxx
@@ -254,11 +254,7 @@ LoadPlaylistFile(const char *utf8path, Error &error)
if (path_fs.IsNull())
return contents;
- TextFile file(path_fs, error);
- if (file.HasFailed()) {
- TranslatePlaylistError(error);
- return contents;
- }
+ TextFile file(path_fs);
char *s;
while ((s = file.ReadLine()) != nullptr) {
diff --git a/src/StateFile.cxx b/src/StateFile.cxx
index fb031d04b..4de3d52f8 100644
--- a/src/StateFile.cxx
+++ b/src/StateFile.cxx
@@ -102,17 +102,12 @@ StateFile::Write()
void
StateFile::Read()
-{
+try {
bool success;
FormatDebug(state_file_domain, "Loading state file %s", path_utf8.c_str());
- Error error;
- TextFile file(path, error);
- if (file.HasFailed()) {
- LogError(error);
- return;
- }
+ TextFile file(path);
#ifdef ENABLE_DATABASE
const SongLoader song_loader(partition.instance.database,
@@ -135,6 +130,8 @@ StateFile::Read()
}
RememberVersions();
+} catch (const std::exception &e) {
+ LogError(e);
}
void
diff --git a/src/config/ConfigFile.cxx b/src/config/ConfigFile.cxx
index 844dc5bb9..364e2dd46 100644
--- a/src/config/ConfigFile.cxx
+++ b/src/config/ConfigFile.cxx
@@ -25,7 +25,6 @@
#include "ConfigTemplates.hxx"
#include "util/Tokenizer.hxx"
#include "util/StringUtil.hxx"
-#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include "fs/Path.hxx"
@@ -65,17 +64,14 @@ config_read_name_value(ConfigBlock &block, char *input, unsigned line)
}
static ConfigBlock *
-config_read_block(BufferedReader &reader, Error &error)
+config_read_block(BufferedReader &reader)
try {
std::unique_ptr<ConfigBlock> block(new ConfigBlock(reader.GetLineNumber()));
while (true) {
char *line = reader.ReadLine();
- if (line == nullptr) {
- if (reader.Check(error))
- throw std::runtime_error("Expected '}' before end-of-file");
- return nullptr;
- }
+ if (line == nullptr)
+ throw std::runtime_error("Expected '}' before end-of-file");
line = StripLeft(line);
if (*line == 0 || *line == CONF_COMMENT)
@@ -114,11 +110,10 @@ Append(ConfigBlock *&head, ConfigBlock *p)
*i = p;
}
-static bool
+static void
ReadConfigBlock(ConfigData &config_data, BufferedReader &reader,
const char *name, ConfigBlockOption o,
- Tokenizer &tokenizer,
- Error &error)
+ Tokenizer &tokenizer)
{
const unsigned i = unsigned(o);
const ConfigTemplate &option = config_block_templates[i];
@@ -143,12 +138,9 @@ ReadConfigBlock(ConfigData &config_data, BufferedReader &reader,
throw FormatRuntimeError("line %u: Unknown tokens after '{'",
reader.GetLineNumber());
- auto *param = config_read_block(reader, error);
- if (param == nullptr)
- return false;
-
+ auto *param = config_read_block(reader);
+ assert(param != nullptr);
Append(head, param);
- return true;
}
gcc_nonnull_all
@@ -196,13 +188,13 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader,
Append(head, param);
}
-static bool
-ReadConfigFile(ConfigData &config_data, BufferedReader &reader, Error &error)
+static void
+ReadConfigFile(ConfigData &config_data, BufferedReader &reader)
{
while (true) {
char *line = reader.ReadLine();
if (line == nullptr)
- return true;
+ return;
line = StripLeft(line);
if (*line == 0 || *line == CONF_COMMENT)
@@ -224,9 +216,8 @@ ReadConfigFile(ConfigData &config_data, BufferedReader &reader, Error &error)
ReadConfigParam(config_data, reader, name, o,
tokenizer);
} else if ((bo = ParseConfigBlockOptionName(name)) != ConfigBlockOption::MAX) {
- if (!ReadConfigBlock(config_data, reader, name, bo,
- tokenizer, error))
- return false;
+ ReadConfigBlock(config_data, reader, name, bo,
+ tokenizer);
} else {
throw FormatRuntimeError("unrecognized parameter in config file at "
"line %u: %s\n",
@@ -235,19 +226,16 @@ ReadConfigFile(ConfigData &config_data, BufferedReader &reader, Error &error)
}
}
-bool
-ReadConfigFile(ConfigData &config_data, Path path, Error &error)
+void
+ReadConfigFile(ConfigData &config_data, Path path)
{
assert(!path.IsNull());
const std::string path_utf8 = path.ToUTF8();
FormatDebug(config_file_domain, "loading file %s", path_utf8.c_str());
- FileReader file(path, error);
- if (!file.IsDefined())
- return false;
+ FileReader file(path);
BufferedReader reader(file);
- return ReadConfigFile(config_data, reader, error) &&
- reader.Check(error);
+ ReadConfigFile(config_data, reader);
}
diff --git a/src/config/ConfigFile.hxx b/src/config/ConfigFile.hxx
index 30bee0614..8aeb055d7 100644
--- a/src/config/ConfigFile.hxx
+++ b/src/config/ConfigFile.hxx
@@ -24,7 +24,7 @@ class Error;
class Path;
struct ConfigData;
-bool
-ReadConfigFile(ConfigData &data, Path path, Error &error);
+void
+ReadConfigFile(ConfigData &data, Path path);
#endif
diff --git a/src/config/ConfigGlobal.cxx b/src/config/ConfigGlobal.cxx
index 192baffec..657f871eb 100644
--- a/src/config/ConfigGlobal.cxx
+++ b/src/config/ConfigGlobal.cxx
@@ -45,10 +45,10 @@ void config_global_init(void)
{
}
-bool
-ReadConfigFile(Path path, Error &error)
+void
+ReadConfigFile(Path path)
{
- return ReadConfigFile(config_data, path, error);
+ return ReadConfigFile(config_data, path);
}
static void
diff --git a/src/config/ConfigGlobal.hxx b/src/config/ConfigGlobal.hxx
index b24b9aada..622105248 100644
--- a/src/config/ConfigGlobal.hxx
+++ b/src/config/ConfigGlobal.hxx
@@ -42,8 +42,8 @@ config_global_finish();
void
config_global_check();
-bool
-ReadConfigFile(Path path, Error &error);
+void
+ReadConfigFile(Path path);
gcc_pure
const config_param *
diff --git a/src/db/plugins/simple/SimpleDatabasePlugin.cxx b/src/db/plugins/simple/SimpleDatabasePlugin.cxx
index 113e9b321..ad266b0af 100644
--- a/src/db/plugins/simple/SimpleDatabasePlugin.cxx
+++ b/src/db/plugins/simple/SimpleDatabasePlugin.cxx
@@ -184,11 +184,9 @@ SimpleDatabase::Load(Error &error)
assert(!path.IsNull());
assert(root != nullptr);
- TextFile file(path, error);
- if (file.HasFailed())
- return false;
+ TextFile file(path);
- if (!db_load_internal(file, *root, error) || !file.Check(error))
+ if (!db_load_internal(file, *root, error))
return false;
FileInfo fi;
@@ -200,7 +198,7 @@ SimpleDatabase::Load(Error &error)
bool
SimpleDatabase::Open(Error &error)
-{
+try {
assert(prefixed_light_song == nullptr);
root = Directory::NewRoot();
@@ -223,6 +221,9 @@ SimpleDatabase::Open(Error &error)
}
return true;
+} catch (const std::exception &e) {
+ error.Set(e);
+ return false;
}
void
diff --git a/src/db/update/ExcludeList.cxx b/src/db/update/ExcludeList.cxx
index b09f349ac..d117be412 100644
--- a/src/db/update/ExcludeList.cxx
+++ b/src/db/update/ExcludeList.cxx
@@ -27,41 +27,18 @@
#include "fs/Path.hxx"
#include "fs/NarrowPath.hxx"
#include "fs/io/TextFile.hxx"
-#include "util/StringUtil.hxx"
-#include "util/Error.hxx"
+#include "system/Error.hxx"
#include "Log.hxx"
#include <assert.h>
#include <string.h>
#include <errno.h>
-#ifdef HAVE_CLASS_GLOB
-
-gcc_pure
-static bool
-IsFileNotFound(const Error &error)
-{
-#ifdef WIN32
- return error.IsDomain(win32_domain) &&
- error.GetCode() == ERROR_FILE_NOT_FOUND;
-#else
- return error.IsDomain(errno_domain) && error.GetCode() == ENOENT;
-#endif
-}
-
-#endif
-
bool
ExcludeList::LoadFile(Path path_fs)
-{
+try {
#ifdef HAVE_CLASS_GLOB
- Error error;
- TextFile file(path_fs, error);
- if (file.HasFailed()) {
- if (!IsFileNotFound(error))
- LogError(error);
- return false;
- }
+ TextFile file(path_fs);
char *line;
while ((line = file.ReadLine()) != nullptr) {
@@ -79,6 +56,13 @@ ExcludeList::LoadFile(Path path_fs)
#endif
return true;
+} catch (const std::system_error &e) {
+ if (!IsFileNotFound(e))
+ LogError(e);
+ return false;
+} catch (const std::exception &e) {
+ LogError(e);
+ return false;
}
bool
diff --git a/src/fs/FileInfo.hxx b/src/fs/FileInfo.hxx
index 7b272568f..5d8661be6 100644
--- a/src/fs/FileInfo.hxx
+++ b/src/fs/FileInfo.hxx
@@ -23,6 +23,7 @@
#include "check.h"
#include "Path.hxx"
#include "util/Error.hxx"
+#include "system/Error.hxx"
#include <stdint.h>
@@ -63,6 +64,20 @@ class FileInfo {
#endif
public:
+ FileInfo() = default;
+
+ FileInfo(Path path, bool follow_symlinks=true) {
+ if (!GetFileInfo(path, *this, follow_symlinks)) {
+#ifdef WIN32
+ throw FormatLastError("Failed to access %s",
+ path.ToUTF8().c_str());
+#else
+ throw FormatErrno("Failed to access %s",
+ path.ToUTF8().c_str());
+#endif
+ }
+ }
+
bool IsRegular() const {
#ifdef WIN32
return (data.dwFileAttributes &
diff --git a/src/fs/StandardDirectory.cxx b/src/fs/StandardDirectory.cxx
index 009f02c37..e6e39f98b 100644
--- a/src/fs/StandardDirectory.cxx
+++ b/src/fs/StandardDirectory.cxx
@@ -200,20 +200,21 @@ ParseConfigLine(char *line, const char *dir_name, AllocatedPath &result_dir)
}
static AllocatedPath GetUserDir(const char *name)
-{
+try {
auto result = AllocatedPath::Null();
auto config_dir = GetUserConfigDir();
if (config_dir.IsNull())
return result;
auto dirs_file = AllocatedPath::Build(config_dir, "user-dirs.dirs");
- TextFile input(dirs_file, IgnoreError());
- if (input.HasFailed())
- return result;
+
+ TextFile input(dirs_file);
char *line;
while ((line = input.ReadLine()) != nullptr)
if (ParseConfigLine(line, name, result))
return result;
return result;
+} catch (const std::exception &e) {
+ return AllocatedPath::Null();
}
#endif
diff --git a/src/fs/io/AutoGunzipReader.cxx b/src/fs/io/AutoGunzipReader.cxx
index b6d30dfd7..e23f69553 100644
--- a/src/fs/io/AutoGunzipReader.cxx
+++ b/src/fs/io/AutoGunzipReader.cxx
@@ -20,7 +20,6 @@
#include "config.h"
#include "AutoGunzipReader.hxx"
#include "GunzipReader.hxx"
-#include "util/Error.hxx"
AutoGunzipReader::~AutoGunzipReader()
{
@@ -35,36 +34,27 @@ IsGzip(const uint8_t data[4])
(data[3] & 0xe0) == 0;
}
-inline bool
-AutoGunzipReader::Detect(Error &error)
+inline void
+AutoGunzipReader::Detect()
{
- const uint8_t *data = (const uint8_t *)peek.Peek(4, error);
+ const uint8_t *data = (const uint8_t *)peek.Peek(4);
if (data == nullptr) {
- if (error.IsDefined())
- return false;
-
next = &peek;
- return true;
+ return;
}
- if (IsGzip(data)) {
- gunzip = new GunzipReader(peek, error);
- if (!gunzip->IsDefined())
- return false;
-
-
- next = gunzip;
- } else
+ if (IsGzip(data))
+ next = gunzip = new GunzipReader(peek);
+ else
next = &peek;
-
- return true;
}
size_t
-AutoGunzipReader::Read(void *data, size_t size, Error &error)
+AutoGunzipReader::Read(void *data, size_t size)
{
- if (next == nullptr && !Detect(error))
- return false;
+ if (next == nullptr)
+ Detect();
- return next->Read(data, size, error);
+ assert(next != nullptr);
+ return next->Read(data, size);
}
diff --git a/src/fs/io/AutoGunzipReader.hxx b/src/fs/io/AutoGunzipReader.hxx
index 29a794aed..783067b02 100644
--- a/src/fs/io/AutoGunzipReader.hxx
+++ b/src/fs/io/AutoGunzipReader.hxx
@@ -43,10 +43,10 @@ public:
~AutoGunzipReader();
/* virtual methods from class Reader */
- virtual size_t Read(void *data, size_t size, Error &error) override;
+ virtual size_t Read(void *data, size_t size) override;
private:
- bool Detect(Error &error);
+ void Detect();
};
#endif
diff --git a/src/fs/io/BufferedReader.cxx b/src/fs/io/BufferedReader.cxx
index 9a296d815..c1de5e386 100644
--- a/src/fs/io/BufferedReader.cxx
+++ b/src/fs/io/BufferedReader.cxx
@@ -25,9 +25,6 @@
bool
BufferedReader::Fill(bool need_more)
{
- if (gcc_unlikely(last_error.IsDefined()))
- return false;
-
if (eof)
return !need_more;
@@ -41,11 +38,8 @@ BufferedReader::Fill(bool need_more)
assert(!w.IsEmpty());
}
- size_t nbytes = reader.Read(w.data, w.size, last_error);
+ size_t nbytes = reader.Read(w.data, w.size);
if (nbytes == 0) {
- if (gcc_unlikely(last_error.IsDefined()))
- return false;
-
eof = true;
return !need_more;
}
@@ -65,7 +59,7 @@ BufferedReader::ReadLine()
}
} while (Fill(true));
- if (last_error.IsDefined() || !eof || buffer.IsEmpty())
+ if (!eof || buffer.IsEmpty())
return nullptr;
auto w = buffer.Write();
diff --git a/src/fs/io/BufferedReader.hxx b/src/fs/io/BufferedReader.hxx
index a0c42d23c..aa8232100 100644
--- a/src/fs/io/BufferedReader.hxx
+++ b/src/fs/io/BufferedReader.hxx
@@ -23,12 +23,10 @@
#include "check.h"
#include "Compiler.h"
#include "util/DynamicFifoBuffer.hxx"
-#include "util/Error.hxx"
#include <stddef.h>
class Reader;
-class Error;
class BufferedReader {
static constexpr size_t MAX_SIZE = 512 * 1024;
@@ -37,8 +35,6 @@ class BufferedReader {
DynamicFifoBuffer<char> buffer;
- Error last_error;
-
bool eof;
unsigned line_number;
@@ -48,19 +44,6 @@ public:
:reader(_reader), buffer(4096), eof(false),
line_number(0) {}
- gcc_pure
- bool Check() const {
- return !last_error.IsDefined();
- }
-
- bool Check(Error &error) const {
- if (last_error.IsDefined()) {
- error.Set(last_error);
- return false;
- } else
- return true;
- }
-
bool Fill(bool need_more);
gcc_pure
diff --git a/src/fs/io/FileReader.cxx b/src/fs/io/FileReader.cxx
index e54f6f3a8..442ebed5d 100644
--- a/src/fs/io/FileReader.cxx
+++ b/src/fs/io/FileReader.cxx
@@ -20,57 +20,49 @@
#include "config.h"
#include "FileReader.hxx"
#include "fs/FileInfo.hxx"
-#include "util/Error.hxx"
+#include "system/Error.hxx"
#ifdef WIN32
-FileReader::FileReader(Path _path, Error &error)
+FileReader::FileReader(Path _path)
:path(_path),
handle(CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
nullptr))
{
- if (handle == INVALID_HANDLE_VALUE) {
- const auto path_utf8 = path.ToUTF8();
- error.FormatLastError("Failed to open %s", path_utf8.c_str());
- }
+ if (handle == INVALID_HANDLE_VALUE)
+ throw FormatLastError("Failed to open %s", path.ToUTF8().c_str());
}
-bool
-FileReader::GetFileInfo(FileInfo &info, Error &error) const
+FileInfo
+FileReader::GetFileInfo() const
{
assert(IsDefined());
- return ::GetFileInfo(path, info, error);
+ return FileInfo(path);
}
size_t
-FileReader::Read(void *data, size_t size, Error &error)
+FileReader::Read(void *data, size_t size)
{
assert(IsDefined());
DWORD nbytes;
- if (!ReadFile(handle, data, size, &nbytes, nullptr)) {
- const auto path_utf8 = path.ToUTF8();
- error.FormatLastError("Failed to read from %s",
- path_utf8.c_str());
- nbytes = 0;
- }
+ if (!ReadFile(handle, data, size, &nbytes, nullptr))
+ throw FormatLastError("Failed to read from %s",
+ path.ToUTF8().c_str());
return nbytes;
}
-bool
-FileReader::Seek(off_t offset, Error &error)
+void
+FileReader::Seek(off_t offset)
{
assert(IsDefined());
auto result = SetFilePointer(handle, offset, nullptr, FILE_BEGIN);
- const bool success = result != INVALID_SET_FILE_POINTER;
- if (!success)
- error.SetLastError("Failed to seek");
-
- return success;
+ if (result == INVALID_SET_FILE_POINTER)
+ throw MakeLastError("Failed to seek");
}
void
@@ -83,52 +75,49 @@ FileReader::Close()
#else
-FileReader::FileReader(Path _path, Error &error)
+FileReader::FileReader(Path _path)
:path(_path)
{
fd.OpenReadOnly(path.c_str());
if (!fd.IsDefined())
- error.FormatErrno("Failed to open %s", path.c_str());
+ throw FormatErrno("Failed to open %s", path.ToUTF8().c_str());
}
-bool
-FileReader::GetFileInfo(FileInfo &info, Error &error) const
+FileInfo
+FileReader::GetFileInfo() const
{
assert(IsDefined());
+ FileInfo info;
const bool success = fstat(fd.Get(), &info.st) == 0;
if (!success)
- error.FormatErrno("Failed to access %s",
+ throw FormatErrno("Failed to access %s",
path.ToUTF8().c_str());
- return success;
+ return info;
}
size_t
-FileReader::Read(void *data, size_t size, Error &error)
+FileReader::Read(void *data, size_t size)
{
assert(IsDefined());
ssize_t nbytes = fd.Read(data, size);
- if (nbytes < 0) {
- error.FormatErrno("Failed to read from %s", path.c_str());
- nbytes = 0;
- }
+ if (nbytes < 0)
+ throw FormatErrno("Failed to read from %s", path.ToUTF8().c_str());
return nbytes;
}
-bool
-FileReader::Seek(off_t offset, Error &error)
+void
+FileReader::Seek(off_t offset)
{
assert(IsDefined());
auto result = fd.Seek(offset);
const bool success = result >= 0;
if (!success)
- error.SetErrno("Failed to seek");
-
- return success;
+ throw MakeErrno("Failed to seek");
}
void
diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
index 642fc5ed1..ee931592b 100644
--- a/src/fs/io/FileReader.hxx
+++ b/src/fs/io/FileReader.hxx
@@ -48,7 +48,7 @@ class FileReader final : public Reader {
#endif
public:
- FileReader(Path _path, Error &error);
+ FileReader(Path _path);
#ifdef WIN32
FileReader(FileReader &&other)
@@ -70,6 +70,7 @@ public:
}
+protected:
bool IsDefined() const {
#ifdef WIN32
return handle != INVALID_HANDLE_VALUE;
@@ -78,6 +79,7 @@ public:
#endif
}
+public:
#ifndef WIN32
FileDescriptor GetFD() const {
return fd;
@@ -86,12 +88,13 @@ public:
void Close();
- bool GetFileInfo(FileInfo &info, Error &error) const;
+ gcc_pure
+ FileInfo GetFileInfo() const;
- bool Seek(off_t offset, Error &error);
+ void Seek(off_t offset);
/* virtual methods from class Reader */
- size_t Read(void *data, size_t size, Error &error) override;
+ size_t Read(void *data, size_t size) override;
};
#endif
diff --git a/src/fs/io/GunzipReader.cxx b/src/fs/io/GunzipReader.cxx
index 78f5b2c69..d7a0f6c60 100644
--- a/src/fs/io/GunzipReader.cxx
+++ b/src/fs/io/GunzipReader.cxx
@@ -20,10 +20,8 @@
#include "config.h"
#include "GunzipReader.hxx"
#include "lib/zlib/Domain.hxx"
-#include "util/Error.hxx"
-#include "util/Domain.hxx"
-GunzipReader::GunzipReader(Reader &_next, Error &error)
+GunzipReader::GunzipReader(Reader &_next) throw(ZlibError)
:next(_next), eof(false)
{
z.next_in = nullptr;
@@ -33,25 +31,17 @@ GunzipReader::GunzipReader(Reader &_next, Error &error)
z.opaque = Z_NULL;
int result = inflateInit2(&z, 16 + MAX_WBITS);
- if (result != Z_OK) {
- z.opaque = this;
- error.Set(zlib_domain, result, zError(result));
- }
-}
-
-GunzipReader::~GunzipReader()
-{
- if (IsDefined())
- inflateEnd(&z);
+ if (result != Z_OK)
+ throw ZlibError(result);
}
inline bool
-GunzipReader::FillBuffer(Error &error)
+GunzipReader::FillBuffer()
{
auto w = buffer.Write();
assert(!w.IsEmpty());
- size_t nbytes = next.Read(w.data, w.size, error);
+ size_t nbytes = next.Read(w.data, w.size);
if (nbytes == 0)
return false;
@@ -60,7 +50,7 @@ GunzipReader::FillBuffer(Error &error)
}
size_t
-GunzipReader::Read(void *data, size_t size, Error &error)
+GunzipReader::Read(void *data, size_t size)
{
if (eof)
return 0;
@@ -73,10 +63,8 @@ GunzipReader::Read(void *data, size_t size, Error &error)
auto r = buffer.Read();
if (r.IsEmpty()) {
- if (FillBuffer(error))
+ if (FillBuffer())
r = buffer.Read();
- else if (error.IsDefined())
- return 0;
else
flush = Z_FINISH;
}
@@ -88,10 +76,8 @@ GunzipReader::Read(void *data, size_t size, Error &error)
if (result == Z_STREAM_END) {
eof = true;
return size - z.avail_out;
- } else if (result != Z_OK) {
- error.Set(zlib_domain, result, zError(result));
- return 0;
- }
+ } else if (result != Z_OK)
+ throw ZlibError(result);
buffer.Consume(r.size - z.avail_in);
diff --git a/src/fs/io/GunzipReader.hxx b/src/fs/io/GunzipReader.hxx
index 381d1af5e..41d57f190 100644
--- a/src/fs/io/GunzipReader.hxx
+++ b/src/fs/io/GunzipReader.hxx
@@ -23,13 +23,11 @@
#include "check.h"
#include "Reader.hxx"
#include "util/StaticFifoBuffer.hxx"
+#include "lib/zlib/Error.hxx"
#include "Compiler.h"
#include <zlib.h>
-class Error;
-class Domain;
-
/**
* A filter that decompresses data using zlib.
*/
@@ -44,25 +42,19 @@ class GunzipReader final : public Reader {
public:
/**
- * Construct the filter. Call IsDefined() to check whether
- * the constructor has succeeded. If not, #error will hold
- * information about the failure.
+ * Construct the filter.
*/
- GunzipReader(Reader &_next, Error &error);
- ~GunzipReader();
+ GunzipReader(Reader &_next) throw(ZlibError);
- /**
- * Check whether the constructor has succeeded.
- */
- bool IsDefined() const {
- return z.opaque == nullptr;
+ ~GunzipReader() {
+ inflateEnd(&z);
}
/* virtual methods from class Reader */
- virtual size_t Read(void *data, size_t size, Error &error) override;
+ size_t Read(void *data, size_t size) override;
private:
- bool FillBuffer(Error &error);
+ bool FillBuffer();
};
#endif
diff --git a/src/fs/io/PeekReader.cxx b/src/fs/io/PeekReader.cxx
index ec9520a37..b9b15bb5d 100644
--- a/src/fs/io/PeekReader.cxx
+++ b/src/fs/io/PeekReader.cxx
@@ -26,7 +26,7 @@
#include <string.h>
const void *
-PeekReader::Peek(size_t size, Error &error)
+PeekReader::Peek(size_t size)
{
assert(size > 0);
assert(size < sizeof(buffer));
@@ -35,7 +35,7 @@ PeekReader::Peek(size_t size, Error &error)
do {
size_t nbytes = next.Read(buffer + buffer_size,
- size - buffer_size, error);
+ size - buffer_size);
if (nbytes == 0)
return nullptr;
@@ -46,7 +46,7 @@ PeekReader::Peek(size_t size, Error &error)
}
size_t
-PeekReader::Read(void *data, size_t size, Error &error)
+PeekReader::Read(void *data, size_t size)
{
size_t buffer_remaining = buffer_size - buffer_position;
if (buffer_remaining > 0) {
@@ -56,5 +56,5 @@ PeekReader::Read(void *data, size_t size, Error &error)
return nbytes;
}
- return next.Read(data, size, error);
+ return next.Read(data, size);
}
diff --git a/src/fs/io/PeekReader.hxx b/src/fs/io/PeekReader.hxx
index c00ed66be..d8bc6d76a 100644
--- a/src/fs/io/PeekReader.hxx
+++ b/src/fs/io/PeekReader.hxx
@@ -44,10 +44,10 @@ public:
PeekReader(Reader &_next)
:next(_next), buffer_size(0), buffer_position(0) {}
- const void *Peek(size_t size, Error &error);
+ const void *Peek(size_t size);
/* virtual methods from class Reader */
- virtual size_t Read(void *data, size_t size, Error &error) override;
+ virtual size_t Read(void *data, size_t size) override;
};
#endif
diff --git a/src/fs/io/Reader.hxx b/src/fs/io/Reader.hxx
index 657f96ac2..d67e963ee 100644
--- a/src/fs/io/Reader.hxx
+++ b/src/fs/io/Reader.hxx
@@ -25,8 +25,6 @@
#include <stddef.h>
-class Error;
-
/**
* An interface that can read bytes from a stream until the stream
* ends.
@@ -43,10 +41,10 @@ public:
* Read data from the stream.
*
* @return the number of bytes read into the given buffer or 0
- * on error/end-of-stream
+ * on end-of-stream
*/
gcc_nonnull_all
- virtual size_t Read(void *data, size_t size, Error &error) = 0;
+ virtual size_t Read(void *data, size_t size) = 0;
};
#endif
diff --git a/src/fs/io/TextFile.cxx b/src/fs/io/TextFile.cxx
index 9866da08a..edb3b26d8 100644
--- a/src/fs/io/TextFile.cxx
+++ b/src/fs/io/TextFile.cxx
@@ -26,22 +26,18 @@
#include <assert.h>
-TextFile::TextFile(Path path_fs, Error &error)
- :file_reader(new FileReader(path_fs, error)),
+TextFile::TextFile(Path path_fs)
+ :file_reader(new FileReader(path_fs)),
#ifdef ENABLE_ZLIB
- gunzip_reader(file_reader->IsDefined()
- ? new AutoGunzipReader(*file_reader)
- : nullptr),
+ gunzip_reader(new AutoGunzipReader(*file_reader)),
#endif
- buffered_reader(file_reader->IsDefined()
- ? new BufferedReader(*
+ buffered_reader(new BufferedReader(*
#ifdef ENABLE_ZLIB
- gunzip_reader
+ gunzip_reader
#else
- file_reader
+ file_reader
#endif
- )
- : nullptr)
+ ))
{
}
@@ -61,11 +57,3 @@ TextFile::ReadLine()
return buffered_reader->ReadLine();
}
-
-bool
-TextFile::Check(Error &error) const
-{
- assert(buffered_reader != nullptr);
-
- return buffered_reader->Check(error);
-}
diff --git a/src/fs/io/TextFile.hxx b/src/fs/io/TextFile.hxx
index bee9e8c23..49ab2287a 100644
--- a/src/fs/io/TextFile.hxx
+++ b/src/fs/io/TextFile.hxx
@@ -23,10 +23,7 @@
#include "check.h"
#include "Compiler.h"
-#include <stddef.h>
-
class Path;
-class Error;
class FileReader;
class AutoGunzipReader;
class BufferedReader;
@@ -41,32 +38,20 @@ class TextFile {
BufferedReader *const buffered_reader;
public:
- TextFile(Path path_fs, Error &error);
+ TextFile(Path path_fs);
TextFile(const TextFile &other) = delete;
~TextFile();
- bool HasFailed() const {
- return gcc_unlikely(buffered_reader == nullptr);
- }
-
/**
* Reads a line from the input file, and strips trailing
* space. There is a reasonable maximum line length, only to
* prevent denial of service.
*
- * Use Check() after nullptr has been returned to check
- * whether an error occurred or end-of-file has been reached.
- *
- * @return a pointer to the line, or nullptr on end-of-file or error
+ * @return a pointer to the line, or nullptr on end-of-file
*/
char *ReadLine();
-
- /**
- * Check whether a ReadLine() call has thrown an error.
- */
- bool Check(Error &error) const;
};
#endif
diff --git a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx
index aa4676470..65fc830dd 100644
--- a/src/input/plugins/FileInputPlugin.cxx
+++ b/src/input/plugins/FileInputPlugin.cxx
@@ -61,14 +61,10 @@ InputStream *
OpenFileInputStream(Path path,
Mutex &mutex, Cond &cond,
Error &error)
-{
- FileReader reader(path, error);
- if (!reader.IsDefined())
- return nullptr;
+try {
+ FileReader reader(path);
- FileInfo info;
- if (!reader.GetFileInfo(info, error))
- return nullptr;
+ const FileInfo info = reader.GetFileInfo();
if (!info.IsRegular()) {
error.Format(file_domain, "Not a regular file: %s",
@@ -84,6 +80,9 @@ OpenFileInputStream(Path path,
return new FileInputStream(path.ToUTF8().c_str(),
std::move(reader), info.GetSize(),
mutex, cond);
+} catch (const std::exception &e) {
+ error.Set(e);
+ return nullptr;
}
static InputStream *
@@ -98,23 +97,24 @@ input_file_open(gcc_unused const char *filename,
bool
FileInputStream::Seek(offset_type new_offset, Error &error)
-{
- if (!reader.Seek((off_t)new_offset, error))
- return false;
-
+try {
+ reader.Seek((off_t)new_offset);
offset = new_offset;
return true;
+} catch (const std::exception &e) {
+ error.Set(e);
+ return false;
}
size_t
FileInputStream::Read(void *ptr, size_t read_size, Error &error)
-{
- ssize_t nbytes = reader.Read(ptr, read_size, error);
- if (nbytes < 0)
- return 0;
-
+try {
+ size_t nbytes = reader.Read(ptr, read_size);
offset += nbytes;
- return (size_t)nbytes;
+ return nbytes;
+} catch (const std::exception &e) {
+ error.Set(e);
+ return 0;
}
const InputPlugin input_plugin_file = {
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx
index 034428d88..f3d5454fc 100644
--- a/test/DumpDatabase.cxx
+++ b/test/DumpDatabase.cxx
@@ -110,10 +110,7 @@ try {
config_global_init();
Error error;
- if (!ReadConfigFile(config_path, error)) {
- cerr << error.GetMessage() << endl;
- return EXIT_FAILURE;
- }
+ ReadConfigFile(config_path);
TagLoadConfig();
diff --git a/test/dump_playlist.cxx b/test/dump_playlist.cxx
index 65e980b21..b6659849a 100644
--- a/test/dump_playlist.cxx
+++ b/test/dump_playlist.cxx
@@ -65,10 +65,7 @@ try {
config_global_init();
Error error;
- if (!ReadConfigFile(config_path, error)) {
- LogError(error);
- return EXIT_FAILURE;
- }
+ ReadConfigFile(config_path);
const ScopeIOThread io_thread;
diff --git a/test/read_conf.cxx b/test/read_conf.cxx
index 4d0fadcc6..a62c20d2c 100644
--- a/test/read_conf.cxx
+++ b/test/read_conf.cxx
@@ -20,7 +20,6 @@
#include "config.h"
#include "config/ConfigGlobal.hxx"
#include "fs/Path.hxx"
-#include "util/Error.hxx"
#include "Log.hxx"
#include <assert.h>
@@ -39,11 +38,7 @@ try {
config_global_init();
- Error error;
- if (!ReadConfigFile(config_path, error)) {
- LogError(error);
- return EXIT_FAILURE;
- }
+ ReadConfigFile(config_path);
ConfigOption option = ParseConfigOptionName(name);
const char *value = option != ConfigOption::MAX
diff --git a/test/run_filter.cxx b/test/run_filter.cxx
index 912bc6470..367d474ae 100644
--- a/test/run_filter.cxx
+++ b/test/run_filter.cxx
@@ -69,7 +69,6 @@ load_filter(const char *name)
int main(int argc, char **argv)
try {
struct audio_format_string af_string;
- Error error2;
char buffer[4096];
if (argc < 3 || argc > 4) {
@@ -84,8 +83,7 @@ try {
/* read configuration file (mpd.conf) */
config_global_init();
- if (!ReadConfigFile(config_path, error2))
- FatalError(error2);
+ ReadConfigFile(config_path);
/* parse the audio format */
diff --git a/test/run_gunzip.cxx b/test/run_gunzip.cxx
index 114fab3e5..469b68ba5 100644
--- a/test/run_gunzip.cxx
+++ b/test/run_gunzip.cxx
@@ -28,32 +28,32 @@
#include <stdlib.h>
#include <unistd.h>
-static bool
-Copy(OutputStream &dest, Reader &src, Error &error)
+static void
+Copy(OutputStream &dest, Reader &src)
{
while (true) {
char buffer[4096];
- size_t nbytes = src.Read(buffer, sizeof(buffer), error);
+ size_t nbytes = src.Read(buffer, sizeof(buffer));
if (nbytes == 0)
- return !error.IsDefined();
+ break;
dest.Write(buffer, nbytes);
}
}
-static bool
-CopyGunzip(OutputStream &dest, Reader &_src, Error &error)
+static void
+CopyGunzip(OutputStream &dest, Reader &_src)
{
- GunzipReader src(_src, error);
- return src.IsDefined() && Copy(dest, src, error);
+ GunzipReader src(_src);
+ Copy(dest, src);
}
-static bool
-CopyGunzip(FILE *_dest, Path src_path, Error &error)
+static void
+CopyGunzip(FILE *_dest, Path src_path)
{
StdioOutputStream dest(_dest);
- FileReader src(src_path, error);
- return src.IsDefined() && CopyGunzip(dest, src, error);
+ FileReader src(src_path);
+ CopyGunzip(dest, src);
}
int
@@ -67,12 +67,7 @@ main(int argc, gcc_unused char **argv)
Path path = Path::FromFS(argv[1]);
try {
- Error error;
- if (!CopyGunzip(stdout, path, error)) {
- fprintf(stderr, "%s\n", error.GetMessage());
- return EXIT_FAILURE;
- }
-
+ CopyGunzip(stdout, path);
return EXIT_SUCCESS;
} catch (const std::exception &e) {
LogError(e);
diff --git a/test/run_neighbor_explorer.cxx b/test/run_neighbor_explorer.cxx
index 3f48ee06f..29ea7b56e 100644
--- a/test/run_neighbor_explorer.cxx
+++ b/test/run_neighbor_explorer.cxx
@@ -59,10 +59,7 @@ try {
Error error;
config_global_init();
- if (!ReadConfigFile(config_path, error)) {
- LogError(error);
- return EXIT_FAILURE;
- }
+ ReadConfigFile(config_path);
/* initialize the core */
diff --git a/test/run_output.cxx b/test/run_output.cxx
index f8f959a07..b9fec7961 100644
--- a/test/run_output.cxx
+++ b/test/run_output.cxx
@@ -161,10 +161,7 @@ try {
/* read configuration file (mpd.conf) */
config_global_init();
- if (!ReadConfigFile(config_path, error)) {
- LogError(error);
- return EXIT_FAILURE;
- }
+ ReadConfigFile(config_path);
EventLoop event_loop;