CharsetASCII.java 9.3 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.agl.charset;

import com.adobe.agl.charset.CharsetDecoderICU;
import com.adobe.agl.charset.CharsetEncoderICU;
import com.adobe.agl.charset.CharsetICU;
import com.adobe.agl.text.UTF16;
import com.adobe.agl.text.UnicodeSet;

import java.nio.*;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

class CharsetASCII
extends CharsetICU {
    protected byte[] fromUSubstitution = new byte[]{26};

    public CharsetASCII(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
        super(icuCanonicalName, javaCanonicalName, aliases);
        this.maxBytesPerChar = 1;
        this.minBytesPerChar = 1;
        this.maxCharsPerByte = 1.0f;
    }

    public CharsetDecoder newDecoder() {
        return new CharsetDecoderASCII(this);
    }

    public CharsetEncoder newEncoder() {
        return new CharsetEncoderASCII(this);
    }

    void getUnicodeSetImpl(UnicodeSet setFillIn, int which) {
        setFillIn.add(0, 127);
    }

    class CharsetEncoderASCII
    extends CharsetEncoderICU {
        private static final int NEED_TO_WRITE_BOM = 1;

        public CharsetEncoderASCII(CharsetICU cs) {
            super(cs, CharsetASCII.this.fromUSubstitution);
            this.implReset();
        }

        protected void implReset() {
            super.implReset();
            this.fromUnicodeStatus = 1;
        }

        protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
            CoderResult cr;
            if (!source.hasRemaining()) {
                return CoderResult.UNDERFLOW;
            }
            if (!target.hasRemaining()) {
                return CoderResult.OVERFLOW;
            }
            int oldSource = source.position();
            int oldTarget = target.position();
            if (this.fromUChar32 != 0) {
                cr = this.encodeTrail(source, (char)this.fromUChar32, flush);
            } else if (source.hasArray() && target.hasArray()) {
                int targetIndex;
                int offset;
                int targetLength;
                int limit;
                int targetOffset;
                char[] sourceArray = source.array();
                int sourceOffset = source.arrayOffset();
                int sourceIndex = oldSource + sourceOffset;
                int sourceLength = source.limit() - oldSource;
                byte[] targetArray = target.array();
                cr = this.encodeLoopCoreOptimized(source, target, sourceArray, targetArray, sourceIndex, offset = (targetIndex = oldTarget + (targetOffset = target.arrayOffset())) - sourceIndex, limit = (sourceLength < (targetLength = target.limit() - oldTarget) ? sourceLength : targetLength) + sourceIndex, flush);
                if (cr == null) {
                    if (sourceLength <= targetLength) {
                        source.position(oldSource + sourceLength);
                        target.position(oldTarget + sourceLength);
                        cr = CoderResult.UNDERFLOW;
                    } else {
                        source.position(oldSource + targetLength);
                        target.position(oldTarget + targetLength);
                        cr = CoderResult.OVERFLOW;
                    }
                }
            } else {
                try {
                    cr = this.encodeLoopCoreUnoptimized(source, target, flush);
                }
                catch (BufferUnderflowException ex) {
                    cr = CoderResult.UNDERFLOW;
                }
                catch (BufferOverflowException ex) {
                    source.position(source.position() - 1);
                    cr = CoderResult.OVERFLOW;
                }
            }
            if (offsets != null) {
                int count = target.position() - oldTarget;
                int sourceIndex = -1;
                while (--count >= 0) {
                    offsets.put(++sourceIndex);
                }
            }
            return cr;
        }

        protected CoderResult encodeLoopCoreOptimized(CharBuffer source, ByteBuffer target, char[] sourceArray, byte[] targetArray, int oldSource, int offset, int limit, boolean flush) {
            int i;
            int ch = 0;
            for (i = oldSource; i < limit && ((ch = sourceArray[i]) & 65408) == 0; ++i) {
                targetArray[i + offset] = (byte)ch;
            }
            if ((ch & 65408) != 0) {
                source.position(i + 1);
                target.position(i + offset);
                return this.encodeMalformedOrUnmappable(source, ch, flush);
            }
            return null;
        }

        protected CoderResult encodeLoopCoreUnoptimized(CharBuffer source, ByteBuffer target, boolean flush) throws BufferUnderflowException, BufferOverflowException {
            char ch;
            while (((ch = source.get()) & 65408) == 0) {
                target.put((byte)ch);
            }
            return this.encodeMalformedOrUnmappable(source, ch, flush);
        }

        protected final CoderResult encodeMalformedOrUnmappable(CharBuffer source, int ch, boolean flush) {
            return UTF16.isSurrogate((char)ch) ? this.encodeTrail(source, (char)ch, flush) : CoderResult.unmappableForLength(1);
        }

        private final CoderResult encodeTrail(CharBuffer source, char lead, boolean flush) {
            CoderResult cr = this.handleSurrogates(source, lead);
            if (cr != null) {
                return cr;
            }
            return CoderResult.unmappableForLength(2);
        }
    }

    class CharsetDecoderASCII
    extends CharsetDecoderICU {
        public CharsetDecoderASCII(CharsetICU cs) {
            super(cs);
        }

        protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
            CoderResult cr;
            if (!source.hasRemaining()) {
                return CoderResult.UNDERFLOW;
            }
            if (!target.hasRemaining()) {
                return CoderResult.OVERFLOW;
            }
            int oldSource = source.position();
            int oldTarget = target.position();
            if (source.hasArray() && target.hasArray()) {
                int targetIndex;
                int offset;
                int targetLength;
                int limit;
                int targetOffset;
                byte[] sourceArray = source.array();
                int sourceOffset = source.arrayOffset();
                int sourceIndex = oldSource + sourceOffset;
                int sourceLength = source.limit() - oldSource;
                char[] targetArray = target.array();
                cr = this.decodeLoopCoreOptimized(source, target, sourceArray, targetArray, sourceIndex, offset = (targetIndex = oldTarget + (targetOffset = target.arrayOffset())) - sourceIndex, limit = (sourceLength < (targetLength = target.limit() - oldTarget) ? sourceLength : targetLength) + sourceIndex);
                if (cr == null) {
                    if (sourceLength <= targetLength) {
                        source.position(oldSource + sourceLength);
                        target.position(oldTarget + sourceLength);
                        cr = CoderResult.UNDERFLOW;
                    } else {
                        source.position(oldSource + targetLength);
                        target.position(oldTarget + targetLength);
                        cr = CoderResult.OVERFLOW;
                    }
                }
            } else {
                try {
                    cr = this.decodeLoopCoreUnoptimized(source, target);
                }
                catch (BufferUnderflowException ex) {
                    cr = CoderResult.UNDERFLOW;
                }
                catch (BufferOverflowException ex) {
                    source.position(source.position() - 1);
                    cr = CoderResult.OVERFLOW;
                }
            }
            if (offsets != null) {
                int count = target.position() - oldTarget;
                int sourceIndex = -1;
                while (--count >= 0) {
                    offsets.put(++sourceIndex);
                }
            }
            return cr;
        }

        protected CoderResult decodeLoopCoreOptimized(ByteBuffer source, CharBuffer target, byte[] sourceArray, char[] targetArray, int oldSource, int offset, int limit) {
            int i;
            int ch = 0;
            for (i = oldSource; i < limit && ((ch = sourceArray[i] & 255) & 128) == 0; ++i) {
                targetArray[i + offset] = (char)ch;
            }
            if ((ch & 128) != 0) {
                source.position(i + 1);
                target.position(i + offset);
                return this.decodeMalformedOrUnmappable(ch);
            }
            return null;
        }

        protected CoderResult decodeLoopCoreUnoptimized(ByteBuffer source, CharBuffer target) throws BufferUnderflowException, BufferOverflowException {
            int ch = 0;
            while (((ch = source.get() & 255) & 128) == 0) {
                target.put((char)ch);
            }
            return this.decodeMalformedOrUnmappable(ch);
        }

        protected CoderResult decodeMalformedOrUnmappable(int ch) {
            this.toUBytesArray[0] = (byte)ch;
            this.toULength = 1;
            return CoderResult.malformedForLength(1);
        }
    }

}