divine 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
data/LICENSE.txt CHANGED
@@ -1,4 +1,5 @@
1
- Copyright (c) 2012 Nils Franzen
1
+ Copyright (c) 2012 Nils Franzen (https://github.com/franzen)
2
+ Copyright (c) 2012 Ahmed H. Ali (https://github.com/Ahmedrali)
2
3
  Copyright (c) 2009-2010, Patrick Reiter Horn (Javascript UTF8 string encode/decode methods taken from the ProtoJS project)
3
4
 
4
5
  MIT License
data/Rakefile CHANGED
@@ -1 +1,50 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ namespace :test do
4
+
5
+ desc "Run Ruby code test suite"
6
+ task :ruby => :environment do
7
+ ruby "test/basic_complex_test/ruby_test/ruby_test.rb"
8
+ ruby "test/binaryTree_test/ruby_test/ruby_test.rb"
9
+ ruby "test/ipv6_test/ruby_test/ruby_test.rb"
10
+ ruby "test/complex_test/ruby_test/ruby_test.rb"
11
+ end
12
+
13
+
14
+ desc "Run JS code test suite"
15
+ task :js => :environment do
16
+ system("node test/basic_complex_test/js_test/js_testBasic.js")
17
+ system("node test/basic_complex_test/js_test/js_testComplex.js")
18
+ system("node test/binaryTree_test/js_test/js_test.js")
19
+ system("node test/ipv6_test/js_test/js_test.js")
20
+ system("node test/complex_test/js_test/js_test.js")
21
+ end
22
+
23
+ desc "Run java code test suite"
24
+ task :java => :environment do
25
+ system("javac -cp test/java_lib/junit.jar: test/ipv6_test/java_test/*.java")
26
+ system("java -cp test/ipv6_test/java_test/:test/java_lib/junit.jar:. org.junit.runner.JUnitCore JavaTest")
27
+
28
+ system("javac -cp test/java_lib/junit.jar: test/complex_test/java_test/*.java")
29
+ system("java -cp test/complex_test/java_test/:test/java_lib/junit.jar:. org.junit.runner.JUnitCore JavaTest")
30
+
31
+ system("javac -cp test/java_lib/junit.jar: test/binaryTree_test/java_test/*.java")
32
+ system("java -cp test/binaryTree_test/java_test/:test/java_lib/junit.jar:. org.junit.runner.JUnitCore JavaTest")
33
+
34
+ system("javac -cp test/java_lib/junit.jar: test/basic_complex_test/java_test/*.java")
35
+ system("java -cp test/basic_complex_test/java_test/:test/java_lib/junit.jar:. org.junit.runner.JUnitCore JavaTest")
36
+ end
37
+
38
+
39
+ desc "Generate Source Code"
40
+ task :environment do
41
+ puts "Divine Version #{Divine::VERSION}"
42
+ lang = Rake.application.top_level_tasks[0].match(/:(.*)/)[1]
43
+
44
+ ruby "test/basic_complex_test/basic_complex_test.rb #{lang}"
45
+ ruby "test/ipv6_test/ipv6_test.rb #{lang}"
46
+ ruby "test/complex_test/complex_test.rb #{lang}"
47
+ ruby "test/binaryTree_test/binaryTree_test.rb #{lang}"
48
+ end
49
+ end
50
+
@@ -35,15 +35,38 @@ module Divine
35
35
  raise "Unknown taget language: #{target}" unless gen
36
36
  puts "Generating code for #{target}"
37
37
  src = gen.generate_code($all_structs, opts)
38
- if opts[:file]
39
- filename = opts[:file]
40
- File.open(filename, 'w+') do |f|
41
- puts "... writing #{filename}"
42
- f.write(src)
38
+ target_dir = getTargetDir(opts[:target_dir])
39
+
40
+ if opts[:package]
41
+ path = target_dir + opts[:package]
42
+ Dir.mkdir(path) unless File.exists?(path)
43
+ for cls in src
44
+ file_name = path+"/"+cls[:file]
45
+ writeFile(file_name, cls[:src])
43
46
  end
47
+ elsif opts[:file]
48
+ path = target_dir + opts[:file]
49
+ writeFile(path, src[0][:src])
44
50
  else
45
51
  puts src
46
52
  end
47
53
  end
54
+
55
+ def getTargetDir(dir)
56
+ # check if the path is relative or absolute if exist
57
+ if dir && File.directory?(dir)
58
+ return dir + "/"
59
+ elsif dir && File.directory?(Dir.pwd + "/" + dir)
60
+ return Dir.pwd + dir + "/"
61
+ end
62
+ ""
63
+ end
64
+
65
+ def writeFile(path, content)
66
+ File.open(path, 'w+') do |f|
67
+ puts "... writing #{path}"
68
+ f.write(content)
69
+ end
70
+ end
48
71
  end
49
- end
72
+ end
@@ -53,7 +53,7 @@ abstract class BabelBase <%= toplevel_class %> {
53
53
  if (c > Integer.MAX_VALUE) {
54
54
  throw new IndexOutOfBoundsException("Binary data to big for java");
55
55
  }
56
- return readBytes((int) readInt32(data), data);
56
+ return readBytes((int) c, data);
57
57
  }
58
58
 
59
59
  protected byte[] readShortBinary(ByteArrayInputStream data) throws IOException {
@@ -61,7 +61,15 @@ abstract class BabelBase <%= toplevel_class %> {
61
61
  }
62
62
 
63
63
  protected String readIpNumber(ByteArrayInputStream data) throws IOException {
64
- byte[] ips = readShortBinary(data);
64
+ byte[] ips = readShortBinary(data);
65
+ if(ips.length == 4){
66
+ return readIpv4Number(ips);
67
+ } else{
68
+ return readIpv6Number(ips);
69
+ }
70
+ }
71
+
72
+ protected String readIpv4Number(byte[] ips){
65
73
  String ip = "";
66
74
  for (byte b : ips) {
67
75
  if (ip.length() > 0) {
@@ -72,9 +80,27 @@ abstract class BabelBase <%= toplevel_class %> {
72
80
  return ip;
73
81
  }
74
82
 
83
+ protected String readIpv6Number(byte[] ips) throws IOException {
84
+ String ip = "";
85
+ int part1, part2;
86
+ for (int i = 0; i < ips.length; i+=2) {
87
+ part1 = ips[i] & 0xFF;
88
+ part2 = ips[i+1] & 0xFF;
89
+ ip += part1 == 0? "" : Integer.toHexString(part1);
90
+ ip += (part1 == 0 && part2 == 0)? "" : (part2 < 10 && part1 != 0? "0" + Integer.toHexString(part2): Integer.toHexString(part2));
91
+ if (i < ips.length-2) {
92
+ ip += ":";
93
+ }
94
+ }
95
+ ip = ip.replaceAll(":{3,}", "::");
96
+ return ip;
97
+ }
98
+
75
99
  protected void writeInt8(int v, ByteArrayOutputStream out) {
76
100
  if (v > 0xFF) { // Max 255
77
101
  raiseError("Too large int8 number: " + v);
102
+ }else if(v < 0){
103
+ raiseError("a negative number passed to int8 number: " + v);
78
104
  }
79
105
  out.write(v);
80
106
  }
@@ -82,22 +108,28 @@ abstract class BabelBase <%= toplevel_class %> {
82
108
  protected void writeInt16(int v, ByteArrayOutputStream out) {
83
109
  if (v > 0xFFFF) { // Max 65.535
84
110
  raiseError("Too large int16 number: " + v);
111
+ }else if(v < 0){
112
+ raiseError("a negative number passed to int16 number: " + v);
85
113
  }
86
114
  writeInt8(v >> 8 & 0xFF, out);
87
115
  writeInt8(v & 0xFF, out);
88
116
  }
89
117
 
90
118
  protected void writeInt24(int v, ByteArrayOutputStream out) {
91
- if (v > 0xFFFFFF) { // Max 16.777.215
119
+ if (v > 0xFFFFFF) { // Max 16.777.215
92
120
  raiseError("Too large int24 number: " + v);
121
+ }else if(v < 0){ // In Case added to Java declaration
122
+ raiseError("a negative number passed to int24 number: " + v);
93
123
  }
94
124
  writeInt8(v >> 16 & 0xFF, out);
95
125
  writeInt16(v & 0xFFFF, out);
96
126
  }
97
127
 
98
128
  protected void writeInt32(long v, ByteArrayOutputStream out) {
99
- if (v > 0xFFFFFFFF) { // Max 4.294.967.295
129
+ if (v > 0xFFFFFFFFL) { // Max 4.294.967.295
100
130
  raiseError("Too large int32 number: " + v);
131
+ }else if(v < 0){
132
+ raiseError("a negative number passed to int32 number: " + v);
101
133
  }
102
134
  writeInt8((int) ((v >> 24) & 0xFF), out);
103
135
  writeInt24((int) (v & 0xFFFFFF), out);
@@ -117,13 +149,24 @@ abstract class BabelBase <%= toplevel_class %> {
117
149
  }
118
150
 
119
151
  protected void writeBinary(byte[] v, ByteArrayOutputStream out) throws IOException {
120
- if (v.length > 0xFFFFFFFF) {
152
+ if (v.length > 0xFFFFFFFFL) {
121
153
  raiseError("Too large binary: " + v.length + " bytes");
122
154
  }
123
155
  writeInt32(v.length, out);
124
156
  out.write(v);
125
157
  }
126
158
 
159
+
160
+ protected void write16Binary(int[] v, ByteArrayOutputStream out) throws IOException {
161
+ if (v.length > 0xFF) {
162
+ raiseError("Too large 16_binary: " + (v.length*2) + " bytes");
163
+ }
164
+ writeInt8(v.length*2, out);
165
+ for(int i = 0; i < v.length; i++){
166
+ this.writeInt16(v[i], out);
167
+ }
168
+ }
169
+
127
170
  protected void writeShortBinary(byte[] v, ByteArrayOutputStream out) throws IOException {
128
171
  if (v.length > 0xFF) {
129
172
  raiseError("Too large short_binary: " + v.length + " bytes");
@@ -133,10 +176,21 @@ abstract class BabelBase <%= toplevel_class %> {
133
176
  }
134
177
 
135
178
  protected void writeIpNumber(String v, ByteArrayOutputStream out) throws IOException {
136
- String[] bs = v.split(".");
137
- byte[] ss = new byte[bs.length];
138
- for (int i = 0; i < bs.length; i++) {
139
- ss[i] = (byte) (Integer.parseInt(bs[i]) & 0xFF);
179
+ if(v.contains(":")){
180
+ writeIpv6Number( v, out);
181
+ }else{
182
+ writeIpv4Number( v, out);
183
+ }
184
+ }
185
+
186
+ protected void writeIpv4Number(String v, ByteArrayOutputStream out) throws IOException {
187
+ byte[] ss = new byte[0];
188
+ if(!v.isEmpty()){
189
+ String[] bs = v.split("\\\\.");
190
+ ss = new byte[bs.length];
191
+ for (int i = 0; i < bs.length; i++) {
192
+ ss[i] = (byte) (Integer.parseInt(bs[i]) & 0xFF);
193
+ }
140
194
  }
141
195
  if (ss.length == 0 || ss.length == 4) {
142
196
  writeShortBinary(ss, out);
@@ -145,6 +199,42 @@ abstract class BabelBase <%= toplevel_class %> {
145
199
  }
146
200
  }
147
201
 
202
+ protected void writeIpv6Number(String v, ByteArrayOutputStream out)
203
+ throws IOException {
204
+ v = v.replaceAll(" ", "") + " "; // Temporary: To avoid the split problem when we have : at the
205
+ // end of "v"
206
+ int[] ss = new int[0];
207
+ boolean contains_ipv6_letters = Pattern.compile("[0-9a-f]+").matcher(
208
+ v.trim().toLowerCase()).find();
209
+ boolean contains_other_letters = Pattern.compile("[^:0-9a-f]+")
210
+ .matcher(v.trim().toLowerCase()).find();
211
+ // make sure of v must have only one "::" and no more than two of ":".
212
+ // e.g. 1::1::1 & 1:::1:205
213
+ if (!v.trim().isEmpty() && v.split(":{3,}").length == 1
214
+ && v.split(":{2}").length <= 2 && !contains_other_letters
215
+ && contains_ipv6_letters) {
216
+ String[] bs = v.split(":");
217
+ ss = new int[bs.length];
218
+ for (int i = 0; i < bs.length; i++) {
219
+ String s = bs[i].trim();
220
+ if (s.length() <= 4) // to avoid such number 0125f
221
+ ss[i] = Integer.parseInt(
222
+ (s.isEmpty() ? "0" : bs[i].trim()), 16);
223
+ else
224
+ raiseError("Unknown IPv6 Group " + i + " which is " + s);
225
+ }
226
+ }
227
+ // Check for make sure of the size of the IP groups in case "::" is used
228
+ // [> 2 & < 8]or not [must == 8]
229
+ if (!contains_other_letters
230
+ && (!v.contains("::") && ss.length == 0 || ss.length == 8)
231
+ || (v.contains("::") && ss.length > 2 && ss.length < 8)) {
232
+ write16Binary(ss, out);
233
+ } else {
234
+ raiseError("Unknown IP v6 number " + v);
235
+ }
236
+ }
237
+
148
238
  protected void raiseError(String msg) {
149
239
  throw new IllegalArgumentException("[" + this.getClass().getCanonicalName() + "] " + msg);
150
240
  }
@@ -154,7 +244,7 @@ EOS
154
244
 
155
245
  def java_class_template_str
156
246
  <<EOS2
157
- public class <%= c.name %> extends BabelBase {
247
+ class <%= c.name %> extends BabelBase {
158
248
  <% unless c.fields.empty? %>
159
249
  <% c.fields.each do |f| %>
160
250
  public <%= this.java_get_type_declaration(f) %> <%= f.name %> = <%= this.java_get_empty_declaration(f) %>;
@@ -172,7 +262,7 @@ public class <%= c.name %> extends BabelBase {
172
262
  }
173
263
 
174
264
  @Override
175
- void deserialize(ByteArrayInputStream bais) throws IOException {
265
+ public void deserialize(ByteArrayInputStream bais) throws IOException {
176
266
  <% c.simple_fields.each do |f| %>
177
267
  this.<%= f.name %> = <%= this.camelize("read", f.type) %>(bais);
178
268
  <% end %>
@@ -389,8 +479,16 @@ EOS2
389
479
 
390
480
  # User defined super class?
391
481
  toplevel = opts[:parent_class] || nil
392
- toplevel = " extends #{toplevel}" if toplevel
393
- return "#{java_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}"
482
+ toplevel = " extends #{toplevel}" if toplevel
483
+ if opts[:package]
484
+ res = [{file: "BabelBase.java", src: "#{java_get_begin_module(opts)}public #{base_template.result({ toplevel_class: toplevel })}"}]
485
+ for cls in src
486
+ res << {file: cls.match(/class (.*) extends/)[1]+".java", src: "#{java_get_begin_module(opts)}public #{cls}"}
487
+ end
488
+ return res
489
+ else
490
+ return [{file: opts[:file], src: "#{java_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}"}]
491
+ end
394
492
  end
395
493
 
396
494
  def java_get_begin_module(opts)
@@ -402,10 +500,19 @@ EOS2
402
500
  "import java.io.IOException;",
403
501
  "import java.util.ArrayList;",
404
502
  "import java.util.HashMap;",
503
+ "import java.util.regex.Pattern;",
405
504
  "import java.nio.charset.Charset;\n\n"
406
505
  ].join("\n")
407
506
  else
408
- nil
507
+ [
508
+ "import java.io.ByteArrayInputStream;",
509
+ "import java.io.ByteArrayOutputStream;",
510
+ "import java.io.IOException;",
511
+ "import java.util.ArrayList;",
512
+ "import java.util.HashMap;",
513
+ "import java.util.regex.Pattern;",
514
+ "import java.nio.charset.Charset;\n\n"
515
+ ].join("\n")
409
516
  end
410
517
  end
411
518
  end
@@ -95,6 +95,14 @@ BabelHelper.prototype.read_short_binary = function (data) {
95
95
 
96
96
  BabelHelper.prototype.read_ip_number = function (data) {
97
97
  var ip_array = this.read_short_binary(data);
98
+ if(ip_array.length == 4){
99
+ return this.read_ipv4_number(ip_array);
100
+ }else{
101
+ return this.read_ipv6_number(ip_array);
102
+ }
103
+ };
104
+
105
+ BabelHelper.prototype.read_ipv4_number = function (ip_array) {
98
106
  ip = "";
99
107
  for (i = 0, len = ip_array.length; i < len; i++) {
100
108
  b = ip_array[i];
@@ -105,6 +113,20 @@ BabelHelper.prototype.read_ip_number = function (data) {
105
113
  }
106
114
  return ip;
107
115
  };
116
+ BabelHelper.prototype.read_ipv6_number = function (ip_array) {
117
+ var ip = "";
118
+ var part1, part2;
119
+ for (i = 0, len = ip_array.length; i < len; i+=2) {
120
+ part1 = ip_array[i];
121
+ part2 = ip_array[i+1];
122
+ ip += part1 == 0? "" : part1.toString(16);
123
+ ip += (part1 == 0 && part2 == 0)? "" : (part2 < 10 && part1 != 0? "0" + part2.toString(16): part2.toString(16));
124
+ if (i < ip_array.length-2)
125
+ ip += ":";
126
+ }
127
+ ip = ip.replace(/:{3,}/g, "::");
128
+ return ip;
129
+ };
108
130
 
109
131
  BabelHelper.prototype.read_string = function (data) {
110
132
  return this.decode_utf8(data.read(this.read_int16(data)))
@@ -112,27 +134,35 @@ BabelHelper.prototype.read_string = function (data) {
112
134
 
113
135
  BabelHelper.prototype.write_int8 = function (v, out) {
114
136
  if (v > 0xFF) // Max 255
115
- this.raise_error("Too large int8 number: " + v);
137
+ this.raise_error("Too large int8 number: " + v);
138
+ if(v < 0)
139
+ this.raise_error("a negative number passed to int8 number: " + v);
116
140
  out.writeByte(v);
117
141
  }
118
142
 
119
143
  BabelHelper.prototype.write_int16 = function (v, out) {
120
144
  if (v > 0xFFFF) // Max 65.535
121
- this.raise_error("Too large int16 number: " + v);
145
+ this.raise_error("Too large int16 number: " + v);
146
+ if(v < 0)
147
+ this.raise_error("a negative number passed to int16 number: " + v);
122
148
  this.write_int8(v >> 8 & 0xFF, out);
123
149
  this.write_int8(v & 0xFF, out);
124
150
  }
125
151
 
126
152
  BabelHelper.prototype.write_int24 = function (v, out) {
127
- if (v > 0xFFFFFF) // Max 16.777.215
128
- this.raise_error("Too large int24 number: " + v);
153
+ if (v > 0xFFFFFF) // Max 16.777.215
154
+ this.raise_error("Too large int24 number: " + v);
155
+ if (v < 0) // In Case added to JavaScript declaration
156
+ this.raise_error("a negative number passed to int24 number: " + v);
129
157
  this.write_int8(v >> 16 & 0xFF, out);
130
158
  this.write_int16(v & 0xFFFF, out);
131
159
  }
132
160
 
133
161
  BabelHelper.prototype.write_int32 = function (v, out) {
134
162
  if (v > 0xFFFFFFFF) // Max 4.294.967.295
135
- this.raise_error("Too large int32 number: " + v);
163
+ this.raise_error("Too large int32 number: " + v);
164
+ if(v < 0)
165
+ this.raise_error("a negative number passed to int32 number: " + v);
136
166
  this.write_int8(v >> 24 & 0xFF, out);
137
167
  this.write_int24(v & 0xFFFFFF, out);
138
168
  }
@@ -141,10 +171,6 @@ BabelHelper.prototype.write_bool = function (v, out) {
141
171
  this.write_int8(v ? 1 : 0, out)
142
172
  }
143
173
 
144
- BabelHelper.prototype.write_bool = function (v, out) {
145
- this.write_int8(v ? 1 : 0, out)
146
- }
147
-
148
174
  BabelHelper.prototype.write_string = function (v, out) {
149
175
  var s = this.encode_utf8(v);
150
176
  if (s.length > 0xFFFF) this.raise_error("Too large string: " + s.length + " bytes");
@@ -168,6 +194,21 @@ BabelHelper.prototype.write_binary = function (v, out) {
168
194
  }
169
195
  }
170
196
 
197
+ BabelHelper.prototype.write_16_binary = function (v, out) {
198
+ if ((v instanceof Array) || (v instanceof Uint8Array)) {
199
+ if (v.length > 0xFF) this.raise_error("Too large 16 binary: " + v.length*2 + " (" + v.constructor.name + ")");
200
+ this.write_int8(v.length * 2, out)
201
+ for (i = 0, len = v.length; i < len; i++) {
202
+ this.write_int16(v[i], out);
203
+ }
204
+
205
+ } else if (v == null) {
206
+ this.raise_error("Unsupported binary 'null'");
207
+ } else {
208
+ this.raise_error("Unsupported binary of type '" + v.constructor.name + "'");
209
+ }
210
+ }
211
+
171
212
  BabelHelper.prototype.write_short_binary = function (v, out) {
172
213
  if ((v instanceof Array) || (v instanceof Uint8Array)) {
173
214
  if (v.length > 0xFF) this.raise_error("Too large binary: " + v.length + " (" + v.constructor.name + ")");
@@ -185,6 +226,24 @@ BabelHelper.prototype.write_short_binary = function (v, out) {
185
226
  }
186
227
 
187
228
  BabelHelper.prototype.write_ip_number = function (v, out) {
229
+ if ((v instanceof Array) || (v instanceof Uint8Array)){
230
+ if(v.length == 4){
231
+ this.write_ipv4_number(v, out);
232
+ }else{
233
+ this.write_ipv6_number(v, out);
234
+ }
235
+ }else if(v.constructor == String){
236
+ if(/:/g.test(v)){
237
+ this.write_ipv6_number(v, out);
238
+ }else{
239
+ this.write_ipv4_number(v, out);
240
+ }
241
+ }else{
242
+ this.raise_error("Unknown IP number '" + v + "'");
243
+ }
244
+ }
245
+
246
+ BabelHelper.prototype.write_ipv4_number = function (v, out) {
188
247
  if ((v instanceof Array) || (v instanceof Uint8Array)) {
189
248
  if (v.length != 4 && v.length != 0) this.raise_error("Unknown IP v4 number " + v);
190
249
  this.write_short_binary(v, out)
@@ -193,10 +252,40 @@ BabelHelper.prototype.write_ip_number = function (v, out) {
193
252
  if (v.length > 0) {
194
253
  ss = v.split(".").map(Number);
195
254
  }
196
- this.write_ip_number(ss, out);
255
+ this.write_ipv4_number(ss, out);
197
256
  } else {
198
257
  this.raise_error("Unknown IP number '" + v + "'");
199
258
  }
259
+ };
260
+
261
+ BabelHelper.prototype.write_ipv6_number = function (v, out) {
262
+ if ((v instanceof Array) || (v instanceof Uint8Array)) {
263
+ this.write_16_binary(v, out)
264
+ } else if (v.constructor == String) {
265
+ var ss = [];
266
+ var contains_ipv6_letters = /[0-9a-f]+/gi.test(v);
267
+ var contains_other_letters = /[^:0-9a-f]+/gi.test(v);
268
+ if (v.length > 0 && v.split(/:{3,}/g).length == 1 && v.split(/:{2}/g).length <= 2 && !contains_other_letters &&
269
+ contains_ipv6_letters) {
270
+ v = v.replace(/ /g, "");
271
+ ss = v.split(":").map(function (t){
272
+ if (t.length > 4)
273
+ new BabelHelper().raise_error("Unknown IP Group number '" + t + "'");
274
+ if (t.length == 0)
275
+ t = "0";
276
+ return parseInt(t, 16);
277
+ });
278
+ }
279
+ if (!contains_other_letters &&
280
+ ( !/::/g.test(v) && ss.length == 0 || ss.length == 8) || ( /::/g.test(v) && ss.length > 2 && ss.length < 8) ) {
281
+ this.write_ipv6_number(ss, out);
282
+ } else {
283
+ this.raise_error("Unknown IP v6 number '" + v + "'");
284
+ }
285
+
286
+ } else {
287
+ this.raise_error("Unknown IP v6 number '" + v + "'");
288
+ }
200
289
  }
201
290
 
202
291
  BabelHelper.prototype.encode_utf8 = function (str) {
@@ -495,7 +584,7 @@ EOS2
495
584
  # User defined super class?
496
585
  toplevel = opts[:parent_class] || nil
497
586
  toplevel = " < #{toplevel}" if toplevel
498
- return "#{javascript_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}#{javascript_get_end_module(opts)}"
587
+ return [{file: opts[:file], src: "#{javascript_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}#{javascript_get_end_module(opts)}"}]
499
588
  end
500
589
 
501
590
  def javascript_get_begin_module(opts)