comparison src/luan/modules/IoLuan.java @ 1333:25746915a241

merge Luan and LuanState
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 12 Feb 2019 22:33:40 -0700
parents f41919741100
children c88b486a9511
comparison
equal deleted inserted replaced
1332:11b7e11f9ed5 1333:25746915a241
27 import java.net.UnknownHostException; 27 import java.net.UnknownHostException;
28 import java.nio.file.Files; 28 import java.nio.file.Files;
29 import java.util.Enumeration; 29 import java.util.Enumeration;
30 import java.util.Map; 30 import java.util.Map;
31 import luan.Luan; 31 import luan.Luan;
32 import luan.LuanState;
33 import luan.LuanTable; 32 import luan.LuanTable;
34 import luan.LuanFunction; 33 import luan.LuanFunction;
35 import luan.LuanException; 34 import luan.LuanException;
36 import luan.modules.url.LuanUrl; 35 import luan.modules.url.LuanUrl;
37 36
45 } 44 }
46 45
47 46
48 public interface LuanWriter { 47 public interface LuanWriter {
49 public Object out(); 48 public Object out();
50 public void write(LuanState luan,Object... args) throws LuanException, IOException; 49 public void write(Luan luan,Object... args) throws LuanException, IOException;
51 public void close() throws IOException; 50 public void close() throws IOException;
52 } 51 }
53 52
54 public static LuanWriter luanWriter(final PrintStream out) { 53 public static LuanWriter luanWriter(final PrintStream out) {
55 return new LuanWriter() { 54 return new LuanWriter() {
56 55
57 public Object out() { 56 public Object out() {
58 return out; 57 return out;
59 } 58 }
60 59
61 public void write(LuanState luan,Object... args) throws LuanException { 60 public void write(Luan luan,Object... args) throws LuanException {
62 for( Object obj : args ) { 61 for( Object obj : args ) {
63 out.print( luan.toString(obj) ); 62 out.print( luan.toString(obj) );
64 } 63 }
65 } 64 }
66 65
75 74
76 public Object out() { 75 public Object out() {
77 return out; 76 return out;
78 } 77 }
79 78
80 public void write(LuanState luan,Object... args) throws LuanException, IOException { 79 public void write(Luan luan,Object... args) throws LuanException, IOException {
81 for( Object obj : args ) { 80 for( Object obj : args ) {
82 out.write( luan.toString(obj) ); 81 out.write( luan.toString(obj) );
83 } 82 }
84 } 83 }
85 84
89 }; 88 };
90 } 89 }
91 90
92 static LuanFunction lines(final BufferedReader in) { 91 static LuanFunction lines(final BufferedReader in) {
93 return new LuanFunction() { 92 return new LuanFunction() {
94 @Override public Object call(LuanState luan,Object[] args) throws LuanException { 93 @Override public Object call(Luan luan,Object[] args) throws LuanException {
95 try { 94 try {
96 if( args.length > 0 ) { 95 if( args.length > 0 ) {
97 if( args.length > 1 || !"close".equals(args[0]) ) 96 if( args.length > 1 || !"close".equals(args[0]) )
98 throw new LuanException( "the only argument allowed is 'close'" ); 97 throw new LuanException( "the only argument allowed is 'close'" );
99 in.close(); 98 in.close();
112 111
113 static LuanFunction blocks(final InputStream in,final int blockSize) { 112 static LuanFunction blocks(final InputStream in,final int blockSize) {
114 return new LuanFunction() { 113 return new LuanFunction() {
115 final byte[] a = new byte[blockSize]; 114 final byte[] a = new byte[blockSize];
116 115
117 @Override public Object call(LuanState luan,Object[] args) throws LuanException { 116 @Override public Object call(Luan luan,Object[] args) throws LuanException {
118 try { 117 try {
119 if( args.length > 0 ) { 118 if( args.length > 0 ) {
120 if( args.length > 1 || !"close".equals(args[0]) ) 119 if( args.length > 1 || !"close".equals(args[0]) )
121 throw new LuanException( "the only argument allowed is 'close'" ); 120 throw new LuanException( "the only argument allowed is 'close'" );
122 in.close(); 121 in.close();
152 151
153 152
154 public static abstract class LuanIn { 153 public static abstract class LuanIn {
155 protected String charset = null; 154 protected String charset = null;
156 155
157 public abstract InputStream inputStream(LuanState luan) throws IOException, LuanException; 156 public abstract InputStream inputStream(Luan luan) throws IOException, LuanException;
158 public abstract String to_string(); 157 public abstract String to_string();
159 public abstract String to_uri_string(); 158 public abstract String to_uri_string();
160 159
161 public Reader reader(LuanState luan) throws IOException, LuanException { 160 public Reader reader(Luan luan) throws IOException, LuanException {
162 InputStream in = inputStream(luan); 161 InputStream in = inputStream(luan);
163 return charset==null ? new InputStreamReader(in) : new InputStreamReader(in,charset); 162 return charset==null ? new InputStreamReader(in) : new InputStreamReader(in,charset);
164 } 163 }
165 164
166 public String read_text(LuanState luan) throws IOException, LuanException { 165 public String read_text(Luan luan) throws IOException, LuanException {
167 Reader in = reader(luan); 166 Reader in = reader(luan);
168 String s = Utils.readAll(in); 167 String s = Utils.readAll(in);
169 in.close(); 168 in.close();
170 return s; 169 return s;
171 } 170 }
172 171
173 public byte[] read_binary(LuanState luan) throws IOException, LuanException { 172 public byte[] read_binary(Luan luan) throws IOException, LuanException {
174 InputStream in = inputStream(luan); 173 InputStream in = inputStream(luan);
175 byte[] a = Utils.readAll(in); 174 byte[] a = Utils.readAll(in);
176 in.close(); 175 in.close();
177 return a; 176 return a;
178 } 177 }
179 178
180 public LuanFunction read_lines(LuanState luan) throws IOException, LuanException { 179 public LuanFunction read_lines(Luan luan) throws IOException, LuanException {
181 return lines(new BufferedReader(reader(luan))); 180 return lines(new BufferedReader(reader(luan)));
182 } 181 }
183 182
184 public LuanFunction read_blocks(LuanState luan,Integer blockSize) throws IOException, LuanException { 183 public LuanFunction read_blocks(Luan luan,Integer blockSize) throws IOException, LuanException {
185 int n = blockSize!=null ? blockSize : Utils.bufSize; 184 int n = blockSize!=null ? blockSize : Utils.bufSize;
186 return blocks(inputStream(luan),n); 185 return blocks(inputStream(luan),n);
187 } 186 }
188 187
189 public boolean exists(LuanState luan) throws IOException, LuanException { 188 public boolean exists(Luan luan) throws IOException, LuanException {
190 try { 189 try {
191 inputStream(luan).close(); 190 inputStream(luan).close();
192 return true; 191 return true;
193 } catch(FileNotFoundException e) { 192 } catch(FileNotFoundException e) {
194 return false; 193 return false;
195 } catch(UnknownHostException e) { 194 } catch(UnknownHostException e) {
196 return false; 195 return false;
197 } 196 }
198 } 197 }
199 198
200 public long checksum(LuanState luan) throws IOException, LuanException { 199 public long checksum(Luan luan) throws IOException, LuanException {
201 long cs = 0; 200 long cs = 0;
202 InputStream in = new BufferedInputStream(inputStream(luan)); 201 InputStream in = new BufferedInputStream(inputStream(luan));
203 int c; 202 int c;
204 while( (c=in.read()) != -1 ) { 203 while( (c=in.read()) != -1 ) {
205 cs = 31 * cs + c; 204 cs = 31 * cs + c;
217 } 216 }
218 } 217 }
219 218
220 public static final LuanIn defaultStdin = new LuanIn() { 219 public static final LuanIn defaultStdin = new LuanIn() {
221 220
222 @Override public InputStream inputStream(LuanState luan) { 221 @Override public InputStream inputStream(Luan luan) {
223 return System.in; 222 return System.in;
224 } 223 }
225 224
226 @Override public String to_string() { 225 @Override public String to_string() {
227 return "<stdin>"; 226 return "<stdin>";
229 228
230 @Override public String to_uri_string() { 229 @Override public String to_uri_string() {
231 return "stdin:"; 230 return "stdin:";
232 } 231 }
233 232
234 @Override public String read_text(LuanState luan) throws IOException { 233 @Override public String read_text(Luan luan) throws IOException {
235 return Utils.readAll(new InputStreamReader(System.in)); 234 return Utils.readAll(new InputStreamReader(System.in));
236 } 235 }
237 236
238 @Override public byte[] read_binary(LuanState luan) throws IOException { 237 @Override public byte[] read_binary(Luan luan) throws IOException {
239 return Utils.readAll(System.in); 238 return Utils.readAll(System.in);
240 } 239 }
241 240
242 @Override public boolean exists(LuanState luan) { 241 @Override public boolean exists(Luan luan) {
243 return true; 242 return true;
244 } 243 }
245 }; 244 };
246 245
247 public static abstract class LuanIO extends LuanIn { 246 public static abstract class LuanIO extends LuanIn {
250 private Writer writer() throws IOException { 249 private Writer writer() throws IOException {
251 OutputStream out = outputStream(); 250 OutputStream out = outputStream();
252 return charset==null ? new OutputStreamWriter(out) : new OutputStreamWriter(out,charset); 251 return charset==null ? new OutputStreamWriter(out) : new OutputStreamWriter(out,charset);
253 } 252 }
254 253
255 public void write(LuanState luan,Object obj) throws LuanException, IOException { 254 public void write(Luan luan,Object obj) throws LuanException, IOException {
256 if( obj instanceof String ) { 255 if( obj instanceof String ) {
257 String s = (String)obj; 256 String s = (String)obj;
258 Writer out = writer(); 257 Writer out = writer();
259 out.write(s); 258 out.write(s);
260 out.close(); 259 out.close();
289 288
290 public OutputStream binary_writer() throws IOException { 289 public OutputStream binary_writer() throws IOException {
291 return new BufferedOutputStream(outputStream()); 290 return new BufferedOutputStream(outputStream());
292 } 291 }
293 292
294 public void write_text(LuanState luan,Object... args) throws LuanException, IOException { 293 public void write_text(Luan luan,Object... args) throws LuanException, IOException {
295 LuanWriter luanWriter = luanWriter(new BufferedWriter(writer())); 294 LuanWriter luanWriter = luanWriter(new BufferedWriter(writer()));
296 luanWriter.write(luan,args); 295 luanWriter.write(luan,args);
297 luanWriter.close(); 296 luanWriter.close();
298 } 297 }
299 } 298 }
306 }; 305 };
307 private final OutputStream out = new OutputStream() { 306 private final OutputStream out = new OutputStream() {
308 @Override public void write(int b) {} 307 @Override public void write(int b) {}
309 }; 308 };
310 309
311 @Override public InputStream inputStream(LuanState luan) { 310 @Override public InputStream inputStream(Luan luan) {
312 return in; 311 return in;
313 } 312 }
314 313
315 @Override OutputStream outputStream() { 314 @Override OutputStream outputStream() {
316 return out; 315 return out;
332 public LuanString(String s) throws LuanException { 331 public LuanString(String s) throws LuanException {
333 Utils.checkNotNull(s); 332 Utils.checkNotNull(s);
334 this.s = s; 333 this.s = s;
335 } 334 }
336 335
337 @Override public InputStream inputStream(LuanState luan) { 336 @Override public InputStream inputStream(Luan luan) {
338 throw new UnsupportedOperationException(); 337 throw new UnsupportedOperationException();
339 } 338 }
340 339
341 @Override OutputStream outputStream() { 340 @Override OutputStream outputStream() {
342 throw new UnsupportedOperationException(); 341 throw new UnsupportedOperationException();
348 347
349 @Override public String to_uri_string() { 348 @Override public String to_uri_string() {
350 return "string:" + s; 349 return "string:" + s;
351 } 350 }
352 351
353 @Override public Reader reader(LuanState luan) { 352 @Override public Reader reader(Luan luan) {
354 return new StringReader(s); 353 return new StringReader(s);
355 } 354 }
356 355
357 @Override public String read_text(LuanState luan) { 356 @Override public String read_text(Luan luan) {
358 return s; 357 return s;
359 } 358 }
360 359
361 @Override public boolean exists(LuanState luan) { 360 @Override public boolean exists(Luan luan) {
362 return true; 361 return true;
363 } 362 }
364 363
365 @Override public LuanWriter text_writer() { 364 @Override public LuanWriter text_writer() {
366 return new LuanWriter() { 365 return new LuanWriter() {
368 367
369 public Object out() { 368 public Object out() {
370 return out; 369 return out;
371 } 370 }
372 371
373 public void write(LuanState luan,Object... args) throws LuanException, IOException { 372 public void write(Luan luan,Object... args) throws LuanException, IOException {
374 for( Object obj : args ) { 373 for( Object obj : args ) {
375 out.write( luan.toString(obj) ); 374 out.write( luan.toString(obj) );
376 } 375 }
377 } 376 }
378 377
384 } 383 }
385 384
386 public static final class LuanFile extends LuanIO { 385 public static final class LuanFile extends LuanIO {
387 public final File file; 386 public final File file;
388 387
389 public LuanFile(LuanState luan,String path) throws LuanException { 388 public LuanFile(Luan luan,String path) throws LuanException {
390 this(luan,new File(path)); 389 this(luan,new File(path));
391 } 390 }
392 391
393 private LuanFile(LuanState luan,File file) throws LuanException { 392 private LuanFile(Luan luan,File file) throws LuanException {
394 this(file); 393 this(file);
395 check(luan,"file:"+file.toString()); 394 check(luan,"file:"+file.toString());
396 } 395 }
397 396
398 private LuanFile(File file) { 397 private LuanFile(File file) {
399 this.file = file; 398 this.file = file;
400 } 399 }
401 400
402 @Override public InputStream inputStream(LuanState luan) throws IOException { 401 @Override public InputStream inputStream(Luan luan) throws IOException {
403 return new FileInputStream(file); 402 return new FileInputStream(file);
404 } 403 }
405 404
406 @Override OutputStream outputStream() throws IOException { 405 @Override OutputStream outputStream() throws IOException {
407 return new FileOutputStream(file); 406 return new FileOutputStream(file);
413 412
414 @Override public String to_uri_string() { 413 @Override public String to_uri_string() {
415 return "file:" + file.toString(); 414 return "file:" + file.toString();
416 } 415 }
417 416
418 public LuanFile child(LuanState luan,String name) throws LuanException { 417 public LuanFile child(Luan luan,String name) throws LuanException {
419 return new LuanFile(luan,new File(file,name)); 418 return new LuanFile(luan,new File(file,name));
420 } 419 }
421 420
422 public LuanTable children(LuanState luan) throws LuanException { 421 public LuanTable children(Luan luan) throws LuanException {
423 File[] files = file.listFiles(); 422 File[] files = file.listFiles();
424 if( files==null ) 423 if( files==null )
425 return null; 424 return null;
426 LuanTable list = new LuanTable(luan); 425 LuanTable list = new LuanTable(luan);
427 for( File f : files ) { 426 for( File f : files ) {
428 list.rawPut(list.rawLength()+1,new LuanFile(luan,f)); 427 list.rawPut(list.rawLength()+1,new LuanFile(luan,f));
429 } 428 }
430 return list; 429 return list;
431 } 430 }
432 431
433 public LuanFile parent(LuanState luan) throws LuanException, IOException { 432 public LuanFile parent(Luan luan) throws LuanException, IOException {
434 File parent = file.getParentFile(); 433 File parent = file.getParentFile();
435 if( parent==null ) 434 if( parent==null )
436 parent = file.getCanonicalFile().getParentFile(); 435 parent = file.getCanonicalFile().getParentFile();
437 return new LuanFile(luan,parent); 436 return new LuanFile(luan,parent);
438 } 437 }
439 438
440 @Override public boolean exists(LuanState luan) { 439 @Override public boolean exists(Luan luan) {
441 return file.exists(); 440 return file.exists();
442 } 441 }
443 442
444 public void rename_to(Object destObj) throws LuanException { 443 public void rename_to(Object destObj) throws LuanException {
445 File dest = objToFile(destObj); 444 File dest = objToFile(destObj);
447 throw new LuanException( "bad argument #1 to 'objToFile' (string or file table expected)" ); 446 throw new LuanException( "bad argument #1 to 'objToFile' (string or file table expected)" );
448 if( !file.renameTo(dest) ) 447 if( !file.renameTo(dest) )
449 throw new LuanException("couldn't rename file "+file+" to "+dest); 448 throw new LuanException("couldn't rename file "+file+" to "+dest);
450 } 449 }
451 450
452 public LuanFile canonical(LuanState luan) throws LuanException, IOException { 451 public LuanFile canonical(Luan luan) throws LuanException, IOException {
453 return new LuanFile(luan,file.getCanonicalFile()); 452 return new LuanFile(luan,file.getCanonicalFile());
454 } 453 }
455 454
456 public LuanFile create_temp_file(LuanState luan,String prefix,String suffix) throws LuanException, IOException { 455 public LuanFile create_temp_file(Luan luan,String prefix,String suffix) throws LuanException, IOException {
457 File tmp = File.createTempFile(prefix,suffix,file); 456 File tmp = File.createTempFile(prefix,suffix,file);
458 return new LuanFile(luan,tmp); 457 return new LuanFile(luan,tmp);
459 } 458 }
460 459
461 public void delete() throws LuanException { 460 public void delete() throws LuanException {
493 public boolean is_symbolic_link() { 492 public boolean is_symbolic_link() {
494 return isSymbolicLink(file); 493 return isSymbolicLink(file);
495 } 494 }
496 } 495 }
497 496
498 public static LuanUrl classpath(LuanState luan,String name) throws LuanException { 497 public static LuanUrl classpath(Luan luan,String name) throws LuanException {
499 if( name.contains("//") ) 498 if( name.contains("//") )
500 return null; 499 return null;
501 String path = name; 500 String path = name;
502 check(luan,"classpath:"+path); 501 check(luan,"classpath:"+path);
503 URL url; 502 URL url;
545 throw new LuanException( "unrecognized options: "+map ); 544 throw new LuanException( "unrecognized options: "+map );
546 } 545 }
547 this.dir = dir; 546 this.dir = dir;
548 } 547 }
549 548
550 @Override public InputStream inputStream(LuanState luan) throws IOException { 549 @Override public InputStream inputStream(Luan luan) throws IOException {
551 return proc.getInputStream(); 550 return proc.getInputStream();
552 } 551 }
553 552
554 @Override OutputStream outputStream() throws IOException { 553 @Override OutputStream outputStream() throws IOException {
555 return proc.getOutputStream(); 554 return proc.getOutputStream();
561 560
562 @Override public String to_uri_string() { 561 @Override public String to_uri_string() {
563 throw new UnsupportedOperationException(); 562 throw new UnsupportedOperationException();
564 } 563 }
565 564
566 @Override public boolean exists(LuanState luan) { 565 @Override public boolean exists(Luan luan) {
567 return true; 566 return true;
568 } 567 }
569 568
570 public void wait_for() 569 public void wait_for()
571 throws IOException, LuanException 570 throws IOException, LuanException
582 err.close(); 581 err.close();
583 throw new LuanException(error); 582 throw new LuanException(error);
584 } 583 }
585 } 584 }
586 585
587 @Override public String read_text(LuanState luan) throws IOException, LuanException { 586 @Override public String read_text(Luan luan) throws IOException, LuanException {
588 String s = super.read_text(luan); 587 String s = super.read_text(luan);
589 wait_for(); 588 wait_for();
590 return s; 589 return s;
591 } 590 }
592 } 591 }
593 592
594 public static final class LuanOs extends BaseOs { 593 public static final class LuanOs extends BaseOs {
595 public LuanOs(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 594 public LuanOs(Luan luan,String cmd,LuanTable options) throws IOException, LuanException {
596 super(cmd,options); 595 super(cmd,options);
597 check(luan,"os:"+cmd); 596 check(luan,"os:"+cmd);
598 this.proc = Runtime.getRuntime().exec(cmd,null,dir); 597 this.proc = Runtime.getRuntime().exec(cmd,null,dir);
599 } 598 }
600 } 599 }
601 600
602 public static final class LuanBash extends BaseOs { 601 public static final class LuanBash extends BaseOs {
603 public LuanBash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 602 public LuanBash(Luan luan,String cmd,LuanTable options) throws IOException, LuanException {
604 super(cmd,options); 603 super(cmd,options);
605 check(luan,"bash:"+cmd); 604 check(luan,"bash:"+cmd);
606 this.proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir); 605 this.proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir);
607 } 606 }
608 } 607 }
613 612
614 public LuanInput(InputStream in) { 613 public LuanInput(InputStream in) {
615 this.in = in; 614 this.in = in;
616 } 615 }
617 616
618 @Override public InputStream inputStream(LuanState luan) { 617 @Override public InputStream inputStream(Luan luan) {
619 return in; 618 return in;
620 } 619 }
621 620
622 @Override public String to_string() { 621 @Override public String to_string() {
623 return "<input_stream>"; 622 return "<input_stream>";
625 624
626 @Override public String to_uri_string() { 625 @Override public String to_uri_string() {
627 throw new UnsupportedOperationException(); 626 throw new UnsupportedOperationException();
628 } 627 }
629 628
630 @Override public boolean exists(LuanState luan) { 629 @Override public boolean exists(Luan luan) {
631 return true; 630 return true;
632 } 631 }
633 }; 632 };
634 633
635 634
639 } catch(UnknownHostException e) { 638 } catch(UnknownHostException e) {
640 return null; 639 return null;
641 } 640 }
642 } 641 }
643 642
644 public static LuanTable my_ips(LuanState luan) throws IOException, LuanException { 643 public static LuanTable my_ips(Luan luan) throws IOException, LuanException {
645 LuanTable tbl = new LuanTable(luan); 644 LuanTable tbl = new LuanTable(luan);
646 for( Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces(); e1.hasMoreElements(); ) { 645 for( Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces(); e1.hasMoreElements(); ) {
647 NetworkInterface ni = e1.nextElement(); 646 NetworkInterface ni = e1.nextElement();
648 for( Enumeration<InetAddress> e2 = ni.getInetAddresses(); e2.hasMoreElements(); ) { 647 for( Enumeration<InetAddress> e2 = ni.getInetAddresses(); e2.hasMoreElements(); ) {
649 InetAddress ia = e2.nextElement(); 648 InetAddress ia = e2.nextElement();
653 } 652 }
654 return tbl; 653 return tbl;
655 } 654 }
656 655
657 656
658 private static void check(LuanState luan,String name) throws LuanException { 657 private static void check(Luan luan,String name) throws LuanException {
659 Luan.checkSecurity(luan,"uri",name); 658 Luan.checkSecurity(luan,"uri",name);
660 } 659 }
661 660
662 661
663 private void IoLuan() {} // never 662 private void IoLuan() {} // never