1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
132
133
134
135 public long getFilePointer() throws IOException
136 {
137 return this.filePointer;
138 }
139
140
141
142
143
144
145 public void seek(long pos) throws IOException
146 {
147 this.filePointer = (int) pos;
148 }
149
150
151
152
153
154
155 public long length() throws IOException
156 {
157 return buf.length;
158 }
159
160
161
162
163
164
165 public void close() throws IOException
166 {
167
168 }
169
170
171
172
173
174
175 public byte readByte() throws IOException
176 {
177 return (byte) this.readUnsignedByte();
178 }
179
180
181
182
183
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
194
195
196
197 public double readDouble() throws IOException
198 {
199 return Double.longBitsToDouble(this.readLong());
200 }
201
202
203
204
205
206
207 public float readFloat() throws IOException
208 {
209 return Float.intBitsToFloat(this.readInt());
210 }
211
212
213
214
215
216
217 public int readInt() throws IOException
218 {
219 return (readUnsignedByte() << 24) | (readUnsignedByte() << 16)
220 | (readUnsignedByte() << 8) | readUnsignedByte();
221 }
222
223
224
225
226
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
242
243
244
245 public int readUnsignedShort() throws IOException
246 {
247 this.readFully(buffer2);
248 return toUnsignedShort(buffer2);
249 }
250
251
252
253
254
255
256 public long readLong() throws IOException
257 {
258 this.readFully(buffer8);
259 return toLong(buffer8);
260 }
261
262
263
264
265
266
267 public short readShort() throws IOException
268 {
269 this.readFully(buffer2);
270 return toShort(buffer2);
271 }
272
273
274
275
276
277
278 public boolean readBoolean() throws IOException
279 {
280 return (this.readUnsignedByte() != 0);
281 }
282
283
284
285
286
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
310
311
312
313 public void readFully(byte[] b) throws IOException
314 {
315 this.readFully(b, 0, b.length);
316 }
317
318
319
320
321
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
349
350
351
352 public String readUTF() throws IOException
353 {
354 return DataInputStream.readUTF(this);
355 }
356
357
358
359
360
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
376
377
378
379 public void write(byte[] b) throws IOException
380 {
381 this.write(b, 0, b.length);
382 }
383
384
385
386
387
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
472
473
474
475 public void write(int b) throws IOException
476 {
477 buffer1[0] = (byte) b;
478 this.write(buffer1);
479 }
480
481
482
483
484
485
486 public void writeBoolean(boolean v) throws IOException
487 {
488 this.write(v ? 1 : 0);
489 }
490
491
492
493
494
495
496 public void writeBytes(String s) throws IOException
497 {
498 write(s.getBytes());
499 }
500
501
502
503
504
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
515
516
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
529
530
531
532 public void writeDouble(double v) throws IOException
533 {
534 writeLong(Double.doubleToLongBits(v));
535 }
536
537
538
539
540
541
542 public void writeFloat(float v) throws IOException
543 {
544 writeInt(Float.floatToIntBits(v));
545 }
546
547
548
549
550
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
563
564
565
566 public void writeLong(long v) throws IOException
567 {
568 write(toBytes(v, buffer8));
569 }
570
571
572
573
574
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
585
586
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
601
602
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 }