// FIXME remove this
private final JS rr;
- public Ibex(Stream rr) { try { this.rr = bless(rr);} catch(JSExn e) { throw new Error("should never happen"); } }
+ public Ibex(Stream rr) { try { this.rr = bless(rr);} catch(JSExn e) { throw new Error("should never happen: " + e); } }
public JS resolveString(String str, boolean permitAbsolute) throws JSExn {
if (str.indexOf("://") != -1) {
- if (permitAbsolute) return (Stream)url2res(str);
+ if (permitAbsolute) return url2res(str);
throw new JSExn("absolute URL " + str + " not permitted here");
}
// root-relative
return ((JS)a).jsclone();
case "bless": return bless((JS)a);
case "ui.browser": Platform.newBrowserWindow(JS.toString(a)); return null;
- case "stream.unzip": return new Stream.Zip((Stream)a);
- case "stream.uncab": return new Stream.Cab((Stream)a);
+ case "stream.unzip": return a == null ? null : new Stream.Zip(a);
+ case "stream.uncab": return a == null ? null : new Stream.Cab(a);
case "stream.cache":
- try { return new Stream.CachedStream((Stream)a, "resources", true); }
+ try { return a == null ? null : new Stream.CachedStream(a, "resources", true); }
catch (Stream.NotCacheableException e) { throw new JSExn("this resource cannot be cached"); }
case "stream.url": {
String url = JS.toString(a);
case "crypto.sha1": /* FEATURE */ return null;
case "crypto.rc4": /* FEATURE */ return null;
case "stream.parse.html": throw new JSExn("not implemented yet"); //return null;
- case "stream.parse.xml": new XMLHelper((JS)b).doParse((JS)a); return null;
+ case "stream.parse.xml": if(a == null) return null; new XMLHelper(b).doParse(a); return null;
// FIXME backgrounding
- case "stream.parse.utf8": try { return JS.S(new String(InputStreamToByteArray.convert(Stream.getInputStream(a)))); }
+ case "stream.parse.utf8": if(a == null) return null;
+ try { return JS.S(new String(InputStreamToByteArray.convert(a.getInputStream()))); }
catch (Exception e) { Log.warn(this, e); }
//#end
break;
case 2:
//#switch(name)
- case "stream.watch": return new Stream.ProgressWatcher((Stream)a, (JS)b);
+ case "stream.watch": return new Stream.ProgressWatcher(a, b);
case "regexp": return new JSRegexp(a, b);
//#end
case 3:
//#switch(name)
- case "ui.font.height": return N(Font.getFont((Stream)a, JS.toInt(b)).textheight(JS.toString(c)));
+ case "ui.font.height": return N(Font.getFont(a, JS.toInt(b)).textheight(JS.toString(c)));
case "ui.font.wait": throw new Error("FIXME: ibex.ui.font.wait not implemented");
- case "ui.font.width": return N(Font.getFont((Stream)a, JS.toInt(b)).textwidth(JS.toString(c)));
+ case "ui.font.width": return N(Font.getFont(a, JS.toInt(b)).textwidth(JS.toString(c)));
//#end
break;
}
throw new JSExn("invalid number of arguments ("+nargs+") for ibex object method "+name+"()");
}
- public Stream url2res(String url) throws JSExn {
+ public JS url2res(String url) throws JSExn {
if (url.startsWith("http://")) return new Stream.HTTP(url);
else if (url.startsWith("https://")) return new Stream.HTTP(url);
else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
public void doParse(JS s) throws JSExn {
try {
- parse(new BufferedReader(new InputStreamReader(Stream.getInputStream(s))));
+ parse(new BufferedReader(new InputStreamReader(s.getInputStream())));
} catch (Wrapper e) {
throw e.wrapee;
} catch (XML.Exn e) {
if (!(js instanceof Blessing)) return null;
return (Blessing)js;
}
+ // FEATURE: This is a gross hack
public InputStream getImage() throws JSExn {
try {
- InputStream in = Stream.getInputStream(this);
+ InputStream in = getInputStream();
if (in != null) return in;
} catch (IOException e) { /* DELIBERATE */ }
String[] exts = new String[] { ".png", ".jpeg", ".gif" };
for (int i=0; i < exts.length; i++)
try {
- InputStream in = Stream.getInputStream(parent.get(JS.S(JS.toString(parentkey) + exts[i])));
+ InputStream in = parent.get(JS.S(JS.toString(parentkey) + exts[i])).getInputStream();
if (in != null) return in;
} catch (IOException f) { /* DELIBERATE */ }
return null;
try {
if (t == null) {
// FEATURE: Might want to handle the ".t" part better
- JS res = (JS) parent.get(JS.S(JS.toString(parentkey) + ".t"));
- // FIXME: need a better description (Stream.toString())
- t = Template.buildTemplate(JS.toString(parentkey), res, ibex);
+ JS res = parent.get(JS.S(JS.toString(parentkey) + ".t"));
+ t = Template.buildTemplate(description(), res, ibex);
}
return t != null ? t.staticScope : null;
} catch (Exception e) {
return null;
}
}
+ private String description() {
+ String s = JS.debugToString(parentkey);
+ for(Blessing b = parent; b != null; b = b.parent) s = JS.debugToString(parentkey) + "." + s;
+ return s;
+ }
public JS call(JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
if (nargs != 1) throw new JSExn("can only call a template with one arg");
getStatic();
public TemplateHelper(String sourceName, JS s, Ibex ibex) throws XML.Exn, IOException, JSExn {
this.sourceName = sourceName;
this.ibex = ibex;
- InputStream is = Stream.getInputStream(s);
+ InputStream is = s.getInputStream();
Ibex.Blessing b = Ibex.Blessing.getBlessing(s).parent;
while(b != null) {
if(b.parentkey != null) initial_uri = JS.toString(b.parentkey) + (initial_uri.equals("") ? "" : "." + initial_uri);
try {
Log.info(Font.class, "loading font " + JS.debugToString(res));
- InputStream is = Stream.getInputStream(res);
+ InputStream is = res.getInputStream();
byte[] fontstream = InputStreamToByteArray.convert(is);
rt.free(loadedStreamAddr);
loadedStreamAddr = rt.xmalloc(fontstream.length);
new java.lang.Thread() { public void run() {
InputStream in = null;
try {
- in = b == null ? Stream.getInputStream(stream) : b.getImage();
+ in = b == null ? stream.getInputStream() : b.getImage();
} catch (IOException e) { Log.error(Picture.class, e);
} catch (JSExn e) { Log.error(Picture.class, e);
}
public Enumeration keys() throws JSExn { throw new JSExn("you can't enumerate the keys of this object (class=" + getClass().getName() +")"); }
public JS get(JS key) throws JSExn { return null; }
public void put(JS key, JS val) throws JSExn { throw new JSExn("" + key + " is read only (class=" + getClass().getName() +")"); }
+
+ public InputStream getInputStream() throws IOException {
+ throw new IOException("this object doesn't have a stream associated with it " + getClass().getName() + ")");
+ }
public final boolean hasTrap(JS key) { return getTrap(key) != null; }
public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
throw new JSExn("method not found (" + JS.debugToString(method) + ")");
- }
+ }
// FIXME: JSArgs objects, pointers into stack frame
public JS call(JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
JS _unclone() { return clonee.unclone(); }
public JS getClonee() { return clonee; }
public Clone(JS clonee) throws JSExn {
- if(!(clonee instanceof Cloneable)) throw new JSExn("" + getClass().getName() + " isn't cloneable");
+ if(!(clonee instanceof Cloneable)) throw new JSExn("" + clonee.getClass().getName() + " isn't cloneable");
this.clonee = clonee;
}
public boolean jsequals(JS o) { return unclone().jsequals(o.unclone()); }
public JS call(JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
return clonee.call(a0, a1, a2, rest, nargs);
}
+ public InputStream getInputStream() throws IOException { return clonee.getInputStream(); }
}
// Static Interpreter Control Methods ///////////////////////////////////////////////////////////////
// Public Interface //////////////////////////////////////////////////////////////////////////////
- // FIXME: This should be in JS, "everything has a stream"
- public static InputStream getInputStream(JS js) throws IOException { return ((Stream)js.unclone()).getInputStream();}
+ /*public static InputStream getInputStream(JS js) throws IOException { return ((Stream)js.unclone()).getInputStream();}*/
public static class NotCacheableException extends Exception { }
private Cache getCache = new Cache(100);
- // FEATURE: Mandate that Streams use only String keys?
- protected JS _get(JS key) throws JSExn { return null; }
+ public abstract JS _get(String key);
public final JS get(JS key) throws JSExn {
JS ret = (JS) getCache.get(key);
- if (ret == null) getCache.put(key, ret = _get(key));
+ if (ret == null) getCache.put(key, ret = _get(JS.toString(key)));
return ret;
}
// Private Interface //////////////////////////////////////////////////////////////////////////////
+ static String getCacheKey(JS s) throws NotCacheableException {
+ if(s instanceof Stream) return ((Stream)s).getCacheKey();
+ throw new NotCacheableException();
+ }
+
public abstract InputStream getInputStream() throws IOException;
protected String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); }
// FEATURE: Only instansiate only ibex.net.HTTP, share with all substreams
public static class HTTP extends Stream {
private String url;
- public String coerceToString() { return "Stream.HTTP:" + url; }
public HTTP(String url) { while (url.endsWith("/")) url = url.substring(0, url.length() - 1); this.url = url; }
- public JS _get(JS key) throws JSExn { return new HTTP(url + "/" + JS.toString(key)); }
+ public JS _get(String key) { return new HTTP(url + "/" + key); }
public String getCacheKey(Vec path) throws NotCacheableException { return url; }
public InputStream getInputStream() throws IOException { return new org.ibex.net.HTTP(url).GET(); }
}
public String getCacheKey() throws NotCacheableException {
if (cacheKey == null) throw new NotCacheableException(); return cacheKey; }
public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(bytes); }
+ public JS _get(String key) { return null; }
}
/** a file */
public static class File extends Stream {
private String path;
public File(String path) { this.path = path; }
- public String coerceToString() { return "file:" + path; }
public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); /* already on disk */ }
public InputStream getInputStream() throws IOException { return new FileInputStream(path); }
- public JS _get(JS key) throws JSExn { return new File(path + java.io.File.separatorChar + JS.toString(key)); }
+ public JS _get(String key) { return new File(path + java.io.File.separatorChar + key); }
}
/** "unwrap" a Zip archive */
public static class Zip extends Stream {
- private Stream parent;
+ private JS parent;
private String path;
- public Zip(Stream parent) { this(parent, null); }
- public Zip(Stream parent, String path) {
+ public Zip(JS parent) { this(parent, null); }
+ public Zip(JS parent, String path) {
while(path != null && path.startsWith("/")) path = path.substring(1);
this.parent = parent;
this.path = path;
}
- public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!zip:"; }
- public JS _get(JS key) throws JSExn { return new Zip(parent, path==null?JS.toString(key):path+'/'+JS.toString(key)); }
+ public String getCacheKey() throws NotCacheableException { return getCacheKey(parent) + "!zip:"; }
+ public JS _get(String key) { return new Zip(parent, path==null?key:path+'/'+key); }
public InputStream getInputStream() throws IOException {
InputStream pis = parent.getInputStream();
ZipInputStream zis = new ZipInputStream(pis);
/** "unwrap" a Cab archive */
public static class Cab extends Stream {
- private Stream parent;
+ private JS parent;
private String path;
- public Cab(Stream parent) { this(parent, null); }
- public Cab(Stream parent, String path) { this.parent = parent; this.path = path; }
- public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!cab:"; }
- public JS _get(JS key) throws JSExn { return new Cab(parent, path==null?JS.toString(key):path+'/'+JS.toString(key)); }
+ public Cab(JS parent) { this(parent, null); }
+ public Cab(JS parent, String path) { this.parent = parent; this.path = path; }
+ public String getCacheKey() throws NotCacheableException { return getCacheKey(parent) + "!cab:"; }
+ public JS _get(String key) { return new Cab(parent, path==null?key:path+'/'+key); }
public InputStream getInputStream() throws IOException { return new MSPack(parent.getInputStream()).getInputStream(path); }
}
public static class Builtin extends Stream {
public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); }
public InputStream getInputStream() throws IOException { return Platform.getBuiltinInputStream(); }
+ public JS _get(String key) { return null; }
}
/** shadow resource which replaces the graft */
public static class ProgressWatcher extends Stream {
- final Stream watchee;
+ final JS watchee;
JS callback;
- public ProgressWatcher(Stream watchee, JS callback) { this.watchee = watchee; this.callback = callback; }
- public String getCacheKey() throws NotCacheableException { return watchee.getCacheKey(); }
+ public ProgressWatcher(JS watchee, JS callback) { this.watchee = watchee; this.callback = callback; }
+ public String getCacheKey() throws NotCacheableException { return getCacheKey(watchee); }
public InputStream getInputStream() throws IOException {
final InputStream is = watchee.getInputStream();
return new FilterInputStream(is) {
}
};
}
+ public JS _get(String s) { return null; }
}
/** subclass from this if you want a CachedInputStream for each path */
public static class CachedStream extends Stream {
- private Stream parent;
+ private JS parent;
private boolean disk = false;
private String key;
+ private String s;
public String getCacheKey() throws NotCacheableException { return key; }
CachedInputStream cis = null;
- public CachedStream(Stream p, String s, boolean d) throws NotCacheableException {
- this.parent = p; this.disk = d; this.key = p.getCacheKey();
+ public CachedStream(JS p, String s, boolean d) throws NotCacheableException {
+ this.parent = p; this.s = s; this.disk = d; this.key = getCacheKey(p);
}
public InputStream getInputStream() throws IOException {
if (cis != null) return cis.getInputStream();
if (!disk) {
cis = new CachedInputStream(parent.getInputStream());
} else {
+ // FEATURE: Move LocalStorage into org.ibex.js or move this out
java.io.File f = org.ibex.core.LocalStorage.Cache.getCacheFileForKey(key);
if (f.exists()) return new FileInputStream(f);
cis = new CachedInputStream(parent.getInputStream(), f);
}
return cis.getInputStream();
}
+ public JS _get(String s) { return null; }
}
}