diff options
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; |