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