1 //
2 //********************************************************************
3 // Copyright (C) 2002, International Business Machines
4 // Corporation and others. All Rights Reserved.
5 //********************************************************************
6 //
7 // File stringtest.cpp
8 //
9
10 #include "threadtest.h"
11 #include "unicode/unistr.h"
12 #include "stdio.h"
13
14 class StringThreadTest: public AbstractThreadTest {
15 public:
16 StringThreadTest();
17 virtual ~StringThreadTest();
18 virtual void check();
19 virtual void runOnce();
20 void makeStringCopies(int recursionCount);
21
22 private:
23 UnicodeString *fCleanStrings;
24 UnicodeString *fSourceStrings;
25 };
26
StringThreadTest()27 StringThreadTest::StringThreadTest() {
28 // cleanStrings and sourceStrings are separately initialized to the same values.
29 // cleanStrings are never touched after in any remotely unsafe way.
30 // sourceStrings are copied during the test, which will run their buffer's reference
31 // counts all over the place.
32 fCleanStrings = new UnicodeString[5];
33 fSourceStrings = new UnicodeString[5];
34
35 fCleanStrings[0] = "When sorrows come, they come not single spies, but in batallions.";
36 fSourceStrings[0] = "When sorrows come, they come not single spies, but in batallions.";
37 fCleanStrings[1] = "Away, you scullion! You rampallion! You fustilarion! I'll tickle your catastrophe!";
38 fSourceStrings[1] = "Away, you scullion! You rampallion! You fustilarion! I'll tickle your catastrophe!";
39 fCleanStrings[2] = "hot";
40 fSourceStrings[2] = "hot";
41 fCleanStrings[3] = "";
42 fSourceStrings[3] = "";
43 fCleanStrings[4] = "Tomorrow, and tomorrow, and tomorrow,\n"
44 "Creeps in this petty pace from day to day\n"
45 "To the last syllable of recorded time;\n"
46 "And all our yesterdays have lighted fools \n"
47 "The way to dusty death. Out, out brief candle!\n"
48 "Life's but a walking shadow, a poor player\n"
49 "That struts and frets his hour upon the stage\n"
50 "And then is heard no more. It is a tale\n"
51 "Told by and idiot, full of sound and fury,\n"
52 "Signifying nothing.\n";
53 fSourceStrings[4] = "Tomorrow, and tomorrow, and tomorrow,\n"
54 "Creeps in this petty pace from day to day\n"
55 "To the last syllable of recorded time;\n"
56 "And all our yesterdays have lighted fools \n"
57 "The way to dusty death. Out, out brief candle!\n"
58 "Life's but a walking shadow, a poor player\n"
59 "That struts and frets his hour upon the stage\n"
60 "And then is heard no more. It is a tale\n"
61 "Told by and idiot, full of sound and fury,\n"
62 "Signifying nothing.\n";
63 };
64
65
~StringThreadTest()66 StringThreadTest::~StringThreadTest() {
67 delete [] fCleanStrings;
68 delete [] fSourceStrings;
69 }
70
71
runOnce()72 void StringThreadTest::runOnce() {
73 makeStringCopies(25);
74 }
75
makeStringCopies(int recursionCount)76 void StringThreadTest::makeStringCopies(int recursionCount) {
77 UnicodeString firstGeneration[5];
78 UnicodeString secondGeneration[5];
79 UnicodeString thirdGeneration[5];
80 UnicodeString fourthGeneration[5];
81
82 // Make four generations of copies of the source strings, in slightly variant ways.
83 //
84 int i;
85 for (i=0; i<5; i++) {
86 firstGeneration[i] = fSourceStrings[i];
87 secondGeneration[i] = firstGeneration[i];
88 thirdGeneration[i] = UnicodeString(secondGeneration[i]);
89 // fourthGeneration[i] = UnicodeString("Lay on, MacDuff, And damn'd be him that first cries, \"Hold, enough!\"");
90 fourthGeneration[i] = UnicodeString();
91 fourthGeneration[i] = thirdGeneration[i];
92 }
93
94
95 // Recurse to make even more copies of the strings/
96 //
97 if (recursionCount > 0) {
98 makeStringCopies(recursionCount-1);
99 }
100
101
102 // Verify that all four generations are equal.
103 for (i=0; i<5; i++) {
104 if (firstGeneration[i] != fSourceStrings[i] ||
105 firstGeneration[i] != secondGeneration[i] ||
106 firstGeneration[i] != thirdGeneration[i] ||
107 firstGeneration[i] != fourthGeneration[i])
108 {
109 fprintf(stderr, "Error, strings don't compare equal.\n");
110 }
111 }
112
113 };
114
115
check()116 void StringThreadTest::check() {
117 //
118 // Check that the reference counts on the buffers for all of the source strings
119 // are one. The ref counts will have run way up while the test threads
120 // make numerous copies of the strings, but at the top of the loop all
121 // of the copies should be gone.
122 //
123 int i;
124
125 for (i=0; i<5; i++) {
126 if (fSourceStrings[i].fFlags & UnicodeString::kRefCounted) {
127 const UChar *buf = fSourceStrings[i].getBuffer();
128 uint32_t refCount = fSourceStrings[i].refCount();
129 if (refCount != 1) {
130 fprintf(stderr, "\nFailure. SourceString Ref Count was %d, should be 1.\n", refCount);
131 }
132 }
133 }
134 };
135
136
137 //
138 // Factory functoin for StringThreadTest.
139 // C function lets ThreadTest create StringTests without needing StringThreadTest header.
140 //
createStringTest()141 AbstractThreadTest *createStringTest() {
142 return new StringThreadTest();
143 };
144