📄 base64.java
字号:
} // 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
*/
@Override
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
* {@link java.io.OutputStream}, given in the constructor, and
* encode/decode to/from Base64 notation on the fly.
*
* @see Base64
* @see java.io.FilterOutputStream
* @since 1.3
*/
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 a {@link Base64#OutputStream} in ENCODE mode.
*
* @param out
* the {@link java.io.OutputStream} 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 {@link java.io.OutputStream} 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.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
* @since 1.3
*/
@Override
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} 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
*/
@Override
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
*/
@Override
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 + -