1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use byteorder::{ReadBytesExt, BigEndian};
use attr::Attr;
use constant::ConstantPool;
use error::{Result, Error};
use std::io::Read;
#[derive(Debug)]
pub struct FieldInfo {
pub access_flags: flags::AccessFlags,
name_index: usize,
desc_index: usize,
pub attrs: Vec<Attr>,
}
impl FieldInfo {
pub fn read<R: Read>(reader: &mut R, cp: &ConstantPool) -> Result<FieldInfo> {
let access_flags = try!(reader.read_u16::<BigEndian>());
let access_flags = match flags::AccessFlags::from_bits(access_flags) {
Some(flags) => flags,
None => return Err(Error::BadAccessFlags(access_flags)),
};
let name_index = try!(reader.read_u16::<BigEndian>()) as usize;
let desc_index = try!(reader.read_u16::<BigEndian>()) as usize;
let attrs_count = try!(reader.read_u16::<BigEndian>()) as usize;
let mut attrs = Vec::with_capacity(attrs_count);
for _ in 0..attrs_count {
let attr = try!(Attr::read(reader, cp));
attrs.push(attr);
}
Ok(FieldInfo {
access_flags: access_flags,
name_index: name_index,
desc_index: desc_index,
attrs: attrs,
})
}
pub fn name<'a>(&self, pool: &'a ConstantPool) -> Option<&'a str> {
pool.get_str(self.name_index)
}
pub fn desc<'a>(&self, pool: &'a ConstantPool) -> Option<&'a str> {
pool.get_str(self.desc_index)
}
}
impl_print! {
FieldInfo(self, printer, constant_pool: &ConstantPool) {
let name = self.name(constant_pool).expect("Invalid name index");
let desc = self.desc(constant_pool).expect("Invalid desc index");
try!(printer.write_indent());
try!(writeln!(printer, "Field `{}` [{}]:", name, desc));
{
let mut printer = printer.sub_indent(1);
try!(printer.write_indent());
try!(writeln!(printer, "Access flags: {:?}", self.access_flags));
try!(printer.write_indent());
try!(writeln!(printer, "Attrs:"));
for attr in self.attrs.iter() {
try!(attr.print(&mut printer.sub_indent(1), constant_pool));
}
}
}
}
pub mod flags {
bitflags! {
pub flags AccessFlags: u16 {
#[doc = "Declared public; may be accessed from outside its package."]
const ACC_PUBLIC = 0x0001,
#[doc = "Declared private; usable only within the defining class."]
const ACC_PRIVATE = 0x0002,
#[doc = "Declared protected; may be accessed within subclasses."]
const ACC_PROTECTED = 0x0004,
#[doc = "Declared static."]
const ACC_STATIC = 0x0008,
#[doc = "Declared final; never directly assigned to after object construction (JLS §17.5)."]
const ACC_FINAL = 0x0010,
#[doc = "Declared volatile; cannot be cached."]
const ACC_VOLATILE = 0x0040,
#[doc = "Declared transient; not written or read by a persistent object manager."]
const ACC_TRANSIENT = 0x0080,
#[doc = "Declared synthetic; not present in the source code."]
const ACC_SYNTHETIC = 0x1000,
#[doc = "Declared as an element of an enum."]
const ACC_ENUM = 0x4000,
}
}
}