Class: JavaClass::ClassFile::JavaClassHeader

Inherits:
Object
  • Object
show all
Extended by:
DelegateDirective
Defined in:
lib/javaclass/classfile/java_class_header.rb,
lib/javaclass/classfile/java_class_header_shortcuts.rb,
lib/javaclass/classfile/java_class_header_as_java_name.rb

Overview

Parse and disassemble Java class files, similar to the javap command. Provides all information of a Java class file. This is just a container for all kind of specialised elements. The constuctor parses and creates all contained elements.

See

java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

See

en.wikipedia.org/wiki/Class

Author

Peter Kofler

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DelegateDirective

delegate, delegate_field

Constructor Details

#initialize(data) ⇒ JavaClassHeader

Create a header with the binary data from the class file.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/javaclass/classfile/java_class_header.rb', line 35

def initialize(data)

  #  ClassFile {
  #    u4 magic; 
  @magic = ClassMagic.new(data)

  #    u2 minor_version;
  #    u2 major_version;
  @version = ClassVersion.new(data)

  #    u2 constant_pool_count;
  #    cp_info constant_pool[constant_pool_count-1];
  @constant_pool = ConstantPool.new(data)
  pos = 8 + @constant_pool.size

  #    u2 access_flags;
  @access_flags = AccessFlags.new(data, pos)
  pos += 2

  #    u2 this_class;
  @this_class_idx = data.u2(pos)
  pos += 2

  #    u2 super_class;
  @super_class_idx = data.u2(pos)
  pos += 2

  #    u2 interfaces_count;
  #    u2 interfaces[interfaces_count];
  count = data.u2(pos)
  @interfaces = data.u2rep(count, pos + 2).collect { |i| @constant_pool.class_item(i) }
  pos += 2 + count*2

  # TODO Implement parsing of fields and methods of the JVM spec 
  #    u2 fields_count;
  #    field_info fields[fields_count];
  #        count = data.u2(pos)
  #        @fields = data.u2rep(count, pos + 2).collect { |i| @constant_pool.field_item(i) }
  #        pos += 2 + count*2

  #    u2 methods_count;
  #    method_info methods[methods_count];
  #        count = data.u2(pos)
  #        @methods = data.u2rep(count, pos + 2).collect { |i| @constant_pool.method_item(i) }
  #        pos += 2 + count*2

  #    u2 attributes_count;
  #    attribute_info attributes[attributes_count];
  #  }
  @references = References.new(@constant_pool, @this_class_idx)
  
  #  Body {
  # Class: add the byte code sequences to the methods so it can be analysed later (see JVM spec)
  #  }

end

Instance Attribute Details

#access_flagsObject (readonly)

Returns the value of attribute access_flags.



30
31
32
# File 'lib/javaclass/classfile/java_class_header.rb', line 30

def access_flags
  @access_flags
end

#constant_poolObject (readonly)

Returns the value of attribute constant_pool.



29
30
31
# File 'lib/javaclass/classfile/java_class_header.rb', line 29

def constant_pool
  @constant_pool
end

#interfacesObject (readonly)

Returns the value of attribute interfaces.



32
33
34
# File 'lib/javaclass/classfile/java_class_header.rb', line 32

def interfaces
  @interfaces
end

#magicObject (readonly)

Returns the value of attribute magic.



27
28
29
# File 'lib/javaclass/classfile/java_class_header.rb', line 27

def magic
  @magic
end

#referencesObject (readonly)

Returns the value of attribute references.



31
32
33
# File 'lib/javaclass/classfile/java_class_header.rb', line 31

def references
  @references
end

#versionObject (readonly)

Returns the value of attribute version.



28
29
30
# File 'lib/javaclass/classfile/java_class_header.rb', line 28

def version
  @version
end

Instance Method Details

#abstract_class?Boolean

Is this class an abstract class (and not an interface)?

Returns:

  • (Boolean)


12
13
14
# File 'lib/javaclass/classfile/java_class_header_shortcuts.rb', line 12

def abstract_class?
  access_flags.abstract? && !access_flags.interface?
end

#dumpObject

Return a debug output of this class that looks similar to javap output.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/javaclass/classfile/java_class_header.rb', line 110

def dump
  d = []
  mod = @access_flags.public? ? 'public ' : ''
  ext = super_class ? " extends #{super_class.to_classname}" : ''
  int = !@interfaces.empty? ? " implements #{@interfaces.join(',')}" : ''
  d << "#{mod}class #{this_class.to_classname}#{ext}#{int}"
  # d << "  SourceFile: \"#{read from LineNumberTable?}\""
  d += @version.dump
  d += @constant_pool.dump
  d << ''
  d << '{'
  d << '}'
  d
end

#interface?Boolean

Is this class an interface (and not an annotation)?

Returns:

  • (Boolean)


7
8
9
# File 'lib/javaclass/classfile/java_class_header_shortcuts.rb', line 7

def interface?
  access_flags.interface? && !access_flags.annotation?
end

#super_classObject

Return the name of the superclass of this class or nil. Returns a JavaVMName.



99
100
101
102
103
104
105
106
107
# File 'lib/javaclass/classfile/java_class_header.rb', line 99

def super_class
  if @super_class_idx > 0
    # This is a ConstantClass entry in the constant pool.
    @constant_pool.class_item(@super_class_idx).class_name
  else
    # special case: java.lang.Object has no superclass 
    nil
  end
end

#this_classObject

Return the name of this class. Returns a JavaVMName.



93
94
95
96
# File 'lib/javaclass/classfile/java_class_header.rb', line 93

def this_class
  # This is a ConstantClass entry in the constant pool.
  @jvmname ||= @constant_pool.class_item(@this_class_idx).class_name 
end

#to_javanameObject

Extend JavaClassHeader to behave like a JavaName in delegating to this_class method which returns a JavaVMName.



10
11
12
# File 'lib/javaclass/classfile/java_class_header_as_java_name.rb', line 10

def to_javaname
  this_class
end

#to_jvmnameObject



14
15
16
# File 'lib/javaclass/classfile/java_class_header_as_java_name.rb', line 14

def to_jvmname
  this_class
end

#to_sObject



30
31
32
# File 'lib/javaclass/classfile/java_class_header_as_java_name.rb', line 30

def to_s
  to_classname
end