in chill-java/src/main/java/com/twitter/chill/Base64.java [1706:1799]
public int read() throws java.io.IOException {
// Do we need to get data?
if( position < 0 ) {
if( encode ) {
byte[] b3 = new byte[3];
int numBinaryBytes = 0;
for( int i = 0; i < 3; i++ ) {
int b = in.read();
// If end of stream, b is -1.
if( b >= 0 ) {
b3[i] = (byte)b;
numBinaryBytes++;
} else {
break; // out of for loop
} // end else: end of stream
} // end for: each needed input byte
if( numBinaryBytes > 0 ) {
encode3to4( b3, 0, numBinaryBytes, buffer, 0, options );
position = 0;
numSigBytes = 4;
} // end if: got data
else {
return -1; // Must be end of stream
} // end else
} // end if: encoding
// Else decoding
else {
byte[] b4 = new byte[4];
int i = 0;
for( i = 0; i < 4; i++ ) {
// Read four "meaningful" bytes:
int b = 0;
do{ b = in.read(); }
while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC );
if( b < 0 ) {
break; // Reads a -1 if end of stream
} // end if: end of stream
b4[i] = (byte)b;
} // end for: each needed input byte
if( i == 4 ) {
numSigBytes = decode4to3( b4, 0, buffer, 0, options );
position = 0;
} // end if: got four characters
else if( i == 0 ){
return -1;
} // end else if: also padded correctly
else {
// Must have broken out from above.
throw new java.io.IOException( "Improperly padded Base64 input." );
} // end
} // end else: decode
} // end else: get data
// Got data?
if( position >= 0 ) {
// End of relevant data?
if( /*!encode &&*/ position >= numSigBytes ){
return -1;
} // end if: got data
if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) {
lineLength = 0;
return '\n';
} // end if
else {
lineLength++; // This isn't important when decoding
// but throwing an extra "if" seems
// just as wasteful.
int b = buffer[ position++ ];
if( position >= bufferLength ) {
position = -1;
} // end if: end
return b & 0xFF; // This is how you "cast" a byte that's
// intended to be unsigned.
} // end else
} // end if: position >= 0
// Else error
else {
throw new java.io.IOException( "Error in Base64 code reading stream." );
} // end else
} // end read