divine 0.0.3 → 0.0.4

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 (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"