blob: 254a6b2c847a87fa09a4f315a0fe30bb9f8eadc5 [file] [log] [blame]
/*
* 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.commons.vfs.provider.ram;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.vfs.RandomAccessContent;
import org.apache.commons.vfs.util.RandomAccessMode;
/**
* RAM File Random Access Content.
* @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
*/
public class RamFileRandomAccessContent implements RandomAccessContent
{
/**
* File Pointer
*/
protected int filePointer = 0;
/**
* Buffer
*/
private byte[] buf;
/**
* buffer
*/
private final byte[] buffer8 = new byte[8];
/**
* buffer
*/
private final byte[] buffer4 = new byte[4];
/**
* buffer
*/
private final byte[] buffer2 = new byte[2];
/**
* buffer
*/
private final byte[] buffer1 = new byte[1];
/**
* Mode
*/
private final RandomAccessMode mode;
/**
* File
*/
private final RamFileObject file;
private final InputStream rafis;
/**
* @param file The file to access.
* @param mode The access mode.
*/
public RamFileRandomAccessContent(RamFileObject file, RandomAccessMode mode)
{
super();
this.buf = file.getData().getBuffer();
this.file = file;
this.mode = mode;
rafis = new InputStream()
{
public int read() throws IOException
{
try
{
return readByte();
}
catch (EOFException e)
{
return -1;
}
}
public long skip(long n) throws IOException
{
seek(getFilePointer() + n);
return n;
}
public void close() throws IOException
{
}
public int read(byte[] b) throws IOException
{
return read(b, 0, b.length);
}
public int read(byte[] b, int off, int len) throws IOException
{
int retLen = Math.min(len, getLeftBytes());
RamFileRandomAccessContent.this.readFully(b, off, retLen);
return retLen;
}
public int available() throws IOException
{
return getLeftBytes();
}
};
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs.RandomAccessContent#getFilePointer()
*/
public long getFilePointer() throws IOException
{
return this.filePointer;
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs.RandomAccessContent#seek(long)
*/
public void seek(long pos) throws IOException
{
this.filePointer = (int) pos;
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs.RandomAccessContent#length()
*/
public long length() throws IOException
{
return buf.length;
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs.RandomAccessContent#close()
*/
public void close() throws IOException
{
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readByte()
*/
public byte readByte() throws IOException
{
return (byte) this.readUnsignedByte();
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readChar()
*/
public char readChar() throws IOException
{
int ch1 = this.readUnsignedByte();
int ch2 = this.readUnsignedByte();
return (char) ((ch1 << 8) + (ch2 << 0));
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readDouble()
*/
public double readDouble() throws IOException
{
return Double.longBitsToDouble(this.readLong());
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readFloat()
*/
public float readFloat() throws IOException
{
return Float.intBitsToFloat(this.readInt());
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readInt()
*/
public int readInt() throws IOException
{
return (readUnsignedByte() << 24) | (readUnsignedByte() << 16)
| (readUnsignedByte() << 8) | readUnsignedByte();
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readUnsignedByte()
*/
public int readUnsignedByte() throws IOException
{
if (filePointer < buf.length)
{
return buf[filePointer++] & 0xFF;
}
else
{
throw new EOFException();
}
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readUnsignedShort()
*/
public int readUnsignedShort() throws IOException
{
this.readFully(buffer2);
return toUnsignedShort(buffer2);
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readLong()
*/
public long readLong() throws IOException
{
this.readFully(buffer8);
return toLong(buffer8);
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readShort()
*/
public short readShort() throws IOException
{
this.readFully(buffer2);
return toShort(buffer2);
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readBoolean()
*/
public boolean readBoolean() throws IOException
{
return (this.readUnsignedByte() != 0);
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#skipBytes(int)
*/
public int skipBytes(int n) throws IOException
{
if (n < 0)
{
throw new IndexOutOfBoundsException(
"The skip number can't be negative");
}
long newPos = filePointer + n;
if (newPos > buf.length)
{
throw new IndexOutOfBoundsException("Tyring to skip too much bytes");
}
seek(newPos);
return n;
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readFully(byte[])
*/
public void readFully(byte[] b) throws IOException
{
this.readFully(b, 0, b.length);
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readFully(byte[], int, int)
*/
public void readFully(byte[] b, int off, int len) throws IOException
{
if (len < 0)
{
throw new IndexOutOfBoundsException("Length is lower than 0");
}
if (len > this.getLeftBytes())
{
throw new IndexOutOfBoundsException("Read length (" + len
+ ") is higher than buffer left bytes ("
+ this.getLeftBytes() + ") ");
}
System.arraycopy(buf, filePointer, b, off, len);
filePointer += len;
}
private int getLeftBytes()
{
return buf.length - filePointer;
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readUTF()
*/
public String readUTF() throws IOException
{
return DataInputStream.readUTF(this);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException
{
if (this.getLeftBytes() < len)
{
int newSize = this.buf.length + len - this.getLeftBytes();
this.file.resize(newSize);
this.buf = this.file.getData().getBuffer();
}
System.arraycopy(b, off, this.buf, filePointer, len);
this.filePointer += len;
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#write(byte[])
*/
public void write(byte[] b) throws IOException
{
this.write(b, 0, b.length);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeByte(int)
*/
public void writeByte(int i) throws IOException
{
this.write(i);
}
/**
* Build a long from first 8 bytes of the array.
*
* @author Apache-Commons-Id Team
* @param b
* The byte[] to convert.
* @return A long.
*/
public static long toLong(byte[] b)
{
return ((((long) b[7]) & 0xFF) + ((((long) b[6]) & 0xFF) << 8)
+ ((((long) b[5]) & 0xFF) << 16)
+ ((((long) b[4]) & 0xFF) << 24)
+ ((((long) b[3]) & 0xFF) << 32)
+ ((((long) b[2]) & 0xFF) << 40)
+ ((((long) b[1]) & 0xFF) << 48) + ((((long) b[0]) & 0xFF) << 56));
}
/**
* Build a 8-byte array from a long. No check is performed on the array
* length.
*
* @author Commons-Id Team
*
* @param n
* The number to convert.
* @param b
* The array to fill.
* @return A byte[].
*/
public static byte[] toBytes(long n, byte[] b)
{
b[7] = (byte) (n);
n >>>= 8;
b[6] = (byte) (n);
n >>>= 8;
b[5] = (byte) (n);
n >>>= 8;
b[4] = (byte) (n);
n >>>= 8;
b[3] = (byte) (n);
n >>>= 8;
b[2] = (byte) (n);
n >>>= 8;
b[1] = (byte) (n);
n >>>= 8;
b[0] = (byte) (n);
return b;
}
/**
* Build a short from first 2 bytes of the array.
*
* @author Apache-Commons-Id Team
* @param b
* The byte[] to convert.
* @return A short.
*/
public static short toShort(byte[] b)
{
return (short) toUnsignedShort(b);
}
/**
* Build a short from first 2 bytes of the array.
*
* @author Apache-Commons-Id Team
* @param b
* The byte[] to convert.
* @return A short.
*/
public static int toUnsignedShort(byte[] b)
{
return ((b[1] & 0xFF) + ((b[0] & 0xFF) << 8));
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#write(int)
*/
public void write(int b) throws IOException
{
buffer1[0] = (byte) b;
this.write(buffer1);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeBoolean(boolean)
*/
public void writeBoolean(boolean v) throws IOException
{
this.write(v ? 1 : 0);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeBytes(java.lang.String)
*/
public void writeBytes(String s) throws IOException
{
write(s.getBytes());
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeChar(int)
*/
public void writeChar(int v) throws IOException
{
buffer2[0] = (byte) ((v >>> 8) & 0xFF);
buffer2[1] = (byte) ((v >>> 0) & 0xFF);
write(buffer2);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeChars(java.lang.String)
*/
public void writeChars(String s) throws IOException
{
int len = s.length();
for (int i = 0; i < len; i++)
{
writeChar(s.charAt(i));
}
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeDouble(double)
*/
public void writeDouble(double v) throws IOException
{
writeLong(Double.doubleToLongBits(v));
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeFloat(float)
*/
public void writeFloat(float v) throws IOException
{
writeInt(Float.floatToIntBits(v));
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeInt(int)
*/
public void writeInt(int v) throws IOException
{
buffer4[0] = (byte) ((v >>> 24) & 0xFF);
buffer4[1] = (byte) ((v >>> 16) & 0xFF);
buffer4[2] = (byte) ((v >>> 8) & 0xFF);
buffer4[3] = (byte) (v & 0xFF);
write(buffer4);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeLong(long)
*/
public void writeLong(long v) throws IOException
{
write(toBytes(v, buffer8));
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeShort(int)
*/
public void writeShort(int v) throws IOException
{
buffer2[0] = (byte) ((v >>> 8) & 0xFF);
buffer2[1] = (byte) (v & 0xFF);
write(buffer2);
}
/*
* (non-Javadoc)
*
* @see java.io.DataOutput#writeUTF(java.lang.String)
*/
public void writeUTF(String str) throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream(str.length());
DataOutputStream dataOut = new DataOutputStream(out);
dataOut.writeUTF(str);
dataOut.flush();
dataOut.close();
byte[] b = out.toByteArray();
write(b);
}
/*
* (non-Javadoc)
*
* @see java.io.DataInput#readLine()
*/
public String readLine() throws IOException
{
throw new UnsupportedOperationException("deprecated");
}
public InputStream getInputStream() throws IOException
{
return rafis;
}
}