lvm_class/attribute/
class.rs1use 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}