stream.h
Go to the documentation of this file.
1 //
2 // Created by Eduard Valeyev on 5/12/21.
3 //
4 
5 #ifndef TTG_SERIALIZATION_STREAM_H
6 #define TTG_SERIALIZATION_STREAM_H
7 
8 #include <streambuf>
9 #include <cstring>
10 
11 namespace ttg::detail {
12 
14  class counting_streambuf : public std::streambuf {
15  public:
16  using std::streambuf::streambuf;
17 
19  size_t size() const { return size_; }
20 
21  protected:
22  std::streamsize xsputn(const char_type* s, std::streamsize n) override {
23  this->size_ += n;
24  return n;
25  }
26 
27  private:
28  size_t size_ = 0;
29  };
30 
32  class iovec_ostreambuf : public std::streambuf {
33  public:
34  using std::streambuf::streambuf;
35 
36  const auto& iovec() const { return iovec_; };
37 
38  protected:
39  std::streamsize xsputn(const char_type* s, std::streamsize n) override {
40  iovec_.emplace_back(s, n);
41  return n;
42  }
43 
44  private:
45  std::vector<std::pair<const void*, std::size_t>> iovec_ = {};
46  };
47 
49  class iovec_istreambuf : public std::streambuf {
50  public:
51  using std::streambuf::streambuf;
52 
53  iovec_istreambuf(const std::vector<std::pair<const void*, std::size_t>>& iovec) : iovec_(iovec) {}
54 
55  protected:
56  std::streamsize xsgetn(char_type* s, std::streamsize max_n) override {
57  const auto n = iovec_[current_item_].second;
58  if (n > max_n)
59  throw std::out_of_range("iovec_istreambuf::xsgetn(dest, max_n): actual size of data exceeds max_n");
60  const char* ptr = static_cast<const char*>(iovec_[current_item_].first);
61  std::copy(ptr, ptr + n, s);
62  return n;
63  }
64 
65  private:
66  std::size_t current_item_ = 0;
67  const std::vector<std::pair<const void*, std::size_t>>& iovec_;
68  };
69 
71  class byte_ostreambuf : public std::streambuf {
72  public:
73  using std::streambuf::streambuf;
74 
75  byte_ostreambuf(char_type* buffer, std::streamsize buffer_size = std::numeric_limits<std::streamsize>::max()) : buffer_(buffer), cursor_(buffer_), buffer_size_(buffer_size) {}
76 
77  // hides basic_streambuf::sputn so can avoid the virtual function dispatch if the compiler is not aggressive enough
78  std::streamsize sputn(const char_type* s, std::streamsize n) noexcept {
79  return this->xsputn(s, n);
80  }
81 
82  std::streamsize xsputn(const char_type* s, std::streamsize n) noexcept override final {
83  assert((cursor_ - buffer_) + n <= buffer_size_);
84  std::memcpy(cursor_, s, n * sizeof(char_type));
85  cursor_ += n;
86  return n;
87  }
88 
90  std::streamsize size() const noexcept {
91  return cursor_ - buffer_;
92  }
93 
94  private:
95  char_type* buffer_;
96  char_type* cursor_; // current location in buffer_
97  std::streamsize buffer_size_;
98  };
99 
101  class byte_istreambuf : public std::streambuf {
102  public:
103  using std::streambuf::streambuf;
104 
105  byte_istreambuf(const char_type* buffer, std::size_t buffer_size = std::numeric_limits<std::size_t>::max()) : buffer_(buffer), cursor_(buffer_), buffer_size_(buffer_size) {}
106 
107  // hides basic_streambuf::sgetn so can avoid the virtual function dispatch if the compiler is not aggressive enough
108  std::streamsize sgetn(char_type* s, std::streamsize n) noexcept {
109  return this->xsgetn(s, n);
110  }
111 
112  std::streamsize xsgetn(char_type* s, std::streamsize max_n) noexcept override final {
113  const auto n_to_read = std::min(buffer_size_ - (cursor_ - buffer_), max_n);
114  std::memcpy(s, cursor_, n_to_read * sizeof(char_type));
115  cursor_ += n_to_read;
116  return n_to_read;
117  }
118 
120  std::streamsize size() const noexcept {
121  return cursor_ - buffer_;
122  }
123 
124  private:
125  const char_type* buffer_;
126  const char_type* cursor_; // current location in buffer_
127  std::streamsize buffer_size_;
128  };
129 
130 } // namespace ttg::detail
131 
132 #endif // TTG_SERIALIZATION_STREAM_H
streambuf that writes bytes to a buffer in memory
Definition: stream.h:101
byte_istreambuf(const char_type *buffer, std::size_t buffer_size=std::numeric_limits< std::size_t >::max())
Definition: stream.h:105
std::streamsize xsgetn(char_type *s, std::streamsize max_n) noexcept override final
Definition: stream.h:112
std::streamsize sgetn(char_type *s, std::streamsize n) noexcept
Definition: stream.h:108
std::streamsize size() const noexcept
number of characters read from the buffer
Definition: stream.h:120
streambuf that writes bytes to a buffer in memory
Definition: stream.h:71
std::streamsize xsputn(const char_type *s, std::streamsize n) noexcept override final
Definition: stream.h:82
std::streamsize sputn(const char_type *s, std::streamsize n) noexcept
Definition: stream.h:78
byte_ostreambuf(char_type *buffer, std::streamsize buffer_size=std::numeric_limits< std::streamsize >::max())
Definition: stream.h:75
std::streamsize size() const noexcept
number of characters written to the buffer
Definition: stream.h:90
streambuf that counts bytes
Definition: stream.h:14
std::streamsize xsputn(const char_type *s, std::streamsize n) override
Definition: stream.h:22
streambuf that reads vector of address-size pairs
Definition: stream.h:49
std::streamsize xsgetn(char_type *s, std::streamsize max_n) override
Definition: stream.h:56
iovec_istreambuf(const std::vector< std::pair< const void *, std::size_t >> &iovec)
Definition: stream.h:53
streambuf that records vector of address-size pairs
Definition: stream.h:32
std::streamsize xsputn(const char_type *s, std::streamsize n) override
Definition: stream.h:39
const auto & iovec() const
Definition: stream.h:36