diff options
Diffstat (limited to 'src/output/plugins/FifoOutputPlugin.cxx')
-rw-r--r-- | src/output/plugins/FifoOutputPlugin.cxx | 102 |
1 files changed, 47 insertions, 55 deletions
diff --git a/src/output/plugins/FifoOutputPlugin.cxx b/src/output/plugins/FifoOutputPlugin.cxx index 9df5a74dd..6611a83c4 100644 --- a/src/output/plugins/FifoOutputPlugin.cxx +++ b/src/output/plugins/FifoOutputPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,9 +21,11 @@ #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 "Log.hxx" @@ -51,16 +53,26 @@ struct FifoOutput { path(AllocatedPath::Null()), input(-1), output(-1), created(false) {} - bool Initialize(const config_param ¶m, Error &error) { - return base.Configure(param, error); + ~FifoOutput() { + Close(); + } + + 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 Delete(); bool Open(Error &error); void Close(); + + unsigned Delay() const; + size_t Play(const void *chunk, size_t size, Error &error); + void Cancel(); }; static constexpr Domain fifo_output_domain("fifo_output"); @@ -94,8 +106,8 @@ FifoOutput::Close() output = -1; } - struct stat st; - if (created && StatFile(path, st)) + FileInfo fi; + if (created && GetFileInfo(path, fi)) Delete(); } @@ -162,18 +174,12 @@ FifoOutput::Open(Error &error) return true; } -static bool -fifo_open(FifoOutput *fd, Error &error) -{ - return fd->Open(error); -} - -static AudioOutput * -fifo_output_init(const config_param ¶m, Error &error) +inline FifoOutput * +FifoOutput::Create(const ConfigBlock &block, Error &error) { FifoOutput *fd = new FifoOutput(); - fd->path = param.GetBlockPath("path", error); + fd->path = block.GetBlockPath("path", error); if (fd->path.IsNull()) { delete fd; @@ -185,26 +191,17 @@ fifo_output_init(const config_param ¶m, Error &error) fd->path_utf8 = fd->path.ToUTF8(); - if (!fd->Initialize(param, error)) { + if (!fd->Initialize(block, error)) { delete fd; return nullptr; } - if (!fifo_open(fd, error)) { + if (!fd->Open(error)) { delete fd; return nullptr; } - return &fd->base; -} - -static void -fifo_output_finish(AudioOutput *ao) -{ - FifoOutput *fd = (FifoOutput *)ao; - - fd->Close(); - delete fd; + return fd; } static bool @@ -226,48 +223,41 @@ fifo_output_close(AudioOutput *ao) delete fd->timer; } -static void -fifo_output_cancel(AudioOutput *ao) +inline void +FifoOutput::Cancel() { - FifoOutput *fd = (FifoOutput *)ao; char buf[FIFO_BUFFER_SIZE]; int bytes = 1; - fd->timer->Reset(); + timer->Reset(); while (bytes > 0 && errno != EINTR) - bytes = read(fd->input, buf, FIFO_BUFFER_SIZE); + bytes = read(input, buf, FIFO_BUFFER_SIZE); if (bytes < 0 && errno != EAGAIN) { FormatErrno(fifo_output_domain, "Flush of FIFO \"%s\" failed", - fd->path_utf8.c_str()); + path_utf8.c_str()); } } -static unsigned -fifo_output_delay(AudioOutput *ao) +inline unsigned +FifoOutput::Delay() const { - FifoOutput *fd = (FifoOutput *)ao; - - return fd->timer->IsStarted() - ? fd->timer->GetDelay() + return timer->IsStarted() + ? timer->GetDelay() : 0; } -static size_t -fifo_output_play(AudioOutput *ao, const void *chunk, size_t size, - Error &error) +inline size_t +FifoOutput::Play(const void *chunk, size_t size, Error &error) { - FifoOutput *fd = (FifoOutput *)ao; - ssize_t bytes; - - if (!fd->timer->IsStarted()) - fd->timer->Start(); - fd->timer->Add(size); + if (!timer->IsStarted()) + timer->Start(); + timer->Add(size); while (true) { - bytes = write(fd->output, chunk, size); + ssize_t bytes = write(output, chunk, size); if (bytes > 0) return (size_t)bytes; @@ -275,33 +265,35 @@ fifo_output_play(AudioOutput *ao, const void *chunk, size_t size, switch (errno) { case EAGAIN: /* The pipe is full, so empty it */ - fifo_output_cancel(&fd->base); + Cancel(); continue; case EINTR: continue; } error.FormatErrno("Failed to write to FIFO %s", - fd->path_utf8.c_str()); + path_utf8.c_str()); return 0; } } } +typedef AudioOutputWrapper<FifoOutput> Wrapper; + const struct AudioOutputPlugin fifo_output_plugin = { "fifo", nullptr, - fifo_output_init, - fifo_output_finish, + &Wrapper::Init, + &Wrapper::Finish, nullptr, nullptr, fifo_output_open, fifo_output_close, - fifo_output_delay, + &Wrapper::Delay, nullptr, - fifo_output_play, + &Wrapper::Play, nullptr, - fifo_output_cancel, + &Wrapper::Cancel, nullptr, nullptr, }; |