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.
Files changed (45) hide show
  1. data/LICENSE.txt +2 -1
  2. data/Rakefile +49 -0
  3. data/lib/divine/code_generators/code_generator.rb +29 -6
  4. data/lib/divine/code_generators/java.rb +121 -14
  5. data/lib/divine/code_generators/javascript.rb +100 -11
  6. data/lib/divine/code_generators/ruby.rb +89 -4
  7. data/lib/divine/version.rb +1 -1
  8. data/test/basic_complex_test/basic_complex_test.rb +34 -0
  9. data/test/basic_complex_test/java_test/JavaTest.java +96 -0
  10. data/test/basic_complex_test/java_test/test_babel.java +368 -0
  11. data/test/basic_complex_test/js_test/js_testBasic.js +58 -0
  12. data/test/basic_complex_test/js_test/js_testComplex.js +68 -0
  13. data/test/basic_complex_test/js_test/test_babel.js +523 -0
  14. data/test/basic_complex_test/ruby_test/ruby_test.rb +68 -0
  15. data/test/basic_complex_test/ruby_test/test_babel.rb +368 -0
  16. data/test/binaryTree_test/binaryTree_test.rb +19 -0
  17. data/test/binaryTree_test/java_test/JavaTest.java +114 -0
  18. data/test/binaryTree_test/java_test/test_binaryTree.java +301 -0
  19. data/test/binaryTree_test/js_test/js_test.js +76 -0
  20. data/test/binaryTree_test/js_test/test_binaryTree.js +447 -0
  21. data/test/binaryTree_test/ruby_test/ruby_test.rb +68 -0
  22. data/test/binaryTree_test/ruby_test/test_binaryTree.rb +303 -0
  23. data/test/complex_test/complex_test.rb +23 -0
  24. data/test/complex_test/java_test/JavaTest.java +126 -0
  25. data/test/complex_test/java_test/test_complex.java +331 -0
  26. data/test/complex_test/js_test/js_test.js +69 -0
  27. data/test/complex_test/js_test/test_complex.js +478 -0
  28. data/test/complex_test/ruby_test/ruby_test.rb +55 -0
  29. data/test/complex_test/ruby_test/test_complex.rb +330 -0
  30. data/test/ipv6_test/ipv6_test.rb +14 -0
  31. data/test/ipv6_test/java_test/JavaTest.java +77 -0
  32. data/test/ipv6_test/java_test/junit.jar +0 -0
  33. data/test/ipv6_test/java_test/test_ipv6.java +270 -0
  34. data/test/ipv6_test/js_test/js_test.js +60 -0
  35. data/test/ipv6_test/js_test/test_ipv6.js +409 -0
  36. data/test/ipv6_test/ruby_test/ruby_test.rb +42 -0
  37. data/test/ipv6_test/ruby_test/test_ipv6.rb +267 -0
  38. data/test/java_lib/junit.jar +0 -0
  39. data/test/unify_test/java_test/test_unify.java +171 -0
  40. data/test/unify_test/js_test/js_test.js +56 -0
  41. data/test/unify_test/js_test/test_unify.js +326 -0
  42. data/test/unify_test/ruby_test/ruby_test.rb +35 -0
  43. data/test/unify_test/ruby_test/test_unify.rb +187 -0
  44. data/test/unify_test/unify_test.rb +17 -0
  45. metadata +77 -3
@@ -46,19 +46,47 @@ module Divine
46
46
  end
47
47
 
48
48
  def read_ip_number(data)
49
- read_short_binary(data).bytes.to_a.join('.')
49
+ ips = read_short_binary(data)
50
+ if ips.size == 4
51
+ read_ipv4_number(ips)
52
+ else
53
+ read_ipv6_number(ips)
54
+ end
50
55
  end
51
56
 
