about summary refs log tree commit diff
path: root/src/libstd/str.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/str.rs')
-rw-r--r--src/libstd/str.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index bd484a5074c..93cac8797bb 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -938,6 +938,7 @@ static TAG_CONT_U8: u8 = 128u8;
 
 /// Unsafe operations
 pub mod raw {
+    use option::{Option, Some};
     use cast;
     use libc;
     use ptr;
@@ -1091,6 +1092,34 @@ pub mod raw {
         vec::raw::set_len(as_owned_vec(s), new_len)
     }
 
+    /// Parses a C "multistring", eg windows env values or
+    /// the req->ptr result in a uv_fs_readdir() call.
+    /// Optionally, a `count` can be passed in, limiting the
+    /// parsing to only being done `count`-times.
+    #[inline]
+    pub unsafe fn from_c_multistring(buf: *libc::c_char, count: Option<uint>) -> ~[~str] {
+        #[fixed_stack_segment]; #[inline(never)];
+
+        let mut curr_ptr: uint = buf as uint;
+        let mut result = ~[];
+        let mut ctr = 0;
+        let (limited_count, limit) = match count {
+            Some(limit) => (true, limit),
+            None => (false, 0)
+        };
+        while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char
+             && ((limited_count && ctr < limit) || !limited_count)) {
+            let env_pair = from_c_str(
+                curr_ptr as *libc::c_char);
+            result.push(env_pair);
+            curr_ptr +=
+                libc::strlen(curr_ptr as *libc::c_char) as uint
+                + 1;
+            ctr += 1;
+        }
+        result
+    }
+
     /// Sets the length of a string
     ///
     /// This will explicitly set the size of the string, without actually
@@ -1106,6 +1135,25 @@ pub mod raw {
         }
     }
 
+    #[test]
+    fn test_str_multistring_parsing() {
+        use option::None;
+        unsafe {
+            let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
+            let ptr = vec::raw::to_ptr(input);
+            let mut result = from_c_multistring(ptr as *libc::c_char, None);
+            assert!(result.len() == 2);
+            let mut ctr = 0;
+            for x in result.iter() {
+                match ctr {
+                    0 => assert_eq!(x, &~"zero"),
+                    1 => assert_eq!(x, &~"one"),
+                    _ => fail!("shouldn't happen!")
+                }
+                ctr += 1;
+            }
+        }
+    }
 }
 
 /*