Mercurial Hosting > luan
comparison src/luan/modules/IoLuan.java @ 168:ebe9db183eb7
rename *Lib.java to *Luan.java
git-svn-id: https://luan-java.googlecode.com/svn/trunk@169 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Sun, 22 Jun 2014 04:42:07 +0000 |
parents | src/luan/modules/IoLib.java@4c0131c2b650 |
children |
comparison
equal
deleted
inserted
replaced
167:4c0131c2b650 | 168:ebe9db183eb7 |
---|---|
1 package luan.modules; | |
2 | |
3 import java.io.InputStream; | |
4 import java.io.OutputStream; | |
5 import java.io.PrintStream; | |
6 import java.io.Reader; | |
7 import java.io.Writer; | |
8 import java.io.FileReader; | |
9 import java.io.FileWriter; | |
10 import java.io.BufferedReader; | |
11 import java.io.BufferedWriter; | |
12 import java.io.BufferedInputStream; | |
13 import java.io.BufferedOutputStream; | |
14 import java.io.File; | |
15 import java.io.FileInputStream; | |
16 import java.io.FileOutputStream; | |
17 import java.io.InputStreamReader; | |
18 import java.io.OutputStreamWriter; | |
19 import java.io.ByteArrayInputStream; | |
20 import java.io.DataInputStream; | |
21 import java.io.DataOutputStream; | |
22 import java.io.IOException; | |
23 import java.net.URL; | |
24 import java.net.Socket; | |
25 import java.net.ServerSocket; | |
26 import java.net.MalformedURLException; | |
27 import luan.LuanState; | |
28 import luan.LuanTable; | |
29 import luan.LuanFunction; | |
30 import luan.LuanJavaFunction; | |
31 import luan.LuanException; | |
32 | |
33 | |
34 public final class IoLuan { | |
35 | |
36 public static final LuanFunction LOADER = new LuanFunction() { | |
37 @Override public Object call(LuanState luan,Object[] args) { | |
38 LuanTable module = new LuanTable(); | |
39 try { | |
40 add( module, "File", LuanState.class, String.class ); | |
41 add( module, "read_console_line", String.class ); | |
42 | |
43 LuanTable stdin = new LuanTable(); | |
44 stdin.put( "read_text", new LuanJavaFunction( | |
45 IoLuan.class.getMethod( "stdin_read_text" ), null | |
46 ) ); | |
47 stdin.put( "read_binary", new LuanJavaFunction( | |
48 IoLuan.class.getMethod( "stdin_read_binary" ), null | |
49 ) ); | |
50 stdin.put( "read_lines", new LuanJavaFunction( | |
51 IoLuan.class.getMethod( "stdin_read_lines" ), null | |
52 ) ); | |
53 stdin.put( "read_blocks", new LuanJavaFunction( | |
54 IoLuan.class.getMethod( "stdin_read_blocks", Integer.class ), null | |
55 ) ); | |
56 module.put( "stdin", stdin ); | |
57 | |
58 add( module, "Socket", String.class, Integer.TYPE ); | |
59 add( module, "socket_server", Integer.TYPE ); | |
60 } catch(NoSuchMethodException e) { | |
61 throw new RuntimeException(e); | |
62 } | |
63 module.put( "stdout", textWriter(System.out) ); | |
64 module.put( "stderr", textWriter(System.err) ); | |
65 return module; | |
66 } | |
67 }; | |
68 | |
69 private static void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { | |
70 t.put( method, new LuanJavaFunction(IoLuan.class.getMethod(method,parameterTypes),null) ); | |
71 } | |
72 | |
73 | |
74 public static String stdin_read_text() throws IOException { | |
75 return Utils.readAll(new InputStreamReader(System.in)); | |
76 } | |
77 | |
78 public static byte[] stdin_read_binary() throws IOException { | |
79 return Utils.readAll(System.in); | |
80 } | |
81 | |
82 public static LuanFunction stdin_read_lines() throws IOException { | |
83 return lines(new BufferedReader(new InputStreamReader(System.in))); | |
84 } | |
85 | |
86 public static LuanFunction stdin_read_blocks(Integer blockSize) throws IOException { | |
87 int n = blockSize!=null ? blockSize : Utils.bufSize; | |
88 return blocks(System.in,n); | |
89 } | |
90 | |
91 public static String read_console_line(String prompt) throws IOException { | |
92 if( prompt==null ) | |
93 prompt = "> "; | |
94 return System.console().readLine(prompt); | |
95 } | |
96 | |
97 | |
98 public interface LuanWriter { | |
99 public void write(LuanState luan,Object... args) throws LuanException, IOException; | |
100 public void close() throws IOException; | |
101 } | |
102 | |
103 public static LuanTable textWriter(final PrintStream out) { | |
104 LuanWriter luanWriter = new LuanWriter() { | |
105 | |
106 public void write(LuanState luan,Object... args) throws LuanException { | |
107 for( Object obj : args ) { | |
108 out.print( luan.toString(obj) ); | |
109 } | |
110 } | |
111 | |
112 public void close() { | |
113 out.close(); | |
114 } | |
115 }; | |
116 return writer(luanWriter); | |
117 } | |
118 | |
119 public static LuanTable textWriter(final Writer out) { | |
120 LuanWriter luanWriter = new LuanWriter() { | |
121 | |
122 public void write(LuanState luan,Object... args) throws LuanException, IOException { | |
123 for( Object obj : args ) { | |
124 out.write( luan.toString(obj) ); | |
125 } | |
126 } | |
127 | |
128 public void close() throws IOException { | |
129 out.close(); | |
130 } | |
131 }; | |
132 return writer(luanWriter); | |
133 } | |
134 | |
135 private static LuanTable writer(LuanWriter luanWriter) { | |
136 LuanTable writer = new LuanTable(); | |
137 try { | |
138 writer.put( "write", new LuanJavaFunction( | |
139 LuanWriter.class.getMethod( "write", LuanState.class, new Object[0].getClass() ), luanWriter | |
140 ) ); | |
141 writer.put( "close", new LuanJavaFunction( | |
142 LuanWriter.class.getMethod( "close" ), luanWriter | |
143 ) ); | |
144 } catch(NoSuchMethodException e) { | |
145 throw new RuntimeException(e); | |
146 } | |
147 return writer; | |
148 } | |
149 | |
150 | |
151 public static LuanTable binaryWriter(final OutputStream out) { | |
152 LuanTable writer = new LuanTable(); | |
153 try { | |
154 writer.put( "write", new LuanJavaFunction( | |
155 OutputStream.class.getMethod( "write", new byte[0].getClass() ), out | |
156 ) ); | |
157 writer.put( "close", new LuanJavaFunction( | |
158 OutputStream.class.getMethod( "close" ), out | |
159 ) ); | |
160 } catch(NoSuchMethodException e) { | |
161 throw new RuntimeException(e); | |
162 } | |
163 return writer; | |
164 } | |
165 | |
166 static LuanFunction lines(final BufferedReader in) { | |
167 return new LuanFunction() { | |
168 @Override public Object call(LuanState luan,Object[] args) throws LuanException { | |
169 try { | |
170 if( args.length > 0 ) { | |
171 if( args.length > 1 || !"close".equals(args[0]) ) | |
172 throw luan.exception( "the only argument allowed is 'close'" ); | |
173 in.close(); | |
174 return null; | |
175 } | |
176 String rtn = in.readLine(); | |
177 if( rtn==null ) | |
178 in.close(); | |
179 return rtn; | |
180 } catch(IOException e) { | |
181 throw luan.exception(e); | |
182 } | |
183 } | |
184 }; | |
185 } | |
186 | |
187 static LuanFunction blocks(final InputStream in,final int blockSize) { | |
188 return new LuanFunction() { | |
189 final byte[] a = new byte[blockSize]; | |
190 | |
191 @Override public Object call(LuanState luan,Object[] args) throws LuanException { | |
192 try { | |
193 if( args.length > 0 ) { | |
194 if( args.length > 1 || !"close".equals(args[0]) ) | |
195 throw luan.exception( "the only argument allowed is 'close'" ); | |
196 in.close(); | |
197 return null; | |
198 } | |
199 if( in.read(a) == -1 ) { | |
200 in.close(); | |
201 return null; | |
202 } | |
203 return a; | |
204 } catch(IOException e) { | |
205 throw luan.exception(e); | |
206 } | |
207 } | |
208 }; | |
209 } | |
210 | |
211 | |
212 | |
213 public static abstract class LuanIn { | |
214 abstract InputStream inputStream() throws IOException; | |
215 public abstract String to_string(); | |
216 | |
217 public String read_text() throws IOException { | |
218 Reader in = new InputStreamReader(inputStream()); | |
219 String s = Utils.readAll(in); | |
220 in.close(); | |
221 return s; | |
222 } | |
223 | |
224 public byte[] read_binary() throws IOException { | |
225 InputStream in = inputStream(); | |
226 byte[] a = Utils.readAll(in); | |
227 in.close(); | |
228 return a; | |
229 } | |
230 | |
231 public LuanFunction read_lines() throws IOException { | |
232 return lines(new BufferedReader(new InputStreamReader(inputStream()))); | |
233 } | |
234 | |
235 public LuanFunction read_blocks(Integer blockSize) throws IOException { | |
236 int n = blockSize!=null ? blockSize : Utils.bufSize; | |
237 return blocks(inputStream(),n); | |
238 } | |
239 | |
240 LuanTable table() { | |
241 LuanTable tbl = new LuanTable(); | |
242 try { | |
243 tbl.put( "to_string", new LuanJavaFunction( | |
244 LuanIn.class.getMethod( "to_string" ), this | |
245 ) ); | |
246 tbl.put( "read_text", new LuanJavaFunction( | |
247 LuanIn.class.getMethod( "read_text" ), this | |
248 ) ); | |
249 tbl.put( "read_binary", new LuanJavaFunction( | |
250 LuanIn.class.getMethod( "read_binary" ), this | |
251 ) ); | |
252 tbl.put( "read_lines", new LuanJavaFunction( | |
253 LuanIn.class.getMethod( "read_lines" ), this | |
254 ) ); | |
255 tbl.put( "read_blocks", new LuanJavaFunction( | |
256 LuanIn.class.getMethod( "read_blocks", Integer.class ), this | |
257 ) ); | |
258 } catch(NoSuchMethodException e) { | |
259 throw new RuntimeException(e); | |
260 } | |
261 return tbl; | |
262 } | |
263 } | |
264 | |
265 public static abstract class LuanIO extends LuanIn { | |
266 abstract OutputStream outputStream() throws IOException; | |
267 | |
268 public void write(LuanState luan,Object obj) throws LuanException, IOException { | |
269 if( obj instanceof String ) { | |
270 String s = (String)obj; | |
271 Writer out = new OutputStreamWriter(outputStream()); | |
272 out.write(s); | |
273 out.close(); | |
274 return; | |
275 } | |
276 if( obj instanceof byte[] ) { | |
277 byte[] a = (byte[])obj; | |
278 OutputStream out = outputStream(); | |
279 Utils.copyAll(new ByteArrayInputStream(a),out); | |
280 out.close(); | |
281 return; | |
282 } | |
283 throw luan.exception( "bad argument #1 to 'write' (string or binary expected)" ); | |
284 } | |
285 | |
286 public LuanTable text_writer() throws IOException { | |
287 return textWriter(new BufferedWriter(new OutputStreamWriter(outputStream()))); | |
288 } | |
289 | |
290 public LuanTable binary_writer() throws IOException { | |
291 return binaryWriter(new BufferedOutputStream(outputStream())); | |
292 } | |
293 | |
294 @Override LuanTable table() { | |
295 LuanTable tbl = super.table(); | |
296 try { | |
297 tbl.put( "write", new LuanJavaFunction( | |
298 LuanIO.class.getMethod( "write", LuanState.class, Object.class ), this | |
299 ) ); | |
300 tbl.put( "text_writer", new LuanJavaFunction( | |
301 LuanIO.class.getMethod( "text_writer" ), this | |
302 ) ); | |
303 tbl.put( "binary_writer", new LuanJavaFunction( | |
304 LuanIO.class.getMethod( "binary_writer" ), this | |
305 ) ); | |
306 } catch(NoSuchMethodException e) { | |
307 throw new RuntimeException(e); | |
308 } | |
309 return tbl; | |
310 } | |
311 } | |
312 | |
313 public static final class LuanUrl extends LuanIn { | |
314 private final URL url; | |
315 | |
316 public LuanUrl(String s) throws MalformedURLException { | |
317 this.url = new URL(s); | |
318 } | |
319 | |
320 @Override InputStream inputStream() throws IOException { | |
321 return url.openStream(); | |
322 } | |
323 | |
324 @Override public String to_string() { | |
325 return url.toString(); | |
326 } | |
327 } | |
328 | |
329 public static final class LuanFile extends LuanIO { | |
330 private final File file; | |
331 | |
332 public LuanFile(String name) { | |
333 this(new File(name)); | |
334 } | |
335 | |
336 public LuanFile(File file) { | |
337 this.file = file; | |
338 } | |
339 | |
340 @Override InputStream inputStream() throws IOException { | |
341 return new FileInputStream(file); | |
342 } | |
343 | |
344 @Override OutputStream outputStream() throws IOException { | |
345 return new FileOutputStream(file); | |
346 } | |
347 | |
348 @Override public String to_string() { | |
349 return file.toString(); | |
350 } | |
351 | |
352 public LuanTable child(String name) { | |
353 return new LuanFile(new File(file,name)).table(); | |
354 } | |
355 | |
356 public LuanTable children() { | |
357 File[] files = file.listFiles(); | |
358 if( files==null ) | |
359 return null; | |
360 LuanTable list = new LuanTable(); | |
361 for( File f : files ) { | |
362 list.add(new LuanFile(f).table()); | |
363 } | |
364 return list; | |
365 } | |
366 | |
367 public boolean exists() { | |
368 return Utils.exists(file); | |
369 } | |
370 | |
371 @Override LuanTable table() { | |
372 LuanTable tbl = super.table(); | |
373 try { | |
374 tbl.put( "name", new LuanJavaFunction( | |
375 File.class.getMethod( "getName" ), file | |
376 ) ); | |
377 tbl.put( "exists", new LuanJavaFunction( | |
378 LuanFile.class.getMethod( "exists" ), this | |
379 ) ); | |
380 tbl.put( "is_directory", new LuanJavaFunction( | |
381 File.class.getMethod( "isDirectory" ), file | |
382 ) ); | |
383 tbl.put( "is_file", new LuanJavaFunction( | |
384 File.class.getMethod( "isFile" ), file | |
385 ) ); | |
386 tbl.put( "delete", new LuanJavaFunction( | |
387 File.class.getMethod( "delete" ), file | |
388 ) ); | |
389 tbl.put( "mkdir", new LuanJavaFunction( | |
390 File.class.getMethod( "mkdir" ), file | |
391 ) ); | |
392 tbl.put( "mkdirs", new LuanJavaFunction( | |
393 File.class.getMethod( "mkdirs" ), file | |
394 ) ); | |
395 tbl.put( "last_modified", new LuanJavaFunction( | |
396 File.class.getMethod( "lastModified" ), file | |
397 ) ); | |
398 tbl.put( "child", new LuanJavaFunction( | |
399 LuanFile.class.getMethod( "child", String.class ), this | |
400 ) ); | |
401 tbl.put( "children", new LuanJavaFunction( | |
402 LuanFile.class.getMethod( "children" ), this | |
403 ) ); | |
404 } catch(NoSuchMethodException e) { | |
405 throw new RuntimeException(e); | |
406 } | |
407 return tbl; | |
408 } | |
409 } | |
410 | |
411 public static LuanIn luanIo(LuanState luan,String name) throws LuanException { | |
412 if( Utils.isFile(name) ) | |
413 return new LuanFile(name); | |
414 String url = Utils.toUrl(name); | |
415 if( url != null ) { | |
416 try { | |
417 return new LuanUrl(url); | |
418 } catch(MalformedURLException e) { | |
419 throw new RuntimeException(e); | |
420 } | |
421 } | |
422 throw luan.exception( "file '"+name+"' not found" ); | |
423 } | |
424 | |
425 public static LuanTable File(LuanState luan,String name) throws LuanException { | |
426 return luanIo(luan,name).table(); | |
427 } | |
428 | |
429 public static final class LuanSocket extends LuanIO { | |
430 private final Socket socket; | |
431 | |
432 public LuanSocket(String host,int port) throws IOException { | |
433 this(new Socket(host,port)); | |
434 } | |
435 | |
436 public LuanSocket(Socket socket) throws IOException { | |
437 this.socket = socket; | |
438 } | |
439 | |
440 @Override InputStream inputStream() throws IOException { | |
441 return socket.getInputStream(); | |
442 } | |
443 | |
444 @Override OutputStream outputStream() throws IOException { | |
445 return socket.getOutputStream(); | |
446 } | |
447 | |
448 @Override public String to_string() { | |
449 return socket.toString(); | |
450 } | |
451 | |
452 public LuanTable Pickle_client(LuanState luan) throws IOException { | |
453 DataInputStream in = new DataInputStream(new BufferedInputStream(inputStream())); | |
454 DataOutputStream out = new DataOutputStream(new BufferedOutputStream(outputStream())); | |
455 return new PickleClient(luan,in,out).table(); | |
456 } | |
457 | |
458 public void run_pickle_server(LuanState luan) throws IOException { | |
459 DataInputStream in = new DataInputStream(new BufferedInputStream(inputStream())); | |
460 DataOutputStream out = new DataOutputStream(new BufferedOutputStream(outputStream())); | |
461 new PickleServer(luan,in,out).run(); | |
462 } | |
463 | |
464 @Override LuanTable table() { | |
465 LuanTable tbl = super.table(); | |
466 try { | |
467 tbl.put( "Pickle_client", new LuanJavaFunction( | |
468 LuanSocket.class.getMethod( "Pickle_client", LuanState.class ), this | |
469 ) ); | |
470 tbl.put( "run_pickle_server", new LuanJavaFunction( | |
471 LuanSocket.class.getMethod( "run_pickle_server", LuanState.class ), this | |
472 ) ); | |
473 } catch(NoSuchMethodException e) { | |
474 throw new RuntimeException(e); | |
475 } | |
476 return tbl; | |
477 } | |
478 } | |
479 | |
480 public static LuanTable Socket(String host,int port) throws IOException { | |
481 return new LuanSocket(host,port).table(); | |
482 } | |
483 | |
484 public static LuanFunction socket_server(int port) throws IOException { | |
485 final ServerSocket ss = new ServerSocket(port); | |
486 return new LuanFunction() { | |
487 @Override public Object call(LuanState luan,Object[] args) throws LuanException { | |
488 try { | |
489 if( args.length > 0 ) { | |
490 if( args.length > 1 || !"close".equals(args[0]) ) | |
491 throw luan.exception( "the only argument allowed is 'close'" ); | |
492 ss.close(); | |
493 return null; | |
494 } | |
495 return new LuanSocket(ss.accept()).table(); | |
496 } catch(IOException e) { | |
497 throw luan.exception(e); | |
498 } | |
499 } | |
500 }; | |
501 } | |
502 | |
503 private void IoLuan() {} // never | |
504 } |