#pragma once #include namespace mbgl { namespace util { // ref https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/ class CharArrayBuffer : public std::streambuf { public: CharArrayBuffer(char const* data, std::size_t size) : begin_(data), end_(data + size), current_(data) {} private: int_type underflow() final { if (current_ == end_) { return traits_type::eof(); } return traits_type::to_int_type(*current_); } int_type uflow() final { if (current_ == end_) { return traits_type::eof(); } return traits_type::to_int_type(*current_++); } int_type pbackfail(int_type ch) final { if (current_ == begin_ || (ch != traits_type::eof() && ch != current_[-1])) { return traits_type::eof(); } return traits_type::to_int_type(*--current_); } std::streamsize showmanyc() final { return end_ - current_; } pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode) final { if (dir == std::ios_base::beg) current_ = std::min(begin_ + off, end_); else if (dir == std::ios_base::cur) current_ = std::min(current_ + off, end_); else current_ = std::max(end_ - off, begin_); // dir == std::ios_base::end return pos_type(off_type(current_ - begin_)); } char const * const begin_; char const * const end_; char const * current_; }; } // namespace util } // namespace mbgl