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