divine 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +4 -14
  2. data/README.md +25 -0
  3. data/Rakefile +34 -19
  4. data/divine.gemspec +1 -0
  5. data/lib/divine.rb +3 -1
  6. data/lib/divine/code_generators/code_generator.rb +51 -1
  7. data/lib/divine/code_generators/csharp.rb +898 -0
  8. data/lib/divine/code_generators/java.rb +125 -13
  9. data/lib/divine/code_generators/javascript.rb +111 -4
  10. data/lib/divine/code_generators/ruby.rb +103 -9
  11. data/lib/divine/dsl.rb +95 -6
  12. data/lib/divine/graph_generator/graph_generator.rb +81 -0
  13. data/lib/divine/version.rb +2 -1
  14. data/test/basic_complex_test/basic_complex_test.rb +5 -0
  15. data/test/basic_complex_test/graph.jpg +0 -0
  16. data/test/basic_complex_test/java_test/JavaTest.java +1 -1
  17. data/test/basic_complex_test/ruby_test/ruby_test.rb +17 -4
  18. data/test/binaryTree_test/binaryTree_test.rb +5 -0
  19. data/test/binaryTree_test/csharp_test/csharp_test.cs +99 -0
  20. data/test/binaryTree_test/graph.png +0 -0
  21. data/test/binaryTree_test/java_test/JavaTest.java +1 -1
  22. data/test/binaryTree_test/ruby_test/ruby_test.rb +26 -3
  23. data/test/complex_test/complex_test.rb +5 -0
  24. data/test/complex_test/csharp_test/csharp_test.cs +109 -0
  25. data/test/complex_test/graph.png +0 -0
  26. data/test/complex_test/java_test/JavaTest.java +1 -1
  27. data/test/complex_test/ruby_test/ruby_test.rb +24 -1
  28. data/test/dynamic_int_test/csharp_test/csharp_test.cs +76 -0
  29. data/test/dynamic_int_test/dynamic_int_test.rb +20 -0
  30. data/test/dynamic_int_test/graph.jpg +0 -0
  31. data/test/dynamic_int_test/java_test/JavaTest.java +72 -0
  32. data/test/dynamic_int_test/js_test/js_test.js +54 -0
  33. data/test/dynamic_int_test/ruby_test/ruby_test.rb +55 -0
  34. data/test/ipv6_test/csharp_test/csharp_test.cs +73 -0
  35. data/test/ipv6_test/graph.jpg +0 -0
  36. data/test/ipv6_test/ipv6_test.rb +5 -0
  37. data/test/ipv6_test/java_test/JavaTest.java +1 -1
  38. data/test/ipv6_test/ruby_test/ruby_test.rb +24 -4
  39. data/test/lib/csharp/nunit.framework.dll +0 -0
  40. data/test/{java_lib → lib/java}/junit.jar +0 -0
  41. data/test/signed_int_test/csharp_test/csharp_test.cs +86 -0
  42. data/test/signed_int_test/graph.jpg +0 -0
  43. data/test/signed_int_test/java_test/JavaTest.java +1 -1
  44. data/test/signed_int_test/ruby_test/ruby_test.rb +21 -1
  45. data/test/signed_int_test/signed_int_test.rb +6 -0
  46. data/test/unify_test/unify_test.rb +17 -4
  47. metadata +54 -8
  48. data/test/signed_float_test/ruby_test/ruby_test.rb +0 -36
  49. data/test/signed_float_test/signed_float_test.rb +0 -14
@@ -1,15 +1,32 @@
1
1
  module Divine
2
2
 
3
+ ##
4
+ # * +Java Helper+ :
5
+ # Support base function needed to build Divine enviroment and classes corresponding to DSL structs
6
+ #
3
7
  class JavaHelperMethods < BabelHelperMethods
8
+
9
+ #
10
+ # Return the header comment
11
+ #
4
12
  def get_header_comment
5
13
  get_header_comment_text.map do |s|
