javaclass 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.
- data/Rakefile +51 -0
- data/Readme.txt +47 -0
- data/history.txt +29 -0
- data/lib/javaclass/access_flags.rb +44 -0
- data/lib/javaclass/class_magic.rb +27 -0
- data/lib/javaclass/class_version.rb +65 -0
- data/lib/javaclass/constant_pool.rb +85 -0
- data/lib/javaclass/constants/base.rb +31 -0
- data/lib/javaclass/constants/double_reference.rb +81 -0
- data/lib/javaclass/constants/single_reference.rb +58 -0
- data/lib/javaclass/constants/value.rb +114 -0
- data/lib/javaclass/java_class_header.rb +88 -0
- data/lib/javaclass/references.rb +31 -0
- data/lib/javaclass/string_ux.rb +39 -0
- data/lib/javaclass.rb +14 -0
- data/test/data/AccessFlagsTestAbstract.class +0 -0
- data/test/data/AccessFlagsTestAbstract.java +3 -0
- data/test/data/AccessFlagsTestFinal.class +0 -0
- data/test/data/AccessFlagsTestFinal.java +3 -0
- data/test/data/AccessFlagsTestInterface.class +0 -0
- data/test/data/AccessFlagsTestInterface.java +3 -0
- data/test/data/AccessFlagsTestPackage.class +0 -0
- data/test/data/AccessFlagsTestPackage.java +3 -0
- data/test/data/AccessFlagsTestPublic$InnerClass.class +0 -0
- data/test/data/AccessFlagsTestPublic.class +0 -0
- data/test/data/AccessFlagsTestPublic.java +7 -0
- data/test/data/ClassVersionTest.java +1 -0
- data/test/data/ClassVersionTest10.class +0 -0
- data/test/data/ClassVersionTest11.class +0 -0
- data/test/data/ClassVersionTest12.class +0 -0
- data/test/data/ClassVersionTest13.class +0 -0
- data/test/data/ClassVersionTest14.class +0 -0
- data/test/data/ClassVersionTest15.class +0 -0
- data/test/data/ClassVersionTest16.class +0 -0
- data/test/data/ConstantPoolTest.class +0 -0
- data/test/data/ConstantPoolTest.java +20 -0
- data/test/data/makeAccessFlagsTest.bat +9 -0
- data/test/data/makeClassVersionTest.bat +35 -0
- data/test/data/makeConstantPoolTest.bat +6 -0
- data/test/setup.rb +14 -0
- data/test/test_access_flags.rb +53 -0
- data/test/test_base.rb +22 -0
- data/test/test_class_version.rb +59 -0
- data/test/test_constant_pool.rb +90 -0
- data/test/test_java_class_header.rb +30 -0
- data/test/test_references.rb +29 -0
- data/test/test_string_ux.rb +30 -0
- data/test/ts_all_tests.rb +36 -0
- metadata +106 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'javaclass/string_ux'
|
2
|
+
require 'javaclass/class_magic'
|
3
|
+
require 'javaclass/class_version'
|
4
|
+
require 'javaclass/constant_pool'
|
5
|
+
require 'javaclass/references'
|
6
|
+
require 'javaclass/access_flags'
|
7
|
+
|
8
|
+
module JavaClass
|
9
|
+
|
10
|
+
# Provide all information of a Java class file.
|
11
|
+
# Author:: Peter Kofler
|
12
|
+
class JavaClassHeader
|
13
|
+
|
14
|
+
attr_reader :magic
|
15
|
+
attr_reader :version
|
16
|
+
attr_reader :constant_pool
|
17
|
+
attr_reader :access_flags
|
18
|
+
attr_reader :references
|
19
|
+
|
20
|
+
# Create a header with the binary _data_ from the class file.
|
21
|
+
def initialize(data)
|
22
|
+
|
23
|
+
# ClassFile {
|
24
|
+
# u4 magic;
|
25
|
+
# u2 minor_version;
|
26
|
+
# u2 major_version;
|
27
|
+
# u2 constant_pool_count;
|
28
|
+
# cp_info constant_pool[constant_pool_count-1];
|
29
|
+
# u2 access_flags;
|
30
|
+
# u2 this_class;
|
31
|
+
# u2 super_class;
|
32
|
+
# u2 interfaces_count;
|
33
|
+
# u2 interfaces[interfaces_count];
|
34
|
+
# u2 fields_count;
|
35
|
+
# field_info fields[fields_count];
|
36
|
+
# u2 methods_count;
|
37
|
+
# method_info methods[methods_count];
|
38
|
+
# u2 attributes_count;
|
39
|
+
# attribute_info attributes[attributes_count];
|
40
|
+
# }
|
41
|
+
|
42
|
+
@magic = ClassMagic.new(data)
|
43
|
+
@version = ClassVersion.new(data)
|
44
|
+
|
45
|
+
@constant_pool = ConstantPool.new(data)
|
46
|
+
pos = 8 + @constant_pool.size
|
47
|
+
|
48
|
+
@access_flags = AccessFlags.new(data, pos)
|
49
|
+
pos += 2
|
50
|
+
|
51
|
+
idx = data.u2(pos)
|
52
|
+
pos += 2
|
53
|
+
@this_class_idx = idx
|
54
|
+
|
55
|
+
@references = References.new(@constant_pool, @this_class_idx)
|
56
|
+
|
57
|
+
idx = data.u2(pos)
|
58
|
+
pos += 2
|
59
|
+
@super_class_idx = idx
|
60
|
+
end
|
61
|
+
|
62
|
+
# Return the name of this class.
|
63
|
+
def this_class
|
64
|
+
@constant_pool[@this_class_idx].to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return the name of the superclass of this class or +nil+.
|
68
|
+
def super_class
|
69
|
+
if @super_class_idx>0
|
70
|
+
@constant_pool[@super_class_idx].to_s
|
71
|
+
else
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return a debug output of this class that looks similar to +javap+ output.
|
77
|
+
def dump
|
78
|
+
d = []
|
79
|
+
# dump << " SourceFile: \"#{@value}\""
|
80
|
+
# dump << "Compiled from \"#{@value}\""
|
81
|
+
d += @version.dump
|
82
|
+
d += @constant_pool.dump
|
83
|
+
d
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'javaclass/constant_pool'
|
2
|
+
|
3
|
+
module JavaClass
|
4
|
+
|
5
|
+
# Container class for list of all classes, methods and fields referenced by this class.
|
6
|
+
# Author:: Peter Kofler
|
7
|
+
class References
|
8
|
+
|
9
|
+
# Create a references container with the constant _pool_ and skip references to _classidx_ which is the host class itself.
|
10
|
+
def initialize(pool, classidx)
|
11
|
+
@constant_pool = pool
|
12
|
+
@class_idx = classidx
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return the constants referring to fields (Constants::ConstantField).
|
16
|
+
# If _includeown_ is +true+ then fields of this class are returned also.
|
17
|
+
def referenced_fields(includeown=false)
|
18
|
+
@constant_pool.find(ConstantPool::FIELD_TAG).find_all { |field| includeown || field.class_index != @class_idx }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return the constants referring to methods (Constants::ConstantMethod) in classes or interfaces.
|
22
|
+
# If _includeown_ is +true+ then methods of this class are returned also.
|
23
|
+
def referenced_methods(includeown=false)
|
24
|
+
@constant_pool.find(ConstantPool::METHOD_TAG, ConstantPool::INTERFACE_METHOD_TAG).find_all do |method|
|
25
|
+
includeown || method.class_index != @class_idx
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
# Add some +unpack+ helper methods for HI-LO byte order (network byte order) contained in this string.
|
3
|
+
# Author:: Peter Kofler
|
4
|
+
class String
|
5
|
+
|
6
|
+
# Return the _index_'th element as byte.
|
7
|
+
def u1(index=0)
|
8
|
+
self[index]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Return the _index_'th and the next element as unsigned word.
|
12
|
+
def u2(index=0)
|
13
|
+
self[index..index+1].unpack('n')[0]
|
14
|
+
# same as self[index]*256 + self[index+1]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return the _index_'th and the next 3 elements as unsigned dword.
|
18
|
+
def u4(index=0)
|
19
|
+
self[index..index+3].unpack('N')[0]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return the _index_'th and the next 7 elements as unsigned qword.
|
23
|
+
def u8(index=0)
|
24
|
+
u4(index) * 256**4 + u4(index+4)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return the _index_'th and the next 3 elements as single precision float.
|
28
|
+
# See:: http://steve.hollasch.net/cgindex/coding/ieeefloat.html
|
29
|
+
# See:: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/196633
|
30
|
+
def single(index=0)
|
31
|
+
self[index..index+3].unpack('g')[0]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return the _index_'th and the next 7 elements as double precision float.
|
35
|
+
def double(index=0)
|
36
|
+
self[index..index+7].unpack('G')[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/javaclass.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'javaclass/java_class_header'
|
2
|
+
|
3
|
+
# Parse and disassemble Java class files, similar to the +javap+ command.
|
4
|
+
# Author:: Peter Kofler
|
5
|
+
# See:: http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
|
6
|
+
# See:: http://en.wikipedia.org/wiki/Class_(file_format)
|
7
|
+
module JavaClass
|
8
|
+
|
9
|
+
# Read and disassemble the given class called _name_ (full file name).
|
10
|
+
def self.parse(name)
|
11
|
+
JavaClassHeader.new(File.open(name, 'rb') {|io| io.read } )
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
public class ClassVersionTest { }
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
public class ConstantPoolTest implements Runnable {
|
2
|
+
|
3
|
+
// Class - it's own and Object
|
4
|
+
// Field ref (plus String)
|
5
|
+
String stringField = "String field";
|
6
|
+
// Method ref - Object ctor
|
7
|
+
// InterfaceMethod
|
8
|
+
{
|
9
|
+
((Runnable)this).run();
|
10
|
+
}
|
11
|
+
final int intField = 42;
|
12
|
+
float floatField = 3.1415898996736E+22f;
|
13
|
+
long longField = 99999999L;
|
14
|
+
double doubleField = 3.14159265258979E-208;
|
15
|
+
// NameAndType - ctor init
|
16
|
+
// Asciz - classname
|
17
|
+
|
18
|
+
public void run(){}
|
19
|
+
|
20
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
if exist ClassVersionTest*.class del ClassVersionTest*.class
|
2
|
+
|
3
|
+
setlocal
|
4
|
+
|
5
|
+
call profile102
|
6
|
+
javac -classpath %CLASSPATH% ClassVersionTest.java
|
7
|
+
ren ClassVersionTest.class ClassVersionTest10.class
|
8
|
+
|
9
|
+
call profile118
|
10
|
+
javac -classpath %CLASSPATH% ClassVersionTest.java
|
11
|
+
ren ClassVersionTest.class ClassVersionTest11.class
|
12
|
+
|
13
|
+
call profile122
|
14
|
+
javac -target 1.2 ClassVersionTest.java
|
15
|
+
ren ClassVersionTest.class ClassVersionTest12.class
|
16
|
+
|
17
|
+
call profile131
|
18
|
+
javac -target 1.3 ClassVersionTest.java
|
19
|
+
ren ClassVersionTest.class ClassVersionTest13.class
|
20
|
+
|
21
|
+
call profile141
|
22
|
+
javac -target 1.4 ClassVersionTest.java
|
23
|
+
ren ClassVersionTest.class ClassVersionTest14.class
|
24
|
+
|
25
|
+
call profile150
|
26
|
+
javac ClassVersionTest.java
|
27
|
+
ren ClassVersionTest.class ClassVersionTest15.class
|
28
|
+
|
29
|
+
call profile160
|
30
|
+
javac ClassVersionTest.java
|
31
|
+
ren ClassVersionTest.class ClassVersionTest16.class
|
32
|
+
|
33
|
+
endlocal
|
34
|
+
|
35
|
+
pause
|
data/test/setup.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
# add the lib to the load path
|
4
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
+
|
6
|
+
TEST_DATA_PATH = File.join(File.dirname(__FILE__), 'data')
|
7
|
+
|
8
|
+
# Load the binary class data of given _name_ from the test path.
|
9
|
+
def load_class(name)
|
10
|
+
File.open("#{TEST_DATA_PATH}/#{name}.class", 'rb') {|io| io.read }
|
11
|
+
end
|
12
|
+
|
13
|
+
# require 'javaclass'
|
14
|
+
# require File.join(File.dirname(__FILE__), %w[.. lib javaclass])
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/java_class_header'
|
3
|
+
|
4
|
+
module TestJavaClass
|
5
|
+
|
6
|
+
class TestAccessFlags < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@cls = {}
|
10
|
+
%w[Public Package Abstract Interface Final].each do |t|
|
11
|
+
eval("@#{t.downcase} = JavaClass::JavaClassHeader.new(load_class('AccessFlagsTest#{t}')).access_flags")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_accessible_eh
|
16
|
+
assert(@public.accessible?)
|
17
|
+
assert(!@package.accessible?)
|
18
|
+
assert(@abstract.accessible?)
|
19
|
+
assert(@interface.accessible?)
|
20
|
+
assert(@final.accessible?)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_public_eh
|
24
|
+
assert(@public.public?)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_interface_eh
|
28
|
+
assert(!@public.interface?)
|
29
|
+
assert(!@package.interface?)
|
30
|
+
assert(!@abstract.interface?)
|
31
|
+
assert(@interface.interface?)
|
32
|
+
assert(!@final.interface?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_abstract_eh
|
36
|
+
assert(!@public.abstract?)
|
37
|
+
assert(!@package.abstract?)
|
38
|
+
assert(@abstract.abstract?)
|
39
|
+
assert(@interface.abstract?)
|
40
|
+
assert(!@final.abstract?)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_final_eh
|
44
|
+
assert(!@public.final?)
|
45
|
+
assert(!@package.final?)
|
46
|
+
assert(!@abstract.final?)
|
47
|
+
assert(!@interface.final?)
|
48
|
+
assert(@final.final?)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/test/test_base.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/constants/base'
|
3
|
+
|
4
|
+
module TestJavaClass
|
5
|
+
|
6
|
+
class TestConstantBase < Test::Unit::TestCase
|
7
|
+
|
8
|
+
class ConstantClass < JavaClass::Constants::Base;
|
9
|
+
def initialize(name=nil); super(name); end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_name
|
13
|
+
v = ConstantClass.new
|
14
|
+
assert_equal("Class", v.name)
|
15
|
+
|
16
|
+
v = ConstantClass.new("Bubu")
|
17
|
+
assert_equal("Bubu", v.name)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/class_version'
|
3
|
+
|
4
|
+
module TestJavaClass
|
5
|
+
|
6
|
+
class TestClassVersion < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@v = (0..6).collect do |i|
|
10
|
+
JavaClass::ClassVersion.new(load_class("ClassVersionTest1#{i}"))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Assert the list of +v+ against the list of _expectations_ when invoking the given block.
|
15
|
+
def assert_classes(expectations)
|
16
|
+
expectations.values_at.each do |i|
|
17
|
+
assert_equal(expectations[i], yield(@v[i]), "#{i}. element")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_major
|
22
|
+
assert_classes([45, 45, 46, 47, 48, 49, 50]) {|v| v.major}
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_minor
|
26
|
+
assert_classes([3, 3, 0, 0, 0, 0, 0]) {|v| v.minor}
|
27
|
+
assert_equal(3, @v[1].minor) # shouldn't it be > 45.3
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_to_s
|
31
|
+
assert_equal('50.0', @v[6].to_s)
|
32
|
+
assert_equal('45.3', @v[0].to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_dump
|
36
|
+
assert_equal([" minor version: 0", " major version: 50"], @v[6].dump)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_to_f
|
40
|
+
assert_equal(50.0, @v[6].to_f)
|
41
|
+
assert_equal(45.3, @v[0].to_f)
|
42
|
+
|
43
|
+
v = JavaClass::ClassVersion.new("....\000\xff\0002")
|
44
|
+
assert_equal(50.255, v.to_f)
|
45
|
+
|
46
|
+
v = JavaClass::ClassVersion.new("....\xff\xff\0002")
|
47
|
+
assert_equal(50.65535, v.to_f)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_jdk_version
|
51
|
+
assert_classes(%w[1.0 1.0 1.2 1.3 1.4 1.5 1.6]) {|v| v.jdk_version}
|
52
|
+
|
53
|
+
v = JavaClass::ClassVersion.new("....\000\xff\0002")
|
54
|
+
assert_equal('unknown', v.jdk_version)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/constant_pool'
|
3
|
+
|
4
|
+
module TestJavaClass
|
5
|
+
|
6
|
+
class TestConstantPool < Test::Unit::TestCase
|
7
|
+
|
8
|
+
# 1.6.0_11 javap.exe output of test class, only tweaked the float value a bit...
|
9
|
+
JAVAP_OUTPUT = ' Constant pool:
|
10
|
+
const #1 = Method #15.#33; // java/lang/Object."<init>":()V
|
11
|
+
const #2 = String #34; // String field
|
12
|
+
const #3 = Field #14.#35; // ConstantPoolTest.stringField:Ljava/lang/String;
|
13
|
+
const #4 = InterfaceMethod #16.#36; // java/lang/Runnable.run:()V
|
14
|
+
const #5 = Field #14.#37; // ConstantPoolTest.intField:I
|
15
|
+
const #6 = float 3.14158995322368e+022f;
|
16
|
+
const #7 = Field #14.#38; // ConstantPoolTest.floatField:F
|
17
|
+
const #8 = long 99999999l;
|
18
|
+
const #10 = Field #14.#39; // ConstantPoolTest.longField:J
|
19
|
+
const #11 = double 3.14159265258979e-208d;
|
20
|
+
const #13 = Field #14.#40; // ConstantPoolTest.doubleField:D
|
21
|
+
const #14 = class #41; // ConstantPoolTest
|
22
|
+
const #15 = class #42; // java/lang/Object
|
23
|
+
const #16 = class #43; // java/lang/Runnable
|
24
|
+
const #17 = Asciz stringField;
|
25
|
+
const #18 = Asciz Ljava/lang/String;;
|
26
|
+
const #19 = Asciz intField;
|
27
|
+
const #20 = Asciz I;
|
28
|
+
const #21 = Asciz ConstantValue;
|
29
|
+
const #22 = int 42;
|
30
|
+
const #23 = Asciz floatField;
|
31
|
+
const #24 = Asciz F;
|
32
|
+
const #25 = Asciz longField;
|
33
|
+
const #26 = Asciz J;
|
34
|
+
const #27 = Asciz doubleField;
|
35
|
+
const #28 = Asciz D;
|
36
|
+
const #29 = Asciz <init>;
|
37
|
+
const #30 = Asciz ()V;
|
38
|
+
const #31 = Asciz Code;
|
39
|
+
const #32 = Asciz run;
|
40
|
+
const #33 = NameAndType #29:#30;// "<init>":()V
|
41
|
+
const #34 = Asciz String field;
|
42
|
+
const #35 = NameAndType #17:#18;// stringField:Ljava/lang/String;
|
43
|
+
const #36 = NameAndType #32:#30;// run:()V
|
44
|
+
const #37 = NameAndType #19:#20;// intField:I
|
45
|
+
const #38 = NameAndType #23:#24;// floatField:F
|
46
|
+
const #39 = NameAndType #25:#26;// longField:J
|
47
|
+
const #40 = NameAndType #27:#28;// doubleField:D
|
48
|
+
const #41 = Asciz ConstantPoolTest;
|
49
|
+
const #42 = Asciz java/lang/Object;
|
50
|
+
const #43 = Asciz java/lang/Runnable;'
|
51
|
+
|
52
|
+
def setup
|
53
|
+
@cp = JavaClass::ConstantPool.new(load_class('ConstantPoolTest'))
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_index
|
57
|
+
assert_equal('Method', @cp[1].name)
|
58
|
+
assert_equal('Field', @cp[10].name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_size
|
62
|
+
assert_equal(331, @cp.size)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_item_count
|
66
|
+
assert_equal(43, @cp.item_count)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_dump
|
70
|
+
# puts @cp.dump.join("\n")
|
71
|
+
assert_equal(JAVAP_OUTPUT.gsub(/ +/,' ').gsub(/"</,'<').gsub(/>"/,'>'), @cp.dump.join("\n").gsub(/( |\t)+/,' '))
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_items
|
75
|
+
pool = @cp.items
|
76
|
+
assert_equal(41, pool.size) # 2 double
|
77
|
+
assert_equal('Method', pool[0].name)
|
78
|
+
assert_equal('stringField', pool[14].value)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_find
|
82
|
+
found = @cp.find(JavaClass::ConstantPool::STRING_TAG)
|
83
|
+
assert_equal(1, found.size)
|
84
|
+
assert_equal('String', found[0].name)
|
85
|
+
assert_equal(34, found[0].string_index)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/java_class_header'
|
3
|
+
|
4
|
+
module TestJavaClass
|
5
|
+
|
6
|
+
class TestJavaClassHeader < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@public = JavaClass::JavaClassHeader.new(load_class("AccessFlagsTestPublic"))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_magic
|
13
|
+
assert(@public.magic.valid?)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_version
|
17
|
+
assert_equal('50.0', @public.version.to_s) # JDK 6
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_this_class
|
21
|
+
assert_equal('packagename/AccessFlagsTestPublic', @public.this_class)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_super_class
|
25
|
+
assert_equal('java/lang/Object', @public.super_class)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/java_class_header'
|
3
|
+
|
4
|
+
module TestJavaClass
|
5
|
+
|
6
|
+
class TestReferences < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@refs = JavaClass::JavaClassHeader.new(load_class("AccessFlagsTestPublic")).references
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_referenced_fields
|
13
|
+
fields = @refs.referenced_fields(false)
|
14
|
+
assert_equal(0, fields.size)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_referenced_methods
|
18
|
+
methods = @refs.referenced_methods(false)
|
19
|
+
assert_equal(1, methods.size) # ctor init
|
20
|
+
assert_equal('java/lang/Object', methods[0].class_name)
|
21
|
+
|
22
|
+
# TODO test with myself (true)...
|
23
|
+
end
|
24
|
+
|
25
|
+
# TODO test referenced classes
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/setup'
|
2
|
+
require 'javaclass/string_ux'
|
3
|
+
|
4
|
+
class TestString < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_u1
|
7
|
+
assert_equal(49, "1".u1(0))
|
8
|
+
assert_equal(49, "212".u1(1))
|
9
|
+
assert_equal(50, "212".u1(2))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_u2
|
13
|
+
assert_equal(49*256+50, "12".u2(0))
|
14
|
+
assert_equal(49*256+50, "312".u2(1))
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_u4
|
18
|
+
assert_equal(1, "\0\0\0\1".u4(0))
|
19
|
+
assert_equal(256**4-2, "\xff\xff\xff\xfe".u4(0))
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_single
|
23
|
+
assert_in_delta(3.14159, '@I�'.single(0), 0.0000002)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_double
|
27
|
+
assert_in_delta(3.14159265258981, "@\t!�T!� ".double(0), 0.00000000000001)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|