UTF16.java 8.86 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.agl.text;

import com.adobe.agl.impl.UCharacterProperty;

public final class UTF16 {
    private UTF16() {
    }

    public static int charAt(String source, int offset16) {
        char single = source.charAt(offset16);
        if (single < '\ud800') {
            return single;
        }
        return UTF16._charAt(source, offset16, single);
    }

    private static int _charAt(String source, int offset16, char single) {
        char lead;
        if (single > '\udfff') {
            return single;
        }
        if (single <= '\udbff') {
            char trail;
            if (source.length() != ++offset16 && (trail = source.charAt(offset16)) >= '\udc00' && trail <= '\udfff') {
                return UCharacterProperty.getRawSupplementary(single, trail);
            }
        } else if (--offset16 >= 0 && (lead = source.charAt(offset16)) >= '\ud800' && lead <= '\udbff') {
            return UCharacterProperty.getRawSupplementary(lead, single);
        }
        return single;
    }

    public static int charAt(StringBuffer source, int offset16) {
        char lead;
        if (offset16 < 0 || offset16 >= source.length()) {
            throw new StringIndexOutOfBoundsException(offset16);
        }
        char single = source.charAt(offset16);
        if (!UTF16.isSurrogate(single)) {
            return single;
        }
        if (single <= '\udbff') {
            char trail;
            if (source.length() != ++offset16 && UTF16.isTrailSurrogate(trail = source.charAt(offset16))) {
                return UCharacterProperty.getRawSupplementary(single, trail);
            }
        } else if (--offset16 >= 0 && UTF16.isLeadSurrogate(lead = source.charAt(offset16))) {
            return UCharacterProperty.getRawSupplementary(lead, single);
        }
        return single;
    }

    public static int charAt(char[] source, int start, int limit, int offset16) {
        if ((offset16 += start) < start || offset16 >= limit) {
            throw new ArrayIndexOutOfBoundsException(offset16);
        }
        char single = source[offset16];
        if (!UTF16.isSurrogate(single)) {
            return single;
        }
        if (single <= '\udbff') {
            if (++offset16 >= limit) {
                return single;
            }
            char trail = source[offset16];
            if (UTF16.isTrailSurrogate(trail)) {
                return UCharacterProperty.getRawSupplementary(single, trail);
            }
        } else {
            char lead;
            if (offset16 == start) {
                return single;
            }
            if (UTF16.isLeadSurrogate(lead = source[--offset16])) {
                return UCharacterProperty.getRawSupplementary(lead, single);
            }
        }
        return single;
    }

    public static int getCharCount(int char32) {
        if (char32 < 65536) {
            return 1;
        }
        return 2;
    }

    public static int bounds(String source, int offset16) {
        char ch = source.charAt(offset16);
        if (UTF16.isSurrogate(ch)) {
            if (UTF16.isLeadSurrogate(ch)) {
                if (++offset16 < source.length() && UTF16.isTrailSurrogate(source.charAt(offset16))) {
                    return 2;
                }
            } else if (--offset16 >= 0 && UTF16.isLeadSurrogate(source.charAt(offset16))) {
                return 5;
            }
        }
        return 1;
    }

    public static boolean isSurrogate(char char16) {
        return (char16 & -2048) == 55296;
    }

    public static boolean isTrailSurrogate(char char16) {
        return (char16 & -1024) == 56320;
    }

    public static boolean isLeadSurrogate(char char16) {
        return (char16 & -1024) == 55296;
    }

    public static char getLeadSurrogate(int char32) {
        if (char32 >= 65536) {
            return (char)(55232 + (char32 >> 10));
        }
        return '\u0000';
    }

    public static char getTrailSurrogate(int char32) {
        if (char32 >= 65536) {
            return (char)(56320 + (char32 & 1023));
        }
        return (char)char32;
    }

    public static String valueOf(int char32) {
        if (char32 < 0 || char32 > 1114111) {
            throw new IllegalArgumentException("Illegal codepoint");
        }
        return UTF16.toString(char32);
    }

