]>
git.proxmox.com Git - rustc.git/blob - src/libserialize/leb128.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 pub fn write_to_vec(vec
: &mut Vec
<u8>, position
: &mut usize, byte
: u8) {
13 if *position
== vec
.len() {
16 vec
[*position
] = byte
;
22 pub fn write_unsigned_leb128(out
: &mut Vec
<u8>, start_position
: usize, mut value
: u64) -> usize {
23 let mut position
= start_position
;
25 let mut byte
= (value
& 0x7F) as u8;
31 write_to_vec(out
, &mut position
, byte
);
38 return position
- start_position
;
42 pub fn read_unsigned_leb128(data
: &[u8], start_position
: usize) -> (u64, usize) {
45 let mut position
= start_position
;
47 let byte
= data
[position
];
49 result
|= ((byte
& 0x7F) as u64) << shift
;
50 if (byte
& 0x80) == 0 {
56 (result
, position
- start_position
)
60 pub fn write_signed_leb128(out
: &mut Vec
<u8>, start_position
: usize, mut value
: i64) -> usize {
61 let mut position
= start_position
;
64 let mut byte
= (value
as u8) & 0x7f;
66 let more
= !((((value
== 0) && ((byte
& 0x40) == 0)) ||
67 ((value
== -1) && ((byte
& 0x40) != 0))));
69 byte
|= 0x80; // Mark this byte to show that more bytes will follow.
72 write_to_vec(out
, &mut position
, byte
);
79 return position
- start_position
;
83 pub fn read_signed_leb128(data
: &[u8], start_position
: usize) -> (i64, usize) {
86 let mut position
= start_position
;
90 byte
= data
[position
];
92 result
|= ((byte
& 0x7F) as i64) << shift
;
95 if (byte
& 0x80) == 0 {
100 if (shift
< 64) && ((byte
& 0x40) != 0) {
102 result
|= -(1i64 << shift
);
105 (result
, position
- start_position
)
109 fn test_unsigned_leb128() {
110 let mut stream
= Vec
::with_capacity(10000);
113 let pos
= stream
.len();
114 let bytes_written
= write_unsigned_leb128(&mut stream
, pos
, 3 << x
);
115 assert_eq
!(stream
.len(), pos
+ bytes_written
);
118 let mut position
= 0;
120 let expected
= 3 << x
;
121 let (actual
, bytes_read
) = read_unsigned_leb128(&stream
, position
);
122 assert_eq
!(expected
, actual
);
123 position
+= bytes_read
;
125 assert_eq
!(stream
.len(), position
);
129 fn test_signed_leb128() {
130 let mut values
= Vec
::new();
134 values
.push(i
* 123457i64);
138 let mut stream
= Vec
::new();
141 let pos
= stream
.len();
142 let bytes_written
= write_signed_leb128(&mut stream
, pos
, x
);
143 assert_eq
!(stream
.len(), pos
+ bytes_written
);
148 let (value
, bytes_read
) = read_signed_leb128(&mut stream
, pos
);
150 assert_eq
!(x
, value
);
152 assert_eq
!(pos
, stream
.len());