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

import com.adobe.agl.impl.NormalizerImpl;
import com.adobe.agl.impl.USerializedSet;
import com.adobe.agl.impl.Utility;
import com.adobe.agl.lang.UCharacter;
import com.adobe.agl.text.Normalizer;
import com.adobe.agl.text.UTF16;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public final class CanonicalIterator {
    private static boolean PROGRESS = false;
    private static boolean SKIP_ZEROS = true;
    private String source;
    private boolean done;
    private String[][] pieces;
    private int[] current;
    private transient StringBuffer buffer = new StringBuffer();
    private static final Set SET_WITH_NULL_STRING = new HashSet();

    public CanonicalIterator(String source) {
        this.setSource(source);
    }

    public String next() {
        if (this.done) {
            return null;
        }
        this.buffer.setLength(0);
        for (int i = 0; i < this.pieces.length; ++i) {
            this.buffer.append(this.pieces[i][this.current[i]]);
        }
        String result = this.buffer.toString();
        int i2 = this.current.length - 1;
        do {
            if (i2 < 0) {
                this.done = true;
                break;
            }
            int[] arrn = this.current;
            int n = i2;
            arrn[n] = arrn[n] + 1;
            if (this.current[i2] < this.pieces[i2].length) break;
            this.current[i2] = 0;
            --i2;
        } while (true);
        return result;
    }

    public void setSource(String newSource) {
        int cp;
        int i;
        this.source = Normalizer.normalize(newSource, Normalizer.NFD);
        this.done = false;
        if (newSource.length() == 0) {
            this.pieces = new String[1][];
            this.current = new int[1];
            this.pieces[0] = new String[]{""};
            return;
        }
        ArrayList<String> segmentList = new ArrayList<String>();
        int start = 0;
        for (i = UTF16.findOffsetFromCodePoint((String)this.source, (int)1); i < this.source.length(); i += UTF16.getCharCount((int)cp)) {
            cp = UTF16.charAt(this.source, i);
            if (!NormalizerImpl.isCanonSafeStart(cp)) continue;
            segmentList.add(this.source.substring(start, i));
            start = i;
        }
        segmentList.add(this.source.substring(start, i));
        this.pieces = new String[segmentList.size()][];
        this.current = new int[segmentList.size()];
        for (i = 0; i < this.pieces.length; ++i) {
            if (PROGRESS) {
                System.out.println("SEGMENT");
            }
            this.pieces[i] = this.getEquivalents((String)segmentList.get(i));
        }
    }

    public static void permute(String source, boolean skipZeros, Set output) {
        int cp;
        if (source.length() <= 2 && UTF16.countCodePoint(source) <= 1) {
            output.add(source);
            return;
        }
        HashSet subpermute = new HashSet();
        for (int i = 0; i < source.length(); i += UTF16.getCharCount((int)cp)) {
            cp = UTF16.charAt(source, i);
            if (skipZeros && i != 0 && UCharacter.getCombiningClass(cp) == 0) continue;
            subpermute.clear();
            CanonicalIterator.permute(source.substring(0, i) + source.substring(i + UTF16.getCharCount(cp)), skipZeros, subpermute);
            String chStr = UTF16.valueOf(source, i);
            Iterator it = subpermute.iterator();
            while (it.hasNext()) {
                String piece = chStr + (String)it.next();
                output.add(piece);
            }
        }
    }

    private String[] getEquivalents(String segment) {
        HashSet<String> result = new HashSet<String>();
        Set basic = this.getEquivalents2(segment);
        HashSet permutations = new HashSet();
        Iterator it = basic.iterator();
        while (it.hasNext()) {
            String item = (String)it.next();
            permutations.clear();
            CanonicalIterator.permute(item, SKIP_ZEROS, permutations);
            Iterator it2 = permutations.iterator();
            while (it2.hasNext()) {
                String possible = (String)it2.next();
                if (Normalizer.compare(possible, segment, 0) == 0) {
                    if (PROGRESS) {
                        System.out.println("Adding Permutation: " + Utility.hex(possible));
                    }
                    result.add(possible);
                    continue;
                }
                if (!PROGRESS) continue;
                System.out.println("-Skipping Permutation: " + Utility.hex(possible));
            }
        }
        String[] finalResult = new String[result.size()];
        result.toArray(finalResult);
        return finalResult;
    }

    private Set getEquivalents2(String segment) {
        HashSet<String> result = new HashSet<String>();
        if (PROGRESS) {
            System.out.println("Adding: " + Utility.hex(segment));
        }
        result.add(segment);
        StringBuffer workingBuffer = new StringBuffer();
        int cp = 0;
        int[] range = new int[2];
        for (int i = 0; i < segment.length(); i += UTF16.getCharCount((int)cp)) {
            USerializedSet starts;
            cp = UTF16.charAt(segment, i);
            if (!NormalizerImpl.getCanonStartSet(cp, starts = new USerializedSet())) continue;
            int j = 0;
            int rangeCount = starts.countRanges();
            for (j = 0; j < rangeCount; ++j) {
                starts.getRange(j, range);
                int end = range[1];
                for (int cp2 = range[0]; cp2 <= end; ++cp2) {
                    Set remainder = this.extract(cp2, segment, i, workingBuffer);
                    if (remainder == null) continue;
                    String prefix = segment.substring(0, i);
                    prefix = prefix + UTF16.valueOf(cp2);
                    Iterator iter = remainder.iterator();
                    while (iter.hasNext()) {
                        String item = (String)iter.next();
                        String toAdd = new String(prefix);
                        toAdd = toAdd + item;
                        result.add(toAdd);
                    }
                }
            }
        }
        return result;
    }

    private Set extract(int comp, String segment, int segmentPos, StringBuffer buf) {
        int cp;
        if (PROGRESS) {
            System.out.println(" extract: " + Utility.hex(UTF16.valueOf(comp)) + ", " + Utility.hex(segment.substring(segmentPos)));
        }
        String decomp = Normalizer.normalize(comp, Normalizer.NFD);
        boolean ok = false;
        int decompPos = 0;
        int decompCp = UTF16.charAt(decomp, 0);
        decompPos += UTF16.getCharCount(decompCp);
        buf.setLength(0);
        for (int i = segmentPos; i < segment.length(); i += UTF16.getCharCount((int)cp)) {
            cp = UTF16.charAt(segment, i);
            if (cp == decompCp) {
                if (PROGRESS) {
                    System.out.println("  matches: " + Utility.hex(UTF16.valueOf(cp)));
                }
                if (decompPos == decomp.length()) {
                    buf.append(segment.substring(i + UTF16.getCharCount(cp)));
                    ok = true;
                    break;
                }
                decompCp = UTF16.charAt(decomp, decompPos);
                decompPos += UTF16.getCharCount(decompCp);
                continue;
            }
            if (PROGRESS) {
                System.out.println("  buffer: " + Utility.hex(UTF16.valueOf(cp)));
            }
            UTF16.append(buf, cp);
        }
        if (!ok) {
            return null;
        }
        if (PROGRESS) {
            System.out.println("Matches");
        }
        if (buf.length() == 0) {
            return SET_WITH_NULL_STRING;
        }
        String remainder = buf.toString();
        if (0 != Normalizer.compare(UTF16.valueOf(comp) + remainder, segment.substring(segmentPos), 0)) {
            return null;
        }
        return this.getEquivalents2(remainder);
    }

    static {
        SET_WITH_NULL_STRING.add("");
    }
}