// License: Modified MIT (NON-AI) // See the LICENSE file in the root directory for license information. // Copyright 2025 Timothy Prepscius #pragma once #include "memstream.h" #include #include #include namespace tjp::core::io { // https://stackoverflow.com/questions/13059091/creating-an-input-stream-from-constant-memory/13059195#13059195 struct imembuf: std::streambuf { imembuf(char const* base, size_t size) { char* p(const_cast(base)); this->setg(p, p, p + size); } }; struct imemstream: virtual imembuf, std::istream { imemstream(char const* base, size_t size) : imembuf(base, size) , std::istream(static_cast(this)) { } imemstream(const std::string_view &s) : imembuf(s.data(), s.size()) , std::istream(static_cast(this)) { } }; struct omembuf: std::streambuf { std::vector &v; size_t offset = 0; omembuf(std::vector &v_) : v(v_) { } // ------------------------ OUTPUT FUNCTIONS ------------------------ int_type overflow ( int_type c) override { if (c != EOF) v.push_back(static_cast(c)); offset = v.size(); return c; } std::streamsize xsputn ( const char* s, std::streamsize num) override { auto written = num; while(num && offset < v.size()) { v[offset++] = *s++; num--; } v.insert(v.end(), s, s+num); offset += num; return written; } pos_type seekpos( pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override { if (pos > v.size()) return pos_type(-1); offset = pos; return pos; } pos_type seekoff( off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override { if (off < 0 && -off > offset) return pos_type(-1); return seekpos(offset + off); } }; struct omemstream: virtual omembuf, std::ostream { omemstream(std::vector &v_) : omembuf(v_) , std::ostream(static_cast(this)) { } }; struct omemstream_: virtual omembuf, std::ostream { std::vector data; omemstream_() : omembuf(data) , std::ostream(static_cast(this)) { } }; } // namespace