org.xwt.mips -> org.ibex.nestedvm
[nestedvm.git] / src / org / ibex / nestedvm / util / Seekable.java
1 package org.ibex.nestedvm.util;
2
3 import java.io.*;
4
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;
12     
13     public class ByteArray implements Seekable {
14         protected byte[] data;
15         protected int pos;
16         private final boolean writable;
17         
18         public ByteArray(byte[] data, boolean writable) {
19             this.data = data;
20             this.pos = 0;
21             this.writable = writable;
22         }
23         
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);
28             pos += len;
29             return len;
30         }
31         
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);        
37             pos += len;
38             return len;
39         }
40         
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*/ }
45     }
46     
47     public class File implements Seekable {
48         private final RandomAccessFile raf;
49         
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); }    
52         
53         public File(java.io.File file, boolean writable) throws IOException {
54             raf = new RandomAccessFile(file,writable ? "rw" : "r");
55         }
56         
57         // NOTE: RandomAccessFile.setLength() is a Java2 function
58         public void setLength(int n) throws IOException { raf.setLength(n); }
59         
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(); }
66     }
67     
68     public class InputStream implements Seekable {
69         private byte[] buffer = new byte[4096];
70         private int bytesRead = 0;
71         private boolean eof = false;
72         private int pos;
73         private java.io.InputStream is;
74         
75         public InputStream(java.io.InputStream is) { this.is = is; }
76         
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);
82             pos += len;
83             return len;
84         }
85         
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);
90                 buffer = buf2;
91             }
92             while(bytesRead < target) {
93                 int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
94                 if(n == -1) {
95                     eof = true;
96                     break;
97                 }
98                 bytesRead += n;
99             }
100         }
101         
102         public int length() throws IOException {
103             while(!eof) readTo(bytesRead+4096);
104             return bytesRead;
105         }
106         
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(); }
111     }
112     
113 }