001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.vfs.provider.ram;
018:
019: import java.io.ByteArrayOutputStream;
020: import java.io.DataInputStream;
021: import java.io.DataOutputStream;
022: import java.io.EOFException;
023: import java.io.IOException;
024: import java.io.InputStream;
025:
026: import org.apache.commons.vfs.RandomAccessContent;
027: import org.apache.commons.vfs.util.RandomAccessMode;
028:
029: /**
030: * RAM File Random Access Content
031: */
032: public class RamFileRandomAccessContent implements RandomAccessContent {
033: /**
034: * Buffer
035: */
036: byte[] buf;
037:
038: /**
039: * File Pointer
040: */
041: protected int filePointer = 0;
042:
043: /**
044: * buffer
045: */
046: private byte buffer8[] = new byte[8];
047:
048: /**
049: * buffer
050: */
051: private byte buffer4[] = new byte[4];
052:
053: /**
054: * buffer
055: */
056: private byte buffer2[] = new byte[2];
057:
058: /**
059: * buffer
060: */
061: private byte buffer1[] = new byte[1];
062:
063: /**
064: * Mode
065: */
066: private RandomAccessMode mode;
067:
068: /**
069: * File
070: */
071: private RamFileObject file;
072:
073: private InputStream rafis;
074:
075: /**
076: * @param mode
077: */
078: public RamFileRandomAccessContent(RamFileObject file,
079: RandomAccessMode mode) {
080: super ();
081: this .buf = file.getData().getBuffer();
082: this .file = file;
083: this .mode = mode;
084:
085: rafis = new InputStream() {
086: public int read() throws IOException {
087: try {
088: return readByte();
089: } catch (EOFException e) {
090: return -1;
091: }
092: }
093:
094: public long skip(long n) throws IOException {
095: seek(getFilePointer() + n);
096: return n;
097: }
098:
099: public void close() throws IOException {
100: close();
101: }
102:
103: public int read(byte b[]) throws IOException {
104: return read(b);
105: }
106:
107: public int read(byte b[], int off, int len)
108: throws IOException {
109: int retLen = Math.min(len, getLeftBytes());
110: RamFileRandomAccessContent.this .readFully(b, off,
111: retLen);
112: return retLen;
113: }
114:
115: public int available() throws IOException {
116: return getLeftBytes();
117: }
118: };
119: }
120:
121: /*
122: * (non-Javadoc)
123: *
124: * @see org.apache.commons.vfs.RandomAccessContent#getFilePointer()
125: */
126: public long getFilePointer() throws IOException {
127: return this .filePointer;
128: }
129:
130: /*
131: * (non-Javadoc)
132: *
133: * @see org.apache.commons.vfs.RandomAccessContent#seek(long)
134: */
135: public void seek(long pos) throws IOException {
136: this .filePointer = (int) pos;
137: }
138:
139: /*
140: * (non-Javadoc)
141: *
142: * @see org.apache.commons.vfs.RandomAccessContent#length()
143: */
144: public long length() throws IOException {
145: return buf.length;
146: }
147:
148: /*
149: * (non-Javadoc)
150: *
151: * @see org.apache.commons.vfs.RandomAccessContent#close()
152: */
153: public void close() throws IOException {
154:
155: }
156:
157: /*
158: * (non-Javadoc)
159: *
160: * @see java.io.DataInput#readByte()
161: */
162: public byte readByte() throws IOException {
163: return (byte) this .readUnsignedByte();
164: }
165:
166: /*
167: * (non-Javadoc)
168: *
169: * @see java.io.DataInput#readChar()
170: */
171: public char readChar() throws IOException {
172: int ch1 = this .readUnsignedByte();
173: int ch2 = this .readUnsignedByte();
174: return (char) ((ch1 << 8) + (ch2 << 0));
175: }
176:
177: /*
178: * (non-Javadoc)
179: *
180: * @see java.io.DataInput#readDouble()
181: */
182: public double readDouble() throws IOException {
183: return Double.longBitsToDouble(this .readLong());
184: }
185:
186: /*
187: * (non-Javadoc)
188: *
189: * @see java.io.DataInput#readFloat()
190: */
191: public float readFloat() throws IOException {
192: return Float.intBitsToFloat(this .readInt());
193: }
194:
195: /*
196: * (non-Javadoc)
197: *
198: * @see java.io.DataInput#readInt()
199: */
200: public int readInt() throws IOException {
201: return (readUnsignedByte() << 24) | (readUnsignedByte() << 16)
202: | (readUnsignedByte() << 8) | readUnsignedByte();
203: }
204:
205: /*
206: * (non-Javadoc)
207: *
208: * @see java.io.DataInput#readUnsignedByte()
209: */
210: public int readUnsignedByte() throws IOException {
211: if (filePointer < buf.length) {
212: return buf[filePointer++] & 0xFF;
213: } else {
214: throw new EOFException();
215: }
216: }
217:
218: /*
219: * (non-Javadoc)
220: *
221: * @see java.io.DataInput#readUnsignedShort()
222: */
223: public int readUnsignedShort() throws IOException {
224: this .readFully(buffer2);
225: return toUnsignedShort(buffer2);
226: }
227:
228: /*
229: * (non-Javadoc)
230: *
231: * @see java.io.DataInput#readLong()
232: */
233: public long readLong() throws IOException {
234: this .readFully(buffer8);
235: return toLong(buffer8);
236: }
237:
238: /*
239: * (non-Javadoc)
240: *
241: * @see java.io.DataInput#readShort()
242: */
243: public short readShort() throws IOException {
244: this .readFully(buffer2);
245: return toShort(buffer2);
246: }
247:
248: /*
249: * (non-Javadoc)
250: *
251: * @see java.io.DataInput#readBoolean()
252: */
253: public boolean readBoolean() throws IOException {
254: return (this .readUnsignedByte() != 0);
255: }
256:
257: /*
258: * (non-Javadoc)
259: *
260: * @see java.io.DataInput#skipBytes(int)
261: */
262: public int skipBytes(int n) throws IOException {
263: if (n < 0) {
264: throw new IndexOutOfBoundsException(
265: "The skip number can't be negative");
266: }
267:
268: long newPos = filePointer + n;
269:
270: if (newPos > buf.length) {
271: throw new IndexOutOfBoundsException(
272: "Tyring to skip too much bytes");
273: }
274:
275: seek(newPos);
276:
277: return n;
278: }
279:
280: /*
281: * (non-Javadoc)
282: *
283: * @see java.io.DataInput#readFully(byte[])
284: */
285: public void readFully(byte[] b) throws IOException {
286: this .readFully(b, 0, b.length);
287: }
288:
289: /*
290: * (non-Javadoc)
291: *
292: * @see java.io.DataInput#readFully(byte[], int, int)
293: */
294: public void readFully(byte[] b, int off, int len)
295: throws IOException {
296: if (len < 0) {
297: throw new IndexOutOfBoundsException(
298: "Length is lower than 0");
299: }
300:
301: if (len > this .getLeftBytes()) {
302: throw new IndexOutOfBoundsException("Read length (" + len
303: + ") is higher than buffer left bytes ("
304: + this .getLeftBytes() + ") ");
305: }
306:
307: System.arraycopy(buf, filePointer, b, off, len);
308:
309: filePointer += len;
310: }
311:
312: private int getLeftBytes() {
313: return buf.length - filePointer;
314: }
315:
316: /*
317: * (non-Javadoc)
318: *
319: * @see java.io.DataInput#readUTF()
320: */
321: public String readUTF() throws IOException {
322: return DataInputStream.readUTF(this );
323: }
324:
325: /*
326: * (non-Javadoc)
327: *
328: * @see java.io.DataOutput#write(byte[], int, int)
329: */
330: public void write(byte[] b, int off, int len) throws IOException {
331: if (this .getLeftBytes() < len) {
332: int newSize = this .buf.length + len - this .getLeftBytes();
333: this .file.resize(newSize);
334: this .buf = this .file.getData().getBuffer();
335: }
336: System.arraycopy(b, off, this .buf, filePointer, len);
337: this .filePointer += len;
338: }
339:
340: /*
341: * (non-Javadoc)
342: *
343: * @see java.io.DataOutput#write(byte[])
344: */
345: public void write(byte[] b) throws IOException {
346: this .write(b, 0, b.length);
347: }
348:
349: /*
350: * (non-Javadoc)
351: *
352: * @see java.io.DataOutput#writeByte(int)
353: */
354: public void writeByte(int i) throws IOException {
355: this .write(i);
356: }
357:
358: /**
359: * Build a long from first 8 bytes of the array.
360: *
361: * @author Apache-Commons-Id Team
362: * @param b
363: * The byte[] to convert.
364: * @return A long.
365: */
366: public static long toLong(byte[] b) {
367: return ((((long) b[7]) & 0xFF) + ((((long) b[6]) & 0xFF) << 8)
368: + ((((long) b[5]) & 0xFF) << 16)
369: + ((((long) b[4]) & 0xFF) << 24)
370: + ((((long) b[3]) & 0xFF) << 32)
371: + ((((long) b[2]) & 0xFF) << 40)
372: + ((((long) b[1]) & 0xFF) << 48) + ((((long) b[0]) & 0xFF) << 56));
373: }
374:
375: /**
376: * Build a 8-byte array from a long. No check is performed on the array
377: * length.
378: *
379: * @author Commons-Id Team
380: *
381: * @param n
382: * The number to convert.
383: * @param b
384: * The array to fill.
385: * @return A byte[].
386: */
387: public static byte[] toBytes(long n, byte[] b) {
388: b[7] = (byte) (n);
389: n >>>= 8;
390: b[6] = (byte) (n);
391: n >>>= 8;
392: b[5] = (byte) (n);
393: n >>>= 8;
394: b[4] = (byte) (n);
395: n >>>= 8;
396: b[3] = (byte) (n);
397: n >>>= 8;
398: b[2] = (byte) (n);
399: n >>>= 8;
400: b[1] = (byte) (n);
401: n >>>= 8;
402: b[0] = (byte) (n);
403: return b;
404: }
405:
406: /**
407: * Build a short from first 2 bytes of the array.
408: *
409: * @author Apache-Commons-Id Team
410: * @param b
411: * The byte[] to convert.
412: * @return A short.
413: */
414: public static short toShort(byte[] b) {
415: return (short) toUnsignedShort(b);
416: }
417:
418: /**
419: * Build a short from first 2 bytes of the array.
420: *
421: * @author Apache-Commons-Id Team
422: * @param b
423: * The byte[] to convert.
424: * @return A short.
425: */
426: public static int toUnsignedShort(byte[] b) {
427: return ((b[1] & 0xFF) + ((b[0] & 0xFF) << 8));
428: }
429:
430: /*
431: * (non-Javadoc)
432: *
433: * @see java.io.DataOutput#write(int)
434: */
435: public void write(int b) throws IOException {
436: buffer1[0] = (byte) b;
437: this .write(buffer1);
438: }
439:
440: /*
441: * (non-Javadoc)
442: *
443: * @see java.io.DataOutput#writeBoolean(boolean)
444: */
445: public void writeBoolean(boolean v) throws IOException {
446: this .write(v ? 1 : 0);
447: }
448:
449: /*
450: * (non-Javadoc)
451: *
452: * @see java.io.DataOutput#writeBytes(java.lang.String)
453: */
454: public void writeBytes(String s) throws IOException {
455: write(s.getBytes());
456: }
457:
458: /*
459: * (non-Javadoc)
460: *
461: * @see java.io.DataOutput#writeChar(int)
462: */
463: public void writeChar(int v) throws IOException {
464: buffer2[0] = (byte) ((v >>> 8) & 0xFF);
465: buffer2[1] = (byte) ((v >>> 0) & 0xFF);
466: write(buffer2);
467: }
468:
469: /*
470: * (non-Javadoc)
471: *
472: * @see java.io.DataOutput#writeChars(java.lang.String)
473: */
474: public void writeChars(String s) throws IOException {
475: int len = s.length();
476: for (int i = 0; i < len; i++) {
477: writeChar(s.charAt(i));
478: }
479: }
480:
481: /*
482: * (non-Javadoc)
483: *
484: * @see java.io.DataOutput#writeDouble(double)
485: */
486: public void writeDouble(double v) throws IOException {
487: writeLong(Double.doubleToLongBits(v));
488: }
489:
490: /*
491: * (non-Javadoc)
492: *
493: * @see java.io.DataOutput#writeFloat(float)
494: */
495: public void writeFloat(float v) throws IOException {
496: writeInt(Float.floatToIntBits(v));
497: }
498:
499: /*
500: * (non-Javadoc)
501: *
502: * @see java.io.DataOutput#writeInt(int)
503: */
504: public void writeInt(int v) throws IOException {
505: buffer4[0] = (byte) ((v >>> 24) & 0xFF);
506: buffer4[1] = (byte) ((v >>> 16) & 0xFF);
507: buffer4[2] = (byte) ((v >>> 8) & 0xFF);
508: buffer4[3] = (byte) (v & 0xFF);
509: write(buffer4);
510: }
511:
512: /*
513: * (non-Javadoc)
514: *
515: * @see java.io.DataOutput#writeLong(long)
516: */
517: public void writeLong(long v) throws IOException {
518: write(toBytes(v, buffer8));
519: }
520:
521: /*
522: * (non-Javadoc)
523: *
524: * @see java.io.DataOutput#writeShort(int)
525: */
526: public void writeShort(int v) throws IOException {
527: buffer2[0] = (byte) ((v >>> 8) & 0xFF);
528: buffer2[1] = (byte) (v & 0xFF);
529: write(buffer2);
530: }
531:
532: /*
533: * (non-Javadoc)
534: *
535: * @see java.io.DataOutput#writeUTF(java.lang.String)
536: */
537: public void writeUTF(String str) throws IOException {
538: ByteArrayOutputStream out = new ByteArrayOutputStream(str
539: .length());
540: DataOutputStream dataOut = new DataOutputStream(out);
541: dataOut.writeUTF(str);
542: dataOut.flush();
543: dataOut.close();
544: byte[] b = out.toByteArray();
545: write(b);
546: }
547:
548: /*
549: * (non-Javadoc)
550: *
551: * @see java.io.DataInput#readLine()
552: */
553: public String readLine() throws IOException {
554: throw new UnsupportedOperationException("deprecated");
555: }
556:
557: public InputStream getInputStream() throws IOException {
558: return rafis;
559: }
560: }
|