classreader/
lib.rs

1
2#[macro_use]
3extern crate log;
4
5mod model;
6mod result;
7mod decode;
8
9use std::char;
10use std::io::Read;
11use std::fs::File;
12
13pub use ::result::*;
14pub use ::model::*;
15pub use ::decode::*;
16
17pub struct ClassReader<'a> {
18    reader: Box<Read + 'a>,
19    position: usize
20}
21
22impl<'a> ClassReader<'a> {
23
24    pub fn new_from_path(path: &str) -> ParseResult<Class> {
25        let mut file = match File::open(path) {
26            Result::Ok(f) => f,
27            Result::Err(e) => { return Result::Err(ParseError::Io(e)); }
28        };
29        ClassReader::new_from_reader(&mut file)
30    }
31
32    pub fn new_from_reader<T: Read + 'a>(reader: &mut T) -> ParseResult<Class> {
33        let mut cr = ClassReader { reader: Box::new(reader), position: 0 };
34
35        let magic = try!(cr.read_u32());
36        let minor_version = try!(cr.read_u16());
37        let major_version = try!(cr.read_u16());
38        let constant_pool = try!(cr.read_constant_pool());
39        let access_flags = try!(cr.read_u16());
40        let this_class = try!(cr.read_u16());
41        let super_class = try!(cr.read_u16());
42        let interfaces = try!(cr.read_interfaces());
43        let fields = try!(cr.read_fields(&constant_pool));
44        let methods = try!(cr.read_methods(&constant_pool));
45        let attributes = try!(cr.read_attributes(&constant_pool));
46
47        Result::Ok(Class {
48            magic: magic,
49            major_version: major_version,
50            minor_version: minor_version,
51            constant_pool: constant_pool,
52            access_flags: access_flags,
53            this_class: this_class,
54            super_class: super_class,
55            interfaces: interfaces,
56            fields: fields,
57            methods: methods,
58            attributes: attributes
59        })
60    }
61
62    fn read_attribute(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Attribute> {
63        let name_index = try!(self.read_u16());
64        let length = try!(self.read_u32());
65
66        let name = match &constant_pool[name_index as usize - 1] {
67            &ConstantPoolInfo::Utf8(ref name) => { name },
68            i @ _ => {
69                let error_message = format!("expected utf8 at index {} but got {:?}", name_index, i);
70                return Result::Err(ParseError::Format(error_message));
71            }
72        };
73
74        let info = match name.as_str() {
75            "Code" => {
76                let max_stack = try!(self.read_u16());
77                let max_locals = try!(self.read_u16());
78                let code_length = try!(self.read_u32());
79                let code = try!(self.read_bytes(code_length));
80                let exception_table_length = try!(self.read_u16());
81                let mut exceptions = Vec::with_capacity(exception_table_length as usize);
82                for _ in 0..exception_table_length {
83                    let start_pc = try!(self.read_u16());
84                    let end_pc = try!(self.read_u16());
85                    let handler_pc = try!(self.read_u16());
86                    let catch_type = try!(self.read_u16());
87
88                    let exception = Exception {
89                        start_pc: start_pc,
90                        end_pc: end_pc,
91                        handler_pc: handler_pc,
92                        catch_type: catch_type
93                    };
94                    exceptions.push(exception);
95                }
96                let attributes = try!(self.read_attributes(constant_pool));
97
98                let instructions = try!(decode_code(&code));
99
100                Attribute::Code {
101                    max_stack: max_stack,
102                    max_locals: max_locals,
103                    code: instructions,
104                    exception_table: exceptions,
105                    attributes: attributes
106                }
107            },
108            "ConstantValue" => {
109                let constvalue_index = try!(self.read_u16());
110                Attribute::ConstantValue { constvalue_index: constvalue_index }
111            },
112            "StackMapTable" => {
113                let number_of_entries = try!(self.read_u16());
114                let mut entries = Vec::with_capacity(number_of_entries as usize);
115                for _ in 0..number_of_entries {
116                    let frame_type = try!(self.read_u8());
117                    let frame = match frame_type {
118                        0...63 => StackMapFrame::SameFrame,
119                        64...127 => {
120                            let info = try!(self.read_verification_type_info());
121                            StackMapFrame::SameLocals1StackItemFrame(info)
122                        },
123                        128...246 => {
124                            let message = format!("reserved frame type {} used", frame_type);
125                            return Result::Err(ParseError::Format(message));
126                        }
127                        247 => {
128                            let offset_delta = try!(self.read_u16());
129                            let info = try!(self.read_verification_type_info());
130                            StackMapFrame::SameLocals1StackItemFrameExtended {
131                                offset_delta: offset_delta,
132                                stack: info
133                            }
134                        },
135                        248...250 => {
136                            let offset_delta = try!(self.read_u16());
137                            StackMapFrame::ChopFrame { offset_delta: offset_delta }
138                        },
139                        251 => {
140                            let offset_delta = try!(self.read_u16());
141                            StackMapFrame::SameFrameExtended { offset_delta: offset_delta }
142                        },
143                        252...254 => {
144                            let offset_delta = try!(self.read_u16());
145                            let infos = try!(self.read_verification_type_infos(frame_type as u16 - 251));
146                            StackMapFrame::AppendFrame {
147                                offset_delta: offset_delta,
148                                locals: infos
149                            }
150                        },
151                        255 => {
152                            let offset_delta = try!(self.read_u16());
153                            let number_of_locals = try!(self.read_u16());
154                            let locals = try!(self.read_verification_type_infos(number_of_locals));
155                            let number_of_stack_items = try!(self.read_u16());
156                            let stack = try!(self.read_verification_type_infos(number_of_stack_items));
157                            StackMapFrame::FullFrame {
158                                offset_delta: offset_delta,
159                                locals: locals,
160                                stack: stack
161                            }
162                        },
163                        _ => panic!("unknown frame type {}", frame_type) // impossible
164                    };
165                    entries.push(frame);
166                }
167                Attribute::StackMapTable(entries)
168            },
169            "Exceptions" => {
170                let number_of_exceptions = try!(self.read_u16());
171                let mut exception_index_table = Vec::with_capacity(number_of_exceptions as usize);
172                for _ in 0..number_of_exceptions {
173                    let exception_index = try!(self.read_u16());
174                    exception_index_table.push(exception_index);
175                }
176                Attribute::Exceptions { exception_index_table: exception_index_table }
177            },
178            "InnerClasses" => {
179                let number_of_classes = try!(self.read_u16());
180                let mut classes = Vec::with_capacity(number_of_classes as usize);
181                for _ in 0..number_of_classes {
182                    let inner_class_info_index = try!(self.read_u16());
183                    let outer_class_info_index = try!(self.read_u16());
184                    let inner_name_index = try!(self.read_u16());
185                    let inner_class_access_flags = try!(self.read_u16());
186
187                    let class = InnerClass {
188                        inner_class_info_index: inner_class_info_index,
189                        outer_class_info_index: outer_class_info_index,
190                        inner_name_index: inner_name_index,
191                        inner_class_access_flags: inner_class_access_flags
192                    };
193                    classes.push(class);
194                }
195                Attribute::InnerClasses {
196                    classes: classes
197                }
198            },
199            "EnclosingMethod" => {
200                let class_index = try!(self.read_u16());
201                let method_index = try!(self.read_u16());
202                Attribute::EnclosingMethod {
203                    class_index: class_index,
204                    method_index: method_index
205                }
206            },
207            "Synthetic" => {
208                Attribute::Synthetic
209            },
210            "Signature" => {
211                let signature_index = try!(self.read_u16());
212                Attribute::Signature { signature_index: signature_index }
213            },
214            "SourceFile" => {
215                let sourcefile_index = try!(self.read_u16());
216                Attribute::SourceFile { sourcefile_index: sourcefile_index }
217            },
218            "SourceDebugExtension" => {
219                let data = try!(self.read_bytes(length));
220                Attribute::SourceDebugExtension(data)
221            },
222            "LineNumberTable" => {
223                let table_length = try!(self.read_u16());
224                let mut entries = Vec::with_capacity(table_length as usize);
225                for _ in 0..table_length {
226                    let start_pc = try!(self.read_u16());
227                    let line_number = try!(self.read_u16());
228                    let entry = LineNumber {
229                        start_pc: start_pc,
230                        line_number: line_number
231                    };
232                    entries.push(entry);
233                }
234                Attribute::LineNumberTable(entries)
235            },
236            "LocalVariableTable" | "LocalVariableTypeTable" => {
237                let table_length = try!(self.read_u16());
238                let mut entries = Vec::with_capacity(table_length as usize);
239                for _ in 0..table_length {
240                    let start_pc = try!(self.read_u16());
241                    let length = try!(self.read_u16());
242                    let name_index = try!(self.read_u16());
243                    let descriptor_or_signature_index = try!(self.read_u16());
244                    let index = try!(self.read_u16());
245                    let entry = LocalVariable {
246                        start_pc: start_pc,
247                        length: length,
248                        name_index: name_index,
249                        descriptor_or_signature_index: descriptor_or_signature_index,
250                        index: index
251                    };
252                    entries.push(entry);
253                }
254                if name == "LocalVariableTable" {
255                    Attribute::LocalVariableTable(entries)
256                } else {
257                    Attribute::LocalVariableTypeTable(entries)
258                }
259            },
260            "Deprecated" => {
261                Attribute::Deprecated
262            },
263            "RuntimeVisibleAnnotations" => {
264                let annotations = try!(self.read_annotations(constant_pool));
265                Attribute::RuntimeVisibleAnnotations(annotations)
266            },
267            "RuntimeInvisibleAnnotations" => {
268                let annotations = try!(self.read_annotations(constant_pool));
269                Attribute::RuntimeInvisibleAnnotations(annotations)
270            },
271            "RuntimeVisibleParameterAnnotations" => {
272                let parameter_annotations = try!(self.read_parameter_annotations(constant_pool));
273                Attribute::RuntimeVisibleParameterAnnotations(parameter_annotations)
274            },
275            "RuntimeInvisibleParameterAnnotations" => {
276                let parameter_annotations = try!(self.read_parameter_annotations(constant_pool));
277                Attribute::RuntimeInvisibleParameterAnnotations(parameter_annotations)
278            },
279            "RuntimeVisibleTypeAnnotations" => {
280                let type_annotations = try!(self.read_type_annotations(constant_pool));
281                Attribute::RuntimeVisibleTypeAnnotations(type_annotations)
282            },
283            "RuntimeInvisibleTypeAnnotations" => {
284                let type_annotations = try!(self.read_type_annotations(constant_pool));
285                Attribute::RuntimeInvisibleTypeAnnotations(type_annotations)
286            },
287            "AnnotationDefault" => {
288                let element_value = try!(self.read_element_value(constant_pool));
289                Attribute::AnnotationDefault { element_value: element_value }
290            },
291            "BootstrapMethods" => {
292                let num_bootstrap_methods = try!(self.read_u16());
293                let mut bootstrap_methods = Vec::with_capacity(num_bootstrap_methods as usize);
294                for _ in 0..num_bootstrap_methods {
295                    let bootstrap_method_ref = try!(self.read_u16());
296                    let num_bootstrap_arguments = try!(self.read_u16());
297                    let mut bootstrap_arguments = Vec::with_capacity(num_bootstrap_arguments as usize);
298                    for _ in 0..num_bootstrap_arguments {
299                        let bootstrap_argument = try!(self.read_u16());
300                        bootstrap_arguments.push(bootstrap_argument);
301                    }
302                    let bootstrap_method = BootstrapMethod {
303                        method_ref: bootstrap_method_ref,
304                        arguments: bootstrap_arguments
305                    };
306                    bootstrap_methods.push(bootstrap_method);
307                }
308                Attribute::BootstrapMethods(bootstrap_methods)
309            },
310            "MethodParameters" => {
311                let num_parameters = try!(self.read_u8());
312                let mut parameters = Vec::with_capacity(num_parameters as usize);
313                for _ in 0..num_parameters {
314                    let name_index = try!(self.read_u16());
315                    let access_flags = try!(self.read_u16());
316                    let parameter = MethodParameter {
317                        name_index: name_index,
318                        access_flags: access_flags
319                    };
320                    parameters.push(parameter);
321                }
322                Attribute::MethodParameters(parameters)
323            },
324            _ => {
325                let info = try!(self.read_bytes(length));
326                Attribute::Unknown(info)
327            }
328        };
329        Result::Ok(info)
330    }
331
332    fn read_verification_type_info(self: &mut ClassReader<'a>) -> ParseResult<VerificationType> {
333        let tag = try!(self.read_u8());
334        let verification_type_info = match tag {
335            0 => VerificationType::Top,
336            1 => VerificationType::Integer,
337            2 => VerificationType::Float,
338            3 => VerificationType::Double,
339            4 => VerificationType::Long,
340            5 => VerificationType::Null,
341            6 => VerificationType::UninitializedThis,
342            7 => {
343                let index = try!(self.read_u16());
344                VerificationType::Object { index: index }
345            }
346            8 => {
347                let offset = try!(self.read_u16());
348                VerificationType::UninitializedVariable { offset: offset }
349            }
350            _ => {
351                let error_message = format!("unknown verification type info tag {}", tag);
352                return Result::Err(ParseError::Format(error_message));
353            }
354        };
355        Result::Ok(verification_type_info)
356    }
357
358    fn read_verification_type_infos(self: &mut ClassReader<'a>, num: u16) -> ParseResult<Vec<VerificationType>> {
359        let mut infos = Vec::with_capacity(num as usize);
360        for _ in 0..num {
361            let info = try!(self.read_verification_type_info());
362            infos.push(info);
363        }
364        Result::Ok(infos)
365    }
366
367    fn read_type_annotations(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<TypeAnnotation>> {
368        let num_annotations = try!(self.read_u16());
369        let mut annotations = Vec::with_capacity(num_annotations as usize);
370        for _ in 0..num_annotations {
371            let annotation = try!(self.read_type_annotation(constant_pool));
372            annotations.push(annotation);
373        }
374        Result::Ok(annotations)
375    }
376
377    fn read_type_annotation(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<TypeAnnotation> {
378        let target_type_tag = try!(self.read_u8());
379        let target_type = match target_type_tag {
380            0x00 => TargetType::Type,
381            0x01 => TargetType::Method,
382            0x10 => TargetType::Supertype,
383            0x11 => TargetType::TypeBound,
384            0x12 => TargetType::MethodBound,
385            0x13 => TargetType::Field,
386            0x14 => TargetType::MethodReturnType,
387            0x15 => TargetType::ReceiverType,
388            0x16 => TargetType::Parameter,
389            0x17 => TargetType::Throws,
390            0x40 => TargetType::LocalVariableDeclaration,
391            0x41 => TargetType::ResourceVariableDeclaration,
392            0x42 => TargetType::ExceptionParameterDeclaration,
393            0x43 => TargetType::Instanceof,
394            0x44 => TargetType::New,
395            0x45 => TargetType::MethodReferenceNew,
396            0x46 => TargetType::MethodReference,
397            0x47 => TargetType::Cast,
398            0x48 => TargetType::ConstructorArgument,
399            0x49 => TargetType::MethodArgument,
400            0x4A => TargetType::MethodReferenceNewArgument,
401            0x4B => TargetType::MethodReferenceArgument,
402            _ => {
403                let message = format!("unknown target type {}", target_type_tag);
404                return Result::Err(ParseError::Format(message));
405            }
406        };
407        let target_info = match target_type_tag {
408            0x00 | 0x01 => {
409                let type_parameter_index = try!(self.read_u8());
410                TargetInfo::TypeParameter { index: type_parameter_index }
411            },
412            0x10 => {
413                let supertype_index = try!(self.read_u16());
414                TargetInfo::Supertype { index: supertype_index }
415            },
416            0x11 | 0x12 => {
417                let type_parameter_index = try!(self.read_u8());
418                let bound_index = try!(self.read_u8());
419                TargetInfo::TypeParameterBound { index: type_parameter_index, bound_index: bound_index }
420            },
421            0x13...0x15 => {
422                TargetInfo::Empty
423            },
424            0x16 => {
425                let formal_parameter_index = try!(self.read_u8());
426                TargetInfo::MethodFormalParameter { index: formal_parameter_index }
427            },
428            0x17 => {
429                let throws_type_index = try!(self.read_u16());
430                TargetInfo::Throws { type_index: throws_type_index }
431            },
432            0x40 | 0x41 => {
433                let table_length = try!(self.read_u16());
434                let mut table = Vec::with_capacity(table_length as usize);
435                for _ in 0..table_length {
436                    let start_pc = try!(self.read_u16());
437                    let length = try!(self.read_u16());
438                    let index = try!(self.read_u16());
439                    let entry = LocalVariableTarget {
440                        start_pc: start_pc,
441                        length: length,
442                        index: index
443                    };
444                    table.push(entry);
445                }
446                TargetInfo::Localvar(table)
447            },
448            0x42 => {
449                let exception_table_index = try!(self.read_u16());
450                TargetInfo::Catch { exception_table_index : exception_table_index }
451            },
452            0x43...0x46 => {
453                let offset = try!(self.read_u16());
454                TargetInfo::Offset(offset)
455            },
456            0x47...0x4B => {
457                let offset = try!(self.read_u16());
458                let type_argument_index = try!(self.read_u8());
459                TargetInfo::TypeArgument { offset: offset, index: type_argument_index }
460            },
461            _ => {
462                let error_message = format!("unknown target type {}", target_type_tag);
463                return Result::Err(ParseError::Format(error_message));
464            }
465        };
466        let path_length = try!(self.read_u8());
467        let mut path = Vec::with_capacity(path_length as usize);
468        for _ in 0..path_length {
469            let type_path_kind_tag = try!(self.read_u8());
470            let type_path_kind = match type_path_kind_tag {
471                0 => TypePathKind::Array,
472                1 => TypePathKind::Nested,
473                2 => TypePathKind::WildcardBound,
474                3 => TypePathKind::TypeArgument,
475                _ => {
476                    let error_message = format!("unknown type path kind {}", type_path_kind_tag);
477                    return Result::Err(ParseError::Format(error_message));
478                }
479            };
480            let type_argument_index = try!(self.read_u8());
481            let path_element = PathElement { kind: type_path_kind, argument_index: type_argument_index };
482            path.push(path_element);
483        }
484        let type_index = try!(self.read_u16());
485        let element_value_pairs = try!(self.read_element_value_pairs(constant_pool));
486        Result::Ok(TypeAnnotation {
487            target_type: target_type,
488            target_info: target_info,
489            type_path: TypePath { path: path },
490            type_index: type_index,
491            element_value_pairs: element_value_pairs
492        })
493    }
494
495    fn read_parameter_annotations(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Vec<Annotation>>> {
496        let num_parameters = try!(self.read_u8());
497        let mut parameter_annotations = Vec::with_capacity(num_parameters as usize);
498        for _ in 0..num_parameters {
499            let annotations = try!(self.read_annotations(constant_pool));
500            parameter_annotations.push(annotations);
501        }
502        Result::Ok(parameter_annotations)
503    }
504
505    fn read_annotations(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Annotation>> {
506        let num_annotations = try!(self.read_u16());
507        let mut annotations = Vec::with_capacity(num_annotations as usize);
508        for _ in 0..num_annotations {
509            let annotation = try!(self.read_annotation(constant_pool));
510            annotations.push(annotation);
511        }
512        Result::Ok(annotations)
513    }
514
515    fn read_annotation(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Annotation> {
516        let type_index = try!(self.read_u16());
517        let element_value_pairs = try!(self.read_element_value_pairs(constant_pool));
518        Result::Ok(Annotation {
519            type_index: type_index,
520            element_value_pairs: element_value_pairs
521        })
522    }
523
524    fn read_element_value_pairs(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<ElementValuePair>> {
525        let num_evps = try!(self.read_u16());
526        let mut element_value_pairs = Vec::with_capacity(num_evps as usize);
527        for _ in 0..num_evps {
528            let element_name_index = try!(self.read_u16());
529            let element_value = try!(self.read_element_value(constant_pool));
530
531            let element_value_pair = ElementValuePair {
532                element_name_index: element_name_index,
533                value: element_value
534            };
535            element_value_pairs.push(element_value_pair);
536        }
537        Result::Ok(element_value_pairs)
538    }
539
540    fn read_element_value(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<ElementValue> {
541        let tag = try!(self.read_u8()) as char;
542        let value = match tag {
543            'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z' | 's' => {
544                let const_value_index = try!(self.read_u16());
545                ElementValue::Constant { const_value_index: const_value_index }
546            },
547            'e' => {
548                let type_name_index = try!(self.read_u16());
549                let const_name_index = try!(self.read_u16());
550                ElementValue::EnumConstant {
551                    type_name_index: type_name_index,
552                    const_name_index: const_name_index
553                }
554            },
555            'c' => {
556                let class_info_index = try!(self.read_u16());
557                ElementValue::Class { class_info_index: class_info_index }
558            },
559            '@' => {
560                let annotation = try!(self.read_annotation(constant_pool));
561                ElementValue::Annotation(annotation)
562            },
563            '[' => {
564                let num_values = try!(self.read_u16());
565                let mut element_values = Vec::with_capacity(num_values as usize);
566                for _ in 0..num_values {
567                    let array_value = try!(self.read_element_value(constant_pool));
568                    element_values.push(array_value);
569                }
570                ElementValue::Array(element_values)
571            },
572            _ => {
573                let message = format!("unknown element value tag {}", tag);
574                return Result::Err(ParseError::Format(message));
575            }
576        };
577        Result::Ok(value)
578    }
579
580    fn read_attributes(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Attribute>> {
581        let attribute_count = try!(self.read_u16());
582        let mut attributes = Vec::with_capacity(attribute_count as usize);
583        for _ in 0..attribute_count {
584            let attribute = try!(self.read_attribute(constant_pool));
585            attributes.push(attribute);
586        }
587        Result::Ok(attributes)
588    }
589
590    fn read_methods(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Method>> {
591        let method_count = try!(self.read_u16());
592        let mut methods = Vec::with_capacity(method_count as usize);
593        for _ in 0..method_count {
594            let access_flags = try!(self.read_u16());
595            let name_index = try!(self.read_u16());
596            let descriptor_index = try!(self.read_u16());
597            let attributes = try!(self.read_attributes(&constant_pool));
598
599            let method = Method {
600                access_flags: access_flags,
601                name_index: name_index,
602                descriptor_index: descriptor_index,
603                attributes: attributes
604            };
605            methods.push(method);
606        }
607        Result::Ok(methods)
608    }
609
610    fn read_fields(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Field>> {
611        let field_count = try!(self.read_u16());
612        let mut fields = Vec::with_capacity(field_count as usize);
613        for _ in 0..field_count {
614            let access_flags = try!(self.read_u16());
615            let name_index = try!(self.read_u16());
616            let descriptor_index = try!(self.read_u16());
617            let attributes = try!(self.read_attributes(&constant_pool));
618
619            let field = Field {
620                access_flags: access_flags,
621                name_index: name_index,
622                descriptor_index:
623                descriptor_index,
624                attributes: attributes };
625            fields.push(field);
626        }
627        Result::Ok(fields)
628    }
629
630    fn read_interfaces(self: &mut ClassReader<'a>) -> ParseResult<Vec<u16>> {
631        let interfaces_count = try!(self.read_u16());
632        let mut interfaces = Vec::with_capacity(interfaces_count as usize);
633        for _ in 0..interfaces_count {
634            let interface = try!(self.read_u16());
635            interfaces.push(interface);
636        }
637        Result::Ok(interfaces)
638    }
639
640    fn read_constant_pool(self: &mut ClassReader<'a>) -> ParseResult<Vec<ConstantPoolInfo>> {
641        let cp_count = try!(self.read_u16()) - 1;
642        let mut cp: Vec<ConstantPoolInfo> = Vec::with_capacity(cp_count as usize);
643
644        let mut i = 0;
645        while i < cp_count {
646            let cp_info = try!(self.read_constant_pool_info());
647            let is_double_length = cp_info.is_double_length();
648
649            cp.push(cp_info);
650            if is_double_length {
651                cp.push(ConstantPoolInfo::Invalid);
652                i += 1;
653            }
654
655            i += 1;
656        }
657
658        Result::Ok(cp)
659    }
660
661    fn read_constant_pool_info(self: &mut ClassReader<'a>) -> ParseResult<ConstantPoolInfo> {
662        let tag = try!(self.read_u8());
663        debug!("read constant pool info tag {}", tag);
664        let info = match tag {
665            1 => {
666                let length = try!(self.read_u16());
667                let data = try!(self.read_bytes(length as u32));
668                let string = read_modified_utf8(&data.clone());
669                trace!("read {} utf8 bytes {:?} -> {}", length, data, string);
670                ConstantPoolInfo::Utf8(string)
671            },
672            3 => {
673                let value = try!(self.read_u32()) as i32;
674                ConstantPoolInfo::Integer(value)
675            },
676            4 => {
677                let value = try!(self.read_u32()) as f32;
678                ConstantPoolInfo::Float(value)
679            },
680            5 => {
681                let value = try!(self.read_u64()) as i64;
682                ConstantPoolInfo::Long(value)
683            },
684            6 => {
685                let value = try!(self.read_u64()) as f64;
686                ConstantPoolInfo::Double(value)
687            },
688            7 => {
689                let name_index = try!(self.read_u16());
690                ConstantPoolInfo::Class(name_index)
691            },
692            8 => {
693                let string_index = try!(self.read_u16());
694                ConstantPoolInfo::String(string_index)
695            },
696            9 => {
697                let class_index = try!(self.read_u16());
698                let name_and_type_index = try!(self.read_u16());
699                ConstantPoolInfo::Fieldref(class_index, name_and_type_index)
700            },
701            10 => {
702                let class_index = try!(self.read_u16());
703                let name_and_type_index = try!(self.read_u16());
704                ConstantPoolInfo::Methodref(class_index, name_and_type_index)
705            },
706            11 => {
707                let class_index = try!(self.read_u16());
708                let name_and_type_index = try!(self.read_u16());
709                ConstantPoolInfo::InterfaceMethodref(class_index, name_and_type_index)
710            },
711            12 => {
712                let name_index = try!(self.read_u16());
713                let descriptor_index = try!(self.read_u16());
714                ConstantPoolInfo::NameAndType(name_index, descriptor_index)
715            },
716            15 => {
717                let reference_kind = try!(self.read_u8());
718                let reference_index = try!(self.read_u16());
719                ConstantPoolInfo::MethodHandle(reference_kind, reference_index)
720            },
721            16 => {
722                let descriptor_index = try!(self.read_u16());
723                ConstantPoolInfo::MethodType(descriptor_index)
724            },
725            18 => {
726                let bootstrap_method_attr_index = try!(self.read_u16());
727                let name_and_type_index = try!(self.read_u16());
728                ConstantPoolInfo::InvokeDynamic(bootstrap_method_attr_index, name_and_type_index)
729            },
730            _ => {
731                let message = format!("unknown constant pool item with tag {}", tag);
732                return Result::Err(ParseError::Format(message));
733            }
734        };
735        Result::Ok(info)
736    }
737
738    fn read_bytes(self: &mut ClassReader<'a>, length: u32) -> ParseResult<Vec<u8>> {
739        let mut vec: Vec<u8> = Vec::with_capacity(length as usize);
740        try!(self.reader.by_ref().take(length as u64).read_to_end(&mut vec));
741
742        self.position += length as usize;
743        Result::Ok(vec)
744    }
745
746    fn read_u64(self: &mut ClassReader<'a>) -> ParseResult<u64> {
747        let mut buf: Vec<u8> = Vec::with_capacity(8);
748        try!(self.reader.by_ref().take(8).read_to_end(&mut buf));
749
750        self.position += 8;
751        Result::Ok((buf[0] as u64) << 56 | (buf[1] as u64) << 48
752                | (buf[2] as u64) << 40 | (buf[3] as u64) << 32
753                | (buf[4] as u64) << 24 | (buf[5] as u64) << 16
754                | (buf[6] as u64) << 8 | (buf[7] as u64))
755    }
756
757    fn read_u32(self: &mut ClassReader<'a>) -> ParseResult<u32> {
758        let mut buf: Vec<u8> = Vec::with_capacity(4);
759        try!(self.reader.by_ref().take(4).read_to_end(&mut buf));
760
761        self.position += 4;
762        Result::Ok((buf[0] as u32) << 24 | (buf[1] as u32) << 16
763                | (buf[2] as u32) << 8 | (buf[3] as u32))
764    }
765
766    fn read_u16(self: &mut ClassReader<'a>) -> ParseResult<u16> {
767        let mut buf: Vec<u8> = Vec::with_capacity(2);
768        try!(self.reader.by_ref().take(2).read_to_end(&mut buf));
769
770        self.position += 2;
771        Result::Ok((buf[0] as u16) << 8 | (buf[1] as u16))
772    }
773
774    fn read_u8(self: &mut ClassReader<'a>) -> ParseResult<u8> {
775        let mut buf: Vec<u8> = Vec::with_capacity(1);
776        try!(self.reader.by_ref().take(1).read_to_end(&mut buf));
777
778        self.position += 1;
779        Result::Ok(buf[0] as u8)
780    }
781
782}
783
784fn read_modified_utf8(buf: &Vec<u8>) -> String {
785    let mut string = String::with_capacity(buf.len());
786
787    let mut i = 0;
788    while i < buf.len() {
789        let b0 = buf[i] as u32;
790        let decoded_char = if (b0 >> 7) == 0 {
791            trace!("read byte {:08.b}", b0);
792            char::from_u32(b0)
793        } else if (b0 >> 5) == 0b110 {
794            i += 1;
795            let b1 = buf[i] as u32; // assert that (b1 >> 6) == 0b10
796            let code_point = ((b0 & 0b0001_1111) << 6)
797                    + (b1 & 0b0011_1111);
798            trace!("read bytes {:08.b} {:08.b} -> {:032.b}", b0, b1, code_point);
799            char::from_u32(code_point)
800        } else if (b0 >> 4) == 0b1110 {
801            i += 1;
802            let b1 = buf[i] as u32; // assert that (b1 >> 6) == 0b10
803            i += 1;
804            let b2 = buf[i] as u32; // assert that (b1 >> 6) == 0b10
805            let check_for_surrogate = i < (buf.len() - 2);
806            if (b0 == 0b11101101) && ((b1 >> 4) == 0b1010) && check_for_surrogate && (buf[i+1] == 0b1110_1101) { // surrogate pair
807                i += 1;
808                let b3 = buf[i] as u32; // assert that b3 == 0b1110_1101
809                i += 1;
810                let b4 = buf[i] as u32; // assert that (b4 >> 4) == b1011
811                i += 1;
812                let b5 = buf[i] as u32; // assert that (b5 >> 6) == b10
813                let code_point = 0b1_0000_0000_0000_0000
814                        + ((b1 & 0b0000_1111) << 16)
815                        + ((b2 & 0b0011_1111) << 10)
816                        + ((b4 & 0b0000_1111) << 6)
817                        + (b5 & 0x0011_1111);
818                trace!("read bytes {:08.b} {:08.b} {:08.b} {:08.b} {:08.b} {:08.b} -> {:032.b}", b0, b1, b2, b3, b4, b5, code_point);
819                trace!(" -> {} {:x}", code_point, code_point);
820                char::from_u32(code_point)
821            } else {
822                let code_point = ((b0 & 0b0000_1111) << 12)
823                        + ((b1 & 0b0011_1111) << 6)
824                        + (b2 & 0b0011_1111);
825                if ((code_point >= 0xD800) && (code_point <= 0xDBFF))
826                        || ((code_point >= 0xDC00) && (code_point <= 0xDFFF)) {
827                    info!("encountered surrogate code point {:x} which is invalid for UTF-8", code_point);
828                    Option::None
829                } else {
830                    trace!("read bytes {:08.b} {:08.b} {:08.b} -> {:032.b}", b0, b1, b2, code_point);
831                    trace!(" -> {} {:x}", code_point, code_point);
832                    char::from_u32(code_point)
833                }
834            }
835        } else {
836            Option::None
837        };
838        match decoded_char {
839            Option::None => string.push('\u{FFFD}'),
840            Option::Some(c) => string.push(c)
841        }
842        i += 1;
843    }
844    string
845}