db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r899819 - in /db/derby/code/trunk/java: client/org/apache/derby/client/net/ engine/org/apache/derby/iapi/services/io/ shared/org/apache/derby/shared/common/io/
Date Fri, 15 Jan 2010 21:32:14 GMT
Author: rhillegas
Date: Fri Jan 15 21:32:14 2010
New Revision: 899819

URL: http://svn.apache.org/viewvc?rev=899819&view=rev
Log:
DERBY-4491: Fix sealing violation which kills the AssertFailureTest on runs against insane
jar files.

Added:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/DynamicByteArrayOutputStream.java
  (with props)
    db/derby/code/trunk/java/client/org/apache/derby/client/net/InputStreamUtil.java   (with
props)
Removed:
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/
Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java

Added: db/derby/code/trunk/java/client/org/apache/derby/client/net/DynamicByteArrayOutputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/DynamicByteArrayOutputStream.java?rev=899819&view=auto
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/DynamicByteArrayOutputStream.java
(added)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/DynamicByteArrayOutputStream.java
Fri Jan 15 21:32:14 2010
@@ -0,0 +1,250 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.DynamicByteArrayOutputStream
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.client.net;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+	A DynamicByteArrayOutputStream allows writing to a dynamically resizable
+	array of bytes.   In addition to dynamic resizing, this extension allows
+	the user of this class to have more control over the position of the stream
+	and can get a direct reference of the array.
+
+    This code is cloned from org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream
+    for use by the client.
+*/
+public class DynamicByteArrayOutputStream extends OutputStream {
+
+	private static int INITIAL_SIZE = 4096;
+
+	private byte[] buf;
+	private int		position;
+	private int		used;		// how many bytes are used
+	private int		beginPosition;
+
+	public DynamicByteArrayOutputStream() {
+		this(INITIAL_SIZE);
+	}
+
+	public DynamicByteArrayOutputStream(int size) {
+		super();
+
+		buf = new byte[size];
+	}
+
+	public DynamicByteArrayOutputStream(byte[] data) {
+		super();
+
+		buf = data;
+	}
+
+	public DynamicByteArrayOutputStream(DynamicByteArrayOutputStream toBeCloned) {
+
+		byte[] cbuf = toBeCloned.getByteArray();
+		buf = new byte[cbuf.length];
+
+		write(cbuf, 0, cbuf.length);
+		position = toBeCloned.getPosition();
+		used = toBeCloned.getUsed();
+		beginPosition = toBeCloned.getBeginPosition();
+	}
+
+	/*
+	 *	OutputStream methods
+	 */
+	public void write(int b) 
+	{
+		if (position >= buf.length)
+			expandBuffer(INITIAL_SIZE);
+
+		buf[position++] = (byte) b;
+
+		if (position > used)
+			used = position;
+	}
+	
+	public void write(byte[] b, int off, int len) 
+	{
+		if ((position+len) > buf.length)
+			expandBuffer(len);
+
+		System.arraycopy(b, off, buf, position, len);
+		position += len;
+
+		if (position > used)
+			used = position;
+	}
+
+	void writeCompleteStream(InputStream dataIn, int len) throws IOException
+	{
+		if ((position+len) > buf.length)
+			expandBuffer(len);
+
+		InputStreamUtil.readFully(dataIn, buf, position, len);
+		position += len;
+
+		if (position > used)
+			used = position;
+	}
+
+	public void close()
+	{
+		buf = null;
+		reset();
+	}
+
+	/*
+	 *	Specific methods
+	 */
+
+	/**
+		Reset the stream for reuse
+	*/
+	public void reset()
+	{
+		position = 0;
+		beginPosition = 0;
+		used = 0;
+	}
+
+	/**
+		Get a reference to the byte array stored in the byte array output
+		stream. Note that the byte array may be longer that getPosition().
+		Bytes beyond and including the current poistion are invalid.
+	*/
+	public byte[] getByteArray()
+	{
+		return buf;
+	}
+
+	/**
+		Get the number of bytes that was used.
+	*/
+	public int getUsed()
+	{
+		return used;
+	}
+
+	/**
+		Get the current position in the stream
+	*/
+	public int getPosition()
+	{
+		return position;
+	}
+
+	/**
+		Get the current position in the stream
+	*/
+	public int getBeginPosition()
+	{
+		return beginPosition;
+	}
+
+	/**
+		Set the position of the stream pointer.
+		It is up to the caller to make sure the stream has no gap of garbage in
+		it or useful information is not left out at the end because the stream
+		does not remember anything about the previous position.
+	*/
+	public void setPosition(int newPosition)
+	{
+		if (newPosition > position)
+		{
+			if (newPosition > buf.length)
+				expandBuffer(newPosition - buf.length);
+		}
+
+		position = newPosition;
+
+		if (position > used)
+			used = position;
+
+		return ;
+	}
+
+	/**
+		Set the begin position of the stream pointer.
+		If the newBeginPosition is larger than the stream itself,
+		then, the begin position is not set.
+	*/
+	public void setBeginPosition(int newBeginPosition)
+	{
+
+		if (newBeginPosition > buf.length)
+			return;
+
+		beginPosition = newBeginPosition;
+	}
+
+	/**
+		Shrink the buffer left by the amount given. Ie.
+		bytes from 0 to amountToShrinkBy are thrown away
+	*/
+	public void discardLeft(int amountToShrinkBy) {
+
+		System.arraycopy(buf, amountToShrinkBy, buf, 0,
+			used - amountToShrinkBy);
+
+		position -= amountToShrinkBy;
+		used -= amountToShrinkBy;
+	}
+
+	/**
+		Expand the buffer by at least the number of bytes requested in minExtension.
+
+		To optimize performance and reduce memory copies and allocation, we have a staged buffer
+		expansion.
+
+		<UL>
+		<LI> buf.length < 128k - increase by 4k
+		<LI> buf.length < 1Mb - increase by 128k
+		<LI> otherwise increase by 1Mb.
+		</UL>
+
+		In all cases, if minExpansion is greater than the value about then the buffer will
+		be increased by minExtension.
+	*/
+	private void expandBuffer(int minExtension)
+	{
+		if (buf.length < (128 * 1024)) {
+			if (minExtension < INITIAL_SIZE)
+				minExtension = INITIAL_SIZE;
+		} else if (buf.length < (1024 * 1024)) {
+
+			if (minExtension < (128 * 1024))
+				minExtension = (128 * 1024);
+		} else {
+			if (minExtension < (1024 * 1024))
+				minExtension = 1024 * 1024;
+		}
+
+		int newsize = buf.length + minExtension;
+
+		byte[] newbuf = new byte[newsize];
+		System.arraycopy(buf, 0, newbuf, 0, buf.length);
+		buf = newbuf;
+	}
+
+}

