1 7 package com.ibm.icu.text; 8 9 import com.ibm.icu.lang.UCharacter; 10 import com.ibm.icu.util.ULocale; 11 12 import java.text.CharacterIterator ; 13 14 15 19 final class BreakTransliterator extends Transliterator { 20 private BreakIterator bi; 21 private String insertion; 22 private int[] boundaries = new int[50]; 23 private int boundaryCount = 0; 24 25 public BreakTransliterator(String ID, UnicodeFilter filter, BreakIterator bi, String insertion) { 26 super(ID, filter); 27 this.bi = bi; 28 this.insertion = insertion; 29 } 30 31 public BreakTransliterator(String ID, UnicodeFilter filter) { 32 this(ID, filter, null, " "); 33 } 34 35 public String getInsertion() { 36 return insertion; 37 } 38 39 public void setInsertion(String insertion) { 40 this.insertion = insertion; 41 } 42 43 public BreakIterator getBreakIterator() { 44 if (bi == null) bi = BreakIterator.getWordInstance(new ULocale("th_TH")); 47 return bi; 48 } 49 50 public void setBreakIterator(BreakIterator bi) { 51 this.bi = bi; 52 } 53 54 static final int LETTER_OR_MARK_MASK = 55 (1<<Character.UPPERCASE_LETTER) 56 | (1<<Character.LOWERCASE_LETTER) 57 | (1<<Character.TITLECASE_LETTER) 58 | (1<<Character.MODIFIER_LETTER) 59 | (1<<Character.OTHER_LETTER) 60 | (1<<Character.COMBINING_SPACING_MARK) 61 | (1<<Character.NON_SPACING_MARK) 62 | (1<<Character.ENCLOSING_MARK) 63 ; 64 protected void handleTransliterate(Replaceable text, Position pos, boolean incremental) { 65 boundaryCount = 0; 66 int boundary = 0; 67 getBreakIterator(); bi.setText(new ReplaceableCharacterIterator(text, pos.start, pos.limit, pos.start)); 69 75 77 80 for(boundary = bi.first(); boundary != BreakIterator.DONE && boundary < pos.limit; boundary = bi.next()) { 81 if (boundary == 0) continue; 82 84 int cp = UTF16.charAt(text, boundary-1); 85 int type = UCharacter.getType(cp); 86 if (((1<<type) & LETTER_OR_MARK_MASK) == 0) continue; 88 89 cp = UTF16.charAt(text, boundary); 90 type = UCharacter.getType(cp); 91 if (((1<<type) & LETTER_OR_MARK_MASK) == 0) continue; 93 94 if (boundaryCount >= boundaries.length) { int[] temp = new int[boundaries.length * 2]; 96 System.arraycopy(boundaries, 0, temp, 0, boundaries.length); 97 boundaries = temp; 98 } 99 100 boundaries[boundaryCount++] = boundary; 101 } 103 104 int delta = 0; 105 int lastBoundary = 0; 106 107 if (boundaryCount != 0) { delta = boundaryCount * insertion.length(); 109 lastBoundary = boundaries[boundaryCount-1]; 110 111 113 while (boundaryCount > 0) { 114 boundary = boundaries[--boundaryCount]; 115 text.replace(boundary, boundary, insertion); 116 } 117 } 118 119 pos.contextLimit += delta; 121 pos.limit += delta; 122 pos.start = incremental ? lastBoundary + delta : pos.limit; 123 } 124 125 126 130 static void register() { 131 Transliterator trans = new BreakTransliterator("Any-BreakInternal", null); 133 Transliterator.registerInstance(trans, false); 134 141 } 142 143 145 static final class ReplaceableCharacterIterator implements CharacterIterator 146 { 147 private Replaceable text; 148 private int begin; 149 private int end; 150 private int pos; 152 153 156 public ReplaceableCharacterIterator(Replaceable text) 157 { 158 this(text, 0); 159 } 160 161 167 public ReplaceableCharacterIterator(Replaceable text, int pos) 168 { 169 this(text, 0, text.length(), pos); 170 } 171 172 181 public ReplaceableCharacterIterator(Replaceable text, int begin, int end, int pos) { 182 if (text == null) { 183 throw new NullPointerException (); 184 } 185 this.text = text; 186 187 if (begin < 0 || begin > end || end > text.length()) { 188 throw new IllegalArgumentException ("Invalid substring range"); 189 } 190 191 if (pos < begin || pos > end) { 192 throw new IllegalArgumentException ("Invalid position"); 193 } 194 195 this.begin = begin; 196 this.end = end; 197 this.pos = pos; 198 } 199 200 208 public void setText(Replaceable text) { 209 if (text == null) { 210 throw new NullPointerException (); 211 } 212 this.text = text; 213 this.begin = 0; 214 this.end = text.length(); 215 this.pos = 0; 216 } 217 218 222 public char first() 223 { 224 pos = begin; 225 return current(); 226 } 227 228 232 public char last() 233 { 234 if (end != begin) { 235 pos = end - 1; 236 } else { 237 pos = end; 238 } 239 return current(); 240 } 241 242 246 public char setIndex(int p) 247 { 248 if (p < begin || p > end) { 249 throw new IllegalArgumentException ("Invalid index"); 250 } 251 pos = p; 252 return current(); 253 } 254 255 259 public char current() 260 { 261 if (pos >= begin && pos < end) { 262 return text.charAt(pos); 263 } 264 else { 265 return DONE; 266 } 267 } 268 269 273 public char next() 274 { 275 if (pos < end - 1) { 276 pos++; 277 return text.charAt(pos); 278 } 279 else { 280 pos = end; 281 return DONE; 282 } 283 } 284 285 289 public char previous() 290 { 291 if (pos > begin) { 292 pos--; 293 return text.charAt(pos); 294 } 295 else { 296 return DONE; 297 } 298 } 299 300 304 public int getBeginIndex() 305 { 306 return begin; 307 } 308 309 313 public int getEndIndex() 314 { 315 return end; 316 } 317 318 322 public int getIndex() 323 { 324 return pos; 325 } 326 327 333 public boolean equals(Object obj) 334 { 335 if (this == obj) { 336 return true; 337 } 338 if (!(obj instanceof ReplaceableCharacterIterator)) { 339 return false; 340 } 341 342 ReplaceableCharacterIterator that = (ReplaceableCharacterIterator) obj; 343 344 if (hashCode() != that.hashCode()) { 345 return false; 346 } 347 if (!text.equals(that.text)) { 348 return false; 349 } 350 if (pos != that.pos || begin != that.begin || end != that.end) { 351 return false; 352 } 353 return true; 354 } 355 356 360 public int hashCode() 361 { 362 return text.hashCode() ^ pos ^ begin ^ end; 363 } 364 365 369 public Object clone() 370 { 371 try { 372 ReplaceableCharacterIterator other 373 = (ReplaceableCharacterIterator) super.clone(); 374 return other; 375 } 376 catch (CloneNotSupportedException e) { 377 throw new IllegalStateException (); 378 } 379 } 380 381 } 382 383 } 384 | Popular Tags |