/*
 * Copyright (c) 2000, 2010, 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.
 */

package sun.nio.cs;

import java.nio.CharBuffer;
import java.nio.charset.CoderResult;
import java.nio.charset.MalformedInputException;
import java.nio.charset.UnmappableCharacterException;

Utility class for dealing with surrogates.
Author:Mark Reinhold, Martin Buchholz, Ulf Zibis
/** * Utility class for dealing with surrogates. * * @author Mark Reinhold * @author Martin Buchholz * @author Ulf Zibis */
public class Surrogate { private Surrogate() { } // TODO: Deprecate/remove the following redundant definitions public static final char MIN_HIGH = Character.MIN_HIGH_SURROGATE; public static final char MAX_HIGH = Character.MAX_HIGH_SURROGATE; public static final char MIN_LOW = Character.MIN_LOW_SURROGATE; public static final char MAX_LOW = Character.MAX_LOW_SURROGATE; public static final char MIN = Character.MIN_SURROGATE; public static final char MAX = Character.MAX_SURROGATE; public static final int UCS4_MIN = Character.MIN_SUPPLEMENTARY_CODE_POINT; public static final int UCS4_MAX = Character.MAX_CODE_POINT;
Tells whether or not the given value is in the high surrogate range. Use of Character.isHighSurrogate is generally preferred.
/** * Tells whether or not the given value is in the high surrogate range. * Use of {@link Character#isHighSurrogate} is generally preferred. */
public static boolean isHigh(int c) { return (MIN_HIGH <= c) && (c <= MAX_HIGH); }
Tells whether or not the given value is in the low surrogate range. Use of Character.isLowSurrogate is generally preferred.
/** * Tells whether or not the given value is in the low surrogate range. * Use of {@link Character#isLowSurrogate} is generally preferred. */
public static boolean isLow(int c) { return (MIN_LOW <= c) && (c <= MAX_LOW); }
Tells whether or not the given value is in the surrogate range. Use of Character.isSurrogate is generally preferred.
/** * Tells whether or not the given value is in the surrogate range. * Use of {@link Character#isSurrogate} is generally preferred. */
public static boolean is(int c) { return (MIN <= c) && (c <= MAX); }
Tells whether or not the given UCS-4 character must be represented as a surrogate pair in UTF-16. Use of Character.isSupplementaryCodePoint is generally preferred.
/** * Tells whether or not the given UCS-4 character must be represented as a * surrogate pair in UTF-16. * Use of {@link Character#isSupplementaryCodePoint} is generally preferred. */
public static boolean neededFor(int uc) { return Character.isSupplementaryCodePoint(uc); }
Returns the high UTF-16 surrogate for the given supplementary UCS-4 character. Use of Character.highSurrogate is generally preferred.
/** * Returns the high UTF-16 surrogate for the given supplementary UCS-4 character. * Use of {@link Character#highSurrogate} is generally preferred. */
public static char high(int uc) { assert Character.isSupplementaryCodePoint(uc); return Character.highSurrogate(uc); }
Returns the low UTF-16 surrogate for the given supplementary UCS-4 character. Use of Character.lowSurrogate is generally preferred.
/** * Returns the low UTF-16 surrogate for the given supplementary UCS-4 character. * Use of {@link Character#lowSurrogate} is generally preferred. */
public static char low(int uc) { assert Character.isSupplementaryCodePoint(uc); return Character.lowSurrogate(uc); }
Converts the given surrogate pair into a 32-bit UCS-4 character. Use of Character.toCodePoint is generally preferred.
/** * Converts the given surrogate pair into a 32-bit UCS-4 character. * Use of {@link Character#toCodePoint} is generally preferred. */
public static int toUCS4(char c, char d) { assert Character.isHighSurrogate(c) && Character.isLowSurrogate(d); return Character.toCodePoint(c, d); }
Surrogate parsing support. Charset implementations may use instances of this class to handle the details of parsing UTF-16 surrogate pairs.
/** * Surrogate parsing support. Charset implementations may use instances of * this class to handle the details of parsing UTF-16 surrogate pairs. */
public static class Parser { public Parser() { } private int character; // UCS-4 private CoderResult error = CoderResult.UNDERFLOW; private boolean isPair;
Returns the UCS-4 character previously parsed.
/** * Returns the UCS-4 character previously parsed. */
public int character() { assert (error == null); return character; }
Tells whether or not the previously-parsed UCS-4 character was originally represented by a surrogate pair.
/** * Tells whether or not the previously-parsed UCS-4 character was * originally represented by a surrogate pair. */
public boolean isPair() { assert (error == null); return isPair; }
Returns the number of UTF-16 characters consumed by the previous parse.
/** * Returns the number of UTF-16 characters consumed by the previous * parse. */
public int increment() { assert (error == null); return isPair ? 2 : 1; }
If the previous parse operation detected an error, return the object describing that error.
/** * If the previous parse operation detected an error, return the object * describing that error. */
public CoderResult error() { assert (error != null); return error; }
Returns an unmappable-input result object, with the appropriate input length, for the previously-parsed character.
/** * Returns an unmappable-input result object, with the appropriate * input length, for the previously-parsed character. */
public CoderResult unmappableResult() { assert (error == null); return CoderResult.unmappableForLength(isPair ? 2 : 1); }
Parses a UCS-4 character from the given source buffer, handling surrogates.
Params:
  • c – The first character
  • in – The source buffer, from which one more character will be consumed if c is a high surrogate
@returns Either a parsed UCS-4 character, in which case the isPair() and increment() methods will return meaningful values, or -1, in which case error() will return a descriptive result object
/** * Parses a UCS-4 character from the given source buffer, handling * surrogates. * * @param c The first character * @param in The source buffer, from which one more character * will be consumed if c is a high surrogate * * @returns Either a parsed UCS-4 character, in which case the isPair() * and increment() methods will return meaningful values, or * -1, in which case error() will return a descriptive result * object */
public int parse(char c, CharBuffer in) { if (Character.isHighSurrogate(c)) { if (!in.hasRemaining()) { error = CoderResult.UNDERFLOW; return -1; } char d = in.get(); if (Character.isLowSurrogate(d)) { character = Character.toCodePoint(c, d); isPair = true; error = null; return character; } error = CoderResult.malformedForLength(1); return -1; } if (Character.isLowSurrogate(c)) { error = CoderResult.malformedForLength(1); return -1; } character = c; isPair = false; error = null; return character; }
Parses a UCS-4 character from the given source buffer, handling surrogates.
Params:
  • c – The first character
  • ia – The input array, from which one more character will be consumed if c is a high surrogate
  • ip – The input index
  • il – The input limit
@returns Either a parsed UCS-4 character, in which case the isPair() and increment() methods will return meaningful values, or -1, in which case error() will return a descriptive result object
/** * Parses a UCS-4 character from the given source buffer, handling * surrogates. * * @param c The first character * @param ia The input array, from which one more character * will be consumed if c is a high surrogate * @param ip The input index * @param il The input limit * * @returns Either a parsed UCS-4 character, in which case the isPair() * and increment() methods will return meaningful values, or * -1, in which case error() will return a descriptive result * object */
public int parse(char c, char[] ia, int ip, int il) { assert (ia[ip] == c); if (Character.isHighSurrogate(c)) { if (il - ip < 2) { error = CoderResult.UNDERFLOW; return -1; } char d = ia[ip + 1]; if (Character.isLowSurrogate(d)) { character = Character.toCodePoint(c, d); isPair = true; error = null; return character; } error = CoderResult.malformedForLength(1); return -1; } if (Character.isLowSurrogate(c)) { error = CoderResult.malformedForLength(1); return -1; } character = c; isPair = false; error = null; return character; } }
Surrogate generation support. Charset implementations may use instances of this class to handle the details of generating UTF-16 surrogate pairs.
/** * Surrogate generation support. Charset implementations may use instances * of this class to handle the details of generating UTF-16 surrogate * pairs. */
public static class Generator { public Generator() { } private CoderResult error = CoderResult.OVERFLOW;
If the previous generation operation detected an error, return the object describing that error.
/** * If the previous generation operation detected an error, return the * object describing that error. */
public CoderResult error() { assert error != null; return error; }
Generates one or two UTF-16 characters to represent the given UCS-4 character.
Params:
  • uc – The UCS-4 character
  • len – The number of input bytes from which the UCS-4 value was constructed (used when creating result objects)
  • dst – The destination buffer, to which one or two UTF-16 characters will be written
@returns Either a positive count of the number of UTF-16 characters written to the destination buffer, or -1, in which case error() will return a descriptive result object
/** * Generates one or two UTF-16 characters to represent the given UCS-4 * character. * * @param uc The UCS-4 character * @param len The number of input bytes from which the UCS-4 value * was constructed (used when creating result objects) * @param dst The destination buffer, to which one or two UTF-16 * characters will be written * * @returns Either a positive count of the number of UTF-16 characters * written to the destination buffer, or -1, in which case * error() will return a descriptive result object */
public int generate(int uc, int len, CharBuffer dst) { if (Character.isBmpCodePoint(uc)) { char c = (char) uc; if (Character.isSurrogate(c)) { error = CoderResult.malformedForLength(len); return -1; } if (dst.remaining() < 1) { error = CoderResult.OVERFLOW; return -1; } dst.put(c); error = null; return 1; } else if (Character.isValidCodePoint(uc)) { if (dst.remaining() < 2) { error = CoderResult.OVERFLOW; return -1; } dst.put(Character.highSurrogate(uc)); dst.put(Character.lowSurrogate(uc)); error = null; return 2; } else { error = CoderResult.unmappableForLength(len); return -1; } }
Generates one or two UTF-16 characters to represent the given UCS-4 character.
Params:
  • uc – The UCS-4 character
  • len – The number of input bytes from which the UCS-4 value was constructed (used when creating result objects)
  • da – The destination array, to which one or two UTF-16 characters will be written
  • dp – The destination position
  • dl – The destination limit
@returns Either a positive count of the number of UTF-16 characters written to the destination buffer, or -1, in which case error() will return a descriptive result object
/** * Generates one or two UTF-16 characters to represent the given UCS-4 * character. * * @param uc The UCS-4 character * @param len The number of input bytes from which the UCS-4 value * was constructed (used when creating result objects) * @param da The destination array, to which one or two UTF-16 * characters will be written * @param dp The destination position * @param dl The destination limit * * @returns Either a positive count of the number of UTF-16 characters * written to the destination buffer, or -1, in which case * error() will return a descriptive result object */
public int generate(int uc, int len, char[] da, int dp, int dl) { if (Character.isBmpCodePoint(uc)) { char c = (char) uc; if (Character.isSurrogate(c)) { error = CoderResult.malformedForLength(len); return -1; } if (dl - dp < 1) { error = CoderResult.OVERFLOW; return -1; } da[dp] = c; error = null; return 1; } else if (Character.isValidCodePoint(uc)) { if (dl - dp < 2) { error = CoderResult.OVERFLOW; return -1; } da[dp] = Character.highSurrogate(uc); da[dp + 1] = Character.lowSurrogate(uc); error = null; return 2; } else { error = CoderResult.unmappableForLength(len); return -1; } } } }