diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index d6ab36ca721..b4431004bd7 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -150,29 +150,6 @@ impl<'self> ToBase64 for &'self [u8] { } } -impl<'self> ToBase64 for &'self str { - /** - * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding. - * - * - * # Example - * - * ~~~ {.rust} - * extern mod extra; - * use extra::base64::{ToBase64, standard}; - * - * fn main () { - * let str = "Hello, World".to_base64(standard); - * printfln!("%s", str); - * } - * ~~~ - * - */ - fn to_base64(&self, config: Config) -> ~str { - self.as_bytes().to_base64(config) - } -} - /// A trait for converting from base64 encoded values. pub trait FromBase64 { /// Converts the value of `self`, interpreted as base64 encoded data, into @@ -180,76 +157,6 @@ pub trait FromBase64 { fn from_base64(&self) -> Result<~[u8], ~str>; } -impl<'self> FromBase64 for &'self [u8] { - /** - * Convert base64 `u8` vector into u8 byte values. - * Every 4 encoded characters is converted into 3 octets, modulo padding. - * - * # Example - * - * ~~~ {.rust} - * extern mod extra; - * use extra::base64::{ToBase64, FromBase64, standard}; - * - * fn main () { - * let str = [52,32].to_base64(standard); - * printfln!("%s", str); - * let bytes = str.from_base64(); - * printfln!("%?", bytes); - * } - * ~~~ - */ - fn from_base64(&self) -> Result<~[u8], ~str> { - let mut r = ~[]; - let mut buf: u32 = 0; - let mut modulus = 0; - - let mut it = self.iter(); - for &byte in it { - let ch = byte as char; - let val = byte as u32; - - match ch { - 'A'..'Z' => buf |= val - 0x41, - 'a'..'z' => buf |= val - 0x47, - '0'..'9' => buf |= val + 0x04, - '+'|'-' => buf |= 0x3E, - '/'|'_' => buf |= 0x3F, - '\r'|'\n' => loop, - '=' => break, - _ => return Err(~"Invalid Base64 character") - } - - buf <<= 6; - modulus += 1; - if modulus == 4 { - modulus = 0; - r.push((buf >> 22) as u8); - r.push((buf >> 14) as u8); - r.push((buf >> 6 ) as u8); - } - } - - if !it.all(|&byte| {byte as char == '='}) { - return Err(~"Invalid Base64 character"); - } - - match modulus { - 2 => { - r.push((buf >> 10) as u8); - } - 3 => { - r.push((buf >> 16) as u8); - r.push((buf >> 8 ) as u8); - } - 0 => (), - _ => return Err(~"Invalid Base64 length") - } - - Ok(r) - } -} - impl<'self> FromBase64 for &'self str { /** * Convert any base64 encoded string (literal, `@`, `&`, or `~`) @@ -279,7 +186,56 @@ impl<'self> FromBase64 for &'self str { * ~~~ */ fn from_base64(&self) -> Result<~[u8], ~str> { - self.as_bytes().from_base64() + let mut r = ~[]; + let mut buf: u32 = 0; + let mut modulus = 0; + + let mut it = self.byte_iter().enumerate(); + for (idx, byte) in it { + let val = byte as u32; + + match byte as char { + 'A'..'Z' => buf |= val - 0x41, + 'a'..'z' => buf |= val - 0x47, + '0'..'9' => buf |= val + 0x04, + '+'|'-' => buf |= 0x3E, + '/'|'_' => buf |= 0x3F, + '\r'|'\n' => loop, + '=' => break, + _ => return Err(fmt!("Invalid character '%c' at position %u", + self.char_at(idx), idx)) + } + + buf <<= 6; + modulus += 1; + if modulus == 4 { + modulus = 0; + r.push((buf >> 22) as u8); + r.push((buf >> 14) as u8); + r.push((buf >> 6 ) as u8); + } + } + + for (idx, byte) in it { + if (byte as char) != '=' { + return Err(fmt!("Invalid character '%c' at position %u", + self.char_at(idx), idx)); + } + } + + match modulus { + 2 => { + r.push((buf >> 10) as u8); + } + 3 => { + r.push((buf >> 16) as u8); + r.push((buf >> 8 ) as u8); + } + 0 => (), + _ => return Err(~"Invalid Base64 length") + } + + Ok(r) } } @@ -290,27 +246,28 @@ mod test { #[test] fn test_to_base64_basic() { - assert_eq!("".to_base64(STANDARD), ~""); - assert_eq!("f".to_base64(STANDARD), ~"Zg=="); - assert_eq!("fo".to_base64(STANDARD), ~"Zm8="); - assert_eq!("foo".to_base64(STANDARD), ~"Zm9v"); - assert_eq!("foob".to_base64(STANDARD), ~"Zm9vYg=="); - assert_eq!("fooba".to_base64(STANDARD), ~"Zm9vYmE="); - assert_eq!("foobar".to_base64(STANDARD), ~"Zm9vYmFy"); + assert_eq!("".as_bytes().to_base64(STANDARD), ~""); + assert_eq!("f".as_bytes().to_base64(STANDARD), ~"Zg=="); + assert_eq!("fo".as_bytes().to_base64(STANDARD), ~"Zm8="); + assert_eq!("foo".as_bytes().to_base64(STANDARD), ~"Zm9v"); + assert_eq!("foob".as_bytes().to_base64(STANDARD), ~"Zm9vYg=="); + assert_eq!("fooba".as_bytes().to_base64(STANDARD), ~"Zm9vYmE="); + assert_eq!("foobar".as_bytes().to_base64(STANDARD), ~"Zm9vYmFy"); } #[test] fn test_to_base64_line_break() { assert!(![0u8, 1000].to_base64(Config {line_length: None, ..STANDARD}) .contains("\r\n")); - assert_eq!("foobar".to_base64(Config {line_length: Some(4), ..STANDARD}), + assert_eq!("foobar".as_bytes().to_base64(Config {line_length: Some(4), + ..STANDARD}), ~"Zm9v\r\nYmFy"); } #[test] fn test_to_base64_padding() { - assert_eq!("f".to_base64(Config {pad: false, ..STANDARD}), ~"Zg"); - assert_eq!("fo".to_base64(Config {pad: false, ..STANDARD}), ~"Zm8"); + assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), ~"Zg"); + assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), ~"Zm8"); } #[test] @@ -344,7 +301,7 @@ mod test { #[test] fn test_from_base64_invalid_char() { assert!("Zm$=".from_base64().is_err()) - assert!("Zg==$".from_base64().is_err()); + assert!("Zg==$".from_base64().is_err()); } #[test] @@ -368,20 +325,20 @@ mod test { } #[bench] - pub fn to_base64(bh: & mut BenchHarness) { + pub fn bench_to_base64(bh: & mut BenchHarness) { let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; do bh.iter { - s.to_base64(STANDARD); + s.as_bytes().to_base64(STANDARD); } bh.bytes = s.len() as u64; } #[bench] - pub fn from_base64(bh: & mut BenchHarness) { + pub fn bench_from_base64(bh: & mut BenchHarness) { let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - let b = s.to_base64(STANDARD); + let b = s.as_bytes().to_base64(STANDARD); do bh.iter { b.from_base64(); } diff --git a/src/libextra/hex.rs b/src/libextra/hex.rs index ddd1276a987..2a6a8a52055 100644 --- a/src/libextra/hex.rs +++ b/src/libextra/hex.rs @@ -50,29 +50,6 @@ impl<'self> ToHex for &'self [u8] { } } -impl<'self> ToHex for &'self str { - /** - * Convert any string (literal, `@`, `&`, or `~`) to hexadecimal encoding. - * - * - * # Example - * - * ~~~ {.rust} - * extern mod extra; - * use extra::ToHex; - * - * fn main () { - * let str = "Hello, World".to_hex(); - * printfln!("%s", str); - * } - * ~~~ - * - */ - fn to_hex(&self) -> ~str { - self.as_bytes().to_hex() - } -} - /// A trait for converting hexadecimal encoded values pub trait FromHex { /// Converts the value of `self`, interpreted as hexadecimal encoded data, @@ -80,61 +57,6 @@ pub trait FromHex { fn from_hex(&self) -> Result<~[u8], ~str>; } -impl<'self> FromHex for &'self [u8] { - /** - * Convert hexadecimal `u8` vector into u8 byte values. - * Every 2 encoded characters is converted into 1 octet. - * Whitespace is ignored. - * - * # Example - * - * ~~~ {.rust} - * extern mod extra; - * use extra::hex::{ToHex, FromHex}; - * - * fn main () { - * let str = [52,32].to_hex(); - * printfln!("%s", str); - * let bytes = str.from_hex().get(); - * printfln!("%?", bytes); - * } - * ~~~ - */ - fn from_hex(&self) -> Result<~[u8], ~str> { - // This may be an overestimate if there is any whitespace - let mut b = vec::with_capacity(self.len() / 2); - let mut modulus = 0; - let mut buf = 0u8; - - for (idx, &byte) in self.iter().enumerate() { - buf <<= 4; - - match byte as char { - 'A'..'F' => buf |= byte - ('A' as u8) + 10, - 'a'..'f' => buf |= byte - ('a' as u8) + 10, - '0'..'9' => buf |= byte - ('0' as u8), - ' '|'\r'|'\n'|'\t' => { - buf >>= 4; - loop - } - _ => return Err(fmt!("Invalid byte '%c' found at position %u", - byte as char, idx)) - } - - modulus += 1; - if modulus == 2 { - modulus = 0; - b.push(buf); - } - } - - match modulus { - 0 => Ok(b), - _ => Err(~"Invalid input length") - } - } -} - impl<'self> FromHex for &'self str { /** * Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`) @@ -164,7 +86,37 @@ impl<'self> FromHex for &'self str { * ~~~ */ fn from_hex(&self) -> Result<~[u8], ~str> { - self.as_bytes().from_hex() + // This may be an overestimate if there is any whitespace + let mut b = vec::with_capacity(self.len() / 2); + let mut modulus = 0; + let mut buf = 0u8; + + for (idx, byte) in self.byte_iter().enumerate() { + buf <<= 4; + + match byte as char { + 'A'..'F' => buf |= byte - ('A' as u8) + 10, + 'a'..'f' => buf |= byte - ('a' as u8) + 10, + '0'..'9' => buf |= byte - ('0' as u8), + ' '|'\r'|'\n'|'\t' => { + buf >>= 4; + loop + } + _ => return Err(fmt!("Invalid character '%c' at position %u", + self.char_at(idx), idx)) + } + + modulus += 1; + if modulus == 2 { + modulus = 0; + b.push(buf); + } + } + + match modulus { + 0 => Ok(b), + _ => Err(~"Invalid input length") + } } } @@ -175,7 +127,7 @@ mod tests { #[test] pub fn test_to_hex() { - assert_eq!("foobar".to_hex(), ~"666f6f626172"); + assert_eq!("foobar".as_bytes().to_hex(), ~"666f6f626172"); } #[test] @@ -223,7 +175,7 @@ mod tests { let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; do bh.iter { - s.to_hex(); + s.as_bytes().to_hex(); } bh.bytes = s.len() as u64; } @@ -232,7 +184,7 @@ mod tests { pub fn bench_from_hex(bh: & mut BenchHarness) { let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - let b = s.to_hex(); + let b = s.as_bytes().to_hex(); do bh.iter { b.from_hex(); }