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
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)