AnnotationID.java 11.4 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.internal.pdftoolkit.core.cos.CosDictionary
 *  com.adobe.internal.pdftoolkit.core.cos.CosObject
 *  com.adobe.internal.pdftoolkit.core.exceptions.PDFIOException
 *  com.adobe.internal.pdftoolkit.core.exceptions.PDFInvalidDocumentException
 *  com.adobe.internal.pdftoolkit.core.exceptions.PDFSecurityException
 *  com.adobe.internal.pdftoolkit.core.types.ASName
 *  com.adobe.internal.pdftoolkit.core.types.ASString
 */
package com.adobe.internal.pdftoolkit.pdf.impl;

import com.adobe.internal.pdftoolkit.core.cos.CosDictionary;
import com.adobe.internal.pdftoolkit.core.cos.CosObject;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFIOException;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFInvalidDocumentException;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFSecurityException;
import com.adobe.internal.pdftoolkit.core.types.ASName;
import com.adobe.internal.pdftoolkit.core.types.ASString;
import com.adobe.internal.pdftoolkit.pdf.document.PDFCosDictionary;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotation;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotationFactory;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotationPopup;
import com.adobe.internal.pdftoolkit.pdf.interactive.annotation.PDFAnnotationWidget;
import com.adobe.internal.pdftoolkit.pdf.interactive.forms.PDFField;
import com.adobe.internal.pdftoolkit.pdf.interactive.forms.PDFFieldNode;
import com.adobe.internal.pdftoolkit.pdf.interactive.forms.PDFInteractiveForm;
import com.adobe.internal.pdftoolkit.pdf.utils.PDFUtil;
import java.util.Iterator;
import java.util.Map;

public class AnnotationID {
    protected static final int INITIAL_SIZE = 8;
    protected char[] mBuffer;
    protected int mCount;
    protected static final char[] pdfDocToUCSTable = new char[]{'\u0000', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\b', '\t', '\n', '\u000b', '\f', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u02d8', '\u02c7', '\u02c6', '\u02d9', '\u02dd', '\u02db', '\u00b0', '\u02dc', ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\ufffd', '\u2022', '\u2020', '\u2021', '\u2026', '\u2014', '\u2013', '\u0192', '\u2044', '\u2039', '\u203a', '\u2212', '\u2030', '\u201e', '\u201c', '\u201d', '\u2018', '\u2019', '\u201a', '\u2122', '\ufffe', '\uffff', '\u0141', '\u0152', '\u0160', '\u0178', '\u017d', '\u0131', '\u0142', '\u0153', '\u0161', '\u017e', '\ufffd', '\u20ac', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', '\u00ac', '\ufffd', '\u00ae', '\u00af', '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', '\u00b5', '\u00b6', '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', '\u00be', '\u00bf', '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', '\u00c6', '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', '\u00cd', '\u00ce', '\u00cf', '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', '\u00d6', '\u00d7', '\u00d8', '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', '\u00df', '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', '\u00e6', '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', '\u00ed', '\u00ee', '\u00ef', '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', '\u00fc', '\u00fd', '\u00fe', '\u00ff'};

    public AnnotationID() {
        this.mBuffer = new char[8];
        this.mCount = 0;
    }

    public AnnotationID(PDFAnnotation annot) throws PDFInvalidDocumentException, PDFIOException, PDFSecurityException {
        this(annot, null, null);
    }

    private static AnnotationID getID(PDFAnnotation annot, Map map, Object collator) throws PDFInvalidDocumentException, PDFIOException, PDFSecurityException {
        if (map == null) {
            return new AnnotationID(annot);
        }
        AnnotationID id = (AnnotationID)map.get(annot);
        if (id == null) {
            id = new AnnotationID(annot, map, collator);
            map.put(annot, id);
            return id;
        }
        return id;
    }

    protected AnnotationID(PDFAnnotation annot, Map map, Object collator) throws PDFInvalidDocumentException, PDFIOException, PDFSecurityException {
        this();
        if (annot instanceof PDFAnnotationWidget && ((PDFAnnotationWidget)annot).isField()) {
            PDFField field = ((PDFAnnotationWidget)annot).getField();
            this.appendQualifiedName(field);
            if (!field.getCosDictionary().containsKey((Object)ASName.k_T)) {
                int index = 0;
                Iterator<PDFField> iter = field.getParent().iterator();
                while (iter.hasNext()) {
                    PDFFieldNode kid = iter.next();
                    if (kid instanceof PDFField && PDFUtil.isPDFCosObjectRefEqual(kid, field)) {
                        this.append(46);
                        if (index <= 0) {
                            this.append(48);
                        } else {
                            int value = index;
                            for (int divisor = 1000000000; divisor != 0; divisor /= 10) {
                                if (index < divisor) continue;
                                this.append(value / divisor + 48);
                                value -= value / divisor * divisor;
                            }
                        }
                        break;
                    }
                    ++index;
                }
            }
        } else if (annot.hasName()) {
            this.appendStringValue(annot, ASName.k_NM);
        } else if (annot instanceof PDFAnnotationPopup && annot.dictionaryContains(ASName.k_Parent)) {
            PDFAnnotation parentAnnot = PDFAnnotationFactory.getInstance(annot.getCosDictionary().get(ASName.k_Parent));
            this.append(AnnotationID.getID(parentAnnot, map, collator));
            this.append(46);
            this.append(48);
        } else {
            this.append(85);
            this.append(110);
            this.append(107);
            this.append(110);
            this.append(111);
            this.append(119);
            this.append(110);
        }
    }

