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 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 66 StringThreadTest::~StringThreadTest() { 67 delete [] fCleanStrings; 68 delete [] fSourceStrings; 69 } 70 71 72 void StringThreadTest::runOnce() { 73 makeStringCopies(25); 74 } 75 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 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 // 141 AbstractThreadTest *createStringTest() { 142 return new StringThreadTest(); 143 }; 144