@Override
    void decode(byte[] in, int inPos, int inAvail) {
        if (eof) {
            return;
        }
        if (inAvail < 0) {
            eof = true;
        }
        for (int i = 0; i < inAvail; i++) {
            ensureBufferSize(decodeSize);
            byte b = in[inPos++];
            if (b == PAD) {
                // We're done.
                eof = true;
                break;
            } else {
                if (b >= 0 && b < DECODE_TABLE.length) {
                    int result = DECODE_TABLE[b];
                    if (result >= 0) {
                        modulus = (modulus + 1) % BYTES_PER_ENCODED_BLOCK;
                        bitWorkArea = (bitWorkArea << BITS_PER_ENCODED_BYTE) + result;
                        if (modulus == 0) {
                            buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS);
                            buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS);
                            buffer[pos++] = (byte) (bitWorkArea & MASK_8BITS);
                        }
                    }
                }
            }
        }

        // Two forms of EOF as far as base64 decoder is concerned: actual
        // EOF (-1) and first time '=' character is encountered in stream.
        // This approach makes the '=' padding characters completely optional.
        if (eof && modulus != 0) {
            ensureBufferSize(decodeSize);

            // We have some spare bits remaining
            // Output all whole multiples of 8 bits and ignore the rest
            switch (modulus) {
                // case 1: // 6 bits - ignore entirely
                // break;
                case 2: // 12 bits = 8 + 4
                    bitWorkArea = bitWorkArea >> 4; // dump the extra 4 bits
                    buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS);
                    break;
                case 3: // 18 bits = 8 + 8 + 2
                    bitWorkArea = bitWorkArea >> 2; // dump 2 bits
                    buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS);
                    buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS);
                    break;
            }
        }
    }
@ Override void decode ( byte [ ] in , int inPos , int inAvail ) { if ( eof ) { return ; } if ( inAvail < 0 ) { eof = true ; } for ( int i = 0 ; i < inAvail ; i ++ ) { ensureBufferSize ( decodeSize ) ; byte b = in [ inPos ++ ] ; if ( b == PAD ) { eof = true ; break ; } else { if ( b >= 0 && b < DECODE_TABLE . length ) { int result = DECODE_TABLE [ b ] ; if ( result >= 0 ) { modulus = ( modulus + 1 ) % BYTES_PER_ENCODED_BLOCK ; bitWorkArea = ( bitWorkArea << BITS_PER_ENCODED_BYTE ) + result ; if ( modulus == 0 ) { buffer [ pos ++ ] = ( byte ) ( ( bitWorkArea > > 16 ) & MASK_8BITS ) ; buffer [ pos ++ ] = ( byte ) ( ( bitWorkArea > > 8 ) & MASK_8BITS ) ; buffer [ pos ++ ] = ( byte ) ( bitWorkArea & MASK_8BITS ) ; } } } } } if ( eof && modulus != 0 ) { ensureBufferSize ( decodeSize ) ; switch ( modulus ) { case 2 : bitWorkArea = bitWorkArea > > 4 ; buffer [ pos ++ ] = ( byte ) ( ( bitWorkArea ) & MASK_8BITS ) ; break ; case 3 : bitWorkArea = bitWorkArea > > 2 ; buffer [ pos ++ ] = ( byte ) ( ( bitWorkArea > > 8 ) & MASK_8BITS ) ; buffer [ pos ++ ] = ( byte ) ( ( bitWorkArea ) & MASK_8BITS ) ; break ; } } }
<p>
Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once with the
data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" call is not
necessary when decoding, but it doesn't hurt, either.
</p>
<p>
Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are silently
ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, garbage-out philosophy: it
will not check the provided data for validity.
</p>
<p>
Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
</p>

@param in byte[] array of ascii data to base64 decode.
@param inPos Position to start reading data from.
@param inAvail Amount of bytes available from input for encoding.