Sponge
CS144's user-space TCP library
buffer.cc
Go to the documentation of this file.
1 #include "buffer.hh"
2 
3 using namespace std;
4 
5 void Buffer::remove_prefix(const size_t n) {
6  if (n > str().size()) {
7  throw out_of_range("Buffer::remove_prefix");
8  }
9  _starting_offset += n;
10  if (_storage and _starting_offset == _storage->size()) {
11  _storage.reset();
12  }
13 }
14 
15 void BufferList::append(const BufferList &other) {
16  for (const auto &buf : other._buffers) {
17  _buffers.push_back(buf);
18  }
19 }
20 
21 BufferList::operator Buffer() const {
22  switch (_buffers.size()) {
23  case 0:
24  return {};
25  case 1:
26  return _buffers[0];
27  default: {
28  throw runtime_error(
29  "BufferList: please use concatenate() to combine a multi-Buffer BufferList into one Buffer");
30  }
31  }
32 }
33 
34 string BufferList::concatenate() const {
35  std::string ret;
36  ret.reserve(size());
37  for (const auto &buf : _buffers) {
38  ret.append(buf);
39  }
40  return ret;
41 }
42 
43 size_t BufferList::size() const {
44  size_t ret = 0;
45  for (const auto &buf : _buffers) {
46  ret += buf.size();
47  }
48  return ret;
49 }
50 
51 void BufferList::remove_prefix(size_t n) {
52  while (n > 0) {
53  if (_buffers.empty()) {
54  throw std::out_of_range("BufferList::remove_prefix");
55  }
56 
57  if (n < _buffers.front().str().size()) {
58  _buffers.front().remove_prefix(n);
59  n = 0;
60  } else {
61  n -= _buffers.front().str().size();
62  _buffers.pop_front();
63  }
64  }
65 }
66 
68  for (const auto &x : buffers.buffers()) {
69  _views.push_back(x);
70  }
71 }
72 
74  while (n > 0) {
75  if (_views.empty()) {
76  throw std::out_of_range("BufferListView::remove_prefix");
77  }
78 
79  if (n < _views.front().size()) {
80  _views.front().remove_prefix(n);
81  n = 0;
82  } else {
83  n -= _views.front().size();
84  _views.pop_front();
85  }
86  }
87 }
88 
89 size_t BufferViewList::size() const {
90  size_t ret = 0;
91  for (const auto &buf : _views) {
92  ret += buf.size();
93  }
94  return ret;
95 }
96 
98  vector<iovec> ret;
99  ret.reserve(_views.size());
100  for (const auto &x : _views) {
101  ret.push_back({const_cast<char *>(x.data()), x.size()});
102  }
103  return ret;
104 }
T append(T... args)
A reference-counted read-only string that can discard bytes from the front.
Definition: buffer.hh:15
void remove_prefix(const size_t n)
Discard the first n bytes of the string (does not require a copy or move)
Definition: buffer.cc:5
A reference-counted discontiguous string that can discard bytes from the front.
Definition: buffer.hh:57
const std::deque< Buffer > & buffers() const
Access the underlying queue of Buffers.
Definition: buffer.hh:78
void append(const BufferList &other)
Append a BufferList.
Definition: buffer.cc:15
std::deque< Buffer > _buffers
Definition: buffer.hh:59
std::string concatenate() const
Make a copy to a new std::string.
Definition: buffer.cc:34
void remove_prefix(size_t n)
Discard the first n bytes of the string (does not require a copy or move)
Definition: buffer.cc:51
size_t size() const
Size of the string.
Definition: buffer.cc:43
BufferViewList(const std::string &str)
Construct from a std::string.
Definition: buffer.hh:106
size_t size() const
Size of the string.
Definition: buffer.cc:89
void remove_prefix(size_t n)
Discard the first n bytes of the string (does not require a copy or move)
Definition: buffer.cc:73
std::vector< iovec > as_iovecs() const
Convert to a vector of iovec structures.
Definition: buffer.cc:97
T push_back(T... args)
T reserve(T... args)