diff options
-rw-r--r-- | src/libutil/util.hh | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/libutil/util.hh b/src/libutil/util.hh index a8f6f99b957f..f38c2bb7c154 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -435,14 +435,50 @@ void callSuccess( argument. This is useful for large strings. The caller must ensure that the string object is not destroyed while it's referenced by this object. */ -struct istringstream_nocopy : public std::stringstream +class istringbuf_nocopy : public std::streambuf { - istringstream_nocopy(const std::string & s) + const std::string & s; + std::streamsize off; +public: + istringbuf_nocopy(const std::string & s) : s{s}, off{0} + { + } + +private: + int_type underflow() + { + if (off == s.size()) + return traits_type::eof(); + return traits_type::to_int_type(s[off]); + } + + int_type uflow() + { + if (off == s.size()) + return traits_type::eof(); + return traits_type::to_int_type(s[off++]); + } + + int_type pbackfail(int_type ch) + { + if (off == 0 || (ch != traits_type::eof() && ch != s[off - 1])) + return traits_type::eof(); + + return traits_type::to_int_type(s[--off]); + } + + std::streamsize showmanyc() { - rdbuf()->pubsetbuf( - (char *) s.data(), s.size()); + return s.size() - off; } }; +struct istringstream_nocopy : public std::istream +{ + istringbuf_nocopy buf; + istringstream_nocopy(const std::string & s) : std::istream(&buf), buf(s) {}; +}; + + } |