--- old/src/java.base/share/classes/sun/text/normalizer/CodePointMap.java 2020-01-10 13:50:49.000000000 -0800 +++ /dev/null 2020-01-10 13:50:49.000000000 -0800 @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -// (c) 2018 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html#License - -// created: 2018may10 Markus W. Scherer - -package sun.text.normalizer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Abstract map from Unicode code points (U+0000..U+10FFFF) to integer values. - * This does not implement java.util.Map. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ -public abstract class CodePointMap implements Iterable { - /** - * Selectors for how getRange() should report value ranges overlapping with surrogates. - * Most users should use NORMAL. - * - * @see #getRange - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public enum RangeOption { - /** - * getRange() enumerates all same-value ranges as stored in the map. - * Most users should use this option. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - NORMAL, - /** - * getRange() enumerates all same-value ranges as stored in the map, - * except that lead surrogates (U+D800..U+DBFF) are treated as having the - * surrogateValue, which is passed to getRange() as a separate parameter. - * The surrogateValue is not transformed via filter(). - * See {@link Character#isHighSurrogate}. - * - *

Most users should use NORMAL instead. - * - *

This option is useful for maps that map surrogate code *units* to - * special values optimized for UTF-16 string processing - * or for special error behavior for unpaired surrogates, - * but those values are not to be associated with the lead surrogate code *points*. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - FIXED_LEAD_SURROGATES, - /** - * getRange() enumerates all same-value ranges as stored in the map, - * except that all surrogates (U+D800..U+DFFF) are treated as having the - * surrogateValue, which is passed to getRange() as a separate parameter. - * The surrogateValue is not transformed via filter(). - * See {@link Character#isSurrogate}. - * - *

Most users should use NORMAL instead. - * - *

This option is useful for maps that map surrogate code *units* to - * special values optimized for UTF-16 string processing - * or for special error behavior for unpaired surrogates, - * but those values are not to be associated with the lead surrogate code *points*. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - FIXED_ALL_SURROGATES - } - - /** - * Callback function interface: Modifies a map value. - * Optionally called by getRange(). - * The modified value will be returned by the getRange() function. - * - *

Can be used to ignore some of the value bits, - * make a filter for one of several values, - * return a value index computed from the map value, etc. - * - * @see #getRange - * @see #iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public interface ValueFilter { - /** - * Modifies the map value. - * - * @param value map value - * @return modified value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public int apply(int value); - } - - /** - * Range iteration result data. - * Code points from start to end map to the same value. - * The value may have been modified by {@link ValueFilter#apply(int)}, - * or it may be the surrogateValue if a RangeOption other than "normal" was used. - * - * @see #getRange - * @see #iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public static final class Range { - private int start; - private int end; - private int value; - - /** - * Constructor. Sets start and end to -1 and value to 0. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public Range() { - start = end = -1; - value = 0; - } - - /** - * @return the start code point - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public int getStart() { return start; } - /** - * @return the (inclusive) end code point - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public int getEnd() { return end; } - /** - * @return the range value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public int getValue() { return value; } - /** - * Sets the range. When using {@link #iterator()}, - * iteration will resume after the newly set end. - * - * @param start new start code point - * @param end new end code point - * @param value new value - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public void set(int start, int end, int value) { - this.start = start; - this.end = end; - this.value = value; - } - } - - private final class RangeIterator implements Iterator { - private Range range = new Range(); - - @Override - public boolean hasNext() { - return -1 <= range.end && range.end < 0x10ffff; - } - - @Override - public Range next() { - if (getRange(range.end + 1, null, range)) { - return range; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public final void remove() { - throw new UnsupportedOperationException(); - } - } - - /** - * Iterates over code points of a string and fetches map values. - * This does not implement java.util.Iterator. - * - *

-     * void onString(CodePointMap map, CharSequence s, int start) {
-     *     CodePointMap.StringIterator iter = map.stringIterator(s, start);
-     *     while (iter.next()) {
-     *         int end = iter.getIndex();  // code point from between start and end
-     *         useValue(s, start, end, iter.getCodePoint(), iter.getValue());
-     *         start = end;
-     *     }
-     * }
-     * 
- * - *

This class is not intended for public subclassing. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public class StringIterator { - /** - * @internal - * @deprecated This API is ICU internal only. - */ - @Deprecated - protected CharSequence s; - /** - * @internal - * @deprecated This API is ICU internal only. - */ - @Deprecated - protected int sIndex; - /** - * @internal - * @deprecated This API is ICU internal only. - */ - @Deprecated - protected int c; - /** - * @internal - * @deprecated This API is ICU internal only. - */ - @Deprecated - protected int value; - - /** - * @internal - * @deprecated This API is ICU internal only. - */ - @Deprecated - protected StringIterator(CharSequence s, int sIndex) { - this.s = s; - this.sIndex = sIndex; - c = -1; - value = 0; - } - - /** - * Resets the iterator to a new string and/or a new string index. - * - * @param s string to iterate over - * @param sIndex string index where the iteration will start - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public void reset(CharSequence s, int sIndex) { - this.s = s; - this.sIndex = sIndex; - c = -1; - value = 0; - } - - /** - * Reads the next code point, post-increments the string index, - * and gets a value from the map. - * Sets an implementation-defined error value if the code point is an unpaired surrogate. - * - * @return true if the string index was not yet at the end of the string; - * otherwise the iterator did not advance - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public boolean next() { - if (sIndex >= s.length()) { - return false; - } - c = Character.codePointAt(s, sIndex); - sIndex += Character.charCount(c); - value = get(c); - return true; - } - - /** - * Reads the previous code point, pre-decrements the string index, - * and gets a value from the map. - * Sets an implementation-defined error value if the code point is an unpaired surrogate. - * - * @return true if the string index was not yet at the start of the string; - * otherwise the iterator did not advance - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public boolean previous() { - if (sIndex <= 0) { - return false; - } - c = Character.codePointBefore(s, sIndex); - sIndex -= Character.charCount(c); - value = get(c); - return true; - } - /** - * @return the string index - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public final int getIndex() { return sIndex; } - /** - * @return the code point - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public final int getCodePoint() { return c; } - /** - * @return the map value, - * or an implementation-defined error value if - * the code point is an unpaired surrogate - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public final int getValue() { return value; } - } - - /** - * Protected no-args constructor. - * - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - protected CodePointMap() { - } - - /** - * Returns the value for a code point as stored in the map, with range checking. - * Returns an implementation-defined error value if c is not in the range 0..U+10FFFF. - * - * @param c the code point - * @return the map value, - * or an implementation-defined error value if - * the code point is not in the range 0..U+10FFFF - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public abstract int get(int c); - - /** - * Sets the range object to a range of code points beginning with the start parameter. - * The range start is the same as the start input parameter - * (even if there are preceding code points that have the same value). - * The range end is the last code point such that - * all those from start to there have the same value. - * Returns false if start is not 0..U+10FFFF. - * Can be used to efficiently iterate over all same-value ranges in a map. - * (This is normally faster than iterating over code points and get()ting each value, - * but may be much slower than a data structure that stores ranges directly.) - * - *

If the {@link ValueFilter} parameter is not null, then - * the value to be delivered is passed through that filter, and the return value is the end - * of the range where all values are modified to the same actual value. - * The value is unchanged if that parameter is null. - * - *

Example: - *

-     * int start = 0;
-     * CodePointMap.Range range = new CodePointMap.Range();
-     * while (map.getRange(start, null, range)) {
-     *     int end = range.getEnd();
-     *     int value = range.getValue();
-     *     // Work with the range start..end and its value.
-     *     start = end + 1;
-     * }
-     * 
- * - * @param start range start - * @param filter an object that may modify the map data value, - * or null if the values from the map are to be used unmodified - * @param range the range object that will be set to the code point range and value - * @return true if start is 0..U+10FFFF; otherwise no new range is fetched - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public abstract boolean getRange(int start, ValueFilter filter, Range range); - - /** - * Sets the range object to a range of code points beginning with the start parameter. - * The range start is the same as the start input parameter - * (even if there are preceding code points that have the same value). - * The range end is the last code point such that - * all those from start to there have the same value. - * Returns false if start is not 0..U+10FFFF. - * - *

Same as the simpler {@link #getRange(int, ValueFilter, Range)} but optionally - * modifies the range if it overlaps with surrogate code points. - * - * @param start range start - * @param option defines whether surrogates are treated normally, - * or as having the surrogateValue; usually {@link RangeOption#NORMAL} - * @param surrogateValue value for surrogates; ignored if option=={@link RangeOption#NORMAL} - * @param filter an object that may modify the map data value, - * or null if the values from the map are to be used unmodified - * @param range the range object that will be set to the code point range and value - * @return true if start is 0..U+10FFFF; otherwise no new range is fetched - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public boolean getRange(int start, RangeOption option, int surrogateValue, - ValueFilter filter, Range range) { - assert option != null; - if (!getRange(start, filter, range)) { - return false; - } - if (option == RangeOption.NORMAL) { - return true; - } - int surrEnd = option == RangeOption.FIXED_ALL_SURROGATES ? 0xdfff : 0xdbff; - int end = range.end; - if (end < 0xd7ff || start > surrEnd) { - return true; - } - // The range overlaps with surrogates, or ends just before the first one. - if (range.value == surrogateValue) { - if (end >= surrEnd) { - // Surrogates followed by a non-surrValue range, - // or surrogates are part of a larger surrValue range. - return true; - } - } else { - if (start <= 0xd7ff) { - range.end = 0xd7ff; // Non-surrValue range ends before surrValue surrogates. - return true; - } - // Start is a surrogate with a non-surrValue code *unit* value. - // Return a surrValue code *point* range. - range.value = surrogateValue; - if (end > surrEnd) { - range.end = surrEnd; // Surrogate range ends before non-surrValue rest of range. - return true; - } - } - // See if the surrValue surrogate range can be merged with - // an immediately following range. - if (getRange(surrEnd + 1, filter, range) && range.value == surrogateValue) { - range.start = start; - return true; - } - range.start = start; - range.end = surrEnd; - range.value = surrogateValue; - return true; - } - - /** - * Convenience iterator over same-map-value code point ranges. - * Same as looping over all ranges with {@link #getRange(int, ValueFilter, Range)} - * without filtering. - * Adjacent ranges have different map values. - * - *

The iterator always returns the same Range object. - * - * @return a Range iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - @Override - public Iterator iterator() { - return new RangeIterator(); - } - - /** - * Returns an iterator (not a java.util.Iterator) over code points of a string - * for fetching map values. - * - * @param s string to iterate over - * @param sIndex string index where the iteration will start - * @return the iterator - * @draft ICU 63 - * @provisional This API might change or be removed in a future release. - */ - public StringIterator stringIterator(CharSequence s, int sIndex) { - return new StringIterator(s, sIndex); - } -} --- /dev/null 2020-01-10 13:50:49.000000000 -0800 +++ new/src/java.base/share/classes/jdk/internal/icu/util/CodePointMap.java 2020-01-10 13:50:48.000000000 -0800 @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +// (c) 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html#License + +// created: 2018may10 Markus W. Scherer + +package jdk.internal.icu.util; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Abstract map from Unicode code points (U+0000..U+10FFFF) to integer values. + * This does not implement java.util.Map. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ +public abstract class CodePointMap implements Iterable { + /** + * Selectors for how getRange() should report value ranges overlapping with surrogates. + * Most users should use NORMAL. + * + * @see #getRange + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public enum RangeOption { + /** + * getRange() enumerates all same-value ranges as stored in the map. + * Most users should use this option. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + NORMAL, + /** + * getRange() enumerates all same-value ranges as stored in the map, + * except that lead surrogates (U+D800..U+DBFF) are treated as having the + * surrogateValue, which is passed to getRange() as a separate parameter. + * The surrogateValue is not transformed via filter(). + * See {@link Character#isHighSurrogate}. + * + *

