Mercurial Hosting > luan
changeset 758:c29d11d675fd
added Json.toString() and rpc now sends tables as json
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 19 Jul 2016 00:57:37 -0600 |
parents | e1dfeddfbc7b |
children | ae612dfc57cb |
files | core/src/luan/modules/IoLuan.java core/src/luan/modules/RpcLuan.java core/src/luan/modules/parsers/Json.java |
diffstat | 3 files changed, 150 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/modules/IoLuan.java Mon Jul 18 20:18:02 2016 -0600 +++ b/core/src/luan/modules/IoLuan.java Tue Jul 19 00:57:37 2016 -0600 @@ -171,6 +171,21 @@ } + private static File objToFile(Object obj) { + if( obj instanceof String ) { + return new File((String)obj); + } + if( obj instanceof LuanTable ) { + LuanTable t = (LuanTable)obj; + Object java = t.rawGet("java"); + if( java instanceof LuanFile ) { + LuanFile luanFile = (LuanFile)java; + return luanFile.file; + } + } + return null; + } + public static abstract class LuanIn { public abstract InputStream inputStream() throws IOException, LuanException; @@ -213,13 +228,16 @@ } } - public void unzip(String path) throws IOException, LuanException { + public void unzip(Object path) throws IOException, LuanException { + File pathFile = objToFile(path); + if( pathFile==null ) + throw new LuanException( "bad argument #1 to 'unzip' (string or file table expected)" ); ZipInputStream in = new ZipInputStream(new BufferedInputStream(inputStream())); ZipEntry entry; while( (entry = in.getNextEntry()) != null ) { if( entry.isDirectory() ) continue; - File file = new File(path,entry.getName()); + File file = new File(pathFile,entry.getName()); file.getParentFile().mkdirs(); OutputStream out = new FileOutputStream(file); Utils.copyAll(in,out); @@ -255,7 +273,7 @@ LuanIn.class.getMethod( "exists" ), this ) ); tbl.rawPut( "unzip", new LuanJavaFunction( - LuanIn.class.getMethod( "unzip", String.class ), this + LuanIn.class.getMethod( "unzip", Object.class ), this ) ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); @@ -333,12 +351,15 @@ return binaryWriter(new BufferedOutputStream(outputStream())); } - public void zip(LuanState luan,String basePath,LuanTable filePathList) throws LuanException, IOException { + public void zip(LuanState luan,Object basePathObj,LuanTable filePathList) throws LuanException, IOException { + File basePathFile = objToFile(basePathObj); + if( basePathFile==null ) + throw new LuanException( "bad argument #1 to 'zip' (string or file table expected)" ); String[] filePaths; if( filePathList==null ) { - File file = new File(basePath).getCanonicalFile(); + File file = basePathFile.getCanonicalFile(); filePaths = new String[]{file.toString()}; - basePath = file.getParent(); + basePathFile = file.getParentFile(); } else { List list = filePathList.asList(); filePaths = new String[list.size()]; @@ -349,8 +370,7 @@ filePaths[i] = (String)obj; } } - if( !basePath.endsWith("/") ) - basePath += '/'; + String basePath = basePathFile.toString() + '/'; ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(outputStream())); zip(out,basePath,filePaths); out.close(); @@ -393,7 +413,7 @@ LuanIO.class.getMethod( "binary_writer" ), this ) ); tbl.rawPut( "zip", new LuanJavaFunction( - LuanIO.class.getMethod( "zip", LuanState.class, String.class, LuanTable.class ), this + LuanIO.class.getMethod( "zip", LuanState.class, Object.class, LuanTable.class ), this ) ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); @@ -537,8 +557,12 @@ return file.exists(); } - public boolean rename_to(String dest) { - return file.renameTo(new File(dest)); + public void rename_to(Object destObj) throws LuanException { + File dest = objToFile(destObj); + if( dest==null ) + throw new LuanException( "bad argument #1 to 'objToFile' (string or file table expected)" ); + if( !file.renameTo(dest) ) + throw new LuanException("couldn't rename file "+file+" to "+dest); } public LuanTable canonical(LuanState luan) throws LuanException, IOException { @@ -605,7 +629,7 @@ LuanFile.class.getMethod( "parent", LuanState.class ), this ) ); tbl.rawPut( "rename_to", new LuanJavaFunction( - LuanFile.class.getMethod( "rename_to", String.class ), this + LuanFile.class.getMethod( "rename_to", Object.class ), this ) ); tbl.rawPut( "canonical", new LuanJavaFunction( LuanFile.class.getMethod( "canonical", LuanState.class ), this
--- a/core/src/luan/modules/RpcLuan.java Mon Jul 18 20:18:02 2016 -0600 +++ b/core/src/luan/modules/RpcLuan.java Tue Jul 19 00:57:37 2016 -0600 @@ -20,6 +20,8 @@ import luan.LuanFunction; import luan.LuanException; import luan.LuanMethod; +import luan.modules.parsers.Json; +import luan.modules.parsers.ParseException; public final class RpcLuan { @@ -144,7 +146,8 @@ } else if( obj instanceof LuanTable ) { out.write(TABLE); - String s = pickle( luan, obj, Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) ); +// String s = pickle( luan, obj, Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) ); + String s = Json.toString(obj); writeString(out,s); } else @@ -166,8 +169,15 @@ return readBinary(in,readInt(in)); case TABLE: String s = readString(in); +/* LuanFunction fn = Luan.load("return "+s,"rpc-reader"); return fn.call(luan); +*/ + try { + return Json.parse(s); + } catch(ParseException e) { + throw new LuanException(e); + } case IO: return new LuanInputStream(in,close).table(); default: @@ -224,7 +234,7 @@ out.write((v >>> 0) & 0xFF); } - +/* private static String pickle(LuanState luan,Object obj,Set<LuanTable> set) throws LuanException { if( obj == null ) return "nil"; @@ -253,7 +263,7 @@ } throw new LuanException( "invalid type: " + obj.getClass() ); } - +*/ private static class Close { boolean b = true;
--- a/core/src/luan/modules/parsers/Json.java Mon Jul 18 20:18:02 2016 -0600 +++ b/core/src/luan/modules/parsers/Json.java Tue Jul 19 00:57:37 2016 -0600 @@ -4,7 +4,9 @@ import java.util.ArrayList; import java.util.Map; import java.util.LinkedHashMap; +import java.util.Iterator; import luan.LuanTable; +import luan.LuanException; public final class Json { @@ -201,4 +203,103 @@ private void spaces() { while( parser.anyOf(" \t\r\n") ); } + + + + + + + + + + public static String toString(Object obj) throws LuanException { + StringBuilder sb = new StringBuilder(); + toString(obj,sb); + return sb.toString(); + } + + private static void toString(Object obj,StringBuilder sb) throws LuanException { + if( obj == null || obj instanceof Boolean || obj instanceof Number ) { + sb.append(obj); + return; + } + if( obj instanceof String ) { + toString((String)obj,sb); + return; + } + if( obj instanceof LuanTable ) { + toString((LuanTable)obj,sb); + return; + } + throw new LuanException("can't handle type "+obj.getClass().getName()); + } + + private static void toString(final String s,StringBuilder sb) { + sb.append('"'); + for( int i=0; i<s.length(); i++ ) { + char c = s.charAt(i); + switch(c) { + case '"': + sb.append("\\\""); + break; + case '\\': + sb.append("\\\\"); + break; + case '\b': + sb.append("\\b"); + break; + case '\f': + sb.append("\\f"); + break; + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + case '\t': + sb.append("\\t"); + break; + default: + sb.append(c); + } + } + sb.append('"'); + } + + private static void toString(LuanTable t,StringBuilder sb) throws LuanException { + if( t.isList() ) { + final List list = t.asList(); + if( list.isEmpty() ) { + sb.append("{}"); + return; + } + sb.append('['); + toString(list.get(0),sb); + for( int i=1; i<list.size(); i++ ) { + sb.append(','); + toString(list.get(i),sb); + } + sb.append(']'); + return; + } + sb.append('{'); + Iterator<Map.Entry<Object,Object>> i = t.rawIterator(); + toString(i.next(),sb); + while( i.hasNext() ) { + sb.append(','); + toString(i.next(),sb); + } + sb.append('}'); + } + + private static void toString(Map.Entry<Object,Object> entry,StringBuilder sb) throws LuanException { + Object key = entry.getKey(); + if( !(key instanceof String) ) + throw new LuanException("table keys must be strings"); + toString((String)key,sb); + sb.append(':'); + toString(entry.getValue(),sb); + } + }