in src/main/java/org/apache/commons/codec/binary/Base16.java [151:200]
void decode(final byte[] data, int offset, final int length, final Context context) {
if (context.eof || length < 0) {
context.eof = true;
if (context.ibitWorkArea != 0) {
validateTrailingCharacter();
}
return;
}
final int dataLen = Math.min(data.length - offset, length);
final int availableChars = (context.ibitWorkArea != 0 ? 1 : 0) + dataLen;
// small optimisation to short-cut the rest of this method when it is fed byte-by-byte
if (availableChars == 1 && availableChars == dataLen) {
// store 1/2 byte for next invocation of decode, we offset by +1 as empty-value is 0
context.ibitWorkArea = decodeOctet(data[offset]) + 1;
return;
}
// we must have an even number of chars to decode
final int charsToProcess = availableChars % BYTES_PER_ENCODED_BLOCK == 0 ? availableChars : availableChars - 1;
final int end = offset + dataLen;
final byte[] buffer = ensureBufferSize(charsToProcess / BYTES_PER_ENCODED_BLOCK, context);
int result;
if (dataLen < availableChars) {
// we have 1/2 byte from previous invocation to decode
result = (context.ibitWorkArea - 1) << BITS_PER_ENCODED_BYTE;
result |= decodeOctet(data[offset++]);
buffer[context.pos++] = (byte)result;
// reset to empty-value for next invocation!
context.ibitWorkArea = 0;
}
final int loopEnd = end - 1;
while (offset < loopEnd) {
result = decodeOctet(data[offset++]) << BITS_PER_ENCODED_BYTE;
result |= decodeOctet(data[offset++]);
buffer[context.pos++] = (byte)result;
}
// we have one char of a hex-pair left over
if (offset < end) {
// store 1/2 byte for next invocation of decode, we offset by +1 as empty-value is 0
context.ibitWorkArea = decodeOctet(data[offset]) + 1;
}
}