jclassfile 0.6.0

Java class files parser
Documentation
use crate::attributes::{get_attributes, Attribute};
use crate::constant_pool::ConstantPool;
use crate::error::Result;
use crate::extractors::{get_bitfield, get_int};
use bitflags::bitflags;
use derive_new::new;
use getset::{CopyGetters, Getters};

bitflags! {
    #[derive(Debug, PartialEq)]
    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
    /// Method access and property modifiers
    pub struct MethodFlags: u16 {
        /// Declared public; may be accessed from outside its package.
        const ACC_PUBLIC = 0x0001;
        /// Declared private; accessible only within the defining class and other classes belonging to the same nest (JVMS §5.4.4).
        const ACC_PRIVATE = 0x0002;
        /// Declared protected; may be accessed within subclasses.
        const ACC_PROTECTED = 0x0004;
        /// Declared static.
        const ACC_STATIC = 0x0008;
        /// Declared final; must not be overridden (JVMS §5.4.5).
        const ACC_FINAL = 0x0010;
        /// Declared synchronized; invocation is wrapped by a monitor use.
        const ACC_SYNCHRONIZED = 0x0020;
        /// A bridge method, generated by the compiler.
        const ACC_BRIDGE = 0x0040;
        /// Declared with variable number of arguments.
        const ACC_VARARGS = 0x0080;
        /// Declared native; implemented in a language other than the Java programming language.
        const ACC_NATIVE = 0x0100;
        /// Declared abstract; no implementation is provided.
        const ACC_ABSTRACT = 0x0400;
        /// In a class file whose major version number is at least 46 and at most 60: Declared strictfp.
        const ACC_STRICT = 0x0800;
        /// Declared synthetic; not present in the source code.
        const ACC_SYNTHETIC = 0x1000;
    }
}

#[derive(Debug, PartialEq, Getters, CopyGetters, new)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
/// `method_info` structure (JVMS §4.6).
pub struct MethodInfo {
    #[get = "pub"]
    /// Access and property flags for the method
    access_flags: MethodFlags,
    #[get_copy = "pub"]
    /// Name index in the constant pool
    name_index: u16,
    #[get_copy = "pub"]
    /// Descriptor index in the constant pool
    descriptor_index: u16,
    #[get = "pub"]
    /// Attributes associated with the method
    attributes: Vec<Attribute>,
}

pub(crate) fn get_methods(
    data: &[u8],
    mut start_from: &mut usize,
    constant_pool_vec: &Vec<ConstantPool>,
) -> Result<Vec<MethodInfo>> {
    let methods_count: u16 = get_int(&data, &mut start_from)?;
    let mut methods = Vec::with_capacity(methods_count as usize);
    for _ in 0..methods_count {
        methods.push(MethodInfo::new(
            get_bitfield(&data, &mut start_from)?,
            get_int(&data, &mut start_from)?,
            get_int(&data, &mut start_from)?,
            get_attributes(&data, &mut start_from, &constant_pool_vec)?,
        ))
    }

    Ok(methods)
}