unageanu-javaclass 0.0.1 → 0.1.1
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.
- data/lib/javaclass/accessflag.rb +278 -278
- data/lib/javaclass/attribute.rb +1058 -1058
- data/lib/javaclass/base.rb +368 -368
- data/lib/javaclass/class.rb +281 -281
- data/lib/javaclass/constant.rb +520 -520
- data/lib/javaclass/member.rb +192 -192
- data/lib/javaclass/reader.rb +445 -445
- data/lib/javaclass.rb +7 -7
- data/sample/class_list.rb +38 -8
- data/sample/create_assert.rb +68 -68
- data/sample/sample.rb +26 -26
- data/sample/type_hierarchy.rb +93 -0
- data/test/test_access_flag.rb +205 -205
- data/test/test_attribute.rb +955 -955
- data/test/test_class.rb +90 -90
- data/test/test_constant.rb +830 -830
- data/test/test_member.rb +282 -282
- metadata +2 -1
data/lib/javaclass/class.rb
CHANGED
@@ -1,282 +1,282 @@
|
|
1
|
-
require "javaclass/base"
|
2
|
-
|
3
|
-
module JavaClass
|
4
|
-
|
5
|
-
#
|
6
|
-
#===クラス
|
7
|
-
#
|
8
|
-
class Class
|
9
|
-
include JavaClass::Base
|
10
|
-
include JavaClass::Converters
|
11
|
-
include JavaClass::Item
|
12
|
-
|
13
|
-
#
|
14
|
-
#=== コンストラクタ
|
15
|
-
#
|
16
|
-
def initialize( )
|
17
|
-
@constant_pool = []
|
18
|
-
@interface_indexs = []
|
19
|
-
@fields = []
|
20
|
-
@methods = []
|
21
|
-
@attributes = {}
|
22
|
-
end
|
23
|
-
|
24
|
-
#
|
25
|
-
#===クラスバージョンを文字列で取得する
|
26
|
-
#<b>戻り値</b>::クラスバージョン
|
27
|
-
#
|
28
|
-
def version
|
29
|
-
@major_version.to_s << "." << @minor_version.to_s
|
30
|
-
end
|
31
|
-
|
32
|
-
#
|
33
|
-
#=== クラス名を取得する。
|
34
|
-
#<b>戻り値</b>::クラス名
|
35
|
-
#
|
36
|
-
def name
|
37
|
-
get_constant(@this_class_index).name
|
38
|
-
end
|
39
|
-
|
40
|
-
#
|
41
|
-
#=== 親クラス名を取得する。
|
42
|
-
#<b>戻り値</b>::親クラス名
|
43
|
-
#
|
44
|
-
def super_class
|
45
|
-
get_constant(@super_class_index).name
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
#=== 実装しているインターフェイス名を配列で取得する。
|
50
|
-
#<b>戻り値</b>::実装しているインターフェイス名の配列
|
51
|
-
#
|
52
|
-
def interfaces
|
53
|
-
@interface_indexs.map {|i| get_constant(i).name }
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
#=== ソースファイルを取得する。
|
58
|
-
#<b>戻り値</b>::ソースファイル
|
59
|
-
#
|
60
|
-
def source_file
|
61
|
-
attributes.key?('SourceFile') ?
|
62
|
-
attributes['SourceFile'].source_file : nil
|
63
|
-
end
|
64
|
-
|
65
|
-
#
|
66
|
-
#=== クラス名を取得する。
|
67
|
-
#<b>戻り値</b>::クラス名
|
68
|
-
#
|
69
|
-
def enclosing_method
|
70
|
-
attributes.key?('EnclosingMethod') ?
|
71
|
-
attributes['EnclosingMethod'] : nil
|
72
|
-
end
|
73
|
-
|
74
|
-
#
|
75
|
-
#=== クラスで利用しているインナークラスを配列で取得する。
|
76
|
-
#<b>戻り値</b>::インナークラスの配列
|
77
|
-
#
|
78
|
-
def inner_classes
|
79
|
-
attributes.key?('InnerClasses') ?
|
80
|
-
attributes['InnerClasses'].classes : []
|
81
|
-
end
|
82
|
-
|
83
|
-
#
|
84
|
-
#===indexのConstantを取得する。
|
85
|
-
#*index::constant_poolでのConstantのインデックス
|
86
|
-
#<b>戻り値</b>::Constant
|
87
|
-
#
|
88
|
-
def get_constant( index )
|
89
|
-
return nil if index == 0
|
90
|
-
return @constant_pool[index]
|
91
|
-
end
|
92
|
-
#
|
93
|
-
#===indexのConstantの値を取得する。
|
94
|
-
#*index::constant_poolでのConstantのインデックス
|
95
|
-
#<b>戻り値</b>::Constantの値
|
96
|
-
#
|
97
|
-
def get_constant_value( index )
|
98
|
-
return nil if index == 0
|
99
|
-
return @constant_pool[index].bytes
|
100
|
-
end
|
101
|
-
#
|
102
|
-
#===indexのConstantの値の文字列表現を取得する。
|
103
|
-
#*index::constant_poolでのConstantのインデックス
|
104
|
-
#<b>戻り値</b>::Constantの値の文字列表現
|
105
|
-
#
|
106
|
-
def get_constant_as_string( index )
|
107
|
-
return nil if index == 0
|
108
|
-
return @constant_pool[index].to_s
|
109
|
-
end
|
110
|
-
#
|
111
|
-
#===同じConstantがなければ追加する。
|
112
|
-
#*constant::Constant
|
113
|
-
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
114
|
-
#
|
115
|
-
def put_constant( constant )
|
116
|
-
index = @constant_pool.index constant
|
117
|
-
if index == nil
|
118
|
-
constant.java_class = self
|
119
|
-
index = @constant_pool.push( constant ).length-1
|
120
|
-
# doubleとlongの場合、次は欠番
|
121
|
-
tag = constant.tag
|
122
|
-
if tag == JavaClass::Constant::CONSTANT_Double \
|
123
|
-
|| tag == JavaClass::Constant::CONSTANT_Long
|
124
|
-
@constant_pool.push( nil )
|
125
|
-
end
|
126
|
-
end
|
127
|
-
return index
|
128
|
-
end
|
129
|
-
|
130
|
-
#
|
131
|
-
#===UTF8Constantがプールになければ追加する。
|
132
|
-
#*value::文字列値
|
133
|
-
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
134
|
-
#
|
135
|
-
def put_utf8_constant( value )
|
136
|
-
put_constant( UTF8Constant.new( nil, Constant::CONSTANT_Utf8, value ))
|
137
|
-
end
|
138
|
-
|
139
|
-
#
|
140
|
-
#===整数型のConstantがプールになければ追加する。
|
141
|
-
#*value::整数値
|
142
|
-
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
143
|
-
#
|
144
|
-
def put_integer_constant( value )
|
145
|
-
put_constant( IntegerConstant.new( nil, Constant::CONSTANT_Integer, value ))
|
146
|
-
end
|
147
|
-
|
148
|
-
#
|
149
|
-
#===整数(Long)型のConstantがプールになければ追加する。
|
150
|
-
#*value::整数値
|
151
|
-
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
152
|
-
#
|
153
|
-
def put_long_constant( value )
|
154
|
-
put_constant( LongConstant.new( nil, Constant::CONSTANT_Long, value ))
|
155
|
-
end
|
156
|
-
|
157
|
-
#
|
158
|
-
#===文字列型のConstantがプールになければ追加する。
|
159
|
-
#*value::文字列値
|
160
|
-
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
161
|
-
#
|
162
|
-
def put_string_constant( value )
|
163
|
-
put_constant( StringConstant.new( nil, Constant::CONSTANT_String,
|
164
|
-
put_utf8_constant( value ) ))
|
165
|
-
end
|
166
|
-
|
167
|
-
|
168
|
-
#
|
169
|
-
#===条件にマッチするメソッドを取得する。
|
170
|
-
#*name::メソッド名
|
171
|
-
#*return_type::戻り値型(省略した場合、戻り値を問わない)
|
172
|
-
#*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
|
173
|
-
#<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
|
174
|
-
#
|
175
|
-
def find_method( name, return_type=nil, parameters=nil )
|
176
|
-
@methods.find {|m|
|
177
|
-
( m.name.eql?( name ) ) \
|
178
|
-
&& ( return_type != nil ? m.return_type.eql?(return_type) : true ) \
|
179
|
-
&& ( parameters != nil ? m.parameters.eql?(parameters) : true )
|
180
|
-
}
|
181
|
-
end
|
182
|
-
|
183
|
-
#
|
184
|
-
#===条件にマッチするフィールドを取得する。
|
185
|
-
#*name::メソッド名
|
186
|
-
#*return_type::戻り値型(省略した場合、戻り値を問わない)
|
187
|
-
#*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
|
188
|
-
#<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
|
189
|
-
#
|
190
|
-
def find_field( name )
|
191
|
-
@fields.find {|f|
|
192
|
-
f.name.eql?( name )
|
193
|
-
}
|
194
|
-
end
|
195
|
-
|
196
|
-
def new_field
|
197
|
-
|
198
|
-
end
|
199
|
-
|
200
|
-
def new_method( name, descriptor )
|
201
|
-
|
202
|
-
end
|
203
|
-
|
204
|
-
|
205
|
-
# クラスの文字列表現を得る
|
206
|
-
def to_s
|
207
|
-
str = "// version #{version}\n"
|
208
|
-
str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
|
209
|
-
str << "// !deprecated!\n" if deprecated?
|
210
|
-
str << "#{attributes['SourceFile'].to_s}\n" if attributes.key? 'SourceFile'
|
211
|
-
str << "#{attributes['EnclosingMethod'].to_s}\n" if attributes.key? 'EnclosingMethod'
|
212
|
-
str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
|
213
|
-
str << "#{access_flag.to_s} #{name} "
|
214
|
-
str << "\nextends #{super_class} " if super_class != nil
|
215
|
-
if interfaces.size > 0
|
216
|
-
interface_names = interfaces.map {|interface| interface }
|
217
|
-
str << "\nimplements #{interface_names.join(', ')} "
|
218
|
-
end
|
219
|
-
str << "{\n\n"
|
220
|
-
inner_classes.each {|inner_class|
|
221
|
-
str << " " << inner_class.to_s << "\n"
|
222
|
-
}
|
223
|
-
str << "\n"
|
224
|
-
@fields.each {|f|
|
225
|
-
str << indent( f.to_s + ";", 4 ) << "\n"
|
226
|
-
}
|
227
|
-
str << "\n"
|
228
|
-
@methods.each {|m|
|
229
|
-
str << indent( m.to_s, 4 ) << "\n"
|
230
|
-
}
|
231
|
-
str << "\n}"
|
232
|
-
end
|
233
|
-
|
234
|
-
def indent( str, size )
|
235
|
-
ind = " "*size
|
236
|
-
ind += str.gsub( /\n/, "\n" << " "*size )
|
237
|
-
end
|
238
|
-
|
239
|
-
def to_bytes()
|
240
|
-
bytes = to_byte( 0xCAFEBABE, 4)
|
241
|
-
bytes += to_byte( @minor_version, 2)
|
242
|
-
bytes += to_byte( @major_version, 2)
|
243
|
-
|
244
|
-
bytes += to_byte( @constant_pool.length, 2)
|
245
|
-
@constant_pool.each {|c|
|
246
|
-
bytes += c.to_bytes() if c != nil
|
247
|
-
}
|
248
|
-
bytes += @access_flag.to_bytes()
|
249
|
-
bytes += to_byte( @this_class_index, 2)
|
250
|
-
bytes += to_byte( @super_class_index, 2)
|
251
|
-
bytes += to_byte( @interface_indexs.length, 2)
|
252
|
-
@interface_indexs.each {|i|
|
253
|
-
bytes += to_byte( i, 2 )
|
254
|
-
}
|
255
|
-
bytes += to_byte( @fields.length, 2)
|
256
|
-
@fields.each {|f|
|
257
|
-
bytes += f.to_bytes()
|
258
|
-
}
|
259
|
-
bytes += to_byte( @methods.length, 2)
|
260
|
-
@methods.each {|m|
|
261
|
-
bytes += m.to_bytes()
|
262
|
-
}
|
263
|
-
bytes += to_byte( @attributes.size, 2)
|
264
|
-
@attributes.keys.sort!.each {|k|
|
265
|
-
bytes += @attributes[k].to_bytes()
|
266
|
-
}
|
267
|
-
return bytes
|
268
|
-
end
|
269
|
-
|
270
|
-
attr :major_version, true
|
271
|
-
attr :minor_version, true
|
272
|
-
attr :constant_pool, true
|
273
|
-
attr :access_flag, true
|
274
|
-
attr :this_class_index, true
|
275
|
-
attr :super_class_index, true
|
276
|
-
attr :interface_indexs, true
|
277
|
-
attr :fields, true
|
278
|
-
attr :methods, true
|
279
|
-
attr :attributes, true
|
280
|
-
end
|
281
|
-
|
1
|
+
require "javaclass/base"
|
2
|
+
|
3
|
+
module JavaClass
|
4
|
+
|
5
|
+
#
|
6
|
+
#===クラス
|
7
|
+
#
|
8
|
+
class Class
|
9
|
+
include JavaClass::Base
|
10
|
+
include JavaClass::Converters
|
11
|
+
include JavaClass::Item
|
12
|
+
|
13
|
+
#
|
14
|
+
#=== コンストラクタ
|
15
|
+
#
|
16
|
+
def initialize( )
|
17
|
+
@constant_pool = []
|
18
|
+
@interface_indexs = []
|
19
|
+
@fields = []
|
20
|
+
@methods = []
|
21
|
+
@attributes = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
#===クラスバージョンを文字列で取得する
|
26
|
+
#<b>戻り値</b>::クラスバージョン
|
27
|
+
#
|
28
|
+
def version
|
29
|
+
@major_version.to_s << "." << @minor_version.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
#=== クラス名を取得する。
|
34
|
+
#<b>戻り値</b>::クラス名
|
35
|
+
#
|
36
|
+
def name
|
37
|
+
get_constant(@this_class_index).name
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
#=== 親クラス名を取得する。
|
42
|
+
#<b>戻り値</b>::親クラス名
|
43
|
+
#
|
44
|
+
def super_class
|
45
|
+
get_constant(@super_class_index).name
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
#=== 実装しているインターフェイス名を配列で取得する。
|
50
|
+
#<b>戻り値</b>::実装しているインターフェイス名の配列
|
51
|
+
#
|
52
|
+
def interfaces
|
53
|
+
@interface_indexs.map {|i| get_constant(i).name }
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
#=== ソースファイルを取得する。
|
58
|
+
#<b>戻り値</b>::ソースファイル
|
59
|
+
#
|
60
|
+
def source_file
|
61
|
+
attributes.key?('SourceFile') ?
|
62
|
+
attributes['SourceFile'].source_file : nil
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
#=== クラス名を取得する。
|
67
|
+
#<b>戻り値</b>::クラス名
|
68
|
+
#
|
69
|
+
def enclosing_method
|
70
|
+
attributes.key?('EnclosingMethod') ?
|
71
|
+
attributes['EnclosingMethod'] : nil
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
#=== クラスで利用しているインナークラスを配列で取得する。
|
76
|
+
#<b>戻り値</b>::インナークラスの配列
|
77
|
+
#
|
78
|
+
def inner_classes
|
79
|
+
attributes.key?('InnerClasses') ?
|
80
|
+
attributes['InnerClasses'].classes : []
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
#===indexのConstantを取得する。
|
85
|
+
#*index::constant_poolでのConstantのインデックス
|
86
|
+
#<b>戻り値</b>::Constant
|
87
|
+
#
|
88
|
+
def get_constant( index )
|
89
|
+
return nil if index == 0
|
90
|
+
return @constant_pool[index]
|
91
|
+
end
|
92
|
+
#
|
93
|
+
#===indexのConstantの値を取得する。
|
94
|
+
#*index::constant_poolでのConstantのインデックス
|
95
|
+
#<b>戻り値</b>::Constantの値
|
96
|
+
#
|
97
|
+
def get_constant_value( index )
|
98
|
+
return nil if index == 0
|
99
|
+
return @constant_pool[index].bytes
|
100
|
+
end
|
101
|
+
#
|
102
|
+
#===indexのConstantの値の文字列表現を取得する。
|
103
|
+
#*index::constant_poolでのConstantのインデックス
|
104
|
+
#<b>戻り値</b>::Constantの値の文字列表現
|
105
|
+
#
|
106
|
+
def get_constant_as_string( index )
|
107
|
+
return nil if index == 0
|
108
|
+
return @constant_pool[index].to_s
|
109
|
+
end
|
110
|
+
#
|
111
|
+
#===同じConstantがなければ追加する。
|
112
|
+
#*constant::Constant
|
113
|
+
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
114
|
+
#
|
115
|
+
def put_constant( constant )
|
116
|
+
index = @constant_pool.index constant
|
117
|
+
if index == nil
|
118
|
+
constant.java_class = self
|
119
|
+
index = @constant_pool.push( constant ).length-1
|
120
|
+
# doubleとlongの場合、次は欠番
|
121
|
+
tag = constant.tag
|
122
|
+
if tag == JavaClass::Constant::CONSTANT_Double \
|
123
|
+
|| tag == JavaClass::Constant::CONSTANT_Long
|
124
|
+
@constant_pool.push( nil )
|
125
|
+
end
|
126
|
+
end
|
127
|
+
return index
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
#===UTF8Constantがプールになければ追加する。
|
132
|
+
#*value::文字列値
|
133
|
+
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
134
|
+
#
|
135
|
+
def put_utf8_constant( value )
|
136
|
+
put_constant( UTF8Constant.new( nil, Constant::CONSTANT_Utf8, value ))
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
#===整数型のConstantがプールになければ追加する。
|
141
|
+
#*value::整数値
|
142
|
+
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
143
|
+
#
|
144
|
+
def put_integer_constant( value )
|
145
|
+
put_constant( IntegerConstant.new( nil, Constant::CONSTANT_Integer, value ))
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
#===整数(Long)型のConstantがプールになければ追加する。
|
150
|
+
#*value::整数値
|
151
|
+
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
152
|
+
#
|
153
|
+
def put_long_constant( value )
|
154
|
+
put_constant( LongConstant.new( nil, Constant::CONSTANT_Long, value ))
|
155
|
+
end
|
156
|
+
|
157
|
+
#
|
158
|
+
#===文字列型のConstantがプールになければ追加する。
|
159
|
+
#*value::文字列値
|
160
|
+
#<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
|
161
|
+
#
|
162
|
+
def put_string_constant( value )
|
163
|
+
put_constant( StringConstant.new( nil, Constant::CONSTANT_String,
|
164
|
+
put_utf8_constant( value ) ))
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
#
|
169
|
+
#===条件にマッチするメソッドを取得する。
|
170
|
+
#*name::メソッド名
|
171
|
+
#*return_type::戻り値型(省略した場合、戻り値を問わない)
|
172
|
+
#*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
|
173
|
+
#<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
|
174
|
+
#
|
175
|
+
def find_method( name, return_type=nil, parameters=nil )
|
176
|
+
@methods.find {|m|
|
177
|
+
( m.name.eql?( name ) ) \
|
178
|
+
&& ( return_type != nil ? m.return_type.eql?(return_type) : true ) \
|
179
|
+
&& ( parameters != nil ? m.parameters.eql?(parameters) : true )
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
#===条件にマッチするフィールドを取得する。
|
185
|
+
#*name::メソッド名
|
186
|
+
#*return_type::戻り値型(省略した場合、戻り値を問わない)
|
187
|
+
#*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
|
188
|
+
#<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
|
189
|
+
#
|
190
|
+
def find_field( name )
|
191
|
+
@fields.find {|f|
|
192
|
+
f.name.eql?( name )
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
def new_field
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
def new_method( name, descriptor )
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
# クラスの文字列表現を得る
|
206
|
+
def to_s
|
207
|
+
str = "// version #{version}\n"
|
208
|
+
str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
|
209
|
+
str << "// !deprecated!\n" if deprecated?
|
210
|
+
str << "#{attributes['SourceFile'].to_s}\n" if attributes.key? 'SourceFile'
|
211
|
+
str << "#{attributes['EnclosingMethod'].to_s}\n" if attributes.key? 'EnclosingMethod'
|
212
|
+
str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
|
213
|
+
str << "#{access_flag.to_s} #{name} "
|
214
|
+
str << "\nextends #{super_class} " if super_class != nil
|
215
|
+
if interfaces.size > 0
|
216
|
+
interface_names = interfaces.map {|interface| interface }
|
217
|
+
str << "\nimplements #{interface_names.join(', ')} "
|
218
|
+
end
|
219
|
+
str << "{\n\n"
|
220
|
+
inner_classes.each {|inner_class|
|
221
|
+
str << " " << inner_class.to_s << "\n"
|
222
|
+
}
|
223
|
+
str << "\n"
|
224
|
+
@fields.each {|f|
|
225
|
+
str << indent( f.to_s + ";", 4 ) << "\n"
|
226
|
+
}
|
227
|
+
str << "\n"
|
228
|
+
@methods.each {|m|
|
229
|
+
str << indent( m.to_s, 4 ) << "\n"
|
230
|
+
}
|
231
|
+
str << "\n}"
|
232
|
+
end
|
233
|
+
|
234
|
+
def indent( str, size )
|
235
|
+
ind = " "*size
|
236
|
+
ind += str.gsub( /\n/, "\n" << " "*size )
|
237
|
+
end
|
238
|
+
|
239
|
+
def to_bytes()
|
240
|
+
bytes = to_byte( 0xCAFEBABE, 4)
|
241
|
+
bytes += to_byte( @minor_version, 2)
|
242
|
+
bytes += to_byte( @major_version, 2)
|
243
|
+
|
244
|
+
bytes += to_byte( @constant_pool.length, 2)
|
245
|
+
@constant_pool.each {|c|
|
246
|
+
bytes += c.to_bytes() if c != nil
|
247
|
+
}
|
248
|
+
bytes += @access_flag.to_bytes()
|
249
|
+
bytes += to_byte( @this_class_index, 2)
|
250
|
+
bytes += to_byte( @super_class_index, 2)
|
251
|
+
bytes += to_byte( @interface_indexs.length, 2)
|
252
|
+
@interface_indexs.each {|i|
|
253
|
+
bytes += to_byte( i, 2 )
|
254
|
+
}
|
255
|
+
bytes += to_byte( @fields.length, 2)
|
256
|
+
@fields.each {|f|
|
257
|
+
bytes += f.to_bytes()
|
258
|
+
}
|
259
|
+
bytes += to_byte( @methods.length, 2)
|
260
|
+
@methods.each {|m|
|
261
|
+
bytes += m.to_bytes()
|
262
|
+
}
|
263
|
+
bytes += to_byte( @attributes.size, 2)
|
264
|
+
@attributes.keys.sort!.each {|k|
|
265
|
+
bytes += @attributes[k].to_bytes()
|
266
|
+
}
|
267
|
+
return bytes
|
268
|
+
end
|
269
|
+
|
270
|
+
attr :major_version, true
|
271
|
+
attr :minor_version, true
|
272
|
+
attr :constant_pool, true
|
273
|
+
attr :access_flag, true
|
274
|
+
attr :this_class_index, true
|
275
|
+
attr :super_class_index, true
|
276
|
+
attr :interface_indexs, true
|
277
|
+
attr :fields, true
|
278
|
+
attr :methods, true
|
279
|
+
attr :attributes, true
|
280
|
+
end
|
281
|
+
|
282
282
|
end
|