1use std::io::{self, Write};
2
3pub const COPY_MAX: usize = 48 * 1024;
4
5pub fn copy(text: &str) -> bool {
6 if text.len() > COPY_MAX {
7 return false;
8 }
9 let mut out = io::stdout();
10 write!(out, "\x1b]52;c;{}\x07", base64(text.as_bytes())).is_ok() && out.flush().is_ok()
11}
12
13pub fn base64(bytes: &[u8]) -> String {
14 const ABC: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
15 let mut out = String::with_capacity(bytes.len().div_ceil(3) * 4);
16 for chunk in bytes.chunks(3) {
17 let b = [
18 chunk[0],
19 *chunk.get(1).unwrap_or(&0),
20 *chunk.get(2).unwrap_or(&0),
21 ];
22 let n = (u32::from(b[0]) << 16) | (u32::from(b[1]) << 8) | u32::from(b[2]);
23 for k in 0..4 {
24 if k <= chunk.len() {
25 out.push(ABC[(n >> (18 - 6 * k) & 63) as usize] as char);
26 } else {
27 out.push('=');
28 }
29 }
30 }
31 out
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn base64_matches_the_standard_alphabet() {
40 assert_eq!(base64(b""), "");
41 assert_eq!(base64(b"f"), "Zg==");
42 assert_eq!(base64(b"fo"), "Zm8=");
43 assert_eq!(base64(b"foo"), "Zm9v");
44 assert_eq!(base64("panic: ΓΌ".as_bytes()), "cGFuaWM6IMO8");
45 }
46}