summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/PlaylistFile.cxx7
-rw-r--r--src/PlaylistSave.cxx4
-rw-r--r--src/StateFile.cxx13
-rw-r--r--src/StateFile.hxx2
-rw-r--r--src/db/plugins/simple/DirectorySave.cxx3
-rw-r--r--src/db/plugins/simple/SimpleDatabasePlugin.cxx14
-rw-r--r--src/db/plugins/simple/SimpleDatabasePlugin.hxx2
-rw-r--r--src/db/update/Service.cxx4
-rw-r--r--src/encoder/ToOutputStream.cxx9
-rw-r--r--src/encoder/ToOutputStream.hxx5
-rw-r--r--src/fs/io/BufferedOutputStream.cxx63
-rw-r--r--src/fs/io/BufferedOutputStream.hxx40
-rw-r--r--src/fs/io/FileOutputStream.cxx45
-rw-r--r--src/fs/io/FileOutputStream.hxx2
-rw-r--r--src/fs/io/GzipOutputStream.cxx37
-rw-r--r--src/fs/io/GzipOutputStream.hxx6
-rw-r--r--src/fs/io/OutputStream.hxx8
-rw-r--r--src/fs/io/StdioOutputStream.hxx5
-rw-r--r--src/output/plugins/RecorderOutputPlugin.cxx60
19 files changed, 122 insertions, 207 deletions
diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx
index c90af9760..d0af1c7f5 100644
--- a/src/PlaylistFile.cxx
+++ b/src/PlaylistFile.cxx
@@ -239,8 +239,7 @@ SavePlaylistFile(const PlaylistFileContents &contents, const char *utf8path,
for (const auto &uri_utf8 : contents)
playlist_print_uri(bos, uri_utf8.c_str());
- if (!bos.Flush(error))
- return false;
+ bos.Flush();
fos.Commit();
return true;
@@ -415,9 +414,7 @@ spl_append_song(const char *utf8path, const DetachedSong &song, Error &error)
playlist_print_song(bos, song);
- if (!bos.Flush(error))
- return false;
-
+ bos.Flush();
fos.Commit();
idle_add(IDLE_STORED_PLAYLIST);
diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx
index d83ceb2b7..9ed4d832b 100644
--- a/src/PlaylistSave.cxx
+++ b/src/PlaylistSave.cxx
@@ -86,9 +86,7 @@ spl_save_queue(const char *name_utf8, const Queue &queue, Error &error)
for (unsigned i = 0; i < queue.GetLength(); i++)
playlist_print_song(bos, queue.Get(i));
- if (!bos.Flush(error))
- return false;
-
+ bos.Flush();
fos.Commit();
idle_add(IDLE_STORED_PLAYLIST);
diff --git a/src/StateFile.cxx b/src/StateFile.cxx
index 7c92ae0ee..fb031d04b 100644
--- a/src/StateFile.cxx
+++ b/src/StateFile.cxx
@@ -75,12 +75,12 @@ StateFile::Write(BufferedOutputStream &os)
playlist_state_save(os, partition.playlist, partition.pc);
}
-inline bool
-StateFile::Write(OutputStream &os, Error &error)
+inline void
+StateFile::Write(OutputStream &os)
{
BufferedOutputStream bos(os);
Write(bos);
- return bos.Flush(error);
+ bos.Flush();
}
void
@@ -90,13 +90,8 @@ StateFile::Write()
"Saving state file %s", path_utf8.c_str());
try {
- Error error;
FileOutputStream fos(path);
- if (!Write(fos, error)) {
- LogError(error);
- return;
- }
-
+ Write(fos);
fos.Commit();
} catch (const std::exception &e) {
LogError(e);
diff --git a/src/StateFile.hxx b/src/StateFile.hxx
index b96b89dfb..4157552fd 100644
--- a/src/StateFile.hxx
+++ b/src/StateFile.hxx
@@ -60,7 +60,7 @@ public:
void CheckModified();
private:
- bool Write(OutputStream &os, Error &error);
+ void Write(OutputStream &os);
void Write(BufferedOutputStream &os);
/**
diff --git a/src/db/plugins/simple/DirectorySave.cxx b/src/db/plugins/simple/DirectorySave.cxx
index 868507c67..017854c6d 100644
--- a/src/db/plugins/simple/DirectorySave.cxx
+++ b/src/db/plugins/simple/DirectorySave.cxx
@@ -90,9 +90,6 @@ directory_save(BufferedOutputStream &os, const Directory &directory)
if (!child.IsMount())
directory_save(os, child);
-
- if (!os.Check())
- return;
}
for (const auto &song : directory.songs)
diff --git a/src/db/plugins/simple/SimpleDatabasePlugin.cxx b/src/db/plugins/simple/SimpleDatabasePlugin.cxx
index aa62870c6..113e9b321 100644
--- a/src/db/plugins/simple/SimpleDatabasePlugin.cxx
+++ b/src/db/plugins/simple/SimpleDatabasePlugin.cxx
@@ -364,8 +364,8 @@ SimpleDatabase::GetStats(const DatabaseSelection &selection,
return ::GetStats(*this, selection, stats, error);
}
-bool
-SimpleDatabase::Save(Error &error)
+void
+SimpleDatabase::Save()
{
{
const ScopeDatabaseLock protect;
@@ -395,16 +395,12 @@ SimpleDatabase::Save(Error &error)
db_save_internal(bos, *root);
- if (!bos.Flush(error)) {
- return false;
- }
+ bos.Flush();
#ifdef ENABLE_ZLIB
if (gzip != nullptr) {
- bool success = gzip->Flush(error);
+ gzip->Flush();
gzip.reset();
- if (!success)
- return false;
}
#endif
@@ -413,8 +409,6 @@ SimpleDatabase::Save(Error &error)
FileInfo fi;
if (GetFileInfo(path, fi))
mtime = fi.GetModificationTime();
-
- return true;
}
bool
diff --git a/src/db/plugins/simple/SimpleDatabasePlugin.hxx b/src/db/plugins/simple/SimpleDatabasePlugin.hxx
index 7a28099d9..438bd1280 100644
--- a/src/db/plugins/simple/SimpleDatabasePlugin.hxx
+++ b/src/db/plugins/simple/SimpleDatabasePlugin.hxx
@@ -83,7 +83,7 @@ public:
return *root;
}
- bool Save(Error &error);
+ void Save();
/**
* Returns true if there is a valid database file on the disk.
diff --git a/src/db/update/Service.cxx b/src/db/update/Service.cxx
index f1dc581d8..9d02ee60d 100644
--- a/src/db/update/Service.cxx
+++ b/src/db/update/Service.cxx
@@ -130,9 +130,7 @@ UpdateService::Task()
if (modified || !next.db->FileExists()) {
try {
- Error error;
- if (!next.db->Save(error))
- LogError(error, "Failed to save database");
+ next.db->Save();
} catch (const std::exception &e) {
LogError(e, "Failed to save database");
}
diff --git a/src/encoder/ToOutputStream.cxx b/src/encoder/ToOutputStream.cxx
index 43345cf70..0d2cfc96c 100644
--- a/src/encoder/ToOutputStream.cxx
+++ b/src/encoder/ToOutputStream.cxx
@@ -22,8 +22,8 @@
#include "EncoderInterface.hxx"
#include "fs/io/OutputStream.hxx"
-bool
-EncoderToOutputStream(OutputStream &os, Encoder &encoder, Error &error)
+void
+EncoderToOutputStream(OutputStream &os, Encoder &encoder)
{
while (true) {
/* read from the encoder */
@@ -31,11 +31,10 @@ EncoderToOutputStream(OutputStream &os, Encoder &encoder, Error &error)
char buffer[32768];
size_t nbytes = encoder_read(&encoder, buffer, sizeof(buffer));
if (nbytes == 0)
- return true;
+ return;
/* write everything to the stream */
- if (!os.Write(buffer, nbytes, error))
- return false;
+ os.Write(buffer, nbytes);
}
}
diff --git a/src/encoder/ToOutputStream.hxx b/src/encoder/ToOutputStream.hxx
index e3fb7b908..d87295d89 100644
--- a/src/encoder/ToOutputStream.hxx
+++ b/src/encoder/ToOutputStream.hxx
@@ -24,9 +24,8 @@
struct Encoder;
class OutputStream;
-class Error;
-bool
-EncoderToOutputStream(OutputStream &os, Encoder &encoder, Error &error);
+void
+EncoderToOutputStream(OutputStream &os, Encoder &encoder);
#endif
diff --git a/src/fs/io/BufferedOutputStream.cxx b/src/fs/io/BufferedOutputStream.cxx
index 2268eb50c..ec727ae19 100644
--- a/src/fs/io/BufferedOutputStream.cxx
+++ b/src/fs/io/BufferedOutputStream.cxx
@@ -26,7 +26,7 @@
#include <stdio.h>
bool
-BufferedOutputStream::AppendToBuffer(const void *data, size_t size)
+BufferedOutputStream::AppendToBuffer(const void *data, size_t size) noexcept
{
auto r = buffer.Write();
if (r.size < size)
@@ -37,46 +37,36 @@ BufferedOutputStream::AppendToBuffer(const void *data, size_t size)
return true;
}
-bool
+void
BufferedOutputStream::Write(const void *data, size_t size)
{
- if (gcc_unlikely(last_error.IsDefined()))
- /* the stream has already failed */
- return false;
-
/* try to append to the current buffer */
if (AppendToBuffer(data, size))
- return true;
+ return;
/* not enough room in the buffer - flush it */
- if (!Flush())
- return false;
+ Flush();
/* see if there's now enough room */
if (AppendToBuffer(data, size))
- return true;
+ return;
/* too large for the buffer: direct write */
- return os.Write(data, size, last_error);
+ os.Write(data, size);
}
-bool
+void
BufferedOutputStream::Write(const char *p)
{
- return Write(p, strlen(p));
+ Write(p, strlen(p));
}
-bool
+void
BufferedOutputStream::Format(const char *fmt, ...)
{
- if (gcc_unlikely(last_error.IsDefined()))
- return false;
-
auto r = buffer.Write();
if (r.IsEmpty()) {
- if (!Flush())
- return false;
-
+ Flush();
r = buffer.Write();
}
@@ -90,8 +80,7 @@ BufferedOutputStream::Format(const char *fmt, ...)
/* buffer was not large enough; flush it and try
again */
- if (!Flush())
- return false;
+ Flush();
r = buffer.Write();
@@ -112,37 +101,15 @@ BufferedOutputStream::Format(const char *fmt, ...)
}
buffer.Append(size);
- return true;
}
-bool
+void
BufferedOutputStream::Flush()
{
- if (!Check())
- return false;
-
- auto r = buffer.Read();
- if (r.IsEmpty())
- return true;
-
- bool success = os.Write(r.data, r.size, last_error);
- if (gcc_likely(success))
- buffer.Consume(r.size);
- return success;
-}
-
-bool
-BufferedOutputStream::Flush(Error &error)
-{
- if (!Check(error))
- return false;
-
auto r = buffer.Read();
if (r.IsEmpty())
- return true;
+ return;
- bool success = os.Write(r.data, r.size, error);
- if (gcc_likely(success))
- buffer.Consume(r.size);
- return success;
+ os.Write(r.data, r.size);
+ buffer.Consume(r.size);
}
diff --git a/src/fs/io/BufferedOutputStream.hxx b/src/fs/io/BufferedOutputStream.hxx
index 63a3f4aee..9e4a18a52 100644
--- a/src/fs/io/BufferedOutputStream.hxx
+++ b/src/fs/io/BufferedOutputStream.hxx
@@ -23,67 +23,37 @@
#include "check.h"
#include "Compiler.h"
#include "util/DynamicFifoBuffer.hxx"
-#include "util/Error.hxx"
#include <stddef.h>
class OutputStream;
-class Error;
/**
* An #OutputStream wrapper that buffers its output to reduce the
* number of OutputStream::Write() calls.
- *
- * It simplifies error handling by managing an #Error attribute.
- * Invoke any number of writes, and check for errors in the end using
- * Check().
*/
class BufferedOutputStream {
OutputStream &os;
DynamicFifoBuffer<char> buffer;
- Error last_error;
-
public:
BufferedOutputStream(OutputStream &_os)
:os(_os), buffer(32768) {}
- bool Write(const void *data, size_t size);
- bool Write(const char *p);
+ void Write(const void *data, size_t size);
+ void Write(const char *p);
gcc_printf(2,3)
- bool Format(const char *fmt, ...);
-
- /**
- * Returns false if an error has occurred.
- */
- gcc_pure
- bool Check() const {
- return !last_error.IsDefined();
- }
-
- /**
- * Returns false if an error has occurred. In that case, a
- * copy of the #Error is returned.
- */
- bool Check(Error &error) const {
- if (last_error.IsDefined()) {
- error.Set(last_error);
- return false;
- } else
- return true;
- }
+ void Format(const char *fmt, ...);
/**
* Write buffer contents to the #OutputStream.
*/
- bool Flush();
-
- bool Flush(Error &error);
+ void Flush();
private:
- bool AppendToBuffer(const void *data, size_t size);
+ bool AppendToBuffer(const void *data, size_t size) noexcept;
};
#endif
diff --git a/src/fs/io/FileOutputStream.cxx b/src/fs/io/FileOutputStream.cxx
index d0b1edd56..8eabaa313 100644
--- a/src/fs/io/FileOutputStream.cxx
+++ b/src/fs/io/FileOutputStream.cxx
@@ -21,9 +21,6 @@
#include "FileOutputStream.hxx"
#include "fs/FileSystem.hxx"
#include "system/Error.hxx"
-#include "util/Error.hxx"
-
-#include <system_error>
#ifdef WIN32
@@ -50,26 +47,19 @@ BaseFileOutputStream::Tell() const
return uint64_t(high) << 32 | uint64_t(low);
}
-bool
-BaseFileOutputStream::Write(const void *data, size_t size, Error &error)
+void
+BaseFileOutputStream::Write(const void *data, size_t size)
{
assert(IsDefined());
DWORD nbytes;
- if (!WriteFile(handle, data, size, &nbytes, nullptr)) {
- error.FormatLastError("Failed to write to %s",
- path.ToUTF8().c_str());
- return false;
- }
-
- if (size_t(nbytes) != size) {
- error.FormatLastError(ERROR_DISK_FULL,
- "Failed to write to %s",
- path.ToUTF8().c_str());
- return false;
- }
+ if (!WriteFile(handle, data, size, &nbytes, nullptr))
+ throw FormatLastError("Failed to write to %s",
+ GetPath().c_str());
- return true;
+ if (size_t(nbytes) != size)
+ throw FormatLastError(ERROR_DISK_FULL, "Failed to write to %s",
+ GetPath().c_str());
}
void
@@ -143,22 +133,17 @@ BaseFileOutputStream::Tell() const
return fd.Tell();
}
-bool
-BaseFileOutputStream::Write(const void *data, size_t size, Error &error)
+void
+BaseFileOutputStream::Write(const void *data, size_t size)
{
assert(IsDefined());
ssize_t nbytes = fd.Write(data, size);
- if (nbytes < 0) {
- error.FormatErrno("Failed to write to %s", GetPath().c_str());
- return false;
- } else if ((size_t)nbytes < size) {
- error.FormatErrno(ENOSPC,
- "Failed to write to %s", GetPath().c_str());
- return false;
- }
-
- return true;
+ if (nbytes < 0)
+ throw FormatErrno("Failed to write to %s", GetPath().c_str());
+ else if ((size_t)nbytes < size)
+ throw FormatErrno(ENOSPC, "Failed to write to %s",
+ GetPath().c_str());
}
void
diff --git a/src/fs/io/FileOutputStream.hxx b/src/fs/io/FileOutputStream.hxx
index 0cf8bfc4d..00bd77d9f 100644
--- a/src/fs/io/FileOutputStream.hxx
+++ b/src/fs/io/FileOutputStream.hxx
@@ -119,7 +119,7 @@ public:
uint64_t Tell() const;
/* virtual methods from class OutputStream */
- bool Write(const void *data, size_t size, Error &error) override;
+ void Write(const void *data, size_t size) override;
};
class FileOutputStream final : public BaseFileOutputStream {
diff --git a/src/fs/io/GzipOutputStream.cxx b/src/fs/io/GzipOutputStream.cxx
index e903aaaa3..a4cccf298 100644
--- a/src/fs/io/GzipOutputStream.cxx
+++ b/src/fs/io/GzipOutputStream.cxx
@@ -21,7 +21,6 @@
#include "GzipOutputStream.hxx"
#include "lib/zlib/Domain.hxx"
#include "lib/zlib/Error.hxx"
-#include "util/Error.hxx"
GzipOutputStream::GzipOutputStream(OutputStream &_next) throw(ZlibError)
:next(_next)
@@ -47,8 +46,8 @@ GzipOutputStream::~GzipOutputStream()
deflateEnd(&z);
}
-bool
-GzipOutputStream::Flush(Error &error)
+void
+GzipOutputStream::Flush()
{
/* no more input */
z.next_in = nullptr;
@@ -60,21 +59,18 @@ GzipOutputStream::Flush(Error &error)
z.avail_out = sizeof(output);
int result = deflate(&z, Z_FINISH);
- if (z.next_out > output &&
- !next.Write(output, z.next_out - output, error))
- return false;
+ if (z.next_out > output)
+ next.Write(output, z.next_out - output);
if (result == Z_STREAM_END)
- return true;
- else if (result != Z_OK) {
- error.Set(zlib_domain, result, zError(result));
- return false;
- }
- }
+ break;
+ else if (result != Z_OK)
+ throw ZlibError(result);
+ }
}
-bool
-GzipOutputStream::Write(const void *_data, size_t size, Error &error)
+void
+GzipOutputStream::Write(const void *_data, size_t size)
{
/* zlib's API requires non-const input pointer */
void *data = const_cast<void *>(_data);
@@ -88,15 +84,10 @@ GzipOutputStream::Write(const void *_data, size_t size, Error &error)
z.avail_out = sizeof(output);
int result = deflate(&z, Z_NO_FLUSH);
- if (result != Z_OK) {
- error.Set(zlib_domain, result, zError(result));
- return false;
- }
+ if (result != Z_OK)
+ throw ZlibError(result);
- if (z.next_out > output &&
- !next.Write(output, z.next_out - output, error))
- return false;
+ if (z.next_out > output)
+ next.Write(output, z.next_out - output);
}
-
- return true;
}
diff --git a/src/fs/io/GzipOutputStream.hxx b/src/fs/io/GzipOutputStream.hxx
index 700a69354..dbf509ecc 100644
--- a/src/fs/io/GzipOutputStream.hxx
+++ b/src/fs/io/GzipOutputStream.hxx
@@ -28,8 +28,6 @@
#include <assert.h>
#include <zlib.h>
-class Error;
-
/**
* A filter that compresses data written to it using zlib, forwarding
* compressed data in the "gzip" format.
@@ -52,10 +50,10 @@ public:
* Finish the file and write all data remaining in zlib's
* output buffer.
*/
- bool Flush(Error &error);
+ void Flush();
/* virtual methods from class OutputStream */
- bool Write(const void *data, size_t size, Error &error) override;
+ void Write(const void *data, size_t size) override;
};
#endif
diff --git a/src/fs/io/OutputStream.hxx b/src/fs/io/OutputStream.hxx
index f7d101180..f2eda1ecd 100644
--- a/src/fs/io/OutputStream.hxx
+++ b/src/fs/io/OutputStream.hxx
@@ -21,18 +21,18 @@
#define MPD_OUTPUT_STREAM_HXX
#include "check.h"
-#include "Compiler.h"
#include <stddef.h>
-class Error;
-
class OutputStream {
public:
OutputStream() = default;
OutputStream(const OutputStream &) = delete;
- virtual bool Write(const void *data, size_t size, Error &error) = 0;
+ /**
+ * Throws std::exception on error.
+ */
+ virtual void Write(const void *data, size_t size) = 0;
};
#endif
diff --git a/src/fs/io/StdioOutputStream.hxx b/src/fs/io/StdioOutputStream.hxx
index 88dbe6f00..99a32a052 100644
--- a/src/fs/io/StdioOutputStream.hxx
+++ b/src/fs/io/StdioOutputStream.hxx
@@ -22,7 +22,6 @@
#include "check.h"
#include "OutputStream.hxx"
-#include "fs/AllocatedPath.hxx"
#include "Compiler.h"
#include <stdio.h>
@@ -34,12 +33,10 @@ public:
StdioOutputStream(FILE *_file):file(_file) {}
/* virtual methods from class OutputStream */
- bool Write(const void *data, size_t size,
- gcc_unused Error &error) override {
+ void Write(const void *data, size_t size) override {
fwrite(data, 1, size, file);
/* this class is debug-only and ignores errors */
- return true;
}
};
diff --git a/src/output/plugins/RecorderOutputPlugin.cxx b/src/output/plugins/RecorderOutputPlugin.cxx
index 562e36f87..cab303641 100644
--- a/src/output/plugins/RecorderOutputPlugin.cxx
+++ b/src/output/plugins/RecorderOutputPlugin.cxx
@@ -95,7 +95,7 @@ class RecorderOutput {
/**
* Writes pending data from the encoder to the output file.
*/
- bool EncoderToFile(Error &error);
+ void EncoderToFile();
void SendTag(const Tag &tag);
@@ -175,12 +175,12 @@ RecorderOutput::Create(const ConfigBlock &block, Error &error)
return recorder;
}
-inline bool
-RecorderOutput::EncoderToFile(Error &error)
+inline void
+RecorderOutput::EncoderToFile()
{
assert(file != nullptr);
- return EncoderToOutputStream(*file, *encoder, error);
+ EncoderToOutputStream(*file, *encoder);
}
inline bool
@@ -213,9 +213,11 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
}
if (!HasDynamicPath()) {
- if (!EncoderToFile(error)) {
+ try {
+ EncoderToFile();
+ } catch (const std::exception &e) {
encoder->Close();
- delete file;
+ error.Set(recorder_domain, e.what());
return false;
}
} else {
@@ -237,8 +239,15 @@ RecorderOutput::Commit(Error &error)
/* flush the encoder and write the rest to the file */
- bool success = encoder_end(encoder, error) &&
- EncoderToFile(error);
+ bool success = encoder_end(encoder, error);
+ if (success) {
+ try {
+ EncoderToFile();
+ } catch (...) {
+ encoder->Close();
+ throw;
+ }
+ }
/* now really close everything */
@@ -328,9 +337,12 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
AudioFormat as before */
assert(new_audio_format == effective_audio_format);
- if (!EncoderToOutputStream(*new_file, *encoder, error)) {
+ try {
+ EncoderToOutputStream(*new_file, *encoder);
+ } catch (const std::exception &e) {
encoder->Close();
delete new_file;
+ error.Set(recorder_domain, e.what());
return false;
}
@@ -376,9 +388,19 @@ RecorderOutput::SendTag(const Tag &tag)
}
Error error;
- if (!encoder_pre_tag(encoder, error) ||
- !EncoderToFile(error) ||
- !encoder_tag(encoder, tag, error))
+ if (!encoder_pre_tag(encoder, error)) {
+ LogError(error);
+ return;
+ }
+
+ try {
+ EncoderToFile();
+ } catch (const std::exception &e) {
+ LogError(e);
+ return;
+ }
+
+ if (!encoder_tag(encoder, tag, error))
LogError(error);
}
@@ -393,9 +415,17 @@ RecorderOutput::Play(const void *chunk, size_t size, Error &error)
return size;
}
- return encoder_write(encoder, chunk, size, error) &&
- EncoderToFile(error)
- ? size : 0;
+ if (!encoder_write(encoder, chunk, size, error))
+ return 0;
+
+ try {
+ EncoderToFile();
+ } catch (const std::exception &e) {
+ error.Set(recorder_domain, e.what());
+ return 0;
+ }
+
+ return size;
}
typedef AudioOutputWrapper<RecorderOutput> Wrapper;