Skip to main content

lvm_class/attribute/
class.rs

1use crate::ClassFormatErr;
2use crate::attribute::{AttributeKind, SharedAttribute};
3use crate::constant_pool::ConstantPool;
4use common::utils::cursor::ByteCursor;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum ClassAttribute {
8    Shared(SharedAttribute),
9    SourceFile(u16),
10    InnerClasses(Vec<InnerClassEntry>),
11    EnclosingMethod(u16, u16),
12    SourceDebugExtension,
13    BootstrapMethods(Vec<BootstrapMethodEntry>),
14    Module,
15    ModulePackages,
16    ModuleMainClass,
17    NestHost(u16),
18    NestMembers(Vec<u16>),
19    Record,
20    PermittedSubclasses(Vec<u16>),
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct BootstrapMethodEntry {
25    pub bootstrap_method_idx: u16,
26    pub bootstrap_arguments: Vec<u16>,
27}
28
29impl BootstrapMethodEntry {
30    pub(crate) fn new(bootstrap_method_ref: u16, bootstrap_arguments: Vec<u16>) -> Self {
31        Self {
32            bootstrap_method_idx: bootstrap_method_ref,
33            bootstrap_arguments,
34        }
35    }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct InnerClassEntry {
40    pub inner_class_info_index: u16,
41    pub outer_class_info_index: u16,
42    pub inner_name_index: u16,
43    pub inner_class_access_flags: u16,
44}
45
46impl InnerClassEntry {
47    pub(crate) fn new(
48        inner_class_info_index: u16,
49        outer_class_info_index: u16,
50        inner_name_index: u16,
51        inner_class_access_flags: u16,
52    ) -> Self {
53        Self {
54            inner_class_info_index,
55            outer_class_info_index,
56            inner_name_index,
57            inner_class_access_flags,
58        }
59    }
60}
61
62impl<'a> ClassAttribute {
63    pub(crate) fn read(
64        pool: &ConstantPool,
65        cursor: &mut ByteCursor<'a>,
66    ) -> Result<Self, ClassFormatErr> {
67        let attribute_name_index = cursor.u16()?;
68        let _attribute_length = cursor.u32()? as usize;
69
70        let attribute_kind = AttributeKind::try_from(pool.get_utf8(&attribute_name_index)?)?;
71        match attribute_kind {
72            AttributeKind::SourceFile => Ok(ClassAttribute::SourceFile(cursor.u16()?)),
73            AttributeKind::BootstrapMethods => {
74                let number_of_bootstrap_methods = cursor.u16()? as usize;
75                let mut methods = Vec::with_capacity(number_of_bootstrap_methods);
76                for _ in 0..number_of_bootstrap_methods {
77                    let bootstrap_method_ref = cursor.u16()?;
78                    let number_of_bootstrap_arguments = cursor.u16()? as usize;
79                    let mut bootstrap_arguments = Vec::with_capacity(number_of_bootstrap_arguments);
80                    for _ in 0..number_of_bootstrap_arguments {
81                        bootstrap_arguments.push(cursor.u16()?);
82                    }
83                    methods.push(BootstrapMethodEntry::new(
84                        bootstrap_method_ref,
85                        bootstrap_arguments,
86                    ));
87                }
88                Ok(ClassAttribute::BootstrapMethods(methods))
89            }
90            AttributeKind::InnerClasses => {
91                let number_of_classes = cursor.u16()? as usize;
92                let mut classes = Vec::with_capacity(number_of_classes);
93                for _ in 0..number_of_classes {
94                    classes.push(InnerClassEntry::new(
95                        cursor.u16()?,
96                        cursor.u16()?,
97                        cursor.u16()?,
98                        cursor.u16()?,
99                    ));
100                }
101                Ok(ClassAttribute::InnerClasses(classes))
102            }
103            AttributeKind::NestMembers => {
104                let number_of_classes = cursor.u16()? as usize;
105                let mut classes = Vec::with_capacity(number_of_classes);
106                for _ in 0..number_of_classes {
107                    classes.push(cursor.u16()?);
108                }
109                Ok(ClassAttribute::NestMembers(classes))
110            }
111            AttributeKind::NestHost => {
112                let host_class_index = cursor.u16()?;
113                Ok(ClassAttribute::NestHost(host_class_index))
114            }
115            AttributeKind::EnclosingMethod => {
116                let class_index = cursor.u16()?;
117                let method_index = cursor.u16()?;
118                Ok(ClassAttribute::EnclosingMethod(class_index, method_index))
119            }
120            AttributeKind::PermittedSubclasses => {
121                let number_of_classes = cursor.u16()? as usize;
122                let mut classes = Vec::with_capacity(number_of_classes);
123                for _ in 0..number_of_classes {
124                    classes.push(cursor.u16()?);
125                }
126                Ok(ClassAttribute::PermittedSubclasses(classes))
127            }
128            AttributeKind::RuntimeVisibleAnnotations
129            | AttributeKind::RuntimeVisibleTypeAnnotations
130            | AttributeKind::RuntimeInvisibleTypeAnnotations
131            | AttributeKind::Synthetic
132            | AttributeKind::Deprecated
133            | AttributeKind::RuntimeInvisibleAnnotations
134            | AttributeKind::Signature => Ok(ClassAttribute::Shared(SharedAttribute::read(
135                attribute_kind,
136                cursor,
137            )?)),
138            other => unimplemented!("Class attribute {:?} not implemented", other),
139        }
140    }
141}