ckb_script_ipc_common/
vlq.rs1use alloc::vec::Vec;
2
3use crate::error::IpcError;
4pub fn vlq_encode(mut value: u64) -> Vec<u8> {
6 let mut buffer = Vec::new();
7 loop {
8 let mut byte = (value & 0x7F) as u8;
9 value >>= 7;
10 if value != 0 {
11 byte |= 0x80;
12 }
13 buffer.push(byte);
14 if value == 0 {
15 break;
16 }
17 }
18 buffer
19}
20
21pub fn vlq_decode(bytes: &[u8]) -> Result<u64, IpcError> {
23 let mut value = 0u64;
24 let mut shift = 0;
25 for &byte in bytes {
26 value |= ((byte & 0x7F) as u64) << shift;
27 if byte & 0x80 == 0 {
28 return Ok(value);
29 }
30 shift += 7;
31 if shift >= 64 {
32 return Err(IpcError::DecodeVlqOverflow);
33 }
34 }
35 Err(IpcError::IncompleteVlqSeq)
36}
37
38#[cfg(test)]
39mod tests {
40 use alloc::vec;
41
42 use super::*;
43
44 #[test]
45 fn test_vlq_encode() {
46 assert_eq!(vlq_encode(0), vec![0]);
47 assert_eq!(vlq_encode(127), vec![127]);
48 assert_eq!(vlq_encode(128), vec![128, 1]);
49 assert_eq!(vlq_encode(16384), vec![128, 128, 1]);
50 assert_eq!(
51 vlq_encode(u64::MAX),
52 vec![255, 255, 255, 255, 255, 255, 255, 255, 255, 1]
53 );
54 }
55
56 #[test]
57 fn test_vlq_decode() {
58 assert_eq!(vlq_decode(&[0]).unwrap(), 0);
59 assert_eq!(vlq_decode(&[127]).unwrap(), 127);
60 assert_eq!(vlq_decode(&[128, 1]).unwrap(), 128);
61 assert_eq!(vlq_decode(&[128, 128, 1]).unwrap(), 16384);
62 assert_eq!(
63 vlq_decode(&[255, 255, 255, 255, 255, 255, 255, 255, 255, 1]).unwrap(),
64 u64::MAX
65 );
66 }
67
68 #[test]
69 fn test_vlq_encode_decode_roundtrip() {
70 let test_values = vec![0, 1, 127, 128, 16383, 16384, u64::MAX / 2, u64::MAX];
71 for value in test_values {
72 let encoded = vlq_encode(value);
73 let decoded = vlq_decode(&encoded).unwrap();
74 assert_eq!(decoded, value, "Roundtrip failed for value: {}", value);
75 }
76 }
77
78 #[test]
79 fn test_vlq_decode_errors() {
80 assert!(matches!(
81 vlq_decode(&[128, 128, 128, 128, 128, 128, 128, 128, 128, 128]),
82 Err(IpcError::DecodeVlqOverflow)
83 ));
84 assert!(matches!(
85 vlq_decode(&[128]),
86 Err(IpcError::IncompleteVlqSeq)
87 ));
88 }
89}