about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/error.rs18
-rw-r--r--src/libstd/os.rs2
-rw-r--r--src/libstd/sys/windows/os.rs39
3 files changed, 53 insertions, 6 deletions
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 9ad2655f6e9..cd7d9aacc90 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -78,10 +78,9 @@
 //! }
 //! ```
 
-use option::Option;
-use option::Option::None;
-use kinds::Send;
-use string::String;
+use prelude::*;
+
+use str::Utf8Error;
 
 /// Base functionality for all errors in Rust.
 pub trait Error: Send {
@@ -107,3 +106,14 @@ impl<E> FromError<E> for E {
         err
     }
 }
+
+impl Error for Utf8Error {
+    fn description(&self) -> &str {
+        match *self {
+            Utf8Error::TooShort => "invalid utf-8: not enough bytes",
+            Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
+        }
+    }
+
+    fn detail(&self) -> Option<String> { Some(self.to_string()) }
+}
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 258e8964a9f..a16ee982f5c 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -729,7 +729,7 @@ fn real_args() -> Vec<String> {
         // Push it onto the list.
         let ptr = ptr as *const u16;
         let buf = slice::from_raw_buf(&ptr, len);
-        let opt_s = String::from_utf16(::str::truncate_utf16_at_nul(buf));
+        let opt_s = String::from_utf16(os_imp::truncate_utf16_at_nul(buf));
         opt_s.expect("CommandLineToArgvW returned invalid UTF-16")
     });
 
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index e2220b7b67b..e1016048e58 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -31,6 +31,16 @@ use libc::types::os::arch::extra::DWORD;
 
 const BUF_BYTES : uint = 2048u;
 
+/// Return a slice of `v` ending at (and not including) the first NUL
+/// (0).
+pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
+    match v.iter().position(|c| *c == 0) {
+        // don't include the 0
+        Some(i) => v[..i],
+        None => v
+    }
+}
+
 pub fn errno() -> uint {
     use libc::types::os::arch::extra::DWORD;
 
@@ -87,7 +97,7 @@ pub fn error_string(errnum: i32) -> String {
             return format!("OS Error {} (FormatMessageW() returned error {})", errnum, fm_err);
         }
 
-        let msg = String::from_utf16(::str::truncate_utf16_at_nul(&buf));
+        let msg = String::from_utf16(truncate_utf16_at_nul(&buf));
         match msg {
             Some(msg) => format!("OS Error {}: {}", errnum, msg),
             None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum),
@@ -294,3 +304,30 @@ pub fn page_size() -> uint {
         return info.dwPageSize as uint;
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::truncate_utf16_at_nul;
+
+    #[test]
+    fn test_truncate_utf16_at_nul() {
+        let v = [];
+        let b: &[u16] = &[];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [0, 2, 3];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [1, 0, 3];
+        let b: &[u16] = &[1];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [1, 2, 0];
+        let b: &[u16] = &[1, 2];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+
+        let v = [1, 2, 3];
+        let b: &[u16] = &[1, 2, 3];
+        assert_eq!(truncate_utf16_at_nul(&v), b);
+    }
+}