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