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     }