All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.internal.io.stream.IO Maven / Gradle / Ivy

There is a newer version: 2024.11.18598.20241113T125352Z-241000
Show newest version
/* ****************************************************************************
 *
 *	File: IO.java
 *
 * ****************************************************************************
 *
 *	ADOBE CONFIDENTIAL
 *	___________________
 *
 *	Copyright 2003-2006 Adobe Systems Incorporated
 *	All Rights Reserved.
 *
 *	NOTICE: All information contained herein is, and remains the property of
 *	Adobe Systems Incorporated and its suppliers, if any. The intellectual
 *	and technical concepts contained herein are proprietary to Adobe Systems
 *	Incorporated and its suppliers and may be covered by U.S. and Foreign
 *	Patents, patents in process, and are protected by trade secret or
 *	copyright law. Dissemination of this information or reproduction of this
 *	material is strictly forbidden unless prior written permission is obtained
 *	from Adobe Systems Incorporated.
 *
 * ***************************************************************************/

package com.adobe.internal.io.stream;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Contains static utility functions for working with both IO classes.
 */
public final class IO 
{
	private static final int DEFAULT_CHUNK_SIZE = 32768;
	private static final boolean USE_THREADLOCAL_BUFFER = true;
	private static ThreadLocal tlBuffer = new ThreadLocal(){
		protected synchronized byte[] initialValue() {
			return new byte[DEFAULT_CHUNK_SIZE];
		}
	};
	
	private static byte[] getBuffer(boolean useThreadLocalBuffer){
		if(USE_THREADLOCAL_BUFFER && useThreadLocalBuffer)
			return tlBuffer.get();
		else
			return new byte[DEFAULT_CHUNK_SIZE];
	}
	private IO(){}
	
	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies the source InputStream to the destination OuputStream.
	 *
	 * @param is InputStream to be copied
	 * @param os OutputSream to copy to
	 *
	 * @throws IOException 
	 */
	public final static long copy(InputStream is, OutputStream os)
	throws IOException
	{
		byte[] buf = getBuffer(true);
		long bytesCopied = 0;
		int bytes = 0;
		while ((bytes = is.read(buf)) != -1)
		{
			os.write(buf, 0, bytes);
			bytesCopied += bytes;
		}
		
		return bytesCopied;
	}
	
	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies length number of bytes from the InputStream to the destination OuputStream.
	 *
	 * @param is InputByteStream to be copied
	 * @param length The amount of bytes to be copies
	 * @param os OutputTream to copy to
	 * @throws IOException
	 */
	public final static long copy(InputStream is, long length, OutputStream os)
	throws IOException
	{
		return copyInternal(is, length, os, true);
	}
	
	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies length number of bytes from the InputStream to the destination OuputStream.
	 *
	 * @param is InputByteStream to be copied
	 * @param length The amount of bytes to be copies
	 * @param os OutputTream to copy to
	 * @throws IOException
	 */
	static long copyInternal(InputStream is, long length, OutputStream os, boolean useThreadLocalBuffer) throws IOException{
		byte[] buf = getBuffer(useThreadLocalBuffer);
		long bytesToCopy = length;
		int bytesThisRead = 0;
		long bytesCopied = 0;
		while (bytesToCopy > 0 && (bytesThisRead = is.read(buf, 0, bytesToCopy > buf.length ? buf.length : (int)bytesToCopy)) != -1) 
		{
			os.write(buf, 0, bytesThisRead);
			bytesToCopy -= bytesThisRead;
			bytesCopied += bytesThisRead;
		}
		return bytesCopied;
	}
	
	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Parses the passed BitInputStream based on bitsPerValue and fills destination OuputStream with
	 * the parsed values.
	 *
	 * @param is BitInputStream to be copied
	 * @param os OutputSream to copy to
	 *
	 * @throws IOException 
	 */
	public final static long copy(BitInputStream is, OutputStream os, int bitsPerValue)
	throws IOException
	{
		byte[] buf = getBuffer(true);
		long bytesCopied = 0;
		int bytes = 0;
		while ((bytes = is.read(buf, bitsPerValue, buf.length)) != 0)
		{
			os.write(buf, 0, bytes);
			bytesCopied += bytes;
		}
		
		return bytesCopied;
	}
	/**
	 * Copies length number of samples each with bits "bitsPerValue" from BitInputStream to the outputstream.
	 * @param is
	 * @param length
	 * @param os
	 * @param bitsPerValue
	 * @return long Number of samples actually read.
	 * @throws IOException
	 */
	public final static long copy(BitInputStream is, long length, OutputStream os, int bitsPerValue)
	throws IOException
	{
		byte[] buf = getBuffer(true);
		long bytesToCopy = length;
		int bytesThisRead = 0;
		long bytesCopied = 0;
		while (bytesToCopy > 0 && (bytesThisRead = is.read(buf, bitsPerValue, bytesToCopy > buf.length ? buf.length : (int)bytesToCopy)) != 0) 
		{
			os.write(buf, 0, bytesThisRead);
			bytesToCopy -= bytesThisRead;
			bytesCopied += bytesThisRead;
		}
		return bytesCopied;
	}
	
	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies the source InputStream to the destination OuputStream.
	 *
	 * @param is InputStream to be copied
	 * @param os OutputTream to copy to
	 *
	 * @throws IOException 
	 */
	public final static long copy(InputByteStream is, OutputByteStream os)
	throws IOException
	{
		return IO.copy(is, 0, is.length(), os);
	}

	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies the source InputStream to the destination OuputStream.
	 *
	 * @param is InputStream to be copied
	 * @param os OutputTream to copy to
	 *
	 * @throws IOException 
	 */
	public final static long copy(InputByteStream is, OutputStream os)
	throws IOException
	{
		return IO.copy(is, 0, is.length(), os);
	}


	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies bytes from the InputByteStream to the destination OuputStream.
	 *
	 * @param is InputByteStream to be copied
	 * @param offset The offset into the InputByteStream where the copy should begin
	 * @param length The amount of bytes to be copies
	 * @param os OutputTream to copy to
	 * @throws IOException
	 */
	public final static long copy(InputByteStream is, long offset, long length, OutputByteStream os)
	throws IOException
	{
		byte[] buf = getBuffer(true);
		is.seek(offset);
		long bytesToCopy = length;
		int bytesThisRead = 0;
		long bytesCopied = 0;
		while (bytesToCopy > 0 && (bytesThisRead = is.read(buf)) != -1) 
		{
			if (bytesThisRead < bytesToCopy) 
			{
				os.write(buf, 0, bytesThisRead);
				bytesToCopy -= bytesThisRead;
				bytesCopied += bytesThisRead;
			} else {
				os.write(buf, 0, (int)bytesToCopy);
				bytesToCopy = 0;
				bytesCopied += bytesThisRead;
			}
		}
		return bytesCopied;
	}

	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies bytes from the InputByteStream to the destination OuputStream.
	 *
	 * @param is InputByteStream to be copied
	 * @param offset The offset into the InputByteStream where the copy should begin
	 * @param length The amount of bytes to be copied
	 * @param os OutputStream to copy to
	 * @param blockSize size of the block to use in copying
	 * @throws IOException
	 */
	public final static long copy(InputByteStream is, long offset, long length, OutputStream os, int blockSize)
	throws IOException
	{
		if (blockSize < 1)
		{
			throw new IOException("Block size can't be smaller than 1 byte.");
		}

		byte[] buf = null;
		if(blockSize <= DEFAULT_CHUNK_SIZE)
			buf = getBuffer(true);
		else
			buf = new byte[blockSize];
		is.seek(offset);
		long bytesToCopy = length;
		int bytesThisRead = 0;
		long bytesCopied = 0;
		while ((bytesThisRead = is.read(buf, 0, blockSize)) != -1 && bytesToCopy > 0) 
		{
			if (bytesThisRead < bytesToCopy) 
			{
				os.write(buf, 0, bytesThisRead);
				bytesToCopy -= bytesThisRead;
			} 
			else
			{
				os.write(buf, 0, (int)bytesToCopy);
				bytesToCopy = 0;
			}
			bytesCopied += bytesThisRead;
		}
		
		return bytesCopied;
	} 


	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies bytes from the InputByteStream to the destination OuputStream.
	 *
	 * @param is InputByteStream to be copied
	 * @param offset The offset into the InputByteStream where the copy should begin
	 * @param length The amount of bytes to be copies
	 * @param os OutputTream to copy to
	 * @throws IOException
	 */
	public final static long copy(InputByteStream is, long offset, long length, OutputStream os)
	throws IOException
	{
		//Assume a default block size
		return IO.copy(is, offset, length, os, DEFAULT_CHUNK_SIZE);
	}


	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * This utility method converts an long to a byte array
	 * @param value - long value to be written
	 * @param width - int number of bytes to be written
	 */
	public final static byte[] longToByteArray(long value, int width)
	{
		byte[] bytes = new byte[width];
		while (--width >= 0) {
			bytes[width] = (byte)value;
			value >>= 8;
		}
		return bytes;
	}

	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Obtains the InputByteStream's content as a byte array.
	 * Generally it is a bad idea to copy the whole stream's content into memory
	 * but for the text streams this is the only way to convert the text stream's
	 * content to Unicode from PDFDocEncoding or UCS-2.
	 *
	 * @return  byte array in memory that contains the complete byte sequence
	 *          in the stream.
	 * @throws IOException
	 */
	public static final byte[] inputByteStreamToArray(InputByteStream byteStream)
	throws IOException
	{
		int length = (int)byteStream.length();
		byte[] bytes = new byte[length];
		long len = byteStream.read(bytes);
		return (len > 0) ? bytes : null;
	}

