1 package org.ibex.nestedvm.util;
5 public interface Seekable {
6 public int read(byte[] buf, int offset, int length) throws IOException;
7 public int write(byte[] buf, int offset, int length) throws IOException;
8 public int length() throws IOException;
9 public void seek(int pos) throws IOException;
10 public void close() throws IOException;
11 public int pos() throws IOException;
13 public class ByteArray implements Seekable {
14 protected byte[] data;
16 private final boolean writable;
18 public ByteArray(byte[] data, boolean writable) {
21 this.writable = writable;
24 public int read(byte[] buf, int off, int len) {
25 len = Math.min(len,data.length-pos);
26 if(len <= 0) return -1;
27 System.arraycopy(data,pos,buf,off,len);
32 public int write(byte[] buf, int off, int len) throws IOException {
33 if(!writable) throw new IOException("read-only data");
34 len = Math.min(len,data.length-pos);
35 if(len <= 0) throw new IOException("no space");
36 System.arraycopy(buf,off,data,pos,len);
41 public int length() { return data.length; }
42 public int pos() { return pos; }
43 public void seek(int pos) { this.pos = pos; }
44 public void close() { /*noop*/ }
47 public class File implements Seekable {
48 private final RandomAccessFile raf;
50 public File(String fileName) throws IOException { this(fileName,false); }
51 public File(String fileName, boolean writable) throws IOException { this(new java.io.File(fileName),writable); }
53 public File(java.io.File file, boolean writable) throws IOException {
54 raf = new RandomAccessFile(file,writable ? "rw" : "r");
57 // NOTE: RandomAccessFile.setLength() is a Java2 function
58 public void setLength(int n) throws IOException { raf.setLength(n); }
60 public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); }
61 public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; }
62 public void seek(int pos) throws IOException{ raf.seek(pos); }
63 public int pos() throws IOException { return (int) raf.getFilePointer(); }
64 public int length() throws IOException { return (int)raf.length(); }
65 public void close() throws IOException { raf.close(); }
68 public class InputStream implements Seekable {
69 private byte[] buffer = new byte[4096];
70 private int bytesRead = 0;
71 private boolean eof = false;
73 private java.io.InputStream is;
75 public InputStream(java.io.InputStream is) { this.is = is; }
77 public int read(byte[] outbuf, int off, int len) throws IOException {
78 if(pos >= bytesRead && !eof) readTo(pos + 1);
79 len = Math.min(len,bytesRead-pos);
80 if(len <= 0) return -1;
81 System.arraycopy(buffer,pos,outbuf,off,len);
86 private void readTo(int target) throws IOException {
87 if(target >= buffer.length) {
88 byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)];
89 System.arraycopy(buffer,0,buf2,0,bytesRead);
92 while(bytesRead < target) {
93 int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
102 public int length() throws IOException {
103 while(!eof) readTo(bytesRead+4096);
107 public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); }
108 public void seek(int pos) { this.pos = pos; }
109 public int pos() { return pos; }
110 public void close() throws IOException { is.close(); }