! Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at beginning of input. Does not support changing the underlying std::streambuf in mid-input. Maintains underlying std::istream and std::streambuf to support subsequent use of standard std::istream operations to process any input characters following those used in parsing the JSON input. Clears the std::istream flags; any input
| 4856 | subsequent call for input from the std::istream. |
| 4857 | */ |
| 4858 | class input_stream_adapter |
| 4859 | { |
| 4860 | public: |
| 4861 | using char_type = char; |
| 4862 | |
| 4863 | ~input_stream_adapter() |
| 4864 | { |
| 4865 | // clear stream flags; we use underlying streambuf I/O, do not |
| 4866 | // maintain ifstream flags, except eof |
| 4867 | if (is != nullptr) |
| 4868 | { |
| 4869 | is->clear(is->rdstate() & std::ios::eofbit); |
| 4870 | } |
| 4871 | } |
| 4872 | |
| 4873 | explicit input_stream_adapter(std::istream& i) |
| 4874 | : is(&i), sb(i.rdbuf()) |
| 4875 | {} |
| 4876 | |
| 4877 | // delete because of pointer members |
| 4878 | input_stream_adapter(const input_stream_adapter&) = delete; |
| 4879 | input_stream_adapter& operator=(input_stream_adapter&) = delete; |
| 4880 | input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete; |
| 4881 | |
| 4882 | input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb) |
| 4883 | { |
| 4884 | rhs.is = nullptr; |
| 4885 | rhs.sb = nullptr; |
| 4886 | } |
| 4887 | |
| 4888 | // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to |
| 4889 | // ensure that std::char_traits<char>::eof() and the character 0xFF do not |
| 4890 | // end up as the same value, eg. 0xFFFFFFFF. |
| 4891 | std::char_traits<char>::int_type get_character() |
| 4892 | { |
| 4893 | auto res = sb->sbumpc(); |
| 4894 | // set eof manually, as we don't use the istream interface. |
| 4895 | if (JSON_HEDLEY_UNLIKELY(res == EOF)) |
| 4896 | { |
| 4897 | is->clear(is->rdstate() | std::ios::eofbit); |
| 4898 | } |
| 4899 | return res; |
| 4900 | } |
| 4901 | |
| 4902 | private: |
| 4903 | /// the associated input stream |
| 4904 | std::istream* is = nullptr; |
| 4905 | std::streambuf* sb = nullptr; |
| 4906 | }; |
| 4907 | |
| 4908 | // General-purpose iterator-based adapter. It might not be as fast as |
| 4909 | // theoretically possible for some containers, but it is extremely versatile. |