diff options
| author | bors <bors@rust-lang.org> | 2013-09-17 14:05:45 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-09-17 14:05:45 -0700 |
| commit | c135cb268355afe77d2ce0313a8d3e20a4e2fdd3 (patch) | |
| tree | 561787933db67139783cc13d1d2ac276391120f3 /src/libstd/str.rs | |
| parent | 9e8fb4ad61cfe97413eb92d764aa6aeeb23d5afa (diff) | |
| parent | 70152ff55722878cde684ee6462c14c65f2c4729 (diff) | |
auto merge of #9235 : olsonjeffery/rust/newrt_file_io_1, r=thestinger
A quick rundown:
- added `file::{readdir, stat, mkdir, rmdir}`
- Added access-constrained versions of `FileStream`; `FileReader` and `FileWriter` respectively
- big rework in `uv::file` .. most actions are by-val-self methods on `FsRequest`; `FileDescriptor` has gone the way of the dinosaurs
- playing nice w/ homing IO (I just copied ecr's work, hehe), etc
- added `FileInfo` trait, with an impl for `Path`
- wrapper for file-specific actions, with the file path always implied by self's value
- has the means to create `FileReader` & `FileWriter` (this isn't exposed in the top-level free function API)
- has "safe" wrappers for `stat()` that won't throw in the event of non-existence/error (in this case, I mean `is_file` and `exists`)
- actions should fail if done on non-regular-files, as appropriate
- added `DirectoryInfo` trait, with an impl for `Path`
- pretty much ditto above, but for directories
- added `readdir` (!!) to iterate over entries in a dir as a `~[Path]` (this was *brutal* to get working)
...<del>and lots of other stuff</del>not really. Do your worst!
Diffstat (limited to 'src/libstd/str.rs')
| -rw-r--r-- | src/libstd/str.rs | 48 |
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; + } + } + } } /* |
