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