// Copyright (C) 2012 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#include <dlib/vectorstream.h>
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include "tester.h"
namespace
{
using namespace test;
using namespace dlib;
using namespace std;
logger dlog("test.vectorstream");
template <typename CharType, typename stream>
void test1_variant(std::vector<CharType>& buf, stream& s)
{
for (int i = -1000; i <= 1000; ++i)
{
char ch = i;
s.put(ch);
}
DLIB_TEST(buf.size() == 2001);
int cnt = -1000;
for (unsigned long i = 0; i < buf.size(); ++i)
{
char ch = cnt;
DLIB_TEST((char)buf[i] == ch);
++cnt;
}
for (int i = -1000; 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); //Let iostream decide which path to take. In theory it could decide to use any.
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(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();
serialize(temp, s);
std::string temp2;
deserialize(temp2, s);
DLIB_TEST(temp2 == temp);
s.put('1');
s.put('2');
s.put('3');
s.put('4');
DLIB_TEST(s.get() == '1');
DLIB_TEST(s.get() == '2');
DLIB_TEST(s.get() == '3');
DLIB_TEST(s.get() == '4');
s.putback('4');
DLIB_TEST(s.get() == '4');
s.putback('4');
s.putback('3');
s.putback('2');
s.putback('1');
DLIB_TEST(s.get() == '1');
DLIB_TEST(s.get() == '2');
DLIB_TEST(s.get() == '3');
DLIB_TEST(s.get() == '4');
DLIB_TEST(s.good() == true);
DLIB_TEST(s.get() == EOF);
DLIB_TEST(s.good() == false);
// make sure seeking to a crazy offset doesn't mess things up
s.clear();
s.seekg(1000000);
DLIB_TEST(s.get() == EOF);
DLIB_TEST(s.good() == false);
s.clear();
s.seekg(1000000);
char sbuf[100];
s.read(sbuf, sizeof(sbuf));
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);
}
{
std::vector<int8_t> buf;
vectorstream s1(buf);
test1_variant(buf, s1);
}
{
vector<int8_t> buf;
dlib::vectorstream s1(buf);
std::iostream& s2 = s1;
test1_variant(buf, s2);
}
{
std::vector<uint8_t> buf;
vectorstream s1(buf);
test1_variant(buf, s1);
}
{
vector<uint8_t> buf;
dlib::vectorstream s1(buf);
std::iostream& s2 = s1;
test1_variant(buf, s2);
}
}
// ----------------------------------------------------------------------------------------
class test_vectorstream : public tester
{
public:
test_vectorstream (
) :
tester ("test_vectorstream",
"Runs tests on the vectorstream component.")
{}
void perform_test (
)
{
test1();
}
} a;
}