blob: 15ccb20e6bf7d79a0f7b08055ec2481bcf101d6f [file] [log] [blame]
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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.axis.utils;
import org.apache.axis.AxisEngine;
import org.apache.axis.AxisProperties;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Class ByteArray
*/
public class ByteArray extends OutputStream {
protected static double DEFAULT_CACHE_INCREMENT = 2.5;
protected static int DEFAULT_RESIDENT_SIZE = 512 * 1024 * 1024; // 512 MB
protected static boolean DEFAULT_ENABLE_BACKING_STORE = true;
protected static int WORKING_BUFFER_SIZE = 8192;
protected org.apache.axis.utils.ByteArrayOutputStream cache = null;
protected int max_size = 0;
protected File bs_handle = null;
protected OutputStream bs_stream = null;
protected long count = 0;
protected boolean enableBackingStore = DEFAULT_ENABLE_BACKING_STORE;
public boolean isEnableBackingStore() {
return enableBackingStore;
}
public void setEnableBackingStore(boolean enableBackingStore) {
this.enableBackingStore = enableBackingStore;
}
public static boolean isDEFAULT_ENABLE_BACKING_STORE() {
return DEFAULT_ENABLE_BACKING_STORE;
}
public static void setDEFAULT_ENABLE_BACKING_STORE(
boolean DEFAULT_ENABLE_BACKING_STORE) {
ByteArray.DEFAULT_ENABLE_BACKING_STORE = DEFAULT_ENABLE_BACKING_STORE;
}
public static int getDEFAULT_RESIDENT_SIZE() {
return DEFAULT_RESIDENT_SIZE;
}
public static void setDEFAULT_RESIDENT_SIZE(int DEFAULT_RESIDENT_SIZE) {
ByteArray.DEFAULT_RESIDENT_SIZE = DEFAULT_RESIDENT_SIZE;
}
public static double getDEFAULT_CACHE_INCREMENT() {
return DEFAULT_CACHE_INCREMENT;
}
public static void setDEFAULT_CACHE_INCREMENT(
double DEFAULT_CACHE_INCREMENT) {
ByteArray.DEFAULT_CACHE_INCREMENT = DEFAULT_CACHE_INCREMENT;
}
static {
String value;
value = AxisProperties.getProperty(
AxisEngine.PROP_BYTE_BUFFER_CACHE_INCREMENT,
"" + DEFAULT_CACHE_INCREMENT);
DEFAULT_CACHE_INCREMENT = Double.parseDouble(value);
value = AxisProperties.getProperty(
AxisEngine.PROP_BYTE_BUFFER_RESIDENT_MAX_SIZE,
"" + DEFAULT_RESIDENT_SIZE);
DEFAULT_RESIDENT_SIZE = Integer.parseInt(value);
value = AxisProperties.getProperty(
AxisEngine.PROP_BYTE_BUFFER_WORK_BUFFER_SIZE,
"" + WORKING_BUFFER_SIZE);
WORKING_BUFFER_SIZE = Integer.parseInt(value);
value =
AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_BACKING,
"" + DEFAULT_ENABLE_BACKING_STORE);
if (value.equalsIgnoreCase("true") ||
value.equals("1") ||
value.equalsIgnoreCase("yes")) {
DEFAULT_ENABLE_BACKING_STORE = true;
} else {
DEFAULT_ENABLE_BACKING_STORE = false;
}
}
/**
* Constructor ByteArray
*/
public ByteArray() {
this(DEFAULT_RESIDENT_SIZE);
}
/**
* Constructor ByteArray
*
* @param max_resident_size
*/
public ByteArray(int max_resident_size) {
this(0, max_resident_size);
}
/**
* Constructor ByteArray
*
* @param probable_size
* @param max_resident_size
*/
public ByteArray(int probable_size, int max_resident_size) {
if (probable_size > max_resident_size) {
probable_size = 0;
}
if (probable_size < WORKING_BUFFER_SIZE) {
probable_size = WORKING_BUFFER_SIZE;
}
cache = new org.apache.axis.utils.ByteArrayOutputStream(probable_size);
max_size = max_resident_size;
}
/**
* Method write
*
* @param bytes
* @throws IOException
*/
public void write(byte bytes[]) throws IOException {
write(bytes, 0, bytes.length);
}
/**
* Method write
*
* @param bytes
* @param start
* @param length
* @throws IOException
*/
public void write(byte bytes[], int start, int length) throws IOException {
count += length;
if (cache != null) {
increaseCapacity(length);
}
if (cache != null) {
cache.write(bytes, start, length);
} else if (bs_stream != null) {
bs_stream.write(bytes, start, length);
} else {
throw new IOException("ByteArray does not have a backing store!");
}
}
/**
* Method write
*
* @param b
* @throws IOException
*/
public void write(int b) throws IOException {
count += 1;
if (cache != null) {
increaseCapacity(1);
}
if (cache != null) {
cache.write(b);
} else if (bs_stream != null) {
bs_stream.write(b);
} else {
throw new IOException("ByteArray does not have a backing store!");
}
}
/**
* Method close
*
* @throws IOException
*/
public void close() throws IOException {
if (bs_stream != null) {
bs_stream.close();
bs_stream = null;
}
}
/**
* Method size
*
* @return
*/
public long size() {
return count;
}
/**
* Method flush
*
* @throws IOException
*/
public void flush() throws IOException {
if (bs_stream != null) {
bs_stream.flush();
}
}
/**
* Method increaseCapacity
*
* @param count
* @throws IOException
*/
protected void increaseCapacity(int count) throws IOException {
if (cache == null) {
return;
}
if (count + cache.size() <= max_size) {
return;
} else if (enableBackingStore) {
switchToBackingStore();
} else {
throw new IOException("ByteArray can not increase capacity by " +
count +
" due to max size limit of " + max_size);
}
}
/**
* Method discardBuffer
*/
public synchronized void discardBuffer() {
cache = null;
if (bs_stream != null) {
try {
bs_stream.close();
} catch (IOException e) {
// just ignore it...
}
bs_stream = null;
}
discardBackingStore();
}
/**
* Method makeInputStream
*
* @return
* @throws IOException
* @throws FileNotFoundException
*/
protected InputStream makeInputStream()
throws IOException, FileNotFoundException {
close();
if (cache != null) {
return new ByteArrayInputStream(cache.toByteArray());
} else if (bs_handle != null) {
return createBackingStoreInputStream();
} else {
return null;
}
}
/**
* Method finalize
*/
protected void finalize() {
discardBuffer();
}
/**
* Method switchToBackingStore
*
* @throws IOException
*/
protected void switchToBackingStore() throws IOException {
bs_handle = File.createTempFile("Axis", ".msg");
bs_handle.createNewFile();
bs_handle.deleteOnExit();
bs_stream = new FileOutputStream(bs_handle);
bs_stream.write(cache.toByteArray());
cache = null;
}
/**
* Method getBackingStoreFileName
*
* @throws IOException
*/
public String getBackingStoreFileName() throws IOException {
String fileName = null;
if (bs_handle != null) {
fileName = bs_handle.getCanonicalPath();
}
return fileName;
}
/**
* Method discardBackingStore
*/
protected void discardBackingStore() {
if (bs_handle != null) {
bs_handle.delete();
bs_handle = null;
}
}
/**
* Method createBackingStoreInputStream
*
* @return
* @throws FileNotFoundException
*/
protected InputStream createBackingStoreInputStream()
throws FileNotFoundException {
try {
return new BufferedInputStream(
new FileInputStream(bs_handle.getCanonicalPath()));
} catch (IOException e) {
throw new FileNotFoundException(bs_handle.getAbsolutePath());
}
}
/**
* Method toByteArray
*
* @return
* @throws IOException
*/
public byte[] toByteArray() throws IOException {
InputStream inp = this.makeInputStream();
byte[] buf = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
buf = new byte[WORKING_BUFFER_SIZE];
int len;
while ((len = inp.read(buf, 0, WORKING_BUFFER_SIZE)) != -1) {
baos.write(buf, 0, len);
}
inp.close();
discardBackingStore();
return baos.toByteArray();
}
/**
* Method writeTo
*
* @param os
* @throws IOException
*/
public void writeTo(OutputStream os) throws IOException {
InputStream inp = this.makeInputStream();
byte[] buf = null;
buf = new byte[WORKING_BUFFER_SIZE];
int len;
while ((len = inp.read(buf, 0, WORKING_BUFFER_SIZE)) != -1) {
os.write(buf, 0, len);
}
inp.close();
discardBackingStore();
}
}