57
+ def read_ipv4_number(ips)
58
+ ips.bytes.to_a.join('.')
59
+ end
60
+
61
+ def read_ipv6_number(ips)
62
+ ipv6 = []
63
+ ips.bytes.each_slice(2) do |t|
64
+ fst = t[0]
65
+ lst = t[1]
66
+ tmp = ""
67
+ tmp = fst.to_s 16 if fst != 0
68
+ if fst != 0 and lst < 10
69
+ tmp << "0#{lst.to_s 16}"
70
+ elsif fst != 0 and lst > 10 or fst == 0 and lst > 0
71
+ tmp << lst.to_s(16)
72
+ end
73
+ ipv6.push(tmp)
74
+ end
75
+ ipv6.join(':').gsub(/:{2,}/, "::")
76
+ end
77
+
52
78
  ### Write methods ###
53
79
  def write_int8(v, out)
54
80
  v = v.to_i
55
81
  raise_error "Too large int8 number: #{v}" if v > 0xFF # Max 255
82
+ raise_error "a negative number passed to int8 number: #{v}" if v < 0
56
83
  out << v
57
84
  end
58
85
 
59
86
  def write_int16(v, out)
60
87
  v = v.to_i
61
88
  raise_error "Too large int16 number: #{v}" if v > 0xFFFF # Max 65.535
89
+ raise_error "a negative number passed to int16 number: #{v}" if v < 0
62
90
  write_int8( v >> 8 & 0xFF, out)
63
91
  write_int8( v & 0xFF, out)
64
92
  end
@@ -66,6 +94,7 @@ module Divine
66
94
  def write_int24(v, out)
67
95
  v = v.to_i
68
96
  raise_error "Too large int24 number: #{v}" if v > 0xFFFFFF # Max 16.777.215
97
+ raise_error "a negative number passed to int24 number: #{v}" if v < 0 # In Case added to ruby declaration
69
98
  write_int8( v >> 16 & 0xFF, out)
70
99
  write_int16( v & 0xFFFF, out)
71
100
  end
@@ -73,6 +102,7 @@ module Divine
73
102
  def write_int32(v, out)
74
103
  v = v.to_i
75
104
  raise_error "Too large int32 number: #{v}" if v > 0xFFFFFFFF # Max 4.294.967.295
105
+ raise_error "a negative number passed to int32 number: #{v}" if v < 0
76
106
  write_int8( v >> 24 & 0xFF, out)
77
107
  write_int24( v & 0xFFFFFF, out)
78
108
  end
@@ -105,6 +135,19 @@ module Divine
105
135
  end
106
136
  end
107
137
 
138
+ def write_16_binary(v, out)
139
+ if v.is_a?(Array)
140
+ raise_error "Too large 16 binary: #{v.size} (#{v.class.name})" unless v.size*2 < 0xFF
141
+ write_int8(v.size * 2, out) # IPv6 consists of 8 parts each of them has zise of 2 bytes
142
+ v.each do |x|
143
+ write_int16(x, out)
144
+ end
145
+ else
146
+ raise_error "Unsupported binary 'nil'" if v == nil
147
+ raise_error "Unsupported binary of type '#{v.class.name}'"
148
+ end
149
+ end
150
+
108
151
  def write_short_binary(v, out)
109
152
  if v.is_a?(Array)
110
153
  raise_error "Too large short_binary: #{v.size} (#{v.class.name})" unless v.size < 0xFF
@@ -123,6 +166,24 @@ module Divine
123
166
  end
124
167
 
125
168
  def write_ip_number(v, out)
169
+ if v.is_a?(Array)
170
+ if v.size == 4
171
+ write_ipv4_number(v, out);
172
+ else
173
+ write_ipv6_number(v, out);
174
+ end
175
+ elsif v.is_a?(String)
176
+ if v.include?":"
177
+ write_ipv6_number(v, out);
178
+ else
179
+ write_ipv4_number(v, out);
180
+ end
181
+ else
182
+ raise_error "Unknown IP number '#{v}'"
183
+ end
184
+ end
185
+
186
+ def write_ipv4_number(v,out)
126
187
  if v.is_a?(Array)
127
188
  raise_error "Unknown IP v4 number #{v}" unless v.size == 0 || v.size == 4 # Only IPv4 for now
