blob: 938b04981c310434f388d17a070c828772843d77 [file] [log] [blame]
/*
*******************************************************************************
* 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;
}