#pragma once

#include <unistd.h>
#include <memory>

class OutStream {
public:
	virtual bool write(const void *buf, size_t len) = 0;
	virtual ~OutStream() = default;
};

typedef std::unique_ptr<OutStream> strm_ptr;

class FilterOutStream : public OutStream {
public:
	FilterOutStream() = default;

	FilterOutStream(strm_ptr &&ptr) : out(std::move(ptr)) {}

	void set_out(strm_ptr &&ptr) { out = std::move(ptr); }

	bool write(const void *buf, size_t len) override {
		return out ? out->write(buf, len) : false;
	}

protected:
	strm_ptr out;
};

class FDOutStream : public OutStream {
public:
	FDOutStream(int fd, bool close = false) : fd(fd), close(close) {}

	bool write(const void *buf, size_t len) override {
		return ::write(fd, buf, len) == len;
	}

	~FDOutStream() override {
		if (close)
			::close(fd);
	}

protected:
	int fd;
	bool close;
};
