1 #pragma once 2 3 #include <streambuf> 4 5 namespace mbgl { 6 namespace util { 7 8 // ref https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/ 9 10 class CharArrayBuffer : public std::streambuf 11 { 12 public: CharArrayBuffer(char const * data,std::size_t size)13 CharArrayBuffer(char const* data, std::size_t size) 14 : begin_(data), end_(data + size), current_(data) {} 15 16 private: underflow()17 int_type underflow() final { 18 if (current_ == end_) { 19 return traits_type::eof(); 20 } 21 return traits_type::to_int_type(*current_); 22 } 23 uflow()24 int_type uflow() final { 25 if (current_ == end_) { 26 return traits_type::eof(); 27 } 28 return traits_type::to_int_type(*current_++); 29 } 30 pbackfail(int_type ch)31 int_type pbackfail(int_type ch) final { 32 if (current_ == begin_ || (ch != traits_type::eof() && ch != current_[-1])) { 33 return traits_type::eof(); 34 } 35 return traits_type::to_int_type(*--current_); 36 } 37 showmanyc()38 std::streamsize showmanyc() final { 39 return end_ - current_; 40 } 41 seekoff(off_type off,std::ios_base::seekdir dir,std::ios_base::openmode)42 pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode) final { 43 if (dir == std::ios_base::beg) current_ = std::min(begin_ + off, end_); 44 else if (dir == std::ios_base::cur) current_ = std::min(current_ + off, end_); 45 else current_ = std::max(end_ - off, begin_); // dir == std::ios_base::end 46 return pos_type(off_type(current_ - begin_)); 47 } 48 49 char const * const begin_; 50 char const * const end_; 51 char const * current_; 52 }; 53 54 } // namespace util 55 } // namespace mbgl 56