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