// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.util.encoders;

import java.io.OutputStream;
import java.io.IOException;

public class HexEncoder implements Encoder
{
    protected final byte[] encodingTable;
    protected final byte[] decodingTable;
    
    protected void initialiseDecodingTable() {
        for (int i = 0; i < this.decodingTable.length; ++i) {
            this.decodingTable[i] = -1;
        }
        for (int j = 0; j < this.encodingTable.length; ++j) {
            this.decodingTable[this.encodingTable[j]] = (byte)j;
        }
        this.decodingTable[65] = this.decodingTable[97];
        this.decodingTable[66] = this.decodingTable[98];
        this.decodingTable[67] = this.decodingTable[99];
        this.decodingTable[68] = this.decodingTable[100];
        this.decodingTable[69] = this.decodingTable[101];
        this.decodingTable[70] = this.decodingTable[102];
    }
    
    public HexEncoder() {
        this.encodingTable = new byte[] { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102 };
        this.decodingTable = new byte[128];
        this.initialiseDecodingTable();
    }
    
    public int encode(final byte[] array, final int n, final int n2, final byte[] array2, final int n3) throws IOException {
        int i;
        int n4;
        int n5;
        int n6;
        for (i = n, n4 = n + n2, n5 = n3; i < n4; n6 = (array[i++] & 0xFF), array2[n5++] = this.encodingTable[n6 >>> 4], array2[n5++] = this.encodingTable[n6 & 0xF]) {}
        return n5 - n3;
    }
    
    @Override
    public int getEncodedLength(final int n) {
        return n * 2;
    }
    
    @Override
    public int getMaxDecodedLength(final int n) {
        return n / 2;
    }
    
    @Override
    public int encode(final byte[] array, int n, final int n2, final OutputStream outputStream) throws IOException {
        if (n2 < 0) {
            return 0;
        }
        final byte[] b = new byte[72];
        int min;
        for (int i = n2; i > 0; i -= min) {
            min = Math.min(36, i);
            outputStream.write(b, 0, this.encode(array, n, min, b, 0));
            n += min;
        }
        return n2 * 2;
    }
    
    private static boolean ignore(final char c) {
        return c == '\n' || c == '\r' || c == '\t' || c == ' ';
    }
    
    @Override
    public int decode(final byte[] array, final int n, final int n2, final OutputStream outputStream) throws IOException {
        int n3 = 0;
        final byte[] array2 = new byte[36];
        int len = 0;
        int n4;
        for (n4 = n + n2; n4 > n && ignore((char)array[n4 - 1]); --n4) {}
        int i = n;
        while (i < n4) {
            while (i < n4 && ignore((char)array[i])) {
                ++i;
            }
            byte b;
            for (b = this.decodingTable[array[i++]]; i < n4 && ignore((char)array[i]); ++i) {}
            final byte b2 = this.decodingTable[array[i++]];
            if ((b | b2) < 0) {
                throw new IOException("invalid characters encountered in Hex data");
            }
            array2[len++] = (byte)(b << 4 | b2);
            if (len == array2.length) {
                outputStream.write(array2);
                len = 0;
            }
            ++n3;
        }
        if (len > 0) {
            outputStream.write(array2, 0, len);
        }
        return n3;
    }
    
    @Override
    public int decode(final String s, final OutputStream outputStream) throws IOException {
        int n = 0;
        final byte[] array = new byte[36];
        int len = 0;
        int length;
        for (length = s.length(); length > 0 && ignore(s.charAt(length - 1)); --length) {}
        int i = 0;
        while (i < length) {
            while (i < length && ignore(s.charAt(i))) {
                ++i;
            }
            byte b;
            for (b = this.decodingTable[s.charAt(i++)]; i < length && ignore(s.charAt(i)); ++i) {}
            final byte b2 = this.decodingTable[s.charAt(i++)];
            if ((b | b2) < 0) {
                throw new IOException("invalid characters encountered in Hex string");
            }
            array[len++] = (byte)(b << 4 | b2);
            if (len == array.length) {
                outputStream.write(array);
                len = 0;
            }
            ++n;
        }
        if (len > 0) {
            outputStream.write(array, 0, len);
        }
        return n;
    }
    
    byte[] decodeStrict(final String s, final int n, final int n2) throws IOException {
        if (null == s) {
            throw new NullPointerException("'str' cannot be null");
        }
        if (n < 0 || n2 < 0 || n > s.length() - n2) {
            throw new IndexOutOfBoundsException("invalid offset and/or length specified");
        }
        if (0x0 != (n2 & 0x1)) {
            throw new IOException("a hexadecimal encoding must have an even number of characters");
        }
        final int n3 = n2 >>> 1;
        final byte[] array = new byte[n3];
        int n4 = n;
        for (int i = 0; i < n3; ++i) {
            final int n5 = this.decodingTable[s.charAt(n4++)] << 4 | this.decodingTable[s.charAt(n4++)];
            if (n5 < 0) {
                throw new IOException("invalid characters encountered in Hex string");
            }
            array[i] = (byte)n5;
        }
        return array;
    }
}
