]> git.lizzy.rs Git - rust.git/commitdiff
Implement FromBase64 for &[u8].
authorSimon Sapin <simon.sapin@exyr.org>
Sat, 19 Jul 2014 15:46:14 +0000 (16:46 +0100)
committerSimon Sapin <simon.sapin@exyr.org>
Sat, 19 Jul 2014 15:46:14 +0000 (16:46 +0100)
The algorithm was already based on bytes internally.

Also use byte literals instead of casting u8 to char for matching.

src/libserialize/base64.rs

index 80a8a06edda6b36cfc0fa9a3c83b3e5b59e1429c..79c1d6554113f1b665e6c7e381c582f4aaf30d7d 100644 (file)
@@ -161,7 +161,7 @@ pub trait FromBase64 {
 /// Errors that can occur when decoding a base64 encoded string
 pub enum FromBase64Error {
     /// The input contained a character not part of the base64 format
-    InvalidBase64Character(char, uint),
+    InvalidBase64Byte(u8, uint),
     /// The input had an invalid length
     InvalidBase64Length,
 }
@@ -169,7 +169,7 @@ pub enum FromBase64Error {
 impl fmt::Show for FromBase64Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            InvalidBase64Character(ch, idx) =>
+            InvalidBase64Byte(ch, idx) =>
                 write!(f, "Invalid character '{}' at position {}", ch, idx),
             InvalidBase64Length => write!(f, "Invalid length"),
         }
@@ -205,24 +205,31 @@ impl<'a> FromBase64 for &'a str {
      * }
      * ```
      */
+    #[inline]
+    fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
+        self.as_bytes().from_base64()
+    }
+}
+
+impl<'a> FromBase64 for &'a [u8] {
     fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
         let mut r = Vec::new();
         let mut buf: u32 = 0;
         let mut modulus = 0i;
 
-        let mut it = self.bytes().enumerate();
-        for (idx, byte) in it {
+        let mut it = self.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' => continue,
-                '=' => break,
-                _ => return Err(InvalidBase64Character(self.char_at(idx), idx)),
+            match byte {
+                b'A'..b'Z' => buf |= val - 0x41,
+                b'a'..b'z' => buf |= val - 0x47,
+                b'0'..b'9' => buf |= val + 0x04,
+                b'+' | b'-' => buf |= 0x3E,
+                b'/' | b'_' => buf |= 0x3F,
+                b'\r' | b'\n' => continue,
+                b'=' => break,
+                _ => return Err(InvalidBase64Byte(self[idx], idx)),
             }
 
             buf <<= 6;
@@ -235,10 +242,10 @@ fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
             }
         }
 
-        for (idx, byte) in it {
-            match byte as char {
-                '='|'\r'|'\n' => continue,
-                _ => return Err(InvalidBase64Character(self.char_at(idx), idx)),
+        for (idx, &byte) in it {
+            match byte {
+                b'=' | b'\r' | b'\n' => continue,
+                _ => return Err(InvalidBase64Byte(self[idx], idx)),
             }
         }
 
@@ -308,6 +315,11 @@ fn test_from_base64_basic() {
         assert_eq!("Zm9vYmFy".from_base64().unwrap().as_slice(), "foobar".as_bytes());
     }
 
+    #[test]
+    fn test_from_base64_bytes() {
+        assert_eq!(b"Zm9vYmFy".from_base64().unwrap().as_slice(), "foobar".as_bytes());
+    }
+
     #[test]
     fn test_from_base64_newlines() {
         assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap().as_slice(),