1use crate::util::{Error, Result};
2use num_bigint::{BigInt, Sign};
3use num_traits::Zero;
4
5#[inline]
7pub fn pop_bool(stack: &mut Vec<Vec<u8>>) -> Result<bool> {
8 if stack.len() == 0 {
9 let msg = "Cannot pop bool, empty stack".to_string();
10 return Err(Error::ScriptError(msg));
11 }
12 let top = stack.pop().unwrap();
13 if top.len() > 4 {
15 let msg = format!("Cannot pop bool, len too long {}", top.len());
16 return Err(Error::ScriptError(msg));
17 }
18 Ok(decode_bool(&top))
19}
20
21#[inline]
23pub fn pop_num(stack: &mut Vec<Vec<u8>>) -> Result<i32> {
24 if stack.len() == 0 {
25 let msg = "Cannot pop num, empty stack".to_string();
26 return Err(Error::ScriptError(msg));
27 }
28 let top = stack.pop().unwrap();
29 if top.len() > 4 {
32 let msg = format!("Cannot pop num, len too long {}", top.len());
33 return Err(Error::ScriptError(msg));
34 }
35 Ok(decode_num(&top)? as i32)
36}
37
38#[inline]
40pub fn pop_bigint(stack: &mut Vec<Vec<u8>>) -> Result<BigInt> {
41 if stack.len() == 0 {
42 let msg = "Cannot pop bigint, empty stack".to_string();
43 return Err(Error::ScriptError(msg));
44 }
45 let mut top = stack.pop().unwrap();
46 Ok(decode_bigint(&mut top))
47}
48
49#[inline]
51pub fn decode_bool(s: &[u8]) -> bool {
52 if s.len() == 0 {
53 return false;
54 }
55 for i in 0..s.len() - 1 {
56 if s[i] != 0 {
57 return true;
58 }
59 }
60 s[s.len() - 1] & 127 != 0
61}
62
63#[inline]
65pub fn decode_num(s: &[u8]) -> Result<i64> {
66 let mut val = match s.len() {
67 0 => return Ok(0),
68 1 => (s[0] & 127) as i64,
69 2 => (((s[1] & 127) as i64) << 8) + ((s[0] as i64) << 0),
70 3 => (((s[2] & 127) as i64) << 16) + ((s[1] as i64) << 8) + ((s[0] as i64) << 0),
71 4 => {
72 (((s[3] & 127) as i64) << 24)
73 + ((s[2] as i64) << 16)
74 + ((s[1] as i64) << 8)
75 + ((s[0] as i64) << 0)
76 }
77 _ => {
78 for i in 4..s.len() - 1 {
79 if s[i] != 0 {
80 return Err(Error::ScriptError("Number too big".to_string()));
81 }
82 }
83 if s[s.len() - 1] & 127 != 0 {
84 return Err(Error::ScriptError("Number too big".to_string()));
85 }
86 ((s[3] as i64) << 24)
87 + ((s[2] as i64) << 16)
88 + ((s[1] as i64) << 8)
89 + ((s[0] as i64) << 0)
90 }
91 };
92 if s[s.len() - 1] & 128 != 0 {
93 val = 0 - val;
94 }
95 Ok(val)
96}
97
98#[inline]
100pub fn encode_num(val: i64) -> Result<Vec<u8>> {
101 if val > 2147483647 || val < -2147483647 {
103 return Err(Error::ScriptError("Number out of range".to_string()));
104 }
105 let (posval, negmask) = if val < 0 { (-val, 128) } else { (val, 0) };
106 if posval == 0 {
107 Ok(vec![])
108 } else if posval < 128 {
109 Ok(vec![(posval as u8) | negmask])
110 } else if posval < 32768 {
111 Ok(vec![(posval >> 0) as u8, ((posval >> 8) as u8) | negmask])
112 } else if posval < 8388608 {
113 Ok(vec![
114 (posval >> 0) as u8,
115 (posval >> 8) as u8,
116 ((posval >> 16) as u8) | negmask,
117 ])
118 } else {
119 Ok(vec![
120 (posval >> 0) as u8,
121 (posval >> 8) as u8,
122 (posval >> 16) as u8,
123 ((posval >> 24) as u8) | negmask,
124 ])
125 }
126}
127
128#[inline]
130pub fn decode_bigint(s: &mut [u8]) -> BigInt {
131 let len = s.len();
132 if s.len() == 0 {
133 return BigInt::zero();
134 }
135 let mut sign = Sign::Plus;
136 if s[len - 1] & 0x80 == 0x80 {
137 sign = Sign::Minus;
138 }
139 s[len - 1] &= !0x80;
140 BigInt::from_bytes_le(sign, &s)
141}
142
143#[inline]
145pub fn encode_bigint(val: BigInt) -> Vec<u8> {
146 let mut result = val.to_bytes_le();
147 if result.1[result.1.len() - 1] & 0x80 == 0x80 {
148 result.1.push(match result.0 {
149 Sign::Plus | Sign::NoSign => 0x00,
150 Sign::Minus => 0x80,
151 });
152 } else if result.0 == Sign::Minus {
153 let len = result.1.len();
154 result.1[len - 1] |= 0x80;
155 }
156 if result.1.len() == 1 && result.1[0] == 0 {
157 return vec![];
158 }
159 result.1
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 #[test]
167 fn decode_bool_tests() {
168 assert!(decode_bool(&[1]) == true);
169 assert!(decode_bool(&[255, 0, 0, 0]) == true);
170 assert!(decode_bool(&[0, 0, 0, 129]) == true);
171 assert!(decode_bool(&[0]) == false);
172 assert!(decode_bool(&[0, 0, 0, 0]) == false);
173 assert!(decode_bool(&[0, 0, 0, 128]) == false);
174 assert!(decode_bool(&[]) == false);
175 }
176
177 #[test]
178 fn pop_bool_tests() {
179 assert!(pop_bool(&mut vec![vec![1]]).unwrap() == true);
180 assert!(pop_bool(&mut vec![vec![0, 0, 0, 127]]).unwrap() == true);
181 assert!(pop_bool(&mut vec![vec![0, 0, 0, 127]]).unwrap() == true);
182 assert!(pop_bool(&mut vec![]).is_err());
183 assert!(pop_bool(&mut vec![vec![0, 0, 0, 0, 0]]).is_err());
184 assert!(pop_bool(&mut vec![vec![]]).unwrap() == false);
185 assert!(pop_bool(&mut vec![vec![0]]).unwrap() == false);
186 assert!(pop_bool(&mut vec![vec![0, 0, 0, 0]]).unwrap() == false);
187 assert!(pop_bool(&mut vec![vec![0, 0, 0, 128]]).unwrap() == false);
188 }
189
190 #[test]
191 fn encode_decode_num_tests() {
192 assert!(encode_num(2147483647).is_ok());
194 assert!(encode_num(-2147483647).is_ok());
195 assert!(encode_num(2147483648).is_err());
196 assert!(encode_num(-2147483648).is_err());
197 assert!(decode_num(&encode_num(0).unwrap()).unwrap() == 0);
199 assert!(decode_num(&encode_num(1).unwrap()).unwrap() == 1);
200 assert!(decode_num(&encode_num(-1).unwrap()).unwrap() == -1);
201 assert!(decode_num(&encode_num(1111).unwrap()).unwrap() == 1111);
202 assert!(decode_num(&encode_num(-1111).unwrap()).unwrap() == -1111);
203 assert!(decode_num(&encode_num(111111).unwrap()).unwrap() == 111111);
204 assert!(decode_num(&encode_num(-111111).unwrap()).unwrap() == -111111);
205 assert!(decode_num(&encode_num(2147483647).unwrap()).unwrap() == 2147483647);
206 assert!(decode_num(&encode_num(-2147483647).unwrap()).unwrap() == -2147483647);
207 }
208
209 #[test]
210 fn pop_num_tests() {
211 assert!(pop_num(&mut vec![vec![]]).unwrap() == 0);
212 assert!(pop_num(&mut vec![vec![1]]).unwrap() == 1);
213 assert!(pop_num(&mut vec![vec![129]]).unwrap() == -1);
214 assert!(pop_num(&mut vec![vec![0, 0, 0, 0]]).unwrap() == 0);
215 assert!(pop_num(&mut vec![vec![0, 0, 0, 0, 0]]).is_err());
216 }
217}