bindgen_jni/class_file_visitor/
mod.rs

1//! [Java SE 7 § 4](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html):  Lower level I/O for parsing .class files
2
3use bitflags::bitflags;
4
5    mod attribute;
6pub mod constant;
7pub mod field;
8    mod header;
9    mod io_ext;
10pub mod method;
11    mod version;
12
13//use attribute::*;
14//use constant::*;
15//use field::*;
16//use header::*;
17use io_ext::*;
18//use method::*;
19//use version::*;
20
21pub use attribute::{Attribute};
22pub use constant::{Visitor as ConstantVisitor};
23pub use field::{Field, Visitor as FieldVisitor};
24pub use header::{Header};
25//pub use io_ext::{};
26pub use method::{Method, Visitor as MethodVisitor};
27pub use version::{MajorVersion};
28
29use std::io::{self, *};
30
31// https://en.wikipedia.org/wiki/Java_class_file
32// https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
33
34/// [Java SE 7 § 4.1](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1):  Visitor for ClassFile fields as read straight from I/O.
35pub trait Visitor : constant::Visitor + field::Visitor + method::Visitor {
36    // Methods + comments are organized by invoke order
37
38    fn on_header(&mut self, _header: Header) {}
39    // constant::Visitor
40    fn on_class_access_flags(&mut self, _class_access_flags: ClassAccessFlags) {}
41    fn on_this_class(&mut self, _this_class: u16) {}
42    fn on_super_class(&mut self, _super_class: u16) {}
43    fn on_interface(&mut self, _interface: u16) {}
44    // field::Visitor
45    // method::Visitor
46    fn on_class_attribute(&mut self, _attribute_index: u16, _class_attribute: Attribute) {}
47}
48
49bitflags! {
50    #[derive(Default)]
51    /// [Java SE 7 § 4.1](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1):  ClassFile::access_flags values.
52    pub struct ClassAccessFlags : u16 {
53        /// Declared `public`; may be accessed from outside its package.
54        const PUBLIC        = 0x0001;
55        /// Declared `static`.
56        const STATIC        = 0x0008;
57        /// Declared `final`; no subclasses allowed.
58        const FINAL         = 0x0010;
59        /// Treat superclass methods specifically when invoked by the *invokespecial* instruction.
60        const SUPER         = 0x0020;
61        /// Is an interface, not a class.
62        const INTERFACE     = 0x0200;
63        /// Declared `abstract`; must not be instantiated.
64        const ABSTRACT      = 0x0400;
65        /// Declared synthetic; not present in the source code.
66        const SYNTHETIC     = 0x1000;
67        /// Declared as an annotation type.
68        const ANNOTATION    = 0x2000;
69        /// Declared as an enum type.
70        const ENUM          = 0x4000;
71    }
72}
73
74impl ClassAccessFlags {
75    pub(crate) fn read(r: &mut impl Read) -> io::Result<Self> {
76        Ok(Self::from_bits_truncate(read_u2(r)?))
77    }
78}
79
80/// [Java SE 7 &sect; 4](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html):  Read a class File.
81pub fn read(read: &mut impl Read, visitor: &mut impl Visitor) -> io::Result<()> {
82    visitor.on_header(Header::read(read)?);
83    constant::read_pool_visitor(read, visitor)?;
84    visitor.on_class_access_flags(ClassAccessFlags::read(read)?);
85    visitor.on_this_class(read_u2(read)?);
86    visitor.on_super_class(read_u2(read)?);
87    let interfaces = read_u2(read)?;
88    for _ in 0..interfaces {
89        visitor.on_interface(read_u2(read)?);
90    }
91    Field::read_list_visitor(read, visitor)?;
92    Method::read_list_visitor(read, visitor)?;
93    let class_attribute_count = read_u2(read)?;
94    Attribute::read_list_callback(read, class_attribute_count, |index, attribute| visitor.on_class_attribute(index, attribute))?;
95    Ok(())
96}