diff --git a/src/libscio.hpp b/src/libscio.hpp index 3b4c582..0ccbe14 100644 --- a/src/libscio.hpp +++ b/src/libscio.hpp @@ -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; diff --git a/src/memstreambuf.cpp b/src/memstreambuf.cpp index eb29e35..7e0a85f 100644 --- a/src/memstreambuf.cpp +++ b/src/memstreambuf.cpp @@ -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) { @@ -55,25 +52,53 @@ 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*/) { - 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"); + std::ios_base::seekdir dir, + std::ios_base::openmode which) { + if (which & std::ios::in) { // reading + switch (dir) { + case std::ios::beg: + if (off < 0 || static_cast(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(pos) > _size) return EOF; + setg(_mem, gptr() + off, _mem + _size); + break; + } + case std::ios::end: + if (off > 0 || static_cast(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 gptr() - _mem; + return EOF; } std::streambuf::pos_type sc::io::memstreambuf::seekpos(std::streambuf::pos_type pos, - std::ios_base::openmode /*which*/) { - setg(_mem, _mem + pos, _mem + _size); - return gptr() - _mem; + std::ios_base::openmode which) { + if (which & std::ios::in) { + if (pos < 0 || static_cast(pos) > _size) return EOF; + setg(_mem, _mem + pos, _mem + _size); + 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; }