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

docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.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.



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
91
92
93
94
95
96
97
98
99
# File 'lib/javaclass/classfile/java_class_header.rb', line 40

def initialize(data)
  pos = 0

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

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

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

  #    u2 access_flags;
  @access_flags = ClassAccessFlags.new(data.u2(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

  #    u2 fields_count;
  #    field_info fields[fields_count];
  @fields = Fields.new(data, pos, @constant_pool)
  pos += @fields.size
  
  #    u2 methods_count;
  #    method_info methods[methods_count];
  @methods = Methods.new(data, pos, @constant_pool)
  pos += @methods.size

  #    u2 attributes_count;
  #    attribute_info attributes[attributes_count];
  attr = Attributes::Attributes.new(data, pos, @constant_pool)
  pos += attr.size
  @attributes =  ClassFileAttributes.new(attr, this_class)
   
  #  }
  @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.



34
35
36
# File 'lib/javaclass/classfile/java_class_header.rb', line 34

def access_flags
  @access_flags
end

#attributesObject (readonly)

Returns the value of attribute attributes.



37
38
39
# File 'lib/javaclass/classfile/java_class_header.rb', line 37

def attributes
  @attributes
end

#constant_poolObject (readonly)

Returns the value of attribute constant_pool.



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

def constant_pool
  @constant_pool
end

#interfacesObject (readonly)

Returns the value of attribute interfaces.



36
37
38
# File 'lib/javaclass/classfile/java_class_header.rb', line 36

def interfaces
  @interfaces
end

#magicObject (readonly)

Returns the value of attribute magic.



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

def magic
  @magic
end

#referencesObject (readonly)

Returns the value of attribute references.



35
36
37
# File 'lib/javaclass/classfile/java_class_header.rb', line 35

def references
  @references
end

#versionObject (readonly)

Returns the value of attribute version.



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

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_class?
end

#dumpObject

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



119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/javaclass/classfile/java_class_header.rb', line 119

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: \"#{attributes.source_file}\""
  d += @version.dump
  d += @constant_pool.dump
  d << ''
  d << '{'
  d << '}'
  d
end

#inner?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/javaclass/classfile/java_class_header_shortcuts.rb', line 16

def inner?
  attributes.inner?
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_class?
end

#super_classObject

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



108
109
110
111
112
113
114
115
116
# File 'lib/javaclass/classfile/java_class_header.rb', line 108

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.



102
103
104
105
# File 'lib/javaclass/classfile/java_class_header.rb', line 102

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