1313// limitations under the License.
1414use std:: collections:: HashSet ;
1515// use std::fmt;
16+ use std:: ops:: Deref ;
1617use std:: str;
1718
1819use strings:: * ;
@@ -21,7 +22,7 @@ use dalvik::{DalvikInstruction, parse_bytecode};
2122
2223const NO_INDEX : u32 = 0xFFFFFFFF ;
2324
24- fn type_list < ' a > ( dex : & ' a DexFile < ' a > , off : u32 , parse_cls_desc : bool ) -> Vec < & ' a bstr > {
25+ fn type_list < ' a > ( dex : & DexFileNoProtos < ' a > , off : u32 , parse_cls_desc : bool ) -> Vec < & ' a bstr > {
2526 if off == 0 { return Vec :: new ( ) ; }
2627
2728 let mut st = dex. stream ( off) ;
@@ -89,7 +90,7 @@ pub struct FieldId<'a> {
8990 pub desc : & ' a bstr ,
9091}
9192impl < ' a > FieldId < ' a > {
92- fn new ( dex : & ' a DexFile < ' a > , field_idx : u32 ) -> FieldId < ' a > {
93+ fn new ( dex : & DexFile < ' a > , field_idx : u32 ) -> FieldId < ' a > {
9394 let mut st = dex. stream ( dex. field_ids . off + field_idx* 8 ) ;
9495 FieldId {
9596 cname : dex. cls_type ( st. u16 ( ) as u32 ) ,
@@ -191,15 +192,30 @@ impl<'a> CodeItem<'a> {
191192 }
192193}
193194
195+ fn parse_prototype < ' a > ( dex : & DexFileNoProtos < ' a > , proto_idx : u32 ) -> ( BString , Vec < & ' a bstr > , & ' a bstr ) {
196+ let mut st = dex. stream ( dex. proto_ids . off + proto_idx * 12 ) ;
197+ st. u32 ( ) ;
198+ let return_type = dex. raw_type ( st. u32 ( ) ) ;
199+ let param_types = type_list ( dex, st. u32 ( ) , false ) ;
200+
201+ let mut desc = vec ! [ b'(' ] ;
202+ for part in & param_types {
203+ desc. extend_from_slice ( part) ;
204+ }
205+ desc. push ( b')' ) ;
206+ desc. extend_from_slice ( return_type) ;
207+ ( desc, param_types, return_type)
208+ }
209+
194210pub struct MethodId < ' a > {
195211 pub cname : & ' a bstr ,
196212 pub name : & ' a bstr ,
197- pub desc : BString ,
213+ pub desc : & ' a bstr ,
198214 pub return_type : & ' a bstr ,
199215 pub method_idx : u32 ,
200216
217+ proto_idx : u32 ,
201218 cdesc : & ' a bstr ,
202- param_types : Vec < & ' a bstr > ,
203219}
204220impl < ' a > MethodId < ' a > {
205221 fn new ( dex : & ' a DexFile < ' a > , method_idx : u32 ) -> MethodId < ' a > {
@@ -209,35 +225,24 @@ impl<'a> MethodId<'a> {
209225 let proto_idx = st. u16 ( ) as u32 ;
210226 let name = dex. string ( st. u32 ( ) ) ;
211227
212- st = dex. stream ( dex. proto_ids . off + proto_idx * 12 ) ;
213- st. u32 ( ) ;
214- let return_type = dex. raw_type ( st. u32 ( ) ) ;
215- let param_types = type_list ( dex, st. u32 ( ) , false ) ;
216-
217- let mut desc = vec ! [ b'(' ] ;
218- for part in & param_types {
219- desc. extend_from_slice ( part) ;
220- }
221- desc. push ( b')' ) ;
222- desc. extend_from_slice ( return_type) ;
223-
224228 MethodId {
225229 cname : cname,
226230 name : name,
227- desc : desc ,
228- return_type : return_type ,
231+ desc : & dex . proto ( proto_idx ) . 0 ,
232+ return_type : dex . proto ( proto_idx ) . 2 ,
229233 method_idx : method_idx,
234+ proto_idx : proto_idx,
230235
231236 cdesc : dex. raw_type ( cname_idx) ,
232- param_types : param_types,
233237 }
234238 }
235239
236- pub fn spaced_param_types ( & self , isstatic : bool ) -> Vec < Option < & ' a bstr > > {
237- let mut res = Vec :: with_capacity ( self . param_types . len ( ) + 1 ) ;
240+ pub fn spaced_param_types ( & self , dex : & DexFile < ' a > , isstatic : bool ) -> Vec < Option < & ' a bstr > > {
241+ let param_types = & dex. proto ( self . proto_idx ) . 1 ;
242+ let mut res = Vec :: with_capacity ( param_types. len ( ) + 1 ) ;
238243 if !isstatic { res. push ( Some ( self . cdesc ) ) ; }
239244
240- for param in & self . param_types {
245+ for param in param_types {
241246 res. push ( Some ( param) ) ;
242247 if param[ 0 ] == b'J' || param[ 0 ] == b'D' { res. push ( None ) ; }
243248 }
@@ -350,19 +355,17 @@ impl SizeOff {
350355 }
351356}
352357
353- #[ allow( dead_code) ] //data is not used
354- pub struct DexFile < ' a > {
358+ pub struct DexFileNoProtos < ' a > {
355359 raw : & ' a bstr ,
356360 string_ids : SizeOff ,
357361 type_ids : SizeOff ,
358362 proto_ids : SizeOff ,
359363 field_ids : SizeOff ,
360364 method_ids : SizeOff ,
361365 class_defs : SizeOff ,
362- data : SizeOff ,
363366}
364- impl < ' a > DexFile < ' a > {
365- pub fn new ( data : & bstr ) -> DexFile {
367+ impl < ' a > DexFileNoProtos < ' a > {
368+ pub fn new ( data : & bstr ) -> DexFileNoProtos {
366369 let mut stream = Reader ( data) ;
367370 stream. read ( 36 ) ;
368371 if stream. u32 ( ) != 0x70 {
@@ -375,24 +378,17 @@ impl<'a> DexFile<'a> {
375378 SizeOff :: new ( & mut stream) ;
376379 stream. u32 ( ) ;
377380
378- DexFile {
381+ DexFileNoProtos {
379382 raw : data,
380383 string_ids : SizeOff :: new ( & mut stream) ,
381384 type_ids : SizeOff :: new ( & mut stream) ,
382385 proto_ids : SizeOff :: new ( & mut stream) ,
383386 field_ids : SizeOff :: new ( & mut stream) ,
384387 method_ids : SizeOff :: new ( & mut stream) ,
385388 class_defs : SizeOff :: new ( & mut stream) ,
386- data : SizeOff :: new ( & mut stream) ,
389+ // data: SizeOff::new(&mut stream),
387390 }
388391 }
389- pub fn parse_classes ( & ' a self ) -> Vec < DexClass < ' a > > {
390- let mut classes = Vec :: with_capacity ( self . class_defs . size as usize ) ;
391- for i in 0 ..self . class_defs . size {
392- classes. push ( DexClass :: new ( & self , self . class_defs . off , i) ) ;
393- }
394- classes
395- }
396392
397393 fn stream ( & self , offset : u32 ) -> Reader < ' a > {
398394 Reader ( self . raw . split_at ( offset as usize ) . 1 )
@@ -401,29 +397,58 @@ impl<'a> DexFile<'a> {
401397 self . stream ( i) . u32 ( )
402398 }
403399
404- pub fn string ( & self , i : u32 ) -> & bstr {
400+ pub fn string ( & self , i : u32 ) -> & ' a bstr {
405401 let data_off = self . u32 ( self . string_ids . off + i* 4 ) ;
406402 let mut stream = self . stream ( data_off) ;
407403 stream. uleb128 ( ) ; // Ignore decoded length
408404 stream. cstr ( )
409405 }
410406
411- pub fn raw_type ( & self , i : u32 ) -> & bstr {
407+ pub fn raw_type ( & self , i : u32 ) -> & ' a bstr {
412408 assert ! ( i < self . type_ids. size) ;
413409 self . string ( self . u32 ( self . type_ids . off + i* 4 ) )
414410 }
415411
416- pub fn cls_type ( & self , i : u32 ) -> & bstr {
412+ pub fn cls_type ( & self , i : u32 ) -> & ' a bstr {
417413 let data = self . raw_type ( i) ;
418414 if data[ 0 ] == b'L' {
419415 & data[ 1 ..data. len ( ) -1 ]
420416 } else { data }
421417 }
422418
423- fn cls_type_opt ( & self , i : u32 ) -> Option < & bstr > {
419+ fn cls_type_opt ( & self , i : u32 ) -> Option < & ' a bstr > {
424420 if i == NO_INDEX { None } else { Some ( self . cls_type ( i) ) }
425421 }
422+ }
423+
424+ pub struct DexFile < ' a > {
425+ dex : DexFileNoProtos < ' a > ,
426+ protos : Vec < ( BString , Vec < & ' a bstr > , & ' a bstr ) > ,
427+ }
428+ impl < ' a > Deref for DexFile < ' a > {
429+ type Target = DexFileNoProtos < ' a > ;
430+ fn deref ( & self ) -> & Self :: Target { & self . dex }
431+ }
432+ impl < ' a > DexFile < ' a > {
433+ pub fn new ( data : & bstr ) -> DexFile {
434+ let dex = DexFileNoProtos :: new ( data) ;
435+ let n = dex. proto_ids . size ;
436+ let mut protos = Vec :: with_capacity ( n as usize ) ;
437+ for i in 0 ..n {
438+ protos. push ( parse_prototype ( & dex, i) ) ;
439+ }
440+ DexFile { dex : dex, protos : protos}
441+ }
442+
443+ pub fn parse_classes ( & ' a self ) -> Vec < DexClass < ' a > > {
444+ let mut classes = Vec :: with_capacity ( self . class_defs . size as usize ) ;
445+ for i in 0 ..self . class_defs . size {
446+ classes. push ( DexClass :: new ( & self , self . class_defs . off , i) ) ;
447+ }
448+ classes
449+ }
426450
427451 pub fn field_id ( & self , i : u32 ) -> FieldId { FieldId :: new ( self , i) }
428452 pub fn method_id ( & self , i : u32 ) -> MethodId { MethodId :: new ( self , i) }
429- }
453+ fn proto ( & self , i : u32 ) -> & ( BString , Vec < & ' a bstr > , & ' a bstr ) { & self . protos [ i as usize ] }
454+ }
0 commit comments