	/**
	 * Only for internal engineering use. This api can change without notice.
	 * 
	 * Copies the source InputStream to the destination OuputStream.
	 *
	 * @param is InputStream to be copied
	 * @param obs OutputByteSream to copy to
	 * @throws IOException 
	 * */
	public static long copy(InputStream is, OutputByteStream obs) 
	throws IOException
	{
		
		byte[] buf = getBuffer(true);
		int bytes = 0;
		long bytesCopied = 0;
		while (is.available() > 0 && (bytes = is.read(buf)) != -1)
		{
			obs.write(buf, 0, bytes);
			bytesCopied += bytes;
		}
		
		return bytesCopied;
	}

	/**
	 * Compare two InputByteStream instances on a byte for byte basis.  This
	 * compares the two streams from their current positions until the end of the 
	 * streams.  When this method returns the position of the streams will be just 
	 * beyond the point of failure.  The comparison is on a byte level and the 
	 * "lesser" stream is the one whose byte value at given position is of lower 
	 * numeric value than the other stream or the stream which is shorter.
	 * @param stream1
	 * @param stream2
	 * @return 0 if the streams are equal; negative if stream1 is "less" than stream2; and positive if stream1 is "greater" than stream2
	 * @throws IOException
	 */
	public static int compareInputByteStreams(InputByteStream stream1, InputByteStream stream2) 
	throws IOException
	{
		int b1;
		int b2;

		do
		{
			b1 = stream1.read();
			b2 = stream2.read();
			if (b1 != b2)
			{
				return b1 - b2;
			}
		} while (b1 != -1);
		return b1 - b2;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy