This commit is contained in:
flamingcow
2019-05-04 23:21:11 -07:00
commit dd9a0a974f
6 changed files with 188 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.a
*.o

15
Makefile Normal file
View File

@@ -0,0 +1,15 @@
FIRE_CXX ?= clang++
FIRE_CXXFLAGS ?= -O3 -std=gnu++2a -Wall -Werror
all: firebuf.a
objects = stream_buffer.o buffer.o
firebuf.a: $(objects)
ar rcs $@ $^
%.o: %.cc *.h Makefile
$(FIRE_CXX) $(FIRE_CXXFLAGS) -c -o $@ $<
clean:
rm --force firebuf.a *.o

83
buffer.cc Normal file
View File

@@ -0,0 +1,83 @@
#include "buffer.h"
namespace firebuf {
ConstBuffer::ConstBuffer(const char *buf, size_t len)
: const_buf_(buf),
len_(len) {}
size_t ConstBuffer::ReadMaxLen() const {
return len_ - start_;
}
const char *ConstBuffer::Read(size_t len) {
if (ReadMaxLen() < len) {
return nullptr;
}
const auto *ret = &const_buf_[start_];
start_ += len;
return ret;
}
bool ConstBuffer::Discard(size_t len) {
if (len > ReadMaxLen()) {
return false;
}
static_cast<void>(Read(len));
return true;
}
void ConstBuffer::ResetRead() {
start_ = commit_;
}
void ConstBuffer::Commit() {
commit_ = start_;
}
Buffer::Buffer(char *buf, size_t size, size_t len)
: ConstBuffer(buf, size),
buf_(buf),
size_(size) {
len_ = len;
}
Buffer::Buffer(size_t size)
: Buffer(new char[size], size, 0) {
own_buf_.reset(buf_);
}
char *Buffer::WritePtr() {
return &buf_[len_];
}
size_t Buffer::WriteMaxLen() const {
return size_ - len_;
}
bool Buffer::Write(const std::string_view& str) {
if (WriteMaxLen() < str.size()) {
return false;
}
memcpy(WritePtr(), str.data(), str.size());
Wrote(str.size());
return true;
}
void Buffer::Wrote(size_t len) {
CHECK_LE(len, WriteMaxLen());
len_ += len;
}
void Buffer::Consume() {
if (commit_ == 0) {
return;
}
memmove(buf_, &buf_[commit_], len_ - commit_);
len_ -= commit_;
start_ -= commit_;
commit_ = 0;
}
} // namespace firebuf

53
buffer.h Normal file
View File

@@ -0,0 +1,53 @@
#pragma once
#include <glog/logging.h>
#include <memory>
#include <string_view>
namespace firebuf {
class ConstBuffer {
public:
ConstBuffer(const char *buf, size_t len);
[[nodiscard]] size_t ReadMaxLen() const;
[[nodiscard]] virtual const char *Read(size_t len);
template<class T> [[nodiscard]] const T *ReadObj();
bool Discard(size_t len); // like Read() but don't use the result
void ResetRead(); // next read from last commit
void Commit(); // commit read position
protected:
const char *const_buf_;
size_t len_;
size_t start_ = 0;
size_t commit_ = 0;
};
class Buffer : public ConstBuffer {
public:
Buffer(char *buf, size_t size, size_t len);
Buffer(size_t size);
[[nodiscard]] char *WritePtr();
[[nodiscard]] size_t WriteMaxLen() const;
bool Write(const std::string_view& str);
void Wrote(size_t len);
void Consume(); // discard up to last commit
protected:
std::unique_ptr<char[]> own_buf_;
char *buf_;
const size_t size_;
};
template<class T> const T *ConstBuffer::ReadObj() {
if (ReadMaxLen() < sizeof(T)) {
return nullptr;
}
return reinterpret_cast<const T*>(Read(sizeof(T)));
}
} // namespace firebuf

18
stream_buffer.cc Normal file
View File

@@ -0,0 +1,18 @@
#include "stream_buffer.h"
namespace firebuf {
StreamBuffer::StreamBuffer(int sock, size_t size)
: Buffer(size),
sock_(sock) {}
bool StreamBuffer::Refill() {
auto read_len = read(sock_, WritePtr(), WriteMaxLen());
if (read_len == 0) {
return false;
}
Wrote(read_len);
return true;
}
} // namespace firebuf

17
stream_buffer.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
#include "buffer.h"
namespace firebuf {
class StreamBuffer : public Buffer {
public:
StreamBuffer(int sock, size_t size);
[[nodiscard]] bool Refill();
private:
int sock_;
};
} // namespace firebuf