public Res getParent() { return null; }
+ /** an InputStream that makes sure it is not in the MessageQueue when blocked on a read */
+ private static class BackgroundInputStream extends FilterInputStream {
+ BackgroundInputStream(InputStream i) { super(i); }
+ private void suspend() throws IOException {
+ if (!ThreadMessage.suspendThread())
+ throw new IOException("attempt to perform background-only operation in a foreground thread");
+ }
+ private void resume() {
+ ThreadMessage.resumeThread();
+ }
+ public int read() throws IOException {
+ suspend();
+ try { return super.read(); }
+ finally { resume(); }
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ suspend();
+ try { return super.read(b, off, len); }
+ finally { resume(); }
+ }
+ }
+
/** returns an InputStream containing the Resource's contents */
- public InputStream getInputStream() throws IOException { return getInputStream(""); }
+ public final InputStream getInputStream() throws IOException { return new BackgroundInputStream(getInputStream("")); }
public abstract InputStream getInputStream(String path) throws IOException;
/** graft newResource in place of this resource on its parent */
return new FileInputStream((path + rest).replace('/', java.io.File.separatorChar)); }
}
- /** wrap a Res around a preexisting InputStream */
- public static class IS extends Res {
- InputStream parent;
- IS(InputStream parent) { this.parent = parent; }
- public InputStream getInputStream(String path) {
- if (!"".equals(path)) throw new JS.Exn("can't access subresources of IS");
- return parent;
- }
- }
-
/** "unwrap" a Zip archive */
public static class Zip extends Res {
private Res parent;
ZipInputStream zis = new ZipInputStream(parent.getInputStream());
ZipEntry ze = zis.getNextEntry();
while(ze != null && !ze.getName().equals(path)) ze = zis.getNextEntry();
- if (ze == null) throw new JS.Exn("requested file not found in archive");
+ if (ze == null) throw new JS.Exn("requested file (" + path + ") not found in archive");
return zis;
}
}