/* */ package com.ibm.icu.util; /* */ /* */ import java.io.IOException; /* */ import java.nio.ByteBuffer; /* */ import java.util.ArrayList; /* */ import java.util.Iterator; /* */ import java.util.NoSuchElementException; /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public final class BytesTrie /* */ implements Cloneable, Iterable<Entry> /* */ { /* */ public BytesTrie(byte[] trieBytes, int offset) /* */ { /* 46 */ this.bytes_ = trieBytes; /* 47 */ this.pos_ = (this.root_ = offset); /* 48 */ this.remainingMatchLength_ = -1; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Object clone() /* */ throws CloneNotSupportedException /* */ { /* 60 */ return super.clone(); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ public BytesTrie reset() /* */ { /* 70 */ this.pos_ = this.root_; /* 71 */ this.remainingMatchLength_ = -1; /* 72 */ return this; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public BytesTrie saveState(State state) /* */ { /* 103 */ state.bytes = this.bytes_; /* 104 */ state.root = this.root_; /* 105 */ state.pos = this.pos_; /* 106 */ state.remainingMatchLength = this.remainingMatchLength_; /* 107 */ return this; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public BytesTrie resetToState(State state) /* */ { /* 122 */ if ((this.bytes_ == state.bytes) && (this.bytes_ != null) && (this.root_ == state.root)) { /* 123 */ this.pos_ = state.pos; /* 124 */ this.remainingMatchLength_ = state.remainingMatchLength; /* */ } else { /* 126 */ throw new IllegalArgumentException("incompatible trie state"); /* */ } /* 128 */ return this; /* */ } /* */ /* */ /* */ public static final class State /* */ { /* */ private byte[] bytes; /* */ /* */ private int root; /* */ /* */ private int pos; /* */ /* */ private int remainingMatchLength; /* */ } /* */ /* */ public static enum Result /* */ { /* 145 */ NO_MATCH, /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 153 */ NO_VALUE, /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 162 */ FINAL_VALUE, /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 171 */ INTERMEDIATE_VALUE; /* */ /* */ /* */ /* */ /* */ private Result() {} /* */ /* */ /* */ /* */ /* */ public boolean matches() /* */ { /* 183 */ return this != NO_MATCH; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public boolean hasValue() /* */ { /* 192 */ return ordinal() >= 2; /* */ } /* */ /* */ /* */ /* */ /* */ public boolean hasNext() /* */ { /* 200 */ return (ordinal() & 0x1) != 0; /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Result current() /* */ { /* 211 */ int pos = this.pos_; /* 212 */ if (pos < 0) { /* 213 */ return Result.NO_MATCH; /* */ } /* */ int node; /* 216 */ return (this.remainingMatchLength_ < 0) && ((node = this.bytes_[pos] & 0xFF) >= 32) ? valueResults_[(node & 0x1)] : Result.NO_VALUE; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Result first(int inByte) /* */ { /* 231 */ this.remainingMatchLength_ = -1; /* 232 */ if (inByte < 0) { /* 233 */ inByte += 256; /* */ } /* 235 */ return nextImpl(this.root_, inByte); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Result next(int inByte) /* */ { /* 247 */ int pos = this.pos_; /* 248 */ if (pos < 0) { /* 249 */ return Result.NO_MATCH; /* */ } /* 251 */ if (inByte < 0) { /* 252 */ inByte += 256; /* */ } /* 254 */ int length = this.remainingMatchLength_; /* 255 */ if (length >= 0) /* */ { /* 257 */ if (inByte == (this.bytes_[(pos++)] & 0xFF)) { /* 258 */ this.remainingMatchLength_ = (--length); /* 259 */ this.pos_ = pos; /* */ int node; /* 261 */ return (length < 0) && ((node = this.bytes_[pos] & 0xFF) >= 32) ? valueResults_[(node & 0x1)] : Result.NO_VALUE; /* */ } /* */ /* 264 */ stop(); /* 265 */ return Result.NO_MATCH; /* */ } /* */ /* 268 */ return nextImpl(pos, inByte); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Result next(byte[] s, int sIndex, int sLimit) /* */ { /* 289 */ if (sIndex >= sLimit) /* */ { /* 291 */ return current(); /* */ } /* 293 */ int pos = this.pos_; /* 294 */ if (pos < 0) { /* 295 */ return Result.NO_MATCH; /* */ } /* 297 */ int length = this.remainingMatchLength_; /* */ /* */ /* */ /* */ for (;;) /* */ { /* 303 */ if (sIndex == sLimit) { /* 304 */ this.remainingMatchLength_ = length; /* 305 */ this.pos_ = pos; /* */ int node; /* 307 */ return (length < 0) && ((node = this.bytes_[pos] & 0xFF) >= 32) ? valueResults_[(node & 0x1)] : Result.NO_VALUE; /* */ } /* */ /* 310 */ byte inByte = s[(sIndex++)]; /* 311 */ if (length < 0) { /* 312 */ this.remainingMatchLength_ = length; /* */ } /* */ else { /* 315 */ if (inByte != this.bytes_[pos]) { /* 316 */ stop(); /* 317 */ return Result.NO_MATCH; /* */ } /* 319 */ pos++; /* 320 */ length--; continue; /* */ } /* */ for (;;) { /* 323 */ int node = this.bytes_[(pos++)] & 0xFF; /* 324 */ if (node < 16) { /* 325 */ Result result = branchNext(pos, node, inByte & 0xFF); /* 326 */ if (result == Result.NO_MATCH) { /* 327 */ return Result.NO_MATCH; /* */ } /* */ /* 330 */ if (sIndex == sLimit) { /* 331 */ return result; /* */ } /* 333 */ if (result == Result.FINAL_VALUE) /* */ { /* 335 */ stop(); /* 336 */ return Result.NO_MATCH; /* */ } /* 338 */ inByte = s[(sIndex++)]; /* 339 */ pos = this.pos_; /* 340 */ } else { if (node < 32) /* */ { /* 342 */ length = node - 16; /* 343 */ if (inByte != this.bytes_[pos]) { /* 344 */ stop(); /* 345 */ return Result.NO_MATCH; /* */ } /* 347 */ pos++; /* 348 */ length--; /* 349 */ break; } /* 350 */ if ((node & 0x1) != 0) /* */ { /* 352 */ stop(); /* 353 */ return Result.NO_MATCH; /* */ } /* */ /* 356 */ pos = skipValue(pos, node); /* */ /* 358 */ assert ((this.bytes_[pos] & 0xFF) < 32); /* */ } /* */ } /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public int getValue() /* */ { /* 375 */ int pos = this.pos_; /* 376 */ int leadByte = this.bytes_[(pos++)] & 0xFF; /* 377 */ assert (leadByte >= 32); /* 378 */ return readValue(this.bytes_, pos, leadByte >> 1); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public long getUniqueValue() /* */ { /* 391 */ int pos = this.pos_; /* 392 */ if (pos < 0) { /* 393 */ return 0L; /* */ } /* */ /* 396 */ long uniqueValue = findUniqueValue(this.bytes_, pos + this.remainingMatchLength_ + 1, 0L); /* */ /* 398 */ return uniqueValue << 31 >> 31; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public int getNextBytes(Appendable out) /* */ { /* 411 */ int pos = this.pos_; /* 412 */ if (pos < 0) { /* 413 */ return 0; /* */ } /* 415 */ if (this.remainingMatchLength_ >= 0) { /* 416 */ append(out, this.bytes_[pos] & 0xFF); /* 417 */ return 1; /* */ } /* 419 */ int node = this.bytes_[(pos++)] & 0xFF; /* 420 */ if (node >= 32) { /* 421 */ if ((node & 0x1) != 0) { /* 422 */ return 0; /* */ } /* 424 */ pos = skipValue(pos, node); /* 425 */ node = this.bytes_[(pos++)] & 0xFF; /* 426 */ assert (node < 32); /* */ } /* */ /* 429 */ if (node < 16) { /* 430 */ if (node == 0) { /* 431 */ node = this.bytes_[(pos++)] & 0xFF; /* */ } /* 433 */ getNextBranchBytes(this.bytes_, pos, ++node, out); /* 434 */ return node; /* */ } /* */ /* 437 */ append(out, this.bytes_[pos] & 0xFF); /* 438 */ return 1; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Iterator iterator() /* */ { /* 449 */ return new Iterator(this.bytes_, this.pos_, this.remainingMatchLength_, 0, null); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Iterator iterator(int maxStringLength) /* */ { /* 461 */ return new Iterator(this.bytes_, this.pos_, this.remainingMatchLength_, maxStringLength, null); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public static Iterator iterator(byte[] trieBytes, int offset, int maxStringLength) /* */ { /* 475 */ return new Iterator(trieBytes, offset, -1, maxStringLength, null); /* */ } /* */ /* */ public static final class Entry /* */ { /* */ public int value; /* */ private byte[] bytes; /* */ private int length; /* */ /* */ private Entry(int capacity) { /* 485 */ this.bytes = new byte[capacity]; /* */ } /* */ /* */ /* */ /* */ /* */ public int bytesLength() /* */ { /* 493 */ return this.length; /* */ } /* */ /* */ /* */ /* */ /* */ public byte byteAt(int index) /* */ { /* 501 */ return this.bytes[index]; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ public void copyBytesTo(byte[] dest, int destOffset) /* */ { /* 510 */ System.arraycopy(this.bytes, 0, dest, destOffset, this.length); /* */ } /* */ /* */ /* */ /* */ /* */ public ByteBuffer bytesAsByteBuffer() /* */ { /* 518 */ return ByteBuffer.wrap(this.bytes, 0, this.length).asReadOnlyBuffer(); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ private void ensureCapacity(int len) /* */ { /* 529 */ if (this.bytes.length < len) { /* 530 */ byte[] newBytes = new byte[Math.min(2 * this.bytes.length, 2 * len)]; /* 531 */ System.arraycopy(this.bytes, 0, newBytes, 0, this.length); /* 532 */ this.bytes = newBytes; /* */ } /* */ } /* */ /* 536 */ private void append(byte b) { ensureCapacity(this.length + 1); /* 537 */ this.bytes[(this.length++)] = b; /* */ } /* */ /* 540 */ private void append(byte[] b, int off, int len) { ensureCapacity(this.length + len); /* 541 */ System.arraycopy(b, off, this.bytes, this.length, len); /* 542 */ this.length += len; } /* */ /* 544 */ private void truncateString(int newLength) { this.length = newLength; } /* */ } /* */ /* */ public static final class Iterator implements Iterator<BytesTrie.Entry> { /* */ private byte[] bytes_; /* */ private int pos_; /* */ private int initialPos_; /* */ private int remainingMatchLength_; /* */ private int initialRemainingMatchLength_; /* */ private int maxLength_; /* */ private BytesTrie.Entry entry_; /* */ /* */ private Iterator(byte[] trieBytes, int offset, int remainingMatchLength, int maxStringLength) { /* 557 */ this.bytes_ = trieBytes; /* 558 */ this.pos_ = (this.initialPos_ = offset); /* 559 */ this.remainingMatchLength_ = (this.initialRemainingMatchLength_ = remainingMatchLength); /* 560 */ this.maxLength_ = maxStringLength; /* 561 */ this.entry_ = new BytesTrie.Entry(this.maxLength_ != 0 ? this.maxLength_ : 32, null); /* 562 */ int length = this.remainingMatchLength_; /* 563 */ if (length >= 0) /* */ { /* 565 */ length++; /* 566 */ if ((this.maxLength_ > 0) && (length > this.maxLength_)) { /* 567 */ length = this.maxLength_; /* */ } /* 569 */ BytesTrie.Entry.access$600(this.entry_, this.bytes_, this.pos_, length); /* 570 */ this.pos_ += length; /* 571 */ this.remainingMatchLength_ -= length; /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ public Iterator reset() /* */ { /* 582 */ this.pos_ = this.initialPos_; /* 583 */ this.remainingMatchLength_ = this.initialRemainingMatchLength_; /* 584 */ int length = this.remainingMatchLength_ + 1; /* 585 */ if ((this.maxLength_ > 0) && (length > this.maxLength_)) { /* 586 */ length = this.maxLength_; /* */ } /* 588 */ BytesTrie.Entry.access$700(this.entry_, length); /* 589 */ this.pos_ += length; /* 590 */ this.remainingMatchLength_ -= length; /* 591 */ this.stack_.clear(); /* 592 */ return this; /* */ } /* */ /* */ /* */ /* */ /* */ public boolean hasNext() /* */ { /* 600 */ return (this.pos_ >= 0) || (!this.stack_.isEmpty()); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public BytesTrie.Entry next() /* */ { /* 615 */ int pos = this.pos_; /* 616 */ if (pos < 0) { /* 617 */ if (this.stack_.isEmpty()) { /* 618 */ throw new NoSuchElementException(); /* */ } /* */ /* */ /* 622 */ long top = ((Long)this.stack_.remove(this.stack_.size() - 1)).longValue(); /* 623 */ int length = (int)top; /* 624 */ pos = (int)(top >> 32); /* 625 */ BytesTrie.Entry.access$700(this.entry_, length & 0xFFFF); /* 626 */ length >>>= 16; /* 627 */ if (length > 1) { /* 628 */ pos = branchNext(pos, length); /* 629 */ if (pos < 0) { /* 630 */ return this.entry_; /* */ } /* */ } else { /* 633 */ BytesTrie.Entry.access$800(this.entry_, this.bytes_[(pos++)]); /* */ } /* */ } /* 636 */ if (this.remainingMatchLength_ >= 0) /* */ { /* */ /* 639 */ return truncateAndStop(); /* */ } /* */ for (;;) { /* 642 */ int node = this.bytes_[(pos++)] & 0xFF; /* 643 */ if (node >= 32) /* */ { /* 645 */ boolean isFinal = (node & 0x1) != 0; /* 646 */ this.entry_.value = BytesTrie.readValue(this.bytes_, pos, node >> 1); /* 647 */ if ((isFinal) || ((this.maxLength_ > 0) && (BytesTrie.Entry.access$1000(this.entry_) == this.maxLength_))) { /* 648 */ this.pos_ = -1; /* */ } else { /* 650 */ this.pos_ = BytesTrie.skipValue(pos, node); /* */ } /* 652 */ return this.entry_; /* */ } /* 654 */ if ((this.maxLength_ > 0) && (BytesTrie.Entry.access$1000(this.entry_) == this.maxLength_)) { /* 655 */ return truncateAndStop(); /* */ } /* 657 */ if (node < 16) { /* 658 */ if (node == 0) { /* 659 */ node = this.bytes_[(pos++)] & 0xFF; /* */ } /* 661 */ pos = branchNext(pos, node + 1); /* 662 */ if (pos < 0) { /* 663 */ return this.entry_; /* */ } /* */ } /* */ else { /* 667 */ int length = node - 16 + 1; /* 668 */ if ((this.maxLength_ > 0) && (BytesTrie.Entry.access$1000(this.entry_) + length > this.maxLength_)) { /* 669 */ BytesTrie.Entry.access$600(this.entry_, this.bytes_, pos, this.maxLength_ - BytesTrie.Entry.access$1000(this.entry_)); /* 670 */ return truncateAndStop(); /* */ } /* 672 */ BytesTrie.Entry.access$600(this.entry_, this.bytes_, pos, length); /* 673 */ pos += length; /* */ } /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ public void remove() /* */ { /* 685 */ throw new UnsupportedOperationException(); /* */ } /* */ /* */ private BytesTrie.Entry truncateAndStop() { /* 689 */ this.pos_ = -1; /* 690 */ this.entry_.value = -1; /* 691 */ return this.entry_; /* */ } /* */ /* */ private int branchNext(int pos, int length) { /* 695 */ while (length > 5) { /* 696 */ pos++; /* */ /* 698 */ this.stack_.add(Long.valueOf(BytesTrie.skipDelta(this.bytes_, pos) << 32 | length - (length >> 1) << 16 | BytesTrie.Entry.access$1000(this.entry_))); /* */ /* 700 */ length >>= 1; /* 701 */ pos = BytesTrie.jumpByDelta(this.bytes_, pos); /* */ } /* */ /* */ /* 705 */ byte trieByte = this.bytes_[(pos++)]; /* 706 */ int node = this.bytes_[(pos++)] & 0xFF; /* 707 */ boolean isFinal = (node & 0x1) != 0; /* 708 */ int value = BytesTrie.readValue(this.bytes_, pos, node >> 1); /* 709 */ pos = BytesTrie.skipValue(pos, node); /* 710 */ this.stack_.add(Long.valueOf(pos << 32 | length - 1 << 16 | BytesTrie.Entry.access$1000(this.entry_))); /* 711 */ BytesTrie.Entry.access$800(this.entry_, trieByte); /* 712 */ if (isFinal) { /* 713 */ this.pos_ = -1; /* 714 */ this.entry_.value = value; /* 715 */ return -1; /* */ } /* 717 */ return pos + value; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 737 */ private ArrayList<Long> stack_ = new ArrayList(); /* */ } /* */ /* */ private void stop() { /* 741 */ this.pos_ = -1; /* */ } /* */ /* */ private static int readValue(byte[] bytes, int pos, int leadByte) /* */ { /* */ int value; /* */ int value; /* 748 */ if (leadByte < 81) { /* 749 */ value = leadByte - 16; } else { int value; /* 750 */ if (leadByte < 108) { /* 751 */ value = leadByte - 81 << 8 | bytes[pos] & 0xFF; } else { int value; /* 752 */ if (leadByte < 126) { /* 753 */ value = leadByte - 108 << 16 | (bytes[pos] & 0xFF) << 8 | bytes[(pos + 1)] & 0xFF; } else { int value; /* 754 */ if (leadByte == 126) { /* 755 */ value = (bytes[pos] & 0xFF) << 16 | (bytes[(pos + 1)] & 0xFF) << 8 | bytes[(pos + 2)] & 0xFF; /* */ } else /* 757 */ value = bytes[pos] << 24 | (bytes[(pos + 1)] & 0xFF) << 16 | (bytes[(pos + 2)] & 0xFF) << 8 | bytes[(pos + 3)] & 0xFF; /* */ } } } /* 759 */ return value; /* */ } /* */ /* 762 */ private static int skipValue(int pos, int leadByte) { assert (leadByte >= 32); /* 763 */ if (leadByte >= 162) { /* 764 */ if (leadByte < 216) { /* 765 */ pos++; /* 766 */ } else if (leadByte < 252) { /* 767 */ pos += 2; /* */ } else { /* 769 */ pos += 3 + (leadByte >> 1 & 0x1); /* */ } /* */ } /* 772 */ return pos; /* */ } /* */ /* 775 */ private static int skipValue(byte[] bytes, int pos) { int leadByte = bytes[(pos++)] & 0xFF; /* 776 */ return skipValue(pos, leadByte); /* */ } /* */ /* */ private static int jumpByDelta(byte[] bytes, int pos) /* */ { /* 781 */ int delta = bytes[(pos++)] & 0xFF; /* 782 */ if (delta >= 192) /* */ { /* 784 */ if (delta < 240) { /* 785 */ delta = delta - 192 << 8 | bytes[(pos++)] & 0xFF; /* 786 */ } else if (delta < 254) { /* 787 */ delta = delta - 240 << 16 | (bytes[pos] & 0xFF) << 8 | bytes[(pos + 1)] & 0xFF; /* 788 */ pos += 2; /* 789 */ } else if (delta == 254) { /* 790 */ delta = (bytes[pos] & 0xFF) << 16 | (bytes[(pos + 1)] & 0xFF) << 8 | bytes[(pos + 2)] & 0xFF; /* 791 */ pos += 3; /* */ } else { /* 793 */ delta = bytes[pos] << 24 | (bytes[(pos + 1)] & 0xFF) << 16 | (bytes[(pos + 2)] & 0xFF) << 8 | bytes[(pos + 3)] & 0xFF; /* 794 */ pos += 4; /* */ } } /* 796 */ return pos + delta; /* */ } /* */ /* */ private static int skipDelta(byte[] bytes, int pos) { /* 800 */ int delta = bytes[(pos++)] & 0xFF; /* 801 */ if (delta >= 192) { /* 802 */ if (delta < 240) { /* 803 */ pos++; /* 804 */ } else if (delta < 254) { /* 805 */ pos += 2; /* */ } else { /* 807 */ pos += 3 + (delta & 0x1); /* */ } /* */ } /* 810 */ return pos; /* */ } /* */ /* 813 */ private static Result[] valueResults_ = { Result.INTERMEDIATE_VALUE, Result.FINAL_VALUE }; /* */ static final int kMaxBranchLinearSubNodeLength = 5; /* */ static final int kMinLinearMatch = 16; /* */ static final int kMaxLinearMatchLength = 16; /* */ /* 818 */ private Result branchNext(int pos, int length, int inByte) { if (length == 0) { /* 819 */ length = this.bytes_[(pos++)] & 0xFF; /* */ } /* 821 */ length++; /* */ /* */ /* 824 */ while (length > 5) { /* 825 */ if (inByte < (this.bytes_[(pos++)] & 0xFF)) { /* 826 */ length >>= 1; /* 827 */ pos = jumpByDelta(this.bytes_, pos); /* */ } else { /* 829 */ length -= (length >> 1); /* 830 */ pos = skipDelta(this.bytes_, pos); /* */ } /* */ } /* */ /* */ /* */ do /* */ { /* 837 */ if (inByte == (this.bytes_[(pos++)] & 0xFF)) /* */ { /* 839 */ int node = this.bytes_[pos] & 0xFF; /* 840 */ assert (node >= 32); /* 841 */ Result result; Result result; if ((node & 0x1) != 0) /* */ { /* 843 */ result = Result.FINAL_VALUE; /* */ } /* */ else { /* 846 */ pos++; /* */ /* 848 */ node >>= 1; /* */ int delta; /* 850 */ int delta; if (node < 81) { /* 851 */ delta = node - 16; } else { int delta; /* 852 */ if (node < 108) { /* 853 */ delta = node - 81 << 8 | this.bytes_[(pos++)] & 0xFF; /* 854 */ } else if (node < 126) { /* 855 */ int delta = node - 108 << 16 | (this.bytes_[pos] & 0xFF) << 8 | this.bytes_[(pos + 1)] & 0xFF; /* 856 */ pos += 2; /* 857 */ } else if (node == 126) { /* 858 */ int delta = (this.bytes_[pos] & 0xFF) << 16 | (this.bytes_[(pos + 1)] & 0xFF) << 8 | this.bytes_[(pos + 2)] & 0xFF; /* 859 */ pos += 3; /* */ } else { /* 861 */ delta = this.bytes_[pos] << 24 | (this.bytes_[(pos + 1)] & 0xFF) << 16 | (this.bytes_[(pos + 2)] & 0xFF) << 8 | this.bytes_[(pos + 3)] & 0xFF; /* 862 */ pos += 4; /* */ } /* */ } /* 865 */ pos += delta; /* 866 */ node = this.bytes_[pos] & 0xFF; /* 867 */ result = node >= 32 ? valueResults_[(node & 0x1)] : Result.NO_VALUE; /* */ } /* 869 */ this.pos_ = pos; /* 870 */ return result; /* */ } /* 872 */ length--; /* 873 */ pos = skipValue(this.bytes_, pos); /* 874 */ } while (length > 1); /* 875 */ if (inByte == (this.bytes_[(pos++)] & 0xFF)) { /* 876 */ this.pos_ = pos; /* 877 */ int node = this.bytes_[pos] & 0xFF; /* 878 */ return node >= 32 ? valueResults_[(node & 0x1)] : Result.NO_VALUE; /* */ } /* 880 */ stop(); /* 881 */ return Result.NO_MATCH; } /* */ /* */ static final int kMinValueLead = 32; /* */ private static final int kValueIsFinal = 1; /* */ static final int kMinOneByteValueLead = 16; /* */ static final int kMaxOneByteValue = 64; /* */ /* 888 */ private Result nextImpl(int pos, int inByte) { for (;;) { int node = this.bytes_[(pos++)] & 0xFF; /* 889 */ if (node < 16) /* 890 */ return branchNext(pos, node, inByte); /* 891 */ if (node < 32) /* */ { /* 893 */ int length = node - 16; /* 894 */ if (inByte != (this.bytes_[(pos++)] & 0xFF)) break; /* 895 */ this.remainingMatchLength_ = (--length); /* 896 */ this.pos_ = pos; /* 897 */ return (length < 0) && ((node = this.bytes_[pos] & 0xFF) >= 32) ? valueResults_[(node & 0x1)] : Result.NO_VALUE; /* */ } /* */ /* */ /* */ /* */ /* 903 */ if ((node & 0x1) != 0) { /* */ break; /* */ } /* */ /* */ /* 908 */ pos = skipValue(pos, node); /* */ /* 910 */ assert ((this.bytes_[pos] & 0xFF) < 32); /* */ } /* */ /* 913 */ stop(); /* 914 */ return Result.NO_MATCH; /* */ } /* */ /* */ static final int kMinTwoByteValueLead = 81; /* */ static final int kMaxTwoByteValue = 6911; /* */ static final int kMinThreeByteValueLead = 108; /* */ static final int kFourByteValueLead = 126; /* */ static final int kMaxThreeByteValue = 1179647; /* */ /* */ private static long findUniqueValueFromBranch(byte[] bytes, int pos, int length, long uniqueValue) { /* 924 */ while (length > 5) { /* 925 */ pos++; /* 926 */ uniqueValue = findUniqueValueFromBranch(bytes, jumpByDelta(bytes, pos), length >> 1, uniqueValue); /* 927 */ if (uniqueValue == 0L) { /* 928 */ return 0L; /* */ } /* 930 */ length -= (length >> 1); /* 931 */ pos = skipDelta(bytes, pos); /* */ } /* */ do { /* 934 */ pos++; /* */ /* 936 */ int node = bytes[(pos++)] & 0xFF; /* 937 */ boolean isFinal = (node & 0x1) != 0; /* 938 */ int value = readValue(bytes, pos, node >> 1); /* 939 */ pos = skipValue(pos, node); /* 940 */ if (isFinal) { /* 941 */ if (uniqueValue != 0L) { /* 942 */ if (value != (int)(uniqueValue >> 1)) { /* 943 */ return 0L; /* */ } /* */ } else { /* 946 */ uniqueValue = value << 1 | 1L; /* */ } /* */ } else { /* 949 */ uniqueValue = findUniqueValue(bytes, pos + value, uniqueValue); /* 950 */ if (uniqueValue == 0L) { /* 951 */ return 0L; /* */ } /* */ } /* 954 */ length--; } while (length > 1); /* */ /* 956 */ return pos + 1 << 33 | uniqueValue & 0x1FFFFFFFF; /* */ } /* */ /* */ static final int kFiveByteValueLead = 127; /* */ static final int kMaxOneByteDelta = 191; /* */ static final int kMinTwoByteDeltaLead = 192; /* */ /* */ private static long findUniqueValue(byte[] bytes, int pos, long uniqueValue) { /* 964 */ for (;;) { int node = bytes[(pos++)] & 0xFF; /* 965 */ if (node < 16) { /* 966 */ if (node == 0) { /* 967 */ node = bytes[(pos++)] & 0xFF; /* */ } /* 969 */ uniqueValue = findUniqueValueFromBranch(bytes, pos, node + 1, uniqueValue); /* 970 */ if (uniqueValue == 0L) { /* 971 */ return 0L; /* */ } /* 973 */ pos = (int)(uniqueValue >>> 33); /* 974 */ } else if (node < 32) /* */ { /* 976 */ pos += node - 16 + 1; /* */ } else { /* 978 */ boolean isFinal = (node & 0x1) != 0; /* 979 */ int value = readValue(bytes, pos, node >> 1); /* 980 */ if (uniqueValue != 0L) { /* 981 */ if (value != (int)(uniqueValue >> 1)) { /* 982 */ return 0L; /* */ } /* */ } else { /* 985 */ uniqueValue = value << 1 | 1L; /* */ } /* 987 */ if (isFinal) { /* 988 */ return uniqueValue; /* */ } /* 990 */ pos = skipValue(pos, node); /* */ } } } /* */ /* */ static final int kMinThreeByteDeltaLead = 240; /* */ static final int kFourByteDeltaLead = 254; /* */ static final int kFiveByteDeltaLead = 255; /* */ static final int kMaxTwoByteDelta = 12287; /* */ /* 998 */ private static void getNextBranchBytes(byte[] bytes, int pos, int length, Appendable out) { while (length > 5) { /* 999 */ pos++; /* 1000 */ getNextBranchBytes(bytes, jumpByDelta(bytes, pos), length >> 1, out); /* 1001 */ length -= (length >> 1); /* 1002 */ pos = skipDelta(bytes, pos); /* */ } /* */ do { /* 1005 */ append(out, bytes[(pos++)] & 0xFF); /* 1006 */ pos = skipValue(bytes, pos); /* 1007 */ length--; } while (length > 1); /* 1008 */ append(out, bytes[pos] & 0xFF); } /* */ /* */ static final int kMaxThreeByteDelta = 917503; /* */ /* 1012 */ private static void append(Appendable out, int c) { try { out.append((char)c); /* */ } catch (IOException e) { /* 1014 */ throw new RuntimeException(e); /* */ } /* */ } /* */ /* */ private byte[] bytes_; /* */ private int root_; /* */ private int pos_; /* */ private int remainingMatchLength_; /* */ } /* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\util\BytesTrie.class * Java compiler version: 5 (49.0) * JD-Core Version: 0.7.1 */