in src/com/amazon/ion/impl/Base64Encoder.java [204:289]
private void loadNextBuffer() throws IOException
{
int inlen = 0;
int convert, c = -1, cbin;
this._bufEnd = 0;
this._bufPos = 0;
if (this._state == 1) {
return;
}
// try to read in 4 convertable text characters from the source stream
while (inlen < 4) {
c = this._source.read();
if (c == -1 || c == 65535 || c == this._terminator || c == this._otherTerminator) {
_terminatingChar = c;
break;
}
if (IonTextUtils.isWhitespace(c)) continue;
cbin = characterToBinary(c);
this._buffer[inlen++] = (char)cbin;
}
if (inlen != 4) {
if (inlen == 0 && c != this._terminator) {
this._state = 1;
return;
}
// read through the trailing '='s
int templen = inlen;
while (c == this._terminator) {
templen++;
c = this._source.read();
}
if (templen != 4) {
throw new IonException("base64 character count must be divisible by 4, using '=' for padding");
}
else if (inlen < 1) {
throw new IonException("base64 character count must be divisible by 4, but using no more than 3 '=' chars for padding");
}
this._terminatingChar = c;
}
// now convert those characters
int ii = 0;
for (;;) {
// next usable char:
c = this._buffer[ii++];
convert = c << 18;
// next usable char:
c = this._buffer[ii++];
convert |= (c << 12);
if (inlen < 3) {
// with 2 input chars (6*2 = 12 bits) we get only 1 output byte (8 bits)
this._buffer[this._bufEnd++] = (char)((convert & 0x00FF0000) >> 16);
this._state = 1; // if we ran out, then we're done
break;
}
// next usable char:
c = this._buffer[ii++];
convert |= (c << 6);
if (inlen < 4) {
// with 3 input chars (6*3 = 18 bits) we get 2 output bytes (8*2 = 16 bits)
this._buffer[this._bufEnd++] = (char)((convert & 0x00FF0000) >> 16);
this._buffer[this._bufEnd++] = (char)((convert & 0x0000FF00) >> 8);
this._state = 1; // if we ran out, then we're done
break;
}
// next (and final possible out of 4) usable char:
c = this._buffer[ii++];
convert |= (c << 0);
// and with 4 input chars (6*4 = 24 bits) we get the full 3 output byte2 (8*3 = 24 bits)
this._buffer[this._bufEnd++] = (char)((convert & 0x00FF0000) >> 16);
this._buffer[this._bufEnd++] = (char)((convert & 0x0000FF00) >> 8);
this._buffer[this._bufEnd++] = (char)((convert & 0x000000FF) >> 0);
break;
}
return;
}