128
189
  write_short_binary(v, out)
@@ -130,12 +191,36 @@ module Divine
130
191
  ss = v.split(/\./).map do |s|
131
192
  s.to_i
132
193
  end
133
- write_ip_number(ss, out)
194
+ write_ipv4_number(ss, out)
134
195
  else
135
196
  raise_error "Unknown IP number '#{v}'"
136
197
  end
137
198
  end
138
199
 
200
+ def write_ipv6_number(v, out)
201
+ if v.is_a?(Array)
202
+ write_16_binary(v, out)
203
+ elsif v.is_a?(String)
204
+ v = v.gsub(" ","") + " " # Temporary: To avoid the split problem when we have : at the end of "v"
205
+ raise_error "Unknown IPv6 number #{v}" unless v.strip.empty? ||
206
+ v.strip.match(/[^:0-9a-f]+/i) == nil && #Should not contains numbers or letters 0-9a-f
207
+ v.strip.match(/[0-9a-f]+/i) != nil && #Should contains numbers or letters 0-9a-f
208
+ v.match(":{3,}") == nil &&
209
+ v.split("::").size <= 2
210
+ ss = v.split(/:/).map do |s|
211
+ s = s.strip
212
+ raise_error "Unknown IPv6 Group #{s}" unless s.size <= 4
213
+ s.to_i 16
214
+ end
215
+ ss = [] if v.strip.empty?
216
+ raise_error "Unknown IPv6 number #{v}" unless (!v.include?("::") && ss.size == 0 || ss.size == 8) ||
217
+ (v.include?("::") && ss.size > 2 && ss.size < 8)
218
+ write_ipv6_number(ss, out)
219
+ else
220
+ raise_error "Unknown IPv6 number '#{v}'"
221
+ end
222
+ end
223
+
139
224
  private
140
225
  def raise_error(msg)
141
226
  raise "[#{self.class.name}] #{msg}"
@@ -335,7 +420,7 @@ module Divine
335
420
  # User defined super class?
336
421
  toplevel = opts[:parent_class] || nil
337
422
  toplevel = " < #{toplevel}" if toplevel
338
- return "#{ruby_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}#{ruby_get_end_module(opts)}"
423
+ return [{file: opts[:file], src: "#{ruby_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}#{ruby_get_end_module(opts)}"}]
339
424
  end
340
425
 
341
426
  def ruby_get_begin_module(opts)
@@ -357,4 +442,4 @@ module Divine
357
442
 
358
443
 
359
444
  $language_generators[:ruby] = RubyGenerator.new
