void decode()

in src/main/java/org/apache/commons/codec/binary/Base32.java [437:529]


    void decode(final byte[] input, int inPos, final int inAvail, final Context context) {
        // package protected for access from I/O streams
        if (context.eof) {
            return;
        }
        if (inAvail < 0) {
            context.eof = true;
        }
        final int decodeSize = this.encodeSize - 1;
        for (int i = 0; i < inAvail; i++) {
            final byte b = input[inPos++];
            if (b == pad) {
                // We're done.
                context.eof = true;
                break;
            }
            final byte[] buffer = ensureBufferSize(decodeSize, context);
            if (b >= 0 && b < this.decodeTable.length) {
                final int result = this.decodeTable[b];
                if (result >= 0) {
                    context.modulus = (context.modulus + 1) % BYTES_PER_ENCODED_BLOCK;
                    // collect decoded bytes
                    context.lbitWorkArea = (context.lbitWorkArea << BITS_PER_ENCODED_BYTE) + result;
                    if (context.modulus == 0) { // we can output the 5 bytes
                        buffer[context.pos++] = (byte) (context.lbitWorkArea >> 32 & MASK_8BITS);
                        buffer[context.pos++] = (byte) (context.lbitWorkArea >> 24 & MASK_8BITS);
                        buffer[context.pos++] = (byte) (context.lbitWorkArea >> 16 & MASK_8BITS);
                        buffer[context.pos++] = (byte) (context.lbitWorkArea >> 8 & MASK_8BITS);
                        buffer[context.pos++] = (byte) (context.lbitWorkArea & MASK_8BITS);
                    }
                }
            }
        }
        // Two forms of EOF as far as Base32 decoder is concerned: actual
        // EOF (-1) and first time '=' character is encountered in stream.
        // This approach makes the '=' padding characters completely optional.
        if (context.eof && context.modulus > 0) { // if modulus == 0, nothing to do
            final byte[] buffer = ensureBufferSize(decodeSize, context);
            // We ignore partial bytes, i.e. only multiples of 8 count.
            // Any combination not part of a valid encoding is either partially decoded
            // or will raise an exception. Possible trailing characters are 2, 4, 5, 7.
            // It is not possible to encode with 1, 3, 6 trailing characters.
            // For backwards compatibility 3 & 6 chars are decoded anyway rather than discarded.
            // See the encode(byte[]) method EOF section.
            switch (context.modulus) {
//              case 0 : // impossible, as excluded above
            case 1: // 5 bits - either ignore entirely, or raise an exception
                validateTrailingCharacters();
                // falls-through
            case 2: // 10 bits, drop 2 and output one byte
                validateCharacter(MASK_2_BITS, context);
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 2 & MASK_8BITS);
                break;
            case 3: // 15 bits, drop 7 and output 1 byte, or raise an exception
                validateTrailingCharacters();
                // Not possible from a valid encoding but decode anyway
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 7 & MASK_8BITS);
                break;
            case 4: // 20 bits = 2*8 + 4
                validateCharacter(MASK_4_BITS, context);
                context.lbitWorkArea = context.lbitWorkArea >> 4; // drop 4 bits
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 8 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea & MASK_8BITS);
                break;
            case 5: // 25 bits = 3*8 + 1
                validateCharacter(MASK_1_BITS, context);
                context.lbitWorkArea = context.lbitWorkArea >> 1;
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 16 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 8 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea & MASK_8BITS);
                break;
            case 6: // 30 bits = 3*8 + 6, or raise an exception
                validateTrailingCharacters();
                // Not possible from a valid encoding but decode anyway
                context.lbitWorkArea = context.lbitWorkArea >> 6;
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 16 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 8 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea & MASK_8BITS);
                break;
            case 7: // 35 bits = 4*8 +3
                validateCharacter(MASK_3_BITS, context);
                context.lbitWorkArea = context.lbitWorkArea >> 3;
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 24 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 16 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea >> 8 & MASK_8BITS);
                buffer[context.pos++] = (byte) (context.lbitWorkArea & MASK_8BITS);
                break;
            default:
                // modulus can be 0-7, and we excluded 0,1 already
                throw new IllegalStateException("Impossible modulus " + context.modulus);
            }
        }
    }