1use super::{CONTINUATION_BIT, SIGN_BIT, low_bits_of_byte};
2use std::fmt;
3use std::io;
4use bytes::Buf;
5
6pub trait LEB128Read {
8 fn read_signed(&mut self) -> Result<(i64, usize), Error>;
11
12 fn read_unsigned(&mut self) -> Result<(u64, usize), Error>;
15}
16
17#[derive(Debug)]
20pub enum Error {
21 IoError(io::Error),
23 Overflow,
25}
26
27impl From<io::Error> for Error {
28 fn from(e: io::Error) -> Self {
29 Error::IoError(e)
30 }
31}
32
33impl fmt::Display for Error {
34 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
35 write!(f,
36 "leb128::read::Error: {}",
37 ::std::error::Error::description(self))
38 }
39}
40
41impl ::std::error::Error for Error {
42 fn description(&self) -> &str {
43 match *self {
44 Error::IoError(ref e) => e.description(),
45 Error::Overflow => "The number being read is larger than can be represented",
46 }
47 }
48
49 fn cause(&self) -> Option<&::std::error::Error> {
50 match *self {
51 Error::IoError(ref e) => Some(e),
52 Error::Overflow => None,
53 }
54 }
55}
56
57impl<R> LEB128Read for R
58 where R: Buf
59{
60 fn read_signed(&mut self) -> Result<(i64, usize), Error> {
61 let mut result = 0;
62 let mut shift = 0;
63 let size = 64;
64 let mut byte;
65 let mut bytes_read = 0;
66
67 loop {
68 if !self.has_remaining() {
69 return Err(Error::IoError(io::Error::new(io::ErrorKind::UnexpectedEof, "Not enough data")))
70 }
71
72 byte = self.get_u8();
73 bytes_read += 1;
74 if shift == 63 && byte != 0x00 && byte != 0x7f {
75 return Err(Error::Overflow);
76 }
77
78 let low_bits = low_bits_of_byte(byte) as i64;
79 result |= low_bits << shift;
80 shift += 7;
81
82 if byte & CONTINUATION_BIT == 0 {
83 break;
84 }
85 }
86
87 if shift < size && (SIGN_BIT & byte) == SIGN_BIT {
88 result |= !0 << shift;
90 }
91
92 Ok((result, bytes_read))
93 }
94
95 fn read_unsigned(&mut self) -> Result<(u64, usize), Error> {
96 let mut result = 0;
97 let mut shift = 0;
98 let mut bytes_read = 0;
99
100 loop {
101 if !self.has_remaining() {
102 return Err(Error::IoError(io::Error::new(io::ErrorKind::UnexpectedEof, "Not enough data")))
103 }
104
105 let byte = self.get_u8();
106 bytes_read += 1;
107
108 if shift == 63 && byte != 0x00 && byte != 0x01 {
109 return Err(Error::Overflow);
110 }
111
112 let low_bits = low_bits_of_byte(byte) as u64;
113 result |= low_bits << shift;
114
115 if byte & CONTINUATION_BIT == 0 {
116 return Ok((result, bytes_read));
117 }
118
119 shift += 7;
120 }
121 }
122}