@@ -467,37 +467,44 @@ pub mod reader {
467
467
f ( & d. data [ d. start ..d. end ] )
468
468
}
469
469
470
-
471
470
pub fn doc_as_u8 ( d : Doc ) -> u8 {
472
471
assert_eq ! ( d. end, d. start + 1 ) ;
473
472
d. data [ d. start ]
474
473
}
475
474
476
- pub fn doc_as_u16 ( d : Doc ) -> u16 {
477
- assert_eq ! ( d. end, d. start + 2 ) ;
478
- let mut b = [ 0 ; 2 ] ;
479
- bytes:: copy_memory ( & d. data [ d. start ..d. end ] , & mut b) ;
480
- unsafe { ( * ( b. as_ptr ( ) as * const u16 ) ) . to_be ( ) }
481
- }
482
-
483
- pub fn doc_as_u32 ( d : Doc ) -> u32 {
484
- assert_eq ! ( d. end, d. start + 4 ) ;
485
- let mut b = [ 0 ; 4 ] ;
486
- bytes:: copy_memory ( & d. data [ d. start ..d. end ] , & mut b) ;
487
- unsafe { ( * ( b. as_ptr ( ) as * const u32 ) ) . to_be ( ) }
488
- }
489
-
490
475
pub fn doc_as_u64 ( d : Doc ) -> u64 {
491
- assert_eq ! ( d. end, d. start + 8 ) ;
492
- let mut b = [ 0 ; 8 ] ;
493
- bytes:: copy_memory ( & d. data [ d. start ..d. end ] , & mut b) ;
494
- unsafe { ( * ( b. as_ptr ( ) as * const u64 ) ) . to_be ( ) }
476
+ if d. end >= 8 {
477
+ // For performance, we read 8 big-endian bytes,
478
+ // and mask off the junk if there is any. This
479
+ // obviously won't work on the first 8 bytes
480
+ // of a file - we will fall of the start
481
+ // of the page and segfault.
482
+
483
+ let mut b = [ 0 ; 8 ] ;
484
+ bytes:: copy_memory ( & d. data [ d. end -8 ..d. end ] , & mut b) ;
485
+ let data = unsafe { ( * ( b. as_ptr ( ) as * const u64 ) ) . to_be ( ) } ;
486
+ let len = d. end - d. start ;
487
+ if len < 8 {
488
+ data & ( ( 1 <<( len* 8 ) ) -1 )
489
+ } else {
490
+ data
491
+ }
492
+ } else {
493
+ let mut result = 0 ;
494
+ for b in & d. data [ d. start ..d. end ] {
495
+ result = ( result<<8 ) + ( * b as u64 ) ;
496
+ }
497
+ result
498
+ }
495
499
}
496
500
497
- pub fn doc_as_i8 ( d : Doc ) -> i8 { doc_as_u8 ( d) as i8 }
498
- pub fn doc_as_i16 ( d : Doc ) -> i16 { doc_as_u16 ( d) as i16 }
499
- pub fn doc_as_i32 ( d : Doc ) -> i32 { doc_as_u32 ( d) as i32 }
500
- pub fn doc_as_i64 ( d : Doc ) -> i64 { doc_as_u64 ( d) as i64 }
501
+ #[ inline] pub fn doc_as_u16 ( d : Doc ) -> u16 { doc_as_u64 ( d) as u16 }
502
+ #[ inline] pub fn doc_as_u32 ( d : Doc ) -> u32 { doc_as_u64 ( d) as u32 }
503
+
504
+ #[ inline] pub fn doc_as_i8 ( d : Doc ) -> i8 { doc_as_u8 ( d) as i8 }
505
+ #[ inline] pub fn doc_as_i16 ( d : Doc ) -> i16 { doc_as_u16 ( d) as i16 }
506
+ #[ inline] pub fn doc_as_i32 ( d : Doc ) -> i32 { doc_as_u32 ( d) as i32 }
507
+ #[ inline] pub fn doc_as_i64 ( d : Doc ) -> i64 { doc_as_u64 ( d) as i64 }
501
508
502
509
pub struct Decoder < ' a > {
503
510
parent : Doc < ' a > ,
@@ -996,35 +1003,43 @@ pub mod writer {
996
1003
997
1004
pub fn wr_tagged_u64 ( & mut self , tag_id : usize , v : u64 ) -> EncodeResult {
998
1005
let bytes: [ u8 ; 8 ] = unsafe { mem:: transmute ( v. to_be ( ) ) } ;
999
- self . wr_tagged_bytes ( tag_id, & bytes)
1006
+ // tagged integers are emitted in big-endian, with no
1007
+ // leading zeros.
1008
+ let leading_zero_bytes = v. leading_zeros ( ) /8 ;
1009
+ self . wr_tagged_bytes ( tag_id, & bytes[ leading_zero_bytes as usize ..] )
1000
1010
}
1001
1011
1002
- pub fn wr_tagged_u32 ( & mut self , tag_id : usize , v : u32 ) -> EncodeResult {
1003
- let bytes : [ u8 ; 4 ] = unsafe { mem :: transmute ( v . to_be ( ) ) } ;
1004
- self . wr_tagged_bytes ( tag_id, & bytes )
1012
+ # [ inline ]
1013
+ pub fn wr_tagged_u32 ( & mut self , tag_id : usize , v : u32 ) -> EncodeResult {
1014
+ self . wr_tagged_u64 ( tag_id, v as u64 )
1005
1015
}
1006
1016
1017
+ #[ inline]
1007
1018
pub fn wr_tagged_u16 ( & mut self , tag_id : usize , v : u16 ) -> EncodeResult {
1008
- let bytes: [ u8 ; 2 ] = unsafe { mem:: transmute ( v. to_be ( ) ) } ;
1009
- self . wr_tagged_bytes ( tag_id, & bytes)
1019
+ self . wr_tagged_u64 ( tag_id, v as u64 )
1010
1020
}
1011
1021
1022
+ #[ inline]
1012
1023
pub fn wr_tagged_u8 ( & mut self , tag_id : usize , v : u8 ) -> EncodeResult {
1013
1024
self . wr_tagged_bytes ( tag_id, & [ v] )
1014
1025
}
1015
1026
1027
+ #[ inline]
1016
1028
pub fn wr_tagged_i64 ( & mut self , tag_id : usize , v : i64 ) -> EncodeResult {
1017
1029
self . wr_tagged_u64 ( tag_id, v as u64 )
1018
1030
}
1019
1031
1032
+ #[ inline]
1020
1033
pub fn wr_tagged_i32 ( & mut self , tag_id : usize , v : i32 ) -> EncodeResult {
1021
1034
self . wr_tagged_u32 ( tag_id, v as u32 )
1022
1035
}
1023
1036
1037
+ #[ inline]
1024
1038
pub fn wr_tagged_i16 ( & mut self , tag_id : usize , v : i16 ) -> EncodeResult {
1025
1039
self . wr_tagged_u16 ( tag_id, v as u16 )
1026
1040
}
1027
1041
1042
+ #[ inline]
1028
1043
pub fn wr_tagged_i8 ( & mut self , tag_id : usize , v : i8 ) -> EncodeResult {
1029
1044
self . wr_tagged_bytes ( tag_id, & [ v as u8 ] )
1030
1045
}
0 commit comments