1//Small header to get STLport numerous defines:
2#include <utility>
3
4#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
5#  include <rope>
6
7#  if !defined (_STLP_USE_NO_IOSTREAMS)
8#    include <sstream>
9#  endif
10#endif
11
12#include "cppunit/cppunit_proxy.h"
13
14// #include <stdlib.h> // for rand etc
15
16#if defined (_STLP_USE_NAMESPACES)
17using namespace std;
18#endif
19
20//
21// TestCase class
22//
23class RopeTest : public CPPUNIT_NS::TestCase
24{
25  CPPUNIT_TEST_SUITE(RopeTest);
26#if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS)
27  CPPUNIT_IGNORE;
28#endif
29  CPPUNIT_TEST(io);
30#if defined (_STLP_USE_NO_IOSTREAMS)
31  CPPUNIT_STOP_IGNORE;
32#endif
33  CPPUNIT_TEST(find1);
34  CPPUNIT_TEST(find2);
35  CPPUNIT_TEST(construct_from_char);
36  CPPUNIT_TEST(bug_report);
37#if !defined (_STLP_MEMBER_TEMPLATES)
38  CPPUNIT_IGNORE;
39#endif
40  CPPUNIT_TEST(test_saved_rope_iterators);
41  CPPUNIT_TEST_SUITE_END();
42
43protected:
44  void io();
45  void find1();
46  void find2();
47  void construct_from_char();
48  void bug_report();
49  void test_saved_rope_iterators();
50};
51
52CPPUNIT_TEST_SUITE_REGISTRATION(RopeTest);
53
54//
55// tests implementation
56//
57void RopeTest::io()
58{
59#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && !defined (_STLP_USE_NO_IOSTREAMS)
60  char const* cstr = "rope test string";
61  crope rstr(cstr);
62
63  {
64    ostringstream ostr;
65    ostr << rstr;
66
67    CPPUNIT_ASSERT( ostr );
68    CPPUNIT_ASSERT( ostr.str() == cstr );
69  }
70#endif
71}
72
73void RopeTest::find1()
74{
75#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
76  crope r("Fuzzy Wuzzy was a bear");
77  crope::size_type n = r.find( "hair" );
78  CPPUNIT_ASSERT( n == crope::npos );
79
80  n = r.find("ear");
81
82  CPPUNIT_ASSERT( n == (r.size() - 3) );
83#endif
84}
85
86void RopeTest::find2()
87{
88#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
89  crope r("Fuzzy Wuzzy was a bear");
90  crope::size_type n = r.find( 'e' );
91  CPPUNIT_ASSERT( n == (r.size() - 3) );
92#endif
93}
94
95void RopeTest::construct_from_char()
96{
97#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
98  crope r('1');
99  char const* s = r.c_str();
100  CPPUNIT_ASSERT( '1' == s[0] && '\0' == s[1] );
101#endif
102}
103
104// Test used for a bug report from Peter Hercek
105void RopeTest::bug_report()
106{
107#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
108  //first create a rope bigger than crope::_S_copy_max = 23
109  // so that any string addition is added to a new leaf
110  crope evilRope("12345678901234567890123_");
111  //crope* pSevenCharRope( new TRope("1234567") );
112  crope sevenCharRope0("12345678");
113  crope sevenCharRope1("1234567");
114  // add _Rope_RopeRep<c,a>::_S_alloc_granularity-1 = 7 characters
115  evilRope += "1234567"; // creates a new leaf
116  crope sevenCharRope2("1234567");
117  // add one more character to the leaf
118  evilRope += '8'; // here is the write beyond the allocated memory
119  CPPUNIT_ASSERT( strcmp(sevenCharRope2.c_str(), "1234567") == 0 );
120#endif
121}
122
123#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
124const char str[] = "ilcpsklryvmcpjnbpbwllsrehfmxrkecwitrsglrexvtjmxypu\
125nbqfgxmuvgfajclfvenhyuhuorjosamibdnjdbeyhkbsomblto\
126uujdrbwcrrcgbflqpottpegrwvgajcrgwdlpgitydvhedtusip\
127pyvxsuvbvfenodqasajoyomgsqcpjlhbmdahyviuemkssdslde\
128besnnngpesdntrrvysuipywatpfoelthrowhfexlwdysvspwlk\
129fblfdf";
130
131crope create_rope( int len )
132{
133   int l = len/2;
134   crope result;
135   if(l <= 2)
136   {
137      static int j = 0;
138      for(int i = 0; i < len; ++i)
139      {
140         // char c = 'a' + rand() % ('z' - 'a');
141         result.append(1, /* c */ str[j++] );
142         j %= sizeof(str);
143      }
144   }
145   else
146   {
147      result = create_rope(len/2);
148      result.append(create_rope(len/2));
149   }
150   return result;
151}
152
153#endif
154
155void RopeTest::test_saved_rope_iterators()
156{
157#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \
158    defined (_STLP_MEMBER_TEMPLATES)
159   //
160   // Try and create a rope with a complex tree structure:
161   //
162   // srand(0);
163   crope r = create_rope(300);
164   string expected(r.begin(), r.end());
165   CPPUNIT_ASSERT(expected.size() == r.size());
166   CPPUNIT_ASSERT(equal(expected.begin(), expected.end(), r.begin()));
167   crope::const_iterator i(r.begin()), j(r.end());
168   int pos = 0;
169   while(i != j)
170   {
171      crope::const_iterator k;
172      // This initial read triggers the bug:
173      CPPUNIT_ASSERT(*i);
174      k = i;
175      int newpos = pos;
176      // Now make sure that i is incremented into the next leaf:
177      while(i != j)
178      {
179         CPPUNIT_ASSERT(*i == expected[newpos]);
180         ++i;
181         ++newpos;
182      }
183      // Back up from stored value and continue:
184      i = k;
185      ++i;
186      ++pos;
187   }
188#endif
189}
190