output/fifo: migrate from class Error to C++ exceptions
This commit is contained in:
parent
c8aa7afdc6
commit
543c5034af
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user