1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2013, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package android.icu.impl; 11 12 import java.text.CharacterIterator; 13 14 import android.icu.text.UTF16; 15 16 /** 17 * @hide Only a subset of ICU is exposed in Android 18 */ 19 public final class CharacterIteration { 20 // disallow instantiation 21 private CharacterIteration() { } 22 23 // 32 bit Char value returned from when an iterator has run out of range. 24 // Positive value so fast case (not end, not surrogate) can be checked 25 // with a single test. 26 public static final int DONE32 = 0x7fffffff; 27 28 /** 29 * Move the iterator forward to the next code point, and return that code point, 30 * leaving the iterator positioned at char returned. 31 * For Supplementary chars, the iterator is left positioned at the lead surrogate. 32 * @param ci The character iterator 33 * @return The next code point. 34 */ 35 public static int next32(CharacterIterator ci) { 36 // If the current position is at a surrogate pair, move to the trail surrogate 37 // which leaves it in position for underlying iterator's next() to work. 38 int c = ci.current(); 39 if (c >= UTF16.LEAD_SURROGATE_MIN_VALUE && c<=UTF16.LEAD_SURROGATE_MAX_VALUE) { 40 c = ci.next(); 41 if (c<UTF16.TRAIL_SURROGATE_MIN_VALUE || c>UTF16.TRAIL_SURROGATE_MAX_VALUE) { 42 ci.previous(); 43 } 44 } 45 46 // For BMP chars, this next() is the real deal. 47 c = ci.next(); 48 49 // If we might have a lead surrogate, we need to peak ahead to get the trail 50 // even though we don't want to really be positioned there. 51 if (c >= UTF16.LEAD_SURROGATE_MIN_VALUE) { 52 c = nextTrail32(ci, c); 53 } 54 55 if (c >= UTF16.SUPPLEMENTARY_MIN_VALUE && c != DONE32) { 56 // We got a supplementary char. Back the iterator up to the postion 57 // of the lead surrogate. 58 ci.previous(); 59 } 60 return c; 61 } 62 63 64 // Out-of-line portion of the in-line Next32 code. 65 // The call site does an initial ci.next() and calls this function 66 // if the 16 bit value it gets is >= LEAD_SURROGATE_MIN_VALUE. 67 // NOTE: we leave the underlying char iterator positioned in the 68 // middle of a surrogate pair. ci.next() will work correctly 69 // from there, but the ci.getIndex() will be wrong, and needs 70 // adjustment. 71 public static int nextTrail32(CharacterIterator ci, int lead) { 72 if (lead == CharacterIterator.DONE && ci.getIndex() >= ci.getEndIndex()) { 73 return DONE32; 74 } 75 int retVal = lead; 76 if (lead <= UTF16.LEAD_SURROGATE_MAX_VALUE) { 77 char cTrail = ci.next(); 78 if (UTF16.isTrailSurrogate(cTrail)) { 79 retVal = ((lead - UTF16.LEAD_SURROGATE_MIN_VALUE) << 10) + 80 (cTrail - UTF16.TRAIL_SURROGATE_MIN_VALUE) + 81 UTF16.SUPPLEMENTARY_MIN_VALUE; 82 } else { 83 ci.previous(); 84 } 85 } 86 return retVal; 87 } 88 89 public static int previous32(CharacterIterator ci) { 90 if (ci.getIndex() <= ci.getBeginIndex()) { 91 return DONE32; 92 } 93 char trail = ci.previous(); 94 int retVal = trail; 95 if (UTF16.isTrailSurrogate(trail) && ci.getIndex()>ci.getBeginIndex()) { 96 char lead = ci.previous(); 97 if (UTF16.isLeadSurrogate(lead)) { 98 retVal = (((int)lead - UTF16.LEAD_SURROGATE_MIN_VALUE) << 10) + 99 ((int)trail - UTF16.TRAIL_SURROGATE_MIN_VALUE) + 100 UTF16.SUPPLEMENTARY_MIN_VALUE; 101 } else { 102 ci.next(); 103 } 104 } 105 return retVal; 106 } 107 108 public static int current32(CharacterIterator ci) { 109 char lead = ci.current(); 110 int retVal = lead; 111 if (retVal < UTF16.LEAD_SURROGATE_MIN_VALUE) { 112 return retVal; 113 } 114 if (UTF16.isLeadSurrogate(lead)) { 115 int trail = (int)ci.next(); 116 ci.previous(); 117 if (UTF16.isTrailSurrogate((char)trail)) { 118 retVal = ((lead - UTF16.LEAD_SURROGATE_MIN_VALUE) << 10) + 119 (trail - UTF16.TRAIL_SURROGATE_MIN_VALUE) + 120 UTF16.SUPPLEMENTARY_MIN_VALUE; 121 } 122 } else { 123 if (lead == CharacterIterator.DONE) { 124 if (ci.getIndex() >= ci.getEndIndex()) { 125 retVal = DONE32; 126 } 127 } 128 } 129 return retVal; 130 } 131 } 132