Skip to content

Instantly share code, notes, and snippets.

@addam
Created May 31, 2018 20:00
Show Gist options
  • Save addam/9a80975e293b66555ae6026edddd5bb9 to your computer and use it in GitHub Desktop.
Save addam/9a80975e293b66555ae6026edddd5bb9 to your computer and use it in GitHub Desktop.
Minimalist std::streambuf subclass for custom reading
#include <sstream>
#include <fstream>
#include <iostream>
#include <array>
class Buffer : public std::streambuf {
// we use ifstream here only for the sake of example
std::ifstream file;
std::array<char, 1024> data;
bool reload() {
unsigned count = file.readsome(&data[0], data.size());
if (not count) {
file.read(&data[0], data.size());
count = file.gcount();
}
setg(&data[0], &data[0], &data[count]);
return count;
}
std::streamsize xsgetn(char* s, std::streamsize n) {
for (std::streamsize i = 0; i != n; ++i) {
if (gptr() == egptr() and not reload()) {
return i;
}
*s++ = *_M_in_cur++;
}
return n;
}
int_type underflow() {
return (gptr() == egptr() and not reload()) ? traits_type::eof() : *_M_in_cur;
}
int_type uflow() {
return (gptr() == egptr() and not reload()) ? traits_type::eof() : *_M_in_cur++;
}
public:
Buffer(const std::string &filename): file(filename) {
}
};
int main() {
Buffer buf("streambuf.cpp");
std::istream stream(&buf);
std::string tmp;
while (buf.sgetc() != Buffer::traits_type::eof()) {
stream >> tmp;
}
std::cout << tmp << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment