From 0ea66a1275da319e2443fa1536cec7ea7fc53b53 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Thu, 7 Aug 2014 18:10:23 +0200
Subject: fs/io/Reader: new interface

---
 src/fs/io/FileReader.cxx | 98 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/fs/io/FileReader.hxx | 67 +++++++++++++++++++++++++++++++++
 src/fs/io/Reader.hxx     | 51 +++++++++++++++++++++++++
 3 files changed, 216 insertions(+)
 create mode 100644 src/fs/io/FileReader.cxx
 create mode 100644 src/fs/io/FileReader.hxx
 create mode 100644 src/fs/io/Reader.hxx

(limited to 'src/fs')

diff --git a/src/fs/io/FileReader.cxx b/src/fs/io/FileReader.cxx
new file mode 100644
index 000000000..d63cd8ab0
--- /dev/null
+++ b/src/fs/io/FileReader.cxx
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "FileReader.hxx"
+#include "system/fd_util.h"
+#include "util/Error.hxx"
+
+#ifdef WIN32
+
+FileReader::FileReader(Path _path, Error &error)
+	:path(_path),
+	 handle(CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ,
+			   nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
+			   nullptr))
+{
+	if (handle == INVALID_HANDLE_VALUE)
+		error.FormatLastError("Failed to open %s", path.c_str());
+}
+
+size_t
+FileReader::Read(void *data, size_t size, Error &error)
+{
+	assert(IsDefined());
+
+	DWORD nbytes;
+	if (!ReadFile(handle, data, size, &nbytes, nullptr)) {
+		error.FormatLastError("Failed to read from %s", path.c_str());
+		nbytes = 0;
+	}
+
+	return nbytes;
+}
+
+void
+FileReader::Close()
+{
+	assert(IsDefined());
+
+	CloseHandle(handle);
+}
+
+#else
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+FileReader::FileReader(Path _path, Error &error)
+	:path(_path),
+	 fd(open_cloexec(path.c_str(),
+			 O_RDONLY,
+			 0))
+{
+	if (fd < 0)
+		error.FormatErrno("Failed to open %s", path.c_str());
+}
+
+size_t
+FileReader::Read(void *data, size_t size, Error &error)
+{
+	assert(IsDefined());
+
+	ssize_t nbytes = read(fd, data, size);
+	if (nbytes < 0) {
+		error.FormatErrno("Failed to read from %s", path.c_str());
+		nbytes = 0;
+	}
+
+	return nbytes;
+}
+
+void
+FileReader::Close()
+{
+	assert(IsDefined());
+
+	close(fd);
+	fd = -1;
+}
+
+#endif
diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
new file mode 100644
index 000000000..34b43943c
--- /dev/null
+++ b/src/fs/io/FileReader.hxx
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_FILE_READER_HXX
+#define MPD_FILE_READER_HXX
+
+#include "check.h"
+#include "Reader.hxx"
+#include "fs/AllocatedPath.hxx"
+
+#include <assert.h>
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+class Path;
+
+class FileReader final : public Reader {
+	AllocatedPath path;
+
+#ifdef WIN32
+	HANDLE handle;
+#else
+	int fd;
+#endif
+
+public:
+	FileReader(Path _path, Error &error);
+
+	~FileReader() {
+		if (IsDefined())
+			Close();
+	}
+
+
+	bool IsDefined() const {
+#ifdef WIN32
+		return handle != INVALID_HANDLE_VALUE;
+#else
+		return fd >= 0;
+#endif
+	}
+
+	void Close();
+
+	/* virtual methods from class Reader */
+	size_t Read(void *data, size_t size, Error &error) override;
+};
+
+#endif
diff --git a/src/fs/io/Reader.hxx b/src/fs/io/Reader.hxx
new file mode 100644
index 000000000..adf7a0667
--- /dev/null
+++ b/src/fs/io/Reader.hxx
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_READER_HXX
+#define MPD_READER_HXX
+
+#include "check.h"
+#include "Compiler.h"
+
+#include <stddef.h>
+
+class Error;
+
+/**
+ * An interface that can read bytes from a stream until the stream
+ * ends.
+ *
+ * This interface is simpler and less cumbersome to use than
+ * #InputStream.
+ */
+class Reader {
+public:
+	Reader() = default;
+	Reader(const Reader &) = delete;
+
+	/**
+	 * Read data from the stream.
+	 *
+	 * @return the number of bytes read into the given buffer or 0
+	 * on error/end-of-stream
+	 */
+	virtual size_t Read(void *data, size_t size, Error &error) = 0;
+};
+
+#endif
-- 
cgit v1.2.3