cauterize 0.0.1.pre12 → 0.0.1.pre13
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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/example/Cauterize +0 -2
- data/lib/cauterize/builders/c/buildable.rb +7 -0
- data/lib/cauterize/builders/c/builtin.rb +4 -0
- data/lib/cauterize/builders/c/composite.rb +8 -0
- data/lib/cauterize/builders/c/enumeration.rb +8 -4
- data/lib/cauterize/builders/c/fixed_array.rb +11 -2
- data/lib/cauterize/builders/c/group.rb +26 -1
- data/lib/cauterize/builders/c/scalar.rb +4 -0
- data/lib/cauterize/builders/c/variable_array.rb +17 -3
- data/lib/cauterize/builders/cs/builtin.rb +1 -1
- data/lib/cauterize/builders/cs/fixed_array.rb +3 -1
- data/lib/cauterize/builders/ruby/builtin.rb +1 -1
- data/lib/cauterize/builders/ruby/composite.rb +10 -7
- data/lib/cauterize/builders/ruby/enumeration.rb +9 -9
- data/lib/cauterize/builders/ruby/fixed_array.rb +4 -4
- data/lib/cauterize/builders/ruby/group.rb +9 -9
- data/lib/cauterize/builders/ruby/scalar.rb +3 -3
- data/lib/cauterize/builders/ruby/variable_array.rb +5 -5
- data/lib/cauterize/c_builder.rb +6 -0
- data/lib/cauterize/enumeration.rb +4 -14
- data/lib/cauterize/representation.rb +32 -0
- data/lib/cauterize/ruby_builder.rb +7 -5
- data/lib/cauterize/variable_array.rb +3 -12
- data/lib/cauterize/version.rb +1 -1
- data/spec/base_type_spec.rb +2 -2
- data/spec/builders/c/group_spec.rb +21 -0
- data/spec/builders/c/variable_array_spec.rb +2 -4
- data/spec/builders/cs/fixed_array_spec.rb +2 -1
- data/spec/builders/cs/variable_array_spec.rb +0 -1
- data/spec/c_builder_spec.rb +22 -2
- data/spec/cs_builder_spec.rb +0 -2
- data/spec/doc_builder_spec.rb +0 -2
- data/spec/ruby_builder_spec.rb +5 -2
- data/spec/ruby_generated_spec.rb +735 -0
- data/spec/support/spec_sample_model.rb +1 -3
- data/spec/variable_array_spec.rb +5 -19
- data/support/cs/src/CauterizeFixedArrayFormatter.cs +27 -9
- data/support/cs/src/CauterizeVariableArrayFormatter.cs +28 -11
- data/support/ruby/src/cauterize_ruby_baseclasses.rb +297 -176
- data/support/ruby/src/cauterize_ruby_builtins.rb +121 -95
- metadata +25 -39
@@ -17,7 +17,6 @@ module Cauterize
|
|
17
17
|
end
|
18
18
|
|
19
19
|
Cauterize.variable_array(:int8_list) do |a|
|
20
|
-
a.size_type :uint8
|
21
20
|
a.array_type :int8
|
22
21
|
a.array_size 200
|
23
22
|
end
|
@@ -53,9 +52,8 @@ module Cauterize
|
|
53
52
|
end
|
54
53
|
|
55
54
|
Cauterize.variable_array(:int8_list) do |a|
|
56
|
-
a.size_type :uint8
|
57
55
|
a.array_type :int8
|
58
|
-
a.array_size
|
56
|
+
a.array_size 2000
|
59
57
|
end
|
60
58
|
|
61
59
|
Cauterize.composite(:two_things) do |t|
|
data/spec/variable_array_spec.rb
CHANGED
@@ -61,26 +61,12 @@ module Cauterize
|
|
61
61
|
end
|
62
62
|
|
63
63
|
describe :size_type do
|
64
|
-
it "
|
65
|
-
|
66
|
-
@a.size_type :
|
67
|
-
@a.instance_variable_get(:@size_type).name.should == :uint16_t
|
68
|
-
end
|
69
|
-
|
70
|
-
it "raises an error if the type doesn't eixst" do
|
71
|
-
lambda { @a.size_type :uintLOL_t }.should raise_error /does not correspond to a type/
|
72
|
-
end
|
64
|
+
it "determines the type used to encode the array size" do
|
65
|
+
@a.array_size 30000
|
66
|
+
@a.size_type.name.should == :uint16
|
73
67
|
|
74
|
-
|
75
|
-
|
76
|
-
Cauterize.enumeration(:lol)
|
77
|
-
lambda { @a.size_type :lol }.should raise_error /is not a built-in or scalar/
|
78
|
-
end
|
79
|
-
|
80
|
-
it "is the defined type if no argument is passed" do
|
81
|
-
s = Cauterize.scalar(:uint32_t)
|
82
|
-
@a.size_type :uint32_t
|
83
|
-
@a.size_type.should be s
|
68
|
+
@a.array_size 10
|
69
|
+
@a.size_type.name.should == :uint8
|
84
70
|
end
|
85
71
|
end
|
86
72
|
end
|
@@ -11,16 +11,27 @@ namespace Cauterize
|
|
11
11
|
}
|
12
12
|
public override object Deserialize(Stream serializationStream, Type t)
|
13
13
|
{
|
14
|
-
var ret = t.GetConstructor(new Type[] {}).Invoke(new object[] {});
|
15
14
|
var arrayField = t.BaseType.GetField("_data", BindingFlags.NonPublic | BindingFlags.Instance);
|
16
|
-
var array = (Array)arrayField.GetValue(ret);
|
17
15
|
var arrayType = arrayField.FieldType.GetElementType();
|
18
|
-
|
19
|
-
for (var i = 0; i < array.Length; i++)
|
16
|
+
if (arrayType == typeof (Byte))
|
20
17
|
{
|
21
|
-
|
18
|
+
var arraySize = (int) t.GetField("MySize").GetValue(null);
|
19
|
+
var arrayData = new byte[arraySize];
|
20
|
+
serializationStream.Read(arrayData, 0, arraySize);
|
21
|
+
var ret = t.GetConstructor(new Type[] {typeof (Byte[])}).Invoke(new object[] {arrayData});
|
22
|
+
return ret;
|
23
|
+
}
|
24
|
+
else
|
25
|
+
{
|
26
|
+
var ret = t.GetConstructor(new Type[] {}).Invoke(new object[] {});
|
27
|
+
var array = (Array)arrayField.GetValue(ret);
|
28
|
+
var subFormatter = _typeFormatterFactory.GetFormatter(arrayType);
|
29
|
+
for (var i = 0; i < array.Length; i++)
|
30
|
+
{
|
31
|
+
array.SetValue(subFormatter.Deserialize(serializationStream, arrayType), i);
|
32
|
+
}
|
33
|
+
return ret;
|
22
34
|
}
|
23
|
-
return ret;
|
24
35
|
}
|
25
36
|
|
26
37
|
public override void Serialize(Stream serializationStream, object obj)
|
@@ -29,10 +40,17 @@ namespace Cauterize
|
|
29
40
|
var arrayField = t.BaseType.GetField("_data", BindingFlags.NonPublic | BindingFlags.Instance);
|
30
41
|
var array = (Array)arrayField.GetValue(obj);
|
31
42
|
var arrayType = arrayField.FieldType.GetElementType();
|
32
|
-
|
33
|
-
|
43
|
+
if (arrayType == typeof (Byte))
|
44
|
+
{
|
45
|
+
serializationStream.Write((byte[]) array, 0, array.Length);
|
46
|
+
}
|
47
|
+
else
|
34
48
|
{
|
35
|
-
subFormatter
|
49
|
+
var subFormatter = _typeFormatterFactory.GetFormatter(arrayType);
|
50
|
+
for (var i = 0; i < array.Length; i++)
|
51
|
+
{
|
52
|
+
subFormatter.Serialize(serializationStream, array.GetValue(i));
|
53
|
+
}
|
36
54
|
}
|
37
55
|
}
|
38
56
|
}
|
@@ -14,20 +14,30 @@ namespace Cauterize
|
|
14
14
|
|
15
15
|
public override object Deserialize(Stream serializationStream, Type t)
|
16
16
|
{
|
17
|
+
var arrayField = t.BaseType.GetField("_data", BindingFlags.NonPublic | BindingFlags.Instance);
|
18
|
+
var arrayType = arrayField.FieldType.GetElementType();
|
17
19
|
var sizeType = (Type) t.GetField("SizeType").GetValue(null);
|
18
20
|
var sizeFormatter = _typeFormatterFactory.GetFormatter(sizeType);
|
19
21
|
var rawSize = sizeFormatter.Deserialize(serializationStream, sizeType);
|
20
22
|
var arraySize = PrimitiveSupport.TypeToInt(rawSize);
|
21
|
-
|
22
|
-
var arrayField = t.BaseType.GetField("_data", BindingFlags.NonPublic | BindingFlags.Instance);
|
23
|
-
var array = (Array)arrayField.GetValue(ret);
|
24
|
-
var arrayType = arrayField.FieldType.GetElementType();
|
25
|
-
var subFormatter = _typeFormatterFactory.GetFormatter(arrayType);
|
26
|
-
for (var i = 0; i < arraySize; i++)
|
23
|
+
if (arrayType == typeof (Byte))
|
27
24
|
{
|
28
|
-
|
25
|
+
var arrayData = new byte[arraySize];
|
26
|
+
serializationStream.Read(arrayData, 0, arraySize);
|
27
|
+
var ret = t.GetConstructor(new Type[] {typeof (Byte[])}).Invoke(new object[] {arrayData});
|
28
|
+
return ret;
|
29
|
+
}
|
30
|
+
else
|
31
|
+
{
|
32
|
+
var ret = t.GetConstructor(new Type[] {typeof (int)}).Invoke(new object[] {arraySize});
|
33
|
+
var array = (Array)arrayField.GetValue(ret);
|
34
|
+
var subFormatter = _typeFormatterFactory.GetFormatter(arrayType);
|
35
|
+
for (var i = 0; i < arraySize; i++)
|
36
|
+
{
|
37
|
+
array.SetValue(subFormatter.Deserialize(serializationStream, arrayType), i);
|
38
|
+
}
|
39
|
+
return ret;
|
29
40
|
}
|
30
|
-
return ret;
|
31
41
|
}
|
32
42
|
|
33
43
|
public override void Serialize(Stream serializationStream, object obj)
|
@@ -39,10 +49,17 @@ namespace Cauterize
|
|
39
49
|
var sizeFormatter = _typeFormatterFactory.GetFormatter(sizeType);
|
40
50
|
sizeFormatter.Serialize(serializationStream, PrimitiveSupport.IntToType(sizeType, array.Length));
|
41
51
|
var arrayType = arrayField.FieldType.GetElementType();
|
42
|
-
|
43
|
-
|
52
|
+
if (arrayType == typeof (Byte))
|
53
|
+
{
|
54
|
+
serializationStream.Write((byte[])array, 0, array.Length);
|
55
|
+
}
|
56
|
+
else
|
44
57
|
{
|
45
|
-
subFormatter
|
58
|
+
var subFormatter = _typeFormatterFactory.GetFormatter(arrayType);
|
59
|
+
for (var i = 0; i < array.Length; i++)
|
60
|
+
{
|
61
|
+
subFormatter.Serialize(serializationStream, array.GetValue(i));
|
62
|
+
}
|
46
63
|
}
|
47
64
|
}
|
48
65
|
}
|
@@ -1,246 +1,367 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module CauterizeRuby
|
4
|
+
class Data
|
5
|
+
@@specializers = Hash.new { |h, k| k }
|
6
|
+
|
7
|
+
def self.set_specializer(c)
|
8
|
+
@@specializers[self] = c
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.do_construct(x)
|
12
|
+
if x.is_a? Data
|
13
|
+
raise "Invalid Type: was #{x.class}, expected #{self}" if not x.is_a?(self)
|
14
|
+
x
|
15
|
+
else
|
16
|
+
self.new x
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.construct(x)
|
21
|
+
@@specializers[self].do_construct(x)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.unpackio(x)
|
25
|
+
@@specializers[self].do_unpackio(x)
|
26
|
+
end
|
27
|
+
|
28
|
+
def pack
|
29
|
+
x = ""
|
30
|
+
packio(x)
|
7
31
|
x
|
8
|
-
else
|
9
|
-
self.new x
|
10
32
|
end
|
11
|
-
end
|
12
33
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
34
|
+
def self.unpack(x)
|
35
|
+
self.unpackio(StringIO.new(x))
|
36
|
+
end
|
17
37
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@val = val
|
22
|
-
end
|
23
|
-
def to_ruby
|
24
|
-
@val
|
25
|
-
end
|
26
|
-
end
|
38
|
+
def ==(other)
|
39
|
+
(self <=> other) == 0
|
40
|
+
end
|
27
41
|
|
28
|
-
|
29
|
-
|
30
|
-
|
42
|
+
#this promotes 'other' to a cauterize type if it's not one already
|
43
|
+
# this way 'cmp' can always assume 'other' is of the same type
|
44
|
+
def <=>(other)
|
45
|
+
cmp(self.class.construct(other))
|
46
|
+
end
|
31
47
|
end
|
32
48
|
|
33
|
-
|
34
|
-
|
49
|
+
class Builtin < Data
|
50
|
+
def initialize(val)
|
51
|
+
@val = val
|
52
|
+
end
|
53
|
+
def to_ruby
|
54
|
+
@val
|
55
|
+
end
|
56
|
+
# for builtins max_size == min_size
|
57
|
+
def self.min_size() max_size end
|
58
|
+
def num_bytes() self.class::max_size end
|
35
59
|
end
|
36
|
-
end
|
37
60
|
|
38
|
-
class
|
39
|
-
|
40
|
-
|
41
|
-
|
61
|
+
class BuiltinInteger < Builtin
|
62
|
+
def initialize(val)
|
63
|
+
#this will always set @val to a regular ruby Fixnum
|
64
|
+
super(val.to_i)
|
65
|
+
end
|
42
66
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
67
|
+
def to_i
|
68
|
+
@val
|
69
|
+
end
|
47
70
|
|
48
|
-
|
49
|
-
|
50
|
-
|
71
|
+
def to_f
|
72
|
+
@val.to_f
|
73
|
+
end
|
51
74
|
end
|
52
|
-
end
|
53
75
|
|
76
|
+
class BuiltinFloat < Builtin
|
77
|
+
def initialize(val)
|
78
|
+
#this will always set @val to a regular ruby float
|
79
|
+
super(val.to_f)
|
80
|
+
end
|
54
81
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
82
|
+
def to_f
|
83
|
+
@val
|
84
|
+
end
|
59
85
|
|
60
|
-
|
61
|
-
|
86
|
+
def to_i
|
87
|
+
@val.to_i
|
88
|
+
end
|
62
89
|
end
|
63
90
|
|
64
|
-
|
65
|
-
|
91
|
+
class BuiltinBool < Builtin
|
92
|
+
def initialize(val)
|
93
|
+
#this will always set @val to a regular ruby boolean value
|
94
|
+
super((val)? true : false)
|
95
|
+
end
|
66
96
|
end
|
67
97
|
|
68
|
-
def self.unpackio(str)
|
69
|
-
self.new self.builtin.unpackio(str)
|
70
|
-
end
|
71
|
-
end
|
72
98
|
|
73
|
-
class
|
74
|
-
|
75
|
-
|
76
|
-
|
99
|
+
class Scalar < Data
|
100
|
+
attr_reader :builtin
|
101
|
+
def initialize(val)
|
102
|
+
# @builtin is going to be some form of Builtin
|
103
|
+
@builtin = self.class.builtin.construct val
|
104
|
+
raise "#{self.class}: Out of range value: #{@builtin.to_ruby}, for #{self.class}" if not @builtin.in_range(@builtin.to_ruby)
|
105
|
+
end
|
77
106
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
107
|
+
def to_ruby
|
108
|
+
@builtin.to_ruby
|
109
|
+
end
|
82
110
|
|
83
|
-
|
84
|
-
|
111
|
+
def to_i
|
112
|
+
@builtin.to_i
|
113
|
+
end
|
85
114
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
115
|
+
def to_f
|
116
|
+
@builtin.to_f
|
117
|
+
end
|
90
118
|
|
91
|
-
|
92
|
-
|
93
|
-
|
119
|
+
def packio(x)
|
120
|
+
@builtin.packio(x)
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.do_unpackio(str)
|
124
|
+
self.new self.builtin.unpackio(str)
|
125
|
+
end
|
94
126
|
|
95
|
-
|
96
|
-
|
127
|
+
def cmp(other)
|
128
|
+
@builtin <=> other.builtin
|
129
|
+
end
|
130
|
+
|
131
|
+
def num_bytes() @builtin.num_bytes end
|
132
|
+
def self.max_size() builtin::max_size end
|
133
|
+
def self.min_size() builtin::min_size end
|
97
134
|
end
|
98
|
-
end
|
99
135
|
|
136
|
+
class Array < Data
|
100
137
|
|
101
|
-
|
102
|
-
attr_reader :length
|
103
|
-
attr_reader :elems
|
138
|
+
include Enumerable
|
104
139
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
140
|
+
def initialize(elems)
|
141
|
+
if elems.is_a? String
|
142
|
+
# a special case for strings
|
143
|
+
initialize_arr(elems.unpack("C*"))
|
144
|
+
else
|
145
|
+
initialize_arr(elems)
|
146
|
+
end
|
147
|
+
end
|
110
148
|
|
111
|
-
|
112
|
-
|
113
|
-
|
149
|
+
def each
|
150
|
+
elems.each do |e|
|
151
|
+
yield e
|
152
|
+
end
|
153
|
+
end
|
114
154
|
|
115
|
-
|
116
|
-
|
117
|
-
|
155
|
+
def to_ruby
|
156
|
+
@elems.map{|e| e.to_ruby}
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_string
|
160
|
+
to_ruby.to_a.pack("C*")
|
161
|
+
end
|
162
|
+
|
163
|
+
def cmp(other)
|
164
|
+
elems <=> other.elems
|
165
|
+
end
|
118
166
|
end
|
119
|
-
end
|
120
167
|
|
168
|
+
class FixedArray < Array
|
169
|
+
attr_reader :elems
|
121
170
|
|
122
|
-
|
123
|
-
|
171
|
+
def initialize_arr(elems)
|
172
|
+
@elems = elems.map { |e| self.class.elem_type.construct(e) }
|
173
|
+
raise "#{self.class}: Invalid length: #{@elems.length}, expected: #{self.class.length}" if @elems.length != self.class.length
|
174
|
+
end
|
124
175
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
@fields = Hash[field_values.map do |field_name, value|
|
131
|
-
[field_name, self.class.fields[field_name].construct(value)]
|
132
|
-
end]
|
133
|
-
end
|
176
|
+
def packio(x)
|
177
|
+
elems.each do |e|
|
178
|
+
e.packio(x)
|
179
|
+
end
|
180
|
+
end
|
134
181
|
|
135
|
-
|
136
|
-
|
137
|
-
|
182
|
+
def self.do_unpackio(str)
|
183
|
+
self.new (1..self.length).map { self.elem_type.unpackio(str) }
|
184
|
+
end
|
138
185
|
|
139
|
-
|
140
|
-
|
186
|
+
def num_bytes() elems.reduce(0) {|sum, e| sum + e.num_bytes} end
|
187
|
+
def self.max_size() length * elem_type::max_size end
|
188
|
+
def self.min_size() length * elem_type::min_size end
|
141
189
|
end
|
142
190
|
|
143
|
-
def self.unpackio(str)
|
144
|
-
self.new Hash[self.fields.keys.map do |k|
|
145
|
-
[k, self.fields[k].unpackio(str)]
|
146
|
-
end]
|
147
|
-
end
|
148
191
|
|
149
|
-
|
192
|
+
class VariableArray < Array
|
193
|
+
attr_reader :length
|
194
|
+
attr_reader :elems
|
195
|
+
|
196
|
+
def initialize_arr(elems)
|
197
|
+
@elems = elems.map { |e| self.class.elem_type.construct(e) }
|
198
|
+
@length = self.class.size_type.new @elems.length
|
199
|
+
raise "#{self.class}: Invalid length: #{@elems.length}, max length is: #{self.class.max_length}" if @elems.length > self.class.max_length
|
200
|
+
end
|
150
201
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
202
|
+
def packio(x)
|
203
|
+
@length.packio(x)
|
204
|
+
@elems.each do |e|
|
205
|
+
e.packio(x)
|
206
|
+
end
|
156
207
|
end
|
208
|
+
|
209
|
+
def self.do_unpackio(str)
|
210
|
+
length = self.size_type.unpackio(str)
|
211
|
+
self.new (1..length.to_i).map { self.elem_type.unpackio(str) }
|
212
|
+
end
|
213
|
+
|
214
|
+
def num_bytes() length.num_bytes + elems.reduce(0) {|sum, e| sum + e.num_bytes} end
|
215
|
+
def self.max_size() size_type::max_size + (max_length * elem_type::max_size) end
|
216
|
+
def self.min_size() size_type::min_size end
|
157
217
|
end
|
158
|
-
end
|
159
218
|
|
160
219
|
|
161
|
-
class
|
162
|
-
|
220
|
+
class Composite < Data
|
221
|
+
attr_reader :fields
|
163
222
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
223
|
+
def initialize(field_values)
|
224
|
+
missing_keys = self.class.fields.keys - field_values.keys
|
225
|
+
extra_keys = field_values.keys - self.class.fields.keys
|
226
|
+
bad_init = !extra_keys.empty? || !missing_keys.empty?
|
227
|
+
raise "#{self.class}: Invalid initialization params, missing fields: #{missing_keys}, extra fields: #{extra_keys}" if bad_init
|
228
|
+
@fields = Hash[self.class.fields.keys.map do |field_name|
|
229
|
+
[field_name, self.class.fields[field_name].construct(field_values[field_name])]
|
230
|
+
end]
|
231
|
+
end
|
168
232
|
|
169
|
-
|
170
|
-
|
171
|
-
|
233
|
+
def to_ruby
|
234
|
+
Hash[@fields.map{|name, value| [name, value.to_ruby]}]
|
235
|
+
end
|
172
236
|
|
173
|
-
|
237
|
+
def packio(x)
|
238
|
+
@fields.values.each do |v|
|
239
|
+
v.packio(x)
|
240
|
+
end
|
241
|
+
end
|
174
242
|
|
175
|
-
|
176
|
-
|
177
|
-
|
243
|
+
def self.do_unpackio(str)
|
244
|
+
self.new Hash[self.fields.keys.map do |k|
|
245
|
+
[k, self.fields[k].unpackio(str)]
|
246
|
+
end]
|
247
|
+
end
|
178
248
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
249
|
+
def cmp(other)
|
250
|
+
fields.values <=> other.fields.values
|
251
|
+
end
|
252
|
+
|
253
|
+
def num_bytes
|
254
|
+
fields.values.reduce(0) {|sum, v| sum + v.num_bytes}
|
255
|
+
end
|
183
256
|
|
184
|
-
|
185
|
-
|
257
|
+
def self.max_size
|
258
|
+
fields.values.reduce(0) {|sum, v| sum + v::max_size}
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.min_size
|
262
|
+
fields.values.reduce(0) {|sum, v| sum + v::min_size}
|
263
|
+
end
|
186
264
|
end
|
187
|
-
end
|
188
265
|
|
189
266
|
|
190
|
-
class
|
191
|
-
|
192
|
-
attr_reader :data
|
267
|
+
class Enumeration < Data
|
268
|
+
attr_reader :field_name
|
193
269
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
else
|
198
|
-
{ tag: tag_field_name,
|
199
|
-
data: data.to_ruby }
|
270
|
+
def initialize(field_name)
|
271
|
+
raise "#{self.class}: Invalid field name: #{field_name}, Valid field names are: #{self.class.fields.keys}" if not self.class.fields.keys.include?(field_name)
|
272
|
+
@field_name = field_name
|
200
273
|
end
|
201
|
-
end
|
202
274
|
|
203
|
-
|
204
|
-
|
205
|
-
|
275
|
+
def to_ruby
|
276
|
+
@field_name
|
277
|
+
end
|
206
278
|
|
207
|
-
|
208
|
-
self.tag_type.construct((self.tag_prefix + field_name.to_s).to_sym)
|
209
|
-
end
|
279
|
+
def to_i() self.class.fields[@field_name] end
|
210
280
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
t.to_sym
|
215
|
-
end
|
216
|
-
|
217
|
-
def initialize(h)
|
218
|
-
@tag = self.class.tag_from_field_name(h[:tag])
|
281
|
+
def packio(x)
|
282
|
+
self.class.repr_type.construct(self.class.fields[@field_name]).packio(x)
|
283
|
+
end
|
219
284
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
285
|
+
def self.from_int(i)
|
286
|
+
raise "#{self}: Invalid enumeration value: #{i.to_i}" if not self.fields.values.include? i.to_i
|
287
|
+
self.new(self.fields.invert[i.to_i])
|
288
|
+
end
|
289
|
+
|
290
|
+
def self.do_unpackio(str)
|
291
|
+
self.from_int(self.repr_type.unpackio(str).to_i)
|
225
292
|
end
|
226
|
-
end
|
227
293
|
|
228
|
-
|
229
|
-
|
230
|
-
@tag.pack
|
231
|
-
else
|
232
|
-
@tag.pack + @data.pack
|
294
|
+
def cmp(other)
|
295
|
+
to_i <=> other.to_i
|
233
296
|
end
|
297
|
+
|
298
|
+
def num_bytes() self.class.repr_type::max_size end
|
299
|
+
def self.max_size() repr_type::max_size end
|
300
|
+
def self.min_size() repr_type::min_size end
|
234
301
|
end
|
235
302
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
303
|
+
|
304
|
+
class Group < Data
|
305
|
+
attr_reader :tag
|
306
|
+
attr_reader :data
|
307
|
+
|
308
|
+
def to_ruby
|
309
|
+
if data.nil?
|
310
|
+
{ tag: tag_field_name }
|
311
|
+
else
|
312
|
+
{ tag: tag_field_name,
|
313
|
+
data: data.to_ruby }
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def tag_field_name
|
318
|
+
self.class.from_tag_field_name(@tag.field_name)
|
319
|
+
end
|
320
|
+
|
321
|
+
def self.tag_from_field_name(field_name)
|
322
|
+
self.tag_type.construct((self.tag_prefix + field_name.to_s).to_sym)
|
323
|
+
end
|
324
|
+
|
325
|
+
def self.from_tag_field_name(tag_name)
|
326
|
+
t = tag_name.to_s
|
327
|
+
t.slice!(self.tag_prefix)
|
328
|
+
t.to_sym
|
329
|
+
end
|
330
|
+
|
331
|
+
def initialize(h)
|
332
|
+
@tag = self.class.tag_from_field_name(h[:tag])
|
333
|
+
field_class = self.class.fields[tag_field_name]
|
334
|
+
@data = (field_class.nil?) ? nil : field_class.construct(h[:data])
|
335
|
+
end
|
336
|
+
|
337
|
+
def packio(x)
|
338
|
+
@tag.packio(x)
|
339
|
+
@data.packio(x) unless @data.nil?
|
340
|
+
end
|
341
|
+
|
342
|
+
def self.do_unpackio(str)
|
343
|
+
tag = self.tag_type.unpackio(str)
|
344
|
+
field_name = self.from_tag_field_name(tag.field_name)
|
345
|
+
data_type = self.fields[field_name]
|
346
|
+
if data_type.nil?
|
347
|
+
self.new({ tag: field_name })
|
348
|
+
else
|
349
|
+
self.new({ tag: field_name, data: data_type.unpackio(str) })
|
350
|
+
end
|
244
351
|
end
|
352
|
+
|
353
|
+
def cmp(other)
|
354
|
+
r = (tag <=> other.tag)
|
355
|
+
if r == 0
|
356
|
+
data <=> other.data
|
357
|
+
else
|
358
|
+
r
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def num_bytes() tag.num_bytes + ((data.nil?) ? 0 : data.num_bytes) end
|
363
|
+
|
364
|
+
def self.max_size() tag_type::max_size + fields.values.map{|v| (v.nil?) ? 0 : v::max_size}.max end
|
365
|
+
def self.min_size() tag_type::min_size + fields.values.map{|v| (v.nil?) ? 0 : v::min_size}.min end
|
245
366
|
end
|
246
367
|
end
|