1use getset::{CopyGetters, Getters};
3use scroll::Pread;
4use std::fmt;
5
6use crate::uint32_t;
7
8#[derive(Debug, Pread, CopyGetters)]
9#[get_copy = "pub"]
10pub struct RegionHeader {
11 start_off: uint32_t,
13 end_off: uint32_t,
15 class_idx_size: uint32_t,
17 class_idx_off: uint32_t,
19 method_string_literal_region_idx_size: uint32_t,
21 method_string_literal_region_idx_off: uint32_t,
23 field_idx_size: uint32_t,
26 field_idx_off: uint32_t,
27 proto_idx_size: uint32_t,
29 proto_idx_off: uint32_t,
30}
31
32#[derive(Debug, CopyGetters, Getters, Default)]
36#[get = "pub"]
37pub struct FieldType {
38 pub name: String,
41}
42
43impl fmt::Display for FieldType {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(f, "{}", self.name)
46 }
47}
48
49#[derive(Debug, Default)]
50pub struct ClassRegionIndex {
51 offsets: Vec<FieldType>,
53}
54
55impl ClassRegionIndex {
56 pub fn push(&mut self, field_type: FieldType) {
57 self.offsets.push(field_type);
58 }
59
60 pub fn get(&self, idx: &usize) -> &FieldType {
61 &self.offsets[*idx]
62 }
63}
64
65#[derive(Debug, Getters, Default)]
66#[get = "pub"]
67pub struct MethodStringLiteralRegionIndex {
68 offsets: Vec<uint32_t>,
69}
70
71impl MethodStringLiteralRegionIndex {
72 pub fn push(&mut self, offset: uint32_t) {
73 self.offsets.push(offset);
74 }
75
76 pub fn get(&self, idx: &usize) -> &uint32_t {
77 &self.offsets[*idx]
78 }
79}
80
81#[derive(Debug, Getters, Default)]
82#[get = "pub"]
83pub struct FieldRegionIndex {
84 offsets: Vec<uint32_t>,
85}
86
87impl FieldRegionIndex {
88 pub fn push(&mut self, offset: uint32_t) {
89 self.offsets.push(offset);
90 }
91}
92
93#[derive(Debug, Getters, Default)]
94#[get = "pub"]
95pub struct ProtoRegionIndex {
96 offsets: Vec<uint32_t>,
97}
98
99impl ProtoRegionIndex {
100 pub fn push(&mut self, offset: uint32_t) {
101 self.offsets.push(offset);
102 }
103}
104
105#[derive(Debug, Getters)]
106#[get = "pub"]
107pub struct Region {
108 header: RegionHeader,
109 class_region_idx: ClassRegionIndex,
111 method_string_literal_region_idx: MethodStringLiteralRegionIndex,
113 field_region_idx: FieldRegionIndex,
114 proto_region_idx: ProtoRegionIndex,
115}
116
117impl Region {
118 pub fn new(
119 header: RegionHeader,
120 cri: ClassRegionIndex,
121 mslri: MethodStringLiteralRegionIndex,
122 field_region_idx: FieldRegionIndex,
123 proto_region_idx: ProtoRegionIndex,
124 ) -> Self {
125 Self {
126 header,
127 class_region_idx: cri,
128 method_string_literal_region_idx: mslri,
129 field_region_idx,
130 proto_region_idx,
131 }
132 }
133
134 pub fn is_here(&self, off: usize) -> bool {
136 self.header.start_off() as usize <= off && off < self.header.end_off() as usize
137 }
138
139 pub fn get_class_name(&self, idx: usize) -> &FieldType {
142 self.class_region_idx.get(&idx)
143 }
144
145 pub fn get_msl_offset(&self, idx: usize) -> &uint32_t {
147 self.method_string_literal_region_idx.get(&idx)
148 }
149}