DirectZ
Loading...
Searching...
No Matches
memory_buffer.hpp
Go to the documentation of this file.
1#pragma once
2#include <string>
3#include <streambuf>
4#include <vector>
5
16class memory_buffer : public std::streambuf {
17public:
19 // Set initial pointers for an empty buffer to avoid null pointer issues.
20 update_pointers();
21 }
22
23 // Non-copyable
24 memory_buffer(const memory_buffer&) = delete;
26
27 // Method to get the buffer contents.
28 std::string str() const {
29 if (buffer_.empty()) {
30 return {};
31 }
32 return std::string(buffer_.data(), buffer_.size());
33 }
34
35 // Method to set the buffer contents.
36 void str(const std::string& s) {
37 buffer_.assign(s.begin(), s.end());
38 // After setting content, update the stream pointers to reflect the new state.
39 update_pointers(0, buffer_.size()); // Set put pointer to the end
40 }
41
42protected:
46 int_type underflow() override {
47 return traits_type::eof();
48 }
49
55 int_type overflow(int_type c = traits_type::eof()) override {
56 if (c == traits_type::eof()) {
57 return traits_type::eof();
58 }
59
60 std::ptrdiff_t get_offset = eback() ? gptr() - eback() : 0;
61
62 buffer_.push_back(traits_type::to_char_type(c));
63
64 // The buffer has grown. Update all pointers, placing the put pointer at the new end.
65 update_pointers(get_offset, buffer_.size());
66
67 return c;
68 }
69
73 pos_type seekoff(off_type off, std::ios_base::seekdir dir,
74 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override {
75
76 off_type new_pos;
77
78 // Calculate the target absolute position based on direction
79 switch (dir) {
80 case std::ios_base::beg:
81 new_pos = off;
82 break;
83 case std::ios_base::cur: {
84 off_type current_pos = 0;
85 if (which & std::ios_base::in) {
86 // If get pointer is valid, use it, otherwise position is 0
87 if (gptr() != nullptr) {
88 current_pos = gptr() - eback();
89 }
90 } else if (which & std::ios_base::out) {
91 // If put pointer is valid, use it, otherwise position is 0
92 if (pptr() != nullptr) {
93 current_pos = pptr() - pbase();
94 }
95 }
96 new_pos = current_pos + off;
97 break;
98 }
99 case std::ios_base::end:
100 new_pos = buffer_.size() + off;
101 break;
102 default:
103 return pos_type(off_type(-1));
104 }
105
106 // Validate that the new position is within the buffer bounds.
107 if (new_pos < 0 || new_pos > static_cast<off_type>(buffer_.size())) {
108 return pos_type(off_type(-1));
109 }
110
111 // Update the actual get/put pointers based on the valid new position.
112 char* base = buffer_.data();
113 char* end = base + buffer_.size();
114
115 if (which & std::ios_base::in) {
116 setg(base, base + new_pos, end);
117 }
118 if (which & std::ios_base::out) {
119 setp(base, end);
120 pbump(static_cast<int>(new_pos));
121 }
122
123 return pos_type(new_pos);
124 }
125
129 pos_type seekpos(pos_type pos,
130 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override {
131 return seekoff(pos, std::ios_base::beg, which);
132 }
133
134private:
138 void update_pointers(std::ptrdiff_t get_offset = 0, std::ptrdiff_t put_offset = 0) {
139 // Use .data() which is safe even for empty vectors in C++11 and later.
140 char* base = buffer_.data();
141 char* end = base + buffer_.size();
142
143 // Set get area
144 setg(base, base + get_offset, end);
145
146 // Set put area
147 setp(base, end);
148 pbump(static_cast<int>(put_offset));
149 }
150
151 std::vector<char> buffer_;
152};
void str(const std::string &s)
Definition memory_buffer.hpp:36
memory_buffer()
Definition memory_buffer.hpp:18
std::string str() const
Definition memory_buffer.hpp:28
memory_buffer & operator=(const memory_buffer &)=delete
int_type underflow() override
Called when the get area is exhausted. For an in-memory buffer, this means EOF.
Definition memory_buffer.hpp:46
pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out) override
Implements seeking to an absolute or relative position. This is the corrected version.
Definition memory_buffer.hpp:73
memory_buffer(const memory_buffer &)=delete
pos_type seekpos(pos_type pos, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out) override
Implements seeking to an absolute position by deferring to seekoff.
Definition memory_buffer.hpp:129
int_type overflow(int_type c=traits_type::eof()) override
Called when a write occurs at or past the end of the put area.
Definition memory_buffer.hpp:55