@@ -19,6 +19,7 @@ use {ArrayLength, GenericArray};
1919use core:: fmt;
2020use core:: ops:: Add ;
2121use core:: str;
22+ use core:: cmp:: min;
2223use typenum:: * ;
2324
2425static LOWER_CHARS : & ' static [ u8 ] = b"0123456789abcdef" ;
@@ -30,28 +31,32 @@ where
3031 <T as Add < T > >:: Output : ArrayLength < u8 > ,
3132{
3233 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
33- let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) ) ;
34+ let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) * 2 ) ;
35+ let max_hex = ( max_digits >> 1 ) + ( max_digits & 1 ) ;
3436
3537 if T :: to_usize ( ) < 1024 {
3638 // For small arrays use a stack allocated
3739 // buffer of 2x number of bytes
3840 let mut res = GenericArray :: < u8 , Sum < T , T > > :: default ( ) ;
3941
40- for ( i, c) in self . iter ( ) . take ( max_digits ) . enumerate ( ) {
42+ for ( i, c) in self . iter ( ) . take ( max_hex ) . enumerate ( ) {
4143 res[ i * 2 ] = LOWER_CHARS [ ( c >> 4 ) as usize ] ;
4244 res[ i * 2 + 1 ] = LOWER_CHARS [ ( c & 0xF ) as usize ] ;
4345 }
44- f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits * 2 ] ) } ) ?;
46+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits] ) } ) ?;
4547 } else {
4648 // For large array use chunks of up to 1024 bytes (2048 hex chars)
4749 let mut buf = [ 0u8 ; 2048 ] ;
50+ let mut digits_left = max_digits;
4851
49- for chunk in self [ ..max_digits ] . chunks ( 1024 ) {
52+ for chunk in self [ ..max_hex ] . chunks ( 1024 ) {
5053 for ( i, c) in chunk. iter ( ) . enumerate ( ) {
5154 buf[ i * 2 ] = LOWER_CHARS [ ( c >> 4 ) as usize ] ;
5255 buf[ i * 2 + 1 ] = LOWER_CHARS [ ( c & 0xF ) as usize ] ;
5356 }
54- f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..chunk. len ( ) * 2 ] ) } ) ?;
57+ let n = min ( chunk. len ( ) * 2 , digits_left) ;
58+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..n] ) } ) ?;
59+ digits_left -= n;
5560 }
5661 }
5762 Ok ( ( ) )
@@ -64,28 +69,32 @@ where
6469 <T as Add < T > >:: Output : ArrayLength < u8 > ,
6570{
6671 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
67- let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) ) ;
72+ let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) * 2 ) ;
73+ let max_hex = ( max_digits >> 1 ) + ( max_digits & 1 ) ;
6874
6975 if T :: to_usize ( ) < 1024 {
7076 // For small arrays use a stack allocated
7177 // buffer of 2x number of bytes
7278 let mut res = GenericArray :: < u8 , Sum < T , T > > :: default ( ) ;
7379
74- for ( i, c) in self . iter ( ) . take ( max_digits ) . enumerate ( ) {
80+ for ( i, c) in self . iter ( ) . take ( max_hex ) . enumerate ( ) {
7581 res[ i * 2 ] = UPPER_CHARS [ ( c >> 4 ) as usize ] ;
7682 res[ i * 2 + 1 ] = UPPER_CHARS [ ( c & 0xF ) as usize ] ;
7783 }
78- f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits * 2 ] ) } ) ?;
84+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits] ) } ) ?;
7985 } else {
8086 // For large array use chunks of up to 1024 bytes (2048 hex chars)
8187 let mut buf = [ 0u8 ; 2048 ] ;
88+ let mut digits_left = max_digits;
8289
83- for chunk in self [ ..max_digits ] . chunks ( 1024 ) {
90+ for chunk in self [ ..max_hex ] . chunks ( 1024 ) {
8491 for ( i, c) in chunk. iter ( ) . enumerate ( ) {
8592 buf[ i * 2 ] = UPPER_CHARS [ ( c >> 4 ) as usize ] ;
8693 buf[ i * 2 + 1 ] = UPPER_CHARS [ ( c & 0xF ) as usize ] ;
8794 }
88- f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..chunk. len ( ) * 2 ] ) } ) ?;
95+ let n = min ( chunk. len ( ) * 2 , digits_left) ;
96+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..n] ) } ) ?;
97+ digits_left -= n;
8998 }
9099 }
91100 Ok ( ( ) )
0 commit comments