1 7 8 package com.ibm.icu.impl; 9 10 import com.ibm.icu.lang.UCharacter; 11 import com.ibm.icu.text.UTF16; 12 import com.ibm.icu.util.RangeValueIterator; 13 14 83 public class TrieIterator implements RangeValueIterator 84 85 { 86 88 94 public TrieIterator(Trie trie) 95 { 96 if (trie == null) { 97 throw new IllegalArgumentException ( 98 "Argument trie cannot be null"); 99 } 100 m_trie_ = trie; 101 m_initialValue_ = extract(m_trie_.getInitialValue()); 103 reset(); 104 } 105 106 108 119 public final boolean next(Element element) 120 { 121 if (m_nextCodepoint_ > UCharacter.MAX_VALUE) { 122 return false; 123 } 124 if (m_nextCodepoint_ < UCharacter.SUPPLEMENTARY_MIN_VALUE && 125 calculateNextBMPElement(element)) { 126 return true; 127 } 128 calculateNextSupplementaryElement(element); 129 return true; 130 } 131 132 136 public final void reset() 137 { 138 m_currentCodepoint_ = 0; 139 m_nextCodepoint_ = 0; 140 m_nextIndex_ = 0; 141 m_nextBlock_ = m_trie_.m_index_[0] << Trie.INDEX_STAGE_2_SHIFT_; 142 if (m_nextBlock_ == 0) { 143 m_nextValue_ = m_initialValue_; 144 } 145 else { 146 m_nextValue_ = extract(m_trie_.getValue(m_nextBlock_)); 147 } 148 m_nextBlockIndex_ = 0; 149 m_nextTrailIndexOffset_ = TRAIL_SURROGATE_INDEX_BLOCK_LENGTH_; 150 } 151 152 154 164 protected int extract(int value) 165 { 166 return value; 167 } 168 169 171 178 private final void setResult(Element element, int start, int limit, 179 int value) 180 { 181 element.start = start; 182 element.limit = limit; 183 element.value = value; 184 } 185 186 197 private final boolean calculateNextBMPElement(Element element) 198 { 199 int currentBlock = m_nextBlock_; 200 int currentValue = m_nextValue_; 201 m_currentCodepoint_ = m_nextCodepoint_; 202 m_nextCodepoint_ ++; 203 m_nextBlockIndex_ ++; 204 if (!checkBlockDetail(currentValue)) { 205 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 206 currentValue); 207 return true; 208 } 209 while (m_nextCodepoint_ < UCharacter.SUPPLEMENTARY_MIN_VALUE) { 212 m_nextIndex_ ++; 213 if (m_nextCodepoint_ == LEAD_SURROGATE_MIN_VALUE_) { 217 m_nextIndex_ = BMP_INDEX_LENGTH_; 220 } 221 else if (m_nextCodepoint_ == TRAIL_SURROGATE_MIN_VALUE_) { 222 m_nextIndex_ = m_nextCodepoint_ >> Trie.INDEX_STAGE_1_SHIFT_; 224 } 225 226 m_nextBlockIndex_ = 0; 227 if (!checkBlock(currentBlock, currentValue)) { 228 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 229 currentValue); 230 return true; 231 } 232 } 233 m_nextCodepoint_ --; m_nextBlockIndex_ --; return false; 236 } 237 238 256 private final void calculateNextSupplementaryElement(Element element) 257 { 258 int currentValue = m_nextValue_; 259 int currentBlock = m_nextBlock_; 260 m_nextCodepoint_ ++; 261 m_nextBlockIndex_ ++; 262 263 if (UTF16.getTrailSurrogate(m_nextCodepoint_) 264 != UTF16.TRAIL_SURROGATE_MIN_VALUE) { 265 if (!checkNullNextTrailIndex() && !checkBlockDetail(currentValue)) { 268 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 269 currentValue); 270 m_currentCodepoint_ = m_nextCodepoint_; 271 return; 272 } 273 m_nextIndex_ ++; 275 m_nextTrailIndexOffset_ ++; 276 if (!checkTrailBlock(currentBlock, currentValue)) { 277 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 278 currentValue); 279 m_currentCodepoint_ = m_nextCodepoint_; 280 return; 281 } 282 } 283 int nextLead = UTF16.getLeadSurrogate(m_nextCodepoint_); 284 while (nextLead < TRAIL_SURROGATE_MIN_VALUE_) { 286 int leadBlock = 288 m_trie_.m_index_[nextLead >> Trie.INDEX_STAGE_1_SHIFT_] << 289 Trie.INDEX_STAGE_2_SHIFT_; 290 if (leadBlock == m_trie_.m_dataOffset_) { 291 if (currentValue != m_initialValue_) { 293 m_nextValue_ = m_initialValue_; 294 m_nextBlock_ = 0; 295 m_nextBlockIndex_ = 0; 296 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 297 currentValue); 298 m_currentCodepoint_ = m_nextCodepoint_; 299 return; 300 } 301 302 nextLead += DATA_BLOCK_LENGTH_; 303 m_nextCodepoint_ = UCharacterProperty.getRawSupplementary( 309 (char)nextLead, 310 (char)UTF16.TRAIL_SURROGATE_MIN_VALUE); 311 continue; 312 } 313 if (m_trie_.m_dataManipulate_ == null) { 314 throw new NullPointerException ( 315 "The field DataManipulate in this Trie is null"); 316 } 317 m_nextIndex_ = m_trie_.m_dataManipulate_.getFoldingOffset( 319 m_trie_.getValue(leadBlock + 320 (nextLead & Trie.INDEX_STAGE_3_MASK_))); 321 if (m_nextIndex_ <= 0) { 322 if (currentValue != m_initialValue_) { 324 m_nextValue_ = m_initialValue_; 325 m_nextBlock_ = 0; 326 m_nextBlockIndex_ = 0; 327 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 328 currentValue); 329 m_currentCodepoint_ = m_nextCodepoint_; 330 return; 331 } 332 m_nextCodepoint_ += TRAIL_SURROGATE_COUNT_; 333 } else { 334 m_nextTrailIndexOffset_ = 0; 335 if (!checkTrailBlock(currentBlock, currentValue)) { 336 setResult(element, m_currentCodepoint_, m_nextCodepoint_, 337 currentValue); 338 m_currentCodepoint_ = m_nextCodepoint_; 339 return; 340 } 341 } 342 nextLead ++; 343 } 344 345 setResult(element, m_currentCodepoint_, UCharacter.MAX_VALUE + 1, 347 currentValue); 348 } 349 350 362 private final boolean checkBlockDetail(int currentValue) 363 { 364 while (m_nextBlockIndex_ < DATA_BLOCK_LENGTH_) { 365 m_nextValue_ = extract(m_trie_.getValue(m_nextBlock_ + 366 m_nextBlockIndex_)); 367 if (m_nextValue_ != currentValue) { 368 return false; 369 } 370 ++ m_nextBlockIndex_; 371 ++ m_nextCodepoint_; 372 } 373 return true; 374 } 375 376 388 private final boolean checkBlock(int currentBlock, int currentValue) 389 { 390 m_nextBlock_ = m_trie_.m_index_[m_nextIndex_] << 391 Trie.INDEX_STAGE_2_SHIFT_; 392 if (m_nextBlock_ == currentBlock && 393 (m_nextCodepoint_ - m_currentCodepoint_) >= DATA_BLOCK_LENGTH_) { 394 m_nextCodepoint_ += DATA_BLOCK_LENGTH_; 397 } 398 else if (m_nextBlock_ == 0) { 399 if (currentValue != m_initialValue_) { 401 m_nextValue_ = m_initialValue_; 402 m_nextBlockIndex_ = 0; 403 return false; 404 } 405 m_nextCodepoint_ += DATA_BLOCK_LENGTH_; 406 } 407 else { 408 if (!checkBlockDetail(currentValue)) { 409 return false; 410 } 411 } 412 return true; 413 } 414 415 427 private final boolean checkTrailBlock(int currentBlock, 428 int currentValue) 429 { 430 while (m_nextTrailIndexOffset_ < TRAIL_SURROGATE_INDEX_BLOCK_LENGTH_) 432 { 433 m_nextBlockIndex_ = 0; 435 if (!checkBlock(currentBlock, currentValue)) { 437 return false; 438 } 439 m_nextTrailIndexOffset_ ++; 440 m_nextIndex_ ++; 441 } 442 return true; 443 } 444 445 454 private final boolean checkNullNextTrailIndex() 455 { 456 if (m_nextIndex_ <= 0) { 457 m_nextCodepoint_ += TRAIL_SURROGATE_COUNT_ - 1; 458 int nextLead = UTF16.getLeadSurrogate(m_nextCodepoint_); 459 int leadBlock = 460 m_trie_.m_index_[nextLead >> Trie.INDEX_STAGE_1_SHIFT_] << 461 Trie.INDEX_STAGE_2_SHIFT_; 462 if (m_trie_.m_dataManipulate_ == null) { 463 throw new NullPointerException ( 464 "The field DataManipulate in this Trie is null"); 465 } 466 m_nextIndex_ = m_trie_.m_dataManipulate_.getFoldingOffset( 467 m_trie_.getValue(leadBlock + 468 (nextLead & Trie.INDEX_STAGE_3_MASK_))); 469 m_nextIndex_ --; 470 m_nextBlockIndex_ = DATA_BLOCK_LENGTH_; 471 return true; 472 } 473 return false; 474 } 475 476 478 481 private static final int BMP_INDEX_LENGTH_ = 482 0x10000 >> Trie.INDEX_STAGE_1_SHIFT_; 483 486 private static final int LEAD_SURROGATE_MIN_VALUE_ = 0xD800; 487 490 private static final int TRAIL_SURROGATE_MIN_VALUE_ = 0xDC00; 491 494 private static final int TRAIL_SURROGATE_MAX_VALUE_ = 0xDFFF; 495 498 private static final int TRAIL_SURROGATE_COUNT_ = 0x400; 499 506 private static final int TRAIL_SURROGATE_INDEX_BLOCK_LENGTH_ = 507 1 << (10 - Trie.INDEX_STAGE_1_SHIFT_); 508 511 private static final int DATA_BLOCK_LENGTH_ = 512 1 << Trie.INDEX_STAGE_1_SHIFT_; 513 516 private static final int DATA_BLOCK_SUPPLEMENTARY_LENGTH_ = 517 DATA_BLOCK_LENGTH_ << 10; 518 521 private Trie m_trie_; 522 525 private int m_initialValue_; 526 529 private int m_currentCodepoint_; 530 private int m_nextCodepoint_; 531 private int m_nextValue_; 532 private int m_nextIndex_; 533 private int m_nextBlock_; 534 private int m_nextBlockIndex_; 535 private int m_nextTrailIndexOffset_; 536 539 private int m_start_; 540 private int m_limit_; 541 private int m_value_; 542 } 543 | Popular Tags |