360
- end
445
+ end
@@ -1,3 +1,3 @@
1
1
  module Divine
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,34 @@
1
+
2
+ require 'divine'
3
+
4
+ struct 'TestBasic' do
5
+ int8 :i8
6
+ int16 :i16
7
+ int32 :i32
8
+ string :str
9
+ ip_number :ip
10
+ binary :guid
11
+ end
12
+
13
+ struct 'Entry' do
14
+
15
+ end
16
+
17
+
18
+ struct(:TestComplex) {
19
+ list :list1, :int32
20
+ list :list2, :int8
21
+ map :map1, :int8, :int32
22
+ map(:map2, :string) {
23
+ list 'Entry'
24
+ }
25
+ }
26
+
27
+ if ARGV[0] == "ruby"
28
+ Divine::CodeGenerator.new.generate(:ruby, file: 'test_babel.rb', module: 'BabelTest', parent_class: "Object", target_dir: 'test/basic_complex_test/ruby_test')
29
+ elsif ARGV[0] == "js"
30
+ Divine::CodeGenerator.new.generate(:javascript, file: 'test_babel.js', target_dir: 'test/basic_complex_test/js_test')
31
+ elsif ARGV[0] == "java"
32
+ Divine::CodeGenerator.new.generate(:java, file: 'test_babel.java', target_dir: 'test/basic_complex_test/java_test')
33
+ end
34
+
@@ -0,0 +1,96 @@
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 testBasicTest() throws IOException {
16
+ System.out.println("Test Basic Test");
17
+ TestBasic testbasic_ser = new TestBasic();
18
+ TestBasic testbasic_deser = new TestBasic();
19
+
20
+ testbasic_ser.i8 = 16;
21
+ testbasic_ser.i16 = 458;
22
+ testbasic_ser.i32 = 365248;
23
+ testbasic_ser.str = "Testing String";
24
+ testbasic_ser.ip = "";
25
+
26
+ serialize(testbasic_ser);
27
+ byte[] read = deserialize();
28
+ testbasic_deser.deserialize(new ByteArrayInputStream(read));
29
+
30
+ org.junit.Assert.assertEquals(testbasic_ser.i8, testbasic_deser.i8);
31
+ org.junit.Assert.assertEquals(testbasic_ser.i16, testbasic_deser.i16);
32
+ org.junit.Assert.assertEquals(testbasic_ser.i32, testbasic_deser.i32);
33
+ org.junit.Assert.assertEquals(testbasic_ser.str, testbasic_deser.str);
34
+ org.junit.Assert.assertEquals(testbasic_ser.ip, testbasic_deser.ip);
35
+ }
36
+
37
+ @Test
38
+ public void testComplexTest() throws IOException {
39
+ TestComplex testcomplex_ser = new TestComplex();
40
+ TestComplex testcomplex_deser = new TestComplex();
41
+ testcomplex_ser.list1 = new ArrayList<Long>();
42
+ testcomplex_ser.list1.add(123456L);
43
+ testcomplex_ser.list1.add(654321L);
44
+
45
+ testcomplex_ser.list2 = new ArrayList<Integer>();
46
+ testcomplex_ser.list2.add(123);
47
+ testcomplex_ser.list2.add(221);
48
+
49
+ testcomplex_ser.map1 = new HashMap<Integer, Long>();
50
+ testcomplex_ser.map1.put(12, 123456L);
51
+ testcomplex_ser.map1.put(13, 6543231L);
52
+
53
+ testcomplex_ser.map2 = new HashMap<String, ArrayList<Entry>>();
54
+ ArrayList<Entry> tmp = new ArrayList<Entry>();
55
+ tmp.add(new Entry());
56
+ tmp.add(new Entry());
57
+ testcomplex_ser.map2.put("Key_1", tmp);
58
+ testcomplex_ser.map2.put("Key_2", tmp);
59
+
60
+ serialize(testcomplex_ser);
61
+ byte[] read = deserialize();
62
+ testcomplex_deser.deserialize(new ByteArrayInputStream(read));
63
+
64
+ org.junit.Assert.assertTrue (testcomplex_ser.list1.containsAll(testcomplex_deser.list1));
65
+ org.junit.Assert.assertTrue (testcomplex_ser.list2.containsAll(testcomplex_deser.list2));
66
+ for (Integer k : testcomplex_ser.map1.keySet()){
67
+ org.junit.Assert.assertEquals(testcomplex_ser.map1.get(k), testcomplex_deser.map1.get(k));
68
+ }
69
+ for (String k : testcomplex_ser.map2.keySet()){
70
+ org.junit.Assert.assertEquals(testcomplex_ser.map2.get(k).size(), testcomplex_deser.map2.get(k).size() );
71
+ }
72
+
73
+ }
74
+
75
+ public void serialize(BabelBase obj) throws IOException {
76
+ byte[] data = obj.serialize();
77
+ File file = new File("test/basic_complex_test/java_test/bin.babel");
78
+ try {
79
+ new FileOutputStream(file).write(data);
80
+ } catch (Exception e) {
81
+ e.printStackTrace();
82
+ }
83
+ }
84
+
85
+ public byte[] deserialize() throws IOException{
86
+ File file = new File("test/basic_complex_test/java_test/bin.babel");
87
+ byte[] data = new byte[(int) file.length()];
88
+ try {
89
+ new FileInputStream(file).read(data);
90
+ } catch (Exception e) {
91
+ e.printStackTrace();
92
+ }
93
+ return data;
94
+ }
95
+
96
+ }
@@ -0,0 +1,368 @@
1
+ import java.io.ByteArrayInputStream;
2
+ import java.io.ByteArrayOutputStream;
3
+ import java.io.IOException;
4
+ import java.util.ArrayList;
5
+ import java.util.HashMap;
6
+ import java.util.regex.Pattern;
7
+ import java.nio.charset.Charset;
8
+
9
+ abstract class BabelBase {
10
+ private static final Charset UTF8 = Charset.forName("UTF-8");
11
+
12
+ public byte[] serialize() throws IOException {
13
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
14
+ serializeInternal(baos);
15
+ baos.close();
16
+ return baos.toByteArray();
17
+ }
18
+
19
+ abstract void serializeInternal(ByteArrayOutputStream baos) throws IOException;
20
+
21
+ abstract void deserialize(ByteArrayInputStream baos) throws IOException;
22
+
23
+ protected int readInt8(ByteArrayInputStream data) {
24
+ return data.read() & 0xff;
25
+ }
26
+
27
+ protected int readInt16(ByteArrayInputStream data) {
28
+ return (data.read() << 8) | readInt8(data);
29
+ }
30
+
31
+ protected int readInt24(ByteArrayInputStream data) {
32
+ return (data.read() << 16) | readInt16(data);
33
+ }
34
+
35
+ protected long readInt32(ByteArrayInputStream data) {
36
+ return (data.read() << 24) | readInt24(data);
37
+ }
38
+
39
+ protected boolean readBool(ByteArrayInputStream data) {
40
+ return readInt8(data) == 1;
41
+ }
42
+
43
+ protected String readString(ByteArrayInputStream data) throws IOException {
44
+ // Force utf8
45
+ return new String(readBytes(readInt16(data), data), UTF8);
46
+ }
47
+
48
+ private byte[] readBytes(int size, ByteArrayInputStream data) throws IOException {
49
+ byte[] bs = new byte[size];
50
+ data.read(bs);
51
+ return bs;
52
+ }
53
+
54
+ protected byte[] readBinary(ByteArrayInputStream data) throws IOException {
55
+ long c = readInt32(data);
56
+ if (c > Integer.MAX_VALUE) {
57
+ throw new IndexOutOfBoundsException("Binary data to big for java");
58
+ }
59
+ return readBytes((int) c, data);
60
+ }
61
+
62
+ protected byte[] readShortBinary(ByteArrayInputStream data) throws IOException {
63
+ return readBytes(readInt8(data), data);
64
+ }
65
+
66
+ protected String readIpNumber(ByteArrayInputStream data) throws IOException {
67
+ byte[] ips = readShortBinary(data);
68
+ if(ips.length == 4){
69
+ return readIpv4Number(ips);
70
+ } else{
71
+ return readIpv6Number(ips);
72
+ }
73
+ }
74
+
75
+ protected String readIpv4Number(byte[] ips){
76
+ String ip = "";
77
+ for (byte b : ips) {
78
+ if (ip.length() > 0) {
79
+ ip += ".";
80
+ }
81
+ ip += (b & 0xFF);
82
+ }
83
+ return ip;
84
+ }
85
+
86
+ protected String readIpv6Number(byte[] ips) throws IOException {
87
+ String ip = "";
88
+ int part1, part2;
89
+ for (int i = 0; i < ips.length; i+=2) {
90
+ part1 = ips[i] & 0xFF;
91
+ part2 = ips[i+1] & 0xFF;
92
+ ip += part1 == 0? "" : Integer.toHexString(part1);
93
+ ip += (part1 == 0 && part2 == 0)? "" : (part2 < 10 && part1 != 0? "0" + Integer.toHexString(part2): Integer.toHexString(part2));
94
+ if (i < ips.length-2) {
95
+ ip += ":";
96
+ }
97
+ }
98
+ ip = ip.replaceAll(":{3,}", "::");
99
+ return ip;
100
+ }
101
+
102
+ protected void writeInt8(int v, ByteArrayOutputStream out) {
103
+ if (v > 0xFF) { // Max 255
104
+ raiseError("Too large int8 number: " + v);
105
+ }else if(v < 0){
106
+ raiseError("a negative number passed to int8 number: " + v);
107
+ }
108
+ out.write(v);
109
+ }
110
+
111
+ protected void writeInt16(int v, ByteArrayOutputStream out) {
112
+ if (v > 0xFFFF) { // Max 65.535
113
+ raiseError("Too large int16 number: " + v);
114
+ }else if(v < 0){
115
+ raiseError("a negative number passed to int16 number: " + v);
116
+ }
117
+ writeInt8(v >> 8 & 0xFF, out);
118
+ writeInt8(v & 0xFF, out);
119
+ }
120
+
121
+ protected void writeInt24(int v, ByteArrayOutputStream out) {
122
+ if (v > 0xFFFFFF) { // Max 16.777.215
123
+ raiseError("Too large int24 number: " + v);
124
+ }else if(v < 0){ // In Case added to Java declaration
125
+ raiseError("a negative number passed to int24 number: " + v);
126
+ }
127
+ writeInt8(v >> 16 & 0xFF, out);
128
+ writeInt16(v & 0xFFFF, out);
129
+ }
130
+
131
+ protected void writeInt32(long v, ByteArrayOutputStream out) {
132
+ if (v > 0xFFFFFFFFL) { // Max 4.294.967.295
133
+ raiseError("Too large int32 number: " + v);
134
+ }else if(v < 0){
135
+ raiseError("a negative number passed to int32 number: " + v);
136
+ }
137
+ writeInt8((int) ((v >> 24) & 0xFF), out);
138
+ writeInt24((int) (v & 0xFFFFFF), out);
139
+ }
140
+
141
+ protected void writeBool(boolean v, ByteArrayOutputStream out) {
142
+ writeInt8(v ? 1 : 0, out);
143
+ }
144
+
145
+ protected void writeString(String v, ByteArrayOutputStream out) throws IOException {
146
+ byte[] bs = v.getBytes(UTF8);
147
+ if (bs.length > 0xFFFF) {
148
+ raiseError("Too large string: " + bs.length + " bytes");
149
+ }
150
+ writeInt16(bs.length, out);
151
+ out.write(bs);
152
+ }
153
+
154
+ protected void writeBinary(byte[] v, ByteArrayOutputStream out) throws IOException {
155
+ if (v.length > 0xFFFFFFFFL) {
156
+ raiseError("Too large binary: " + v.length + " bytes");
157
+ }
158
+ writeInt32(v.length, out);
159
+ out.write(v);
160
+ }
161
+
162
+
163
+ protected void write16Binary(int[] v, ByteArrayOutputStream out) throws IOException {
164
+ if (v.length > 0xFF) {
165
+ raiseError("Too large 16_binary: " + (v.length*2) + " bytes");
166
+ }
167
+ writeInt8(v.length*2, out);
168
+ for(int i = 0; i < v.length; i++){
169
+ this.writeInt16(v[i], out);
170
+ }
171
+ }
172
+
173
+ protected void writeShortBinary(byte[] v, ByteArrayOutputStream out) throws IOException {
174
+ if (v.length > 0xFF) {
175
+ raiseError("Too large short_binary: " + v.length + " bytes");
176
+ }
177
+ writeInt8(v.length, out);
178
+ out.write(v);
179
+ }
180
+
181
+ protected void writeIpNumber(String v, ByteArrayOutputStream out) throws IOException {
182
+ if(v.contains(":")){
183
+ writeIpv6Number( v, out);
184
+ }else{
185
+ writeIpv4Number( v, out);
186
+ }
187
+ }
188
+
189
+ protected void writeIpv4Number(String v, ByteArrayOutputStream out) throws IOException {
190
+ byte[] ss = new byte[0];
191
+ if(!v.isEmpty()){
192
+ String[] bs = v.split("\\.");
193
+ ss = new byte[bs.length];
194
+ for (int i = 0; i < bs.length; i++) {
195
+ ss[i] = (byte) (Integer.parseInt(bs[i]) & 0xFF);
196
+ }
197
+ }
198
+ if (ss.length == 0 || ss.length == 4) {
199
+ writeShortBinary(ss, out);
200
+ } else {
201
+ raiseError("Unknown IP v4 number " + v); // Only IPv4 for now
202
+ }
203
+ }
204
+
205
+ protected void writeIpv6Number(String v, ByteArrayOutputStream out)
206
+ throws IOException {
207
+ v = v.replaceAll(" ", "") + " "; // Temporary: To avoid the split problem when we have : at the
208
+ // end of "v"
209
+ int[] ss = new int[0];
210
+ boolean contains_ipv6_letters = Pattern.compile("[0-9a-f]+").matcher(
211
+ v.trim().toLowerCase()).find();
212
+ boolean contains_other_letters = Pattern.compile("[^:0-9a-f]+")
213
+ .matcher(v.trim().toLowerCase()).find();
214
+ // make sure of v must have only one "::" and no more than two of ":".
215
+ // e.g. 1::1::1 & 1:::1:205
216
+ if (!v.trim().isEmpty() && v.split(":{3,}").length == 1
217
+ && v.split(":{2}").length <= 2 && !contains_other_letters
218
+ && contains_ipv6_letters) {
219
+ String[] bs = v.split(":");
220
+ ss = new int[bs.length];
221
+ for (int i = 0; i < bs.length; i++) {
222
+ String s = bs[i].trim();
223
+ if (s.length() <= 4) // to avoid such number 0125f
224
+ ss[i] = Integer.parseInt(
225
+ (s.isEmpty() ? "0" : bs[i].trim()), 16);
226
+ else
227
+ raiseError("Unknown IPv6 Group " + i + " which is " + s);
228
+ }
229
+ }
230
+ // Check for make sure of the size of the IP groups in case "::" is used
231
+ // [> 2 & < 8]or not [must == 8]
232
+ if (!contains_other_letters
233
+ && (!v.contains("::") && ss.length == 0 || ss.length == 8)
234
+ || (v.contains("::") && ss.length > 2 && ss.length < 8)) {
235
+ write16Binary(ss, out);
236
+ } else {
237
+ raiseError("Unknown IP v6 number " + v);
238
+ }
239
+ }
240
+
241
+ protected void raiseError(String msg) {
242
+ throw new IllegalArgumentException("[" + this.getClass().getCanonicalName() + "] " + msg);
243
+ }
244
+ }
245
+
246
+
247
+ class Entry extends BabelBase {
248
+
249
+ @Override
250
+ void serializeInternal(ByteArrayOutputStream baos) throws IOException {
251
+ }
252
+
253
+ @Override
254
+ public void deserialize(ByteArrayInputStream bais) throws IOException {
255
+ }
256
+ }
257
+
258
+
259
+ class TestBasic extends BabelBase {
260
+ public int i8 = 0;
261
+ public int i16 = 0;
262
+ public long i32 = 0L;
263
+ public String str = "";
264
+ public String ip = "";
265
+ public byte[] guid = new byte[0];
266
+
267
+ @Override
268
+ void serializeInternal(ByteArrayOutputStream baos) throws IOException {
269
+ writeInt8(this.i8, baos);
270
+ writeInt16(this.i16, baos);
271
+ writeInt32(this.i32, baos);
272
+ writeString(this.str, baos);
273
+ writeIpNumber(this.ip, baos);
274
+ writeBinary(this.guid, baos);
275
+ }
276
+
277
+ @Override
278
+ public void deserialize(ByteArrayInputStream bais) throws IOException {
279
+ this.i8 = readInt8(bais);
280
+ this.i16 = readInt16(bais);
281
+ this.i32 = readInt32(bais);
282
+ this.str = readString(bais);
283
+ this.ip = readIpNumber(bais);
284
+ this.guid = readBinary(bais);
285
+ }
286
+ }
287
+
288
+
289
+ class TestComplex extends BabelBase {
290
+ public ArrayList<Long> list1 = new ArrayList<Long>();
291
+ public ArrayList<Integer> list2 = new ArrayList<Integer>();
292
+ public HashMap<Integer, Long> map1 = new HashMap<Integer, Long>();
293
+ public HashMap<String, ArrayList<Entry>> map2 = new HashMap<String, ArrayList<Entry>>();
294
+
295
+ @Override
296
+ void serializeInternal(ByteArrayOutputStream baos) throws IOException {
297
+ // Serialize list 'list1'
298
+ writeInt32(list1.size(), baos);
299
+ for(int var_101=0; var_101<list1.size(); var_101++) {
300
+ long var_100 = list1.get(var_101);
301
+ writeInt32(var_100, baos);
302
+ }
303
+ // Serialize list 'list2'
304
+ writeInt32(list2.size(), baos);
305
+ for(int var_103=0; var_103<list2.size(); var_103++) {
306
+ int var_102 = list2.get(var_103);
307
+ writeInt8(var_102, baos);
308
+ }
309
+ // Serialize map 'map1'
310
+ writeInt32(map1.size(), baos);
311
+ for(int var_104 : map1.keySet()) {
312
+ long var_105 = map1.get(var_104);
313
+ writeInt8(var_104, baos);
314
+ writeInt32(var_105, baos);
315
+ }
316
+ // Serialize map 'map2'
317
+ writeInt32(map2.size(), baos);
318
+ for(String var_106 : map2.keySet()) {
319
+ ArrayList<Entry> var_107 = map2.get(var_106);
320
+ writeString(var_106, baos);
321
+ writeInt32(var_107.size(), baos);
322
+ for(int var_109=0; var_109<var_107.size(); var_109++) {
323
+ Entry var_108 = var_107.get(var_109);
324
+ var_108.serializeInternal(baos);
325
+ }
326
+ }
327
+ }
328
+
329
+ @Override
330
+ public void deserialize(ByteArrayInputStream bais) throws IOException {
331
+ // Deserialize list 'list1'
332
+ this.list1 = new ArrayList<Long>();
333
+ int var_10a = (int)this.readInt32(bais);
334
+ for(int var_10c=0; var_10c<var_10a; var_10c++) {
335
+ long var_10b = readInt32(bais);
336
+ this.list1.add(var_10b);
337
+ }
338
+ // Deserialize list 'list2'
339
+ this.list2 = new ArrayList<Integer>();
340
+ int var_10d = (int)this.readInt32(bais);
341
+ for(int var_10f=0; var_10f<var_10d; var_10f++) {
342
+ int var_10e = readInt8(bais);
343
+ this.list2.add(var_10e);
344
+ }
345
+ // Deserialize map 'map1'
346
+ this.map1 = new HashMap<Integer, Long>();
347
+ int var_110 = (int)readInt32(bais);
348
+ for(int var_113=0; var_113<var_110; var_113++) {
349
+ int var_111 = readInt8(bais);
350
+ long var_112 = readInt32(bais);
351
+ this.map1.put(var_111, var_112);
352
+ }
353
+ // Deserialize map 'map2'
354
+ this.map2 = new HashMap<String, ArrayList<Entry>>();
355
+ int var_114 = (int)readInt32(bais);
356
+ for(int var_117=0; var_117<var_114; var_117++) {
357
+ String var_115 = readString(bais);
358
+ ArrayList<Entry> var_116 = new ArrayList<Entry>();
359
+ int var_118 = (int)this.readInt32(bais);
360
+ for(int var_11a=0; var_11a<var_118; var_11a++) {
361
+ Entry var_119 = new Entry();
362
+ var_119.deserialize(bais);
363
+ var_116.add(var_119);
364
+ }
365
+ this.map2.put(var_115, var_116);
366
+ }
367
+ }
368
+ }