    public static String valueOf(String source, int offset16) {
        switch (UTF16.bounds(source, offset16)) {
            case 2: {
                return source.substring(offset16, offset16 + 2);
            }
            case 5: {
                return source.substring(offset16 - 1, offset16 + 1);
            }
        }
        return source.substring(offset16, offset16 + 1);
    }

    public static int findOffsetFromCodePoint(String source, int offset32) {
        int count;
        int size = source.length();
        int result = 0;
        if (offset32 < 0 || offset32 > size) {
            throw new StringIndexOutOfBoundsException(offset32);
        }
        for (count = offset32; result < size && count > 0; --count, ++result) {
            char ch = source.charAt(result);
            if (!UTF16.isLeadSurrogate(ch) || result + 1 >= size || !UTF16.isTrailSurrogate(source.charAt(result + 1))) continue;
            ++result;
        }
        if (count != 0) {
            throw new StringIndexOutOfBoundsException(offset32);
        }
        return result;
    }

    public static int findCodePointOffset(String source, int offset16) {
        if (offset16 < 0 || offset16 > source.length()) {
            throw new StringIndexOutOfBoundsException(offset16);
        }
        int result = 0;
        boolean hadLeadSurrogate = false;
        for (int i = 0; i < offset16; ++i) {
            char ch = source.charAt(i);
            if (hadLeadSurrogate && UTF16.isTrailSurrogate(ch)) {
                hadLeadSurrogate = false;
                continue;
            }
            hadLeadSurrogate = UTF16.isLeadSurrogate(ch);
            ++result;
        }
        if (offset16 == source.length()) {
            return result;
        }
        if (hadLeadSurrogate && UTF16.isTrailSurrogate(source.charAt(offset16))) {
            --result;
        }
        return result;
    }

    public static StringBuffer append(StringBuffer target, int char32) {
        if (char32 < 0 || char32 > 1114111) {
            throw new IllegalArgumentException("Illegal codepoint: " + Integer.toHexString(char32));
        }
        if (char32 >= 65536) {
            target.append(UTF16.getLeadSurrogate(char32));
            target.append(UTF16.getTrailSurrogate(char32));
        } else {
            target.append((char)char32);
        }
        return target;
    }

    public static int append(char[] target, int limit, int char32) {
        if (char32 < 0 || char32 > 1114111) {
            throw new IllegalArgumentException("Illegal codepoint");
        }
        if (char32 >= 65536) {
            target[limit++] = UTF16.getLeadSurrogate(char32);
            target[limit++] = UTF16.getTrailSurrogate(char32);
        } else {
            target[limit++] = (char)char32;
        }
        return limit;
    }

    public static int countCodePoint(String source) {
        if (source == null || source.length() == 0) {
            return 0;
        }
        return UTF16.findCodePointOffset(source, source.length());
    }

    public static int moveCodePointOffset(String source, int offset16, int shift32) {
        int count;
        int result = offset16;
        int size = source.length();
        if (offset16 < 0 || offset16 > size) {
            throw new StringIndexOutOfBoundsException(offset16);
        }
        if (shift32 > 0) {
            if (shift32 + offset16 > size) {
                throw new StringIndexOutOfBoundsException(offset16);
            }
            for (count = shift32; result < size && count > 0; --count, ++result) {
                char ch = source.charAt(result);
                if (!UTF16.isLeadSurrogate(ch) || result + 1 >= size || !UTF16.isTrailSurrogate(source.charAt(result + 1))) continue;
                ++result;
            }
        } else {
            if (offset16 + shift32 < 0) {
                throw new StringIndexOutOfBoundsException(offset16);
            }
            for (count = - shift32; count > 0 && --result >= 0; --count) {
                char ch = source.charAt(result);
                if (!UTF16.isTrailSurrogate(ch) || result <= 0 || !UTF16.isLeadSurrogate(source.charAt(result - 1))) continue;
                --result;
            }
        }
        if (count != 0) {
            throw new StringIndexOutOfBoundsException(shift32);
        }
        return result;
    }

    private static String toString(int ch) {
        if (ch < 65536) {
            return String.valueOf((char)ch);
        }
        StringBuffer result = new StringBuffer();
        result.append(UTF16.getLeadSurrogate(ch));
        result.append(UTF16.getTrailSurrogate(ch));
        return result.toString();
    }
}