vectorstream updates: added seekoff and seekpos (#2179)

* [DLIB] added seekpos and seekoff functions. These are necessary for functions in iostream base class to work properly. e.g. seekg. Note that in seekoff, you do NOT want to check the validity of read_pos after it has been updated. dlib::vectorstream and std::iostream work together to set EOF and/or badbit. Doing something like seekg(10000) should not throw even if the underlying buffer has 2 bytes. You should check if EOF is set and possibly call clear(). We have removed seekg from dlib::vectorstream as this adds confusion. Now std::iostream::seekg is called which somewhere down the callstack will call seekpos and/or seekoff. So there should be no diverging functionality between calling seekg on dlib::vectorstream& or std::iostream& when there is a cast.

* [DLIB] vectorstream unit test is updated to run identical tests on dlib::vectorstream& and std::iostream&

* [DLIB] only support read pointers and delete copy and move semantics

* [DLIB] explicit tests for seekg() in different directions

* [DLIB]  - no need to delete the move constructor and move assign operator. This is implicitly done by deleting the copy constructor and copy assign operator.

* [DLIB]  - remove leftover comments. no need
		- use more idiomatic notation

Co-authored-by: pf <pf@pf-ubuntu-dev>
This commit is contained in:
pfeatherstone 2020-09-17 01:37:36 +01:00 committed by GitHub
parent cdeb2e067c
commit d4fe74b5a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 21 deletions

View File

@ -21,16 +21,10 @@ namespace
logger dlog("test.vectorstream");
// ----------------------------------------------------------------------------------------
void test1()
template <typename stream>
void test1_variant(std::vector<char>& buf, stream& s)
{
print_spinner();
std::vector<char> buf;
vectorstream s(buf);
for (int i = -1000; i <= 1000; ++i)
{
char ch = i;
@ -59,7 +53,7 @@ namespace
DLIB_TEST(s.get() == EOF);
s.clear();
s.seekg(6);
s.seekg(6); //Let iostream decide which path to take. In theory it could decide to use any.
for (int i = -1000+6; i <= 1000; ++i)
{
@ -71,13 +65,58 @@ namespace
DLIB_TEST(s.peek() == EOF);
DLIB_TEST(s.get() == EOF);
s.clear();
s.seekg(6, std::ios_base::beg);
for (int i = -1000+6; i <= 1000; ++i)
{
DLIB_TEST(s.peek() != EOF);
char ch1 = i;
char ch2 = s.get();
DLIB_TEST(ch1 == ch2);
}
DLIB_TEST(s.peek() == EOF);
DLIB_TEST(s.get() == EOF);
s.clear();
s.seekg(1000, std::ios_base::beg); //read_pos should be 1000
DLIB_TEST(s.good()); //yep, still good
DLIB_TEST(s.peek() == char(0)); //read_pos should still be 1000
s.seekg(6, std::ios_base::cur); //read_pos should be 1006
for (int i = 6; i <= 1000; ++i)
{
DLIB_TEST(s.peek() != EOF);
char ch1 = i;
char ch2 = s.get();
DLIB_TEST(ch1 == ch2);
}
DLIB_TEST(s.peek() == EOF);
DLIB_TEST(s.get() == EOF);
s.clear();
s.seekg(-6, std::ios_base::end); //read_pos should be 1995
for (int i = 995; i <= 1000; ++i)
{
DLIB_TEST(s.peek() != EOF);
char ch1 = i;
char ch2 = s.get();
DLIB_TEST(ch1 == ch2);
}
DLIB_TEST(s.peek() == EOF);
DLIB_TEST(s.get() == EOF);
std::string temp;
temp = "one two three!";
s.clear();
s.seekg(0);
buf.clear();
s.clear();
serialize(temp, s);
std::string temp2;
@ -119,6 +158,26 @@ namespace
DLIB_TEST(s.good() == false);
}
// ----------------------------------------------------------------------------------------
void test1()
{
print_spinner();
{
std::vector<char> buf;
vectorstream s1(buf);
test1_variant(buf, s1);
}
{
vector<char> buf;
dlib::vectorstream s1(buf);
std::iostream& s2 = s1;
test1_variant(buf, s2);
}
}
// ----------------------------------------------------------------------------------------
class test_vectorstream : public tester

View File

@ -11,7 +11,7 @@
#include <vector>
#include <cstdio>
#include "../algs.h"
#include "../assert.h"
#ifdef _MSC_VER
// Disable the warning about inheriting from std::iostream 'via dominance' since this warning is a warning about
@ -43,6 +43,32 @@ namespace dlib
{
read_pos = pos;
}
pos_type seekpos(pos_type pos, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);
}
pos_type seekoff(off_type off, std::ios_base::seekdir dir,
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out )
{
DLIB_ASSERT(mode == std::ios_base::in, "vectorstream does not support std::ios_base::out");
switch (dir)
{
case std::ios_base::beg:
read_pos = off;
break;
case std::ios_base::cur:
read_pos += off;
break;
case std::ios_base::end:
read_pos = buffer.size() + off;
break;
default:
break;
}
return pos_type(read_pos);
}
// ------------------------ OUTPUT FUNCTIONS ------------------------
@ -120,15 +146,10 @@ namespace dlib
std::iostream(&buf),
buf(buffer)
{}
std::istream& seekg (
std::streampos pos
)
{
buf.seekg(pos);
return *this;
}
vectorstream(const vectorstream& ori) = delete;
vectorstream(vectorstream&& item) = delete;
private:
vector_streambuf buf;
};