Fixed seeking

This commit is contained in:
Bob Polis 2022-12-12 18:36:08 +01:00
parent 270492d1a7
commit b7112f0d23
2 changed files with 49 additions and 24 deletions

View File

@ -327,8 +327,8 @@ namespace sc {
protected:
// input
int_type underflow() override;
int_type uflow() override;
std::streamsize xsgetn(char* s, std::streamsize n) override;
// output
int_type overflow(int_type c) override;

View File

@ -12,6 +12,11 @@ void sc::io::memstreambuf::init(char* mem, size_t size) {
setg(_mem, _mem, _mem + _size);
}
std::streambuf::int_type sc::io::memstreambuf::underflow() {
if (gptr() == _mem + _size) return EOF;
return *gptr();
}
std::streambuf::int_type sc::io::memstreambuf::uflow() {
if (gptr() == _mem + _size) return EOF;
char c = *gptr();
@ -19,14 +24,6 @@ std::streambuf::int_type sc::io::memstreambuf::uflow() {
return c;
}
std::streamsize sc::io::memstreambuf::xsgetn(char* s, std::streamsize n) {
std::streamsize left = _mem + _size - gptr();
std::streamsize tot_read = std::min(left, n);
if (tot_read == 0) return EOF;
std::memcpy(s, gptr(), tot_read);
return tot_read;
}
std::streambuf::int_type sc::io::memstreambuf::overflow(std::streambuf::int_type c) {
// TODO
// if (c != EOF) {
@ -43,7 +40,7 @@ std::streambuf::int_type sc::io::memstreambuf::overflow(std::streambuf::int_type
return c;
}
std::streamsize sc::io::memstreambuf::xsputn(const char* s, std::streamsize num) {
std::streamsize sc::io::memstreambuf::xsputn(const char* /*s*/, std::streamsize num) {
// TODO
// int res = write(_fd, s, num);
// if (res != num) {
@ -56,24 +53,52 @@ std::streamsize sc::io::memstreambuf::xsputn(const char* s, std::streamsize num)
std::streambuf::pos_type sc::io::memstreambuf::seekoff(std::streambuf::off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode /*which*/) {
std::ios_base::openmode which) {
if (which & std::ios::in) { // reading
switch (dir) {
case std::ios_base::beg: setg(_mem, _mem + off, _mem + _size); break;
case std::ios_base::end: setg(_mem, _mem + _size - off, _mem + _size); break;
case std::ios_base::cur: setg(_mem, gptr() + off, _mem + _size); break;
default: throw std::runtime_error("invalid seekdir");
case std::ios::beg:
if (off < 0 || static_cast<size_t>(off) > _size) return EOF;
setg(_mem, _mem + off, _mem + _size);
break;
case std::ios::cur: {
int64_t pos = gptr() - _mem + off;
if (pos < 0 || static_cast<size_t>(pos) > _size) return EOF;
setg(_mem, gptr() + off, _mem + _size);
break;
}
case std::ios::end:
if (off > 0 || static_cast<size_t>(off) < -_size) return EOF;
setg(_mem, _mem + _size + off - 1, _mem + _size);
break;
}
return gptr() - _mem;
} else if (which & std::ios::out) { // writing
switch (dir) { // TODO
case std::ios::beg:
break;
case std::ios::cur:
break;
case std::ios::end:
break;
}
return pptr() - _mem;
}
return EOF;
}
std::streambuf::pos_type sc::io::memstreambuf::seekpos(std::streambuf::pos_type pos,
std::ios_base::openmode /*which*/) {
std::ios_base::openmode which) {
if (which & std::ios::in) {
if (pos < 0 || static_cast<size_t>(pos) > _size) return EOF;
setg(_mem, _mem + pos, _mem + _size);
return gptr() - _mem;
return pos;
} else if (which & std::ios::out) {
// TODO
return pos;
}
return EOF;
}
std::streambuf::int_type sc::io::memstreambuf::pbackfail(std::streambuf::int_type /*c*/) {
setg(_mem, gptr() - 1, _mem + _size);
if (gptr() < _mem) return EOF;
return 0;
return EOF;
}