Propchange: db/derby/code/trunk/java/client/org/apache/derby/client/net/DynamicByteArrayOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/client/org/apache/derby/client/net/InputStreamUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/InputStreamUtil.java?rev=899819&view=auto
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/InputStreamUtil.java (added)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/InputStreamUtil.java Fri Jan
15 21:32:14 2010
@@ -0,0 +1,186 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.InputStreamUtil
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.client.net;
+
+import java.io.*;
+
+/**
+	Utility methods for InputStream that are stand-ins for
+	a small subset of DataInput methods. This avoids pushing
+	a DataInputStream just to get this functionality.
+
+    This code is cloned from org.apache.derby.iapi.services.io.InputStreamUtil
+    for use by the client.
+*/
+public final class InputStreamUtil {
+    private static final int SKIP_FRAGMENT_SIZE = Integer.MAX_VALUE;
+
+	/**
+		Read an unsigned byte from an InputStream, throwing an EOFException
+		if the end of the input is reached.
+
+		@exception IOException if an I/O error occurs.
+		@exception EOFException if the end of the stream is reached
+
+		@see DataInput#readUnsignedByte
+	
+	*/
+	public static int readUnsignedByte(InputStream in) throws IOException {
+		int b = in.read();
+		if (b < 0)
+			throw new EOFException();
+
+		return b;
+	}
+
+	/**
+		Read a number of bytes into an array.
+
+		@exception IOException if an I/O error occurs.
+		@exception EOFException if the end of the stream is reached
+
+		@see DataInput#readFully
+
+	*/
+	public static void readFully(InputStream in, byte b[],
+                                 int offset,
+                                 int len) throws IOException
+	{
+		do {
+			int bytesRead = in.read(b, offset, len);
+			if (bytesRead < 0)
+				throw new EOFException();
+			len -= bytesRead;
+			offset += bytesRead;
+		} while (len != 0);
+	}
+
+
+	/**
+		Read a number of bytes into an array.
+        Keep reading in a loop until len bytes are read or EOF is reached or
+        an exception is thrown. Return the number of bytes read.
+        (InputStream.read(byte[],int,int) does not guarantee to read len bytes
+         even if it can do so without reaching EOF or raising an exception.)
+
+		@exception IOException if an I/O error occurs.
+	*/
+	public static int readLoop(InputStream in,
+                                byte b[],
+                                int offset,
+                                int len)
+        throws IOException
+	{
+        int firstOffset = offset;
+		do {
+			int bytesRead = in.read(b, offset, len);
+			if (bytesRead <= 0)
+                break;
+			len -= bytesRead;
+			offset += bytesRead;
+		} while (len != 0);
+        return offset - firstOffset;
+	}
+
+    /**
+     * Skips until EOF, returns number of bytes skipped.
+     * @param is
+     *      InputStream to be skipped.
+     * @return
+     *      number of bytes skipped in fact.
+     * @throws IOException
+     *      if IOException occurs. It doesn't contain EOFException.
+     * @throws NullPointerException
+     *      if the param 'is' equals null.
+     */
+    public static long skipUntilEOF(InputStream is) throws IOException {
+        if(is == null)
+            throw new NullPointerException();
+
+        long bytes = 0;
+        while(true){
+            long r = skipPersistent(is, SKIP_FRAGMENT_SIZE);
+            bytes += r;
+            if(r < SKIP_FRAGMENT_SIZE)
+                return bytes;
+        }
+    }
+
+    /**
+     * Skips requested number of bytes,
+     * throws EOFException if there is too few bytes in the stream.
+     * @param is
+     *      InputStream to be skipped.
+     * @param skippedBytes
+     *      number of bytes to skip. if skippedBytes <= zero, do nothing.
+     * @throws EOFException
+     *      if EOF meets before requested number of bytes are skipped.
+     * @throws IOException
+     *      if IOException occurs. It doesn't contain EOFException.
+     * @throws NullPointerException
+     *      if the param 'is' equals null.
+     */
+    public static void skipFully(InputStream is, long skippedBytes)
+    throws IOException {
+        if(is == null)
+            throw new NullPointerException();
+
+        if(skippedBytes <= 0)
+            return;
+
+        long bytes = skipPersistent(is, skippedBytes);
+
+        if(bytes < skippedBytes)
+            throw new EOFException();
+    }
+
+    /**
+     * Tries harder to skip the requested number of bytes.
+     * <p>
+     * Note that even if the method fails to skip the requested number of bytes,
+     * it will not throw an exception. If this happens, the caller can be sure
+     * that end-of-stream has been reached.
+     *
+     * @param in byte stream
+     * @param bytesToSkip the number of bytes to skip
+     * @return The number of bytes skipped.
+     * @throws IOException if reading from the stream fails
+     */
+    public static final long skipPersistent(InputStream in, long bytesToSkip)
+    throws IOException {
+        long skipped = 0;
+        while (skipped < bytesToSkip) {
+            long skippedNow = in.skip(bytesToSkip - skipped);
+            if (skippedNow == 0) {
+                if (in.read() == -1) {
+                    // EOF, return what we have and leave it up to caller to
+                    // decide what to do about it.
+                    break;
+                } else {
+                    skippedNow = 1; // Added to count below.
+                }
+            }
+            skipped += skippedNow;
+        }
+        return skipped;
+    }
+}

