divine 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +2 -1
- data/Rakefile +49 -0
- data/lib/divine/code_generators/code_generator.rb +29 -6
- data/lib/divine/code_generators/java.rb +121 -14
- data/lib/divine/code_generators/javascript.rb +100 -11
- data/lib/divine/code_generators/ruby.rb +89 -4
- data/lib/divine/version.rb +1 -1
- data/test/basic_complex_test/basic_complex_test.rb +34 -0
- data/test/basic_complex_test/java_test/JavaTest.java +96 -0
- data/test/basic_complex_test/java_test/test_babel.java +368 -0
- data/test/basic_complex_test/js_test/js_testBasic.js +58 -0
- data/test/basic_complex_test/js_test/js_testComplex.js +68 -0
- data/test/basic_complex_test/js_test/test_babel.js +523 -0
- data/test/basic_complex_test/ruby_test/ruby_test.rb +68 -0
- data/test/basic_complex_test/ruby_test/test_babel.rb +368 -0
- data/test/binaryTree_test/binaryTree_test.rb +19 -0
- data/test/binaryTree_test/java_test/JavaTest.java +114 -0
- data/test/binaryTree_test/java_test/test_binaryTree.java +301 -0
- data/test/binaryTree_test/js_test/js_test.js +76 -0
- data/test/binaryTree_test/js_test/test_binaryTree.js +447 -0
- data/test/binaryTree_test/ruby_test/ruby_test.rb +68 -0
- data/test/binaryTree_test/ruby_test/test_binaryTree.rb +303 -0
- data/test/complex_test/complex_test.rb +23 -0
- data/test/complex_test/java_test/JavaTest.java +126 -0
- data/test/complex_test/java_test/test_complex.java +331 -0
- data/test/complex_test/js_test/js_test.js +69 -0
- data/test/complex_test/js_test/test_complex.js +478 -0
- data/test/complex_test/ruby_test/ruby_test.rb +55 -0
- data/test/complex_test/ruby_test/test_complex.rb +330 -0
- data/test/ipv6_test/ipv6_test.rb +14 -0
- data/test/ipv6_test/java_test/JavaTest.java +77 -0
- data/test/ipv6_test/java_test/junit.jar +0 -0
- data/test/ipv6_test/java_test/test_ipv6.java +270 -0
- data/test/ipv6_test/js_test/js_test.js +60 -0
- data/test/ipv6_test/js_test/test_ipv6.js +409 -0
- data/test/ipv6_test/ruby_test/ruby_test.rb +42 -0
- data/test/ipv6_test/ruby_test/test_ipv6.rb +267 -0
- data/test/java_lib/junit.jar +0 -0
- data/test/unify_test/java_test/test_unify.java +171 -0
- data/test/unify_test/js_test/js_test.js +56 -0
- data/test/unify_test/js_test/test_unify.js +326 -0
- data/test/unify_test/ruby_test/ruby_test.rb +35 -0
- data/test/unify_test/ruby_test/test_unify.rb +187 -0
- data/test/unify_test/unify_test.rb +17 -0
- metadata +77 -3
@@ -0,0 +1,303 @@
|
|
1
|
+
module BabelTest
|
2
|
+
|
3
|
+
|
4
|
+
class BabelBase < Object
|
5
|
+
public
|
6
|
+
def serialize
|
7
|
+
out = []
|
8
|
+
serialize_internal(out)
|
9
|
+
out.flatten.pack("C*")
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
### Read methods ###
|
14
|
+
def read_int8(data)
|
15
|
+
data.getbyte
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_int16(data)
|
19
|
+
(data.getbyte << 8) | read_int8(data)
|
20
|
+
end
|
21
|
+
|
22
|
+
def read_int24(data)
|
23
|
+
(data.getbyte << 16) | read_int16(data)
|
24
|
+
end
|
25
|
+
|
26
|
+
def read_int32(data)
|
27
|
+
(data.getbyte << 24) | read_int24(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_bool(data)
|
31
|
+
read_int8(data) == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_string(data)
|
35
|
+
data.read(read_int16(data)).force_encoding('UTF-8')
|
36
|
+
end
|
37
|
+
|
38
|
+
def read_binary(data)
|
39
|
+
data.read(read_int32(data))
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_short_binary(data)
|
43
|
+
data.read(read_int8(data))
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_ip_number(data)
|
47
|
+
ips = read_short_binary(data)
|
48
|
+
if ips.size == 4
|
49
|
+
read_ipv4_number(ips)
|
50
|
+
else
|
51
|
+
read_ipv6_number(ips)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def read_ipv4_number(ips)
|
56
|
+
ips.bytes.to_a.join('.')
|
57
|
+
end
|
58
|
+
|
59
|
+
def read_ipv6_number(ips)
|
60
|
+
ipv6 = []
|
61
|
+
ips.bytes.each_slice(2) do |t|
|
62
|
+
fst = t[0]
|
63
|
+
lst = t[1]
|
64
|
+
tmp = ""
|
65
|
+
tmp = fst.to_s 16 if fst != 0
|
66
|
+
if fst != 0 and lst < 10
|
67
|
+
tmp << "0#{lst.to_s 16}"
|
68
|
+
elsif fst != 0 and lst > 10 or fst == 0 and lst > 0
|
69
|
+
tmp << lst.to_s(16)
|
70
|
+
end
|
71
|
+
ipv6.push(tmp)
|
72
|
+
end
|
73
|
+
ipv6.join(':').gsub(/:{2,}/, "::")
|
74
|
+
end
|
75
|
+
|
76
|
+
### Write methods ###
|
77
|
+
def write_int8(v, out)
|
78
|
+
v = v.to_i
|
79
|
+
raise_error "Too large int8 number: #{v}" if v > 0xFF # Max 255
|
80
|
+
raise_error "a negative number passed to int8 number: #{v}" if v < 0
|
81
|
+
out << v
|
82
|
+
end
|
83
|
+
|
84
|
+
def write_int16(v, out)
|
85
|
+
v = v.to_i
|
86
|
+
raise_error "Too large int16 number: #{v}" if v > 0xFFFF # Max 65.535
|
87
|
+
raise_error "a negative number passed to int16 number: #{v}" if v < 0
|
88
|
+
write_int8( v >> 8 & 0xFF, out)
|
89
|
+
write_int8( v & 0xFF, out)
|
90
|
+
end
|
91
|
+
|
92
|
+
def write_int24(v, out)
|
93
|
+
v = v.to_i
|
94
|
+
raise_error "Too large int24 number: #{v}" if v > 0xFFFFFF # Max 16.777.215
|
95
|
+
raise_error "a negative number passed to int24 number: #{v}" if v < 0 # In Case added to ruby declaration
|
96
|
+
write_int8( v >> 16 & 0xFF, out)
|
97
|
+
write_int16( v & 0xFFFF, out)
|
98
|
+
end
|
99
|
+
|
100
|
+
def write_int32(v, out)
|
101
|
+
v = v.to_i
|
102
|
+
raise_error "Too large int32 number: #{v}" if v > 0xFFFFFFFF # Max 4.294.967.295
|
103
|
+
raise_error "a negative number passed to int32 number: #{v}" if v < 0
|
104
|
+
write_int8( v >> 24 & 0xFF, out)
|
105
|
+
write_int24( v & 0xFFFFFF, out)
|
106
|
+
end
|
107
|
+
|
108
|
+
def write_bool(v, out)
|
109
|
+
write_int8(v ? 1 : 0, out)
|
110
|
+
end
|
111
|
+
|
112
|
+
def write_string(v, out)
|
113
|
+
s = force_to_utf8_string(v)
|
114
|
+
raise_error "Too large string: #{s.bytesize} bytes" if s.bytesize > 0xFFFF
|
115
|
+
write_int16(s.bytesize, out)
|
116
|
+
out << s.bytes.to_a
|
117
|
+
end
|
118
|
+
|
119
|
+
def write_binary(v, out)
|
120
|
+
if v.is_a?(Array)
|
121
|
+
raise_error "Too large binary: #{v.size} (#{v.class.name})" unless v.size < 0xFFFFFFFF
|
122
|
+
write_int32(v.size, out)
|
123
|
+
v.each do |x|
|
124
|
+
write_int8(x, out)
|
125
|
+
end
|
126
|
+
elsif v.is_a?(String)
|
127
|
+
raise_error "Too large binary: #{v.size} (#{v.class.name})" unless v.size < 0xFFFFFFFF
|
128
|
+
write_int32(v.size, out)
|
129
|
+
out << v.bytes.to_a
|
130
|
+
else
|
131
|
+
raise_error "Unsupported binary 'nil'" if v == nil
|
132
|
+
raise_error "Unsupported binary of type '#{v.class.name}'"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def write_16_binary(v, out)
|
137
|
+
if v.is_a?(Array)
|
138
|
+
raise_error "Too large 16 binary: #{v.size} (#{v.class.name})" unless v.size*2 < 0xFF
|
139
|
+
write_int8(v.size * 2, out) # IPv6 consists of 8 parts each of them has zise of 2 bytes
|
140
|
+
v.each do |x|
|
141
|
+
write_int16(x, out)
|
142
|
+
end
|
143
|
+
else
|
144
|
+
raise_error "Unsupported binary 'nil'" if v == nil
|
145
|
+
raise_error "Unsupported binary of type '#{v.class.name}'"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def write_short_binary(v, out)
|
150
|
+
if v.is_a?(Array)
|
151
|
+
raise_error "Too large short_binary: #{v.size} (#{v.class.name})" unless v.size < 0xFF
|
152
|
+
write_int8(v.size, out)
|
153
|
+
v.each do |x|
|
154
|
+
write_int8(x, out)
|
155
|
+
end
|
156
|
+
elsif v.is_a?(String)
|
157
|
+
raise_error "To large short_binary: #{v.size} (#{v.class.name})" unless v.size < 0xFF
|
158
|
+
write_int8(v.size, out)
|
159
|
+
out << v.bytes.to_a
|
160
|
+
else
|
161
|
+
raise_error "Unsupported binary 'nil'" if v == nil
|
162
|
+
raise_error "Unsupported binary of type '#{v.class.name}'"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def write_ip_number(v, out)
|
167
|
+
if v.is_a?(Array)
|
168
|
+
if v.size == 4
|
169
|
+
write_ipv4_number(v, out);
|
170
|
+
else
|
171
|
+
write_ipv6_number(v, out);
|
172
|
+
end
|
173
|
+
elsif v.is_a?(String)
|
174
|
+
if v.include?":"
|
175
|
+
write_ipv6_number(v, out);
|
176
|
+
else
|
177
|
+
write_ipv4_number(v, out);
|
178
|
+
end
|
179
|
+
else
|
180
|
+
raise_error "Unknown IP number '#{v}'"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def write_ipv4_number(v,out)
|
185
|
+
if v.is_a?(Array)
|
186
|
+
raise_error "Unknown IP v4 number #{v}" unless v.size == 0 || v.size == 4 # Only IPv4 for now
|
187
|
+
write_short_binary(v, out)
|
188
|
+
elsif v.is_a?(String)
|
189
|
+
ss = v.split(/\./).map do |s|
|
190
|
+
s.to_i
|
191
|
+
end
|
192
|
+
write_ipv4_number(ss, out)
|
193
|
+
else
|
194
|
+
raise_error "Unknown IP number '#{v}'"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def write_ipv6_number(v, out)
|
199
|
+
if v.is_a?(Array)
|
200
|
+
write_16_binary(v, out)
|
201
|
+
elsif v.is_a?(String)
|
202
|
+
v = v.gsub(" ","") + " " # Temporary: To avoid the split problem when we have : at the end of "v"
|
203
|
+
raise_error "Unknown IPv6 number #{v}" unless v.strip.empty? ||
|
204
|
+
v.strip.match(/[^:0-9a-f]+/i) == nil && #Should not contains numbers or letters 0-9a-f
|
205
|
+
v.strip.match(/[0-9a-f]+/i) != nil && #Should contains numbers or letters 0-9a-f
|
206
|
+
v.match(":{3,}") == nil &&
|
207
|
+
v.split("::").size <= 2
|
208
|
+
ss = v.split(/:/).map do |s|
|
209
|
+
s = s.strip
|
210
|
+
raise_error "Unknown IPv6 Group #{s}" unless s.size <= 4
|
211
|
+
s.to_i 16
|
212
|
+
end
|
213
|
+
ss = [] if v.strip.empty?
|
214
|
+
raise_error "Unknown IPv6 number #{v}" unless (!v.include?("::") && ss.size == 0 || ss.size == 8) ||
|
215
|
+
(v.include?("::") && ss.size > 2 && ss.size < 8)
|
216
|
+
write_ipv6_number(ss, out)
|
217
|
+
else
|
218
|
+
raise_error "Unknown IPv6 number '#{v}'"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
private
|
223
|
+
def raise_error(msg)
|
224
|
+
raise "[#{self.class.name}] #{msg}"
|
225
|
+
end
|
226
|
+
|
227
|
+
def force_to_utf8_string(string)
|
228
|
+
if string.encoding != Encoding::UTF_8
|
229
|
+
string = string.encode(Encoding::UTF_8)
|
230
|
+
end
|
231
|
+
return string
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
class BinaryTree < BabelBase
|
238
|
+
attr_accessor :root_node
|
239
|
+
|
240
|
+
def initialize()
|
241
|
+
super
|
242
|
+
@root_node ||= []
|
243
|
+
end
|
244
|
+
|
245
|
+
def serialize_internal(out)
|
246
|
+
print "+"
|
247
|
+
# Serialize list 'root_node'
|
248
|
+
write_int32(root_node.size, out)
|
249
|
+
root_node.each do |var_100|
|
250
|
+
var_100.serialize_internal(out)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def deserialize(data)
|
255
|
+
print "-"
|
256
|
+
# Deserialize list 'root_node'
|
257
|
+
@root_node = []
|
258
|
+
var_101 = read_int32(data)
|
259
|
+
(1..var_101).each do
|
260
|
+
var_102 = Node.new
|
261
|
+
var_102.deserialize(data)
|
262
|
+
@root_node << var_102
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
class Node < BabelBase
|
270
|
+
attr_accessor :i32, :next_node
|
271
|
+
|
272
|
+
def initialize()
|
273
|
+
super
|
274
|
+
@i32 ||= 0
|
275
|
+
@next_node ||= []
|
276
|
+
end
|
277
|
+
|
278
|
+
def serialize_internal(out)
|
279
|
+
print "+"
|
280
|
+
write_int32(i32, out)
|
281
|
+
# Serialize list 'next_node'
|
282
|
+
write_int32(next_node.size, out)
|
283
|
+
next_node.each do |var_103|
|
284
|
+
var_103.serialize_internal(out)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def deserialize(data)
|
289
|
+
print "-"
|
290
|
+
@i32 = read_int32(data)
|
291
|
+
# Deserialize list 'next_node'
|
292
|
+
@next_node = []
|
293
|
+
var_104 = read_int32(data)
|
294
|
+
(1..var_104).each do
|
295
|
+
var_105 = Node.new
|
296
|
+
var_105.deserialize(data)
|
297
|
+
@next_node << var_105
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
require 'divine'
|
3
|
+
|
4
|
+
struct 'IPList' do
|
5
|
+
list :list1, :ip_number
|
6
|
+
list :list2, :ip_number
|
7
|
+
end
|
8
|
+
|
9
|
+
struct 'Complex' do
|
10
|
+
list (:list1) {
|
11
|
+
map(:string) {
|
12
|
+
list 'IPList'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
if ARGV[0] == "ruby"
|
18
|
+
Divine::CodeGenerator.new.generate(:ruby, file: 'test_complex.rb', module: 'BabelTest', parent_class: "Object", target_dir: 'test/complex_test/ruby_test')
|
19
|
+
elsif ARGV[0] == "js"
|
20
|
+
Divine::CodeGenerator.new.generate(:javascript, file: 'test_complex.js', target_dir: 'test/complex_test/js_test')
|
21
|
+
elsif ARGV[0] == "java"
|
22
|
+
Divine::CodeGenerator.new.generate(:java, file: 'test_complex.java', target_dir: 'test/complex_test/java_test')
|
23
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
import java.io.ByteArrayInputStream;
|
3
|
+
import java.io.File;
|
4
|
+
import java.io.FileInputStream;
|
5
|
+
import java.io.FileOutputStream;
|
6
|
+
import java.io.IOException;
|
7
|
+
import java.util.ArrayList;
|
8
|
+
import java.util.Collections;
|
9
|
+
import java.util.HashMap;
|
10
|
+
import org.junit.*;
|
11
|
+
|
12
|
+
public class JavaTest {
|
13
|
+
|
14
|
+
@Test
|
15
|
+
public void testComplexTest() throws IOException {
|
16
|
+
System.out.println("Test Complex Data Structure");
|
17
|
+
Complex complex_ser = buildObject();
|
18
|
+
serialize(complex_ser);
|
19
|
+
byte[] read = deserialize();
|
20
|
+
|
21
|
+
Complex complex_deser = new Complex();
|
22
|
+
complex_deser.deserialize(new ByteArrayInputStream(read));
|
23
|
+
|
24
|
+
compare(complex_ser, complex_deser);
|
25
|
+
}
|
26
|
+
|
27
|
+
public Complex buildObject() {
|
28
|
+
final IPList ipList_1 = new IPList();
|
29
|
+
ipList_1.list1 = new ArrayList<String>() {
|
30
|
+
{
|
31
|
+
add("10.2.2.1");
|
32
|
+
add("127.0.0.1");
|
33
|
+
add("129.36.58.15");
|
34
|
+
}
|
35
|
+
};
|
36
|
+
|
37
|
+
ipList_1.list2 = new ArrayList<String>() {
|
38
|
+
{
|
39
|
+
add("2001:db8::ff00:1:8329");
|
40
|
+
add("ff:ac:12::5f");
|
41
|
+
add("1::");
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
final IPList ipList_2 = new IPList();
|
46
|
+
ipList_2.list1 = new ArrayList<String>() {
|
47
|
+
{
|
48
|
+
add("100.20.20.10");
|
49
|
+
add("17.10.10.1");
|
50
|
+
add("12.36.68.105");
|
51
|
+
}
|
52
|
+
};
|
53
|
+
|
54
|
+
ipList_2.list2 = new ArrayList<String>() {
|
55
|
+
{
|
56
|
+
add("ff:fabf:faf:f15f:f1ff:f2f:1f:f2");
|
57
|
+
add("2001:db8::ff00:1:8329");
|
58
|
+
add("::1");
|
59
|
+
}
|
60
|
+
};
|
61
|
+
|
62
|
+
Complex com = new Complex();
|
63
|
+
com.list1 = new ArrayList<HashMap<String, ArrayList<IPList>>>() {
|
64
|
+
{
|
65
|
+
add(new HashMap<String, ArrayList<IPList>>() {
|
66
|
+
{
|
67
|
+
put("AA", new ArrayList<IPList>() {
|
68
|
+
{
|
69
|
+
add(ipList_1);
|
70
|
+
add(ipList_2);
|
71
|
+
}
|
72
|
+
});
|
73
|
+
}
|
74
|
+
});
|
75
|
+
add(new HashMap<String, ArrayList<IPList>>() {
|
76
|
+
{
|
77
|
+
put("BB", new ArrayList<IPList>() {
|
78
|
+
{
|
79
|
+
add(ipList_2);
|
80
|
+
add(ipList_1);
|
81
|
+
}
|
82
|
+
});
|
83
|
+
}
|
84
|
+
});
|
85
|
+
}
|
86
|
+
};
|
87
|
+
|
88
|
+
return com;
|
89
|
+
}
|
90
|
+
|
91
|
+
public void compare(Complex obj1, Complex obj2) {
|
92
|
+
org.junit.Assert.assertEquals(obj1.list1.size(), obj2.list1.size());
|
93
|
+
org.junit.Assert.assertEquals(obj1.list1.get(0).get("AA").size(),
|
94
|
+
obj2.list1.get(0).get("AA").size());
|
95
|
+
org.junit.Assert.assertEquals(obj1.list1.get(0).get("AA").get(0).list1
|
96
|
+
.size(), obj2.list1.get(0).get("AA").get(0).list1.size());
|
97
|
+
org.junit.Assert.assertEquals(obj1.list1.get(0).get("AA").get(0).list1
|
98
|
+
.get(2), obj2.list1.get(0).get("AA").get(0).list1.get(2));
|
99
|
+
org.junit.Assert.assertEquals(obj1.list1.get(0).get("AA").get(0).list2
|
100
|
+
.get(1), obj2.list1.get(0).get("AA").get(0).list2.get(1));
|
101
|
+
org.junit.Assert.assertEquals(obj1.list1.get(1).get("BB").get(0).list2
|
102
|
+
.get(0), obj2.list1.get(1).get("BB").get(0).list2.get(0));
|
103
|
+
}
|
104
|
+
|
105
|
+
public void serialize(BabelBase obj) throws IOException {
|
106
|
+
byte[] data = obj.serialize();
|
107
|
+
File file = new File("test/complex_test/java_test/bin.babel");
|
108
|
+
try {
|
109
|
+
new FileOutputStream(file).write(data);
|
110
|
+
} catch (Exception e) {
|
111
|
+
e.printStackTrace();
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
public byte[] deserialize() throws IOException{
|
116
|
+
File file = new File("test/complex_test/java_test/bin.babel");
|
117
|
+
byte[] data = new byte[(int) file.length()];
|
118
|
+
try {
|
119
|
+
new FileInputStream(file).read(data);
|
120
|
+
} catch (Exception e) {
|
121
|
+
e.printStackTrace();
|
122
|
+
}
|
123
|
+
return data;
|
124
|
+
}
|
125
|
+
|
126
|
+
}
|