2019-02-23 10:15:54 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <memory>
|
|
|
|
|
2019-02-25 02:39:01 +01:00
|
|
|
#include "utils.h"
|
|
|
|
|
2019-02-23 10:15:54 +01:00
|
|
|
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)) {}
|
|
|
|
|
2019-09-26 05:55:39 +02:00
|
|
|
void setOut(strm_ptr &&ptr) { out = std::move(ptr); }
|
2019-02-23 10:15:54 +01:00
|
|
|
|
2019-09-26 05:55:39 +02:00
|
|
|
OutStream *getOut() { return out.get(); }
|
2019-02-23 21:04:15 +01:00
|
|
|
|
2019-02-23 10:15:54 +01:00
|
|
|
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;
|
|
|
|
};
|
2019-02-23 21:04:15 +01:00
|
|
|
|
|
|
|
class BufOutStream : public OutStream {
|
|
|
|
public:
|
|
|
|
BufOutStream() : buf(nullptr), off(0), cap(0) {};
|
|
|
|
|
|
|
|
bool write(const void *b, size_t len) override {
|
|
|
|
bool resize = false;
|
|
|
|
while (off + len > cap) {
|
|
|
|
cap = cap ? cap << 1 : 1 << 19;
|
|
|
|
resize = true;
|
|
|
|
}
|
|
|
|
if (resize)
|
|
|
|
buf = (char *) xrealloc(buf, cap);
|
|
|
|
memcpy(buf + off, b, len);
|
|
|
|
off += len;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-02-23 22:53:51 +01:00
|
|
|
template <typename bytes, typename length>
|
|
|
|
void release(bytes *&b, length &len) {
|
2019-02-23 21:04:15 +01:00
|
|
|
b = buf;
|
|
|
|
len = off;
|
|
|
|
buf = nullptr;
|
|
|
|
off = cap = 0;
|
|
|
|
}
|
|
|
|
|
2019-02-23 22:53:51 +01:00
|
|
|
template <typename bytes, typename length>
|
|
|
|
void getbuf(bytes *&b, length &len) const {
|
|
|
|
b = buf;
|
|
|
|
len = off;
|
|
|
|
}
|
|
|
|
|
2019-02-23 21:04:15 +01:00
|
|
|
~BufOutStream() override {
|
|
|
|
free(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
char *buf;
|
|
|
|
size_t off;
|
|
|
|
size_t cap;
|
|
|
|
};
|