com.adobe.internal.io.stream.IO Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/* ****************************************************************************
*
* 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;
}
}