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