| /* |
| ******************************************************************************* |
| * Copyright (C) 2010-2014, International Business Machines |
| * Corporation and others. All Rights Reserved. |
| ******************************************************************************* |
| * UTF16CollationIterator.java, ported from utf16collationiterator.h/.cpp |
| * |
| * C++ version created on: 2010oct27 |
| * created by: Markus W. Scherer |
| */ |
| |
| package com.ibm.icu.impl.coll; |
| |
| /** |
| * UTF-16 collation element and character iterator. |
| * Handles normalized UTF-16 text, with length or NUL-terminated. |
| * Unnormalized text is handled by a subclass. |
| */ |
| public class UTF16CollationIterator extends CollationIterator { |
| /** |
| * Partial constructor, see {@link CollationIterator#CollationIterator(CollationData)}. |
| */ |
| public UTF16CollationIterator(CollationData d) { |
| super(d); |
| } |
| |
| public UTF16CollationIterator(CollationData d, boolean numeric, CharSequence s, int p) { |
| super(d, numeric); |
| seq = s; |
| start = 0; |
| pos = p; |
| limit = s.length(); |
| } |
| |
| @Override |
| public boolean equals(Object other) { |
| if(!super.equals(other)) { return false; } |
| UTF16CollationIterator o = (UTF16CollationIterator)other; |
| // Compare the iterator state but not the text: Assume that the caller does that. |
| return (pos - start) == (o.pos - o.start); |
| } |
| |
| @Override |
| public int hashCode() { |
| assert false : "hashCode not designed"; |
| return 42; // any arbitrary constant will do |
| } |
| |
| @Override |
| public void resetToOffset(int newOffset) { |
| reset(); |
| pos = start + newOffset; |
| } |
| |
| @Override |
| public int getOffset() { |
| return pos - start; |
| } |
| |
| public void setText(boolean numeric, CharSequence s, int p) { |
| reset(numeric); |
| seq = s; |
| start = 0; |
| pos = p; |
| limit = s.length(); |
| } |
| |
| @Override |
| public int nextCodePoint() { |
| if(pos == limit) { |
| return Collation.SENTINEL_CP; |
| } |
| char c = seq.charAt(pos++); |
| char trail; |
| if(Character.isHighSurrogate(c) && pos != limit && |
| Character.isLowSurrogate(trail = seq.charAt(pos))) { |
| ++pos; |
| return Character.toCodePoint(c, trail); |
| } else { |
| return c; |
| } |
| } |
| |
| @Override |
| public int previousCodePoint() { |
| if(pos == start) { |
| return Collation.SENTINEL_CP; |
| } |
| char c = seq.charAt(--pos); |
| char lead; |
| if(Character.isLowSurrogate(c) && pos != start && |
| Character.isHighSurrogate(lead = seq.charAt(pos - 1))) { |
| --pos; |
| return Character.toCodePoint(lead, c); |
| } else { |
| return c; |
| } |
| } |
| |
| @Override |
| protected long handleNextCE32() { |
| if(pos == limit) { |
| return NO_CP_AND_CE32; |
| } |
| char c = seq.charAt(pos++); |
| return makeCodePointAndCE32Pair(c, trie.getFromU16SingleLead(c)); |
| } |
| |
| @Override |
| protected char handleGetTrailSurrogate() { |
| if(pos == limit) { return 0; } |
| char trail; |
| if(Character.isLowSurrogate(trail = seq.charAt(pos))) { ++pos; } |
| return trail; |
| } |
| |
| /* boolean foundNULTerminator(); */ |
| |
| @Override |
| protected void forwardNumCodePoints(int num) { |
| while(num > 0 && pos != limit) { |
| char c = seq.charAt(pos++); |
| --num; |
| if(Character.isHighSurrogate(c) && pos != limit && |
| Character.isLowSurrogate(seq.charAt(pos))) { |
| ++pos; |
| } |
| } |
| } |
| |
| @Override |
| protected void backwardNumCodePoints(int num) { |
| while(num > 0 && pos != start) { |
| char c = seq.charAt(--pos); |
| --num; |
| if(Character.isLowSurrogate(c) && pos != start && |
| Character.isHighSurrogate(seq.charAt(pos-1))) { |
| --pos; |
| } |
| } |
| } |
| |
| protected CharSequence seq; |
| protected int start; |
| protected int pos; |
| protected int limit; |
| } |