#include <iostream>
#include <sstream>
namespace std
{
struct substreambuf : public streambuf
{
explicit substreambuf(streambuf* sbuf, streampos pos, streampos len) :
m_sbuf(sbuf),
m_pos(pos),
m_len(len),
m_read(0)
{
m_sbuf->pubseekpos(pos);
setbuf(nullptr, 0);
}
protected:
int underflow()
{
if (m_read >= m_len)
{
return traits_type::eof();
}
return m_sbuf->sgetc();
}
int uflow()
{
if (m_read >= m_len)
{
return traits_type::eof();
}
m_read += 1;
return m_sbuf->sbumpc();
}
streampos seekoff(streamoff off, ios_base::seekdir seekdir, ios_base::openmode openmode = ios_base::in | ios_base::out)
{
if (seekdir == ios_base::beg)
{
off += m_pos;
}
else if (seekdir == ios_base::cur)
{
off += m_pos + m_read;
}
else if (seekdir == ios_base::end)
{
off += m_pos + m_len;
}
return m_sbuf->pubseekpos(off, openmode) - m_pos;
}
streampos seekpos(streampos streampos, ios_base::openmode openmode = ios_base::in | ios_base::out)
{
streampos += m_pos;
if (streampos > m_pos + m_len)
{
return -1;
}
return m_sbuf->pubseekpos(streampos, openmode) - m_pos;
}
private:
streambuf* m_sbuf;
streampos m_pos;
streamsize m_len;
streampos m_read;
};
};
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream ss;
ss << "Hello, World!";
substreambuf asd(ss.rdbuf(), 0, 5);
istream istream(&asd);
char buffer[6] = { '\0' };
istream.read(buffer, sizeof(buffer));
cout << buffer << endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoJI2luY2x1ZGUgPHNzdHJlYW0+CgoJbmFtZXNwYWNlIHN0ZAoJewoJCXN0cnVjdCBzdWJzdHJlYW1idWYgOiBwdWJsaWMgc3RyZWFtYnVmCgkJewoJCQlleHBsaWNpdCBzdWJzdHJlYW1idWYoc3RyZWFtYnVmKiBzYnVmLCBzdHJlYW1wb3MgcG9zLCBzdHJlYW1wb3MgbGVuKSA6CgkJCW1fc2J1ZihzYnVmKSwKCQkJbV9wb3MocG9zKSwKCQkJbV9sZW4obGVuKSwKCQkJbV9yZWFkKDApCgkJCXsKCQkJCW1fc2J1Zi0+cHVic2Vla3Bvcyhwb3MpOwoKCQkJCXNldGJ1ZihudWxscHRyLCAwKTsKCQkJfQoKCQlwcm90ZWN0ZWQ6CgkJCWludCB1bmRlcmZsb3coKQoJCQl7CgkJCQlpZiAobV9yZWFkID49IG1fbGVuKQoJCQkJewoJCQkJCXJldHVybiB0cmFpdHNfdHlwZTo6ZW9mKCk7CgkJCQl9CgoJCQkJcmV0dXJuIG1fc2J1Zi0+c2dldGMoKTsKCQkJfQoKCQkJaW50IHVmbG93KCkKCQkJewoJCQkJaWYgKG1fcmVhZCA+PSBtX2xlbikKCQkJCXsKCQkJCQlyZXR1cm4gdHJhaXRzX3R5cGU6OmVvZigpOwoJCQkJfQoKCQkJCW1fcmVhZCArPSAxOwoKCQkJCXJldHVybiBtX3NidWYtPnNidW1wYygpOwoJCQl9CgoJCQlzdHJlYW1wb3Mgc2Vla29mZihzdHJlYW1vZmYgb2ZmLCBpb3NfYmFzZTo6c2Vla2RpciBzZWVrZGlyLCBpb3NfYmFzZTo6b3Blbm1vZGUgb3Blbm1vZGUgPSBpb3NfYmFzZTo6aW4gfCBpb3NfYmFzZTo6b3V0KQoJCQl7CgkJCQlpZiAoc2Vla2RpciA9PSBpb3NfYmFzZTo6YmVnKQoJCQkJewoJCQkJCW9mZiArPSBtX3BvczsKCQkJCX0KCQkJCWVsc2UgaWYgKHNlZWtkaXIgPT0gaW9zX2Jhc2U6OmN1cikKCQkJCXsKCQkJCQlvZmYgKz0gbV9wb3MgKyBtX3JlYWQ7CgkJCQl9CgkJCQllbHNlIGlmIChzZWVrZGlyID09IGlvc19iYXNlOjplbmQpCgkJCQl7CgkJCQkJb2ZmICs9IG1fcG9zICsgbV9sZW47CgkJCQl9CgoJCQkJcmV0dXJuIG1fc2J1Zi0+cHVic2Vla3BvcyhvZmYsIG9wZW5tb2RlKSAtIG1fcG9zOwoJCQl9CgoJCQlzdHJlYW1wb3Mgc2Vla3BvcyhzdHJlYW1wb3Mgc3RyZWFtcG9zLCBpb3NfYmFzZTo6b3Blbm1vZGUgb3Blbm1vZGUgPSBpb3NfYmFzZTo6aW4gfCBpb3NfYmFzZTo6b3V0KQoJCQl7CgkJCQlzdHJlYW1wb3MgKz0gbV9wb3M7CgoJCQkJaWYgKHN0cmVhbXBvcyA+IG1fcG9zICsgbV9sZW4pCgkJCQl7CgkJCQkJcmV0dXJuIC0xOwoJCQkJfQoKCQkJCXJldHVybiBtX3NidWYtPnB1YnNlZWtwb3Moc3RyZWFtcG9zLCBvcGVubW9kZSkgLSBtX3BvczsKCQkJfQoKCQlwcml2YXRlOgoJCQlzdHJlYW1idWYqIG1fc2J1ZjsKCQkJc3RyZWFtcG9zIG1fcG9zOwoJCQlzdHJlYW1zaXplIG1fbGVuOwoJCQlzdHJlYW1wb3MgbV9yZWFkOwoJCX07Cgl9OwoKI2luY2x1ZGUgPGlvc3RyZWFtPgoJI2luY2x1ZGUgPHNzdHJlYW0+CgoJdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCglpbnQgbWFpbigpCgl7CgkJc3RyaW5nc3RyZWFtIHNzOwoKCQlzcyA8PCAiSGVsbG8sIFdvcmxkISI7CgoJCXN1YnN0cmVhbWJ1ZiBhc2Qoc3MucmRidWYoKSwgMCwgNSk7CgoJCWlzdHJlYW0gaXN0cmVhbSgmYXNkKTsKCgkJY2hhciBidWZmZXJbNl0gPSB7ICdcMCcgfTsKCQlpc3RyZWFtLnJlYWQoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSk7CgoJCWNvdXQgPDwgYnVmZmVyIDw8IGVuZGw7Cgl9