bitwarden_encoding/
chunked.rs1use data_encoding::Encoding;
2
3pub(crate) fn chunked_encode(encoding: &Encoding, data: &[u8]) -> String {
8 chunked_encode_with_limit(encoding, data, usize::MAX / 512)
9}
10
11fn chunked_encode_with_limit(encoding: &Encoding, data: &[u8], max_safe: usize) -> String {
12 let mut output = String::with_capacity(data.len() / 3 * 4 + 4);
14
15 let mut enc = encoding.new_encoder(&mut output);
16 for chunk in data.chunks(max_safe) {
17 enc.append(chunk);
18 }
19 enc.finalize();
20 output
21}
22
23#[cfg(test)]
24mod tests {
25 use data_encoding::{BASE64, BASE64URL_NOPAD};
26
27 use super::*;
28
29 #[test]
30 fn single_chunk_matches_direct_encode() {
31 let data = b"Hello, World!";
32 assert_eq!(chunked_encode(&BASE64, data), BASE64.encode(data));
33 assert_eq!(
34 chunked_encode(&BASE64URL_NOPAD, data),
35 BASE64URL_NOPAD.encode(data)
36 );
37 }
38
39 #[test]
40 fn multi_chunk_matches_direct_encode_base64() {
41 let data: Vec<u8> = (0..30).collect();
44 let expected = BASE64.encode(&data);
45 let result = chunked_encode_with_limit(&BASE64, &data, 6);
46 assert_eq!(result, expected);
47 }
48
49 #[test]
50 fn multi_chunk_matches_direct_encode_base64url() {
51 let data: Vec<u8> = (0..30).collect();
52 let expected = BASE64URL_NOPAD.encode(&data);
53 let result = chunked_encode_with_limit(&BASE64URL_NOPAD, &data, 6);
54 assert_eq!(result, expected);
55 }
56
57 #[test]
58 fn unaligned_chunk_boundary() {
59 let data: Vec<u8> = (0..30).collect();
62 let expected = BASE64.encode(&data);
63 let result = chunked_encode_with_limit(&BASE64, &data, 7);
64 assert_eq!(result, expected);
65 }
66
67 #[test]
68 fn input_exactly_one_chunk() {
69 let data: Vec<u8> = (0..6).collect();
70 let expected = BASE64.encode(&data);
71 let result = chunked_encode_with_limit(&BASE64, &data, 6);
72 assert_eq!(result, expected);
73 }
74
75 #[test]
76 fn input_one_byte_over_chunk() {
77 let data: Vec<u8> = (0..7).collect();
78 let expected = BASE64.encode(&data);
79 let result = chunked_encode_with_limit(&BASE64, &data, 6);
80 assert_eq!(result, expected);
81 }
82
83 #[test]
84 fn empty_input() {
85 assert_eq!(chunked_encode_with_limit(&BASE64, &[], 6), "");
86 assert_eq!(chunked_encode_with_limit(&BASE64URL_NOPAD, &[], 6), "");
87 }
88}