@ -25,14 +25,14 @@ import java.util.LinkedList;
@@ -25,14 +25,14 @@ import java.util.LinkedList;
/ * *
* A speedy alternative to { @link java . io . ByteArrayOutputStream } .
* < p > Unlike { @link java . io . ByteArrayOutputStream } , this implementation is backed by a
* { @link java . util . LinkedList } of byte [ ] instead of 1 constantly resizing byte [ ] .
* It does not copy buffers when it ' s expanded . < / p >
*
* < p > Unlike { @link java . io . ByteArrayOutputStream } , this implementation is backed
* by a { @link java . util . LinkedList } of { @code byte [ ] } instead of 1 constantly
* resizing { @code byte [ ] } . It does not copy buffers when it gets expanded .
*
* < p > The initial buffer is only created when the stream is first written .
* There ' s also no copying of the internal buffer if its contents is extracted with the
* { @link # writeTo ( OutputStream ) } method .
* Instances of this class are NOT THREAD SAFE . < / p >
* There is also no copying of the internal buffer if its contents is extracted
* with the { @link # writeTo ( OutputStream ) } method .
*
* @author Craig Andrews
* @since 4 . 2
@ -41,28 +41,30 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -41,28 +41,30 @@ public final class FastByteArrayOutputStream extends OutputStream {
private static final int DEFAULT_BLOCK_SIZE = 256 ;
// the buffers used to store the content bytes
// The buffers used to store the content bytes
private final LinkedList < byte [ ] > buffers = new LinkedList < byte [ ] > ( ) ;
// is the stream closed?
private boolean closed = false ;
// The size, in bytes, to use when allocating the first byte[]
private final int initialBlockSize ;
// The size, in bytes, to use when allocating the next next byte[]
private int nextBlockSize = 0 ;
// the size, in bytes, to use when allocating the next next byte[]
private int nextBlockSize ;
// The number of bytes in previous buffers.
// (The number of bytes in the current buffer is in 'index'.)
private int alreadyBufferedSize = 0 ;
// t he index in the byte[] found at buffers.getLast() to be written next
// T he index in the byte[] found at buffers.getLast() to be written next
private int index = 0 ;
// number of bytes in previous buffers
// the number of bytes in the current buffer is in index
private int alreadyBufferedSize = 0 ;
// Is the stream closed?
private boolean closed = false ;
// the size, in bytes, to use when allocating the first byte[]
private final int initialBlockSize ;
/ * *
* Create a new < code > FastByteArrayOutputStream < / code >
* with the default initial capacity of { @value # DEFAULT_BLOCK_SIZE } bytes .
* with the default initial capacity of 256 bytes .
* /
public FastByteArrayOutputStream ( ) {
this ( DEFAULT_BLOCK_SIZE ) ;
@ -76,20 +78,23 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -76,20 +78,23 @@ public final class FastByteArrayOutputStream extends OutputStream {
public FastByteArrayOutputStream ( int initialBlockSize ) {
Assert . isTrue ( initialBlockSize > 0 , "Initial block size must be greater than 0" ) ;
this . initialBlockSize = initialBlockSize ;
nextBlockSize = initialBlockSize ;
this . nextBlockSize = initialBlockSize ;
}
// Overridden methods
@Override
public void write ( int datum ) throws IOException {
if ( closed ) {
if ( this . closed ) {
throw new IOException ( "Stream closed" ) ;
}
else {
if ( buffers . peekLast ( ) = = null | | buffers . getLast ( ) . length = = index ) {
if ( this . buffers . peekLast ( ) = = null | | this . buffers . getLast ( ) . length = = this . index ) {
addBuffer ( 1 ) ;
}
// store the byte
buffers . getLast ( ) [ index + + ] = ( byte ) datum ;
this . buffers . getLast ( ) [ this . index + + ] = ( byte ) datum ;
}
}
@ -98,60 +103,81 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -98,60 +103,81 @@ public final class FastByteArrayOutputStream extends OutputStream {
if ( data = = null ) {
throw new NullPointerException ( ) ;
}
else if ( ( offset < 0 ) | | ( ( offset + length ) > data . length ) | | ( length < 0 ) ) {
else if ( offset < 0 | | offset + length > data . length | | length < 0 ) {
throw new IndexOutOfBoundsException ( ) ;
}
else if ( closed ) {
else if ( this . closed ) {
throw new IOException ( "Stream closed" ) ;
}
else {
if ( buffers . peekLast ( ) = = null | | buffers . getLast ( ) . length = = index ) {
if ( this . buffers . peekLast ( ) = = null | | this . buffers . getLast ( ) . length = = this . index ) {
addBuffer ( length ) ;
}
if ( ( index + length ) > buffers . getLast ( ) . length ) {
if ( this . index + length > this . buffers . getLast ( ) . length ) {
int pos = offset ;
do {
if ( index = = buffers . getLast ( ) . length ) {
if ( this . index = = this . buffers . getLast ( ) . length ) {
addBuffer ( length ) ;
}
int copyLength = buffers . getLast ( ) . length - index ;
int copyLength = this . buffers . getLast ( ) . length - this . index ;
if ( length < copyLength ) {
copyLength = length ;
}
System . arraycopy ( data , off set , buffers . getLast ( ) , index , copyLength ) ;
off set + = copyLength ;
index + = copyLength ;
System . arraycopy ( data , p os, this . buffers . getLast ( ) , this . index , copyLength ) ;
p os + = copyLength ;
this . index + = copyLength ;
length - = copyLength ;
} while ( length > 0 ) ;
}
while ( length > 0 ) ;
}
else {
// Copy in the sub array
System . arraycopy ( data , offset , buffers . getLast ( ) , index , length ) ;
index + = length ;
// copy in the sub- array
System . arraycopy ( data , offset , this . buffers . getLast ( ) , this . index , length ) ;
this . index + = length ;
}
}
}
@Override
public void close ( ) {
closed = true ;
this . closed = true ;
}
/ * *
* Returns the number of bytes stored in this < code > FastByteArrayOutputStream < / code >
* Convert the buffer ' s contents into a string decoding bytes using the
* platform ' s default character set . The length of the new < tt > String < / tt >
* is a function of the character set , and hence may not be equal to the
* size of the buffer .
* < p > This method always replaces malformed - input and unmappable - character
* sequences with the default replacement string for the platform ' s
* default character set . The { @linkplain java . nio . charset . CharsetDecoder }
* class should be used when more control over the decoding process is
* required .
* @return a String decoded from the buffer ' s contents
* /
@Override
public String toString ( ) {
return new String ( toByteArrayUnsafe ( ) ) ;
}
// Custom methods
/ * *
* Return the number of bytes stored in this < code > FastByteArrayOutputStream < / code > .
* /
public int size ( ) {
return alreadyBufferedSize + index ;
return ( this . alreadyBufferedSize + this . index ) ;
}
/ * *
* Convert the stream ' s data to a byte array and return the byte array .
*
* < p > Also replaces the internal structures with the byte array to conserve memory :
* if the byte array is being made anyways , mind as well as use it .
* This approach also means that if this method is called twice without any writes in between ,
* if the byte array is being made anyways , mind as well as use it . This approach
* also means that if this method is called twice without any writes in between ,
* the second call is a no - op .
* This method is "unsafe" as it returns the internal buffer - callers should not modify the returned buffer . < / p >
*
* < p > This method is "unsafe" as it returns the internal buffer .
* Callers should not modify the returned buffer .
* @return the current contents of this output stream , as a byte array .
* @see # size ( )
* @see # toByteArray ( )
@ -162,16 +188,14 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -162,16 +188,14 @@ public final class FastByteArrayOutputStream extends OutputStream {
return new byte [ 0 ] ;
}
resize ( totalSize ) ;
return buffers . getFirst ( ) ;
return this . buffers . getFirst ( ) ;
}
/ * *
* Creates a newly allocated byte array .
*
* < p > Its size is the current
* size of this output stream and the valid contents of the buffer
* have been copied into it . < / p >
*
* @return the current contents of this output stream , as a byte array .
* @see # size ( )
* @see # toByteArrayUnsafe ( )
@ -184,54 +208,49 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -184,54 +208,49 @@ public final class FastByteArrayOutputStream extends OutputStream {
}
/ * *
* Resets the contents of this < code > FastByteArrayOutputStreamInputStream < / code >
* Reset the contents of this < code > FastByteArrayOutputStream < / code > .
* < p > All currently accumulated output in the output stream is discarded .
* The output stream can be used again . < / p >
* The output stream can be used again .
* /
public void reset ( ) {
buffers . clear ( ) ;
nextBlockSize = initialBlockSize ;
closed = false ;
index = 0 ;
alreadyBufferedSize = 0 ;
this . buffers . clear ( ) ;
this . nextBlockSize = this . initialBlockSize ;
this . closed = false ;
this . index = 0 ;
this . alreadyBufferedSize = 0 ;
}
/ * *
* Get an { @link java . io . InputStream } to retrieve the data in this OutputStream
*
* Get an { @link InputStream } to retrieve the data in this OutputStream .
* < p > Note that if any methods are called on the OutputStream
* ( including , but not limited to , any of the write methods , { @link # reset ( ) } ,
* { @link # toByteArray ( ) } , and { @link # toByteArrayUnsafe ( ) } ) then the { @link java . io . InputStream } ' s
* behavior is undefined . < / p >
*
* @return { @link java . io . InputStream } of the contents of this < code > FastByteArrayOutputStreamInputStream < / code >
* { @link # toByteArray ( ) } , and { @link # toByteArrayUnsafe ( ) } ) then the
* { @link java . io . InputStream } ' s behavior is undefined .
* @return { @link InputStream } of the contents of this OutputStream
* /
public InputStream getInputStream ( ) {
return new FastByteArrayOutputStream InputStream ( this ) ;
return new FastByteArrayInputStream ( this ) ;
}
/ * *
* Write the buffers content to the given OutputStream
*
* Write the buffers content to the given OutputStream .
* @param out the OutputStream to write to
* /
public void writeTo ( OutputStream out ) throws IOException {
Iterator < byte [ ] > iter = buffers . iterator ( ) ;
while ( iter . hasNext ( ) ) {
byte [ ] bytes = iter . next ( ) ;
if ( iter . hasNext ( ) ) {
Iterator < byte [ ] > it = this . buffers . iterator ( ) ;
while ( it . hasNext ( ) ) {
byte [ ] bytes = it . next ( ) ;
if ( it . hasNext ( ) ) {
out . write ( bytes , 0 , bytes . length ) ;
}
else {
out . write ( bytes , 0 , index ) ;
out . write ( bytes , 0 , this . index ) ;
}
}
}
/ * *
* Resize the internal buffer size to a specified capacity .
*
* @param targetCapacity the desired size of the buffer
* @throws IllegalArgumentException if the given capacity is smaller than
* the actual size of the content stored in the buffer already
@ -240,54 +259,53 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -240,54 +259,53 @@ public final class FastByteArrayOutputStream extends OutputStream {
public void resize ( int targetCapacity ) {
Assert . isTrue ( targetCapacity > = size ( ) , "New capacity must not be smaller than current size" ) ;
if ( buffers . peekFirst ( ) = = null ) {
nextBlockSize = targetCapacity - size ( ) ;
this . nextBlockSize = targetCapacity - size ( ) ;
}
else if ( size ( ) = = targetCapacity & & buffers . getFirst ( ) . length = = targetCapacity ) {
else if ( size ( ) = = targetCapacity & & this . buffers . getFirst ( ) . length = = targetCapacity ) {
// do nothing - already at the targetCapacity
}
else {
int totalSize = size ( ) ;
byte [ ] data = new byte [ targetCapacity ] ;
int pos = 0 ;
Iterator < byte [ ] > iter = buffers . iterator ( ) ;
while ( iter . hasNext ( ) ) {
byte [ ] bytes = iter . next ( ) ;
if ( iter . hasNext ( ) ) {
Iterator < byte [ ] > it = this . buffers . iterator ( ) ;
while ( it . hasNext ( ) ) {
byte [ ] bytes = it . next ( ) ;
if ( it . hasNext ( ) ) {
System . arraycopy ( bytes , 0 , data , pos , bytes . length ) ;
pos + = bytes . length ;
}
else {
System . arraycopy ( bytes , 0 , data , pos , index ) ;
System . arraycopy ( bytes , 0 , data , pos , this . index ) ;
}
}
buffers . clear ( ) ;
buffers . add ( data ) ;
index = totalSize ;
alreadyBufferedSize = 0 ;
this . buffers . clear ( ) ;
this . buffers . add ( data ) ;
this . index = totalSize ;
this . alreadyBufferedSize = 0 ;
}
}
/ * *
* Create a new buffer and store it in the LinkedList
*
* < p > Adds a new buffer that can store at least { @code minCapacity } bytes < / p >
* < p > Adds a new buffer that can store at least { @code minCapacity } bytes .
* /
private void addBuffer ( int minCapacity ) {
if ( buffers . peekLast ( ) ! = null ) {
alreadyBufferedSize + = index ;
index = 0 ;
if ( this . buffers . peekLast ( ) ! = null ) {
this . alreadyBufferedSize + = this . index ;
this . index = 0 ;
}
if ( nextBlockSize < minCapacity ) {
nextBlockSize = nextPowerOf2 ( minCapacity ) ;
if ( this . nextBlockSize < minCapacity ) {
this . nextBlockSize = nextPowerOf2 ( minCapacity ) ;
}
buffers . add ( new byte [ nextBlockSize ] ) ;
nextBlockSize * = 2 ; // block size doubles each time
this . buffers . add ( new byte [ this . nextBlockSize ] ) ;
this . nextBlockSize * = 2 ; // block size doubles each time
}
/ * *
* Get the next power of 2 of a number ( ex , the next power of 2 of 119 is 128 )
* Get the next power of 2 of a number ( ex , the next power of 2 of 119 is 128 ) .
* /
private static final int nextPowerOf2 ( int val ) {
private static int nextPowerOf2 ( int val ) {
val - - ;
val = ( val > > 1 ) | val ;
val = ( val > > 2 ) | val ;
@ -298,88 +316,67 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -298,88 +316,67 @@ public final class FastByteArrayOutputStream extends OutputStream {
return val ;
}
/ * *
* Converts the buffer ' s contents into a string decoding bytes using the
* platform ' s default character set . The length of the new < tt > String < / tt >
* is a function of the character set , and hence may not be equal to the
* size of the buffer .
*
* < p > This method always replaces malformed - input and unmappable - character
* sequences with the default replacement string for the platform ' s
* default character set . The { @linkplain java . nio . charset . CharsetDecoder }
* class should be used when more control over the decoding process is
* required . < / p >
*
* @return String decoded from the buffer ' s contents .
* /
@Override
public String toString ( ) {
return new String ( toByteArrayUnsafe ( ) ) ;
}
/ * *
* An implementation of { @link java . io . InputStream } that reads from < code > FastByteArrayOutputStream < / code >
* Instances of this class are NOT THREAD SAFE .
* An implementation of { @link java . io . InputStream } that reads from a given
* < code > FastByteArrayOutputStream < / code > .
* /
private static final class FastByteArrayOutputStreamInputStream extends UpdateMessageDigestInputStream {
int totalBytesRead = 0 ;
private static final class FastByteArrayInputStream extends UpdateMessageDigestInputStream {
private final FastByteArrayOutputStream fastByteArrayOutputStream ;
int nextIndexInCurrentBuffer = 0 ;
private final Iterator < byte [ ] > buffersIterator ;
final Iterator < byte [ ] > buffersIterato r;
private byte [ ] currentBuffer ;
byte [ ] currentBuffer ;
private int currentBufferLength = 0 ;
int currentBufferLength ;
private int nextIndexInCurrentBuffer = 0 ;
final FastByteArrayOutputStream fastByteArrayOutputStream ;
private int totalBytesRead = 0 ;
/ * *
* Create a new < code > FastByteArrayOutputStreamInputStream < / code > backed
* by the given < code > FastByteArrayOutputStream < / code >
* by the given < code > FastByteArrayOutputStream < / code > .
* /
public FastByteArrayOutputStream InputStream ( FastByteArrayOutputStream fastByteArrayOutputStream ) {
public FastByteArrayInputStream ( FastByteArrayOutputStream fastByteArrayOutputStream ) {
this . fastByteArrayOutputStream = fastByteArrayOutputStream ;
buffersIterator = fastByteArrayOutputStream . buffers . iterator ( ) ;
if ( buffersIterator . hasNext ( ) ) {
currentBuffer = buffersIterator . next ( ) ;
if ( currentBuffer = = fastByteArrayOutputStream . buffers . getLast ( ) ) {
currentBufferLength = fastByteArrayOutputStream . index ;
this . buffersIterator = fastByteArrayOutputStream . buffers . iterator ( ) ;
if ( this . buffersIterator . hasNext ( ) ) {
this . currentBuffer = this . buffersIterator . next ( ) ;
if ( this . currentBuffer = = fastByteArrayOutputStream . buffers . getLast ( ) ) {
this . currentBufferLength = fastByteArrayOutputStream . index ;
}
else {
currentBufferLength = currentBuffer . length ;
this . currentBufferLength = this . currentBuffer . length ;
}
}
else {
currentBuffer = null ;
}
}
@Override
public int read ( ) {
if ( currentBuffer = = null ) {
if ( this . currentBuffer = = null ) {
// this stream doesn't have any data in it
return - 1 ;
}
else {
if ( nextIndexInCurrentBuffer < currentBufferLength ) {
totalBytesRead + + ;
return currentBuffer [ nextIndexInCurrentBuffer + + ] ;
if ( this . nextIndexInCurrentBuffer < this . currentBufferLength ) {
this . totalBytesRead + + ;
return this . currentBuffer [ this . nextIndexInCurrentBuffer + + ] ;
}
else {
if ( buffersIterator . hasNext ( ) ) {
currentBuffer = buffersIterator . next ( ) ;
if ( currentBuffer = = fastByteArrayOutputStream . buffers . getLast ( ) ) {
currentBufferLength = fastByteArrayOutputStream . index ;
if ( this . buffersIterator . hasNext ( ) ) {
this . currentBuffer = this . buffersIterator . next ( ) ;
if ( this . currentBuffer = = this . fastByteArrayOutputStream . buffers . getLast ( ) ) {
this . currentBufferLength = this . fastByteArrayOutputStream . index ;
}
else {
currentBufferLength = currentBuffer . length ;
this . currentBufferLength = this . currentBuffer . length ;
}
nextIndexInCurrentBuffer = 0 ;
this . nextIndexInCurrentBuffer = 0 ;
}
else {
currentBuffer = null ;
this . currentBuffer = null ;
}
return read ( ) ;
}
@ -409,31 +406,31 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -409,31 +406,31 @@ public final class FastByteArrayOutputStream extends OutputStream {
throw new IllegalArgumentException ( "off must be 0 or greater: " + off ) ;
}
else {
if ( currentBuffer = = null ) {
if ( this . currentBuffer = = null ) {
// this stream doesn't have any data in it
return 0 ;
}
else {
if ( nextIndexInCurrentBuffer < currentBufferLength ) {
int bytesToCopy = Math . min ( len , currentBufferLength - nextIndexInCurrentBuffer ) ;
System . arraycopy ( currentBuffer , nextIndexInCurrentBuffer , b , off , bytesToCopy ) ;
totalBytesRead + = bytesToCopy ;
nextIndexInCurrentBuffer + = bytesToCopy ;
return bytesToCopy + read ( b , off + bytesToCopy , len - bytesToCopy ) ;
if ( this . nextIndexInCurrentBuffer < this . currentBufferLength ) {
int bytesToCopy = Math . min ( len , this . currentBufferLength - this . nextIndexInCurrentBuffer ) ;
System . arraycopy ( this . currentBuffer , this . nextIndexInCurrentBuffer , b , off , bytesToCopy ) ;
this . totalBytesRead + = bytesToCopy ;
this . nextIndexInCurrentBuffer + = bytesToCopy ;
return ( bytesToCopy + read ( b , off + bytesToCopy , len - bytesToCopy ) ) ;
}
else {
if ( buffersIterator . hasNext ( ) ) {
currentBuffer = buffersIterator . next ( ) ;
if ( currentBuffer = = fastByteArrayOutputStream . buffers . getLast ( ) ) {
currentBufferLength = fastByteArrayOutputStream . index ;
if ( this . buffersIterator . hasNext ( ) ) {
this . currentBuffer = this . buffersIterator . next ( ) ;
if ( this . currentBuffer = = this . fastByteArrayOutputStream . buffers . getLast ( ) ) {
this . currentBufferLength = this . fastByteArrayOutputStream . index ;
}
else {
currentBufferLength = currentBuffer . length ;
this . currentBufferLength = this . currentBuffer . length ;
}
nextIndexInCurrentBuffer = 0 ;
this . nextIndexInCurrentBuffer = 0 ;
}
else {
currentBuffer = null ;
this . currentBuffer = null ;
}
return read ( b , off , len ) ;
}
@ -444,8 +441,7 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -444,8 +441,7 @@ public final class FastByteArrayOutputStream extends OutputStream {
@Override
public long skip ( long n ) throws IOException {
if ( n > Integer . MAX_VALUE ) {
throw new IllegalArgumentException ( "n exceeds maximum (" +
Integer . MAX_VALUE + "): " + n ) ;
throw new IllegalArgumentException ( "n exceeds maximum (" + Integer . MAX_VALUE + "): " + n ) ;
}
else if ( n = = 0 ) {
return 0 ;
@ -454,30 +450,30 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -454,30 +450,30 @@ public final class FastByteArrayOutputStream extends OutputStream {
throw new IllegalArgumentException ( "n must be 0 or greater: " + n ) ;
}
int len = ( int ) n ;
if ( currentBuffer = = null ) {
if ( this . currentBuffer = = null ) {
// this stream doesn't have any data in it
return 0 ;
}
else {
if ( nextIndexInCurrentBuffer < currentBufferLength ) {
int bytesToSkip = Math . min ( len , currentBufferLength - nextIndexInCurrentBuffer ) ;
totalBytesRead + = bytesToSkip ;
nextIndexInCurrentBuffer + = bytesToSkip ;
return bytesToSkip + skip ( len - bytesToSkip ) ;
if ( this . nextIndexInCurrentBuffer < this . currentBufferLength ) {
int bytesToSkip = Math . min ( len , this . currentBufferLength - this . nextIndexInCurrentBuffer ) ;
this . totalBytesRead + = bytesToSkip ;
this . nextIndexInCurrentBuffer + = bytesToSkip ;
return ( bytesToSkip + skip ( len - bytesToSkip ) ) ;
}
else {
if ( buffersIterator . hasNext ( ) ) {
currentBuffer = buffersIterator . next ( ) ;
if ( currentBuffer = = fastByteArrayOutputStream . buffers . getLast ( ) ) {
currentBufferLength = fastByteArrayOutputStream . index ;
if ( this . buffersIterator . hasNext ( ) ) {
this . currentBuffer = this . buffersIterator . next ( ) ;
if ( this . currentBuffer = = this . fastByteArrayOutputStream . buffers . getLast ( ) ) {
this . currentBufferLength = this . fastByteArrayOutputStream . index ;
}
else {
currentBufferLength = currentBuffer . length ;
this . currentBufferLength = this . currentBuffer . length ;
}
nextIndexInCurrentBuffer = 0 ;
this . nextIndexInCurrentBuffer = 0 ;
}
else {
currentBuffer = null ;
this . currentBuffer = null ;
}
return skip ( len ) ;
}
@ -486,12 +482,11 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -486,12 +482,11 @@ public final class FastByteArrayOutputStream extends OutputStream {
@Override
public int available ( ) {
return fastByteArrayOutputStream . size ( ) - totalBytesRead ;
return ( this . fastByteArrayOutputStream . size ( ) - this . totalBytesRead ) ;
}
/ * *
* Update the message digest with the remaining bytes in this stream .
*
* @param messageDigest The message digest to update
* /
public void updateMessageDigest ( MessageDigest messageDigest ) {
@ -505,7 +500,7 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -505,7 +500,7 @@ public final class FastByteArrayOutputStream extends OutputStream {
* @param len how many bytes to read from this stream and use to update the message digest
* /
public void updateMessageDigest ( MessageDigest messageDigest , int len ) {
if ( currentBuffer = = null ) {
if ( this . currentBuffer = = null ) {
// this stream doesn't have any data in it
return ;
}
@ -516,29 +511,30 @@ public final class FastByteArrayOutputStream extends OutputStream {
@@ -516,29 +511,30 @@ public final class FastByteArrayOutputStream extends OutputStream {
throw new IllegalArgumentException ( "len must be 0 or greater: " + len ) ;
}
else {
if ( nextIndexInCurrentBuffer < currentBufferLength ) {
int bytesToCopy = Math . min ( len , currentBufferLength - nextIndexInCurrentBuffer ) ;
messageDigest . update ( currentBuffer , nextIndexInCurrentBuffer , bytesToCopy ) ;
nextIndexInCurrentBuffer + = bytesToCopy ;
if ( this . nextIndexInCurrentBuffer < this . currentBufferLength ) {
int bytesToCopy = Math . min ( len , this . currentBufferLength - this . nextIndexInCurrentBuffer ) ;
messageDigest . update ( this . currentBuffer , this . nextIndexInCurrentBuffer , bytesToCopy ) ;
this . nextIndexInCurrentBuffer + = bytesToCopy ;
updateMessageDigest ( messageDigest , len - bytesToCopy ) ;
}
else {
if ( buffersIterator . hasNext ( ) ) {
currentBuffer = buffersIterator . next ( ) ;
if ( currentBuffer = = fastByteArrayOutputStream . buffers . getLast ( ) ) {
currentBufferLength = fastByteArrayOutputStream . index ;
if ( this . buffersIterator . hasNext ( ) ) {
this . currentBuffer = this . buffersIterator . next ( ) ;
if ( this . currentBuffer = = this . fastByteArrayOutputStream . buffers . getLast ( ) ) {
this . currentBufferLength = this . fastByteArrayOutputStream . index ;
}
else {
currentBufferLength = currentBuffer . length ;
this . currentBufferLength = this . currentBuffer . length ;
}
nextIndexInCurrentBuffer = 0 ;
this . nextIndexInCurrentBuffer = 0 ;
}
else {
currentBuffer = null ;
this . currentBuffer = null ;
}
updateMessageDigest ( messageDigest , len ) ;
}
}
}
}
}