//Small header to get STLport numerous defines:
#include <utility>
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
# include <rope>
# if !defined (_STLP_USE_NO_IOSTREAMS)
# include <sstream>
# endif
#endif
#include "cppunit/cppunit_proxy.h"
// #include <stdlib.h> // for rand etc
#if defined (_STLP_USE_NAMESPACES)
using namespace std;
#endif
//
// TestCase class
//
class RopeTest : public CPPUNIT_NS::TestCase
{
CPPUNIT_TEST_SUITE(RopeTest);
#if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS)
CPPUNIT_IGNORE;
#endif
CPPUNIT_TEST(io);
#if defined (_STLP_USE_NO_IOSTREAMS)
CPPUNIT_STOP_IGNORE;
#endif
CPPUNIT_TEST(find1);
CPPUNIT_TEST(find2);
CPPUNIT_TEST(construct_from_char);
CPPUNIT_TEST(bug_report);
#if !defined (_STLP_MEMBER_TEMPLATES)
CPPUNIT_IGNORE;
#endif
CPPUNIT_TEST(test_saved_rope_iterators);
CPPUNIT_TEST_SUITE_END();
protected:
void io();
void find1();
void find2();
void construct_from_char();
void bug_report();
void test_saved_rope_iterators();
};
CPPUNIT_TEST_SUITE_REGISTRATION(RopeTest);
//
// tests implementation
//
void RopeTest::io()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && !defined (_STLP_USE_NO_IOSTREAMS)
char const* cstr = "rope test string";
crope rstr(cstr);
{
ostringstream ostr;
ostr << rstr;
CPPUNIT_ASSERT( ostr );
CPPUNIT_ASSERT( ostr.str() == cstr );
}
#endif
}
void RopeTest::find1()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
crope r("Fuzzy Wuzzy was a bear");
crope::size_type n = r.find( "hair" );
CPPUNIT_ASSERT( n == crope::npos );
n = r.find("ear");
CPPUNIT_ASSERT( n == (r.size() - 3) );
#endif
}
void RopeTest::find2()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
crope r("Fuzzy Wuzzy was a bear");
crope::size_type n = r.find( 'e' );
CPPUNIT_ASSERT( n == (r.size() - 3) );
#endif
}
void RopeTest::construct_from_char()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
crope r('1');
char const* s = r.c_str();
CPPUNIT_ASSERT( '1' == s[0] && '\0' == s[1] );
#endif
}
// Test used for a bug report from Peter Hercek
void RopeTest::bug_report()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
//first create a rope bigger than crope::_S_copy_max = 23
// so that any string addition is added to a new leaf
crope evilRope("12345678901234567890123_");
//crope* pSevenCharRope( new TRope("1234567") );
crope sevenCharRope0("12345678");
crope sevenCharRope1("1234567");
// add _Rope_RopeRep<c,a>::_S_alloc_granularity-1 = 7 characters
evilRope += "1234567"; // creates a new leaf
crope sevenCharRope2("1234567");
// add one more character to the leaf
evilRope += '8'; // here is the write beyond the allocated memory
CPPUNIT_ASSERT( strcmp(sevenCharRope2.c_str(), "1234567") == 0 );
#endif
}
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
const char str[] = "ilcpsklryvmcpjnbpbwllsrehfmxrkecwitrsglrexvtjmxypu\
nbqfgxmuvgfajclfvenhyuhuorjosamibdnjdbeyhkbsomblto\
uujdrbwcrrcgbflqpottpegrwvgajcrgwdlpgitydvhedtusip\
pyvxsuvbvfenodqasajoyomgsqcpjlhbmdahyviuemkssdslde\
besnnngpesdntrrvysuipywatpfoelthrowhfexlwdysvspwlk\
fblfdf";
crope create_rope( int len )
{
int l = len/2;
crope result;
if(l <= 2)
{
static int j = 0;
for(int i = 0; i < len; ++i)
{
// char c = 'a' + rand() % ('z' - 'a');
result.append(1, /* c */ str[j++] );
j %= sizeof(str);
}
}
else
{
result = create_rope(len/2);
result.append(create_rope(len/2));
}
return result;
}
#endif
void RopeTest::test_saved_rope_iterators()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \
defined (_STLP_MEMBER_TEMPLATES)
//
// Try and create a rope with a complex tree structure:
//
// srand(0);
crope r = create_rope(300);
string expected(r.begin(), r.end());
CPPUNIT_ASSERT(expected.size() == r.size());
CPPUNIT_ASSERT(equal(expected.begin(), expected.end(), r.begin()));
crope::const_iterator i(r.begin()), j(r.end());
int pos = 0;
while(i != j)
{
crope::const_iterator k;
// This initial read triggers the bug:
CPPUNIT_ASSERT(*i);
k = i;
int newpos = pos;
// Now make sure that i is incremented into the next leaf:
while(i != j)
{
CPPUNIT_ASSERT(*i == expected[newpos]);
++i;
++newpos;
}
// Back up from stored value and continue:
i = k;
++i;
++pos;
}
#endif
}