    protected void append(int oneChar) {
        this.ensureCapacity(this.mCount + 1);
        this.mBuffer[this.mCount++] = (char)oneChar;
    }

    protected void append(AnnotationID id) {
        this.ensureCapacity(this.mCount + id.mCount);
        System.arraycopy(id.mBuffer, 0, this.mBuffer, this.mCount, id.mCount);
        this.mCount += id.mCount;
    }

    protected void appendQualifiedName(PDFFieldNode node) throws PDFInvalidDocumentException, PDFIOException, PDFSecurityException {
        PDFFieldNode parent = node.getParent();
        if (parent == null || parent instanceof PDFInteractiveForm) {
            this.appendStringValue(node, ASName.k_T);
            return;
        }
        this.appendQualifiedName(parent);
        if (node.dictionaryContains(ASName.k_T)) {
            this.append(46);
            this.appendStringValue(node, ASName.k_T);
        }
    }

    protected void appendStringValue(PDFCosDictionary dict, ASName key) throws PDFInvalidDocumentException, PDFIOException, PDFSecurityException {
        ASString asString = dict.getDictionaryStringValue(key);
        if (asString == null) {
            return;
        }
        byte[] bytes = asString.getBytes();
        if (bytes.length >= 2 && (bytes[0] == -2 && bytes[1] == -1 || bytes[0] == -1 && bytes[1] == -2)) {
            this.appendUCS(bytes);
        } else {
            this.appendDoc(bytes);
        }
    }

    protected void ensureCapacity(int newSize) {
        if (this.mBuffer.length < newSize) {
            int size;
            for (size = this.mBuffer.length; size < newSize; size *= 2) {
            }
            char[] newBuffer = new char[size];
            System.arraycopy(this.mBuffer, 0, newBuffer, 0, this.mCount);
            this.mBuffer = newBuffer;
        }
    }

    protected void appendUCS(byte[] bytes) {
        int bytesRemaining = bytes.length & -2;
        if (bytesRemaining >= 2 && (bytes[0] == -2 && bytes[1] == -1 || bytes[0] == -1 && bytes[1] == -2)) {
            int byteIndex = 0;
            boolean bigEndian = false;
            if (bytes[0] == -2) {
                bigEndian = true;
            }
            if ((bytesRemaining -= 2) >= 2 && this.readOneUniChar(bytes, byteIndex += 2, bigEndian) == 27) {
                if ((bytesRemaining -= 2) >= 2 && this.isAlpha(bytes[byteIndex]) && this.isAlpha(bytes[(byteIndex += 2) + 1]) && (bytesRemaining -= 2) >= 2 && this.isAlpha(bytes[byteIndex]) && this.isAlpha(bytes[(byteIndex += 2) + 1])) {
                    byteIndex += 2;
                    bytesRemaining -= 2;
                }
                if (bytesRemaining >= 2 && this.readOneUniChar(bytes, byteIndex, bigEndian) == 27) {
                    byteIndex += 2;
                    bytesRemaining -= 2;
                }
            }
            while (bytesRemaining >= 2) {
                int curChar = this.readOneUniChar(bytes, byteIndex, bigEndian);
                if (curChar >= 55296 && curChar < 57344) {
                    int nextChar;
                    if (curChar >= 55296 && curChar < 56320 && bytesRemaining >= 4 && (nextChar = this.readOneUniChar(bytes, byteIndex + 2, bigEndian)) >= 56320 && nextChar < 57344) {
                        this.append(curChar);
                        this.append(nextChar);
                        byteIndex += 2;
                        bytesRemaining -= 2;
                    }
                } else {
                    this.append(curChar);
                }
                byteIndex += 2;
                bytesRemaining -= 2;
            }
        }
    }

    protected int readOneUniChar(byte[] bytes, int offset, boolean bigEndian) {
        int oneChar = 0;
        if (bigEndian) {
            oneChar = bytes[offset] << 8;
            oneChar |= bytes[offset + 1] & 255;
        } else {
            oneChar = bytes[offset] & 255;
            oneChar |= bytes[offset + 1] << 8;
        }
        return oneChar & 65535;
    }

    protected boolean isAlpha(byte textChar) {
        if (textChar >= 65 && textChar <= 90 || textChar >= 97 && textChar <= 122) {
            return true;
        }
        return false;
    }

    protected void appendDoc(byte[] bytes) {
        for (int i = 0; i < bytes.length; ++i) {
            char outChar = pdfDocToUCSTable[bytes[i] & 255];
            if (outChar == '\ufffe') {
                this.append(102);
                this.append(105);
                continue;
            }
            if (outChar == '\uffff') {
                this.append(102);
                this.append(108);
                continue;
            }
            this.append(outChar);
        }
    }

    public String asString() {
        return new String(this.mBuffer, 0, this.mCount);
    }

    public String toString() {
        return new String(this.mBuffer, 0, this.mCount);
    }
}