📄 base64.java
字号:
numBinaryBytes++; } // end if: not end of stream } // end try: read catch( java.io.IOException e ) { // Only a problem if we got no data at all. if( i == 0 ) throw e; } // end catch } // end for: each needed input byte if( numBinaryBytes > 0 ) { encode3to4( b3, 0, numBinaryBytes, buffer, 0 ); position = 0; numSigBytes = 4; } // end if: got data else { return -1; } // 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 b4[i] = (byte)b; } // end for: each needed input byte 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 {@link #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. * @since 1.3 */ 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 ******** */ /** * A {@link Base64.OutputStream} will write data to another * <tt>java.io.OutputStream</tt>, given in the constructor, * and encode/decode to/from Base64 notation on the fly. * * @see Base64 * @since 1.3 */ public static class OutputStream extends java.io.FilterOutputStream { 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 a {@link Base64.OutputStream} in ENCODE mode. * * @param out the <tt>java.io.OutputStream</tt> to which data will be written. * @since 1.3 */ public OutputStream( java.io.OutputStream out ) { this( out, ENCODE ); } // end constructor /** * Constructs a {@link Base64.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 <tt>java.io.OutputStream</tt> to which data will be written. * @param options Specified options. * @see Base64#ENCODE * @see Base64#DECODE * @see Base64#DONT_BREAK_LINES * @since 1.3 */ public OutputStream( java.io.OutputStream out, int options ) { super( out ); 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 * @since 1.3 */ 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 {@link #write(int)} 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 * @since 1.3 */ 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. * * @since 1.3 */ 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. * * @since 1.5.1 */ 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. * * @since 1.5.1 */ 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 + -