1 package org.ibex.nestedvm.util;
5 public abstract class Seekable {
6 public abstract int read(byte[] buf, int offset, int length) throws IOException;
7 public abstract int write(byte[] buf, int offset, int length) throws IOException;
8 public abstract int length() throws IOException;
9 public abstract void seek(int pos) throws IOException;
10 public abstract void close() throws IOException;
11 public abstract int pos() throws IOException;
13 public int read() throws IOException {
14 byte[] buf = new byte[1];
15 int n = read(buf,0,1);
16 return n == -1 ? -1 : buf[0]&0xff;
19 public int tryReadFully(byte[] buf, int off, int len) throws IOException {
22 int n = read(buf,off,len);
28 return total == 0 ? -1 : total;
31 public static class ByteArray extends Seekable {
32 protected byte[] data;
34 private final boolean writable;
36 public ByteArray(byte[] data, boolean writable) {
39 this.writable = writable;
42 public int read(byte[] buf, int off, int len) {
43 len = Math.min(len,data.length-pos);
44 if(len <= 0) return -1;
45 System.arraycopy(data,pos,buf,off,len);
50 public int write(byte[] buf, int off, int len) throws IOException {
51 if(!writable) throw new IOException("read-only data");
52 len = Math.min(len,data.length-pos);
53 if(len <= 0) throw new IOException("no space");
54 System.arraycopy(buf,off,data,pos,len);
59 public int length() { return data.length; }
60 public int pos() { return pos; }
61 public void seek(int pos) { this.pos = pos; }
62 public void close() { /*noop*/ }
65 public static class File extends Seekable {
66 private final RandomAccessFile raf;
68 public File(String fileName) throws IOException { this(fileName,false); }
69 public File(String fileName, boolean writable) throws IOException { this(new java.io.File(fileName),writable,false); }
71 public File(java.io.File file, boolean writable, boolean truncate) throws IOException {
72 String mode = writable ? "rw" : "r";
73 raf = truncate ? Platform.truncatedRandomAccessFile(file,mode) : new RandomAccessFile(file,mode);
76 public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); }
77 public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; }
78 public void seek(int pos) throws IOException{ raf.seek(pos); }
79 public int pos() throws IOException { return (int) raf.getFilePointer(); }
80 public int length() throws IOException { return (int)raf.length(); }
81 public void close() throws IOException { raf.close(); }
84 public static class InputStream extends Seekable {
85 private byte[] buffer = new byte[4096];
86 private int bytesRead = 0;
87 private boolean eof = false;
89 private java.io.InputStream is;
91 public InputStream(java.io.InputStream is) { this.is = is; }
93 public int read(byte[] outbuf, int off, int len) throws IOException {
94 if(pos >= bytesRead && !eof) readTo(pos + 1);
95 len = Math.min(len,bytesRead-pos);
96 if(len <= 0) return -1;
97 System.arraycopy(buffer,pos,outbuf,off,len);
102 private void readTo(int target) throws IOException {
103 if(target >= buffer.length) {
104 byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)];
105 System.arraycopy(buffer,0,buf2,0,bytesRead);
108 while(bytesRead < target) {
109 int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
118 public int length() throws IOException {
119 while(!eof) readTo(bytesRead+4096);
123 public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); }
124 public void seek(int pos) { this.pos = pos; }
125 public int pos() { return pos; }
126 public void close() throws IOException { is.close(); }