output/recorder: migrate from class Error to C++ exceptions

This commit is contained in:
Max Kellermann 2016-11-07 09:16:43 +01:00
parent d8b6aff23a
commit dd9ab16d67

View File

@ -31,7 +31,7 @@
#include "Log.hxx" #include "Log.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "fs/io/FileOutputStream.hxx" #include "fs/io/FileOutputStream.hxx"
#include "util/Error.hxx" #include "util/RuntimeError.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
@ -75,21 +75,14 @@ class RecorderOutput {
*/ */
FileOutputStream *file; FileOutputStream *file;
RecorderOutput() RecorderOutput(const ConfigBlock &block);
:base(recorder_output_plugin) {}
~RecorderOutput() { ~RecorderOutput() {
delete prepared_encoder; delete prepared_encoder;
} }
bool Initialize(const ConfigBlock &block, Error &error_r) {
return base.Configure(block, error_r);
}
static RecorderOutput *Create(const ConfigBlock &block, Error &error); static RecorderOutput *Create(const ConfigBlock &block, Error &error);
bool Configure(const ConfigBlock &block, Error &error);
bool Open(AudioFormat &audio_format, Error &error); bool Open(AudioFormat &audio_format, Error &error);
void Close(); void Close();
@ -116,22 +109,19 @@ private:
void Commit(); void Commit();
void FinishFormat(); void FinishFormat();
bool ReopenFormat(AllocatedPath &&new_path, Error &error); void ReopenFormat(AllocatedPath &&new_path);
}; };
inline bool RecorderOutput::RecorderOutput(const ConfigBlock &block)
RecorderOutput::Configure(const ConfigBlock &block, Error &error) :base(recorder_output_plugin, block)
{ {
/* read configuration */ /* read configuration */
const char *encoder_name = const char *encoder_name =
block.GetBlockValue("encoder", "vorbis"); block.GetBlockValue("encoder", "vorbis");
const auto encoder_plugin = encoder_plugin_get(encoder_name); const auto encoder_plugin = encoder_plugin_get(encoder_name);
if (encoder_plugin == nullptr) { if (encoder_plugin == nullptr)
error.Format(config_domain, throw FormatRuntimeError("No such encoder: %s", encoder_name);
"No such encoder: %s", encoder_name);
return false;
}
path = block.GetPath("path"); path = block.GetPath("path");
@ -139,44 +129,21 @@ RecorderOutput::Configure(const ConfigBlock &block, Error &error)
if (fmt != nullptr) if (fmt != nullptr)
format_path = fmt; format_path = fmt;
if (path.IsNull() && fmt == nullptr) { if (path.IsNull() && fmt == nullptr)
error.Set(config_domain, "'path' not configured"); throw std::runtime_error("'path' not configured");
return false;
}
if (!path.IsNull() && fmt != nullptr) { if (!path.IsNull() && fmt != nullptr)
error.Set(config_domain, "Cannot have both 'path' and 'format_path'"); throw std::runtime_error("Cannot have both 'path' and 'format_path'");
return false;
}
/* initialize encoder */ /* initialize encoder */
prepared_encoder = encoder_init(*encoder_plugin, block); prepared_encoder = encoder_init(*encoder_plugin, block);
return true;
} }
RecorderOutput * RecorderOutput *
RecorderOutput::Create(const ConfigBlock &block, Error &error) RecorderOutput::Create(const ConfigBlock &block, Error &)
{ {
RecorderOutput *recorder = new RecorderOutput(); return new RecorderOutput(block);
try {
if (!recorder->Initialize(block, error)) {
delete recorder;
return nullptr;
}
if (!recorder->Configure(block, error)) {
delete recorder;
return nullptr;
}
} catch (...) {
delete recorder;
throw;
}
return recorder;
} }
inline void inline void
@ -188,19 +155,14 @@ RecorderOutput::EncoderToFile()
} }
inline bool inline bool
RecorderOutput::Open(AudioFormat &audio_format, Error &error) RecorderOutput::Open(AudioFormat &audio_format, Error &)
{ {
/* create the output file */ /* create the output file */
if (!HasDynamicPath()) { if (!HasDynamicPath()) {
assert(!path.IsNull()); assert(!path.IsNull());
try { file = new FileOutputStream(path);
file = new FileOutputStream(path);
} catch (const std::exception &e) {
error.Set(recorder_domain, e.what());
return false;
}
} else { } else {
/* don't open the file just yet; wait until we have /* don't open the file just yet; wait until we have
a tag that we can use to build the path */ a tag that we can use to build the path */
@ -221,10 +183,9 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
if (!HasDynamicPath()) { if (!HasDynamicPath()) {
try { try {
EncoderToFile(); EncoderToFile();
} catch (const std::exception &e) { } catch (const std::runtime_error &) {
delete encoder; delete encoder;
error.Set(recorder_domain, e.what()); throw;
return false;
} }
} else { } else {
/* remember the AudioFormat for ReopenFormat() */ /* remember the AudioFormat for ReopenFormat() */
@ -308,20 +269,14 @@ RecorderOutput::FinishFormat()
path.SetNull(); path.SetNull();
} }
inline bool inline void
RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error) RecorderOutput::ReopenFormat(AllocatedPath &&new_path)
{ {
assert(HasDynamicPath()); assert(HasDynamicPath());
assert(path.IsNull()); assert(path.IsNull());
assert(file == nullptr); assert(file == nullptr);
FileOutputStream *new_file; FileOutputStream *new_file = new FileOutputStream(path);
try {
new_file = new FileOutputStream(path);
} catch (const std::exception &e) {
error.Set(recorder_domain, e.what());
return false;
}
AudioFormat new_audio_format = effective_audio_format; AudioFormat new_audio_format = effective_audio_format;
@ -341,8 +296,7 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
} catch (const std::exception &e) { } catch (const std::exception &e) {
delete encoder; delete encoder;
delete new_file; delete new_file;
error.Set(recorder_domain, e.what()); throw;
return false;
} }
path = std::move(new_path); path = std::move(new_path);
@ -350,8 +304,6 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
FormatDebug(recorder_domain, "Recording to \"%s\"", FormatDebug(recorder_domain, "Recording to \"%s\"",
path.ToUTF8().c_str()); path.ToUTF8().c_str());
return true;
} }
inline void inline void
@ -382,9 +334,10 @@ RecorderOutput::SendTag(const Tag &tag)
if (new_path != path) { if (new_path != path) {
FinishFormat(); FinishFormat();
Error error; try {
if (!ReopenFormat(std::move(new_path), error)) { ReopenFormat(std::move(new_path));
LogError(error); } catch (const std::runtime_error &e) {
LogError(e);
return; return;
} }
} }
@ -396,7 +349,7 @@ RecorderOutput::SendTag(const Tag &tag)
} }
inline size_t inline size_t
RecorderOutput::Play(const void *chunk, size_t size, Error &error) RecorderOutput::Play(const void *chunk, size_t size, Error &)
{ {
if (file == nullptr) { if (file == nullptr) {
/* not currently encoding to a file; discard incoming /* not currently encoding to a file; discard incoming
@ -408,12 +361,7 @@ RecorderOutput::Play(const void *chunk, size_t size, Error &error)
encoder->Write(chunk, size); encoder->Write(chunk, size);
try { EncoderToFile();
EncoderToFile();
} catch (const std::exception &e) {
error.Set(recorder_domain, e.what());
return 0;
}
return size; return size;
} }