Propchange: db/derby/code/trunk/java/client/org/apache/derby/client/net/InputStreamUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java?rev=899819&r1=899818&r2=899819&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java Fri Jan 15 21:32:14
2010
@@ -23,9 +23,7 @@
 import org.apache.derby.client.am.DisconnectException;
 import org.apache.derby.client.am.ClientMessageId;
 import org.apache.derby.client.am.SqlException;
-import org.apache.derby.shared.common.io.DynamicByteArrayOutputStream;
 import org.apache.derby.shared.common.reference.SQLState;
-import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.reference.DRDAConstants;
 
 import java.io.BufferedInputStream;
@@ -1620,14 +1618,9 @@
         offset_ += bytesToCopy;
     }
 
+    // should not be called if val is null
     final void writeUDT( Object val ) throws SqlException
     {
-        // should not be called if val is null
-        if ( val == null )
-        {
-            SanityManager.THROWASSERT( "UDT is null" );
-        }
-
         byte[] buffer = null;
         int length = 0;
         

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java?rev=899819&r1=899818&r2=899819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java
Fri Jan 15 21:32:14 2010
@@ -33,10 +33,217 @@
 	the user of this class to have more control over the position of the stream
 	and can get a direct reference of the array.
 */
-public class DynamicByteArrayOutputStream extends org.apache.derby.shared.common.io.DynamicByteArrayOutputStream
-{
-	public DynamicByteArrayOutputStream() { super(); }
-	public DynamicByteArrayOutputStream(int size) { super( size ); }
-	public DynamicByteArrayOutputStream(byte[] data) { super( data ); }
-	public DynamicByteArrayOutputStream(DynamicByteArrayOutputStream toBeCloned) { super( toBeCloned
); }
+public class DynamicByteArrayOutputStream extends OutputStream {
+
+	private static int INITIAL_SIZE = 4096;
+
+	private byte[] buf;
+	private int		position;
+	private int		used;		// how many bytes are used
+	private int		beginPosition;
+
+	public DynamicByteArrayOutputStream() {
+		this(INITIAL_SIZE);
+	}
+
+	public DynamicByteArrayOutputStream(int size) {
+		super();
+
+		buf = new byte[size];
+	}
+
+	public DynamicByteArrayOutputStream(byte[] data) {
+		super();
+
+		buf = data;
+	}
+
+	public DynamicByteArrayOutputStream(DynamicByteArrayOutputStream toBeCloned) {
+
+		byte[] cbuf = toBeCloned.getByteArray();
+		buf = new byte[cbuf.length];
+
+		write(cbuf, 0, cbuf.length);
+		position = toBeCloned.getPosition();
+		used = toBeCloned.getUsed();
+		beginPosition = toBeCloned.getBeginPosition();
+	}
+
+	/*
+	 *	OutputStream methods
+	 */
+	public void write(int b) 
+	{
+		if (position >= buf.length)
+			expandBuffer(INITIAL_SIZE);
+
+		buf[position++] = (byte) b;
+
+		if (position > used)
+			used = position;
+	}
+	
+	public void write(byte[] b, int off, int len) 
+	{
+		if ((position+len) > buf.length)
+			expandBuffer(len);
+
+		System.arraycopy(b, off, buf, position, len);
+		position += len;
+
+		if (position > used)
+			used = position;
+	}
+
+	void writeCompleteStream(InputStream dataIn, int len) throws IOException
+	{
+		if ((position+len) > buf.length)
+			expandBuffer(len);
+
+		org.apache.derby.iapi.services.io.InputStreamUtil.readFully(dataIn, buf, position, len);
+		position += len;
+
+		if (position > used)
+			used = position;
+	}
+
+	public void close()
+	{
+		buf = null;
+		reset();
+	}
+
+	/*
+	 *	Specific methods
+	 */
+
+	/**
+		Reset the stream for reuse
+	*/
+	public void reset()
+	{
+		position = 0;
+		beginPosition = 0;
+		used = 0;
+	}
+
+	/**
+		Get a reference to the byte array stored in the byte array output
+		stream. Note that the byte array may be longer that getPosition().
+		Bytes beyond and including the current poistion are invalid.
+	*/
+	public byte[] getByteArray()
+	{
+		return buf;
+	}
+
+	/**
+		Get the number of bytes that was used.
+	*/
+	public int getUsed()
+	{
+		return used;
+	}
+
+	/**
+		Get the current position in the stream
+	*/
+	public int getPosition()
+	{
+		return position;
+	}
+
+	/**
+		Get the current position in the stream
+	*/
+	public int getBeginPosition()
+	{
+		return beginPosition;
+	}
+
+	/**
+		Set the position of the stream pointer.
+		It is up to the caller to make sure the stream has no gap of garbage in
+		it or useful information is not left out at the end because the stream
+		does not remember anything about the previous position.
+	*/
+	public void setPosition(int newPosition)
+	{
+		if (newPosition > position)
+		{
+			if (newPosition > buf.length)
+				expandBuffer(newPosition - buf.length);
+		}
+
+		position = newPosition;
+
+		if (position > used)
+			used = position;
+
+		return ;
+	}
+
+	/**
+		Set the begin position of the stream pointer.
+		If the newBeginPosition is larger than the stream itself,
+		then, the begin position is not set.
+	*/
+	public void setBeginPosition(int newBeginPosition)
+	{
+
+		if (newBeginPosition > buf.length)
+			return;
+
+		beginPosition = newBeginPosition;
+	}
+
+	/**
+		Shrink the buffer left by the amount given. Ie.
+		bytes from 0 to amountToShrinkBy are thrown away
+	*/
+	public void discardLeft(int amountToShrinkBy) {
+
+		System.arraycopy(buf, amountToShrinkBy, buf, 0,
+			used - amountToShrinkBy);
+
+		position -= amountToShrinkBy;
+		used -= amountToShrinkBy;
+	}
+
+	/**
+		Expand the buffer by at least the number of bytes requested in minExtension.
+
+		To optimize performance and reduce memory copies and allocation, we have a staged buffer
+		expansion.
+
+		<UL>
+		<LI> buf.length < 128k - increase by 4k
+		<LI> buf.length < 1Mb - increase by 128k
+		<LI> otherwise increase by 1Mb.
+		</UL>
+
+		In all cases, if minExpansion is greater than the value about then the buffer will
+		be increased by minExtension.
+	*/
+	private void expandBuffer(int minExtension)
+	{
+		if (buf.length < (128 * 1024)) {
+			if (minExtension < INITIAL_SIZE)
+				minExtension = INITIAL_SIZE;
+		} else if (buf.length < (1024 * 1024)) {
+
+			if (minExtension < (128 * 1024))
+				minExtension = (128 * 1024);
+		} else {
+			if (minExtension < (1024 * 1024))
+				minExtension = 1024 * 1024;
+		}
+
+		int newsize = buf.length + minExtension;
+
+		byte[] newbuf = new byte[newsize];
+		System.arraycopy(buf, 0, newbuf, 0, buf.length);
+		buf = newbuf;
+	}
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java?rev=899819&r1=899818&r2=899819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java
Fri Jan 15 21:32:14 2010
@@ -28,5 +28,156 @@
 	a small subset of DataInput methods. This avoids pushing
 	a DataInputStream just to get this functionality.
 */
-public final class InputStreamUtil extends org.apache.derby.shared.common.io.InputStreamUtil
-{}
+public final class InputStreamUtil {
+    private static final int SKIP_FRAGMENT_SIZE = Integer.MAX_VALUE;
+
+	/**
+		Read an unsigned byte from an InputStream, throwing an EOFException
+		if the end of the input is reached.
+
+		@exception IOException if an I/O error occurs.
+		@exception EOFException if the end of the stream is reached
+
+		@see DataInput#readUnsignedByte
+	
+	*/
+	public static int readUnsignedByte(InputStream in) throws IOException {
+		int b = in.read();
+		if (b < 0)
+			throw new EOFException();
+
+		return b;
+	}
+
+	/**
+		Read a number of bytes into an array.
+
+		@exception IOException if an I/O error occurs.
+		@exception EOFException if the end of the stream is reached
+
+		@see DataInput#readFully
+
+	*/
+	public static void readFully(InputStream in, byte b[],
+                                 int offset,
+                                 int len) throws IOException
+	{
+		do {
+			int bytesRead = in.read(b, offset, len);
+			if (bytesRead < 0)
+				throw new EOFException();
+			len -= bytesRead;
+			offset += bytesRead;
+		} while (len != 0);
+	}
+
+
+	/**
+		Read a number of bytes into an array.
+        Keep reading in a loop until len bytes are read or EOF is reached or
+        an exception is thrown. Return the number of bytes read.
+        (InputStream.read(byte[],int,int) does not guarantee to read len bytes
+         even if it can do so without reaching EOF or raising an exception.)
+
+		@exception IOException if an I/O error occurs.
+	*/
+	public static int readLoop(InputStream in,
+                                byte b[],
+                                int offset,
+                                int len)
+        throws IOException
+	{
+        int firstOffset = offset;
+		do {
+			int bytesRead = in.read(b, offset, len);
+			if (bytesRead <= 0)
+                break;
+			len -= bytesRead;
+			offset += bytesRead;
+		} while (len != 0);
+        return offset - firstOffset;
+	}
+
+    /**
+     * Skips until EOF, returns number of bytes skipped.
+     * @param is
+     *      InputStream to be skipped.
+     * @return
+     *      number of bytes skipped in fact.
+     * @throws IOException
+     *      if IOException occurs. It doesn't contain EOFException.
+     * @throws NullPointerException
+     *      if the param 'is' equals null.
+     */
+    public static long skipUntilEOF(InputStream is) throws IOException {
+        if(is == null)
+            throw new NullPointerException();
+
+        long bytes = 0;
+        while(true){
+            long r = skipPersistent(is, SKIP_FRAGMENT_SIZE);
+            bytes += r;
+            if(r < SKIP_FRAGMENT_SIZE)
+                return bytes;
+        }
+    }
+
+    /**
+     * Skips requested number of bytes,
+     * throws EOFException if there is too few bytes in the stream.
+     * @param is
+     *      InputStream to be skipped.
+     * @param skippedBytes
+     *      number of bytes to skip. if skippedBytes <= zero, do nothing.
+     * @throws EOFException
+     *      if EOF meets before requested number of bytes are skipped.
+     * @throws IOException
+     *      if IOException occurs. It doesn't contain EOFException.
+     * @throws NullPointerException
+     *      if the param 'is' equals null.
+     */
+    public static void skipFully(InputStream is, long skippedBytes)
+    throws IOException {
+        if(is == null)
+            throw new NullPointerException();
+
+        if(skippedBytes <= 0)
+            return;
+
+        long bytes = skipPersistent(is, skippedBytes);
+
+        if(bytes < skippedBytes)
+            throw new EOFException();
+    }
+
+    /**
+     * Tries harder to skip the requested number of bytes.
+     * <p>
+     * Note that even if the method fails to skip the requested number of bytes,
+     * it will not throw an exception. If this happens, the caller can be sure
+     * that end-of-stream has been reached.
+     *
+     * @param in byte stream
+     * @param bytesToSkip the number of bytes to skip
+     * @return The number of bytes skipped.
+     * @throws IOException if reading from the stream fails
+     */
+    public static final long skipPersistent(InputStream in, long bytesToSkip)
+    throws IOException {
+        long skipped = 0;
+        while (skipped < bytesToSkip) {
+            long skippedNow = in.skip(bytesToSkip - skipped);
+            if (skippedNow == 0) {
+                if (in.read() == -1) {
+                    // EOF, return what we have and leave it up to caller to
+                    // decide what to do about it.
+                    break;
+                } else {
+                    skippedNow = 1; // Added to count below.
+                }
+            }
+            skipped += skippedNow;
+        }
+        return skipped;
+    }
+}



Mime
View raw message