comparison src/luan/modules/IoLuan.java @ 1267:9fa8b8389578

add LuanTable.luan; support metatable __gc(); add luan.sql;
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 12 Nov 2018 02:10:41 -0700
parents e38f5869e9df
children d83f6cc558de
comparison
equal deleted inserted replaced
1266:05934fbf635a 1267:9fa8b8389578
77 out.close(); 77 out.close();
78 } 78 }
79 }; 79 };
80 } 80 }
81 81
82 public static LuanTable textWriter(final PrintStream out) { 82 public static LuanTable textWriter(LuanState luan,final PrintStream out) {
83 return writer(luanWriter(out)); 83 return writer(luan,luanWriter(out));
84 } 84 }
85 85
86 private static LuanWriter luanWriter(final Writer out) { 86 private static LuanWriter luanWriter(final Writer out) {
87 return new LuanWriter() { 87 return new LuanWriter() {
88 88
100 out.close(); 100 out.close();
101 } 101 }
102 }; 102 };
103 } 103 }
104 104
105 public static LuanTable textWriter(final Writer out) { 105 public static LuanTable textWriter(LuanState luan,final Writer out) {
106 return writer(luanWriter(out)); 106 return writer(luan,luanWriter(out));
107 } 107 }
108 108
109 private static LuanTable writer(LuanWriter luanWriter) { 109 private static LuanTable writer(LuanState luan,LuanWriter luanWriter) {
110 LuanTable writer = new LuanTable(); 110 LuanTable writer = new LuanTable(luan);
111 writer.rawPut( "java", luanWriter.out() ); 111 writer.rawPut( "java", luanWriter.out() );
112 try { 112 try {
113 writer.rawPut( "write", new LuanJavaFunction( 113 writer.rawPut( "write", new LuanJavaFunction(
114 LuanWriter.class.getMethod( "write", LuanState.class, new Object[0].getClass() ), luanWriter 114 LuanWriter.class.getMethod( "write", LuanState.class, new Object[0].getClass() ), luanWriter
115 ) ); 115 ) );
121 } 121 }
122 return writer; 122 return writer;
123 } 123 }
124 124
125 125
126 public static LuanTable binaryWriter(final OutputStream out) { 126 public static LuanTable binaryWriter(LuanState luan,final OutputStream out) {
127 LuanTable writer = new LuanTable(); 127 LuanTable writer = new LuanTable(luan);
128 writer.rawPut( "java", out ); 128 writer.rawPut( "java", out );
129 try { 129 try {
130 writer.rawPut( "write", new LuanJavaFunction( 130 writer.rawPut( "write", new LuanJavaFunction(
131 OutputStream.class.getMethod( "write", new byte[0].getClass() ), out 131 OutputStream.class.getMethod( "write", new byte[0].getClass() ), out
132 ) ); 132 ) );
200 return null; 200 return null;
201 } 201 }
202 202
203 203
204 public static abstract class LuanIn { 204 public static abstract class LuanIn {
205 public abstract InputStream inputStream() throws IOException, LuanException; 205 public abstract InputStream inputStream(LuanState luan) throws IOException, LuanException;
206 public abstract String to_string(); 206 public abstract String to_string();
207 public abstract String to_uri_string(); 207 public abstract String to_uri_string();
208 208
209 public Reader reader() throws IOException, LuanException { 209 public Reader reader(LuanState luan) throws IOException, LuanException {
210 return new InputStreamReader(inputStream()); 210 return new InputStreamReader(inputStream(luan));
211 } 211 }
212 212
213 public String read_text() throws IOException, LuanException { 213 public String read_text(LuanState luan) throws IOException, LuanException {
214 Reader in = reader(); 214 Reader in = reader(luan);
215 String s = Utils.readAll(in); 215 String s = Utils.readAll(in);
216 in.close(); 216 in.close();
217 return s; 217 return s;
218 } 218 }
219 219
220 public byte[] read_binary() throws IOException, LuanException { 220 public byte[] read_binary(LuanState luan) throws IOException, LuanException {
221 InputStream in = inputStream(); 221 InputStream in = inputStream(luan);
222 byte[] a = Utils.readAll(in); 222 byte[] a = Utils.readAll(in);
223 in.close(); 223 in.close();
224 return a; 224 return a;
225 } 225 }
226 226
227 public LuanFunction read_lines() throws IOException, LuanException { 227 public LuanFunction read_lines(LuanState luan) throws IOException, LuanException {
228 return lines(new BufferedReader(reader())); 228 return lines(new BufferedReader(reader(luan)));
229 } 229 }
230 230
231 public LuanFunction read_blocks(Integer blockSize) throws IOException, LuanException { 231 public LuanFunction read_blocks(LuanState luan,Integer blockSize) throws IOException, LuanException {
232 int n = blockSize!=null ? blockSize : Utils.bufSize; 232 int n = blockSize!=null ? blockSize : Utils.bufSize;
233 return blocks(inputStream(),n); 233 return blocks(inputStream(luan),n);
234 } 234 }
235 235
236 public boolean exists() throws IOException, LuanException { 236 public boolean exists(LuanState luan) throws IOException, LuanException {
237 try { 237 try {
238 inputStream().close(); 238 inputStream(luan).close();
239 return true; 239 return true;
240 } catch(FileNotFoundException e) { 240 } catch(FileNotFoundException e) {
241 return false; 241 return false;
242 } catch(UnknownHostException e) { 242 } catch(UnknownHostException e) {
243 return false; 243 return false;
244 } 244 }
245 } 245 }
246 246
247 public long checksum() throws IOException, LuanException { 247 public long checksum(LuanState luan) throws IOException, LuanException {
248 long cs = 0; 248 long cs = 0;
249 InputStream in = new BufferedInputStream(inputStream()); 249 InputStream in = new BufferedInputStream(inputStream(luan));
250 int c; 250 int c;
251 while( (c=in.read()) != -1 ) { 251 while( (c=in.read()) != -1 ) {
252 cs = 31 * cs + c; 252 cs = 31 * cs + c;
253 } 253 }
254 in.close(); 254 in.close();
255 return cs; 255 return cs;
256 } 256 }
257 257
258 public LuanTable table() { 258 public LuanTable table(LuanState luan) {
259 LuanTable tbl = new LuanTable(); 259 LuanTable tbl = new LuanTable(luan);
260 try { 260 try {
261 tbl.rawPut( "java", this ); 261 tbl.rawPut( "java", this );
262 tbl.rawPut( "to_string", new LuanJavaFunction( 262 tbl.rawPut( "to_string", new LuanJavaFunction(
263 LuanIn.class.getMethod( "to_string" ), this 263 LuanIn.class.getMethod( "to_string" ), this
264 ) ); 264 ) );
265 tbl.rawPut( "to_uri_string", new LuanJavaFunction( 265 tbl.rawPut( "to_uri_string", new LuanJavaFunction(
266 LuanIn.class.getMethod( "to_uri_string" ), this 266 LuanIn.class.getMethod( "to_uri_string" ), this
267 ) ); 267 ) );
268 tbl.rawPut( "read_text", new LuanJavaFunction( 268 tbl.rawPut( "read_text", new LuanJavaFunction(
269 LuanIn.class.getMethod( "read_text" ), this 269 LuanIn.class.getMethod( "read_text", LuanState.class ), this
270 ) ); 270 ) );
271 tbl.rawPut( "read_binary", new LuanJavaFunction( 271 tbl.rawPut( "read_binary", new LuanJavaFunction(
272 LuanIn.class.getMethod( "read_binary" ), this 272 LuanIn.class.getMethod( "read_binary", LuanState.class ), this
273 ) ); 273 ) );
274 tbl.rawPut( "read_lines", new LuanJavaFunction( 274 tbl.rawPut( "read_lines", new LuanJavaFunction(
275 LuanIn.class.getMethod( "read_lines" ), this 275 LuanIn.class.getMethod( "read_lines", LuanState.class ), this
276 ) ); 276 ) );
277 tbl.rawPut( "read_blocks", new LuanJavaFunction( 277 tbl.rawPut( "read_blocks", new LuanJavaFunction(
278 LuanIn.class.getMethod( "read_blocks", Integer.class ), this 278 LuanIn.class.getMethod( "read_blocks", LuanState.class, Integer.class ), this
279 ) ); 279 ) );
280 tbl.rawPut( "exists", new LuanJavaFunction( 280 tbl.rawPut( "exists", new LuanJavaFunction(
281 LuanIn.class.getMethod( "exists" ), this 281 LuanIn.class.getMethod( "exists", LuanState.class ), this
282 ) ); 282 ) );
283 tbl.rawPut( "checksum", new LuanJavaFunction( 283 tbl.rawPut( "checksum", new LuanJavaFunction(
284 LuanIn.class.getMethod( "checksum" ), this 284 LuanIn.class.getMethod( "checksum", LuanState.class ), this
285 ) ); 285 ) );
286 } catch(NoSuchMethodException e) { 286 } catch(NoSuchMethodException e) {
287 throw new RuntimeException(e); 287 throw new RuntimeException(e);
288 } 288 }
289 return tbl; 289 return tbl;
290 } 290 }
291 } 291 }
292 292
293 public static final LuanIn defaultStdin = new LuanIn() { 293 public static final LuanIn defaultStdin = new LuanIn() {
294 294
295 @Override public InputStream inputStream() { 295 @Override public InputStream inputStream(LuanState luan) {
296 return System.in; 296 return System.in;
297 } 297 }
298 298
299 @Override public String to_string() { 299 @Override public String to_string() {
300 return "<stdin>"; 300 return "<stdin>";
302 302
303 @Override public String to_uri_string() { 303 @Override public String to_uri_string() {
304 return "stdin:"; 304 return "stdin:";
305 } 305 }
306 306
307 @Override public String read_text() throws IOException { 307 @Override public String read_text(LuanState luan) throws IOException {
308 return Utils.readAll(new InputStreamReader(System.in)); 308 return Utils.readAll(new InputStreamReader(System.in));
309 } 309 }
310 310
311 @Override public byte[] read_binary() throws IOException { 311 @Override public byte[] read_binary(LuanState luan) throws IOException {
312 return Utils.readAll(System.in); 312 return Utils.readAll(System.in);
313 } 313 }
314 314
315 @Override public boolean exists() { 315 @Override public boolean exists(LuanState luan) {
316 return true; 316 return true;
317 } 317 }
318 }; 318 };
319 319
320 public static abstract class LuanIO extends LuanIn { 320 public static abstract class LuanIO extends LuanIn {
321 abstract OutputStream outputStream() throws IOException; 321 abstract OutputStream outputStream() throws IOException;
322 322
323 public void write(Object obj) throws LuanException, IOException { 323 public void write(LuanState luan,Object obj) throws LuanException, IOException {
324 if( obj instanceof String ) { 324 if( obj instanceof String ) {
325 String s = (String)obj; 325 String s = (String)obj;
326 Writer out = new OutputStreamWriter(outputStream()); 326 Writer out = new OutputStreamWriter(outputStream());
327 out.write(s); 327 out.write(s);
328 out.close(); 328 out.close();
338 if( obj instanceof LuanTable ) { 338 if( obj instanceof LuanTable ) {
339 LuanTable t = (LuanTable)obj; 339 LuanTable t = (LuanTable)obj;
340 Object java = t.rawGet("java"); 340 Object java = t.rawGet("java");
341 if( java instanceof LuanIn ) { 341 if( java instanceof LuanIn ) {
342 LuanIn luanIn = (LuanIn)java; 342 LuanIn luanIn = (LuanIn)java;
343 InputStream in = luanIn.inputStream(); 343 InputStream in = luanIn.inputStream(luan);
344 OutputStream out = outputStream(); 344 OutputStream out = outputStream();
345 Utils.copyAll(in,out); 345 Utils.copyAll(in,out);
346 out.close(); 346 out.close();
347 in.close(); 347 in.close();
348 return; 348 return;
349 } 349 }
350 } 350 }
351 throw new LuanException( "bad argument #1 to 'write' (string or binary or Io.uri expected)" ); 351 throw new LuanException( "bad argument #1 to 'write' (string or binary or Io.uri expected)" );
352 } 352 }
353 353
354 public LuanTable text_writer() throws IOException { 354 public LuanTable text_writer(LuanState luan) throws IOException {
355 return textWriter(new BufferedWriter(new OutputStreamWriter(outputStream()))); 355 return textWriter(luan,new BufferedWriter(new OutputStreamWriter(outputStream())));
356 } 356 }
357 357
358 public LuanTable binary_writer() throws IOException { 358 public LuanTable binary_writer(LuanState luan) throws IOException {
359 return binaryWriter(new BufferedOutputStream(outputStream())); 359 return binaryWriter(luan,new BufferedOutputStream(outputStream()));
360 } 360 }
361 361
362 public void write_text(LuanState luan,Object... args) throws LuanException, IOException { 362 public void write_text(LuanState luan,Object... args) throws LuanException, IOException {
363 LuanWriter luanWriter = luanWriter(new BufferedWriter(new OutputStreamWriter(outputStream()))); 363 LuanWriter luanWriter = luanWriter(new BufferedWriter(new OutputStreamWriter(outputStream())));
364 luanWriter.write(luan,args); 364 luanWriter.write(luan,args);
365 luanWriter.close(); 365 luanWriter.close();
366 } 366 }
367 367
368 @Override public LuanTable table() { 368 @Override public LuanTable table(LuanState luan) {
369 LuanTable tbl = super.table(); 369 LuanTable tbl = super.table(luan);
370 try { 370 try {
371 tbl.rawPut( "write", new LuanJavaFunction( 371 tbl.rawPut( "write", new LuanJavaFunction(
372 LuanIO.class.getMethod( "write", Object.class ), this 372 LuanIO.class.getMethod( "write", LuanState.class, Object.class ), this
373 ) ); 373 ) );
374 tbl.rawPut( "text_writer", new LuanJavaFunction( 374 tbl.rawPut( "text_writer", new LuanJavaFunction(
375 LuanIO.class.getMethod( "text_writer" ), this 375 LuanIO.class.getMethod( "text_writer", LuanState.class ), this
376 ) ); 376 ) );
377 tbl.rawPut( "binary_writer", new LuanJavaFunction( 377 tbl.rawPut( "binary_writer", new LuanJavaFunction(
378 LuanIO.class.getMethod( "binary_writer" ), this 378 LuanIO.class.getMethod( "binary_writer", LuanState.class ), this
379 ) ); 379 ) );
380 tbl.rawPut( "write_text", new LuanJavaFunction( 380 tbl.rawPut( "write_text", new LuanJavaFunction(
381 LuanIO.class.getMethod( "write_text", LuanState.class, new Object[0].getClass() ), this 381 LuanIO.class.getMethod( "write_text", LuanState.class, new Object[0].getClass() ), this
382 ) ); 382 ) );
383 } catch(NoSuchMethodException e) { 383 } catch(NoSuchMethodException e) {
395 }; 395 };
396 private final OutputStream out = new OutputStream() { 396 private final OutputStream out = new OutputStream() {
397 @Override public void write(int b) {} 397 @Override public void write(int b) {}
398 }; 398 };
399 399
400 @Override public InputStream inputStream() { 400 @Override public InputStream inputStream(LuanState luan) {
401 return in; 401 return in;
402 } 402 }
403 403
404 @Override OutputStream outputStream() { 404 @Override OutputStream outputStream() {
405 return out; 405 return out;
420 420
421 private LuanString(String s) { 421 private LuanString(String s) {
422 this.s = s; 422 this.s = s;
423 } 423 }
424 424
425 @Override public InputStream inputStream() { 425 @Override public InputStream inputStream(LuanState luan) {
426 throw new UnsupportedOperationException(); 426 throw new UnsupportedOperationException();
427 } 427 }
428 428
429 @Override OutputStream outputStream() { 429 @Override OutputStream outputStream() {
430 throw new UnsupportedOperationException(); 430 throw new UnsupportedOperationException();
436 436
437 @Override public String to_uri_string() { 437 @Override public String to_uri_string() {
438 return "string:" + s; 438 return "string:" + s;
439 } 439 }
440 440
441 @Override public Reader reader() { 441 @Override public Reader reader(LuanState luan) {
442 return new StringReader(s); 442 return new StringReader(s);
443 } 443 }
444 444
445 @Override public String read_text() { 445 @Override public String read_text(LuanState luan) {
446 return s; 446 return s;
447 } 447 }
448 448
449 @Override public boolean exists() { 449 @Override public boolean exists(LuanState luan) {
450 return true; 450 return true;
451 } 451 }
452 452
453 @Override public LuanTable text_writer() throws IOException { 453 @Override public LuanTable text_writer(LuanState luan) throws IOException {
454 LuanWriter luanWriter = new LuanWriter() { 454 LuanWriter luanWriter = new LuanWriter() {
455 private final Writer out = new StringWriter(); 455 private final Writer out = new StringWriter();
456 456
457 public Object out() { 457 public Object out() {
458 return out; 458 return out;
466 466
467 public void close() throws IOException { 467 public void close() throws IOException {
468 s = out.toString(); 468 s = out.toString();
469 } 469 }
470 }; 470 };
471 return writer(luanWriter); 471 return writer(luan,luanWriter);
472 } 472 }
473 } 473 }
474 474
475 public static final class LuanFile extends LuanIO { 475 public static final class LuanFile extends LuanIO {
476 public final File file; 476 public final File file;
482 482
483 private LuanFile(File file) { 483 private LuanFile(File file) {
484 this.file = file; 484 this.file = file;
485 } 485 }
486 486
487 @Override public InputStream inputStream() throws IOException { 487 @Override public InputStream inputStream(LuanState luan) throws IOException {
488 return new FileInputStream(file); 488 return new FileInputStream(file);
489 } 489 }
490 490
491 @Override OutputStream outputStream() throws IOException { 491 @Override OutputStream outputStream() throws IOException {
492 return new FileOutputStream(file); 492 return new FileOutputStream(file);
499 @Override public String to_uri_string() { 499 @Override public String to_uri_string() {
500 return "file:" + file.toString(); 500 return "file:" + file.toString();
501 } 501 }
502 502
503 public LuanTable child(LuanState luan,String name) throws LuanException { 503 public LuanTable child(LuanState luan,String name) throws LuanException {
504 return new LuanFile(luan,new File(file,name)).table(); 504 return new LuanFile(luan,new File(file,name)).table(luan);
505 } 505 }
506 506
507 public LuanTable children(LuanState luan) throws LuanException { 507 public LuanTable children(LuanState luan) throws LuanException {
508 File[] files = file.listFiles(); 508 File[] files = file.listFiles();
509 if( files==null ) 509 if( files==null )
510 return null; 510 return null;
511 LuanTable list = new LuanTable(); 511 LuanTable list = new LuanTable(luan);
512 for( File f : files ) { 512 for( File f : files ) {
513 list.rawPut(list.rawLength()+1,new LuanFile(luan,f).table()); 513 list.rawPut(list.rawLength()+1,new LuanFile(luan,f).table(luan));
514 } 514 }
515 return list; 515 return list;
516 } 516 }
517 517
518 public LuanTable parent(LuanState luan) throws LuanException, IOException { 518 public LuanTable parent(LuanState luan) throws LuanException, IOException {
519 File parent = file.getParentFile(); 519 File parent = file.getParentFile();
520 if( parent==null ) 520 if( parent==null )
521 parent = file.getCanonicalFile().getParentFile(); 521 parent = file.getCanonicalFile().getParentFile();
522 return new LuanFile(luan,parent).table(); 522 return new LuanFile(luan,parent).table(luan);
523 } 523 }
524 524
525 @Override public boolean exists() { 525 @Override public boolean exists(LuanState luan) {
526 return file.exists(); 526 return file.exists();
527 } 527 }
528 528
529 public void rename_to(Object destObj) throws LuanException { 529 public void rename_to(Object destObj) throws LuanException {
530 File dest = objToFile(destObj); 530 File dest = objToFile(destObj);
533 if( !file.renameTo(dest) ) 533 if( !file.renameTo(dest) )
534 throw new LuanException("couldn't rename file "+file+" to "+dest); 534 throw new LuanException("couldn't rename file "+file+" to "+dest);
535 } 535 }
536 536
537 public LuanTable canonical(LuanState luan) throws LuanException, IOException { 537 public LuanTable canonical(LuanState luan) throws LuanException, IOException {
538 return new LuanFile(luan,file.getCanonicalFile()).table(); 538 return new LuanFile(luan,file.getCanonicalFile()).table(luan);
539 } 539 }
540 540
541 public LuanTable create_temp_file(LuanState luan,String prefix,String suffix) throws LuanException, IOException { 541 public LuanTable create_temp_file(LuanState luan,String prefix,String suffix) throws LuanException, IOException {
542 File tmp = File.createTempFile(prefix,suffix,file); 542 File tmp = File.createTempFile(prefix,suffix,file);
543 return new LuanFile(luan,tmp).table(); 543 return new LuanFile(luan,tmp).table(luan);
544 } 544 }
545 545
546 public void delete() throws LuanException { 546 public void delete() throws LuanException {
547 if( file.exists() ) 547 if( file.exists() )
548 delete(file); 548 delete(file);
569 public void set_last_modified(long time) throws LuanException { 569 public void set_last_modified(long time) throws LuanException {
570 if( !file.setLastModified(time) ) 570 if( !file.setLastModified(time) )
571 throw new LuanException("couldn't set_last_modified on "+file); 571 throw new LuanException("couldn't set_last_modified on "+file);
572 } 572 }
573 573
574 @Override public LuanTable table() { 574 @Override public LuanTable table(LuanState luan) {
575 LuanTable tbl = super.table(); 575 LuanTable tbl = super.table(luan);
576 try { 576 try {
577 tbl.rawPut( "name", new LuanJavaFunction( 577 tbl.rawPut( "name", new LuanJavaFunction(
578 File.class.getMethod( "getName" ), file 578 File.class.getMethod( "getName" ), file
579 ) ); 579 ) );
580 tbl.rawPut( "is_directory", new LuanJavaFunction( 580 tbl.rawPut( "is_directory", new LuanJavaFunction(
624 } 624 }
625 return tbl; 625 return tbl;
626 } 626 }
627 } 627 }
628 628
629 public static LuanTable null_(String ignore) { 629 public static LuanTable null_(LuanState luan,String ignore) {
630 return nullIO.table(); 630 return nullIO.table(luan);
631 } 631 }
632 632
633 public static LuanTable string(String s) throws LuanException { 633 public static LuanTable string(LuanState luan,String s) throws LuanException {
634 Utils.checkNotNull(s); 634 Utils.checkNotNull(s);
635 return new LuanString(s).table(); 635 return new LuanString(s).table(luan);
636 } 636 }
637 637
638 public static LuanTable file(LuanState luan,String name) throws LuanException { 638 public static LuanTable file(LuanState luan,String name) throws LuanException {
639 File file = new File(name); 639 File file = new File(name);
640 return new LuanFile(luan,file).table(); 640 return new LuanFile(luan,file).table(luan);
641 } 641 }
642 642
643 public static LuanTable classpath(LuanState luan,String name) throws LuanException { 643 public static LuanTable classpath(LuanState luan,String name) throws LuanException {
644 if( name.contains("//") ) 644 if( name.contains("//") )
645 return null; 645 return null;
664 } 664 }
665 } 665 }
666 } 666 }
667 } 667 }
668 if( url != null ) 668 if( url != null )
669 return new LuanUrl(luan,url,null).table(); 669 return new LuanUrl(url,null).table(luan);
670 670
671 return null; 671 return null;
672 } 672 }
673 673
674 private static LuanTable url(LuanState luan,String url,LuanTable options) throws IOException, LuanException { 674 private static LuanTable url(LuanState luan,String url,LuanTable options) throws IOException, LuanException {
675 return new LuanUrl(luan,new URL(url),options).table(); 675 return new LuanUrl(new URL(url),options).table(luan);
676 } 676 }
677 677
678 public static LuanTable http(LuanState luan,String path,LuanTable options) throws IOException, LuanException { 678 public static LuanTable http(LuanState luan,String path,LuanTable options) throws IOException, LuanException {
679 return url(luan,"http:"+path,options); 679 return url(luan,"http:"+path,options);
680 } 680 }
687 return classpath( luan, "luan/modules/" + path ); 687 return classpath( luan, "luan/modules/" + path );
688 } 688 }
689 689
690 public static LuanTable stdin(LuanState luan) throws LuanException { 690 public static LuanTable stdin(LuanState luan) throws LuanException {
691 LuanTable io = (LuanTable)PackageLuan.require(luan,"luan:Io.luan"); 691 LuanTable io = (LuanTable)PackageLuan.require(luan,"luan:Io.luan");
692 return (LuanTable)io.get(luan,"stdin"); 692 return (LuanTable)io.get("stdin");
693 } 693 }
694 694
695 public static LuanTable newSchemes() { 695 public static LuanTable newSchemes(LuanState luan) {
696 LuanTable schemes = new LuanTable(); 696 LuanTable schemes = new LuanTable(luan);
697 try { 697 try {
698 schemes.rawPut( "null", new LuanJavaFunction(IoLuan.class.getMethod("null_",String.class),null) ); 698 schemes.rawPut( "null", new LuanJavaFunction(IoLuan.class.getMethod("null_",LuanState.class,String.class),null) );
699 add( schemes, "string", String.class ); 699 add( schemes, "string", LuanState.class, String.class );
700 add( schemes, "file", LuanState.class, String.class ); 700 add( schemes, "file", LuanState.class, String.class );
701 add( schemes, "classpath", LuanState.class, String.class ); 701 add( schemes, "classpath", LuanState.class, String.class );
702 // add( schemes, "socket", String.class ); 702 // add( schemes, "socket", String.class );
703 add( schemes, "http", LuanState.class, String.class, LuanTable.class ); 703 add( schemes, "http", LuanState.class, String.class, LuanTable.class );
704 add( schemes, "https", LuanState.class, String.class, LuanTable.class ); 704 add( schemes, "https", LuanState.class, String.class, LuanTable.class );
713 } 713 }
714 714
715 private static LuanTable schemes(LuanState luan) throws LuanException { 715 private static LuanTable schemes(LuanState luan) throws LuanException {
716 LuanTable t = (LuanTable)PackageLuan.loaded(luan).rawGet("luan:Io.luan"); 716 LuanTable t = (LuanTable)PackageLuan.loaded(luan).rawGet("luan:Io.luan");
717 if( t == null ) 717 if( t == null )
718 return newSchemes(); 718 return newSchemes(luan);
719 t = (LuanTable)t.get(luan,"schemes"); 719 t = (LuanTable)t.get("schemes");
720 if( t == null ) 720 if( t == null )
721 return newSchemes(); 721 return newSchemes(luan);
722 return t; 722 return t;
723 } 723 }
724 724
725 public static LuanTable uri(LuanState luan,String name,LuanTable options) throws LuanException { 725 public static LuanTable uri(LuanState luan,String name,LuanTable options) throws LuanException {
726 int i = name.indexOf(':'); 726 int i = name.indexOf(':');
727 if( i == -1 ) 727 if( i == -1 )
728 throw new LuanException( "invalid Io.uri name '"+name+"', missing scheme" ); 728 throw new LuanException( "invalid Io.uri name '"+name+"', missing scheme" );
729 String scheme = name.substring(0,i); 729 String scheme = name.substring(0,i);
730 String location = name.substring(i+1); 730 String location = name.substring(i+1);
731 LuanTable schemes = schemes(luan); 731 LuanTable schemes = schemes(luan);
732 LuanFunction opener = (LuanFunction)schemes.get(luan,scheme); 732 LuanFunction opener = (LuanFunction)schemes.get(scheme);
733 if( opener == null ) 733 if( opener == null )
734 throw new LuanException( "invalid scheme '"+scheme+"' in '"+name+"'" ); 734 throw new LuanException( "invalid scheme '"+scheme+"' in '"+name+"'" );
735 return (LuanTable)Luan.first(opener.call(luan,new Object[]{location,options})); 735 return (LuanTable)Luan.first(opener.call(luan,new Object[]{location,options}));
736 } 736 }
737 /* 737 /*
800 public static class BaseOs extends LuanIO { 800 public static class BaseOs extends LuanIO {
801 private final String cmd; 801 private final String cmd;
802 final File dir; 802 final File dir;
803 Process proc; 803 Process proc;
804 804
805 private BaseOs(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 805 private BaseOs(String cmd,LuanTable options) throws IOException, LuanException {
806 this.cmd = cmd; 806 this.cmd = cmd;
807 File dir = null; 807 File dir = null;
808 if( options != null ) { 808 if( options != null ) {
809 Map map = options.asMap(luan); 809 Map map = options.asMap();
810 Object obj = map.remove("dir"); 810 Object obj = map.remove("dir");
811 dir = objToFile(obj); 811 dir = objToFile(obj);
812 if( dir==null ) 812 if( dir==null )
813 throw new LuanException( "bad option 'dir' (string or file table expected)" ); 813 throw new LuanException( "bad option 'dir' (string or file table expected)" );
814 if( !map.isEmpty() ) 814 if( !map.isEmpty() )
815 throw new LuanException( "unrecognized options: "+map ); 815 throw new LuanException( "unrecognized options: "+map );
816 } 816 }
817 this.dir = dir; 817 this.dir = dir;
818 } 818 }
819 819
820 @Override public InputStream inputStream() throws IOException { 820 @Override public InputStream inputStream(LuanState luan) throws IOException {
821 return proc.getInputStream(); 821 return proc.getInputStream();
822 } 822 }
823 823
824 @Override OutputStream outputStream() throws IOException { 824 @Override OutputStream outputStream() throws IOException {
825 return proc.getOutputStream(); 825 return proc.getOutputStream();
831 831
832 @Override public String to_uri_string() { 832 @Override public String to_uri_string() {
833 throw new UnsupportedOperationException(); 833 throw new UnsupportedOperationException();
834 } 834 }
835 835
836 @Override public boolean exists() { 836 @Override public boolean exists(LuanState luan) {
837 return true; 837 return true;
838 } 838 }
839 839
840 public void wait_for() 840 public void wait_for()
841 throws IOException, LuanException 841 throws IOException, LuanException
852 err.close(); 852 err.close();
853 throw new LuanException(error); 853 throw new LuanException(error);
854 } 854 }
855 } 855 }
856 856
857 @Override public String read_text() throws IOException, LuanException { 857 @Override public String read_text(LuanState luan) throws IOException, LuanException {
858 String s = super.read_text(); 858 String s = super.read_text(luan);
859 wait_for(); 859 wait_for();
860 return s; 860 return s;
861 } 861 }
862 862
863 @Override public LuanTable table() { 863 @Override public LuanTable table(LuanState luan) {
864 LuanTable tbl = super.table(); 864 LuanTable tbl = super.table(luan);
865 try { 865 try {
866 tbl.rawPut( "wait_for", new LuanJavaFunction( 866 tbl.rawPut( "wait_for", new LuanJavaFunction(
867 BaseOs.class.getMethod( "wait_for" ), this 867 BaseOs.class.getMethod( "wait_for" ), this
868 ) ); 868 ) );
869 } catch(NoSuchMethodException e) { 869 } catch(NoSuchMethodException e) {
873 } 873 }
874 } 874 }
875 875
876 public static final class LuanOs extends BaseOs { 876 public static final class LuanOs extends BaseOs {
877 private LuanOs(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 877 private LuanOs(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException {
878 super(luan,cmd,options); 878 super(cmd,options);
879 check(luan,"os:"+cmd); 879 check(luan,"os:"+cmd);
880 this.proc = Runtime.getRuntime().exec(cmd,null,dir); 880 this.proc = Runtime.getRuntime().exec(cmd,null,dir);
881 } 881 }
882 } 882 }
883 883
884 public static LuanTable os(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 884 public static LuanTable os(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException {
885 return new LuanOs(luan,cmd,options).table(); 885 return new LuanOs(luan,cmd,options).table(luan);
886 } 886 }
887 887
888 public static final class LuanBash extends BaseOs { 888 public static final class LuanBash extends BaseOs {
889 private LuanBash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 889 private LuanBash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException {
890 super(luan,cmd,options); 890 super(cmd,options);
891 check(luan,"bash:"+cmd); 891 check(luan,"bash:"+cmd);
892 this.proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir); 892 this.proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir);
893 } 893 }
894 } 894 }
895 895
896 public static LuanTable bash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException { 896 public static LuanTable bash(LuanState luan,String cmd,LuanTable options) throws IOException, LuanException {
897 return new LuanBash(luan,cmd,options).table(); 897 return new LuanBash(luan,cmd,options).table(luan);
898 } 898 }
899 899
900 900
901 901
902 public static class LuanInput extends LuanIn { 902 public static class LuanInput extends LuanIn {
904 904
905 public LuanInput(InputStream in) { 905 public LuanInput(InputStream in) {
906 this.in = in; 906 this.in = in;
907 } 907 }
908 908
909 @Override public InputStream inputStream() { 909 @Override public InputStream inputStream(LuanState luan) {
910 return in; 910 return in;
911 } 911 }
912 912
913 @Override public String to_string() { 913 @Override public String to_string() {
914 return "<input_stream>"; 914 return "<input_stream>";
916 916
917 @Override public String to_uri_string() { 917 @Override public String to_uri_string() {
918 throw new UnsupportedOperationException(); 918 throw new UnsupportedOperationException();
919 } 919 }
920 920
921 @Override public boolean exists() { 921 @Override public boolean exists(LuanState luan) {
922 return true; 922 return true;
923 } 923 }
924 }; 924 };
925 925
926 926
930 } catch(UnknownHostException e) { 930 } catch(UnknownHostException e) {
931 return null; 931 return null;
932 } 932 }
933 } 933 }
934 934
935 public static LuanTable my_ips() throws IOException { 935 public static LuanTable my_ips(LuanState luan) throws IOException {
936 LuanTable tbl = new LuanTable(); 936 LuanTable tbl = new LuanTable(luan);
937 for( Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces(); e1.hasMoreElements(); ) { 937 for( Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces(); e1.hasMoreElements(); ) {
938 NetworkInterface ni = e1.nextElement(); 938 NetworkInterface ni = e1.nextElement();
939 for( Enumeration<InetAddress> e2 = ni.getInetAddresses(); e2.hasMoreElements(); ) { 939 for( Enumeration<InetAddress> e2 = ni.getInetAddresses(); e2.hasMoreElements(); ) {
940 InetAddress ia = e2.nextElement(); 940 InetAddress ia = e2.nextElement();
941 if( ia instanceof Inet4Address ) 941 if( ia instanceof Inet4Address )