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

This commit is contained in:
Max Kellermann 2016-11-05 15:13:14 +01:00
parent c8aa7afdc6
commit 543c5034af

View File

@ -19,15 +19,14 @@
#include "config.h"
#include "FifoOutputPlugin.hxx"
#include "config/ConfigError.hxx"
#include "../OutputAPI.hxx"
#include "../Wrapper.hxx"
#include "../Timer.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/FileSystem.hxx"
#include "fs/FileInfo.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include "Log.hxx"
#include "open.h"
@ -40,35 +39,28 @@ class FifoOutput {
AudioOutput base;
AllocatedPath path;
const AllocatedPath path;
std::string path_utf8;
int input;
int output;
bool created;
int input = -1;
int output = -1;
bool created = false;
Timer *timer;
public:
FifoOutput()
:base(fifo_output_plugin),
path(AllocatedPath::Null()), input(-1), output(-1),
created(false) {}
FifoOutput(const ConfigBlock &block);
~FifoOutput() {
CloseFifo();
}
bool Initialize(const ConfigBlock &block, Error &error) {
return base.Configure(block, error);
}
static FifoOutput *Create(const ConfigBlock &block, Error &error);
bool Create(Error &error);
bool Check(Error &error);
void Create();
void Check();
void Delete();
bool OpenFifo(Error &error);
void OpenFifo();
void CloseFifo();
bool Open(AudioFormat &audio_format, Error &error);
@ -81,6 +73,18 @@ public:
static constexpr Domain fifo_output_domain("fifo_output");
FifoOutput::FifoOutput(const ConfigBlock &block)
:base(fifo_output_plugin, block),
path(block.GetPath("path"))
{
if (path.IsNull())
throw std::runtime_error("No \"path\" parameter specified");
path_utf8 = path.ToUTF8();
OpenFifo();
}
inline void
FifoOutput::Delete()
{
@ -115,93 +119,59 @@ FifoOutput::CloseFifo()
Delete();
}
inline bool
FifoOutput::Create(Error &error)
inline void
FifoOutput::Create()
{
if (!MakeFifo(path, 0666)) {
error.FormatErrno("Couldn't create FIFO \"%s\"",
if (!MakeFifo(path, 0666))
throw FormatErrno("Couldn't create FIFO \"%s\"",
path_utf8.c_str());
return false;
}
created = true;
return true;
}
inline bool
FifoOutput::Check(Error &error)
inline void
FifoOutput::Check()
{
struct stat st;
if (!StatFile(path, st)) {
if (errno == ENOENT) {
/* Path doesn't exist */
return Create(error);
Create();
return;
}
error.FormatErrno("Failed to stat FIFO \"%s\"",
throw FormatErrno("Failed to stat FIFO \"%s\"",
path_utf8.c_str());
return false;
}
if (!S_ISFIFO(st.st_mode)) {
error.Format(fifo_output_domain,
"\"%s\" already exists, but is not a FIFO",
path_utf8.c_str());
return false;
}
return true;
if (!S_ISFIFO(st.st_mode))
throw FormatRuntimeError("\"%s\" already exists, but is not a FIFO",
path_utf8.c_str());
}
inline bool
FifoOutput::OpenFifo(Error &error)
{
if (!Check(error))
return false;
inline void
FifoOutput::OpenFifo()
try {
Check();
input = OpenFile(path, O_RDONLY|O_NONBLOCK|O_BINARY, 0);
if (input < 0) {
error.FormatErrno("Could not open FIFO \"%s\" for reading",
if (input < 0)
throw FormatErrno("Could not open FIFO \"%s\" for reading",
path_utf8.c_str());
CloseFifo();
return false;
}
output = OpenFile(path, O_WRONLY|O_NONBLOCK|O_BINARY, 0);
if (output < 0) {
error.FormatErrno("Could not open FIFO \"%s\" for writing",
if (output < 0)
throw FormatErrno("Could not open FIFO \"%s\" for writing",
path_utf8.c_str());
CloseFifo();
return false;
}
return true;
} catch (...) {
CloseFifo();
throw;
}
inline FifoOutput *
FifoOutput::Create(const ConfigBlock &block, Error &error)
FifoOutput::Create(const ConfigBlock &block, Error &)
{
FifoOutput *fd = new FifoOutput();
fd->path = block.GetPath("path");
if (fd->path.IsNull()) {
delete fd;
throw std::runtime_error("No \"path\" parameter specified");
}
fd->path_utf8 = fd->path.ToUTF8();
if (!fd->Initialize(block, error)) {
delete fd;
return nullptr;
}
if (!fd->OpenFifo(error)) {
delete fd;
return nullptr;
}
return fd;
return new FifoOutput(block);
}
bool
@ -244,7 +214,7 @@ FifoOutput::Delay() const
}
inline size_t
FifoOutput::Play(const void *chunk, size_t size, Error &error)
FifoOutput::Play(const void *chunk, size_t size, Error &)
{
if (!timer->IsStarted())
timer->Start();
@ -265,9 +235,8 @@ FifoOutput::Play(const void *chunk, size_t size, Error &error)
continue;
}
error.FormatErrno("Failed to write to FIFO %s",
throw FormatErrno("Failed to write to FIFO %s",
path_utf8.c_str());
return 0;
}
}
}