jbcrs_basic/writer/
mod.rs1mod encode;
2
3use result::*;
4use super::constpool::*;
5use super::tree::*;
6use self::encode::Encoder;
7
8pub fn write(constant_pool: &Pool, class: &Class) -> Result<Vec<u8>> {
10 let mut encoder = Encoder::new();
11
12 encoder.write_bytes(MAGIC);
14 encoder.write_u16(class.minor_version);
15 encoder.write_u16(class.major_version);
16
17 write_constant_pool(&mut encoder, constant_pool);
18
19 encoder.write_u16(class.access_flags.bits());
20 encoder.write_u16(class.name);
21 encoder.write_u16(class.super_name);
22
23 encoder.write_u16(class.interfaces.len() as u16);
24 for interface in &class.interfaces {
25 encoder.write_u16(*interface);
26 }
27
28 write_fields(&mut encoder, &class.fields);
29 write_methods(&mut encoder, &class.methods);
30
31 write_attributes(&mut encoder, &class.attributes);
32
33 Ok(encoder.bytes())
34}
35
36fn write_constant_pool(encoder: &mut Encoder, pool: &Pool) {
38 encoder.write_u16(pool.len());
40 for (_index, item) in pool.iter() {
41 match *item {
42 Item::UTF8(ref s) => {
43 encoder.write_u8(1);
44 encoder.write_u16(s.len() as u16);
45 encoder.write_str(s.as_ref());
46 }
47 Item::Integer(value) => {
48 encoder.write_u8(3);
49 encoder.write_i32(value);
50 }
51 Item::Float(value) => {
52 encoder.write_u8(4);
53 encoder.write_f32(value);
54 }
55 Item::Long(value) => {
56 encoder.write_u8(5);
57 encoder.write_i64(value);
58 }
59 Item::Double(value) => {
60 encoder.write_u8(6);
61 encoder.write_f64(value);
62 }
63 Item::Class(class) => {
64 encoder.write_u8(7);
65 encoder.write_u16(class);
66 }
67 Item::String(class) => {
68 encoder.write_u8(8);
69 encoder.write_u16(class);
70 }
71 Item::FieldRef {
72 class,
73 name_and_type,
74 } => {
75 encoder.write_u8(9);
76 encoder.write_u16(class);
77 encoder.write_u16(name_and_type);
78 }
79 Item::MethodRef {
80 class,
81 name_and_type,
82 } => {
83 encoder.write_u8(10);
84 encoder.write_u16(class);
85 encoder.write_u16(name_and_type);
86 }
87 Item::InterfaceMethodRef {
88 class,
89 name_and_type,
90 } => {
91 encoder.write_u8(11);
92 encoder.write_u16(class);
93 encoder.write_u16(name_and_type);
94 }
95 Item::NameAndType { name, desc } => {
96 encoder.write_u8(12);
97 encoder.write_u16(name);
98 encoder.write_u16(desc);
99 }
100 Item::MethodHandle { ref kind, index } => {
101 use self::ReferenceKind::*;
102
103 encoder.write_u8(15);
104 encoder.write_u8(match *kind {
105 GetField => 1,
106 GetStatic => 2,
107 PutField => 3,
108 PutStatic => 4,
109 InvokeVirtual => 5,
110 InvokeStatic => 6,
111 InvokeSpecial => 7,
112 NewInvokeSpecial => 8,
113 InvokeInterface => 9,
114 });
115 encoder.write_u16(index);
116 }
117 Item::MethodType(index) => {
118 encoder.write_u8(16);
119 encoder.write_u16(index);
120 }
121 Item::InvokeDynamic {
122 bootstrap_method,
123 name_and_type,
124 } => {
125 encoder.write_u8(18);
126 encoder.write_u16(bootstrap_method);
127 encoder.write_u16(name_and_type);
128 }
129 Item::Module(index) => {
130 encoder.write_u8(19);
131 encoder.write_u16(index);
132 }
133 Item::Package(index) => {
134 encoder.write_u8(20);
135 encoder.write_u16(index);
136 }
137 }
138 }
139}
140
141fn write_fields(encoder: &mut Encoder, fields: &[Field]) {
143 encoder.write_u16(fields.len() as u16);
144 for field in fields {
145 encoder.write_u16(field.access_flags.bits());
146 encoder.write_u16(field.name);
147 encoder.write_u16(field.desc);
148 write_attributes(encoder, &field.attributes);
149 }
150}
151
152fn write_methods(encoder: &mut Encoder, methods: &[Method]) {
154 encoder.write_u16(methods.len() as u16);
155 for method in methods {
156 encoder.write_u16(method.access_flags.bits());
157 encoder.write_u16(method.name);
158 encoder.write_u16(method.desc);
159 write_attributes(encoder, &method.attributes);
160 }
161}
162
163fn write_attributes(encoder: &mut Encoder, _attributes: &[Attribute]) {
165 encoder.write_u16(0);
167}