X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FRes.java;h=196bb2c04146f01f7c6c14d67019b1db72f22f45;hb=6a96430e10e27fc1de5754cb5add705f929dd109;hp=896220bb95e5fa6e75e35f1b7631fea326c1bdb6;hpb=308cbbe7be5a020b654771ea07ff07f13475793a;p=org.ibex.core.git diff --git a/src/org/xwt/Res.java b/src/org/xwt/Res.java index 896220b..196bb2c 100644 --- a/src/org/xwt/Res.java +++ b/src/org/xwt/Res.java @@ -21,8 +21,33 @@ public abstract class Res extends JS { public Res getParent() { return null; } + /** an InputStream that makes sure it is not in the MessageQueue when blocked on a read */ + // FIXME + 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 */ @@ -46,14 +71,15 @@ public abstract class Res extends JS { return ret; } - public static Res stringToRes(String url) { return stringToRes(url, false); } - public static Res stringToRes(String url, boolean permitLocalFilesystem) { - if (url.indexOf('!') != -1) - return (Res)(new Zip(stringToRes(url.substring(0, url.lastIndexOf('!')))). - get(url.substring(url.lastIndexOf('!') + 1))); + public static Res stringToRes(String url) { + if (url.indexOf('!') != -1) { + Res ret = new Zip(stringToRes(url.substring(0, url.lastIndexOf('!')))); + String subpath = url.substring(url.lastIndexOf('!') + 1); + if (subpath.length() > 0) ret = (Res)ret.get(subpath); + return ret; + } if (url.startsWith("http://")) return new HTTP(url); if (url.startsWith("https://")) return new HTTP(url); - if (url.startsWith("file:") && permitLocalFilesystem) return new File(url.substring(5)); if (url.startsWith("cab:")) return new CAB(stringToRes(url.substring(4))); if (url.startsWith("data:")) return new ByteArray(Base64.decode(url.substring(5))); if (url.startsWith("utf8:")) return new ByteArray(url.substring(5).getBytes()); @@ -78,6 +104,7 @@ public abstract class Res extends JS { public static class HTTP extends CachedRes { private String url; HTTP(String url) { this.url = url; } + public String getDescriptiveName() { return url; } public InputStream _getInputStream(String path) throws IOException { return new org.xwt.HTTP(url + path).GET(); } } @@ -86,6 +113,7 @@ public abstract class Res extends JS { public static class ByteArray extends Res { private byte[] bytes; ByteArray(byte[] bytes) { this.bytes = bytes; } + public String getDescriptiveName() { return "byte[]"; } public InputStream getInputStream(String path) throws IOException { if (!"".equals(path)) throw new JS.Exn("can't get subresources of a byte[] resource"); return new ByteArrayInputStream(bytes); @@ -96,34 +124,37 @@ public abstract class Res extends JS { public static class File extends Res { private String path; File(String path) { this.path = path; } + public String getDescriptiveName() { return "file://" + path; } public InputStream getInputStream(String rest) throws IOException { 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; Zip(Res parent) { this.parent = parent; } + public String getDescriptiveName() { return parent.getDescriptiveName() + "!"; } public InputStream getInputStream(String path) throws IOException { if (path.startsWith("/")) path = path.substring(1); - ZipInputStream zis = new ZipInputStream(parent.getInputStream()); + InputStream pis = parent.getInputStream(); + ZipInputStream zis = new ZipInputStream(pis); 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"); - return zis; + if (ze == null) throw new JS.Exn("requested file (" + path + ") not found in archive"); + return new KnownLength.KnownLengthInputStream(zis, (int)ze.getSize()); } } + /** the Builtin resource */ + public static class Builtin extends Res { + public Builtin() { }; + public String getDescriptiveName() { return "[builtin]"; } + public InputStream getInputStream(String path) throws IOException { + if (!path.equals("")) throw new IOException("the builtin resource has no subresources"); + return Platform.getBuiltinInputStream(); + } + } + /** what you get when you reference a subresource */ public static class Ref extends Res { Res parent; @@ -131,7 +162,9 @@ public abstract class Res extends JS { Ref(Res parent, Object key) { this.parent = parent; this.key = key; } public String getDescriptiveName() { String pdn = parent.getDescriptiveName(); - return pdn.equals("") ? key.toString() : (pdn + "." + key.toString()); + if (pdn.equals("")) return key.toString(); + if (!pdn.endsWith("!")) pdn += "."; + return pdn + key.toString(); } public Res addExtension(String extension) { return (key instanceof String && ((String)key).endsWith(extension)) ? this : new Ref(parent, key + extension); @@ -170,11 +203,13 @@ public abstract class Res extends JS { /** shadow resource which replaces the graft */ public static class ProgressWatcher extends Res { - Res watchee; - JS.Callable callback; - ProgressWatcher(Res watchee, JS.Callable callback) { this.watchee = watchee; this.callback = callback; } + final Res watchee; + JS.CompiledFunction callback; + ProgressWatcher(Res watchee, JS.CompiledFunction callback) { this.watchee = watchee; this.callback = callback; } + public String getDescriptiveName() { return watchee.getDescriptiveName(); } public InputStream getInputStream(String s) throws IOException { - return new FilterInputStream(watchee.getInputStream(s)) { + final InputStream is = watchee.getInputStream(s); + return new FilterInputStream(is) { int bytesDownloaded = 0; public int read() throws IOException { int ret = super.read(); @@ -184,10 +219,12 @@ public abstract class Res extends JS { public int read(byte[] b, int off, int len) throws IOException { int ret = super.read(b, off, len); if (ret != 1) bytesDownloaded += ret; - ThreadMessage.newthread(new JS.Callable() { public Object call(JS.Array a) { + Scheduler.add(new Scheduler.Task() { public Object call(Object arg) { JS.Array args = new JS.Array(); args.addElement(new Integer(bytesDownloaded)); - callback.call(args); + args.addElement(new Integer(is instanceof KnownLength ? ((KnownLength)is).getLength() : 0)); + // FIXME + // new JS.Thread(callback, callbackScope).resume(); return null; } }); return ret;