UBiDiProps.java 5.41 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.agl.impl;

import com.adobe.agl.impl.CharTrie;
import com.adobe.agl.impl.ICUBinary;
import com.adobe.agl.impl.ICUData;
import com.adobe.agl.impl.TrieIterator;
import com.adobe.agl.text.UnicodeSet;
import com.adobe.agl.util.RangeValueIterator;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

public final class UBiDiProps {
    private static UBiDiProps gBdp = null;
    private static UBiDiProps gBdpDummy = null;
    private int[] indexes;
    private int[] mirrors;
    private byte[] jgArray;
    private CharTrie trie;
    private static final byte[] FMT = new byte[]{66, 105, 68, 105};

    public UBiDiProps() throws IOException {
        InputStream is = ICUData.getStream("data/icudt40b/ubidi.icu");
        BufferedInputStream b = new BufferedInputStream(is, 4096);
        this.readData(b);
        b.close();
        is.close();
    }

    private void readData(InputStream is) throws IOException {
        int i;
        DataInputStream inputStream = new DataInputStream(is);
        ICUBinary.readHeader(inputStream, FMT, new IsAcceptable());
        int count = inputStream.readInt();
        if (count < 0) {
            throw new IOException("indexes[0] too small in ubidi.icu");
        }
        this.indexes = new int[count];
        this.indexes[0] = count;
        for (i = 1; i < count; ++i) {
            this.indexes[i] = inputStream.readInt();
        }
        this.trie = new CharTrie(inputStream, null);
        count = this.indexes[3];
        if (count > 0) {
            this.mirrors = new int[count];
            for (i = 0; i < count; ++i) {
                this.mirrors[i] = inputStream.readInt();
            }
        }
        count = this.indexes[5] - this.indexes[4];
        this.jgArray = new byte[count];
        for (i = 0; i < count; ++i) {
            this.jgArray[i] = inputStream.readByte();
        }
    }

    public static final synchronized UBiDiProps getSingleton() throws IOException {
        if (gBdp == null) {
            gBdp = new UBiDiProps();
        }
        return gBdp;
    }

    private UBiDiProps(boolean makeDummy) {
        this.indexes = new int[16];
        this.indexes[0] = 16;
        this.trie = new CharTrie(0, 0, null);
    }

    public static final synchronized UBiDiProps getDummy() {
        if (gBdpDummy == null) {
            gBdpDummy = new UBiDiProps(true);
        }
        return gBdpDummy;
    }

    public final void addPropertyStarts(UnicodeSet set) {
        int i;
        TrieIterator iter = new TrieIterator(this.trie);
        RangeValueIterator.Element element = new RangeValueIterator.Element();
        while (iter.next(element)) {
            set.add(element.start);
        }
        int length = this.indexes[3];
        for (i = 0; i < length; ++i) {
            int c = UBiDiProps.getMirrorCodePoint(this.mirrors[i]);
            set.add(c, c + 1);
        }
        int start = this.indexes[4];
        int limit = this.indexes[5];
        length = limit - start;
        byte prev = 0;
        for (i = 0; i < length; ++i) {
            byte jg = this.jgArray[i];
            if (jg != prev) {
                set.add(start);
                prev = jg;
            }
            ++start;
        }
        if (prev != 0) {
            set.add(limit);
        }
    }

    public final int getClass(int c) {
        return UBiDiProps.getClassFromProps(this.trie.getCodePointValue(c));
    }

    public final boolean isMirrored(int c) {
        return UBiDiProps.getFlagFromProps(this.trie.getCodePointValue(c), 12);
    }

    public final int getMirror(int c) {
        char props = this.trie.getCodePointValue(c);
        int delta = (short)props >> 13;
        if (delta != -4) {
            return c + delta;
        }
        int length = this.indexes[3];
        for (int i = 0; i < length; ++i) {
            int m = this.mirrors[i];
            int c2 = UBiDiProps.getMirrorCodePoint(m);
            if (c == c2) {
                return UBiDiProps.getMirrorCodePoint(this.mirrors[UBiDiProps.getMirrorIndex(m)]);
            }
            if (c < c2) break;
        }
        return c;
    }

    public final boolean isBidiControl(int c) {
        return UBiDiProps.getFlagFromProps(this.trie.getCodePointValue(c), 11);
    }

    public final boolean isJoinControl(int c) {
        return UBiDiProps.getFlagFromProps(this.trie.getCodePointValue(c), 10);
    }

    public final int getJoiningType(int c) {
        return (this.trie.getCodePointValue(c) & 224) >> 5;
    }

    public final int getJoiningGroup(int c) {
        int start = this.indexes[4];
        int limit = this.indexes[5];
        if (start <= c && c < limit) {
            return this.jgArray[c - start] & 255;
        }
        return 0;
    }

    private static final int getClassFromProps(int props) {
        return props & 31;
    }

    private static final boolean getFlagFromProps(int props, int shift) {
        return (props >> shift & 1) != 0;
    }

    private static final int getMirrorCodePoint(int m) {
        return m & 2097151;
    }

    private static final int getMirrorIndex(int m) {
        return m >>> 21;
    }

    private final class IsAcceptable
    implements ICUBinary.Authenticate {
        private IsAcceptable() {
        }

        public boolean isDataVersionAcceptable(byte[] version) {
            return version[0] == 1 && version[2] == 5 && version[3] == 2;
        }
    }

}