Most users should use NORMAL instead. + * + *

This option is useful for maps that map surrogate code *units* to + * special values optimized for UTF-16 string processing + * or for special error behavior for unpaired surrogates, + * but those values are not to be associated with the lead surrogate code *points*. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + FIXED_LEAD_SURROGATES, + /** + * getRange() enumerates all same-value ranges as stored in the map, + * except that all surrogates (U+D800..U+DFFF) are treated as having the + * surrogateValue, which is passed to getRange() as a separate parameter. + * The surrogateValue is not transformed via filter(). + * See {@link Character#isSurrogate}. + * + *

Most users should use NORMAL instead. + * + *

This option is useful for maps that map surrogate code *units* to + * special values optimized for UTF-16 string processing + * or for special error behavior for unpaired surrogates, + * but those values are not to be associated with the lead surrogate code *points*. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + FIXED_ALL_SURROGATES + } + + /** + * Callback function interface: Modifies a map value. + * Optionally called by getRange(). + * The modified value will be returned by the getRange() function. + * + *

Can be used to ignore some of the value bits, + * make a filter for one of several values, + * return a value index computed from the map value, etc. + * + * @see #getRange + * @see #iterator + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public interface ValueFilter { + /** + * Modifies the map value. + * + * @param value map value + * @return modified value + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public int apply(int value); + } + + /** + * Range iteration result data. + * Code points from start to end map to the same value. + * The value may have been modified by {@link ValueFilter#apply(int)}, + * or it may be the surrogateValue if a RangeOption other than "normal" was used. + * + * @see #getRange + * @see #iterator + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public static final class Range { + private int start; + private int end; + private int value; + + /** + * Constructor. Sets start and end to -1 and value to 0. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public Range() { + start = end = -1; + value = 0; + } + + /** + * @return the start code point + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public int getStart() { return start; } + /** + * @return the (inclusive) end code point + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public int getEnd() { return end; } + /** + * @return the range value + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public int getValue() { return value; } + /** + * Sets the range. When using {@link #iterator()}, + * iteration will resume after the newly set end. + * + * @param start new start code point + * @param end new end code point + * @param value new value + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public void set(int start, int end, int value) { + this.start = start; + this.end = end; + this.value = value; + } + } + + private final class RangeIterator implements Iterator { + private Range range = new Range(); + + @Override + public boolean hasNext() { + return -1 <= range.end && range.end < 0x10ffff; + } + + @Override + public Range next() { + if (getRange(range.end + 1, null, range)) { + return range; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public final void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * Iterates over code points of a string and fetches map values. + * This does not implement java.util.Iterator. + * + *

+     * void onString(CodePointMap map, CharSequence s, int start) {
+     *     CodePointMap.StringIterator iter = map.stringIterator(s, start);
+     *     while (iter.next()) {
+     *         int end = iter.getIndex();  // code point from between start and end
+     *         useValue(s, start, end, iter.getCodePoint(), iter.getValue());
+     *         start = end;
+     *     }
+     * }
+     * 
+ * + *

This class is not intended for public subclassing. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public class StringIterator { + /** + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + protected CharSequence s; + /** + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + protected int sIndex; + /** + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + protected int c; + /** + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + protected int value; + + /** + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + protected StringIterator(CharSequence s, int sIndex) { + this.s = s; + this.sIndex = sIndex; + c = -1; + value = 0; + } + + /** + * Resets the iterator to a new string and/or a new string index. + * + * @param s string to iterate over + * @param sIndex string index where the iteration will start + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public void reset(CharSequence s, int sIndex) { + this.s = s; + this.sIndex = sIndex; + c = -1; + value = 0; + } + + /** + * Reads the next code point, post-increments the string index, + * and gets a value from the map. + * Sets an implementation-defined error value if the code point is an unpaired surrogate. + * + * @return true if the string index was not yet at the end of the string; + * otherwise the iterator did not advance + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public boolean next() { + if (sIndex >= s.length()) { + return false; + } + c = Character.codePointAt(s, sIndex); + sIndex += Character.charCount(c); + value = get(c); + return true; + } + + /** + * Reads the previous code point, pre-decrements the string index, + * and gets a value from the map. + * Sets an implementation-defined error value if the code point is an unpaired surrogate. + * + * @return true if the string index was not yet at the start of the string; + * otherwise the iterator did not advance + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public boolean previous() { + if (sIndex <= 0) { + return false; + } + c = Character.codePointBefore(s, sIndex); + sIndex -= Character.charCount(c); + value = get(c); + return true; + } + /** + * @return the string index + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public final int getIndex() { return sIndex; } + /** + * @return the code point + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public final int getCodePoint() { return c; } + /** + * @return the map value, + * or an implementation-defined error value if + * the code point is an unpaired surrogate + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public final int getValue() { return value; } + } + + /** + * Protected no-args constructor. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + protected CodePointMap() { + } + + /** + * Returns the value for a code point as stored in the map, with range checking. + * Returns an implementation-defined error value if c is not in the range 0..U+10FFFF. + * + * @param c the code point + * @return the map value, + * or an implementation-defined error value if + * the code point is not in the range 0..U+10FFFF + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public abstract int get(int c); + + /** + * Sets the range object to a range of code points beginning with the start parameter. + * The range start is the same as the start input parameter + * (even if there are preceding code points that have the same value). + * The range end is the last code point such that + * all those from start to there have the same value. + * Returns false if start is not 0..U+10FFFF. + * Can be used to efficiently iterate over all same-value ranges in a map. + * (This is normally faster than iterating over code points and get()ting each value, + * but may be much slower than a data structure that stores ranges directly.) + * + *

If the {@link ValueFilter} parameter is not null, then + * the value to be delivered is passed through that filter, and the return value is the end + * of the range where all values are modified to the same actual value. + * The value is unchanged if that parameter is null. + * + *

Example: + *

+     * int start = 0;
+     * CodePointMap.Range range = new CodePointMap.Range();
+     * while (map.getRange(start, null, range)) {
+     *     int end = range.getEnd();
+     *     int value = range.getValue();
+     *     // Work with the range start..end and its value.
+     *     start = end + 1;
+     * }
+     * 
+ * + * @param start range start + * @param filter an object that may modify the map data value, + * or null if the values from the map are to be used unmodified + * @param range the range object that will be set to the code point range and value + * @return true if start is 0..U+10FFFF; otherwise no new range is fetched + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public abstract boolean getRange(int start, ValueFilter filter, Range range); + + /** + * Sets the range object to a range of code points beginning with the start parameter. + * The range start is the same as the start input parameter + * (even if there are preceding code points that have the same value). + * The range end is the last code point such that + * all those from start to there have the same value. + * Returns false if start is not 0..U+10FFFF. + * + *

Same as the simpler {@link #getRange(int, ValueFilter, Range)} but optionally + * modifies the range if it overlaps with surrogate code points. + * + * @param start range start + * @param option defines whether surrogates are treated normally, + * or as having the surrogateValue; usually {@link RangeOption#NORMAL} + * @param surrogateValue value for surrogates; ignored if option=={@link RangeOption#NORMAL} + * @param filter an object that may modify the map data value, + * or null if the values from the map are to be used unmodified + * @param range the range object that will be set to the code point range and value + * @return true if start is 0..U+10FFFF; otherwise no new range is fetched + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public boolean getRange(int start, RangeOption option, int surrogateValue, + ValueFilter filter, Range range) { + assert option != null; + if (!getRange(start, filter, range)) { + return false; + } + if (option == RangeOption.NORMAL) { + return true; + } + int surrEnd = option == RangeOption.FIXED_ALL_SURROGATES ? 0xdfff : 0xdbff; + int end = range.end; + if (end < 0xd7ff || start > surrEnd) { + return true; + } + // The range overlaps with surrogates, or ends just before the first one. + if (range.value == surrogateValue) { + if (end >= surrEnd) { + // Surrogates followed by a non-surrValue range, + // or surrogates are part of a larger surrValue range. + return true; + } + } else { + if (start <= 0xd7ff) { + range.end = 0xd7ff; // Non-surrValue range ends before surrValue surrogates. + return true; + } + // Start is a surrogate with a non-surrValue code *unit* value. + // Return a surrValue code *point* range. + range.value = surrogateValue; + if (end > surrEnd) { + range.end = surrEnd; // Surrogate range ends before non-surrValue rest of range. + return true; + } + } + // See if the surrValue surrogate range can be merged with + // an immediately following range. + if (getRange(surrEnd + 1, filter, range) && range.value == surrogateValue) { + range.start = start; + return true; + } + range.start = start; + range.end = surrEnd; + range.value = surrogateValue; + return true; + } + + /** + * Convenience iterator over same-map-value code point ranges. + * Same as looping over all ranges with {@link #getRange(int, ValueFilter, Range)} + * without filtering. + * Adjacent ranges have different map values. + * + *

The iterator always returns the same Range object. + * + * @return a Range iterator + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + @Override + public Iterator iterator() { + return new RangeIterator(); + } + + /** + * Returns an iterator (not a java.util.Iterator) over code points of a string + * for fetching map values. + * + * @param s string to iterate over + * @param sIndex string index where the iteration will start + * @return the iterator + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + */ + public StringIterator stringIterator(CharSequence s, int sIndex) { + return new StringIterator(s, sIndex); + } +}