View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.commons.vfs.provider.ram;
    18
    19  import java.io.ByteArrayOutputStream;
    20  import java.io.DataInputStream;
    21  import java.io.DataOutputStream;
    22  import java.io.EOFException;
    23  import java.io.IOException;
    24  import java.io.InputStream;
    25
    26  import org.apache.commons.vfs.RandomAccessContent;
    27  import org.apache.commons.vfs.util.RandomAccessMode;
    28
    29  /***
    30   * RAM File Random Access Content
    31   */
    32  public class RamFileRandomAccessContent implements RandomAccessContent
    33  {
    34  	/***
    35  	 * Buffer
    36  	 */
    37  	byte[] buf;
    38
    39  	/***
    40  	 * File Pointer
    41  	 */
    42  	protected int filePointer = 0;
    43
    44  	/***
    45  	 * buffer
    46  	 */
    47  	private byte buffer8[] = new byte[8];
    48
    49  	/***
    50  	 * buffer
    51  	 */
    52  	private byte buffer4[] = new byte[4];
    53
    54  	/***
    55  	 * buffer
    56  	 */
    57  	private byte buffer2[] = new byte[2];
    58
    59  	/***
    60  	 * buffer
    61  	 */
    62  	private byte buffer1[] = new byte[1];
    63
    64  	/***
    65  	 * Mode
    66  	 */
    67  	private RandomAccessMode mode;
    68
    69  	/***
    70  	 * File
    71  	 */
    72  	private RamFileObject file;
    73
    74  	private InputStream rafis;
    75
    76  	/***
    77  	 * @param mode
    78  	 */
    79  	public RamFileRandomAccessContent(RamFileObject file, RandomAccessMode mode)
    80  	{
    81  		super();
    82  		this.buf = file.getData().getBuffer();
    83  		this.file = file;
    84  		this.mode = mode;
    85
    86  		rafis = new InputStream()
    87  		{
    88  			public int read() throws IOException
    89  			{
    90  				try
    91  				{
    92  					return readByte();
    93  				}
    94  				catch (EOFException e)
    95  				{
    96  					return -1;
    97  				}
    98  			}
    99
    100 			public long skip(long n) throws IOException
    101 			{
    102 				seek(getFilePointer() + n);
    103 				return n;
    104 			}
    105
    106 			public void close() throws IOException
    107 			{
    108 				close();
    109 			}
    110
    111 			public int read(byte b[]) throws IOException
    112 			{
    113 				return read(b);
    114 			}
    115
    116 			public int read(byte b[], int off, int len) throws IOException
    117 			{
    118 				int retLen = Math.min(len, getLeftBytes());
    119 				RamFileRandomAccessContent.this.readFully(b, off, retLen);
    120 				return retLen;
    121 			}
    122
    123 			public int available() throws IOException
    124 			{
    125 				return getLeftBytes();
    126 			}
    127 		};
    128 	}
    129
    130 	/*
    131 	 * (non-Javadoc)
    132 	 *
    133 	 * @see org.apache.commons.vfs.RandomAccessContent#getFilePointer()
    134 	 */
    135 	public long getFilePointer() throws IOException
    136 	{
    137 		return this.filePointer;
    138 	}
    139
    140 	/*
    141 	 * (non-Javadoc)
    142 	 *
    143 	 * @see org.apache.commons.vfs.RandomAccessContent#seek(long)
    144 	 */
    145 	public void seek(long pos) throws IOException
    146 	{
    147 		this.filePointer = (int) pos;
    148 	}
    149
    150 	/*
    151 	 * (non-Javadoc)
    152 	 *
    153 	 * @see org.apache.commons.vfs.RandomAccessContent#length()
    154 	 */
    155 	public long length() throws IOException
    156 	{
    157 		return buf.length;
    158 	}
    159
    160 	/*
    161 	 * (non-Javadoc)
    162 	 *
    163 	 * @see org.apache.commons.vfs.RandomAccessContent#close()
    164 	 */
    165 	public void close() throws IOException
    166 	{
    167
    168 	}
    169
    170 	/*
    171 	 * (non-Javadoc)
    172 	 *
    173 	 * @see java.io.DataInput#readByte()
    174 	 */
    175 	public byte readByte() throws IOException
    176 	{
    177 		return (byte) this.readUnsignedByte();
    178 	}
    179
    180 	/*
    181 	 * (non-Javadoc)
    182 	 *
    183 	 * @see java.io.DataInput#readChar()
    184 	 */
    185 	public char readChar() throws IOException
    186 	{
    187 		int ch1 = this.readUnsignedByte();
    188 		int ch2 = this.readUnsignedByte();
    189 		return (char) ((ch1 << 8) + (ch2 << 0));
    190 	}
    191
    192 	/*
    193 	 * (non-Javadoc)
    194 	 *
    195 	 * @see java.io.DataInput#readDouble()
    196 	 */
    197 	public double readDouble() throws IOException
    198 	{
    199 		return Double.longBitsToDouble(this.readLong());
    200 	}
    201
    202 	/*
    203 	 * (non-Javadoc)
    204 	 *
    205 	 * @see java.io.DataInput#readFloat()
    206 	 */
    207 	public float readFloat() throws IOException
    208 	{
    209 		return Float.intBitsToFloat(this.readInt());
    210 	}
    211
    212 	/*
    213 	 * (non-Javadoc)
    214 	 *
    215 	 * @see java.io.DataInput#readInt()
    216 	 */
    217 	public int readInt() throws IOException
    218 	{
    219 		return (readUnsignedByte() << 24) | (readUnsignedByte() << 16)
    220 				| (readUnsignedByte() << 8) | readUnsignedByte();
    221 	}
    222
    223 	/*
    224 	 * (non-Javadoc)
    225 	 *
    226 	 * @see java.io.DataInput#readUnsignedByte()
    227 	 */
    228 	public int readUnsignedByte() throws IOException
    229 	{
    230 		if (filePointer < buf.length)
    231 		{
    232 			return buf[filePointer++] & 0xFF;
    233 		}
    234 		else
    235 		{
    236 			throw new EOFException();
    237 		}
    238 	}
    239
    240 	/*
    241 	 * (non-Javadoc)
    242 	 *
    243 	 * @see java.io.DataInput#readUnsignedShort()
    244 	 */
    245 	public int readUnsignedShort() throws IOException
    246 	{
    247 		this.readFully(buffer2);
    248 		return toUnsignedShort(buffer2);
    249 	}
    250
    251 	/*
    252 	 * (non-Javadoc)
    253 	 *
    254 	 * @see java.io.DataInput#readLong()
    255 	 */
    256 	public long readLong() throws IOException
    257 	{
    258 		this.readFully(buffer8);
    259 		return toLong(buffer8);
    260 	}
    261
    262 	/*
    263 	 * (non-Javadoc)
    264 	 *
    265 	 * @see java.io.DataInput#readShort()
    266 	 */
    267 	public short readShort() throws IOException
    268 	{
    269 		this.readFully(buffer2);
    270 		return toShort(buffer2);
    271 	}
    272
    273 	/*
    274 	 * (non-Javadoc)
    275 	 *
    276 	 * @see java.io.DataInput#readBoolean()
    277 	 */
    278 	public boolean readBoolean() throws IOException
    279 	{
    280 		return (this.readUnsignedByte() != 0);
    281 	}
    282
    283 	/*
    284 	 * (non-Javadoc)
    285 	 *
    286 	 * @see java.io.DataInput#skipBytes(int)
    287 	 */
    288 	public int skipBytes(int n) throws IOException
    289 	{
    290 		if (n < 0)
    291 		{
    292 			throw new IndexOutOfBoundsException(
    293 					"The skip number can't be negative");
    294 		}
    295
    296 		long newPos = filePointer + n;
    297
    298 		if (newPos > buf.length)
    299 		{
    300 			throw new IndexOutOfBoundsException("Tyring to skip too much bytes");
    301 		}
    302
    303 		seek(newPos);
    304
    305 		return n;
    306 	}
    307
    308 	/*
    309 	 * (non-Javadoc)
    310 	 *
    311 	 * @see java.io.DataInput#readFully(byte[])
    312 	 */
    313 	public void readFully(byte[] b) throws IOException
    314 	{
    315 		this.readFully(b, 0, b.length);
    316 	}
    317
    318 	/*
    319 	 * (non-Javadoc)
    320 	 *
    321 	 * @see java.io.DataInput#readFully(byte[], int, int)
    322 	 */
    323 	public void readFully(byte[] b, int off, int len) throws IOException
    324 	{
    325 		if (len < 0)
    326 		{
    327 			throw new IndexOutOfBoundsException("Length is lower than 0");
    328 		}
    329
    330 		if (len > this.getLeftBytes())
    331 		{
    332 			throw new IndexOutOfBoundsException("Read length (" + len
    333 					+ ") is higher than buffer left bytes ("
    334 					+ this.getLeftBytes() + ") ");
    335 		}
    336
    337 		System.arraycopy(buf, filePointer, b, off, len);
    338
    339 		filePointer += len;
    340 	}
    341
    342 	private int getLeftBytes()
    343 	{
    344 		return buf.length - filePointer;
    345 	}
    346
    347 	/*
    348 	 * (non-Javadoc)
    349 	 *
    350 	 * @see java.io.DataInput#readUTF()
    351 	 */
    352 	public String readUTF() throws IOException
    353 	{
    354 		return DataInputStream.readUTF(this);
    355 	}
    356
    357 	/*
    358 	 * (non-Javadoc)
    359 	 *
    360 	 * @see java.io.DataOutput#write(byte[], int, int)
    361 	 */
    362 	public void write(byte[] b, int off, int len) throws IOException
    363 	{
    364 		if (this.getLeftBytes() < len)
    365 		{
    366 			int newSize = this.buf.length + len - this.getLeftBytes();
    367 			this.file.resize(newSize);
    368 			this.buf = this.file.getData().getBuffer();
    369 		}
    370 		System.arraycopy(b, off, this.buf, filePointer, len);
    371 		this.filePointer += len;
    372 	}
    373
    374 	/*
    375 	 * (non-Javadoc)
    376 	 *
    377 	 * @see java.io.DataOutput#write(byte[])
    378 	 */
    379 	public void write(byte[] b) throws IOException
    380 	{
    381 		this.write(b, 0, b.length);
    382 	}
    383
    384 	/*
    385 	 * (non-Javadoc)
    386 	 *
    387 	 * @see java.io.DataOutput#writeByte(int)
    388 	 */
    389 	public void writeByte(int i) throws IOException
    390 	{
    391 		this.write(i);
    392 	}
    393
    394 	/***
    395 	 * Build a long from first 8 bytes of the array.
    396 	 *
    397 	 * @author Apache-Commons-Id Team
    398 	 * @param b
    399 	 *            The byte[] to convert.
    400 	 * @return A long.
    401 	 */
    402 	public static long toLong(byte[] b)
    403 	{
    404 		return ((((long) b[7]) & 0xFF) + ((((long) b[6]) & 0xFF) << 8)
    405 				+ ((((long) b[5]) & 0xFF) << 16)
    406 				+ ((((long) b[4]) & 0xFF) << 24)
    407 				+ ((((long) b[3]) & 0xFF) << 32)
    408 				+ ((((long) b[2]) & 0xFF) << 40)
    409 				+ ((((long) b[1]) & 0xFF) << 48) + ((((long) b[0]) & 0xFF) << 56));
    410 	}
    411
    412 	/***
    413 	 * Build a 8-byte array from a long. No check is performed on the array
    414 	 * length.
    415 	 *
    416 	 * @author Commons-Id Team
    417 	 *
    418 	 * @param n
    419 	 *            The number to convert.
    420 	 * @param b
    421 	 *            The array to fill.
    422 	 * @return A byte[].
    423 	 */
    424 	public static byte[] toBytes(long n, byte[] b)
    425 	{
    426 		b[7] = (byte) (n);
    427 		n >>>= 8;
    428 		b[6] = (byte) (n);
    429 		n >>>= 8;
    430 		b[5] = (byte) (n);
    431 		n >>>= 8;
    432 		b[4] = (byte) (n);
    433 		n >>>= 8;
    434 		b[3] = (byte) (n);
    435 		n >>>= 8;
    436 		b[2] = (byte) (n);
    437 		n >>>= 8;
    438 		b[1] = (byte) (n);
    439 		n >>>= 8;
    440 		b[0] = (byte) (n);
    441 		return b;
    442 	}
    443
    444 	/***
    445 	 * Build a short from first 2 bytes of the array.
    446 	 *
    447 	 * @author Apache-Commons-Id Team
    448 	 * @param b
    449 	 *            The byte[] to convert.
    450 	 * @return A short.
    451 	 */
    452 	public static short toShort(byte[] b)
    453 	{
    454 		return (short) toUnsignedShort(b);
    455 	}
    456
    457 	/***
    458 	 * Build a short from first 2 bytes of the array.
    459 	 *
    460 	 * @author Apache-Commons-Id Team
    461 	 * @param b
    462 	 *            The byte[] to convert.
    463 	 * @return A short.
    464 	 */
    465 	public static int toUnsignedShort(byte[] b)
    466 	{
    467 		return ((b[1] & 0xFF) + ((b[0] & 0xFF) << 8));
    468 	}
    469
    470 	/*
    471 	 * (non-Javadoc)
    472 	 *
    473 	 * @see java.io.DataOutput#write(int)
    474 	 */
    475 	public void write(int b) throws IOException
    476 	{
    477 		buffer1[0] = (byte) b;
    478 		this.write(buffer1);
    479 	}
    480
    481 	/*
    482 	 * (non-Javadoc)
    483 	 *
    484 	 * @see java.io.DataOutput#writeBoolean(boolean)
    485 	 */
    486 	public void writeBoolean(boolean v) throws IOException
    487 	{
    488 		this.write(v ? 1 : 0);
    489 	}
    490
    491 	/*
    492 	 * (non-Javadoc)
    493 	 *
    494 	 * @see java.io.DataOutput#writeBytes(java.lang.String)
    495 	 */
    496 	public void writeBytes(String s) throws IOException
    497 	{
    498 		write(s.getBytes());
    499 	}
    500
    501 	/*
    502 	 * (non-Javadoc)
    503 	 *
    504 	 * @see java.io.DataOutput#writeChar(int)
    505 	 */
    506 	public void writeChar(int v) throws IOException
    507 	{
    508 		buffer2[0] = (byte) ((v >>> 8) & 0xFF);
    509 		buffer2[1] = (byte) ((v >>> 0) & 0xFF);
    510 		write(buffer2);
    511 	}
    512
    513 	/*
    514 	 * (non-Javadoc)
    515 	 *
    516 	 * @see java.io.DataOutput#writeChars(java.lang.String)
    517 	 */
    518 	public void writeChars(String s) throws IOException
    519 	{
    520 		int len = s.length();
    521 		for (int i = 0; i < len; i++)
    522 		{
    523 			writeChar(s.charAt(i));
    524 		}
    525 	}
    526
    527 	/*
    528 	 * (non-Javadoc)
    529 	 *
    530 	 * @see java.io.DataOutput#writeDouble(double)
    531 	 */
    532 	public void writeDouble(double v) throws IOException
    533 	{
    534 		writeLong(Double.doubleToLongBits(v));
    535 	}
    536
    537 	/*
    538 	 * (non-Javadoc)
    539 	 *
    540 	 * @see java.io.DataOutput#writeFloat(float)
    541 	 */
    542 	public void writeFloat(float v) throws IOException
    543 	{
    544 		writeInt(Float.floatToIntBits(v));
    545 	}
    546
    547 	/*
    548 	 * (non-Javadoc)
    549 	 *
    550 	 * @see java.io.DataOutput#writeInt(int)
    551 	 */
    552 	public void writeInt(int v) throws IOException
    553 	{
    554 		buffer4[0] = (byte) ((v >>> 24) & 0xFF);
    555 		buffer4[1] = (byte) ((v >>> 16) & 0xFF);
    556 		buffer4[2] = (byte) ((v >>> 8) & 0xFF);
    557 		buffer4[3] = (byte) (v & 0xFF);
    558 		write(buffer4);
    559 	}
    560
    561 	/*
    562 	 * (non-Javadoc)
    563 	 *
    564 	 * @see java.io.DataOutput#writeLong(long)
    565 	 */
    566 	public void writeLong(long v) throws IOException
    567 	{
    568 		write(toBytes(v, buffer8));
    569 	}
    570
    571 	/*
    572 	 * (non-Javadoc)
    573 	 *
    574 	 * @see java.io.DataOutput#writeShort(int)
    575 	 */
    576 	public void writeShort(int v) throws IOException
    577 	{
    578 		buffer2[0] = (byte) ((v >>> 8) & 0xFF);
    579 		buffer2[1] = (byte) (v & 0xFF);
    580 		write(buffer2);
    581 	}
    582
    583 	/*
    584 	 * (non-Javadoc)
    585 	 *
    586 	 * @see java.io.DataOutput#writeUTF(java.lang.String)
    587 	 */
    588 	public void writeUTF(String str) throws IOException
    589 	{
    590 		ByteArrayOutputStream out = new ByteArrayOutputStream(str.length());
    591 		DataOutputStream dataOut = new DataOutputStream(out);
    592 		dataOut.writeUTF(str);
    593 		dataOut.flush();
    594 		dataOut.close();
    595 		byte[] b = out.toByteArray();
    596 		write(b);
    597 	}
    598
    599 	/*
    600 	 * (non-Javadoc)
    601 	 *
    602 	 * @see java.io.DataInput#readLine()
    603 	 */
    604 	public String readLine() throws IOException
    605 	{
    606 		throw new UnsupportedOperationException("deprecated");
    607 	}
    608
    609 	public InputStream getInputStream() throws IOException
    610 	{
    611 		return rafis;
    612 	}
    613 }