1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (C) 2010-2011, International Business Machines 4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Corporation and others. All Rights Reserved. 5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* file name: bytetrietest.cpp 7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* encoding: US-ASCII 8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* tab size: 8 (not used) 9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* indentation:4 10b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* 11b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* created on: 2010nov16 12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* created by: Markus W. Scherer 13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho*/ 14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include <string.h> 16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h" 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/bytestrie.h" 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/bytestriebuilder.h" 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/localpointer.h" 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/stringpiece.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "intltest.h" 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct StringAndValue { 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const char *s; 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t value; 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass BytesTrieTest : public IntlTest { 32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrieTest(); 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~BytesTrieTest(); 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL); 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestBuilder(); 38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestEmpty(); 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void Test_a(); 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void Test_a_ab(); 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestShortestBranch(); 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestBranches(); 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestLongSequence(); 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestLongBranch(); 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestValuesForState(); 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestCompact(); 47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie *buildMonthsTrie(UStringTrieBuildOption buildOption); 49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestHasUniqueValue(); 50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestGetNextBytes(); 51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestIteratorFromBranch(); 52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestIteratorFromLinearMatch(); 53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestTruncatingIteratorFromRoot(); 54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestTruncatingIteratorFromLinearMatchShort(); 55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestTruncatingIteratorFromLinearMatchLong(); 56b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void TestIteratorFromBytes(); 57b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 58b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkData(const StringAndValue data[], int32_t dataLength); 59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkData(const StringAndValue data[], int32_t dataLength, UStringTrieBuildOption buildOption); 60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie *buildTrie(const StringAndValue data[], int32_t dataLength, 61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieBuildOption buildOption); 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkFirst(BytesTrie &trie, const StringAndValue data[], int32_t dataLength); 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkNext(BytesTrie &trie, const StringAndValue data[], int32_t dataLength); 64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkNextWithState(BytesTrie &trie, const StringAndValue data[], int32_t dataLength); 65b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkNextString(BytesTrie &trie, const StringAndValue data[], int32_t dataLength); 66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkIterator(const BytesTrie &trie, const StringAndValue data[], int32_t dataLength); 67b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void checkIterator(BytesTrie::Iterator &iter, const StringAndValue data[], int32_t dataLength); 68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrieBuilder *builder_; 71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoextern IntlTest *createBytesTrieTest() { 74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new BytesTrieTest(); 75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoBytesTrieTest::BytesTrieTest() : builder_(NULL) { 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "BytesTrieTest()"); 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_=new BytesTrieBuilder(errorCode); 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoBytesTrieTest::~BytesTrieTest() { 83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete builder_; 84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { 87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(exec) { 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("TestSuite BytesTrieTest: "); 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO_BEGIN; 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestBuilder); 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestEmpty); 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(Test_a); 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(Test_a_ab); 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestShortestBranch); 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestBranches); 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestLongSequence); 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestLongBranch); 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestValuesForState); 100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestCompact); 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestHasUniqueValue); 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestGetNextBytes); 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestIteratorFromBranch); 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestIteratorFromLinearMatch); 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestTruncatingIteratorFromRoot); 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestTruncatingIteratorFromLinearMatchShort); 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestTruncatingIteratorFromLinearMatchLong); 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO(TestIteratorFromBytes); 109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TESTCASE_AUTO_END; 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestBuilder() { 113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestBuilder()"); 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->clear(); 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete builder_->build(USTRINGTRIE_BUILD_FAST, errorCode); 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.reset()!=U_INDEX_OUTOFBOUNDS_ERROR) { 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("BytesTrieBuilder().build() did not set U_INDEX_OUTOFBOUNDS_ERROR"); 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // TODO: remove .build(...) once add() checks for duplicates. 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->add("=", 0, errorCode).add("=", 1, errorCode).build(USTRINGTRIE_BUILD_FAST, errorCode); 122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.reset()!=U_ILLEGAL_ARGUMENT_ERROR) { 123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("BytesTrieBuilder.add() did not detect duplicates"); 124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestEmpty() { 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "", 0 } 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::Test_a() { 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", 1 } 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::Test_a_ab() { 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", 1 }, 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ab", 100 } 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestShortestBranch() { 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", 1000 }, 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "b", 2000 } 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestBranches() { 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", 0x10 }, 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "cc", 0x40 }, 162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "e", 0x100 }, 163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ggg", 0x400 }, 164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "i", 0x1000 }, 165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "kkkk", 0x4000 }, 166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "n", 0x10000 }, 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ppppp", 0x40000 }, 168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "r", 0x100000 }, 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "sss", 0x200000 }, 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "t", 0x400000 }, 171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "uu", 0x800000 }, 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "vv", 0x7fffffff }, 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "zz", 0x80000000 } 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t length=2; length<=LENGTHOF(data); ++length) { 176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho infoln("TestBranches length=%d", (int)length); 177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, length); 178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestLongSequence() { 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", -1 }, 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // sequence of linear-match nodes 185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", -2 }, 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // more than 256 bytes 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", -3 } 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestLongBranch() { 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Split-branch and interesting compact-integer values. 199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", -2 }, 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "b", -1 }, 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "c", 0 }, 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "d2", 1 }, 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "f", 0x3f }, 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "g", 0x40 }, 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "h", 0x41 }, 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "j23", 0x1900 }, 208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "j24", 0x19ff }, 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "j25", 0x1a00 }, 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "k2", 0x1a80 }, 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "k3", 0x1aff }, 212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "l234567890", 0x1b00 }, 213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "l234567890123", 0x1b01 }, 214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn", 0x10ffff }, 215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "oooooooooooooooooooooooooooooooooooooooooooooooooooooo", 0x110000 }, 216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "pppppppppppppppppppppppppppppppppppppppppppppppppppppp", 0x120000 }, 217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "r", 0x333333 }, 218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "s2345", 0x4444444 }, 219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "t234567890", 0x77777777 }, 220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "z", 0x80000001 } 221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestValuesForState() { 226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check that saveState() and resetToState() interact properly 227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // with next() and current(). 228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", -1 }, 230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ab", -2 }, 231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abc", -3 }, 232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcd", -4 }, 233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcde", -5 }, 234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdef", -6 } 235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestCompact() { 240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Duplicate trailing strings and values provide opportunities for compacting. 241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+", 0 }, 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+august", 8 }, 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+december", 12 }, 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+july", 7 }, 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+june", 6 }, 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+november", 11 }, 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+october", 10 }, 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "+september", 9 }, 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-", 0 }, 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-august", 8 }, 252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-december", 12 }, 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-july", 7 }, 254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-june", 6 }, 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-november", 11 }, 256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-october", 10 }, 257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "-september", 9 }, 258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // The l+n branch (with its sub-nodes) is a duplicate but will be written 259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // both times because each time it follows a different linear-match node. 260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "xjuly", 7 }, 261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "xjune", 6 } 262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, LENGTHOF(data)); 264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoBytesTrie *BytesTrieTest::buildMonthsTrie(UStringTrieBuildOption buildOption) { 267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // All types of nodes leading to the same value, 268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // for code coverage of recursive functions. 269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // In particular, we need a lot of branches on some single level 270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // to exercise a split-branch node. 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "august", 8 }, 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jan", 1 }, 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jan.", 1 }, 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jana", 1 }, 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janbb", 1 }, 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janc", 1 }, 278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janddd", 1 }, 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janee", 1 }, 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janef", 1 }, 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janf", 1 }, 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jangg", 1 }, 283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janh", 1 }, 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janiiii", 1 }, 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janj", 1 }, 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jankk", 1 }, 287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jankl", 1 }, 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jankmm", 1 }, 289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janl", 1 }, 290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janm", 1 }, 291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jannnnnnnnnnnnnnnnnnnnnnnnnnnnn", 1 }, 292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jano", 1 }, 293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janpp", 1 }, 294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janqqq", 1 }, 295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janr", 1 }, 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "januar", 1 }, 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "january", 1 }, 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "july", 7 }, 299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jun", 6 }, 300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jun.", 6 }, 301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "june", 6 } 302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return buildTrie(data, LENGTHOF(data), buildOption); 304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestHasUniqueValue() { 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildMonthsTrie(USTRINGTRIE_BUILD_FAST)); 308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t uniqueValue; 312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie->hasUniqueValue(uniqueValue)) { 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("unique value at root"); 314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('j'); 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('n'); 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // hasUniqueValue() directly after next() 319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!trie->hasUniqueValue(uniqueValue) || uniqueValue!=1) { 320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("not unique value 1 after \"jan\""); 321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->first('j'); 323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('u'); 324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie->hasUniqueValue(uniqueValue)) { 325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("unique value after \"ju\""); 326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie->next('n')!=USTRINGTRIE_INTERMEDIATE_VALUE || 6!=trie->getValue()) { 328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("not normal value 6 after \"jun\""); 329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // hasUniqueValue() after getValue() 331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!trie->hasUniqueValue(uniqueValue) || uniqueValue!=6) { 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("not unique value 6 after \"jun\""); 333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // hasUniqueValue() from within a linear-match node 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->first('a'); 336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('u'); 337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!trie->hasUniqueValue(uniqueValue) || uniqueValue!=8) { 338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("not unique value 8 after \"au\""); 339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestGetNextBytes() { 343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildMonthsTrie(USTRINGTRIE_BUILD_SMALL)); 344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char buffer[40]; 348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CheckedArrayByteSink sink(buffer, LENGTHOF(buffer)); 349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t count=trie->getNextBytes(sink); 350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(count!=2 || sink.NumberOfBytesAppended()!=2 || buffer[0]!='a' || buffer[1]!='j') { 351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("months getNextBytes()!=[aj] at root"); 352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('j'); 354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('n'); 356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // getNextBytes() directly after next() 357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count=trie->getNextBytes(sink.Reset()); 358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho buffer[count]=0; 359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(count!=20 || sink.NumberOfBytesAppended()!=20 || 0!=strcmp(buffer, ".abcdefghijklmnopqru")) { 360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("months getNextBytes()!=[.abcdefghijklmnopqru] after \"jan\""); 361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // getNextBytes() after getValue() 363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->getValue(); // next() had returned USTRINGTRIE_INTERMEDIATE_VALUE. 364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho memset(buffer, 0, sizeof(buffer)); 365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count=trie->getNextBytes(sink.Reset()); 366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(count!=20 || sink.NumberOfBytesAppended()!=20 || 0!=strcmp(buffer, ".abcdefghijklmnopqru")) { 367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("months getNextBytes()!=[.abcdefghijklmnopqru] after \"jan\"+getValue()"); 368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // getNextBytes() from a linear-match node 370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('u'); 371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho memset(buffer, 0, sizeof(buffer)); 372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count=trie->getNextBytes(sink.Reset()); 373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(count!=1 || sink.NumberOfBytesAppended()!=1 || buffer[0]!='a') { 374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("months getNextBytes()!=[a] after \"janu\""); 375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho memset(buffer, 0, sizeof(buffer)); 378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count=trie->getNextBytes(sink.Reset()); 379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(count!=1 || sink.NumberOfBytesAppended()!=1 || buffer[0]!='r') { 380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("months getNextBytes()!=[r] after \"janua\""); 381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('r'); 383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('y'); 384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // getNextBytes() after a final match 385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count=trie->getNextBytes(sink.Reset()); 386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(count!=0 || sink.NumberOfBytesAppended()!=0) { 387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("months getNextBytes()!=[] after \"january\""); 388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestIteratorFromBranch() { 392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildMonthsTrie(USTRINGTRIE_BUILD_FAST)); 393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Go to a branch node. 397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('j'); 398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('n'); 400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestIteratorFromBranch()"); 401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(*trie, 0, errorCode); 402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("BytesTrie::Iterator(trie) constructor")) { 403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Expected data: Same as in buildMonthsTrie(), except only the suffixes 406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // following "jan". 407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "", 1 }, 409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { ".", 1 }, 410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "a", 1 }, 411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "bb", 1 }, 412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "c", 1 }, 413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ddd", 1 }, 414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ee", 1 }, 415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ef", 1 }, 416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "f", 1 }, 417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "gg", 1 }, 418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "h", 1 }, 419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "iiii", 1 }, 420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "j", 1 }, 421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "kk", 1 }, 422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "kl", 1 }, 423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "kmm", 1 }, 424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "l", 1 }, 425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "m", 1 }, 426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "nnnnnnnnnnnnnnnnnnnnnnnnnnnn", 1 }, 427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "o", 1 }, 428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "pp", 1 }, 429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "qqq", 1 }, 430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "r", 1 }, 431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "uar", 1 }, 432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "uary", 1 } 433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, data, LENGTHOF(data)); 435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reset, and we should get the same result. 436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("after iter.reset()"); 437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter.reset(), data, LENGTHOF(data)); 438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestIteratorFromLinearMatch() { 441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildMonthsTrie(USTRINGTRIE_BUILD_SMALL)); 442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Go into a linear-match node. 446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('j'); 447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('n'); 449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('u'); 450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestIteratorFromLinearMatch()"); 452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(*trie, 0, errorCode); 453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("BytesTrie::Iterator(trie) constructor")) { 454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Expected data: Same as in buildMonthsTrie(), except only the suffixes 457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // following "janua". 458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "r", 1 }, 460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "ry", 1 } 461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, data, LENGTHOF(data)); 463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reset, and we should get the same result. 464b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("after iter.reset()"); 465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter.reset(), data, LENGTHOF(data)); 466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestTruncatingIteratorFromRoot() { 469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildMonthsTrie(USTRINGTRIE_BUILD_FAST)); 470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestTruncatingIteratorFromRoot()"); 474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(*trie, 4, errorCode); 475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("BytesTrie::Iterator(trie) constructor")) { 476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Expected data: Same as in buildMonthsTrie(), except only the first 4 characters 479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // of each string, and no string duplicates from the truncation. 480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "augu", -1 }, 482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jan", 1 }, 483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jan.", 1 }, 484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jana", 1 }, 485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janb", -1 }, 486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janc", 1 }, 487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jand", -1 }, 488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jane", -1 }, 489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janf", 1 }, 490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jang", -1 }, 491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janh", 1 }, 492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jani", -1 }, 493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janj", 1 }, 494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jank", -1 }, 495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janl", 1 }, 496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janm", 1 }, 497b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jann", -1 }, 498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jano", 1 }, 499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janp", -1 }, 500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janq", -1 }, 501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janr", 1 }, 502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "janu", -1 }, 503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "july", 7 }, 504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jun", 6 }, 505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "jun.", 6 }, 506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "june", 6 } 507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, data, LENGTHOF(data)); 509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reset, and we should get the same result. 510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("after iter.reset()"); 511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter.reset(), data, LENGTHOF(data)); 512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 513b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestTruncatingIteratorFromLinearMatchShort() { 515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdef", 10 }, 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdepq", 200 }, 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdeyz", 3000 } 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildTrie(data, LENGTHOF(data), USTRINGTRIE_BUILD_FAST)); 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Go into a linear-match node. 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('b'); 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestTruncatingIteratorFromLinearMatchShort()"); 528b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Truncate within the linear-match node. 529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(*trie, 2, errorCode); 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("BytesTrie::Iterator(trie) constructor")) { 531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue expected[]={ 534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "cd", -1 } 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, expected, LENGTHOF(expected)); 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reset, and we should get the same result. 538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("after iter.reset()"); 539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter.reset(), expected, LENGTHOF(expected)); 540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestTruncatingIteratorFromLinearMatchLong() { 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdef", 10 }, 545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdepq", 200 }, 546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "abcdeyz", 3000 } 547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildTrie(data, LENGTHOF(data), USTRINGTRIE_BUILD_FAST)); 549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Go into a linear-match node. 553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('a'); 554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('b'); 555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie->next('c'); 556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestTruncatingIteratorFromLinearMatchLong()"); 557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Truncate after the linear-match node. 558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(*trie, 3, errorCode); 559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("BytesTrie::Iterator(trie) constructor")) { 560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue expected[]={ 563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "def", 10 }, 564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "dep", -1 }, 565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "dey", -1 } 566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, expected, LENGTHOF(expected)); 568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reset, and we should get the same result. 569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("after iter.reset()"); 570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter.reset(), expected, LENGTHOF(expected)); 571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::TestIteratorFromBytes() { 574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static const StringAndValue data[]={ 575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "mm", 3 }, 576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "mmm", 33 }, 577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "mmnop", 333 } 578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->clear(); 580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "TestIteratorFromBytes()"); 581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<LENGTHOF(data); ++i) { 582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->add(data[i].s, data[i].value, errorCode); 583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 584b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringPiece trieBytes=builder_->buildStringPiece(USTRINGTRIE_BUILD_FAST, errorCode); 585b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(trieBytes.data(), 0, errorCode); 586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, data, LENGTHOF(data)); 587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkData(const StringAndValue data[], int32_t dataLength) { 590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("checkData(dataLength=%d, fast)", (int)dataLength); 591b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, dataLength, USTRINGTRIE_BUILD_FAST); 592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("checkData(dataLength=%d, small)", (int)dataLength); 593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkData(data, dataLength, USTRINGTRIE_BUILD_SMALL); 594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 596b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkData(const StringAndValue data[], int32_t dataLength, UStringTrieBuildOption buildOption) { 597b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(buildTrie(data, dataLength, buildOption)); 598b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.isNull()) { 599b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; // buildTrie() reported an error 600b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkFirst(*trie, data, dataLength); 602b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkNext(*trie, data, dataLength); 603b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkNextWithState(*trie, data, dataLength); 604b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkNextString(*trie, data, dataLength); 605b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(*trie, data, dataLength); 606b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 607b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 608b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoBytesTrie *BytesTrieTest::buildTrie(const StringAndValue data[], int32_t dataLength, 609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieBuildOption buildOption) { 610b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "buildTrie()"); 611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Add the items to the trie builder in an interesting (not trivial, not random) order. 612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index, step; 613b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(dataLength&1) { 614b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Odd number of items. 615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho index=dataLength/2; 616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho step=2; 617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if((dataLength%3)!=0) { 618b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Not a multiple of 3. 619b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho index=dataLength/5; 620b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho step=3; 621b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 622b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho index=dataLength-1; 623b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho step=-1; 624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 625b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->clear(); 626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<dataLength; ++i) { 627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->add(data[index].s, data[index].value, errorCode); 628b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho index=(index+step)%dataLength; 629b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringPiece sp=builder_->buildStringPiece(buildOption, errorCode); 631b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<BytesTrie> trie(builder_->build(buildOption, errorCode)); 632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!errorCode.logIfFailureAndReset("add()/build()")) { 633b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho builder_->add("zzz", 999, errorCode); 634b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.reset()!=U_NO_WRITE_PERMISSION) { 635b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("builder.build().add(zzz) did not set U_NO_WRITE_PERMISSION"); 636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 637b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 638b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho logln("serialized trie size: %ld bytes\n", (long)sp.length()); 639b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringPiece sp2=builder_->buildStringPiece(buildOption, errorCode); 640b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(sp.data()==sp2.data()) { 641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("builder.buildStringPiece() before & after build() returned same array"); 642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 643b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.isFailure()) { 644b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Tries from either build() method should be identical but 647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // BytesTrie does not implement equals(). 648b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We just return either one. 649b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if((dataLength&1)!=0) { 650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return trie.orphan(); 651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new BytesTrie(sp2.data()); 653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 654b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 655b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 656b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkFirst(BytesTrie &trie, 657b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const StringAndValue data[], int32_t dataLength) { 658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<dataLength; ++i) { 659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int c=*data[i].s; 660b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(c==0) { 661b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; // skip empty string 662b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 663b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieResult firstResult=trie.first(c); 664b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t firstValue=USTRINGTRIE_HAS_VALUE(firstResult) ? trie.getValue() : -1; 665b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieResult nextResult=trie.next(data[i].s[1]); 666b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(firstResult!=trie.reset().next(c) || 667b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho firstResult!=trie.current() || 668b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho firstValue!=(USTRINGTRIE_HAS_VALUE(firstResult) ? trie.getValue() : -1) || 669b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nextResult!=trie.next(data[i].s[1]) 670b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 671b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.first(%c)!=trie.reset().next(same) for %s", 672b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho c, data[i].s); 673b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 674b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 675b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.reset(); 676b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 677b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 678b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkNext(BytesTrie &trie, 679b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const StringAndValue data[], int32_t dataLength) { 680b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::State state; 681b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<dataLength; ++i) { 682b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t stringLength= (i&1) ? -1 : strlen(data[i].s); 683b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieResult result; 684b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if( !USTRINGTRIE_HAS_VALUE(result=trie.next(data[i].s, stringLength)) || 685b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result!=trie.current() 686b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie does not seem to contain %s", data[i].s); 688b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(trie.getValue()!=data[i].value) { 689b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie value for %s is %ld=0x%lx instead of expected %ld=0x%lx", 690b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho data[i].s, 691b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (long)trie.getValue(), (long)trie.getValue(), 692b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (long)data[i].value, (long)data[i].value); 693b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(result!=trie.current() || trie.getValue()!=data[i].value) { 694b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie value for %s changes when repeating current()/getValue()", data[i].s); 695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 696b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.reset(); 697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stringLength=strlen(data[i].s); 698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result=trie.current(); 699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t j=0; j<stringLength; ++j) { 700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!USTRINGTRIE_HAS_NEXT(result)) { 701b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.current()!=hasNext before end of %s (at index %d)", data[i].s, j); 702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(result==USTRINGTRIE_INTERMEDIATE_VALUE) { 705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.getValue(); 706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.current()!=USTRINGTRIE_INTERMEDIATE_VALUE) { 707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.getValue().current()!=USTRINGTRIE_INTERMEDIATE_VALUE before end of %s (at index %d)", data[i].s, j); 708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result=trie.next(data[i].s[j]); 712b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!USTRINGTRIE_MATCHES(result)) { 713b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next()=USTRINGTRIE_NO_MATCH before end of %s (at index %d)", data[i].s, j); 714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(result!=trie.current()) { 717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next()!=following current() before end of %s (at index %d)", data[i].s, j); 718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!USTRINGTRIE_HAS_VALUE(result)) { 722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next()!=hasValue at the end of %s", data[i].s); 723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.getValue(); 726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(result!=trie.current()) { 727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.current() != current()+getValue()+current() after end of %s", 728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho data[i].s); 729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Compare the final current() with whether next() can actually continue. 731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.saveState(state); 732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool nextContinues=FALSE; 733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Try all graphic characters; we only use those in test strings in this file. 734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if U_CHARSET_FAMILY==U_ASCII_FAMILY 735b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t minChar=0x20; 736b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t maxChar=0x7e; 737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY 738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t minChar=0x40; 739b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t maxChar=0xfe; 740b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#else 741b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t minChar=0; 742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t maxChar=0xff; 743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif 744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t c=minChar; c<=maxChar; ++c) { 745b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.resetToState(state).next(c)) { 746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nextContinues=TRUE; 747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if((result==USTRINGTRIE_INTERMEDIATE_VALUE)!=nextContinues) { 751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("(trie.current()==USTRINGTRIE_INTERMEDIATE_VALUE) contradicts " 752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "(trie.next(some byte)!=USTRINGTRIE_NO_MATCH) after end of %s", data[i].s); 753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.reset(); 755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 756b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 757b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 758b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkNextWithState(BytesTrie &trie, 759b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const StringAndValue data[], int32_t dataLength) { 760b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::State noState, state; 761b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<dataLength; ++i) { 762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if((i&1)==0) { 763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This should have no effect. 764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.resetToState(noState); 765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const char *expectedString=data[i].s; 767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t stringLength=strlen(expectedString); 768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t partialLength=stringLength/3; 769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t j=0; j<partialLength; ++j) { 770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!USTRINGTRIE_MATCHES(trie.next(expectedString[j]))) { 771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next()=USTRINGTRIE_NO_MATCH for a prefix of %s", data[i].s); 772b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.saveState(state); 776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieResult resultAtState=trie.current(); 777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UStringTrieResult result; 778b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t valueAtState=-99; 779b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(USTRINGTRIE_HAS_VALUE(resultAtState)) { 780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueAtState=trie.getValue(); 781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result=trie.next(0); // mismatch 783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(result!=USTRINGTRIE_NO_MATCH || result!=trie.current()) { 784b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next(0) matched after part of %s", data[i].s); 785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 786b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if( resultAtState!=trie.resetToState(state).current() || 787b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (USTRINGTRIE_HAS_VALUE(resultAtState) && valueAtState!=trie.getValue()) 788b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 789b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next(part of %s) changes current()/getValue() after " 790b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "saveState/next(0)/resetToState", 791b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho data[i].s); 792b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(!USTRINGTRIE_HAS_VALUE( 793b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result=trie.next(expectedString+partialLength, 794b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stringLength-partialLength)) || 795b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result!=trie.current()) { 796b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next(rest of %s) does not seem to contain %s after " 797b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho "saveState/next(0)/resetToState", 798b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho data[i].s, data[i].s); 799b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(!USTRINGTRIE_HAS_VALUE( 800b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result=trie.resetToState(state). 801b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho next(expectedString+partialLength, 802b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho stringLength-partialLength)) || 803b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result!=trie.current()) { 804b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie does not seem to contain %s after saveState/next(rest)/resetToState", 805b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho data[i].s); 806b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(trie.getValue()!=data[i].value) { 807b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie value for %s is %ld=0x%lx instead of expected %ld=0x%lx", 808b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho data[i].s, 809b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (long)trie.getValue(), (long)trie.getValue(), 810b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (long)data[i].value, (long)data[i].value); 811b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 812b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.reset(); 813b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 814b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 815b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 816b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// next(string) is also tested in other functions, 817b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// but here we try to go partway through the string, and then beyond it. 818b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkNextString(BytesTrie &trie, 819b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const StringAndValue data[], int32_t dataLength) { 820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<dataLength; ++i) { 821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const char *expectedString=data[i].s; 822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t stringLength=strlen(expectedString); 823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!trie.next(expectedString, stringLength/2)) { 824b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next(up to middle of string)=USTRINGTRIE_NO_MATCH for %s", data[i].s); 825b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 827b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Test that we stop properly at the end of the string. 828b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(trie.next(expectedString+stringLength/2, stringLength+1-stringLength/2)) { 829b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie.next(string+NUL)!=USTRINGTRIE_NO_MATCH for %s", data[i].s); 830b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 831b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho trie.reset(); 832b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 833b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 834b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 835b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkIterator(const BytesTrie &trie, 836b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const StringAndValue data[], int32_t dataLength) { 837b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "checkIterator()"); 838b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BytesTrie::Iterator iter(trie, 0, errorCode); 839b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("BytesTrie::Iterator(trie) constructor")) { 840b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 841b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 842b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkIterator(iter, data, dataLength); 843b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 844b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 845b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid BytesTrieTest::checkIterator(BytesTrie::Iterator &iter, 846b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const StringAndValue data[], int32_t dataLength) { 847b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IcuTestErrorCode errorCode(*this, "checkIterator()"); 848b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=0; i<dataLength; ++i) { 849b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!iter.hasNext()) { 850b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie iterator hasNext()=FALSE for item %d: %s", (int)i, data[i].s); 851b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 852b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 853b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool hasNext=iter.next(errorCode); 854b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(errorCode.logIfFailureAndReset("trie iterator next() for item %d: %s", (int)i, data[i].s)) { 855b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 856b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 857b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!hasNext) { 858b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie iterator next()=FALSE for item %d: %s", (int)i, data[i].s); 859b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 860b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 861b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(iter.getString()!=StringPiece(data[i].s)) { 862b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie iterator next().getString()=%s but expected %s for item %d", 863b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho iter.getString().data(), data[i].s, (int)i); 864b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(iter.getValue()!=data[i].value) { 866b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie iterator next().getValue()=%ld=0x%lx but expected %ld=0x%lx for item %d: %s", 867b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (long)iter.getValue(), (long)iter.getValue(), 868b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (long)data[i].value, (long)data[i].value, 869b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (int)i, data[i].s); 870b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 871b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 872b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(iter.hasNext()) { 873b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie iterator hasNext()=TRUE after all items"); 874b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 875b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool hasNext=iter.next(errorCode); 876b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errorCode.logIfFailureAndReset("trie iterator next() after all items"); 877b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(hasNext) { 878b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errln("trie iterator next()=TRUE after all items"); 879b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 880b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 881