1/* 2******************************************************************************* 3* Copyright (C) 2010-2014, International Business Machines 4* Corporation and others. All Rights Reserved. 5******************************************************************************* 6* UTF16CollationIterator.java, ported from utf16collationiterator.h/.cpp 7* 8* C++ version created on: 2010oct27 9* created by: Markus W. Scherer 10*/ 11 12package com.ibm.icu.impl.coll; 13 14/** 15 * UTF-16 collation element and character iterator. 16 * Handles normalized UTF-16 text, with length or NUL-terminated. 17 * Unnormalized text is handled by a subclass. 18 */ 19public class UTF16CollationIterator extends CollationIterator { 20 /** 21 * Partial constructor, see {@link CollationIterator#CollationIterator(CollationData)}. 22 */ 23 public UTF16CollationIterator(CollationData d) { 24 super(d); 25 } 26 27 public UTF16CollationIterator(CollationData d, boolean numeric, CharSequence s, int p) { 28 super(d, numeric); 29 seq = s; 30 start = 0; 31 pos = p; 32 limit = s.length(); 33 } 34 35 @Override 36 public boolean equals(Object other) { 37 if(!super.equals(other)) { return false; } 38 UTF16CollationIterator o = (UTF16CollationIterator)other; 39 // Compare the iterator state but not the text: Assume that the caller does that. 40 return (pos - start) == (o.pos - o.start); 41 } 42 43 @Override 44 public int hashCode() { 45 assert false : "hashCode not designed"; 46 return 42; // any arbitrary constant will do 47 } 48 49 @Override 50 public void resetToOffset(int newOffset) { 51 reset(); 52 pos = start + newOffset; 53 } 54 55 @Override 56 public int getOffset() { 57 return pos - start; 58 } 59 60 public void setText(boolean numeric, CharSequence s, int p) { 61 reset(numeric); 62 seq = s; 63 start = 0; 64 pos = p; 65 limit = s.length(); 66 } 67 68 @Override 69 public int nextCodePoint() { 70 if(pos == limit) { 71 return Collation.SENTINEL_CP; 72 } 73 char c = seq.charAt(pos++); 74 char trail; 75 if(Character.isHighSurrogate(c) && pos != limit && 76 Character.isLowSurrogate(trail = seq.charAt(pos))) { 77 ++pos; 78 return Character.toCodePoint(c, trail); 79 } else { 80 return c; 81 } 82 } 83 84 @Override 85 public int previousCodePoint() { 86 if(pos == start) { 87 return Collation.SENTINEL_CP; 88 } 89 char c = seq.charAt(--pos); 90 char lead; 91 if(Character.isLowSurrogate(c) && pos != start && 92 Character.isHighSurrogate(lead = seq.charAt(pos - 1))) { 93 --pos; 94 return Character.toCodePoint(lead, c); 95 } else { 96 return c; 97 } 98 } 99 100 @Override 101 protected long handleNextCE32() { 102 if(pos == limit) { 103 return NO_CP_AND_CE32; 104 } 105 char c = seq.charAt(pos++); 106 return makeCodePointAndCE32Pair(c, trie.getFromU16SingleLead(c)); 107 } 108 109 @Override 110 protected char handleGetTrailSurrogate() { 111 if(pos == limit) { return 0; } 112 char trail; 113 if(Character.isLowSurrogate(trail = seq.charAt(pos))) { ++pos; } 114 return trail; 115 } 116 117 /* boolean foundNULTerminator(); */ 118 119 @Override 120 protected void forwardNumCodePoints(int num) { 121 while(num > 0 && pos != limit) { 122 char c = seq.charAt(pos++); 123 --num; 124 if(Character.isHighSurrogate(c) && pos != limit && 125 Character.isLowSurrogate(seq.charAt(pos))) { 126 ++pos; 127 } 128 } 129 } 130 131 @Override 132 protected void backwardNumCodePoints(int num) { 133 while(num > 0 && pos != start) { 134 char c = seq.charAt(--pos); 135 --num; 136 if(Character.isLowSurrogate(c) && pos != start && 137 Character.isHighSurrogate(seq.charAt(pos-1))) { 138 --pos; 139 } 140 } 141 } 142 143 protected CharSequence seq; 144 protected int start; 145 protected int pos; 146 protected int limit; 147} 148