summaryrefslogtreecommitdiff
path: root/src/buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.cc')
-rw-r--r--src/buffer.cc30
1 files changed, 18 insertions, 12 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index 65c6757..3073a45 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -20,7 +20,7 @@ class FixedBuffer : public Buffer {
avail = 0;
} else {
avail = (data_.get() + size_) - rptr_;
- if (avail < need) {
+ if (avail < need && rptr_ > data_.get()) {
rotate();
return rptr(avail, need);
}
@@ -36,7 +36,7 @@ class FixedBuffer : public Buffer {
if (rptr_ == wptr_)
reset();
} else {
- assert(rptr_ != wptr_ || !full_);
+ assert(rptr_ != wptr_ || full_);
assert(std::cmp_greater_equal((data_.get() + size_) - rptr_, size));
rptr_ += size;
if (rptr_ == data_.get() + size_) {
@@ -59,7 +59,7 @@ class FixedBuffer : public Buffer {
avail = 0;
} else {
avail = (data_.get() + size_) - wptr_;
- if (avail < need) {
+ if (avail < need && rptr_ > data_.get()) {
rotate();
return wptr(avail, need);
}
@@ -102,18 +102,24 @@ class FixedBuffer : public Buffer {
}
void rotate() {
- size_t to_move = (data_.get() + size_) - rptr_;
- if (wptr_ + to_move > rptr_) {
- auto tmp = std::make_unique_for_overwrite<char[]>(to_move);
- memcpy(tmp.get(), rptr_, to_move);
- memmove(data_.get() + to_move, data_.get(), wptr_ - data_.get());
- memcpy(data_.get(), tmp.get(), to_move);
+ if (rptr_ < wptr_) {
+ size_t size = wptr_ - rptr_;
+ memmove(data_.get(), rptr_, size);
+ wptr_ = data_.get() + size;
} else {
- memmove(data_.get() + to_move, data_.get(), wptr_ - data_.get());
- memcpy(data_.get(), rptr_, to_move);
+ size_t to_move = (data_.get() + size_) - rptr_;
+ if (wptr_ + to_move > rptr_) {
+ auto tmp = std::make_unique_for_overwrite<char[]>(to_move);
+ memcpy(tmp.get(), rptr_, to_move);
+ memmove(data_.get() + to_move, data_.get(), wptr_ - data_.get());
+ memcpy(data_.get(), tmp.get(), to_move);
+ } else {
+ memmove(data_.get() + to_move, data_.get(), wptr_ - data_.get());
+ memcpy(data_.get(), rptr_, to_move);
+ }
+ wptr_ += to_move;
}
rptr_ = data_.get();
- wptr_ += to_move;
}
size_t const size_;