111 lines
2.3 KiB
C++
Executable File
111 lines
2.3 KiB
C++
Executable File
// 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 <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
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<char*>(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<std::streambuf*>(this)) {
|
|
}
|
|
|
|
imemstream(const std::string_view &s)
|
|
: imembuf(s.data(), s.size())
|
|
, std::istream(static_cast<std::streambuf*>(this)) {
|
|
}
|
|
|
|
};
|
|
|
|
struct omembuf: std::streambuf {
|
|
std::vector<char> &v;
|
|
size_t offset = 0;
|
|
omembuf(std::vector<char> &v_) : v(v_) {
|
|
|
|
}
|
|
|
|
// ------------------------ OUTPUT FUNCTIONS ------------------------
|
|
|
|
int_type overflow ( int_type c) override
|
|
{
|
|
if (c != EOF) v.push_back(static_cast<char>(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<char> &v_)
|
|
: omembuf(v_)
|
|
, std::ostream(static_cast<std::streambuf*>(this)) {
|
|
}
|
|
};
|
|
|
|
struct omemstream_: virtual omembuf, std::ostream {
|
|
std::vector<char> data;
|
|
|
|
omemstream_()
|
|
: omembuf(data)
|
|
, std::ostream(static_cast<std::streambuf*>(this)) {
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|