From 0e57d10a60449d6b4668fced7db716f217d9fe68 Mon Sep 17 00:00:00 2001 From: Syn Wee Quek Date: Wed, 20 Aug 2003 00:20:37 +0000 Subject: [PATCH] ICU-3064 updated trie java port X-SVN-Rev: 12880 --- .../com/ibm/icu/dev/test/util/TrieTest.java | 1074 +++++++---------- .../src/com/ibm/icu/impl/IntTrieBuilder.java | 261 +++- icu4j/src/com/ibm/icu/impl/TrieBuilder.java | 14 +- icu4j/src/com/ibm/icu/impl/TrieIterator.java | 57 +- .../icu/text/CollationParsedRuleBuilder.java | 14 +- 5 files changed, 694 insertions(+), 726 deletions(-) diff --git a/icu4j/src/com/ibm/icu/dev/test/util/TrieTest.java b/icu4j/src/com/ibm/icu/dev/test/util/TrieTest.java index b153eb6e943..1a6d3a706d3 100755 --- a/icu4j/src/com/ibm/icu/dev/test/util/TrieTest.java +++ b/icu4j/src/com/ibm/icu/dev/test/util/TrieTest.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/util/TrieTest.java,v $ -* $Date: 2003/06/10 00:55:41 $ -* $Revision: 1.7 $ +* $Date: 2003/08/20 00:19:19 $ +* $Revision: 1.8 $ * ******************************************************************************* */ @@ -17,8 +17,12 @@ import com.ibm.icu.dev.test.TestFmwk; import com.ibm.icu.impl.Trie; import com.ibm.icu.impl.IntTrie; import com.ibm.icu.impl.CharTrie; +import com.ibm.icu.impl.TrieBuilder; +import com.ibm.icu.impl.IntTrieBuilder; +import com.ibm.icu.impl.TrieIterator; import com.ibm.icu.impl.UCharacterProperty; import com.ibm.icu.text.UTF16; +import com.ibm.icu.util.RangeValueIterator; import com.ibm.icu.lang.UCharacter; import java.io.ByteArrayInputStream; @@ -52,81 +56,438 @@ public final class TrieTest extends TestFmwk } } - /** - * Testing the constructors of the Tries + /** + * Values for setting possibly overlapping, out-of-order ranges of values */ - public void TestInit() + private static final class SetRange { - byte array[] = new byte[INT_TRIE_DATA_.length << 1]; - for (int i = 0; i < INT_TRIE_DATA_.length; i ++) { - array[i << 1] = (byte)((INT_TRIE_DATA_[i] >> 8) & 0xFF); - array[(i << 1) + 1] = (byte)(INT_TRIE_DATA_[i] & 0xFF); + SetRange(int start, int limit, int value, boolean overwrite) + { + this.start = start; + this.limit = limit; + this.value = value; + this.overwrite = overwrite; } - ByteArrayInputStream inputStream = new ByteArrayInputStream( - array); - IntDataManipulate datamanipulate = new IntDataManipulate(); - // chartrie should fail with int data - try { - /*CharTrie chartrie = */new CharTrie(inputStream, datamanipulate); - errln("CharTrie should fail with Int data during construction"); - } catch (Exception e) { + + int start, limit; + int value; + boolean overwrite; + }; + + /** + * Values for testing: + * value is set from the previous boundary's limit to before + * this boundary's limit + */ + private static final class CheckRange + { + CheckRange(int limit, int value) + { + this.limit = limit; + this.value = value; } - // inttrie should pass with int data - try { - inputStream.reset(); - /*IntTrie m_trie_ = */new IntTrie(inputStream, datamanipulate); - } catch (Exception e) { - errln("Failed reading IntTrie data"); - } + + int limit; + int value; + }; + + private static final class storageHolder + { + double bogus; // needed for aligining the storage + byte storage[] = new byte[10000000]; + }; + + + private static final class _testFoldedValue + implements TrieBuilder.DataManipulate + { + public _testFoldedValue(IntTrieBuilder builder) + { + m_builder_ = builder; + } + + public int getFoldedValue(int start, int offset) + { + int foldedValue = 0; + int limit = start + 0x400; + while (start < limit) { + int value = m_builder_.getValue(start); + if (m_builder_.isInZeroBlock(start)) { + start += TrieBuilder.DATA_BLOCK_LENGTH; + } + else { + foldedValue |= value; + ++ start; + } + } + + if (foldedValue != 0) { + return (offset << 16) | foldedValue; + } + return 0; + } + + private IntTrieBuilder m_builder_; } - public void TestIntValues() + private static final class _testFoldingOffset + implements Trie.DataManipulate { - byte array[] = new byte[INT_TRIE_DATA_.length << 1]; - for (int i = 0; i < INT_TRIE_DATA_.length; i ++) { - array[i << 1] = (byte)((INT_TRIE_DATA_[i] >> 8) & 0xFF); - array[(i << 1) + 1] = (byte)(INT_TRIE_DATA_[i] & 0xFF); + public int getFoldingOffset(int value) + { + return value >>> 16; } - ByteArrayInputStream inputStream = new ByteArrayInputStream(array); - IntTrie trie = null; - try { - trie = new IntTrie(inputStream, new IntDataManipulate()); - } catch (Exception e) { - errln("Failed reading trie data"); - } - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < STRING_1_.length; i ++) { - UTF16.append(buffer, STRING_1_[i]); - } - String str = buffer.toString(); - int values[] = VALUE_1_; - internalTestIntValues(trie, str, values); - - // testing invalid codepoints - int result = 0; - result = trie.getCodePointValue(0x110000); - if (result != 0) { - errln("Error: Expected value for illegal codepoint should be 0"); + } + + private static final class _testEnumValue extends TrieIterator + { + public _testEnumValue(Trie data) + { + super(data); } - for (int i = 0; i < 0xFFFF; i ++) { - - if (trie.getBMPValue((char)i) != trie.getCodePointValue(i)) { - errln("For BMP codepoint, getBMPValue should be the same " + - "as getCodepointValue"); - } - } - for (int i = 0x10000; i < 0x10ffff; i ++) { - char lead = UTF16.getLeadSurrogate(i); - char trail = UTF16.getTrailSurrogate(i); - int value = trie.getCodePointValue(i); - if (value != trie.getSurrogateValue(lead, trail) || - value != trie.getTrailValue(trie.getLeadValue(lead), - trail)) { - errln("For Non-BMP codepoints, getSurrogateValue should be " - + "the same s getCodepointValue and getTrailValue"); - } - } + protected int extract(int value) + { + return value ^ 0x5555; + } + } + + private void _testTrieIteration(IntTrie trie, CheckRange checkRanges[], + int countCheckRanges) + { + // write a string + int countValues = 0; + StringBuffer s = new StringBuffer(); + int values[] = new int[30]; + for (int i = 0; i < countCheckRanges; ++ i) { + int c = checkRanges[i].limit; + if (c != 0) { + -- c; + UTF16.append(s, c); + values[countValues ++] = checkRanges[i].value; + } + } + int limit = s.length(); + // try forward + int p = 0; + int i = 0; + while(p < limit) { + int c = UTF16.charAt(s, p); + p += UTF16.getCharCount(c); + int value = trie.getCodePointValue(c); + if (value != values[i]) { + errln("wrong value from UTRIE_NEXT(U+" + + Integer.toHexString(c) + "): 0x" + + Integer.toHexString(value) + " instead of 0x" + + Integer.toHexString(values[i])); + } + // unlike the c version lead is 0 if c is non-supplementary + char lead = UTF16.getLeadSurrogate(c); + char trail = UTF16.getTrailSurrogate(c); + if (lead == 0 + ? trail != s.charAt(p - 1) + : !UTF16.isLeadSurrogate(lead) + || !UTF16.isTrailSurrogate(trail) || lead != s.charAt(p - 2) + || trail != s.charAt(p - 1)) { + errln("wrong (lead, trail) from UTRIE_NEXT(U+" + + Integer.toHexString(c)); + continue; + } + if (lead != 0) { + value = trie.getLeadValue(lead); + value = trie.getTrailValue(value, trail); + if (value != trie.getSurrogateValue(lead, trail) + && value != values[i]) { + errln("wrong value from getting supplementary " + + "values (U+" + + Integer.toHexString(c) + "): 0x" + + Integer.toHexString(value) + " instead of 0x" + + Integer.toHexString(values[i])); + } + } + ++ i; + } + } + + private void _testTrieRanges(SetRange setRanges[], int countSetRanges, + CheckRange checkRanges[], int countCheckRanges, + boolean latin1Linear) + { + IntTrieBuilder newTrie = new IntTrieBuilder(null, 2000, + checkRanges[0].value, + checkRanges[0].value, + latin1Linear); + + // set values from setRanges[] + boolean ok = true; + for (int i = 0; i < countSetRanges; ++ i) { + int start = setRanges[i].start; + int limit = setRanges[i].limit; + int value = setRanges[i].value; + boolean overwrite = setRanges[i].overwrite; + if ((limit - start) == 1 && overwrite) { + ok &= newTrie.setValue(start, value); + } + else { + ok &= newTrie.setRange(start, limit, value, overwrite); + } + } + if (!ok) { + errln("setting values into a trie failed"); + return; + } + + // verify that all these values are in the new Trie + int start = 0; + for (int i = 0; i < countCheckRanges; ++ i) { + int limit = checkRanges[i].limit; + int value = checkRanges[i].value; + + while (start < limit) { + if (value != newTrie.getValue(start)) { + errln("newTrie [U+" + + Integer.toHexString(start) + "]==0x" + + Integer.toHexString(newTrie.getValue(start)) + + " instead of 0x" + Integer.toHexString(value)); + } + ++ start; + } + } + + IntTrie trie = newTrie.serialize(new _testFoldedValue(newTrie), + new _testFoldingOffset()); + + // test linear Latin-1 range from utrie_getData() + if (latin1Linear) { + start = 0; + for (int i = 0; i < countCheckRanges && start <= 0xff; ++ i) { + int limit = checkRanges[i].limit; + int value = checkRanges[i].value; + + while (start < limit && start <= 0xff) { + if (value != trie.getLatin1LinearValue((char)start)) { + errln("IntTrie.getLatin1LinearValue[U+" + + Integer.toHexString(start) + "]==0x" + + Integer.toHexString( + trie.getLatin1LinearValue((char) start)) + + " instead of 0x" + Integer.toHexString(value)); + } + ++ start; + } + } + } + + if (latin1Linear != trie.isLatin1Linear()) { + errln("trie serialization did not preserve " + + "Latin-1-linearity"); + } + + // verify that all these values are in the serialized Trie + start = 0; + for (int i = 0; i < countCheckRanges; ++ i) { + int limit = checkRanges[i].limit; + int value = checkRanges[i].value; + + if (start == 0xd800) { + // skip surrogates + start = limit; + continue; + } + + while (start < limit) { + if (start <= 0xffff) { + int value2 = trie.getBMPValue((char)start); + if (value != value2) { + errln("serialized trie.getBMPValue(U+" + + Integer.toHexString(start) + " == 0x" + + Integer.toHexString(value2) + " instead of 0x" + + Integer.toHexString(value)); + } + if (!UTF16.isLeadSurrogate((char)start)) { + value2 = trie.getLeadValue((char)start); + if (value != value2) { + errln("serialized trie.getLeadValue(U+" + + Integer.toHexString(start) + " == 0x" + + Integer.toHexString(value2) + " instead of 0x" + + Integer.toHexString(value)); + } + } + } + int value2 = trie.getCodePointValue(start); + if (value != value2) { + errln("serialized trie.getCodePointValue(U+" + + Integer.toHexString(start) + ")==0x" + + Integer.toHexString(value2) + " instead of 0x" + + Integer.toHexString(value)); + } + ++ start; + } + } + + // enumerate and verify all ranges + + int enumRanges = 1; + TrieIterator iter = new _testEnumValue(trie); + RangeValueIterator.Element result = new RangeValueIterator.Element(); + while (iter.next(result)) { + if (result.start != checkRanges[enumRanges -1].limit + || result.limit != checkRanges[enumRanges].limit + || (result.value ^ 0x5555) != checkRanges[enumRanges].value) { + errln("utrie_enum() delivers wrong range [U+" + + Integer.toHexString(result.start) + "..U+" + + Integer.toHexString(result.limit) + "].0x" + + Integer.toHexString(result.value ^ 0x5555) + + " instead of [U+" + + Integer.toHexString(checkRanges[enumRanges -1].limit) + + "..U+" + + Integer.toHexString(checkRanges[enumRanges].limit) + + "].0x" + + Integer.toHexString(checkRanges[enumRanges].value)); + } + enumRanges ++; + } + + // test linear Latin-1 range + if (trie.isLatin1Linear()) { + for (start = 0; start < 0x100; ++ start) { + if (trie.getLatin1LinearValue((char)start) + != trie.getLeadValue((char)start)) { + errln("trie.getLatin1LinearValue[U+" + + Integer.toHexString(start) + "]=0x" + + Integer.toHexString( + trie.getLatin1LinearValue((char)start)) + + " instead of 0x" + + Integer.toHexString( + trie.getLeadValue((char)start))); + } + } + } + + _testTrieIteration(trie, checkRanges, countCheckRanges); + } + + private void _testTrieRanges2(SetRange setRanges[], + int countSetRanges, + CheckRange checkRanges[], + int countCheckRanges) + { + _testTrieRanges(setRanges, countSetRanges, checkRanges, countCheckRanges, + false); + + _testTrieRanges(setRanges, countSetRanges, checkRanges, countCheckRanges, + true); + } + + private void _testTrieRanges4(SetRange setRanges[], int countSetRanges, + CheckRange checkRanges[], + int countCheckRanges) + { + _testTrieRanges2(setRanges, countSetRanges, checkRanges, + countCheckRanges); + } + + // test data ------------------------------------------------------------ + + /** + * set consecutive ranges, even with value 0 + */ + private static SetRange setRanges1[]={ + new SetRange(0, 0x20, 0, false), + new SetRange(0x20, 0xa7, 0x1234, false), + new SetRange(0xa7, 0x3400, 0, false), + new SetRange(0x3400, 0x9fa6, 0x6162, false), + new SetRange(0x9fa6, 0xda9e, 0x3132, false), + // try to disrupt _testFoldingOffset16() + new SetRange(0xdada, 0xeeee, 0x87ff, false), + new SetRange(0xeeee, 0x11111, 1, false), + new SetRange(0x11111, 0x44444, 0x6162, false), + new SetRange(0x44444, 0x60003, 0, false), + new SetRange(0xf0003, 0xf0004, 0xf, false), + new SetRange(0xf0004, 0xf0006, 0x10, false), + new SetRange(0xf0006, 0xf0007, 0x11, false), + new SetRange(0xf0007, 0xf0020, 0x12, false), + new SetRange(0xf0020, 0x110000, 0, false) + }; + + private static CheckRange checkRanges1[]={ + new CheckRange(0, 0), // dummy start range to make _testEnumRange() simpler + new CheckRange(0x20, 0), + new CheckRange(0xa7, 0x1234), + new CheckRange(0x3400, 0), + new CheckRange(0x9fa6, 0x6162), + new CheckRange(0xda9e, 0x3132), + new CheckRange(0xdada, 0), + new CheckRange(0xeeee, 0x87ff), + new CheckRange(0x11111,1), + new CheckRange(0x44444,0x6162), + new CheckRange(0xf0003,0), + new CheckRange(0xf0004,0xf), + new CheckRange(0xf0006,0x10), + new CheckRange(0xf0007,0x11), + new CheckRange(0xf0020,0x12), + new CheckRange(0x110000, 0) + }; + + /** + * set some interesting overlapping ranges + */ + private static SetRange setRanges2[]={ + new SetRange(0x21, 0x7f, 0x5555, true), + new SetRange(0x2f800,0x2fedc, 0x7a, true), + new SetRange(0x72, 0xdd, 3, true), + new SetRange(0xdd, 0xde, 4, false), + new SetRange(0x2f987,0x2fa98, 5, true), + new SetRange(0x2f777,0x2f833, 0, true), + new SetRange(0x2f900,0x2ffee, 1, false), + new SetRange(0x2ffee,0x2ffef, 2, true) + }; + + private static CheckRange checkRanges2[]={ + // dummy start range to make _testEnumRange() simpler + new CheckRange(0, 0), + new CheckRange(0x21, 0), + new CheckRange(0x72, 0x5555), + new CheckRange(0xdd, 3), + new CheckRange(0xde, 4), + new CheckRange(0x2f833,0), + new CheckRange(0x2f987,0x7a), + new CheckRange(0x2fa98,5), + new CheckRange(0x2fedc,0x7a), + new CheckRange(0x2ffee,1), + new CheckRange(0x2ffef,2), + new CheckRange(0x110000, 0) + }; + + /** + * use a non-zero initial value + */ + private static SetRange setRanges3[]={ + new SetRange(0x31, 0xa4, 1, false), + new SetRange(0x3400, 0x6789, 2, false), + new SetRange(0x30000,0x34567,9, true), + new SetRange(0x45678,0x56789,3, true) + }; + + private static CheckRange checkRanges3[]={ + // dummy start range, also carries the initial value + new CheckRange(0, 9), + new CheckRange(0x31, 9), + new CheckRange(0xa4, 1), + new CheckRange(0x3400, 9), + new CheckRange(0x6789, 2), + new CheckRange(0x45678,9), + new CheckRange(0x56789,3), + new CheckRange(0x110000,9) + }; + + public void TestIntTrie() + { + _testTrieRanges4(setRanges1, setRanges1.length, checkRanges1, + checkRanges1.length); + _testTrieRanges4(setRanges2, setRanges2.length, checkRanges2, + checkRanges2.length); + _testTrieRanges4(setRanges3, setRanges3.length, checkRanges3, + checkRanges3.length); } public void TestCharValues() @@ -162,584 +523,5 @@ public final class TrieTest extends TestFmwk } } } - - // private class ------------------------------------------------ - - private static class IntDataManipulate implements Trie.DataManipulate - { - public int getFoldingOffset(int data) - { - return data >> 16; - } - } - - // private data members ----------------------------------------- - - // trie data, generated from icu4c - private final char INT_TRIE_DATA_[] = { - 0x5472, 0x6965, 0x0, 0x125, 0x0, 0x8c0, 0x0, 0x18c, 0x0, 0x8, 0x8, 0x8, -0x8, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x1e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x4f, 0x4f, 0x4f, -0x4f, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x29, 0x29, 0x29, 0x29, 0x29, -0x5b, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2e, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -0x20, 0x20, 0x22, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, -0x32, 0x32, 0x32, 0x32, 0x36, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, -0x17, 0x17, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1234, 0x0, 0x1234, -0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, -0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, -0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, -0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, -0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, -0x0, 0x1234, 0x0, 0x1234, 0x0, 0x1234, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, -0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, -0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, -0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, -0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, -0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, -0x0, 0x1, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, -0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x6162, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, -0x0, 0x10, 0x0, 0x10, 0x0, 0x11, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, -0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, -0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, -0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, -0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x820, 0x1, 0x820, 0x1, -0x820, 0x1, 0x820, 0x1, 0x840, 0x6163, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, -0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, -0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, -0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, -0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, -0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, -0x860, 0x6162, 0x860, 0x6162, 0x860, 0x6162, 0x880, 0x6162, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, 0x0, 0x3132, -0x8a0, 0x1f, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, 0x0, 0x27, -0x0, 0x27, 0x0, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 - }; - - private final int STRING_1_[] = {0, 0x20, 0xa7, 0x3400, 0x9fa6, 0xdada, - 0xeeee, 0x11111, 0x44444, 0xf0003, - 0xf0004, 0xf0006, 0xf0007, 0xf0020}; - private final int VALUE_1_[] = {0, 0x1234, 0, 0x6162, 0x3132, 0x27, 1, - 0x6162, 0, 0xf, 0x10, 0x11, 0x12, 0}; - - // private methods ---------------------------------------------- - - private void internalTestIntValues(IntTrie trie, String str, - int values[]) - { - // try forward - int count = 0; - int valueindex = 0; - while (count < str.length()) { - int value; - char c = str.charAt(count ++); - char c2 = UTF16.isLeadSurrogate(c) && count < str.length() && - UTF16.isTrailSurrogate(str.charAt(count)) - ? str.charAt(count ++) : 0; - if (c2 != 0) { - value = trie.getSurrogateValue(c, c2); - } - else { - value = trie.getBMPValue(c); - } - if (value != values[valueindex]) { - errln("Error: Expected value for 0x" + Integer.toHexString(c) + - " and 0x" + Integer.toHexString(c2) + " should be " + - values[valueindex] + " not " + value); - } - value = trie.getLeadValue(c); - if (c2 != 0) { - value = trie.getTrailValue(value, c2); - } - if (value != values[valueindex]) { - errln("Error: Expected value for 0x" + Integer.toHexString(c) + - " and 0x" + Integer.toHexString(c2) + " should be " + - values[valueindex] + " not " + value); - } - if (c2!=0) { - int codepoint = UCharacter.getCodePoint(c, c2); - value = trie.getCodePointValue(codepoint); - } - else { - value = trie.getBMPValue(c); - } - if (value != values[valueindex]) { - errln("Error: Expected value for 0x" + Integer.toHexString(c) + - " and 0x" + Integer.toHexString(c2) + " should be " + - values[valueindex] + " not " + value); - } - valueindex ++; - } - } } diff --git a/icu4j/src/com/ibm/icu/impl/IntTrieBuilder.java b/icu4j/src/com/ibm/icu/impl/IntTrieBuilder.java index ca08e04bbf4..ffbf71296ca 100644 --- a/icu4j/src/com/ibm/icu/impl/IntTrieBuilder.java +++ b/icu4j/src/com/ibm/icu/impl/IntTrieBuilder.java @@ -5,8 +5,8 @@ ****************************************************************************** * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/IntTrieBuilder.java,v $ -* $Date: 2002/10/31 01:09:18 $ -* $Revision: 1.3 $ +* $Date: 2003/08/20 00:19:19 $ +* $Revision: 1.4 $ * ****************************************************************************** */ @@ -14,6 +14,7 @@ package com.ibm.icu.impl; import com.ibm.icu.lang.UCharacter; +import com.ibm.icu.text.UTF16; import java.util.Arrays; /** @@ -31,7 +32,7 @@ import java.util.Arrays; *
  • Smaller memory footprint. * * This is a direct port from the ICU4C version - * @version $Revision: 1.3 $ + * @version $Revision: 1.4 $ * @author Syn Wee Quek */ public class IntTrieBuilder extends TrieBuilder @@ -47,6 +48,7 @@ public class IntTrieBuilder extends TrieBuilder m_data_ = new int[m_dataCapacity_]; System.arraycopy(table.m_data_, 0, m_data_, 0, m_dataLength_); m_initialValue_ = table.m_initialValue_; + m_leadUnitValue_ = table.m_leadUnitValue_; } /** @@ -58,10 +60,11 @@ public class IntTrieBuilder extends TrieBuilder * @return updated table */ public IntTrieBuilder(int aliasdata[], int maxdatalength, - int initialvalue, boolean latin1linear) + int initialvalue, int leadunitvalue, + boolean latin1linear) { super(); - if (maxdatalength < DATA_BLOCK_LENGTH_ || (latin1linear + if (maxdatalength < DATA_BLOCK_LENGTH || (latin1linear && maxdatalength < 1024)) { throw new IllegalArgumentException( "Argument maxdatalength is too small"); @@ -75,7 +78,7 @@ public class IntTrieBuilder extends TrieBuilder } // preallocate and reset the first data block (block index 0) - int j = DATA_BLOCK_LENGTH_; + int j = DATA_BLOCK_LENGTH; if (latin1linear) { // preallocate and reset the first block (number 0) and Latin-1 @@ -87,7 +90,7 @@ public class IntTrieBuilder extends TrieBuilder // do this at least for trie->index[0] even if that block is // only partly used for Latin-1 m_index_[i ++] = j; - j += DATA_BLOCK_LENGTH_; + j += DATA_BLOCK_LENGTH; } while (i < (256 >> SHIFT_)); } @@ -95,6 +98,7 @@ public class IntTrieBuilder extends TrieBuilder // reset the initially allocated blocks to the initial value Arrays.fill(m_data_, 0, m_dataLength_, initialvalue); m_initialValue_ = initialvalue; + m_leadUnitValue_ = leadunitvalue; m_dataCapacity_ = maxdatalength; m_isLatin1Linear_ = latin1linear; m_isCompacted_ = false; @@ -246,13 +250,135 @@ public class IntTrieBuilder extends TrieBuilder triedatamanipulate); } - // public data member --------------------------------------------- + /** + * Set a value in a range of code points [start..limit]. + * All code points c with start <= c < limit will get the value if + * overwrite is true or if the old value is 0. + * @param start the first code point to get the value + * @param limit one past the last code point to get the value + * @param value the value + * @param overwrite flag for whether old non-initial values are to be + * overwritten + * @return false if a failure occurred (illegal argument or data array + * overrun) + */ + public boolean setRange(int start, int limit, int value, + boolean overwrite) + { + // repeat value in [start..limit[ + // mark index values for repeat-data blocks by setting bit 31 of the + // index values fill around existing values if any, if(overwrite) + + // valid, uncompacted trie and valid indexes? + if (m_isCompacted_ || start < UCharacter.MIN_VALUE + || start > UCharacter.MAX_VALUE || limit < UCharacter.MIN_VALUE + || limit > (UCharacter.MAX_VALUE + 1) || start > limit) { + return false; + } + + if (start == limit) { + return true; // nothing to do + } + + if ((start & MASK_) != 0) { + // set partial block at [start..following block boundary[ + int block = getDataBlock(start); + if (block < 0) { + return false; + } + + int nextStart = (start + DATA_BLOCK_LENGTH) & ~MASK_; + if (nextStart <= limit) { + fillBlock(block, start & MASK_, DATA_BLOCK_LENGTH, + value, overwrite); + start = nextStart; + } + else { + fillBlock(block, start & MASK_, limit & MASK_, + value, overwrite); + return true; + } + } + + // number of positions in the last, partial block + int rest = limit & MASK_; + + // round down limit to a block boundary + limit &= ~MASK_; + + // iterate over all-value blocks + int repeatBlock = 0; + if (value == m_initialValue_) { + // repeatBlock = 0; assigned above + } + else { + repeatBlock = -1; + } + while (start < limit) { + // get index value + int block = m_index_[start >> SHIFT_]; + if (block > 0) { + // already allocated, fill in value + fillBlock(block, 0, DATA_BLOCK_LENGTH, value, overwrite); + } + else if (m_data_[-block] != value && (block == 0 || overwrite)) { + // set the repeatBlock instead of the current block 0 or range + // block + if (repeatBlock >= 0) { + m_index_[start >> SHIFT_] = -repeatBlock; + } + else { + // create and set and fill the repeatBlock + repeatBlock = getDataBlock(start); + if (repeatBlock < 0) { + return false; + } + + // set the negative block number to indicate that it is a + // repeat block + m_index_[start >> SHIFT_] = -repeatBlock; + fillBlock(repeatBlock, 0, DATA_BLOCK_LENGTH, value, true); + } + } + + start += DATA_BLOCK_LENGTH; + } + + if (rest > 0) { + // set partial block at [last block boundary..limit[ + int block = getDataBlock(start); + if (block < 0) { + return false; + } + fillBlock(block, 0, rest, value, overwrite); + } + + return true; + } + + // protected data member ------------------------------------------------ protected int m_data_[]; protected int m_initialValue_; - + + // private data member ------------------------------------------------ + + private int m_leadUnitValue_; + // private methods ------------------------------------------------------ + private int allocDataBlock() + { + int newBlock = m_dataLength_; + int newTop = newBlock + DATA_BLOCK_LENGTH; + if (newTop > m_dataCapacity_) { + // out of memory in the data array + return -1; + } + m_dataLength_ = newTop; + return newBlock; + } + /** * No error checking for illegal arguments. * @param ch codepoint to look for @@ -267,18 +393,16 @@ public class IntTrieBuilder extends TrieBuilder } // allocate a new data block - int newBlock = m_dataLength_; - int newTop = newBlock + DATA_BLOCK_LENGTH_; - if (newTop > m_dataCapacity_) { + int newBlock = allocDataBlock(); + if (newBlock < 0) { // out of memory in the data array return -1; } - m_dataLength_ = newTop; m_index_[ch] = newBlock; // copy-on-write for a block from a setRange() - Arrays.fill(m_data_, newBlock, newBlock + DATA_BLOCK_LENGTH_, - m_initialValue_); + System.arraycopy(m_data_, Math.abs(indexValue), m_data_, newBlock, + DATA_BLOCK_LENGTH << 2); return newBlock; } @@ -307,34 +431,34 @@ public class IntTrieBuilder extends TrieBuilder // if Latin-1 is preallocated and linear, then do not compact Latin-1 // data - int overlapStart = DATA_BLOCK_LENGTH_; + int overlapStart = DATA_BLOCK_LENGTH; if (m_isLatin1Linear_ && SHIFT_ <= 8) { overlapStart += 256; } - int newStart = DATA_BLOCK_LENGTH_; + int newStart = DATA_BLOCK_LENGTH; int prevEnd = newStart - 1; for (int start = newStart; start < m_dataLength_;) { // start: index of first entry of current block // prevEnd: index to last entry of previous block // newStart: index where the current block is to be moved // skip blocks that are not used - if (m_map_[start >> SHIFT_] < 0) { + if (m_map_[start >>> SHIFT_] < 0) { // advance start to the next block - start += DATA_BLOCK_LENGTH_; + start += DATA_BLOCK_LENGTH; // leave prevEnd and newStart with the previous block! continue; } // search for an identical block if (start >= overlapStart) { int i = findSameDataBlock(m_data_, newStart, start, - overlap ? DATA_GRANULARITY_ : DATA_BLOCK_LENGTH_); + overlap ? DATA_GRANULARITY_ : DATA_BLOCK_LENGTH); if (i >= 0) { // found an identical block, set the other block's index // value for the current block - m_map_[start >> SHIFT_] = i; + m_map_[start >>> SHIFT_] = i; // advance start to the next block - start += DATA_BLOCK_LENGTH_; + start += DATA_BLOCK_LENGTH; // leave prevEnd and newStart with the previous block! continue; } @@ -347,7 +471,7 @@ public class IntTrieBuilder extends TrieBuilder if (x == m_data_[prevEnd] && overlap && start >= overlapStart) { // overlap by at least one - for (i = 1; i < DATA_BLOCK_LENGTH_ + for (i = 1; i < DATA_BLOCK_LENGTH && x == m_data_[start + i] && x == m_data_[prevEnd - i]; ++ i) { @@ -358,23 +482,23 @@ public class IntTrieBuilder extends TrieBuilder } if (i > 0) { // some overlap - m_map_[start >> SHIFT_] = newStart - i; + m_map_[start >>> SHIFT_] = newStart - i; // move the non-overlapping indexes to their new positions start += i; - for (i = DATA_BLOCK_LENGTH_ - i; i > 0; -- i) { + for (i = DATA_BLOCK_LENGTH - i; i > 0; -- i) { m_data_[newStart ++] = m_data_[start ++]; } } else if (newStart < start) { // no overlap, just move the indexes to their new positions - m_map_[start >> SHIFT_] = newStart; - for (i = DATA_BLOCK_LENGTH_; i > 0; -- i) { + m_map_[start >>> SHIFT_] = newStart; + for (i = DATA_BLOCK_LENGTH; i > 0; -- i) { m_data_[newStart ++] = m_data_[start ++]; } } else { // no overlap && newStart==start - m_map_[start >> SHIFT_] = start; - newStart += DATA_BLOCK_LENGTH_; + m_map_[start >>> SHIFT_] = start; + newStart += DATA_BLOCK_LENGTH; start = newStart; } @@ -382,7 +506,7 @@ public class IntTrieBuilder extends TrieBuilder } // now adjust the index (stage 1) table for (int i = 0; i < m_indexLength_; ++ i) { - m_index_[i] = m_map_[m_index_[i] >>> SHIFT_]; + m_index_[i] = m_map_[Math.abs(m_index_[i]) >>> SHIFT_]; } m_dataLength_ = newStart; } @@ -398,16 +522,16 @@ public class IntTrieBuilder extends TrieBuilder int otherBlock, int step) { // ensure that we do not even partially get past dataLength - dataLength -= DATA_BLOCK_LENGTH_; + dataLength -= DATA_BLOCK_LENGTH; for (int block = 0; block <= dataLength; block += step) { int i = 0; - for (i = 0; i < DATA_BLOCK_LENGTH_; ++ i) { + for (i = 0; i < DATA_BLOCK_LENGTH; ++ i) { if (data[block + i] != data[otherBlock + i]) { break; } } - if (i == DATA_BLOCK_LENGTH_) { + if (i == DATA_BLOCK_LENGTH) { return block; } } @@ -433,16 +557,33 @@ public class IntTrieBuilder extends TrieBuilder System.arraycopy(index, 0xd800 >> SHIFT_, leadIndexes, 0, SURROGATE_BLOCK_COUNT_); - // to protect the copied lead surrogate values, - // mark all their indexes as repeat blocks - // (causes copy-on-write) - for (char c = 0xd800; c <= 0xdbff; ++ c) { - int block = index[c >> SHIFT_]; - if (block > 0) { - index[c >> SHIFT_] =- block; + // set all values for lead surrogate code *units* to leadUnitValue + // so that by default runtime lookups will find no data for associated + // supplementary code points, unless there is data for such code points + // which will result in a non-zero folding value below that is set for + // the respective lead units + // the above saved the indexes for surrogate code *points* + // fill the indexes with simplified code from utrie_setRange32() + int block = 0; + if (m_leadUnitValue_ == m_initialValue_) { + // leadUnitValue == initialValue, use all-initial-value block + // block = 0; if block here left empty + } + else { + // create and fill the repeatBlock + block = allocDataBlock(); + if (block < 0) { + // data table overflow + throw new InternalError("Internal error: Out of memory space"); } + fillBlock(block, 0, DATA_BLOCK_LENGTH, m_leadUnitValue_, true); + // negative block number to indicate that it is a repeat block + block = -block; } - + for (int c = (0xd800 >> SHIFT_); c < (0xdc00 >> SHIFT_); ++ c) { + m_index_[c] = block; + } + // Fold significant index values into the area just after the BMP // indexes. // In case the first lead surrogate has significant data, @@ -457,13 +598,16 @@ public class IntTrieBuilder extends TrieBuilder // there is data, treat the full block for a lead surrogate c &= ~0x3ff; // is there an identical index block? - int block = findSameIndexBlock(index, indexLength, c >> SHIFT_); - // get a folded value for [c..c+0x400[ and, if 0, set it for - // the lead surrogate + block = findSameIndexBlock(index, indexLength, c >> SHIFT_); + + // get a folded value for [c..c+0x400[ and, + // if different from the value for the lead surrogate code + // point, set it for the lead surrogate code unit + int value = manipulate.getFoldedValue(c, block + SURROGATE_BLOCK_COUNT_); - if (value != 0) { - if (!setValue(0xd7c0 + (c >> 10), value)) { + if (value != getValue(UTF16.getLeadSurrogate(c))) { + if (!setValue(UTF16.getLeadSurrogate(c), value)) { // data table overflow throw new ArrayIndexOutOfBoundsException( "Data table overflow"); @@ -480,7 +624,7 @@ public class IntTrieBuilder extends TrieBuilder c += 0x400; } else { - c += DATA_BLOCK_LENGTH_; + c += DATA_BLOCK_LENGTH; } } @@ -505,5 +649,28 @@ public class IntTrieBuilder extends TrieBuilder indexLength += SURROGATE_BLOCK_COUNT_; m_indexLength_ = indexLength; } + + /** + * @internal + */ + private void fillBlock(int block, int start, int limit, int value, + boolean overwrite) + { + limit += block; + block += start; + if (overwrite) { + while (block < limit) { + m_data_[block ++] = value; + } + } + else { + while (block < limit) { + if (m_data_[block] == m_initialValue_) { + m_data_[block] = value; + } + ++ block; + } + } + } } \ No newline at end of file diff --git a/icu4j/src/com/ibm/icu/impl/TrieBuilder.java b/icu4j/src/com/ibm/icu/impl/TrieBuilder.java index 06ff8d7561b..b45fb6386d1 100755 --- a/icu4j/src/com/ibm/icu/impl/TrieBuilder.java +++ b/icu4j/src/com/ibm/icu/impl/TrieBuilder.java @@ -5,8 +5,8 @@ ****************************************************************************** * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/TrieBuilder.java,v $ -* $Date: 2002/09/06 01:50:43 $ -* $Revision: 1.8 $ +* $Date: 2003/08/20 00:19:20 $ +* $Revision: 1.9 $ * ****************************************************************************** */ @@ -31,7 +31,7 @@ import java.util.Arrays; *
  • Smaller memory footprint. * * This is a direct port from the ICU4C version - * @version $Revision: 1.8 $ + * @version $Revision: 1.9 $ * @author Syn Wee Quek */ public class TrieBuilder @@ -42,7 +42,7 @@ public class TrieBuilder * Number of data values in a stage 2 (data array) block. 2, 4, 8, .., * 0x200 */ - public static final int DATA_BLOCK_LENGTH_ = 1 << Trie.INDEX_STAGE_1_SHIFT_; + public static final int DATA_BLOCK_LENGTH = 1 << Trie.INDEX_STAGE_1_SHIFT_; // public class declaration ---------------------------------------- @@ -141,7 +141,7 @@ public class TrieBuilder protected static final int SURROGATE_BLOCK_COUNT_ = 1 << (10 - SHIFT_); /** * Mask for getting the lower bits from the input index. - * DATA_BLOCK_LENGTH_ - 1. + * DATA_BLOCK_LENGTH - 1. */ protected static final int MASK_ = Trie.INDEX_STAGE_3_MASK_; /** @@ -253,10 +253,10 @@ public class TrieBuilder /** * Maximum length of the build-time data (stage 2) array. - * The maximum length is 0x110000 + DATA_BLOCK_LENGTH_ + 0x400. + * The maximum length is 0x110000 + DATA_BLOCK_LENGTH + 0x400. * (Number of Unicode code points + one all-initial-value block + * possible duplicate entries for 1024 lead surrogates.) */ private static final int MAX_BUILD_TIME_DATA_LENGTH_ = - 0x110000 + DATA_BLOCK_LENGTH_ + 0x400; + 0x110000 + DATA_BLOCK_LENGTH + 0x400; } \ No newline at end of file diff --git a/icu4j/src/com/ibm/icu/impl/TrieIterator.java b/icu4j/src/com/ibm/icu/impl/TrieIterator.java index d7b896b93c5..7139f2afc94 100755 --- a/icu4j/src/com/ibm/icu/impl/TrieIterator.java +++ b/icu4j/src/com/ibm/icu/impl/TrieIterator.java @@ -5,8 +5,8 @@ ****************************************************************************** * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/TrieIterator.java,v $ -* $Date: 2002/11/16 01:49:26 $ -* $Revision: 1.8 $ +* $Date: 2003/08/20 00:19:19 $ +* $Revision: 1.9 $ * ****************************************************************************** */ @@ -131,7 +131,7 @@ public class TrieIterator implements RangeValueIterator } if (m_nextCodepoint_ < UCharacter.SUPPLEMENTARY_MIN_VALUE && calculateNextBMPElement(element)) { - return true; + return true; } calculateNextSupplementaryElement(element); return true; @@ -268,22 +268,26 @@ public class TrieIterator implements RangeValueIterator m_nextCodepoint_ ++; m_nextBlockIndex_ ++; - if (!checkNullNextTrailIndex() && !checkBlockDetail(currentValue)) { - setResult(element, m_currentCodepoint_, m_nextCodepoint_, - currentValue); - m_currentCodepoint_ = m_nextCodepoint_; - return; + if (UTF16.getTrailSurrogate(m_nextCodepoint_) + != UTF16.TRAIL_SURROGATE_MIN_VALUE) { + // this piece is only called when we are in the middle of a lead + // surrogate block + if (!checkNullNextTrailIndex() && !checkBlockDetail(currentValue)) { + setResult(element, m_currentCodepoint_, m_nextCodepoint_, + currentValue); + m_currentCodepoint_ = m_nextCodepoint_; + return; + } + // we have cleared one block + m_nextIndex_ ++; + m_nextTrailIndexOffset_ ++; + if (!checkTrailBlock(currentBlock, currentValue)) { + setResult(element, m_currentCodepoint_, m_nextCodepoint_, + currentValue); + m_currentCodepoint_ = m_nextCodepoint_; + return; + } } - // we have cleared one block - m_nextIndex_ ++; - m_nextTrailIndexOffset_ ++; - if (!checkTrailBlock(currentBlock, currentValue)) { - setResult(element, m_currentCodepoint_, m_nextCodepoint_, - currentValue); - m_currentCodepoint_ = m_nextCodepoint_; - return; - } - int nextLead = UTF16.getLeadSurrogate(m_nextCodepoint_); // enumerate supplementary code points while (nextLead < TRAIL_SURROGATE_MIN_VALUE_) { @@ -293,10 +297,25 @@ public class TrieIterator implements RangeValueIterator Trie.INDEX_STAGE_2_SHIFT_; if (leadBlock == m_trie_.m_dataOffset_) { // no entries for a whole block of lead surrogates + if (currentValue != m_initialValue_) { + m_nextValue_ = m_initialValue_; + m_nextBlock_ = 0; + m_nextBlockIndex_ = 0; + setResult(element, m_currentCodepoint_, m_nextCodepoint_, + currentValue); + m_currentCodepoint_ = m_nextCodepoint_; + return; + } + nextLead += DATA_BLOCK_LENGTH_; // number of total affected supplementary codepoints in one // block - m_nextCodepoint_ += DATA_BLOCK_SUPPLEMENTARY_LENGTH_; + // this is not a simple addition of + // DATA_BLOCK_SUPPLEMENTARY_LENGTH since we need to consider + // that we might have moved some of the codepoints + m_nextCodepoint_ = UCharacterProperty.getRawSupplementary( + (char)nextLead, + (char)UTF16.TRAIL_SURROGATE_MIN_VALUE); continue; } if (m_trie_.m_dataManipulate_ == null) { diff --git a/icu4j/src/com/ibm/icu/text/CollationParsedRuleBuilder.java b/icu4j/src/com/ibm/icu/text/CollationParsedRuleBuilder.java index 15f6c97cc1f..805ed9f2629 100644 --- a/icu4j/src/com/ibm/icu/text/CollationParsedRuleBuilder.java +++ b/icu4j/src/com/ibm/icu/text/CollationParsedRuleBuilder.java @@ -5,8 +5,8 @@ ******************************************************************************* * * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/CollationParsedRuleBuilder.java,v $ -* $Date: 2003/07/16 05:52:08 $ -* $Revision: 1.22 $ +* $Date: 2003/08/20 00:20:37 $ +* $Revision: 1.23 $ * ******************************************************************************* */ @@ -848,7 +848,7 @@ final class CollationParsedRuleBuilder boolean inBlockZero = m_mapping_.isInZeroBlock(cp); int tag = getCETag(value); if (inBlockZero == true) { - cp += TrieBuilder.DATA_BLOCK_LENGTH_; + cp += TrieBuilder.DATA_BLOCK_LENGTH; } else if (!(isSpecial(value) && (tag == CE_IMPLICIT_TAG_ || tag == CE_NOT_FOUND_TAG_))) { @@ -882,10 +882,10 @@ final class CollationParsedRuleBuilder m_expansions_ = new Vector(); // Do your own mallocs for the structure, array and have linear // Latin 1 - m_mapping_ = new IntTrieBuilder(null, 0x100000, - RuleBasedCollator.CE_SPECIAL_FLAG_ - | (CE_NOT_FOUND_TAG_ << 24), - true); + int trieinitialvalue = RuleBasedCollator.CE_SPECIAL_FLAG_ + | (CE_NOT_FOUND_TAG_ << 24); + m_mapping_ = new IntTrieBuilder(null, 0x100000, trieinitialvalue, + trieinitialvalue, true); m_prefixLookup_ = new Hashtable(); // uhash_open(prefixLookupHash, prefixLookupComp); m_contractions_ = new ContractionTable(m_mapping_);