mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
feat: memory_istream seek support
This commit is contained in:
parent
07702f9e57
commit
ce0f90d21e
2 changed files with 62 additions and 1 deletions
|
|
@ -15,8 +15,33 @@ public:
|
||||||
memory_streambuf(const memory_streambuf&) = delete;
|
memory_streambuf(const memory_streambuf&) = delete;
|
||||||
memory_streambuf& operator=(const memory_streambuf&) = delete;
|
memory_streambuf& operator=(const memory_streambuf&) = delete;
|
||||||
|
|
||||||
|
pos_type seekoff(off_type off, std::ios_base::seekdir way,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::in) override {
|
||||||
|
if (!(mode & std::ios_base::in)) return pos_type(off_type(-1));
|
||||||
|
char* base = eback();
|
||||||
|
char* end = egptr();
|
||||||
|
if (!base || !end) return pos_type(off_type(-1));
|
||||||
|
|
||||||
|
std::ptrdiff_t current = gptr() - base;
|
||||||
|
std::ptrdiff_t newpos;
|
||||||
|
if (way == std::ios_base::beg) newpos = off;
|
||||||
|
else if (way == std::ios_base::cur) newpos = current + off;
|
||||||
|
else if (way == std::ios_base::end) newpos = (end - base) + off;
|
||||||
|
else return pos_type(off_type(-1));
|
||||||
|
|
||||||
|
if (newpos < 0 || base + newpos > end) return pos_type(off_type(-1));
|
||||||
|
setg(base, base + newpos, end);
|
||||||
|
return pos_type(off_type(newpos));
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_type seekpos(pos_type sp, std::ios_base::openmode mode = std::ios_base::in) override {
|
||||||
|
return seekoff(off_type(sp), std::ios_base::beg, mode);
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
int_type underflow() override {
|
int_type underflow() override {
|
||||||
|
if (gptr() < egptr()) {
|
||||||
|
return traits_type::to_int_type(*gptr());
|
||||||
|
}
|
||||||
return traits_type::eof();
|
return traits_type::eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +61,7 @@ private:
|
||||||
class memory_view_streambuf : public std::streambuf {
|
class memory_view_streambuf : public std::streambuf {
|
||||||
public:
|
public:
|
||||||
explicit memory_view_streambuf(const util::Buffer<char>& buffer)
|
explicit memory_view_streambuf(const util::Buffer<char>& buffer)
|
||||||
: buffer(std::move(buffer)) {
|
: buffer(buffer) {
|
||||||
char* base = const_cast<char*>(this->buffer.data());
|
char* base = const_cast<char*>(this->buffer.data());
|
||||||
char* end = base + this->buffer.size();
|
char* end = base + this->buffer.size();
|
||||||
setg(base, base, end);
|
setg(base, base, end);
|
||||||
|
|
@ -45,8 +70,33 @@ public:
|
||||||
memory_view_streambuf(const memory_view_streambuf&) = delete;
|
memory_view_streambuf(const memory_view_streambuf&) = delete;
|
||||||
memory_view_streambuf& operator=(const memory_view_streambuf&) = delete;
|
memory_view_streambuf& operator=(const memory_view_streambuf&) = delete;
|
||||||
|
|
||||||
|
pos_type seekoff(off_type off, std::ios_base::seekdir way,
|
||||||
|
std::ios_base::openmode mode = std::ios_base::in) override {
|
||||||
|
if (!(mode & std::ios_base::in)) return pos_type(off_type(-1));
|
||||||
|
char* base = eback();
|
||||||
|
char* end = egptr();
|
||||||
|
if (!base || !end) return pos_type(off_type(-1));
|
||||||
|
|
||||||
|
std::ptrdiff_t current = gptr() - base;
|
||||||
|
std::ptrdiff_t newpos;
|
||||||
|
if (way == std::ios_base::beg) newpos = off;
|
||||||
|
else if (way == std::ios_base::cur) newpos = current + off;
|
||||||
|
else if (way == std::ios_base::end) newpos = (end - base) + off;
|
||||||
|
else return pos_type(off_type(-1));
|
||||||
|
|
||||||
|
if (newpos < 0 || base + newpos > end) return pos_type(off_type(-1));
|
||||||
|
setg(base, base + newpos, end);
|
||||||
|
return pos_type(off_type(newpos));
|
||||||
|
}
|
||||||
|
|
||||||
|
pos_type seekpos(pos_type sp, std::ios_base::openmode mode = std::ios_base::in) override {
|
||||||
|
return seekoff(off_type(sp), std::ios_base::beg, mode);
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
int_type underflow() override {
|
int_type underflow() override {
|
||||||
|
if (gptr() < egptr()) {
|
||||||
|
return traits_type::to_int_type(*gptr());
|
||||||
|
}
|
||||||
return traits_type::eof();
|
return traits_type::eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,15 @@ TEST(io, memory_istream) {
|
||||||
ASSERT_EQ(text, std::string(data));
|
ASSERT_EQ(text, std::string(data));
|
||||||
stream.read(text.data(), 1);
|
stream.read(text.data(), 1);
|
||||||
ASSERT_TRUE(stream.eof());
|
ASSERT_TRUE(stream.eof());
|
||||||
|
|
||||||
|
// seek
|
||||||
|
stream.clear();
|
||||||
|
stream.seekg(0);
|
||||||
|
ASSERT_TRUE(stream.good());
|
||||||
|
stream.read(text.data(), n);
|
||||||
|
ASSERT_EQ(text, std::string(data));
|
||||||
|
stream.seekg(-6, std::ios_base::cur);
|
||||||
|
ASSERT_TRUE(stream.good());
|
||||||
|
stream.read(text.data(), 6);
|
||||||
|
ASSERT_EQ(text.substr(0, 6), "world!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue