abstract RandomAccessFile.setLength() for Jdk11 support
[nestedvm.git] / src / org / ibex / nestedvm / util / Seekable.java
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 package org.ibex.nestedvm.util;
6
7 import java.io.*;
8
9 public abstract class Seekable { 
10     public abstract int read(byte[] buf, int offset, int length) throws IOException;
11     public abstract int write(byte[] buf, int offset, int length) throws IOException;
12     public abstract int length() throws IOException;
13     public abstract void seek(int pos) throws IOException;
14     public abstract void close() throws IOException;
15     public abstract int pos() throws IOException;
16
17     public void resize(long length) throws IOException {
18         throw new IOException("resize not implemented for " + getClass());
19     }
20     /** If pos == 0 and size == 0 lock covers whole file. */
21     public Lock lock(long pos, long size, boolean shared) throws IOException {
22         throw new IOException("lock not implemented for " + getClass());
23     }
24     
25     public int read() throws IOException {
26         byte[] buf = new byte[1];
27         int n = read(buf,0,1);
28         return n == -1 ? -1 : buf[0]&0xff;
29     }
30     
31     public int tryReadFully(byte[] buf, int off, int len) throws IOException {
32         int total = 0;
33         while(len > 0) {
34                 int n = read(buf,off,len);
35                 if(n == -1) break;
36                 off += n;
37                 len -= n;
38             total += n;
39         }
40         return total == 0 ? -1 : total;
41     }
42     
43     public static class ByteArray extends Seekable {
44         protected byte[] data;
45         protected int pos;
46         private final boolean writable;
47         
48         public ByteArray(byte[] data, boolean writable) {
49             this.data = data;
50             this.pos = 0;
51             this.writable = writable;
52         }
53         
54         public int read(byte[] buf, int off, int len) {
55             len = Math.min(len,data.length-pos);
56             if(len <= 0) return -1;
57             System.arraycopy(data,pos,buf,off,len);
58             pos += len;
59             return len;
60         }
61                 
62         public int write(byte[] buf, int off, int len) throws IOException {
63             if(!writable) throw new IOException("read-only data");
64             len = Math.min(len,data.length-pos);
65             if(len <= 0) throw new IOException("no space");
66             System.arraycopy(buf,off,data,pos,len);        
67             pos += len;
68             return len;
69         }
70         
71         public int length() { return data.length; }
72         public int pos() { return pos; }
73         public void seek(int pos) { this.pos = pos; }
74         public void close() { /*noop*/ }
75     }
76     
77     public static class File extends Seekable {
78         private final java.io.File file;
79         private final RandomAccessFile raf;
80         
81         public File(String fileName) throws IOException { this(fileName,false); }
82         public File(String fileName, boolean writable) throws IOException { this(new java.io.File(fileName),writable,false); }    
83         
84         public File(java.io.File file, boolean writable, boolean truncate) throws IOException {
85             this.file = file;
86             String mode = writable ? "rw" : "r";
87             raf = new RandomAccessFile(file,mode);
88             if (truncate) Platform.setFileLength(raf, 0);
89         }
90         
91         public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); }
92         public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; }
93         public void seek(int pos) throws IOException{ raf.seek(pos); }
94         public int pos()  throws IOException { return (int) raf.getFilePointer(); }
95         public int length() throws IOException { return (int)raf.length(); }
96         public void close() throws IOException { raf.close(); }
97         public void resize(long length) throws IOException { Platform.setFileLength(raf, (int)length); }
98         public boolean equals(Object o) {
99             return o != null && o instanceof File
100                    && file.equals(((File)o).file);
101         }
102         public Lock lock(long pos, long size, boolean shared)
103                 throws IOException {
104             return Platform.lockFile(this, raf, pos, size, shared);
105         }
106     }
107     
108     public static class InputStream extends Seekable {
109         private byte[] buffer = new byte[4096];
110         private int bytesRead = 0;
111         private boolean eof = false;
112         private int pos;
113         private java.io.InputStream is;
114         
115         public InputStream(java.io.InputStream is) { this.is = is; }
116         
117         public int read(byte[] outbuf, int off, int len) throws IOException {
118             if(pos >= bytesRead && !eof) readTo(pos + 1);
119             len = Math.min(len,bytesRead-pos);
120             if(len <= 0) return -1;
121             System.arraycopy(buffer,pos,outbuf,off,len);
122             pos += len;
123             return len;
124         }
125         
126         private void readTo(int target) throws IOException {
127             if(target >= buffer.length) {
128                 byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)];
129                 System.arraycopy(buffer,0,buf2,0,bytesRead);
130                 buffer = buf2;
131             }
132             while(bytesRead < target) {
133                 int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
134                 if(n == -1) {
135                     eof = true;
136                     break;
137                 }
138                 bytesRead += n;
139             }
140         }
141         
142         public int length() throws IOException {
143             while(!eof) readTo(bytesRead+4096);
144             return bytesRead;
145         }
146         
147         public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); }
148         public void seek(int pos) { this.pos = pos; }
149         public int pos() { return pos; }
150         public void close() throws IOException { is.close(); }
151     }
152     
153     public abstract static class Lock {
154         private Object owner = null;
155
156         public abstract Seekable seekable();
157         public abstract boolean isShared();
158         public abstract boolean isValid();
159         public abstract void release() throws IOException;
160         public abstract long position();
161         public abstract long size();
162
163         public void setOwner(Object o) { owner = o; }
164         public Object getOwner() { return owner; }
165
166         public final boolean contains(int start, int len) {
167             return start >= position() &&  position() + size() >= start + len;
168         }
169
170         public final boolean contained(int start, int len) {
171             return start < position() && position() + size() < start + len;
172         }
173
174         public final boolean overlaps(int start, int len) {
175             return contains(start, len) || contained(start, len);
176         }
177     }
178 }