    // 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");

    // ----------------------------------------------------------------------------------------

        void test1()
        {
            print_spinner();

            std::vector<char> buf;
            vectorstream s(buf);

            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(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);

            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);

            std::string temp;
            temp = "one two three!";

            s.seekg(0);
            buf.clear();
            s.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);
        }

    // ----------------------------------------------------------------------------------------

        class test_vectorstream : public tester
        {
        public:
            test_vectorstream (
            ) :
                tester ("test_vectorstream",
                        "Runs tests on the vectorstream component.")
            {}

            void perform_test (
            )
            {
                test1();
            }
        } a;

    }