569 lines
18 KiB
C++
569 lines
18 KiB
C++
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <ctime>
|
|
#include <cstdlib>
|
|
#include <dlib/sliding_buffer.h>
|
|
|
|
#include <dlib/lz77_buffer.h>
|
|
|
|
#include "tester.h"
|
|
|
|
namespace
|
|
{
|
|
using namespace test;
|
|
using namespace std;
|
|
using namespace dlib;
|
|
|
|
logger dlog("test.lz77_buffer");
|
|
|
|
template <
|
|
typename buf
|
|
>
|
|
void lz77_buffer_kernel_test (
|
|
)
|
|
/*!
|
|
requires
|
|
- buf is an implementation of lz77_buffer/lz77_buffer_kernel_abstract.h
|
|
ensures
|
|
- runs tests on buf for compliance with the specs
|
|
!*/
|
|
{
|
|
typedef dlib::sliding_buffer<unsigned char>::kernel_1a sbuf;
|
|
|
|
buf test(8,20);
|
|
srand(static_cast<unsigned int>(time(0)));
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,test.get_history_buffer_limit());
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
for (int g = 0; g < 2; ++g)
|
|
{
|
|
test.clear();
|
|
|
|
for (int i = 0; i < 1000; ++i)
|
|
{
|
|
test.add('a');
|
|
}
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 20);
|
|
|
|
|
|
test.shift_buffers(5);
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 15);
|
|
|
|
|
|
|
|
unsigned long index, length, temp;
|
|
temp = test.get_lookahead_buffer_size();
|
|
test.find_match(index,length,5);
|
|
|
|
|
|
DLIB_TEST_MSG(length <= temp,
|
|
"length: " << length <<
|
|
"\ntemp: " << temp);
|
|
DLIB_TEST(test.get_lookahead_buffer_size() <= 15);
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int g = 0; g < 2; ++g)
|
|
{
|
|
|
|
|
|
|
|
test.clear();
|
|
|
|
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_limit() == 256-20);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
unsigned long a,b, temp = test.get_lookahead_buffer_size();
|
|
test.find_match(a,b,0);
|
|
DLIB_TEST(b <= temp);
|
|
DLIB_TEST(b == 0);
|
|
|
|
test.find_match(a,b,5);
|
|
DLIB_TEST(b == 0);
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_limit() == 256-20);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
|
|
ostringstream sout;
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_limit() == 20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_limit() == 20,);\n";
|
|
istringstream sin(sout.str());
|
|
|
|
sout.str("");
|
|
sout.clear();
|
|
|
|
unsigned char ch;
|
|
sbuf sbuffer;
|
|
sbuffer.set_size(8);
|
|
|
|
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
DLIB_TEST(test.lookahead_buffer(test.get_lookahead_buffer_size()-1) == ch);
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 1);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
DLIB_TEST(test.lookahead_buffer(test.get_lookahead_buffer_size()-1) == ch);
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 2);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
DLIB_TEST(test.lookahead_buffer(test.get_lookahead_buffer_size()-1) == ch);
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 3);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
|
|
// add 17 chars to test so that the lookahead buffer will be full
|
|
for (int i = 0; i < 17; ++i)
|
|
{
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
DLIB_TEST(test.lookahead_buffer(test.get_lookahead_buffer_size()-1) == ch);
|
|
}
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 20);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.lookahead_buffer(0) == sbuffer[20]);
|
|
|
|
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
DLIB_TEST(test.lookahead_buffer(test.get_lookahead_buffer_size()-1) == ch);
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 20);
|
|
DLIB_TEST(test.get_history_buffer_size() == 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// add the above text to test and make sure it gives the correct results
|
|
ch = sin.get();
|
|
while (sin)
|
|
{
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
DLIB_TEST(test.lookahead_buffer(test.get_lookahead_buffer_size()-1) == ch);
|
|
DLIB_TEST(test.history_buffer(0) == sbuffer[21]);
|
|
DLIB_TEST(test.history_buffer(1) == sbuffer[22]);
|
|
|
|
ch = sin.get();
|
|
}
|
|
|
|
|
|
|
|
// make sure the contents of lookahead_buffer and history_buffer
|
|
// match what is in sbuffer
|
|
sbuffer.rotate_right(1);
|
|
for (unsigned int i = 0; i < test.get_history_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()+i] == test.history_buffer(i));
|
|
}
|
|
for (unsigned int i = 0; i < test.get_lookahead_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()-1-i] == test.lookahead_buffer(i));
|
|
}
|
|
sbuffer.rotate_left(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sbuffer.rotate_right(1); // do this because we never put anything in sbuffer[0]
|
|
|
|
unsigned long match_index, match_length;
|
|
unsigned long ltemp = test.get_lookahead_buffer_size();
|
|
test.find_match(match_index,match_length,0);
|
|
DLIB_TEST(match_length <= ltemp);
|
|
|
|
|
|
// verify the match with sbuffer
|
|
for (unsigned int i = 0; i < match_length; ++i)
|
|
{
|
|
DLIB_TEST_MSG(sbuffer[19-i] == sbuffer[match_index+20-i],i);
|
|
}
|
|
|
|
|
|
sin.str("");
|
|
sin.clear();
|
|
|
|
} // for (int g = 0; g < 2; ++g)
|
|
|
|
|
|
for (int g = 0; g < 8; ++g)
|
|
{
|
|
test.clear();
|
|
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_limit() == 256-20);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
sbuf sbuffer;
|
|
sbuffer.set_size(8);
|
|
|
|
ostringstream sout;
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_limit() == 20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_limit() == 20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_lookahead_buffer_size() == 0,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
sout << "DLIB_TEST_MSG(test.get_history_buffer_limit() == 256-20,);\n";
|
|
istringstream sin(sout.str());
|
|
|
|
unsigned char ch;
|
|
for (int i = 0; i < 100; ++i)
|
|
{
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
}
|
|
|
|
// make sure the contents of lookahead_buffer and history_buffer
|
|
// match what is in sbuffer
|
|
sbuffer.rotate_right(1);
|
|
for (unsigned int i = 0; i < test.get_history_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()+i] == test.history_buffer(i));
|
|
}
|
|
for (unsigned int i = 0; i < test.get_lookahead_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()-1-i] == test.lookahead_buffer(i));
|
|
}
|
|
sbuffer.rotate_left(1);
|
|
|
|
|
|
|
|
|
|
unsigned long match_index, match_length;
|
|
unsigned long ltemp = test.get_lookahead_buffer_size();
|
|
test.find_match(match_index,match_length,0);
|
|
DLIB_TEST(match_length <= ltemp);
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 20-match_length);
|
|
|
|
sbuffer.rotate_right(1); // do this because we never put anything in sbuffer[0]
|
|
// verify the match with sbuffer
|
|
for (unsigned int i = 0; i < match_length; ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[i+20-match_length] == sbuffer[i+1+match_index+20-match_length]);
|
|
}
|
|
sbuffer.rotate_left(1); // free up sbuffer[0] for new data
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 7+g*2; ++i)
|
|
{
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
}
|
|
|
|
ch = '?';
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
ch = 'a';
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
ch = 'v';
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
ch = 'i';
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
ch = 's';
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
|
|
|
|
// adjust sbuffer due to the last call to test.find_match()
|
|
// but only if we haven't already added enough (20 or more) chars
|
|
// to fill the lookahead buffer already.
|
|
if (match_length > static_cast<unsigned int>(12+g*2))
|
|
sbuffer.rotate_left(match_length-(12+g*2));
|
|
|
|
|
|
|
|
|
|
|
|
// make sure the contents of lookahead_buffer and history_buffer
|
|
// match what is in sbuffer
|
|
sbuffer.rotate_right(1);
|
|
for (unsigned int i = 0; i < test.get_history_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()+i] == test.history_buffer(i));
|
|
}
|
|
for (unsigned int i = 0; i < test.get_lookahead_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()-1-i] == test.lookahead_buffer(i));
|
|
}
|
|
sbuffer.rotate_left(1);
|
|
|
|
|
|
|
|
|
|
test.find_match(match_index,match_length,10+g);
|
|
|
|
if (match_length > 0)
|
|
DLIB_TEST(match_length >= static_cast<unsigned int>(10+g) );
|
|
|
|
|
|
sbuffer.rotate_right(1); // do this because we never put anything in sbuffer[0]
|
|
// verify the match with sbuffer
|
|
for (unsigned int i = 0; i < match_length; ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[i+20-match_length] == sbuffer[i+1+match_index+20-match_length]);
|
|
}
|
|
sbuffer.rotate_left(1); // free up sbuffer[0] for new data
|
|
|
|
} // for (int g = 0; g < 8; ++g)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
srand(static_cast<unsigned int>(time(0)));
|
|
|
|
for (int g = 0; g < 200; ++g)
|
|
{
|
|
test.clear();
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_limit() == 256-20);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
sbuf sbuffer;
|
|
sbuffer.set_size(8);
|
|
|
|
ostringstream sout;
|
|
int l = ::rand()%500;
|
|
for (int i = 0; i < l; ++i)
|
|
{
|
|
char temp = static_cast<char>(::rand()%256);
|
|
sout << temp;
|
|
}
|
|
istringstream sin(sout.str());
|
|
|
|
unsigned char ch;
|
|
for (int i = 0; i < l; ++i)
|
|
{
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
}
|
|
|
|
// make sure the contents of lookahead_buffer and history_buffer
|
|
// match what is in sbuffer
|
|
sbuffer.rotate_right(1);
|
|
|
|
// adjust so that sbuffer[19] is the same as lookahead_buffer[0]
|
|
if (test.get_lookahead_buffer_size() < 20)
|
|
sbuffer.rotate_left(20-test.get_lookahead_buffer_size());
|
|
|
|
for (unsigned int i = 0; i < test.get_history_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()+i] == test.history_buffer(i));
|
|
}
|
|
for (unsigned int i = 0; i < test.get_lookahead_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()-1-i] == test.lookahead_buffer(i));
|
|
}
|
|
sbuffer.rotate_left(1);
|
|
|
|
|
|
|
|
unsigned long match_index, match_length;
|
|
unsigned long lookahead_size_before = test.get_lookahead_buffer_size();
|
|
test.find_match(match_index,match_length,0);
|
|
DLIB_TEST(match_length <= lookahead_size_before);
|
|
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == lookahead_size_before-match_length);
|
|
|
|
sbuffer.rotate_right(1); // do this because we never put anything in sbuffer[0]
|
|
// verify the match with sbuffer
|
|
for (unsigned int i = 0; i < match_length; ++i)
|
|
{
|
|
DLIB_TEST_MSG(sbuffer[19-i] == sbuffer[match_index+20-i],i);
|
|
}
|
|
sbuffer.rotate_left(1); // free up sbuffer[0] for new data
|
|
|
|
} // for (int g = 0; g < 200; ++g)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
srand(static_cast<unsigned int>(time(0)));
|
|
|
|
for (int g = 0; g < 300; ++g)
|
|
{
|
|
test.clear();
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_size() == 0);
|
|
DLIB_TEST(test.get_history_buffer_limit() == 256-20);
|
|
DLIB_TEST(test.get_lookahead_buffer_limit() == 20);
|
|
|
|
|
|
sbuf sbuffer;
|
|
sbuffer.set_size(8);
|
|
|
|
ostringstream sout;
|
|
int l = ::rand()%500;
|
|
for (int i = 0; i < l; ++i)
|
|
{
|
|
char temp = static_cast<char>(::rand()%20);
|
|
sout << temp;
|
|
sout << temp;
|
|
sout << temp;
|
|
sout << temp;
|
|
sout << temp;
|
|
sout << temp;
|
|
}
|
|
istringstream sin(sout.str());
|
|
|
|
unsigned char ch;
|
|
for (int i = 0; i < l; ++i)
|
|
{
|
|
ch = sin.get();
|
|
sbuffer[0] = ch; sbuffer.rotate_left(1);
|
|
test.add(ch);
|
|
}
|
|
|
|
// make sure the contents of lookahead_buffer and history_buffer
|
|
// match what is in sbuffer
|
|
sbuffer.rotate_right(1);
|
|
|
|
// adjust so that sbuffer[19] is the same as lookahead_buffer[0]
|
|
if (test.get_lookahead_buffer_size() < 20)
|
|
sbuffer.rotate_left(20-test.get_lookahead_buffer_size());
|
|
|
|
for (unsigned int i = 0; i < test.get_history_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()+i] == test.history_buffer(i));
|
|
}
|
|
for (unsigned int i = 0; i < test.get_lookahead_buffer_size(); ++i)
|
|
{
|
|
DLIB_TEST(sbuffer[test.get_lookahead_buffer_limit()-1-i] == test.lookahead_buffer(i));
|
|
}
|
|
sbuffer.rotate_left(1);
|
|
|
|
|
|
|
|
unsigned long match_index = 0, match_length = 0;
|
|
unsigned long lookahead_size_before = test.get_lookahead_buffer_size();
|
|
unsigned long history_size_before = test.get_history_buffer_size();
|
|
test.find_match(match_index,match_length,2);
|
|
|
|
if (match_length != 0)
|
|
{
|
|
DLIB_TEST_MSG(match_index < history_size_before,
|
|
"match_index: " << match_index <<
|
|
"\nhistory_size_before: " << history_size_before);
|
|
|
|
}
|
|
|
|
|
|
DLIB_TEST(test.get_lookahead_buffer_size() == lookahead_size_before-match_length);
|
|
|
|
sbuffer.rotate_right(1); // do this because we never put anything in sbuffer[0]
|
|
// verify the match with sbuffer
|
|
for (unsigned int i = 0; i < match_length; ++i)
|
|
{
|
|
DLIB_TEST_MSG(sbuffer[19-i] == sbuffer[match_index+20-i],i);
|
|
}
|
|
sbuffer.rotate_left(1); // free up sbuffer[0] for new data
|
|
|
|
|
|
|
|
} // for (int g = 0; g < 300; ++g)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class lz77_buffer_tester : public tester
|
|
{
|
|
public:
|
|
lz77_buffer_tester (
|
|
) :
|
|
tester ("test_lz77_buffer",
|
|
"Runs tests on the lz77_buffer component.")
|
|
{}
|
|
|
|
void perform_test (
|
|
)
|
|
{
|
|
dlog << LINFO << "testing kernel_1a";
|
|
lz77_buffer_kernel_test<lz77_buffer::kernel_1a> ();
|
|
dlog << LINFO << "testing kernel_1a_c";
|
|
lz77_buffer_kernel_test<lz77_buffer::kernel_1a_c>();
|
|
dlog << LINFO << "testing kernel_2a";
|
|
lz77_buffer_kernel_test<lz77_buffer::kernel_2a> ();
|
|
dlog << LINFO << "testing kernel_2a_c";
|
|
lz77_buffer_kernel_test<lz77_buffer::kernel_2a_c>();
|
|
}
|
|
} a;
|
|
|
|
}
|
|
|