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 }