1 cananian 1.1.2.1 // INFileInputStream.java, created Wed Dec 30 02:01:00 1998 by cananian 2 cananian 1.1.2.3 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.3 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Interpret.Quads; 5 cananian 1.1.2.1 6 cananian 1.1.2.2 import harpoon.ClassFile.HClass; 7 cananian 1.1.2.2 import harpoon.ClassFile.HField; 8 cananian 1.1.2.2 import harpoon.ClassFile.HMethod; 9 cananian 1.1.2.1 10 cananian 1.1.2.1 import java.io.FileInputStream; 11 cananian 1.1.2.1 import java.io.InputStream; 12 cananian 1.1.2.1 import java.io.IOException; 13 cananian 1.1.2.1 /** 14 cananian 1.1.2.1 * <code>INFileInputStream</code> provides implementations of the native 15 cananian 1.1.2.1 * methods in <code>java.io.FileInputStream</code>. 16 cananian 1.1.2.1 * 17 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 18 cananian 1.2 * @version $Id: INFileInputStream.java,v 1.2 2002/02/25 21:05:45 cananian Exp $ 19 cananian 1.1.2.1 */ 20 cananian 1.1.2.6 final class INFileInputStream { 21 cananian 1.1.2.1 static final void register(StaticState ss) { 22 cananian 1.1.2.7 ss.registerOverride(fdConstructor(ss)); 23 cananian 1.1.2.6 ss.register(open(ss)); 24 cananian 1.1.2.6 ss.register(close(ss)); 25 cananian 1.1.2.6 ss.register(read(ss)); 26 cananian 1.1.2.6 ss.register(readBytes(ss)); 27 cananian 1.1.2.6 ss.register(skip(ss)); 28 cananian 1.1.2.6 ss.register(available(ss)); 29 cananian 1.1.2.4 // JDK 1.2 only 30 cananian 1.1.2.6 try { ss.register(initIDs(ss)); } catch (NoSuchMethodError e) { } 31 cananian 1.1.2.1 } 32 cananian 1.1.2.1 // associate shadow InputStream with every object. 33 cananian 1.1.2.5 // Make a serializable wrapper for it. 34 cananian 1.1.2.5 static class InputStreamWrapper implements java.io.Serializable { 35 cananian 1.1.2.5 transient InputStream is; 36 cananian 1.1.2.5 InputStreamWrapper(InputStream is) { this.is = is; } 37 cananian 1.1.2.5 private void writeObject(java.io.ObjectOutputStream out) 38 cananian 1.1.2.5 throws java.io.IOException { 39 cananian 1.1.2.5 if (is==System.in) out.writeByte(0); 40 cananian 1.1.2.5 else throw new java.io.NotSerializableException(); 41 cananian 1.1.2.5 } 42 cananian 1.1.2.5 private void readObject(java.io.ObjectInputStream in) 43 cananian 1.1.2.5 throws java.io.IOException { 44 cananian 1.1.2.5 switch(in.readByte()) { 45 cananian 1.1.2.5 case 0: is = System.in; break; 46 cananian 1.1.2.5 default: throw new java.io.InvalidObjectException("Unknown input stream."); 47 cananian 1.1.2.5 } 48 cananian 1.1.2.5 } 49 cananian 1.1.2.5 } 50 cananian 1.1.2.9 // helper method: create a new interpreted FileInputStream from a real one. 51 cananian 1.1.2.9 static ObjectRef openInputStream(StaticState ss, InputStream is) { 52 cananian 1.1.2.9 // make fileinputstream object 53 cananian 1.1.2.9 ObjectRef fis_obj = new ObjectRef(ss, ss.HCfistream); 54 cananian 1.1.2.9 fis_obj.putClosure(new InputStreamWrapper(is)); 55 cananian 1.1.2.9 // make file descriptor object 56 cananian 1.1.2.9 ObjectRef fd_obj = new ObjectRef(ss, ss.HCfiledesc); 57 cananian 1.1.2.9 // mark file descriptor to indicate it is 'valid'. 58 cananian 1.1.2.9 HField hf1 = ss.HCfiledesc.getField("fd"); 59 cananian 1.1.2.9 fd_obj.update(hf1, new Integer(4)); 60 cananian 1.1.2.9 // set fileinputstream's filedescriptor. 61 cananian 1.1.2.9 HField hf0 = ss.HCfistream.getField("fd"); 62 cananian 1.1.2.9 fis_obj.update(hf0, fd_obj); 63 cananian 1.1.2.9 // done. 64 cananian 1.1.2.9 return fis_obj; 65 cananian 1.1.2.9 } 66 cananian 1.1.2.1 67 cananian 1.1.2.1 private static final ObjectRef security(StaticState ss) 68 cananian 1.1.2.1 throws InterpretedThrowable { 69 cananian 1.1.2.6 HMethod hm=ss.HCsystem.getMethod("getSecurityManager", new HClass[0]); 70 cananian 1.1.2.1 return (ObjectRef) Method.invoke(ss, hm, new Object[0]); 71 cananian 1.1.2.1 } 72 cananian 1.1.2.1 73 cananian 1.1.2.1 // disallow constructor from FileDescriptor 74 cananian 1.1.2.6 private static final NativeMethod fdConstructor(StaticState ss0) { 75 cananian 1.1.2.6 final HMethod hm = 76 cananian 1.1.2.6 ss0.HCfistream.getConstructor(new HClass[] { ss0.HCfiledesc }); 77 cananian 1.1.2.1 return new NativeMethod() { 78 cananian 1.1.2.1 HMethod getMethod() { return hm; } 79 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 80 cananian 1.1.2.1 throws InterpretedThrowable { 81 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 82 cananian 1.1.2.1 ObjectRef fd_obj = (ObjectRef) params[1]; 83 cananian 1.1.2.1 // check safety. 84 cananian 1.1.2.1 if (fd_obj==null) { 85 cananian 1.1.2.1 ObjectRef ex_obj = 86 cananian 1.1.2.6 ss.makeThrowable(ss.HCnullpointerE); 87 cananian 1.1.2.1 throw new InterpretedThrowable(ex_obj, ss); 88 cananian 1.1.2.1 } 89 cananian 1.1.2.1 ObjectRef security = security(ss); 90 cananian 1.1.2.1 if (security != null) { 91 cananian 1.1.2.1 HMethod HMcr = 92 cananian 1.1.2.6 ss.HCsmanager.getMethod("checkRead", 93 cananian 1.1.2.6 new HClass[] { ss.HCfiledesc }); 94 cananian 1.1.2.1 Method.invoke(ss, HMcr, new Object[] { fd_obj }); 95 cananian 1.1.2.1 } 96 cananian 1.1.2.4 // compare supplied file descriptor to FileDescriptor.in 97 cananian 1.1.2.6 HField hf = ss.HCfiledesc.getField("in"); 98 cananian 1.1.2.4 if (fd_obj == ss.get(hf)) { // System.in 99 cananian 1.1.2.5 obj.putClosure(new InputStreamWrapper(System.in)); 100 cananian 1.1.2.6 HField hf0 = ss.HCfistream.getField("fd"); 101 cananian 1.1.2.1 obj.update(hf0, fd_obj); 102 cananian 1.1.2.1 return null; 103 cananian 1.1.2.1 } else { 104 cananian 1.1.2.1 ObjectRef ex_obj = 105 cananian 1.1.2.6 ss.makeThrowable(ss.HCioE, "unsupported."); 106 cananian 1.1.2.1 throw new InterpretedThrowable(ex_obj, ss); 107 cananian 1.1.2.1 } 108 cananian 1.1.2.1 } 109 cananian 1.1.2.1 }; 110 cananian 1.1.2.1 } 111 cananian 1.1.2.6 private static final NativeMethod open(StaticState ss0) { 112 cananian 1.1.2.6 final HMethod hm = 113 cananian 1.1.2.6 ss0.HCfistream.getMethod("open", new HClass[] { ss0.HCstring }); 114 cananian 1.1.2.1 return new NativeMethod() { 115 cananian 1.1.2.1 HMethod getMethod() { return hm; } 116 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 117 cananian 1.1.2.1 throws InterpretedThrowable { 118 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 119 cananian 1.1.2.1 String filename = ss.ref2str((ObjectRef) params[1]); 120 cananian 1.1.2.9 if (ss.TRACE) 121 cananian 1.1.2.1 System.err.println("OPENING "+filename); 122 cananian 1.1.2.1 try { 123 cananian 1.1.2.5 obj.putClosure(new InputStreamWrapper(new FileInputStream(filename))); 124 cananian 1.1.2.1 // mark file descriptor to indicate it is 'valid'. 125 cananian 1.1.2.6 HField hf0 = ss.HCfistream.getField("fd"); 126 cananian 1.1.2.6 HField hf1 = ss.HCfiledesc.getField("fd"); 127 cananian 1.1.2.1 ((ObjectRef)obj.get(hf0)).update(hf1, new Integer(4)); 128 cananian 1.1.2.1 return null; 129 cananian 1.1.2.1 } catch (IOException e) { 130 cananian 1.1.2.8 obj = ss.makeThrowable 131 cananian 1.1.2.8 (ss.linker.forName("java.io.FileNotFoundException"), 132 cananian 1.1.2.8 e.getMessage()); 133 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 134 cananian 1.1.2.1 } catch (SecurityException e) { 135 cananian 1.1.2.6 obj = ss.makeThrowable(ss.HCsecurityE, e.getMessage()); 136 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 137 cananian 1.1.2.1 } 138 cananian 1.1.2.1 } 139 cananian 1.1.2.1 }; 140 cananian 1.1.2.1 } 141 cananian 1.1.2.6 private static final NativeMethod close(StaticState ss0) { 142 cananian 1.1.2.6 final HMethod hm = ss0.HCfistream.getMethod("close", new HClass[0]); 143 cananian 1.1.2.1 return new NativeMethod() { 144 cananian 1.1.2.1 HMethod getMethod() { return hm; } 145 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 146 cananian 1.1.2.1 throws InterpretedThrowable { 147 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 148 cananian 1.1.2.5 InputStream is = ((InputStreamWrapper) obj.getClosure()).is; 149 cananian 1.1.2.6 HField hf = ss.HCfistream.getField("fd"); 150 cananian 1.1.2.1 try { 151 cananian 1.1.2.1 is.close(); 152 cananian 1.1.2.1 obj.putClosure(null); 153 cananian 1.1.2.1 obj.update(hf, null); 154 cananian 1.1.2.1 return null; 155 cananian 1.1.2.1 } catch (IOException e) { 156 cananian 1.1.2.6 obj = ss.makeThrowable(ss.HCioE, e.getMessage()); 157 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 158 cananian 1.1.2.1 } 159 cananian 1.1.2.1 } 160 cananian 1.1.2.1 }; 161 cananian 1.1.2.1 } 162 cananian 1.1.2.6 private static final NativeMethod read(StaticState ss0) { 163 cananian 1.1.2.1 final HMethod hm = 164 cananian 1.1.2.6 ss0.HCfistream.getMethod("read", "()I"); 165 cananian 1.1.2.1 return new NativeMethod() { 166 cananian 1.1.2.1 HMethod getMethod() { return hm; } 167 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 168 cananian 1.1.2.1 throws InterpretedThrowable { 169 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 170 cananian 1.1.2.5 InputStream is = ((InputStreamWrapper) obj.getClosure()).is; 171 cananian 1.1.2.1 try { 172 cananian 1.1.2.1 return new Integer(is.read()); 173 cananian 1.1.2.1 } catch (IOException e) { 174 cananian 1.1.2.6 obj = ss.makeThrowable(ss.HCioE, e.getMessage()); 175 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 176 cananian 1.1.2.1 } 177 cananian 1.1.2.1 } 178 cananian 1.1.2.1 }; 179 cananian 1.1.2.1 } 180 cananian 1.1.2.6 private static final NativeMethod readBytes(StaticState ss0) { 181 cananian 1.1.2.1 final HMethod hm = 182 cananian 1.1.2.6 ss0.HCfistream.getMethod("readBytes", "([BII)I"); 183 cananian 1.1.2.1 return new NativeMethod() { 184 cananian 1.1.2.1 HMethod getMethod() { return hm; } 185 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 186 cananian 1.1.2.1 throws InterpretedThrowable { 187 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 188 cananian 1.1.2.1 ArrayRef ba = (ArrayRef) params[1]; 189 cananian 1.1.2.1 int off = ((Integer) params[2]).intValue(); 190 cananian 1.1.2.1 int len = ((Integer) params[3]).intValue(); 191 cananian 1.1.2.5 InputStream is = ((InputStreamWrapper) obj.getClosure()).is; 192 cananian 1.1.2.1 try { 193 cananian 1.1.2.1 byte[] b = new byte[len]; 194 cananian 1.1.2.1 len = is.read(b, 0, len); 195 cananian 1.1.2.1 // copy into byte array. 196 cananian 1.1.2.1 for (int i=0; i<len; i++) 197 cananian 1.1.2.1 ba.update(off+i, new Byte(b[i])); 198 cananian 1.1.2.1 return new Integer(len); 199 cananian 1.1.2.1 } catch (IOException e) { 200 cananian 1.1.2.6 obj = ss.makeThrowable(ss.HCioE, e.getMessage()); 201 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 202 cananian 1.1.2.1 } 203 cananian 1.1.2.1 } 204 cananian 1.1.2.1 }; 205 cananian 1.1.2.1 } 206 cananian 1.1.2.6 private static final NativeMethod skip(StaticState ss0) { 207 cananian 1.1.2.1 final HMethod hm = 208 cananian 1.1.2.6 ss0.HCfistream.getMethod("skip", "(J)J" ); 209 cananian 1.1.2.1 return new NativeMethod() { 210 cananian 1.1.2.1 HMethod getMethod() { return hm; } 211 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 212 cananian 1.1.2.1 throws InterpretedThrowable { 213 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 214 cananian 1.1.2.1 Long n = (Long) params[1]; 215 cananian 1.1.2.5 InputStream is = ((InputStreamWrapper) obj.getClosure()).is; 216 cananian 1.1.2.1 try { 217 cananian 1.1.2.1 return new Long(is.skip(n.longValue())); 218 cananian 1.1.2.1 } catch (IOException e) { 219 cananian 1.1.2.6 obj = ss.makeThrowable(ss.HCioE, e.getMessage()); 220 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 221 cananian 1.1.2.1 } 222 cananian 1.1.2.1 } 223 cananian 1.1.2.1 }; 224 cananian 1.1.2.1 } 225 cananian 1.1.2.6 private static final NativeMethod available(StaticState ss0) { 226 cananian 1.1.2.1 final HMethod hm = 227 cananian 1.1.2.6 ss0.HCfistream.getMethod("available", "()I" ); 228 cananian 1.1.2.1 return new NativeMethod() { 229 cananian 1.1.2.1 HMethod getMethod() { return hm; } 230 cananian 1.1.2.1 Object invoke(StaticState ss, Object[] params) 231 cananian 1.1.2.1 throws InterpretedThrowable { 232 cananian 1.1.2.1 ObjectRef obj = (ObjectRef) params[0]; 233 cananian 1.1.2.5 InputStream is = ((InputStreamWrapper) obj.getClosure()).is; 234 cananian 1.1.2.1 try { 235 cananian 1.1.2.1 return new Integer(is.available()); 236 cananian 1.1.2.1 } catch (IOException e) { 237 cananian 1.1.2.6 obj = ss.makeThrowable(ss.HCioE, e.getMessage()); 238 cananian 1.1.2.1 throw new InterpretedThrowable(obj, ss); 239 cananian 1.1.2.1 } 240 cananian 1.1.2.1 } 241 cananian 1.1.2.1 }; 242 cananian 1.1.2.4 } 243 cananian 1.1.2.4 // "initialize JNI offsets" for JDK 1.2. Currently a NOP. 244 cananian 1.1.2.6 private static final NativeMethod initIDs(StaticState ss0) { 245 cananian 1.1.2.4 final HMethod hm = 246 cananian 1.1.2.6 ss0.HCfistream.getMethod("initIDs", new HClass[0]); 247 cananian 1.1.2.4 return new NullNativeMethod(hm); 248 cananian 1.1.2.1 } 249 cananian 1.2 }