/* */ package com.ibm.icu.impl; /* */ /* */ import com.ibm.icu.text.UTF16; /* */ import java.io.DataOutputStream; /* */ import java.io.IOException; /* */ import java.io.OutputStream; /* */ import java.util.Arrays; /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public class IntTrieBuilder /* */ extends TrieBuilder /* */ { /* */ protected int[] m_data_; /* */ protected int m_initialValue_; /* */ private int m_leadUnitValue_; /* */ /* */ public IntTrieBuilder(IntTrieBuilder table) /* */ { /* 44 */ super(table); /* 45 */ this.m_data_ = new int[this.m_dataCapacity_]; /* 46 */ System.arraycopy(table.m_data_, 0, this.m_data_, 0, this.m_dataLength_); /* 47 */ this.m_initialValue_ = table.m_initialValue_; /* 48 */ this.m_leadUnitValue_ = table.m_leadUnitValue_; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public IntTrieBuilder(int[] aliasdata, int maxdatalength, int initialvalue, int leadunitvalue, boolean latin1linear) /* */ { /* 63 */ if ((maxdatalength < 32) || ((latin1linear) && (maxdatalength < 1024))) /* */ { /* 65 */ throw new IllegalArgumentException("Argument maxdatalength is too small"); /* */ } /* */ /* */ /* 69 */ if (aliasdata != null) { /* 70 */ this.m_data_ = aliasdata; /* */ } /* */ else { /* 73 */ this.m_data_ = new int[maxdatalength]; /* */ } /* */ /* */ /* 77 */ int j = 32; /* */ /* 79 */ if (latin1linear) /* */ { /* */ /* */ /* */ /* 84 */ int i = 0; /* */ /* */ do /* */ { /* 88 */ this.m_index_[(i++)] = j; /* 89 */ j += 32; /* 90 */ } while (i < 8); /* */ } /* */ /* 93 */ this.m_dataLength_ = j; /* */ /* 95 */ Arrays.fill(this.m_data_, 0, this.m_dataLength_, initialvalue); /* 96 */ this.m_initialValue_ = initialvalue; /* 97 */ this.m_leadUnitValue_ = leadunitvalue; /* 98 */ this.m_dataCapacity_ = maxdatalength; /* 99 */ this.m_isLatin1Linear_ = latin1linear; /* 100 */ this.m_isCompacted_ = false; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public int getValue(int ch) /* */ { /* 171 */ if ((this.m_isCompacted_) || (ch > 1114111) || (ch < 0)) { /* 172 */ return 0; /* */ } /* */ /* 175 */ int block = this.m_index_[(ch >> 5)]; /* 176 */ return this.m_data_[(Math.abs(block) + (ch & 0x1F))]; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public int getValue(int ch, boolean[] inBlockZero) /* */ { /* 189 */ if ((this.m_isCompacted_) || (ch > 1114111) || (ch < 0)) { /* 190 */ if (inBlockZero != null) { /* 191 */ inBlockZero[0] = true; /* */ } /* 193 */ return 0; /* */ } /* */ /* 196 */ int block = this.m_index_[(ch >> 5)]; /* 197 */ if (inBlockZero != null) { /* 198 */ inBlockZero[0] = (block == 0 ? 1 : false); /* */ } /* 200 */ return this.m_data_[(Math.abs(block) + (ch & 0x1F))]; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public boolean setValue(int ch, int value) /* */ { /* 214 */ if ((this.m_isCompacted_) || (ch > 1114111) || (ch < 0)) { /* 215 */ return false; /* */ } /* */ /* 218 */ int block = getDataBlock(ch); /* 219 */ if (block < 0) { /* 220 */ return false; /* */ } /* */ /* 223 */ this.m_data_[(block + (ch & 0x1F))] = value; /* 224 */ return true; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public IntTrie serialize(TrieBuilder.DataManipulate datamanipulate, Trie.DataManipulate triedatamanipulate) /* */ { /* 236 */ if (datamanipulate == null) { /* 237 */ throw new IllegalArgumentException("Parameters can not be null"); /* */ } /* */ /* */ /* 241 */ if (!this.m_isCompacted_) /* */ { /* 243 */ compact(false); /* */ /* 245 */ fold(datamanipulate); /* */ /* 247 */ compact(true); /* 248 */ this.m_isCompacted_ = true; /* */ } /* */ /* 251 */ if (this.m_dataLength_ >= 262144) { /* 252 */ throw new ArrayIndexOutOfBoundsException("Data length too small"); /* */ } /* */ /* 255 */ char[] index = new char[this.m_indexLength_]; /* 256 */ int[] data = new int[this.m_dataLength_]; /* */ /* */ /* 259 */ for (int i = 0; i < this.m_indexLength_; i++) { /* 260 */ index[i] = ((char)(this.m_index_[i] >>> 2)); /* */ } /* */ /* 263 */ System.arraycopy(this.m_data_, 0, data, 0, this.m_dataLength_); /* */ /* 265 */ int options = 37; /* 266 */ options |= 0x100; /* 267 */ if (this.m_isLatin1Linear_) { /* 268 */ options |= 0x200; /* */ } /* 270 */ return new IntTrie(index, data, this.m_initialValue_, options, triedatamanipulate); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public int serialize(OutputStream os, boolean reduceTo16Bits, TrieBuilder.DataManipulate datamanipulate) /* */ throws IOException /* */ { /* 295 */ if (datamanipulate == null) { /* 296 */ throw new IllegalArgumentException("Parameters can not be null"); /* */ } /* */ /* */ /* */ /* 301 */ if (!this.m_isCompacted_) /* */ { /* 303 */ compact(false); /* */ /* 305 */ fold(datamanipulate); /* */ /* 307 */ compact(true); /* 308 */ this.m_isCompacted_ = true; /* */ } /* */ /* */ int length; /* */ /* 313 */ if (reduceTo16Bits) { /* 314 */ length = this.m_dataLength_ + this.m_indexLength_; /* */ } else { /* 316 */ length = this.m_dataLength_; /* */ } /* 318 */ if (length >= 262144) { /* 319 */ throw new ArrayIndexOutOfBoundsException("Data length too small"); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* 327 */ int length = 16 + 2 * this.m_indexLength_; /* 328 */ if (reduceTo16Bits) { /* 329 */ length += 2 * this.m_dataLength_; /* */ } else { /* 331 */ length += 4 * this.m_dataLength_; /* */ } /* */ /* 334 */ if (os == null) /* */ { /* 336 */ return length; /* */ } /* */ /* 339 */ DataOutputStream dos = new DataOutputStream(os); /* 340 */ dos.writeInt(1416784229); /* */ /* 342 */ int options = 37; /* 343 */ if (!reduceTo16Bits) { /* 344 */ options |= 0x100; /* */ } /* 346 */ if (this.m_isLatin1Linear_) { /* 347 */ options |= 0x200; /* */ } /* 349 */ dos.writeInt(options); /* */ /* 351 */ dos.writeInt(this.m_indexLength_); /* 352 */ dos.writeInt(this.m_dataLength_); /* */ /* */ /* 355 */ if (reduceTo16Bits) /* */ { /* 357 */ for (int i = 0; i < this.m_indexLength_; i++) { /* 358 */ int v = this.m_index_[i] + this.m_indexLength_ >>> 2; /* 359 */ dos.writeChar(v); /* */ } /* */ /* */ /* 363 */ for (int i = 0; i < this.m_dataLength_; i++) { /* 364 */ int v = this.m_data_[i] & 0xFFFF; /* 365 */ dos.writeChar(v); /* */ } /* */ } /* */ else { /* 369 */ for (int i = 0; i < this.m_indexLength_; i++) { /* 370 */ int v = this.m_index_[i] >>> 2; /* 371 */ dos.writeChar(v); /* */ } /* */ /* */ /* 375 */ for (int i = 0; i < this.m_dataLength_; i++) { /* 376 */ dos.writeInt(this.m_data_[i]); /* */ } /* */ } /* */ /* 380 */ return length; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public boolean setRange(int start, int limit, int value, boolean overwrite) /* */ { /* 405 */ if ((this.m_isCompacted_) || (start < 0) || (start > 1114111) || (limit < 0) || (limit > 1114112) || (start > limit)) /* */ { /* */ /* 408 */ return false; /* */ } /* */ /* 411 */ if (start == limit) { /* 412 */ return true; /* */ } /* */ /* 415 */ if ((start & 0x1F) != 0) /* */ { /* 417 */ int block = getDataBlock(start); /* 418 */ if (block < 0) { /* 419 */ return false; /* */ } /* */ /* 422 */ int nextStart = start + 32 & 0xFFFFFFE0; /* 423 */ if (nextStart <= limit) { /* 424 */ fillBlock(block, start & 0x1F, 32, value, overwrite); /* */ /* 426 */ start = nextStart; /* */ } /* */ else { /* 429 */ fillBlock(block, start & 0x1F, limit & 0x1F, value, overwrite); /* */ /* 431 */ return true; /* */ } /* */ } /* */ /* */ /* 436 */ int rest = limit & 0x1F; /* */ /* */ /* 439 */ limit &= 0xFFFFFFE0; /* */ /* */ /* 442 */ int repeatBlock = 0; /* 443 */ if (value != this.m_initialValue_) /* */ { /* */ /* */ /* 447 */ repeatBlock = -1; /* */ } /* 449 */ while (start < limit) /* */ { /* 451 */ int block = this.m_index_[(start >> 5)]; /* 452 */ if (block > 0) /* */ { /* 454 */ fillBlock(block, 0, 32, value, overwrite); /* */ } /* 456 */ else if ((this.m_data_[(-block)] != value) && ((block == 0) || (overwrite))) /* */ { /* */ /* 459 */ if (repeatBlock >= 0) { /* 460 */ this.m_index_[(start >> 5)] = (-repeatBlock); /* */ } /* */ else /* */ { /* 464 */ repeatBlock = getDataBlock(start); /* 465 */ if (repeatBlock < 0) { /* 466 */ return false; /* */ } /* */ /* */ /* */ /* 471 */ this.m_index_[(start >> 5)] = (-repeatBlock); /* 472 */ fillBlock(repeatBlock, 0, 32, value, true); /* */ } /* */ } /* */ /* 476 */ start += 32; /* */ } /* */ /* 479 */ if (rest > 0) /* */ { /* 481 */ int block = getDataBlock(start); /* 482 */ if (block < 0) { /* 483 */ return false; /* */ } /* 485 */ fillBlock(block, 0, rest, value, overwrite); /* */ } /* */ /* 488 */ return true; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ private int allocDataBlock() /* */ { /* 504 */ int newBlock = this.m_dataLength_; /* 505 */ int newTop = newBlock + 32; /* 506 */ if (newTop > this.m_dataCapacity_) /* */ { /* 508 */ return -1; /* */ } /* 510 */ this.m_dataLength_ = newTop; /* 511 */ return newBlock; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ private int getDataBlock(int ch) /* */ { /* 521 */ ch >>= 5; /* 522 */ int indexValue = this.m_index_[ch]; /* 523 */ if (indexValue > 0) { /* 524 */ return indexValue; /* */ } /* */ /* */ /* 528 */ int newBlock = allocDataBlock(); /* 529 */ if (newBlock < 0) /* */ { /* 531 */ return -1; /* */ } /* 533 */ this.m_index_[ch] = newBlock; /* */ /* */ /* 536 */ System.arraycopy(this.m_data_, Math.abs(indexValue), this.m_data_, newBlock, 128); /* */ /* 538 */ return newBlock; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ private void compact(boolean overlap) /* */ { /* 555 */ if (this.m_isCompacted_) { /* 556 */ return; /* */ } /* */ /* */ /* */ /* 561 */ findUnusedBlocks(); /* */ /* */ /* */ /* 565 */ int overlapStart = 32; /* 566 */ if (this.m_isLatin1Linear_) { /* 567 */ overlapStart += 256; /* */ } /* */ /* 570 */ int newStart = 32; /* */ /* 572 */ for (int start = newStart; start < this.m_dataLength_;) /* */ { /* */ /* */ /* */ /* 577 */ if (this.m_map_[(start >>> 5)] < 0) /* */ { /* 579 */ start += 32; /* */ /* */ } /* */ else /* */ { /* 584 */ if (start >= overlapStart) { /* 585 */ int i = findSameDataBlock(this.m_data_, newStart, start, overlap ? 4 : 32); /* */ /* 587 */ if (i >= 0) /* */ { /* */ /* 590 */ this.m_map_[(start >>> 5)] = i; /* */ /* 592 */ start += 32; /* */ /* 594 */ continue; /* */ } /* */ } /* */ /* */ int i; /* 599 */ if ((overlap) && (start >= overlapStart)) /* */ { /* 601 */ i = 28; } /* 602 */ int i; while ((i > 0) && (!equal_int(this.m_data_, newStart - i, start, i))) { /* 603 */ i -= 4; continue; /* */ /* 605 */ i = 0; /* */ } /* 607 */ if (i > 0) /* */ { /* 609 */ this.m_map_[(start >>> 5)] = (newStart - i); /* */ /* 611 */ start += i; /* 612 */ for (i = 32 - i; i > 0; i--) { /* 613 */ this.m_data_[(newStart++)] = this.m_data_[(start++)]; /* */ } /* */ } /* 616 */ else if (newStart < start) /* */ { /* 618 */ this.m_map_[(start >>> 5)] = newStart; /* 619 */ for (i = 32; i > 0; i--) { /* 620 */ this.m_data_[(newStart++)] = this.m_data_[(start++)]; /* */ } /* */ } /* */ else { /* 624 */ this.m_map_[(start >>> 5)] = start; /* 625 */ newStart += 32; /* 626 */ start = newStart; /* */ } /* */ } /* */ } /* 630 */ for (int i = 0; i < this.m_indexLength_; i++) { /* 631 */ this.m_index_[i] = this.m_map_[(Math.abs(this.m_index_[i]) >>> 5)]; /* */ } /* 633 */ this.m_dataLength_ = newStart; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ private static final int findSameDataBlock(int[] data, int dataLength, int otherBlock, int step) /* */ { /* */ /* */ /* */ /* */ /* */ /* */ /* 649 */ for (int block = 0; block <= dataLength; block += step) { /* 650 */ if (equal_int(data, block, otherBlock, 32)) { /* 651 */ return block; /* */ } /* */ } /* 654 */ return -1; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ private final void fold(TrieBuilder.DataManipulate manipulate) /* */ { /* 670 */ int[] leadIndexes = new int[32]; /* 671 */ int[] index = this.m_index_; /* */ /* 673 */ System.arraycopy(index, 1728, leadIndexes, 0, 32); /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 683 */ int block = 0; /* 684 */ if (this.m_leadUnitValue_ != this.m_initialValue_) /* */ { /* */ /* */ /* */ /* */ /* 690 */ block = allocDataBlock(); /* 691 */ if (block < 0) /* */ { /* 693 */ throw new IllegalStateException("Internal error: Out of memory space"); /* */ } /* 695 */ fillBlock(block, 0, 32, this.m_leadUnitValue_, true); /* */ /* 697 */ block = -block; /* */ } /* 699 */ for (int c = 1728; c < 1760; c++) { /* 700 */ this.m_index_[c] = block; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 710 */ int indexLength = 2048; /* */ /* 712 */ for (int c = 65536; c < 1114112;) { /* 713 */ if (index[(c >> 5)] != 0) /* */ { /* 715 */ c &= 0xFC00; /* */ /* 717 */ block = findSameIndexBlock(index, indexLength, c >> 5); /* */ /* */ /* */ /* */ /* */ /* 723 */ int value = manipulate.getFoldedValue(c, block + 32); /* */ /* 725 */ if (value != getValue(UTF16.getLeadSurrogate(c))) { /* 726 */ if (!setValue(UTF16.getLeadSurrogate(c), value)) /* */ { /* 728 */ throw new ArrayIndexOutOfBoundsException("Data table overflow"); /* */ } /* */ /* */ /* 732 */ if (block == indexLength) /* */ { /* */ /* 735 */ System.arraycopy(index, c >> 5, index, indexLength, 32); /* */ /* 737 */ indexLength += 32; /* */ } /* */ } /* 740 */ c += 1024; /* */ } /* */ else { /* 743 */ c += 32; /* */ } /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* 755 */ if (indexLength >= 34816) { /* 756 */ throw new ArrayIndexOutOfBoundsException("Index table overflow"); /* */ } /* */ /* */ /* 760 */ System.arraycopy(index, 2048, index, 2080, indexLength - 2048); /* */ /* */ /* 763 */ System.arraycopy(leadIndexes, 0, index, 2048, 32); /* */ /* 765 */ indexLength += 32; /* 766 */ this.m_indexLength_ = indexLength; /* */ } /* */ /* */ /* */ /* */ /* */ /* */ private void fillBlock(int block, int start, int limit, int value, boolean overwrite) /* */ { /* 775 */ limit += block; /* 776 */ block += start; /* 777 */ if (overwrite) { /* 778 */ while (block < limit) { /* 779 */ this.m_data_[(block++)] = value; /* */ } /* */ } /* */ /* 783 */ while (block < limit) { /* 784 */ if (this.m_data_[block] == this.m_initialValue_) { /* 785 */ this.m_data_[block] = value; /* */ } /* 787 */ block++; /* */ } /* */ } /* */ } /* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\impl\IntTrieBuilder.class * Java compiler version: 5 (49.0) * JD-Core Version: 0.7.1 */