6
14
  "// #{s}"
7
15
  end.join("\n")
8
16
  end
9
17
 
18
+ ##
19
+ # Generate the base Divine Java Class
20
+ # that contains the main methods:
21
+ # * serialize
22
+ # * serialize Internal
23
+ # * deserialize
24
+ # * Read Methods
25
+ # * Write Methods
26
+
10
27
  def java_base_class_template_str
11
28
  <<EOS
12
- abstract class BabelBase <%= toplevel_class %> {
29
+ abstract class Divine <%= toplevel_class %> {
13
30
  private static final Charset UTF8 = Charset.forName("UTF-8");
14
31
 
15
32
  public byte[] serialize() throws IOException {
@@ -47,6 +64,17 @@ abstract class BabelBase <%= toplevel_class %> {
47
64
  return (readInt32(data) << 32) | (readInt32(data) & 0xFFFFFFFFL);
48
65
  }
49
66
 
67
+ protected long readDint63(ByteArrayInputStream data) {
68
+ int b = readInt8(data);
69
+ long val = b & 0x7F;
70
+ while((b >> 7) == 1){
71
+ b = readInt8(data);
72
+ val = val << 7;
73
+ val = val | b & 0x7F;
74
+ }
75
+ return val;
76
+ }
77
+
50
78
  protected boolean readBool(ByteArrayInputStream data) {
51
79
  return readInt8(data) == 1;
52
80
  }
@@ -161,14 +189,30 @@ abstract class BabelBase <%= toplevel_class %> {
161
189
 
162
190
  protected void writeSint64(long v, ByteArrayOutputStream out) {
163
191
  if (v > Long.MAX_VALUE) { // Max 9,223,372,036,854,775,807
164
- raiseError("Too large sInt64 number: " + v + ", Max = " + Integer.MAX_VALUE);
165
- }else if(v < Long.MIN_VALUE){ // Min -9,223,372,036,854,775,807
166
- raiseError("Too small sInt64 number: " + v + ", Min = " + Integer.MIN_VALUE);
192
+ raiseError("Too large sInt64 number: " + v + ", Max = " + Long.MAX_VALUE);
193
+ }else if(v < Long.MIN_VALUE){ // Min -9,223,372,036,854,775,808
194
+ raiseError("Too small sInt64 number: " + v + ", Min = " + Long.MIN_VALUE);
167
195
  }
168
196
  writeInt32(((v >> 32) & 0xFFFFFFFFL), out);
169
197
  writeInt32( (v & 0xFFFFFFFFL) , out);
170
198
  }
171
199
 
200
+ protected void writeDint63(long v, ByteArrayOutputStream out) {
201
+ if (v > Long.MAX_VALUE) { // Max 9,223,372,036,854,775,807
202
+ raiseError("Too large Dynamic Int64 number: " + v + ", Max = " + Long.MAX_VALUE);
203
+ }else if(v < 0){ // Min 0
204
+ raiseError("Too small Dynamic Int64 number: " + v + ", Min = " + 0);
205
+ }
206
+ String[] bytes = new StringBuffer(Long.toBinaryString(v)).reverse().toString().split("(?<=\\\\G.......)");
207
+
208
+ for (int i = bytes.length - 1; i >= 0; i--){
209
+ String s = bytes[i];
210
+ s += new String(new char[7 - s.length()]).replace("\\\\0", "0") + Math.min(i, 1);
211
+ int t = Integer.parseInt(new StringBuffer(s).reverse().toString(), 2);
212
+ this.writeInt8(t, out);
213
+ }
214
+ }
215
+
172
216
  protected void writeBool(boolean v, ByteArrayOutputStream out) {
173
217
  writeInt8(v ? 1 : 0, out);
174
218
  }
@@ -276,9 +320,13 @@ abstract class BabelBase <%= toplevel_class %> {
276
320
  EOS
277
321
  end
278
322
 
323
+ ##
324
+ # Generate Java Class that corresponding to the struct definition
325
+ # * *Args* :
326
+ # - +sh+ -> Struct Name
279
327
  def java_class_template(sh)
280
328
  code = [
281
- "class #{sh.name} extends BabelBase {",
329
+ "class #{sh.name} extends Divine {",
282
330
  :indent,
283
331
  "",
284
332
 
@@ -354,6 +402,30 @@ EOS
354
402
  format_src(3, 3, code)
355
403
  end
356
404
 
405
+ ##
406
+ # Generate default java data types declaration values corresponding to each DSL types:
407
+ # * DSL Type --> Corresponding Default Java Value
408
+ # * dint63 --> 0 range -> [0 - 9,223,372,036,854,775,807]
409
+ # * 1 byte: range -> [0 - 127]
410
+ # * 2 bytes: range -> [0 - 16,383]
411
+ # * 3 bytes: range -> [0 - 2,097,151]
412
+ # * 4 bytes: range -> [0 - 268,435,455]
413
+ # * 5 bytes: range -> [0 - 34,359,738,367]
414
+ # * 6 bytes: range -> [0 - 4,398,046,511,103]
415
+ # * 7 bytes: range -> [0 - 562,949,953,421,311]
416
+ # * 8 bytes: range -> [0 - 72,057,594,037,927,935]
417
+ # * 9 bytes: range -> [0 - 9,223,372,036,854,775,807]
418
+ # * int8 --> 0 Range -> [0 - 255]
419
+ # * int16 --> 0 Range -> [0 - 65535]
420
+ # * int32 --> 0L Range -> [0 - 4.294.967.295]
421
+ # * sint32 --> 0 Range -> [-2.147.483.648 - 2.147.483.647]
422
+ # * sint64 --> 0L Range -> [-9.223.372.036.854.775.808, 9.223.372.036.854.775.807]
423
+ # * string --> ""
424
+ # * ip_number--> ""
425
+ # * binary --> new Byte[0]
426
+ # * short_binary --> new Byte[0]
427
+ # * list --> new ArrayList<type>()
428
+ # * map --> new HashMap<keyType, valueType>()
357
429
 
358
430
  def java_get_empty_declaration(types, is_reference_type = false)
359
431
  if types.respond_to? :referenced_types
@@ -378,7 +450,7 @@ EOS
378
450
  is_reference_type ? "new Byte[0]" : "new byte[0]"
379
451
  when :int8, :int16, :sint32
380
452
  "0"
381
- when :int32, :sint64
453
+ when :int32, :sint64, :dint63
382
454
  "0L"
383
455
  when :string, :ip_number
384
456
  "\"\""
@@ -391,7 +463,23 @@ EOS
391
463
  end
392
464
  end
393
465
  end
394
-
466
+
467
+ ##
468
+ # Generate java data types declaration corresponding to each DSL type
469
+ # * DSL Type --> Corresponding Java Type
470
+ # * int8 --> int
471
+ # * int16 --> int
472
+ # * sint32 --> int
473
+ # * int32 --> long
474
+ # * sint64 --> long
475
+ # * dint63 --> long
476
+ # * string --> String
477
+ # * ip_number--> String
478
+ # * binary --> Byte[]
479
+ # * short_binary --> Byte[]
480
+ # * list --> ArrayList<type>
481
+ # * map --> HashMap<keyType, valueType>
482
+
395
483
  def java_get_type_declaration(types, is_reference_type = false)
396
484
  if types.respond_to? :referenced_types
397
485
  java_get_type_declaration(types.referenced_types, is_reference_type)
@@ -418,7 +506,7 @@ EOS
418
506
  is_reference_type ? "Byte[]" : "byte[]"
419
507
  when :int8, :int16, :sint32
420
508
  is_reference_type ? "Integer" : "int"
421
- when :int32, :sint64
509
+ when :int32, :sint64, :dint63
422
510
  is_reference_type ? "Long" : "long"
423
511
  when :string, :ip_number
424
512
  "String"
@@ -431,7 +519,12 @@ EOS
431
519
  end
432
520
  end
433
521
  end
434
-
522
+
523
+ ##
524
+ # Generate the way of serializing different DSL types
525
+ # * *Args* :
526
+ # - +var+ -> variable name
527
+ # - +types+ -> variable type
435
528
  def java_serialize_internal(var, types)
436
529
  if types.respond_to? :first
437
530
  case types.first
@@ -476,6 +569,11 @@ EOS
476
569
  end
477
570
  end
478
571
 
572
+ ##
573
+ # Generate the way of deserializing different DSL types
574
+ # * *Args* :
575
+ # - +var+ -> variable name
576
+ # - +types+ -> variable type
479
577
  def java_deserialize_internal(var, types)
480
578
  if types.respond_to? :first
481
579
  case types.first
@@ -531,8 +629,16 @@ EOS
531
629
  end
532
630
  end
533
631
 
534
-
632
+ ##
633
+ # Responsible for generating Divine and structs classes
634
+ #
535
635
  class JavaGenerator < JavaHelperMethods
636
+
637
+ ##
638
+ # Generate Java class(es)
639
+ # * *Args* :
640
+ # - +structs+ -> Dictionary of structs
641
+ # - +opts+ -> Dictionary that contains generation params [file, debug, package, parent_class, target_dir]
536
642
  def generate_code(structs, opts)
537
643
  $debug_java = true if opts[:debug]
538
644
  base_template = Erubis::Eruby.new(java_base_class_template_str)
@@ -548,7 +654,7 @@ EOS
548
654
  toplevel = opts[:parent_class] || nil
549
655
  toplevel = " extends #{toplevel}" if toplevel
550
656
  if opts[:package]
551
- res = [{file: "BabelBase.java", src: "#{java_get_begin_module(opts)}public #{base_template.result({ toplevel_class: toplevel })}"}]
657
+ res = [{file: "Divine.java", src: "#{java_get_begin_module(opts)}public #{base_template.result({ toplevel_class: toplevel })}"}]
552
658
  for cls in src
553
659
  res << {file: cls.match(/class (.*) extends/)[1]+".java", src: "#{java_get_begin_module(opts)}public #{cls}"}
554
660
  end
@@ -557,7 +663,11 @@ EOS
557
663
  return [{file: opts[:file], src: "#{java_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}"}]
558
664
  end
559
665
  end
560
-
666
+ ##
667
+ # Build package name and list of imports
668
+ # * *Args* :
669
+ # - +opts+ -> Dictionary that contains package name in key 'package'
670
+ #
561
671
  def java_get_begin_module(opts)
562
672
  str = "#{get_header_comment}\n\n"
563
673
  str << "package #{opts[:package]};" if opts[:package]
@@ -565,7 +675,9 @@ EOS
565
675
  str << "\n\n"
566
676
  return str
567
677
  end
568
-
678
+ ##
679
+ # Generate list of imports needed in generated java classes
680
+ #
569
681
  def get_java_imports
570
682
  [
571
683
  "java.io.ByteArrayInputStream",
@@ -6,14 +6,27 @@
6
6
 
7
7
  module Divine
8
8
  $debug_javascript = false
9
-
9
+ ##
10
+ # * +JS Helper+ :
11
+ # Support base function needed to build base divine functions and DSL structs
12
+ #
10
13
  class JavascriptHelperMethods < BabelHelperMethods
14
+
15
+ #
16
+ # Return the header comment
17
+ #
11
18
  def get_header_comment
12
19
  get_header_comment_text.map do |s|
13
20
  "// #{s}"
14
21
  end.join("\n")
15
22
  end
16
-
23
+ ##
24
+ # Generate the base functions of:
25
+ # * serialize
26
+ # * deserialize
27
+ # * Read Methods
28
+ # * Write Methods
29
+
17
30
  def javascript_base_class_template_str
18
31
  <<EOS
19
32
  // ------------------------------------------------------------ DivineDataReader
@@ -114,6 +127,29 @@ DivineHelper.prototype.read_sint64 = function (data) {
114
127
  }
115
128
  }
116
129
 
130
+ DivineHelper.prototype.read_dint63 = function (data) {
131
+ var byte = this.read_int8(data)
132
+ var part1 = part2 = ""; // To hold first 32-bit and second 32-bit respectively
133
+ var bin = byte & 0x7F; // tmp To hold binary string
134
+ var numBytes = 1;
135
+ while ((byte >> 7) == 1) {
136
+ byte = this.read_int8(data)
137
+ bin = bin << 7
138
+ bin = bin | byte & 0x7F
139
+ numBytes ++;
140
+ if (numBytes == 4 && (byte >> 7) == 1){
141
+ part1 = bin.toString(2);
142
+ bin = 1; // To avoid unshifting of zero
143
+ }
144
+ }
145
+ bin = bin.toString(2);
146
+ if (bin.length > 1 && part1 != "")
147
+ bin = bin.substr(1, bin.length);
148
+ part2 = bin;
149
+ var val = parseInt(part1 + part2, 2);
150
+ return val;
151
+ }
152
+
117
153
  DivineHelper.prototype.read_binary = function (data) {
118
154
  return data.read(this.read_int32(data));
119
155
  };
@@ -230,6 +266,23 @@ DivineHelper.prototype.write_sint64 = function (v, out) {
230
266
  this.write_int32(parseInt(part2, 2), out);
231
267
  }
232
268
 
269
+ DivineHelper.prototype.write_dint63 = function (v, out) {
270
+ var max = Math.pow(2, 53) - 1;
271
+ var min = 0;
272
+ if (v > max) // Max 9,007,199,254,740,991
273
+ this.raise_error("Too large Dynamic Int53 number: " + v + ", Max = " + max);
274
+ if (v < min) // Min 0
275
+ this.raise_error("Too small Dynamic Int53 number: " + v + ", Min = " + min);
276
+
277
+ bytes = v.toString(2).split("").reverse().join("").split(/(.{7})/).filter(function(t){if (t != "" ) return true});
278
+ for (var i = bytes.length - 1; i >= 0; i--){
279
+ var bin = bytes[i];
280
+ bin += Array(8 - bin.length).join("0") + Math.min(i,1);
281
+ var val = parseInt(bin.split("").reverse().join(""), 2);
282
+ this.write_int8(val, out);
283
+ }
284
+ }
285
+
233
286
  DivineHelper.prototype.write_bool = function (v, out) {
234
287
  this.write_int8(v ? 1 : 0, out)
235
288
  }
@@ -454,6 +507,11 @@ DivineHelper.prototype.raise_error = function (msg) {
454
507
  EOS
455
508
  end
456
509
 
510
+ ##
511
+ # Generate required functions that corresponding to the struct definition
512
+ # * *Args* :
513
+ # - +sh+ -> Struct Name
514
+
457
515
  def javascript_class_template(sh)
458
516
  code = [
459
517
  "",
@@ -537,6 +595,29 @@ EOS
537
595
  format_src(0, 3, code)
538
596
  end
539
597
 
598
+ ##
599
+ # Generate default JS data types declaration values corresponding to each DSL types:
600
+ # * DSL Type --> Corresponding Default JS Value
601
+ # * dint63 --> 0 range -> [0 - 9.007.199.254.740.991]
602
+ # * 1 byte: range -> [0 - 127]
603
+ # * 2 bytes: range -> [0 - 16,383]
604
+ # * 3 bytes: range -> [0 - 2,097,151]
605
+ # * 4 bytes: range -> [0 - 268,435,455]
606
+ # * 5 bytes: range -> [0 - 34,359,738,367]
607
+ # * 6 bytes: range -> [0 - 4,398,046,511,103]
608
+ # * 7 bytes: range -> [0 - 562,949,953,421,311]
609
+ # * 8 bytes: range -> [0 - 9.007.199.254.740.991] (limited by 53-bit)
610
+ # * int8 --> 0 Range -> [0 - 255]
611
+ # * int16 --> 0 Range -> [0 - 65535]
612
+ # * int32 --> 0 Range -> [0 - 4.294.967.295]
613
+ # * sint32 --> 0 Range -> [-2.147.483.648 - 2.147.483.647]
614
+ # * sint64 --> 0 Range -> [-9.007.199.254.740.992, 9.007.199.254.740.991] (limited by 53-bit)
615
+ # * string --> ""
616
+ # * ip_number--> ""
617
+ # * binary --> []
618
+ # * short_binary --> []
619
+ # * list --> []
620
+ # * map --> {}
540
621
 
541
622
  def javascript_get_empty_declaration(field)
542
623
  case field.type
@@ -544,7 +625,7 @@ EOS
544
625
  "[]"
545
626
  when :map
546
627
  "{}"
547
- when :int8, :int16, :int32, :sint32, :sint64
628
+ when :int8, :int16, :int32, :sint32, :sint64, :dint63
548
629
  "0"
549
630
  when :string, :ip_number
550
631
  "\"\""
@@ -553,6 +634,12 @@ EOS
553
634
  end
554
635
  end
555
636
 
637
+ ##
638
+ # Generate the way of serializing different DSL types
639
+ # * *Args* :
640
+ # - +var+ -> variable name
641
+ # - +types+ -> variable type
642
+
556
643
  def javascript_serialize_internal(var, types)
557
644
  if types.respond_to? :first
558
645
  case types.first
@@ -600,6 +687,12 @@ EOS
600
687
  end
601
688
  end
602
689
 
690
+ ##
691
+ # Generate the way of deserializing different DSL types
692
+ # * *Args* :
693
+ # - +var+ -> variable name
694
+ # - +types+ -> variable type
695
+
603
696
  def javascript_deserialize_internal(var, types)
604
697
  if types.respond_to? :first
605
698
  case types.first
@@ -656,8 +749,18 @@ EOS
656
749
  end
657
750
 
658
751
 
752
+ ##
753
+ # Responsible for generating Divine and structs functions
754
+ #
659
755
 
660
756
  class JavascriptGenerator < JavascriptHelperMethods
757
+
758
+ ##
759
+ # Generate JS Functions
760
+ # * *Args* :
761
+ # - +structs+ -> Dictionary of structs
762
+ # - +opts+ -> Dictionary that contains generation params [file, debug, parent_class, target_dir]
763
+
661
764
  def generate_code(structs, opts)
662
765
  $debug_javascript = true if opts[:debug]
663
766
  base_template = Erubis::Eruby.new(javascript_base_class_template_str)
@@ -674,11 +777,15 @@ EOS
674
777
  toplevel = " < #{toplevel}" if toplevel
675
778
  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)}"}]
676
779
  end
677
-
780
+
781
+ #
782
+ # Build Header Comments
783
+ #
678
784
  def javascript_get_begin_module(opts)
679
785
  "#{get_header_comment}\n\n"
680
786
  end
681
787
 
788
+ # Do nothing
682
789
  def javascript_get_end_module(opts)
683
790
  nil
684
791
  end
@@ -1,15 +1,32 @@
1
1
  module Divine
2
2
 
3
+ ##
4
+ # * +Ruby Helper+ :
5
+ # Support base function needed to build Divine enviroment and classes corresponding to DSL structs
6
+ #
3
7
  class RubyHelperMethods < BabelHelperMethods
8
+
9
+ #
10
+ # Return the header comment
11
+ #
4
12
  def get_header_comment
5
13
  get_header_comment_text.map do |s|
6
14
  "# #{s}"
7
15
  end.join("\n")
8
16
  end
9
17
 
18
+ ##
19
+ # Generate the base Divine Ruby Class
20
+ # that contains the main methods:
21
+ # * serialize
22
+ # * serialize Internal
23
+ # * deserialize
24
+ # * Read Methods
25
+ # * Write Methods
26
+
10
27
  def ruby_base_class_template_str
11
28
  %q{
12
- class BabelBase<%= toplevel_class %>
29
+ class Divine<%= toplevel_class %>
13
30
  public
14
31
  def serialize
15
32
  out = []
@@ -53,6 +70,17 @@ module Divine
53
70
  return num
54
71
  end
55
72
 
73
+ def read_dint63(data)
74
+ byte = read_int8(data)
75
+ val = byte & 0x7F
76
+ while (byte >> 7) == 1
77
+ byte = read_int8(data)
78
+ val = val << 7
79
+ val = val | byte & 0x7F
80
+ end
81
+ val
82
+ end
83
+
56
84
  def read_bool(data)
57
85
  read_int8(data) == 1
58
86
  end
@@ -145,12 +173,26 @@ module Divine
145
173
  v = v.to_i
146
174
  max = (2** (64 - 1)) - 1
147
175
  min = (2** (64 - 1) ) - (2** 64)
148
- raise_error "Too large Sint32 number: #{v} , Max = #{max}" if v > max # Max 2.147.483.647
149
- raise_error "Too small sInt32 number: #{v} , Min = #{min}" if v < min # Min -2.147.483.648
176
+ raise_error "Too large Sint64 number: #{v} , Max = #{max}" if v > max # Max 9.223.372.036.854.775.807
177
+ raise_error "Too small sInt64 number: #{v} , Min = #{min}" if v < min # Min -9.223.372.036.854.775.808
150
178
  write_int32( v >> 32 & 0xFFFFFFFF, out)
151
179
  write_int32( v & 0xFFFFFFFF, out)
152
180
  end
153
181
 
182
+ def write_dint63(v, out)
183
+ v = v.to_i
184
+ max = (2** (64 - 1)) - 1
185
+ min = 0
186
+ raise_error "Too large Dynamic int63 number: #{v} , Max = #{max}" if v > max # Max 9.223.372.036.854.775.807
187
+ raise_error "Too small Dynamic int63 number: #{v} , Min = #{min}" if v < min # Min 0
188
+
189
+ bytes = v.to_s(2).reverse.split(/([01]{7})/).reject{ |t| t == ""}.each_with_index.map{ |t, i| t = t + "0"*(7-t.length) + [i,1].min.to_s}
190
+ bytes.reverse.map{ |t|
191
+ val = t.reverse.to_i 2
192
+ write_int8(val, out)
193
+ }
194
+ end
195
+
154
196
  def write_bool(v, out)
155
197
  write_int8(v ? 1 : 0, out)
156
198
  end
@@ -279,10 +321,14 @@ module Divine
279
321
  end
280
322
  }
281
323
  end
324
+ ##
325
+ # Generate Ruby Class that corresponding to the struct definition
326
+ # * *Args* :
327
+ # - +sh+ -> Struct Name
282
328
 
283
329
  def ruby_class_template(sh)
284
330
  code = [
285
- "class #{sh.name} < BabelBase",
331
+ "class #{sh.name} < Divine",
286
332
  :indent,
287
333
  "",
288
334
 
@@ -364,7 +410,30 @@ module Divine
364
410
  ]
365
411
  format_src(0, 3, code)
366
412
  end
367
-
413
+ ##
414
+ # Generate default Ruby data types declaration values corresponding to each DSL types:
415
+ # * DSL Type --> Corresponding Default Ruby Value
416
+ # * dint63 --> 0 range -> [0 - 9,223,372,036,854,775,807]
417
+ # * 1 byte: range -> [0 - 127]
418
+ # * 2 bytes: range -> [0 - 16,383]
419
+ # * 3 bytes: range -> [0 - 2,097,151]
420
+ # * 4 bytes: range -> [0 - 268,435,455]
421
+ # * 5 bytes: range -> [0 - 34,359,738,367]
422
+ # * 6 bytes: range -> [0 - 4,398,046,511,103]
423
+ # * 7 bytes: range -> [0 - 562,949,953,421,311]
424
+ # * 8 bytes: range -> [0 - 72,057,594,037,927,935]
425
+ # * 9 bytes: range -> [0 - 9,223,372,036,854,775,807]
426
+ # * int8 --> 0 Range -> [0 - 255]
427
+ # * int16 --> 0 Range -> [0 - 65535]
428
+ # * int32 --> 0 Range -> [0 - 4.294.967.295]
429
+ # * sint32 --> 0 Range -> [-2.147.483.648 - 2.147.483.647]
430
+ # * sint64 --> 0 Range -> [-9.223.372.036.854.775.808, 9.223.372.036.854.775.807]
431
+ # * string --> ""
432
+ # * ip_number--> ""
433
+ # * binary --> []
434
+ # * short_binary --> []
435
+ # * list --> []
436
+ # * map --> {}
368
437
 
369
438
  def ruby_get_empty_declaration(field)
370
439
  case field.type
@@ -372,7 +441,7 @@ module Divine
372
441
  "[]"
373
442
  when :map
374
443
  "{}"
375
- when :int8, :int16, :int32, :sint32, :sint64
444
+ when :dint63, :int8, :int16, :int32, :sint32, :sint64
376
445
  "0"
377
446
  when :string, :ip_number
378
447
  "\"\""
@@ -381,6 +450,12 @@ module Divine
381
450
  end
382
451
  end
383
452
 
453
+ ##
454
+ # Generate the way of serializing different DSL types
455
+ # * *Args* :
456
+ # - +var+ -> variable name
457
+ # - +types+ -> variable type
458
+
384
459
  def ruby_serialize_internal(var, types)
385
460
  if types.respond_to? :first
386
461
  case types.first
@@ -422,6 +497,12 @@ module Divine
422
497
  end
423
498
  end
424
499
 
500
+ ##
501
+ # Generate the way of deserializing different DSL types
502
+ # * *Args* :
503
+ # - +var+ -> variable name
504
+ # - +types+ -> variable type
505
+
425
506
  def ruby_deserialize_internal(var, types)
426
507
  if types.respond_to? :first
427
508
  case types.first
@@ -476,10 +557,17 @@ module Divine
476
557
  end
477
558
 
478
559
 
479
-
560
+ ##
561
+ # Responsible for generating Divine and structs classes
562
+ #
480
563
  class RubyGenerator < RubyHelperMethods
481
564
  @debug = true
482
-
565
+ ##
566
+ # Generate Ruby class(es)
567
+ # * *Args* :
568
+ # - +structs+ -> Dictionary of structs
569
+ # - +opts+ -> Dictionary that contains generation params [file, module, parent_class, target_dir]
570
+
483
571
  def generate_code(structs, opts)
484
572
  base_template = Erubis::Eruby.new(ruby_base_class_template_str)
485
573
  keys = structs.keys.sort
@@ -496,6 +584,11 @@ module Divine
496
584
  return [{file: opts[:file], src: "#{get_header_comment}\n#{ruby_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel, this: self })}\n\n#{src.join("\n\n")}#{ruby_get_end_module(opts)}"}]
497
585
  end
498
586
 
587
+ ##
588
+ # Build module name
589
+ # * *Args* :
590
+ # - +opts+ -> Dictionary contains module name in key module
591
+
499
592
  def ruby_get_begin_module(opts)
500
593
  if opts[:module]
501
594
  "module #{opts[:module]}\n\n"
@@ -503,7 +596,8 @@ module Divine
503
596
  nil
504
597
  end
505
598
  end
506
-
599
+ ##
600
+ # Ending the module
507
601
  def ruby_get_end_module(opts)
508
602
  if opts[:module]
509
603
  "\n\nend\n"