From 6d99a2f8a99baedab90fb8bd6cb6e1507fad736b Mon Sep 17 00:00:00 2001 From: Jesse Jones Date: Sat, 17 Nov 2012 10:13:11 -0800 Subject: [PATCH] Made more stuff pure. escape functions in char, io.with_str_reader, base64 and md5sum, cell.empty_cell and is_empty. --- src/libcore/char.rs | 12 +-- src/libcore/io.rs | 2 +- src/libstd/base64.rs | 174 ++++++++++++++++++++++--------------------- src/libstd/cell.rs | 4 +- src/libstd/md4.rs | 14 ++-- 5 files changed, 105 insertions(+), 101 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index b76571864e0..802aaf12bdd 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -126,16 +126,18 @@ * - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN` * - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN` */ -pub fn escape_unicode(c: char) -> ~str { +pub pure fn escape_unicode(c: char) -> ~str { let s = u32::to_str(c as u32, 16u); let (c, pad) = (if c <= '\xff' { ('x', 2u) } else if c <= '\uffff' { ('u', 4u) } else { ('U', 8u) }); assert str::len(s) <= pad; let mut out = ~"\\"; - str::push_str(&mut out, str::from_char(c)); - for uint::range(str::len(s), pad) |_i| { str::push_str(&mut out, ~"0"); } - str::push_str(&mut out, s); + unsafe { + str::push_str(&mut out, str::from_char(c)); + for uint::range(str::len(s), pad) |_i| { str::push_str(&mut out, ~"0"); } + str::push_str(&mut out, s); + } move out } @@ -151,7 +153,7 @@ pub fn escape_unicode(c: char) -> ~str { * - Any other chars in the range [0x20,0x7e] are not escaped. * - Any other chars are given hex unicode escapes; see `escape_unicode`. */ -pub fn escape_default(c: char) -> ~str { +pub pure fn escape_default(c: char) -> ~str { match c { '\t' => ~"\\t", '\r' => ~"\\r", diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 4629878b4b7..535ab883581 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -512,7 +512,7 @@ fn tell() -> uint { self.pos } f(BytesReader { bytes: bytes, pos: 0u } as Reader) } -pub fn with_str_reader(s: &str, f: fn(Reader) -> T) -> T { +pub pure fn with_str_reader(s: &str, f: fn(Reader) -> T) -> T { str::byte_slice(s, |bytes| with_bytes_reader(bytes, f)) } diff --git a/src/libstd/base64.rs b/src/libstd/base64.rs index 9bad4d39750..177074de8f6 100644 --- a/src/libstd/base64.rs +++ b/src/libstd/base64.rs @@ -2,72 +2,73 @@ use io::Reader; pub trait ToBase64 { - fn to_base64() -> ~str; + pure fn to_base64() -> ~str; } impl &[u8]: ToBase64 { - fn to_base64() -> ~str { + pure fn to_base64() -> ~str { let chars = str::chars( ~"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ); - let len = self.len(); let mut s = ~""; - str::reserve(&mut s, ((len + 3u) / 4u) * 3u); - - let mut i = 0u; - - while i < len - (len % 3u) { - let n = (self[i] as uint) << 16u | - (self[i + 1u] as uint) << 8u | - (self[i + 2u] as uint); - - // This 24-bit number gets separated into four 6-bit numbers. - str::push_char(&mut s, chars[(n >> 18u) & 63u]); - str::push_char(&mut s, chars[(n >> 12u) & 63u]); - str::push_char(&mut s, chars[(n >> 6u) & 63u]); - str::push_char(&mut s, chars[n & 63u]); - - i += 3u; - } - - // Heh, would be cool if we knew this was exhaustive - // (the dream of bounded integer types) - match len % 3 { - 0 => (), - 1 => { - let n = (self[i] as uint) << 16u; - str::push_char(&mut s, chars[(n >> 18u) & 63u]); - str::push_char(&mut s, chars[(n >> 12u) & 63u]); - str::push_char(&mut s, '='); - str::push_char(&mut s, '='); - } - 2 => { - let n = (self[i] as uint) << 16u | (self[i + 1u] as uint) << 8u; - str::push_char(&mut s, chars[(n >> 18u) & 63u]); - str::push_char(&mut s, chars[(n >> 12u) & 63u]); - str::push_char(&mut s, chars[(n >> 6u) & 63u]); - str::push_char(&mut s, '='); - } - _ => fail ~"Algebra is broken, please alert the math police" + unsafe { + let len = self.len(); + str::reserve(&mut s, ((len + 3u) / 4u) * 3u); + + let mut i = 0u; + + while i < len - (len % 3u) { + let n = (self[i] as uint) << 16u | + (self[i + 1u] as uint) << 8u | + (self[i + 2u] as uint); + + // This 24-bit number gets separated into four 6-bit numbers. + str::push_char(&mut s, chars[(n >> 18u) & 63u]); + str::push_char(&mut s, chars[(n >> 12u) & 63u]); + str::push_char(&mut s, chars[(n >> 6u) & 63u]); + str::push_char(&mut s, chars[n & 63u]); + + i += 3u; + } + + // Heh, would be cool if we knew this was exhaustive + // (the dream of bounded integer types) + match len % 3 { + 0 => (), + 1 => { + let n = (self[i] as uint) << 16u; + str::push_char(&mut s, chars[(n >> 18u) & 63u]); + str::push_char(&mut s, chars[(n >> 12u) & 63u]); + str::push_char(&mut s, '='); + str::push_char(&mut s, '='); + } + 2 => { + let n = (self[i] as uint) << 16u | (self[i + 1u] as uint) << 8u; + str::push_char(&mut s, chars[(n >> 18u) & 63u]); + str::push_char(&mut s, chars[(n >> 12u) & 63u]); + str::push_char(&mut s, chars[(n >> 6u) & 63u]); + str::push_char(&mut s, '='); + } + _ => fail ~"Algebra is broken, please alert the math police" + } } - s } } impl &str: ToBase64 { - fn to_base64() -> ~str { + pure fn to_base64() -> ~str { str::to_bytes(self).to_base64() } } pub trait FromBase64 { - fn from_base64() -> ~[u8]; + pure fn from_base64() -> ~[u8]; } impl ~[u8]: FromBase64 { - fn from_base64() -> ~[u8] { + pure fn from_base64() -> ~[u8] { if self.len() % 4u != 0u { fail ~"invalid base64 length"; } let len = self.len(); @@ -80,55 +81,56 @@ fn from_base64() -> ~[u8] { let mut r = vec::with_capacity((len / 4u) * 3u - padding); - let mut i = 0u; - while i < len { - let mut n = 0u; - - for iter::repeat(4u) { - let ch = self[i] as char; - n <<= 6u; - - if ch >= 'A' && ch <= 'Z' { - n |= (ch as uint) - 0x41u; - } else if ch >= 'a' && ch <= 'z' { - n |= (ch as uint) - 0x47u; - } else if ch >= '0' && ch <= '9' { - n |= (ch as uint) + 0x04u; - } else if ch == '+' { - n |= 0x3Eu; - } else if ch == '/' { - n |= 0x3Fu; - } else if ch == '=' { - match len - i { - 1u => { - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - return copy r; - } - 2u => { - r.push(((n >> 10u) & 0xFFu) as u8); - return copy r; - } - _ => fail ~"invalid base64 padding" + unsafe { + let mut i = 0u; + while i < len { + let mut n = 0u; + + for iter::repeat(4u) { + let ch = self[i] as char; + n <<= 6u; + + if ch >= 'A' && ch <= 'Z' { + n |= (ch as uint) - 0x41u; + } else if ch >= 'a' && ch <= 'z' { + n |= (ch as uint) - 0x47u; + } else if ch >= '0' && ch <= '9' { + n |= (ch as uint) + 0x04u; + } else if ch == '+' { + n |= 0x3Eu; + } else if ch == '/' { + n |= 0x3Fu; + } else if ch == '=' { + match len - i { + 1u => { + r.push(((n >> 16u) & 0xFFu) as u8); + r.push(((n >> 8u ) & 0xFFu) as u8); + return copy r; + } + 2u => { + r.push(((n >> 10u) & 0xFFu) as u8); + return copy r; + } + _ => fail ~"invalid base64 padding" + } + } else { + fail ~"invalid base64 character"; } - } else { - fail ~"invalid base64 character"; - } - - i += 1u; - }; - - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - r.push(((n ) & 0xFFu) as u8); + + i += 1u; + }; + + r.push(((n >> 16u) & 0xFFu) as u8); + r.push(((n >> 8u ) & 0xFFu) as u8); + r.push(((n ) & 0xFFu) as u8); + } } - r } } impl ~str: FromBase64 { - fn from_base64() -> ~[u8] { + pure fn from_base64() -> ~[u8] { str::to_bytes(self).from_base64() } } diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index 4f79bf2b316..78027aa8907 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -12,7 +12,7 @@ pub fn Cell(value: T) -> Cell { Cell { value: Some(move value) } } -pub fn empty_cell() -> Cell { +pub pure fn empty_cell() -> Cell { Cell { value: None } } @@ -37,7 +37,7 @@ fn put_back(value: T) { } /// Returns true if the cell is empty and false if the cell is full. - fn is_empty() -> bool { + pure fn is_empty() -> bool { self.value.is_none() } diff --git a/src/libstd/md4.rs b/src/libstd/md4.rs index 581beb78bdc..d9bc03c311d 100644 --- a/src/libstd/md4.rs +++ b/src/libstd/md4.rs @@ -1,6 +1,6 @@ #[forbid(deprecated_mode)]; -pub fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { +pub pure fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { // subtle: if orig_len is merely uint, then the code below // which performs shifts by 32 bits or more has undefined // results. @@ -10,14 +10,14 @@ pub fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { let mut msg = vec::append(vec::from_slice(msg), ~[0x80u8]); let mut bitlen = orig_len + 8u64; while (bitlen + 64u64) % 512u64 > 0u64 { - msg.push(0u8); + unsafe {msg.push(0u8);} bitlen += 8u64; } // append length let mut i = 0u64; while i < 8u64 { - msg.push((orig_len >> (i * 8u64)) as u8); + unsafe {msg.push((orig_len >> (i * 8u64)) as u8);} i += 1u64; } @@ -26,7 +26,7 @@ pub fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { let mut c = 0x98badcfeu32; let mut d = 0x10325476u32; - fn rot(r: int, x: u32) -> u32 { + pure fn rot(r: int, x: u32) -> u32 { let r = r as u32; (x << r) | (x >> (32u32 - r)) } @@ -84,9 +84,9 @@ fn rot(r: int, x: u32) -> u32 { return {a: a, b: b, c: c, d: d}; } -pub fn md4_str(msg: &[u8]) -> ~str { +pub pure fn md4_str(msg: &[u8]) -> ~str { let {a, b, c, d} = md4(msg); - fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) { + pure fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) { f(a); f(b); f(c); f(d); } let mut result = ~""; @@ -102,7 +102,7 @@ fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) { result } -pub fn md4_text(msg: &str) -> ~str { md4_str(str::to_bytes(msg)) } +pub pure fn md4_text(msg: &str) -> ~str { md4_str(str::to_bytes(msg)) } #[test] fn test_md4() { -- GitLab