diff --git a/src/enc/mod.rs b/src/enc/mod.rs index f15f041..920f5fe 100644 --- a/src/enc/mod.rs +++ b/src/enc/mod.rs @@ -24,7 +24,7 @@ use std::collections::HashMap; use crate::*; use crate::dec::{self, decode}; -use crate::{is_string_char, is_whitespace, switch64, BytesEncoding}; +use crate::{is_string_char, is_whitespace, BytesEncoding}; pub use error::Error; @@ -154,9 +154,6 @@ pub fn bytes_format(bytes: &[u8], encoding: BytesEncoding) -> Term<'static> { Term(chunks.into_iter().next().unwrap()) } } - BytesEncoding::Switch64 { allow_whitespace } => { - Term(T::OwnedStr(switch64::encode(bytes, allow_whitespace))) - } } } diff --git a/src/lib.rs b/src/lib.rs index 2f37ac0..33b3fed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,6 @@ pub mod dec; pub mod enc; -pub mod switch64; #[cfg(feature = "dryoc")] pub mod crypto; @@ -101,8 +100,6 @@ pub enum BytesEncoding { Base64 { split: bool }, /// Hexadecimal encoding Hex { split: bool }, - /// Switch64 encoding, a mix of plain text and base64 - Switch64 { allow_whitespace: bool }, } impl Default for BytesEncoding { @@ -116,9 +113,6 @@ impl BytesEncoding { match self { BytesEncoding::Base64 { .. } => BytesEncoding::Base64 { split: false }, BytesEncoding::Hex { .. } => BytesEncoding::Hex { split: false }, - BytesEncoding::Switch64 { .. } => BytesEncoding::Switch64 { - allow_whitespace: false, - }, } } } @@ -135,9 +129,6 @@ pub(crate) const LIST_DELIM: u8 = b';'; const BASE_EXTRA_CHARS: &[u8] = b".,:?!@$^<>|&#'_-+*/%"; const STR_EXTRA_CHARS: &[u8] = b"\\"; -pub(crate) const SWITCH64_SEPARATOR: u8 = b'\\'; -pub(crate) const SWITCH64_EXTRA_CHARS: &[u8] = BASE_EXTRA_CHARS; - #[inline] pub(crate) fn is_string_char(c: u8) -> bool { c.is_ascii_alphanumeric() || BASE_EXTRA_CHARS.contains(&c) || STR_EXTRA_CHARS.contains(&c) diff --git a/src/serde/mod.rs b/src/serde/mod.rs index a4bde56..06df916 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -32,17 +32,6 @@ mod tests { eprintln!("Serialized (concise): {}", ser_concise); assert_eq!(ser_concise, expected_concise); assert_eq!(from_bytes::(ser_concise.as_bytes()).unwrap(), input); - - // let ser_str_hex = input - // .serialize(&mut Serializer { - // string_format: BytesEncoding::Switch64 { - // allow_whitespace: true, - // }, - // bytes_format: BytesEncoding::Hex { split: true }, - // }) - // .unwrap() - // .encode(); - // panic!("{}", debug(&ser_str_hex)); } #[test] diff --git a/src/switch64.rs b/src/switch64.rs deleted file mode 100644 index 5043e98..0000000 --- a/src/switch64.rs +++ /dev/null @@ -1,134 +0,0 @@ -//! The Switch64 encoding for text strings -//! -//! Allowed characters are encoded as-is. -//! Others are encoded using base64. -//! Plain parts and base64-encoded parts are separated by a backslasah `\` - -use crate::{SWITCH64_EXTRA_CHARS, SWITCH64_SEPARATOR}; - -pub fn encode(bytes: &[u8], allow_whitespace: bool) -> Vec { - let mut output = Vec::with_capacity(bytes.len()); - - let mut pos = 0; - while pos < bytes.len() { - // Determine how many bytes to copy as-is - let cnt = bytes[pos..] - .iter() - .take_while(|c| is_valid_plaintext_char(**c, allow_whitespace)) - .count(); - - // Copy those bytes as-is - output.extend_from_slice(&bytes[pos..pos + cnt]); - pos += cnt; - - // If some bytes remain, switch to base64 encoding - if pos < bytes.len() { - output.push(SWITCH64_SEPARATOR); - } else { - break; - } - - // Count how many bytes to write as base64 - // We stop at the first position where we find three consecutive - // characters to encode as-is - let mut b64end = bytes.len(); - for i in pos..bytes.len() { - if i + 3 > bytes.len() { - break; - } - if bytes[i..i + 3] - .iter() - .all(|c| is_valid_plaintext_char(*c, allow_whitespace)) - { - b64end = i; - break; - } - } - - output.extend_from_slice( - base64::encode_config(&bytes[pos..b64end], base64::URL_SAFE_NO_PAD).as_bytes(), - ); - pos = b64end; - - if pos < bytes.len() { - output.push(SWITCH64_SEPARATOR); - } - } - - output -} - -pub fn decode(bytes: &[u8]) -> Result, base64::DecodeError> { - let mut output = Vec::with_capacity(bytes.len()); - - let mut pos = 0; - while pos < bytes.len() { - let cnt = bytes[pos..] - .iter() - .take_while(|c| **c != SWITCH64_SEPARATOR) - .count(); - output.extend_from_slice(&bytes[pos..pos + cnt]); - pos += cnt + 1; - - if pos >= bytes.len() { - break; - } - - let cnt = bytes[pos..] - .iter() - .take_while(|c| **c != SWITCH64_SEPARATOR) - .count(); - output.extend_from_slice(&base64::decode_config( - &bytes[pos..pos + cnt], - base64::URL_SAFE_NO_PAD, - )?); - pos += cnt + 1; - } - - Ok(output) -} - -#[inline] -fn is_valid_plaintext_char(c: u8, allow_whitespace: bool) -> bool { - c.is_ascii_alphanumeric() - || (allow_whitespace && c.is_ascii_whitespace()) - || SWITCH64_EXTRA_CHARS.contains(&c) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::debug; - - #[test] - fn test_encode() { - assert_eq!(debug(&encode(&b"hello world"[..], true)), "hello world"); - assert_eq!( - debug(&encode(&b"hello, world!"[..], true)), - "hello, world!" - ); - } - - #[test] - fn test_decode() { - assert_eq!(debug(&decode(&b"hello world"[..]).unwrap()), "hello world"); - assert_eq!( - debug(&decode(&b"hello\\LA\\ world\\IQ"[..]).unwrap()), - "hello, world!" - ); - assert_eq!(debug(&decode(&b"\\LDssQCQ7OA"[..]).unwrap()), ",;,@$;8"); - } - - #[test] - fn test_encdec() { - for s in [ - br#"assert_eq!(debug(&decode(&b"hello\\LA\\ world\\IQ"[..]).unwrap()), "hello, world!");"#.to_vec(), - br#"- a list, which may contain any number of any kind of terms (can be mixed)"#.to_vec(), - base64::decode("dVcG5EzJqGP/2ZGkVu4ewzfAug1W96tb2KiBOVyPUXfw8uD34DEepW/PPqRzi0HL").unwrap(), - br#",;,@$;8"#.to_vec() - ] { - assert_eq!(decode(&encode(&s, true)).unwrap(), s); - assert_eq!(decode(&encode(&s, false)).unwrap(), s); - } - } -}