📄 base64.java
字号:
if( i == 4 )
{
numSigBytes = decode4to3( b4, 0, buffer, 0 );
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;
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;
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
{
// When JDK1.4 is more accepted, use an assertion here.
throw new java.io.IOException( "Error in Base64 code reading stream." );
} // end else
} // end read
/**
* Calls read repeatedly until the end of stream
* is reached or <var>len</var> bytes are read.
* Returns number of bytes read into array or -1 if
* end of stream is encountered.
*
* @param dest array to hold values
* @param off offset for array
* @param len max number of bytes to read into array
* @return bytes read into array or -1 if end of stream is encountered.
*/
public int read( byte[] dest, int off, int len ) throws java.io.IOException
{
int i;
int b;
for( i = 0; i < len; i++ )
{
b = read();
//if( b < 0 && i == 0 )
// return -1;
if( b >= 0 )
dest[off + i] = (byte)b;
else if( i == 0 )
return -1;
else
break; // Out of 'for' loop
} // end for: each byte read
return i;
} // end read
} // end inner class InputStream
/* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */
/**
* An OutputStream will write data to another OutputStream,
* given in the constructor,
* and encode/decode to/from Base64 notation on the fly.
*
*/
public static class OutputStream extends java.io.FilterOutputStream
{
private int options;
private boolean encode;
private int position;
private byte[] buffer;
private int bufferLength;
private int lineLength;
private boolean breakLines;
private byte[] b4; // Scratch used in a few places
private boolean suspendEncoding;
/**
* Constructs an OutputStream in ENCODE mode.
*
* @param out the OutputStream to which data will be written.
*/
public OutputStream( java.io.OutputStream out )
{
this( out, ENCODE );
} // end constructor
/**
* Constructs an OutputStream in
* either ENCODE or DECODE mode.
* <p>
* Valid options:<pre>
* ENCODE or DECODE: Encode or Decode as data is read.
* DONT_BREAK_LINES: don't break lines at 76 characters
* (only meaningful when encoding)
* <i>Note: Technically, this makes your encoding non-compliant.</i>
* </pre>
* <p>
* Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
*
* @param out the OutputStream to which data will be written.
* @param options Specified options.
*/
public OutputStream( java.io.OutputStream out, int options )
{
super( out );
this.options = options;
this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
this.encode = (options & ENCODE) == ENCODE;
this.bufferLength = encode ? 3 : 4;
this.buffer = new byte[ bufferLength ];
this.position = 0;
this.lineLength = 0;
this.suspendEncoding = false;
this.b4 = new byte[4];
} // end constructor
/**
* Writes the byte to the output stream after
* converting to/from Base64 notation.
* When encoding, bytes are buffered three
* at a time before the output stream actually
* gets a write() call.
* When decoding, bytes are buffered four
* at a time.
*
* @param theByte the byte to write
*/
public void write(int theByte) throws java.io.IOException
{
// Encoding suspended?
if( suspendEncoding )
{
super.out.write( theByte );
return;
} // end if: supsended
// Encode?
if( encode )
{
buffer[ position++ ] = (byte)theByte;
if( position >= bufferLength ) // Enough to encode.
{
out.write( encode3to4( b4, buffer, bufferLength ) );
lineLength += 4;
if( breakLines && lineLength >= MAX_LINE_LENGTH )
{
out.write( NEW_LINE );
lineLength = 0;
} // end if: end of line
position = 0;
} // end if: enough to output
} // end if: encoding
// Else, Decoding
else
{
// Meaningful Base64 character?
if( DECODABET[ theByte & 0x7f ] > WHITE_SPACE_ENC )
{
buffer[ position++ ] = (byte)theByte;
if( position >= bufferLength ) // Enough to output.
{
int len = Base64.decode4to3( buffer, 0, b4, 0 );
out.write( b4, 0, len );
//out.write( Base64.decode4to3( buffer ) );
position = 0;
} // end if: enough to output
} // end if: meaningful base64 character
else if( DECODABET[ theByte & 0x7f ] != WHITE_SPACE_ENC )
{
throw new java.io.IOException( "Invalid character in Base64 data." );
} // end else: not white space either
} // end else: decoding
} // end write
/**
* Calls write repeatedly until <var>len</var>
* bytes are written.
*
* @param theBytes array from which to read bytes
* @param off offset for array
* @param len max number of bytes to read into array
*/
public void write( byte[] theBytes, int off, int len ) throws java.io.IOException
{
// Encoding suspended?
if( suspendEncoding )
{
super.out.write( theBytes, off, len );
return;
} // end if: supsended
for( int i = 0; i < len; i++ )
{
write( theBytes[ off + i ] );
} // end for: each byte written
} // end write
/**
* Method added by PHIL. [Thanks, PHIL. -Rob]
* This pads the buffer without closing the stream.
*/
public void flushBase64() throws java.io.IOException
{
if( position > 0 )
{
if( encode )
{
out.write( encode3to4( b4, buffer, position ) );
position = 0;
} // end if: encoding
else
{
throw new java.io.IOException( "Base64 input not properly padded." );
} // end else: decoding
} // end if: buffer partially full
} // end flush
/**
* Flushes and closes (I think, in the superclass) the stream.
*
*/
public void close() throws java.io.IOException
{
// 1. Ensure that pending characters are written
flushBase64();
// 2. Actually close the stream
// Base class both flushes and closes.
super.close();
buffer = null;
out = null;
} // end close
/**
* Suspends encoding of the stream.
* May be helpful if you need to embed a piece of
* base640-encoded data in a stream.
*
*/
public void suspendEncoding() throws java.io.IOException
{
flushBase64();
this.suspendEncoding = true;
} // end suspendEncoding
/**
* Resumes encoding of the stream.
* May be helpful if you need to embed a piece of
* base640-encoded data in a stream.
*
*/
public void resumeEncoding()
{
this.suspendEncoding = false;
} // end resumeEncoding
} // end inner class OutputStream
} // end class Base64
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -