@@ -23,23 +23,36 @@ limitations under the License.
2323#include " types.hpp"
2424
2525
26-
2726// Ahem ... Visual Studio
28- // This ostreambuf class is required because Microsoft cannot bother to implement
29- // streambuf::pubsetbuf().
30- template <typename T>
31- struct ostreambuf : public std ::basic_streambuf<T, std::char_traits<T> >
32- {
33- ostreambuf (T* buffer, std::streamsize length) {
34- this ->setp (buffer, &buffer[length]);
27+ // This code is required because Microsoft cannot bother to implement streambuf::pubsetbuf().
28+ // Also On libstdc++, pubsetbuf() silently ignores the supplied buffer and leaves internal pointers null.
29+
30+ class ifixedbuf : public std ::streambuf {
31+ public:
32+ ifixedbuf (char * data, std::size_t size) {
33+ // Always manually set the read pointers.
34+ // pubsetbuf() is unreliable on libstdc++, and MSVC doesn't implement it.
35+ this ->setg (data, data, data + size);
36+ }
37+ };
38+
39+ class ofixedbuf : public std ::streambuf {
40+ public:
41+ ofixedbuf (char * data, std::size_t size) {
42+ // Always set buffer manually — pubsetbuf is useless on libstdc++
43+ this ->setp (data, data + size);
44+ }
45+
46+ std::size_t written () const {
47+ return this ->pptr () - this ->pbase ();
3548 }
3649};
3750
38- template < typename T>
39- struct istreambuf : public std ::basic_streambuf<T, std::char_traits<T> >
40- {
41- istreambuf (T* buffer, std::streamsize length) {
42- this ->setg (buffer, buffer, &buffer[length] );
51+ class iofixedbuf : public std ::streambuf {
52+ public:
53+ iofixedbuf ( char * data, std:: size_t size) {
54+ this -> setg (data, data, data + size);
55+ this ->setp (data, data + size );
4356 }
4457};
4558
0 commit comments