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

import com.adobe.agl.text.UCharacterIterator;

public class BOCU {
    public static int compress(String source, byte[] buffer, int offset) {
        int prev = 0;
        UCharacterIterator iterator = UCharacterIterator.getInstance(source);
        int codepoint = iterator.nextCodePoint();
        while (codepoint != -1) {
            prev = prev < 19968 || prev >= 40960 ? (prev & -128) - -80 : 30292;
            offset = BOCU.writeDiff(codepoint - prev, buffer, offset);
            prev = codepoint;
            codepoint = iterator.nextCodePoint();
        }
        return offset;
    }

    public static int getCompressionLength(String source) {
        int prev = 0;
        int result = 0;
        UCharacterIterator iterator = UCharacterIterator.getInstance(source);
        int codepoint = iterator.nextCodePoint();
        while (codepoint != -1) {
            prev = prev < 19968 || prev >= 40960 ? (prev & -128) - -80 : 30292;
            codepoint = iterator.nextCodePoint();
            result += BOCU.lengthOfDiff(codepoint - prev);
            prev = codepoint;
        }
        return result;
    }

    private static final long getNegDivMod(int number, int factor) {
        int modulo = number % factor;
        long result = number / factor;
        if (modulo < 0) {
            --result;
            modulo += factor;
        }
        return result << 32 | (long)modulo;
    }

    private static final int writeDiff(int diff, byte[] buffer, int offset) {
        if (diff >= -80) {
            if (diff <= 80) {
                buffer[offset++] = (byte)(129 + diff);
            } else if (diff <= 10667) {
                buffer[offset++] = (byte)(210 + diff / 253);
                buffer[offset++] = (byte)(3 + diff % 253);
            } else if (diff <= 192785) {
                buffer[offset + 2] = (byte)(3 + diff % 253);
                buffer[offset + 1] = (byte)(3 + (diff /= 253) % 253);
                buffer[offset] = (byte)(252 + diff / 253);
                offset += 3;
            } else {
                buffer[offset + 3] = (byte)(3 + diff % 253);
                buffer[offset] = (byte)(3 + (diff /= 253) % 253);
                buffer[offset + 1] = (byte)(3 + (diff /= 253) % 253);
                buffer[offset] = -1;
                offset += 4;
            }
        } else {
            long division = BOCU.getNegDivMod(diff, 253);
            int modulo = (int)division;
            if (diff >= -10668) {
                diff = (int)(division >> 32);
                buffer[offset++] = (byte)(49 + diff);
                buffer[offset++] = (byte)(3 + modulo);
            } else if (diff >= -192786) {
                buffer[offset + 2] = (byte)(3 + modulo);
                diff = (int)(division >> 32);
                division = BOCU.getNegDivMod(diff, 253);
                modulo = (int)division;
                diff = (int)(division >> 32);
                buffer[offset + 1] = (byte)(3 + modulo);
                buffer[offset] = (byte)(7 + diff);
                offset += 3;
            } else {
                buffer[offset + 3] = (byte)(3 + modulo);
                diff = (int)(division >> 32);
                division = BOCU.getNegDivMod(diff, 253);
                modulo = (int)division;
                diff = (int)(division >> 32);
                buffer[offset + 2] = (byte)(3 + modulo);
                division = BOCU.getNegDivMod(diff, 253);
                modulo = (int)division;
                buffer[offset + 1] = (byte)(3 + modulo);
                buffer[offset] = 3;
                offset += 4;
            }
        }
        return offset;
    }

    private static final int lengthOfDiff(int diff) {
        if (diff >= -80) {
            if (diff <= 80) {
                return 1;
            }
            if (diff <= 10667) {
                return 2;
            }
            if (diff <= 192785) {
                return 3;
            }
            return 4;
        }
        if (diff >= -10668) {
            return 2;
        }
        if (diff >= -192786) {
            return 3;
        }
        return 4;
    }
}