summaryrefslogtreecommitdiffstats
path: root/third_party/rust/base64/examples
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/base64/examples
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--third_party/rust/base64/examples/base64.rs89
-rw-r--r--third_party/rust/base64/examples/make_tables.rs179
2 files changed, 268 insertions, 0 deletions
diff --git a/third_party/rust/base64/examples/base64.rs b/third_party/rust/base64/examples/base64.rs
new file mode 100644
index 0000000000..cba745b05e
--- /dev/null
+++ b/third_party/rust/base64/examples/base64.rs
@@ -0,0 +1,89 @@
+use std::fs::File;
+use std::io::{self, Read};
+use std::path::PathBuf;
+use std::process;
+use std::str::FromStr;
+
+use base64::{read, write};
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+enum CharacterSet {
+ Standard,
+ UrlSafe,
+}
+
+impl Default for CharacterSet {
+ fn default() -> Self {
+ CharacterSet::Standard
+ }
+}
+
+impl Into<base64::Config> for CharacterSet {
+ fn into(self) -> base64::Config {
+ match self {
+ CharacterSet::Standard => base64::STANDARD,
+ CharacterSet::UrlSafe => base64::URL_SAFE,
+ }
+ }
+}
+
+impl FromStr for CharacterSet {
+ type Err = String;
+ fn from_str(s: &str) -> Result<CharacterSet, String> {
+ match s {
+ "standard" => Ok(CharacterSet::Standard),
+ "urlsafe" => Ok(CharacterSet::UrlSafe),
+ _ => Err(format!("charset '{}' unrecognized", s)),
+ }
+ }
+}
+
+/// Base64 encode or decode FILE (or standard input), to standard output.
+#[derive(Debug, StructOpt)]
+struct Opt {
+ /// decode data
+ #[structopt(short = "d", long = "decode")]
+ decode: bool,
+ /// The character set to choose. Defaults to the standard base64 character set.
+ /// Supported character sets include "standard" and "urlsafe".
+ #[structopt(long = "charset")]
+ charset: Option<CharacterSet>,
+ /// The file to encode/decode.
+ #[structopt(parse(from_os_str))]
+ file: Option<PathBuf>,
+}
+
+fn main() {
+ let opt = Opt::from_args();
+ let stdin;
+ let mut input: Box<dyn Read> = match opt.file {
+ None => {
+ stdin = io::stdin();
+ Box::new(stdin.lock())
+ }
+ Some(ref f) if f.as_os_str() == "-" => {
+ stdin = io::stdin();
+ Box::new(stdin.lock())
+ }
+ Some(f) => Box::new(File::open(f).unwrap()),
+ };
+ let config = opt.charset.unwrap_or_default().into();
+ let stdout = io::stdout();
+ let mut stdout = stdout.lock();
+ let r = if opt.decode {
+ let mut decoder = read::DecoderReader::new(&mut input, config);
+ io::copy(&mut decoder, &mut stdout)
+ } else {
+ let mut encoder = write::EncoderWriter::new(&mut stdout, config);
+ io::copy(&mut input, &mut encoder)
+ };
+ if let Err(e) = r {
+ eprintln!(
+ "Base64 {} failed with {}",
+ if opt.decode { "decode" } else { "encode" },
+ e
+ );
+ process::exit(1);
+ }
+}
diff --git a/third_party/rust/base64/examples/make_tables.rs b/third_party/rust/base64/examples/make_tables.rs
new file mode 100644
index 0000000000..2f27c0eb95
--- /dev/null
+++ b/third_party/rust/base64/examples/make_tables.rs
@@ -0,0 +1,179 @@
+use std::collections::{HashMap, HashSet};
+use std::iter::Iterator;
+
+fn main() {
+ println!("pub const INVALID_VALUE: u8 = 255;");
+
+ // A-Z
+ let standard_alphabet: Vec<u8> = (0x41..0x5B)
+ // a-z
+ .chain(0x61..0x7B)
+ // 0-9
+ .chain(0x30..0x3A)
+ // +
+ .chain(0x2B..0x2C)
+ // /
+ .chain(0x2F..0x30)
+ .collect();
+ print_encode_table(&standard_alphabet, "STANDARD_ENCODE", 0);
+ print_decode_table(&standard_alphabet, "STANDARD_DECODE", 0);
+
+ // A-Z
+ let url_alphabet: Vec<u8> = (0x41..0x5B)
+ // a-z
+ .chain(0x61..0x7B)
+ // 0-9
+ .chain(0x30..0x3A)
+ // -
+ .chain(0x2D..0x2E)
+ // _
+ .chain(0x5F..0x60)
+ .collect();
+ print_encode_table(&url_alphabet, "URL_SAFE_ENCODE", 0);
+ print_decode_table(&url_alphabet, "URL_SAFE_DECODE", 0);
+
+ // ./0123456789
+ let crypt_alphabet: Vec<u8> = (b'.'..(b'9' + 1))
+ // A-Z
+ .chain(b'A'..(b'Z' + 1))
+ // a-z
+ .chain(b'a'..(b'z' + 1))
+ .collect();
+ print_encode_table(&crypt_alphabet, "CRYPT_ENCODE", 0);
+ print_decode_table(&crypt_alphabet, "CRYPT_DECODE", 0);
+
+ // ./
+ let bcrypt_alphabet: Vec<u8> = (b'.'..(b'/' + 1))
+ // A-Z
+ .chain(b'A'..(b'Z' + 1))
+ // a-z
+ .chain(b'a'..(b'z' + 1))
+ // 0-9
+ .chain(b'0'..(b'9' + 1))
+ .collect();
+ print_encode_table(&bcrypt_alphabet, "BCRYPT_ENCODE", 0);
+ print_decode_table(&bcrypt_alphabet, "BCRYPT_DECODE", 0);
+
+ // A-Z
+ let imap_alphabet: Vec<u8> = (0x41..0x5B)
+ // a-z
+ .chain(0x61..0x7B)
+ // 0-9
+ .chain(0x30..0x3A)
+ // +
+ .chain(0x2B..0x2C)
+ // ,
+ .chain(0x2C..0x2D)
+ .collect();
+ print_encode_table(&imap_alphabet, "IMAP_MUTF7_ENCODE", 0);
+ print_decode_table(&imap_alphabet, "IMAP_MUTF7_DECODE", 0);
+
+ // '!' - '-'
+ let binhex_alphabet: Vec<u8> = (0x21..0x2E)
+ // 0-9
+ .chain(0x30..0x3A)
+ // @-N
+ .chain(0x40..0x4F)
+ // P-V
+ .chain(0x50..0x57)
+ // X-[
+ .chain(0x58..0x5C)
+ // `-f
+ .chain(0x60..0x66)
+ // h-m
+ .chain(0x68..0x6E)
+ // p-r
+ .chain(0x70..0x73)
+ .collect();
+ print_encode_table(&binhex_alphabet, "BINHEX_ENCODE", 0);
+ print_decode_table(&binhex_alphabet, "BINHEX_DECODE", 0);
+}
+
+fn print_encode_table(alphabet: &[u8], const_name: &str, indent_depth: usize) {
+ check_alphabet(alphabet);
+ println!("#[rustfmt::skip]");
+ println!(
+ "{:width$}pub const {}: &[u8; 64] = &[",
+ "",
+ const_name,
+ width = indent_depth
+ );
+
+ for (i, b) in alphabet.iter().enumerate() {
+ println!(
+ "{:width$}{}, // input {} (0x{:X}) => '{}' (0x{:X})",
+ "",
+ b,
+ i,
+ i,
+ String::from_utf8(vec![*b as u8]).unwrap(),
+ b,
+ width = indent_depth + 4
+ );
+ }
+
+ println!("{:width$}];", "", width = indent_depth);
+}
+
+fn print_decode_table(alphabet: &[u8], const_name: &str, indent_depth: usize) {
+ check_alphabet(alphabet);
+ // map of alphabet bytes to 6-bit morsels
+ let mut input_to_morsel = HashMap::<u8, u8>::new();
+
+ // standard base64 alphabet bytes, in order
+ for (morsel, ascii_byte) in alphabet.iter().enumerate() {
+ // truncation cast is fine here
+ let _ = input_to_morsel.insert(*ascii_byte, morsel as u8);
+ }
+
+ println!("#[rustfmt::skip]");
+ println!(
+ "{:width$}pub const {}: &[u8; 256] = &[",
+ "",
+ const_name,
+ width = indent_depth
+ );
+ for ascii_byte in 0..256 {
+ let (value, comment) = match input_to_morsel.get(&(ascii_byte as u8)) {
+ None => (
+ "INVALID_VALUE".to_string(),
+ format!("input {} (0x{:X})", ascii_byte, ascii_byte),
+ ),
+ Some(v) => (
+ format!("{}", *v),
+ format!(
+ "input {} (0x{:X} char '{}') => {} (0x{:X})",
+ ascii_byte,
+ ascii_byte,
+ String::from_utf8(vec![ascii_byte as u8]).unwrap(),
+ *v,
+ *v
+ ),
+ ),
+ };
+
+ println!(
+ "{:width$}{}, // {}",
+ "",
+ value,
+ comment,
+ width = indent_depth + 4
+ );
+ }
+ println!("{:width$}];", "", width = indent_depth);
+}
+
+fn check_alphabet(alphabet: &[u8]) {
+ // ensure all characters are distinct
+ assert_eq!(64, alphabet.len());
+ let mut set: HashSet<u8> = HashSet::new();
+ set.extend(alphabet);
+ assert_eq!(64, set.len());
+
+ // must be ASCII to be valid as single UTF-8 bytes
+ for &b in alphabet {
+ assert!(b <= 0x7F_u8);
+ // = is assumed to be padding, so cannot be used as a symbol
+ assert_ne!(b'=', b);
+ }
+}