@@ -11,55 +11,60 @@ mod gps_data_codec {
1111 offset : u32 ,
1212 }
1313
14- fn decode_unsigned_value_from_string ( encoded : & [ u8 ] , offset : u32 ) -> DecodingResult {
15- let mut value: i64 = 0 ;
16- let mut consumed: u32 = 0 ;
17- let mut byte: u8 = 0 ;
18- while consumed == 0 || byte >= 0x20 {
19- byte = encoded[ ( consumed + offset) as usize ] - 63 ;
20- value |= ( ( byte & 0x1f ) as i64 ) << ( consumed * 5 ) ;
21- consumed += 1 ;
22- }
23- DecodingResult {
24- value,
25- offset : offset + consumed,
14+ fn decode_unsigned_value_from_string ( slice : & [ u8 ] , offset : u32 ) -> DecodingResult {
15+ let mut result: i64 = 0 ;
16+ let mut shift = 0 ;
17+ let mut position: u32 = offset;
18+ loop {
19+ let byte = slice[ position as usize ] - 63 ;
20+ position += 1 ;
21+ if ( byte & 0x20 ) == 0 {
22+ result |= ( byte as i64 ) << shift;
23+ return DecodingResult {
24+ value : result,
25+ offset : position,
26+ }
27+ } else {
28+ result |= ( ( byte & 0x1f ) as i64 ) << shift;
29+ }
30+ shift += 5
2631 }
2732 }
2833
2934 fn decode_signed_value_from_string ( encoded : & [ u8 ] , offset : u32 ) -> DecodingResult {
3035 let tmp_result: DecodingResult = decode_unsigned_value_from_string ( encoded, offset) ;
31- let tmp_value: i64 = tmp_result. value ;
32- if tmp_value & 1 == 1 {
36+ if tmp_result. value & 1 == 1 {
3337 DecodingResult {
34- value : !( tmp_value >> 1 ) ,
38+ value : !( tmp_result . value >> 1 ) ,
3539 offset : tmp_result. offset ,
3640 }
3741 } else {
3842 DecodingResult {
39- value : tmp_value >> 1 ,
43+ value : tmp_result . value >> 1 ,
4044 offset : tmp_result. offset ,
4145 }
4246 }
4347 }
4448
45- fn encode_unsigned_number ( num : u64 ) -> Vec < u8 > {
46- let mut encoded: Vec < u8 > = vec ! [ ] ;
47- let mut tmp: u64 = num;
48- while tmp >= 0x20 {
49- encoded. push ( ( 0x20 | ( tmp as u8 & 0x1f ) ) + 63 ) ;
50- tmp >>= 5 ;
49+ fn encode_unsigned_number ( out : & mut Vec < u8 > , mut num : u64 ) {
50+ loop {
51+ if num < 0x20 {
52+ out. push ( num as u8 + 63 ) ;
53+ break
54+ } else {
55+ out. push ( ( ( num as u8 & 0x1f ) | 0x20 ) + 63 ) ;
56+ num >>= 5 ;
57+ }
5158 }
52- encoded. push ( tmp as u8 + 63 ) ;
53- encoded
5459 }
5560
56- fn encode_signed_number ( num : i64 ) -> Vec < u8 > {
61+ fn encode_signed_number ( out : & mut Vec < u8 > , num : i64 ) {
5762 let mut sgn_num: i64 = num << 1 ;
5863 if num < 0 {
5964 sgn_num = !sgn_num;
6065 }
6166 let unsigned_num = sgn_num as u64 ;
62- encode_unsigned_number ( unsigned_num)
67+ encode_unsigned_number ( out , unsigned_num) ;
6368 }
6469
6570 const YEAR2010 : i64 = 1262304000 ;
@@ -108,16 +113,16 @@ mod gps_data_codec {
108113 prev_longitude += longitude_diff;
109114
110115 if is_first {
111- output . append ( & mut encode_signed_number ( timestamp_diff) ) ;
116+ encode_signed_number ( & mut output , timestamp_diff) ;
112117 is_first = false ;
113118 } else {
114119 if * timestamp < prev_timestamp {
115120 return Err ( PyValueError :: new_err ( "Input data is not sorted" ) ) ;
116121 }
117- output . append ( & mut encode_unsigned_number ( timestamp_diff as u64 ) ) ;
122+ encode_unsigned_number ( & mut output , timestamp_diff as u64 ) ;
118123 }
119- output . append ( & mut encode_signed_number ( latitude_diff) ) ;
120- output . append ( & mut encode_signed_number ( longitude_diff) ) ;
124+ encode_signed_number ( & mut output , latitude_diff) ;
125+ encode_signed_number ( & mut output , longitude_diff) ;
121126 }
122127 Ok ( unsafe { String :: from_utf8_unchecked ( output) } )
123128 }
0 commit comments