Mercurial Hosting > luan
comparison src/luan/lib/PickleCon.java @ 129:486a0641bca4
add pickle client/server;
fix parser bugs;
git-svn-id: https://luan-java.googlecode.com/svn/trunk@130 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Mon, 09 Jun 2014 09:16:16 +0000 |
parents | |
children | 0594c132888b |
comparison
equal
deleted
inserted
replaced
128:f0a4abe58593 | 129:486a0641bca4 |
---|---|
1 package luan.lib; | |
2 | |
3 import java.io.OutputStream; | |
4 import java.io.BufferedOutputStream; | |
5 import java.io.DataInputStream; | |
6 import java.io.DataOutputStream; | |
7 import java.io.IOException; | |
8 import java.util.Set; | |
9 import java.util.IdentityHashMap; | |
10 import java.util.Collections; | |
11 import java.util.Map; | |
12 import java.util.List; | |
13 import java.util.ArrayList; | |
14 import luan.Luan; | |
15 import luan.LuanTable; | |
16 import luan.LuanState; | |
17 import luan.LuanFunction; | |
18 import luan.LuanJavaFunction; | |
19 import luan.LuanException; | |
20 | |
21 | |
22 public final class PickleCon { | |
23 final LuanState luan; | |
24 private final DataInputStream in; | |
25 private final LuanFunction _read_binary; | |
26 private final LuanTable ioModule; | |
27 private final DataOutputStream out; | |
28 private final List<byte[]> binaries = new ArrayList<byte[]>(); | |
29 String src; | |
30 | |
31 PickleCon(LuanState luan,DataInputStream in,DataOutputStream out) { | |
32 this.in = in; | |
33 this.luan = luan; | |
34 try { | |
35 this._read_binary = new LuanJavaFunction( | |
36 PickleCon.class.getMethod( "_read_binary", Integer.TYPE ), this | |
37 ); | |
38 } catch(NoSuchMethodException e) { | |
39 throw new RuntimeException(e); | |
40 } | |
41 this.ioModule = (LuanTable)luan.loaded().get("Io"); | |
42 | |
43 this.out = out; | |
44 } | |
45 | |
46 public byte[] _read_binary(int size) throws IOException, LuanException { | |
47 byte[] a = new byte[size]; | |
48 int i = 0; | |
49 while( i < size ) { | |
50 int n = in.read(a,i,size-i); | |
51 if( n == -1 ) | |
52 throw luan.JAVA.exception( "end of stream" ); | |
53 i += n; | |
54 } | |
55 return a; | |
56 } | |
57 | |
58 public Object read() throws IOException, LuanException { | |
59 ioModule.put("_read_binary",_read_binary); | |
60 src = in.readUTF(); | |
61 LuanFunction fn = BasicLib.load(luan,src,"pickle-reader",true,false); | |
62 Object rtn = luan.JAVA.call(fn,null); | |
63 ioModule.put("_binaries",null); | |
64 return rtn; | |
65 } | |
66 | |
67 public String pickle(Object obj) throws LuanException { | |
68 if( obj == null ) | |
69 return "nil"; | |
70 if( obj instanceof Number ) | |
71 return Luan.toString((Number)obj); | |
72 if( obj instanceof String ) | |
73 return "\"" + Luan.stringEncode((String)obj) + "\""; | |
74 if( obj instanceof LuanTable ) | |
75 return pickle( (LuanTable)obj, Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) ); | |
76 if( obj instanceof byte[] ) { | |
77 byte[] a = (byte[])obj; | |
78 binaries.add(a); | |
79 return "Io._binaries[" + binaries.size() + "]"; | |
80 } | |
81 throw luan.JAVA.exception( "invalid type: " + obj.getClass() ); | |
82 } | |
83 | |
84 private String pickle(Object obj,Set<LuanTable> set) throws LuanException { | |
85 return obj instanceof LuanTable ? pickle((LuanTable)obj,set) : pickle(obj); | |
86 } | |
87 | |
88 private String pickle(LuanTable tbl,Set<LuanTable> set) throws LuanException { | |
89 if( !set.add(tbl) ) { | |
90 throw luan.JAVA.exception( "circular reference in table" ); | |
91 } | |
92 StringBuilder sb = new StringBuilder(); | |
93 sb.append( "{" ); | |
94 for( Map.Entry<Object,Object> entry : tbl ) { | |
95 sb.append( "[" ); | |
96 sb.append( pickle(entry.getKey(),set) ); | |
97 sb.append( "]=" ); | |
98 sb.append( pickle(entry.getValue(),set) ); | |
99 sb.append( ", " ); | |
100 } | |
101 sb.append( "}" ); | |
102 return sb.toString(); | |
103 } | |
104 | |
105 public void write(Object... args) throws LuanException, IOException { | |
106 StringBuilder sb = new StringBuilder(); | |
107 if( !binaries.isEmpty() ) { | |
108 sb.append( "Io._binaries = {}\n" ); | |
109 for( byte[] a : binaries ) { | |
110 sb.append( "Io._binaries[#Io._binaries+1] = Io._read_binary(" + a.length + ")\n" ); | |
111 } | |
112 } | |
113 for( Object obj : args ) { | |
114 sb.append( luan.JAVA.toString(obj) ); | |
115 } | |
116 out.writeUTF( sb.toString() ); | |
117 for( byte[] a : binaries ) { | |
118 out.write(a); | |
119 } | |
120 out.flush(); | |
121 binaries.clear(); | |
122 } | |
123 | |
124 public void close() throws IOException { | |
125 in.close(); | |
126 out.close(); | |
127 } | |
128 } |